diff --git a/[refs] b/[refs] index 47ed13daa8d1..49610f67c3e1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2873957df0ead5b53fa00fddfb52ca3df38af4a9 +refs/heads/master: d9d52b5178af586d679c1052fb161ee05ea2e83f diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index a73b9b3cffad..405aea02dfbf 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -3956,7 +3956,6 @@ F: net/rfkill/ F: net/wireless/ F: include/net/ieee80211* F: include/linux/wireless.h -F: include/linux/iw_handler.h F: drivers/net/wireless/ NETWORKING DRIVERS diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index b9e7618a1473..dbd26f992158 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -1453,6 +1453,20 @@ config FORCEDETH To compile this driver as a module, choose M here. The module will be called forcedeth. +config FORCEDETH_NAPI + bool "Use Rx Polling (NAPI) (EXPERIMENTAL)" + depends on FORCEDETH && EXPERIMENTAL + help + NAPI is a new driver API designed to reduce CPU and interrupt load + when the driver is receiving lots of packets from the card. It is + still somewhat experimental and thus not yet enabled by default. + + If your estimated Rx load is 10kpps or more, or if the card will be + deployed on potentially unfriendly networks (e.g. in a firewall), + then say Y here. + + If in doubt, say N. + config CS89x0 tristate "CS89x0 support" depends on NET_ETHERNET && (ISA || EISA || MACH_IXDP2351 \ diff --git a/trunk/drivers/net/bnx2x_main.c b/trunk/drivers/net/bnx2x_main.c index 2bc35c794aec..f706ed191f19 100644 --- a/trunk/drivers/net/bnx2x_main.c +++ b/trunk/drivers/net/bnx2x_main.c @@ -1726,7 +1726,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) skb->protocol = eth_type_trans(skb, bp->dev); - if ((bp->dev->features & NETIF_F_RXHASH) && + if ((bp->dev->features & ETH_FLAG_RXHASH) && (cqe_fp_status_flags & ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG)) skb->rxhash = le32_to_cpu( diff --git a/trunk/drivers/net/e1000/e1000_ethtool.c b/trunk/drivers/net/e1000/e1000_ethtool.c index 2a3b2dccd06d..d6931cabe421 100644 --- a/trunk/drivers/net/e1000/e1000_ethtool.c +++ b/trunk/drivers/net/e1000/e1000_ethtool.c @@ -1808,7 +1808,7 @@ static int e1000_get_coalesce(struct net_device *netdev, if (adapter->hw.mac_type < e1000_82545) return -EOPNOTSUPP; - if (adapter->itr_setting <= 4) + if (adapter->itr_setting <= 3) ec->rx_coalesce_usecs = adapter->itr_setting; else ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting; @@ -1826,14 +1826,12 @@ static int e1000_set_coalesce(struct net_device *netdev, return -EOPNOTSUPP; if ((ec->rx_coalesce_usecs > E1000_MAX_ITR_USECS) || - ((ec->rx_coalesce_usecs > 4) && + ((ec->rx_coalesce_usecs > 3) && (ec->rx_coalesce_usecs < E1000_MIN_ITR_USECS)) || (ec->rx_coalesce_usecs == 2)) return -EINVAL; - if (ec->rx_coalesce_usecs == 4) { - adapter->itr = adapter->itr_setting = 4; - } else if (ec->rx_coalesce_usecs <= 3) { + if (ec->rx_coalesce_usecs <= 3) { adapter->itr = 20000; adapter->itr_setting = ec->rx_coalesce_usecs; } else { diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index 4dd2c23775cb..e6ebc222459f 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -31,7 +31,7 @@ char e1000_driver_name[] = "e1000"; static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; -#define DRV_VERSION "7.3.21-k6-NAPI" +#define DRV_VERSION "7.3.21-k5-NAPI" const char e1000_driver_version[] = DRV_VERSION; static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; @@ -2386,22 +2386,6 @@ static void e1000_watchdog(unsigned long data) } } - /* Simple mode for Interrupt Throttle Rate (ITR) */ - if (hw->mac_type >= e1000_82540 && adapter->itr_setting == 4) { - /* - * Symmetric Tx/Rx gets a reduced ITR=2000; - * Total asymmetrical Tx or Rx gets ITR=8000; - * everyone else is between 2000-8000. - */ - u32 goc = (adapter->gotcl + adapter->gorcl) / 10000; - u32 dif = (adapter->gotcl > adapter->gorcl ? - adapter->gotcl - adapter->gorcl : - adapter->gorcl - adapter->gotcl) / 10000; - u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000; - - ew32(ITR, 1000000000 / (itr * 256)); - } - /* Cause software interrupt to ensure rx ring is cleaned */ ew32(ICS, E1000_ICS_RXDMT0); diff --git a/trunk/drivers/net/e1000/e1000_param.c b/trunk/drivers/net/e1000/e1000_param.c index 9fbb562dc964..543c6d1767bc 100644 --- a/trunk/drivers/net/e1000/e1000_param.c +++ b/trunk/drivers/net/e1000/e1000_param.c @@ -484,17 +484,11 @@ void __devinit e1000_check_options(struct e1000_adapter *adapter) adapter->itr_setting = adapter->itr; adapter->itr = 20000; break; - case 4: - e_dev_info("%s set to simplified " - "(2000-8000) ints mode\n", opt.name); - adapter->itr_setting = adapter->itr; - break; default: e1000_validate_option(&adapter->itr, &opt, adapter); - /* save the setting, because the dynamic bits - * change itr. - * clear the lower two bits because they are + /* save the setting, because the dynamic bits change itr */ + /* clear the lower two bits because they are * used as control */ adapter->itr_setting = adapter->itr & ~3; break; diff --git a/trunk/drivers/net/e1000e/82571.c b/trunk/drivers/net/e1000e/82571.c index 1e73eddee24a..17a25e19bbba 100644 --- a/trunk/drivers/net/e1000e/82571.c +++ b/trunk/drivers/net/e1000e/82571.c @@ -1845,7 +1845,7 @@ struct e1000_info e1000_82574_info = { | FLAG_HAS_SMART_POWER_DOWN | FLAG_HAS_AMT | FLAG_HAS_CTRLEXT_ON_LOAD, - .pba = 36, + .pba = 20, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, .mac_ops = &e82571_mac_ops, @@ -1862,7 +1862,7 @@ struct e1000_info e1000_82583_info = { | FLAG_HAS_SMART_POWER_DOWN | FLAG_HAS_AMT | FLAG_HAS_CTRLEXT_ON_LOAD, - .pba = 36, + .pba = 20, .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, .get_variants = e1000_get_variants_82571, .mac_ops = &e82571_mac_ops, diff --git a/trunk/drivers/net/e1000e/e1000.h b/trunk/drivers/net/e1000e/e1000.h index c0b3db40bd73..906c4daaabe9 100644 --- a/trunk/drivers/net/e1000e/e1000.h +++ b/trunk/drivers/net/e1000e/e1000.h @@ -189,8 +189,6 @@ struct e1000_buffer { unsigned long time_stamp; u16 length; u16 next_to_watch; - unsigned int segs; - unsigned int bytecount; u16 mapped_as_page; }; /* Rx */ diff --git a/trunk/drivers/net/e1000e/ethtool.c b/trunk/drivers/net/e1000e/ethtool.c index 6ff376cfe139..7f9915cf2a59 100644 --- a/trunk/drivers/net/e1000e/ethtool.c +++ b/trunk/drivers/net/e1000e/ethtool.c @@ -412,6 +412,7 @@ static int e1000_set_tso(struct net_device *netdev, u32 data) netdev->features &= ~NETIF_F_TSO6; } + e_info("TSO is %s\n", data ? "Enabled" : "Disabled"); adapter->flags |= FLAG_TSO_FORCE; return 0; } @@ -1890,7 +1891,7 @@ static int e1000_get_coalesce(struct net_device *netdev, { struct e1000_adapter *adapter = netdev_priv(netdev); - if (adapter->itr_setting <= 4) + if (adapter->itr_setting <= 3) ec->rx_coalesce_usecs = adapter->itr_setting; else ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting; @@ -1905,14 +1906,12 @@ static int e1000_set_coalesce(struct net_device *netdev, struct e1000_hw *hw = &adapter->hw; if ((ec->rx_coalesce_usecs > E1000_MAX_ITR_USECS) || - ((ec->rx_coalesce_usecs > 4) && + ((ec->rx_coalesce_usecs > 3) && (ec->rx_coalesce_usecs < E1000_MIN_ITR_USECS)) || (ec->rx_coalesce_usecs == 2)) return -EINVAL; - if (ec->rx_coalesce_usecs == 4) { - adapter->itr = adapter->itr_setting = 4; - } else if (ec->rx_coalesce_usecs <= 3) { + if (ec->rx_coalesce_usecs <= 3) { adapter->itr = 20000; adapter->itr_setting = ec->rx_coalesce_usecs; } else { diff --git a/trunk/drivers/net/e1000e/netdev.c b/trunk/drivers/net/e1000e/netdev.c index c5f65a29865a..d13760dc27f8 100644 --- a/trunk/drivers/net/e1000e/netdev.c +++ b/trunk/drivers/net/e1000e/netdev.c @@ -52,7 +52,7 @@ #include "e1000.h" -#define DRV_VERSION "1.0.2-k4" +#define DRV_VERSION "1.0.2-k2" char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; @@ -548,23 +548,26 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, rx_desc = E1000_RX_DESC(*rx_ring, i); rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); - if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) { - /* - * Force memory writes to complete before letting h/w - * know there are new descriptors to fetch. (Only - * applicable for weak-ordered memory model archs, - * such as IA-64). - */ - wmb(); - writel(i, adapter->hw.hw_addr + rx_ring->tail); - } i++; if (i == rx_ring->count) i = 0; buffer_info = &rx_ring->buffer_info[i]; } - rx_ring->next_to_use = i; + if (rx_ring->next_to_use != i) { + rx_ring->next_to_use = i; + if (i-- == 0) + i = (rx_ring->count - 1); + + /* + * Force memory writes to complete before letting h/w + * know there are new descriptors to fetch. (Only + * applicable for weak-ordered memory model archs, + * such as IA-64). + */ + wmb(); + writel(i, adapter->hw.hw_addr + rx_ring->tail); + } } /** @@ -646,17 +649,6 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma); - if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) { - /* - * Force memory writes to complete before letting h/w - * know there are new descriptors to fetch. (Only - * applicable for weak-ordered memory model archs, - * such as IA-64). - */ - wmb(); - writel(i<<1, adapter->hw.hw_addr + rx_ring->tail); - } - i++; if (i == rx_ring->count) i = 0; @@ -664,7 +656,26 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, } no_buffers: - rx_ring->next_to_use = i; + if (rx_ring->next_to_use != i) { + rx_ring->next_to_use = i; + + if (!(i--)) + i = (rx_ring->count - 1); + + /* + * Force memory writes to complete before letting h/w + * know there are new descriptors to fetch. (Only + * applicable for weak-ordered memory model archs, + * such as IA-64). + */ + wmb(); + /* + * Hardware increments by 16 bytes, but packet split + * descriptors are 32 bytes...so we increment tail + * twice as much. + */ + writel(i<<1, adapter->hw.hw_addr + rx_ring->tail); + } } /** @@ -990,8 +1001,14 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) cleaned = (i == eop); if (cleaned) { - total_tx_packets += buffer_info->segs; - total_tx_bytes += buffer_info->bytecount; + struct sk_buff *skb = buffer_info->skb; + unsigned int segs, bytecount; + segs = skb_shinfo(skb)->gso_segs ?: 1; + /* multiply data chunks by size of headers */ + bytecount = ((segs - 1) * skb_headlen(skb)) + + skb->len; + total_tx_packets += segs; + total_tx_bytes += bytecount; } e1000_put_txbuf(adapter, buffer_info); @@ -4070,22 +4087,6 @@ static void e1000_watchdog_task(struct work_struct *work) } } - /* Simple mode for Interrupt Throttle Rate (ITR) */ - if (adapter->itr_setting == 4) { - /* - * Symmetric Tx/Rx gets a reduced ITR=2000; - * Total asymmetrical Tx or Rx gets ITR=8000; - * everyone else is between 2000-8000. - */ - u32 goc = (adapter->gotc + adapter->gorc) / 10000; - u32 dif = (adapter->gotc > adapter->gorc ? - adapter->gotc - adapter->gorc : - adapter->gorc - adapter->gotc) / 10000; - u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000; - - ew32(ITR, 1000000000 / (itr * 256)); - } - /* Cause software interrupt to ensure Rx ring is cleaned */ if (adapter->msix_entries) ew32(ICS, adapter->rx_ring->ims_val); @@ -4260,7 +4261,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, struct e1000_buffer *buffer_info; unsigned int len = skb_headlen(skb); unsigned int offset = 0, size, count = 0, i; - unsigned int f, bytecount, segs; + unsigned int f; i = tx_ring->next_to_use; @@ -4320,13 +4321,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, } } - segs = skb_shinfo(skb)->gso_segs ?: 1; - /* multiply data chunks by size of headers */ - bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len; - tx_ring->buffer_info[i].skb = skb; - tx_ring->buffer_info[i].segs = segs; - tx_ring->buffer_info[i].bytecount = bytecount; tx_ring->buffer_info[first].next_to_watch = i; return count; @@ -5456,8 +5451,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev, SET_NETDEV_DEV(netdev, &pdev->dev); - netdev->irq = pdev->irq; - pci_set_drvdata(pdev, netdev); adapter = netdev_priv(netdev); hw = &adapter->hw; diff --git a/trunk/drivers/net/e1000e/param.c b/trunk/drivers/net/e1000e/param.c index 0f4077c3d538..f775a481063d 100644 --- a/trunk/drivers/net/e1000e/param.c +++ b/trunk/drivers/net/e1000e/param.c @@ -351,11 +351,6 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) adapter->itr_setting = adapter->itr; adapter->itr = 20000; break; - case 4: - e_info("%s set to simplified (2000-8000 ints) " - "mode\n", opt.name); - adapter->itr_setting = 4; - break; default: /* * Save the setting, because the dynamic bits diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index e282d0ae6a3d..5cf0e6615695 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -1104,16 +1104,20 @@ static void nv_disable_hw_interrupts(struct net_device *dev, u32 mask) static void nv_napi_enable(struct net_device *dev) { +#ifdef CONFIG_FORCEDETH_NAPI struct fe_priv *np = get_nvpriv(dev); napi_enable(&np->napi); +#endif } static void nv_napi_disable(struct net_device *dev) { +#ifdef CONFIG_FORCEDETH_NAPI struct fe_priv *np = get_nvpriv(dev); napi_disable(&np->napi); +#endif } #define MII_READ (-1) @@ -1806,6 +1810,7 @@ static int nv_alloc_rx_optimized(struct net_device *dev) } /* If rx bufs are exhausted called after 50ms to attempt to refresh */ +#ifdef CONFIG_FORCEDETH_NAPI static void nv_do_rx_refill(unsigned long data) { struct net_device *dev = (struct net_device *) data; @@ -1814,6 +1819,41 @@ static void nv_do_rx_refill(unsigned long data) /* Just reschedule NAPI rx processing */ napi_schedule(&np->napi); } +#else +static void nv_do_rx_refill(unsigned long data) +{ + struct net_device *dev = (struct net_device *) data; + struct fe_priv *np = netdev_priv(dev); + int retcode; + + if (!using_multi_irqs(dev)) { + if (np->msi_flags & NV_MSI_X_ENABLED) + disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); + else + disable_irq(np->pci_dev->irq); + } else { + disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); + } + if (!nv_optimized(np)) + retcode = nv_alloc_rx(dev); + else + retcode = nv_alloc_rx_optimized(dev); + if (retcode) { + spin_lock_irq(&np->lock); + if (!np->in_shutdown) + mod_timer(&np->oom_kick, jiffies + OOM_REFILL); + spin_unlock_irq(&np->lock); + } + if (!using_multi_irqs(dev)) { + if (np->msi_flags & NV_MSI_X_ENABLED) + enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); + else + enable_irq(np->pci_dev->irq); + } else { + enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); + } +} +#endif static void nv_init_rx(struct net_device *dev) { @@ -2776,7 +2816,11 @@ static int nv_rx_process(struct net_device *dev, int limit) skb->protocol = eth_type_trans(skb, dev); dprintk(KERN_DEBUG "%s: nv_rx_process: %d bytes, proto %d accepted.\n", dev->name, len, skb->protocol); - napi_gro_receive(&np->napi, skb); +#ifdef CONFIG_FORCEDETH_NAPI + netif_receive_skb(skb); +#else + netif_rx(skb); +#endif dev->stats.rx_packets++; dev->stats.rx_bytes += len; next_pkt: @@ -2865,14 +2909,27 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) dev->name, len, skb->protocol); if (likely(!np->vlangrp)) { - napi_gro_receive(&np->napi, skb); +#ifdef CONFIG_FORCEDETH_NAPI + netif_receive_skb(skb); +#else + netif_rx(skb); +#endif } else { vlanflags = le32_to_cpu(np->get_rx.ex->buflow); if (vlanflags & NV_RX3_VLAN_TAG_PRESENT) { - vlan_gro_receive(&np->napi, np->vlangrp, - vlanflags & NV_RX3_VLAN_TAG_MASK, skb); +#ifdef CONFIG_FORCEDETH_NAPI + vlan_hwaccel_receive_skb(skb, np->vlangrp, + vlanflags & NV_RX3_VLAN_TAG_MASK); +#else + vlan_hwaccel_rx(skb, np->vlangrp, + vlanflags & NV_RX3_VLAN_TAG_MASK); +#endif } else { - napi_gro_receive(&np->napi, skb); +#ifdef CONFIG_FORCEDETH_NAPI + netif_receive_skb(skb); +#else + netif_rx(skb); +#endif } } @@ -3439,6 +3496,10 @@ static irqreturn_t nv_nic_irq(int foo, void *data) struct net_device *dev = (struct net_device *) data; struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); +#ifndef CONFIG_FORCEDETH_NAPI + int total_work = 0; + int loop_count = 0; +#endif dprintk(KERN_DEBUG "%s: nv_nic_irq\n", dev->name); @@ -3455,6 +3516,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data) nv_msi_workaround(np); +#ifdef CONFIG_FORCEDETH_NAPI if (napi_schedule_prep(&np->napi)) { /* * Disable further irq's (msix not enabled with napi) @@ -3463,6 +3525,65 @@ static irqreturn_t nv_nic_irq(int foo, void *data) __napi_schedule(&np->napi); } +#else + do + { + int work = 0; + if ((work = nv_rx_process(dev, RX_WORK_PER_LOOP))) { + if (unlikely(nv_alloc_rx(dev))) { + spin_lock(&np->lock); + if (!np->in_shutdown) + mod_timer(&np->oom_kick, jiffies + OOM_REFILL); + spin_unlock(&np->lock); + } + } + + spin_lock(&np->lock); + work += nv_tx_done(dev, TX_WORK_PER_LOOP); + spin_unlock(&np->lock); + + if (!work) + break; + + total_work += work; + + loop_count++; + } + while (loop_count < max_interrupt_work); + + if (nv_change_interrupt_mode(dev, total_work)) { + /* setup new irq mask */ + writel(np->irqmask, base + NvRegIrqMask); + } + + if (unlikely(np->events & NVREG_IRQ_LINK)) { + spin_lock(&np->lock); + nv_link_irq(dev); + spin_unlock(&np->lock); + } + if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) { + spin_lock(&np->lock); + nv_linkchange(dev); + spin_unlock(&np->lock); + np->link_timeout = jiffies + LINK_TIMEOUT; + } + if (unlikely(np->events & NVREG_IRQ_RECOVER_ERROR)) { + spin_lock(&np->lock); + /* disable interrupts on the nic */ + if (!(np->msi_flags & NV_MSI_X_ENABLED)) + writel(0, base + NvRegIrqMask); + else + writel(np->irqmask, base + NvRegIrqMask); + pci_push(base); + + if (!np->in_shutdown) { + np->nic_poll_irq = np->irqmask; + np->recover_error = 1; + mod_timer(&np->nic_poll, jiffies + POLL_WAIT); + } + spin_unlock(&np->lock); + } +#endif dprintk(KERN_DEBUG "%s: nv_nic_irq completed\n", dev->name); return IRQ_HANDLED; @@ -3478,6 +3599,10 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) struct net_device *dev = (struct net_device *) data; struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); +#ifndef CONFIG_FORCEDETH_NAPI + int total_work = 0; + int loop_count = 0; +#endif dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized\n", dev->name); @@ -3494,6 +3619,7 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) nv_msi_workaround(np); +#ifdef CONFIG_FORCEDETH_NAPI if (napi_schedule_prep(&np->napi)) { /* * Disable further irq's (msix not enabled with napi) @@ -3501,6 +3627,66 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) writel(0, base + NvRegIrqMask); __napi_schedule(&np->napi); } +#else + do + { + int work = 0; + if ((work = nv_rx_process_optimized(dev, RX_WORK_PER_LOOP))) { + if (unlikely(nv_alloc_rx_optimized(dev))) { + spin_lock(&np->lock); + if (!np->in_shutdown) + mod_timer(&np->oom_kick, jiffies + OOM_REFILL); + spin_unlock(&np->lock); + } + } + + spin_lock(&np->lock); + work += nv_tx_done_optimized(dev, TX_WORK_PER_LOOP); + spin_unlock(&np->lock); + + if (!work) + break; + + total_work += work; + + loop_count++; + } + while (loop_count < max_interrupt_work); + + if (nv_change_interrupt_mode(dev, total_work)) { + /* setup new irq mask */ + writel(np->irqmask, base + NvRegIrqMask); + } + + if (unlikely(np->events & NVREG_IRQ_LINK)) { + spin_lock(&np->lock); + nv_link_irq(dev); + spin_unlock(&np->lock); + } + if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) { + spin_lock(&np->lock); + nv_linkchange(dev); + spin_unlock(&np->lock); + np->link_timeout = jiffies + LINK_TIMEOUT; + } + if (unlikely(np->events & NVREG_IRQ_RECOVER_ERROR)) { + spin_lock(&np->lock); + /* disable interrupts on the nic */ + if (!(np->msi_flags & NV_MSI_X_ENABLED)) + writel(0, base + NvRegIrqMask); + else + writel(np->irqmask, base + NvRegIrqMask); + pci_push(base); + + if (!np->in_shutdown) { + np->nic_poll_irq = np->irqmask; + np->recover_error = 1; + mod_timer(&np->nic_poll, jiffies + POLL_WAIT); + } + spin_unlock(&np->lock); + } + +#endif dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized completed\n", dev->name); return IRQ_HANDLED; @@ -3549,6 +3735,7 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) return IRQ_RETVAL(i); } +#ifdef CONFIG_FORCEDETH_NAPI static int nv_napi_poll(struct napi_struct *napi, int budget) { struct fe_priv *np = container_of(napi, struct fe_priv, napi); @@ -3564,15 +3751,14 @@ static int nv_napi_poll(struct napi_struct *napi, int budget) tx_work += nv_tx_done(dev, np->tx_ring_size); spin_unlock_irqrestore(&np->lock, flags); - rx_count = nv_rx_process(dev, budget - rx_work); + rx_count = nv_rx_process(dev, budget); retcode = nv_alloc_rx(dev); } else { spin_lock_irqsave(&np->lock, flags); tx_work += nv_tx_done_optimized(dev, np->tx_ring_size); spin_unlock_irqrestore(&np->lock, flags); - rx_count = nv_rx_process_optimized(dev, - budget - rx_work); + rx_count = nv_rx_process_optimized(dev, budget); retcode = nv_alloc_rx_optimized(dev); } } while (retcode == 0 && @@ -3619,6 +3805,7 @@ static int nv_napi_poll(struct napi_struct *napi, int budget) } return rx_work; } +#endif static irqreturn_t nv_nic_irq_rx(int foo, void *data) { @@ -5524,7 +5711,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; dev->features |= NETIF_F_TSO; - dev->features |= NETIF_F_GRO; } np->vlanctl_bits = 0; @@ -5577,7 +5763,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i else dev->netdev_ops = &nv_netdev_ops_optimized; +#ifdef CONFIG_FORCEDETH_NAPI netif_napi_add(dev, &np->napi, nv_napi_poll, RX_WORK_PER_LOOP); +#endif SET_ETHTOOL_OPS(dev, &ops); dev->watchdog_timeo = NV_WATCHDOG_TIMEO; @@ -5680,7 +5868,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i /* msix has had reported issues when modifying irqmask as in the case of napi, therefore, disable for now */ -#if 0 +#ifndef CONFIG_FORCEDETH_NAPI np->msi_flags |= NV_MSI_X_CAPABLE; #endif } diff --git a/trunk/drivers/net/igb/igb.h b/trunk/drivers/net/igb/igb.h index 6e63d9a7fc75..735ede9c7d75 100644 --- a/trunk/drivers/net/igb/igb.h +++ b/trunk/drivers/net/igb/igb.h @@ -141,10 +141,8 @@ struct igb_buffer { unsigned long time_stamp; u16 length; u16 next_to_watch; - unsigned int bytecount; + u16 mapped_as_page; u16 gso_segs; - union skb_shared_tx shtx; - u8 mapped_as_page; }; /* RX */ struct { diff --git a/trunk/drivers/net/igb/igb_main.c b/trunk/drivers/net/igb/igb_main.c index 589cf4a6427a..438737d58688 100644 --- a/trunk/drivers/net/igb/igb_main.c +++ b/trunk/drivers/net/igb/igb_main.c @@ -3899,33 +3899,34 @@ static inline int igb_tx_map_adv(struct igb_ring *tx_ring, struct sk_buff *skb, { struct igb_buffer *buffer_info; struct device *dev = tx_ring->dev; - unsigned int hlen = skb_headlen(skb); + unsigned int len = skb_headlen(skb); unsigned int count = 0, i; unsigned int f; - u16 gso_segs = skb_shinfo(skb)->gso_segs ?: 1; i = tx_ring->next_to_use; buffer_info = &tx_ring->buffer_info[i]; - BUG_ON(hlen >= IGB_MAX_DATA_PER_TXD); - buffer_info->length = hlen; + BUG_ON(len >= IGB_MAX_DATA_PER_TXD); + buffer_info->length = len; /* set time_stamp *before* dma to help avoid a possible race */ buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = i; - buffer_info->dma = dma_map_single(dev, skb->data, hlen, + buffer_info->dma = dma_map_single(dev, skb->data, len, DMA_TO_DEVICE); if (dma_mapping_error(dev, buffer_info->dma)) goto dma_error; for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { - struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[f]; - unsigned int len = frag->size; + struct skb_frag_struct *frag; count++; i++; if (i == tx_ring->count) i = 0; + frag = &skb_shinfo(skb)->frags[f]; + len = frag->size; + buffer_info = &tx_ring->buffer_info[i]; BUG_ON(len >= IGB_MAX_DATA_PER_TXD); buffer_info->length = len; @@ -3943,10 +3944,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; - /* 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; + tx_ring->buffer_info[i].gso_segs = skb_shinfo(skb)->gso_segs ?: 1; tx_ring->buffer_info[first].next_to_watch = i; return ++count; @@ -5290,21 +5288,22 @@ static void igb_systim_to_hwtstamp(struct igb_adapter *adapter, /** * igb_tx_hwtstamp - utility function which checks for TX time stamp * @q_vector: pointer to q_vector containing needed info - * @buffer: pointer to igb_buffer structure + * @skb: packet that was just sent * * If we were asked to do hardware stamping and such a time stamp is * available, then it must have been for this skb here because we only * allow only one such packet into the queue. */ -static void igb_tx_hwtstamp(struct igb_q_vector *q_vector, struct igb_buffer *buffer_info) +static void igb_tx_hwtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb) { struct igb_adapter *adapter = q_vector->adapter; + union skb_shared_tx *shtx = skb_tx(skb); struct e1000_hw *hw = &adapter->hw; struct skb_shared_hwtstamps shhwtstamps; u64 regval; /* if skb does not support hw timestamp or TX stamp not valid exit */ - if (likely(!buffer_info->shtx.hardware) || + if (likely(!shtx->hardware) || !(rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID)) return; @@ -5312,7 +5311,7 @@ static void igb_tx_hwtstamp(struct igb_q_vector *q_vector, struct igb_buffer *bu regval |= (u64)rd32(E1000_TXSTMPH) << 32; igb_systim_to_hwtstamp(adapter, &shhwtstamps, regval); - skb_tstamp_tx(buffer_info->skb, &shhwtstamps); + skb_tstamp_tx(skb, &shhwtstamps); } /** @@ -5327,6 +5326,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector) struct net_device *netdev = tx_ring->netdev; struct e1000_hw *hw = &adapter->hw; struct igb_buffer *buffer_info; + struct sk_buff *skb; union e1000_adv_tx_desc *tx_desc, *eop_desc; unsigned int total_bytes = 0, total_packets = 0; unsigned int i, eop, count = 0; @@ -5342,12 +5342,19 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector) tx_desc = E1000_TX_DESC_ADV(*tx_ring, i); buffer_info = &tx_ring->buffer_info[i]; cleaned = (i == eop); + skb = buffer_info->skb; - if (buffer_info->skb) { - total_bytes += buffer_info->bytecount; + if (skb) { + unsigned int segs, bytecount; /* gso_segs is currently only valid for tcp */ - total_packets += buffer_info->gso_segs; - igb_tx_hwtstamp(q_vector, buffer_info); + segs = buffer_info->gso_segs; + /* multiply data chunks by size of headers */ + bytecount = ((segs - 1) * skb_headlen(skb)) + + skb->len; + total_packets += segs; + total_bytes += bytecount; + + igb_tx_hwtstamp(q_vector, skb); } igb_unmap_and_free_tx_resource(tx_ring, buffer_info); diff --git a/trunk/drivers/net/ixgbe/ixgbe.h b/trunk/drivers/net/ixgbe/ixgbe.h index d0ea3d6dea95..ec6bcc0660c6 100644 --- a/trunk/drivers/net/ixgbe/ixgbe.h +++ b/trunk/drivers/net/ixgbe/ixgbe.h @@ -104,6 +104,10 @@ #define MAX_EMULATION_MAC_ADDRS 16 #define VMDQ_P(p) ((p) + adapter->num_vfs) +#define IXGBE_SUBDEV_ID_82598AF_MEZZ 0x0049 +#define IXGBE_SUBDEV_ID_82598AF_MENLO_Q_MEZZ 0x004a +#define IXGBE_SUBDEV_ID_82598AF_MENLO_E_MEZZ 0x004b + struct vf_data_storage { unsigned char vf_mac_addresses[ETH_ALEN]; u16 vf_mc_hashes[IXGBE_MAX_VF_MC_ENTRIES]; @@ -111,10 +115,7 @@ struct vf_data_storage { u16 default_vf_vlan_id; u16 vlans_enabled; bool clear_to_send; - bool pf_set_mac; int rar; - u16 pf_vlan; /* When set, guest VLAN config not allowed. */ - u16 pf_qos; }; /* wrapper around a pointer to a socket buffer, diff --git a/trunk/drivers/net/ixgbe/ixgbe_main.c b/trunk/drivers/net/ixgbe/ixgbe_main.c index d1a1868df817..ff59f88dc7a1 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ixgbe/ixgbe_main.c @@ -2722,7 +2722,7 @@ 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); + ixgbe_set_vmolr(hw, adapter->num_vfs); } /* Program MRQC for the distribution of queues */ @@ -4314,6 +4314,9 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter) int err = 0; int vector, v_budget; + if (!(adapter->flags & IXGBE_FLAG_MSIX_CAPABLE)) + goto try_msi; + /* * It's easy to be greedy for MSI-X vectors, but it really * doesn't do us much good if we have a lot more vectors @@ -4345,7 +4348,7 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter) if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) goto out; } - +try_msi: adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; @@ -4626,6 +4629,18 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->ring_feature[RING_F_RSS].indices = rss; adapter->flags |= IXGBE_FLAG_RSS_ENABLED; adapter->ring_feature[RING_F_DCB].indices = IXGBE_MAX_DCB_INDICES; + adapter->flags |= IXGBE_FLAG_MSIX_CAPABLE; + if (adapter->hw.device_id == IXGBE_DEV_ID_82598AF_DUAL_PORT) { + switch (adapter->hw.subsystem_device_id) { + case IXGBE_SUBDEV_ID_82598AF_MEZZ: + case IXGBE_SUBDEV_ID_82598AF_MENLO_Q_MEZZ: + case IXGBE_SUBDEV_ID_82598AF_MENLO_E_MEZZ: + adapter->flags &= ~IXGBE_FLAG_MSIX_CAPABLE; + break; + default: + break; + } + } if (hw->mac.type == ixgbe_mac_82598EB) { if (hw->device_id == IXGBE_DEV_ID_82598AT) adapter->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE; @@ -6311,10 +6326,6 @@ static const struct net_device_ops ixgbe_netdev_ops = { .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, - .ndo_set_vf_mac = ixgbe_ndo_set_vf_mac, - .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, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ixgbe_netpoll, #endif diff --git a/trunk/drivers/net/ixgbe/ixgbe_sriov.c b/trunk/drivers/net/ixgbe/ixgbe_sriov.c index 221b2ca994e6..d4cd20f30199 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_sriov.c +++ b/trunk/drivers/net/ixgbe/ixgbe_sriov.c @@ -113,47 +113,23 @@ 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_set_vmolr(struct ixgbe_hw *hw, u32 vf) { u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); - vmolr |= (IXGBE_VMOLR_ROMPE | + vmolr |= (IXGBE_VMOLR_AUPE | + IXGBE_VMOLR_ROMPE | IXGBE_VMOLR_ROPE | IXGBE_VMOLR_BAM); - if (aupe) - vmolr |= IXGBE_VMOLR_AUPE; - else - vmolr &= ~IXGBE_VMOLR_AUPE; IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr); } -static void ixgbe_set_vmvir(struct ixgbe_adapter *adapter, u32 vid, u32 vf) -{ - struct ixgbe_hw *hw = &adapter->hw; - - if (vid) - IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), - (vid | IXGBE_VMVIR_VLANA_DEFAULT)); - else - IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0); -} - inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) { struct ixgbe_hw *hw = &adapter->hw; /* reset offloads to defaults */ - if (adapter->vfinfo[vf].pf_vlan) { - ixgbe_set_vf_vlan(adapter, true, - adapter->vfinfo[vf].pf_vlan, vf); - ixgbe_set_vmvir(adapter, - (adapter->vfinfo[vf].pf_vlan | - (adapter->vfinfo[vf].pf_qos << - VLAN_PRIO_SHIFT)), vf); - ixgbe_set_vmolr(hw, vf, false); - } else { - ixgbe_set_vmvir(adapter, 0, vf); - ixgbe_set_vmolr(hw, vf, true); - } + ixgbe_set_vmolr(hw, vf); + /* reset multicast table array for vf */ adapter->vfinfo[vf].num_vf_mc_hashes = 0; @@ -287,12 +263,10 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) case IXGBE_VF_SET_MAC_ADDR: { u8 *new_mac = ((u8 *)(&msgbuf[1])); - if (is_valid_ether_addr(new_mac) && - !adapter->vfinfo[vf].pf_set_mac) + if (is_valid_ether_addr(new_mac)) ixgbe_set_vf_mac(adapter, vf, new_mac); else - ixgbe_set_vf_mac(adapter, - vf, adapter->vfinfo[vf].vf_mac_addresses); + retval = -1; } break; case IXGBE_VF_SET_MULTICAST: @@ -386,76 +360,3 @@ void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter) } } -int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - if (!is_valid_ether_addr(mac) || (vf >= adapter->num_vfs)) - return -EINVAL; - adapter->vfinfo[vf].pf_set_mac = true; - dev_info(&adapter->pdev->dev, "setting MAC %pM on VF %d\n", mac, vf); - dev_info(&adapter->pdev->dev, "Reload the VF driver to make this" - " change effective."); - if (test_bit(__IXGBE_DOWN, &adapter->state)) { - dev_warn(&adapter->pdev->dev, "The VF MAC address has been set," - " but the PF device is not up.\n"); - dev_warn(&adapter->pdev->dev, "Bring the PF device up before" - " attempting to use the VF device.\n"); - } - return ixgbe_set_vf_mac(adapter, vf, mac); -} - -int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) -{ - int err = 0; - struct ixgbe_adapter *adapter = netdev_priv(netdev); - - if ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7)) - return -EINVAL; - if (vlan || qos) { - err = ixgbe_set_vf_vlan(adapter, true, vlan, vf); - if (err) - goto out; - ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf); - ixgbe_set_vmolr(&adapter->hw, vf, false); - adapter->vfinfo[vf].pf_vlan = vlan; - adapter->vfinfo[vf].pf_qos = qos; - dev_info(&adapter->pdev->dev, - "Setting VLAN %d, QOS 0x%x on VF %d\n", vlan, qos, vf); - if (test_bit(__IXGBE_DOWN, &adapter->state)) { - dev_warn(&adapter->pdev->dev, - "The VF VLAN has been set," - " but the PF device is not up.\n"); - dev_warn(&adapter->pdev->dev, - "Bring the PF device up before" - " attempting to use the VF device.\n"); - } - } else { - err = ixgbe_set_vf_vlan(adapter, false, - adapter->vfinfo[vf].pf_vlan, vf); - ixgbe_set_vmvir(adapter, vlan, vf); - ixgbe_set_vmolr(&adapter->hw, vf, true); - adapter->vfinfo[vf].pf_vlan = 0; - adapter->vfinfo[vf].pf_qos = 0; - } -out: - return err; -} - -int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate) -{ - return -EOPNOTSUPP; -} - -int ixgbe_ndo_get_vf_config(struct net_device *netdev, - int vf, struct ifla_vf_info *ivi) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - if (vf >= adapter->num_vfs) - return -EINVAL; - ivi->vf = vf; - memcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN); - ivi->tx_rate = 0; - ivi->vlan = adapter->vfinfo[vf].pf_vlan; - ivi->qos = adapter->vfinfo[vf].pf_qos; - return 0; -} diff --git a/trunk/drivers/net/ixgbe/ixgbe_sriov.h b/trunk/drivers/net/ixgbe/ixgbe_sriov.h index 184730ecdfb6..51d1106c45a1 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_sriov.h +++ b/trunk/drivers/net/ixgbe/ixgbe_sriov.h @@ -32,7 +32,7 @@ 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_set_vmolr(struct ixgbe_hw *hw, u32 vf); 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); @@ -42,12 +42,6 @@ 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); void ixgbe_dump_registers(struct ixgbe_adapter *adapter); -int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac); -int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan, - u8 qos); -int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate); -int ixgbe_ndo_get_vf_config(struct net_device *netdev, - int vf, struct ifla_vf_info *ivi); #endif /* _IXGBE_SRIOV_H_ */ diff --git a/trunk/drivers/net/ixgbe/ixgbe_type.h b/trunk/drivers/net/ixgbe/ixgbe_type.h index 4277cbbb8126..a0f9084c81cd 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_type.h +++ b/trunk/drivers/net/ixgbe/ixgbe_type.h @@ -219,7 +219,6 @@ #define IXGBE_MTQC 0x08120 #define IXGBE_VLVF(_i) (0x0F100 + ((_i) * 4)) /* 64 of these (0-63) */ #define IXGBE_VLVFB(_i) (0x0F200 + ((_i) * 4)) /* 128 of these (0-127) */ -#define IXGBE_VMVIR(_i) (0x08000 + ((_i) * 4)) /* 64 of these (0-63) */ #define IXGBE_VT_CTL 0x051B0 #define IXGBE_VFRE(_i) (0x051E0 + ((_i) * 4)) #define IXGBE_VFTE(_i) (0x08110 + ((_i) * 4)) @@ -1312,10 +1311,6 @@ #define IXGBE_VLVF_ENTRIES 64 #define IXGBE_VLVF_VLANID_MASK 0x00000FFF -/* Per VF Port VLAN insertion rules */ -#define IXGBE_VMVIR_VLANA_DEFAULT 0x40000000 /* Always use default VLAN */ -#define IXGBE_VMVIR_VLANA_NEVER 0x80000000 /* Never insert VLAN tag */ - #define IXGBE_ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.1q protocol */ /* STATUS Bit Masks */ diff --git a/trunk/drivers/net/ks8851.c b/trunk/drivers/net/ks8851.c index b4fb07a6f13f..b8ed1ee37ac1 100644 --- a/trunk/drivers/net/ks8851.c +++ b/trunk/drivers/net/ks8851.c @@ -78,9 +78,7 @@ union ks8851_tx_hdr { * @msg_enable: The message flags controlling driver output (see ethtool). * @fid: Incrementing frame id tag. * @rc_ier: Cached copy of KS_IER. - * @rc_ccr: Cached copy of KS_CCR. * @rc_rxqcr: Cached copy of KS_RXQCR. - * @eeprom_size: Companion eeprom size in Bytes, 0 if no eeprom * * The @lock ensures that the chip is protected when certain operations are * in progress. When the read or write packet transfer is in progress, most @@ -111,8 +109,6 @@ struct ks8851_net { u16 rc_ier; u16 rc_rxqcr; - u16 rc_ccr; - u16 eeprom_size; struct mii_if_info mii; struct ks8851_rxctrl rxctrl; @@ -1034,234 +1030,6 @@ static const struct net_device_ops ks8851_netdev_ops = { .ndo_validate_addr = eth_validate_addr, }; -/* Companion eeprom access */ - -enum { /* EEPROM programming states */ - EEPROM_CONTROL, - EEPROM_ADDRESS, - EEPROM_DATA, - EEPROM_COMPLETE -}; - -/** - * ks8851_eeprom_read - read a 16bits word in ks8851 companion EEPROM - * @dev: The network device the PHY is on. - * @addr: EEPROM address to read - * - * eeprom_size: used to define the data coding length. Can be changed - * through debug-fs. - * - * Programs a read on the EEPROM using ks8851 EEPROM SW access feature. - * Warning: The READ feature is not supported on ks8851 revision 0. - * - * Rough programming model: - * - on period start: set clock high and read value on bus - * - on period / 2: set clock low and program value on bus - * - start on period / 2 - */ -unsigned int ks8851_eeprom_read(struct net_device *dev, unsigned int addr) -{ - struct ks8851_net *ks = netdev_priv(dev); - int eepcr; - int ctrl = EEPROM_OP_READ; - int state = EEPROM_CONTROL; - int bit_count = EEPROM_OP_LEN - 1; - unsigned int data = 0; - int dummy; - unsigned int addr_len; - - addr_len = (ks->eeprom_size == 128) ? 6 : 8; - - /* start transaction: chip select high, authorize write */ - mutex_lock(&ks->lock); - eepcr = EEPCR_EESA | EEPCR_EESRWA; - ks8851_wrreg16(ks, KS_EEPCR, eepcr); - eepcr |= EEPCR_EECS; - ks8851_wrreg16(ks, KS_EEPCR, eepcr); - mutex_unlock(&ks->lock); - - while (state != EEPROM_COMPLETE) { - /* falling clock period starts... */ - /* set EED_IO pin for control and address */ - eepcr &= ~EEPCR_EEDO; - switch (state) { - case EEPROM_CONTROL: - eepcr |= ((ctrl >> bit_count) & 1) << 2; - if (bit_count-- <= 0) { - bit_count = addr_len - 1; - state = EEPROM_ADDRESS; - } - break; - case EEPROM_ADDRESS: - eepcr |= ((addr >> bit_count) & 1) << 2; - bit_count--; - break; - case EEPROM_DATA: - /* Change to receive mode */ - eepcr &= ~EEPCR_EESRWA; - break; - } - - /* lower clock */ - eepcr &= ~EEPCR_EESCK; - - mutex_lock(&ks->lock); - ks8851_wrreg16(ks, KS_EEPCR, eepcr); - mutex_unlock(&ks->lock); - - /* waitread period / 2 */ - udelay(EEPROM_SK_PERIOD / 2); - - /* rising clock period starts... */ - - /* raise clock */ - mutex_lock(&ks->lock); - eepcr |= EEPCR_EESCK; - ks8851_wrreg16(ks, KS_EEPCR, eepcr); - mutex_unlock(&ks->lock); - - /* Manage read */ - switch (state) { - case EEPROM_ADDRESS: - if (bit_count < 0) { - bit_count = EEPROM_DATA_LEN - 1; - state = EEPROM_DATA; - } - break; - case EEPROM_DATA: - mutex_lock(&ks->lock); - dummy = ks8851_rdreg16(ks, KS_EEPCR); - mutex_unlock(&ks->lock); - data |= ((dummy >> EEPCR_EESB_OFFSET) & 1) << bit_count; - if (bit_count-- <= 0) - state = EEPROM_COMPLETE; - break; - } - - /* wait period / 2 */ - udelay(EEPROM_SK_PERIOD / 2); - } - - /* close transaction */ - mutex_lock(&ks->lock); - eepcr &= ~EEPCR_EECS; - ks8851_wrreg16(ks, KS_EEPCR, eepcr); - eepcr = 0; - ks8851_wrreg16(ks, KS_EEPCR, eepcr); - mutex_unlock(&ks->lock); - - return data; -} - -/** - * ks8851_eeprom_write - write a 16bits word in ks8851 companion EEPROM - * @dev: The network device the PHY is on. - * @op: operand (can be WRITE, EWEN, EWDS) - * @addr: EEPROM address to write - * @data: data to write - * - * eeprom_size: used to define the data coding length. Can be changed - * through debug-fs. - * - * Programs a write on the EEPROM using ks8851 EEPROM SW access feature. - * - * Note that a write enable is required before writing data. - * - * Rough programming model: - * - on period start: set clock high - * - on period / 2: set clock low and program value on bus - * - start on period / 2 - */ -void ks8851_eeprom_write(struct net_device *dev, unsigned int op, - unsigned int addr, unsigned int data) -{ - struct ks8851_net *ks = netdev_priv(dev); - int eepcr; - int state = EEPROM_CONTROL; - int bit_count = EEPROM_OP_LEN - 1; - unsigned int addr_len; - - addr_len = (ks->eeprom_size == 128) ? 6 : 8; - - switch (op) { - case EEPROM_OP_EWEN: - addr = 0x30; - break; - case EEPROM_OP_EWDS: - addr = 0; - break; - } - - /* start transaction: chip select high, authorize write */ - mutex_lock(&ks->lock); - eepcr = EEPCR_EESA | EEPCR_EESRWA; - ks8851_wrreg16(ks, KS_EEPCR, eepcr); - eepcr |= EEPCR_EECS; - ks8851_wrreg16(ks, KS_EEPCR, eepcr); - mutex_unlock(&ks->lock); - - while (state != EEPROM_COMPLETE) { - /* falling clock period starts... */ - /* set EED_IO pin for control and address */ - eepcr &= ~EEPCR_EEDO; - switch (state) { - case EEPROM_CONTROL: - eepcr |= ((op >> bit_count) & 1) << 2; - if (bit_count-- <= 0) { - bit_count = addr_len - 1; - state = EEPROM_ADDRESS; - } - break; - case EEPROM_ADDRESS: - eepcr |= ((addr >> bit_count) & 1) << 2; - if (bit_count-- <= 0) { - if (op == EEPROM_OP_WRITE) { - bit_count = EEPROM_DATA_LEN - 1; - state = EEPROM_DATA; - } else { - state = EEPROM_COMPLETE; - } - } - break; - case EEPROM_DATA: - eepcr |= ((data >> bit_count) & 1) << 2; - if (bit_count-- <= 0) - state = EEPROM_COMPLETE; - break; - } - - /* lower clock */ - eepcr &= ~EEPCR_EESCK; - - mutex_lock(&ks->lock); - ks8851_wrreg16(ks, KS_EEPCR, eepcr); - mutex_unlock(&ks->lock); - - /* wait period / 2 */ - udelay(EEPROM_SK_PERIOD / 2); - - /* rising clock period starts... */ - - /* raise clock */ - eepcr |= EEPCR_EESCK; - mutex_lock(&ks->lock); - ks8851_wrreg16(ks, KS_EEPCR, eepcr); - mutex_unlock(&ks->lock); - - /* wait period / 2 */ - udelay(EEPROM_SK_PERIOD / 2); - } - - /* close transaction */ - mutex_lock(&ks->lock); - eepcr &= ~EEPCR_EECS; - ks8851_wrreg16(ks, KS_EEPCR, eepcr); - eepcr = 0; - ks8851_wrreg16(ks, KS_EEPCR, eepcr); - mutex_unlock(&ks->lock); - -} - /* ethtool support */ static void ks8851_get_drvinfo(struct net_device *dev, @@ -1308,117 +1076,6 @@ static int ks8851_nway_reset(struct net_device *dev) return mii_nway_restart(&ks->mii); } -static int ks8851_get_eeprom_len(struct net_device *dev) -{ - struct ks8851_net *ks = netdev_priv(dev); - return ks->eeprom_size; -} - -static int ks8851_get_eeprom(struct net_device *dev, - struct ethtool_eeprom *eeprom, u8 *bytes) -{ - struct ks8851_net *ks = netdev_priv(dev); - u16 *eeprom_buff; - int first_word; - int last_word; - int ret_val = 0; - u16 i; - - if (eeprom->len == 0) - return -EINVAL; - - if (eeprom->len > ks->eeprom_size) - return -EINVAL; - - eeprom->magic = ks8851_rdreg16(ks, KS_CIDER); - - first_word = eeprom->offset >> 1; - last_word = (eeprom->offset + eeprom->len - 1) >> 1; - - eeprom_buff = kmalloc(sizeof(u16) * - (last_word - first_word + 1), GFP_KERNEL); - if (!eeprom_buff) - return -ENOMEM; - - for (i = 0; i < last_word - first_word + 1; i++) - eeprom_buff[i] = ks8851_eeprom_read(dev, first_word + 1); - - /* Device's eeprom is little-endian, word addressable */ - for (i = 0; i < last_word - first_word + 1; i++) - le16_to_cpus(&eeprom_buff[i]); - - memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); - kfree(eeprom_buff); - - return ret_val; -} - -static int ks8851_set_eeprom(struct net_device *dev, - struct ethtool_eeprom *eeprom, u8 *bytes) -{ - struct ks8851_net *ks = netdev_priv(dev); - u16 *eeprom_buff; - void *ptr; - int max_len; - int first_word; - int last_word; - int ret_val = 0; - u16 i; - - if (eeprom->len == 0) - return -EOPNOTSUPP; - - if (eeprom->len > ks->eeprom_size) - return -EINVAL; - - if (eeprom->magic != ks8851_rdreg16(ks, KS_CIDER)) - return -EFAULT; - - first_word = eeprom->offset >> 1; - last_word = (eeprom->offset + eeprom->len - 1) >> 1; - max_len = (last_word - first_word + 1) * 2; - eeprom_buff = kmalloc(max_len, GFP_KERNEL); - if (!eeprom_buff) - return -ENOMEM; - - ptr = (void *)eeprom_buff; - - if (eeprom->offset & 1) { - /* need read/modify/write of first changed EEPROM word */ - /* only the second byte of the word is being modified */ - eeprom_buff[0] = ks8851_eeprom_read(dev, first_word); - ptr++; - } - if ((eeprom->offset + eeprom->len) & 1) - /* need read/modify/write of last changed EEPROM word */ - /* only the first byte of the word is being modified */ - eeprom_buff[last_word - first_word] = - ks8851_eeprom_read(dev, last_word); - - - /* Device's eeprom is little-endian, word addressable */ - le16_to_cpus(&eeprom_buff[0]); - le16_to_cpus(&eeprom_buff[last_word - first_word]); - - memcpy(ptr, bytes, eeprom->len); - - for (i = 0; i < last_word - first_word + 1; i++) - eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]); - - ks8851_eeprom_write(dev, EEPROM_OP_EWEN, 0, 0); - - for (i = 0; i < last_word - first_word + 1; i++) { - ks8851_eeprom_write(dev, EEPROM_OP_WRITE, first_word + i, - eeprom_buff[i]); - mdelay(EEPROM_WRITE_TIME); - } - - ks8851_eeprom_write(dev, EEPROM_OP_EWDS, 0, 0); - - kfree(eeprom_buff); - return ret_val; -} - static const struct ethtool_ops ks8851_ethtool_ops = { .get_drvinfo = ks8851_get_drvinfo, .get_msglevel = ks8851_get_msglevel, @@ -1427,9 +1084,6 @@ static const struct ethtool_ops ks8851_ethtool_ops = { .set_settings = ks8851_set_settings, .get_link = ks8851_get_link, .nway_reset = ks8851_nway_reset, - .get_eeprom_len = ks8851_get_eeprom_len, - .get_eeprom = ks8851_get_eeprom, - .set_eeprom = ks8851_set_eeprom, }; /* MII interface controls */ @@ -1615,14 +1269,6 @@ static int __devinit ks8851_probe(struct spi_device *spi) goto err_id; } - /* cache the contents of the CCR register for EEPROM, etc. */ - ks->rc_ccr = ks8851_rdreg16(ks, KS_CCR); - - if (ks->rc_ccr & CCR_EEPROM) - ks->eeprom_size = 128; - else - ks->eeprom_size = 0; - ks8851_read_selftest(ks); ks8851_init_mac(ks); diff --git a/trunk/drivers/net/ks8851.h b/trunk/drivers/net/ks8851.h index 537fb06e5932..f52c312cc356 100644 --- a/trunk/drivers/net/ks8851.h +++ b/trunk/drivers/net/ks8851.h @@ -25,24 +25,12 @@ #define OBCR_ODS_16mA (1 << 6) #define KS_EEPCR 0x22 -#define EEPCR_EESRWA (1 << 5) #define EEPCR_EESA (1 << 4) -#define EEPCR_EESB_OFFSET 3 -#define EEPCR_EESB (1 << EEPCR_EESB_OFFSET) +#define EEPCR_EESB (1 << 3) #define EEPCR_EEDO (1 << 2) #define EEPCR_EESCK (1 << 1) #define EEPCR_EECS (1 << 0) -#define EEPROM_OP_LEN 3 /* bits:*/ -#define EEPROM_OP_READ 0x06 -#define EEPROM_OP_EWEN 0x04 -#define EEPROM_OP_WRITE 0x05 -#define EEPROM_OP_EWDS 0x14 - -#define EEPROM_DATA_LEN 16 /* 16 bits EEPROM */ -#define EEPROM_WRITE_TIME 4 /* wrt ack time in ms */ -#define EEPROM_SK_PERIOD 400 /* in us */ - #define KS_MBIR 0x24 #define MBIR_TXMBF (1 << 12) #define MBIR_TXMBFA (1 << 11) diff --git a/trunk/drivers/net/octeon/octeon_mgmt.c b/trunk/drivers/net/octeon/octeon_mgmt.c index 392470333174..6b1d443f2ce5 100644 --- a/trunk/drivers/net/octeon/octeon_mgmt.c +++ b/trunk/drivers/net/octeon/octeon_mgmt.c @@ -189,19 +189,12 @@ static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p) mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port)); while (mix_orcnt.s.orcnt) { - spin_lock_irqsave(&p->tx_list.lock, flags); - - mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port)); - - if (mix_orcnt.s.orcnt == 0) { - spin_unlock_irqrestore(&p->tx_list.lock, flags); - break; - } - dma_sync_single_for_cpu(p->dev, p->tx_ring_handle, ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE), DMA_BIDIRECTIONAL); + spin_lock_irqsave(&p->tx_list.lock, flags); + re.d64 = p->tx_ring[p->tx_next_clean]; p->tx_next_clean = (p->tx_next_clean + 1) % OCTEON_MGMT_TX_RING_SIZE; @@ -380,6 +373,7 @@ static int octeon_mgmt_receive_one(struct octeon_mgmt *p) mix_ircnt.s.ircnt = 1; cvmx_write_csr(CVMX_MIXX_IRCNT(port), mix_ircnt.u64); return rc; + } static int octeon_mgmt_receive_packets(struct octeon_mgmt *p, int budget) @@ -389,6 +383,7 @@ static int octeon_mgmt_receive_packets(struct octeon_mgmt *p, int budget) union cvmx_mixx_ircnt mix_ircnt; int rc; + mix_ircnt.u64 = cvmx_read_csr(CVMX_MIXX_IRCNT(port)); while (work_done < budget && mix_ircnt.s.ircnt) { @@ -480,11 +475,12 @@ static void octeon_mgmt_set_rx_filtering(struct net_device *netdev) unsigned int multicast_mode = 1; /* 1 - Reject all multicast. */ struct octeon_mgmt_cam_state cam_state; struct netdev_hw_addr *ha; + struct list_head *pos; int available_cam_entries; memset(&cam_state, 0, sizeof(cam_state)); - if ((netdev->flags & IFF_PROMISC) || netdev->uc.count > 7) { + if ((netdev->flags & IFF_PROMISC) || netdev->dev_addrs.count > 7) { cam_mode = 0; available_cam_entries = 8; } else { @@ -492,13 +488,13 @@ static void octeon_mgmt_set_rx_filtering(struct net_device *netdev) * One CAM entry for the primary address, leaves seven * for the secondary addresses. */ - available_cam_entries = 7 - netdev->uc.count; + available_cam_entries = 7 - netdev->dev_addrs.count; } if (netdev->flags & IFF_MULTICAST) { if (cam_mode == 0 || (netdev->flags & IFF_ALLMULTI) || netdev_mc_count(netdev) > available_cam_entries) - multicast_mode = 2; /* 2 - Accept all multicast. */ + multicast_mode = 2; /* 1 - Accept all multicast. */ else multicast_mode = 0; /* 0 - Use CAM. */ } @@ -506,14 +502,19 @@ static void octeon_mgmt_set_rx_filtering(struct net_device *netdev) if (cam_mode == 1) { /* Add primary address. */ octeon_mgmt_cam_state_add(&cam_state, netdev->dev_addr); - netdev_for_each_uc_addr(ha, netdev) - octeon_mgmt_cam_state_add(&cam_state, ha->addr); + list_for_each(pos, &netdev->dev_addrs.list) { + struct netdev_hw_addr *hw_addr; + hw_addr = list_entry(pos, struct netdev_hw_addr, list); + octeon_mgmt_cam_state_add(&cam_state, hw_addr->addr); + list = list->next; + } } if (multicast_mode == 0) { netdev_for_each_mc_addr(ha, netdev) octeon_mgmt_cam_state_add(&cam_state, ha->addr); } + spin_lock_irqsave(&p->lock, flags); /* Disable packet I/O. */ @@ -522,6 +523,7 @@ static void octeon_mgmt_set_rx_filtering(struct net_device *netdev) agl_gmx_prtx.s.en = 0; cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_prtx.u64); + adr_ctl.u64 = 0; adr_ctl.s.cam_mode = cam_mode; adr_ctl.s.mcst = multicast_mode; @@ -594,7 +596,8 @@ static irqreturn_t octeon_mgmt_interrupt(int cpl, void *dev_id) mixx_isr.u64 = cvmx_read_csr(CVMX_MIXX_ISR(port)); /* Clear any pending interrupts */ - cvmx_write_csr(CVMX_MIXX_ISR(port), mixx_isr.u64); + cvmx_write_csr(CVMX_MIXX_ISR(port), + cvmx_read_csr(CVMX_MIXX_ISR(port))); cvmx_read_csr(CVMX_MIXX_ISR(port)); if (mixx_isr.s.irthresh) { @@ -828,9 +831,9 @@ static int octeon_mgmt_open(struct net_device *netdev) mix_irhwm.s.irhwm = 0; cvmx_write_csr(CVMX_MIXX_IRHWM(port), mix_irhwm.u64); - /* Interrupt when we have 1 or more packets to clean. */ + /* Interrupt when we have 5 or more packets to clean. */ mix_orhwm.u64 = 0; - mix_orhwm.s.orhwm = 1; + mix_orhwm.s.orhwm = 5; cvmx_write_csr(CVMX_MIXX_ORHWM(port), mix_orhwm.u64); /* Enable receive and transmit interrupts */ @@ -924,6 +927,7 @@ static int octeon_mgmt_stop(struct net_device *netdev) octeon_mgmt_reset_hw(p); + free_irq(p->irq, netdev); /* dma_unmap is a nop on Octeon, so just free everything. */ @@ -940,6 +944,7 @@ static int octeon_mgmt_stop(struct net_device *netdev) DMA_BIDIRECTIONAL); kfree(p->tx_ring); + return 0; } @@ -949,7 +954,6 @@ static int octeon_mgmt_xmit(struct sk_buff *skb, struct net_device *netdev) int port = p->port; union mgmt_port_ring_entry re; unsigned long flags; - int rv = NETDEV_TX_BUSY; re.d64 = 0; re.s.len = skb->len; @@ -959,18 +963,15 @@ static int octeon_mgmt_xmit(struct sk_buff *skb, struct net_device *netdev) spin_lock_irqsave(&p->tx_list.lock, flags); - if (unlikely(p->tx_current_fill >= ring_max_fill(OCTEON_MGMT_TX_RING_SIZE) - 1)) { - spin_unlock_irqrestore(&p->tx_list.lock, flags); - netif_stop_queue(netdev); - spin_lock_irqsave(&p->tx_list.lock, flags); - } - if (unlikely(p->tx_current_fill >= ring_max_fill(OCTEON_MGMT_TX_RING_SIZE))) { spin_unlock_irqrestore(&p->tx_list.lock, flags); + dma_unmap_single(p->dev, re.s.addr, re.s.len, DMA_TO_DEVICE); - goto out; + + netif_stop_queue(netdev); + return NETDEV_TX_BUSY; } __skb_queue_tail(&p->tx_list, skb); @@ -993,10 +994,9 @@ static int octeon_mgmt_xmit(struct sk_buff *skb, struct net_device *netdev) cvmx_write_csr(CVMX_MIXX_ORING2(port), 1); netdev->trans_start = jiffies; - rv = NETDEV_TX_OK; -out: + octeon_mgmt_clean_tx_buffers(p); octeon_mgmt_update_tx_stats(netdev); - return rv; + return NETDEV_TX_OK; } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -1106,6 +1106,7 @@ static int __init octeon_mgmt_probe(struct platform_device *pdev) netdev->netdev_ops = &octeon_mgmt_ops; netdev->ethtool_ops = &octeon_mgmt_ethtool_ops; + /* The mgmt ports get the first N MACs. */ for (i = 0; i < 6; i++) netdev->dev_addr[i] = octeon_bootinfo->mac_addr_base[i]; diff --git a/trunk/drivers/net/phy/Kconfig b/trunk/drivers/net/phy/Kconfig index a527e37728cd..fc5938ba3d78 100644 --- a/trunk/drivers/net/phy/Kconfig +++ b/trunk/drivers/net/phy/Kconfig @@ -88,11 +88,6 @@ config LSI_ET1011C_PHY ---help--- Supports the LSI ET1011C PHY. -config MICREL_PHY - tristate "Driver for Micrel PHYs" - ---help--- - Supports the KSZ9021, VSC8201, KS8001 PHYs. - config FIXED_PHY bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs" depends on PHYLIB=y diff --git a/trunk/drivers/net/phy/Makefile b/trunk/drivers/net/phy/Makefile index 13bebab65d02..1342585af381 100644 --- a/trunk/drivers/net/phy/Makefile +++ b/trunk/drivers/net/phy/Makefile @@ -20,5 +20,4 @@ obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o obj-$(CONFIG_NATIONAL_PHY) += national.o obj-$(CONFIG_STE10XP) += ste10Xp.o -obj-$(CONFIG_MICREL_PHY) += micrel.o obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o diff --git a/trunk/drivers/net/phy/micrel.c b/trunk/drivers/net/phy/micrel.c deleted file mode 100644 index 68dd107bad24..000000000000 --- a/trunk/drivers/net/phy/micrel.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * drivers/net/phy/micrel.c - * - * Driver for Micrel PHYs - * - * Author: David J. Choi - * - * Copyright (c) 2010 Micrel, Inc. - * - * 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. - * - * Support : ksz9021 , vsc8201, ks8001 - */ - -#include -#include -#include - -#define PHY_ID_KSZ9021 0x00221611 -#define PHY_ID_VSC8201 0x000FC413 -#define PHY_ID_KS8001 0x0022161A - - -static int kszphy_config_init(struct phy_device *phydev) -{ - return 0; -} - - -static struct phy_driver ks8001_driver = { - .phy_id = PHY_ID_KS8001, - .phy_id_mask = 0x00fffff0, - .features = PHY_BASIC_FEATURES, - .flags = PHY_POLL, - .config_init = kszphy_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .driver = { .owner = THIS_MODULE,}, -}; - -static struct phy_driver vsc8201_driver = { - .phy_id = PHY_ID_VSC8201, - .name = "Micrel VSC8201", - .phy_id_mask = 0x00fffff0, - .features = PHY_BASIC_FEATURES, - .flags = PHY_POLL, - .config_init = kszphy_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .driver = { .owner = THIS_MODULE,}, -}; - -static struct phy_driver ksz9021_driver = { - .phy_id = PHY_ID_KSZ9021, - .phy_id_mask = 0x000fff10, - .name = "Micrel KSZ9021 Gigabit PHY", - .features = PHY_GBIT_FEATURES | SUPPORTED_Pause, - .flags = PHY_POLL, - .config_init = kszphy_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .driver = { .owner = THIS_MODULE, }, -}; - -static int __init ksphy_init(void) -{ - int ret; - - ret = phy_driver_register(&ks8001_driver); - if (ret) - goto err1; - ret = phy_driver_register(&vsc8201_driver); - if (ret) - goto err2; - - ret = phy_driver_register(&ksz9021_driver); - if (ret) - goto err3; - return 0; - -err3: - phy_driver_unregister(&vsc8201_driver); -err2: - phy_driver_unregister(&ks8001_driver); -err1: - return ret; -} - -static void __exit ksphy_exit(void) -{ - phy_driver_unregister(&ks8001_driver); - phy_driver_unregister(&vsc8201_driver); - phy_driver_unregister(&ksz9021_driver); -} - -module_init(ksphy_init); -module_exit(ksphy_exit); - -MODULE_DESCRIPTION("Micrel PHY driver"); -MODULE_AUTHOR("David J. Choi"); -MODULE_LICENSE("GPL"); - -static struct mdio_device_id micrel_tbl[] = { - { PHY_ID_KSZ9021, 0x000fff10 }, - { PHY_ID_VSC8201, 0x00fffff0 }, - { PHY_ID_KS8001, 0x00fffff0 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, micrel_tbl); diff --git a/trunk/drivers/net/ppp_generic.c b/trunk/drivers/net/ppp_generic.c index 5441688daba7..35f195329fdd 100644 --- a/trunk/drivers/net/ppp_generic.c +++ b/trunk/drivers/net/ppp_generic.c @@ -405,7 +405,6 @@ static ssize_t ppp_read(struct file *file, char __user *buf, DECLARE_WAITQUEUE(wait, current); ssize_t ret; struct sk_buff *skb = NULL; - struct iovec iov; ret = count; @@ -449,9 +448,7 @@ static ssize_t ppp_read(struct file *file, char __user *buf, if (skb->len > count) goto outf; ret = -EFAULT; - iov.iov_base = buf; - iov.iov_len = count; - if (skb_copy_datagram_iovec(skb, 0, &iov, skb->len)) + if (copy_to_user(buf, skb->data, skb->len)) goto outf; ret = skb->len; @@ -1570,22 +1567,13 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb) struct channel *pch = chan->ppp; int proto; - if (!pch) { + if (!pch || skb->len == 0) { kfree_skb(skb); return; } - read_lock_bh(&pch->upl); - if (!pskb_may_pull(skb, 2)) { - kfree_skb(skb); - if (pch->ppp) { - ++pch->ppp->dev->stats.rx_length_errors; - ppp_receive_error(pch->ppp); - } - goto done; - } - proto = PPP_PROTO(skb); + read_lock_bh(&pch->upl); if (!pch->ppp || proto >= 0xc000 || proto == PPP_CCPFRAG) { /* put it on the channel queue */ skb_queue_tail(&pch->file.rq, skb); @@ -1597,8 +1585,6 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb) } else { ppp_do_recv(pch->ppp, skb, pch); } - -done: read_unlock_bh(&pch->upl); } @@ -1631,8 +1617,7 @@ ppp_input_error(struct ppp_channel *chan, int code) static void ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) { - /* note: a 0-length skb is used as an error indication */ - if (skb->len > 0) { + if (pskb_may_pull(skb, 2)) { #ifdef CONFIG_PPP_MULTILINK /* XXX do channel-level decompression here */ if (PPP_PROTO(skb) == PPP_MP) @@ -1640,10 +1625,15 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) else #endif /* CONFIG_PPP_MULTILINK */ ppp_receive_nonmp_frame(ppp, skb); - } else { - kfree_skb(skb); - ppp_receive_error(ppp); + return; } + + if (skb->len > 0) + /* note: a 0-length skb is used as an error indication */ + ++ppp->dev->stats.rx_length_errors; + + kfree_skb(skb); + ppp_receive_error(ppp); } static void diff --git a/trunk/drivers/net/pppoe.c b/trunk/drivers/net/pppoe.c index 99f031a08a01..c059c8db42e3 100644 --- a/trunk/drivers/net/pppoe.c +++ b/trunk/drivers/net/pppoe.c @@ -290,6 +290,12 @@ static void pppoe_flush_dev(struct net_device *dev) struct pppoe_net *pn; int i; + BUG_ON(dev == NULL); + + pn = pppoe_pernet(dev_net(dev)); + if (!pn) /* already freed */ + return; + write_lock_bh(&pn->hash_lock); for (i = 0; i < PPPOE_HASH_SIZE; i++) { struct pppox_sock *po = pn->hash_table[i]; diff --git a/trunk/drivers/net/tun.c b/trunk/drivers/net/tun.c index e525a6cf5587..6b150c072a41 100644 --- a/trunk/drivers/net/tun.c +++ b/trunk/drivers/net/tun.c @@ -110,6 +110,9 @@ struct tun_struct { struct tap_filter txflt; struct socket socket; struct socket_wq wq; + + int vnet_hdr_sz; + #ifdef TUN_DEBUG int debug; #endif @@ -563,7 +566,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, } if (tun->flags & TUN_VNET_HDR) { - if ((len -= sizeof(gso)) > count) + if ((len -= tun->vnet_hdr_sz) > count) return -EINVAL; if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) @@ -575,7 +578,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, if (gso.hdr_len > len) return -EINVAL; - offset += sizeof(gso); + offset += tun->vnet_hdr_sz; } if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { @@ -718,7 +721,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun, if (tun->flags & TUN_VNET_HDR) { struct virtio_net_hdr gso = { 0 }; /* no info leak */ - if ((len -= sizeof(gso)) < 0) + if ((len -= tun->vnet_hdr_sz) < 0) return -EINVAL; if (skb_is_gso(skb)) { @@ -749,7 +752,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun, if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total, sizeof(gso)))) return -EFAULT; - total += sizeof(gso); + total += tun->vnet_hdr_sz; } len = min_t(int, skb->len, len); @@ -1035,6 +1038,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) tun->dev = dev; tun->flags = flags; tun->txflt.count = 0; + tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr); err = -ENOMEM; sk = sk_alloc(net, AF_UNSPEC, GFP_KERNEL, &tun_proto); @@ -1177,6 +1181,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, struct sock_fprog fprog; struct ifreq ifr; int sndbuf; + int vnet_hdr_sz; int ret; if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89) @@ -1322,6 +1327,25 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, tun->socket.sk->sk_sndbuf = sndbuf; break; + case TUNGETVNETHDRSZ: + vnet_hdr_sz = tun->vnet_hdr_sz; + if (copy_to_user(argp, &vnet_hdr_sz, sizeof(vnet_hdr_sz))) + ret = -EFAULT; + break; + + case TUNSETVNETHDRSZ: + if (copy_from_user(&vnet_hdr_sz, argp, sizeof(vnet_hdr_sz))) { + ret = -EFAULT; + break; + } + if (vnet_hdr_sz < (int)sizeof(struct virtio_net_hdr)) { + ret = -EINVAL; + break; + } + + tun->vnet_hdr_sz = vnet_hdr_sz; + break; + case TUNATTACHFILTER: /* Can be set only for TAPs */ ret = -EINVAL; diff --git a/trunk/drivers/net/usb/dm9601.c b/trunk/drivers/net/usb/dm9601.c index 47634b617107..291add255246 100644 --- a/trunk/drivers/net/usb/dm9601.c +++ b/trunk/drivers/net/usb/dm9601.c @@ -240,7 +240,7 @@ static int dm_write_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 valu goto out; dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg); - dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1a : 0x12); + dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1c : 0x14); for (i = 0; i < DM_TIMEOUT; i++) { u8 tmp; diff --git a/trunk/drivers/net/wireless/Kconfig b/trunk/drivers/net/wireless/Kconfig index 2fbe9b4506c0..77500cb7fd26 100644 --- a/trunk/drivers/net/wireless/Kconfig +++ b/trunk/drivers/net/wireless/Kconfig @@ -38,12 +38,6 @@ config LIBERTAS_THINFIRM ---help--- A library for Marvell Libertas 8xxx devices using thinfirm. -config LIBERTAS_THINFIRM_DEBUG - bool "Enable full debugging output in the Libertas thin firmware module." - depends on LIBERTAS_THINFIRM - ---help--- - Debugging support. - config LIBERTAS_THINFIRM_USB tristate "Marvell Libertas 8388 USB 802.11b/g cards with thin firmware" depends on LIBERTAS_THINFIRM && USB diff --git a/trunk/drivers/net/wireless/at76c50x-usb.c b/trunk/drivers/net/wireless/at76c50x-usb.c index 7a626d4e100f..0fb419936dff 100644 --- a/trunk/drivers/net/wireless/at76c50x-usb.c +++ b/trunk/drivers/net/wireless/at76c50x-usb.c @@ -1889,7 +1889,6 @@ static void at76_dwork_hw_scan(struct work_struct *work) } static int at76_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, struct cfg80211_scan_request *req) { struct at76_priv *priv = hw->priv; diff --git a/trunk/drivers/net/wireless/ath/ar9170/main.c b/trunk/drivers/net/wireless/ath/ar9170/main.c index 2e9b330f6413..0312cee39570 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/main.c +++ b/trunk/drivers/net/wireless/ath/ar9170/main.c @@ -927,6 +927,7 @@ static void ar9170_rx_phy_status(struct ar9170 *ar, /* TODO: we could do something with phy_errors */ status->signal = ar->noise[0] + phy->rssi_combined; + status->noise = ar->noise[0]; } static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len) @@ -2547,7 +2548,8 @@ void *ar9170_alloc(size_t priv_size) BIT(NL80211_IFTYPE_ADHOC); ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | - IEEE80211_HW_SIGNAL_DBM; + IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_NOISE_DBM; if (modparam_ht) { ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; diff --git a/trunk/drivers/net/wireless/ath/ath5k/base.c b/trunk/drivers/net/wireless/ath/ath5k/base.c index 7f5953fac434..c274979ada3a 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/base.c +++ b/trunk/drivers/net/wireless/ath/ath5k/base.c @@ -548,7 +548,8 @@ ath5k_pci_probe(struct pci_dev *pdev, SET_IEEE80211_DEV(hw, &pdev->dev); hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | - IEEE80211_HW_SIGNAL_DBM; + IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_NOISE_DBM; hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | @@ -2029,7 +2030,8 @@ ath5k_tasklet_rx(unsigned long data) rxs->freq = sc->curchan->center_freq; rxs->band = sc->curband->band; - rxs->signal = sc->ah->ah_noise_floor + rs.rs_rssi; + rxs->noise = sc->ah->ah_noise_floor; + rxs->signal = rxs->noise + rs.rs_rssi; rxs->antenna = rs.rs_antenna; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ani.c b/trunk/drivers/net/wireless/ath/ath9k/ani.c index ba8b20f01594..cec62d311c78 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ani.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ani.c @@ -657,3 +657,12 @@ void ath9k_hw_ani_init(struct ath_hw *ah) if (ah->config.enable_ani) ah->proc_phyerr |= HAL_PROCESS_ANI; } + +void ath9k_hw_ani_disable(struct ath_hw *ah) +{ + ath_print(ath9k_hw_common(ah), ATH_DBG_ANI, "Disabling ANI\n"); + + ath9k_hw_disable_mib_counters(ah); + REG_WRITE(ah, AR_PHY_ERR_1, 0); + REG_WRITE(ah, AR_PHY_ERR_2, 0); +} diff --git a/trunk/drivers/net/wireless/ath/ath9k/ani.h b/trunk/drivers/net/wireless/ath/ath9k/ani.h index 3356762ea384..4e1ab94a5153 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ani.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ani.h @@ -118,5 +118,6 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt, void ath9k_hw_procmibevent(struct ath_hw *ah); void ath9k_hw_ani_setup(struct ath_hw *ah); void ath9k_hw_ani_init(struct ath_hw *ah); +void ath9k_hw_ani_disable(struct ath_hw *ah); #endif /* ANI_H */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar5008_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar5008_initvals.h index 025c31ac6146..cd953f6c4628 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar5008_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar5008_initvals.h @@ -249,7 +249,7 @@ static const u32 ar5416Common[][2] = { { 0x00008258, 0x00000000 }, { 0x0000825c, 0x400000ff }, { 0x00008260, 0x00080922 }, - { 0x00008264, 0x88000010 }, + { 0x00008264, 0xa8000010 }, { 0x00008270, 0x00000000 }, { 0x00008274, 0x40000000 }, { 0x00008278, 0x003e4180 }, diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c index b2c17c98bb38..de8ce1291a46 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -850,7 +850,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites); - if (IS_CHAN_A_FAST_CLOCK(ah, chan)) { + if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) { REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, regWrites); } @@ -892,7 +892,8 @@ static void ar5008_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan) rfMode |= (IS_CHAN_5GHZ(chan)) ? AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ; - if (IS_CHAN_A_FAST_CLOCK(ah, chan)) + if ((AR_SREV_9280_20(ah) || AR_SREV_9300_20_OR_LATER(ah)) + && IS_CHAN_A_5MHZ_SPACED(chan)) rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); REG_WRITE(ah, AR_PHY_MODE, rfMode); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c index a8a8cdc04afa..adb33b34a56d 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -408,8 +408,6 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); } else { - ENABLE_REGWRITE_BUFFER(ah); - REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); @@ -430,9 +428,6 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, /* Load the new settings */ REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); - - REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } udelay(1000); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9002_initvals.h index dae7f3304eb8..f06313d3bad6 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9002_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9002_initvals.h @@ -793,7 +793,7 @@ static const u32 ar9280Common_9280_2[][2] = { { 0x00008258, 0x00000000 }, { 0x0000825c, 0x400000ff }, { 0x00008260, 0x00080922 }, - { 0x00008264, 0x88a00010 }, + { 0x00008264, 0xa8a00010 }, { 0x00008270, 0x00000000 }, { 0x00008274, 0x40000000 }, { 0x00008278, 0x003e4180 }, @@ -1963,7 +1963,7 @@ static const u32 ar9285Common_9285[][2] = { { 0x00008258, 0x00000000 }, { 0x0000825c, 0x400000ff }, { 0x00008260, 0x00080922 }, - { 0x00008264, 0x88a00010 }, + { 0x00008264, 0xa8a00010 }, { 0x00008270, 0x00000000 }, { 0x00008274, 0x40000000 }, { 0x00008278, 0x003e4180 }, @@ -3185,7 +3185,7 @@ static const u32 ar9287Common_9287_1_0[][2] = { { 0x00008258, 0x00000000 }, { 0x0000825c, 0x400000ff }, { 0x00008260, 0x00080922 }, - { 0x00008264, 0x88a00010 }, + { 0x00008264, 0xa8a00010 }, { 0x00008270, 0x00000000 }, { 0x00008274, 0x40000000 }, { 0x00008278, 0x003e4180 }, @@ -4973,7 +4973,7 @@ static const u32 ar9271Common_9271[][2] = { { 0x00008258, 0x00000000 }, { 0x0000825c, 0x400000ff }, { 0x00008260, 0x00080922 }, - { 0x00008264, 0x88a00010 }, + { 0x00008264, 0xa8a00010 }, { 0x00008270, 0x00000000 }, { 0x00008274, 0x40000000 }, { 0x00008278, 0x003e4180 }, diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/trunk/drivers/net/wireless/ath/ath9k/ar9002_phy.c index ed314e89bfe1..18cfe1a9781c 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -455,12 +455,16 @@ static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah, pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL); if (chan && IS_CHAN_5GHZ(chan)) { - if (IS_CHAN_A_FAST_CLOCK(ah, chan)) - pll = 0x142c; - else if (AR_SREV_9280_20(ah)) - pll = 0x2850; - else - pll |= SM(0x28, AR_RTC_9160_PLL_DIV); + pll |= SM(0x28, AR_RTC_9160_PLL_DIV); + + + if (AR_SREV_9280_20(ah)) { + if (((chan->channel % 20) == 0) + || ((chan->channel % 10) == 0)) + pll = 0x2850; + else + pll = 0x142c; + } } else { pll |= SM(0x2c, AR_RTC_9160_PLL_DIV); } diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 5fcafb460877..5e20b4860c7f 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -755,8 +755,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, } /* Do Tx IQ Calibration */ - if (ah->config.tx_iq_calibration) - ar9003_hw_tx_iq_cal(ah); + ar9003_hw_tx_iq_cal(ah); /* Revert chainmasks to their original values before NF cal */ ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 8a79550dff71..5d92be47c5a5 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -659,9 +659,6 @@ static void ar9300_swap_eeprom(struct ar9300_eeprom *eep) word = swab16(eep->baseEepHeader.regDmn[1]); eep->baseEepHeader.regDmn[1] = word; - dword = swab32(eep->baseEepHeader.swreg); - eep->baseEepHeader.swreg = dword; - dword = swab32(eep->modalHeader2G.antCtrlCommon); eep->modalHeader2G.antCtrlCommon = dword; @@ -1203,7 +1200,7 @@ static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah, u8 *pFreqBin; if (is2GHz) { - numPiers = AR9300_NUM_2G_20_TARGET_POWERS; + numPiers = AR9300_NUM_5G_20_TARGET_POWERS; pEepromTargetPwr = eep->calTargetPower2G; pFreqBin = eep->calTarget_freqbin_2G; } else { @@ -1239,7 +1236,7 @@ static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah, u8 *pFreqBin; if (is2GHz) { - numPiers = AR9300_NUM_2G_20_TARGET_POWERS; + numPiers = AR9300_NUM_5G_20_TARGET_POWERS; pEepromTargetPwr = eep->calTargetPower2GHT20; pFreqBin = eep->calTarget_freqbin_2GHT20; } else { @@ -1820,7 +1817,6 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, u8 twiceMaxRegulatoryPower, u8 powerLimit) { - ah->txpower_limit = powerLimit; ar9003_hw_set_target_power_eeprom(ah, chan->channel); ar9003_hw_calibration_apply(ah, chan->channel); } diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index d8c0318f416f..5fe335e22c89 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -265,7 +265,7 @@ struct cal_ctl_edge_pwr { } __packed; struct cal_ctl_data_2g { - struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_2G]; + struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G]; } __packed; struct cal_ctl_data_5g { diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9003_initvals.h index a131cd10ef29..e0391b12e533 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_initvals.h @@ -31,7 +31,7 @@ static const u32 ar9300_2p0_radio_postamble[][5] = { 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}, + {0x0000a410, 0x000050da, 0x000050da, 0x000050da, 0x000050da}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, @@ -545,7 +545,7 @@ static const u32 ar9300_2p0_soc_postamble[][5] = { }; static const u32 ar9200_merlin_2p0_radio_core[][2] = { - /* Addr allmodes */ + /* Addr common */ {0x00007800, 0x00040000}, {0x00007804, 0xdb005012}, {0x00007808, 0x04924914}, @@ -835,71 +835,71 @@ static const u32 ar9300_2p0_baseband_core[][2] = { static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000050db, 0x000050db, 0x000050d9, 0x000050d9}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050da, 0x000050da}, {0x0000a500, 0x00020220, 0x00020220, 0x00000000, 0x00000000}, {0x0000a504, 0x06020223, 0x06020223, 0x04000002, 0x04000002}, - {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, - {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, - {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, - {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, - {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, - {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, - {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, - {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, - {0x0000a530, 0x34043643, 0x34043643, 0x2a000e20, 0x2a000e20}, - {0x0000a534, 0x38043a44, 0x38043a44, 0x2e000e22, 0x2e000e22}, - {0x0000a538, 0x3b043e45, 0x3b043e45, 0x31000e24, 0x31000e24}, - {0x0000a53c, 0x40063e46, 0x40063e46, 0x34001640, 0x34001640}, - {0x0000a540, 0x44083e46, 0x44083e46, 0x38001660, 0x38001660}, - {0x0000a544, 0x46083e66, 0x46083e66, 0x3b001861, 0x3b001861}, - {0x0000a548, 0x4b0a3e69, 0x4b0a3e69, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x4f0a5e66, 0x4f0a5e66, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x540a7e66, 0x540a7e66, 0x44001c84, 0x44001c84}, - {0x0000a554, 0x570a7e89, 0x570a7e89, 0x48001ce3, 0x48001ce3}, - {0x0000a558, 0x5c0e7e8a, 0x5c0e7e8a, 0x4c001ce5, 0x4c001ce5}, - {0x0000a55c, 0x60127e8b, 0x60127e8b, 0x50001ce9, 0x50001ce9}, - {0x0000a560, 0x65127ecc, 0x65127ecc, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x6b169ecd, 0x6b169ecd, 0x56001eec, 0x56001eec}, - {0x0000a568, 0x70169f0e, 0x70169f0e, 0x56001eec, 0x56001eec}, - {0x0000a56c, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, - {0x0000a570, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, - {0x0000a574, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, - {0x0000a578, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, - {0x0000a57c, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, + {0x0000a508, 0x0b022220, 0x0b022220, 0x08000004, 0x08000004}, + {0x0000a50c, 0x10022223, 0x10022223, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x17022620, 0x17022620, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x1b022622, 0x1b022622, 0x11000400, 0x11000400}, + {0x0000a518, 0x1f022822, 0x1f022822, 0x15000402, 0x15000402}, + {0x0000a51c, 0x24022842, 0x24022842, 0x19000404, 0x19000404}, + {0x0000a520, 0x28042840, 0x28042840, 0x1b000603, 0x1b000603}, + {0x0000a524, 0x2c042842, 0x2c042842, 0x1f000a02, 0x1f000a02}, + {0x0000a528, 0x30042844, 0x30042844, 0x23000a04, 0x23000a04}, + {0x0000a52c, 0x34042846, 0x34042846, 0x26000a20, 0x26000a20}, + {0x0000a530, 0x39042869, 0x39042869, 0x2a000e20, 0x2a000e20}, + {0x0000a534, 0x3d062869, 0x3d062869, 0x2e000e22, 0x2e000e22}, + {0x0000a538, 0x44062c69, 0x44062c69, 0x31000e24, 0x31000e24}, + {0x0000a53c, 0x48063069, 0x48063069, 0x34001640, 0x34001640}, + {0x0000a540, 0x4c0a3065, 0x4c0a3065, 0x38001660, 0x38001660}, + {0x0000a544, 0x500a3069, 0x500a3069, 0x3b001861, 0x3b001861}, + {0x0000a548, 0x530a3469, 0x530a3469, 0x3e001a81, 0x3e001a81}, + {0x0000a54c, 0x590a7464, 0x590a7464, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x5e0a7865, 0x5e0a7865, 0x44001c84, 0x44001c84}, + {0x0000a554, 0x630a7e66, 0x630a7e66, 0x48001ce3, 0x48001ce3}, + {0x0000a558, 0x680a7e89, 0x680a7e89, 0x4c001ce5, 0x4c001ce5}, + {0x0000a55c, 0x6e0a7e8c, 0x6e0a7e8c, 0x50001ce9, 0x50001ce9}, + {0x0000a560, 0x730e7e8c, 0x730e7e8c, 0x54001ceb, 0x54001ceb}, + {0x0000a564, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, + {0x0000a568, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, + {0x0000a56c, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, + {0x0000a570, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, + {0x0000a574, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, + {0x0000a578, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, + {0x0000a57c, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, {0x0000a580, 0x00820220, 0x00820220, 0x00800000, 0x00800000}, {0x0000a584, 0x06820223, 0x06820223, 0x04800002, 0x04800002}, - {0x0000a588, 0x0a822220, 0x0a822220, 0x08800004, 0x08800004}, - {0x0000a58c, 0x0f822223, 0x0f822223, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x14822620, 0x14822620, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x18822622, 0x18822622, 0x11800400, 0x11800400}, - {0x0000a598, 0x1b822822, 0x1b822822, 0x15800402, 0x15800402}, - {0x0000a59c, 0x20822842, 0x20822842, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x22822c41, 0x22822c41, 0x1b800603, 0x1b800603}, - {0x0000a5a4, 0x28823042, 0x28823042, 0x1f800a02, 0x1f800a02}, - {0x0000a5a8, 0x2c823044, 0x2c823044, 0x23800a04, 0x23800a04}, - {0x0000a5ac, 0x2f823644, 0x2f823644, 0x26800a20, 0x26800a20}, - {0x0000a5b0, 0x34843643, 0x34843643, 0x2a800e20, 0x2a800e20}, - {0x0000a5b4, 0x38843a44, 0x38843a44, 0x2e800e22, 0x2e800e22}, - {0x0000a5b8, 0x3b843e45, 0x3b843e45, 0x31800e24, 0x31800e24}, - {0x0000a5bc, 0x40863e46, 0x40863e46, 0x34801640, 0x34801640}, - {0x0000a5c0, 0x4c8a3065, 0x44883e46, 0x44883e46, 0x38801660}, - {0x0000a5c4, 0x46883e66, 0x46883e66, 0x3b801861, 0x3b801861}, - {0x0000a5c8, 0x4b8a3e69, 0x4b8a3e69, 0x3e801a81, 0x3e801a81}, - {0x0000a5cc, 0x4f8a5e66, 0x4f8a5e66, 0x42801a83, 0x42801a83}, - {0x0000a5d0, 0x548a7e66, 0x548a7e66, 0x44801c84, 0x44801c84}, - {0x0000a5d4, 0x578a7e89, 0x578a7e89, 0x48801ce3, 0x48801ce3}, - {0x0000a5d8, 0x5c8e7e8a, 0x5c8e7e8a, 0x4c801ce5, 0x4c801ce5}, - {0x0000a5dc, 0x60927e8b, 0x60927e8b, 0x50801ce9, 0x50801ce9}, - {0x0000a5e0, 0x65927ecc, 0x65927ecc, 0x54801ceb, 0x54801ceb}, - {0x0000a5e4, 0x6b969ecd, 0x6b969ecd, 0x56801eec, 0x56801eec}, - {0x0000a5e8, 0x70969f0e, 0x70969f0e, 0x56801eec, 0x56801eec}, - {0x0000a5ec, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, - {0x0000a5f0, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, - {0x0000a5f4, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, - {0x0000a5f8, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, - {0x0000a5fc, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, + {0x0000a588, 0x0b822220, 0x0b822220, 0x08800004, 0x08800004}, + {0x0000a58c, 0x10822223, 0x10822223, 0x0b800200, 0x0b800200}, + {0x0000a590, 0x17822620, 0x17822620, 0x0f800202, 0x0f800202}, + {0x0000a594, 0x1b822622, 0x1b822622, 0x11800400, 0x11800400}, + {0x0000a598, 0x1f822822, 0x1f822822, 0x15800402, 0x15800402}, + {0x0000a59c, 0x24822842, 0x24822842, 0x19800404, 0x19800404}, + {0x0000a5a0, 0x28842840, 0x28842840, 0x1b800603, 0x1b800603}, + {0x0000a5a4, 0x2c842842, 0x2c842842, 0x1f800a02, 0x1f800a02}, + {0x0000a5a8, 0x30842844, 0x30842844, 0x23800a04, 0x23800a04}, + {0x0000a5ac, 0x34842846, 0x34842846, 0x26800a20, 0x26800a20}, + {0x0000a5b0, 0x39842869, 0x39842869, 0x2a800e20, 0x2a800e20}, + {0x0000a5b4, 0x3d862869, 0x3d862869, 0x2e800e22, 0x2e800e22}, + {0x0000a5b8, 0x44862c69, 0x44862c69, 0x31800e24, 0x31800e24}, + {0x0000a5bc, 0x48863069, 0x48863069, 0x34801640, 0x34801640}, + {0x0000a5c0, 0x4c8a3065, 0x4c8a3065, 0x38801660, 0x38801660}, + {0x0000a5c4, 0x508a3069, 0x508a3069, 0x3b801861, 0x3b801861}, + {0x0000a5c8, 0x538a3469, 0x538a3469, 0x3e801a81, 0x3e801a81}, + {0x0000a5cc, 0x598a7464, 0x598a7464, 0x42801a83, 0x42801a83}, + {0x0000a5d0, 0x5e8a7865, 0x5e8a7865, 0x44801c84, 0x44801c84}, + {0x0000a5d4, 0x638a7e66, 0x638a7e66, 0x48801ce3, 0x48801ce3}, + {0x0000a5d8, 0x688a7e89, 0x688a7e89, 0x4c801ce5, 0x4c801ce5}, + {0x0000a5dc, 0x6e8a7e8c, 0x6e8a7e8c, 0x50801ce9, 0x50801ce9}, + {0x0000a5e0, 0x738e7e8c, 0x738e7e8c, 0x54801ceb, 0x54801ceb}, + {0x0000a5e4, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, + {0x0000a5e8, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, + {0x0000a5ec, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, + {0x0000a5f0, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, + {0x0000a5f4, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, + {0x0000a5f8, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, + {0x0000a5fc, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, {0x00016048, 0xad241a61, 0xad241a61, 0xad241a61, 0xad241a61}, {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, @@ -913,71 +913,71 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = { static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000050db, 0x000050db, 0x000050d9, 0x000050d9}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050da, 0x000050da}, {0x0000a500, 0x00020220, 0x00020220, 0x00000000, 0x00000000}, {0x0000a504, 0x06020223, 0x06020223, 0x04000002, 0x04000002}, - {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, - {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, - {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, - {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, - {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, - {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, - {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, - {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, - {0x0000a530, 0x34043643, 0x34043643, 0x2a000e20, 0x2a000e20}, - {0x0000a534, 0x38043a44, 0x38043a44, 0x2e000e22, 0x2e000e22}, - {0x0000a538, 0x3b043e45, 0x3b043e45, 0x31000e24, 0x31000e24}, - {0x0000a53c, 0x40063e46, 0x40063e46, 0x34001640, 0x34001640}, - {0x0000a540, 0x44083e46, 0x44083e46, 0x38001660, 0x38001660}, - {0x0000a544, 0x46083e66, 0x46083e66, 0x3b001861, 0x3b001861}, - {0x0000a548, 0x4b0a3e69, 0x4b0a3e69, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x4f0a5e66, 0x4f0a5e66, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x540a7e66, 0x540a7e66, 0x44001c84, 0x44001c84}, - {0x0000a554, 0x570a7e89, 0x570a7e89, 0x48001ce3, 0x48001ce3}, - {0x0000a558, 0x5c0e7e8a, 0x5c0e7e8a, 0x4c001ce5, 0x4c001ce5}, - {0x0000a55c, 0x60127e8b, 0x60127e8b, 0x50001ce9, 0x50001ce9}, - {0x0000a560, 0x65127ecc, 0x65127ecc, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x6b169ecd, 0x6b169ecd, 0x56001eec, 0x56001eec}, - {0x0000a568, 0x70169f0e, 0x70169f0e, 0x56001eec, 0x56001eec}, - {0x0000a56c, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, - {0x0000a570, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, - {0x0000a574, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, - {0x0000a578, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, - {0x0000a57c, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, + {0x0000a508, 0x0b022220, 0x0b022220, 0x08000004, 0x08000004}, + {0x0000a50c, 0x10022223, 0x10022223, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x17022620, 0x17022620, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x1b022622, 0x1b022622, 0x11000400, 0x11000400}, + {0x0000a518, 0x1f022822, 0x1f022822, 0x15000402, 0x15000402}, + {0x0000a51c, 0x24022842, 0x24022842, 0x19000404, 0x19000404}, + {0x0000a520, 0x28042840, 0x28042840, 0x1b000603, 0x1b000603}, + {0x0000a524, 0x2c042842, 0x2c042842, 0x1f000a02, 0x1f000a02}, + {0x0000a528, 0x30042844, 0x30042844, 0x23000a04, 0x23000a04}, + {0x0000a52c, 0x34042846, 0x34042846, 0x26000a20, 0x26000a20}, + {0x0000a530, 0x39042869, 0x39042869, 0x2a000e20, 0x2a000e20}, + {0x0000a534, 0x3d062869, 0x3d062869, 0x2e000e22, 0x2e000e22}, + {0x0000a538, 0x44062c69, 0x44062c69, 0x31000e24, 0x31000e24}, + {0x0000a53c, 0x48063069, 0x48063069, 0x34001640, 0x34001640}, + {0x0000a540, 0x4c0a3065, 0x4c0a3065, 0x38001660, 0x38001660}, + {0x0000a544, 0x500a3069, 0x500a3069, 0x3b001861, 0x3b001861}, + {0x0000a548, 0x530a3469, 0x530a3469, 0x3e001a81, 0x3e001a81}, + {0x0000a54c, 0x590a7464, 0x590a7464, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x5e0a7865, 0x5e0a7865, 0x44001c84, 0x44001c84}, + {0x0000a554, 0x630a7e66, 0x630a7e66, 0x48001ce3, 0x48001ce3}, + {0x0000a558, 0x680a7e89, 0x680a7e89, 0x4c001ce5, 0x4c001ce5}, + {0x0000a55c, 0x6e0a7e8c, 0x6e0a7e8c, 0x50001ce9, 0x50001ce9}, + {0x0000a560, 0x730e7e8c, 0x730e7e8c, 0x54001ceb, 0x54001ceb}, + {0x0000a564, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, + {0x0000a568, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, + {0x0000a56c, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, + {0x0000a570, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, + {0x0000a574, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, + {0x0000a578, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, + {0x0000a57c, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, {0x0000a580, 0x00820220, 0x00820220, 0x00800000, 0x00800000}, {0x0000a584, 0x06820223, 0x06820223, 0x04800002, 0x04800002}, - {0x0000a588, 0x0a822220, 0x0a822220, 0x08800004, 0x08800004}, - {0x0000a58c, 0x0f822223, 0x0f822223, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x14822620, 0x14822620, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x18822622, 0x18822622, 0x11800400, 0x11800400}, - {0x0000a598, 0x1b822822, 0x1b822822, 0x15800402, 0x15800402}, - {0x0000a59c, 0x20822842, 0x20822842, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x22822c41, 0x22822c41, 0x1b800603, 0x1b800603}, - {0x0000a5a4, 0x28823042, 0x28823042, 0x1f800a02, 0x1f800a02}, - {0x0000a5a8, 0x2c823044, 0x2c823044, 0x23800a04, 0x23800a04}, - {0x0000a5ac, 0x2f823644, 0x2f823644, 0x26800a20, 0x26800a20}, - {0x0000a5b0, 0x34843643, 0x34843643, 0x2a800e20, 0x2a800e20}, - {0x0000a5b4, 0x38843a44, 0x38843a44, 0x2e800e22, 0x2e800e22}, - {0x0000a5b8, 0x3b843e45, 0x3b843e45, 0x31800e24, 0x31800e24}, - {0x0000a5bc, 0x40863e46, 0x40863e46, 0x34801640, 0x34801640}, - {0x0000a5c0, 0x44883e46, 0x44883e46, 0x38801660, 0x38801660}, - {0x0000a5c4, 0x46883e66, 0x46883e66, 0x3b801861, 0x3b801861}, - {0x0000a5c8, 0x4b8a3e69, 0x4b8a3e69, 0x3e801a81, 0x3e801a81}, - {0x0000a5cc, 0x4f8a5e66, 0x4f8a5e66, 0x42801a83, 0x42801a83}, - {0x0000a5d0, 0x548a7e66, 0x548a7e66, 0x44801c84, 0x44801c84}, - {0x0000a5d4, 0x578a7e89, 0x578a7e89, 0x48801ce3, 0x48801ce3}, - {0x0000a5d8, 0x5c8e7e8a, 0x5c8e7e8a, 0x4c801ce5, 0x4c801ce5}, - {0x0000a5dc, 0x60927e8b, 0x60927e8b, 0x50801ce9, 0x50801ce9}, - {0x0000a5e0, 0x65927ecc, 0x65927ecc, 0x54801ceb, 0x54801ceb}, - {0x0000a5e4, 0x6b969ecd, 0x6b969ecd, 0x56801eec, 0x56801eec}, - {0x0000a5e8, 0x70969f0e, 0x70969f0e, 0x56801eec, 0x56801eec}, - {0x0000a5ec, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, - {0x0000a5f0, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, - {0x0000a5f4, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, - {0x0000a5f8, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, - {0x0000a5fc, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, + {0x0000a588, 0x0b822220, 0x0b822220, 0x08800004, 0x08800004}, + {0x0000a58c, 0x10822223, 0x10822223, 0x0b800200, 0x0b800200}, + {0x0000a590, 0x17822620, 0x17822620, 0x0f800202, 0x0f800202}, + {0x0000a594, 0x1b822622, 0x1b822622, 0x11800400, 0x11800400}, + {0x0000a598, 0x1f822822, 0x1f822822, 0x15800402, 0x15800402}, + {0x0000a59c, 0x24822842, 0x24822842, 0x19800404, 0x19800404}, + {0x0000a5a0, 0x28842840, 0x28842840, 0x1b800603, 0x1b800603}, + {0x0000a5a4, 0x2c842842, 0x2c842842, 0x1f800a02, 0x1f800a02}, + {0x0000a5a8, 0x30842844, 0x30842844, 0x23800a04, 0x23800a04}, + {0x0000a5ac, 0x34842846, 0x34842846, 0x26800a20, 0x26800a20}, + {0x0000a5b0, 0x39842869, 0x39842869, 0x2a800e20, 0x2a800e20}, + {0x0000a5b4, 0x3d862869, 0x3d862869, 0x2e800e22, 0x2e800e22}, + {0x0000a5b8, 0x44862c69, 0x44862c69, 0x31800e24, 0x31800e24}, + {0x0000a5bc, 0x48863069, 0x48863069, 0x34801640, 0x34801640}, + {0x0000a5c0, 0x4c8a3065, 0x4c8a3065, 0x38801660, 0x38801660}, + {0x0000a5c4, 0x508a3069, 0x508a3069, 0x3b801861, 0x3b801861}, + {0x0000a5c8, 0x538a3469, 0x538a3469, 0x3e801a81, 0x3e801a81}, + {0x0000a5cc, 0x598a7464, 0x598a7464, 0x42801a83, 0x42801a83}, + {0x0000a5d0, 0x5e8a7865, 0x5e8a7865, 0x44801c84, 0x44801c84}, + {0x0000a5d4, 0x638a7e66, 0x638a7e66, 0x48801ce3, 0x48801ce3}, + {0x0000a5d8, 0x688a7e89, 0x688a7e89, 0x4c801ce5, 0x4c801ce5}, + {0x0000a5dc, 0x6e8a7e8c, 0x6e8a7e8c, 0x50801ce9, 0x50801ce9}, + {0x0000a5e0, 0x738e7e8c, 0x738e7e8c, 0x54801ceb, 0x54801ceb}, + {0x0000a5e4, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, + {0x0000a5e8, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, + {0x0000a5ec, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, + {0x0000a5f0, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, + {0x0000a5f4, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, + {0x0000a5f8, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, + {0x0000a5fc, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, {0x00016048, 0x8c001a61, 0x8c001a61, 0x8c001a61, 0x8c001a61}, {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, @@ -1251,7 +1251,7 @@ static const u32 ar9300Common_rx_gain_table_2p0[][2] = { 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}, + {0x0000a410, 0x000050da, 0x000050da, 0x000050da, 0x000050da}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, @@ -1760,22 +1760,31 @@ static const u32 ar9300_2p0_soc_preamble[][2] = { {0x00007038, 0x000004c2}, }; +/* + * PCIE-PHY programming array, to be used prior to entering + * full sleep (holding RTC in reset, PLL is ON in L1 mode) + */ static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p0[][2] = { - /* Addr allmodes */ {0x00004040, 0x08212e5e}, {0x00004040, 0x0008003b}, {0x00004044, 0x00000000}, }; +/* + * PCIE-PHY programming array, to be used when not in + * full sleep (holding RTC in reset) + */ static const u32 ar9300PciePhy_clkreq_enable_L1_2p0[][2] = { - /* Addr allmodes */ {0x00004040, 0x08253e5e}, {0x00004040, 0x0008003b}, {0x00004044, 0x00000000}, }; +/* + * PCIE-PHY programming array, to be used prior to entering + * full sleep (holding RTC in reset) + */ static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = { - /* Addr allmodes */ {0x00004040, 0x08213e5e}, {0x00004040, 0x0008003b}, {0x00004044, 0x00000000}, diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 37ba37481a47..7d111fbf8bc5 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -311,9 +311,6 @@ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds, { struct ar9003_txc *ads = (struct ar9003_txc *) ds; - if (txpower > ah->txpower_limit) - txpower = ah->txpower_limit; - txpower += ah->txpower_indexoffset; if (txpower > 63) txpower = 63; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 80431a2f6dc1..137543b2d739 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -375,7 +375,16 @@ static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah, else if (chan && IS_CHAN_QUARTER_RATE(chan)) pll |= SM(0x2, AR_RTC_9300_PLL_CLKSEL); - pll |= SM(0x2c, AR_RTC_9300_PLL_DIV); + if (chan && IS_CHAN_5GHZ(chan)) { + pll |= SM(0x28, AR_RTC_9300_PLL_DIV); + + /* + * When doing fast clock, set PLL to 0x142c + */ + if (IS_CHAN_A_5MHZ_SPACED(chan)) + pll = 0x142c; + } else + pll |= SM(0x2c, AR_RTC_9300_PLL_DIV); return pll; } @@ -583,7 +592,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, * For 5GHz channels requiring Fast Clock, apply * different modal values. */ - if (IS_CHAN_A_FAST_CLOCK(ah, chan)) + if (IS_CHAN_A_5MHZ_SPACED(chan)) REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, regWrites); @@ -613,7 +622,7 @@ static void ar9003_hw_set_rfmode(struct ath_hw *ah, rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan)) ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; - if (IS_CHAN_A_FAST_CLOCK(ah, chan)) + if (IS_CHAN_A_5MHZ_SPACED(chan)) rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); REG_WRITE(ah, AR_PHY_MODE, rfMode); @@ -1093,7 +1102,6 @@ static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf " "to load: AR_PHY_AGC_CONTROL=0x%x\n", REG_READ(ah, AR_PHY_AGC_CONTROL)); - return; } /* diff --git a/trunk/drivers/net/wireless/ath/ath9k/common.c b/trunk/drivers/net/wireless/ath/ath9k/common.c index b4424a623cf5..09effdedc8c0 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/common.c +++ b/trunk/drivers/net/wireless/ath/ath9k/common.c @@ -212,6 +212,7 @@ int ath9k_cmn_rx_skb_preprocess(struct ath_common *common, rx_status->mactime = ath9k_hw_extend_tsf(ah, rx_stats->rs_tstamp); rx_status->band = hw->conf.channel->band; rx_status->freq = hw->conf.channel->center_freq; + rx_status->noise = common->ani.noise_floor; rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi; rx_status->antenna = rx_stats->rs_antenna; rx_status->flag |= RX_FLAG_TSFT; diff --git a/trunk/drivers/net/wireless/ath/ath9k/eeprom.h b/trunk/drivers/net/wireless/ath/ath9k/eeprom.h index 21354c15a9a9..fb9c8c92eabe 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/trunk/drivers/net/wireless/ath/ath9k/eeprom.h @@ -300,8 +300,7 @@ struct base_eep_header { u32 binBuildNumber; u8 deviceType; u8 pwdclkind; - u8 fastClk5g; - u8 divChain; + u8 futureBase_1[2]; u8 rxGainType; u8 dacHiPwrMode_5G; u8 openLoopPwrCntl; diff --git a/trunk/drivers/net/wireless/ath/ath9k/eeprom_def.c b/trunk/drivers/net/wireless/ath/ath9k/eeprom_def.c index e591ad6016e5..cf59799ef307 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/trunk/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -274,8 +274,6 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah, return pBase->txMask; case EEP_RX_MASK: return pBase->rxMask; - case EEP_FSTCLK_5G: - return pBase->fastClk5g; case EEP_RXGAIN_TYPE: return pBase->rxGainType; case EEP_TXGAIN_TYPE: diff --git a/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c b/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c index 74872ca76f9a..3091bb3cef9b 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -93,24 +93,14 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, return ret; } -static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, - struct sk_buff_head *list) -{ - struct sk_buff *skb; - - while ((skb = __skb_dequeue(list)) != NULL) { - dev_kfree_skb_any(skb); - TX_STAT_INC(skb_dropped); - } -} - static void hif_usb_tx_cb(struct urb *urb) { struct tx_buf *tx_buf = (struct tx_buf *) urb->context; struct hif_device_usb *hif_dev = tx_buf->hif_dev; struct sk_buff *skb; + bool drop, flush; - if (!hif_dev || !tx_buf) + if (!hif_dev) return; switch (urb->status) { @@ -118,47 +108,57 @@ static void hif_usb_tx_cb(struct urb *urb) break; case -ENOENT: case -ECONNRESET: + break; case -ENODEV: case -ESHUTDOWN: - /* - * The URB has been killed, free the SKBs - * and return. - */ - ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); return; default: break; } - /* Check if TX has been stopped */ - spin_lock(&hif_dev->tx.tx_lock); - if (hif_dev->tx.flags & HIF_USB_TX_STOP) { + if (tx_buf) { + spin_lock(&hif_dev->tx.tx_lock); + drop = !!(hif_dev->tx.flags & HIF_USB_TX_STOP); + flush = !!(hif_dev->tx.flags & HIF_USB_TX_FLUSH); spin_unlock(&hif_dev->tx.tx_lock); - ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); - goto add_free; - } - spin_unlock(&hif_dev->tx.tx_lock); - - /* Complete the queued SKBs. */ - while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) { - ath9k_htc_txcompletion_cb(hif_dev->htc_handle, - skb, 1); - TX_STAT_INC(skb_completed); - } - -add_free: - /* Re-initialize the SKB queue */ - tx_buf->len = tx_buf->offset = 0; - __skb_queue_head_init(&tx_buf->skb_queue); - - /* Add this TX buffer to the free list */ - spin_lock(&hif_dev->tx.tx_lock); - list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); - hif_dev->tx.tx_buf_cnt++; - if (!(hif_dev->tx.flags & HIF_USB_TX_STOP)) - __hif_usb_tx(hif_dev); /* Check for pending SKBs */ - TX_STAT_INC(buf_completed); - spin_unlock(&hif_dev->tx.tx_lock); + + while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) { + if (!drop && !flush) { + ath9k_htc_txcompletion_cb(hif_dev->htc_handle, + skb, 1); + TX_STAT_INC(skb_completed); + } else { + dev_kfree_skb_any(skb); + TX_STAT_INC(skb_dropped); + } + } + + if (flush) + return; + + tx_buf->len = tx_buf->offset = 0; + __skb_queue_head_init(&tx_buf->skb_queue); + + spin_lock(&hif_dev->tx.tx_lock); + list_del(&tx_buf->list); + list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf); + hif_dev->tx.tx_buf_cnt++; + if (!drop) + __hif_usb_tx(hif_dev); /* Check for pending SKBs */ + TX_STAT_INC(buf_completed); + spin_unlock(&hif_dev->tx.tx_lock); + } +} + +static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, + struct sk_buff_head *list) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(list)) != NULL) { + dev_kfree_skb_any(skb); + TX_STAT_INC(skb_dropped); + } } /* TX lock has to be taken */ @@ -178,7 +178,8 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) return 0; tx_buf = list_first_entry(&hif_dev->tx.tx_buf, struct tx_buf, list); - list_move_tail(&tx_buf->list, &hif_dev->tx.tx_pending); + list_del(&tx_buf->list); + list_add_tail(&tx_buf->list, &hif_dev->tx.tx_pending); hif_dev->tx.tx_buf_cnt--; tx_skb_cnt = min_t(u16, hif_dev->tx.tx_skb_cnt, MAX_TX_AGGR_NUM); @@ -510,18 +511,9 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) if (likely(urb->actual_length != 0)) { skb_put(skb, urb->actual_length); - /* Process the command first */ - ath9k_htc_rx_msg(hif_dev->htc_handle, skb, - skb->len, USB_REG_IN_PIPE); - - nskb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC); - if (!nskb) { - dev_err(&hif_dev->udev->dev, - "ath9k_htc: REG_IN memory allocation failure\n"); - urb->context = NULL; - return; - } + if (!nskb) + goto resubmit; usb_fill_int_urb(urb, hif_dev->udev, usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE), @@ -531,9 +523,12 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret) { kfree_skb(nskb); - urb->context = NULL; + goto free; } + ath9k_htc_rx_msg(hif_dev->htc_handle, skb, + skb->len, USB_REG_IN_PIPE); + return; } @@ -553,17 +548,20 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev) { + unsigned long flags; struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; - list_for_each_entry_safe(tx_buf, tx_buf_tmp, - &hif_dev->tx.tx_buf, list) { - usb_kill_urb(tx_buf->urb); + list_for_each_entry_safe(tx_buf, tx_buf_tmp, &hif_dev->tx.tx_buf, list) { list_del(&tx_buf->list); usb_free_urb(tx_buf->urb); kfree(tx_buf->buf); kfree(tx_buf); } + spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); + hif_dev->tx.flags |= HIF_USB_TX_FLUSH; + spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); + list_for_each_entry_safe(tx_buf, tx_buf_tmp, &hif_dev->tx.tx_pending, list) { usb_kill_urb(tx_buf->urb); @@ -572,6 +570,10 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev) kfree(tx_buf->buf); kfree(tx_buf); } + + spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); + hif_dev->tx.flags &= ~HIF_USB_TX_FLUSH; + spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); } static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) @@ -895,26 +897,6 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, return ret; } -static void ath9k_hif_usb_reboot(struct usb_device *udev) -{ - u32 reboot_cmd = 0xffffffff; - void *buf; - int ret; - - buf = kmalloc(4, GFP_KERNEL); - if (!buf) - return; - - memcpy(buf, &reboot_cmd, 4); - - ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, USB_REG_OUT_PIPE), - buf, 4, NULL, HZ); - if (ret) - dev_err(&udev->dev, "ath9k_htc: USB reboot failed\n"); - - kfree(buf); -} - static void ath9k_hif_usb_disconnect(struct usb_interface *interface) { struct usb_device *udev = interface_to_usbdev(interface); @@ -922,15 +904,14 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface) (struct hif_device_usb *) usb_get_intfdata(interface); if (hif_dev) { - ath9k_htc_hw_deinit(hif_dev->htc_handle, - (udev->state == USB_STATE_NOTATTACHED) ? true : false); + ath9k_htc_hw_deinit(hif_dev->htc_handle, true); ath9k_htc_hw_free(hif_dev->htc_handle); ath9k_hif_usb_dev_deinit(hif_dev); usb_set_intfdata(interface, NULL); } if (hif_dev->flags & HIF_USB_START) - ath9k_hif_usb_reboot(udev); + usb_reset_device(udev); kfree(hif_dev); dev_info(&udev->dev, "ath9k_htc: USB layer deinitialized\n"); diff --git a/trunk/drivers/net/wireless/ath/ath9k/hif_usb.h b/trunk/drivers/net/wireless/ath/ath9k/hif_usb.h index 0aca49b6fcb6..7d49a8af420e 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/trunk/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -61,6 +61,7 @@ struct tx_buf { }; #define HIF_USB_TX_STOP BIT(0) +#define HIF_USB_TX_FLUSH BIT(1) struct hif_usb_tx { u8 flags; diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc.h b/trunk/drivers/net/wireless/ath/ath9k/htc.h index 1ae18bbc4d9e..c765ff4a505c 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc.h +++ b/trunk/drivers/net/wireless/ath/ath9k/htc.h @@ -329,7 +329,6 @@ struct htc_beacon_config { #define OP_ASSOCIATED BIT(8) #define OP_ENABLE_BEACON BIT(9) #define OP_LED_DEINIT BIT(10) -#define OP_UNPLUGGED BIT(11) struct ath9k_htc_priv { struct device *dev; @@ -379,7 +378,6 @@ struct ath9k_htc_priv { struct mutex htc_pm_lock; unsigned long ps_usecount; bool ps_enabled; - bool ps_idle; struct ath_led radio_led; struct ath_led assoc_led; diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 701f2ef5a440..a86189629d92 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -744,9 +744,6 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, if (ret) goto err_init; - /* The device may have been unplugged earlier. */ - priv->op_flags &= ~OP_UNPLUGGED; - ret = ath9k_init_device(priv, devid); if (ret) goto err_init; @@ -763,11 +760,6 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug) { if (htc_handle->drv_priv) { - - /* Check if the device has been yanked out. */ - if (hotunplug) - htc_handle->drv_priv->op_flags |= OP_UNPLUGGED; - ath9k_deinit_device(htc_handle->drv_priv); ath9k_deinit_wmi(htc_handle->drv_priv); ieee80211_free_hw(htc_handle->drv_priv->hw); diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c index ca7f3a78eb11..ec7bcc8696ec 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -94,11 +94,8 @@ void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv) if (--priv->ps_usecount != 0) goto unlock; - if (priv->ps_idle) - ath9k_hw_setpower(priv->ah, ATH9K_PM_FULL_SLEEP); - else if (priv->ps_enabled) + if (priv->ps_enabled) ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP); - unlock: mutex_unlock(&priv->htc_pm_lock); } @@ -156,6 +153,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, ath_print(common, ATH_DBG_FATAL, "Unable to reset channel (%u Mhz) " "reset status %d\n", channel->center_freq, ret); + ath9k_htc_ps_restore(priv); goto err; } @@ -1099,7 +1097,7 @@ static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return 0; } -static int ath9k_htc_radio_enable(struct ieee80211_hw *hw) +static int ath9k_htc_start(struct ieee80211_hw *hw) { struct ath9k_htc_priv *priv = hw->priv; struct ath_hw *ah = priv->ah; @@ -1115,6 +1113,8 @@ static int ath9k_htc_radio_enable(struct ieee80211_hw *hw) "Starting driver with initial channel: %d MHz\n", curchan->center_freq); + mutex_lock(&priv->mutex); + /* setup initial channel */ init_channel = ath9k_cmn_get_curchannel(hw, ah); @@ -1127,7 +1127,7 @@ static int ath9k_htc_radio_enable(struct ieee80211_hw *hw) ath_print(common, ATH_DBG_FATAL, "Unable to reset hardware; reset status %d " "(freq %u MHz)\n", ret, curchan->center_freq); - return ret; + goto mutex_unlock; } ath_update_txpow(priv); @@ -1135,8 +1135,16 @@ static int ath9k_htc_radio_enable(struct ieee80211_hw *hw) mode = ath9k_htc_get_curmode(priv, init_channel); htc_mode = cpu_to_be16(mode); WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode); + if (ret) + goto mutex_unlock; + WMI_CMD(WMI_ATH_INIT_CMDID); + if (ret) + goto mutex_unlock; + WMI_CMD(WMI_START_RECV_CMDID); + if (ret) + goto mutex_unlock; ath9k_host_rx_init(priv); @@ -1149,22 +1157,12 @@ static int ath9k_htc_radio_enable(struct ieee80211_hw *hw) ieee80211_wake_queues(hw); - return ret; -} - -static int ath9k_htc_start(struct ieee80211_hw *hw) -{ - struct ath9k_htc_priv *priv = hw->priv; - int ret = 0; - - mutex_lock(&priv->mutex); - ret = ath9k_htc_radio_enable(hw); +mutex_unlock: mutex_unlock(&priv->mutex); - return ret; } -static void ath9k_htc_radio_disable(struct ieee80211_hw *hw) +static void ath9k_htc_stop(struct ieee80211_hw *hw) { struct ath9k_htc_priv *priv = hw->priv; struct ath_hw *ah = priv->ah; @@ -1172,18 +1170,14 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw) int ret = 0; u8 cmd_rsp; + mutex_lock(&priv->mutex); + if (priv->op_flags & OP_INVALID) { ath_print(common, ATH_DBG_ANY, "Device not present\n"); + mutex_unlock(&priv->mutex); return; } - /* 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_aggr_work); - cancel_delayed_work_sync(&priv->ath9k_led_blink_work); - ath9k_led_stop_brightness(priv); - ath9k_htc_ps_wakeup(priv); htc_stop(priv->htc); WMI_CMD(WMI_DISABLE_INTR_CMDID); @@ -1195,6 +1189,11 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw) ath9k_htc_ps_restore(priv); ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); + cancel_work_sync(&priv->ps_work); + cancel_delayed_work_sync(&priv->ath9k_ani_work); + cancel_delayed_work_sync(&priv->ath9k_aggr_work); + cancel_delayed_work_sync(&priv->ath9k_led_blink_work); + ath9k_led_stop_brightness(priv); skb_queue_purge(&priv->tx_queue); /* Remove monitor interface here */ @@ -1208,20 +1207,11 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw) } priv->op_flags |= OP_INVALID; + mutex_unlock(&priv->mutex); ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); } -static void ath9k_htc_stop(struct ieee80211_hw *hw) -{ - struct ath9k_htc_priv *priv = hw->priv; - - mutex_lock(&priv->mutex); - ath9k_htc_radio_disable(hw); - mutex_unlock(&priv->mutex); -} - - static int ath9k_htc_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { @@ -1335,23 +1325,6 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&priv->mutex); - if (changed & IEEE80211_CONF_CHANGE_IDLE) { - bool enable_radio = false; - bool idle = !!(conf->flags & IEEE80211_CONF_IDLE); - - if (!idle && priv->ps_idle) - enable_radio = true; - - priv->ps_idle = idle; - - if (enable_radio) { - ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); - ath9k_htc_radio_enable(hw); - ath_print(common, ATH_DBG_CONFIG, - "not-idle: enabling radio\n"); - } - } - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { struct ieee80211_channel *curchan = hw->conf.channel; int pos = curchan->hw_value; @@ -1395,13 +1368,6 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) } } - if (priv->ps_idle) { - ath_print(common, ATH_DBG_CONFIG, - "idle: disabling radio\n"); - ath9k_htc_radio_disable(hw); - } - - mutex_unlock(&priv->mutex); return 0; diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 28abc7d5e909..2c3c51007dd3 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -244,25 +244,16 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, enum htc_endpoint_id ep_id, bool txok) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv; - struct ath_common *common = ath9k_hw_common(priv->ah); struct ieee80211_tx_info *tx_info; if (!skb) return; - if (ep_id == priv->mgmt_ep) { + if (ep_id == priv->mgmt_ep) skb_pull(skb, sizeof(struct tx_mgmt_hdr)); - } else if ((ep_id == priv->data_bk_ep) || - (ep_id == priv->data_be_ep) || - (ep_id == priv->data_vi_ep) || - (ep_id == priv->data_vo_ep)) { + else + /* TODO: Check for cab/uapsd/data */ skb_pull(skb, sizeof(struct tx_frame_hdr)); - } else { - ath_print(common, ATH_DBG_FATAL, - "Unsupported TX EPID: %d\n", ep_id); - dev_kfree_skb_any(skb); - return; - } tx_info = IEEE80211_SKB_CB(skb); @@ -448,32 +439,10 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, struct ieee80211_hw *hw = priv->hw; struct sk_buff *skb = rxbuf->skb; struct ath_common *common = ath9k_hw_common(priv->ah); - struct ath_htc_rx_status *rxstatus; int hdrlen, padpos, padsize; int last_rssi = ATH_RSSI_DUMMY_MARKER; __le16 fc; - if (skb->len <= HTC_RX_FRAME_HEADER_SIZE) { - ath_print(common, ATH_DBG_FATAL, - "Corrupted RX frame, dropping\n"); - goto rx_next; - } - - rxstatus = (struct ath_htc_rx_status *)skb->data; - - if (be16_to_cpu(rxstatus->rs_datalen) - - (skb->len - HTC_RX_FRAME_HEADER_SIZE) != 0) { - ath_print(common, ATH_DBG_FATAL, - "Corrupted RX data len, dropping " - "(dlen: %d, skblen: %d)\n", - rxstatus->rs_datalen, skb->len); - goto rx_next; - } - - /* Get the RX status information */ - memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE); - skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); - hdr = (struct ieee80211_hdr *)skb->data; fc = hdr->frame_control; hdrlen = ieee80211_get_hdrlen_from_skb(skb); @@ -638,6 +607,8 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb, struct ath_hw *ah = priv->ah; struct ath_common *common = ath9k_hw_common(ah); struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL; + struct ath_htc_rx_status *rxstatus; + u32 len = 0; spin_lock(&priv->rx.rxbuflock); list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) { @@ -654,7 +625,27 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb, goto err; } + len = skb->len; + if (len <= HTC_RX_FRAME_HEADER_SIZE) { + ath_print(common, ATH_DBG_FATAL, + "Corrupted RX frame, dropping\n"); + goto err; + } + + rxstatus = (struct ath_htc_rx_status *)skb->data; + + if (be16_to_cpu(rxstatus->rs_datalen) - + (len - HTC_RX_FRAME_HEADER_SIZE) != 0) { + ath_print(common, ATH_DBG_FATAL, + "Corrupted RX data len, dropping " + "(epid: %d, dlen: %d, skblen: %d)\n", + ep_id, rxstatus->rs_datalen, len); + goto err; + } + spin_lock(&priv->rx.rxbuflock); + memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE); + skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); rxbuf->skb = skb; rxbuf->in_process = true; spin_unlock(&priv->rx.rxbuflock); diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_hst.c b/trunk/drivers/net/wireless/ath/ath9k/htc_hst.c index 7bf6ce1e7e2e..f2dca258bdc2 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -341,9 +341,8 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, skb_pull(skb, sizeof(struct htc_frame_hdr)); if (endpoint->ep_callbacks.tx) { - endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv, - skb, htc_hdr->endpoint_id, - txok); + endpoint->ep_callbacks.tx(htc_handle->drv_priv, skb, + htc_hdr->endpoint_id, txok); } } diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c index 559019262d30..5a29048db3b1 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c @@ -26,7 +26,6 @@ #define ATH9K_CLOCK_RATE_CCK 22 #define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 #define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 -#define ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM 44 static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); @@ -92,11 +91,7 @@ static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) 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; - else - return usecs * ATH9K_CLOCK_RATE_5GHZ_OFDM; + return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM; } static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs) @@ -391,12 +386,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) ah->config.rx_intr_mitigation = true; - /* - * Tx IQ Calibration (ah->config.tx_iq_calibration) is only - * used by AR9003, but it is showing reliability issues. - * It will take a while to fix so this is currently disabled. - */ - /* * We need this for PCI devices only (Cardbus, PCI, miniPCI) * _and_ if on non-uniprocessor systems (Multiprocessor/HT). @@ -830,6 +819,9 @@ void ath9k_hw_deinit(struct ath_hw *ah) if (common->state < ATH_HW_INITIALIZED) goto free_hw; + if (!AR_SREV_9100(ah)) + ath9k_hw_ani_disable(ah); + ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); free_hw: @@ -1229,7 +1221,8 @@ 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) || IS_CHAN_A_5MHZ_SPACED(chan) || + IS_CHAN_A_5MHZ_SPACED(ah->curchan))) { if (ath9k_hw_channel_change(ah, chan)) { ath9k_hw_loadnf(ah, ah->curchan); @@ -2193,8 +2186,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_EDMA | ATH9K_HW_CAP_LDPC | - ATH9K_HW_CAP_FASTCLOCK; + pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_LDPC; pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH; pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH; pCap->rx_status_len = sizeof(struct ar9003_rxs); @@ -2202,11 +2194,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->txs_len = sizeof(struct ar9003_txs); } else { pCap->tx_desc_len = sizeof(struct ath_desc); - if (AR_SREV_9280_20(ah) && - ((ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) <= - AR5416_EEP_MINOR_VER_16) || - ah->eep_ops->get_eeprom(ah, EEP_FSTCLK_5G))) - pCap->hw_caps |= ATH9K_HW_CAP_FASTCLOCK; } if (AR_SREV_9300_20_OR_LATER(ah)) diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.h b/trunk/drivers/net/wireless/ath/ath9k/hw.h index 77245dff5993..a78e09bab431 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.h +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.h @@ -198,7 +198,6 @@ enum ath9k_hw_caps { 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), }; enum ath9k_capability_type { @@ -262,7 +261,6 @@ struct ath9k_ops_config { #define AR_BASE_FREQ_5GHZ 4900 #define AR_SPUR_FEEQ_BOUND_HT40 19 #define AR_SPUR_FEEQ_BOUND_HT20 10 - bool tx_iq_calibration; /* Only available for >= AR9003 */ int spurmode; u16 spurchans[AR_EEPROM_MODAL_SPURS][2]; u8 max_txtrig_level; @@ -369,9 +367,10 @@ struct ath9k_channel { #define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0) #define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0) #define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0) -#define IS_CHAN_A_FAST_CLOCK(_ah, _c) \ +#define IS_CHAN_A_5MHZ_SPACED(_c) \ ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \ - ((_ah)->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)) + (((_c)->channel % 20) != 0) && \ + (((_c)->channel % 10) != 0)) /* These macros check chanmode and not channelFlags */ #define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B) @@ -719,7 +718,6 @@ struct ath_hw { u32 *addac5416_21; u32 *bank6Temp; - u8 txpower_limit; int16_t txpower_indexoffset; int coverage_class; u32 beacon_interval; diff --git a/trunk/drivers/net/wireless/ath/ath9k/mac.c b/trunk/drivers/net/wireless/ath/ath9k/mac.c index 0e425cb4bbb1..7bbf502563bc 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/mac.c +++ b/trunk/drivers/net/wireless/ath/ath9k/mac.c @@ -878,12 +878,10 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, if (ints & ATH9K_INT_TX) { if (ah->config.tx_intr_mitigation) mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM; - else { - if (ah->txok_interrupt_mask) - mask |= AR_IMR_TXOK; - if (ah->txdesc_interrupt_mask) - mask |= AR_IMR_TXDESC; - } + if (ah->txok_interrupt_mask) + mask |= AR_IMR_TXOK; + if (ah->txdesc_interrupt_mask) + mask |= AR_IMR_TXDESC; if (ah->txerr_interrupt_mask) mask |= AR_IMR_TXERR; if (ah->txeol_interrupt_mask) diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index 893b552981a0..aad370a7f95b 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -2044,25 +2044,6 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, return ret; } -static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) -{ - 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; - - return 0; -} - static void ath9k_sw_scan_start(struct ieee80211_hw *hw) { struct ath_wiphy *aphy = hw->priv; @@ -2134,7 +2115,6 @@ struct ieee80211_ops ath9k_ops = { .set_tsf = ath9k_set_tsf, .reset_tsf = ath9k_reset_tsf, .ampdu_action = ath9k_ampdu_action, - .get_survey = ath9k_get_survey, .sw_scan_start = ath9k_sw_scan_start, .sw_scan_complete = ath9k_sw_scan_complete, .rfkill_poll = ath9k_rfkill_poll_state, diff --git a/trunk/drivers/net/wireless/ath/ath9k/wmi.c b/trunk/drivers/net/wireless/ath/ath9k/wmi.c index e23172c9caaf..dc6c6fc2e095 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/wmi.c +++ b/trunk/drivers/net/wireless/ath/ath9k/wmi.c @@ -276,9 +276,6 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, int time_left, ret = 0; unsigned long flags; - if (wmi->drv_priv->op_flags & OP_UNPLUGGED) - return 0; - if (!wmi) return -EINVAL; @@ -305,14 +302,14 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, wmi->cmd_rsp_buf = rsp_buf; wmi->cmd_rsp_len = rsp_len; - spin_lock_irqsave(&wmi->wmi_lock, flags); - wmi->last_cmd_id = cmd_id; - spin_unlock_irqrestore(&wmi->wmi_lock, flags); - ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len); if (ret) goto out; + spin_lock_irqsave(&wmi->wmi_lock, flags); + wmi->last_cmd_id = cmd_id; + spin_unlock_irqrestore(&wmi->wmi_lock, flags); + time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout); if (!time_left) { ath_print(common, ATH_DBG_WMI, diff --git a/trunk/drivers/net/wireless/ath/ath9k/wmi.h b/trunk/drivers/net/wireless/ath/ath9k/wmi.h index 765db5faa2d3..167e15c50062 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/wmi.h +++ b/trunk/drivers/net/wireless/ath/ath9k/wmi.h @@ -126,14 +126,14 @@ void ath9k_wmi_tasklet(unsigned long data); do { \ ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, NULL, 0, \ (u8 *) &cmd_rsp, \ - sizeof(cmd_rsp), HZ*2); \ + sizeof(cmd_rsp), HZ); \ } while (0) #define WMI_CMD_BUF(_wmi_cmd, _buf) \ do { \ ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, \ (u8 *) _buf, sizeof(*_buf), \ - &cmd_rsp, sizeof(cmd_rsp), HZ*2); \ + &cmd_rsp, sizeof(cmd_rsp), HZ); \ } while (0) #endif /* WMI_H */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index 3db19172b43b..b0d345a675fe 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -2290,8 +2290,6 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) ath_tx_complete_buf(sc, bf, txq, &bf_head, &txs, txok, 0); - ath_wake_mac80211_queue(sc, txq); - spin_lock_bh(&txq->axq_lock); if (!list_empty(&txq->txq_fifo_pending)) { INIT_LIST_HEAD(&bf_head); diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index 7965b70efbab..997303bcf4ae 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -4571,23 +4571,6 @@ static void b43_op_sw_scan_complete_notifier(struct ieee80211_hw *hw) mutex_unlock(&wl->mutex); } -static int b43_op_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) -{ - struct b43_wl *wl = hw_to_b43_wl(hw); - struct b43_wldev *dev = wl->current_dev; - struct ieee80211_conf *conf = &hw->conf; - - if (idx != 0) - return -ENOENT; - - survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = dev->stats.link_noise; - - return 0; -} - static const struct ieee80211_ops b43_hw_ops = { .tx = b43_op_tx, .conf_tx = b43_op_conf_tx, @@ -4607,7 +4590,6 @@ static const struct ieee80211_ops b43_hw_ops = { .sta_notify = b43_op_sta_notify, .sw_scan_start = b43_op_sw_scan_start_notifier, .sw_scan_complete = b43_op_sw_scan_complete_notifier, - .get_survey = b43_op_get_survey, .rfkill_poll = b43_rfkill_poll, }; @@ -4923,7 +4905,8 @@ static int b43_wireless_init(struct ssb_device *dev) /* fill hw info */ hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_SIGNAL_DBM; + IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_NOISE_DBM; hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | diff --git a/trunk/drivers/net/wireless/b43/xmit.c b/trunk/drivers/net/wireless/b43/xmit.c index e6b0528f3b52..eda06529ef5f 100644 --- a/trunk/drivers/net/wireless/b43/xmit.c +++ b/trunk/drivers/net/wireless/b43/xmit.c @@ -610,6 +610,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) } /* Link quality statistics */ + status.noise = dev->stats.link_noise; if ((chanstat & B43_RX_CHAN_PHYTYPE) == B43_PHYTYPE_N) { // s8 rssi = max(rxhdr->power0, rxhdr->power1); //TODO: Find out what the rssi value is (dBm or percentage?) diff --git a/trunk/drivers/net/wireless/b43legacy/main.c b/trunk/drivers/net/wireless/b43legacy/main.c index 1713f5f7a58b..bb2dd9329aa0 100644 --- a/trunk/drivers/net/wireless/b43legacy/main.c +++ b/trunk/drivers/net/wireless/b43legacy/main.c @@ -3482,23 +3482,6 @@ static int b43legacy_op_beacon_set_tim(struct ieee80211_hw *hw, return 0; } -static int b43legacy_op_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) -{ - struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); - struct b43legacy_wldev *dev = wl->current_dev; - struct ieee80211_conf *conf = &hw->conf; - - if (idx != 0) - return -ENOENT; - - survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = dev->stats.link_noise; - - return 0; -} - static const struct ieee80211_ops b43legacy_hw_ops = { .tx = b43legacy_op_tx, .conf_tx = b43legacy_op_conf_tx, @@ -3511,7 +3494,6 @@ static const struct ieee80211_ops b43legacy_hw_ops = { .start = b43legacy_op_start, .stop = b43legacy_op_stop, .set_tim = b43legacy_op_beacon_set_tim, - .get_survey = b43legacy_op_get_survey, .rfkill_poll = b43legacy_rfkill_poll, }; @@ -3787,7 +3769,8 @@ static int b43legacy_wireless_init(struct ssb_device *dev) /* fill hw info */ hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_SIGNAL_DBM; + IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_NOISE_DBM; hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_STATION) | diff --git a/trunk/drivers/net/wireless/b43legacy/xmit.c b/trunk/drivers/net/wireless/b43legacy/xmit.c index 7d177d97f1f7..9c8882d9275e 100644 --- a/trunk/drivers/net/wireless/b43legacy/xmit.c +++ b/trunk/drivers/net/wireless/b43legacy/xmit.c @@ -548,6 +548,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev, (phystat0 & B43legacy_RX_PHYST0_OFDM), (phystat0 & B43legacy_RX_PHYST0_GAINCTL), (phystat3 & B43legacy_RX_PHYST3_TRSTATE)); + status.noise = dev->stats.link_noise; /* change to support A PHY */ if (phystat0 & B43legacy_RX_PHYST0_OFDM) status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false); diff --git a/trunk/drivers/net/wireless/iwlwifi/Makefile b/trunk/drivers/net/wireless/iwlwifi/Makefile index 7c7235385513..5ed2dcbe6d01 100644 --- a/trunk/drivers/net/wireless/iwlwifi/Makefile +++ b/trunk/drivers/net/wireless/iwlwifi/Makefile @@ -22,6 +22,5 @@ iwlagn-$(CONFIG_IWL5000) += iwl-1000.o # 3945 obj-$(CONFIG_IWL3945) += iwl3945.o iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o -iwl3945-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-3945-debugfs.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c index fb59af2d41c6..8431ffce37d3 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -282,6 +282,7 @@ struct iwl_cfg iwl1000_bg_cfg = { .use_bsm = false, .max_ll_items = OTP_MAX_LL_ITEMS_1000, .shadow_ram_support = false, + .ht_greenfield_support = true, .led_compensation = 51, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .support_ct_kill_exit = true, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c deleted file mode 100644 index 6a9c64a50e36..000000000000 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c +++ /dev/null @@ -1,500 +0,0 @@ -/****************************************************************************** - * - * 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 - *****************************************************************************/ - -#include "iwl-3945-debugfs.h" - -ssize_t iwl3945_ucode_rx_stats_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - int pos = 0; - char *buf; - int bufsz = sizeof(struct iwl39_statistics_rx_phy) * 40 + - sizeof(struct iwl39_statistics_rx_non_phy) * 40 + 400; - ssize_t ret; - struct iwl39_statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm; - struct iwl39_statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck; - struct iwl39_statistics_rx_non_phy *general, *accum_general; - struct iwl39_statistics_rx_non_phy *delta_general, *max_general; - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - buf = kzalloc(bufsz, GFP_KERNEL); - if (!buf) { - IWL_ERR(priv, "Can not allocate Buffer\n"); - return -ENOMEM; - } - - /* - * The statistic information display here is based on - * the last statistics notification from uCode - * might not reflect the current uCode activity - */ - ofdm = &priv->_3945.statistics.rx.ofdm; - cck = &priv->_3945.statistics.rx.cck; - general = &priv->_3945.statistics.rx.general; - accum_ofdm = &priv->_3945.accum_statistics.rx.ofdm; - accum_cck = &priv->_3945.accum_statistics.rx.cck; - accum_general = &priv->_3945.accum_statistics.rx.general; - delta_ofdm = &priv->_3945.delta_statistics.rx.ofdm; - delta_cck = &priv->_3945.delta_statistics.rx.cck; - delta_general = &priv->_3945.delta_statistics.rx.general; - max_ofdm = &priv->_3945.max_delta.rx.ofdm; - max_cck = &priv->_3945.max_delta.rx.cck; - max_general = &priv->_3945.max_delta.rx.general; - - pos += iwl_dbgfs_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), - 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:", - 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:", - 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:", - 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:", - 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:", - 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), - 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:", - 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:", - 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:", - 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:", - 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:", - 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:", - 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:", - 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:", - 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, "%-32s current" - "acumulative delta max\n", - "Statistics_Rx - CCK:"); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "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:", - 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:", - 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:", - 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:", - 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:", - 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:", - 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:", - 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:", - 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:", - 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:", - 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:", - 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:", - 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:", - 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:", - 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, "%-32s current" - "acumulative delta max\n", - "Statistics_Rx - GENERAL:"); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "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:", - 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:", - 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:", - 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:", - le32_to_cpu(general->non_channel_beacons), - accum_general->non_channel_beacons, - delta_general->non_channel_beacons, - max_general->non_channel_beacons); - - ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); - kfree(buf); - return ret; -} - -ssize_t iwl3945_ucode_tx_stats_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - int pos = 0; - char *buf; - int bufsz = (sizeof(struct iwl39_statistics_tx) * 48) + 250; - ssize_t ret; - struct iwl39_statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - buf = kzalloc(bufsz, GFP_KERNEL); - if (!buf) { - IWL_ERR(priv, "Can not allocate Buffer\n"); - return -ENOMEM; - } - - /* - * The statistic information display here is based on - * the last statistics notification from uCode - * might not reflect the current uCode activity - */ - tx = &priv->_3945.statistics.tx; - accum_tx = &priv->_3945.accum_statistics.tx; - delta_tx = &priv->_3945.delta_statistics.tx; - max_tx = &priv->_3945.max_delta.tx; - pos += iwl_dbgfs_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:", - 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:", - 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:", - 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:", - 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:", - 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:", - 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:", - 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:", - 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:", - le32_to_cpu(tx->actual_ack_cnt), - accum_tx->actual_ack_cnt, - delta_tx->actual_ack_cnt, - max_tx->actual_ack_cnt); - - ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); - kfree(buf); - return ret; -} - -ssize_t iwl3945_ucode_general_stats_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - int pos = 0; - char *buf; - int bufsz = sizeof(struct iwl39_statistics_general) * 10 + 300; - ssize_t ret; - struct iwl39_statistics_general *general, *accum_general; - struct iwl39_statistics_general *delta_general, *max_general; - struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; - struct iwl39_statistics_div *div, *accum_div, *delta_div, *max_div; - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - buf = kzalloc(bufsz, GFP_KERNEL); - if (!buf) { - IWL_ERR(priv, "Can not allocate Buffer\n"); - return -ENOMEM; - } - - /* - * The statistic information display here is based on - * the last statistics notification from uCode - * might not reflect the current uCode activity - */ - general = &priv->_3945.statistics.general; - dbg = &priv->_3945.statistics.general.dbg; - div = &priv->_3945.statistics.general.div; - accum_general = &priv->_3945.accum_statistics.general; - delta_general = &priv->_3945.delta_statistics.general; - max_general = &priv->_3945.max_delta.general; - accum_dbg = &priv->_3945.accum_statistics.general.dbg; - delta_dbg = &priv->_3945.delta_statistics.general.dbg; - max_dbg = &priv->_3945.max_delta.general.dbg; - accum_div = &priv->_3945.accum_statistics.general.div; - delta_div = &priv->_3945.delta_statistics.general.div; - max_div = &priv->_3945.max_delta.general.div; - pos += iwl_dbgfs_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 %10u %10u %10u\n", - "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:", - 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", - "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:", - 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:", - 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:", - 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:", - 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:", - 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:", - le32_to_cpu(div->probe_time), accum_div->probe_time, - delta_div->probe_time, max_div->probe_time); - ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); - kfree(buf); - return ret; -} diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h b/trunk/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h deleted file mode 100644 index 70809c53c215..000000000000 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h +++ /dev/null @@ -1,60 +0,0 @@ -/****************************************************************************** - * - * 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 - *****************************************************************************/ - -#include "iwl-dev.h" -#include "iwl-core.h" -#include "iwl-debug.h" - -#ifdef CONFIG_IWLWIFI_DEBUGFS -ssize_t iwl3945_ucode_rx_stats_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos); -ssize_t iwl3945_ucode_tx_stats_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos); -ssize_t iwl3945_ucode_general_stats_read(struct file *file, - char __user *user_buf, size_t count, - loff_t *ppos); -#else -static ssize_t iwl3945_ucode_rx_stats_read(struct file *file, - char __user *user_buf, size_t count, - loff_t *ppos) -{ - return 0; -} -static ssize_t iwl3945_ucode_tx_stats_read(struct file *file, - char __user *user_buf, size_t count, - loff_t *ppos) -{ - return 0; -} -static ssize_t iwl3945_ucode_general_stats_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - return 0; -} -#endif diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-3945.c b/trunk/drivers/net/wireless/iwlwifi/iwl-3945.c index 17197a78d894..59af2594c9c5 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -50,7 +50,6 @@ #include "iwl-helpers.h" #include "iwl-led.h" #include "iwl-3945-led.h" -#include "iwl-3945-debugfs.h" #define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ @@ -294,7 +293,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, * iwl3945_rx_reply_tx - Handle Tx response */ static void iwl3945_rx_reply_tx(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { struct iwl_rx_packet *pkt = rxb_addr(rxb); u16 sequence = le16_to_cpu(pkt->hdr.sequence); @@ -352,81 +351,18 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv, * RX handler implementations * *****************************************************************************/ -#ifdef CONFIG_IWLWIFI_DEBUG -/* - * based on the assumption of all statistics counter are in DWORD - * FIXME: This function is for debugging, do not deal with - * the case of counters roll-over. - */ -static void iwl3945_accumulative_statistics(struct iwl_priv *priv, - __le32 *stats) -{ - int i; - __le32 *prev_stats; - u32 *accum_stats; - u32 *delta, *max_delta; - - prev_stats = (__le32 *)&priv->_3945.statistics; - accum_stats = (u32 *)&priv->_3945.accum_statistics; - delta = (u32 *)&priv->_3945.delta_statistics; - max_delta = (u32 *)&priv->_3945.max_delta; - - for (i = sizeof(__le32); i < sizeof(struct iwl3945_notif_statistics); - i += sizeof(__le32), stats++, prev_stats++, delta++, - max_delta++, accum_stats++) { - if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { - *delta = (le32_to_cpu(*stats) - - le32_to_cpu(*prev_stats)); - *accum_stats += *delta; - if (*delta > *max_delta) - *max_delta = *delta; - } - } - - /* reset accumulative statistics for "no-counter" type statistics */ - priv->_3945.accum_statistics.general.temperature = - priv->_3945.statistics.general.temperature; - priv->_3945.accum_statistics.general.ttl_timestamp = - priv->_3945.statistics.general.ttl_timestamp; -} -#endif void iwl3945_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", (int)sizeof(struct iwl3945_notif_statistics), le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); -#ifdef CONFIG_IWLWIFI_DEBUG - iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); -#endif memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics)); } -void iwl3945_reply_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - __le32 *flag = (__le32 *)&pkt->u.raw; - - if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) { -#ifdef CONFIG_IWLWIFI_DEBUG - memset(&priv->_3945.accum_statistics, 0, - sizeof(struct iwl3945_notif_statistics)); - memset(&priv->_3945.delta_statistics, 0, - sizeof(struct iwl3945_notif_statistics)); - memset(&priv->_3945.max_delta, 0, - sizeof(struct iwl3945_notif_statistics)); -#endif - IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); - } - iwl3945_hw_rx_statistics(priv, rxb); -} - - /****************************************************************************** * * Misc. internal state and helper functions @@ -2800,12 +2736,6 @@ static struct iwl_lib_ops iwl3945_lib = { .isr = iwl_isr_legacy, .config_ap = iwl3945_config_ap, .add_bcast_station = iwl3945_add_bcast_station, - - .debugfs_ops = { - .rx_stats_read = iwl3945_ucode_rx_stats_read, - .tx_stats_read = iwl3945_ucode_tx_stats_read, - .general_stats_read = iwl3945_ucode_general_stats_read, - }, }; static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-3945.h b/trunk/drivers/net/wireless/iwlwifi/iwl-3945.h index 643adb644bb8..e9674f0a1e94 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -264,8 +264,6 @@ extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv); extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); -void iwl3945_reply_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); extern void iwl3945_disable_events(struct iwl_priv *priv); extern int iwl4965_get_temperature(const struct iwl_priv *priv); extern void iwl3945_post_associate(struct iwl_priv *priv); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c index 115d3ea1142f..e43493685271 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -200,57 +200,26 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) /* Set initial sensitivity parameters */ /* Set initial calibration set */ - priv->hw_params.sens = &iwl5000_sensitivity; - priv->hw_params.calib_init_cfg = - BIT(IWL_CALIB_XTAL) | - BIT(IWL_CALIB_LO) | - BIT(IWL_CALIB_TX_IQ) | - BIT(IWL_CALIB_TX_IQ_PERD) | - BIT(IWL_CALIB_BASE_BAND); - - return 0; -} - -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->mod_params->num_of_queues; - - priv->hw_params.max_txq_num = priv->cfg->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 * - sizeof(struct iwlagn_scd_bc_tbl); - priv->hw_params.tfd_size = sizeof(struct iwl_tfd); - priv->hw_params.max_stations = IWL5000_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; - - priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; - priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; - - priv->hw_params.max_bsm_size = 0; - priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | - BIT(IEEE80211_BAND_5GHZ); - priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; - - priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); - 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); - - /* Set initial sensitivity parameters */ - /* Set initial calibration set */ - priv->hw_params.sens = &iwl5150_sensitivity; - priv->hw_params.calib_init_cfg = - BIT(IWL_CALIB_DC) | - BIT(IWL_CALIB_LO) | - BIT(IWL_CALIB_TX_IQ) | - BIT(IWL_CALIB_BASE_BAND); + switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { + case CSR_HW_REV_TYPE_5150: + priv->hw_params.sens = &iwl5150_sensitivity; + priv->hw_params.calib_init_cfg = + BIT(IWL_CALIB_DC) | + BIT(IWL_CALIB_LO) | + BIT(IWL_CALIB_TX_IQ) | + BIT(IWL_CALIB_BASE_BAND); + + break; + default: + priv->hw_params.sens = &iwl5000_sensitivity; + priv->hw_params.calib_init_cfg = + BIT(IWL_CALIB_XTAL) | + BIT(IWL_CALIB_LO) | + BIT(IWL_CALIB_TX_IQ) | + BIT(IWL_CALIB_TX_IQ_PERD) | + BIT(IWL_CALIB_BASE_BAND); + break; + } return 0; } @@ -363,7 +332,7 @@ static struct iwl_lib_ops iwl5000_lib = { }; static struct iwl_lib_ops iwl5150_lib = { - .set_hw_params = iwl5150_hw_set_hw_params, + .set_hw_params = iwl5000_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, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c index 7acef703253a..7da23d3ff7b6 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -176,56 +176,24 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) /* Set initial sensitivity parameters */ /* Set initial calibration set */ priv->hw_params.sens = &iwl6000_sensitivity; - priv->hw_params.calib_init_cfg = - BIT(IWL_CALIB_XTAL) | - BIT(IWL_CALIB_LO) | - BIT(IWL_CALIB_TX_IQ) | - BIT(IWL_CALIB_BASE_BAND); - - return 0; -} - -static int iwl6050_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->mod_params->num_of_queues; - - priv->hw_params.max_txq_num = priv->cfg->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 * - sizeof(struct iwlagn_scd_bc_tbl); - priv->hw_params.tfd_size = sizeof(struct iwl_tfd); - priv->hw_params.max_stations = IWL5000_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; - - priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; - priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; - - priv->hw_params.max_bsm_size = 0; - priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | - BIT(IEEE80211_BAND_5GHZ); - priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; - - priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); - 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); - - /* Set initial sensitivity parameters */ - /* Set initial calibration set */ - priv->hw_params.sens = &iwl6000_sensitivity; - priv->hw_params.calib_init_cfg = - BIT(IWL_CALIB_XTAL) | - BIT(IWL_CALIB_DC) | - BIT(IWL_CALIB_LO) | - BIT(IWL_CALIB_TX_IQ) | - BIT(IWL_CALIB_BASE_BAND); + switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { + case CSR_HW_REV_TYPE_6x50: + priv->hw_params.calib_init_cfg = + BIT(IWL_CALIB_XTAL) | + BIT(IWL_CALIB_DC) | + BIT(IWL_CALIB_LO) | + BIT(IWL_CALIB_TX_IQ) | + BIT(IWL_CALIB_BASE_BAND); + + break; + default: + priv->hw_params.calib_init_cfg = + BIT(IWL_CALIB_XTAL) | + BIT(IWL_CALIB_LO) | + BIT(IWL_CALIB_TX_IQ) | + BIT(IWL_CALIB_BASE_BAND); + break; + } return 0; } @@ -336,7 +304,7 @@ static const struct iwl_ops iwl6000_ops = { }; static struct iwl_lib_ops iwl6050_lib = { - .set_hw_params = iwl6050_hw_set_hw_params, + .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, @@ -500,6 +468,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = { .pa_type = IWL_PA_INTERNAL, .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, + .ht_greenfield_support = true, .led_compensation = 51, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .supports_idle = true, @@ -532,6 +501,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = { .pa_type = IWL_PA_INTERNAL, .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, + .ht_greenfield_support = true, .led_compensation = 51, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .supports_idle = true, @@ -598,6 +568,7 @@ struct iwl_cfg iwl6050_2abg_cfg = { .pa_type = IWL_PA_SYSTEM, .max_ll_items = OTP_MAX_LL_ITEMS_6x50, .shadow_ram_support = true, + .ht_greenfield_support = true, .led_compensation = 51, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .supports_idle = true, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index a27347425968..4bd0aecc7713 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1395,29 +1395,16 @@ void iwlagn_request_scan(struct iwl_priv *priv) rate = IWL_RATE_1M_PLCP; rate_flags = RATE_MCS_CCK_MSK; } - scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED; + scan->good_CRC_th = 0; 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. + * 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_NEVER; + scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0; break; default: IWL_WARN(priv, "Invalid scan band count\n"); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index bfcac5608d87..0e6161d7c764 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -868,14 +868,14 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index); rs_collect_tx_data(curr_tbl, rs_index, - info->status.ampdu_len, - info->status.ampdu_ack_len); + info->status.ampdu_ack_len, + info->status.ampdu_ack_map); /* Update success/fail counts if not searching for new mode */ if (lq_sta->stay_in_tbl) { - lq_sta->total_success += info->status.ampdu_ack_len; - lq_sta->total_failed += (info->status.ampdu_len - - info->status.ampdu_ack_len); + lq_sta->total_success += info->status.ampdu_ack_map; + lq_sta->total_failed += (info->status.ampdu_ack_len - + info->status.ampdu_ack_map); } } else { /* @@ -2078,12 +2078,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, } /* Else we have enough samples; calculate estimate of * actual average throughput */ - if (window->average_tpt != ((window->success_ratio * - tbl->expected_tpt[index] + 64) / 128)) { - IWL_ERR(priv, "expected_tpt should have been calculated by now\n"); - window->average_tpt = ((window->success_ratio * - tbl->expected_tpt[index] + 64) / 128); - } + + /* Sanity-check TPT calculations */ + BUG_ON(window->average_tpt != ((window->success_ratio * + tbl->expected_tpt[index] + 64) / 128)); /* If we are searching for better modulation mode, check success. */ if (lq_sta->search_better_tbl && diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index c2a5c85542bf..11661fa28f21 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -83,15 +83,6 @@ 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))) - return tid_to_ac[tid]; - - /* no support for TIDs 8-15 yet */ - return -EINVAL; -} - static inline int get_fifo_from_tid(u16 tid) { if (likely(tid < ARRAY_SIZE(tid_to_ac))) @@ -1000,7 +991,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn) tid_data = &priv->stations[sta_id].tid[tid]; *ssn = SEQ_TO_SN(tid_data->seq_number); tid_data->agg.txq_id = txq_id; - priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(get_ac_from_tid(tid), txq_id); + priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(tx_fifo, txq_id); spin_unlock_irqrestore(&priv->sta_lock, flags); ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo, @@ -1233,9 +1224,8 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, memset(&info->status, 0, sizeof(info->status)); info->flags |= IEEE80211_TX_STAT_ACK; info->flags |= IEEE80211_TX_STAT_AMPDU; - info->status.ampdu_ack_len = successes; - info->status.ampdu_ack_map = bitmap; - info->status.ampdu_len = agg->frame_count; + info->status.ampdu_ack_map = successes; + info->status.ampdu_ack_len = agg->frame_count; iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c index a672d3379cfd..00344d64635c 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2654,6 +2654,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv) /* Tell mac80211 our characteristics */ hw->flags = IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_NOISE_DBM | IEEE80211_HW_AMPDU_AGGREGATION | IEEE80211_HW_SPECTRUM_MGMT; @@ -3001,6 +3002,18 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, return 0; } +static int iwl_mac_get_stats(struct ieee80211_hw *hw, + struct ieee80211_low_level_stats *stats) +{ + struct iwl_priv *priv = hw->priv; + + priv = hw->priv; + IWL_DEBUG_MAC80211(priv, "enter\n"); + IWL_DEBUG_MAC80211(priv, "leave\n"); + + return 0; +} + static void iwl_mac_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum sta_notify_cmd cmd, @@ -3378,6 +3391,7 @@ static struct ieee80211_ops iwl_hw_ops = { .configure_filter = iwl_configure_filter, .set_key = iwl_mac_set_key, .update_tkip_key = iwl_mac_update_tkip_key, + .get_stats = iwl_mac_get_stats, .conf_tx = iwl_mac_conf_tx, .reset_tsf = iwl_mac_reset_tsf, .bss_info_changed = iwl_bss_info_changed, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h b/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h index 0086019b7a15..67c723cc32d2 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2663,9 +2663,7 @@ struct iwl_ssid_ie { #define PROBE_OPTION_MAX_3945 4 #define PROBE_OPTION_MAX 20 #define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF) -#define IWL_GOOD_CRC_TH_DISABLED 0 -#define IWL_GOOD_CRC_TH_DEFAULT cpu_to_le16(1) -#define IWL_GOOD_CRC_TH_NEVER cpu_to_le16(0xffff) +#define IWL_GOOD_CRC_TH cpu_to_le16(1) #define IWL_MAX_SCAN_SIZE 1024 #define IWL_MAX_CMD_SIZE 4096 #define IWL_MAX_PROBE_REQUEST 200 diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c index 4cdf4d3a9ddb..56a9f1741419 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2117,6 +2117,10 @@ EXPORT_SYMBOL(iwl_mac_remove_interface); /** * iwl_mac_config - mac80211 config callback + * + * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to + * be set inappropriately and the driver currently sets the hardware up to + * use it whenever needed. */ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) { @@ -2931,12 +2935,6 @@ int iwl_pci_resume(struct pci_dev *pdev) struct iwl_priv *priv = pci_get_drvdata(pdev); int ret; - /* - * We disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state. - */ - pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); - pci_set_power_state(pdev, PCI_D0); ret = pci_enable_device(pdev); if (ret) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h index 727360944859..a0cc11ecbe93 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h @@ -512,9 +512,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); -int iwl_mac_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct cfg80211_scan_request *req); +int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); void iwl_internal_short_hw_scan(struct iwl_priv *priv); int iwl_force_reset(struct iwl_priv *priv, int mode); u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 4aabb542fcbe..61faf2dd7fbe 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1059,8 +1059,10 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, size_t count, loff_t *ppos) { struct iwl_priv *priv = file->private_data; - return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file, - user_buf, count, ppos); + if (priv->cfg->ops->lib->debugfs_ops.rx_stats_read) + return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file, + user_buf, count, ppos); + return 0; } static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, @@ -1068,8 +1070,10 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, size_t count, loff_t *ppos) { struct iwl_priv *priv = file->private_data; - return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file, - user_buf, count, ppos); + if (priv->cfg->ops->lib->debugfs_ops.tx_stats_read) + return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file, + user_buf, count, ppos); + return 0; } static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, @@ -1077,8 +1081,10 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, size_t count, loff_t *ppos) { struct iwl_priv *priv = file->private_data; - return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file, - user_buf, count, ppos); + if (priv->cfg->ops->lib->debugfs_ops.general_stats_read) + return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file, + user_buf, count, ppos); + return 0; } static ssize_t iwl_dbgfs_sensitivity_read(struct file *file, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h b/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h index 58c69a5798d4..bdc60aae75ec 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1202,11 +1202,6 @@ struct iwl_priv { struct delayed_work rfkill_poll; struct iwl3945_notif_statistics statistics; -#ifdef CONFIG_IWLWIFI_DEBUG - struct iwl3945_notif_statistics accum_statistics; - struct iwl3945_notif_statistics delta_statistics; - struct iwl3945_notif_statistics max_delta; -#endif u32 sta_supp_rates; int last_rx_rssi; /* From Rx packet statistics */ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c b/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c index d12fd5553846..f4b897804a80 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -313,8 +313,7 @@ static int iwl_scan_initiate(struct iwl_priv *priv) } int iwl_mac_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct cfg80211_scan_request *req) + struct cfg80211_scan_request *req) { struct iwl_priv *priv = hw->priv; int ret; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c index c7e1d7d09e02..a41ba72ceb00 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -957,7 +957,7 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv) * statistics request from the host as well as for the periodic * statistics notifications (after received beacons) from the uCode. */ - priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_reply_statistics; + priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics; priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics; iwl_setup_rx_scan_handlers(priv); @@ -2939,8 +2939,7 @@ void iwl3945_request_scan(struct iwl_priv *priv) * 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; + scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0; band = IEEE80211_BAND_5GHZ; break; default: @@ -3874,6 +3873,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) /* Tell mac80211 our characteristics */ hw->flags = IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_NOISE_DBM | IEEE80211_HW_SPECTRUM_MGMT; if (!priv->cfg->broken_powersave) diff --git a/trunk/drivers/net/wireless/iwmc3200wifi/bus.h b/trunk/drivers/net/wireless/iwmc3200wifi/bus.h index 62edd5888a7b..836663eec257 100644 --- a/trunk/drivers/net/wireless/iwmc3200wifi/bus.h +++ b/trunk/drivers/net/wireless/iwmc3200wifi/bus.h @@ -31,7 +31,7 @@ struct iwm_if_ops { int (*disable)(struct iwm_priv *iwm); int (*send_chunk)(struct iwm_priv *iwm, u8* buf, int count); - void (*debugfs_init)(struct iwm_priv *iwm, struct dentry *parent_dir); + int (*debugfs_init)(struct iwm_priv *iwm, struct dentry *parent_dir); void (*debugfs_exit)(struct iwm_priv *iwm); const char *umac_name; diff --git a/trunk/drivers/net/wireless/iwmc3200wifi/debug.h b/trunk/drivers/net/wireless/iwmc3200wifi/debug.h index a0c13a49ab3c..e35c9b693d1f 100644 --- a/trunk/drivers/net/wireless/iwmc3200wifi/debug.h +++ b/trunk/drivers/net/wireless/iwmc3200wifi/debug.h @@ -113,10 +113,13 @@ struct iwm_debugfs { }; #ifdef CONFIG_IWM_DEBUG -void iwm_debugfs_init(struct iwm_priv *iwm); +int iwm_debugfs_init(struct iwm_priv *iwm); void iwm_debugfs_exit(struct iwm_priv *iwm); #else -static inline void iwm_debugfs_init(struct iwm_priv *iwm) {} +static inline int iwm_debugfs_init(struct iwm_priv *iwm) +{ + return 0; +} static inline void iwm_debugfs_exit(struct iwm_priv *iwm) {} #endif diff --git a/trunk/drivers/net/wireless/iwmc3200wifi/debugfs.c b/trunk/drivers/net/wireless/iwmc3200wifi/debugfs.c index 53b0b7711f02..724441368a18 100644 --- a/trunk/drivers/net/wireless/iwmc3200wifi/debugfs.c +++ b/trunk/drivers/net/wireless/iwmc3200wifi/debugfs.c @@ -48,11 +48,12 @@ static struct { #define add_dbg_module(dbg, name, id, initlevel) \ do { \ + struct dentry *d; \ dbg.dbg_module[id] = (initlevel); \ - dbg.dbg_module_dentries[id] = \ - debugfs_create_x8(name, 0600, \ - dbg.dbgdir, \ - &(dbg.dbg_module[id])); \ + d = debugfs_create_x8(name, 0600, dbg.dbgdir, \ + &(dbg.dbg_module[id])); \ + if (!IS_ERR(d)) \ + dbg.dbg_module_dentries[id] = d; \ } while (0) static int iwm_debugfs_u32_read(void *data, u64 *val) @@ -422,29 +423,89 @@ static const struct file_operations iwm_debugfs_fw_err_fops = { .read = iwm_debugfs_fw_err_read, }; -void iwm_debugfs_init(struct iwm_priv *iwm) +int iwm_debugfs_init(struct iwm_priv *iwm) { - int i; + int i, result; + char devdir[16]; iwm->dbg.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL); - iwm->dbg.devdir = debugfs_create_dir(wiphy_name(iwm_to_wiphy(iwm)), - iwm->dbg.rootdir); + result = PTR_ERR(iwm->dbg.rootdir); + if (!result || IS_ERR(iwm->dbg.rootdir)) { + if (result == -ENODEV) { + IWM_ERR(iwm, "DebugFS (CONFIG_DEBUG_FS) not " + "enabled in kernel config\n"); + result = 0; /* No debugfs support */ + } + IWM_ERR(iwm, "Couldn't create rootdir: %d\n", result); + goto error; + } + + snprintf(devdir, sizeof(devdir), "%s", wiphy_name(iwm_to_wiphy(iwm))); + + iwm->dbg.devdir = debugfs_create_dir(devdir, iwm->dbg.rootdir); + result = PTR_ERR(iwm->dbg.devdir); + if (IS_ERR(iwm->dbg.devdir) && (result != -ENODEV)) { + IWM_ERR(iwm, "Couldn't create devdir: %d\n", result); + goto error; + } + iwm->dbg.dbgdir = debugfs_create_dir("debug", iwm->dbg.devdir); + result = PTR_ERR(iwm->dbg.dbgdir); + if (IS_ERR(iwm->dbg.dbgdir) && (result != -ENODEV)) { + IWM_ERR(iwm, "Couldn't create dbgdir: %d\n", result); + goto error; + } + iwm->dbg.rxdir = debugfs_create_dir("rx", iwm->dbg.devdir); + result = PTR_ERR(iwm->dbg.rxdir); + if (IS_ERR(iwm->dbg.rxdir) && (result != -ENODEV)) { + IWM_ERR(iwm, "Couldn't create rx dir: %d\n", result); + goto error; + } + iwm->dbg.txdir = debugfs_create_dir("tx", iwm->dbg.devdir); + result = PTR_ERR(iwm->dbg.txdir); + if (IS_ERR(iwm->dbg.txdir) && (result != -ENODEV)) { + IWM_ERR(iwm, "Couldn't create tx dir: %d\n", result); + goto error; + } + iwm->dbg.busdir = debugfs_create_dir("bus", iwm->dbg.devdir); - if (iwm->bus_ops->debugfs_init) - iwm->bus_ops->debugfs_init(iwm, iwm->dbg.busdir); + result = PTR_ERR(iwm->dbg.busdir); + if (IS_ERR(iwm->dbg.busdir) && (result != -ENODEV)) { + IWM_ERR(iwm, "Couldn't create bus dir: %d\n", result); + goto error; + } + + if (iwm->bus_ops->debugfs_init) { + result = iwm->bus_ops->debugfs_init(iwm, iwm->dbg.busdir); + if (result < 0) { + IWM_ERR(iwm, "Couldn't create bus entry: %d\n", result); + goto error; + } + } + iwm->dbg.dbg_level = IWM_DL_NONE; iwm->dbg.dbg_level_dentry = debugfs_create_file("level", 0200, iwm->dbg.dbgdir, iwm, &fops_iwm_dbg_level); + result = PTR_ERR(iwm->dbg.dbg_level_dentry); + if (IS_ERR(iwm->dbg.dbg_level_dentry) && (result != -ENODEV)) { + IWM_ERR(iwm, "Couldn't create dbg_level: %d\n", result); + goto error; + } + iwm->dbg.dbg_modules = IWM_DM_DEFAULT; iwm->dbg.dbg_modules_dentry = debugfs_create_file("modules", 0200, iwm->dbg.dbgdir, iwm, &fops_iwm_dbg_modules); + result = PTR_ERR(iwm->dbg.dbg_modules_dentry); + if (IS_ERR(iwm->dbg.dbg_modules_dentry) && (result != -ENODEV)) { + IWM_ERR(iwm, "Couldn't create dbg_modules: %d\n", result); + goto error; + } for (i = 0; i < __IWM_DM_NR; i++) add_dbg_module(iwm->dbg, iwm_debug_module[i].name, @@ -453,15 +514,44 @@ void iwm_debugfs_init(struct iwm_priv *iwm) iwm->dbg.txq_dentry = debugfs_create_file("queues", 0200, iwm->dbg.txdir, iwm, &iwm_debugfs_txq_fops); + result = PTR_ERR(iwm->dbg.txq_dentry); + if (IS_ERR(iwm->dbg.txq_dentry) && (result != -ENODEV)) { + IWM_ERR(iwm, "Couldn't create tx queue: %d\n", result); + goto error; + } + iwm->dbg.tx_credit_dentry = debugfs_create_file("credits", 0200, iwm->dbg.txdir, iwm, &iwm_debugfs_tx_credit_fops); + result = PTR_ERR(iwm->dbg.tx_credit_dentry); + if (IS_ERR(iwm->dbg.tx_credit_dentry) && (result != -ENODEV)) { + IWM_ERR(iwm, "Couldn't create tx credit: %d\n", result); + goto error; + } + iwm->dbg.rx_ticket_dentry = debugfs_create_file("tickets", 0200, iwm->dbg.rxdir, iwm, &iwm_debugfs_rx_ticket_fops); + result = PTR_ERR(iwm->dbg.rx_ticket_dentry); + if (IS_ERR(iwm->dbg.rx_ticket_dentry) && (result != -ENODEV)) { + IWM_ERR(iwm, "Couldn't create rx ticket: %d\n", result); + goto error; + } + iwm->dbg.fw_err_dentry = debugfs_create_file("last_fw_err", 0200, iwm->dbg.dbgdir, iwm, &iwm_debugfs_fw_err_fops); + result = PTR_ERR(iwm->dbg.fw_err_dentry); + if (IS_ERR(iwm->dbg.fw_err_dentry) && (result != -ENODEV)) { + IWM_ERR(iwm, "Couldn't create last FW err: %d\n", result); + goto error; + } + + + return 0; + + error: + return result; } void iwm_debugfs_exit(struct iwm_priv *iwm) diff --git a/trunk/drivers/net/wireless/iwmc3200wifi/sdio.c b/trunk/drivers/net/wireless/iwmc3200wifi/sdio.c index 1acea37f39f8..1eafd6dec3fd 100644 --- a/trunk/drivers/net/wireless/iwmc3200wifi/sdio.c +++ b/trunk/drivers/net/wireless/iwmc3200wifi/sdio.c @@ -366,13 +366,21 @@ static const struct file_operations iwm_debugfs_sdio_fops = { .read = iwm_debugfs_sdio_read, }; -static void if_sdio_debugfs_init(struct iwm_priv *iwm, struct dentry *parent_dir) +static int if_sdio_debugfs_init(struct iwm_priv *iwm, struct dentry *parent_dir) { + int result; struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm); hw->cccr_dentry = debugfs_create_file("cccr", 0200, parent_dir, iwm, &iwm_debugfs_sdio_fops); + result = PTR_ERR(hw->cccr_dentry); + if (IS_ERR(hw->cccr_dentry) && (result != -ENODEV)) { + IWM_ERR(iwm, "Couldn't create CCCR entry: %d\n", result); + return result; + } + + return 0; } static void if_sdio_debugfs_exit(struct iwm_priv *iwm) @@ -432,7 +440,11 @@ static int iwm_sdio_probe(struct sdio_func *func, hw = iwm_private(iwm); hw->iwm = iwm; - iwm_debugfs_init(iwm); + ret = iwm_debugfs_init(iwm); + if (ret < 0) { + IWM_ERR(iwm, "Debugfs registration failed\n"); + goto if_free; + } sdio_set_drvdata(func, hw); @@ -461,6 +473,7 @@ static int iwm_sdio_probe(struct sdio_func *func, destroy_workqueue(hw->isr_wq); debugfs_exit: iwm_debugfs_exit(iwm); + if_free: iwm_if_free(iwm); return ret; } diff --git a/trunk/drivers/net/wireless/libertas/if_sdio.c b/trunk/drivers/net/wireless/libertas/if_sdio.c index 64dd345d30f5..13dfeda742bc 100644 --- a/trunk/drivers/net/wireless/libertas/if_sdio.c +++ b/trunk/drivers/net/wireless/libertas/if_sdio.c @@ -324,9 +324,7 @@ static int if_sdio_wait_status(struct if_sdio_card *card, const u8 condition) timeout = jiffies + HZ; while (1) { status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); - if (ret) - return ret; - if ((status & condition) == condition) + if (ret || (status & condition)) break; if (time_after(jiffies, timeout)) return -ETIMEDOUT; diff --git a/trunk/drivers/net/wireless/libertas_tf/cmd.c b/trunk/drivers/net/wireless/libertas_tf/cmd.c index 8945afd6ce3e..b620daf59ef7 100644 --- a/trunk/drivers/net/wireless/libertas_tf/cmd.c +++ b/trunk/drivers/net/wireless/libertas_tf/cmd.c @@ -7,8 +7,6 @@ * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include "libertas_tf.h" @@ -84,8 +82,6 @@ int lbtf_update_hw_spec(struct lbtf_private *priv) int ret = -1; u32 i; - lbtf_deb_enter(LBTF_DEB_CMD); - memset(&cmd, 0, sizeof(cmd)); cmd.hdr.size = cpu_to_le16(sizeof(cmd)); memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN); @@ -108,8 +104,6 @@ int lbtf_update_hw_spec(struct lbtf_private *priv) priv->fwrelease >> 8 & 0xff, priv->fwrelease & 0xff, priv->fwcapinfo); - lbtf_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n", - cmd.hwifversion, cmd.version); /* Clamp region code to 8-bit since FW spec indicates that it should * only ever be 8-bit, even though the field size is 16-bit. Some @@ -124,10 +118,8 @@ int lbtf_update_hw_spec(struct lbtf_private *priv) } /* if it's unidentified region code, use the default (USA) */ - if (i >= MRVDRV_MAX_REGION_CODE) { + if (i >= MRVDRV_MAX_REGION_CODE) priv->regioncode = 0x10; - pr_info("unidentified region code; using the default (USA)\n"); - } if (priv->current_addr[0] == 0xff) memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN); @@ -136,7 +128,6 @@ int lbtf_update_hw_spec(struct lbtf_private *priv) lbtf_geo_init(priv); out: - lbtf_deb_leave(LBTF_DEB_CMD); return ret; } @@ -150,18 +141,13 @@ int lbtf_update_hw_spec(struct lbtf_private *priv) */ int lbtf_set_channel(struct lbtf_private *priv, u8 channel) { - int ret = 0; struct cmd_ds_802_11_rf_channel cmd; - lbtf_deb_enter(LBTF_DEB_CMD); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET); cmd.channel = cpu_to_le16(channel); - ret = lbtf_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd); - lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", ret); - return ret; + return lbtf_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd); } int lbtf_beacon_set(struct lbtf_private *priv, struct sk_buff *beacon) @@ -169,28 +155,20 @@ int lbtf_beacon_set(struct lbtf_private *priv, struct sk_buff *beacon) struct cmd_ds_802_11_beacon_set cmd; int size; - lbtf_deb_enter(LBTF_DEB_CMD); - - if (beacon->len > MRVL_MAX_BCN_SIZE) { - lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", -1); + if (beacon->len > MRVL_MAX_BCN_SIZE) return -1; - } size = sizeof(cmd) - sizeof(cmd.beacon) + beacon->len; cmd.hdr.size = cpu_to_le16(size); cmd.len = cpu_to_le16(beacon->len); memcpy(cmd.beacon, (u8 *) beacon->data, beacon->len); lbtf_cmd_async(priv, CMD_802_11_BEACON_SET, &cmd.hdr, size); - - lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", 0); return 0; } int lbtf_beacon_ctrl(struct lbtf_private *priv, bool beacon_enable, - int beacon_int) -{ + int beacon_int) { struct cmd_ds_802_11_beacon_control cmd; - lbtf_deb_enter(LBTF_DEB_CMD); cmd.hdr.size = cpu_to_le16(sizeof(cmd)); cmd.action = cpu_to_le16(CMD_ACT_SET); @@ -198,8 +176,6 @@ int lbtf_beacon_ctrl(struct lbtf_private *priv, bool beacon_enable, cmd.beacon_period = cpu_to_le16(beacon_int); lbtf_cmd_async(priv, CMD_802_11_BEACON_CTRL, &cmd.hdr, sizeof(cmd)); - - lbtf_deb_leave(LBTF_DEB_CMD); return 0; } @@ -207,28 +183,17 @@ static void lbtf_queue_cmd(struct lbtf_private *priv, struct cmd_ctrl_node *cmdnode) { unsigned long flags; - lbtf_deb_enter(LBTF_DEB_HOST); - if (!cmdnode) { - lbtf_deb_host("QUEUE_CMD: cmdnode is NULL\n"); - goto qcmd_done; - } + if (!cmdnode) + return; - if (!cmdnode->cmdbuf->size) { - lbtf_deb_host("DNLD_CMD: cmd size is zero\n"); - goto qcmd_done; - } + if (!cmdnode->cmdbuf->size) + return; cmdnode->result = 0; spin_lock_irqsave(&priv->driver_lock, flags); list_add_tail(&cmdnode->list, &priv->cmdpendingq); spin_unlock_irqrestore(&priv->driver_lock, flags); - - lbtf_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n", - le16_to_cpu(cmdnode->cmdbuf->command)); - -qcmd_done: - lbtf_deb_leave(LBTF_DEB_HOST); } static void lbtf_submit_command(struct lbtf_private *priv, @@ -241,33 +206,22 @@ static void lbtf_submit_command(struct lbtf_private *priv, int timeo = 5 * HZ; int ret; - lbtf_deb_enter(LBTF_DEB_HOST); - cmd = cmdnode->cmdbuf; spin_lock_irqsave(&priv->driver_lock, flags); priv->cur_cmd = cmdnode; cmdsize = le16_to_cpu(cmd->size); command = le16_to_cpu(cmd->command); - - lbtf_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n", - command, le16_to_cpu(cmd->seqnum), cmdsize); - lbtf_deb_hex(LBTF_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize); - ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize); spin_unlock_irqrestore(&priv->driver_lock, flags); - if (ret) { - pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret); + if (ret) /* Let the timer kick in and retry, and potentially reset the whole thing if the condition persists */ timeo = HZ; - } /* Setup the timer after transmit command */ mod_timer(&priv->command_timer, jiffies + timeo); - - lbtf_deb_leave(LBTF_DEB_HOST); } /** @@ -277,10 +231,8 @@ static void lbtf_submit_command(struct lbtf_private *priv, static void __lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv, struct cmd_ctrl_node *cmdnode) { - lbtf_deb_enter(LBTF_DEB_HOST); - if (!cmdnode) - goto cl_ins_out; + return; cmdnode->callback = NULL; cmdnode->callback_arg = 0; @@ -288,9 +240,6 @@ static void __lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv, memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE); list_add_tail(&cmdnode->list, &priv->cmdfreeq); - -cl_ins_out: - lbtf_deb_leave(LBTF_DEB_HOST); } static void lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv, @@ -319,41 +268,29 @@ int lbtf_cmd_set_mac_multicast_addr(struct lbtf_private *priv) { struct cmd_ds_mac_multicast_addr cmd; - lbtf_deb_enter(LBTF_DEB_CMD); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); cmd.action = cpu_to_le16(CMD_ACT_SET); cmd.nr_of_adrs = cpu_to_le16((u16) priv->nr_of_multicastmacaddr); - - lbtf_deb_cmd("MULTICAST_ADR: setting %d addresses\n", cmd.nr_of_adrs); - memcpy(cmd.maclist, priv->multicastlist, priv->nr_of_multicastmacaddr * ETH_ALEN); lbtf_cmd_async(priv, CMD_MAC_MULTICAST_ADR, &cmd.hdr, sizeof(cmd)); - - lbtf_deb_leave(LBTF_DEB_CMD); return 0; } void lbtf_set_mode(struct lbtf_private *priv, enum lbtf_mode mode) { struct cmd_ds_set_mode cmd; - lbtf_deb_enter(LBTF_DEB_WEXT); cmd.hdr.size = cpu_to_le16(sizeof(cmd)); cmd.mode = cpu_to_le16(mode); - lbtf_deb_wext("Switching to mode: 0x%x\n", mode); lbtf_cmd_async(priv, CMD_802_11_SET_MODE, &cmd.hdr, sizeof(cmd)); - - lbtf_deb_leave(LBTF_DEB_WEXT); } void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid) { struct cmd_ds_set_bssid cmd; - lbtf_deb_enter(LBTF_DEB_CMD); cmd.hdr.size = cpu_to_le16(sizeof(cmd)); cmd.activate = activate ? 1 : 0; @@ -361,13 +298,11 @@ void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid) memcpy(cmd.bssid, bssid, ETH_ALEN); lbtf_cmd_async(priv, CMD_802_11_SET_BSSID, &cmd.hdr, sizeof(cmd)); - lbtf_deb_leave(LBTF_DEB_CMD); } int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr) { struct cmd_ds_802_11_mac_address cmd; - lbtf_deb_enter(LBTF_DEB_CMD); cmd.hdr.size = cpu_to_le16(sizeof(cmd)); cmd.action = cpu_to_le16(CMD_ACT_SET); @@ -375,7 +310,6 @@ int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr) memcpy(cmd.macadd, mac_addr, ETH_ALEN); lbtf_cmd_async(priv, CMD_802_11_MAC_ADDRESS, &cmd.hdr, sizeof(cmd)); - lbtf_deb_leave(LBTF_DEB_CMD); return 0; } @@ -384,8 +318,6 @@ int lbtf_set_radio_control(struct lbtf_private *priv) int ret = 0; struct cmd_ds_802_11_radio_control cmd; - lbtf_deb_enter(LBTF_DEB_CMD); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); cmd.action = cpu_to_le16(CMD_ACT_SET); @@ -409,28 +341,19 @@ int lbtf_set_radio_control(struct lbtf_private *priv) else cmd.control &= cpu_to_le16(~TURN_ON_RF); - lbtf_deb_cmd("RADIO_SET: radio %d, preamble %d\n", priv->radioon, - priv->preamble); - ret = lbtf_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd); - - lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", ret); return ret; } void lbtf_set_mac_control(struct lbtf_private *priv) { struct cmd_ds_mac_control cmd; - lbtf_deb_enter(LBTF_DEB_CMD); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); cmd.action = cpu_to_le16(priv->mac_control); cmd.reserved = 0; lbtf_cmd_async(priv, CMD_MAC_CONTROL, &cmd.hdr, sizeof(cmd)); - - lbtf_deb_leave(LBTF_DEB_CMD); } /** @@ -442,43 +365,29 @@ void lbtf_set_mac_control(struct lbtf_private *priv) */ int lbtf_allocate_cmd_buffer(struct lbtf_private *priv) { - int ret = 0; u32 bufsize; u32 i; struct cmd_ctrl_node *cmdarray; - lbtf_deb_enter(LBTF_DEB_HOST); - /* Allocate and initialize the command array */ bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS; cmdarray = kzalloc(bufsize, GFP_KERNEL); - if (!cmdarray) { - lbtf_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n"); - ret = -1; - goto done; - } + if (!cmdarray) + return -1; priv->cmd_array = cmdarray; /* Allocate and initialize each command buffer in the command array */ for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL); - if (!cmdarray[i].cmdbuf) { - lbtf_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n"); - ret = -1; - goto done; - } + if (!cmdarray[i].cmdbuf) + return -1; } for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { init_waitqueue_head(&cmdarray[i].cmdwait_q); lbtf_cleanup_and_insert_cmd(priv, &cmdarray[i]); } - - ret = 0; - -done: - lbtf_deb_leave_args(LBTF_DEB_HOST, "ret %d", ret); - return ret; + return 0; } /** @@ -493,13 +402,9 @@ int lbtf_free_cmd_buffer(struct lbtf_private *priv) struct cmd_ctrl_node *cmdarray; unsigned int i; - lbtf_deb_enter(LBTF_DEB_HOST); - /* need to check if cmd array is allocated or not */ - if (priv->cmd_array == NULL) { - lbtf_deb_host("FREE_CMD_BUF: cmd_array is NULL\n"); - goto done; - } + if (priv->cmd_array == NULL) + return 0; cmdarray = priv->cmd_array; @@ -513,8 +418,6 @@ int lbtf_free_cmd_buffer(struct lbtf_private *priv) kfree(priv->cmd_array); priv->cmd_array = NULL; -done: - lbtf_deb_leave(LBTF_DEB_HOST); return 0; } @@ -530,8 +433,6 @@ static struct cmd_ctrl_node *lbtf_get_cmd_ctrl_node(struct lbtf_private *priv) struct cmd_ctrl_node *tempnode; unsigned long flags; - lbtf_deb_enter(LBTF_DEB_HOST); - if (!priv) return NULL; @@ -541,14 +442,11 @@ static struct cmd_ctrl_node *lbtf_get_cmd_ctrl_node(struct lbtf_private *priv) tempnode = list_first_entry(&priv->cmdfreeq, struct cmd_ctrl_node, list); list_del(&tempnode->list); - } else { - lbtf_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n"); + } else tempnode = NULL; - } spin_unlock_irqrestore(&priv->driver_lock, flags); - lbtf_deb_leave(LBTF_DEB_HOST); return tempnode; } @@ -564,20 +462,16 @@ int lbtf_execute_next_command(struct lbtf_private *priv) struct cmd_ctrl_node *cmdnode = NULL; struct cmd_header *cmd; unsigned long flags; - int ret = 0; - /* Debug group is lbtf_deb_THREAD and not lbtf_deb_HOST, because the + /* Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the * only caller to us is lbtf_thread() and we get even when a * data packet is received */ - lbtf_deb_enter(LBTF_DEB_THREAD); spin_lock_irqsave(&priv->driver_lock, flags); if (priv->cur_cmd) { - pr_alert("EXEC_NEXT_CMD: already processing command!\n"); spin_unlock_irqrestore(&priv->driver_lock, flags); - ret = -1; - goto done; + return -1; } if (!list_empty(&priv->cmdpendingq)) { @@ -589,17 +483,11 @@ int lbtf_execute_next_command(struct lbtf_private *priv) cmd = cmdnode->cmdbuf; list_del(&cmdnode->list); - lbtf_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n", - le16_to_cpu(cmd->command)); spin_unlock_irqrestore(&priv->driver_lock, flags); lbtf_submit_command(priv, cmdnode); } else spin_unlock_irqrestore(&priv->driver_lock, flags); - - ret = 0; -done: - lbtf_deb_leave(LBTF_DEB_THREAD); - return ret; + return 0; } static struct cmd_ctrl_node *__lbtf_cmd_async(struct lbtf_private *priv, @@ -610,22 +498,14 @@ static struct cmd_ctrl_node *__lbtf_cmd_async(struct lbtf_private *priv, { struct cmd_ctrl_node *cmdnode; - lbtf_deb_enter(LBTF_DEB_HOST); - - if (priv->surpriseremoved) { - lbtf_deb_host("PREP_CMD: card removed\n"); - cmdnode = ERR_PTR(-ENOENT); - goto done; - } + if (priv->surpriseremoved) + return ERR_PTR(-ENOENT); cmdnode = lbtf_get_cmd_ctrl_node(priv); if (cmdnode == NULL) { - lbtf_deb_host("PREP_CMD: cmdnode is NULL\n"); - /* Wake up main thread to execute next command */ queue_work(lbtf_wq, &priv->cmd_work); - cmdnode = ERR_PTR(-ENOBUFS); - goto done; + return ERR_PTR(-ENOBUFS); } cmdnode->callback = callback; @@ -640,24 +520,17 @@ static struct cmd_ctrl_node *__lbtf_cmd_async(struct lbtf_private *priv, cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size); cmdnode->cmdbuf->seqnum = cpu_to_le16(priv->seqnum); cmdnode->cmdbuf->result = 0; - - lbtf_deb_host("PREP_CMD: command 0x%04x\n", command); - cmdnode->cmdwaitqwoken = 0; lbtf_queue_cmd(priv, cmdnode); queue_work(lbtf_wq, &priv->cmd_work); - done: - lbtf_deb_leave_args(LBTF_DEB_HOST, "ret %p", cmdnode); return cmdnode; } void lbtf_cmd_async(struct lbtf_private *priv, uint16_t command, struct cmd_header *in_cmd, int in_cmd_size) { - lbtf_deb_enter(LBTF_DEB_CMD); __lbtf_cmd_async(priv, command, in_cmd, in_cmd_size, NULL, 0); - lbtf_deb_leave(LBTF_DEB_CMD); } int __lbtf_cmd(struct lbtf_private *priv, uint16_t command, @@ -670,35 +543,30 @@ int __lbtf_cmd(struct lbtf_private *priv, uint16_t command, unsigned long flags; int ret = 0; - lbtf_deb_enter(LBTF_DEB_HOST); - cmdnode = __lbtf_cmd_async(priv, command, in_cmd, in_cmd_size, callback, callback_arg); - if (IS_ERR(cmdnode)) { - ret = PTR_ERR(cmdnode); - goto done; - } + if (IS_ERR(cmdnode)) + return PTR_ERR(cmdnode); might_sleep(); ret = wait_event_interruptible(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken); - if (ret) { - pr_info("PREP_CMD: command 0x%04x interrupted by signal: %d\n", - command, ret); - goto done; + if (ret) { + printk(KERN_DEBUG + "libertastf: command 0x%04x interrupted by signal", + command); + return ret; } spin_lock_irqsave(&priv->driver_lock, flags); ret = cmdnode->result; if (ret) - pr_info("PREP_CMD: command 0x%04x failed: %d\n", + printk(KERN_DEBUG "libertastf: command 0x%04x failed: %d\n", command, ret); __lbtf_cleanup_and_insert_cmd(priv, cmdnode); spin_unlock_irqrestore(&priv->driver_lock, flags); -done: - lbtf_deb_leave_args(LBTF_DEB_HOST, "ret %d", ret); return ret; } EXPORT_SYMBOL_GPL(__lbtf_cmd); @@ -719,8 +587,6 @@ int lbtf_process_rx_command(struct lbtf_private *priv) unsigned long flags; uint16_t result; - lbtf_deb_enter(LBTF_DEB_CMD); - mutex_lock(&priv->lock); spin_lock_irqsave(&priv->driver_lock, flags); @@ -736,7 +602,7 @@ int lbtf_process_rx_command(struct lbtf_private *priv) result = le16_to_cpu(resp->result); if (net_ratelimit()) - pr_info("libertastf: cmd response 0x%04x, seq %d, size %d\n", + printk(KERN_DEBUG "libertastf: cmd response 0x%04x, seq %d, size %d\n", respcmd, le16_to_cpu(resp->seqnum), le16_to_cpu(resp->size)); @@ -773,7 +639,7 @@ int lbtf_process_rx_command(struct lbtf_private *priv) switch (respcmd) { case CMD_RET(CMD_GET_HW_SPEC): case CMD_RET(CMD_802_11_RESET): - pr_info("libertastf: reset failed\n"); + printk(KERN_DEBUG "libertastf: reset failed\n"); break; } @@ -800,6 +666,5 @@ int lbtf_process_rx_command(struct lbtf_private *priv) done: mutex_unlock(&priv->lock); - lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", ret); return ret; } diff --git a/trunk/drivers/net/wireless/libertas_tf/deb_defs.h b/trunk/drivers/net/wireless/libertas_tf/deb_defs.h deleted file mode 100644 index ae753962d8b5..000000000000 --- a/trunk/drivers/net/wireless/libertas_tf/deb_defs.h +++ /dev/null @@ -1,104 +0,0 @@ -/** - * This header file contains global constant/enum definitions, - * global variable declaration. - */ -#ifndef _LBS_DEB_DEFS_H_ -#define _LBS_DEB_EFS_H_ - -#ifndef DRV_NAME -#define DRV_NAME "libertas_tf" -#endif - -#include - -#ifdef CONFIG_LIBERTAS_THINFIRM_DEBUG -#define DEBUG -#define PROC_DEBUG -#endif - -#define LBTF_DEB_ENTER 0x00000001 -#define LBTF_DEB_LEAVE 0x00000002 -#define LBTF_DEB_MAIN 0x00000004 -#define LBTF_DEB_NET 0x00000008 -#define LBTF_DEB_MESH 0x00000010 -#define LBTF_DEB_WEXT 0x00000020 -#define LBTF_DEB_IOCTL 0x00000040 -#define LBTF_DEB_SCAN 0x00000080 -#define LBTF_DEB_ASSOC 0x00000100 -#define LBTF_DEB_JOIN 0x00000200 -#define LBTF_DEB_11D 0x00000400 -#define LBTF_DEB_DEBUGFS 0x00000800 -#define LBTF_DEB_ETHTOOL 0x00001000 -#define LBTF_DEB_HOST 0x00002000 -#define LBTF_DEB_CMD 0x00004000 -#define LBTF_DEB_RX 0x00008000 -#define LBTF_DEB_TX 0x00010000 -#define LBTF_DEB_USB 0x00020000 -#define LBTF_DEB_CS 0x00040000 -#define LBTF_DEB_FW 0x00080000 -#define LBTF_DEB_THREAD 0x00100000 -#define LBTF_DEB_HEX 0x00200000 -#define LBTF_DEB_SDIO 0x00400000 -#define LBTF_DEB_MACOPS 0x00800000 - -extern unsigned int lbtf_debug; - - -#ifdef DEBUG -#define LBTF_DEB_LL(grp, grpnam, fmt, args...) \ -do { if ((lbtf_debug & (grp)) == (grp)) \ - printk(KERN_DEBUG DRV_NAME grpnam "%s: " fmt, \ - in_interrupt() ? " (INT)" : "", ## args); } while (0) -#else -#define LBTF_DEB_LL(grp, grpnam, fmt, args...) do {} while (0) -#endif - -#define lbtf_deb_enter(grp) \ - LBTF_DEB_LL(grp | LBTF_DEB_ENTER, " enter", "%s()\n", __func__); -#define lbtf_deb_enter_args(grp, fmt, args...) \ - LBTF_DEB_LL(grp | LBTF_DEB_ENTER, " enter", "%s(" fmt ")\n", __func__, ## args); -#define lbtf_deb_leave(grp) \ - LBTF_DEB_LL(grp | LBTF_DEB_LEAVE, " leave", "%s()\n", __func__); -#define lbtf_deb_leave_args(grp, fmt, args...) \ - LBTF_DEB_LL(grp | LBTF_DEB_LEAVE, " leave", "%s(), " fmt "\n", \ - __func__, ##args); -#define lbtf_deb_main(fmt, args...) LBTF_DEB_LL(LBTF_DEB_MAIN, " main", fmt, ##args) -#define lbtf_deb_net(fmt, args...) LBTF_DEB_LL(LBTF_DEB_NET, " net", fmt, ##args) -#define lbtf_deb_mesh(fmt, args...) LBTF_DEB_LL(LBTF_DEB_MESH, " mesh", fmt, ##args) -#define lbtf_deb_wext(fmt, args...) LBTF_DEB_LL(LBTF_DEB_WEXT, " wext", fmt, ##args) -#define lbtf_deb_ioctl(fmt, args...) LBTF_DEB_LL(LBTF_DEB_IOCTL, " ioctl", fmt, ##args) -#define lbtf_deb_scan(fmt, args...) LBTF_DEB_LL(LBTF_DEB_SCAN, " scan", fmt, ##args) -#define lbtf_deb_assoc(fmt, args...) LBTF_DEB_LL(LBTF_DEB_ASSOC, " assoc", fmt, ##args) -#define lbtf_deb_join(fmt, args...) LBTF_DEB_LL(LBTF_DEB_JOIN, " join", fmt, ##args) -#define lbtf_deb_11d(fmt, args...) LBTF_DEB_LL(LBTF_DEB_11D, " 11d", fmt, ##args) -#define lbtf_deb_debugfs(fmt, args...) LBTF_DEB_LL(LBTF_DEB_DEBUGFS, " debugfs", fmt, ##args) -#define lbtf_deb_ethtool(fmt, args...) LBTF_DEB_LL(LBTF_DEB_ETHTOOL, " ethtool", fmt, ##args) -#define lbtf_deb_host(fmt, args...) LBTF_DEB_LL(LBTF_DEB_HOST, " host", fmt, ##args) -#define lbtf_deb_cmd(fmt, args...) LBTF_DEB_LL(LBTF_DEB_CMD, " cmd", fmt, ##args) -#define lbtf_deb_rx(fmt, args...) LBTF_DEB_LL(LBTF_DEB_RX, " rx", fmt, ##args) -#define lbtf_deb_tx(fmt, args...) LBTF_DEB_LL(LBTF_DEB_TX, " tx", fmt, ##args) -#define lbtf_deb_fw(fmt, args...) LBTF_DEB_LL(LBTF_DEB_FW, " fw", fmt, ##args) -#define lbtf_deb_usb(fmt, args...) LBTF_DEB_LL(LBTF_DEB_USB, " usb", fmt, ##args) -#define lbtf_deb_usbd(dev, fmt, args...) LBTF_DEB_LL(LBTF_DEB_USB, " usbd", "%s:" fmt, dev_name(dev), ##args) -#define lbtf_deb_cs(fmt, args...) LBTF_DEB_LL(LBTF_DEB_CS, " cs", fmt, ##args) -#define lbtf_deb_thread(fmt, args...) LBTF_DEB_LL(LBTF_DEB_THREAD, " thread", fmt, ##args) -#define lbtf_deb_sdio(fmt, args...) LBTF_DEB_LL(LBTF_DEB_SDIO, " thread", fmt, ##args) -#define lbtf_deb_macops(fmt, args...) LBTF_DEB_LL(LBTF_DEB_MACOPS, " thread", fmt, ##args) - -#ifdef DEBUG -static inline void lbtf_deb_hex(unsigned int grp, const char *prompt, u8 *buf, int len) -{ - char newprompt[32]; - - if (len && - (lbtf_debug & LBTF_DEB_HEX) && - (lbtf_debug & grp)) { - snprintf(newprompt, sizeof(newprompt), DRV_NAME " %s: ", prompt); - print_hex_dump_bytes(prompt, DUMP_PREFIX_NONE, buf, len); - } -} -#else -#define lbtf_deb_hex(grp, prompt, buf, len) do {} while (0) -#endif - -#endif diff --git a/trunk/drivers/net/wireless/libertas_tf/if_usb.c b/trunk/drivers/net/wireless/libertas_tf/if_usb.c index 4412c279ca94..8cc9db60c14b 100644 --- a/trunk/drivers/net/wireless/libertas_tf/if_usb.c +++ b/trunk/drivers/net/wireless/libertas_tf/if_usb.c @@ -7,13 +7,6 @@ * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. */ -#define DRV_NAME "lbtf_usb" - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "libertas_tf.h" -#include "if_usb.h" - #include #include #include @@ -21,8 +14,10 @@ #include #include -#define INSANEDEBUG 0 -#define lbtf_deb_usb2(...) do { if (INSANEDEBUG) lbtf_deb_usbd(__VA_ARGS__); } while (0) +#define DRV_NAME "lbtf_usb" + +#include "libertas_tf.h" +#include "if_usb.h" #define MESSAGE_HEADER_LEN 4 @@ -58,14 +53,9 @@ static int if_usb_reset_device(struct if_usb_card *cardp); */ static void if_usb_write_bulk_callback(struct urb *urb) { - if (urb->status != 0) { - /* print the failure status number for debug */ - pr_info("URB in failure status: %d\n", urb->status); - } else { - lbtf_deb_usb2(&urb->dev->dev, "URB status is successful\n"); - lbtf_deb_usb2(&urb->dev->dev, "Actual length transmitted %d\n", - urb->actual_length); - } + if (urb->status != 0) + printk(KERN_INFO "libertastf: URB in failure status: %d\n", + urb->status); } /** @@ -75,8 +65,6 @@ static void if_usb_write_bulk_callback(struct urb *urb) */ static void if_usb_free(struct if_usb_card *cardp) { - lbtf_deb_enter(LBTF_DEB_USB); - /* Unlink tx & rx urb */ usb_kill_urb(cardp->tx_urb); usb_kill_urb(cardp->rx_urb); @@ -93,8 +81,6 @@ static void if_usb_free(struct if_usb_card *cardp) kfree(cardp->ep_out_buf); cardp->ep_out_buf = NULL; - - lbtf_deb_leave(LBTF_DEB_USB); } static void if_usb_setup_firmware(struct lbtf_private *priv) @@ -102,33 +88,23 @@ static void if_usb_setup_firmware(struct lbtf_private *priv) struct if_usb_card *cardp = priv->card; struct cmd_ds_set_boot2_ver b2_cmd; - lbtf_deb_enter(LBTF_DEB_USB); - if_usb_submit_rx_urb(cardp); b2_cmd.hdr.size = cpu_to_le16(sizeof(b2_cmd)); b2_cmd.action = 0; b2_cmd.version = cardp->boot2_version; if (lbtf_cmd_with_response(priv, CMD_SET_BOOT2_VER, &b2_cmd)) - lbtf_deb_usb("Setting boot2 version failed\n"); - - lbtf_deb_leave(LBTF_DEB_USB); + printk(KERN_INFO "libertastf: setting boot2 version failed\n"); } static void if_usb_fw_timeo(unsigned long priv) { struct if_usb_card *cardp = (void *)priv; - lbtf_deb_enter(LBTF_DEB_USB); - if (!cardp->fwdnldover) { + if (!cardp->fwdnldover) /* Download timed out */ cardp->priv->surpriseremoved = 1; - pr_err("Download timed out\n"); - } else { - lbtf_deb_usb("Download complete, no event. Assuming success\n"); - } wake_up(&cardp->fw_wq); - lbtf_deb_leave(LBTF_DEB_USB); } /** @@ -149,14 +125,11 @@ static int if_usb_probe(struct usb_interface *intf, struct if_usb_card *cardp; int i; - lbtf_deb_enter(LBTF_DEB_USB); udev = interface_to_usbdev(intf); cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL); - if (!cardp) { - pr_err("Out of memory allocating private data.\n"); + if (!cardp) goto error; - } setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp); init_waitqueue_head(&cardp->fw_wq); @@ -164,62 +137,38 @@ static int if_usb_probe(struct usb_interface *intf, cardp->udev = udev; iface_desc = intf->cur_altsetting; - lbtf_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X" - " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n", - le16_to_cpu(udev->descriptor.bcdUSB), - udev->descriptor.bDeviceClass, - udev->descriptor.bDeviceSubClass, - udev->descriptor.bDeviceProtocol); - for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (usb_endpoint_is_bulk_in(endpoint)) { cardp->ep_in_size = 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); } 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, "Bulk out size is %d\n", - cardp->ep_out_size); } } - if (!cardp->ep_out_size || !cardp->ep_in_size) { - lbtf_deb_usbd(&udev->dev, "Endpoints not found\n"); + if (!cardp->ep_out_size || !cardp->ep_in_size) /* Endpoints not found */ goto dealloc; - } cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!cardp->rx_urb) { - lbtf_deb_usbd(&udev->dev, "Rx URB allocation failed\n"); + if (!cardp->rx_urb) goto dealloc; - } cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!cardp->tx_urb) { - lbtf_deb_usbd(&udev->dev, "Tx URB allocation failed\n"); + if (!cardp->tx_urb) goto dealloc; - } cardp->cmd_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!cardp->cmd_urb) { - lbtf_deb_usbd(&udev->dev, "Cmd URB allocation failed\n"); + if (!cardp->cmd_urb) goto dealloc; - } cardp->ep_out_buf = kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE, GFP_KERNEL); - if (!cardp->ep_out_buf) { - lbtf_deb_usbd(&udev->dev, "Could not allocate buffer\n"); + if (!cardp->ep_out_buf) goto dealloc; - } priv = lbtf_add_card(cardp, &udev->dev); if (!priv) @@ -240,7 +189,6 @@ static int if_usb_probe(struct usb_interface *intf, dealloc: if_usb_free(cardp); error: -lbtf_deb_leave(LBTF_DEB_MAIN); return -ENOMEM; } @@ -254,8 +202,6 @@ static void if_usb_disconnect(struct usb_interface *intf) struct if_usb_card *cardp = usb_get_intfdata(intf); struct lbtf_private *priv = (struct lbtf_private *) cardp->priv; - lbtf_deb_enter(LBTF_DEB_MAIN); - if_usb_reset_device(cardp); if (priv) @@ -266,8 +212,6 @@ static void if_usb_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); usb_put_dev(interface_to_usbdev(intf)); - - lbtf_deb_leave(LBTF_DEB_MAIN); } /** @@ -282,8 +226,6 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp) struct fwdata *fwdata = cardp->ep_out_buf; u8 *firmware = (u8 *) cardp->fw->data; - lbtf_deb_enter(LBTF_DEB_FW); - /* If we got a CRC failure on the last block, back up and retry it */ if (!cardp->CRC_OK) { @@ -291,9 +233,6 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp) cardp->fwseqnum--; } - lbtf_deb_usb2(&cardp->udev->dev, "totalbytes = %d\n", - cardp->totalbytes); - /* struct fwdata (which we sent to the card) has an extra __le32 field in between the header and the data, which is not in the struct fwheader in the actual @@ -307,33 +246,18 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp) memcpy(fwdata->data, &firmware[cardp->totalbytes], le32_to_cpu(fwdata->hdr.datalength)); - lbtf_deb_usb2(&cardp->udev->dev, "Data length = %d\n", - le32_to_cpu(fwdata->hdr.datalength)); - fwdata->seqnum = cpu_to_le32(++cardp->fwseqnum); cardp->totalbytes += le32_to_cpu(fwdata->hdr.datalength); usb_tx_block(cardp, cardp->ep_out_buf, sizeof(struct fwdata) + le32_to_cpu(fwdata->hdr.datalength), 0); - 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); - } 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, "Donwloading FW JUMP BLOCK\n"); - + if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) /* Host has finished FW downloading * Donwloading FW JUMP BLOCK */ cardp->fwfinalblk = 1; - } - lbtf_deb_usb2(&cardp->udev->dev, "Firmware download done; size %d\n", - cardp->totalbytes); - - lbtf_deb_leave(LBTF_DEB_FW); return 0; } @@ -342,8 +266,6 @@ static int if_usb_reset_device(struct if_usb_card *cardp) struct cmd_ds_802_11_reset *cmd = cardp->ep_out_buf + 4; int ret; - lbtf_deb_enter(LBTF_DEB_USB); - *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST); cmd->hdr.command = cpu_to_le16(CMD_802_11_RESET); @@ -358,8 +280,6 @@ static int if_usb_reset_device(struct if_usb_card *cardp) ret = usb_reset_device(cardp->udev); msleep(100); - lbtf_deb_leave_args(LBTF_DEB_USB, "ret %d", ret); - return ret; } EXPORT_SYMBOL_GPL(if_usb_reset_device); @@ -377,15 +297,11 @@ EXPORT_SYMBOL_GPL(if_usb_reset_device); static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb, u8 data) { - int ret = -1; struct urb *urb; - lbtf_deb_enter(LBTF_DEB_USB); /* check if device is removed */ - if (cardp->priv->surpriseremoved) { - lbtf_deb_usbd(&cardp->udev->dev, "Device removed\n"); - goto tx_ret; - } + if (cardp->priv->surpriseremoved) + return -1; if (data) urb = cardp->tx_urb; @@ -399,34 +315,19 @@ 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); - goto tx_ret; - } - - lbtf_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n"); - - ret = 0; - -tx_ret: - lbtf_deb_leave(LBTF_DEB_USB); - return ret; + if (usb_submit_urb(urb, GFP_ATOMIC)) + return -1; + return 0; } static int __if_usb_submit_rx_urb(struct if_usb_card *cardp, void (*callbackfn)(struct urb *urb)) { struct sk_buff *skb; - int ret = -1; - - lbtf_deb_enter(LBTF_DEB_USB); skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE); - if (!skb) { - pr_err("No free skb\n"); - lbtf_deb_leave(LBTF_DEB_USB); + if (!skb) return -1; - } cardp->rx_skb = skb; @@ -438,19 +339,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); - ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC); - if (ret) { - lbtf_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret); + if (usb_submit_urb(cardp->rx_urb, GFP_ATOMIC)) { kfree_skb(skb); cardp->rx_skb = NULL; - lbtf_deb_leave(LBTF_DEB_USB); return -1; - } else { - lbtf_deb_usb2(&cardp->udev->dev, "Submit Rx URB success\n"); - lbtf_deb_leave(LBTF_DEB_USB); + } else return 0; - } } static int if_usb_submit_rx_urb_fwload(struct if_usb_card *cardp) @@ -470,12 +364,8 @@ static void if_usb_receive_fwload(struct urb *urb) struct fwsyncheader *syncfwheader; struct bootcmdresp bcmdresp; - lbtf_deb_enter(LBTF_DEB_USB); if (urb->status) { - lbtf_deb_usbd(&cardp->udev->dev, - "URB status is failed during fw load\n"); kfree_skb(skb); - lbtf_deb_leave(LBTF_DEB_USB); return; } @@ -483,17 +373,12 @@ static void if_usb_receive_fwload(struct urb *urb) __le32 *tmp = (__le32 *)(skb->data); if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) && - tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) { + tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) /* Firmware ready event received */ - pr_info("Firmware ready event received\n"); wake_up(&cardp->fw_wq); - } else { - lbtf_deb_usb("Waiting for confirmation; got %x %x\n", - le32_to_cpu(tmp[0]), le32_to_cpu(tmp[1])); + else if_usb_submit_rx_urb_fwload(cardp); - } kfree_skb(skb); - lbtf_deb_leave(LBTF_DEB_USB); return; } if (cardp->bootcmdresp <= 0) { @@ -504,60 +389,34 @@ static void if_usb_receive_fwload(struct urb *urb) if_usb_submit_rx_urb_fwload(cardp); cardp->bootcmdresp = 1; /* Received valid boot command response */ - lbtf_deb_usbd(&cardp->udev->dev, - "Received valid boot command response\n"); - lbtf_deb_leave(LBTF_DEB_USB); return; } if (bcmdresp.magic != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) { if (bcmdresp.magic == cpu_to_le32(CMD_TYPE_REQUEST) || bcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) || - bcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) { - if (!cardp->bootcmdresp) - pr_info("Firmware already seems alive; resetting\n"); + bcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) cardp->bootcmdresp = -1; - } else { - pr_info("boot cmd response wrong magic number (0x%x)\n", - le32_to_cpu(bcmdresp.magic)); - } - } else if (bcmdresp.cmd != BOOT_CMD_FW_BY_USB) { - pr_info("boot cmd response cmd_tag error (%d)\n", - bcmdresp.cmd); - } else if (bcmdresp.result != BOOT_CMD_RESP_OK) { - pr_info("boot cmd response result error (%d)\n", - bcmdresp.result); - } else { + } else if (bcmdresp.cmd == BOOT_CMD_FW_BY_USB && + bcmdresp.result == BOOT_CMD_RESP_OK) cardp->bootcmdresp = 1; - lbtf_deb_usbd(&cardp->udev->dev, - "Received valid boot command response\n"); - } kfree_skb(skb); if_usb_submit_rx_urb_fwload(cardp); - lbtf_deb_leave(LBTF_DEB_USB); return; } syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC); if (!syncfwheader) { - lbtf_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n"); kfree_skb(skb); - lbtf_deb_leave(LBTF_DEB_USB); return; } memcpy(syncfwheader, skb->data, sizeof(struct fwsyncheader)); - 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)); + if (!syncfwheader->cmd) cardp->CRC_OK = 1; - } else { - lbtf_deb_usbd(&cardp->udev->dev, "FW received Blk with CRC error\n"); + else cardp->CRC_OK = 0; - } - kfree_skb(skb); /* reschedule timer for 200ms hence */ @@ -575,7 +434,6 @@ static void if_usb_receive_fwload(struct urb *urb) kfree(syncfwheader); - lbtf_deb_leave(LBTF_DEB_USB); return; } @@ -587,7 +445,6 @@ static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb, { if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + MESSAGE_HEADER_LEN || recvlength < MRVDRV_MIN_PKT_LEN) { - lbtf_deb_usbd(&cardp->udev->dev, "Packet length is Invalid\n"); kfree_skb(skb); return; } @@ -603,8 +460,6 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff, struct lbtf_private *priv) { if (recvlength > LBS_CMD_BUFFER_SIZE) { - lbtf_deb_usbd(&cardp->udev->dev, - "The receive buffer is too large\n"); kfree_skb(skb); return; } @@ -634,24 +489,16 @@ static void if_usb_receive(struct urb *urb) uint32_t recvtype = 0; __le32 *pkt = (__le32 *) skb->data; - lbtf_deb_enter(LBTF_DEB_USB); - if (recvlength) { if (urb->status) { - lbtf_deb_usbd(&cardp->udev->dev, "RX URB failed: %d\n", - urb->status); kfree_skb(skb); goto setup_for_next; } recvbuff = skb->data; recvtype = le32_to_cpu(pkt[0]); - lbtf_deb_usbd(&cardp->udev->dev, - "Recv length = 0x%x, Recv type = 0x%X\n", - recvlength, recvtype); } else if (urb->status) { kfree_skb(skb); - lbtf_deb_leave(LBTF_DEB_USB); return; } @@ -668,7 +515,6 @@ 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); /* Icky undocumented magic special case */ if (event_cause & 0xffff0000) { @@ -683,22 +529,21 @@ static void if_usb_receive(struct urb *urb) } else if (event_cause == LBTF_EVENT_BCN_SENT) lbtf_bcn_sent(priv); else - lbtf_deb_usbd(&cardp->udev->dev, + printk(KERN_DEBUG "Unsupported notification %d received\n", event_cause); kfree_skb(skb); break; } default: - lbtf_deb_usbd(&cardp->udev->dev, - "libertastf: unknown command type 0x%X\n", recvtype); + printk(KERN_DEBUG "libertastf: unknown command type 0x%X\n", + recvtype); kfree_skb(skb); break; } setup_for_next: if_usb_submit_rx_urb(cardp); - lbtf_deb_leave(LBTF_DEB_USB); } /** @@ -717,9 +562,6 @@ static int if_usb_host_to_card(struct lbtf_private *priv, uint8_t type, struct if_usb_card *cardp = priv->card; u8 data = 0; - lbtf_deb_usbd(&cardp->udev->dev, "*** type = %u\n", type); - lbtf_deb_usbd(&cardp->udev->dev, "size after = %d\n", nb); - if (type == MVMS_CMD) { *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST); } else { @@ -797,10 +639,8 @@ static int check_fwfile_format(const u8 *data, u32 totlen) } while (!exit); if (ret) - pr_err("firmware file format check FAIL\n"); - else - lbtf_deb_fw("firmware file format check PASS\n"); - + printk(KERN_INFO + "libertastf: firmware file format check failed\n"); return ret; } @@ -811,12 +651,10 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp) static int reset_count = 10; int ret = 0; - lbtf_deb_enter(LBTF_DEB_USB); - ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev); if (ret < 0) { - pr_err("request_firmware() failed with %#x\n", ret); - pr_err("firmware %s not found\n", lbtf_fw_name); + printk(KERN_INFO "libertastf: firmware %s not found\n", + lbtf_fw_name); goto done; } @@ -825,7 +663,6 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp) restart: if (if_usb_submit_rx_urb_fwload(cardp) < 0) { - lbtf_deb_usbd(&cardp->udev->dev, "URB submission is failed\n"); ret = -1; goto release_fw; } @@ -872,13 +709,14 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp) usb_kill_urb(cardp->rx_urb); if (!cardp->fwdnldover) { - pr_info("failed to load fw, resetting device!\n"); + printk(KERN_INFO "libertastf: failed to load fw," + " resetting device!\n"); if (--reset_count >= 0) { if_usb_reset_device(cardp); goto restart; } - pr_info("FW download failure, time = %d ms\n", i * 100); + printk(KERN_INFO "libertastf: fw download failure\n"); ret = -1; goto release_fw; } @@ -892,7 +730,6 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp) if_usb_setup_firmware(cardp->priv); done: - lbtf_deb_leave_args(LBTF_DEB_USB, "ret %d", ret); return ret; } EXPORT_SYMBOL_GPL(if_usb_prog_firmware); @@ -914,19 +751,13 @@ static int __init if_usb_init_module(void) { int ret = 0; - lbtf_deb_enter(LBTF_DEB_MAIN); - ret = usb_register(&if_usb_driver); - - lbtf_deb_leave_args(LBTF_DEB_MAIN, "ret %d", ret); return ret; } static void __exit if_usb_exit_module(void) { - lbtf_deb_enter(LBTF_DEB_MAIN); usb_deregister(&if_usb_driver); - lbtf_deb_leave(LBTF_DEB_MAIN); } module_init(if_usb_init_module); diff --git a/trunk/drivers/net/wireless/libertas_tf/libertas_tf.h b/trunk/drivers/net/wireless/libertas_tf/libertas_tf.h index fbbaaae7a1ae..4cc42dd5a005 100644 --- a/trunk/drivers/net/wireless/libertas_tf/libertas_tf.h +++ b/trunk/drivers/net/wireless/libertas_tf/libertas_tf.h @@ -13,8 +13,6 @@ #include #include -#include "deb_defs.h" - #ifndef DRV_NAME #define DRV_NAME "libertas_tf" #endif diff --git a/trunk/drivers/net/wireless/libertas_tf/main.c b/trunk/drivers/net/wireless/libertas_tf/main.c index 60787de56f3a..7533a23e0500 100644 --- a/trunk/drivers/net/wireless/libertas_tf/main.c +++ b/trunk/drivers/net/wireless/libertas_tf/main.c @@ -7,12 +7,10 @@ * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include -#include #include "libertas_tf.h" +#include "linux/etherdevice.h" #define DRIVER_RELEASE_VERSION "004.p0" /* thinfirm version: 5.132.X.pX */ @@ -20,17 +18,7 @@ #define LBTF_FW_VER_MAX 0x0584ffff #define QOS_CONTROL_LEN 2 -/* Module parameters */ -unsigned int lbtf_debug; -EXPORT_SYMBOL_GPL(lbtf_debug); -module_param_named(libertas_tf_debug, lbtf_debug, int, 0644); - -static const char lbtf_driver_version[] = "THINFIRM-USB8388-" DRIVER_RELEASE_VERSION -#ifdef DEBUG - "-dbg" -#endif - ""; - +static const char lbtf_driver_version[] = "THINFIRM-USB8388-" DRIVER_RELEASE_VERSION; struct workqueue_struct *lbtf_wq; static const struct ieee80211_channel lbtf_channels[] = { @@ -93,9 +81,6 @@ static void lbtf_cmd_work(struct work_struct *work) { struct lbtf_private *priv = container_of(work, struct lbtf_private, cmd_work); - - lbtf_deb_enter(LBTF_DEB_CMD); - spin_lock_irq(&priv->driver_lock); /* command response? */ if (priv->cmd_response_rxed) { @@ -123,16 +108,11 @@ static void lbtf_cmd_work(struct work_struct *work) priv->cmd_timed_out = 0; spin_unlock_irq(&priv->driver_lock); - if (!priv->fw_ready) { - lbtf_deb_leave_args(LBTF_DEB_CMD, "fw not ready"); + if (!priv->fw_ready) return; - } - /* Execute the next command */ if (!priv->cur_cmd) lbtf_execute_next_command(priv); - - lbtf_deb_leave(LBTF_DEB_CMD); } /** @@ -146,7 +126,6 @@ static int lbtf_setup_firmware(struct lbtf_private *priv) { int ret = -1; - lbtf_deb_enter(LBTF_DEB_FW); /* * Read priv address from HW */ @@ -162,7 +141,6 @@ static int lbtf_setup_firmware(struct lbtf_private *priv) ret = 0; done: - lbtf_deb_leave_args(LBTF_DEB_FW, "ret: %d", ret); return ret; } @@ -174,7 +152,6 @@ static void command_timer_fn(unsigned long data) { struct lbtf_private *priv = (struct lbtf_private *)data; unsigned long flags; - lbtf_deb_enter(LBTF_DEB_CMD); spin_lock_irqsave(&priv->driver_lock, flags); @@ -191,12 +168,10 @@ static void command_timer_fn(unsigned long data) queue_work(lbtf_wq, &priv->cmd_work); out: spin_unlock_irqrestore(&priv->driver_lock, flags); - lbtf_deb_leave(LBTF_DEB_CMD); } static int lbtf_init_adapter(struct lbtf_private *priv) { - lbtf_deb_enter(LBTF_DEB_MAIN); memset(priv->current_addr, 0xff, ETH_ALEN); mutex_init(&priv->lock); @@ -213,16 +188,13 @@ static int lbtf_init_adapter(struct lbtf_private *priv) if (lbtf_allocate_cmd_buffer(priv)) return -1; - lbtf_deb_leave(LBTF_DEB_MAIN); return 0; } static void lbtf_free_adapter(struct lbtf_private *priv) { - lbtf_deb_enter(LBTF_DEB_MAIN); lbtf_free_cmd_buffer(priv); del_timer(&priv->command_timer); - lbtf_deb_leave(LBTF_DEB_MAIN); } static int lbtf_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) @@ -249,18 +221,14 @@ static void lbtf_tx_work(struct work_struct *work) struct sk_buff *skb = NULL; int err; - lbtf_deb_enter(LBTF_DEB_MACOPS | LBTF_DEB_TX); - if ((priv->vif->type == NL80211_IFTYPE_AP) && (!skb_queue_empty(&priv->bc_ps_buf))) skb = skb_dequeue(&priv->bc_ps_buf); else if (priv->skb_to_tx) { skb = priv->skb_to_tx; priv->skb_to_tx = NULL; - } else { - lbtf_deb_leave(LBTF_DEB_MACOPS | LBTF_DEB_TX); + } else return; - } len = skb->len; info = IEEE80211_SKB_CB(skb); @@ -268,7 +236,6 @@ static void lbtf_tx_work(struct work_struct *work) if (priv->surpriseremoved) { dev_kfree_skb_any(skb); - lbtf_deb_leave(LBTF_DEB_MACOPS | LBTF_DEB_TX); return; } @@ -282,7 +249,6 @@ static void lbtf_tx_work(struct work_struct *work) ETH_ALEN); txpd->tx_packet_length = cpu_to_le16(len); txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd)); - lbtf_deb_hex(LBTF_DEB_TX, "TX Data", skb->data, min_t(unsigned int, skb->len, 100)); BUG_ON(priv->tx_skb); spin_lock_irq(&priv->driver_lock); priv->tx_skb = skb; @@ -291,9 +257,7 @@ static void lbtf_tx_work(struct work_struct *work) if (err) { dev_kfree_skb_any(skb); priv->tx_skb = NULL; - pr_err("TX error: %d", err); } - lbtf_deb_leave(LBTF_DEB_MACOPS | LBTF_DEB_TX); } static int lbtf_op_start(struct ieee80211_hw *hw) @@ -302,8 +266,6 @@ static int lbtf_op_start(struct ieee80211_hw *hw) void *card = priv->card; int ret = -1; - lbtf_deb_enter(LBTF_DEB_MACOPS); - if (!priv->fw_ready) /* Upload firmware */ if (priv->hw_prog_firmware(card)) @@ -324,12 +286,10 @@ static int lbtf_op_start(struct ieee80211_hw *hw) } printk(KERN_INFO "libertastf: Marvell WLAN 802.11 thinfirm adapter\n"); - lbtf_deb_leave(LBTF_DEB_MACOPS); return 0; err_prog_firmware: priv->hw_reset_device(card); - lbtf_deb_leave_args(LBTF_DEB_MACOPS, "error programing fw; ret=%d", ret); return ret; } @@ -340,9 +300,6 @@ static void lbtf_op_stop(struct ieee80211_hw *hw) struct sk_buff *skb; struct cmd_ctrl_node *cmdnode; - - lbtf_deb_enter(LBTF_DEB_MACOPS); - /* Flush pending command nodes */ spin_lock_irqsave(&priv->driver_lock, flags); list_for_each_entry(cmdnode, &priv->cmdpendingq, list) { @@ -359,7 +316,6 @@ static void lbtf_op_stop(struct ieee80211_hw *hw) priv->radioon = RADIO_OFF; lbtf_set_radio_control(priv); - lbtf_deb_leave(LBTF_DEB_MACOPS); return; } @@ -367,7 +323,6 @@ static int lbtf_op_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct lbtf_private *priv = hw->priv; - lbtf_deb_enter(LBTF_DEB_MACOPS); if (priv->vif != NULL) return -EOPNOTSUPP; @@ -385,7 +340,6 @@ static int lbtf_op_add_interface(struct ieee80211_hw *hw, return -EOPNOTSUPP; } lbtf_set_mac_address(priv, (u8 *) vif->addr); - lbtf_deb_leave(LBTF_DEB_MACOPS); return 0; } @@ -393,7 +347,6 @@ static void lbtf_op_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct lbtf_private *priv = hw->priv; - lbtf_deb_enter(LBTF_DEB_MACOPS); if (priv->vif->type == NL80211_IFTYPE_AP || priv->vif->type == NL80211_IFTYPE_MESH_POINT) @@ -401,20 +354,17 @@ static void lbtf_op_remove_interface(struct ieee80211_hw *hw, lbtf_set_mode(priv, LBTF_PASSIVE_MODE); lbtf_set_bssid(priv, 0, NULL); priv->vif = NULL; - lbtf_deb_leave(LBTF_DEB_MACOPS); } static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed) { struct lbtf_private *priv = hw->priv; struct ieee80211_conf *conf = &hw->conf; - lbtf_deb_enter(LBTF_DEB_MACOPS); if (conf->channel->center_freq != priv->cur_freq) { priv->cur_freq = conf->channel->center_freq; lbtf_set_channel(priv, conf->channel->hw_value); } - lbtf_deb_leave(LBTF_DEB_MACOPS); return 0; } @@ -445,16 +395,11 @@ static void lbtf_op_configure_filter(struct ieee80211_hw *hw, { struct lbtf_private *priv = hw->priv; int old_mac_control = priv->mac_control; - - lbtf_deb_enter(LBTF_DEB_MACOPS); - changed_flags &= SUPPORTED_FIF_FLAGS; *new_flags &= SUPPORTED_FIF_FLAGS; - if (!changed_flags) { - lbtf_deb_leave(LBTF_DEB_MACOPS); + if (!changed_flags) return; - } if (*new_flags & (FIF_PROMISC_IN_BSS)) priv->mac_control |= CMD_ACT_MAC_PROMISCUOUS_ENABLE; @@ -480,8 +425,6 @@ static void lbtf_op_configure_filter(struct ieee80211_hw *hw, if (priv->mac_control != old_mac_control) lbtf_set_mac_control(priv); - - lbtf_deb_leave(LBTF_DEB_MACOPS); } static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw, @@ -491,7 +434,6 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw, { struct lbtf_private *priv = hw->priv; struct sk_buff *beacon; - lbtf_deb_enter(LBTF_DEB_MACOPS); if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_INT)) { switch (priv->vif->type) { @@ -522,8 +464,6 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw, priv->preamble = CMD_TYPE_LONG_PREAMBLE; lbtf_set_radio_control(priv); } - - lbtf_deb_leave(LBTF_DEB_MACOPS); } static const struct ieee80211_ops lbtf_ops = { @@ -546,8 +486,6 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) unsigned int flags; struct ieee80211_hdr *hdr; - lbtf_deb_enter(LBTF_DEB_RX); - prxpd = (struct rxpd *) skb->data; stats.flag = 0; @@ -556,6 +494,7 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) stats.freq = priv->cur_freq; stats.band = IEEE80211_BAND_2GHZ; stats.signal = prxpd->snr; + stats.noise = prxpd->nf; /* Marvell rate index has a hole at value 4 */ if (prxpd->rx_rate > 4) --prxpd->rx_rate; @@ -577,15 +516,7 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) } memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats)); - - lbtf_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n", - skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd)); - lbtf_deb_hex(LBTF_DEB_RX, "RX Data", skb->data, - min_t(unsigned int, skb->len, 100)); - ieee80211_rx_irqsafe(priv->hw, skb); - - lbtf_deb_leave(LBTF_DEB_RX); return 0; } EXPORT_SYMBOL_GPL(lbtf_rx); @@ -602,8 +533,6 @@ struct lbtf_private *lbtf_add_card(void *card, struct device *dmdev) struct ieee80211_hw *hw; struct lbtf_private *priv = NULL; - lbtf_deb_enter(LBTF_DEB_MAIN); - hw = ieee80211_alloc_hw(sizeof(struct lbtf_private), &lbtf_ops); if (!hw) goto done; @@ -646,7 +575,6 @@ struct lbtf_private *lbtf_add_card(void *card, struct device *dmdev) priv = NULL; done: - lbtf_deb_leave_args(LBTF_DEB_MAIN, "priv %p", priv); return priv; } EXPORT_SYMBOL_GPL(lbtf_add_card); @@ -656,8 +584,6 @@ int lbtf_remove_card(struct lbtf_private *priv) { struct ieee80211_hw *hw = priv->hw; - lbtf_deb_enter(LBTF_DEB_MAIN); - priv->surpriseremoved = 1; del_timer(&priv->command_timer); lbtf_free_adapter(priv); @@ -665,7 +591,6 @@ int lbtf_remove_card(struct lbtf_private *priv) ieee80211_unregister_hw(hw); ieee80211_free_hw(hw); - lbtf_deb_leave(LBTF_DEB_MAIN); return 0; } EXPORT_SYMBOL_GPL(lbtf_remove_card); @@ -724,21 +649,17 @@ EXPORT_SYMBOL_GPL(lbtf_bcn_sent); static int __init lbtf_init_module(void) { - lbtf_deb_enter(LBTF_DEB_MAIN); lbtf_wq = create_workqueue("libertastf"); if (lbtf_wq == NULL) { printk(KERN_ERR "libertastf: couldn't create workqueue\n"); return -ENOMEM; } - lbtf_deb_leave(LBTF_DEB_MAIN); return 0; } static void __exit lbtf_exit_module(void) { - lbtf_deb_enter(LBTF_DEB_MAIN); destroy_workqueue(lbtf_wq); - lbtf_deb_leave(LBTF_DEB_MAIN); } module_init(lbtf_init_module); diff --git a/trunk/drivers/net/wireless/mac80211_hwsim.c b/trunk/drivers/net/wireless/mac80211_hwsim.c index 9fd2beadb6f5..6f0d8c9fa933 100644 --- a/trunk/drivers/net/wireless/mac80211_hwsim.c +++ b/trunk/drivers/net/wireless/mac80211_hwsim.c @@ -974,7 +974,6 @@ static void hw_scan_done(struct work_struct *work) } static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, struct cfg80211_scan_request *req) { struct hw_scan_done *hsd = kzalloc(sizeof(*hsd), GFP_KERNEL); @@ -1021,7 +1020,7 @@ static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw) mutex_lock(&hwsim->mutex); printk(KERN_DEBUG "hwsim sw_scan_complete\n"); - hwsim->scanning = false; + hwsim->scanning = true; mutex_unlock(&hwsim->mutex); } @@ -1300,8 +1299,7 @@ static int __init init_mac80211_hwsim(void) hw->flags = IEEE80211_HW_MFP_CAPABLE | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_STATIC_SMPS | - IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | - IEEE80211_HW_AMPDU_AGGREGATION; + IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS; /* ask mac80211 to reserve space for magic */ hw->vif_data_size = sizeof(struct hwsim_vif_priv); diff --git a/trunk/drivers/net/wireless/mwl8k.c b/trunk/drivers/net/wireless/mwl8k.c index 808adb909095..73bbd080c6e7 100644 --- a/trunk/drivers/net/wireless/mwl8k.c +++ b/trunk/drivers/net/wireless/mwl8k.c @@ -750,6 +750,7 @@ mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status, memset(status, 0, sizeof(*status)); status->signal = -rxd->rssi; + status->noise = -rxd->noise_floor; if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) { status->flag |= RX_FLAG_HT; @@ -851,6 +852,7 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status, memset(status, 0, sizeof(*status)); status->signal = -rxd->rssi; + status->noise = -rxd->noise_level; status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info); status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info); @@ -3982,8 +3984,8 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, hw->queues = MWL8K_TX_QUEUES; - /* Set rssi values to dBm */ - hw->flags |= IEEE80211_HW_SIGNAL_DBM; + /* Set rssi and noise values to dBm */ + hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM; hw->vif_data_size = sizeof(struct mwl8k_vif); hw->sta_data_size = sizeof(struct mwl8k_sta); diff --git a/trunk/drivers/net/wireless/orinoco/Kconfig b/trunk/drivers/net/wireless/orinoco/Kconfig index 60819bcf4377..6116b546861d 100644 --- a/trunk/drivers/net/wireless/orinoco/Kconfig +++ b/trunk/drivers/net/wireless/orinoco/Kconfig @@ -132,10 +132,3 @@ config PCMCIA_SPECTRUM This driver requires firmware download on startup. Utilities for downloading Symbol firmware are available at - -config ORINOCO_USB - tristate "Agere Orinoco USB support" - depends on USB && HERMES - select FW_LOADER - ---help--- - This driver is for USB versions of the Agere Orinoco card. diff --git a/trunk/drivers/net/wireless/orinoco/Makefile b/trunk/drivers/net/wireless/orinoco/Makefile index bfdefb85abcd..e6452698eba9 100644 --- a/trunk/drivers/net/wireless/orinoco/Makefile +++ b/trunk/drivers/net/wireless/orinoco/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_PCI_HERMES) += orinoco_pci.o obj-$(CONFIG_TMD_HERMES) += orinoco_tmd.o obj-$(CONFIG_NORTEL_HERMES) += orinoco_nortel.o obj-$(CONFIG_PCMCIA_SPECTRUM) += spectrum_cs.o -obj-$(CONFIG_ORINOCO_USB) += orinoco_usb.o # Orinoco should be endian clean. ccflags-y += -D__CHECK_ENDIAN__ diff --git a/trunk/drivers/net/wireless/orinoco/airport.c b/trunk/drivers/net/wireless/orinoco/airport.c index 9bcee10c9308..c60df2c1aca3 100644 --- a/trunk/drivers/net/wireless/orinoco/airport.c +++ b/trunk/drivers/net/wireless/orinoco/airport.c @@ -77,9 +77,9 @@ airport_resume(struct macio_dev *mdev) enable_irq(card->irq); - priv->hw.ops->lock_irqsave(&priv->lock, &flags); + spin_lock_irqsave(&priv->lock, flags); err = orinoco_up(priv); - priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); + spin_unlock_irqrestore(&priv->lock, flags); return err; } @@ -195,7 +195,7 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match) ssleep(1); /* Reset it before we get the interrupt */ - hw->ops->init(hw); + hermes_init(hw); if (request_irq(card->irq, orinoco_interrupt, 0, DRIVER_NAME, priv)) { printk(KERN_ERR PFX "Couldn't get IRQ %d\n", card->irq); @@ -210,7 +210,7 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match) } /* Register an interface with the stack */ - if (orinoco_if_add(priv, phys_addr, card->irq, NULL) != 0) { + if (orinoco_if_add(priv, phys_addr, card->irq) != 0) { printk(KERN_ERR PFX "orinoco_if_add() failed\n"); goto failed; } diff --git a/trunk/drivers/net/wireless/orinoco/cfg.c b/trunk/drivers/net/wireless/orinoco/cfg.c index 81d228de9e5d..90dd4d0595c3 100644 --- a/trunk/drivers/net/wireless/orinoco/cfg.c +++ b/trunk/drivers/net/wireless/orinoco/cfg.c @@ -189,7 +189,7 @@ static int orinoco_set_channel(struct wiphy *wiphy, if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { /* Fast channel change - no commit if successful */ hermes_t *hw = &priv->hw; - err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST | + err = hermes_docmd_wait(hw, HERMES_CMD_TEST | HERMES_TEST_SET_CHANNEL, channel, NULL); } diff --git a/trunk/drivers/net/wireless/orinoco/fw.c b/trunk/drivers/net/wireless/orinoco/fw.c index 3e1947d097ca..5ea0f7cf85b1 100644 --- a/trunk/drivers/net/wireless/orinoco/fw.c +++ b/trunk/drivers/net/wireless/orinoco/fw.c @@ -122,7 +122,7 @@ orinoco_dl_firmware(struct orinoco_private *priv, dev_dbg(dev, "Attempting to download firmware %s\n", firmware); /* Read current plug data */ - err = hw->ops->read_pda(hw, pda, fw->pda_addr, fw->pda_size); + err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0); dev_dbg(dev, "Read PDA returned %d\n", err); if (err) goto free; @@ -149,7 +149,7 @@ orinoco_dl_firmware(struct orinoco_private *priv, } /* Enable aux port to allow programming */ - err = hw->ops->program_init(hw, le32_to_cpu(hdr->entry_point)); + err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point)); dev_dbg(dev, "Program init returned %d\n", err); if (err != 0) goto abort; @@ -177,7 +177,7 @@ orinoco_dl_firmware(struct orinoco_private *priv, goto abort; /* Tell card we've finished */ - err = hw->ops->program_end(hw); + err = hermesi_program_end(hw); dev_dbg(dev, "Program end returned %d\n", err); if (err != 0) goto abort; @@ -224,7 +224,7 @@ symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw, if (!pda) return -ENOMEM; - ret = hw->ops->read_pda(hw, pda, fw->pda_addr, fw->pda_size); + ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1); if (ret) goto free; } @@ -260,7 +260,7 @@ symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw, } /* Reset hermes chip and make sure it responds */ - ret = hw->ops->init(hw); + ret = hermes_init(hw); /* hermes_reset() should return 0 with the secondary firmware */ if (secondary && ret != 0) diff --git a/trunk/drivers/net/wireless/orinoco/hermes.c b/trunk/drivers/net/wireless/orinoco/hermes.c index 6c6a23e08df6..1a2fca76fd3c 100644 --- a/trunk/drivers/net/wireless/orinoco/hermes.c +++ b/trunk/drivers/net/wireless/orinoco/hermes.c @@ -51,26 +51,6 @@ #define CMD_COMPL_TIMEOUT (20000) /* in iterations of ~10us */ #define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */ -/* - * AUX port access. To unlock the AUX port write the access keys to the - * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL - * register. Then read it and make sure it's HERMES_AUX_ENABLED. - */ -#define HERMES_AUX_ENABLE 0x8000 /* Enable auxiliary port access */ -#define HERMES_AUX_DISABLE 0x4000 /* Disable to auxiliary port access */ -#define HERMES_AUX_ENABLED 0xC000 /* Auxiliary port is open */ -#define HERMES_AUX_DISABLED 0x0000 /* Auxiliary port is closed */ - -#define HERMES_AUX_PW0 0xFE01 -#define HERMES_AUX_PW1 0xDC23 -#define HERMES_AUX_PW2 0xBA45 - -/* HERMES_CMD_DOWNLD */ -#define HERMES_PROGRAM_DISABLE (0x0000 | HERMES_CMD_DOWNLD) -#define HERMES_PROGRAM_ENABLE_VOLATILE (0x0100 | HERMES_CMD_DOWNLD) -#define HERMES_PROGRAM_ENABLE_NON_VOLATILE (0x0200 | HERMES_CMD_DOWNLD) -#define HERMES_PROGRAM_NON_VOLATILE (0x0300 | HERMES_CMD_DOWNLD) - /* * Debugging helpers */ @@ -90,7 +70,6 @@ #endif /* ! HERMES_DEBUG */ -static const struct hermes_ops hermes_ops_local; /* * Internal functions @@ -132,9 +111,9 @@ static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0, */ /* For doing cmds that wipe the magic constant in SWSUPPORT0 */ -static int hermes_doicmd_wait(hermes_t *hw, u16 cmd, - u16 parm0, u16 parm1, u16 parm2, - struct hermes_response *resp) +int hermes_doicmd_wait(hermes_t *hw, u16 cmd, + u16 parm0, u16 parm1, u16 parm2, + struct hermes_response *resp) { int err = 0; int k; @@ -184,18 +163,17 @@ static int hermes_doicmd_wait(hermes_t *hw, u16 cmd, out: return err; } +EXPORT_SYMBOL(hermes_doicmd_wait); void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing) { hw->iobase = address; hw->reg_spacing = reg_spacing; hw->inten = 0x0; - hw->eeprom_pda = false; - hw->ops = &hermes_ops_local; } EXPORT_SYMBOL(hermes_struct_init); -static int hermes_init(hermes_t *hw) +int hermes_init(hermes_t *hw) { u16 reg; int err = 0; @@ -239,6 +217,7 @@ static int hermes_init(hermes_t *hw) return err; } +EXPORT_SYMBOL(hermes_init); /* Issue a command to the chip, and (busy!) wait for it to * complete. @@ -249,8 +228,8 @@ static int hermes_init(hermes_t *hw) * > 0 on error returned by the firmware * * Callable from any context, but locking is your problem. */ -static int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, - struct hermes_response *resp) +int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, + struct hermes_response *resp) { int err; int k; @@ -312,8 +291,9 @@ static int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, out: return err; } +EXPORT_SYMBOL(hermes_docmd_wait); -static int hermes_allocate(hermes_t *hw, u16 size, u16 *fid) +int hermes_allocate(hermes_t *hw, u16 size, u16 *fid) { int err = 0; int k; @@ -353,6 +333,7 @@ static int hermes_allocate(hermes_t *hw, u16 size, u16 *fid) return 0; } +EXPORT_SYMBOL(hermes_allocate); /* Set up a BAP to read a particular chunk of data from card's internal buffer. * @@ -422,8 +403,8 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset) * 0 on success * > 0 on error from firmware */ -static int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len, - u16 id, u16 offset) +int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len, + u16 id, u16 offset) { int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; int err = 0; @@ -441,6 +422,7 @@ static int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len, out: return err; } +EXPORT_SYMBOL(hermes_bap_pread); /* Write a block of data to the chip's buffer, via the * BAP. Synchronization/serialization is the caller's problem. @@ -450,8 +432,8 @@ static int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len, * 0 on success * > 0 on error from firmware */ -static int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len, - u16 id, u16 offset) +int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len, + u16 id, u16 offset) { int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; int err = 0; @@ -469,6 +451,7 @@ static int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len, out: return err; } +EXPORT_SYMBOL(hermes_bap_pwrite); /* Read a Length-Type-Value record from the card. * @@ -478,8 +461,8 @@ static int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len, * practice. * * Callable from user or bh context. */ -static int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize, - u16 *length, void *buf) +int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize, + u16 *length, void *buf) { int err = 0; int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; @@ -522,9 +505,10 @@ static int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize, return 0; } +EXPORT_SYMBOL(hermes_read_ltv); -static int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, - u16 length, const void *value) +int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, + u16 length, const void *value) { int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; int err = 0; @@ -549,228 +533,4 @@ static int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, return err; } - -/*** Hermes AUX control ***/ - -static inline void -hermes_aux_setaddr(hermes_t *hw, u32 addr) -{ - hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7)); - hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F)); -} - -static inline int -hermes_aux_control(hermes_t *hw, int enabled) -{ - int desired_state = enabled ? HERMES_AUX_ENABLED : HERMES_AUX_DISABLED; - int action = enabled ? HERMES_AUX_ENABLE : HERMES_AUX_DISABLE; - int i; - - /* Already open? */ - if (hermes_read_reg(hw, HERMES_CONTROL) == desired_state) - return 0; - - hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0); - hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1); - hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2); - hermes_write_reg(hw, HERMES_CONTROL, action); - - for (i = 0; i < 20; i++) { - udelay(10); - if (hermes_read_reg(hw, HERMES_CONTROL) == - desired_state) - return 0; - } - - return -EBUSY; -} - -/*** Hermes programming ***/ - -/* About to start programming data (Hermes I) - * offset is the entry point - * - * Spectrum_cs' Symbol fw does not require this - * wl_lkm Agere fw does - * Don't know about intersil - */ -static int hermesi_program_init(hermes_t *hw, u32 offset) -{ - int err; - - /* Disable interrupts?*/ - /*hw->inten = 0x0;*/ - /*hermes_write_regn(hw, INTEN, 0);*/ - /*hermes_set_irqmask(hw, 0);*/ - - /* Acknowledge any outstanding command */ - hermes_write_regn(hw, EVACK, 0xFFFF); - - /* Using init_cmd_wait rather than cmd_wait */ - err = hw->ops->init_cmd_wait(hw, - 0x0100 | HERMES_CMD_INIT, - 0, 0, 0, NULL); - if (err) - return err; - - err = hw->ops->init_cmd_wait(hw, - 0x0000 | HERMES_CMD_INIT, - 0, 0, 0, NULL); - if (err) - return err; - - err = hermes_aux_control(hw, 1); - pr_debug("AUX enable returned %d\n", err); - - if (err) - return err; - - pr_debug("Enabling volatile, EP 0x%08x\n", offset); - err = hw->ops->init_cmd_wait(hw, - HERMES_PROGRAM_ENABLE_VOLATILE, - offset & 0xFFFFu, - offset >> 16, - 0, - NULL); - pr_debug("PROGRAM_ENABLE returned %d\n", err); - - return err; -} - -/* Done programming data (Hermes I) - * - * Spectrum_cs' Symbol fw does not require this - * wl_lkm Agere fw does - * Don't know about intersil - */ -static int hermesi_program_end(hermes_t *hw) -{ - struct hermes_response resp; - int rc = 0; - int err; - - rc = hw->ops->cmd_wait(hw, HERMES_PROGRAM_DISABLE, 0, &resp); - - pr_debug("PROGRAM_DISABLE returned %d, " - "r0 0x%04x, r1 0x%04x, r2 0x%04x\n", - rc, resp.resp0, resp.resp1, resp.resp2); - - if ((rc == 0) && - ((resp.status & HERMES_STATUS_CMDCODE) != HERMES_CMD_DOWNLD)) - rc = -EIO; - - err = hermes_aux_control(hw, 0); - pr_debug("AUX disable returned %d\n", err); - - /* Acknowledge any outstanding command */ - hermes_write_regn(hw, EVACK, 0xFFFF); - - /* Reinitialise, ignoring return */ - (void) hw->ops->init_cmd_wait(hw, 0x0000 | HERMES_CMD_INIT, - 0, 0, 0, NULL); - - return rc ? rc : err; -} - -static int hermes_program_bytes(struct hermes *hw, const char *data, - u32 addr, u32 len) -{ - /* wl lkm splits the programming into chunks of 2000 bytes. - * This restriction appears to come from USB. The PCMCIA - * adapters can program the whole lot in one go */ - hermes_aux_setaddr(hw, addr); - hermes_write_bytes(hw, HERMES_AUXDATA, data, len); - return 0; -} - -/* Read PDA from the adapter */ -static int hermes_read_pda(hermes_t *hw, __le16 *pda, u32 pda_addr, u16 pda_len) -{ - int ret; - u16 pda_size; - u16 data_len = pda_len; - __le16 *data = pda; - - if (hw->eeprom_pda) { - /* PDA of spectrum symbol is in eeprom */ - - /* Issue command to read EEPROM */ - ret = hw->ops->cmd_wait(hw, HERMES_CMD_READMIF, 0, NULL); - if (ret) - return ret; - } else { - /* wl_lkm does not include PDA size in the PDA area. - * We will pad the information into pda, so other routines - * don't have to be modified */ - pda[0] = cpu_to_le16(pda_len - 2); - /* Includes CFG_PROD_DATA but not itself */ - pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */ - data_len = pda_len - 4; - data = pda + 2; - } - - /* Open auxiliary port */ - ret = hermes_aux_control(hw, 1); - pr_debug("AUX enable returned %d\n", ret); - if (ret) - return ret; - - /* Read PDA */ - hermes_aux_setaddr(hw, pda_addr); - hermes_read_words(hw, HERMES_AUXDATA, data, data_len / 2); - - /* Close aux port */ - ret = hermes_aux_control(hw, 0); - pr_debug("AUX disable returned %d\n", ret); - - /* Check PDA length */ - pda_size = le16_to_cpu(pda[0]); - pr_debug("Actual PDA length %d, Max allowed %d\n", - pda_size, pda_len); - if (pda_size > pda_len) - return -EINVAL; - - return 0; -} - -static void hermes_lock_irqsave(spinlock_t *lock, - unsigned long *flags) __acquires(lock) -{ - spin_lock_irqsave(lock, *flags); -} - -static void hermes_unlock_irqrestore(spinlock_t *lock, - unsigned long *flags) __releases(lock) -{ - spin_unlock_irqrestore(lock, *flags); -} - -static void hermes_lock_irq(spinlock_t *lock) __acquires(lock) -{ - spin_lock_irq(lock); -} - -static void hermes_unlock_irq(spinlock_t *lock) __releases(lock) -{ - spin_unlock_irq(lock); -} - -/* Hermes operations for local buses */ -static const struct hermes_ops hermes_ops_local = { - .init = hermes_init, - .cmd_wait = hermes_docmd_wait, - .init_cmd_wait = hermes_doicmd_wait, - .allocate = hermes_allocate, - .read_ltv = hermes_read_ltv, - .write_ltv = hermes_write_ltv, - .bap_pread = hermes_bap_pread, - .bap_pwrite = hermes_bap_pwrite, - .read_pda = hermes_read_pda, - .program_init = hermesi_program_init, - .program_end = hermesi_program_end, - .program = hermes_program_bytes, - .lock_irqsave = hermes_lock_irqsave, - .unlock_irqrestore = hermes_unlock_irqrestore, - .lock_irq = hermes_lock_irq, - .unlock_irq = hermes_unlock_irq, -}; +EXPORT_SYMBOL(hermes_write_ltv); diff --git a/trunk/drivers/net/wireless/orinoco/hermes.h b/trunk/drivers/net/wireless/orinoco/hermes.h index 9ca34e722b45..2dddbb597c4d 100644 --- a/trunk/drivers/net/wireless/orinoco/hermes.h +++ b/trunk/drivers/net/wireless/orinoco/hermes.h @@ -374,37 +374,6 @@ struct hermes_multicast { /* Timeouts */ #define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */ -struct hermes; - -/* Functions to access hardware */ -struct hermes_ops { - int (*init)(struct hermes *hw); - int (*cmd_wait)(struct hermes *hw, u16 cmd, u16 parm0, - struct hermes_response *resp); - int (*init_cmd_wait)(struct hermes *hw, u16 cmd, - u16 parm0, u16 parm1, u16 parm2, - struct hermes_response *resp); - int (*allocate)(struct hermes *hw, u16 size, u16 *fid); - int (*read_ltv)(struct hermes *hw, int bap, u16 rid, unsigned buflen, - u16 *length, void *buf); - int (*write_ltv)(struct hermes *hw, int bap, u16 rid, - u16 length, const void *value); - int (*bap_pread)(struct hermes *hw, int bap, void *buf, int len, - u16 id, u16 offset); - int (*bap_pwrite)(struct hermes *hw, int bap, const void *buf, - int len, u16 id, u16 offset); - int (*read_pda)(struct hermes *hw, __le16 *pda, - u32 pda_addr, u16 pda_len); - int (*program_init)(struct hermes *hw, u32 entry_point); - int (*program_end)(struct hermes *hw); - int (*program)(struct hermes *hw, const char *buf, - u32 addr, u32 len); - void (*lock_irqsave)(spinlock_t *lock, unsigned long *flags); - void (*unlock_irqrestore)(spinlock_t *lock, unsigned long *flags); - void (*lock_irq)(spinlock_t *lock); - void (*unlock_irq)(spinlock_t *lock); -}; - /* Basic control structure */ typedef struct hermes { void __iomem *iobase; @@ -412,9 +381,6 @@ typedef struct hermes { #define HERMES_16BIT_REGSPACING 0 #define HERMES_32BIT_REGSPACING 1 u16 inten; /* Which interrupts should be enabled? */ - bool eeprom_pda; - const struct hermes_ops *ops; - void *priv; } hermes_t; /* Register access convenience macros */ @@ -428,6 +394,22 @@ typedef struct hermes { /* Function prototypes */ void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing); +int hermes_init(hermes_t *hw); +int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, + struct hermes_response *resp); +int hermes_doicmd_wait(hermes_t *hw, u16 cmd, + u16 parm0, u16 parm1, u16 parm2, + struct hermes_response *resp); +int hermes_allocate(hermes_t *hw, u16 size, u16 *fid); + +int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len, + u16 id, u16 offset); +int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len, + u16 id, u16 offset); +int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned buflen, + u16 *length, void *buf); +int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, + u16 length, const void *value); /* Inline functions */ @@ -444,13 +426,13 @@ static inline void hermes_set_irqmask(hermes_t *hw, u16 events) static inline int hermes_enable_port(hermes_t *hw, int port) { - return hw->ops->cmd_wait(hw, HERMES_CMD_ENABLE | (port << 8), + return hermes_docmd_wait(hw, HERMES_CMD_ENABLE | (port << 8), 0, NULL); } static inline int hermes_disable_port(hermes_t *hw, int port) { - return hw->ops->cmd_wait(hw, HERMES_CMD_DISABLE | (port << 8), + return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8), 0, NULL); } @@ -458,7 +440,7 @@ static inline int hermes_disable_port(hermes_t *hw, int port) * information frame in __orinoco_ev_info() */ static inline int hermes_inquire(hermes_t *hw, u16 rid) { - return hw->ops->cmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL); + return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL); } #define HERMES_BYTES_TO_RECLEN(n) ((((n)+1)/2) + 1) @@ -493,10 +475,10 @@ static inline void hermes_clear_words(struct hermes *hw, int off, } #define HERMES_READ_RECORD(hw, bap, rid, buf) \ - (hw->ops->read_ltv((hw), (bap), (rid), sizeof(*buf), NULL, (buf))) + (hermes_read_ltv((hw), (bap), (rid), sizeof(*buf), NULL, (buf))) #define HERMES_WRITE_RECORD(hw, bap, rid, buf) \ - (hw->ops->write_ltv((hw), (bap), (rid), \ - HERMES_BYTES_TO_RECLEN(sizeof(*buf)), (buf))) + (hermes_write_ltv((hw), (bap), (rid), \ + HERMES_BYTES_TO_RECLEN(sizeof(*buf)), (buf))) static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word) { diff --git a/trunk/drivers/net/wireless/orinoco/hermes_dld.c b/trunk/drivers/net/wireless/orinoco/hermes_dld.c index 6da85e75fce0..fb157eb889ca 100644 --- a/trunk/drivers/net/wireless/orinoco/hermes_dld.c +++ b/trunk/drivers/net/wireless/orinoco/hermes_dld.c @@ -46,11 +46,37 @@ #define PFX "hermes_dld: " +/* + * AUX port access. To unlock the AUX port write the access keys to the + * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL + * register. Then read it and make sure it's HERMES_AUX_ENABLED. + */ +#define HERMES_AUX_ENABLE 0x8000 /* Enable auxiliary port access */ +#define HERMES_AUX_DISABLE 0x4000 /* Disable to auxiliary port access */ +#define HERMES_AUX_ENABLED 0xC000 /* Auxiliary port is open */ +#define HERMES_AUX_DISABLED 0x0000 /* Auxiliary port is closed */ + +#define HERMES_AUX_PW0 0xFE01 +#define HERMES_AUX_PW1 0xDC23 +#define HERMES_AUX_PW2 0xBA45 + +/* HERMES_CMD_DOWNLD */ +#define HERMES_PROGRAM_DISABLE (0x0000 | HERMES_CMD_DOWNLD) +#define HERMES_PROGRAM_ENABLE_VOLATILE (0x0100 | HERMES_CMD_DOWNLD) +#define HERMES_PROGRAM_ENABLE_NON_VOLATILE (0x0200 | HERMES_CMD_DOWNLD) +#define HERMES_PROGRAM_NON_VOLATILE (0x0300 | HERMES_CMD_DOWNLD) + /* End markers used in dblocks */ #define PDI_END 0x00000000 /* End of PDA */ #define BLOCK_END 0xFFFFFFFF /* Last image block */ #define TEXT_END 0x1A /* End of text header */ +/* Limit the amout we try to download in a single shot. + * Size is in bytes. + */ +#define MAX_DL_SIZE 1024 +#define LIMIT_PROGRAM_SIZE 0 + /* * The following structures have little-endian fields denoted by * the leading underscore. Don't access them directly - use inline @@ -139,6 +165,41 @@ pdi_len(const struct pdi *pdi) return 2 * (le16_to_cpu(pdi->len) - 1); } +/*** Hermes AUX control ***/ + +static inline void +hermes_aux_setaddr(hermes_t *hw, u32 addr) +{ + hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7)); + hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F)); +} + +static inline int +hermes_aux_control(hermes_t *hw, int enabled) +{ + int desired_state = enabled ? HERMES_AUX_ENABLED : HERMES_AUX_DISABLED; + int action = enabled ? HERMES_AUX_ENABLE : HERMES_AUX_DISABLE; + int i; + + /* Already open? */ + if (hermes_read_reg(hw, HERMES_CONTROL) == desired_state) + return 0; + + hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0); + hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1); + hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2); + hermes_write_reg(hw, HERMES_CONTROL, action); + + for (i = 0; i < 20; i++) { + udelay(10); + if (hermes_read_reg(hw, HERMES_CONTROL) == + desired_state) + return 0; + } + + return -EBUSY; +} + /*** Plug Data Functions ***/ /* @@ -210,7 +271,62 @@ hermes_plug_pdi(hermes_t *hw, const struct pdr *first_pdr, return -EINVAL; /* do the actual plugging */ - hw->ops->program(hw, pdi->data, pdr_addr(pdr), pdi_len(pdi)); + hermes_aux_setaddr(hw, pdr_addr(pdr)); + hermes_write_bytes(hw, HERMES_AUXDATA, pdi->data, pdi_len(pdi)); + + return 0; +} + +/* Read PDA from the adapter */ +int hermes_read_pda(hermes_t *hw, + __le16 *pda, + u32 pda_addr, + u16 pda_len, + int use_eeprom) /* can we get this into hw? */ +{ + int ret; + u16 pda_size; + u16 data_len = pda_len; + __le16 *data = pda; + + if (use_eeprom) { + /* PDA of spectrum symbol is in eeprom */ + + /* Issue command to read EEPROM */ + ret = hermes_docmd_wait(hw, HERMES_CMD_READMIF, 0, NULL); + if (ret) + return ret; + } else { + /* wl_lkm does not include PDA size in the PDA area. + * We will pad the information into pda, so other routines + * don't have to be modified */ + pda[0] = cpu_to_le16(pda_len - 2); + /* Includes CFG_PROD_DATA but not itself */ + pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */ + data_len = pda_len - 4; + data = pda + 2; + } + + /* Open auxiliary port */ + ret = hermes_aux_control(hw, 1); + pr_debug(PFX "AUX enable returned %d\n", ret); + if (ret) + return ret; + + /* read PDA from EEPROM */ + hermes_aux_setaddr(hw, pda_addr); + hermes_read_words(hw, HERMES_AUXDATA, data, data_len / 2); + + /* Close aux port */ + ret = hermes_aux_control(hw, 0); + pr_debug(PFX "AUX disable returned %d\n", ret); + + /* Check PDA length */ + pda_size = le16_to_cpu(pda[0]); + pr_debug(PFX "Actual PDA length %d, Max allowed %d\n", + pda_size, pda_len); + if (pda_size > pda_len) + return -EINVAL; return 0; } @@ -273,13 +389,101 @@ hermes_blocks_length(const char *first_block, const void *end) /*** Hermes programming ***/ +/* About to start programming data (Hermes I) + * offset is the entry point + * + * Spectrum_cs' Symbol fw does not require this + * wl_lkm Agere fw does + * Don't know about intersil + */ +int hermesi_program_init(hermes_t *hw, u32 offset) +{ + int err; + + /* Disable interrupts?*/ + /*hw->inten = 0x0;*/ + /*hermes_write_regn(hw, INTEN, 0);*/ + /*hermes_set_irqmask(hw, 0);*/ + + /* Acknowledge any outstanding command */ + hermes_write_regn(hw, EVACK, 0xFFFF); + + /* Using doicmd_wait rather than docmd_wait */ + err = hermes_doicmd_wait(hw, + 0x0100 | HERMES_CMD_INIT, + 0, 0, 0, NULL); + if (err) + return err; + + err = hermes_doicmd_wait(hw, + 0x0000 | HERMES_CMD_INIT, + 0, 0, 0, NULL); + if (err) + return err; + + err = hermes_aux_control(hw, 1); + pr_debug(PFX "AUX enable returned %d\n", err); + + if (err) + return err; + + pr_debug(PFX "Enabling volatile, EP 0x%08x\n", offset); + err = hermes_doicmd_wait(hw, + HERMES_PROGRAM_ENABLE_VOLATILE, + offset & 0xFFFFu, + offset >> 16, + 0, + NULL); + pr_debug(PFX "PROGRAM_ENABLE returned %d\n", err); + + return err; +} + +/* Done programming data (Hermes I) + * + * Spectrum_cs' Symbol fw does not require this + * wl_lkm Agere fw does + * Don't know about intersil + */ +int hermesi_program_end(hermes_t *hw) +{ + struct hermes_response resp; + int rc = 0; + int err; + + rc = hermes_docmd_wait(hw, HERMES_PROGRAM_DISABLE, 0, &resp); + + pr_debug(PFX "PROGRAM_DISABLE returned %d, " + "r0 0x%04x, r1 0x%04x, r2 0x%04x\n", + rc, resp.resp0, resp.resp1, resp.resp2); + + if ((rc == 0) && + ((resp.status & HERMES_STATUS_CMDCODE) != HERMES_CMD_DOWNLD)) + rc = -EIO; + + err = hermes_aux_control(hw, 0); + pr_debug(PFX "AUX disable returned %d\n", err); + + /* Acknowledge any outstanding command */ + hermes_write_regn(hw, EVACK, 0xFFFF); + + /* Reinitialise, ignoring return */ + (void) hermes_doicmd_wait(hw, 0x0000 | HERMES_CMD_INIT, + 0, 0, 0, NULL); + + return rc ? rc : err; +} + /* Program the data blocks */ int hermes_program(hermes_t *hw, const char *first_block, const void *end) { const struct dblock *blk; u32 blkaddr; u32 blklen; - int err = 0; +#if LIMIT_PROGRAM_SIZE + u32 addr; + u32 len; +#endif blk = (const struct dblock *) first_block; @@ -294,10 +498,30 @@ int hermes_program(hermes_t *hw, const char *first_block, const void *end) pr_debug(PFX "Programming block of length %d " "to address 0x%08x\n", blklen, blkaddr); - err = hw->ops->program(hw, blk->data, blkaddr, blklen); - if (err) - break; - +#if !LIMIT_PROGRAM_SIZE + /* wl_lkm driver splits this into writes of 2000 bytes */ + hermes_aux_setaddr(hw, blkaddr); + hermes_write_bytes(hw, HERMES_AUXDATA, blk->data, + blklen); +#else + len = (blklen < MAX_DL_SIZE) ? blklen : MAX_DL_SIZE; + addr = blkaddr; + + while (addr < (blkaddr + blklen)) { + pr_debug(PFX "Programming subblock of length %d " + "to address 0x%08x. Data @ %p\n", + len, addr, &blk->data[addr - blkaddr]); + + hermes_aux_setaddr(hw, addr); + hermes_write_bytes(hw, HERMES_AUXDATA, + &blk->data[addr - blkaddr], + len); + + addr += len; + len = ((blkaddr + blklen - addr) < MAX_DL_SIZE) ? + (blkaddr + blklen - addr) : MAX_DL_SIZE; + } +#endif blk = (const struct dblock *) &blk->data[blklen]; if ((void *) blk > (end - sizeof(*blk))) @@ -306,7 +530,7 @@ int hermes_program(hermes_t *hw, const char *first_block, const void *end) blkaddr = dblock_addr(blk); blklen = dblock_len(blk); } - return err; + return 0; } /*** Default plugging data for Hermes I ***/ @@ -466,8 +690,9 @@ int hermes_apply_pda_with_defaults(hermes_t *hw, if ((pdi_len(pdi) == pdr_len(pdr)) && ((void *) pdi->data + pdi_len(pdi) < pda_end)) { /* do the actual plugging */ - hw->ops->program(hw, pdi->data, pdr_addr(pdr), - pdi_len(pdi)); + hermes_aux_setaddr(hw, pdr_addr(pdr)); + hermes_write_bytes(hw, HERMES_AUXDATA, + pdi->data, pdi_len(pdi)); } } diff --git a/trunk/drivers/net/wireless/orinoco/hw.c b/trunk/drivers/net/wireless/orinoco/hw.c index 6fbd78850123..741f8cea95b9 100644 --- a/trunk/drivers/net/wireless/orinoco/hw.c +++ b/trunk/drivers/net/wireless/orinoco/hw.c @@ -177,9 +177,9 @@ int determine_fw_capabilities(struct orinoco_private *priv, /* 3Com MAC : 00:50:DA:* */ memset(tmp, 0, sizeof(tmp)); /* Get the Symbol firmware version */ - err = hw->ops->read_ltv(hw, USER_BAP, - HERMES_RID_SECONDARYVERSION_SYMBOL, - SYMBOL_MAX_VER_LEN, NULL, &tmp); + err = hermes_read_ltv(hw, USER_BAP, + HERMES_RID_SECONDARYVERSION_SYMBOL, + SYMBOL_MAX_VER_LEN, NULL, &tmp); if (err) { dev_warn(dev, "Error %d reading Symbol firmware info. " "Wildly guessing capabilities...\n", err); @@ -286,8 +286,8 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr) u16 reclen; /* Get the MAC address */ - err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, - ETH_ALEN, NULL, dev_addr); + err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, + ETH_ALEN, NULL, dev_addr); if (err) { dev_warn(dev, "Failed to read MAC address!\n"); goto out; @@ -296,8 +296,8 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr) dev_dbg(dev, "MAC address %pM\n", dev_addr); /* Get the station name */ - err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, - sizeof(nickbuf), &reclen, &nickbuf); + err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, + sizeof(nickbuf), &reclen, &nickbuf); if (err) { dev_err(dev, "failed to read station name\n"); goto out; @@ -413,11 +413,11 @@ int orinoco_hw_allocate_fid(struct orinoco_private *priv) struct hermes *hw = &priv->hw; int err; - err = hw->ops->allocate(hw, priv->nicbuf_size, &priv->txfid); + err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) { /* Try workaround for old Symbol firmware bug */ priv->nicbuf_size = TX_NICBUF_SIZE_BUG; - err = hw->ops->allocate(hw, priv->nicbuf_size, &priv->txfid); + err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); dev_warn(dev, "Firmware ALLOC bug detected " "(old Symbol firmware?). Work around %s\n", @@ -463,9 +463,8 @@ int orinoco_hw_program_rids(struct orinoco_private *priv) struct hermes_idstring idbuf; /* Set the MAC address */ - err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, - HERMES_BYTES_TO_RECLEN(ETH_ALEN), - dev->dev_addr); + err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, + HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr); if (err) { printk(KERN_ERR "%s: Error %d setting MAC address\n", dev->name, err); @@ -528,7 +527,7 @@ int orinoco_hw_program_rids(struct orinoco_private *priv) idbuf.len = cpu_to_le16(strlen(priv->desired_essid)); memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val)); /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */ - err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID, + err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID, HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), &idbuf); if (err) { @@ -536,7 +535,7 @@ int orinoco_hw_program_rids(struct orinoco_private *priv) dev->name, err); return err; } - err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID, + err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID, HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), &idbuf); if (err) { @@ -548,9 +547,9 @@ int orinoco_hw_program_rids(struct orinoco_private *priv) /* Set the station name */ idbuf.len = cpu_to_le16(strlen(priv->nick)); memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val)); - err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, - HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2), - &idbuf); + err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, + HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2), + &idbuf); if (err) { printk(KERN_ERR "%s: Error %d setting nickname\n", dev->name, err); @@ -665,12 +664,12 @@ int orinoco_hw_program_rids(struct orinoco_private *priv) if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { /* Enable monitor mode */ dev->type = ARPHRD_IEEE80211; - err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST | + err = hermes_docmd_wait(hw, HERMES_CMD_TEST | HERMES_TEST_MONITOR, 0, NULL); } else { /* Disable monitor mode */ dev->type = ARPHRD_ETHER; - err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST | + err = hermes_docmd_wait(hw, HERMES_CMD_TEST | HERMES_TEST_STOP, 0, NULL); } if (err) @@ -696,8 +695,8 @@ int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc) if ((key < 0) || (key >= 4)) return -EINVAL; - err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV, - sizeof(tsc_arr), NULL, &tsc_arr); + err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV, + sizeof(tsc_arr), NULL, &tsc_arr); if (!err) memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0])); @@ -876,7 +875,7 @@ int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv) memcpy(key, priv->keys[i].key, priv->keys[i].key_len); - err = hw->ops->write_ltv(hw, USER_BAP, + err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDEFAULTKEY0 + i, HERMES_BYTES_TO_RECLEN(keylen), key); @@ -1093,7 +1092,7 @@ int __orinoco_hw_set_multicast_list(struct orinoco_private *priv, memcpy(mclist.addr[i++], ha->addr, ETH_ALEN); } - err = hw->ops->write_ltv(hw, USER_BAP, + err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES, HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN), &mclist); @@ -1135,15 +1134,15 @@ int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID : HERMES_RID_CNFDESIREDSSID; - err = hw->ops->read_ltv(hw, USER_BAP, rid, sizeof(essidbuf), - NULL, &essidbuf); + err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf), + NULL, &essidbuf); if (err) goto fail_unlock; } else { *active = 0; - err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID, - sizeof(essidbuf), NULL, &essidbuf); + err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID, + sizeof(essidbuf), NULL, &essidbuf); if (err) goto fail_unlock; } @@ -1214,8 +1213,8 @@ int orinoco_hw_get_bitratelist(struct orinoco_private *priv, if (orinoco_lock(priv, &flags) != 0) return -EBUSY; - err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES, - sizeof(list), NULL, &list); + err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES, + sizeof(list), NULL, &list); orinoco_unlock(priv, &flags); if (err) @@ -1282,7 +1281,7 @@ int orinoco_hw_trigger_scan(struct orinoco_private *priv, idbuf.len = cpu_to_le16(len); memcpy(idbuf.val, ssid->ssid, len); - err = hw->ops->write_ltv(hw, USER_BAP, + err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFSCANSSID_AGERE, HERMES_BYTES_TO_RECLEN(len + 2), &idbuf); @@ -1346,8 +1345,8 @@ int orinoco_hw_get_current_bssid(struct orinoco_private *priv, hermes_t *hw = &priv->hw; int err; - err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID, - ETH_ALEN, NULL, addr); + err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID, + ETH_ALEN, NULL, addr); return err; } diff --git a/trunk/drivers/net/wireless/orinoco/main.c b/trunk/drivers/net/wireless/orinoco/main.c index 1d60c7e4392a..413e9ab6cab3 100644 --- a/trunk/drivers/net/wireless/orinoco/main.c +++ b/trunk/drivers/net/wireless/orinoco/main.c @@ -254,7 +254,7 @@ void set_port_type(struct orinoco_private *priv) /* Device methods */ /********************************************************************/ -int orinoco_open(struct net_device *dev) +static int orinoco_open(struct net_device *dev) { struct orinoco_private *priv = ndev_priv(dev); unsigned long flags; @@ -272,9 +272,8 @@ int orinoco_open(struct net_device *dev) return err; } -EXPORT_SYMBOL(orinoco_open); -int orinoco_stop(struct net_device *dev) +static int orinoco_stop(struct net_device *dev) { struct orinoco_private *priv = ndev_priv(dev); int err = 0; @@ -282,27 +281,25 @@ int orinoco_stop(struct net_device *dev) /* We mustn't use orinoco_lock() here, because we need to be able to close the interface even if hw_unavailable is set (e.g. as we're released after a PC Card removal) */ - orinoco_lock_irq(priv); + spin_lock_irq(&priv->lock); priv->open = 0; err = __orinoco_down(priv); - orinoco_unlock_irq(priv); + spin_unlock_irq(&priv->lock); return err; } -EXPORT_SYMBOL(orinoco_stop); -struct net_device_stats *orinoco_get_stats(struct net_device *dev) +static struct net_device_stats *orinoco_get_stats(struct net_device *dev) { struct orinoco_private *priv = ndev_priv(dev); return &priv->stats; } -EXPORT_SYMBOL(orinoco_get_stats); -void orinoco_set_multicast_list(struct net_device *dev) +static void orinoco_set_multicast_list(struct net_device *dev) { struct orinoco_private *priv = ndev_priv(dev); unsigned long flags; @@ -316,9 +313,8 @@ void orinoco_set_multicast_list(struct net_device *dev) __orinoco_set_multicast_list(dev); orinoco_unlock(priv, &flags); } -EXPORT_SYMBOL(orinoco_set_multicast_list); -int orinoco_change_mtu(struct net_device *dev, int new_mtu) +static int orinoco_change_mtu(struct net_device *dev, int new_mtu) { struct orinoco_private *priv = ndev_priv(dev); @@ -334,7 +330,6 @@ int orinoco_change_mtu(struct net_device *dev, int new_mtu) return 0; } -EXPORT_SYMBOL(orinoco_change_mtu); /********************************************************************/ /* Tx path */ @@ -405,8 +400,8 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) memset(&desc, 0, sizeof(desc)); *txcntl = cpu_to_le16(tx_control); - err = hw->ops->bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), - txfid, 0); + err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), + txfid, 0); if (err) { if (net_ratelimit()) printk(KERN_ERR "%s: Error %d writing Tx " @@ -419,8 +414,8 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) memset(&desc, 0, sizeof(desc)); desc.tx_control = cpu_to_le16(tx_control); - err = hw->ops->bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), - txfid, 0); + err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), + txfid, 0); if (err) { if (net_ratelimit()) printk(KERN_ERR "%s: Error %d writing Tx " @@ -463,8 +458,8 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) memcpy(eh, &hdr, sizeof(hdr)); } - err = hw->ops->bap_pwrite(hw, USER_BAP, skb->data, skb->len, - txfid, HERMES_802_3_OFFSET); + err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len, + txfid, HERMES_802_3_OFFSET); if (err) { printk(KERN_ERR "%s: Error %d writing packet to BAP\n", dev->name, err); @@ -495,8 +490,8 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic); /* Write the MIC */ - err = hw->ops->bap_pwrite(hw, USER_BAP, &mic_buf[0], len, - txfid, HERMES_802_3_OFFSET + offset); + err = hermes_bap_pwrite(hw, USER_BAP, &mic_buf[0], len, + txfid, HERMES_802_3_OFFSET + offset); if (err) { printk(KERN_ERR "%s: Error %d writing MIC to BAP\n", dev->name, err); @@ -507,7 +502,7 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) /* Finally, we actually initiate the send */ netif_stop_queue(dev); - err = hw->ops->cmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, + err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, txfid, NULL); if (err) { netif_start_queue(dev); @@ -577,9 +572,9 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw) return; /* Nothing's really happened */ /* Read part of the frame header - we need status and addr1 */ - err = hw->ops->bap_pread(hw, IRQ_BAP, &hdr, - sizeof(struct hermes_txexc_data), - fid, 0); + err = hermes_bap_pread(hw, IRQ_BAP, &hdr, + sizeof(struct hermes_txexc_data), + fid, 0); hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID); stats->tx_errors++; @@ -620,7 +615,7 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw) netif_wake_queue(dev); } -void orinoco_tx_timeout(struct net_device *dev) +static void orinoco_tx_timeout(struct net_device *dev) { struct orinoco_private *priv = ndev_priv(dev); struct net_device_stats *stats = &priv->stats; @@ -635,7 +630,6 @@ void orinoco_tx_timeout(struct net_device *dev) schedule_work(&priv->reset_work); } -EXPORT_SYMBOL(orinoco_tx_timeout); /********************************************************************/ /* Rx path (data frames) */ @@ -770,9 +764,9 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid, /* If any, copy the data from the card to the skb */ if (datalen > 0) { - err = hw->ops->bap_pread(hw, IRQ_BAP, skb_put(skb, datalen), - ALIGN(datalen, 2), rxfid, - HERMES_802_2_OFFSET); + err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen), + ALIGN(datalen, 2), rxfid, + HERMES_802_2_OFFSET); if (err) { printk(KERN_ERR "%s: error %d reading monitor frame\n", dev->name, err); @@ -798,7 +792,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid, stats->rx_dropped++; } -void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) +static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) { struct orinoco_private *priv = ndev_priv(dev); struct net_device_stats *stats = &priv->stats; @@ -820,8 +814,8 @@ void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) rxfid = hermes_read_regn(hw, RXFID); - err = hw->ops->bap_pread(hw, IRQ_BAP, desc, sizeof(*desc), - rxfid, 0); + err = hermes_bap_pread(hw, IRQ_BAP, desc, sizeof(*desc), + rxfid, 0); if (err) { printk(KERN_ERR "%s: error %d reading Rx descriptor. " "Frame dropped.\n", dev->name, err); @@ -888,9 +882,9 @@ void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) nothing is removed. 2 is for aligning the IP header. */ skb_reserve(skb, ETH_HLEN + 2); - err = hw->ops->bap_pread(hw, IRQ_BAP, skb_put(skb, length), - ALIGN(length, 2), rxfid, - HERMES_802_2_OFFSET); + err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length), + ALIGN(length, 2), rxfid, + HERMES_802_2_OFFSET); if (err) { printk(KERN_ERR "%s: error %d reading frame. " "Frame dropped.\n", dev->name, err); @@ -919,7 +913,6 @@ void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) out: kfree(desc); } -EXPORT_SYMBOL(__orinoco_ev_rx); static void orinoco_rx(struct net_device *dev, struct hermes_rx_descriptor *desc, @@ -1152,9 +1145,9 @@ static void orinoco_join_ap(struct work_struct *work) goto out; /* Read scan results from the firmware */ - err = hw->ops->read_ltv(hw, USER_BAP, - HERMES_RID_SCANRESULTSTABLE, - MAX_SCAN_LEN, &len, buf); + err = hermes_read_ltv(hw, USER_BAP, + HERMES_RID_SCANRESULTSTABLE, + MAX_SCAN_LEN, &len, buf); if (err) { printk(KERN_ERR "%s: Cannot read scan results\n", dev->name); @@ -1201,8 +1194,8 @@ static void orinoco_send_bssid_wevent(struct orinoco_private *priv) union iwreq_data wrqu; int err; - err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID, - ETH_ALEN, NULL, wrqu.ap_addr.sa_data); + err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID, + ETH_ALEN, NULL, wrqu.ap_addr.sa_data); if (err != 0) return; @@ -1224,8 +1217,8 @@ static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv) if (!priv->has_wpa) return; - err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO, - sizeof(buf), NULL, &buf); + err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO, + sizeof(buf), NULL, &buf); if (err != 0) return; @@ -1254,9 +1247,8 @@ static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv) if (!priv->has_wpa) return; - err = hw->ops->read_ltv(hw, USER_BAP, - HERMES_RID_CURRENT_ASSOC_RESP_INFO, - sizeof(buf), NULL, &buf); + err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO, + sizeof(buf), NULL, &buf); if (err != 0) return; @@ -1361,7 +1353,7 @@ static void orinoco_process_scan_results(struct work_struct *work) spin_unlock_irqrestore(&priv->scan_lock, flags); } -void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) +static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) { struct orinoco_private *priv = ndev_priv(dev); u16 infofid; @@ -1379,8 +1371,8 @@ void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) infofid = hermes_read_regn(hw, INFOFID); /* Read the info frame header - don't try too hard */ - err = hw->ops->bap_pread(hw, IRQ_BAP, &info, sizeof(info), - infofid, 0); + err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info), + infofid, 0); if (err) { printk(KERN_ERR "%s: error %d reading info frame. " "Frame dropped.\n", dev->name, err); @@ -1401,8 +1393,8 @@ void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) len = sizeof(tallies); } - err = hw->ops->bap_pread(hw, IRQ_BAP, &tallies, len, - infofid, sizeof(info)); + err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len, + infofid, sizeof(info)); if (err) break; @@ -1437,8 +1429,8 @@ void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) break; } - err = hw->ops->bap_pread(hw, IRQ_BAP, &linkstatus, len, - infofid, sizeof(info)); + err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len, + infofid, sizeof(info)); if (err) break; newstatus = le16_to_cpu(linkstatus.linkstatus); @@ -1502,8 +1494,8 @@ void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) } /* Read scan data */ - err = hw->ops->bap_pread(hw, IRQ_BAP, (void *) buf, len, - infofid, sizeof(info)); + err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len, + infofid, sizeof(info)); if (err) { kfree(buf); qabort_scan(priv); @@ -1555,8 +1547,8 @@ void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) break; /* Read scan data */ - err = hw->ops->bap_pread(hw, IRQ_BAP, (void *) bss, len, - infofid, sizeof(info)); + err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len, + infofid, sizeof(info)); if (err) kfree(bss); else @@ -1579,7 +1571,6 @@ void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) return; } -EXPORT_SYMBOL(__orinoco_ev_info); static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw) { @@ -1656,7 +1647,7 @@ static int orinoco_reinit_firmware(struct orinoco_private *priv) struct hermes *hw = &priv->hw; int err; - err = hw->ops->init(hw); + err = hermes_init(hw); if (priv->do_fw_download && !err) { err = orinoco_download(priv); if (err) @@ -1744,7 +1735,7 @@ void orinoco_reset(struct work_struct *work) } /* This has to be called from user context */ - orinoco_lock_irq(priv); + spin_lock_irq(&priv->lock); priv->hw_unavailable--; @@ -1759,7 +1750,7 @@ void orinoco_reset(struct work_struct *work) dev->trans_start = jiffies; } - orinoco_unlock_irq(priv); + spin_unlock_irq(&priv->lock); return; disable: @@ -1993,7 +1984,7 @@ int orinoco_init(struct orinoco_private *priv) priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN; /* Initialize the firmware */ - err = hw->ops->init(hw); + err = hermes_init(hw); if (err != 0) { dev_err(dev, "Failed to initialize firmware (err = %d)\n", err); @@ -2076,9 +2067,9 @@ int orinoco_init(struct orinoco_private *priv) /* Make the hardware available, as long as it hasn't been * removed elsewhere (e.g. by PCMCIA hot unplug) */ - orinoco_lock_irq(priv); + spin_lock_irq(&priv->lock); priv->hw_unavailable--; - orinoco_unlock_irq(priv); + spin_unlock_irq(&priv->lock); dev_dbg(dev, "Ready\n"); @@ -2201,8 +2192,7 @@ EXPORT_SYMBOL(alloc_orinocodev); */ int orinoco_if_add(struct orinoco_private *priv, unsigned long base_addr, - unsigned int irq, - const struct net_device_ops *ops) + unsigned int irq) { struct wiphy *wiphy = priv_to_wiphy(priv); struct wireless_dev *wdev; @@ -2221,17 +2211,12 @@ int orinoco_if_add(struct orinoco_private *priv, /* Setup / override net_device fields */ dev->ieee80211_ptr = wdev; + dev->netdev_ops = &orinoco_netdev_ops; dev->watchdog_timeo = HZ; /* 1 second timeout */ dev->wireless_handlers = &orinoco_handler_def; #ifdef WIRELESS_SPY dev->wireless_data = &priv->wireless_data; #endif - /* Default to standard ops if not set */ - if (ops) - dev->netdev_ops = ops; - else - dev->netdev_ops = &orinoco_netdev_ops; - /* we use the default eth_mac_addr for setting the MAC addr */ /* Reserve space in skb for the SNAP header */ @@ -2320,7 +2305,7 @@ int orinoco_up(struct orinoco_private *priv) unsigned long flags; int err; - priv->hw.ops->lock_irqsave(&priv->lock, &flags); + spin_lock_irqsave(&priv->lock, flags); err = orinoco_reinit_firmware(priv); if (err) { @@ -2340,7 +2325,7 @@ int orinoco_up(struct orinoco_private *priv) } exit: - priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); + spin_unlock_irqrestore(&priv->lock, flags); return 0; } @@ -2352,7 +2337,7 @@ void orinoco_down(struct orinoco_private *priv) unsigned long flags; int err; - priv->hw.ops->lock_irqsave(&priv->lock, &flags); + spin_lock_irqsave(&priv->lock, flags); err = __orinoco_down(priv); if (err) printk(KERN_WARNING "%s: Error %d downing interface\n", @@ -2360,7 +2345,7 @@ void orinoco_down(struct orinoco_private *priv) netif_device_detach(dev); priv->hw_unavailable++; - priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); + spin_unlock_irqrestore(&priv->lock, flags); } EXPORT_SYMBOL(orinoco_down); diff --git a/trunk/drivers/net/wireless/orinoco/orinoco.h b/trunk/drivers/net/wireless/orinoco/orinoco.h index e9f415a56d4d..ff6b7b1d421d 100644 --- a/trunk/drivers/net/wireless/orinoco/orinoco.h +++ b/trunk/drivers/net/wireless/orinoco/orinoco.h @@ -190,24 +190,12 @@ extern void free_orinocodev(struct orinoco_private *priv); extern int orinoco_init(struct orinoco_private *priv); extern int orinoco_if_add(struct orinoco_private *priv, unsigned long base_addr, - unsigned int irq, - const struct net_device_ops *ops); + unsigned int irq); extern void orinoco_if_del(struct orinoco_private *priv); extern int orinoco_up(struct orinoco_private *priv); extern void orinoco_down(struct orinoco_private *priv); extern irqreturn_t orinoco_interrupt(int irq, void *dev_id); -extern void __orinoco_ev_info(struct net_device *dev, hermes_t *hw); -extern void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw); - -/* Common ndo functions exported for reuse by orinoco_usb */ -int orinoco_open(struct net_device *dev); -int orinoco_stop(struct net_device *dev); -struct net_device_stats *orinoco_get_stats(struct net_device *dev); -void orinoco_set_multicast_list(struct net_device *dev); -int orinoco_change_mtu(struct net_device *dev, int new_mtu); -void orinoco_tx_timeout(struct net_device *dev); - /********************************************************************/ /* Locking and synchronization functions */ /********************************************************************/ @@ -215,11 +203,11 @@ void orinoco_tx_timeout(struct net_device *dev); static inline int orinoco_lock(struct orinoco_private *priv, unsigned long *flags) { - priv->hw.ops->lock_irqsave(&priv->lock, flags); + spin_lock_irqsave(&priv->lock, *flags); if (priv->hw_unavailable) { DEBUG(1, "orinoco_lock() called with hw_unavailable (dev=%p)\n", priv->ndev); - priv->hw.ops->unlock_irqrestore(&priv->lock, flags); + spin_unlock_irqrestore(&priv->lock, *flags); return -EBUSY; } return 0; @@ -228,17 +216,7 @@ static inline int orinoco_lock(struct orinoco_private *priv, static inline void orinoco_unlock(struct orinoco_private *priv, unsigned long *flags) { - priv->hw.ops->unlock_irqrestore(&priv->lock, flags); -} - -static inline void orinoco_lock_irq(struct orinoco_private *priv) -{ - priv->hw.ops->lock_irq(&priv->lock); -} - -static inline void orinoco_unlock_irq(struct orinoco_private *priv) -{ - priv->hw.ops->unlock_irq(&priv->lock); + spin_unlock_irqrestore(&priv->lock, *flags); } /*** Navigate from net_device to orinoco_private ***/ diff --git a/trunk/drivers/net/wireless/orinoco/orinoco_cs.c b/trunk/drivers/net/wireless/orinoco/orinoco_cs.c index f99b13ba92b3..fdc961379170 100644 --- a/trunk/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/trunk/drivers/net/wireless/orinoco/orinoco_cs.c @@ -296,7 +296,7 @@ orinoco_cs_config(struct pcmcia_device *link) /* Register an interface with the stack */ if (orinoco_if_add(priv, link->io.BasePort1, - link->irq.AssignedIRQ, NULL) != 0) { + link->irq.AssignedIRQ) != 0) { printk(KERN_ERR PFX "orinoco_if_add() failed\n"); goto failed; } @@ -327,9 +327,9 @@ orinoco_cs_release(struct pcmcia_device *link) /* We're committed to taking the device away now, so mark the * hardware as unavailable */ - priv->hw.ops->lock_irqsave(&priv->lock, &flags); + spin_lock_irqsave(&priv->lock, flags); priv->hw_unavailable++; - priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); + spin_unlock_irqrestore(&priv->lock, flags); pcmcia_disable_device(link); if (priv->hw.iobase) diff --git a/trunk/drivers/net/wireless/orinoco/orinoco_nortel.c b/trunk/drivers/net/wireless/orinoco/orinoco_nortel.c index bc3ea0b67a4f..075f446b3139 100644 --- a/trunk/drivers/net/wireless/orinoco/orinoco_nortel.c +++ b/trunk/drivers/net/wireless/orinoco/orinoco_nortel.c @@ -220,7 +220,7 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev, goto fail; } - err = orinoco_if_add(priv, 0, 0, NULL); + err = orinoco_if_add(priv, 0, 0); if (err) { printk(KERN_ERR PFX "orinoco_if_add() failed\n"); goto fail; diff --git a/trunk/drivers/net/wireless/orinoco/orinoco_pci.c b/trunk/drivers/net/wireless/orinoco/orinoco_pci.c index 468197f86673..bda5317cc596 100644 --- a/trunk/drivers/net/wireless/orinoco/orinoco_pci.c +++ b/trunk/drivers/net/wireless/orinoco/orinoco_pci.c @@ -170,7 +170,7 @@ static int orinoco_pci_init_one(struct pci_dev *pdev, goto fail; } - err = orinoco_if_add(priv, 0, 0, NULL); + err = orinoco_if_add(priv, 0, 0); if (err) { printk(KERN_ERR PFX "orinoco_if_add() failed\n"); goto fail; diff --git a/trunk/drivers/net/wireless/orinoco/orinoco_plx.c b/trunk/drivers/net/wireless/orinoco/orinoco_plx.c index 9358f4d2307b..e0d5874ab42f 100644 --- a/trunk/drivers/net/wireless/orinoco/orinoco_plx.c +++ b/trunk/drivers/net/wireless/orinoco/orinoco_plx.c @@ -259,7 +259,7 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, goto fail; } - err = orinoco_if_add(priv, 0, 0, NULL); + err = orinoco_if_add(priv, 0, 0); if (err) { printk(KERN_ERR PFX "orinoco_if_add() failed\n"); goto fail; diff --git a/trunk/drivers/net/wireless/orinoco/orinoco_tmd.c b/trunk/drivers/net/wireless/orinoco/orinoco_tmd.c index 784605f0af15..88cbc7902aa0 100644 --- a/trunk/drivers/net/wireless/orinoco/orinoco_tmd.c +++ b/trunk/drivers/net/wireless/orinoco/orinoco_tmd.c @@ -156,7 +156,7 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev, goto fail; } - err = orinoco_if_add(priv, 0, 0, NULL); + err = orinoco_if_add(priv, 0, 0); if (err) { printk(KERN_ERR PFX "orinoco_if_add() failed\n"); goto fail; diff --git a/trunk/drivers/net/wireless/orinoco/orinoco_usb.c b/trunk/drivers/net/wireless/orinoco/orinoco_usb.c deleted file mode 100644 index e22093359f3e..000000000000 --- a/trunk/drivers/net/wireless/orinoco/orinoco_usb.c +++ /dev/null @@ -1,1800 +0,0 @@ -/* - * USB Orinoco driver - * - * Copyright (c) 2003 Manuel Estrada Sainz - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License - * at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and - * limitations under the License. - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License version 2 (the "GPL"), in - * which case the provisions of the GPL are applicable instead of the - * above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use your - * version of this file under the MPL, indicate your decision by - * deleting the provisions above and replace them with the notice and - * other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file - * under either the MPL or the GPL. - * - * Queueing code based on linux-wlan-ng 0.2.1-pre5 - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * - * The license is the same as above. - * - * Initialy based on USB Skeleton driver - 0.7 - * - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.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. - * - * NOTE: The original USB Skeleton driver is GPL, but all that code is - * gone so MPL/GPL applies. - */ - -#define DRIVER_NAME "orinoco_usb" -#define PFX DRIVER_NAME ": " - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "orinoco.h" - -#ifndef URB_ASYNC_UNLINK -#define URB_ASYNC_UNLINK 0 -#endif - -/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */ -static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; -#define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2) - -struct header_struct { - /* 802.3 */ - u8 dest[ETH_ALEN]; - u8 src[ETH_ALEN]; - __be16 len; - /* 802.2 */ - u8 dsap; - u8 ssap; - u8 ctrl; - /* SNAP */ - u8 oui[3]; - __be16 ethertype; -} __attribute__ ((packed)); - -struct ez_usb_fw { - u16 size; - const u8 *code; -}; - -static struct ez_usb_fw firmware = { - .size = 0, - .code = NULL, -}; - -#ifdef CONFIG_USB_DEBUG -static int debug = 1; -#else -static int debug; -#endif - -/* Debugging macros */ -#undef dbg -#define dbg(format, arg...) \ - do { if (debug) printk(KERN_DEBUG PFX "%s: " format "\n", \ - __func__ , ## arg); } while (0) -#undef err -#define err(format, arg...) \ - do { printk(KERN_ERR PFX format "\n", ## arg); } while (0) - -/* Module paramaters */ -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Debug enabled or not"); - -MODULE_FIRMWARE("orinoco_ezusb_fw"); - -/* - * Under some conditions, the card gets stuck and stops paying attention - * to the world (i.e. data communication stalls) until we do something to - * it. Sending an INQ_TALLIES command seems to be enough and should be - * harmless otherwise. This behaviour has been observed when using the - * driver on a systemimager client during installation. In the past a - * timer was used to send INQ_TALLIES commands when there was no other - * activity, but it was troublesome and was removed. - */ - -#define USB_COMPAQ_VENDOR_ID 0x049f /* Compaq Computer Corp. */ -#define USB_COMPAQ_WL215_ID 0x001f /* Compaq WL215 USB Adapter */ -#define USB_COMPAQ_W200_ID 0x0076 /* Compaq W200 USB Adapter */ -#define USB_HP_WL215_ID 0x0082 /* Compaq WL215 USB Adapter */ - -#define USB_MELCO_VENDOR_ID 0x0411 -#define USB_BUFFALO_L11_ID 0x0006 /* BUFFALO WLI-USB-L11 */ -#define USB_BUFFALO_L11G_WR_ID 0x000B /* BUFFALO WLI-USB-L11G-WR */ -#define USB_BUFFALO_L11G_ID 0x000D /* BUFFALO WLI-USB-L11G */ - -#define USB_LUCENT_VENDOR_ID 0x047E /* Lucent Technologies */ -#define USB_LUCENT_ORINOCO_ID 0x0300 /* Lucent/Agere Orinoco USB Client */ - -#define USB_AVAYA8_VENDOR_ID 0x0D98 -#define USB_AVAYAE_VENDOR_ID 0x0D9E -#define USB_AVAYA_WIRELESS_ID 0x0300 /* Avaya Wireless USB Card */ - -#define USB_AGERE_VENDOR_ID 0x0D4E /* Agere Systems */ -#define USB_AGERE_MODEL0801_ID 0x1000 /* Wireless USB Card Model 0801 */ -#define USB_AGERE_MODEL0802_ID 0x1001 /* Wireless USB Card Model 0802 */ -#define USB_AGERE_REBRANDED_ID 0x047A /* WLAN USB Card */ - -#define USB_ELSA_VENDOR_ID 0x05CC -#define USB_ELSA_AIRLANCER_ID 0x3100 /* ELSA AirLancer USB-11 */ - -#define USB_LEGEND_VENDOR_ID 0x0E7C -#define USB_LEGEND_JOYNET_ID 0x0300 /* Joynet WLAN USB Card */ - -#define USB_SAMSUNG_VENDOR_ID 0x04E8 -#define USB_SAMSUNG_SEW2001U1_ID 0x5002 /* Samsung SEW-2001u Card */ -#define USB_SAMSUNG_SEW2001U2_ID 0x5B11 /* Samsung SEW-2001u Card */ -#define USB_SAMSUNG_SEW2003U_ID 0x7011 /* Samsung SEW-2003U Card */ - -#define USB_IGATE_VENDOR_ID 0x0681 -#define USB_IGATE_IGATE_11M_ID 0x0012 /* I-GATE 11M USB Card */ - -#define USB_FUJITSU_VENDOR_ID 0x0BF8 -#define USB_FUJITSU_E1100_ID 0x1002 /* connect2AIR WLAN E-1100 USB */ - -#define USB_2WIRE_VENDOR_ID 0x1630 -#define USB_2WIRE_WIRELESS_ID 0xff81 /* 2Wire Wireless USB adapter */ - - -#define EZUSB_REQUEST_FW_TRANS 0xA0 -#define EZUSB_REQUEST_TRIGER 0xAA -#define EZUSB_REQUEST_TRIG_AC 0xAC -#define EZUSB_CPUCS_REG 0x7F92 - -#define EZUSB_RID_TX 0x0700 -#define EZUSB_RID_RX 0x0701 -#define EZUSB_RID_INIT1 0x0702 -#define EZUSB_RID_ACK 0x0710 -#define EZUSB_RID_READ_PDA 0x0800 -#define EZUSB_RID_PROG_INIT 0x0852 -#define EZUSB_RID_PROG_SET_ADDR 0x0853 -#define EZUSB_RID_PROG_BYTES 0x0854 -#define EZUSB_RID_PROG_END 0x0855 -#define EZUSB_RID_DOCMD 0x0860 - -/* Recognize info frames */ -#define EZUSB_IS_INFO(id) ((id >= 0xF000) && (id <= 0xF2FF)) - -#define EZUSB_MAGIC 0x0210 - -#define EZUSB_FRAME_DATA 1 -#define EZUSB_FRAME_CONTROL 2 - -#define DEF_TIMEOUT (3*HZ) - -#define BULK_BUF_SIZE 2048 - -#define MAX_DL_SIZE (BULK_BUF_SIZE - sizeof(struct ezusb_packet)) - -#define FW_BUF_SIZE 64 -#define FW_VAR_OFFSET_PTR 0x359 -#define FW_VAR_VALUE 0 -#define FW_HOLE_START 0x100 -#define FW_HOLE_END 0x300 - -struct ezusb_packet { - __le16 magic; /* 0x0210 */ - u8 req_reply_count; - u8 ans_reply_count; - __le16 frame_type; /* 0x01 for data frames, 0x02 otherwise */ - __le16 size; /* transport size */ - __le16 crc; /* CRC up to here */ - __le16 hermes_len; - __le16 hermes_rid; - u8 data[0]; -} __attribute__ ((packed)); - -/* Table of devices that work or may work with this driver */ -static struct usb_device_id ezusb_table[] = { - {USB_DEVICE(USB_COMPAQ_VENDOR_ID, USB_COMPAQ_WL215_ID)}, - {USB_DEVICE(USB_COMPAQ_VENDOR_ID, USB_HP_WL215_ID)}, - {USB_DEVICE(USB_COMPAQ_VENDOR_ID, USB_COMPAQ_W200_ID)}, - {USB_DEVICE(USB_MELCO_VENDOR_ID, USB_BUFFALO_L11_ID)}, - {USB_DEVICE(USB_MELCO_VENDOR_ID, USB_BUFFALO_L11G_WR_ID)}, - {USB_DEVICE(USB_MELCO_VENDOR_ID, USB_BUFFALO_L11G_ID)}, - {USB_DEVICE(USB_LUCENT_VENDOR_ID, USB_LUCENT_ORINOCO_ID)}, - {USB_DEVICE(USB_AVAYA8_VENDOR_ID, USB_AVAYA_WIRELESS_ID)}, - {USB_DEVICE(USB_AVAYAE_VENDOR_ID, USB_AVAYA_WIRELESS_ID)}, - {USB_DEVICE(USB_AGERE_VENDOR_ID, USB_AGERE_MODEL0801_ID)}, - {USB_DEVICE(USB_AGERE_VENDOR_ID, USB_AGERE_MODEL0802_ID)}, - {USB_DEVICE(USB_ELSA_VENDOR_ID, USB_ELSA_AIRLANCER_ID)}, - {USB_DEVICE(USB_LEGEND_VENDOR_ID, USB_LEGEND_JOYNET_ID)}, - {USB_DEVICE_VER(USB_SAMSUNG_VENDOR_ID, USB_SAMSUNG_SEW2001U1_ID, - 0, 0)}, - {USB_DEVICE(USB_SAMSUNG_VENDOR_ID, USB_SAMSUNG_SEW2001U2_ID)}, - {USB_DEVICE(USB_SAMSUNG_VENDOR_ID, USB_SAMSUNG_SEW2003U_ID)}, - {USB_DEVICE(USB_IGATE_VENDOR_ID, USB_IGATE_IGATE_11M_ID)}, - {USB_DEVICE(USB_FUJITSU_VENDOR_ID, USB_FUJITSU_E1100_ID)}, - {USB_DEVICE(USB_2WIRE_VENDOR_ID, USB_2WIRE_WIRELESS_ID)}, - {USB_DEVICE(USB_AGERE_VENDOR_ID, USB_AGERE_REBRANDED_ID)}, - {} /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, ezusb_table); - -/* Structure to hold all of our device specific stuff */ -struct ezusb_priv { - struct usb_device *udev; - struct net_device *dev; - struct mutex mtx; - spinlock_t req_lock; - struct list_head req_pending; - struct list_head req_active; - spinlock_t reply_count_lock; - u16 hermes_reg_fake[0x40]; - u8 *bap_buf; - struct urb *read_urb; - int read_pipe; - int write_pipe; - u8 reply_count; -}; - -enum ezusb_state { - EZUSB_CTX_START, - EZUSB_CTX_QUEUED, - EZUSB_CTX_REQ_SUBMITTED, - EZUSB_CTX_REQ_COMPLETE, - EZUSB_CTX_RESP_RECEIVED, - EZUSB_CTX_REQ_TIMEOUT, - EZUSB_CTX_REQ_FAILED, - EZUSB_CTX_RESP_TIMEOUT, - EZUSB_CTX_REQSUBMIT_FAIL, - EZUSB_CTX_COMPLETE, -}; - -struct request_context { - struct list_head list; - atomic_t refcount; - struct completion done; /* Signals that CTX is dead */ - int killed; - struct urb *outurb; /* OUT for req pkt */ - struct ezusb_priv *upriv; - struct ezusb_packet *buf; - int buf_length; - struct timer_list timer; /* Timeout handling */ - enum ezusb_state state; /* Current state */ - /* the RID that we will wait for */ - u16 out_rid; - u16 in_rid; -}; - - -/* Forward declarations */ -static void ezusb_ctx_complete(struct request_context *ctx); -static void ezusb_req_queue_run(struct ezusb_priv *upriv); -static void ezusb_bulk_in_callback(struct urb *urb); - -static inline u8 ezusb_reply_inc(u8 count) -{ - if (count < 0x7F) - return count + 1; - else - return 1; -} - -static void ezusb_request_context_put(struct request_context *ctx) -{ - if (!atomic_dec_and_test(&ctx->refcount)) - return; - - WARN_ON(!ctx->done.done); - BUG_ON(ctx->outurb->status == -EINPROGRESS); - BUG_ON(timer_pending(&ctx->timer)); - usb_free_urb(ctx->outurb); - kfree(ctx->buf); - kfree(ctx); -} - -static inline void ezusb_mod_timer(struct ezusb_priv *upriv, - struct timer_list *timer, - unsigned long expire) -{ - if (!upriv->udev) - return; - mod_timer(timer, expire); -} - -static void ezusb_request_timerfn(u_long _ctx) -{ - struct request_context *ctx = (void *) _ctx; - - ctx->outurb->transfer_flags |= URB_ASYNC_UNLINK; - if (usb_unlink_urb(ctx->outurb) == -EINPROGRESS) { - ctx->state = EZUSB_CTX_REQ_TIMEOUT; - } else { - ctx->state = EZUSB_CTX_RESP_TIMEOUT; - dbg("couldn't unlink"); - atomic_inc(&ctx->refcount); - ctx->killed = 1; - ezusb_ctx_complete(ctx); - ezusb_request_context_put(ctx); - } -}; - -static struct request_context *ezusb_alloc_ctx(struct ezusb_priv *upriv, - u16 out_rid, u16 in_rid) -{ - struct request_context *ctx; - - ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC); - if (!ctx) - return NULL; - - memset(ctx, 0, sizeof(*ctx)); - - ctx->buf = kmalloc(BULK_BUF_SIZE, GFP_ATOMIC); - if (!ctx->buf) { - kfree(ctx); - return NULL; - } - ctx->outurb = usb_alloc_urb(0, GFP_ATOMIC); - if (!ctx->outurb) { - kfree(ctx->buf); - kfree(ctx); - return NULL; - } - - ctx->upriv = upriv; - ctx->state = EZUSB_CTX_START; - ctx->out_rid = out_rid; - ctx->in_rid = in_rid; - - atomic_set(&ctx->refcount, 1); - init_completion(&ctx->done); - - init_timer(&ctx->timer); - ctx->timer.function = ezusb_request_timerfn; - ctx->timer.data = (u_long) ctx; - return ctx; -} - - -/* Hopefully the real complete_all will soon be exported, in the mean - * while this should work. */ -static inline void ezusb_complete_all(struct completion *comp) -{ - complete(comp); - complete(comp); - complete(comp); - complete(comp); -} - -static void ezusb_ctx_complete(struct request_context *ctx) -{ - struct ezusb_priv *upriv = ctx->upriv; - unsigned long flags; - - spin_lock_irqsave(&upriv->req_lock, flags); - - list_del_init(&ctx->list); - if (upriv->udev) { - spin_unlock_irqrestore(&upriv->req_lock, flags); - ezusb_req_queue_run(upriv); - spin_lock_irqsave(&upriv->req_lock, flags); - } - - switch (ctx->state) { - case EZUSB_CTX_COMPLETE: - case EZUSB_CTX_REQSUBMIT_FAIL: - case EZUSB_CTX_REQ_FAILED: - case EZUSB_CTX_REQ_TIMEOUT: - case EZUSB_CTX_RESP_TIMEOUT: - spin_unlock_irqrestore(&upriv->req_lock, flags); - - if ((ctx->out_rid == EZUSB_RID_TX) && upriv->dev) { - struct net_device *dev = upriv->dev; - struct orinoco_private *priv = ndev_priv(dev); - struct net_device_stats *stats = &priv->stats; - - if (ctx->state != EZUSB_CTX_COMPLETE) - stats->tx_errors++; - else - stats->tx_packets++; - - netif_wake_queue(dev); - } - ezusb_complete_all(&ctx->done); - ezusb_request_context_put(ctx); - break; - - default: - spin_unlock_irqrestore(&upriv->req_lock, flags); - if (!upriv->udev) { - /* This is normal, as all request contexts get flushed - * when the device is disconnected */ - err("Called, CTX not terminating, but device gone"); - ezusb_complete_all(&ctx->done); - ezusb_request_context_put(ctx); - break; - } - - err("Called, CTX not in terminating state."); - /* Things are really bad if this happens. Just leak - * the CTX because it may still be linked to the - * queue or the OUT urb may still be active. - * Just leaking at least prevents an Oops or Panic. - */ - break; - } -} - -/** - * ezusb_req_queue_run: - * Description: - * Note: Only one active CTX at any one time, because there's no - * other (reliable) way to match the response URB to the correct - * CTX. - **/ -static void ezusb_req_queue_run(struct ezusb_priv *upriv) -{ - unsigned long flags; - struct request_context *ctx; - int result; - - spin_lock_irqsave(&upriv->req_lock, flags); - - if (!list_empty(&upriv->req_active)) - goto unlock; - - if (list_empty(&upriv->req_pending)) - goto unlock; - - ctx = - list_entry(upriv->req_pending.next, struct request_context, - list); - - if (!ctx->upriv->udev) - goto unlock; - - /* We need to split this off to avoid a race condition */ - list_move_tail(&ctx->list, &upriv->req_active); - - if (ctx->state == EZUSB_CTX_QUEUED) { - atomic_inc(&ctx->refcount); - result = usb_submit_urb(ctx->outurb, GFP_ATOMIC); - if (result) { - ctx->state = EZUSB_CTX_REQSUBMIT_FAIL; - - spin_unlock_irqrestore(&upriv->req_lock, flags); - - err("Fatal, failed to submit command urb." - " error=%d\n", result); - - ezusb_ctx_complete(ctx); - ezusb_request_context_put(ctx); - goto done; - } - - ctx->state = EZUSB_CTX_REQ_SUBMITTED; - ezusb_mod_timer(ctx->upriv, &ctx->timer, - jiffies + DEF_TIMEOUT); - } - - unlock: - spin_unlock_irqrestore(&upriv->req_lock, flags); - - done: - return; -} - -static void ezusb_req_enqueue_run(struct ezusb_priv *upriv, - struct request_context *ctx) -{ - unsigned long flags; - - spin_lock_irqsave(&upriv->req_lock, flags); - - if (!ctx->upriv->udev) { - spin_unlock_irqrestore(&upriv->req_lock, flags); - goto done; - } - atomic_inc(&ctx->refcount); - list_add_tail(&ctx->list, &upriv->req_pending); - spin_unlock_irqrestore(&upriv->req_lock, flags); - - ctx->state = EZUSB_CTX_QUEUED; - ezusb_req_queue_run(upriv); - - done: - return; -} - -static void ezusb_request_out_callback(struct urb *urb) -{ - unsigned long flags; - enum ezusb_state state; - struct request_context *ctx = urb->context; - struct ezusb_priv *upriv = ctx->upriv; - - spin_lock_irqsave(&upriv->req_lock, flags); - - del_timer(&ctx->timer); - - if (ctx->killed) { - spin_unlock_irqrestore(&upriv->req_lock, flags); - pr_warning("interrupt called with dead ctx"); - goto out; - } - - state = ctx->state; - - if (urb->status == 0) { - switch (state) { - case EZUSB_CTX_REQ_SUBMITTED: - if (ctx->in_rid) { - ctx->state = EZUSB_CTX_REQ_COMPLETE; - /* reply URB still pending */ - ezusb_mod_timer(upriv, &ctx->timer, - jiffies + DEF_TIMEOUT); - spin_unlock_irqrestore(&upriv->req_lock, - flags); - break; - } - /* fall through */ - case EZUSB_CTX_RESP_RECEIVED: - /* IN already received before this OUT-ACK */ - ctx->state = EZUSB_CTX_COMPLETE; - spin_unlock_irqrestore(&upriv->req_lock, flags); - ezusb_ctx_complete(ctx); - break; - - default: - spin_unlock_irqrestore(&upriv->req_lock, flags); - err("Unexpected state(0x%x, %d) in OUT URB", - state, urb->status); - break; - } - } else { - /* If someone cancels the OUT URB then its status - * should be either -ECONNRESET or -ENOENT. - */ - switch (state) { - case EZUSB_CTX_REQ_SUBMITTED: - case EZUSB_CTX_RESP_RECEIVED: - ctx->state = EZUSB_CTX_REQ_FAILED; - /* fall through */ - - case EZUSB_CTX_REQ_FAILED: - case EZUSB_CTX_REQ_TIMEOUT: - spin_unlock_irqrestore(&upriv->req_lock, flags); - - ezusb_ctx_complete(ctx); - break; - - default: - spin_unlock_irqrestore(&upriv->req_lock, flags); - - err("Unexpected state(0x%x, %d) in OUT URB", - state, urb->status); - break; - } - } - out: - ezusb_request_context_put(ctx); -} - -static void ezusb_request_in_callback(struct ezusb_priv *upriv, - struct urb *urb) -{ - struct ezusb_packet *ans = urb->transfer_buffer; - struct request_context *ctx = NULL; - enum ezusb_state state; - unsigned long flags; - - /* Find the CTX on the active queue that requested this URB */ - spin_lock_irqsave(&upriv->req_lock, flags); - if (upriv->udev) { - struct list_head *item; - - list_for_each(item, &upriv->req_active) { - struct request_context *c; - int reply_count; - - c = list_entry(item, struct request_context, list); - reply_count = - ezusb_reply_inc(c->buf->req_reply_count); - if ((ans->ans_reply_count == reply_count) - && (le16_to_cpu(ans->hermes_rid) == c->in_rid)) { - ctx = c; - break; - } - dbg("Skipped (0x%x/0x%x) (%d/%d)", - le16_to_cpu(ans->hermes_rid), - c->in_rid, ans->ans_reply_count, reply_count); - } - } - - if (ctx == NULL) { - spin_unlock_irqrestore(&upriv->req_lock, flags); - err("%s: got unexpected RID: 0x%04X", __func__, - le16_to_cpu(ans->hermes_rid)); - ezusb_req_queue_run(upriv); - return; - } - - /* The data we want is in the in buffer, exchange */ - urb->transfer_buffer = ctx->buf; - ctx->buf = (void *) ans; - ctx->buf_length = urb->actual_length; - - state = ctx->state; - switch (state) { - case EZUSB_CTX_REQ_SUBMITTED: - /* We have received our response URB before - * our request has been acknowledged. Do NOT - * destroy our CTX yet, because our OUT URB - * is still alive ... - */ - ctx->state = EZUSB_CTX_RESP_RECEIVED; - spin_unlock_irqrestore(&upriv->req_lock, flags); - - /* Let the machine continue running. */ - break; - - case EZUSB_CTX_REQ_COMPLETE: - /* This is the usual path: our request - * has already been acknowledged, and - * we have now received the reply. - */ - ctx->state = EZUSB_CTX_COMPLETE; - - /* Stop the intimer */ - del_timer(&ctx->timer); - spin_unlock_irqrestore(&upriv->req_lock, flags); - - /* Call the completion handler */ - ezusb_ctx_complete(ctx); - break; - - default: - spin_unlock_irqrestore(&upriv->req_lock, flags); - - pr_warning("Matched IN URB, unexpected context state(0x%x)", - state); - /* Throw this CTX away and try submitting another */ - del_timer(&ctx->timer); - ctx->outurb->transfer_flags |= URB_ASYNC_UNLINK; - usb_unlink_urb(ctx->outurb); - ezusb_req_queue_run(upriv); - break; - } /* switch */ -} - - -static void ezusb_req_ctx_wait(struct ezusb_priv *upriv, - struct request_context *ctx) -{ - switch (ctx->state) { - case EZUSB_CTX_QUEUED: - case EZUSB_CTX_REQ_SUBMITTED: - case EZUSB_CTX_REQ_COMPLETE: - case EZUSB_CTX_RESP_RECEIVED: - if (in_softirq()) { - /* If we get called from a timer, timeout timers don't - * get the chance to run themselves. So we make sure - * that we don't sleep for ever */ - int msecs = DEF_TIMEOUT * (1000 / HZ); - while (!ctx->done.done && msecs--) - udelay(1000); - } else { - wait_event_interruptible(ctx->done.wait, - ctx->done.done); - } - break; - default: - /* Done or failed - nothing to wait for */ - break; - } -} - -static inline u16 build_crc(struct ezusb_packet *data) -{ - u16 crc = 0; - u8 *bytes = (u8 *)data; - int i; - - for (i = 0; i < 8; i++) - crc = (crc << 1) + bytes[i]; - - return crc; -} - -/** - * ezusb_fill_req: - * - * if data == NULL and length > 0 the data is assumed to be already in - * the target buffer and only the header is filled. - * - */ -static int ezusb_fill_req(struct ezusb_packet *req, u16 length, u16 rid, - const void *data, u16 frame_type, u8 reply_count) -{ - int total_size = sizeof(*req) + length; - - BUG_ON(total_size > BULK_BUF_SIZE); - - req->magic = cpu_to_le16(EZUSB_MAGIC); - req->req_reply_count = reply_count; - req->ans_reply_count = 0; - req->frame_type = cpu_to_le16(frame_type); - req->size = cpu_to_le16(length + 4); - req->crc = cpu_to_le16(build_crc(req)); - req->hermes_len = cpu_to_le16(HERMES_BYTES_TO_RECLEN(length)); - req->hermes_rid = cpu_to_le16(rid); - if (data) - memcpy(req->data, data, length); - return total_size; -} - -static int ezusb_submit_in_urb(struct ezusb_priv *upriv) -{ - int retval = 0; - void *cur_buf = upriv->read_urb->transfer_buffer; - - if (upriv->read_urb->status == -EINPROGRESS) { - dbg("urb busy, not resubmiting"); - retval = -EBUSY; - goto exit; - } - usb_fill_bulk_urb(upriv->read_urb, upriv->udev, upriv->read_pipe, - cur_buf, BULK_BUF_SIZE, - ezusb_bulk_in_callback, upriv); - upriv->read_urb->transfer_flags = 0; - retval = usb_submit_urb(upriv->read_urb, GFP_ATOMIC); - if (retval) - err("%s submit failed %d", __func__, retval); - - exit: - return retval; -} - -static inline int ezusb_8051_cpucs(struct ezusb_priv *upriv, int reset) -{ - u8 res_val = reset; /* avoid argument promotion */ - - if (!upriv->udev) { - err("%s: !upriv->udev", __func__); - return -EFAULT; - } - return usb_control_msg(upriv->udev, - usb_sndctrlpipe(upriv->udev, 0), - EZUSB_REQUEST_FW_TRANS, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | - USB_DIR_OUT, EZUSB_CPUCS_REG, 0, &res_val, - sizeof(res_val), DEF_TIMEOUT); -} - -static int ezusb_firmware_download(struct ezusb_priv *upriv, - struct ez_usb_fw *fw) -{ - u8 fw_buffer[FW_BUF_SIZE]; - int retval, addr; - int variant_offset; - - /* - * This byte is 1 and should be replaced with 0. The offset is - * 0x10AD in version 0.0.6. The byte in question should follow - * the end of the code pointed to by the jump in the beginning - * of the firmware. Also, it is read by code located at 0x358. - */ - variant_offset = be16_to_cpup((__be16 *) &fw->code[FW_VAR_OFFSET_PTR]); - if (variant_offset >= fw->size) { - printk(KERN_ERR PFX "Invalid firmware variant offset: " - "0x%04x\n", variant_offset); - retval = -EINVAL; - goto fail; - } - - retval = ezusb_8051_cpucs(upriv, 1); - if (retval < 0) - goto fail; - for (addr = 0; addr < fw->size; addr += FW_BUF_SIZE) { - /* 0x100-0x300 should be left alone, it contains card - * specific data, like USB enumeration information */ - if ((addr >= FW_HOLE_START) && (addr < FW_HOLE_END)) - continue; - - memcpy(fw_buffer, &fw->code[addr], FW_BUF_SIZE); - if (variant_offset >= addr && - variant_offset < addr + FW_BUF_SIZE) { - dbg("Patching card_variant byte at 0x%04X", - variant_offset); - fw_buffer[variant_offset - addr] = FW_VAR_VALUE; - } - retval = usb_control_msg(upriv->udev, - usb_sndctrlpipe(upriv->udev, 0), - EZUSB_REQUEST_FW_TRANS, - USB_TYPE_VENDOR | USB_RECIP_DEVICE - | USB_DIR_OUT, - addr, 0x0, - fw_buffer, FW_BUF_SIZE, - DEF_TIMEOUT); - - if (retval < 0) - goto fail; - } - retval = ezusb_8051_cpucs(upriv, 0); - if (retval < 0) - goto fail; - - goto exit; - fail: - printk(KERN_ERR PFX "Firmware download failed, error %d\n", - retval); - exit: - return retval; -} - -static int ezusb_access_ltv(struct ezusb_priv *upriv, - struct request_context *ctx, - u16 length, const void *data, u16 frame_type, - void *ans_buff, int ans_size, u16 *ans_length) -{ - int req_size; - int retval = 0; - enum ezusb_state state; - - BUG_ON(in_irq()); - - if (!upriv->udev) { - dbg("Device disconnected"); - return -ENODEV; - } - - if (upriv->read_urb->status != -EINPROGRESS) - err("%s: in urb not pending", __func__); - - /* protect upriv->reply_count, guarantee sequential numbers */ - spin_lock_bh(&upriv->reply_count_lock); - req_size = ezusb_fill_req(ctx->buf, length, ctx->out_rid, data, - frame_type, upriv->reply_count); - usb_fill_bulk_urb(ctx->outurb, upriv->udev, upriv->write_pipe, - ctx->buf, req_size, - ezusb_request_out_callback, ctx); - - if (ctx->in_rid) - upriv->reply_count = ezusb_reply_inc(upriv->reply_count); - - ezusb_req_enqueue_run(upriv, ctx); - - spin_unlock_bh(&upriv->reply_count_lock); - - if (ctx->in_rid) - ezusb_req_ctx_wait(upriv, ctx); - - state = ctx->state; - switch (state) { - case EZUSB_CTX_COMPLETE: - retval = ctx->outurb->status; - break; - - case EZUSB_CTX_QUEUED: - case EZUSB_CTX_REQ_SUBMITTED: - if (!ctx->in_rid) - break; - default: - err("%s: Unexpected context state %d", __func__, - state); - /* fall though */ - case EZUSB_CTX_REQ_TIMEOUT: - case EZUSB_CTX_REQ_FAILED: - case EZUSB_CTX_RESP_TIMEOUT: - case EZUSB_CTX_REQSUBMIT_FAIL: - printk(KERN_ERR PFX "Access failed, resetting (state %d," - " reply_count %d)\n", state, upriv->reply_count); - upriv->reply_count = 0; - if (state == EZUSB_CTX_REQ_TIMEOUT - || state == EZUSB_CTX_RESP_TIMEOUT) { - printk(KERN_ERR PFX "ctx timed out\n"); - retval = -ETIMEDOUT; - } else { - printk(KERN_ERR PFX "ctx failed\n"); - retval = -EFAULT; - } - goto exit; - break; - } - if (ctx->in_rid) { - struct ezusb_packet *ans = ctx->buf; - int exp_len; - - if (ans->hermes_len != 0) - exp_len = le16_to_cpu(ans->hermes_len) * 2 + 12; - else - exp_len = 14; - - if (exp_len != ctx->buf_length) { - err("%s: length mismatch for RID 0x%04x: " - "expected %d, got %d", __func__, - ctx->in_rid, exp_len, ctx->buf_length); - retval = -EIO; - goto exit; - } - - if (ans_buff) - memcpy(ans_buff, ans->data, - min_t(int, exp_len, ans_size)); - if (ans_length) - *ans_length = le16_to_cpu(ans->hermes_len); - } - exit: - ezusb_request_context_put(ctx); - return retval; -} - -static int ezusb_write_ltv(hermes_t *hw, int bap, u16 rid, - u16 length, const void *data) -{ - struct ezusb_priv *upriv = hw->priv; - u16 frame_type; - struct request_context *ctx; - - if (length == 0) - return -EINVAL; - - length = HERMES_RECLEN_TO_BYTES(length); - - /* On memory mapped devices HERMES_RID_CNFGROUPADDRESSES can be - * set to be empty, but the USB bridge doesn't like it */ - if (length == 0) - return 0; - - ctx = ezusb_alloc_ctx(upriv, rid, EZUSB_RID_ACK); - if (!ctx) - return -ENOMEM; - - if (rid == EZUSB_RID_TX) - frame_type = EZUSB_FRAME_DATA; - else - frame_type = EZUSB_FRAME_CONTROL; - - return ezusb_access_ltv(upriv, ctx, length, data, frame_type, - NULL, 0, NULL); -} - -static int ezusb_read_ltv(hermes_t *hw, int bap, u16 rid, - unsigned bufsize, u16 *length, void *buf) -{ - struct ezusb_priv *upriv = hw->priv; - struct request_context *ctx; - - if ((bufsize < 0) || (bufsize % 2)) - return -EINVAL; - - ctx = ezusb_alloc_ctx(upriv, rid, rid); - if (!ctx) - return -ENOMEM; - - return ezusb_access_ltv(upriv, ctx, 0, NULL, EZUSB_FRAME_CONTROL, - buf, bufsize, length); -} - -static int ezusb_doicmd_wait(hermes_t *hw, u16 cmd, u16 parm0, u16 parm1, - u16 parm2, struct hermes_response *resp) -{ - struct ezusb_priv *upriv = hw->priv; - struct request_context *ctx; - - __le16 data[4] = { - cpu_to_le16(cmd), - cpu_to_le16(parm0), - cpu_to_le16(parm1), - cpu_to_le16(parm2), - }; - dbg("0x%04X, parm0 0x%04X, parm1 0x%04X, parm2 0x%04X", - cmd, parm0, parm1, parm2); - ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_DOCMD, EZUSB_RID_ACK); - if (!ctx) - return -ENOMEM; - - return ezusb_access_ltv(upriv, ctx, sizeof(data), &data, - EZUSB_FRAME_CONTROL, NULL, 0, NULL); -} - -static int ezusb_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, - struct hermes_response *resp) -{ - struct ezusb_priv *upriv = hw->priv; - struct request_context *ctx; - - __le16 data[4] = { - cpu_to_le16(cmd), - cpu_to_le16(parm0), - 0, - 0, - }; - dbg("0x%04X, parm0 0x%04X", cmd, parm0); - ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_DOCMD, EZUSB_RID_ACK); - if (!ctx) - return -ENOMEM; - - return ezusb_access_ltv(upriv, ctx, sizeof(data), &data, - EZUSB_FRAME_CONTROL, NULL, 0, NULL); -} - -static int ezusb_bap_pread(struct hermes *hw, int bap, - void *buf, int len, u16 id, u16 offset) -{ - struct ezusb_priv *upriv = hw->priv; - struct ezusb_packet *ans = (void *) upriv->read_urb->transfer_buffer; - int actual_length = upriv->read_urb->actual_length; - - if (id == EZUSB_RID_RX) { - if ((sizeof(*ans) + offset + len) > actual_length) { - printk(KERN_ERR PFX "BAP read beyond buffer end " - "in rx frame\n"); - return -EINVAL; - } - memcpy(buf, ans->data + offset, len); - return 0; - } - - if (EZUSB_IS_INFO(id)) { - /* Include 4 bytes for length/type */ - if ((sizeof(*ans) + offset + len - 4) > actual_length) { - printk(KERN_ERR PFX "BAP read beyond buffer end " - "in info frame\n"); - return -EFAULT; - } - memcpy(buf, ans->data + offset - 4, len); - } else { - printk(KERN_ERR PFX "Unexpected fid 0x%04x\n", id); - return -EINVAL; - } - - return 0; -} - -static int ezusb_read_pda(struct hermes *hw, __le16 *pda, - u32 pda_addr, u16 pda_len) -{ - struct ezusb_priv *upriv = hw->priv; - struct request_context *ctx; - __le16 data[] = { - cpu_to_le16(pda_addr & 0xffff), - cpu_to_le16(pda_len - 4) - }; - ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_READ_PDA, EZUSB_RID_READ_PDA); - if (!ctx) - return -ENOMEM; - - /* wl_lkm does not include PDA size in the PDA area. - * We will pad the information into pda, so other routines - * don't have to be modified */ - pda[0] = cpu_to_le16(pda_len - 2); - /* Includes CFG_PROD_DATA but not itself */ - pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */ - - return ezusb_access_ltv(upriv, ctx, sizeof(data), &data, - EZUSB_FRAME_CONTROL, &pda[2], pda_len - 4, - NULL); -} - -static int ezusb_program_init(struct hermes *hw, u32 entry_point) -{ - struct ezusb_priv *upriv = hw->priv; - struct request_context *ctx; - __le32 data = cpu_to_le32(entry_point); - - ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_PROG_INIT, EZUSB_RID_ACK); - if (!ctx) - return -ENOMEM; - - return ezusb_access_ltv(upriv, ctx, sizeof(data), &data, - EZUSB_FRAME_CONTROL, NULL, 0, NULL); -} - -static int ezusb_program_end(struct hermes *hw) -{ - struct ezusb_priv *upriv = hw->priv; - struct request_context *ctx; - - ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_PROG_END, EZUSB_RID_ACK); - if (!ctx) - return -ENOMEM; - - return ezusb_access_ltv(upriv, ctx, 0, NULL, - EZUSB_FRAME_CONTROL, NULL, 0, NULL); -} - -static int ezusb_program_bytes(struct hermes *hw, const char *buf, - u32 addr, u32 len) -{ - struct ezusb_priv *upriv = hw->priv; - struct request_context *ctx; - __le32 data = cpu_to_le32(addr); - int err; - - ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_PROG_SET_ADDR, EZUSB_RID_ACK); - if (!ctx) - return -ENOMEM; - - err = ezusb_access_ltv(upriv, ctx, sizeof(data), &data, - EZUSB_FRAME_CONTROL, NULL, 0, NULL); - if (err) - return err; - - ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_PROG_BYTES, EZUSB_RID_ACK); - if (!ctx) - return -ENOMEM; - - return ezusb_access_ltv(upriv, ctx, len, buf, - EZUSB_FRAME_CONTROL, NULL, 0, NULL); -} - -static int ezusb_program(struct hermes *hw, const char *buf, - u32 addr, u32 len) -{ - u32 ch_addr; - u32 ch_len; - int err = 0; - - /* We can only send 2048 bytes out of the bulk xmit at a time, - * so we have to split any programming into chunks of <2048 - * bytes. */ - - ch_len = (len < MAX_DL_SIZE) ? len : MAX_DL_SIZE; - ch_addr = addr; - - while (ch_addr < (addr + len)) { - pr_debug("Programming subblock of length %d " - "to address 0x%08x. Data @ %p\n", - ch_len, ch_addr, &buf[ch_addr - addr]); - - err = ezusb_program_bytes(hw, &buf[ch_addr - addr], - ch_addr, ch_len); - if (err) - break; - - ch_addr += ch_len; - ch_len = ((addr + len - ch_addr) < MAX_DL_SIZE) ? - (addr + len - ch_addr) : MAX_DL_SIZE; - } - - return err; -} - -static netdev_tx_t ezusb_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct orinoco_private *priv = ndev_priv(dev); - struct net_device_stats *stats = &priv->stats; - struct ezusb_priv *upriv = priv->card; - int err = 0; - char *p; - struct ethhdr *eh; - int len, data_len, data_off; - __le16 tx_control; - unsigned long flags; - struct request_context *ctx; - u8 *buf; - int tx_size; - - if (!netif_running(dev)) { - printk(KERN_ERR "%s: Tx on stopped device!\n", - dev->name); - return NETDEV_TX_BUSY; - } - - if (netif_queue_stopped(dev)) { - printk(KERN_DEBUG "%s: Tx while transmitter busy!\n", - dev->name); - return NETDEV_TX_BUSY; - } - - if (orinoco_lock(priv, &flags) != 0) { - printk(KERN_ERR - "%s: orinoco_xmit() called while hw_unavailable\n", - dev->name); - return NETDEV_TX_BUSY; - } - - if (!netif_carrier_ok(dev) || - (priv->iw_mode == NL80211_IFTYPE_MONITOR)) { - /* Oops, the firmware hasn't established a connection, - silently drop the packet (this seems to be the - safest approach). */ - stats->tx_errors++; - orinoco_unlock(priv, &flags); - dev_kfree_skb(skb); - return NETDEV_TX_OK; - } - - ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_TX, 0); - if (!ctx) - goto fail; - - memset(ctx->buf, 0, BULK_BUF_SIZE); - buf = ctx->buf->data; - - /* Length of the packet body */ - /* FIXME: what if the skb is smaller than this? */ - len = max_t(int, skb->len - ETH_HLEN, ETH_ZLEN - ETH_HLEN); - - eh = (struct ethhdr *) skb->data; - - tx_control = cpu_to_le16(0); - memcpy(buf, &tx_control, sizeof(tx_control)); - buf += sizeof(tx_control); - /* Encapsulate Ethernet-II frames */ - if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */ - struct header_struct *hdr = (void *) buf; - buf += sizeof(*hdr); - data_len = len; - data_off = sizeof(tx_control) + sizeof(*hdr); - p = skb->data + ETH_HLEN; - - /* 802.3 header */ - memcpy(hdr->dest, eh->h_dest, ETH_ALEN); - memcpy(hdr->src, eh->h_source, ETH_ALEN); - hdr->len = htons(data_len + ENCAPS_OVERHEAD); - - /* 802.2 header */ - memcpy(&hdr->dsap, &encaps_hdr, sizeof(encaps_hdr)); - - hdr->ethertype = eh->h_proto; - } else { /* IEEE 802.3 frame */ - data_len = len + ETH_HLEN; - data_off = sizeof(tx_control); - p = skb->data; - } - - memcpy(buf, p, data_len); - buf += data_len; - - /* Finally, we actually initiate the send */ - netif_stop_queue(dev); - - /* The card may behave better if we send evenly sized usb transfers */ - tx_size = ALIGN(buf - ctx->buf->data, 2); - - err = ezusb_access_ltv(upriv, ctx, tx_size, NULL, - EZUSB_FRAME_DATA, NULL, 0, NULL); - - if (err) { - netif_start_queue(dev); - if (net_ratelimit()) - printk(KERN_ERR "%s: Error %d transmitting packet\n", - dev->name, err); - stats->tx_errors++; - goto fail; - } - - dev->trans_start = jiffies; - stats->tx_bytes += data_off + data_len; - - orinoco_unlock(priv, &flags); - - dev_kfree_skb(skb); - - return NETDEV_TX_OK; - - fail: - orinoco_unlock(priv, &flags); - return NETDEV_TX_BUSY; -} - -static int ezusb_allocate(struct hermes *hw, u16 size, u16 *fid) -{ - *fid = EZUSB_RID_TX; - return 0; -} - - -static int ezusb_hard_reset(struct orinoco_private *priv) -{ - struct ezusb_priv *upriv = priv->card; - int retval = ezusb_8051_cpucs(upriv, 1); - - if (retval < 0) { - err("Failed to reset"); - return retval; - } - - retval = ezusb_8051_cpucs(upriv, 0); - if (retval < 0) { - err("Failed to unreset"); - return retval; - } - - dbg("sending control message"); - retval = usb_control_msg(upriv->udev, - usb_sndctrlpipe(upriv->udev, 0), - EZUSB_REQUEST_TRIGER, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | - USB_DIR_OUT, 0x0, 0x0, NULL, 0, - DEF_TIMEOUT); - if (retval < 0) { - err("EZUSB_REQUEST_TRIGER failed retval %d", retval); - return retval; - } -#if 0 - dbg("Sending EZUSB_REQUEST_TRIG_AC"); - retval = usb_control_msg(upriv->udev, - usb_sndctrlpipe(upriv->udev, 0), - EZUSB_REQUEST_TRIG_AC, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | - USB_DIR_OUT, 0x00FA, 0x0, NULL, 0, - DEF_TIMEOUT); - if (retval < 0) { - err("EZUSB_REQUEST_TRIG_AC failed retval %d", retval); - return retval; - } -#endif - - return 0; -} - - -static int ezusb_init(hermes_t *hw) -{ - struct ezusb_priv *upriv = hw->priv; - int retval; - - BUG_ON(in_interrupt()); - BUG_ON(!upriv); - - upriv->reply_count = 0; - /* Write the MAGIC number on the simulated registers to keep - * orinoco.c happy */ - hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC); - hermes_write_regn(hw, RXFID, EZUSB_RID_RX); - - usb_kill_urb(upriv->read_urb); - ezusb_submit_in_urb(upriv); - - retval = ezusb_write_ltv(hw, 0, EZUSB_RID_INIT1, - HERMES_BYTES_TO_RECLEN(2), "\x10\x00"); - if (retval < 0) { - printk(KERN_ERR PFX "EZUSB_RID_INIT1 error %d\n", retval); - return retval; - } - - retval = ezusb_docmd_wait(hw, HERMES_CMD_INIT, 0, NULL); - if (retval < 0) { - printk(KERN_ERR PFX "HERMES_CMD_INIT error %d\n", retval); - return retval; - } - - return 0; -} - -static void ezusb_bulk_in_callback(struct urb *urb) -{ - struct ezusb_priv *upriv = (struct ezusb_priv *) urb->context; - struct ezusb_packet *ans = urb->transfer_buffer; - u16 crc; - u16 hermes_rid; - - if (upriv->udev == NULL) { - dbg("disconnected"); - return; - } - - if (urb->status == -ETIMEDOUT) { - /* When a device gets unplugged we get this every time - * we resubmit, flooding the logs. Since we don't use - * USB timeouts, it shouldn't happen any other time*/ - pr_warning("%s: urb timed out, not resubmiting", __func__); - return; - } - if (urb->status == -ECONNABORTED) { - pr_warning("%s: connection abort, resubmiting urb", - __func__); - goto resubmit; - } - if ((urb->status == -EILSEQ) - || (urb->status == -ENOENT) - || (urb->status == -ECONNRESET)) { - dbg("status %d, not resubmiting", urb->status); - return; - } - if (urb->status) - dbg("status: %d length: %d", - urb->status, urb->actual_length); - if (urb->actual_length < sizeof(*ans)) { - err("%s: short read, ignoring", __func__); - goto resubmit; - } - crc = build_crc(ans); - if (le16_to_cpu(ans->crc) != crc) { - err("CRC error, ignoring packet"); - goto resubmit; - } - - hermes_rid = le16_to_cpu(ans->hermes_rid); - if ((hermes_rid != EZUSB_RID_RX) && !EZUSB_IS_INFO(hermes_rid)) { - ezusb_request_in_callback(upriv, urb); - } else if (upriv->dev) { - struct net_device *dev = upriv->dev; - struct orinoco_private *priv = ndev_priv(dev); - hermes_t *hw = &priv->hw; - - if (hermes_rid == EZUSB_RID_RX) { - __orinoco_ev_rx(dev, hw); - } else { - hermes_write_regn(hw, INFOFID, - le16_to_cpu(ans->hermes_rid)); - __orinoco_ev_info(dev, hw); - } - } - - resubmit: - if (upriv->udev) - ezusb_submit_in_urb(upriv); -} - -static inline void ezusb_delete(struct ezusb_priv *upriv) -{ - struct net_device *dev; - struct list_head *item; - struct list_head *tmp_item; - unsigned long flags; - - BUG_ON(in_interrupt()); - BUG_ON(!upriv); - - dev = upriv->dev; - mutex_lock(&upriv->mtx); - - upriv->udev = NULL; /* No timer will be rearmed from here */ - - usb_kill_urb(upriv->read_urb); - - spin_lock_irqsave(&upriv->req_lock, flags); - list_for_each_safe(item, tmp_item, &upriv->req_active) { - struct request_context *ctx; - int err; - - ctx = list_entry(item, struct request_context, list); - atomic_inc(&ctx->refcount); - - ctx->outurb->transfer_flags |= URB_ASYNC_UNLINK; - err = usb_unlink_urb(ctx->outurb); - - spin_unlock_irqrestore(&upriv->req_lock, flags); - if (err == -EINPROGRESS) - wait_for_completion(&ctx->done); - - del_timer_sync(&ctx->timer); - /* FIXME: there is an slight chance for the irq handler to - * be running */ - if (!list_empty(&ctx->list)) - ezusb_ctx_complete(ctx); - - ezusb_request_context_put(ctx); - spin_lock_irqsave(&upriv->req_lock, flags); - } - spin_unlock_irqrestore(&upriv->req_lock, flags); - - list_for_each_safe(item, tmp_item, &upriv->req_pending) - ezusb_ctx_complete(list_entry(item, - struct request_context, list)); - - if (upriv->read_urb->status == -EINPROGRESS) - printk(KERN_ERR PFX "Some URB in progress\n"); - - mutex_unlock(&upriv->mtx); - - kfree(upriv->read_urb->transfer_buffer); - if (upriv->bap_buf != NULL) - kfree(upriv->bap_buf); - if (upriv->read_urb != NULL) - usb_free_urb(upriv->read_urb); - if (upriv->dev) { - struct orinoco_private *priv = ndev_priv(upriv->dev); - orinoco_if_del(priv); - free_orinocodev(priv); - } -} - -static void ezusb_lock_irqsave(spinlock_t *lock, - unsigned long *flags) __acquires(lock) -{ - spin_lock_bh(lock); -} - -static void ezusb_unlock_irqrestore(spinlock_t *lock, - unsigned long *flags) __releases(lock) -{ - spin_unlock_bh(lock); -} - -static void ezusb_lock_irq(spinlock_t *lock) __acquires(lock) -{ - spin_lock_bh(lock); -} - -static void ezusb_unlock_irq(spinlock_t *lock) __releases(lock) -{ - spin_unlock_bh(lock); -} - -static const struct hermes_ops ezusb_ops = { - .init = ezusb_init, - .cmd_wait = ezusb_docmd_wait, - .init_cmd_wait = ezusb_doicmd_wait, - .allocate = ezusb_allocate, - .read_ltv = ezusb_read_ltv, - .write_ltv = ezusb_write_ltv, - .bap_pread = ezusb_bap_pread, - .read_pda = ezusb_read_pda, - .program_init = ezusb_program_init, - .program_end = ezusb_program_end, - .program = ezusb_program, - .lock_irqsave = ezusb_lock_irqsave, - .unlock_irqrestore = ezusb_unlock_irqrestore, - .lock_irq = ezusb_lock_irq, - .unlock_irq = ezusb_unlock_irq, -}; - -static const struct net_device_ops ezusb_netdev_ops = { - .ndo_open = orinoco_open, - .ndo_stop = orinoco_stop, - .ndo_start_xmit = ezusb_xmit, - .ndo_set_multicast_list = orinoco_set_multicast_list, - .ndo_change_mtu = orinoco_change_mtu, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, - .ndo_tx_timeout = orinoco_tx_timeout, - .ndo_get_stats = orinoco_get_stats, -}; - -static int ezusb_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(interface); - struct orinoco_private *priv; - hermes_t *hw; - struct ezusb_priv *upriv = NULL; - struct usb_interface_descriptor *iface_desc; - struct usb_endpoint_descriptor *ep; - const struct firmware *fw_entry; - int retval = 0; - int i; - - priv = alloc_orinocodev(sizeof(*upriv), &udev->dev, - ezusb_hard_reset, NULL); - if (!priv) { - err("Couldn't allocate orinocodev"); - goto exit; - } - - hw = &priv->hw; - - upriv = priv->card; - - mutex_init(&upriv->mtx); - spin_lock_init(&upriv->reply_count_lock); - - spin_lock_init(&upriv->req_lock); - INIT_LIST_HEAD(&upriv->req_pending); - INIT_LIST_HEAD(&upriv->req_active); - - upriv->udev = udev; - - hw->iobase = (void __force __iomem *) &upriv->hermes_reg_fake; - hw->reg_spacing = HERMES_16BIT_REGSPACING; - hw->priv = upriv; - hw->ops = &ezusb_ops; - - /* set up the endpoint information */ - /* check out the endpoints */ - - iface_desc = &interface->altsetting[0].desc; - for (i = 0; i < iface_desc->bNumEndpoints; ++i) { - ep = &interface->altsetting[0].endpoint[i].desc; - - if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) - == USB_DIR_IN) && - ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_BULK)) { - /* we found a bulk in endpoint */ - if (upriv->read_urb != NULL) { - pr_warning("Found a second bulk in ep, ignored"); - continue; - } - - upriv->read_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!upriv->read_urb) { - err("No free urbs available"); - goto error; - } - if (le16_to_cpu(ep->wMaxPacketSize) != 64) - pr_warning("bulk in: wMaxPacketSize!= 64"); - if (ep->bEndpointAddress != (2 | USB_DIR_IN)) - pr_warning("bulk in: bEndpointAddress: %d", - ep->bEndpointAddress); - upriv->read_pipe = usb_rcvbulkpipe(udev, - ep-> - bEndpointAddress); - upriv->read_urb->transfer_buffer = - kmalloc(BULK_BUF_SIZE, GFP_KERNEL); - if (!upriv->read_urb->transfer_buffer) { - err("Couldn't allocate IN buffer"); - goto error; - } - } - - if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) - == USB_DIR_OUT) && - ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_BULK)) { - /* we found a bulk out endpoint */ - if (upriv->bap_buf != NULL) { - pr_warning("Found a second bulk out ep, ignored"); - continue; - } - - if (le16_to_cpu(ep->wMaxPacketSize) != 64) - pr_warning("bulk out: wMaxPacketSize != 64"); - if (ep->bEndpointAddress != 2) - pr_warning("bulk out: bEndpointAddress: %d", - ep->bEndpointAddress); - upriv->write_pipe = usb_sndbulkpipe(udev, - ep-> - bEndpointAddress); - upriv->bap_buf = kmalloc(BULK_BUF_SIZE, GFP_KERNEL); - if (!upriv->bap_buf) { - err("Couldn't allocate bulk_out_buffer"); - goto error; - } - } - } - if (!upriv->bap_buf || !upriv->read_urb) { - err("Didn't find the required bulk endpoints"); - goto error; - } - - if (request_firmware(&fw_entry, "orinoco_ezusb_fw", - &interface->dev) == 0) { - firmware.size = fw_entry->size; - firmware.code = fw_entry->data; - } - if (firmware.size && firmware.code) { - ezusb_firmware_download(upriv, &firmware); - } else { - err("No firmware to download"); - goto error; - } - - if (ezusb_hard_reset(priv) < 0) { - err("Cannot reset the device"); - goto error; - } - - /* If the firmware is already downloaded orinoco.c will call - * ezusb_init but if the firmware is not already there, that will make - * the kernel very unstable, so we try initializing here and quit in - * case of error */ - if (ezusb_init(hw) < 0) { - err("Couldn't initialize the device"); - err("Firmware may not be downloaded or may be wrong."); - goto error; - } - - /* Initialise the main driver */ - if (orinoco_init(priv) != 0) { - err("orinoco_init() failed\n"); - goto error; - } - - if (orinoco_if_add(priv, 0, 0, &ezusb_netdev_ops) != 0) { - upriv->dev = NULL; - err("%s: orinoco_if_add() failed", __func__); - goto error; - } - upriv->dev = priv->ndev; - - goto exit; - - error: - ezusb_delete(upriv); - if (upriv->dev) { - /* upriv->dev was 0, so ezusb_delete() didn't free it */ - free_orinocodev(priv); - } - upriv = NULL; - retval = -EFAULT; - exit: - if (fw_entry) { - firmware.code = NULL; - firmware.size = 0; - release_firmware(fw_entry); - } - usb_set_intfdata(interface, upriv); - return retval; -} - - -static void ezusb_disconnect(struct usb_interface *intf) -{ - struct ezusb_priv *upriv = usb_get_intfdata(intf); - usb_set_intfdata(intf, NULL); - ezusb_delete(upriv); - printk(KERN_INFO PFX "Disconnected\n"); -} - - -/* usb specific object needed to register this driver with the usb subsystem */ -static struct usb_driver orinoco_driver = { - .name = DRIVER_NAME, - .probe = ezusb_probe, - .disconnect = ezusb_disconnect, - .id_table = ezusb_table, -}; - -/* Can't be declared "const" or the whole __initdata section will - * become const */ -static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION - " (Manuel Estrada Sainz)"; - -static int __init ezusb_module_init(void) -{ - int err; - - printk(KERN_DEBUG "%s\n", version); - - /* register this driver with the USB subsystem */ - err = usb_register(&orinoco_driver); - if (err < 0) { - printk(KERN_ERR PFX "usb_register failed, error %d\n", - err); - return err; - } - - return 0; -} - -static void __exit ezusb_module_exit(void) -{ - /* deregister this driver with the USB subsystem */ - usb_deregister(&orinoco_driver); -} - - -module_init(ezusb_module_init); -module_exit(ezusb_module_exit); - -MODULE_AUTHOR("Manuel Estrada Sainz"); -MODULE_DESCRIPTION - ("Driver for Orinoco wireless LAN cards using EZUSB bridge"); -MODULE_LICENSE("Dual MPL/GPL"); diff --git a/trunk/drivers/net/wireless/orinoco/spectrum_cs.c b/trunk/drivers/net/wireless/orinoco/spectrum_cs.c index 9b1af4976bf5..59bda240fdc2 100644 --- a/trunk/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/trunk/drivers/net/wireless/orinoco/spectrum_cs.c @@ -349,7 +349,6 @@ spectrum_cs_config(struct pcmcia_device *link) goto failed; hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); - hw->eeprom_pda = true; /* * This actually configures the PCMCIA socket -- setting up @@ -375,7 +374,7 @@ spectrum_cs_config(struct pcmcia_device *link) /* Register an interface with the stack */ if (orinoco_if_add(priv, link->io.BasePort1, - link->irq.AssignedIRQ, NULL) != 0) { + link->irq.AssignedIRQ) != 0) { printk(KERN_ERR PFX "orinoco_if_add() failed\n"); goto failed; } @@ -406,9 +405,9 @@ spectrum_cs_release(struct pcmcia_device *link) /* We're committed to taking the device away now, so mark the * hardware as unavailable */ - priv->hw.ops->lock_irqsave(&priv->lock, &flags); + spin_lock_irqsave(&priv->lock, flags); priv->hw_unavailable++; - priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); + spin_unlock_irqrestore(&priv->lock, flags); pcmcia_disable_device(link); if (priv->hw.iobase) diff --git a/trunk/drivers/net/wireless/orinoco/wext.c b/trunk/drivers/net/wireless/orinoco/wext.c index 5775124e2aee..a1006bf430cc 100644 --- a/trunk/drivers/net/wireless/orinoco/wext.c +++ b/trunk/drivers/net/wireless/orinoco/wext.c @@ -458,7 +458,7 @@ static int orinoco_ioctl_setfreq(struct net_device *dev, if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { /* Fast channel change - no commit if successful */ hermes_t *hw = &priv->hw; - err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST | + err = hermes_docmd_wait(hw, HERMES_CMD_TEST | HERMES_TEST_SET_CHANNEL, chan, NULL); } @@ -1273,8 +1273,8 @@ static int orinoco_ioctl_getrid(struct net_device *dev, if (orinoco_lock(priv, &flags) != 0) return -EBUSY; - err = hw->ops->read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length, - extra); + err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length, + extra); if (err) goto out; diff --git a/trunk/drivers/net/wireless/p54/main.c b/trunk/drivers/net/wireless/p54/main.c index c072f41747ca..7bbd9d3bba60 100644 --- a/trunk/drivers/net/wireless/p54/main.c +++ b/trunk/drivers/net/wireless/p54/main.c @@ -546,7 +546,8 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | IEEE80211_HW_BEACON_FILTER | - IEEE80211_HW_REPORTS_TX_ACK_STATUS; + IEEE80211_HW_REPORTS_TX_ACK_STATUS | + IEEE80211_HW_NOISE_DBM; dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC) | diff --git a/trunk/drivers/net/wireless/p54/p54pci.c b/trunk/drivers/net/wireless/p54/p54pci.c index 07c4528f6e6b..ca42ccb23d76 100644 --- a/trunk/drivers/net/wireless/p54/p54pci.c +++ b/trunk/drivers/net/wireless/p54/p54pci.c @@ -277,14 +277,6 @@ static void p54p_tasklet(unsigned long dev_id) struct p54p_priv *priv = dev->priv; struct p54p_ring_control *ring_control = priv->ring_control; - p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, 3, ring_control->tx_mgmt, - ARRAY_SIZE(ring_control->tx_mgmt), - priv->tx_buf_mgmt); - - p54p_check_tx_ring(dev, &priv->tx_idx_data, 1, ring_control->tx_data, - ARRAY_SIZE(ring_control->tx_data), - priv->tx_buf_data); - p54p_check_rx_ring(dev, &priv->rx_idx_mgmt, 2, ring_control->rx_mgmt, ARRAY_SIZE(ring_control->rx_mgmt), priv->rx_buf_mgmt); @@ -293,6 +285,14 @@ static void p54p_tasklet(unsigned long dev_id) wmb(); P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE)); + + p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, 3, ring_control->tx_mgmt, + ARRAY_SIZE(ring_control->tx_mgmt), + priv->tx_buf_mgmt); + + p54p_check_tx_ring(dev, &priv->tx_idx_data, 1, ring_control->tx_data, + ARRAY_SIZE(ring_control->tx_data), + priv->tx_buf_data); } static irqreturn_t p54p_interrupt(int irq, void *dev_id) diff --git a/trunk/drivers/net/wireless/p54/txrx.c b/trunk/drivers/net/wireless/p54/txrx.c index 4e6891099d43..2ceff5480355 100644 --- a/trunk/drivers/net/wireless/p54/txrx.c +++ b/trunk/drivers/net/wireless/p54/txrx.c @@ -350,6 +350,7 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb) rx_status->flag |= RX_FLAG_MMIC_ERROR; rx_status->signal = p54_rssi_to_dbm(priv, hdr->rssi); + rx_status->noise = priv->noise; if (hdr->rate & 0x10) rx_status->flag |= RX_FLAG_SHORTPRE; if (priv->hw->conf.channel->band == IEEE80211_BAND_5GHZ) diff --git a/trunk/drivers/net/wireless/rt2x00/Kconfig b/trunk/drivers/net/wireless/rt2x00/Kconfig index eea1ef2f502b..5239e082cd0f 100644 --- a/trunk/drivers/net/wireless/rt2x00/Kconfig +++ b/trunk/drivers/net/wireless/rt2x00/Kconfig @@ -87,7 +87,7 @@ if RT2800PCI config RT2800PCI_RT30XX bool "rt2800pci - Include support for rt30xx (PCI/PCIe/PCMCIA) devices" - default y + default n ---help--- This adds support for rt30xx wireless chipset family to the rt2800pci driver. @@ -156,7 +156,7 @@ if RT2800USB config RT2800USB_RT30XX bool "rt2800usb - Include support for rt30xx (USB) devices" - default y + default n ---help--- This adds support for rt30xx wireless chipset family to the rt2800usb driver. diff --git a/trunk/drivers/net/wireless/rt2x00/rt2400pci.c b/trunk/drivers/net/wireless/rt2x00/rt2400pci.c index 06b92f8b7a55..cdbf59108ef9 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1018,8 +1018,8 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_desc_write(entry_priv->desc, 1, word); rt2x00_desc_read(txd, 2, &word); - rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, txdesc->length); - rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, txdesc->length); + rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, skb->len); + rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, skb->len); rt2x00_desc_write(txd, 2, word); rt2x00_desc_read(txd, 3, &word); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500pci.c b/trunk/drivers/net/wireless/rt2x00/rt2500pci.c index ae8e205df269..89e986f449da 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1209,7 +1209,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); - rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); + rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); rt2x00_desc_write(txd, 0, word); } diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c index 41d9996c80e6..7185cb05f257 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1072,7 +1072,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); - rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); + rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); rt2x00_set_field32(&word, TXD_W0_CIPHER, !!txdesc->cipher); rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx); rt2x00_desc_write(txd, 0, word); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800.h b/trunk/drivers/net/wireless/rt2x00/rt2800.h index 2aa03751c341..ec893721cc80 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2800.h @@ -107,7 +107,7 @@ /* * INT_SOURCE_CSR: Interrupt source register. * Write one to clear corresponding bit. - * TX_FIFO_STATUS: FIFO Statistics is full, sw should read TX_STA_FIFO + * TX_FIFO_STATUS: FIFO Statistics is full, sw should read 0x171c */ #define INT_SOURCE_CSR 0x0200 #define INT_SOURCE_CSR_RXDELAYINT FIELD32(0x00000001) @@ -845,7 +845,7 @@ * TX_BAND_CFG: 0x1 use upper 20MHz, 0x0 use lower 20MHz */ #define TX_BAND_CFG 0x132c -#define TX_BAND_CFG_HT40_MINUS FIELD32(0x00000001) +#define TX_BAND_CFG_HT40_PLUS FIELD32(0x00000001) #define TX_BAND_CFG_A FIELD32(0x00000002) #define TX_BAND_CFG_BG FIELD32(0x00000004) @@ -1519,7 +1519,7 @@ struct mac_iveiv_entry { * BBP 3: RX Antenna */ #define BBP3_RX_ANTENNA FIELD8(0x18) -#define BBP3_HT40_MINUS FIELD8(0x20) +#define BBP3_HT40_PLUS FIELD8(0x20) /* * BBP 4: Bandwidth @@ -1565,11 +1565,6 @@ struct mac_iveiv_entry { */ #define RFCSR12_TX_POWER FIELD8(0x1f) -/* - * RFCSR 13: - */ -#define RFCSR13_TX_POWER FIELD8(0x1f) - /* * RFCSR 15: */ diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c index e37bbeab9233..2648f315a934 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c @@ -41,6 +41,9 @@ #if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE) #include "rt2x00usb.h" #endif +#if defined(CONFIG_RT2X00_LIB_PCI) || defined(CONFIG_RT2X00_LIB_PCI_MODULE) +#include "rt2x00pci.h" +#endif #include "rt2800lib.h" #include "rt2800.h" #include "rt2800usb.h" @@ -73,23 +76,6 @@ MODULE_LICENSE("GPL"); rt2800_regbusy_read((__dev), H2M_MAILBOX_CSR, \ H2M_MAILBOX_CSR_OWNER, (__reg)) -static inline bool rt2800_is_305x_soc(struct rt2x00_dev *rt2x00dev) -{ - /* check for rt2872 on SoC */ - if (!rt2x00_is_soc(rt2x00dev) || - !rt2x00_rt(rt2x00dev, RT2872)) - return false; - - /* we know for sure that these rf chipsets are used on rt305x boards */ - if (rt2x00_rf(rt2x00dev, RF3020) || - rt2x00_rf(rt2x00dev, RF3021) || - rt2x00_rf(rt2x00dev, RF3022)) - return true; - - NOTICE(rt2x00dev, "Unknown RF chipset on rt305x\n"); - return false; -} - static void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, const u8 value) { @@ -808,11 +794,6 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, TXPOWER_G_TO_DEV(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)); - rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); - rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset); rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); @@ -868,7 +849,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, } rt2800_register_read(rt2x00dev, TX_BAND_CFG, ®); - rt2x00_set_field32(®, TX_BAND_CFG_HT40_MINUS, conf_is_ht40_minus(conf)); + rt2x00_set_field32(®, TX_BAND_CFG_HT40_PLUS, conf_is_ht40_plus(conf)); rt2x00_set_field32(®, TX_BAND_CFG_A, rf->channel > 14); rt2x00_set_field32(®, TX_BAND_CFG_BG, rf->channel <= 14); rt2800_register_write(rt2x00dev, TX_BAND_CFG, reg); @@ -901,7 +882,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_bbp_write(rt2x00dev, 4, bbp); rt2800_bbp_read(rt2x00dev, 3, &bbp); - rt2x00_set_field8(&bbp, BBP3_HT40_MINUS, conf_is_ht40_minus(conf)); + rt2x00_set_field8(&bbp, BBP3_HT40_PLUS, conf_is_ht40_plus(conf)); rt2800_bbp_write(rt2x00dev, 3, bbp); if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { @@ -1570,9 +1551,6 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_wait_bbp_ready(rt2x00dev))) return -EACCES; - if (rt2800_is_305x_soc(rt2x00dev)) - rt2800_bbp_write(rt2x00dev, 31, 0x08); - rt2800_bbp_write(rt2x00dev, 65, 0x2c); rt2800_bbp_write(rt2x00dev, 66, 0x38); @@ -1593,9 +1571,6 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 79, 0x13); rt2800_bbp_write(rt2x00dev, 80, 0x05); rt2800_bbp_write(rt2x00dev, 81, 0x33); - } else if (rt2800_is_305x_soc(rt2x00dev)) { - rt2800_bbp_write(rt2x00dev, 78, 0x0e); - rt2800_bbp_write(rt2x00dev, 80, 0x08); } else { rt2800_bbp_write(rt2x00dev, 81, 0x37); } @@ -1616,16 +1591,12 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) || rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || - rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || - rt2800_is_305x_soc(rt2x00dev)) + rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E)) rt2800_bbp_write(rt2x00dev, 103, 0xc0); else rt2800_bbp_write(rt2x00dev, 103, 0x00); - if (rt2800_is_305x_soc(rt2x00dev)) - rt2800_bbp_write(rt2x00dev, 105, 0x01); - else - rt2800_bbp_write(rt2x00dev, 105, 0x05); + rt2800_bbp_write(rt2x00dev, 105, 0x05); rt2800_bbp_write(rt2x00dev, 106, 0x35); if (rt2x00_rt(rt2x00dev, RT3071) || @@ -1642,6 +1613,11 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 138, value); } + if (rt2x00_rt(rt2x00dev, RT2872)) { + rt2800_bbp_write(rt2x00dev, 31, 0x08); + rt2800_bbp_write(rt2x00dev, 78, 0x0e); + rt2800_bbp_write(rt2x00dev, 80, 0x08); + } for (i = 0; i < EEPROM_BBP_SIZE; i++) { rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); @@ -1727,8 +1703,7 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) if (!rt2x00_rt(rt2x00dev, RT3070) && !rt2x00_rt(rt2x00dev, RT3071) && !rt2x00_rt(rt2x00dev, RT3090) && - !rt2x00_rt(rt2x00dev, RT3390) && - !rt2800_is_305x_soc(rt2x00dev)) + !rt2x00_rt(rt2x00dev, RT3390)) return 0; /* @@ -1796,40 +1771,6 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 29, 0x8f); rt2800_rfcsr_write(rt2x00dev, 30, 0x20); rt2800_rfcsr_write(rt2x00dev, 31, 0x0f); - } else if (rt2800_is_305x_soc(rt2x00dev)) { - rt2800_rfcsr_write(rt2x00dev, 0, 0x50); - rt2800_rfcsr_write(rt2x00dev, 1, 0x01); - rt2800_rfcsr_write(rt2x00dev, 2, 0xf7); - rt2800_rfcsr_write(rt2x00dev, 3, 0x75); - rt2800_rfcsr_write(rt2x00dev, 4, 0x40); - rt2800_rfcsr_write(rt2x00dev, 5, 0x03); - rt2800_rfcsr_write(rt2x00dev, 6, 0x02); - rt2800_rfcsr_write(rt2x00dev, 7, 0x50); - rt2800_rfcsr_write(rt2x00dev, 8, 0x39); - rt2800_rfcsr_write(rt2x00dev, 9, 0x0f); - rt2800_rfcsr_write(rt2x00dev, 10, 0x60); - rt2800_rfcsr_write(rt2x00dev, 11, 0x21); - rt2800_rfcsr_write(rt2x00dev, 12, 0x75); - rt2800_rfcsr_write(rt2x00dev, 13, 0x75); - rt2800_rfcsr_write(rt2x00dev, 14, 0x90); - rt2800_rfcsr_write(rt2x00dev, 15, 0x58); - rt2800_rfcsr_write(rt2x00dev, 16, 0xb3); - rt2800_rfcsr_write(rt2x00dev, 17, 0x92); - rt2800_rfcsr_write(rt2x00dev, 18, 0x2c); - rt2800_rfcsr_write(rt2x00dev, 19, 0x02); - rt2800_rfcsr_write(rt2x00dev, 20, 0xba); - rt2800_rfcsr_write(rt2x00dev, 21, 0xdb); - rt2800_rfcsr_write(rt2x00dev, 22, 0x00); - rt2800_rfcsr_write(rt2x00dev, 23, 0x31); - rt2800_rfcsr_write(rt2x00dev, 24, 0x08); - rt2800_rfcsr_write(rt2x00dev, 25, 0x01); - rt2800_rfcsr_write(rt2x00dev, 26, 0x25); - rt2800_rfcsr_write(rt2x00dev, 27, 0x23); - rt2800_rfcsr_write(rt2x00dev, 28, 0x13); - rt2800_rfcsr_write(rt2x00dev, 29, 0x83); - rt2800_rfcsr_write(rt2x00dev, 30, 0x00); - rt2800_rfcsr_write(rt2x00dev, 31, 0x00); - return 0; } if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { @@ -2045,6 +1986,7 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); } else if (rt2x00_rt(rt2x00dev, RT2860) || rt2x00_rt(rt2x00dev, RT2870) || + rt2x00_rt(rt2x00dev, RT2872) || rt2x00_rt(rt2x00dev, RT2872)) { /* * There is a max of 2 RX streams for RT28x0 series @@ -2376,11 +2318,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) else spec->ht.ht_supported = false; - /* - * Don't set IEEE80211_HT_CAP_SUP_WIDTH_20_40 for now as it causes - * reception problems with HT40 capable 11n APs - */ spec->ht.cap = + IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800pci.c b/trunk/drivers/net/wireless/rt2x00/rt2800pci.c index f08b6a37bf2d..0e52f174896c 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800pci.c @@ -663,7 +663,7 @@ static int rt2800pci_write_tx_data(struct queue_entry* entry, test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? txdesc->key_idx : 0xff); rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, - txdesc->length); + skb->len - txdesc->l2pad); rt2x00_set_field32(&word, TXWI_W1_PACKETID, skbdesc->entry->queue->qid + 1); rt2x00_desc_write(txwi, 1, word); @@ -895,6 +895,10 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) + rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2; + rxdesc->noise = + (rt2x00_get_field32(rxwi3, RXWI_W3_SNR0) + + rt2x00_get_field32(rxwi3, RXWI_W3_SNR1)) / 2; + rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT); /* diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c index e3f3a97db807..95c8a6134ff8 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c @@ -437,7 +437,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? txdesc->key_idx : 0xff); rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, - txdesc->length); + skb->len - txdesc->l2pad); rt2x00_set_field32(&word, TXWI_W1_PACKETID, skbdesc->entry->queue->qid + 1); rt2x00_desc_write(txwi, 1, word); @@ -645,6 +645,10 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) + rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2; + rxdesc->noise = + (rt2x00_get_field32(rxwi3, RXWI_W3_SNR0) + + rt2x00_get_field32(rxwi3, RXWI_W3_SNR1)) / 2; + rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT); /* @@ -1023,7 +1027,7 @@ static struct usb_device_id rt2800usb_device_table[] = { #ifdef CONFIG_RT2800USB_UNKNOWN /* * Unclear what kind of devices these are (they aren't supported by the - * vendor linux driver). + * vendor driver). */ /* Amigo */ { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -1036,7 +1040,6 @@ static struct usb_device_id rt2800usb_device_table[] = { /* AzureWave */ { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x13d3, 0x3322), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Belkin */ { USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Buffalo */ @@ -1055,7 +1058,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07d1, 0x3c15), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c17), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Encore */ { USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Gemtek */ @@ -1072,13 +1074,11 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Motorola */ { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Ovislink */ - { USB_DEVICE(0x1b75, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Pegatron */ { USB_DEVICE(0x05a6, 0x0101), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1d4d, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1d4d, 0x0011), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Planex */ { USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Qcom */ @@ -1087,7 +1087,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x083a, 0xd522), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x083a, 0xf511), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Sweex */ { USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) }, diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c index 3ae468c4d760..eda73ba735a6 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -435,6 +435,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, rx_status->mactime = rxdesc.timestamp; rx_status->rate_idx = rate_idx; rx_status->signal = rxdesc.rssi; + rx_status->noise = rxdesc.noise; rx_status->flag = rxdesc.flags; rx_status->antenna = rt2x00dev->link.ant.active.rx; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c b/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c index e22029fcf411..91b7fb99ceb4 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -334,10 +334,12 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, txdesc->aifs = entry->queue->aifs; /* - * Header and frame information. + * Header and alignment information. */ - txdesc->length = entry->skb->len; txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb); + if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags) && + (entry->skb->len > txdesc->header_length)) + txdesc->l2pad = L2PAD_SIZE(txdesc->header_length); /* * Check whether this frame is to be acked. diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00queue.h b/trunk/drivers/net/wireless/rt2x00/rt2x00queue.h index 94a48c174d67..c1e482bb37b3 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -183,6 +183,7 @@ enum rxdone_entry_desc_flags { * @timestamp: RX Timestamp * @signal: Signal of the received frame. * @rssi: RSSI of the received frame. + * @noise: Measured noise during frame reception. * @size: Data size of the received frame. * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags). * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags). @@ -196,6 +197,7 @@ struct rxdone_entry_desc { u64 timestamp; int signal; int rssi; + int noise; int size; int flags; int dev_flags; @@ -285,8 +287,8 @@ enum txentry_desc_flags { * * @flags: Descriptor flags (See &enum queue_entry_flags). * @queue: Queue identification (See &enum data_queue_qid). - * @length: Length of the entire frame. * @header_length: Length of 802.11 header. + * @l2pad: Amount of padding to align 802.11 payload to 4-byte boundrary. * @length_high: PLCP length high word. * @length_low: PLCP length low word. * @signal: PLCP signal. @@ -311,8 +313,8 @@ struct txentry_desc { enum data_queue_qid queue; - u16 length; u16 header_length; + u16 l2pad; u16 length_high; u16 length_low; diff --git a/trunk/drivers/net/wireless/rt2x00/rt61pci.c b/trunk/drivers/net/wireless/rt2x00/rt61pci.c index 26ee7911fba9..b9885981f3a8 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt61pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt61pci.c @@ -1809,8 +1809,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, if (skbdesc->desc_len > TXINFO_SIZE) { rt2x00_desc_read(txd, 11, &word); - rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, - txdesc->length); + rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skb->len); rt2x00_desc_write(txd, 11, word); } @@ -1833,7 +1832,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_KEY_TABLE, test_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_KEY_INDEX, txdesc->key_idx); - rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); + rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); rt2x00_set_field32(&word, TXD_W0_BURST, test_bit(ENTRY_TXD_BURST, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher); diff --git a/trunk/drivers/net/wireless/rt2x00/rt73usb.c b/trunk/drivers/net/wireless/rt2x00/rt73usb.c index 39b3c6d04af4..576ea9dd2824 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt73usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt73usb.c @@ -1495,7 +1495,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_KEY_TABLE, test_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_KEY_INDEX, txdesc->key_idx); - rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); + rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); rt2x00_set_field32(&word, TXD_W0_BURST2, test_bit(ENTRY_TXD_BURST, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher); diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8180_dev.c b/trunk/drivers/net/wireless/rtl818x/rtl8180_dev.c index 21307f2412b8..6b46329b732f 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8180_dev.c @@ -188,7 +188,6 @@ static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio) info->flags |= IEEE80211_TX_STAT_ACK; info->status.rates[0].count = (flags & 0xFF) + 1; - info->status.rates[1].idx = -1; ieee80211_tx_status_irqsafe(dev, skb); if (ring->entries - skb_queue_len(&ring->queue) == 2) @@ -298,7 +297,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) entry->flags = cpu_to_le32(tx_flags); __skb_queue_tail(&ring->queue, skb); if (ring->entries - skb_queue_len(&ring->queue) < 2) - ieee80211_stop_queue(dev, prio); + ieee80211_stop_queue(dev, skb_get_queue_mapping(skb)); spin_unlock_irqrestore(&priv->lock, flags); rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); @@ -828,7 +827,6 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, const char *chip_name, *rf_name = NULL; u32 reg; u16 eeprom_val; - u8 mac_addr[ETH_ALEN]; err = pci_enable_device(pdev); if (err) { @@ -989,13 +987,12 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam); } - eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)mac_addr, 3); - if (!is_valid_ether_addr(mac_addr)) { + eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)dev->wiphy->perm_addr, 3); + if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using" " randomly generated MAC addr\n", pci_name(pdev)); - random_ether_addr(mac_addr); + random_ether_addr(dev->wiphy->perm_addr); } - SET_IEEE80211_PERM_ADDR(dev, mac_addr); /* CCK TX power */ for (i = 0; i < 14; i += 2) { @@ -1027,7 +1024,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, } printk(KERN_INFO "%s: hwaddr %pM, %s + %s\n", - wiphy_name(dev->wiphy), mac_addr, + wiphy_name(dev->wiphy), dev->wiphy->perm_addr, chip_name, priv->rf->name); return 0; diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c b/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c index 891b8490e349..738921fda027 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -1333,7 +1333,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, u16 txpwr, reg; u16 product_id = le16_to_cpu(udev->descriptor.idProduct); int err, i; - u8 mac_addr[ETH_ALEN]; dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops); if (!dev) { @@ -1391,13 +1390,12 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, udelay(10); eeprom_93cx6_multiread(&eeprom, RTL8187_EEPROM_MAC_ADDR, - (__le16 __force *)mac_addr, 3); - if (!is_valid_ether_addr(mac_addr)) { + (__le16 __force *)dev->wiphy->perm_addr, 3); + if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { printk(KERN_WARNING "rtl8187: Invalid hwaddr! Using randomly " "generated MAC address\n"); - random_ether_addr(mac_addr); + random_ether_addr(dev->wiphy->perm_addr); } - SET_IEEE80211_PERM_ADDR(dev, mac_addr); channel = priv->channels; for (i = 0; i < 3; i++) { @@ -1528,7 +1526,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, skb_queue_head_init(&priv->b_tx_status.queue); printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s, rfkill mask %d\n", - wiphy_name(dev->wiphy), mac_addr, + wiphy_name(dev->wiphy), dev->wiphy->perm_addr, chip_name, priv->asic_rev, priv->rf->name, priv->rfkill_mask); #ifdef CONFIG_RTL8187_LEDS diff --git a/trunk/drivers/net/wireless/wl12xx/wl1251_main.c b/trunk/drivers/net/wireless/wl12xx/wl1251_main.c index 00b24282fc73..51614d181ccb 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/trunk/drivers/net/wireless/wl12xx/wl1251_main.c @@ -857,7 +857,6 @@ static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, } static int wl1251_op_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, struct cfg80211_scan_request *req) { struct wl1251 *wl = hw->priv; @@ -1292,6 +1291,7 @@ int wl1251_init_ieee80211(struct wl1251 *wl) wl->hw->channel_change_time = 10000; wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_NOISE_DBM | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_SUPPORTS_UAPSD; diff --git a/trunk/drivers/net/wireless/wl12xx/wl1251_rx.c b/trunk/drivers/net/wireless/wl12xx/wl1251_rx.c index af5c67b4da95..6f229e0990f4 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1251_rx.c +++ b/trunk/drivers/net/wireless/wl12xx/wl1251_rx.c @@ -74,6 +74,12 @@ static void wl1251_rx_status(struct wl1251 *wl, status->signal = desc->rssi; + /* + * FIXME: guessing that snr needs to be divided by two, otherwise + * the values don't make any sense + */ + status->noise = desc->rssi - desc->snr / 2; + status->freq = ieee80211_channel_to_frequency(desc->channel); status->flag |= RX_FLAG_TSFT; diff --git a/trunk/drivers/net/wireless/wl12xx/wl1271_acx.c b/trunk/drivers/net/wireless/wl12xx/wl1271_acx.c index e19e2f8f1e52..2ad086efe06e 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1271_acx.c +++ b/trunk/drivers/net/wireless/wl12xx/wl1271_acx.c @@ -590,7 +590,7 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl) /* BT-WLAN coext parameters */ for (i = 0; i < CONF_SG_PARAMS_MAX; i++) - param->params[i] = cpu_to_le32(c->params[i]); + param->params[i] = c->params[i]; param->param_idx = CONF_SG_PARAMS_ALL; ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param)); diff --git a/trunk/drivers/net/wireless/wl12xx/wl1271_boot.c b/trunk/drivers/net/wireless/wl12xx/wl1271_boot.c index acb1d9e6b7d2..8087dc17f29d 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1271_boot.c +++ b/trunk/drivers/net/wireless/wl12xx/wl1271_boot.c @@ -351,7 +351,7 @@ static int wl1271_boot_soft_reset(struct wl1271 *wl) static int wl1271_boot_run_firmware(struct wl1271 *wl) { int loop, ret; - u32 chip_id, intr; + u32 chip_id, interrupt; wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); @@ -368,15 +368,15 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl) loop = 0; while (loop++ < INIT_LOOP) { udelay(INIT_LOOP_DELAY); - intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); + interrupt = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); - if (intr == 0xffffffff) { + if (interrupt == 0xffffffff) { wl1271_error("error reading hardware complete " "init indication"); return -EIO; } /* check that ACX_INTR_INIT_COMPLETE is enabled */ - else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) { + else if (interrupt & WL1271_ACX_INTR_INIT_COMPLETE) { wl1271_write32(wl, ACX_REG_INTERRUPT_ACK, WL1271_ACX_INTR_INIT_COMPLETE); break; diff --git a/trunk/drivers/net/wireless/wl12xx/wl1271_cmd.c b/trunk/drivers/net/wireless/wl12xx/wl1271_cmd.c index 62c11af1d8e2..6b5ba8ec94c9 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/trunk/drivers/net/wireless/wl12xx/wl1271_cmd.c @@ -37,7 +37,7 @@ #include "wl1271_cmd.h" #include "wl1271_event.h" -#define WL1271_CMD_FAST_POLL_COUNT 50 +#define WL1271_CMD_POLL_COUNT 5 /* * send command to firmware @@ -77,11 +77,11 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, goto out; } + udelay(10); poll_count++; - if (poll_count < WL1271_CMD_FAST_POLL_COUNT) - udelay(10); - else - msleep(1); + if (poll_count == WL1271_CMD_POLL_COUNT) + wl1271_info("cmd polling took over %d cycles", + poll_count); intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); } @@ -318,7 +318,7 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) join->rx_config_options = cpu_to_le32(wl->rx_config); join->rx_filter_options = cpu_to_le32(wl->rx_filter); join->bss_type = bss_type; - join->basic_rate_set = cpu_to_le32(wl->basic_rate_set); + join->basic_rate_set = wl->basic_rate_set; if (wl->band == IEEE80211_BAND_5GHZ) join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; @@ -615,7 +615,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, params->params.scan_options = cpu_to_le16(scan_options); params->params.num_probe_requests = probe_requests; - params->params.tx_rate = cpu_to_le32(rate); + params->params.tx_rate = rate; params->params.tid_trigger = 0; params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; diff --git a/trunk/drivers/net/wireless/wl12xx/wl1271_conf.h b/trunk/drivers/net/wireless/wl12xx/wl1271_conf.h index d046d044b5bd..c44307c4bcf8 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1271_conf.h +++ b/trunk/drivers/net/wireless/wl12xx/wl1271_conf.h @@ -401,7 +401,7 @@ enum { }; struct conf_sg_settings { - u32 params[CONF_SG_PARAMS_MAX]; + __le32 params[CONF_SG_PARAMS_MAX]; u8 state; }; diff --git a/trunk/drivers/net/wireless/wl12xx/wl1271_main.c b/trunk/drivers/net/wireless/wl12xx/wl1271_main.c index 62e544041d0d..e47a58d2cc19 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/trunk/drivers/net/wireless/wl12xx/wl1271_main.c @@ -1118,13 +1118,14 @@ static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters) } } -static int wl1271_dummy_join(struct wl1271 *wl) +static int wl1271_join_channel(struct wl1271 *wl, int channel) { int ret = 0; /* we need to use a dummy BSSID for now */ static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde, 0xad, 0xbe, 0xef }; + wl->channel = channel; memcpy(wl->bssid, dummy_bssid, ETH_ALEN); /* pass through frames from all BSS */ @@ -1140,47 +1141,7 @@ static int wl1271_dummy_join(struct wl1271 *wl) return ret; } -static int wl1271_join(struct wl1271 *wl) -{ - int ret; - - ret = wl1271_cmd_join(wl, wl->set_bss_type); - if (ret < 0) - goto out; - - set_bit(WL1271_FLAG_JOINED, &wl->flags); - - if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) - goto out; - - /* - * The join command disable the keep-alive mode, shut down its process, - * and also clear the template config, so we need to reset it all after - * the join. The acx_aid starts the keep-alive process, and the order - * of the commands below is relevant. - */ - ret = wl1271_acx_keep_alive_mode(wl, true); - if (ret < 0) - goto out; - - ret = wl1271_acx_aid(wl, wl->aid); - if (ret < 0) - goto out; - - ret = wl1271_cmd_build_klv_null_data(wl); - if (ret < 0) - goto out; - - ret = wl1271_acx_keep_alive_config(wl, CMD_TEMPL_KLV_IDX_NULL_DATA, - ACX_KEEP_ALIVE_TPL_VALID); - if (ret < 0) - goto out; - -out: - return ret; -} - -static int wl1271_unjoin(struct wl1271 *wl) +static int wl1271_unjoin_channel(struct wl1271 *wl) { int ret; @@ -1270,7 +1231,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) "failed %d", ret); if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) { - ret = wl1271_join(wl); + ret = wl1271_cmd_join(wl, wl->set_bss_type); if (ret < 0) wl1271_warning("cmd join to update channel " "failed %d", ret); @@ -1280,9 +1241,9 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_IDLE) { if (conf->flags & IEEE80211_CONF_IDLE && test_bit(WL1271_FLAG_JOINED, &wl->flags)) - wl1271_unjoin(wl); + wl1271_unjoin_channel(wl); else if (!(conf->flags & IEEE80211_CONF_IDLE)) - wl1271_dummy_join(wl); + wl1271_join_channel(wl, channel); if (conf->flags & IEEE80211_CONF_IDLE) { wl->rate_set = wl1271_min_rate_get(wl); @@ -1558,7 +1519,6 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, } static int wl1271_op_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, struct cfg80211_scan_request *req) { struct wl1271 *wl = hw->priv; @@ -1647,6 +1607,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, enum wl1271_cmd_ps_mode mode; struct wl1271 *wl = hw->priv; bool do_join = false; + bool do_keepalive = false; int ret; wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed"); @@ -1741,10 +1702,6 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, if (ret < 0) goto out_sleep; - ret = wl1271_build_qos_null_data(wl); - if (ret < 0) - goto out_sleep; - /* filter out all packets not from this BSSID */ wl1271_configure_filters(wl, 0); @@ -1789,6 +1746,19 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, ret = wl1271_cmd_build_probe_req(wl, NULL, 0, NULL, 0, wl->band); + /* Enable the keep-alive feature */ + ret = wl1271_acx_keep_alive_mode(wl, true); + if (ret < 0) + goto out_sleep; + + /* + * This is awkward. The keep-alive configs must be done + * *after* the join command, because otherwise it will + * not work, but it must only be done *once* because + * otherwise the firmware will start complaining. + */ + do_keepalive = true; + /* enable the connection monitoring feature */ ret = wl1271_acx_conn_monit_params(wl, true); if (ret < 0) @@ -1856,11 +1826,35 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, } if (do_join) { - ret = wl1271_join(wl); + ret = wl1271_cmd_join(wl, wl->set_bss_type); if (ret < 0) { wl1271_warning("cmd join failed %d", ret); goto out_sleep; } + set_bit(WL1271_FLAG_JOINED, &wl->flags); + } + + /* + * The JOIN operation shuts down the firmware keep-alive as a side + * effect, and the ACX_AID will start the keep-alive as a side effect. + * Hence, for non-IBSS, the ACX_AID must always happen *after* the + * JOIN operation, and the template config after the ACX_AID. + */ + if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { + ret = wl1271_acx_aid(wl, wl->aid); + if (ret < 0) + goto out_sleep; + } + + if (do_keepalive) { + ret = wl1271_cmd_build_klv_null_data(wl); + if (ret < 0) + goto out_sleep; + ret = wl1271_acx_keep_alive_config( + wl, CMD_TEMPL_KLV_IDX_NULL_DATA, + ACX_KEEP_ALIVE_TPL_VALID); + if (ret < 0) + goto out_sleep; } out_sleep: @@ -2271,6 +2265,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl) wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval; wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_NOISE_DBM | IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_UAPSD | diff --git a/trunk/drivers/ssb/driver_chipcommon.c b/trunk/drivers/ssb/driver_chipcommon.c index 59ae76bace14..59c3c0fdbecd 100644 --- a/trunk/drivers/ssb/driver_chipcommon.c +++ b/trunk/drivers/ssb/driver_chipcommon.c @@ -233,8 +233,6 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc) { if (!cc->dev) return; /* We don't have a ChipCommon */ - if (cc->dev->id.revision >= 11) - cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); ssb_pmu_init(cc); chipco_powercontrol_init(cc); ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); diff --git a/trunk/drivers/ssb/main.c b/trunk/drivers/ssb/main.c index 7e5b8a8a64cc..80ff7d9e60de 100644 --- a/trunk/drivers/ssb/main.c +++ b/trunk/drivers/ssb/main.c @@ -834,9 +834,6 @@ int ssb_bus_pcibus_register(struct ssb_bus *bus, if (!err) { ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on " "PCI device %s\n", dev_name(&host_pci->dev)); - } else { - ssb_printk(KERN_ERR PFX "Failed to register PCI version" - " of SSB with error %d\n", err); } return err; diff --git a/trunk/drivers/ssb/pci.c b/trunk/drivers/ssb/pci.c index 989e2752cc36..a8dbb06623c9 100644 --- a/trunk/drivers/ssb/pci.c +++ b/trunk/drivers/ssb/pci.c @@ -168,7 +168,7 @@ int ssb_pci_xtal(struct ssb_bus *bus, u32 what, int turn_on) } /* Get the word-offset for a SSB_SPROM_XXX define. */ -#define SPOFF(offset) ((offset) / sizeof(u16)) +#define SPOFF(offset) (((offset) - SSB_SPROM_BASE) / sizeof(u16)) /* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */ #define SPEX16(_outvar, _offset, _mask, _shift) \ out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift)) @@ -254,7 +254,7 @@ static int sprom_do_read(struct ssb_bus *bus, u16 *sprom) int i; for (i = 0; i < bus->sprom_size; i++) - sprom[i] = ioread16(bus->mmio + bus->sprom_offset + (i * 2)); + sprom[i] = ioread16(bus->mmio + SSB_SPROM_BASE + (i * 2)); return 0; } @@ -285,7 +285,7 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom) ssb_printk("75%%"); else if (i % 2) ssb_printk("."); - writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2)); + writew(sprom[i], bus->mmio + SSB_SPROM_BASE + (i * 2)); mmiowb(); msleep(20); } @@ -621,14 +621,6 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, int err = -ENOMEM; u16 *buf; - if (!ssb_is_sprom_available(bus)) { - ssb_printk(KERN_ERR PFX "No SPROM available!\n"); - return -ENODEV; - } - - bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ? - SSB_SPROM_BASE1 : SSB_SPROM_BASE31; - buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); if (!buf) goto out; diff --git a/trunk/drivers/ssb/sprom.c b/trunk/drivers/ssb/sprom.c index 007bc3a03486..f2f920fef10d 100644 --- a/trunk/drivers/ssb/sprom.c +++ b/trunk/drivers/ssb/sprom.c @@ -176,17 +176,3 @@ const struct ssb_sprom *ssb_get_fallback_sprom(void) { return fallback_sprom; } - -/* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */ -bool ssb_is_sprom_available(struct ssb_bus *bus) -{ - /* status register only exists on chipcomon rev >= 11 and we need check - for >= 31 only */ - /* this routine differs from specs as we do not access SPROM directly - on PCMCIA */ - if (bus->bustype == SSB_BUSTYPE_PCI && - bus->chipco.dev->id.revision >= 31) - return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM; - - return true; -} diff --git a/trunk/include/linux/if_tun.h b/trunk/include/linux/if_tun.h index 1350a246893a..06b1829731fd 100644 --- a/trunk/include/linux/if_tun.h +++ b/trunk/include/linux/if_tun.h @@ -51,6 +51,8 @@ #define TUNSETSNDBUF _IOW('T', 212, int) #define TUNATTACHFILTER _IOW('T', 213, struct sock_fprog) #define TUNDETACHFILTER _IOW('T', 214, struct sock_fprog) +#define TUNGETVNETHDRSZ _IOR('T', 215, int) +#define TUNSETVNETHDRSZ _IOW('T', 216, int) /* TUNSETIFF ifr flags */ #define IFF_TUN 0x0001 diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 98112fbddefd..40d4c20d034b 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -218,6 +218,16 @@ struct neighbour; struct neigh_parms; struct sk_buff; +struct netif_rx_stats { + unsigned total; + unsigned dropped; + unsigned time_squeeze; + unsigned cpu_collision; + unsigned received_rps; +}; + +DECLARE_PER_CPU(struct netif_rx_stats, netdev_rx_stat); + struct netdev_hw_addr { struct list_head list; unsigned char addr[MAX_ADDR_LEN]; @@ -878,7 +888,7 @@ struct net_device { unsigned char operstate; /* RFC2863 operstate */ unsigned char link_mode; /* mapping policy to operstate */ - unsigned int mtu; /* interface MTU value */ + unsigned mtu; /* interface MTU value */ unsigned short type; /* interface hardware type */ unsigned short hard_header_len; /* hardware hdr length */ @@ -1380,12 +1390,6 @@ struct softnet_data { struct sk_buff *completion_queue; struct sk_buff_head process_queue; - /* stats */ - unsigned int processed; - unsigned int time_squeeze; - unsigned int cpu_collision; - unsigned int received_rps; - #ifdef CONFIG_RPS struct softnet_data *rps_ipi_list; @@ -1395,7 +1399,6 @@ struct softnet_data { unsigned int cpu; unsigned int input_queue_head; #endif - unsigned dropped; struct sk_buff_head input_pkt_queue; struct napi_struct backlog; }; diff --git a/trunk/include/linux/nl80211.h b/trunk/include/linux/nl80211.h index f8750f9a65b8..2ea3edeee7aa 100644 --- a/trunk/include/linux/nl80211.h +++ b/trunk/include/linux/nl80211.h @@ -709,9 +709,6 @@ enum nl80211_commands { * NL80211_CMD_AUTHENTICATE, NL80211_CMD_DEAUTHENTICATE, * NL80211_CMD_DISASSOCIATE. * - * @NL80211_ATTR_AP_ISOLATE: (AP mode) Do not forward traffic between stations - * connected to this BSS. - * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -867,8 +864,6 @@ enum nl80211_attrs { NL80211_ATTR_LOCAL_STATE_CHANGE, - NL80211_ATTR_AP_ISOLATE, - /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/trunk/include/linux/rculist.h b/trunk/include/linux/rculist.h index 4ec3b38ce9c5..004908b104d5 100644 --- a/trunk/include/linux/rculist.h +++ b/trunk/include/linux/rculist.h @@ -428,23 +428,6 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev, ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ pos = rcu_dereference_raw(pos->next)) -/** - * hlist_for_each_entry_rcu_bh - iterate over rcu list of given type - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the hlist_node within the struct. - * - * This list-traversal primitive may safely run concurrently with - * the _rcu list-mutation primitives such as hlist_add_head_rcu() - * as long as the traversal is guarded by rcu_read_lock(). - */ -#define hlist_for_each_entry_rcu_bh(tpos, pos, head, member) \ - for (pos = rcu_dereference_bh((head)->first); \ - pos && ({ prefetch(pos->next); 1; }) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ - pos = rcu_dereference_bh(pos->next)) - /** * hlist_for_each_entry_continue_rcu - iterate over a hlist continuing after current point * @tpos: the type * to use as a loop cursor. @@ -457,18 +440,6 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev, ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ pos = rcu_dereference(pos->next)) -/** - * hlist_for_each_entry_continue_rcu_bh - iterate over a hlist continuing after current point - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_continue_rcu_bh(tpos, pos, member) \ - for (pos = rcu_dereference_bh((pos)->next); \ - pos && ({ prefetch(pos->next); 1; }) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ - pos = rcu_dereference_bh(pos->next)) - #endif /* __KERNEL__ */ #endif diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index 88d55395a27c..746a652b9f6f 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -187,6 +187,7 @@ union skb_shared_tx { * the end of the header data, ie. at skb->end. */ struct skb_shared_info { + atomic_t dataref; unsigned short nr_frags; unsigned short gso_size; /* Warning: this field is not always filled in (UFO)! */ @@ -196,12 +197,6 @@ struct skb_shared_info { union skb_shared_tx tx_flags; struct sk_buff *frag_list; struct skb_shared_hwtstamps hwtstamps; - - /* - * Warning : all fields before dataref are cleared in __alloc_skb() - */ - atomic_t dataref; - skb_frag_t frags[MAX_SKB_FRAGS]; /* Intermediate layers must ensure that destructor_arg * remains valid until skb destructor */ diff --git a/trunk/include/linux/ssb/ssb.h b/trunk/include/linux/ssb/ssb.h index a2608bff9c78..24f988547361 100644 --- a/trunk/include/linux/ssb/ssb.h +++ b/trunk/include/linux/ssb/ssb.h @@ -305,7 +305,6 @@ struct ssb_bus { /* ID information about the Chip. */ u16 chip_id; u16 chip_rev; - u16 sprom_offset; u16 sprom_size; /* number of words in sprom */ u8 chip_package; @@ -395,9 +394,6 @@ extern int ssb_bus_sdiobus_register(struct ssb_bus *bus, extern void ssb_bus_unregister(struct ssb_bus *bus); -/* Does the device have an SPROM? */ -extern bool ssb_is_sprom_available(struct ssb_bus *bus); - /* Set a fallback SPROM. * See kdoc at the function definition for complete documentation. */ extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom); diff --git a/trunk/include/linux/ssb/ssb_driver_chipcommon.h b/trunk/include/linux/ssb/ssb_driver_chipcommon.h index 2cdf249b4e5f..4e27acf0a92f 100644 --- a/trunk/include/linux/ssb/ssb_driver_chipcommon.h +++ b/trunk/include/linux/ssb/ssb_driver_chipcommon.h @@ -53,7 +53,6 @@ #define SSB_CHIPCO_CAP_64BIT 0x08000000 /* 64-bit Backplane */ #define SSB_CHIPCO_CAP_PMU 0x10000000 /* PMU available (rev >= 20) */ #define SSB_CHIPCO_CAP_ECI 0x20000000 /* ECI available (rev >= 20) */ -#define SSB_CHIPCO_CAP_SPROM 0x40000000 /* SPROM present */ #define SSB_CHIPCO_CORECTL 0x0008 #define SSB_CHIPCO_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */ #define SSB_CHIPCO_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ @@ -386,7 +385,6 @@ /** Chip specific Chip-Status register contents. */ -#define SSB_CHIPCO_CHST_4322_SPROM_EXISTS 0x00000040 /* SPROM present */ #define SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL 0x00000003 #define SSB_CHIPCO_CHST_4325_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ #define SSB_CHIPCO_CHST_4325_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ @@ -400,18 +398,6 @@ #define SSB_CHIPCO_CHST_4325_RCAL_VALUE_SHIFT 4 #define SSB_CHIPCO_CHST_4325_PMUTOP_2B 0x00000200 /* 1 for 2b, 0 for to 2a */ -/** Macros to determine SPROM presence based on Chip-Status register. */ -#define SSB_CHIPCO_CHST_4312_SPROM_PRESENT(status) \ - ((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \ - SSB_CHIPCO_CHST_4325_OTP_SEL) -#define SSB_CHIPCO_CHST_4322_SPROM_PRESENT(status) \ - (status & SSB_CHIPCO_CHST_4322_SPROM_EXISTS) -#define SSB_CHIPCO_CHST_4325_SPROM_PRESENT(status) \ - (((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \ - SSB_CHIPCO_CHST_4325_DEFCIS_SEL) && \ - ((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \ - SSB_CHIPCO_CHST_4325_OTP_SEL)) - /** Clockcontrol masks and values **/ @@ -578,7 +564,6 @@ struct ssb_chipcommon_pmu { struct ssb_chipcommon { struct ssb_device *dev; u32 capabilities; - u32 status; /* Fast Powerup Delay constant */ u16 fast_pwrup_delay; struct ssb_chipcommon_pmu pmu; diff --git a/trunk/include/linux/ssb/ssb_regs.h b/trunk/include/linux/ssb/ssb_regs.h index a6d5225b9275..9ae9082eaeb4 100644 --- a/trunk/include/linux/ssb/ssb_regs.h +++ b/trunk/include/linux/ssb/ssb_regs.h @@ -170,27 +170,26 @@ #define SSB_SPROMSIZE_WORDS_R4 220 #define SSB_SPROMSIZE_BYTES_R123 (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16)) #define SSB_SPROMSIZE_BYTES_R4 (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16)) -#define SSB_SPROM_BASE1 0x1000 -#define SSB_SPROM_BASE31 0x0800 -#define SSB_SPROM_REVISION 0x007E +#define SSB_SPROM_BASE 0x1000 +#define SSB_SPROM_REVISION 0x107E #define SSB_SPROM_REVISION_REV 0x00FF /* SPROM Revision number */ #define SSB_SPROM_REVISION_CRC 0xFF00 /* SPROM CRC8 value */ #define SSB_SPROM_REVISION_CRC_SHIFT 8 /* SPROM Revision 1 */ -#define SSB_SPROM1_SPID 0x0004 /* Subsystem Product ID for PCI */ -#define SSB_SPROM1_SVID 0x0006 /* Subsystem Vendor ID for PCI */ -#define SSB_SPROM1_PID 0x0008 /* Product ID for PCI */ -#define SSB_SPROM1_IL0MAC 0x0048 /* 6 bytes MAC address for 802.11b/g */ -#define SSB_SPROM1_ET0MAC 0x004E /* 6 bytes MAC address for Ethernet */ -#define SSB_SPROM1_ET1MAC 0x0054 /* 6 bytes MAC address for 802.11a */ -#define SSB_SPROM1_ETHPHY 0x005A /* Ethernet PHY settings */ +#define SSB_SPROM1_SPID 0x1004 /* Subsystem Product ID for PCI */ +#define SSB_SPROM1_SVID 0x1006 /* Subsystem Vendor ID for PCI */ +#define SSB_SPROM1_PID 0x1008 /* Product ID for PCI */ +#define SSB_SPROM1_IL0MAC 0x1048 /* 6 bytes MAC address for 802.11b/g */ +#define SSB_SPROM1_ET0MAC 0x104E /* 6 bytes MAC address for Ethernet */ +#define SSB_SPROM1_ET1MAC 0x1054 /* 6 bytes MAC address for 802.11a */ +#define SSB_SPROM1_ETHPHY 0x105A /* Ethernet PHY settings */ #define SSB_SPROM1_ETHPHY_ET0A 0x001F /* MII Address for enet0 */ #define SSB_SPROM1_ETHPHY_ET1A 0x03E0 /* MII Address for enet1 */ #define SSB_SPROM1_ETHPHY_ET1A_SHIFT 5 #define SSB_SPROM1_ETHPHY_ET0M (1<<14) /* MDIO for enet0 */ #define SSB_SPROM1_ETHPHY_ET1M (1<<15) /* MDIO for enet1 */ -#define SSB_SPROM1_BINF 0x005C /* Board info */ +#define SSB_SPROM1_BINF 0x105C /* Board info */ #define SSB_SPROM1_BINF_BREV 0x00FF /* Board Revision */ #define SSB_SPROM1_BINF_CCODE 0x0F00 /* Country Code */ #define SSB_SPROM1_BINF_CCODE_SHIFT 8 @@ -198,63 +197,63 @@ #define SSB_SPROM1_BINF_ANTBG_SHIFT 12 #define SSB_SPROM1_BINF_ANTA 0xC000 /* Available A-PHY antennas */ #define SSB_SPROM1_BINF_ANTA_SHIFT 14 -#define SSB_SPROM1_PA0B0 0x005E -#define SSB_SPROM1_PA0B1 0x0060 -#define SSB_SPROM1_PA0B2 0x0062 -#define SSB_SPROM1_GPIOA 0x0064 /* General Purpose IO pins 0 and 1 */ +#define SSB_SPROM1_PA0B0 0x105E +#define SSB_SPROM1_PA0B1 0x1060 +#define SSB_SPROM1_PA0B2 0x1062 +#define SSB_SPROM1_GPIOA 0x1064 /* General Purpose IO pins 0 and 1 */ #define SSB_SPROM1_GPIOA_P0 0x00FF /* Pin 0 */ #define SSB_SPROM1_GPIOA_P1 0xFF00 /* Pin 1 */ #define SSB_SPROM1_GPIOA_P1_SHIFT 8 -#define SSB_SPROM1_GPIOB 0x0066 /* General Purpuse IO pins 2 and 3 */ +#define SSB_SPROM1_GPIOB 0x1066 /* General Purpuse IO pins 2 and 3 */ #define SSB_SPROM1_GPIOB_P2 0x00FF /* Pin 2 */ #define SSB_SPROM1_GPIOB_P3 0xFF00 /* Pin 3 */ #define SSB_SPROM1_GPIOB_P3_SHIFT 8 -#define SSB_SPROM1_MAXPWR 0x0068 /* Power Amplifier Max Power */ +#define SSB_SPROM1_MAXPWR 0x1068 /* Power Amplifier Max Power */ #define SSB_SPROM1_MAXPWR_BG 0x00FF /* B-PHY and G-PHY (in dBm Q5.2) */ #define SSB_SPROM1_MAXPWR_A 0xFF00 /* A-PHY (in dBm Q5.2) */ #define SSB_SPROM1_MAXPWR_A_SHIFT 8 -#define SSB_SPROM1_PA1B0 0x006A -#define SSB_SPROM1_PA1B1 0x006C -#define SSB_SPROM1_PA1B2 0x006E -#define SSB_SPROM1_ITSSI 0x0070 /* Idle TSSI Target */ +#define SSB_SPROM1_PA1B0 0x106A +#define SSB_SPROM1_PA1B1 0x106C +#define SSB_SPROM1_PA1B2 0x106E +#define SSB_SPROM1_ITSSI 0x1070 /* Idle TSSI Target */ #define SSB_SPROM1_ITSSI_BG 0x00FF /* B-PHY and G-PHY*/ #define SSB_SPROM1_ITSSI_A 0xFF00 /* A-PHY */ #define SSB_SPROM1_ITSSI_A_SHIFT 8 -#define SSB_SPROM1_BFLLO 0x0072 /* Boardflags (low 16 bits) */ -#define SSB_SPROM1_AGAIN 0x0074 /* Antenna Gain (in dBm Q5.2) */ +#define SSB_SPROM1_BFLLO 0x1072 /* Boardflags (low 16 bits) */ +#define SSB_SPROM1_AGAIN 0x1074 /* Antenna Gain (in dBm Q5.2) */ #define SSB_SPROM1_AGAIN_BG 0x00FF /* B-PHY and G-PHY */ #define SSB_SPROM1_AGAIN_BG_SHIFT 0 #define SSB_SPROM1_AGAIN_A 0xFF00 /* A-PHY */ #define SSB_SPROM1_AGAIN_A_SHIFT 8 /* SPROM Revision 2 (inherits from rev 1) */ -#define SSB_SPROM2_BFLHI 0x0038 /* Boardflags (high 16 bits) */ -#define SSB_SPROM2_MAXP_A 0x003A /* A-PHY Max Power */ +#define SSB_SPROM2_BFLHI 0x1038 /* Boardflags (high 16 bits) */ +#define SSB_SPROM2_MAXP_A 0x103A /* A-PHY Max Power */ #define SSB_SPROM2_MAXP_A_HI 0x00FF /* Max Power High */ #define SSB_SPROM2_MAXP_A_LO 0xFF00 /* Max Power Low */ #define SSB_SPROM2_MAXP_A_LO_SHIFT 8 -#define SSB_SPROM2_PA1LOB0 0x003C /* A-PHY PowerAmplifier Low Settings */ -#define SSB_SPROM2_PA1LOB1 0x003E /* A-PHY PowerAmplifier Low Settings */ -#define SSB_SPROM2_PA1LOB2 0x0040 /* A-PHY PowerAmplifier Low Settings */ -#define SSB_SPROM2_PA1HIB0 0x0042 /* A-PHY PowerAmplifier High Settings */ -#define SSB_SPROM2_PA1HIB1 0x0044 /* A-PHY PowerAmplifier High Settings */ -#define SSB_SPROM2_PA1HIB2 0x0046 /* A-PHY PowerAmplifier High Settings */ -#define SSB_SPROM2_OPO 0x0078 /* OFDM Power Offset from CCK Level */ +#define SSB_SPROM2_PA1LOB0 0x103C /* A-PHY PowerAmplifier Low Settings */ +#define SSB_SPROM2_PA1LOB1 0x103E /* A-PHY PowerAmplifier Low Settings */ +#define SSB_SPROM2_PA1LOB2 0x1040 /* A-PHY PowerAmplifier Low Settings */ +#define SSB_SPROM2_PA1HIB0 0x1042 /* A-PHY PowerAmplifier High Settings */ +#define SSB_SPROM2_PA1HIB1 0x1044 /* A-PHY PowerAmplifier High Settings */ +#define SSB_SPROM2_PA1HIB2 0x1046 /* A-PHY PowerAmplifier High Settings */ +#define SSB_SPROM2_OPO 0x1078 /* OFDM Power Offset from CCK Level */ #define SSB_SPROM2_OPO_VALUE 0x00FF #define SSB_SPROM2_OPO_UNUSED 0xFF00 -#define SSB_SPROM2_CCODE 0x007C /* Two char Country Code */ +#define SSB_SPROM2_CCODE 0x107C /* Two char Country Code */ /* SPROM Revision 3 (inherits most data from rev 2) */ -#define SSB_SPROM3_OFDMAPO 0x002C /* A-PHY OFDM Mid Power Offset (4 bytes, BigEndian) */ -#define SSB_SPROM3_OFDMALPO 0x0030 /* A-PHY OFDM Low Power Offset (4 bytes, BigEndian) */ -#define SSB_SPROM3_OFDMAHPO 0x0034 /* A-PHY OFDM High Power Offset (4 bytes, BigEndian) */ -#define SSB_SPROM3_GPIOLDC 0x0042 /* GPIO LED Powersave Duty Cycle (4 bytes, BigEndian) */ +#define SSB_SPROM3_IL0MAC 0x104A /* 6 bytes MAC address for 802.11b/g */ +#define SSB_SPROM3_OFDMAPO 0x102C /* A-PHY OFDM Mid Power Offset (4 bytes, BigEndian) */ +#define SSB_SPROM3_OFDMALPO 0x1030 /* A-PHY OFDM Low Power Offset (4 bytes, BigEndian) */ +#define SSB_SPROM3_OFDMAHPO 0x1034 /* A-PHY OFDM High Power Offset (4 bytes, BigEndian) */ +#define SSB_SPROM3_GPIOLDC 0x1042 /* GPIO LED Powersave Duty Cycle (4 bytes, BigEndian) */ #define SSB_SPROM3_GPIOLDC_OFF 0x0000FF00 /* Off Count */ #define SSB_SPROM3_GPIOLDC_OFF_SHIFT 8 #define SSB_SPROM3_GPIOLDC_ON 0x00FF0000 /* On Count */ #define SSB_SPROM3_GPIOLDC_ON_SHIFT 16 -#define SSB_SPROM3_IL0MAC 0x004A /* 6 bytes MAC address for 802.11b/g */ -#define SSB_SPROM3_CCKPO 0x0078 /* CCK Power Offset */ +#define SSB_SPROM3_CCKPO 0x1078 /* CCK Power Offset */ #define SSB_SPROM3_CCKPO_1M 0x000F /* 1M Rate PO */ #define SSB_SPROM3_CCKPO_2M 0x00F0 /* 2M Rate PO */ #define SSB_SPROM3_CCKPO_2M_SHIFT 4 @@ -265,100 +264,100 @@ #define SSB_SPROM3_OFDMGPO 0x107A /* G-PHY OFDM Power Offset (4 bytes, BigEndian) */ /* SPROM Revision 4 */ -#define SSB_SPROM4_BFLLO 0x0044 /* Boardflags (low 16 bits) */ -#define SSB_SPROM4_BFLHI 0x0046 /* Board Flags Hi */ -#define SSB_SPROM4_IL0MAC 0x004C /* 6 byte MAC address for a/b/g/n */ -#define SSB_SPROM4_CCODE 0x0052 /* Country Code (2 bytes) */ -#define SSB_SPROM4_GPIOA 0x0056 /* Gen. Purpose IO # 0 and 1 */ -#define SSB_SPROM4_GPIOA_P0 0x00FF /* Pin 0 */ -#define SSB_SPROM4_GPIOA_P1 0xFF00 /* Pin 1 */ -#define SSB_SPROM4_GPIOA_P1_SHIFT 8 -#define SSB_SPROM4_GPIOB 0x0058 /* Gen. Purpose IO # 2 and 3 */ -#define SSB_SPROM4_GPIOB_P2 0x00FF /* Pin 2 */ -#define SSB_SPROM4_GPIOB_P3 0xFF00 /* Pin 3 */ -#define SSB_SPROM4_GPIOB_P3_SHIFT 8 -#define SSB_SPROM4_ETHPHY 0x005A /* Ethernet PHY settings ?? */ +#define SSB_SPROM4_IL0MAC 0x104C /* 6 byte MAC address for a/b/g/n */ +#define SSB_SPROM4_ETHPHY 0x105A /* Ethernet PHY settings ?? */ #define SSB_SPROM4_ETHPHY_ET0A 0x001F /* MII Address for enet0 */ #define SSB_SPROM4_ETHPHY_ET1A 0x03E0 /* MII Address for enet1 */ #define SSB_SPROM4_ETHPHY_ET1A_SHIFT 5 #define SSB_SPROM4_ETHPHY_ET0M (1<<14) /* MDIO for enet0 */ #define SSB_SPROM4_ETHPHY_ET1M (1<<15) /* MDIO for enet1 */ -#define SSB_SPROM4_ANTAVAIL 0x005D /* Antenna available bitfields */ -#define SSB_SPROM4_ANTAVAIL_A 0x00FF /* A-PHY bitfield */ -#define SSB_SPROM4_ANTAVAIL_A_SHIFT 0 -#define SSB_SPROM4_ANTAVAIL_BG 0xFF00 /* B-PHY and G-PHY bitfield */ -#define SSB_SPROM4_ANTAVAIL_BG_SHIFT 8 -#define SSB_SPROM4_AGAIN01 0x005E /* Antenna Gain (in dBm Q5.2) */ +#define SSB_SPROM4_CCODE 0x1052 /* Country Code (2 bytes) */ +#define SSB_SPROM4_ANTAVAIL 0x105D /* Antenna available bitfields */ +#define SSB_SPROM4_ANTAVAIL_A 0x00FF /* A-PHY bitfield */ +#define SSB_SPROM4_ANTAVAIL_A_SHIFT 0 +#define SSB_SPROM4_ANTAVAIL_BG 0xFF00 /* B-PHY and G-PHY bitfield */ +#define SSB_SPROM4_ANTAVAIL_BG_SHIFT 8 +#define SSB_SPROM4_BFLLO 0x1044 /* Boardflags (low 16 bits) */ +#define SSB_SPROM4_AGAIN01 0x105E /* Antenna Gain (in dBm Q5.2) */ #define SSB_SPROM4_AGAIN0 0x00FF /* Antenna 0 */ #define SSB_SPROM4_AGAIN0_SHIFT 0 #define SSB_SPROM4_AGAIN1 0xFF00 /* Antenna 1 */ #define SSB_SPROM4_AGAIN1_SHIFT 8 -#define SSB_SPROM4_AGAIN23 0x0060 +#define SSB_SPROM4_AGAIN23 0x1060 #define SSB_SPROM4_AGAIN2 0x00FF /* Antenna 2 */ #define SSB_SPROM4_AGAIN2_SHIFT 0 #define SSB_SPROM4_AGAIN3 0xFF00 /* Antenna 3 */ #define SSB_SPROM4_AGAIN3_SHIFT 8 -#define SSB_SPROM4_MAXP_BG 0x0080 /* Max Power BG in path 1 */ +#define SSB_SPROM4_BFLHI 0x1046 /* Board Flags Hi */ +#define SSB_SPROM4_MAXP_BG 0x1080 /* Max Power BG in path 1 */ #define SSB_SPROM4_MAXP_BG_MASK 0x00FF /* Mask for Max Power BG */ #define SSB_SPROM4_ITSSI_BG 0xFF00 /* Mask for path 1 itssi_bg */ #define SSB_SPROM4_ITSSI_BG_SHIFT 8 -#define SSB_SPROM4_MAXP_A 0x008A /* Max Power A in path 1 */ +#define SSB_SPROM4_MAXP_A 0x108A /* Max Power A in path 1 */ #define SSB_SPROM4_MAXP_A_MASK 0x00FF /* Mask for Max Power A */ #define SSB_SPROM4_ITSSI_A 0xFF00 /* Mask for path 1 itssi_a */ #define SSB_SPROM4_ITSSI_A_SHIFT 8 -#define SSB_SPROM4_PA0B0 0x0082 /* The paXbY locations are */ -#define SSB_SPROM4_PA0B1 0x0084 /* only guesses */ -#define SSB_SPROM4_PA0B2 0x0086 -#define SSB_SPROM4_PA1B0 0x008E -#define SSB_SPROM4_PA1B1 0x0090 -#define SSB_SPROM4_PA1B2 0x0092 +#define SSB_SPROM4_GPIOA 0x1056 /* Gen. Purpose IO # 0 and 1 */ +#define SSB_SPROM4_GPIOA_P0 0x00FF /* Pin 0 */ +#define SSB_SPROM4_GPIOA_P1 0xFF00 /* Pin 1 */ +#define SSB_SPROM4_GPIOA_P1_SHIFT 8 +#define SSB_SPROM4_GPIOB 0x1058 /* Gen. Purpose IO # 2 and 3 */ +#define SSB_SPROM4_GPIOB_P2 0x00FF /* Pin 2 */ +#define SSB_SPROM4_GPIOB_P3 0xFF00 /* Pin 3 */ +#define SSB_SPROM4_GPIOB_P3_SHIFT 8 +#define SSB_SPROM4_PA0B0 0x1082 /* The paXbY locations are */ +#define SSB_SPROM4_PA0B1 0x1084 /* only guesses */ +#define SSB_SPROM4_PA0B2 0x1086 +#define SSB_SPROM4_PA1B0 0x108E +#define SSB_SPROM4_PA1B1 0x1090 +#define SSB_SPROM4_PA1B2 0x1092 /* SPROM Revision 5 (inherits most data from rev 4) */ -#define SSB_SPROM5_CCODE 0x0044 /* Country Code (2 bytes) */ -#define SSB_SPROM5_BFLLO 0x004A /* Boardflags (low 16 bits) */ -#define SSB_SPROM5_BFLHI 0x004C /* Board Flags Hi */ -#define SSB_SPROM5_IL0MAC 0x0052 /* 6 byte MAC address for a/b/g/n */ -#define SSB_SPROM5_GPIOA 0x0076 /* Gen. Purpose IO # 0 and 1 */ +#define SSB_SPROM5_BFLLO 0x104A /* Boardflags (low 16 bits) */ +#define SSB_SPROM5_BFLHI 0x104C /* Board Flags Hi */ +#define SSB_SPROM5_IL0MAC 0x1052 /* 6 byte MAC address for a/b/g/n */ +#define SSB_SPROM5_CCODE 0x1044 /* Country Code (2 bytes) */ +#define SSB_SPROM5_GPIOA 0x1076 /* Gen. Purpose IO # 0 and 1 */ #define SSB_SPROM5_GPIOA_P0 0x00FF /* Pin 0 */ #define SSB_SPROM5_GPIOA_P1 0xFF00 /* Pin 1 */ #define SSB_SPROM5_GPIOA_P1_SHIFT 8 -#define SSB_SPROM5_GPIOB 0x0078 /* Gen. Purpose IO # 2 and 3 */ +#define SSB_SPROM5_GPIOB 0x1078 /* Gen. Purpose IO # 2 and 3 */ #define SSB_SPROM5_GPIOB_P2 0x00FF /* Pin 2 */ #define SSB_SPROM5_GPIOB_P3 0xFF00 /* Pin 3 */ #define SSB_SPROM5_GPIOB_P3_SHIFT 8 /* SPROM Revision 8 */ -#define SSB_SPROM8_BOARDREV 0x0082 /* Board revision */ -#define SSB_SPROM8_BFLLO 0x0084 /* Board flags (bits 0-15) */ -#define SSB_SPROM8_BFLHI 0x0086 /* Board flags (bits 16-31) */ -#define SSB_SPROM8_BFL2LO 0x0088 /* Board flags (bits 32-47) */ -#define SSB_SPROM8_BFL2HI 0x008A /* Board flags (bits 48-63) */ -#define SSB_SPROM8_IL0MAC 0x008C /* 6 byte MAC address */ -#define SSB_SPROM8_CCODE 0x0092 /* 2 byte country code */ -#define SSB_SPROM8_GPIOA 0x0096 /*Gen. Purpose IO # 0 and 1 */ -#define SSB_SPROM8_GPIOA_P0 0x00FF /* Pin 0 */ -#define SSB_SPROM8_GPIOA_P1 0xFF00 /* Pin 1 */ -#define SSB_SPROM8_GPIOA_P1_SHIFT 8 -#define SSB_SPROM8_GPIOB 0x0098 /* Gen. Purpose IO # 2 and 3 */ -#define SSB_SPROM8_GPIOB_P2 0x00FF /* Pin 2 */ -#define SSB_SPROM8_GPIOB_P3 0xFF00 /* Pin 3 */ -#define SSB_SPROM8_GPIOB_P3_SHIFT 8 -#define SSB_SPROM8_ANTAVAIL 0x009C /* Antenna available bitfields*/ -#define SSB_SPROM8_ANTAVAIL_A 0xFF00 /* A-PHY bitfield */ -#define SSB_SPROM8_ANTAVAIL_A_SHIFT 8 -#define SSB_SPROM8_ANTAVAIL_BG 0x00FF /* B-PHY and G-PHY bitfield */ -#define SSB_SPROM8_ANTAVAIL_BG_SHIFT 0 -#define SSB_SPROM8_AGAIN01 0x009E /* Antenna Gain (in dBm Q5.2) */ +#define SSB_SPROM8_BOARDREV 0x1082 /* Board revision */ +#define SSB_SPROM8_BFLLO 0x1084 /* Board flags (bits 0-15) */ +#define SSB_SPROM8_BFLHI 0x1086 /* Board flags (bits 16-31) */ +#define SSB_SPROM8_BFL2LO 0x1088 /* Board flags (bits 32-47) */ +#define SSB_SPROM8_BFL2HI 0x108A /* Board flags (bits 48-63) */ +#define SSB_SPROM8_IL0MAC 0x108C /* 6 byte MAC address */ +#define SSB_SPROM8_CCODE 0x1092 /* 2 byte country code */ +#define SSB_SPROM8_ANTAVAIL 0x109C /* Antenna available bitfields*/ +#define SSB_SPROM8_ANTAVAIL_A 0xFF00 /* A-PHY bitfield */ +#define SSB_SPROM8_ANTAVAIL_A_SHIFT 8 +#define SSB_SPROM8_ANTAVAIL_BG 0x00FF /* B-PHY and G-PHY bitfield */ +#define SSB_SPROM8_ANTAVAIL_BG_SHIFT 0 +#define SSB_SPROM8_AGAIN01 0x109E /* Antenna Gain (in dBm Q5.2) */ #define SSB_SPROM8_AGAIN0 0x00FF /* Antenna 0 */ #define SSB_SPROM8_AGAIN0_SHIFT 0 #define SSB_SPROM8_AGAIN1 0xFF00 /* Antenna 1 */ #define SSB_SPROM8_AGAIN1_SHIFT 8 -#define SSB_SPROM8_AGAIN23 0x00A0 +#define SSB_SPROM8_AGAIN23 0x10A0 #define SSB_SPROM8_AGAIN2 0x00FF /* Antenna 2 */ #define SSB_SPROM8_AGAIN2_SHIFT 0 #define SSB_SPROM8_AGAIN3 0xFF00 /* Antenna 3 */ #define SSB_SPROM8_AGAIN3_SHIFT 8 -#define SSB_SPROM8_RSSIPARM2G 0x00A4 /* RSSI params for 2GHz */ +#define SSB_SPROM8_GPIOA 0x1096 /*Gen. Purpose IO # 0 and 1 */ +#define SSB_SPROM8_GPIOA_P0 0x00FF /* Pin 0 */ +#define SSB_SPROM8_GPIOA_P1 0xFF00 /* Pin 1 */ +#define SSB_SPROM8_GPIOA_P1_SHIFT 8 +#define SSB_SPROM8_GPIOB 0x1098 /* Gen. Purpose IO # 2 and 3 */ +#define SSB_SPROM8_GPIOB_P2 0x00FF /* Pin 2 */ +#define SSB_SPROM8_GPIOB_P3 0xFF00 /* Pin 3 */ +#define SSB_SPROM8_GPIOB_P3_SHIFT 8 +#define SSB_SPROM8_RSSIPARM2G 0x10A4 /* RSSI params for 2GHz */ #define SSB_SPROM8_RSSISMF2G 0x000F #define SSB_SPROM8_RSSISMC2G 0x00F0 #define SSB_SPROM8_RSSISMC2G_SHIFT 4 @@ -366,7 +365,7 @@ #define SSB_SPROM8_RSSISAV2G_SHIFT 8 #define SSB_SPROM8_BXA2G 0x1800 #define SSB_SPROM8_BXA2G_SHIFT 11 -#define SSB_SPROM8_RSSIPARM5G 0x00A6 /* RSSI params for 5GHz */ +#define SSB_SPROM8_RSSIPARM5G 0x10A6 /* RSSI params for 5GHz */ #define SSB_SPROM8_RSSISMF5G 0x000F #define SSB_SPROM8_RSSISMC5G 0x00F0 #define SSB_SPROM8_RSSISMC5G_SHIFT 4 @@ -374,47 +373,47 @@ #define SSB_SPROM8_RSSISAV5G_SHIFT 8 #define SSB_SPROM8_BXA5G 0x1800 #define SSB_SPROM8_BXA5G_SHIFT 11 -#define SSB_SPROM8_TRI25G 0x00A8 /* TX isolation 2.4&5.3GHz */ +#define SSB_SPROM8_TRI25G 0x10A8 /* TX isolation 2.4&5.3GHz */ #define SSB_SPROM8_TRI2G 0x00FF /* TX isolation 2.4GHz */ #define SSB_SPROM8_TRI5G 0xFF00 /* TX isolation 5.3GHz */ #define SSB_SPROM8_TRI5G_SHIFT 8 -#define SSB_SPROM8_TRI5GHL 0x00AA /* TX isolation 5.2/5.8GHz */ +#define SSB_SPROM8_TRI5GHL 0x10AA /* TX isolation 5.2/5.8GHz */ #define SSB_SPROM8_TRI5GL 0x00FF /* TX isolation 5.2GHz */ #define SSB_SPROM8_TRI5GH 0xFF00 /* TX isolation 5.8GHz */ #define SSB_SPROM8_TRI5GH_SHIFT 8 -#define SSB_SPROM8_RXPO 0x00AC /* RX power offsets */ +#define SSB_SPROM8_RXPO 0x10AC /* RX power offsets */ #define SSB_SPROM8_RXPO2G 0x00FF /* 2GHz RX power offset */ #define SSB_SPROM8_RXPO5G 0xFF00 /* 5GHz RX power offset */ #define SSB_SPROM8_RXPO5G_SHIFT 8 -#define SSB_SPROM8_MAXP_BG 0x00C0 /* Max Power 2GHz in path 1 */ +#define SSB_SPROM8_MAXP_BG 0x10C0 /* Max Power 2GHz in path 1 */ #define SSB_SPROM8_MAXP_BG_MASK 0x00FF /* Mask for Max Power 2GHz */ #define SSB_SPROM8_ITSSI_BG 0xFF00 /* Mask for path 1 itssi_bg */ #define SSB_SPROM8_ITSSI_BG_SHIFT 8 -#define SSB_SPROM8_PA0B0 0x00C2 /* 2GHz power amp settings */ -#define SSB_SPROM8_PA0B1 0x00C4 -#define SSB_SPROM8_PA0B2 0x00C6 -#define SSB_SPROM8_MAXP_A 0x00C8 /* Max Power 5.3GHz */ +#define SSB_SPROM8_PA0B0 0x10C2 /* 2GHz power amp settings */ +#define SSB_SPROM8_PA0B1 0x10C4 +#define SSB_SPROM8_PA0B2 0x10C6 +#define SSB_SPROM8_MAXP_A 0x10C8 /* Max Power 5.3GHz */ #define SSB_SPROM8_MAXP_A_MASK 0x00FF /* Mask for Max Power 5.3GHz */ #define SSB_SPROM8_ITSSI_A 0xFF00 /* Mask for path 1 itssi_a */ #define SSB_SPROM8_ITSSI_A_SHIFT 8 -#define SSB_SPROM8_MAXP_AHL 0x00CA /* Max Power 5.2/5.8GHz */ +#define SSB_SPROM8_MAXP_AHL 0x10CA /* Max Power 5.2/5.8GHz */ #define SSB_SPROM8_MAXP_AH_MASK 0x00FF /* Mask for Max Power 5.8GHz */ #define SSB_SPROM8_MAXP_AL_MASK 0xFF00 /* Mask for Max Power 5.2GHz */ #define SSB_SPROM8_MAXP_AL_SHIFT 8 -#define SSB_SPROM8_PA1B0 0x00CC /* 5.3GHz power amp settings */ -#define SSB_SPROM8_PA1B1 0x00CE -#define SSB_SPROM8_PA1B2 0x00D0 -#define SSB_SPROM8_PA1LOB0 0x00D2 /* 5.2GHz power amp settings */ -#define SSB_SPROM8_PA1LOB1 0x00D4 -#define SSB_SPROM8_PA1LOB2 0x00D6 -#define SSB_SPROM8_PA1HIB0 0x00D8 /* 5.8GHz power amp settings */ -#define SSB_SPROM8_PA1HIB1 0x00DA -#define SSB_SPROM8_PA1HIB2 0x00DC -#define SSB_SPROM8_CCK2GPO 0x0140 /* CCK power offset */ -#define SSB_SPROM8_OFDM2GPO 0x0142 /* 2.4GHz OFDM power offset */ -#define SSB_SPROM8_OFDM5GPO 0x0146 /* 5.3GHz OFDM power offset */ -#define SSB_SPROM8_OFDM5GLPO 0x014A /* 5.2GHz OFDM power offset */ -#define SSB_SPROM8_OFDM5GHPO 0x014E /* 5.8GHz OFDM power offset */ +#define SSB_SPROM8_PA1B0 0x10CC /* 5.3GHz power amp settings */ +#define SSB_SPROM8_PA1B1 0x10CE +#define SSB_SPROM8_PA1B2 0x10D0 +#define SSB_SPROM8_PA1LOB0 0x10D2 /* 5.2GHz power amp settings */ +#define SSB_SPROM8_PA1LOB1 0x10D4 +#define SSB_SPROM8_PA1LOB2 0x10D6 +#define SSB_SPROM8_PA1HIB0 0x10D8 /* 5.8GHz power amp settings */ +#define SSB_SPROM8_PA1HIB1 0x10DA +#define SSB_SPROM8_PA1HIB2 0x10DC +#define SSB_SPROM8_CCK2GPO 0x1140 /* CCK power offset */ +#define SSB_SPROM8_OFDM2GPO 0x1142 /* 2.4GHz OFDM power offset */ +#define SSB_SPROM8_OFDM5GPO 0x1146 /* 5.3GHz OFDM power offset */ +#define SSB_SPROM8_OFDM5GLPO 0x114A /* 5.2GHz OFDM power offset */ +#define SSB_SPROM8_OFDM5GHPO 0x114E /* 5.8GHz OFDM power offset */ /* Values for SSB_SPROM1_BINF_CCODE */ enum { diff --git a/trunk/include/net/cfg80211.h b/trunk/include/net/cfg80211.h index 7d10c0182f53..5a4efe54cffd 100644 --- a/trunk/include/net/cfg80211.h +++ b/trunk/include/net/cfg80211.h @@ -511,7 +511,6 @@ struct mpath_info { * @basic_rates: basic rates in IEEE 802.11 format * (or NULL for no change) * @basic_rates_len: number of basic rates - * @ap_isolate: do not forward packets between connected stations */ struct bss_parameters { int use_cts_prot; @@ -519,7 +518,6 @@ struct bss_parameters { int use_short_slot_time; u8 *basic_rates; u8 basic_rates_len; - int ap_isolate; }; struct mesh_config { @@ -1020,8 +1018,6 @@ struct cfg80211_pmksa { * RSN IE. It allows for faster roaming between WPA2 BSSIDs. * @del_pmksa: Delete a cached PMKID. * @flush_pmksa: Flush all cached PMKIDs. - * @set_power_mgmt: Configure WLAN power management. A timeout value of -1 - * allows the driver to adjust the dynamic ps timeout value. * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold. * */ diff --git a/trunk/include/net/mac80211.h b/trunk/include/net/mac80211.h index 54aa16b98b76..78908b516f42 100644 --- a/trunk/include/net/mac80211.h +++ b/trunk/include/net/mac80211.h @@ -145,7 +145,6 @@ struct ieee80211_low_level_stats { * @BSS_CHANGED_BEACON_ENABLED: Beaconing should be * enabled/disabled (beaconing modes) * @BSS_CHANGED_CQM: Connection quality monitor config changed - * @BSS_CHANGED_IBSS: IBSS join status changed */ enum ieee80211_bss_change { BSS_CHANGED_ASSOC = 1<<0, @@ -159,7 +158,6 @@ enum ieee80211_bss_change { BSS_CHANGED_BEACON = 1<<8, BSS_CHANGED_BEACON_ENABLED = 1<<9, BSS_CHANGED_CQM = 1<<10, - BSS_CHANGED_IBSS = 1<<11, }; /** @@ -169,8 +167,6 @@ enum ieee80211_bss_change { * to that BSS) that can change during the lifetime of the BSS. * * @assoc: association status - * @ibss_joined: indicates whether this station is part of an IBSS - * or not * @aid: association ID number, valid only when @assoc is true * @use_cts_prot: use CTS protection * @use_short_preamble: use 802.11b short preamble; @@ -198,7 +194,7 @@ enum ieee80211_bss_change { struct ieee80211_bss_conf { const u8 *bssid; /* association related data */ - bool assoc, ibss_joined; + bool assoc; u16 aid; /* erp related data */ bool use_cts_prot; @@ -560,6 +556,7 @@ enum mac80211_rx_flags { * @signal: signal strength when receiving this frame, either in dBm, in dB or * unspecified depending on the hardware capabilities flags * @IEEE80211_HW_SIGNAL_* + * @noise: noise when receiving this frame, in dBm (DEPRECATED). * @antenna: antenna used * @rate_idx: index of data rate into band's supported rates or MCS index if * HT rates are use (RX_FLAG_HT) @@ -570,6 +567,7 @@ struct ieee80211_rx_status { enum ieee80211_band band; int freq; int signal; + int noise __deprecated; int antenna; int rate_idx; int flag; @@ -670,9 +668,6 @@ enum ieee80211_smps_mode { * @dynamic_ps_timeout: The dynamic powersave timeout (in ms), see the * powersave documentation below. This variable is valid only when * the CONF_PS flag is set. - * @dynamic_ps_forced_timeout: The dynamic powersave timeout (in ms) configured - * by cfg80211 (essentially, wext) If set, this value overrules the value - * chosen by mac80211 based on ps qos network latency. * * @power_level: requested transmit power (in dBm) * @@ -692,7 +687,7 @@ enum ieee80211_smps_mode { */ struct ieee80211_conf { u32 flags; - int power_level, dynamic_ps_timeout, dynamic_ps_forced_timeout; + int power_level, dynamic_ps_timeout; int max_sleep_period; u16 listen_interval; @@ -932,6 +927,10 @@ enum ieee80211_tkip_key_type { * one milliwatt. This is the preferred method since it is standardized * between different devices. @max_signal does not need to be set. * + * @IEEE80211_HW_NOISE_DBM: + * Hardware can provide noise (radio interference) values in units dBm, + * decibel difference from one milliwatt. + * * @IEEE80211_HW_SPECTRUM_MGMT: * Hardware supports spectrum management defined in 802.11h * Measurement, Channel Switch, Quieting, TPC @@ -995,7 +994,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE = 1<<4, IEEE80211_HW_SIGNAL_UNSPEC = 1<<5, IEEE80211_HW_SIGNAL_DBM = 1<<6, - /* use this hole */ + IEEE80211_HW_NOISE_DBM = 1<<7, IEEE80211_HW_SPECTRUM_MGMT = 1<<8, IEEE80211_HW_AMPDU_AGGREGATION = 1<<9, IEEE80211_HW_SUPPORTS_PS = 1<<10, @@ -1655,7 +1654,7 @@ struct ieee80211_ops { struct ieee80211_key_conf *conf, struct ieee80211_sta *sta, u32 iv32, u16 *phase1key); - int (*hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + int (*hw_scan)(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); void (*sw_scan_start)(struct ieee80211_hw *hw); void (*sw_scan_complete)(struct ieee80211_hw *hw); diff --git a/trunk/include/net/sctp/sctp.h b/trunk/include/net/sctp/sctp.h index 65946bc43d00..e9a408718636 100644 --- a/trunk/include/net/sctp/sctp.h +++ b/trunk/include/net/sctp/sctp.h @@ -547,7 +547,7 @@ for (pos = chunk->subh.fwdtsn_hdr->skip;\ #define WORD_ROUND(s) (((s)+3)&~3) /* Make a new instance of type. */ -#define t_new(type, flags) (type *)kzalloc(sizeof(type), flags) +#define t_new(type, flags) (type *)kmalloc(sizeof(type), flags) /* Compare two timevals. */ #define tv_lt(s, t) \ diff --git a/trunk/include/net/sctp/sm.h b/trunk/include/net/sctp/sm.h index 273a8bb683e3..851c813adb3a 100644 --- a/trunk/include/net/sctp/sm.h +++ b/trunk/include/net/sctp/sm.h @@ -437,7 +437,7 @@ sctp_vtag_verify_either(const struct sctp_chunk *chunk, */ if ((!sctp_test_T_bit(chunk) && (ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag)) || - (sctp_test_T_bit(chunk) && asoc->c.peer_vtag && + (sctp_test_T_bit(chunk) && (ntohl(chunk->sctp_hdr->vtag) == asoc->c.peer_vtag))) { return 1; } diff --git a/trunk/include/net/sctp/structs.h b/trunk/include/net/sctp/structs.h index 43257b903c82..597f8e27aaf6 100644 --- a/trunk/include/net/sctp/structs.h +++ b/trunk/include/net/sctp/structs.h @@ -643,15 +643,17 @@ struct sctp_pf { struct sctp_datamsg { /* Chunks waiting to be submitted to lower layer. */ struct list_head chunks; + /* Chunks that have been transmitted. */ + size_t msg_size; /* Reference counting. */ atomic_t refcnt; /* When is this message no longer interesting to the peer? */ unsigned long expires_at; /* Did the messenge fail to send? */ int send_error; - u8 send_failed:1, - can_abandon:1, /* can chunks from this message can be abandoned. */ - can_delay; /* should this message be Nagle delayed */ + char send_failed; + /* Control whether chunks from this message can be abandoned. */ + char can_abandon; }; struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *, @@ -755,6 +757,7 @@ struct sctp_chunk { #define SCTP_NEED_FRTX 0x1 #define SCTP_DONT_FRTX 0x2 __u16 rtt_in_progress:1, /* This chunk used for RTT calc? */ + resent:1, /* Has this chunk ever been resent. */ has_tsn:1, /* Does this chunk have a TSN yet? */ has_ssn:1, /* Does this chunk have a SSN yet? */ singleton:1, /* Only chunk in the packet? */ @@ -876,30 +879,7 @@ struct sctp_transport { /* Reference counting. */ atomic_t refcnt; - int dead:1, - /* RTO-Pending : A flag used to track if one of the DATA - * chunks sent to this address is currently being - * used to compute a RTT. If this flag is 0, - * the next DATA chunk sent to this destination - * should be used to compute a RTT and this flag - * should be set. Every time the RTT - * calculation completes (i.e. the DATA chunk - * is SACK'd) clear this flag. - */ - rto_pending:1, - - /* - * hb_sent : a flag that signals that we have a pending - * heartbeat. - */ - hb_sent:1, - - /* Is the Path MTU update pending on this tranport */ - pmtu_pending:1, - - /* Is this structure kfree()able? */ - malloced:1; - + int dead; /* This is the peer's IP address and port. */ union sctp_addr ipaddr; @@ -929,6 +909,22 @@ struct sctp_transport { /* SRTT : The current smoothed round trip time. */ __u32 srtt; + /* RTO-Pending : A flag used to track if one of the DATA + * chunks sent to this address is currently being + * used to compute a RTT. If this flag is 0, + * the next DATA chunk sent to this destination + * should be used to compute a RTT and this flag + * should be set. Every time the RTT + * calculation completes (i.e. the DATA chunk + * is SACK'd) clear this flag. + * hb_sent : a flag that signals that we have a pending heartbeat. + */ + __u8 rto_pending; + __u8 hb_sent; + + /* Flag to track the current fast recovery state */ + __u8 fast_recovery; + /* * These are the congestion stats. */ @@ -948,6 +944,9 @@ struct sctp_transport { __u32 burst_limited; /* Holds old cwnd when max.burst is applied */ + /* TSN marking the fast recovery exit point */ + __u32 fast_recovery_exit; + /* Destination */ struct dst_entry *dst; /* Source address. */ @@ -978,6 +977,9 @@ struct sctp_transport { */ __u16 pathmaxrxt; + /* is the Path MTU update pending on this tranport */ + __u8 pmtu_pending; + /* PMTU : The current known path MTU. */ __u32 pathmtu; @@ -1021,6 +1023,8 @@ struct sctp_transport { /* This is the list of transports that have chunks to send. */ struct list_head send_ready; + int malloced; /* Is this structure kfree()able? */ + /* State information saved for SFR_CACC algorithm. The key * idea in SFR_CACC is to maintain state at the sender on a * per-destination basis when a changeover happens. @@ -1062,7 +1066,7 @@ void sctp_transport_route(struct sctp_transport *, union sctp_addr *, struct sctp_sock *); void sctp_transport_pmtu(struct sctp_transport *); void sctp_transport_free(struct sctp_transport *); -void sctp_transport_reset_timers(struct sctp_transport *); +void sctp_transport_reset_timers(struct sctp_transport *, int); void sctp_transport_hold(struct sctp_transport *); void sctp_transport_put(struct sctp_transport *); void sctp_transport_update_rto(struct sctp_transport *, __u32); @@ -1716,12 +1720,6 @@ struct sctp_association { /* Highest TSN that is acknowledged by incoming SACKs. */ __u32 highest_sacked; - /* TSN marking the fast recovery exit point */ - __u32 fast_recovery_exit; - - /* Flag to track the current fast recovery state */ - __u8 fast_recovery; - /* The number of unacknowledged data chunks. Reported through * the SCTP_STATUS sockopt. */ diff --git a/trunk/net/core/datagram.c b/trunk/net/core/datagram.c index e0097531417a..95b851f3d713 100644 --- a/trunk/net/core/datagram.c +++ b/trunk/net/core/datagram.c @@ -229,18 +229,13 @@ EXPORT_SYMBOL(skb_free_datagram); void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb) { - if (likely(atomic_read(&skb->users) == 1)) - smp_rmb(); - else if (likely(!atomic_dec_and_test(&skb->users))) - return; - lock_sock_bh(sk); skb_orphan(skb); sk_mem_reclaim_partial(sk); unlock_sock_bh(sk); - /* skb is now orphaned, can be freed outside of locked section */ - __kfree_skb(skb); + /* skb is now orphaned, might be freed outside of locked section */ + consume_skb(skb); } EXPORT_SYMBOL(skb_free_datagram_locked); diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 36d53be4fca6..100dcbd29739 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -2205,6 +2205,8 @@ int netdev_max_backlog __read_mostly = 1000; int netdev_budget __read_mostly = 300; int weight_p __read_mostly = 64; /* old backlog weight */ +DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, }; + #ifdef CONFIG_RPS /* One global table that all flow-based protocols share. */ @@ -2364,7 +2366,7 @@ static void rps_trigger_softirq(void *data) struct softnet_data *sd = data; __napi_schedule(&sd->backlog); - sd->received_rps++; + __get_cpu_var(netdev_rx_stat).received_rps++; } #endif /* CONFIG_RPS */ @@ -2403,6 +2405,7 @@ static int enqueue_to_backlog(struct sk_buff *skb, int cpu, sd = &per_cpu(softnet_data, cpu); local_irq_save(flags); + __get_cpu_var(netdev_rx_stat).total++; rps_lock(sd); if (skb_queue_len(&sd->input_pkt_queue) <= netdev_max_backlog) { @@ -2426,9 +2429,9 @@ static int enqueue_to_backlog(struct sk_buff *skb, int cpu, goto enqueue; } - sd->dropped++; rps_unlock(sd); + __get_cpu_var(netdev_rx_stat).dropped++; local_irq_restore(flags); kfree_skb(skb); @@ -2803,7 +2806,7 @@ static int __netif_receive_skb(struct sk_buff *skb) skb->dev = master; } - __get_cpu_var(softnet_data).processed++; + __get_cpu_var(netdev_rx_stat).total++; skb_reset_network_header(skb); skb_reset_transport_header(skb); @@ -3487,7 +3490,7 @@ static void net_rx_action(struct softirq_action *h) return; softnet_break: - sd->time_squeeze++; + __get_cpu_var(netdev_rx_stat).time_squeeze++; __raise_softirq_irqoff(NET_RX_SOFTIRQ); goto out; } @@ -3688,17 +3691,17 @@ static int dev_seq_show(struct seq_file *seq, void *v) return 0; } -static struct softnet_data *softnet_get_online(loff_t *pos) +static struct netif_rx_stats *softnet_get_online(loff_t *pos) { - struct softnet_data *sd = NULL; + struct netif_rx_stats *rc = NULL; while (*pos < nr_cpu_ids) if (cpu_online(*pos)) { - sd = &per_cpu(softnet_data, *pos); + rc = &per_cpu(netdev_rx_stat, *pos); break; } else ++*pos; - return sd; + return rc; } static void *softnet_seq_start(struct seq_file *seq, loff_t *pos) @@ -3718,12 +3721,12 @@ static void softnet_seq_stop(struct seq_file *seq, void *v) static int softnet_seq_show(struct seq_file *seq, void *v) { - struct softnet_data *sd = v; + struct netif_rx_stats *s = v; seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x %08x %08x\n", - sd->processed, sd->dropped, sd->time_squeeze, 0, + s->total, s->dropped, s->time_squeeze, 0, 0, 0, 0, 0, /* was fastroute */ - sd->cpu_collision, sd->received_rps); + s->cpu_collision, s->received_rps); return 0; } @@ -5866,7 +5869,6 @@ static int __init net_dev_init(void) for_each_possible_cpu(i) { struct softnet_data *sd = &per_cpu(softnet_data, i); - memset(sd, 0, sizeof(*sd)); skb_queue_head_init(&sd->input_pkt_queue); skb_queue_head_init(&sd->process_queue); sd->completion_queue = NULL; diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index a9b0e1f77806..8b9c109166a7 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -181,14 +181,12 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node); if (!skb) goto out; - prefetchw(skb); size = SKB_DATA_ALIGN(size); data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info), gfp_mask, node); if (!data) goto nodata; - prefetchw(data + size); /* * Only clear those fields we need to clear, not those that we will @@ -210,8 +208,15 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, /* make sure we initialize shinfo sequentially */ shinfo = skb_shinfo(skb); - memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); atomic_set(&shinfo->dataref, 1); + shinfo->nr_frags = 0; + shinfo->gso_size = 0; + shinfo->gso_segs = 0; + shinfo->gso_type = 0; + shinfo->ip6_frag_id = 0; + shinfo->tx_flags.flags = 0; + skb_frag_list_init(skb); + memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps)); if (fclone) { struct sk_buff *child = skb + 1; @@ -500,10 +505,16 @@ int skb_recycle_check(struct sk_buff *skb, int skb_size) return 0; skb_release_head_state(skb); - shinfo = skb_shinfo(skb); - memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); atomic_set(&shinfo->dataref, 1); + shinfo->nr_frags = 0; + shinfo->gso_size = 0; + shinfo->gso_segs = 0; + shinfo->gso_type = 0; + shinfo->ip6_frag_id = 0; + shinfo->tx_flags.flags = 0; + skb_frag_list_init(skb); + memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps)); memset(skb, 0, offsetof(struct sk_buff, tail)); skb->data = skb->head + NET_SKB_PAD; diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index 3984f52181f4..34d2d649e396 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -1346,7 +1346,7 @@ struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, const struct in6_addr *add struct hlist_node *node; rcu_read_lock_bh(); - hlist_for_each_entry_rcu_bh(ifp, node, &inet6_addr_lst[hash], addr_lst) { + hlist_for_each_entry_rcu(ifp, node, &inet6_addr_lst[hash], addr_lst) { if (!net_eq(dev_net(ifp->idev->dev), net)) continue; if (ipv6_addr_equal(&ifp->addr, addr)) { @@ -2959,7 +2959,7 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq) for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) { struct hlist_node *n; - hlist_for_each_entry_rcu_bh(ifa, n, &inet6_addr_lst[state->bucket], + hlist_for_each_entry_rcu(ifa, n, &inet6_addr_lst[state->bucket], addr_lst) if (net_eq(dev_net(ifa->idev->dev), net)) return ifa; @@ -2974,12 +2974,12 @@ static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, struct net *net = seq_file_net(seq); struct hlist_node *n = &ifa->addr_lst; - hlist_for_each_entry_continue_rcu_bh(ifa, n, addr_lst) + hlist_for_each_entry_continue_rcu(ifa, n, addr_lst) if (net_eq(dev_net(ifa->idev->dev), net)) return ifa; while (++state->bucket < IN6_ADDR_HSIZE) { - hlist_for_each_entry_rcu_bh(ifa, n, + hlist_for_each_entry(ifa, n, &inet6_addr_lst[state->bucket], addr_lst) { if (net_eq(dev_net(ifa->idev->dev), net)) return ifa; @@ -3000,7 +3000,7 @@ static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos) } static void *if6_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(rcu_bh) + __acquires(rcu) { rcu_read_lock_bh(); return if6_get_idx(seq, *pos); @@ -3016,7 +3016,7 @@ static void *if6_seq_next(struct seq_file *seq, void *v, loff_t *pos) } static void if6_seq_stop(struct seq_file *seq, void *v) - __releases(rcu_bh) + __releases(rcu) { rcu_read_unlock_bh(); } @@ -3093,7 +3093,7 @@ int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr) unsigned int hash = ipv6_addr_hash(addr); rcu_read_lock_bh(); - hlist_for_each_entry_rcu_bh(ifp, n, &inet6_addr_lst[hash], addr_lst) { + hlist_for_each_entry_rcu(ifp, n, &inet6_addr_lst[hash], addr_lst) { if (!net_eq(dev_net(ifp->idev->dev), net)) continue; if (ipv6_addr_equal(&ifp->addr, addr) && @@ -3127,7 +3127,7 @@ static void addrconf_verify(unsigned long foo) for (i = 0; i < IN6_ADDR_HSIZE; i++) { restart: - hlist_for_each_entry_rcu_bh(ifp, node, + hlist_for_each_entry_rcu(ifp, node, &inet6_addr_lst[i], addr_lst) { unsigned long age; diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c index ae37270a0633..845a6e6b9d89 100644 --- a/trunk/net/mac80211/cfg.c +++ b/trunk/net/mac80211/cfg.c @@ -97,6 +97,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy, params->mesh_id_len, params->mesh_id); + if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags) + return 0; + if (type == NL80211_IFTYPE_AP_VLAN && params && params->use_4addr == 0) rcu_assign_pointer(sdata->u.vlan.sta, NULL); @@ -104,9 +107,7 @@ 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; - + sdata->u.mntr_flags = *flags; return 0; } @@ -1114,13 +1115,6 @@ static int ieee80211_change_bss(struct wiphy *wiphy, changed |= BSS_CHANGED_BASIC_RATES; } - if (params->ap_isolate >= 0) { - if (params->ap_isolate) - sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS; - else - sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS; - } - ieee80211_bss_info_change_notify(sdata, changed); return 0; @@ -1405,11 +1399,11 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, return -EOPNOTSUPP; if (enabled == sdata->u.mgd.powersave && - timeout == conf->dynamic_ps_forced_timeout) + timeout == conf->dynamic_ps_timeout) return 0; sdata->u.mgd.powersave = enabled; - conf->dynamic_ps_forced_timeout = timeout; + conf->dynamic_ps_timeout = timeout; /* no change, but if automatic follow powersave */ mutex_lock(&sdata->u.mgd.mtx); diff --git a/trunk/net/mac80211/debugfs_sta.c b/trunk/net/mac80211/debugfs_sta.c index e763f1529ddb..6bc9b07c3eda 100644 --- a/trunk/net/mac80211/debugfs_sta.c +++ b/trunk/net/mac80211/debugfs_sta.c @@ -39,13 +39,6 @@ static const struct file_operations sta_ ##name## _ops = { \ .open = mac80211_open_file_generic, \ } -#define STA_OPS_RW(name) \ -static const struct file_operations sta_ ##name## _ops = { \ - .read = sta_##name##_read, \ - .write = sta_##name##_write, \ - .open = mac80211_open_file_generic, \ -} - #define STA_FILE(name, field, format) \ STA_READ_##format(name, field) \ STA_OPS(name) @@ -163,63 +156,7 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); } - -static ssize_t sta_agg_status_write(struct file *file, const char __user *userbuf, - size_t count, loff_t *ppos) -{ - char _buf[12], *buf = _buf; - struct sta_info *sta = file->private_data; - bool start, tx; - unsigned long tid; - int ret; - - if (count > sizeof(_buf)) - return -EINVAL; - - if (copy_from_user(buf, userbuf, count)) - return -EFAULT; - - buf[sizeof(_buf) - 1] = '\0'; - - if (strncmp(buf, "tx ", 3) == 0) { - buf += 3; - tx = true; - } else if (strncmp(buf, "rx ", 3) == 0) { - buf += 3; - tx = false; - } else - return -EINVAL; - - if (strncmp(buf, "start ", 6) == 0) { - buf += 6; - start = true; - if (!tx) - return -EINVAL; - } else if (strncmp(buf, "stop ", 5) == 0) { - buf += 5; - start = false; - } else - return -EINVAL; - - tid = simple_strtoul(buf, NULL, 0); - - if (tid >= STA_TID_NUM) - return -EINVAL; - - if (tx) { - if (start) - ret = ieee80211_start_tx_ba_session(&sta->sta, tid); - else - ret = ieee80211_stop_tx_ba_session(&sta->sta, tid, - WLAN_BACK_RECIPIENT); - } else { - __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, 3); - ret = 0; - } - - return ret ?: count; -} -STA_OPS_RW(agg_status); +STA_OPS(agg_status); static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) diff --git a/trunk/net/mac80211/driver-ops.h b/trunk/net/mac80211/driver-ops.h index ee8b63f92f71..35e1e581e806 100644 --- a/trunk/net/mac80211/driver-ops.h +++ b/trunk/net/mac80211/driver-ops.h @@ -152,15 +152,14 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local, } static inline int drv_hw_scan(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, struct cfg80211_scan_request *req) { int ret; might_sleep(); - ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); - trace_drv_hw_scan(local, sdata, req, ret); + ret = local->ops->hw_scan(&local->hw, req); + trace_drv_hw_scan(local, req, ret); return ret; } diff --git a/trunk/net/mac80211/driver-trace.h b/trunk/net/mac80211/driver-trace.h index ce734b58d07a..e209cb82ff29 100644 --- a/trunk/net/mac80211/driver-trace.h +++ b/trunk/net/mac80211/driver-trace.h @@ -363,26 +363,23 @@ TRACE_EVENT(drv_update_tkip_key, TRACE_EVENT(drv_hw_scan, TP_PROTO(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, struct cfg80211_scan_request *req, int ret), - TP_ARGS(local, sdata, req, ret), + TP_ARGS(local, req, ret), TP_STRUCT__entry( LOCAL_ENTRY - VIF_ENTRY __field(int, ret) ), TP_fast_assign( LOCAL_ASSIGN; - VIF_ASSIGN; __entry->ret = ret; ), TP_printk( - LOCAL_PR_FMT VIF_PR_FMT " ret:%d", - LOCAL_PR_ARG,VIF_PR_ARG, __entry->ret + LOCAL_PR_FMT " ret:%d", + LOCAL_PR_ARG, __entry->ret ) ); diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index b72ee6435fa3..e6f3b0c7a71f 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -92,12 +92,6 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, if (memcmp(ifibss->bssid, bssid, ETH_ALEN)) sta_info_flush(sdata->local, sdata); - /* if merging, indicate to driver that we leave the old IBSS */ - if (sdata->vif.bss_conf.ibss_joined) { - sdata->vif.bss_conf.ibss_joined = false; - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS); - } - memcpy(ifibss->bssid, bssid, ETH_ALEN); sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; @@ -177,8 +171,6 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, bss_change |= BSS_CHANGED_BSSID; bss_change |= BSS_CHANGED_BEACON; bss_change |= BSS_CHANGED_BEACON_ENABLED; - bss_change |= BSS_CHANGED_IBSS; - sdata->vif.bss_conf.ibss_joined = true; ieee80211_bss_info_change_notify(sdata, bss_change); ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates); @@ -489,9 +481,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " "IBSS networks with same SSID (merge)\n", sdata->name); - ieee80211_request_internal_scan(sdata, - ifibss->ssid, ifibss->ssid_len, - ifibss->fixed_channel ? ifibss->channel : NULL); + ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len); } static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) @@ -598,9 +588,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " "join\n", sdata->name); - ieee80211_request_internal_scan(sdata, - ifibss->ssid, ifibss->ssid_len, - ifibss->fixed_channel ? ifibss->channel : NULL); + ieee80211_request_internal_scan(sdata, ifibss->ssid, + ifibss->ssid_len); } else { int interval = IEEE80211_SCAN_INTERVAL; @@ -908,12 +897,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, sdata->u.ibss.channel = params->channel; sdata->u.ibss.fixed_channel = params->channel_fixed; - /* fix ourselves to that channel now already */ - if (params->channel_fixed) { - sdata->local->oper_channel = params->channel; - sdata->local->oper_channel_type = NL80211_CHAN_NO_HT; - } - if (params->ie) { sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len, GFP_KERNEL); @@ -968,9 +951,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) kfree(sdata->u.ibss.ie); skb = sdata->u.ibss.presp; rcu_assign_pointer(sdata->u.ibss.presp, NULL); - sdata->vif.bss_conf.ibss_joined = false; - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | - BSS_CHANGED_IBSS); + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); synchronize_rcu(); kfree_skb(skb); diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h index cbaf4981e110..c9712f35e596 100644 --- a/trunk/net/mac80211/ieee80211_i.h +++ b/trunk/net/mac80211/ieee80211_i.h @@ -1019,8 +1019,7 @@ void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata); /* scan/BSS handling */ void ieee80211_scan_work(struct work_struct *work); int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, - const u8 *ssid, u8 ssid_len, - struct ieee80211_channel *chan); + const u8 *ssid, u8 ssid_len); int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, struct cfg80211_scan_request *req); void ieee80211_scan_cancel(struct ieee80211_local *local); diff --git a/trunk/net/mac80211/main.c b/trunk/net/mac80211/main.c index bd632e1ee2c5..011ee85bcd57 100644 --- a/trunk/net/mac80211/main.c +++ b/trunk/net/mac80211/main.c @@ -442,7 +442,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) struct ieee80211_local *local = hw_to_local(hw); int result; enum ieee80211_band band; - int channels, max_bitrates; + int channels, i, j, max_bitrates; bool supp_ht; static const u32 cipher_suites[] = { WLAN_CIPHER_SUITE_WEP40, @@ -572,8 +572,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) local->hw.conf.listen_interval = local->hw.max_listen_interval; - local->hw.conf.dynamic_ps_forced_timeout = -1; - result = sta_info_start(local); if (result < 0) goto fail_sta_info; @@ -608,6 +606,21 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) ieee80211_led_init(local); + /* alloc internal scan request */ + i = 0; + local->int_scan_req->ssids = &local->scan_ssid; + local->int_scan_req->n_ssids = 1; + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + if (!hw->wiphy->bands[band]) + continue; + for (j = 0; j < hw->wiphy->bands[band]->n_channels; j++) { + local->int_scan_req->channels[i] = + &hw->wiphy->bands[band]->channels[j]; + i++; + } + } + local->int_scan_req->n_channels = i; + local->network_latency_notifier.notifier_call = ieee80211_max_network_latency; result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY, diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index 358226f63b81..425f66c70013 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -478,7 +478,6 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) { struct ieee80211_sub_if_data *sdata, *found = NULL; int count = 0; - int timeout; if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) { local->ps_sdata = NULL; @@ -512,26 +511,6 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) beaconint_us = ieee80211_tu_to_usec( found->vif.bss_conf.beacon_int); - timeout = local->hw.conf.dynamic_ps_forced_timeout; - if (timeout < 0) { - /* - * The 2 second value is there for compatibility until - * the PM_QOS_NETWORK_LATENCY is configured with real - * values. - */ - if (latency == 2000000000) - timeout = 100; - else if (latency <= 50000) - timeout = 300; - else if (latency <= 100000) - timeout = 100; - else if (latency <= 500000) - timeout = 50; - else - timeout = 0; - } - local->hw.conf.dynamic_ps_timeout = timeout; - if (beaconint_us > latency) { local->ps_sdata = NULL; } else { diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index 9a08f2c446c6..72efbd87c1eb 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -81,6 +81,8 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local, len += 8; if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) len += 1; + if (local->hw.flags & IEEE80211_HW_NOISE_DBM) + len += 1; if (len & 1) /* padding for RX_FLAGS if necessary */ len++; diff --git a/trunk/net/mac80211/scan.c b/trunk/net/mac80211/scan.c index e14c44195ae9..e1a3defdf581 100644 --- a/trunk/net/mac80211/scan.c +++ b/trunk/net/mac80211/scan.c @@ -85,7 +85,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local, { struct cfg80211_bss *cbss; struct ieee80211_bss *bss; - int clen, srlen; + int clen; s32 signal = 0; if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) @@ -114,24 +114,23 @@ ieee80211_bss_info_update(struct ieee80211_local *local, bss->dtim_period = tim_ie->dtim_period; } - /* replace old supported rates if we get new values */ - srlen = 0; + bss->supp_rates_len = 0; if (elems->supp_rates) { - clen = IEEE80211_MAX_SUPP_RATES; + clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; if (clen > elems->supp_rates_len) clen = elems->supp_rates_len; - memcpy(bss->supp_rates, elems->supp_rates, clen); - srlen += clen; + memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates, + clen); + bss->supp_rates_len += clen; } if (elems->ext_supp_rates) { - clen = IEEE80211_MAX_SUPP_RATES - srlen; + clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; if (clen > elems->ext_supp_rates_len) clen = elems->ext_supp_rates_len; - memcpy(bss->supp_rates + srlen, elems->ext_supp_rates, clen); - srlen += clen; + memcpy(&bss->supp_rates[bss->supp_rates_len], + elems->ext_supp_rates, clen); + bss->supp_rates_len += clen; } - if (srlen) - bss->supp_rates_len = srlen; bss->wmm_used = elems->wmm_param || elems->wmm_info; bss->uapsd_supported = is_uapsd_supported(elems); @@ -412,7 +411,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, if (local->ops->hw_scan) { WARN_ON(!ieee80211_prep_hw_scan(local)); - rc = drv_hw_scan(local, sdata, local->hw_scan_req); + rc = drv_hw_scan(local, local->hw_scan_req); } else rc = ieee80211_start_sw_scan(local); @@ -656,7 +655,7 @@ void ieee80211_scan_work(struct work_struct *work) } if (local->hw_scan_req) { - int rc = drv_hw_scan(local, sdata, local->hw_scan_req); + int rc = drv_hw_scan(local, local->hw_scan_req); mutex_unlock(&local->scan_mtx); if (rc) ieee80211_scan_completed(&local->hw, true); @@ -729,12 +728,10 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, } int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, - const u8 *ssid, u8 ssid_len, - struct ieee80211_channel *chan) + const u8 *ssid, u8 ssid_len) { struct ieee80211_local *local = sdata->local; int ret = -EBUSY; - enum nl80211_band band; mutex_lock(&local->scan_mtx); @@ -742,30 +739,6 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, if (local->scan_req) goto unlock; - /* fill internal scan request */ - if (!chan) { - int i, nchan = 0; - - for (band = 0; band < IEEE80211_NUM_BANDS; band++) { - if (!local->hw.wiphy->bands[band]) - continue; - for (i = 0; - i < local->hw.wiphy->bands[band]->n_channels; - i++) { - local->int_scan_req->channels[nchan] = - &local->hw.wiphy->bands[band]->channels[i]; - nchan++; - } - } - - local->int_scan_req->n_channels = nchan; - } else { - local->int_scan_req->channels[0] = chan; - local->int_scan_req->n_channels = 1; - } - - local->int_scan_req->ssids = &local->scan_ssid; - local->int_scan_req->n_ssids = 1; memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN); local->int_scan_req->ssids[0].ssid_len = ssid_len; diff --git a/trunk/net/mac80211/sta_info.c b/trunk/net/mac80211/sta_info.c index 730197591ab5..3de7a2260d65 100644 --- a/trunk/net/mac80211/sta_info.c +++ b/trunk/net/mac80211/sta_info.c @@ -855,12 +855,8 @@ struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, struct sta_info *sta, *nxt; /* Just return a random station ... first in list ... */ - for_each_sta_info(hw_to_local(hw), addr, sta, nxt) { - if (!sta->uploaded) - return NULL; + for_each_sta_info(hw_to_local(hw), addr, sta, nxt) return &sta->sta; - } - return NULL; } EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); @@ -868,19 +864,14 @@ EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, const u8 *addr) { - struct sta_info *sta; + struct ieee80211_sub_if_data *sdata; if (!vif) return NULL; - sta = sta_info_get_bss(vif_to_sdata(vif), addr); - if (!sta) - return NULL; - - if (!sta->uploaded) - return NULL; + sdata = vif_to_sdata(vif); - return &sta->sta; + return ieee80211_find_sta_by_hw(&sdata->local->hw, addr); } EXPORT_SYMBOL(ieee80211_find_sta); diff --git a/trunk/net/mac80211/status.c b/trunk/net/mac80211/status.c index 94613af009f3..11805a3a626f 100644 --- a/trunk/net/mac80211/status.c +++ b/trunk/net/mac80211/status.c @@ -171,7 +171,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) struct net_device *prev_dev = NULL; struct sta_info *sta, *tmp; int retry_count = -1, i; - int rates_idx = -1; bool send_to_cooked; for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { @@ -179,8 +178,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) if (i >= hw->max_rates) { info->status.rates[i].idx = -1; info->status.rates[i].count = 0; - } else if (info->status.rates[i].idx >= 0) { - rates_idx = i; } retry_count += info->status.rates[i].count; @@ -209,10 +206,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) return; } - if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) && - (rates_idx != -1)) - sta->last_tx_rate = info->status.rates[rates_idx]; - if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && (ieee80211_is_data_qos(fc))) { u16 tid, ssn; diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index f3841f43249e..e2aa972d584f 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -593,8 +593,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) struct ieee80211_hdr *hdr = (void *)tx->skb->data; struct ieee80211_supported_band *sband; struct ieee80211_rate *rate; - int i; - u32 len; + int i, len; bool inval = false, rts = false, short_preamble = false; struct ieee80211_tx_rate_control txrc; u32 sta_flags; @@ -603,7 +602,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) sband = tx->local->hw.wiphy->bands[tx->channel->band]; - len = min_t(u32, tx->skb->len + FCS_LEN, + len = min_t(int, tx->skb->len + FCS_LEN, tx->local->hw.wiphy->frag_threshold); /* set up the tx rate control struct we give the RC algo */ diff --git a/trunk/net/mac80211/work.c b/trunk/net/mac80211/work.c index 3dd07600199d..bdb1d05b16fc 100644 --- a/trunk/net/mac80211/work.c +++ b/trunk/net/mac80211/work.c @@ -213,25 +213,15 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, sband = local->hw.wiphy->bands[wk->chan->band]; - if (wk->assoc.supp_rates_len) { - /* - * Get all rates supported by the device and the AP as - * some APs don't like getting a superset of their rates - * in the association request (e.g. D-Link DAP 1353 in - * b-only mode)... - */ - rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates, - wk->assoc.supp_rates_len, - sband, &rates); - } else { - /* - * In case AP not provide any supported rates information - * before association, we send information element(s) with - * all rates that we support. - */ - rates = ~0; - rates_len = sband->n_bitrates; - } + /* + * Get all rates supported by the device and the AP as + * some APs don't like getting a superset of their rates + * in the association request (e.g. D-Link DAP 1353 in + * b-only mode)... + */ + rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates, + wk->assoc.supp_rates_len, + sband, &rates); skb = alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + /* bit too much but doesn't matter */ diff --git a/trunk/net/sched/sch_generic.c b/trunk/net/sched/sch_generic.c index a969b111bd76..aeddabfb8e4e 100644 --- a/trunk/net/sched/sch_generic.c +++ b/trunk/net/sched/sch_generic.c @@ -94,7 +94,7 @@ static inline int handle_dev_cpu_collision(struct sk_buff *skb, * Another cpu is holding lock, requeue & delay xmits for * some time. */ - __get_cpu_var(softnet_data).cpu_collision++; + __get_cpu_var(netdev_rx_stat).cpu_collision++; ret = dev_requeue_skb(skb, q); } diff --git a/trunk/net/sctp/Kconfig b/trunk/net/sctp/Kconfig index 126b014eb79b..58b3e882a187 100644 --- a/trunk/net/sctp/Kconfig +++ b/trunk/net/sctp/Kconfig @@ -37,18 +37,6 @@ menuconfig IP_SCTP if IP_SCTP -config NET_SCTPPROBE - tristate "SCTP: Association probing" - depends on PROC_FS && KPROBES - ---help--- - This module allows for capturing the changes to SCTP association - state in response to incoming packets. It is used for debugging - SCTP congestion control algorithms. If you don't understand - what was just said, you don't need it: say N. - - To compile this code as a module, choose M here: the - module will be called sctp_probe. - config SCTP_DBG_MSG bool "SCTP: Debug messages" help diff --git a/trunk/net/sctp/Makefile b/trunk/net/sctp/Makefile index 5c30b7a873df..6b794734380a 100644 --- a/trunk/net/sctp/Makefile +++ b/trunk/net/sctp/Makefile @@ -3,7 +3,6 @@ # obj-$(CONFIG_IP_SCTP) += sctp.o -obj-$(CONFIG_NET_SCTPPROBE) += sctp_probe.o sctp-y := sm_statetable.o sm_statefuns.o sm_sideeffect.o \ protocol.o endpointola.o associola.o \ @@ -12,8 +11,6 @@ sctp-y := sm_statetable.o sm_statefuns.o sm_sideeffect.o \ tsnmap.o bind_addr.o socket.o primitive.o \ output.o input.o debug.o ssnmap.o auth.o -sctp_probe-y := probe.o - sctp-$(CONFIG_SCTP_DBG_OBJCNT) += objcnt.o sctp-$(CONFIG_PROC_FS) += proc.o sctp-$(CONFIG_SYSCTL) += sysctl.o diff --git a/trunk/net/sctp/associola.c b/trunk/net/sctp/associola.c index 3912420cedcc..99c93ee98ad9 100644 --- a/trunk/net/sctp/associola.c +++ b/trunk/net/sctp/associola.c @@ -87,6 +87,9 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a /* Retrieve the SCTP per socket area. */ sp = sctp_sk((struct sock *)sk); + /* Init all variables to a known value. */ + memset(asoc, 0, sizeof(struct sctp_association)); + /* Discarding const is appropriate here. */ asoc->ep = (struct sctp_endpoint *)ep; sctp_endpoint_hold(asoc->ep); @@ -759,8 +762,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, asoc->peer.retran_path = peer; } - if (asoc->peer.active_path == asoc->peer.retran_path && - peer->state != SCTP_UNCONFIRMED) { + if (asoc->peer.active_path == asoc->peer.retran_path) { asoc->peer.retran_path = peer; } @@ -1318,13 +1320,12 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc) /* Keep track of the next transport in case * we don't find any active transport. */ - if (t->state != SCTP_UNCONFIRMED && !next) + if (!next) next = t; } } - if (t) - asoc->peer.retran_path = t; + asoc->peer.retran_path = t; SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association" " %p addr: ", @@ -1484,7 +1485,7 @@ void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned len) if (asoc->rwnd >= len) { asoc->rwnd -= len; if (over) { - asoc->rwnd_press += asoc->rwnd; + asoc->rwnd_press = asoc->rwnd; asoc->rwnd = 0; } } else { diff --git a/trunk/net/sctp/chunk.c b/trunk/net/sctp/chunk.c index 476caaf100ed..3eab6db59a37 100644 --- a/trunk/net/sctp/chunk.c +++ b/trunk/net/sctp/chunk.c @@ -58,9 +58,9 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg) msg->send_failed = 0; msg->send_error = 0; msg->can_abandon = 0; - msg->can_delay = 1; msg->expires_at = 0; INIT_LIST_HEAD(&msg->chunks); + msg->msg_size = 0; } /* Allocate and initialize datamsg. */ @@ -157,6 +157,7 @@ static void sctp_datamsg_assign(struct sctp_datamsg *msg, struct sctp_chunk *chu { sctp_datamsg_hold(msg); chunk->msg = msg; + msg->msg_size += chunk->skb->len; } @@ -246,7 +247,6 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, if (msg_len >= first_len) { msg_len -= first_len; whole = 1; - msg->can_delay = 0; } /* How many full sized? How many bytes leftover? */ diff --git a/trunk/net/sctp/endpointola.c b/trunk/net/sctp/endpointola.c index e10acc01c75f..7ec09ba03a1c 100644 --- a/trunk/net/sctp/endpointola.c +++ b/trunk/net/sctp/endpointola.c @@ -70,6 +70,8 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, struct sctp_shared_key *null_key; int err; + memset(ep, 0, sizeof(struct sctp_endpoint)); + ep->digest = kzalloc(SCTP_SIGNATURE_SIZE, gfp); if (!ep->digest) return NULL; diff --git a/trunk/net/sctp/output.c b/trunk/net/sctp/output.c index a646681f5acd..fad261d41ec2 100644 --- a/trunk/net/sctp/output.c +++ b/trunk/net/sctp/output.c @@ -429,17 +429,24 @@ int sctp_packet_transmit(struct sctp_packet *packet) list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { list_del_init(&chunk->list); if (sctp_chunk_is_data(chunk)) { - /* 6.3.1 C4) When data is in flight and when allowed - * by rule C5, a new RTT measurement MUST be made each - * round trip. Furthermore, new RTT measurements - * SHOULD be made no more than once per round-trip - * for a given destination transport address. - */ - if (!tp->rto_pending) { - chunk->rtt_in_progress = 1; - tp->rto_pending = 1; + if (!chunk->resent) { + + /* 6.3.1 C4) When data is in flight and when allowed + * by rule C5, a new RTT measurement MUST be made each + * round trip. Furthermore, new RTT measurements + * SHOULD be made no more than once per round-trip + * for a given destination transport address. + */ + + if (!tp->rto_pending) { + chunk->rtt_in_progress = 1; + tp->rto_pending = 1; + } } + + chunk->resent = 1; + has_data = 1; } @@ -674,7 +681,7 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, * Don't delay large message writes that may have been * fragmeneted into small peices. */ - if ((len < max) && chunk->msg->can_delay) { + if ((len < max) && (chunk->msg->msg_size < max)) { retval = SCTP_XMIT_NAGLE_DELAY; goto finish; } diff --git a/trunk/net/sctp/outqueue.c b/trunk/net/sctp/outqueue.c index 5d057178ce0c..abfc0b8dee74 100644 --- a/trunk/net/sctp/outqueue.c +++ b/trunk/net/sctp/outqueue.c @@ -62,7 +62,7 @@ static void sctp_check_transmitted(struct sctp_outq *q, struct list_head *transmitted_queue, struct sctp_transport *transport, struct sctp_sackhdr *sack, - __u32 *highest_new_tsn); + __u32 highest_new_tsn); static void sctp_mark_missing(struct sctp_outq *q, struct list_head *transmitted_queue, @@ -308,7 +308,7 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk) /* If it is data, queue it up, otherwise, send it * immediately. */ - if (sctp_chunk_is_data(chunk)) { + if (SCTP_CID_DATA == chunk->chunk_hdr->type) { /* Is it OK to queue data chunks? */ /* From 9. Termination of Association * @@ -598,23 +598,11 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, if (fast_rtx && !chunk->fast_retransmit) continue; -redo: /* Attempt to append this chunk to the packet. */ status = sctp_packet_append_chunk(pkt, chunk); switch (status) { case SCTP_XMIT_PMTU_FULL: - if (!pkt->has_data && !pkt->has_cookie_echo) { - /* If this packet did not contain DATA then - * retransmission did not happen, so do it - * again. We'll ignore the error here since - * control chunks are already freed so there - * is nothing we can do. - */ - sctp_packet_transmit(pkt); - goto redo; - } - /* Send this packet. */ error = sctp_packet_transmit(pkt); @@ -659,6 +647,14 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, if (chunk->fast_retransmit == SCTP_NEED_FRTX) chunk->fast_retransmit = SCTP_DONT_FRTX; + /* Force start T3-rtx timer when fast retransmitting + * the earliest outstanding TSN + */ + if (!timer && fast_rtx && + ntohl(chunk->subh.data_hdr->tsn) == + asoc->ctsn_ack_point + 1) + timer = 2; + q->empty = 0; break; } @@ -858,12 +854,6 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) if (status != SCTP_XMIT_OK) { /* put the chunk back */ list_add(&chunk->list, &q->control_chunk_list); - } else if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN) { - /* PR-SCTP C5) If a FORWARD TSN is sent, the - * sender MUST assure that at least one T3-rtx - * timer is running. - */ - sctp_transport_reset_timers(transport); } break; @@ -916,7 +906,8 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) rtx_timeout, &start_timer); if (start_timer) - sctp_transport_reset_timers(transport); + sctp_transport_reset_timers(transport, + start_timer-1); /* This can happen on COOKIE-ECHO resend. Only * one chunk can get bundled with a COOKIE-ECHO. @@ -1049,7 +1040,7 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) list_add_tail(&chunk->transmitted_list, &transport->transmitted); - sctp_transport_reset_timers(transport); + sctp_transport_reset_timers(transport, 0); q->empty = 0; @@ -1109,6 +1100,32 @@ static void sctp_sack_update_unack_data(struct sctp_association *assoc, assoc->unack_data = unack_data; } +/* Return the highest new tsn that is acknowledged by the given SACK chunk. */ +static __u32 sctp_highest_new_tsn(struct sctp_sackhdr *sack, + struct sctp_association *asoc) +{ + struct sctp_transport *transport; + struct sctp_chunk *chunk; + __u32 highest_new_tsn, tsn; + struct list_head *transport_list = &asoc->peer.transport_addr_list; + + highest_new_tsn = ntohl(sack->cum_tsn_ack); + + list_for_each_entry(transport, transport_list, transports) { + list_for_each_entry(chunk, &transport->transmitted, + transmitted_list) { + tsn = ntohl(chunk->subh.data_hdr->tsn); + + if (!chunk->tsn_gap_acked && + TSN_lt(highest_new_tsn, tsn) && + sctp_acked(sack, tsn)) + highest_new_tsn = tsn; + } + } + + return highest_new_tsn; +} + /* This is where we REALLY process a SACK. * * Process the SACK against the outqueue. Mostly, this just frees @@ -1128,7 +1145,6 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) struct sctp_transport *primary = asoc->peer.primary_path; int count_of_newacks = 0; int gap_ack_blocks; - u8 accum_moved = 0; /* Grab the association's destination address list. */ transport_list = &asoc->peer.transport_addr_list; @@ -1177,15 +1193,18 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) if (gap_ack_blocks) highest_tsn += ntohs(frags[gap_ack_blocks - 1].gab.end); - if (TSN_lt(asoc->highest_sacked, highest_tsn)) + if (TSN_lt(asoc->highest_sacked, highest_tsn)) { + highest_new_tsn = highest_tsn; asoc->highest_sacked = highest_tsn; + } else { + highest_new_tsn = sctp_highest_new_tsn(sack, asoc); + } - highest_new_tsn = sack_ctsn; /* Run through the retransmit queue. Credit bytes received * and free those chunks that we can. */ - sctp_check_transmitted(q, &q->retransmit, NULL, sack, &highest_new_tsn); + sctp_check_transmitted(q, &q->retransmit, NULL, sack, highest_new_tsn); /* Run through the transmitted queue. * Credit bytes received and free those chunks which we can. @@ -1194,7 +1213,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) */ list_for_each_entry(transport, transport_list, transports) { sctp_check_transmitted(q, &transport->transmitted, - transport, sack, &highest_new_tsn); + transport, sack, highest_new_tsn); /* * SFR-CACC algorithm: * C) Let count_of_newacks be the number of @@ -1204,22 +1223,16 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) count_of_newacks ++; } - /* Move the Cumulative TSN Ack Point if appropriate. */ - if (TSN_lt(asoc->ctsn_ack_point, sack_ctsn)) { - asoc->ctsn_ack_point = sack_ctsn; - accum_moved = 1; - } - if (gap_ack_blocks) { - - if (asoc->fast_recovery && accum_moved) - highest_new_tsn = highest_tsn; - list_for_each_entry(transport, transport_list, transports) sctp_mark_missing(q, &transport->transmitted, transport, highest_new_tsn, count_of_newacks); } + /* Move the Cumulative TSN Ack Point if appropriate. */ + if (TSN_lt(asoc->ctsn_ack_point, sack_ctsn)) + asoc->ctsn_ack_point = sack_ctsn; + /* Update unack_data field in the assoc. */ sctp_sack_update_unack_data(asoc, sack); @@ -1302,7 +1315,7 @@ static void sctp_check_transmitted(struct sctp_outq *q, struct list_head *transmitted_queue, struct sctp_transport *transport, struct sctp_sackhdr *sack, - __u32 *highest_new_tsn_in_sack) + __u32 highest_new_tsn_in_sack) { struct list_head *lchunk; struct sctp_chunk *tchunk; @@ -1374,6 +1387,7 @@ static void sctp_check_transmitted(struct sctp_outq *q, * instance). */ if (!tchunk->tsn_gap_acked && + !tchunk->resent && tchunk->rtt_in_progress) { tchunk->rtt_in_progress = 0; rtt = jiffies - tchunk->sent_at; @@ -1390,7 +1404,6 @@ static void sctp_check_transmitted(struct sctp_outq *q, */ if (!tchunk->tsn_gap_acked) { tchunk->tsn_gap_acked = 1; - *highest_new_tsn_in_sack = tsn; bytes_acked += sctp_data_size(tchunk); if (!tchunk->transport) migrate_bytes += sctp_data_size(tchunk); @@ -1664,8 +1677,7 @@ static void sctp_mark_missing(struct sctp_outq *q, struct sctp_chunk *chunk; __u32 tsn; char do_fast_retransmit = 0; - struct sctp_association *asoc = q->asoc; - struct sctp_transport *primary = asoc->peer.primary_path; + struct sctp_transport *primary = q->asoc->peer.primary_path; list_for_each_entry(chunk, transmitted_queue, transmitted_list) { diff --git a/trunk/net/sctp/probe.c b/trunk/net/sctp/probe.c deleted file mode 100644 index db3a42b8b349..000000000000 --- a/trunk/net/sctp/probe.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * sctp_probe - Observe the SCTP flow with kprobes. - * - * The idea for this came from Werner Almesberger's umlsim - * Copyright (C) 2004, Stephen Hemminger - * - * Modified for SCTP from Stephen Hemminger's code - * Copyright (C) 2010, Wei Yongjun - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -MODULE_AUTHOR("Wei Yongjun "); -MODULE_DESCRIPTION("SCTP snooper"); -MODULE_LICENSE("GPL"); - -static int port __read_mostly = 0; -MODULE_PARM_DESC(port, "Port to match (0=all)"); -module_param(port, int, 0); - -static int bufsize __read_mostly = 64 * 1024; -MODULE_PARM_DESC(bufsize, "Log buffer size (default 64k)"); -module_param(bufsize, int, 0); - -static int full __read_mostly = 1; -MODULE_PARM_DESC(full, "Full log (1=every ack packet received, 0=only cwnd changes)"); -module_param(full, int, 0); - -static const char procname[] = "sctpprobe"; - -static struct { - struct kfifo fifo; - spinlock_t lock; - wait_queue_head_t wait; - struct timespec tstart; -} sctpw; - -static void printl(const char *fmt, ...) -{ - va_list args; - int len; - char tbuf[256]; - - va_start(args, fmt); - len = vscnprintf(tbuf, sizeof(tbuf), fmt, args); - va_end(args); - - kfifo_in_locked(&sctpw.fifo, tbuf, len, &sctpw.lock); - wake_up(&sctpw.wait); -} - -static int sctpprobe_open(struct inode *inode, struct file *file) -{ - kfifo_reset(&sctpw.fifo); - getnstimeofday(&sctpw.tstart); - - return 0; -} - -static ssize_t sctpprobe_read(struct file *file, char __user *buf, - size_t len, loff_t *ppos) -{ - int error = 0, cnt = 0; - unsigned char *tbuf; - - if (!buf) - return -EINVAL; - - if (len == 0) - return 0; - - tbuf = vmalloc(len); - if (!tbuf) - return -ENOMEM; - - error = wait_event_interruptible(sctpw.wait, - kfifo_len(&sctpw.fifo) != 0); - if (error) - goto out_free; - - cnt = kfifo_out_locked(&sctpw.fifo, tbuf, len, &sctpw.lock); - error = copy_to_user(buf, tbuf, cnt) ? -EFAULT : 0; - -out_free: - vfree(tbuf); - - return error ? error : cnt; -} - -static const struct file_operations sctpprobe_fops = { - .owner = THIS_MODULE, - .open = sctpprobe_open, - .read = sctpprobe_read, -}; - -sctp_disposition_t jsctp_sf_eat_sack(const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) -{ - struct sctp_transport *sp; - static __u32 lcwnd = 0; - struct timespec now; - - sp = asoc->peer.primary_path; - - if ((full || sp->cwnd != lcwnd) && - (!port || asoc->peer.port == port || - ep->base.bind_addr.port == port)) { - lcwnd = sp->cwnd; - - getnstimeofday(&now); - now = timespec_sub(now, sctpw.tstart); - - printl("%lu.%06lu ", (unsigned long) now.tv_sec, - (unsigned long) now.tv_nsec / NSEC_PER_USEC); - - printl("%p %5d %5d %5d %8d %5d ", asoc, - ep->base.bind_addr.port, asoc->peer.port, - asoc->pathmtu, asoc->peer.rwnd, asoc->unack_data); - - list_for_each_entry(sp, &asoc->peer.transport_addr_list, - transports) { - if (sp == asoc->peer.primary_path) - printl("*"); - - if (sp->ipaddr.sa.sa_family == AF_INET) - printl("%pI4 ", &sp->ipaddr.v4.sin_addr); - else - printl("%pI6 ", &sp->ipaddr.v6.sin6_addr); - - printl("%2u %8u %8u %8u %8u %8u ", - sp->state, sp->cwnd, sp->ssthresh, - sp->flight_size, sp->partial_bytes_acked, - sp->pathmtu); - } - printl("\n"); - } - - jprobe_return(); - return 0; -} - -static struct jprobe sctp_recv_probe = { - .kp = { - .symbol_name = "sctp_sf_eat_sack_6_2", - }, - .entry = jsctp_sf_eat_sack, -}; - -static __init int sctpprobe_init(void) -{ - int ret = -ENOMEM; - - init_waitqueue_head(&sctpw.wait); - spin_lock_init(&sctpw.lock); - if (kfifo_alloc(&sctpw.fifo, bufsize, GFP_KERNEL)) - return ret; - - if (!proc_net_fops_create(&init_net, procname, S_IRUSR, - &sctpprobe_fops)) - goto free_kfifo; - - ret = register_jprobe(&sctp_recv_probe); - if (ret) - goto remove_proc; - - pr_info("SCTP probe registered (port=%d)\n", port); - - return 0; - -remove_proc: - proc_net_remove(&init_net, procname); -free_kfifo: - kfifo_free(&sctpw.fifo); - return ret; -} - -static __exit void sctpprobe_exit(void) -{ - kfifo_free(&sctpw.fifo); - proc_net_remove(&init_net, procname); - unregister_jprobe(&sctp_recv_probe); -} - -module_init(sctpprobe_init); -module_exit(sctpprobe_exit); diff --git a/trunk/net/sctp/protocol.c b/trunk/net/sctp/protocol.c index 182749867c72..704298f4b284 100644 --- a/trunk/net/sctp/protocol.c +++ b/trunk/net/sctp/protocol.c @@ -474,17 +474,13 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, memset(&fl, 0x0, sizeof(struct flowi)); fl.fl4_dst = daddr->v4.sin_addr.s_addr; - fl.fl_ip_dport = daddr->v4.sin_port; fl.proto = IPPROTO_SCTP; if (asoc) { fl.fl4_tos = RT_CONN_FLAGS(asoc->base.sk); fl.oif = asoc->base.sk->sk_bound_dev_if; - fl.fl_ip_sport = htons(asoc->base.bind_addr.port); } - if (saddr) { + if (saddr) fl.fl4_src = saddr->v4.sin_addr.s_addr; - fl.fl_ip_sport = saddr->v4.sin_port; - } SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ", __func__, &fl.fl4_dst, &fl.fl4_src); @@ -532,7 +528,6 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, if ((laddr->state == SCTP_ADDR_SRC) && (AF_INET == laddr->a.sa.sa_family)) { fl.fl4_src = laddr->a.v4.sin_addr.s_addr; - fl.fl_ip_sport = laddr->a.v4.sin_port; if (!ip_route_output_key(&init_net, &rt, &fl)) { dst = &rt->u.dst; goto out_unlock; diff --git a/trunk/net/sctp/sm_make_chunk.c b/trunk/net/sctp/sm_make_chunk.c index d8261f3d7715..30c1767186b8 100644 --- a/trunk/net/sctp/sm_make_chunk.c +++ b/trunk/net/sctp/sm_make_chunk.c @@ -445,17 +445,10 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, if (!retval) goto nomem_chunk; - /* RFC 2960 6.4 Multi-homed SCTP Endpoints - * - * An endpoint SHOULD transmit reply chunks (e.g., SACK, - * HEARTBEAT ACK, * etc.) to the same destination transport - * address from which it received the DATA or control chunk - * to which it is replying. - * - * [INIT ACK back to where the INIT came from.] + /* Per the advice in RFC 2960 6.4, send this reply to + * the source of the INIT packet. */ retval->transport = chunk->transport; - retval->subh.init_hdr = sctp_addto_chunk(retval, sizeof(initack), &initack); retval->param_hdr.v = sctp_addto_chunk(retval, addrs_len, addrs.v); @@ -494,6 +487,18 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, /* We need to remove the const qualifier at this point. */ retval->asoc = (struct sctp_association *) asoc; + /* RFC 2960 6.4 Multi-homed SCTP Endpoints + * + * An endpoint SHOULD transmit reply chunks (e.g., SACK, + * HEARTBEAT ACK, * etc.) to the same destination transport + * address from which it received the DATA or control chunk + * to which it is replying. + * + * [INIT ACK back to where the INIT came from.] + */ + if (chunk) + retval->transport = chunk->transport; + nomem_chunk: kfree(cookie); nomem_cookie: @@ -1249,6 +1254,7 @@ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb, INIT_LIST_HEAD(&retval->list); retval->skb = skb; retval->asoc = (struct sctp_association *)asoc; + retval->resent = 0; retval->has_tsn = 0; retval->has_ssn = 0; retval->rtt_in_progress = 0; diff --git a/trunk/net/sctp/sm_sideeffect.c b/trunk/net/sctp/sm_sideeffect.c index 3b7230ef77c2..d5ae450b6f02 100644 --- a/trunk/net/sctp/sm_sideeffect.c +++ b/trunk/net/sctp/sm_sideeffect.c @@ -697,15 +697,11 @@ static void sctp_cmd_setup_t2(sctp_cmd_seq_t *cmds, { struct sctp_transport *t; - if (chunk->transport) - t = chunk->transport; - else { - t = sctp_assoc_choose_alter_transport(asoc, + t = sctp_assoc_choose_alter_transport(asoc, asoc->shutdown_last_sent_to); - chunk->transport = t; - } asoc->shutdown_last_sent_to = t; asoc->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = t->rto; + chunk->transport = t; } /* Helper function to change the state of an association. */ diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index ba1add0b13c3..bae764005d2d 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -4384,7 +4384,7 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, transports) { memcpy(&temp, &from->ipaddr, sizeof(temp)); sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); - addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; + addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len; if (space_left < addrlen) return -ENOMEM; if (copy_to_user(to, &temp, addrlen)) diff --git a/trunk/net/sctp/transport.c b/trunk/net/sctp/transport.c index fccf4947aff1..be4d63d5a5cc 100644 --- a/trunk/net/sctp/transport.c +++ b/trunk/net/sctp/transport.c @@ -64,6 +64,9 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, /* Copy in the address. */ peer->ipaddr = *addr; peer->af_specific = sctp_get_af_specific(addr->sa.sa_family); + peer->asoc = NULL; + + peer->dst = NULL; memset(&peer->saddr, 0, sizeof(union sctp_addr)); /* From 6.3.1 RTO Calculation: @@ -73,21 +76,34 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, * parameter 'RTO.Initial'. */ peer->rto = msecs_to_jiffies(sctp_rto_initial); + peer->rtt = 0; + peer->rttvar = 0; + peer->srtt = 0; + peer->rto_pending = 0; + peer->hb_sent = 0; + peer->fast_recovery = 0; peer->last_time_heard = jiffies; peer->last_time_ecne_reduced = jiffies; + peer->init_sent_count = 0; + peer->param_flags = SPP_HB_DISABLE | SPP_PMTUD_ENABLE | SPP_SACKDELAY_ENABLE; + peer->hbinterval = 0; /* Initialize the default path max_retrans. */ peer->pathmaxrxt = sctp_max_retrans_path; + peer->error_count = 0; INIT_LIST_HEAD(&peer->transmitted); INIT_LIST_HEAD(&peer->send_ready); INIT_LIST_HEAD(&peer->transports); + peer->T3_rtx_timer.expires = 0; + peer->hb_timer.expires = 0; + setup_timer(&peer->T3_rtx_timer, sctp_generate_t3_rtx_event, (unsigned long)peer); setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event, @@ -97,6 +113,15 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce)); atomic_set(&peer->refcnt, 1); + peer->dead = 0; + + peer->malloced = 0; + + /* Initialize the state information for SFR-CACC */ + peer->cacc.changeover_active = 0; + peer->cacc.cycling_changeover = 0; + peer->cacc.next_tsn_at_change = 0; + peer->cacc.cacc_saw_newack = 0; return peer; } @@ -170,7 +195,7 @@ static void sctp_transport_destroy(struct sctp_transport *transport) /* Start T3_rtx timer if it is not already running and update the heartbeat * timer. This routine is called every time a DATA chunk is sent. */ -void sctp_transport_reset_timers(struct sctp_transport *transport) +void sctp_transport_reset_timers(struct sctp_transport *transport, int force) { /* RFC 2960 6.3.2 Retransmission Timer Rules * @@ -180,7 +205,7 @@ void sctp_transport_reset_timers(struct sctp_transport *transport) * address. */ - if (!timer_pending(&transport->T3_rtx_timer)) + if (force || !timer_pending(&transport->T3_rtx_timer)) if (!mod_timer(&transport->T3_rtx_timer, jiffies + transport->rto)) sctp_transport_hold(transport); @@ -378,16 +403,15 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) void sctp_transport_raise_cwnd(struct sctp_transport *transport, __u32 sack_ctsn, __u32 bytes_acked) { - struct sctp_association *asoc = transport->asoc; __u32 cwnd, ssthresh, flight_size, pba, pmtu; cwnd = transport->cwnd; flight_size = transport->flight_size; /* See if we need to exit Fast Recovery first */ - if (asoc->fast_recovery && - TSN_lte(asoc->fast_recovery_exit, sack_ctsn)) - asoc->fast_recovery = 0; + if (transport->fast_recovery && + TSN_lte(transport->fast_recovery_exit, sack_ctsn)) + transport->fast_recovery = 0; /* The appropriate cwnd increase algorithm is performed if, and only * if the cumulative TSN whould advanced and the congestion window is @@ -416,7 +440,7 @@ void sctp_transport_raise_cwnd(struct sctp_transport *transport, * 2) the destination's path MTU. This upper bound protects * against the ACK-Splitting attack outlined in [SAVAGE99]. */ - if (asoc->fast_recovery) + if (transport->fast_recovery) return; if (bytes_acked > pmtu) @@ -467,8 +491,6 @@ void sctp_transport_raise_cwnd(struct sctp_transport *transport, void sctp_transport_lower_cwnd(struct sctp_transport *transport, sctp_lower_cwnd_t reason) { - struct sctp_association *asoc = transport->asoc; - switch (reason) { case SCTP_LOWER_CWND_T3_RTX: /* RFC 2960 Section 7.2.3, sctpimpguide @@ -479,11 +501,11 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, * partial_bytes_acked = 0 */ transport->ssthresh = max(transport->cwnd/2, - 4*asoc->pathmtu); - transport->cwnd = asoc->pathmtu; + 4*transport->asoc->pathmtu); + transport->cwnd = transport->asoc->pathmtu; - /* T3-rtx also clears fast recovery */ - asoc->fast_recovery = 0; + /* T3-rtx also clears fast recovery on the transport */ + transport->fast_recovery = 0; break; case SCTP_LOWER_CWND_FAST_RTX: @@ -499,15 +521,15 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, * cwnd = ssthresh * partial_bytes_acked = 0 */ - if (asoc->fast_recovery) + if (transport->fast_recovery) return; /* Mark Fast recovery */ - asoc->fast_recovery = 1; - asoc->fast_recovery_exit = asoc->next_tsn - 1; + transport->fast_recovery = 1; + transport->fast_recovery_exit = transport->asoc->next_tsn - 1; transport->ssthresh = max(transport->cwnd/2, - 4*asoc->pathmtu); + 4*transport->asoc->pathmtu); transport->cwnd = transport->ssthresh; break; @@ -527,7 +549,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, if (time_after(jiffies, transport->last_time_ecne_reduced + transport->rtt)) { transport->ssthresh = max(transport->cwnd/2, - 4*asoc->pathmtu); + 4*transport->asoc->pathmtu); transport->cwnd = transport->ssthresh; transport->last_time_ecne_reduced = jiffies; } @@ -543,7 +565,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, * interval. */ transport->cwnd = max(transport->cwnd/2, - 4*asoc->pathmtu); + 4*transport->asoc->pathmtu); break; } @@ -628,6 +650,7 @@ void sctp_transport_reset(struct sctp_transport *t) t->error_count = 0; t->rto_pending = 0; t->hb_sent = 0; + t->fast_recovery = 0; /* Initialize the state information for SFR-CACC */ t->cacc.changeover_active = 0; diff --git a/trunk/net/unix/garbage.c b/trunk/net/unix/garbage.c index c8df6fda0b1f..14c22c3768da 100644 --- a/trunk/net/unix/garbage.c +++ b/trunk/net/unix/garbage.c @@ -153,6 +153,15 @@ void unix_notinflight(struct file *fp) } } +static inline struct sk_buff *sock_queue_head(struct sock *sk) +{ + return (struct sk_buff *)&sk->sk_receive_queue; +} + +#define receive_queue_for_each_skb(sk, next, skb) \ + for (skb = sock_queue_head(sk)->next, next = skb->next; \ + skb != sock_queue_head(sk); skb = next, next = skb->next) + static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *), struct sk_buff_head *hitlist) { @@ -160,7 +169,7 @@ static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *), struct sk_buff *next; spin_lock(&x->sk_receive_queue.lock); - skb_queue_walk_safe(&x->sk_receive_queue, skb, next) { + receive_queue_for_each_skb(x, next, skb) { /* * Do we have file descriptors ? */ @@ -216,7 +225,7 @@ static void scan_children(struct sock *x, void (*func)(struct unix_sock *), * and perform a scan on them as well. */ spin_lock(&x->sk_receive_queue.lock); - skb_queue_walk_safe(&x->sk_receive_queue, skb, next) { + receive_queue_for_each_skb(x, next, skb) { u = unix_sk(skb->sk); /* diff --git a/trunk/net/wireless/core.c b/trunk/net/wireless/core.c index 37d0e0ab4432..6ac70c101523 100644 --- a/trunk/net/wireless/core.c +++ b/trunk/net/wireless/core.c @@ -705,8 +705,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, wdev->ps = true; else wdev->ps = false; - /* allow mac80211 to determine the timeout */ - wdev->ps_timeout = -1; + wdev->ps_timeout = 100; if (rdev->ops->set_power_mgmt) if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, wdev->ps, diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c index 01da83ddcff7..356a84a5daee 100644 --- a/trunk/net/wireless/nl80211.c +++ b/trunk/net/wireless/nl80211.c @@ -152,7 +152,6 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 }, [NL80211_ATTR_CQM] = { .type = NLA_NESTED, }, [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG }, - [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 }, }; /* policy for the attributes */ @@ -2443,7 +2442,6 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) params.use_cts_prot = -1; params.use_short_preamble = -1; params.use_short_slot_time = -1; - params.ap_isolate = -1; if (info->attrs[NL80211_ATTR_BSS_CTS_PROT]) params.use_cts_prot = @@ -2460,8 +2458,6 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) params.basic_rates_len = nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); } - if (info->attrs[NL80211_ATTR_AP_ISOLATE]) - params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]); rtnl_lock();