]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'for-david' of git://git.kernel.org/pub/scm/linux/kernel/git/chris/linux-2.6
authorDavid S. Miller <davem@davemloft.net>
Fri, 26 Dec 2008 02:10:12 +0000 (18:10 -0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 26 Dec 2008 02:10:12 +0000 (18:10 -0800)
160 files changed:
drivers/infiniband/hw/nes/nes_hw.c
drivers/infiniband/hw/nes/nes_nic.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/net/8139cp.c
drivers/net/8139too.c
drivers/net/amd8111e.c
drivers/net/arm/ep93xx_eth.c
drivers/net/arm/ixp4xx_eth.c
drivers/net/atl1e/atl1e_main.c
drivers/net/au1000_eth.c
drivers/net/b44.c
drivers/net/bnx2.c
drivers/net/bnx2x_main.c
drivers/net/cassini.c
drivers/net/chelsio/sge.c
drivers/net/cpmac.c
drivers/net/cxgb3/adapter.h
drivers/net/cxgb3/cxgb3_ctl_defs.h
drivers/net/cxgb3/cxgb3_offload.c
drivers/net/cxgb3/sge.c
drivers/net/e100.c
drivers/net/e1000/e1000_main.c
drivers/net/e1000e/netdev.c
drivers/net/ehea/ehea_main.c
drivers/net/ehea/ehea_qmr.c
drivers/net/enic/enic_main.c
drivers/net/epic100.c
drivers/net/forcedeth.c
drivers/net/fs_enet/fs_enet-main.c
drivers/net/gianfar.c
drivers/net/ibmveth.c
drivers/net/igb/igb_main.c
drivers/net/ixgb/ixgb_main.c
drivers/net/ixgbe/ixgbe_dcb_nl.c
drivers/net/ixgbe/ixgbe_ethtool.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ixp2000/ixpdev.c
drivers/net/jme.c
drivers/net/jme.h
drivers/net/korina.c
drivers/net/macb.c
drivers/net/mlx4/en_rx.c
drivers/net/myri10ge/myri10ge.c
drivers/net/myri10ge/myri10ge_mcp.h
drivers/net/myri10ge/myri10ge_mcp_gen_header.h
drivers/net/natsemi.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/niu.c
drivers/net/pasemi_mac.c
drivers/net/pcnet32.c
drivers/net/phy/mdio_bus.c
drivers/net/phy/phy_device.c
drivers/net/ppp_async.c
drivers/net/ppp_generic.c
drivers/net/ppp_synctty.c
drivers/net/qla3xxx.c
drivers/net/qlge/qlge_main.c
drivers/net/r6040.c
drivers/net/r8169.c
drivers/net/s2io.c
drivers/net/sb1250-mac.c
drivers/net/sfc/efx.c
drivers/net/sfc/efx.h
drivers/net/skge.c
drivers/net/smsc911x.c
drivers/net/smsc9420.c
drivers/net/spider_net.c
drivers/net/starfire.c
drivers/net/sungem.c
drivers/net/tc35815.c
drivers/net/tehuti.c
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/tsi108_eth.c
drivers/net/tulip/interrupt.c
drivers/net/typhoon.c
drivers/net/ucc_geth.c
drivers/net/usb/asix.c
drivers/net/usb/catc.c
drivers/net/usb/dm9601.c
drivers/net/usb/hso.c
drivers/net/usb/kaweth.c
drivers/net/usb/mcs7830.c
drivers/net/usb/pegasus.c
drivers/net/usb/rtl8150.c
drivers/net/usb/smsc95xx.c
drivers/net/via-rhine.c
drivers/net/virtio_net.c
drivers/net/wan/hd64572.c
drivers/net/wireless/ath5k/ath5k.h
drivers/net/wireless/ath5k/base.c
drivers/net/wireless/ath5k/desc.c
drivers/net/wireless/ath9k/core.h
drivers/net/wireless/ath9k/main.c
drivers/net/wireless/ath9k/rc.c
drivers/net/wireless/ath9k/recv.c
drivers/net/wireless/ath9k/xmit.c
drivers/net/wireless/b43/debugfs.c
drivers/net/wireless/b43/debugfs.h
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/phy_common.c
drivers/net/wireless/b43/phy_g.c
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-3945.h
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-calib.c
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-debug.h
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-io.h
drivers/net/wireless/iwlwifi/iwl-led.c
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/p54/p54.h
drivers/net/wireless/p54/p54common.c
drivers/net/wireless/p54/p54common.h
drivers/net/wireless/p54/p54pci.c
drivers/net/wireless/p54/p54usb.c
drivers/net/wireless/rtl818x/rtl8187_dev.c
drivers/net/xen-netfront.c
include/linux/dcbnl.h
include/linux/netdevice.h
include/linux/nl80211.h
include/net/cfg80211.h
include/net/dcbnl.h
include/net/irda/irda_device.h
include/net/mac80211.h
include/net/netlink.h
include/net/sctp/user.h
net/8021q/vlan_dev.c
net/appletalk/ddp.c
net/bluetooth/rfcomm/core.c
net/core/dev.c
net/dcb/dcbnl.c
net/ipv4/af_inet.c
net/ipv4/igmp.c
net/ipv4/tcp_output.c
net/mac80211/cfg.c
net/mac80211/ht.c
net/mac80211/ieee80211_i.h
net/mac80211/main.c
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/tx.c
net/mac80211/util.c
net/mac80211/wext.c
net/sched/sch_api.c
net/sched/sch_netem.c
net/sched/sch_sfq.c
net/sctp/sm_statefuns.c
net/sctp/socket.c
net/socket.c
net/wireless/nl80211.c

index 7c49cc882d75c580c0c31e20b987cf177d04fc9c..735c125b48af1073c62e1f924e88cf52c39be72e 100644 (file)
@@ -2541,7 +2541,7 @@ static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic
 {
        struct nes_vnic *nesvnic = container_of(cq, struct nes_vnic, nic_cq);
 
-       netif_rx_schedule(nesdev->netdev[nesvnic->netdev_index], &nesvnic->napi);
+       netif_rx_schedule(&nesvnic->napi);
 }
 
 
index 3c96203e0d915ff3ffff6347bc182bfb9e89d5cb..80e7a4d98d5ba15443933cdb48f8085040b3cd8c 100644 (file)
@@ -112,7 +112,7 @@ static int nes_netdev_poll(struct napi_struct *napi, int budget)
        nes_nic_ce_handler(nesdev, nescq);
 
        if (nescq->cqes_pending == 0) {
-               netif_rx_complete(netdev, napi);
+               netif_rx_complete(napi);
                /* clear out completed cqes and arm */
                nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
                                nescq->cq_number | (nescq->cqe_allocs_pending << 16));
index 28eb6f03c588987c1c417377205e53b34b2f5058..a1925810be3cb23f8e768b030c60d68944267b5f 100644 (file)
@@ -446,11 +446,11 @@ poll_more:
                if (dev->features & NETIF_F_LRO)
                        lro_flush_all(&priv->lro.lro_mgr);
 
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
                if (unlikely(ib_req_notify_cq(priv->recv_cq,
                                              IB_CQ_NEXT_COMP |
                                              IB_CQ_REPORT_MISSED_EVENTS)) &&
-                   netif_rx_reschedule(dev, napi))
+                   netif_rx_reschedule(napi))
                        goto poll_more;
        }
 
@@ -462,7 +462,7 @@ void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr)
        struct net_device *dev = dev_ptr;
        struct ipoib_dev_priv *priv = netdev_priv(dev);
 
-       netif_rx_schedule(dev, &priv->napi);
+       netif_rx_schedule(&priv->napi);
 }
 
 static void drain_tx_cq(struct net_device *dev)
index f6d9d1353dd54144aebb8541d85c572f073fac25..dd7ac8290aecfc7323554e90ab0850fe64713346 100644 (file)
@@ -604,7 +604,7 @@ rx_next:
 
                spin_lock_irqsave(&cp->lock, flags);
                cpw16_f(IntrMask, cp_intr_mask);
-               __netif_rx_complete(dev, napi);
+               __netif_rx_complete(napi);
                spin_unlock_irqrestore(&cp->lock, flags);
        }
 
@@ -641,9 +641,9 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
        }
 
        if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
-               if (netif_rx_schedule_prep(dev, &cp->napi)) {
+               if (netif_rx_schedule_prep(&cp->napi)) {
                        cpw16_f(IntrMask, cp_norx_intr_mask);
-                       __netif_rx_schedule(dev, &cp->napi);
+                       __netif_rx_schedule(&cp->napi);
                }
 
        if (status & (TxOK | TxErr | TxEmpty | SWInt))
index 67bbf4f25beac14d425eaf79ff6fb00b715a063e..fe370f8057933244e544cd5849e064e514edaa11 100644 (file)
@@ -2128,7 +2128,7 @@ static int rtl8139_poll(struct napi_struct *napi, int budget)
                 */
                spin_lock_irqsave(&tp->lock, flags);
                RTL_W16_F(IntrMask, rtl8139_intr_mask);
-               __netif_rx_complete(dev, napi);
+               __netif_rx_complete(napi);
                spin_unlock_irqrestore(&tp->lock, flags);
        }
        spin_unlock(&tp->rx_lock);
@@ -2178,9 +2178,9 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
        /* Receive packets are processed by poll routine.
           If not running start it now. */
        if (status & RxAckBits){
-               if (netif_rx_schedule_prep(dev, &tp->napi)) {
+               if (netif_rx_schedule_prep(&tp->napi)) {
                        RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
-                       __netif_rx_schedule(dev, &tp->napi);
+                       __netif_rx_schedule(&tp->napi);
                }
        }
 
index 0bc4f54d5db95861ecb6ff9cbe68b71df0bd370c..187ac6eb6e945e69f8fca9cd87e1161dd1ceb919 100644 (file)
@@ -831,7 +831,7 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
        if (rx_pkt_limit > 0) {
                /* Receive descriptor is empty now */
                spin_lock_irqsave(&lp->lock, flags);
-               __netif_rx_complete(dev, napi);
+               __netif_rx_complete(napi);
                writel(VAL0|RINTEN0, mmio + INTEN0);
                writel(VAL2 | RDMD0, mmio + CMD0);
                spin_unlock_irqrestore(&lp->lock, flags);
@@ -1170,11 +1170,11 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id)
 
        /* Check if Receive Interrupt has occurred. */
        if (intr0 & RINT0) {
-               if (netif_rx_schedule_prep(dev, &lp->napi)) {
+               if (netif_rx_schedule_prep(&lp->napi)) {
                        /* Disable receive interupts */
                        writel(RINTEN0, mmio + INTEN0);
                        /* Schedule a polling routine */
-                       __netif_rx_schedule(dev, &lp->napi);
+                       __netif_rx_schedule(&lp->napi);
                } else if (intren0 & RINTEN0) {
                        printk("************Driver bug! \
                                interrupt while in poll\n");
index 588c9739d13d2891ebbd0d2df7e873ecefc834db..6ecc600c1bccd05c5e22e17af5248fe998e9ecb0 100644 (file)
@@ -298,7 +298,7 @@ poll_some_more:
                int more = 0;
 
                spin_lock_irq(&ep->rx_lock);
-               __netif_rx_complete(dev, napi);
+               __netif_rx_complete(napi);
                wrl(ep, REG_INTEN, REG_INTEN_TX | REG_INTEN_RX);
                if (ep93xx_have_more_rx(ep)) {
                        wrl(ep, REG_INTEN, REG_INTEN_TX);
@@ -415,9 +415,9 @@ static irqreturn_t ep93xx_irq(int irq, void *dev_id)
 
        if (status & REG_INTSTS_RX) {
                spin_lock(&ep->rx_lock);
-               if (likely(netif_rx_schedule_prep(dev, &ep->napi))) {
+               if (likely(netif_rx_schedule_prep(&ep->napi))) {
                        wrl(ep, REG_INTEN, REG_INTEN_TX);
-                       __netif_rx_schedule(dev, &ep->napi);
+                       __netif_rx_schedule(&ep->napi);
                }
                spin_unlock(&ep->rx_lock);
        }
index 1c757b6781bb1a17bd492bf0d158ee250d510423..26af411fc42819f8b7190fc4b4ba263965f003d8 100644 (file)
@@ -473,7 +473,7 @@ static void eth_rx_irq(void *pdev)
        printk(KERN_DEBUG "%s: eth_rx_irq\n", dev->name);
 #endif
        qmgr_disable_irq(port->plat->rxq);
-       netif_rx_schedule(dev, &port->napi);
+       netif_rx_schedule(&port->napi);
 }
 
 static int eth_poll(struct napi_struct *napi, int budget)
@@ -501,7 +501,7 @@ static int eth_poll(struct napi_struct *napi, int budget)
                        printk(KERN_DEBUG "%s: eth_poll netif_rx_complete\n",
                               dev->name);
 #endif
-                       netif_rx_complete(dev, napi);
+                       netif_rx_complete(napi);
                        qmgr_enable_irq(rxq);
                        if (!qmgr_stat_empty(rxq) &&
                            netif_rx_reschedule(dev, napi)) {
@@ -1036,7 +1036,7 @@ static int eth_open(struct net_device *dev)
        }
        ports_open++;
        /* we may already have RX data, enables IRQ */
-       netif_rx_schedule(dev, &port->napi);
+       netif_rx_schedule(&port->napi);
        return 0;
 }
 
index 98b2a7a466b8c3f9377a1812ab551f0c59000995..a72a46145ed78ef896b07ddd83aaf1e463093535 100644 (file)
@@ -1326,9 +1326,9 @@ static irqreturn_t atl1e_intr(int irq, void *data)
                        AT_WRITE_REG(hw, REG_IMR,
                                     IMR_NORMAL_MASK & ~ISR_RX_EVENT);
                        AT_WRITE_FLUSH(hw);
-                       if (likely(netif_rx_schedule_prep(netdev,
+                       if (likely(netif_rx_schedule_prep(
                                   &adapter->napi)))
-                               __netif_rx_schedule(netdev, &adapter->napi);
+                               __netif_rx_schedule(&adapter->napi);
                }
        } while (--max_ints > 0);
        /* re-enable Interrupt*/
@@ -1515,7 +1515,7 @@ static int atl1e_clean(struct napi_struct *napi, int budget)
        /* If no Tx and not enough Rx work done, exit the polling mode */
        if (work_done < budget) {
 quit_polling:
-               netif_rx_complete(netdev, napi);
+               netif_rx_complete(napi);
                imr_data = AT_READ_REG(&adapter->hw, REG_IMR);
                AT_WRITE_REG(&adapter->hw, REG_IMR, imr_data | ISR_RX_EVENT);
                /* test debug */
index ecc2573b3dce29d7580331b1e9339fa458872fdb..9c875bb3f76c642f93203f9096942af72a0e3e53 100644 (file)
@@ -353,7 +353,6 @@ static int mii_probe (struct net_device *dev)
        }
 
        /* now we are supposed to have a proper phydev, to attach to... */
-       BUG_ON(!phydev);
        BUG_ON(phydev->attached_dev);
 
        phydev = phy_connect(dev, phydev->dev.bus_id, &au1000_adjust_link, 0,
index 2c7a32eb92a5c1ffdaa33f3fd008427d47192884..934a95091dc3d72176ff00c0fdc95c19bd2cd5f3 100644 (file)
@@ -875,7 +875,7 @@ static int b44_poll(struct napi_struct *napi, int budget)
        }
 
        if (work_done < budget) {
-               netif_rx_complete(netdev, napi);
+               netif_rx_complete(napi);
                b44_enable_ints(bp);
        }
 
@@ -907,13 +907,13 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id)
                        goto irq_ack;
                }
 
-               if (netif_rx_schedule_prep(dev, &bp->napi)) {
+               if (netif_rx_schedule_prep(&bp->napi)) {
                        /* NOTE: These writes are posted by the readback of
                         *       the ISTAT register below.
                         */
                        bp->istat = istat;
                        __b44_disable_ints(bp);
-                       __netif_rx_schedule(dev, &bp->napi);
+                       __netif_rx_schedule(&bp->napi);
                } else {
                        printk(KERN_ERR PFX "%s: Error, poll already scheduled\n",
                               dev->name);
index 1a2780374a49b2c52385e511345ca7dd06d8f758..d4a3dac21dcfb83fdc7e6c2835705ac66433ec3c 100644 (file)
@@ -547,9 +547,9 @@ bnx2_free_rx_mem(struct bnx2 *bp)
                for (j = 0; j < bp->rx_max_pg_ring; j++) {
                        if (rxr->rx_pg_desc_ring[j])
                                pci_free_consistent(bp->pdev, RXBD_RING_SIZE,
-                                                   rxr->rx_pg_desc_ring[i],
-                                                   rxr->rx_pg_desc_mapping[i]);
-                       rxr->rx_pg_desc_ring[i] = NULL;
+                                                   rxr->rx_pg_desc_ring[j],
+                                                   rxr->rx_pg_desc_mapping[j]);
+                       rxr->rx_pg_desc_ring[j] = NULL;
                }
                if (rxr->rx_pg_ring)
                        vfree(rxr->rx_pg_ring);
@@ -3043,7 +3043,6 @@ bnx2_msi(int irq, void *dev_instance)
 {
        struct bnx2_napi *bnapi = dev_instance;
        struct bnx2 *bp = bnapi->bp;
-       struct net_device *dev = bp->dev;
 
        prefetch(bnapi->status_blk.msi);
        REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
@@ -3054,7 +3053,7 @@ bnx2_msi(int irq, void *dev_instance)
        if (unlikely(atomic_read(&bp->intr_sem) != 0))
                return IRQ_HANDLED;
 
-       netif_rx_schedule(dev, &bnapi->napi);
+       netif_rx_schedule(&bnapi->napi);
 
        return IRQ_HANDLED;
 }
@@ -3064,7 +3063,6 @@ bnx2_msi_1shot(int irq, void *dev_instance)
 {
        struct bnx2_napi *bnapi = dev_instance;
        struct bnx2 *bp = bnapi->bp;
-       struct net_device *dev = bp->dev;
 
        prefetch(bnapi->status_blk.msi);
 
@@ -3072,7 +3070,7 @@ bnx2_msi_1shot(int irq, void *dev_instance)
        if (unlikely(atomic_read(&bp->intr_sem) != 0))
                return IRQ_HANDLED;
 
-       netif_rx_schedule(dev, &bnapi->napi);
+       netif_rx_schedule(&bnapi->napi);
 
        return IRQ_HANDLED;
 }
@@ -3082,7 +3080,6 @@ bnx2_interrupt(int irq, void *dev_instance)
 {
        struct bnx2_napi *bnapi = dev_instance;
        struct bnx2 *bp = bnapi->bp;
-       struct net_device *dev = bp->dev;
        struct status_block *sblk = bnapi->status_blk.msi;
 
        /* When using INTx, it is possible for the interrupt to arrive
@@ -3109,9 +3106,9 @@ bnx2_interrupt(int irq, void *dev_instance)
        if (unlikely(atomic_read(&bp->intr_sem) != 0))
                return IRQ_HANDLED;
 
-       if (netif_rx_schedule_prep(dev, &bnapi->napi)) {
+       if (netif_rx_schedule_prep(&bnapi->napi)) {
                bnapi->last_status_idx = sblk->status_idx;
-               __netif_rx_schedule(dev, &bnapi->napi);
+               __netif_rx_schedule(&bnapi->napi);
        }
 
        return IRQ_HANDLED;
@@ -3221,7 +3218,7 @@ static int bnx2_poll_msix(struct napi_struct *napi, int budget)
                rmb();
                if (likely(!bnx2_has_fast_work(bnapi))) {
 
-                       netif_rx_complete(bp->dev, napi);
+                       netif_rx_complete(napi);
                        REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
                               BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
                               bnapi->last_status_idx);
@@ -3254,7 +3251,7 @@ static int bnx2_poll(struct napi_struct *napi, int budget)
 
                rmb();
                if (likely(!bnx2_has_work(bnapi))) {
-                       netif_rx_complete(bp->dev, napi);
+                       netif_rx_complete(napi);
                        if (likely(bp->flags & BNX2_FLAG_USING_MSI_OR_MSIX)) {
                                REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
                                       BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
index 24d2ae8b74bf1c522fc52efc86b4bd647c3457b6..02ab9b0ea697bd6123fdbb18bc6f3b81c1ea978e 100644 (file)
@@ -1615,7 +1615,7 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
        prefetch(&fp->status_blk->c_status_block.status_block_index);
        prefetch(&fp->status_blk->u_status_block.status_block_index);
 
-       netif_rx_schedule(dev, &bnx2x_fp(bp, index, napi));
+       netif_rx_schedule(&bnx2x_fp(bp, index, napi));
 
        return IRQ_HANDLED;
 }
@@ -1654,7 +1654,7 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
                prefetch(&fp->status_blk->c_status_block.status_block_index);
                prefetch(&fp->status_blk->u_status_block.status_block_index);
 
-               netif_rx_schedule(dev, &bnx2x_fp(bp, 0, napi));
+               netif_rx_schedule(&bnx2x_fp(bp, 0, napi));
 
                status &= ~mask;
        }
@@ -9284,7 +9284,7 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
 #ifdef BNX2X_STOP_ON_ERROR
 poll_panic:
 #endif
-               netif_rx_complete(bp->dev, napi);
+               netif_rx_complete(napi);
 
                bnx2x_ack_sb(bp, FP_SB_ID(fp), USTORM_ID,
                             le16_to_cpu(fp->fp_u_idx), IGU_INT_NOP, 1);
index 023d205e90543c0ebcb37137023a2d9c9cc7435c..321f43d9f0e2caf56a2fb4263e338bc34a80f94e 100644 (file)
@@ -2506,7 +2506,7 @@ static irqreturn_t cas_interruptN(int irq, void *dev_id)
        if (status & INTR_RX_DONE_ALT) { /* handle rx separately */
 #ifdef USE_NAPI
                cas_mask_intr(cp);
-               netif_rx_schedule(dev, &cp->napi);
+               netif_rx_schedule(&cp->napi);
 #else
                cas_rx_ringN(cp, ring, 0);
 #endif
@@ -2557,7 +2557,7 @@ static irqreturn_t cas_interrupt1(int irq, void *dev_id)
        if (status & INTR_RX_DONE_ALT) { /* handle rx separately */
 #ifdef USE_NAPI
                cas_mask_intr(cp);
-               netif_rx_schedule(dev, &cp->napi);
+               netif_rx_schedule(&cp->napi);
 #else
                cas_rx_ringN(cp, 1, 0);
 #endif
@@ -2613,7 +2613,7 @@ static irqreturn_t cas_interrupt(int irq, void *dev_id)
        if (status & INTR_RX_DONE) {
 #ifdef USE_NAPI
                cas_mask_intr(cp);
-               netif_rx_schedule(dev, &cp->napi);
+               netif_rx_schedule(&cp->napi);
 #else
                cas_rx_ringN(cp, 0, 0);
 #endif
@@ -2691,7 +2691,7 @@ rx_comp:
 #endif
        spin_unlock_irqrestore(&cp->lock, flags);
        if (enable_intr) {
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
                cas_unmask_intr(cp);
        }
        return credits;
index 1da70070c2fa6626400de6df033fa30467f434cd..7896468dda119786f36f0f158a3edebfeed58928 100644 (file)
@@ -1613,7 +1613,7 @@ int t1_poll(struct napi_struct *napi, int budget)
        int work_done = process_responses(adapter, budget);
 
        if (likely(work_done < budget)) {
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
                writel(adapter->sge->respQ.cidx,
                       adapter->regs + A_SG_SLEEPING);
        }
@@ -1633,7 +1633,7 @@ irqreturn_t t1_interrupt(int irq, void *data)
 
                if (napi_schedule_prep(&adapter->napi)) {
                        if (process_pure_responses(adapter))
-                               __netif_rx_schedule(dev, &adapter->napi);
+                               __netif_rx_schedule(&adapter->napi);
                        else {
                                /* no data, no NAPI needed */
                                writel(sge->respQ.cidx, adapter->regs + A_SG_SLEEPING);
index d39a77cba1afe0c70214bd02b78df9ea8333a1e2..f66548751c384c1bf111f69b995dd701aa60b713 100644 (file)
@@ -428,7 +428,7 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
                        printk(KERN_WARNING "%s: rx: polling, but no queue\n",
                               priv->dev->name);
                spin_unlock(&priv->rx_lock);
-               netif_rx_complete(priv->dev, napi);
+               netif_rx_complete(napi);
                return 0;
        }
 
@@ -514,7 +514,7 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
        if (processed == 0) {
                /* we ran out of packets to read,
                 * revert to interrupt-driven mode */
-               netif_rx_complete(priv->dev, napi);
+               netif_rx_complete(napi);
                cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1);
                return 0;
        }
@@ -536,7 +536,7 @@ fatal_error:
        }
 
        spin_unlock(&priv->rx_lock);
-       netif_rx_complete(priv->dev, napi);
+       netif_rx_complete(napi);
        netif_tx_stop_all_queues(priv->dev);
        napi_disable(&priv->napi);
 
@@ -802,9 +802,9 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id)
 
        if (status & MAC_INT_RX) {
                queue = (status >> 8) & 7;
-               if (netif_rx_schedule_prep(dev, &priv->napi)) {
+               if (netif_rx_schedule_prep(&priv->napi)) {
                        cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 1 << queue);
-                       __netif_rx_schedule(dev, &priv->napi);
+                       __netif_rx_schedule(&priv->napi);
                }
        }
 
index c190a69c4d7184c00d7769345e885962ba23cb1f..5b346f9eaa8b482c556351a6d7eedf8c4fcce9ba 100644 (file)
@@ -63,6 +63,7 @@ struct port_info {
        struct link_config link_config;
        struct net_device_stats netstats;
        int activity;
+       __be32 iscsi_ipv4addr;
 };
 
 enum {                         /* adapter flags */
index 1d8d46eb3c960e0efd3725d731f947abb02b438f..55099eb3c70ec8c5b6e216cdea84567d392eb87c 100644 (file)
@@ -57,6 +57,7 @@ enum {
        RDMA_GET_MIB            = 19,
 
        GET_RX_PAGE_INFO        = 50,
+       GET_ISCSI_IPV4ADDR      = 51,
 };
 
 /*
@@ -86,6 +87,12 @@ struct iff_mac {
        u16 vlan_tag;
 };
 
+/* Structure used to request a port's iSCSI IPv4 address */
+struct iscsi_ipv4addr {
+       struct net_device *dev; /* the net_device */
+       __be32 ipv4addr;        /* the return iSCSI IPv4 address */
+};
+
 struct pci_dev;
 
 /*
index 265aa8a15afaed2eb5a61177917d07cd6649b476..1ce69b7428041af9ebc6232ffc5a6ac7103ad1a3 100644 (file)
@@ -182,7 +182,9 @@ static struct net_device *get_iff_from_mac(struct adapter *adapter,
 static int cxgb_ulp_iscsi_ctl(struct adapter *adapter, unsigned int req,
                              void *data)
 {
+       int i;
        int ret = 0;
+       unsigned int val = 0;
        struct ulp_iscsi_info *uiip = data;
 
        switch (req) {
@@ -191,32 +193,55 @@ static int cxgb_ulp_iscsi_ctl(struct adapter *adapter, unsigned int req,
                uiip->llimit = t3_read_reg(adapter, A_ULPRX_ISCSI_LLIMIT);
                uiip->ulimit = t3_read_reg(adapter, A_ULPRX_ISCSI_ULIMIT);
                uiip->tagmask = t3_read_reg(adapter, A_ULPRX_ISCSI_TAGMASK);
+
+               val = t3_read_reg(adapter, A_ULPRX_ISCSI_PSZ);
+               for (i = 0; i < 4; i++, val >>= 8)
+                       uiip->pgsz_factor[i] = val & 0xFF;
+
+               val = t3_read_reg(adapter, A_TP_PARA_REG7);
+               uiip->max_txsz =
+               uiip->max_rxsz = min((val >> S_PMMAXXFERLEN0)&M_PMMAXXFERLEN0,
+                                    (val >> S_PMMAXXFERLEN1)&M_PMMAXXFERLEN1);
                /*
                 * On tx, the iscsi pdu has to be <= tx page size and has to
                 * fit into the Tx PM FIFO.
                 */
-               uiip->max_txsz = min(adapter->params.tp.tx_pg_size,
-                                    t3_read_reg(adapter, A_PM1_TX_CFG) >> 17);
-               /* on rx, the iscsi pdu has to be < rx page size and the
-                  whole pdu + cpl headers has to fit into one sge buffer */
-               uiip->max_rxsz = min_t(unsigned int,
-                                      adapter->params.tp.rx_pg_size,
-                                      (adapter->sge.qs[0].fl[1].buf_size -
-                                       sizeof(struct cpl_rx_data) * 2 -
-                                       sizeof(struct cpl_rx_data_ddp)));
+               val = min(adapter->params.tp.tx_pg_size,
+                         t3_read_reg(adapter, A_PM1_TX_CFG) >> 17);
+               uiip->max_txsz = min(val, uiip->max_txsz);
+
+               /* set MaxRxData to 16224 */
+               val = t3_read_reg(adapter, A_TP_PARA_REG2);
+               if ((val >> S_MAXRXDATA) != 0x3f60) {
+                       val &= (M_RXCOALESCESIZE << S_RXCOALESCESIZE);
+                       val |= V_MAXRXDATA(0x3f60);
+                       printk(KERN_INFO
+                               "%s, iscsi set MaxRxData to 16224 (0x%x).\n",
+                               adapter->name, val);
+                       t3_write_reg(adapter, A_TP_PARA_REG2, val);
+               }
+
+               /*
+                * on rx, the iscsi pdu has to be < rx page size and the
+                * the max rx data length programmed in TP
+                */
+               val = min(adapter->params.tp.rx_pg_size,
+                         ((t3_read_reg(adapter, A_TP_PARA_REG2)) >>
+                               S_MAXRXDATA) & M_MAXRXDATA);
+               uiip->max_rxsz = min(val, uiip->max_rxsz);
                break;
        case ULP_ISCSI_SET_PARAMS:
                t3_write_reg(adapter, A_ULPRX_ISCSI_TAGMASK, uiip->tagmask);
-               /* set MaxRxData and MaxCoalesceSize to 16224 */
-               t3_write_reg(adapter, A_TP_PARA_REG2, 0x3f603f60);
                /* program the ddp page sizes */
-               {
-                       int i;
-                       unsigned int val = 0;
-                       for (i = 0; i < 4; i++)
-                               val |= (uiip->pgsz_factor[i] & 0xF) << (8 * i);
-                       if (val)
-                               t3_write_reg(adapter, A_ULPRX_ISCSI_PSZ, val);
+               for (i = 0; i < 4; i++)
+                       val |= (uiip->pgsz_factor[i] & 0xF) << (8 * i);
+               if (val && (val != t3_read_reg(adapter, A_ULPRX_ISCSI_PSZ))) {
+                       printk(KERN_INFO
+                               "%s, setting iscsi pgsz 0x%x, %u,%u,%u,%u.\n",
+                               adapter->name, val, uiip->pgsz_factor[0],
+                               uiip->pgsz_factor[1], uiip->pgsz_factor[2],
+                               uiip->pgsz_factor[3]);
+                       t3_write_reg(adapter, A_ULPRX_ISCSI_PSZ, val);
                }
                break;
        default:
@@ -407,6 +432,12 @@ static int cxgb_offload_ctl(struct t3cdev *tdev, unsigned int req, void *data)
                rx_page_info->page_size = tp->rx_pg_size;
                rx_page_info->num = tp->rx_num_pgs;
                break;
+       case GET_ISCSI_IPV4ADDR: {
+               struct iscsi_ipv4addr *p = data;
+               struct port_info *pi = netdev_priv(p->dev);
+               p->ipv4addr = pi->iscsi_ipv4addr;
+               break;
+       }
        default:
                return -EOPNOTSUPP;
        }
index 63eb97473c8bfed3270e9b141a3af23eb92def9e..6c641a889471012b5e6db7bac57da040d9f36ed8 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/dma-mapping.h>
+#include <net/arp.h>
 #include "common.h"
 #include "regs.h"
 #include "sge_defs.h"
@@ -1862,6 +1863,54 @@ static void restart_tx(struct sge_qset *qs)
        }
 }
 
+/**
+ *     cxgb3_arp_process - process an ARP request probing a private IP address
+ *     @adapter: the adapter
+ *     @skb: the skbuff containing the ARP request
+ *
+ *     Check if the ARP request is probing the private IP address
+ *     dedicated to iSCSI, generate an ARP reply if so.
+ */
+static void cxgb3_arp_process(struct adapter *adapter, struct sk_buff *skb)
+{
+       struct net_device *dev = skb->dev;
+       struct port_info *pi;
+       struct arphdr *arp;
+       unsigned char *arp_ptr;
+       unsigned char *sha;
+       __be32 sip, tip;
+
+       if (!dev)
+               return;
+
+       skb_reset_network_header(skb);
+       arp = arp_hdr(skb);
+
+       if (arp->ar_op != htons(ARPOP_REQUEST))
+               return;
+
+       arp_ptr = (unsigned char *)(arp + 1);
+       sha = arp_ptr;
+       arp_ptr += dev->addr_len;
+       memcpy(&sip, arp_ptr, sizeof(sip));
+       arp_ptr += sizeof(sip);
+       arp_ptr += dev->addr_len;
+       memcpy(&tip, arp_ptr, sizeof(tip));
+
+       pi = netdev_priv(dev);
+       if (tip != pi->iscsi_ipv4addr)
+               return;
+
+       arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
+                dev->dev_addr, sha);
+
+}
+
+static inline int is_arp(struct sk_buff *skb)
+{
+       return skb->protocol == htons(ETH_P_ARP);
+}
+
 /**
  *     rx_eth - process an ingress ethernet packet
  *     @adap: the adapter
@@ -1885,7 +1934,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
        pi = netdev_priv(skb->dev);
        if (pi->rx_csum_offload && p->csum_valid && p->csum == htons(0xffff) &&
            !p->fragment) {
-               rspq_to_qset(rq)->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
+               qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
                skb->ip_summed = CHECKSUM_UNNECESSARY;
        } else
                skb->ip_summed = CHECKSUM_NONE;
@@ -1900,16 +1949,28 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
                                                             grp,
                                                             ntohs(p->vlan),
                                                             p);
-                       else
+                       else {
+                               if (unlikely(pi->iscsi_ipv4addr &&
+                                   is_arp(skb))) {
+                                       unsigned short vtag = ntohs(p->vlan) &
+                                                               VLAN_VID_MASK;
+                                       skb->dev = vlan_group_get_device(grp,
+                                                                        vtag);
+                                       cxgb3_arp_process(adap, skb);
+                               }
                                __vlan_hwaccel_rx(skb, grp, ntohs(p->vlan),
                                                  rq->polling);
+                       }
                else
                        dev_kfree_skb_any(skb);
        } else if (rq->polling) {
                if (lro)
                        lro_receive_skb(&qs->lro_mgr, skb, p);
-               else
+               else {
+                       if (unlikely(pi->iscsi_ipv4addr && is_arp(skb)))
+                               cxgb3_arp_process(adap, skb);
                        netif_receive_skb(skb);
+               }
        } else
                netif_rx(skb);
 }
index dce7ff28c3ff4087b56ada70aff23ec29f90866d..9f38b16ccbbd1b58f308225d15e59f94f1585a1c 100644 (file)
@@ -2049,9 +2049,9 @@ static irqreturn_t e100_intr(int irq, void *dev_id)
        if(stat_ack & stat_ack_rnr)
                nic->ru_running = RU_SUSPENDED;
 
-       if(likely(netif_rx_schedule_prep(netdev, &nic->napi))) {
+       if(likely(netif_rx_schedule_prep(&nic->napi))) {
                e100_disable_irq(nic);
-               __netif_rx_schedule(netdev, &nic->napi);
+               __netif_rx_schedule(&nic->napi);
        }
 
        return IRQ_HANDLED;
@@ -2060,7 +2060,6 @@ static irqreturn_t e100_intr(int irq, void *dev_id)
 static int e100_poll(struct napi_struct *napi, int budget)
 {
        struct nic *nic = container_of(napi, struct nic, napi);
-       struct net_device *netdev = nic->netdev;
        unsigned int work_done = 0;
 
        e100_rx_clean(nic, &work_done, budget);
@@ -2068,7 +2067,7 @@ static int e100_poll(struct napi_struct *napi, int budget)
 
        /* If budget not fully consumed, exit the polling mode */
        if (work_done < budget) {
-               netif_rx_complete(netdev, napi);
+               netif_rx_complete(napi);
                e100_enable_irq(nic);
        }
 
index 116c96e0b1191278926b02518669de024e630f6f..26474c92193f705a3b66e413fa5773da38ce87f2 100644 (file)
@@ -3687,12 +3687,12 @@ static irqreturn_t e1000_intr_msi(int irq, void *data)
                        mod_timer(&adapter->watchdog_timer, jiffies + 1);
        }
 
-       if (likely(netif_rx_schedule_prep(netdev, &adapter->napi))) {
+       if (likely(netif_rx_schedule_prep(&adapter->napi))) {
                adapter->total_tx_bytes = 0;
                adapter->total_tx_packets = 0;
                adapter->total_rx_bytes = 0;
                adapter->total_rx_packets = 0;
-               __netif_rx_schedule(netdev, &adapter->napi);
+               __netif_rx_schedule(&adapter->napi);
        } else
                e1000_irq_enable(adapter);
 
@@ -3747,12 +3747,12 @@ static irqreturn_t e1000_intr(int irq, void *data)
                ew32(IMC, ~0);
                E1000_WRITE_FLUSH();
        }
-       if (likely(netif_rx_schedule_prep(netdev, &adapter->napi))) {
+       if (likely(netif_rx_schedule_prep(&adapter->napi))) {
                adapter->total_tx_bytes = 0;
                adapter->total_tx_packets = 0;
                adapter->total_rx_bytes = 0;
                adapter->total_rx_packets = 0;
-               __netif_rx_schedule(netdev, &adapter->napi);
+               __netif_rx_schedule(&adapter->napi);
        } else
                /* this really should not happen! if it does it is basically a
                 * bug, but not a hard error, so enable ints and continue */
@@ -3793,7 +3793,7 @@ static int e1000_clean(struct napi_struct *napi, int budget)
        if (work_done < budget) {
                if (likely(adapter->itr_setting & 3))
                        e1000_set_itr(adapter);
-               netif_rx_complete(poll_dev, napi);
+               netif_rx_complete(napi);
                e1000_irq_enable(adapter);
        }
 
index f7b05609073df59edd4f8065c1c1f039affbf15b..d4639facd1bddcb72a200ada597d02fc284529e7 100644 (file)
@@ -1179,12 +1179,12 @@ static irqreturn_t e1000_intr_msi(int irq, void *data)
                        mod_timer(&adapter->watchdog_timer, jiffies + 1);
        }
 
-       if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
+       if (netif_rx_schedule_prep(&adapter->napi)) {
                adapter->total_tx_bytes = 0;
                adapter->total_tx_packets = 0;
                adapter->total_rx_bytes = 0;
                adapter->total_rx_packets = 0;
-               __netif_rx_schedule(netdev, &adapter->napi);
+               __netif_rx_schedule(&adapter->napi);
        }
 
        return IRQ_HANDLED;
@@ -1246,12 +1246,12 @@ static irqreturn_t e1000_intr(int irq, void *data)
                        mod_timer(&adapter->watchdog_timer, jiffies + 1);
        }
 
-       if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
+       if (netif_rx_schedule_prep(&adapter->napi)) {
                adapter->total_tx_bytes = 0;
                adapter->total_tx_packets = 0;
                adapter->total_rx_bytes = 0;
                adapter->total_rx_packets = 0;
-               __netif_rx_schedule(netdev, &adapter->napi);
+               __netif_rx_schedule(&adapter->napi);
        }
 
        return IRQ_HANDLED;
@@ -1320,10 +1320,10 @@ static irqreturn_t e1000_intr_msix_rx(int irq, void *data)
                adapter->rx_ring->set_itr = 0;
        }
 
-       if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
+       if (netif_rx_schedule_prep(&adapter->napi)) {
                adapter->total_rx_bytes = 0;
                adapter->total_rx_packets = 0;
-               __netif_rx_schedule(netdev, &adapter->napi);
+               __netif_rx_schedule(&adapter->napi);
        }
        return IRQ_HANDLED;
 }
@@ -2028,7 +2028,7 @@ clean_rx:
        if (work_done < budget) {
                if (adapter->itr_setting & 3)
                        e1000_set_itr(adapter);
-               netif_rx_complete(poll_dev, napi);
+               netif_rx_complete(napi);
                if (adapter->msix_entries)
                        ew32(IMS, adapter->rx_ring->ims_val);
                else
index 44c9ae18383f837056a969d1775d9d28f7ecc7e6..035aa7dfc5cd867e40f72f5bd06ef2b37cb01cf1 100644 (file)
@@ -830,7 +830,7 @@ static int ehea_poll(struct napi_struct *napi, int budget)
        while ((rx != budget) || force_irq) {
                pr->poll_counter = 0;
                force_irq = 0;
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
                ehea_reset_cq_ep(pr->recv_cq);
                ehea_reset_cq_ep(pr->send_cq);
                ehea_reset_cq_n1(pr->recv_cq);
@@ -859,7 +859,7 @@ static void ehea_netpoll(struct net_device *dev)
        int i;
 
        for (i = 0; i < port->num_def_qps; i++)
-               netif_rx_schedule(dev, &port->port_res[i].napi);
+               netif_rx_schedule(&port->port_res[i].napi);
 }
 #endif
 
@@ -867,7 +867,7 @@ static irqreturn_t ehea_recv_irq_handler(int irq, void *param)
 {
        struct ehea_port_res *pr = param;
 
-       netif_rx_schedule(pr->port->netdev, &pr->napi);
+       netif_rx_schedule(&pr->napi);
 
        return IRQ_HANDLED;
 }
index 3c0ec82f36fb0f8e882e9823b9168744368925c9..e8c952b616627f912ce0ced06c1b751f1d3094fc 100644 (file)
@@ -182,7 +182,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter,
                                goto out_kill_hwq;
                        }
                } else {
-                       if ((hret != H_PAGE_REGISTERED) || (!vpage)) {
+                       if (hret != H_PAGE_REGISTERED) {
                                ehea_error("CQ: registration of page failed "
                                           "hret=%lx\n", hret);
                                goto out_kill_hwq;
@@ -303,7 +303,7 @@ struct ehea_eq *ehea_create_eq(struct ehea_adapter *adapter,
                                goto out_kill_hwq;
 
                } else {
-                       if ((hret != H_PAGE_REGISTERED) || (!vpage))
+                       if (hret != H_PAGE_REGISTERED)
                                goto out_kill_hwq;
 
                }
index deddd76a550cbb0f2958a869daa2e5f25038c09e..d039e16f276355a1552e4b6be6a7aecdf1bd0b66 100644 (file)
@@ -411,8 +411,8 @@ static irqreturn_t enic_isr_legacy(int irq, void *data)
        }
 
        if (ENIC_TEST_INTR(pba, ENIC_INTX_WQ_RQ)) {
-               if (netif_rx_schedule_prep(netdev, &enic->napi))
-                       __netif_rx_schedule(netdev, &enic->napi);
+               if (netif_rx_schedule_prep(&enic->napi))
+                       __netif_rx_schedule(&enic->napi);
        } else {
                vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]);
        }
@@ -440,7 +440,7 @@ static irqreturn_t enic_isr_msi(int irq, void *data)
         * writes).
         */
 
-       netif_rx_schedule(enic->netdev, &enic->napi);
+       netif_rx_schedule(&enic->napi);
 
        return IRQ_HANDLED;
 }
@@ -450,7 +450,7 @@ static irqreturn_t enic_isr_msix_rq(int irq, void *data)
        struct enic *enic = data;
 
        /* schedule NAPI polling for RQ cleanup */
-       netif_rx_schedule(enic->netdev, &enic->napi);
+       netif_rx_schedule(&enic->napi);
 
        return IRQ_HANDLED;
 }
@@ -1068,7 +1068,7 @@ static int enic_poll(struct napi_struct *napi, int budget)
                if (netdev->features & NETIF_F_LRO)
                        lro_flush_all(&enic->lro_mgr);
 
-               netif_rx_complete(netdev, napi);
+               netif_rx_complete(napi);
                vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]);
        }
 
@@ -1112,7 +1112,7 @@ static int enic_poll_msix(struct napi_struct *napi, int budget)
                if (netdev->features & NETIF_F_LRO)
                        lro_flush_all(&enic->lro_mgr);
 
-               netif_rx_complete(netdev, napi);
+               netif_rx_complete(napi);
                vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]);
        }
 
index 4a951b8cb4d73cb1db4ca264efb895a6b6529685..f9b37c80dda61f7eb84ca32a26dc93789d57c678 100644 (file)
@@ -1109,9 +1109,9 @@ static irqreturn_t epic_interrupt(int irq, void *dev_instance)
 
        if ((status & EpicNapiEvent) && !ep->reschedule_in_poll) {
                spin_lock(&ep->napi_lock);
-               if (netif_rx_schedule_prep(dev, &ep->napi)) {
+               if (netif_rx_schedule_prep(&ep->napi)) {
                        epic_napi_irq_off(dev, ep);
-                       __netif_rx_schedule(dev, &ep->napi);
+                       __netif_rx_schedule(&ep->napi);
                } else
                        ep->reschedule_in_poll++;
                spin_unlock(&ep->napi_lock);
@@ -1288,7 +1288,7 @@ rx_action:
 
                more = ep->reschedule_in_poll;
                if (!more) {
-                       __netif_rx_complete(dev, napi);
+                       __netif_rx_complete(napi);
                        outl(EpicNapiEvent, ioaddr + INTSTAT);
                        epic_napi_irq_on(dev, ep);
                } else
index 1f2b24743ee9ec0fc1a76c893e7bfa023940f218..5b68dc20168db466a867f63e44823e500568e837 100644 (file)
@@ -1760,7 +1760,7 @@ static void nv_do_rx_refill(unsigned long data)
        struct fe_priv *np = netdev_priv(dev);
 
        /* Just reschedule NAPI rx processing */
-       netif_rx_schedule(dev, &np->napi);
+       netif_rx_schedule(&np->napi);
 }
 #else
 static void nv_do_rx_refill(unsigned long data)
@@ -3403,7 +3403,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
 
 #ifdef CONFIG_FORCEDETH_NAPI
                if (events & NVREG_IRQ_RX_ALL) {
-                       netif_rx_schedule(dev, &np->napi);
+                       netif_rx_schedule(&np->napi);
 
                        /* Disable furthur receive irq's */
                        spin_lock(&np->lock);
@@ -3520,7 +3520,7 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
 
 #ifdef CONFIG_FORCEDETH_NAPI
                if (events & NVREG_IRQ_RX_ALL) {
-                       netif_rx_schedule(dev, &np->napi);
+                       netif_rx_schedule(&np->napi);
 
                        /* Disable furthur receive irq's */
                        spin_lock(&np->lock);
@@ -3678,7 +3678,7 @@ static int nv_napi_poll(struct napi_struct *napi, int budget)
                /* re-enable receive interrupts */
                spin_lock_irqsave(&np->lock, flags);
 
-               __netif_rx_complete(dev, napi);
+               __netif_rx_complete(napi);
 
                np->irqmask |= NVREG_IRQ_RX_ALL;
                if (np->msi_flags & NV_MSI_X_ENABLED)
@@ -3704,7 +3704,7 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data)
        writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus);
 
        if (events) {
-               netif_rx_schedule(dev, &np->napi);
+               netif_rx_schedule(&np->napi);
                /* disable receive interrupts on the nic */
                writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
                pci_push(base);
@@ -6167,7 +6167,7 @@ static struct pci_device_id pci_tbl[] = {
        },
        {       /* MCP79 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
        },
        {       /* MCP79 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
index df66d620b11555385642935d1a73f651981b52b0..4e6a9195fe5f6503e5bd609098a203186fab936c 100644 (file)
@@ -209,7 +209,7 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
 
        if (received < budget) {
                /* done */
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
                (*fep->ops->napi_enable_rx)(dev);
        }
        return received;
@@ -478,7 +478,7 @@ fs_enet_interrupt(int irq, void *dev_id)
                                /* NOTE: it is possible for FCCs in NAPI mode    */
                                /* to submit a spurious interrupt while in poll  */
                                if (napi_ok)
-                                       __netif_rx_schedule(dev, &fep->napi);
+                                       __netif_rx_schedule(&fep->napi);
                        }
                }
 
index 13f49643ba0bed2d59443af6c14d5988371a88e2..c672ecfc95957f24cc3cb0f358bface91b0a2fbd 100644 (file)
@@ -1607,9 +1607,9 @@ static int gfar_clean_tx_ring(struct net_device *dev)
 static void gfar_schedule_cleanup(struct net_device *dev)
 {
        struct gfar_private *priv = netdev_priv(dev);
-       if (netif_rx_schedule_prep(dev, &priv->napi)) {
+       if (netif_rx_schedule_prep(&priv->napi)) {
                gfar_write(&priv->regs->imask, IMASK_RTX_DISABLED);
-               __netif_rx_schedule(dev, &priv->napi);
+               __netif_rx_schedule(&priv->napi);
        }
 }
 
@@ -1863,7 +1863,7 @@ static int gfar_poll(struct napi_struct *napi, int budget)
                return budget;
 
        if (rx_cleaned < budget) {
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
 
                /* Clear the halt bit in RSTAT */
                gfar_write(&priv->regs->rstat, RSTAT_CLEAR_RHALT);
index 02ecfdb4df6b796d54297efb99cea723f92e0676..1f055a9550896824656b5aeb8f7d42b036c3bb0b 100644 (file)
@@ -1028,7 +1028,7 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)
 
                ibmveth_assert(lpar_rc == H_SUCCESS);
 
-               netif_rx_complete(netdev, napi);
+               netif_rx_complete(napi);
 
                if (ibmveth_rxq_pending_buffer(adapter) &&
                    netif_rx_reschedule(netdev, napi)) {
@@ -1047,11 +1047,11 @@ static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance)
        struct ibmveth_adapter *adapter = netdev_priv(netdev);
        unsigned long lpar_rc;
 
-       if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
+       if (netif_rx_schedule_prep(&adapter->napi)) {
                lpar_rc = h_vio_signal(adapter->vdev->unit_address,
                                       VIO_IRQ_DISABLE);
                ibmveth_assert(lpar_rc == H_SUCCESS);
-               __netif_rx_schedule(netdev, &adapter->napi);
+               __netif_rx_schedule(&adapter->napi);
        }
        return IRQ_HANDLED;
 }
index 25df7c9310647080c5da278b798c613fca408374..6a40d9486daf0ed61a4c1dd50a59aae11df9999a 100644 (file)
@@ -3347,8 +3347,8 @@ static irqreturn_t igb_msix_rx(int irq, void *data)
 
        igb_write_itr(rx_ring);
 
-       if (netif_rx_schedule_prep(adapter->netdev, &rx_ring->napi))
-               __netif_rx_schedule(adapter->netdev, &rx_ring->napi);
+       if (netif_rx_schedule_prep(&rx_ring->napi))
+               __netif_rx_schedule(&rx_ring->napi);
 
 #ifdef CONFIG_IGB_DCA
        if (adapter->flags & IGB_FLAG_DCA_ENABLED)
@@ -3500,7 +3500,7 @@ static irqreturn_t igb_intr_msi(int irq, void *data)
                        mod_timer(&adapter->watchdog_timer, jiffies + 1);
        }
 
-       netif_rx_schedule(netdev, &adapter->rx_ring[0].napi);
+       netif_rx_schedule(&adapter->rx_ring[0].napi);
 
        return IRQ_HANDLED;
 }
@@ -3538,7 +3538,7 @@ static irqreturn_t igb_intr(int irq, void *data)
                        mod_timer(&adapter->watchdog_timer, jiffies + 1);
        }
 
-       netif_rx_schedule(netdev, &adapter->rx_ring[0].napi);
+       netif_rx_schedule(&adapter->rx_ring[0].napi);
 
        return IRQ_HANDLED;
 }
@@ -3573,7 +3573,7 @@ static int igb_poll(struct napi_struct *napi, int budget)
            !netif_running(netdev)) {
                if (adapter->itr_setting & 3)
                        igb_set_itr(adapter);
-               netif_rx_complete(netdev, napi);
+               netif_rx_complete(napi);
                if (!test_bit(__IGB_DOWN, &adapter->state))
                        igb_irq_enable(adapter);
                return 0;
@@ -3599,7 +3599,7 @@ static int igb_clean_rx_ring_msix(struct napi_struct *napi, int budget)
 
        /* If not enough Rx work done, exit the polling mode */
        if ((work_done == 0) || !netif_running(netdev)) {
-               netif_rx_complete(netdev, napi);
+               netif_rx_complete(napi);
 
                if (adapter->itr_setting & 3) {
                        if (adapter->num_rx_queues == 1)
index 820a92cc7f620d7895fbe87b39b9a5db4603399c..679125b3bbc9c44210f4026b867aa791eec10d36 100644 (file)
@@ -1721,14 +1721,14 @@ ixgb_intr(int irq, void *data)
                if (!test_bit(__IXGB_DOWN, &adapter->flags))
                        mod_timer(&adapter->watchdog_timer, jiffies);
 
-       if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
+       if (netif_rx_schedule_prep(&adapter->napi)) {
 
                /* Disable interrupts and register for poll. The flush
                  of the posted write is intentionally left out.
                */
 
                IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
-               __netif_rx_schedule(netdev, &adapter->napi);
+               __netif_rx_schedule(&adapter->napi);
        }
        return IRQ_HANDLED;
 }
@@ -1750,7 +1750,7 @@ ixgb_clean(struct napi_struct *napi, int budget)
 
        /* If budget not fully consumed, exit the polling mode */
        if (work_done < budget) {
-               netif_rx_complete(netdev, napi);
+               netif_rx_complete(napi);
                if (!test_bit(__IXGB_DOWN, &adapter->flags))
                        ixgb_irq_enable(adapter);
        }
index 615c2803202a3d829c6797f50999cf9deb685715..8ac639d0da03b29832e676a67d5ea1847b7cb3a2 100644 (file)
@@ -93,6 +93,8 @@ int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
                dst_dcb_cfg->bcn.rp_admin_mode[i - DCB_BCN_ATTR_RP_0] =
                        src_dcb_cfg->bcn.rp_admin_mode[i - DCB_BCN_ATTR_RP_0];
        }
+       dst_dcb_cfg->bcn.bcna_option[0] = src_dcb_cfg->bcn.bcna_option[0];
+       dst_dcb_cfg->bcn.bcna_option[1] = src_dcb_cfg->bcn.bcna_option[1];
        dst_dcb_cfg->bcn.rp_alpha = src_dcb_cfg->bcn.rp_alpha;
        dst_dcb_cfg->bcn.rp_beta = src_dcb_cfg->bcn.rp_beta;
        dst_dcb_cfg->bcn.rp_gd = src_dcb_cfg->bcn.rp_gd;
@@ -124,39 +126,45 @@ static u16 ixgbe_dcb_select_queue(struct net_device *dev, struct sk_buff *skb)
        return 0;
 }
 
-static void ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
+static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
 {
+       u8 err = 0;
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
        DPRINTK(DRV, INFO, "Set DCB Admin Mode.\n");
 
        if (state > 0) {
                /* Turn on DCB */
-               if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
-                       return;
-               } else {
-                       if (netif_running(netdev))
-                               netdev->stop(netdev);
-                       ixgbe_reset_interrupt_capability(adapter);
-                       ixgbe_napi_del_all(adapter);
-                       kfree(adapter->tx_ring);
-                       kfree(adapter->rx_ring);
-                       adapter->tx_ring = NULL;
-                       adapter->rx_ring = NULL;
-                       netdev->select_queue = &ixgbe_dcb_select_queue;
+               if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
+                       goto out;
 
-                       adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
-                       adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
-                       ixgbe_init_interrupt_scheme(adapter);
-                       ixgbe_napi_add_all(adapter);
-                       if (netif_running(netdev))
-                               netdev->open(netdev);
+               if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) {
+                       DPRINTK(DRV, ERR, "Enable failed, needs MSI-X\n");
+                       err = 1;
+                       goto out;
                }
+
+               if (netif_running(netdev))
+                       netdev->netdev_ops->ndo_stop(netdev);
+               ixgbe_reset_interrupt_capability(adapter);
+               ixgbe_napi_del_all(adapter);
+               kfree(adapter->tx_ring);
+               kfree(adapter->rx_ring);
+               adapter->tx_ring = NULL;
+               adapter->rx_ring = NULL;
+               netdev->select_queue = &ixgbe_dcb_select_queue;
+
+               adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
+               adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
+               ixgbe_init_interrupt_scheme(adapter);
+               ixgbe_napi_add_all(adapter);
+               if (netif_running(netdev))
+                       netdev->netdev_ops->ndo_open(netdev);
        } else {
                /* Turn off DCB */
                if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
                        if (netif_running(netdev))
-                               netdev->stop(netdev);
+                               netdev->netdev_ops->ndo_stop(netdev);
                        ixgbe_reset_interrupt_capability(adapter);
                        ixgbe_napi_del_all(adapter);
                        kfree(adapter->tx_ring);
@@ -170,11 +178,11 @@ static void ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
                        ixgbe_init_interrupt_scheme(adapter);
                        ixgbe_napi_add_all(adapter);
                        if (netif_running(netdev))
-                               netdev->open(netdev);
-               } else {
-                       return;
+                               netdev->netdev_ops->ndo_open(netdev);
                }
        }
+out:
+       return err;
 }
 
 static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev,
@@ -451,6 +459,12 @@ static void ixgbe_dcbnl_getbcncfg(struct net_device *netdev, int enum_index,
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
        switch (enum_index) {
+       case DCB_BCN_ATTR_BCNA_0:
+               *setting = adapter->dcb_cfg.bcn.bcna_option[0];
+               break;
+       case DCB_BCN_ATTR_BCNA_1:
+               *setting = adapter->dcb_cfg.bcn.bcna_option[1];
+               break;
        case DCB_BCN_ATTR_ALPHA:
                *setting = adapter->dcb_cfg.bcn.rp_alpha;
                break;
@@ -510,6 +524,18 @@ static void ixgbe_dcbnl_setbcncfg(struct net_device *netdev, int enum_index,
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
        switch (enum_index) {
+       case DCB_BCN_ATTR_BCNA_0:
+               adapter->temp_dcb_cfg.bcn.bcna_option[0] = setting;
+               if (adapter->temp_dcb_cfg.bcn.bcna_option[0] !=
+                       adapter->dcb_cfg.bcn.bcna_option[0])
+                       adapter->dcb_set_bitmap |= BIT_BCN;
+               break;
+       case DCB_BCN_ATTR_BCNA_1:
+               adapter->temp_dcb_cfg.bcn.bcna_option[1] = setting;
+               if (adapter->temp_dcb_cfg.bcn.bcna_option[1] !=
+                       adapter->dcb_cfg.bcn.bcna_option[1])
+                       adapter->dcb_set_bitmap |= BIT_BCN;
+               break;
        case DCB_BCN_ATTR_ALPHA:
                adapter->temp_dcb_cfg.bcn.rp_alpha = setting;
                if (adapter->temp_dcb_cfg.bcn.rp_alpha !=
index ad9759de3cd868e1637e1ba33019b7eaed89a49c..849c1fe28207ad28030c8f83650a91fa590ba748 100644 (file)
@@ -881,8 +881,15 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
                if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
                        for (i = 0; i < MAX_TX_PACKET_BUFFERS; i++) {
                                sprintf(p, "tx_pb_%u_pxon", i);
+                               p += ETH_GSTRING_LEN;
+                               sprintf(p, "tx_pb_%u_pxoff", i);
+                               p += ETH_GSTRING_LEN;
                        }
                        for (i = 0; i < MAX_RX_PACKET_BUFFERS; i++) {
+                               sprintf(p, "rx_pb_%u_pxon", i);
+                               p += ETH_GSTRING_LEN;
+                               sprintf(p, "rx_pb_%u_pxoff", i);
+                               p += ETH_GSTRING_LEN;
                        }
                }
                /* BUG_ON(p - data != IXGBE_STATS_LEN * ETH_GSTRING_LEN); */
index 92b35cfc7a465dfe4e060c03b2fc7af16ae22029..b6ae9f674ba539e210e4c59e77f417ac62cacfcb 100644 (file)
@@ -1012,7 +1012,7 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
        rx_ring = &(adapter->rx_ring[r_idx]);
        /* disable interrupts on this vector only */
        IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx);
-       netif_rx_schedule(adapter->netdev, &q_vector->napi);
+       netif_rx_schedule(&q_vector->napi);
 
        return IRQ_HANDLED;
 }
@@ -1053,7 +1053,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
 
        /* If all Rx work done, exit the polling mode */
        if (work_done < budget) {
-               netif_rx_complete(adapter->netdev, napi);
+               netif_rx_complete(napi);
                if (adapter->itr_setting & 3)
                        ixgbe_set_itr_msix(q_vector);
                if (!test_bit(__IXGBE_DOWN, &adapter->state))
@@ -1102,7 +1102,7 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
        rx_ring = &(adapter->rx_ring[r_idx]);
        /* If all Rx work done, exit the polling mode */
        if (work_done < budget) {
-               netif_rx_complete(adapter->netdev, napi);
+               netif_rx_complete(napi);
                if (adapter->itr_setting & 3)
                        ixgbe_set_itr_msix(q_vector);
                if (!test_bit(__IXGBE_DOWN, &adapter->state))
@@ -1378,13 +1378,13 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
 
        ixgbe_check_fan_failure(adapter, eicr);
 
-       if (netif_rx_schedule_prep(netdev, &adapter->q_vector[0].napi)) {
+       if (netif_rx_schedule_prep(&adapter->q_vector[0].napi)) {
                adapter->tx_ring[0].total_packets = 0;
                adapter->tx_ring[0].total_bytes = 0;
                adapter->rx_ring[0].total_packets = 0;
                adapter->rx_ring[0].total_bytes = 0;
                /* would disable interrupts here but EIAM disabled it */
-               __netif_rx_schedule(netdev, &adapter->q_vector[0].napi);
+               __netif_rx_schedule(&adapter->q_vector[0].napi);
        }
 
        return IRQ_HANDLED;
@@ -2308,7 +2308,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
 
        /* If budget not fully consumed, exit the polling mode */
        if (work_done < budget) {
-               netif_rx_complete(adapter->netdev, napi);
+               netif_rx_complete(napi);
                if (adapter->itr_setting & 3)
                        ixgbe_set_itr(adapter);
                if (!test_bit(__IXGBE_DOWN, &adapter->state))
index bd96dbc8e0219c459587f0df9e640a67c8863254..014745720560df448b6654c0f051093505838e46 100644 (file)
@@ -141,7 +141,7 @@ static int ixpdev_poll(struct napi_struct *napi, int budget)
                        break;
        } while (ixp2000_reg_read(IXP2000_IRQ_THD_RAW_STATUS_A_0) & 0x00ff);
 
-       netif_rx_complete(dev, napi);
+       netif_rx_complete(napi);
        ixp2000_reg_write(IXP2000_IRQ_THD_ENABLE_SET_A_0, 0x00ff);
 
        return rx;
@@ -204,7 +204,7 @@ static irqreturn_t ixpdev_interrupt(int irq, void *dev_id)
 
                ixp2000_reg_wrb(IXP2000_IRQ_THD_ENABLE_CLEAR_A_0, 0x00ff);
                if (likely(napi_schedule_prep(&ip->napi))) {
-                       __netif_rx_schedule(dev, &ip->napi);
+                       __netif_rx_schedule(&ip->napi);
                } else {
                        printk(KERN_CRIT "ixp2000: irq while polling!!\n");
                }
index 15035cb1738a44b24dce5f10089fa2a794713576..08b34051c646d6e4028bb30847ad793c84aedd00 100644 (file)
@@ -1250,7 +1250,6 @@ static int
 jme_poll(JME_NAPI_HOLDER(holder), JME_NAPI_WEIGHT(budget))
 {
        struct jme_adapter *jme = jme_napi_priv(holder);
-       struct net_device *netdev = jme->dev;
        int rest;
 
        rest = jme_process_receive(jme, JME_NAPI_WEIGHT_VAL(budget));
index adaf3ddbf7835387bf6bca79f024d65919739ccb..5154411b5e6b0821054cdefef093947bf99a8333 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 #ifndef __JME_H_INCLUDED__
-#define __JME_H_INCLUDEE__
+#define __JME_H_INCLUDED__
 
 #define DRV_NAME       "jme"
 #define DRV_VERSION    "1.0.3"
@@ -398,15 +398,15 @@ struct jme_ring {
 #define JME_NAPI_WEIGHT(w) int w
 #define JME_NAPI_WEIGHT_VAL(w) w
 #define JME_NAPI_WEIGHT_SET(w, r)
-#define JME_RX_COMPLETE(dev, napis) netif_rx_complete(dev, napis)
+#define JME_RX_COMPLETE(dev, napis) netif_rx_complete(napis)
 #define JME_NAPI_ENABLE(priv) napi_enable(&priv->napi);
 #define JME_NAPI_DISABLE(priv) \
        if (!napi_disable_pending(&priv->napi)) \
                napi_disable(&priv->napi);
 #define JME_RX_SCHEDULE_PREP(priv) \
-       netif_rx_schedule_prep(priv->dev, &priv->napi)
+       netif_rx_schedule_prep(&priv->napi)
 #define JME_RX_SCHEDULE(priv) \
-       __netif_rx_schedule(priv->dev, &priv->napi);
+       __netif_rx_schedule(&priv->napi);
 
 /*
  * Jmac Adapter Private data
index 63626953f07e471780e4ff831496e6c9348a6d6f..4a5580c1126a00b383e4588b4ab6a2fa5376845e 100644 (file)
@@ -327,7 +327,7 @@ static irqreturn_t korina_rx_dma_interrupt(int irq, void *dev_id)
 
        dmas = readl(&lp->rx_dma_regs->dmas);
        if (dmas & (DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR)) {
-               netif_rx_schedule_prep(dev, &lp->napi);
+               netif_rx_schedule_prep(&lp->napi);
 
                dmasm = readl(&lp->rx_dma_regs->dmasm);
                writel(dmasm | (DMA_STAT_DONE |
@@ -466,7 +466,7 @@ static int korina_poll(struct napi_struct *napi, int budget)
 
        work_done = korina_rx(dev, budget);
        if (work_done < budget) {
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
 
                writel(readl(&lp->rx_dma_regs->dmasm) &
                        ~(DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR),
index 261b9507124b695e0ecf8fe91a5ea5cfae8e7f59..a04da4ecaa8811a8be09450389e33288ebe2d80e 100644 (file)
@@ -519,7 +519,7 @@ static int macb_poll(struct napi_struct *napi, int budget)
                 * this function was called last time, and no packets
                 * have been received since.
                 */
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
                goto out;
        }
 
@@ -530,13 +530,13 @@ static int macb_poll(struct napi_struct *napi, int budget)
                dev_warn(&bp->pdev->dev,
                         "No RX buffers complete, status = %02lx\n",
                         (unsigned long)status);
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
                goto out;
        }
 
        work_done = macb_rx(bp, budget);
        if (work_done < budget)
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
 
        /*
         * We've done what we can to clean the buffers. Make sure we
@@ -571,7 +571,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
                }
 
                if (status & MACB_RX_INT_FLAGS) {
-                       if (netif_rx_schedule_prep(dev, &bp->napi)) {
+                       if (netif_rx_schedule_prep(&bp->napi)) {
                                /*
                                 * There's no point taking any more interrupts
                                 * until we have processed the buffers
@@ -579,7 +579,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
                                macb_writel(bp, IDR, MACB_RX_INT_FLAGS);
                                dev_dbg(&bp->pdev->dev,
                                        "scheduling RX softirq\n");
-                               __netif_rx_schedule(dev, &bp->napi);
+                               __netif_rx_schedule(&bp->napi);
                        }
                }
 
index ffe28089b6873041a978b41b57a3520c66942157..c61b0bdca1a433c33771784d88fb8f6eae3f092d 100644 (file)
@@ -814,7 +814,7 @@ void mlx4_en_rx_irq(struct mlx4_cq *mcq)
        struct mlx4_en_priv *priv = netdev_priv(cq->dev);
 
        if (priv->port_up)
-               netif_rx_schedule(cq->dev, &cq->napi);
+               netif_rx_schedule(&cq->napi);
        else
                mlx4_en_arm_cq(priv, cq);
 }
@@ -834,7 +834,7 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget)
                INC_PERF_COUNTER(priv->pstats.napi_quota);
        else {
                /* Done for now */
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
                mlx4_en_arm_cq(priv, cq);
        }
        return done;
index f017c774e1a4c8ef58a73e1c3126e0a2431fe7ef..2da3ce17b981916cb12294c39f045eaeeb0f4b80 100644 (file)
@@ -75,7 +75,7 @@
 #include "myri10ge_mcp.h"
 #include "myri10ge_mcp_gen_header.h"
 
-#define MYRI10GE_VERSION_STR "1.4.3-1.378"
+#define MYRI10GE_VERSION_STR "1.4.4-1.395"
 
 MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
 MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -1515,7 +1515,7 @@ static int myri10ge_poll(struct napi_struct *napi, int budget)
        work_done = myri10ge_clean_rx_done(ss, budget);
 
        if (work_done < budget) {
-               netif_rx_complete(netdev, napi);
+               netif_rx_complete(napi);
                put_be32(htonl(3), ss->irq_claim);
        }
        return work_done;
@@ -1533,7 +1533,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
        /* an interrupt on a non-zero receive-only slice is implicitly
         * valid  since MSI-X irqs are not shared */
        if ((mgp->dev->real_num_tx_queues == 1) && (ss != mgp->ss)) {
-               netif_rx_schedule(ss->dev, &ss->napi);
+               netif_rx_schedule(&ss->napi);
                return (IRQ_HANDLED);
        }
 
@@ -1544,7 +1544,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
        /* low bit indicates receives are present, so schedule
         * napi poll handler */
        if (stats->valid & 1)
-               netif_rx_schedule(ss->dev, &ss->napi);
+               netif_rx_schedule(&ss->napi);
 
        if (!mgp->msi_enabled && !mgp->msix_enabled) {
                put_be32(0, mgp->irq_deassert);
index 993721090777d62004b20686a6136095f6169f2f..11be150e4d67fc1cb70906535a9356dd38051ee6 100644 (file)
@@ -111,61 +111,61 @@ enum myri10ge_mcp_cmd_type {
        MXGEFW_CMD_NONE = 0,
        /* Reset the mcp, it is left in a safe state, waiting
         * for the driver to set all its parameters */
-       MXGEFW_CMD_RESET,
+       MXGEFW_CMD_RESET = 1,
 
        /* get the version number of the current firmware..
         * (may be available in the eeprom strings..? */
-       MXGEFW_GET_MCP_VERSION,
+       MXGEFW_GET_MCP_VERSION = 2,
 
        /* Parameters which must be set by the driver before it can
         * issue MXGEFW_CMD_ETHERNET_UP. They persist until the next
         * MXGEFW_CMD_RESET is issued */
 
-       MXGEFW_CMD_SET_INTRQ_DMA,
+       MXGEFW_CMD_SET_INTRQ_DMA = 3,
        /* data0 = LSW of the host address
         * data1 = MSW of the host address
         * data2 = slice number if multiple slices are used
         */
 
-       MXGEFW_CMD_SET_BIG_BUFFER_SIZE, /* in bytes, power of 2 */
-       MXGEFW_CMD_SET_SMALL_BUFFER_SIZE,       /* in bytes */
+       MXGEFW_CMD_SET_BIG_BUFFER_SIZE = 4,     /* in bytes, power of 2 */
+       MXGEFW_CMD_SET_SMALL_BUFFER_SIZE = 5,   /* in bytes */
 
        /* Parameters which refer to lanai SRAM addresses where the
         * driver must issue PIO writes for various things */
 
-       MXGEFW_CMD_GET_SEND_OFFSET,
-       MXGEFW_CMD_GET_SMALL_RX_OFFSET,
-       MXGEFW_CMD_GET_BIG_RX_OFFSET,
+       MXGEFW_CMD_GET_SEND_OFFSET = 6,
+       MXGEFW_CMD_GET_SMALL_RX_OFFSET = 7,
+       MXGEFW_CMD_GET_BIG_RX_OFFSET = 8,
        /* data0 = slice number if multiple slices are used */
 
-       MXGEFW_CMD_GET_IRQ_ACK_OFFSET,
-       MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET,
+       MXGEFW_CMD_GET_IRQ_ACK_OFFSET = 9,
+       MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET = 10,
 
        /* Parameters which refer to rings stored on the MCP,
         * and whose size is controlled by the mcp */
 
-       MXGEFW_CMD_GET_SEND_RING_SIZE,  /* in bytes */
-       MXGEFW_CMD_GET_RX_RING_SIZE,    /* in bytes */
+       MXGEFW_CMD_GET_SEND_RING_SIZE = 11,     /* in bytes */
+       MXGEFW_CMD_GET_RX_RING_SIZE = 12,       /* in bytes */
 
        /* Parameters which refer to rings stored in the host,
         * and whose size is controlled by the host.  Note that
         * all must be physically contiguous and must contain
         * a power of 2 number of entries.  */
 
-       MXGEFW_CMD_SET_INTRQ_SIZE,      /* in bytes */
+       MXGEFW_CMD_SET_INTRQ_SIZE = 13, /* in bytes */
 #define MXGEFW_CMD_SET_INTRQ_SIZE_FLAG_NO_STRICT_SIZE_CHECK  (1 << 31)
 
        /* command to bring ethernet interface up.  Above parameters
         * (plus mtu & mac address) must have been exchanged prior
         * to issuing this command  */
-       MXGEFW_CMD_ETHERNET_UP,
+       MXGEFW_CMD_ETHERNET_UP = 14,
 
        /* command to bring ethernet interface down.  No further sends
         * or receives may be processed until an MXGEFW_CMD_ETHERNET_UP
         * is issued, and all interrupt queues must be flushed prior
         * to ack'ing this command */
 
-       MXGEFW_CMD_ETHERNET_DOWN,
+       MXGEFW_CMD_ETHERNET_DOWN = 15,
 
        /* commands the driver may issue live, without resetting
         * the nic.  Note that increasing the mtu "live" should
@@ -173,40 +173,40 @@ enum myri10ge_mcp_cmd_type {
         * sufficiently large to handle the new mtu.  Decreasing
         * the mtu live is safe */
 
-       MXGEFW_CMD_SET_MTU,
-       MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET,  /* in microseconds */
-       MXGEFW_CMD_SET_STATS_INTERVAL,  /* in microseconds */
-       MXGEFW_CMD_SET_STATS_DMA_OBSOLETE,      /* replaced by SET_STATS_DMA_V2 */
+       MXGEFW_CMD_SET_MTU = 16,
+       MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET = 17,     /* in microseconds */
+       MXGEFW_CMD_SET_STATS_INTERVAL = 18,     /* in microseconds */
+       MXGEFW_CMD_SET_STATS_DMA_OBSOLETE = 19, /* replaced by SET_STATS_DMA_V2 */
 
-       MXGEFW_ENABLE_PROMISC,
-       MXGEFW_DISABLE_PROMISC,
-       MXGEFW_SET_MAC_ADDRESS,
+       MXGEFW_ENABLE_PROMISC = 20,
+       MXGEFW_DISABLE_PROMISC = 21,
+       MXGEFW_SET_MAC_ADDRESS = 22,
 
-       MXGEFW_ENABLE_FLOW_CONTROL,
-       MXGEFW_DISABLE_FLOW_CONTROL,
+       MXGEFW_ENABLE_FLOW_CONTROL = 23,
+       MXGEFW_DISABLE_FLOW_CONTROL = 24,
 
        /* do a DMA test
         * data0,data1 = DMA address
         * data2       = RDMA length (MSH), WDMA length (LSH)
         * command return data = repetitions (MSH), 0.5-ms ticks (LSH)
         */
-       MXGEFW_DMA_TEST,
+       MXGEFW_DMA_TEST = 25,
 
-       MXGEFW_ENABLE_ALLMULTI,
-       MXGEFW_DISABLE_ALLMULTI,
+       MXGEFW_ENABLE_ALLMULTI = 26,
+       MXGEFW_DISABLE_ALLMULTI = 27,
 
        /* returns MXGEFW_CMD_ERROR_MULTICAST
         * if there is no room in the cache
         * data0,MSH(data1) = multicast group address */
-       MXGEFW_JOIN_MULTICAST_GROUP,
+       MXGEFW_JOIN_MULTICAST_GROUP = 28,
        /* returns MXGEFW_CMD_ERROR_MULTICAST
         * if the address is not in the cache,
         * or is equal to FF-FF-FF-FF-FF-FF
         * data0,MSH(data1) = multicast group address */
-       MXGEFW_LEAVE_MULTICAST_GROUP,
-       MXGEFW_LEAVE_ALL_MULTICAST_GROUPS,
+       MXGEFW_LEAVE_MULTICAST_GROUP = 29,
+       MXGEFW_LEAVE_ALL_MULTICAST_GROUPS = 30,
 
-       MXGEFW_CMD_SET_STATS_DMA_V2,
+       MXGEFW_CMD_SET_STATS_DMA_V2 = 31,
        /* data0, data1 = bus addr,
         * data2 = sizeof(struct mcp_irq_data) from driver point of view, allows
         * adding new stuff to mcp_irq_data without changing the ABI
@@ -216,14 +216,14 @@ enum myri10ge_mcp_cmd_type {
         * (in the upper 16 bits).
         */
 
-       MXGEFW_CMD_UNALIGNED_TEST,
+       MXGEFW_CMD_UNALIGNED_TEST = 32,
        /* same than DMA_TEST (same args) but abort with UNALIGNED on unaligned
         * chipset */
 
-       MXGEFW_CMD_UNALIGNED_STATUS,
+       MXGEFW_CMD_UNALIGNED_STATUS = 33,
        /* return data = boolean, true if the chipset is known to be unaligned */
 
-       MXGEFW_CMD_ALWAYS_USE_N_BIG_BUFFERS,
+       MXGEFW_CMD_ALWAYS_USE_N_BIG_BUFFERS = 34,
        /* data0 = number of big buffers to use.  It must be 0 or a power of 2.
         * 0 indicates that the NIC consumes as many buffers as they are required
         * for packet. This is the default behavior.
@@ -233,8 +233,8 @@ enum myri10ge_mcp_cmd_type {
         * the NIC to be able to receive maximum-sized packets.
         */
 
-       MXGEFW_CMD_GET_MAX_RSS_QUEUES,
-       MXGEFW_CMD_ENABLE_RSS_QUEUES,
+       MXGEFW_CMD_GET_MAX_RSS_QUEUES = 35,
+       MXGEFW_CMD_ENABLE_RSS_QUEUES = 36,
        /* data0 = number of slices n (0, 1, ..., n-1) to enable
         * data1 = interrupt mode | use of multiple transmit queues.
         * 0=share one INTx/MSI.
@@ -249,18 +249,18 @@ enum myri10ge_mcp_cmd_type {
 #define MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE   0x1
 #define MXGEFW_SLICE_ENABLE_MULTIPLE_TX_QUEUES 0x2
 
-       MXGEFW_CMD_GET_RSS_SHARED_INTERRUPT_MASK_OFFSET,
-       MXGEFW_CMD_SET_RSS_SHARED_INTERRUPT_DMA,
+       MXGEFW_CMD_GET_RSS_SHARED_INTERRUPT_MASK_OFFSET = 37,
+       MXGEFW_CMD_SET_RSS_SHARED_INTERRUPT_DMA = 38,
        /* data0, data1 = bus address lsw, msw */
-       MXGEFW_CMD_GET_RSS_TABLE_OFFSET,
+       MXGEFW_CMD_GET_RSS_TABLE_OFFSET = 39,
        /* get the offset of the indirection table */
-       MXGEFW_CMD_SET_RSS_TABLE_SIZE,
+       MXGEFW_CMD_SET_RSS_TABLE_SIZE = 40,
        /* set the size of the indirection table */
-       MXGEFW_CMD_GET_RSS_KEY_OFFSET,
+       MXGEFW_CMD_GET_RSS_KEY_OFFSET = 41,
        /* get the offset of the secret key */
-       MXGEFW_CMD_RSS_KEY_UPDATED,
+       MXGEFW_CMD_RSS_KEY_UPDATED = 42,
        /* tell nic that the secret key's been updated */
-       MXGEFW_CMD_SET_RSS_ENABLE,
+       MXGEFW_CMD_SET_RSS_ENABLE = 43,
        /* data0 = enable/disable rss
         * 0: disable rss.  nic does not distribute receive packets.
         * 1: enable rss.  nic distributes receive packets among queues.
@@ -277,7 +277,7 @@ enum myri10ge_mcp_cmd_type {
 #define MXGEFW_RSS_HASH_TYPE_SRC_DST_PORT 0x5
 #define MXGEFW_RSS_HASH_TYPE_MAX 0x5
 
-       MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE,
+       MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE = 44,
        /* Return data = the max. size of the entire headers of a IPv6 TSO packet.
         * If the header size of a IPv6 TSO packet is larger than the specified
         * value, then the driver must not use TSO.
@@ -286,7 +286,7 @@ enum myri10ge_mcp_cmd_type {
         * always has enough header buffer to store maximum-sized headers.
         */
 
-       MXGEFW_CMD_SET_TSO_MODE,
+       MXGEFW_CMD_SET_TSO_MODE = 45,
        /* data0 = TSO mode.
         * 0: Linux/FreeBSD style (NIC default)
         * 1: NDIS/NetBSD style
@@ -294,33 +294,37 @@ enum myri10ge_mcp_cmd_type {
 #define MXGEFW_TSO_MODE_LINUX  0
 #define MXGEFW_TSO_MODE_NDIS   1
 
-       MXGEFW_CMD_MDIO_READ,
+       MXGEFW_CMD_MDIO_READ = 46,
        /* data0 = dev_addr (PMA/PMD or PCS ...), data1 = register/addr */
-       MXGEFW_CMD_MDIO_WRITE,
+       MXGEFW_CMD_MDIO_WRITE = 47,
        /* data0 = dev_addr,  data1 = register/addr, data2 = value  */
 
-       MXGEFW_CMD_XFP_I2C_READ,
-       /* Starts to get a fresh copy of one byte or of the whole xfp i2c table, the
+       MXGEFW_CMD_I2C_READ = 48,
+       /* Starts to get a fresh copy of one byte or of the module i2c table, the
         * obtained data is cached inside the xaui-xfi chip :
-        *   data0 : "all" flag : 0 => get one byte, 1=> get 256 bytes,
-        *   data1 : if (data0 == 0): index of byte to refresh [ not used otherwise ]
+        *   data0 :  0 => get one byte, 1=> get 256 bytes
+        *   data1 :  If data0 == 0: location to refresh
+        *               bit 7:0  register location
+        *               bit 8:15 is the i2c slave addr (0 is interpreted as 0xA1)
+        *               bit 23:16 is the i2c bus number (for multi-port NICs)
+        *            If data0 == 1: unused
         * The operation might take ~1ms for a single byte or ~65ms when refreshing all 256 bytes
-        * During the i2c operation,  MXGEFW_CMD_XFP_I2C_READ or MXGEFW_CMD_XFP_BYTE attempts
+        * During the i2c operation,  MXGEFW_CMD_I2C_READ or MXGEFW_CMD_I2C_BYTE attempts
         *  will return MXGEFW_CMD_ERROR_BUSY
         */
-       MXGEFW_CMD_XFP_BYTE,
+       MXGEFW_CMD_I2C_BYTE = 49,
        /* Return the last obtained copy of a given byte in the xfp i2c table
-        * (copy cached during the last relevant MXGEFW_CMD_XFP_I2C_READ)
+        * (copy cached during the last relevant MXGEFW_CMD_I2C_READ)
         *   data0 : index of the desired table entry
         *  Return data = the byte stored at the requested index in the table
         */
 
-       MXGEFW_CMD_GET_VPUMP_OFFSET,
+       MXGEFW_CMD_GET_VPUMP_OFFSET = 50,
        /* Return data = NIC memory offset of mcp_vpump_public_global */
-       MXGEFW_CMD_RESET_VPUMP,
+       MXGEFW_CMD_RESET_VPUMP = 51,
        /* Resets the VPUMP state */
 
-       MXGEFW_CMD_SET_RSS_MCP_SLOT_TYPE,
+       MXGEFW_CMD_SET_RSS_MCP_SLOT_TYPE = 52,
        /* data0 = mcp_slot type to use.
         * 0 = the default 4B mcp_slot
         * 1 = 8B mcp_slot_8
@@ -328,7 +332,7 @@ enum myri10ge_mcp_cmd_type {
 #define MXGEFW_RSS_MCP_SLOT_TYPE_MIN        0
 #define MXGEFW_RSS_MCP_SLOT_TYPE_WITH_HASH  1
 
-       MXGEFW_CMD_SET_THROTTLE_FACTOR,
+       MXGEFW_CMD_SET_THROTTLE_FACTOR = 53,
        /* set the throttle factor for ethp_z8e
         * data0 = throttle_factor
         * throttle_factor = 256 * pcie-raw-speed / tx_speed
@@ -344,45 +348,50 @@ enum myri10ge_mcp_cmd_type {
         * with tx_boundary == 4096, max-throttle-factor == 4095 => min-speed == 1Gb/s
         */
 
-       MXGEFW_CMD_VPUMP_UP,
+       MXGEFW_CMD_VPUMP_UP = 54,
        /* Allocates VPump Connection, Send Request and Zero copy buffer address tables */
-       MXGEFW_CMD_GET_VPUMP_CLK,
+       MXGEFW_CMD_GET_VPUMP_CLK = 55,
        /* Get the lanai clock */
 
-       MXGEFW_CMD_GET_DCA_OFFSET,
+       MXGEFW_CMD_GET_DCA_OFFSET = 56,
        /* offset of dca control for WDMAs */
 
        /* VMWare NetQueue commands */
-       MXGEFW_CMD_NETQ_GET_FILTERS_PER_QUEUE,
-       MXGEFW_CMD_NETQ_ADD_FILTER,
+       MXGEFW_CMD_NETQ_GET_FILTERS_PER_QUEUE = 57,
+       MXGEFW_CMD_NETQ_ADD_FILTER = 58,
        /* data0 = filter_id << 16 | queue << 8 | type */
        /* data1 = MS4 of MAC Addr */
        /* data2 = LS2_MAC << 16 | VLAN_tag */
-       MXGEFW_CMD_NETQ_DEL_FILTER,
+       MXGEFW_CMD_NETQ_DEL_FILTER = 59,
        /* data0 = filter_id */
-       MXGEFW_CMD_NETQ_QUERY1,
-       MXGEFW_CMD_NETQ_QUERY2,
-       MXGEFW_CMD_NETQ_QUERY3,
-       MXGEFW_CMD_NETQ_QUERY4,
-
+       MXGEFW_CMD_NETQ_QUERY1 = 60,
+       MXGEFW_CMD_NETQ_QUERY2 = 61,
+       MXGEFW_CMD_NETQ_QUERY3 = 62,
+       MXGEFW_CMD_NETQ_QUERY4 = 63,
+
+       MXGEFW_CMD_RELAX_RXBUFFER_ALIGNMENT = 64,
+       /* When set, small receive buffers can cross page boundaries.
+        * Both small and big receive buffers may start at any address.
+        * This option has performance implications, so use with caution.
+        */
 };
 
 enum myri10ge_mcp_cmd_status {
        MXGEFW_CMD_OK = 0,
-       MXGEFW_CMD_UNKNOWN,
-       MXGEFW_CMD_ERROR_RANGE,
-       MXGEFW_CMD_ERROR_BUSY,
-       MXGEFW_CMD_ERROR_EMPTY,
-       MXGEFW_CMD_ERROR_CLOSED,
-       MXGEFW_CMD_ERROR_HASH_ERROR,
-       MXGEFW_CMD_ERROR_BAD_PORT,
-       MXGEFW_CMD_ERROR_RESOURCES,
-       MXGEFW_CMD_ERROR_MULTICAST,
-       MXGEFW_CMD_ERROR_UNALIGNED,
-       MXGEFW_CMD_ERROR_NO_MDIO,
-       MXGEFW_CMD_ERROR_XFP_FAILURE,
-       MXGEFW_CMD_ERROR_XFP_ABSENT,
-       MXGEFW_CMD_ERROR_BAD_PCIE_LINK
+       MXGEFW_CMD_UNKNOWN = 1,
+       MXGEFW_CMD_ERROR_RANGE = 2,
+       MXGEFW_CMD_ERROR_BUSY = 3,
+       MXGEFW_CMD_ERROR_EMPTY = 4,
+       MXGEFW_CMD_ERROR_CLOSED = 5,
+       MXGEFW_CMD_ERROR_HASH_ERROR = 6,
+       MXGEFW_CMD_ERROR_BAD_PORT = 7,
+       MXGEFW_CMD_ERROR_RESOURCES = 8,
+       MXGEFW_CMD_ERROR_MULTICAST = 9,
+       MXGEFW_CMD_ERROR_UNALIGNED = 10,
+       MXGEFW_CMD_ERROR_NO_MDIO = 11,
+       MXGEFW_CMD_ERROR_I2C_FAILURE = 12,
+       MXGEFW_CMD_ERROR_I2C_ABSENT = 13,
+       MXGEFW_CMD_ERROR_BAD_PCIE_LINK = 14
 };
 
 #define MXGEFW_OLD_IRQ_DATA_LEN 40
index 124bbeac512b6000a0b38a866b7660e3f00b3014..caa6cbbb631e557fa4074be08b4dac212f00a1aa 100644 (file)
@@ -42,6 +42,7 @@ struct mcp_gen_header {
        unsigned short handoff_id_caps; /* bitfield: new mcp must have superset */
        unsigned msix_table_addr;       /* start address of msix table in firmware */
        unsigned bss_addr;      /* start of bss */
+       unsigned features;
        /* 8 */
 };
 
index 9f81fcb968824386efa12fe3fe97967c2dc02fdd..478edb92bca35581509f80a7709354c00a2f3d17 100644 (file)
@@ -2193,10 +2193,10 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
 
        prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]);
 
-       if (netif_rx_schedule_prep(dev, &np->napi)) {
+       if (netif_rx_schedule_prep(&np->napi)) {
                /* Disable interrupts and register for poll */
                natsemi_irq_disable(dev);
-               __netif_rx_schedule(dev, &np->napi);
+               __netif_rx_schedule(&np->napi);
        } else
                printk(KERN_WARNING
                       "%s: Ignoring interrupt, status %#08x, mask %#08x.\n",
@@ -2248,7 +2248,7 @@ static int natsemi_poll(struct napi_struct *napi, int budget)
                np->intr_status = readl(ioaddr + IntrStatus);
        } while (np->intr_status);
 
-       netif_rx_complete(dev, napi);
+       netif_rx_complete(napi);
 
        /* Reenable interrupts providing nothing is trying to shut
         * the chip down. */
index 6876bfd4455aa3a8c3e506bb878426202678955c..ba01524b5531a46d7ced8efd6470ad825601c23e 100644 (file)
@@ -1583,7 +1583,7 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget)
        }
 
        if ((work_done < budget) && tx_complete) {
-               netif_rx_complete(adapter->netdev, &adapter->napi);
+               netif_rx_complete(&adapter->napi);
                netxen_nic_enable_int(adapter);
        }
 
index f219f16ec97a25b65f76c43928ca1f59a2ff077a..5698c155bbf3ffa473891ad15f448fd2db00e899 100644 (file)
@@ -3669,7 +3669,7 @@ static int niu_poll(struct napi_struct *napi, int budget)
        work_done = niu_poll_core(np, lp, budget);
 
        if (work_done < budget) {
-               netif_rx_complete(np->dev, napi);
+               netif_rx_complete(napi);
                niu_ldg_rearm(np, lp, 1);
        }
        return work_done;
@@ -4088,12 +4088,12 @@ static void __niu_fastpath_interrupt(struct niu *np, int ldg, u64 v0)
 static void niu_schedule_napi(struct niu *np, struct niu_ldg *lp,
                              u64 v0, u64 v1, u64 v2)
 {
-       if (likely(netif_rx_schedule_prep(np->dev, &lp->napi))) {
+       if (likely(netif_rx_schedule_prep(&lp->napi))) {
                lp->v0 = v0;
                lp->v1 = v1;
                lp->v2 = v2;
                __niu_fastpath_interrupt(np, lp->ldg_num, v0);
-               __netif_rx_schedule(np->dev, &lp->napi);
+               __netif_rx_schedule(&lp->napi);
        }
 }
 
index fcbf6ccd0a85480125d63baef07b1a283abf9752..dcd199045613f3bbc4921ae2bee71d92f743ff62 100644 (file)
@@ -971,7 +971,7 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data)
        if (*chan->status & PAS_STATUS_ERROR)
                reg |= PAS_IOB_DMA_RXCH_RESET_DINTC;
 
-       netif_rx_schedule(dev, &mac->napi);
+       netif_rx_schedule(&mac->napi);
 
        write_iob_reg(PAS_IOB_DMA_RXCH_RESET(chan->chno), reg);
 
@@ -1011,7 +1011,7 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data)
 
        mod_timer(&txring->clean_timer, jiffies + (TX_CLEAN_INTERVAL)*2);
 
-       netif_rx_schedule(mac->netdev, &mac->napi);
+       netif_rx_schedule(&mac->napi);
 
        if (reg)
                write_iob_reg(PAS_IOB_DMA_TXCH_RESET(chan->chno), reg);
@@ -1641,7 +1641,7 @@ static int pasemi_mac_poll(struct napi_struct *napi, int budget)
        pkts = pasemi_mac_clean_rx(rx_ring(mac), budget);
        if (pkts < budget) {
                /* all done, no more packets present */
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
 
                pasemi_mac_restart_rx_intr(mac);
                pasemi_mac_restart_tx_intr(mac);
index f2b192c80e175b5dc06e8c215e8f00a4184a2dbe..044b7b07f5f48cf83ebbb8c7adce3134a3470f04 100644 (file)
@@ -1397,7 +1397,7 @@ static int pcnet32_poll(struct napi_struct *napi, int budget)
        if (work_done < budget) {
                spin_lock_irqsave(&lp->lock, flags);
 
-               __netif_rx_complete(dev, napi);
+               __netif_rx_complete(napi);
 
                /* clear interrupt masks */
                val = lp->a.read_csr(ioaddr, CSR3);
@@ -2586,14 +2586,14 @@ pcnet32_interrupt(int irq, void *dev_id)
                                       dev->name, csr0);
                        /* unlike for the lance, there is no restart needed */
                }
-               if (netif_rx_schedule_prep(dev, &lp->napi)) {
+               if (netif_rx_schedule_prep(&lp->napi)) {
                        u16 val;
                        /* set interrupt masks */
                        val = lp->a.read_csr(ioaddr, CSR3);
                        val |= 0x5f00;
                        lp->a.write_csr(ioaddr, CSR3, val);
                        mmiowb();
-                       __netif_rx_schedule(dev, &lp->napi);
+                       __netif_rx_schedule(&lp->napi);
                        break;
                }
                csr0 = lp->a.read_csr(ioaddr, CSR0);
index 8755d8cd41661a4251b75366a19f01c2cfc98b38..11adf6ed46288cf1e48a329d555feda84d1d442b 100644 (file)
@@ -63,7 +63,9 @@ EXPORT_SYMBOL(mdiobus_alloc);
 static void mdiobus_release(struct device *d)
 {
        struct mii_bus *bus = to_mii_bus(d);
-       BUG_ON(bus->state != MDIOBUS_RELEASED);
+       BUG_ON(bus->state != MDIOBUS_RELEASED &&
+              /* for compatibility with error handling in drivers */
+              bus->state != MDIOBUS_ALLOCATED);
        kfree(bus);
 }
 
@@ -83,8 +85,7 @@ static struct class mdio_bus_class = {
  */
 int mdiobus_register(struct mii_bus *bus)
 {
-       int i;
-       int err = 0;
+       int i, err;
 
        if (NULL == bus || NULL == bus->name ||
                        NULL == bus->read ||
@@ -105,8 +106,6 @@ int mdiobus_register(struct mii_bus *bus)
                return -EINVAL;
        }
 
-       bus->state = MDIOBUS_REGISTERED;
-
        mutex_init(&bus->mdio_lock);
 
        if (bus->reset)
@@ -118,13 +117,23 @@ int mdiobus_register(struct mii_bus *bus)
                        struct phy_device *phydev;
 
                        phydev = mdiobus_scan(bus, i);
-                       if (IS_ERR(phydev))
+                       if (IS_ERR(phydev)) {
                                err = PTR_ERR(phydev);
+                               goto error;
+                       }
                }
        }
 
+       bus->state = MDIOBUS_REGISTERED;
        pr_info("%s: probed\n", bus->name);
+       return 0;
 
+error:
+       while (--i >= 0) {
+               if (bus->phy_map[i])
+                       device_unregister(&bus->phy_map[i]->dev);
+       }
+       device_del(&bus->dev);
        return err;
 }
 EXPORT_SYMBOL(mdiobus_register);
index f84f6a1b530c09cf74c9d7cdc129d11fb97c81ee..e35460165bf76709211ffa16f969a3b1fb07dbe8 100644 (file)
@@ -232,7 +232,7 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr)
                return NULL;
 
        /*
-        * Broken hardware is sometimes missing the pull down resistor on the
+        * Broken hardware is sometimes missing the pull-up resistor on the
         * MDIO line, which results in reads to non-existent devices returning
         * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent
         * device as well.
index 451bdb57d6fc98b5389a9067e52c49fff9df37c9..6567fabd2e132a4ab4296a8283d32632b299c9d0 100644 (file)
@@ -293,9 +293,6 @@ ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
        err = -EFAULT;
        switch (cmd) {
        case PPPIOCGCHAN:
-               err = -ENXIO;
-               if (!ap)
-                       break;
                err = -EFAULT;
                if (put_user(ppp_channel_index(&ap->chan), p))
                        break;
@@ -303,9 +300,6 @@ ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
                break;
 
        case PPPIOCGUNIT:
-               err = -ENXIO;
-               if (!ap)
-                       break;
                err = -EFAULT;
                if (put_user(ppp_unit_number(&ap->chan), p))
                        break;
index 3ee7830d458dbbb322ef48fd7cbe0e23fb56bbb6..06b448285eb5d0783c104383c12b0e4add6309ea 100644 (file)
@@ -117,6 +117,7 @@ struct ppp {
        unsigned long   last_xmit;      /* jiffies when last pkt sent 9c */
        unsigned long   last_recv;      /* jiffies when last pkt rcvd a0 */
        struct net_device *dev;         /* network interface device a4 */
+       int             closing;        /* is device closing down? a8 */
 #ifdef CONFIG_PPP_MULTILINK
        int             nxchan;         /* next channel to send something on */
        u32             nxseq;          /* next sequence number to send */
@@ -179,7 +180,7 @@ struct channel {
  */
 static DEFINE_MUTEX(all_ppp_mutex);
 static atomic_t ppp_unit_count = ATOMIC_INIT(0);
-static struct idr ppp_units_idr;
+static DEFINE_IDR(ppp_units_idr);
 
 /*
  * all_channels_lock protects all_channels and last_channel_index,
@@ -852,8 +853,6 @@ static int __init ppp_init(void)
                              "ppp");
        }
 
-       idr_init(&ppp_units_idr);
-
 out:
        if (err)
                printk(KERN_ERR "failed to register PPP device (%d)\n", err);
@@ -985,7 +984,7 @@ ppp_xmit_process(struct ppp *ppp)
        struct sk_buff *skb;
 
        ppp_xmit_lock(ppp);
-       if (ppp->dev) {
+       if (!ppp->closing) {
                ppp_push(ppp);
                while (!ppp->xmit_pending
                       && (skb = skb_dequeue(&ppp->file.xq)))
@@ -1453,8 +1452,7 @@ static inline void
 ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
 {
        ppp_recv_lock(ppp);
-       /* ppp->dev == 0 means interface is closing down */
-       if (ppp->dev)
+       if (!ppp->closing)
                ppp_receive_frame(ppp, skb, pch);
        else
                kfree_skb(skb);
@@ -2435,7 +2433,7 @@ ppp_create_interface(int unit, int *retp)
                if (unit_find(&ppp_units_idr, unit))
                        goto out2; /* unit already exists */
                else {
-                       /* darn, someone is cheatting us? */
+                       /* darn, someone is cheating us? */
                        *retp = -EINVAL;
                        goto out2;
                }
@@ -2486,18 +2484,16 @@ init_ppp_file(struct ppp_file *pf, int kind)
  */
 static void ppp_shutdown_interface(struct ppp *ppp)
 {
-       struct net_device *dev;
-
        mutex_lock(&all_ppp_mutex);
-       ppp_lock(ppp);
-       dev = ppp->dev;
-       ppp->dev = NULL;
-       ppp_unlock(ppp);
        /* This will call dev_close() for us. */
-       if (dev) {
-               unregister_netdev(dev);
-               free_netdev(dev);
-       }
+       ppp_lock(ppp);
+       if (!ppp->closing) {
+               ppp->closing = 1;
+               ppp_unlock(ppp);
+               unregister_netdev(ppp->dev);
+       } else
+               ppp_unlock(ppp);
+
        unit_put(&ppp_units_idr, ppp->file.index);
        ppp->file.dead = 1;
        ppp->owner = NULL;
@@ -2542,7 +2538,7 @@ static void ppp_destroy_interface(struct ppp *ppp)
        if (ppp->xmit_pending)
                kfree_skb(ppp->xmit_pending);
 
-       kfree(ppp);
+       free_netdev(ppp->dev);
 }
 
 /*
@@ -2604,7 +2600,7 @@ ppp_connect_channel(struct channel *pch, int unit)
        if (pch->file.hdrlen > ppp->file.hdrlen)
                ppp->file.hdrlen = pch->file.hdrlen;
        hdrlen = pch->file.hdrlen + 2;  /* for protocol bytes */
-       if (ppp->dev && hdrlen > ppp->dev->hard_header_len)
+       if (hdrlen > ppp->dev->hard_header_len)
                ppp->dev->hard_header_len = hdrlen;
        list_add_tail(&pch->clist, &ppp->channels);
        ++ppp->n_channels;
index 801d8f99d4714155e2f3b3f9c0879ec15d2de8ba..1e892b7b1f8cf997764e7a29ffe09bbf745f69ff 100644 (file)
@@ -333,9 +333,6 @@ ppp_synctty_ioctl(struct tty_struct *tty, struct file *file,
        err = -EFAULT;
        switch (cmd) {
        case PPPIOCGCHAN:
-               err = -ENXIO;
-               if (!ap)
-                       break;
                err = -EFAULT;
                if (put_user(ppp_channel_index(&ap->chan), p))
                        break;
@@ -343,9 +340,6 @@ ppp_synctty_ioctl(struct tty_struct *tty, struct file *file,
                break;
 
        case PPPIOCGUNIT:
-               err = -ENXIO;
-               if (!ap)
-                       break;
                err = -EFAULT;
                if (put_user(ppp_unit_number(&ap->chan), p))
                        break;
index 6b7ed1a5b3b7bf8b34e8a0e61ec4a5eb34034029..33e8e62b450212f281cc9e6e641a73ea12d1e492 100644 (file)
@@ -2293,7 +2293,7 @@ static int ql_poll(struct napi_struct *napi, int budget)
 
        if (tx_cleaned + rx_cleaned != budget) {
                spin_lock_irqsave(&qdev->hw_lock, hw_flags);
-               __netif_rx_complete(ndev, napi);
+               __netif_rx_complete(napi);
                ql_update_small_bufq_prod_index(qdev);
                ql_update_lrg_bufq_prod_index(qdev);
                writel(qdev->rsp_consumer_index,
@@ -2352,8 +2352,8 @@ static irqreturn_t ql3xxx_isr(int irq, void *dev_id)
                spin_unlock(&qdev->adapter_lock);
        } else if (value & ISP_IMR_DISABLE_CMPL_INT) {
                ql_disable_interrupts(qdev);
-               if (likely(netif_rx_schedule_prep(ndev, &qdev->napi))) {
-                       __netif_rx_schedule(ndev, &qdev->napi);
+               if (likely(netif_rx_schedule_prep(&qdev->napi))) {
+                       __netif_rx_schedule(&qdev->napi);
                }
        } else {
                return IRQ_NONE;
index 225930fda5af418ec324412f58302813c1bbe5c8..4070d53c94aabcd15805ef285c9a8436be6acedb 100644 (file)
@@ -1647,7 +1647,7 @@ static int ql_napi_poll_msix(struct napi_struct *napi, int budget)
                rx_ring->cq_id);
 
        if (work_done < budget) {
-               __netif_rx_complete(qdev->ndev, napi);
+               __netif_rx_complete(napi);
                ql_enable_completion_interrupt(qdev, rx_ring->irq);
        }
        return work_done;
@@ -1733,7 +1733,7 @@ static irqreturn_t qlge_msix_rx_isr(int irq, void *dev_id)
 {
        struct rx_ring *rx_ring = dev_id;
        struct ql_adapter *qdev = rx_ring->qdev;
-       netif_rx_schedule(qdev->ndev, &rx_ring->napi);
+       netif_rx_schedule(&rx_ring->napi);
        return IRQ_HANDLED;
 }
 
@@ -1819,8 +1819,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
                                                              &rx_ring->rx_work,
                                                              0);
                                else
-                                       netif_rx_schedule(qdev->ndev,
-                                                         &rx_ring->napi);
+                                       netif_rx_schedule(&rx_ring->napi);
                                work_done++;
                        }
                }
@@ -3150,7 +3149,7 @@ static int ql_adapter_down(struct ql_adapter *qdev)
         * a workqueue only if it's a single interrupt
         * environment (MSI/Legacy).
         */
-       for (i = 1; i > qdev->rx_ring_count; i++) {
+       for (i = 1; i < qdev->rx_ring_count; i++) {
                rx_ring = &qdev->rx_ring[i];
                /* Only the RSS rings use NAPI on multi irq
                 * environment.  Outbound completion processing
index 281080d579e19c2ef0254cfba05d130da973962f..53bbddfc8c954ec17381230a4a491374f4a7404e 100644 (file)
@@ -49,8 +49,8 @@
 #include <asm/processor.h>
 
 #define DRV_NAME       "r6040"
-#define DRV_VERSION    "0.18"
-#define DRV_RELDATE    "13Jul2008"
+#define DRV_VERSION    "0.19"
+#define DRV_RELDATE    "18Dec2008"
 
 /* PHY CHIP Address */
 #define PHY1_ADDR      1       /* For MAC1 */
@@ -214,7 +214,7 @@ static int r6040_phy_read(void __iomem *ioaddr, int phy_addr, int reg)
        /* Wait for the read bit to be cleared */
        while (limit--) {
                cmd = ioread16(ioaddr + MMDIO);
-               if (cmd & MDIO_READ)
+               if (!(cmd & MDIO_READ))
                        break;
        }
 
@@ -233,7 +233,7 @@ static void r6040_phy_write(void __iomem *ioaddr, int phy_addr, int reg, u16 val
        /* Wait for the write bit to be cleared */
        while (limit--) {
                cmd = ioread16(ioaddr + MMDIO);
-               if (cmd & MDIO_WRITE)
+               if (!(cmd & MDIO_WRITE))
                        break;
        }
 }
@@ -667,7 +667,7 @@ static int r6040_poll(struct napi_struct *napi, int budget)
        work_done = r6040_rx(dev, budget);
 
        if (work_done < budget) {
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
                /* Enable RX interrupt */
                iowrite16(ioread16(ioaddr + MIER) | RX_INTS, ioaddr + MIER);
        }
@@ -680,8 +680,10 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)
        struct net_device *dev = dev_id;
        struct r6040_private *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->base;
-       u16 status;
+       u16 misr, status;
 
+       /* Save MIER */
+       misr = ioread16(ioaddr + MIER);
        /* Mask off RDC MAC interrupt */
        iowrite16(MSK_INT, ioaddr + MIER);
        /* Read MISR status and clear */
@@ -701,14 +703,17 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)
                        dev->stats.rx_fifo_errors++;
 
                /* Mask off RX interrupt */
-               iowrite16(ioread16(ioaddr + MIER) & ~RX_INTS, ioaddr + MIER);
-               netif_rx_schedule(dev, &lp->napi);
+               misr &= ~RX_INTS;
+               netif_rx_schedule(&lp->napi);
        }
 
        /* TX interrupt request */
        if (status & TX_INTS)
                r6040_tx(dev);
 
+       /* Restore RDC MAC interrupt */
+       iowrite16(misr, ioaddr + MIER);
+
        return IRQ_HANDLED;
 }
 
index dddf6aeff498ef1e4c88a101369481ccc21e4212..2c73ca606b35e0942e31a033791f550ed4db481c 100644 (file)
@@ -3581,8 +3581,8 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
                RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
                tp->intr_mask = ~tp->napi_event;
 
-               if (likely(netif_rx_schedule_prep(dev, &tp->napi)))
-                       __netif_rx_schedule(dev, &tp->napi);
+               if (likely(netif_rx_schedule_prep(&tp->napi)))
+                       __netif_rx_schedule(&tp->napi);
                else if (netif_msg_intr(tp)) {
                        printk(KERN_INFO "%s: interrupt %04x in poll\n",
                               dev->name, status);
@@ -3603,7 +3603,7 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
        rtl8169_tx_interrupt(dev, tp, ioaddr);
 
        if (work_done < budget) {
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
                tp->intr_mask = 0xffff;
                /*
                 * 20040426: the barrier is not strictly required but the
index 1b489df80fa675b88d9cc81de87b3e6f0458aee6..512861923c6bcfd82a76c7d6ec27e9d61619af0b 100644 (file)
@@ -2852,7 +2852,7 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget)
        s2io_chk_rx_buffers(nic, ring);
 
        if (pkts_processed < budget_org) {
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
                /*Re Enable MSI-Rx Vector*/
                addr = (u8 __iomem *)&bar0->xmsi_mask_reg;
                addr += 7 - ring->ring_no;
@@ -2890,7 +2890,7 @@ static int s2io_poll_inta(struct napi_struct *napi, int budget)
                        break;
        }
        if (pkts_processed < budget_org) {
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
                /* Re enable the Rx interrupts for the ring */
                writeq(0, &bar0->rx_traffic_mask);
                readl(&bar0->rx_traffic_mask);
@@ -4344,7 +4344,7 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id)
                val8 = (ring->ring_no == 0) ? 0x7f : 0xff;
                writeb(val8, addr);
                val8 = readb(addr);
-               netif_rx_schedule(dev, &ring->napi);
+               netif_rx_schedule(&ring->napi);
        } else {
                rx_intr_handler(ring, 0);
                s2io_chk_rx_buffers(sp, ring);
@@ -4791,7 +4791,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
 
                if (config->napi) {
                        if (reason & GEN_INTR_RXTRAFFIC) {
-                               netif_rx_schedule(dev, &sp->napi);
+                               netif_rx_schedule(&sp->napi);
                                writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask);
                                writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int);
                                readl(&bar0->rx_traffic_int);
index 480caec1e0248ecc163c990f9f5a3a1dcab415b5..31e38fae017f8def7273d568089914599a1b54d6 100644 (file)
@@ -2039,9 +2039,9 @@ static irqreturn_t sbmac_intr(int irq,void *dev_instance)
                sbdma_tx_process(sc,&(sc->sbm_txdma), 0);
 
        if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) {
-               if (netif_rx_schedule_prep(dev, &sc->napi)) {
+               if (netif_rx_schedule_prep(&sc->napi)) {
                        __raw_writeq(0, sc->sbm_imr);
-                       __netif_rx_schedule(dev, &sc->napi);
+                       __netif_rx_schedule(&sc->napi);
                        /* Depend on the exit from poll to reenable intr */
                }
                else {
@@ -2667,7 +2667,7 @@ static int sbmac_poll(struct napi_struct *napi, int budget)
        sbdma_tx_process(sc, &(sc->sbm_txdma), 1);
 
        if (work_done < budget) {
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
 
 #ifdef CONFIG_SBMAC_COALESCE
                __raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
index 086629c0fe57bcf9a0ea97f8630eb83eeea4babb..42934ba2030d9d08d8c1b0ec987c932de298b1c4 100644 (file)
@@ -230,7 +230,7 @@ static int efx_poll(struct napi_struct *napi, int budget)
                 * since efx_channel_processed() will have no effect if
                 * interrupts have already been disabled.
                 */
-               netif_rx_complete(napi_dev, napi);
+               netif_rx_complete(napi);
                efx_channel_processed(channel);
        }
 
index dd0d45b9e71f2d4a7dc76fc87f28844dd25ad815..0dd7a532c78a4b06a5c92209d763313570983556 100644 (file)
@@ -77,7 +77,7 @@ static inline void efx_schedule_channel(struct efx_channel *channel)
                  channel->channel, raw_smp_processor_id());
        channel->work_pending = true;
 
-       netif_rx_schedule(channel->napi_dev, &channel->napi_str);
+       netif_rx_schedule(&channel->napi_str);
 }
 
 #endif /* EFX_EFX_H */
index f73ee7974003fe293a39703d443c384d9c481f94..c9dbb06f8c9430cfb06779a8486544792972996a 100644 (file)
@@ -3214,7 +3214,7 @@ static int skge_poll(struct napi_struct *napi, int to_do)
                unsigned long flags;
 
                spin_lock_irqsave(&hw->hw_lock, flags);
-               __netif_rx_complete(dev, napi);
+               __netif_rx_complete(napi);
                hw->intr_mask |= napimask[skge->port];
                skge_write32(hw, B0_IMSK, hw->intr_mask);
                skge_read32(hw, B0_IMSK);
@@ -3377,7 +3377,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id)
        if (status & (IS_XA1_F|IS_R1_F)) {
                struct skge_port *skge = netdev_priv(hw->dev[0]);
                hw->intr_mask &= ~(IS_XA1_F|IS_R1_F);
-               netif_rx_schedule(hw->dev[0], &skge->napi);
+               netif_rx_schedule(&skge->napi);
        }
 
        if (status & IS_PA_TO_TX1)
@@ -3397,7 +3397,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id)
 
                if (status & (IS_XA2_F|IS_R2_F)) {
                        hw->intr_mask &= ~(IS_XA2_F|IS_R2_F);
-                       netif_rx_schedule(hw->dev[1], &skge->napi);
+                       netif_rx_schedule(&skge->napi);
                }
 
                if (status & IS_PA_TO_RX2) {
index fa28542b47d5b677f1a7d3fc03601bef07253d6b..5e989d884dddc9bc13e3f14ca7bde9749332b0cf 100644 (file)
@@ -822,7 +822,6 @@ static int __devinit smsc911x_mii_init(struct platform_device *pdev,
                pdata->mii_bus->irq[i] = PHY_POLL;
 
        pdata->mii_bus->parent = &pdev->dev;
-       dev_set_drvdata(&pdev->dev, &pdata->mii_bus);
 
        pdata->using_extphy = 0;
 
@@ -984,7 +983,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
                        /* We processed all packets available.  Tell NAPI it can
                         * stop polling then re-enable rx interrupts */
                        smsc911x_reg_write(pdata, INT_STS, INT_STS_RSFL_);
-                       netif_rx_complete(dev, napi);
+                       netif_rx_complete(napi);
                        temp = smsc911x_reg_read(pdata, INT_EN);
                        temp |= INT_EN_RSFL_EN_;
                        smsc911x_reg_write(pdata, INT_EN, temp);
@@ -1267,8 +1266,6 @@ static int smsc911x_stop(struct net_device *dev)
        struct smsc911x_data *pdata = netdev_priv(dev);
        unsigned int temp;
 
-       BUG_ON(!pdata->phy_dev);
-
        /* Disable all device interrupts */
        temp = smsc911x_reg_read(pdata, INT_CFG);
        temp &= ~INT_CFG_IRQ_EN_;
@@ -1283,7 +1280,8 @@ static int smsc911x_stop(struct net_device *dev)
        smsc911x_tx_update_txcounters(dev);
 
        /* Bring the PHY down */
-       phy_stop(pdata->phy_dev);
+       if (pdata->phy_dev)
+               phy_stop(pdata->phy_dev);
 
        SMSC_TRACE(IFDOWN, "Interface stopped");
        return 0;
@@ -1719,7 +1717,7 @@ static int smsc911x_ethtool_set_eeprom(struct net_device *dev,
        return ret;
 }
 
-static struct ethtool_ops smsc911x_ethtool_ops = {
+static const struct ethtool_ops smsc911x_ethtool_ops = {
        .get_settings = smsc911x_ethtool_getsettings,
        .set_settings = smsc911x_ethtool_setsettings,
        .get_link = ethtool_op_get_link,
@@ -1734,6 +1732,19 @@ static struct ethtool_ops smsc911x_ethtool_ops = {
        .set_eeprom = smsc911x_ethtool_set_eeprom,
 };
 
+static const struct net_device_ops smsc911x_netdev_ops = {
+       .ndo_open               = smsc911x_open,
+       .ndo_stop               = smsc911x_stop,
+       .ndo_start_xmit         = smsc911x_hard_start_xmit,
+       .ndo_get_stats          = smsc911x_get_stats,
+       .ndo_set_multicast_list = smsc911x_set_multicast_list,
+       .ndo_do_ioctl           = smsc911x_do_ioctl,
+       .ndo_validate_addr      = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = smsc911x_poll_controller,
+#endif
+};
+
 /* Initializing private device structures, only called from probe */
 static int __devinit smsc911x_init(struct net_device *dev)
 {
@@ -1829,20 +1840,11 @@ static int __devinit smsc911x_init(struct net_device *dev)
        smsc911x_reg_write(pdata, INT_EN, 0);
 
        ether_setup(dev);
-       dev->open = smsc911x_open;
-       dev->stop = smsc911x_stop;
-       dev->hard_start_xmit = smsc911x_hard_start_xmit;
-       dev->get_stats = smsc911x_get_stats;
-       dev->set_multicast_list = smsc911x_set_multicast_list;
        dev->flags |= IFF_MULTICAST;
-       dev->do_ioctl = smsc911x_do_ioctl;
        netif_napi_add(dev, &pdata->napi, smsc911x_poll, SMSC_NAPI_WEIGHT);
+       dev->netdev_ops = &smsc911x_netdev_ops;
        dev->ethtool_ops = &smsc911x_ethtool_ops;
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = smsc911x_poll_controller;
-#endif                         /* CONFIG_NET_POLL_CONTROLLER */
-
        return 0;
 }
 
@@ -1872,7 +1874,7 @@ static int __devexit smsc911x_drv_remove(struct platform_device *pdev)
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                                           "smsc911x-memory");
        if (!res)
-               platform_get_resource(pdev, IORESOURCE_MEM, 0);
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
        release_mem_region(res->start, res->end - res->start);
 
index 940220f6092135561ab222ac40270fd53e4dc61e..27e017d969667f474b4c647c23c1fffe42a19bbf 100644 (file)
@@ -666,7 +666,7 @@ static irqreturn_t smsc9420_isr(int irq, void *dev_id)
                        smsc9420_pci_flush_write(pd);
 
                        ints_to_clear |= (DMAC_STS_RX_ | DMAC_STS_NIS_);
-                       netif_rx_schedule(pd->dev, &pd->napi);
+                       netif_rx_schedule(&pd->napi);
                }
 
                if (ints_to_clear)
@@ -889,7 +889,7 @@ static int smsc9420_rx_poll(struct napi_struct *napi, int budget)
        smsc9420_pci_flush_write(pd);
 
        if (work_done < budget) {
-               netif_rx_complete(dev, &pd->napi);
+               netif_rx_complete(&pd->napi);
 
                /* re-enable RX DMA interrupts */
                dma_intr_ena = smsc9420_reg_read(pd, DMAC_INTR_ENA);
index 325fbc9612c96b57e465e07255cda608ed445f40..c5c123d3af57f00b5930d7cf318f1a3444f5dcd5 100644 (file)
@@ -1302,7 +1302,7 @@ static int spider_net_poll(struct napi_struct *napi, int budget)
        /* if all packets are in the stack, enable interrupts and return 0 */
        /* if not, return 1 */
        if (packets_done < budget) {
-               netif_rx_complete(netdev, napi);
+               netif_rx_complete(napi);
                spider_net_rx_irq_on(card);
                card->ignore_rx_ramfull = 0;
        }
@@ -1529,8 +1529,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg,
                        spider_net_refill_rx_chain(card);
                        spider_net_enable_rxdmac(card);
                        card->num_rx_ints ++;
-                       netif_rx_schedule(card->netdev,
-                                         &card->napi);
+                       netif_rx_schedule(&card->napi);
                }
                show_error = 0;
                break;
@@ -1550,8 +1549,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg,
                spider_net_refill_rx_chain(card);
                spider_net_enable_rxdmac(card);
                card->num_rx_ints ++;
-               netif_rx_schedule(card->netdev,
-                                 &card->napi);
+               netif_rx_schedule(&card->napi);
                show_error = 0;
                break;
 
@@ -1565,8 +1563,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg,
                spider_net_refill_rx_chain(card);
                spider_net_enable_rxdmac(card);
                card->num_rx_ints ++;
-               netif_rx_schedule(card->netdev,
-                                 &card->napi);
+               netif_rx_schedule(&card->napi);
                show_error = 0;
                break;
 
@@ -1660,11 +1657,11 @@ spider_net_interrupt(int irq, void *ptr)
 
        if (status_reg & SPIDER_NET_RXINT ) {
                spider_net_rx_irq_off(card);
-               netif_rx_schedule(netdev, &card->napi);
+               netif_rx_schedule(&card->napi);
                card->num_rx_ints ++;
        }
        if (status_reg & SPIDER_NET_TXINT)
-               netif_rx_schedule(netdev, &card->napi);
+               netif_rx_schedule(&card->napi);
 
        if (status_reg & SPIDER_NET_LINKINT)
                spider_net_link_reset(netdev);
index 0358809f409c8d8522d983fd54966b54be78b5ef..1902f4fabde140018ed840bcb501cf6e3bb43ae9 100644 (file)
@@ -1290,8 +1290,8 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
                if (intr_status & (IntrRxDone | IntrRxEmpty)) {
                        u32 enable;
 
-                       if (likely(netif_rx_schedule_prep(dev, &np->napi))) {
-                               __netif_rx_schedule(dev, &np->napi);
+                       if (likely(netif_rx_schedule_prep(&np->napi))) {
+                               __netif_rx_schedule(&np->napi);
                                enable = readl(ioaddr + IntrEnable);
                                enable &= ~(IntrRxDone | IntrRxEmpty);
                                writel(enable, ioaddr + IntrEnable);
@@ -1503,6 +1503,11 @@ static int __netdev_rx(struct net_device *dev, int *quota)
                desc->status = 0;
                np->rx_done = (np->rx_done + 1) % DONE_Q_SIZE;
        }
+
+       if (*quota == 0) {      /* out of rx quota */
+               retcode = 1;
+               goto out;
+       }
        writew(np->rx_done, np->base + CompletionQConsumerIdx);
 
  out:
@@ -1530,7 +1535,7 @@ static int netdev_poll(struct napi_struct *napi, int budget)
                intr_status = readl(ioaddr + IntrStatus);
        } while (intr_status & (IntrRxDone | IntrRxEmpty));
 
-       netif_rx_complete(dev, napi);
+       netif_rx_complete(napi);
        intr_status = readl(ioaddr + IntrEnable);
        intr_status |= IntrRxDone | IntrRxEmpty;
        writel(intr_status, ioaddr + IntrEnable);
index f4b0beec4d1960b4a0318d52a6164f312f711d9c..8a7460412482d5165f24f74c3a13a1c7d4df333a 100644 (file)
@@ -921,7 +921,7 @@ static int gem_poll(struct napi_struct *napi, int budget)
                gp->status = readl(gp->regs + GREG_STAT);
        } while (gp->status & GREG_STAT_NAPI);
 
-       __netif_rx_complete(dev, napi);
+       __netif_rx_complete(napi);
        gem_enable_ints(gp);
 
        spin_unlock_irqrestore(&gp->lock, flags);
@@ -944,7 +944,7 @@ static irqreturn_t gem_interrupt(int irq, void *dev_id)
 
        spin_lock_irqsave(&gp->lock, flags);
 
-       if (netif_rx_schedule_prep(dev, &gp->napi)) {
+       if (netif_rx_schedule_prep(&gp->napi)) {
                u32 gem_status = readl(gp->regs + GREG_STAT);
 
                if (gem_status == 0) {
@@ -954,7 +954,7 @@ static irqreturn_t gem_interrupt(int irq, void *dev_id)
                }
                gp->status = gem_status;
                gem_disable_ints(gp);
-               __netif_rx_schedule(dev, &gp->napi);
+               __netif_rx_schedule(&gp->napi);
        }
 
        spin_unlock_irqrestore(&gp->lock, flags);
index 308f365270e9e6e7e904208011e5afdf82e91b3a..bcd0e60cbda98984c9383f55cc4df671510d33a1 100644 (file)
@@ -1609,8 +1609,8 @@ static irqreturn_t tc35815_interrupt(int irq, void *dev_id)
        if (!(dmactl & DMA_IntMask)) {
                /* disable interrupts */
                tc_writel(dmactl | DMA_IntMask, &tr->DMA_Ctl);
-               if (netif_rx_schedule_prep(dev, &lp->napi))
-                       __netif_rx_schedule(dev, &lp->napi);
+               if (netif_rx_schedule_prep(&lp->napi))
+                       __netif_rx_schedule(&lp->napi);
                else {
                        printk(KERN_ERR "%s: interrupt taken in poll\n",
                               dev->name);
@@ -1919,7 +1919,7 @@ static int tc35815_poll(struct napi_struct *napi, int budget)
        spin_unlock(&lp->lock);
 
        if (received < budget) {
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
                /* enable interrupts */
                tc_writel(tc_readl(&tr->DMA_Ctl) & ~DMA_IntMask, &tr->DMA_Ctl);
        }
index 5b83fbb02013fa57d64a0e290ddba485e84f8a7f..a10a83a11d9fb07a02d10d2f8b1fad1f13c26a71 100644 (file)
@@ -265,8 +265,8 @@ static irqreturn_t bdx_isr_napi(int irq, void *dev)
                bdx_isr_extra(priv, isr);
 
        if (isr & (IR_RX_DESC_0 | IR_TX_FREE_0)) {
-               if (likely(netif_rx_schedule_prep(ndev, &priv->napi))) {
-                       __netif_rx_schedule(ndev, &priv->napi);
+               if (likely(netif_rx_schedule_prep(&priv->napi))) {
+                       __netif_rx_schedule(&priv->napi);
                        RET(IRQ_HANDLED);
                } else {
                        /* NOTE: we get here if intr has slipped into window
@@ -289,7 +289,6 @@ static irqreturn_t bdx_isr_napi(int irq, void *dev)
 static int bdx_poll(struct napi_struct *napi, int budget)
 {
        struct bdx_priv *priv = container_of(napi, struct bdx_priv, napi);
-       struct net_device *dev = priv->ndev;
        int work_done;
 
        ENTER;
@@ -303,7 +302,7 @@ static int bdx_poll(struct napi_struct *napi, int budget)
                 * device lock and allow waiting tasks (eg rmmod) to advance) */
                priv->napi_stop = 0;
 
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
                bdx_enable_interrupts(priv);
        }
        return work_done;
index 06bd2f4eee6c03805c9cda9d9007c49717577838..04ae1e86aeaa4c8b05ad6de192034f43e439420d 100644 (file)
 #define TG3_VLAN_TAG_USED 0
 #endif
 
-#define TG3_TSO_SUPPORT        1
-
 #include "tg3.h"
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.96"
-#define DRV_MODULE_RELDATE     "November 21, 2008"
+#define DRV_MODULE_VERSION     "3.97"
+#define DRV_MODULE_RELDATE     "December 10, 2008"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -2237,7 +2235,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                        }
                }
        } else {
-               do_low_power = false;
+               do_low_power = true;
 
                if (tp->link_config.phy_is_low_power == 0) {
                        tp->link_config.phy_is_low_power = 1;
@@ -4453,7 +4451,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
                        sblk->status &= ~SD_STATUS_UPDATED;
 
                if (likely(!tg3_has_work(tp))) {
-                       netif_rx_complete(tp->dev, napi);
+                       netif_rx_complete(napi);
                        tg3_restart_ints(tp);
                        break;
                }
@@ -4463,7 +4461,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
 
 tx_recovery:
        /* work_done is guaranteed to be less than budget. */
-       netif_rx_complete(tp->dev, napi);
+       netif_rx_complete(napi);
        schedule_work(&tp->reset_task);
        return work_done;
 }
@@ -4512,7 +4510,7 @@ static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
        prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
 
        if (likely(!tg3_irq_sync(tp)))
-               netif_rx_schedule(dev, &tp->napi);
+               netif_rx_schedule(&tp->napi);
 
        return IRQ_HANDLED;
 }
@@ -4537,7 +4535,7 @@ static irqreturn_t tg3_msi(int irq, void *dev_id)
         */
        tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
        if (likely(!tg3_irq_sync(tp)))
-               netif_rx_schedule(dev, &tp->napi);
+               netif_rx_schedule(&tp->napi);
 
        return IRQ_RETVAL(1);
 }
@@ -4579,7 +4577,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
        sblk->status &= ~SD_STATUS_UPDATED;
        if (likely(tg3_has_work(tp))) {
                prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
-               netif_rx_schedule(dev, &tp->napi);
+               netif_rx_schedule(&tp->napi);
        } else {
                /* No work, shared interrupt perhaps?  re-enable
                 * interrupts, and flush that PCI write
@@ -4625,7 +4623,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
        tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
        if (tg3_irq_sync(tp))
                goto out;
-       if (netif_rx_schedule_prep(dev, &tp->napi)) {
+       if (netif_rx_schedule_prep(&tp->napi)) {
                prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
                /* Update last_tag to mark that this status has been
                 * seen. Because interrupt may be shared, we may be
@@ -4633,7 +4631,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
                 * if tg3_poll() is not scheduled.
                 */
                tp->last_tag = sblk->status_tag;
-               __netif_rx_schedule(dev, &tp->napi);
+               __netif_rx_schedule(&tp->napi);
        }
 out:
        return IRQ_RETVAL(handled);
@@ -7518,7 +7516,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST;
 
        if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
-               rdmac_mode |= (1 << 27);
+               rdmac_mode |= RDMAC_MODE_IPV4_LSO_EN;
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+               rdmac_mode |= RDMAC_MODE_IPV6_LSO_EN;
 
        /* Receive/send statistics. */
        if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
@@ -9274,8 +9276,8 @@ static int tg3_set_tso(struct net_device *dev, u32 value)
                        return -EINVAL;
                return 0;
        }
-       if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) &&
-           (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)) {
+       if ((dev->features & NETIF_F_IPV6_CSUM) &&
+           (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2)) {
                if (value) {
                        dev->features |= NETIF_F_TSO6;
                        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
@@ -11544,8 +11546,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                if (val & VCPU_CFGSHDW_ASPM_DBNC)
                        tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND;
                if ((val & VCPU_CFGSHDW_WOL_ENABLE) &&
-                   (val & VCPU_CFGSHDW_WOL_MAGPKT) &&
-                   device_may_wakeup(&tp->pdev->dev))
+                   (val & VCPU_CFGSHDW_WOL_MAGPKT))
                        tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
                goto done;
        }
@@ -12157,7 +12158,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                { },
        };
        u32 misc_ctrl_reg;
-       u32 cacheline_sz_reg;
        u32 pci_state_reg, grc_misc_cfg;
        u32 val;
        u16 pci_cmd;
@@ -12327,14 +12327,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
                               tp->misc_host_ctrl);
 
-       pci_read_config_dword(tp->pdev, TG3PCI_CACHELINESZ,
-                             &cacheline_sz_reg);
-
-       tp->pci_cacheline_sz = (cacheline_sz_reg >>  0) & 0xff;
-       tp->pci_lat_timer    = (cacheline_sz_reg >>  8) & 0xff;
-       tp->pci_hdr_type     = (cacheline_sz_reg >> 16) & 0xff;
-       tp->pci_bist         = (cacheline_sz_reg >> 24) & 0xff;
-
        if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714))
                tp->pdev_peer = tg3_find_peer(tp);
@@ -12359,6 +12351,18 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            (tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
                tp->tg3_flags2 |= TG3_FLG2_5705_PLUS;
 
+       /* 5700 B0 chips do not support checksumming correctly due
+        * to hardware bugs.
+        */
+       if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0)
+               tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS;
+       else {
+               tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
+               tp->dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+               if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
+                       tp->dev->features |= NETIF_F_IPV6_CSUM;
+       }
+
        if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
                tp->tg3_flags |= TG3_FLAG_SUPPORT_MSI;
                if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX ||
@@ -12432,17 +12436,15 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
                tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER;
 
+       pci_read_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
+                            &tp->pci_cacheline_sz);
+       pci_read_config_byte(tp->pdev, PCI_LATENCY_TIMER,
+                            &tp->pci_lat_timer);
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 &&
            tp->pci_lat_timer < 64) {
                tp->pci_lat_timer = 64;
-
-               cacheline_sz_reg  = ((tp->pci_cacheline_sz & 0xff) <<  0);
-               cacheline_sz_reg |= ((tp->pci_lat_timer    & 0xff) <<  8);
-               cacheline_sz_reg |= ((tp->pci_hdr_type     & 0xff) << 16);
-               cacheline_sz_reg |= ((tp->pci_bist         & 0xff) << 24);
-
-               pci_write_config_dword(tp->pdev, TG3PCI_CACHELINESZ,
-                                      cacheline_sz_reg);
+               pci_write_config_byte(tp->pdev, PCI_LATENCY_TIMER,
+                                     tp->pci_lat_timer);
        }
 
        if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX) {
@@ -12615,12 +12617,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                return err;
        }
 
-       /* 5700 B0 chips do not support checksumming correctly due
-        * to hardware bugs.
-        */
-       if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0)
-               tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS;
-
        /* Derive initial jumbo mode from MTU assigned in
         * ether_setup() via the alloc_etherdev() call
         */
@@ -13757,9 +13753,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
         * is off by default, but can be enabled using ethtool.
         */
        if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
-               dev->features |= NETIF_F_TSO;
-               if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) &&
-                   (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906))
+               if (dev->features & NETIF_F_IP_CSUM)
+                       dev->features |= NETIF_F_TSO;
+               if ((dev->features & NETIF_F_IPV6_CSUM) &&
+                   (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2))
                        dev->features |= NETIF_F_TSO6;
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
                    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
@@ -13813,18 +13810,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                goto err_out_apeunmap;
        }
 
-       /* Tigon3 can do ipv4 only... and some chips have buggy
-        * checksumming.
-        */
-       if ((tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) == 0) {
-               dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
-               if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
-                       dev->features |= NETIF_F_IPV6_CSUM;
-
-               tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
-       } else
-               tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
-
        /* flow control autonegotiation is default behavior */
        tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
        tp->link_config.flowctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
index 0880cfacdcba16ce5e033f7c7cd7624610e05d1d..8936edfb0438c992c6cf7ceeb8d6880aa0fa98fe 100644 (file)
 #define  TG3PCI_DEVICE_TIGON3_57760     0x1690
 #define  TG3PCI_DEVICE_TIGON3_57790     0x1694
 #define  TG3PCI_DEVICE_TIGON3_57720     0x168c
-#define TG3PCI_COMMAND                 0x00000004
-#define TG3PCI_STATUS                  0x00000006
-#define TG3PCI_CCREVID                 0x00000008
-#define TG3PCI_CACHELINESZ             0x0000000c
-#define TG3PCI_LATTIMER                        0x0000000d
-#define TG3PCI_HEADERTYPE              0x0000000e
-#define TG3PCI_BIST                    0x0000000f
-#define TG3PCI_BASE0_LOW               0x00000010
-#define TG3PCI_BASE0_HIGH              0x00000014
-/* 0x18 --> 0x2c unused */
-#define TG3PCI_SUBSYSVENID             0x0000002c
-#define TG3PCI_SUBSYSID                        0x0000002e
-#define TG3PCI_ROMADDR                 0x00000030
-#define TG3PCI_CAPLIST                 0x00000034
-/* 0x35 --> 0x3c unused */
-#define TG3PCI_IRQ_LINE                        0x0000003c
-#define TG3PCI_IRQ_PIN                 0x0000003d
-#define TG3PCI_MIN_GNT                 0x0000003e
-#define TG3PCI_MAX_LAT                 0x0000003f
-/* 0x40 --> 0x64 unused */
+/* 0x04 --> 0x64 unused */
 #define TG3PCI_MSI_DATA                        0x00000064
 /* 0x66 --> 0x68 unused */
 #define TG3PCI_MISC_HOST_CTRL          0x00000068
 #define  CHIPREV_ID_5752_A1             0x6001
 #define  CHIPREV_ID_5714_A2             0x9002
 #define  CHIPREV_ID_5906_A1             0xc001
-#define  CHIPREV_ID_5784_A0             0x5784000
-#define  CHIPREV_ID_5784_A1             0x5784001
-#define  CHIPREV_ID_5761_A0             0x5761000
-#define  CHIPREV_ID_5761_A1             0x5761001
 #define  GET_ASIC_REV(CHIP_REV_ID)     ((CHIP_REV_ID) >> 12)
 #define   ASIC_REV_5700                         0x07
 #define   ASIC_REV_5701                         0x00
 #define  RDMAC_MODE_MBUF_SBD_CRPT_ENAB  0x00002000
 #define  RDMAC_MODE_FIFO_SIZE_128       0x00020000
 #define  RDMAC_MODE_FIFO_LONG_BURST     0x00030000
+#define  RDMAC_MODE_IPV4_LSO_EN                 0x08000000
+#define  RDMAC_MODE_IPV6_LSO_EN                 0x10000000
 #define RDMAC_STATUS                   0x00004804
 #define  RDMAC_STATUS_TGTABORT          0x00000004
 #define  RDMAC_STATUS_MSTABORT          0x00000008
 #define MII_TG3_ISTAT                  0x1a /* IRQ status register */
 #define MII_TG3_IMASK                  0x1b /* IRQ mask register */
 
-#define MII_TG3_MISC_SHDW              0x1c
-#define MII_TG3_MISC_SHDW_WREN         0x8000
-#define MII_TG3_MISC_SHDW_APD_SEL      0x2800
-
-#define MII_TG3_MISC_SHDW_APD_WKTM_84MS        0x0001
-
 /* ISTAT/IMASK event bits */
 #define MII_TG3_INT_LINKCHG            0x0002
 #define MII_TG3_INT_SPEEDCHG           0x0004
 
 #define MII_TG3_MISC_SHDW              0x1c
 #define MII_TG3_MISC_SHDW_WREN         0x8000
-#define MII_TG3_MISC_SHDW_SCR5_SEL     0x1400
+
+#define MII_TG3_MISC_SHDW_APD_WKTM_84MS        0x0001
+#define MII_TG3_MISC_SHDW_APD_ENABLE   0x0020
 #define MII_TG3_MISC_SHDW_APD_SEL      0x2800
 
 #define MII_TG3_MISC_SHDW_SCR5_C125OE  0x0001
 #define MII_TG3_MISC_SHDW_SCR5_SDTL    0x0004
 #define MII_TG3_MISC_SHDW_SCR5_DLPTLM  0x0008
 #define MII_TG3_MISC_SHDW_SCR5_LPED    0x0010
+#define MII_TG3_MISC_SHDW_SCR5_SEL     0x1400
 
-#define MII_TG3_MISC_SHDW_APD_WKTM_84MS        0x0001
-#define MII_TG3_MISC_SHDW_APD_ENABLE   0x0020
 
 #define MII_TG3_EPHY_TEST              0x1f /* 5906 PHY register */
 #define MII_TG3_EPHY_SHADOW_EN         0x80
@@ -2674,10 +2648,9 @@ struct tg3 {
 
        /* PCI block */
        u32                             pci_chip_rev_id;
+       u16                             pci_cmd;
        u8                              pci_cacheline_sz;
        u8                              pci_lat_timer;
-       u8                              pci_hdr_type;
-       u8                              pci_bist;
 
        int                             pm_cap;
        int                             msi_cap;
@@ -2728,7 +2701,6 @@ struct tg3 {
 
        u32                             led_ctrl;
        u32                             phy_otp;
-       u16                             pci_cmd;
 
        char                            board_part_number[24];
 #define TG3_VER_SIZE 32
index 271bc230c8a9145ee9b24a302cc7a902d4216d62..75461dbd487657bd8e6a8002499db7c54fe2d774 100644 (file)
@@ -888,7 +888,7 @@ static int tsi108_poll(struct napi_struct *napi, int budget)
 
        if (num_received < budget) {
                data->rxpending = 0;
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
 
                TSI_WRITE(TSI108_EC_INTMASK,
                                     TSI_READ(TSI108_EC_INTMASK)
@@ -919,7 +919,7 @@ static void tsi108_rx_int(struct net_device *dev)
         * from tsi108_check_rxring().
         */
 
-       if (netif_rx_schedule_prep(dev, &data->napi)) {
+       if (netif_rx_schedule_prep(&data->napi)) {
                /* Mask, rather than ack, the receive interrupts.  The ack
                 * will happen in tsi108_poll().
                 */
@@ -930,7 +930,7 @@ static void tsi108_rx_int(struct net_device *dev)
                                     | TSI108_INT_RXTHRESH |
                                     TSI108_INT_RXOVERRUN | TSI108_INT_RXERROR |
                                     TSI108_INT_RXWAIT);
-               __netif_rx_schedule(dev, &data->napi);
+               __netif_rx_schedule(&data->napi);
        } else {
                if (!netif_running(dev)) {
                        /* This can happen if an interrupt occurs while the
index 739d610d18c5e6ab7958e52e545405a12b1babe3..6c3428a37c0b9d5c672e777b052a199710d01c97 100644 (file)
@@ -103,7 +103,7 @@ void oom_timer(unsigned long data)
 {
         struct net_device *dev = (struct net_device *)data;
        struct tulip_private *tp = netdev_priv(dev);
-       netif_rx_schedule(dev, &tp->napi);
+       netif_rx_schedule(&tp->napi);
 }
 
 int tulip_poll(struct napi_struct *napi, int budget)
@@ -300,7 +300,7 @@ int tulip_poll(struct napi_struct *napi, int budget)
 
          /* Remove us from polling list and enable RX intr. */
 
-         netif_rx_complete(dev, napi);
+         netif_rx_complete(napi);
          iowrite32(tulip_tbl[tp->chip_id].valid_intrs, tp->base_addr+CSR7);
 
          /* The last op happens after poll completion. Which means the following:
@@ -336,7 +336,7 @@ int tulip_poll(struct napi_struct *napi, int budget)
           * before we did netif_rx_complete(). See? We would lose it. */
 
          /* remove ourselves from the polling list */
-         netif_rx_complete(dev, napi);
+         netif_rx_complete(napi);
 
          return work_done;
 }
@@ -519,7 +519,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
                        rxd++;
                        /* Mask RX intrs and add the device to poll list. */
                        iowrite32(tulip_tbl[tp->chip_id].valid_intrs&~RxPollInt, ioaddr + CSR7);
-                       netif_rx_schedule(dev, &tp->napi);
+                       netif_rx_schedule(&tp->napi);
 
                        if (!(csr5&~(AbnormalIntr|NormalIntr|RxPollInt|TPLnkPass)))
                                break;
index 5386d9b73e6aa78798138e703c9fc520dcea0cbf..0009f4e34433ee9f9130ca2c1a8122df612f07b7 100644 (file)
@@ -1755,7 +1755,6 @@ static int
 typhoon_poll(struct napi_struct *napi, int budget)
 {
        struct typhoon *tp = container_of(napi, struct typhoon, napi);
-       struct net_device *dev = tp->dev;
        struct typhoon_indexes *indexes = tp->indexes;
        int work_done;
 
@@ -1784,7 +1783,7 @@ typhoon_poll(struct napi_struct *napi, int budget)
        }
 
        if (work_done < budget) {
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
                iowrite32(TYPHOON_INTR_NONE,
                                tp->ioaddr + TYPHOON_REG_INTR_MASK);
                typhoon_post_pci_writes(tp->ioaddr);
@@ -1807,10 +1806,10 @@ typhoon_interrupt(int irq, void *dev_instance)
 
        iowrite32(intr_status, ioaddr + TYPHOON_REG_INTR_STATUS);
 
-       if (netif_rx_schedule_prep(dev, &tp->napi)) {
+       if (netif_rx_schedule_prep(&tp->napi)) {
                iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK);
                typhoon_post_pci_writes(ioaddr);
-               __netif_rx_schedule(dev, &tp->napi);
+               __netif_rx_schedule(&tp->napi);
        } else {
                printk(KERN_ERR "%s: Error, poll already scheduled\n",
                        dev->name);
index 5c82f147f151bf1bec6870b955d7b0aa64891059..78a2ede19c5e3ebb8eba25e98ad3e654c616d6a8 100644 (file)
@@ -3330,7 +3330,7 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget)
                struct ucc_fast_private *uccf;
                u32 uccm;
 
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
                uccf = ugeth->uccf;
                uccm = in_be32(uccf->p_uccm);
                uccm |= UCCE_RX_EVENTS;
@@ -3364,10 +3364,10 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
 
        /* check for receive events that require processing */
        if (ucce & UCCE_RX_EVENTS) {
-               if (netif_rx_schedule_prep(dev, &ugeth->napi)) {
+               if (netif_rx_schedule_prep(&ugeth->napi)) {
                        uccm &= ~UCCE_RX_EVENTS;
                        out_be32(uccf->p_uccm, uccm);
-                       __netif_rx_schedule(dev, &ugeth->napi);
+                       __netif_rx_schedule(&ugeth->napi);
                }
        }
 
index de57490103fcd05e58a8610d7fb77b3dbc0ffc20..e009481c606c740cea0b2a30fd7bad7f30f3fe8d 100644 (file)
@@ -246,10 +246,11 @@ out:
 static void asix_async_cmd_callback(struct urb *urb)
 {
        struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
+       int status = urb->status;
 
-       if (urb->status < 0)
+       if (status < 0)
                printk(KERN_DEBUG "asix_async_cmd_callback() failed with %d",
-                       urb->status);
+                       status);
 
        kfree(req);
        usb_free_urb(urb);
index d7621239059a52bab6de340941f625868bfd50b1..cb7acbbb279875893a1fa3f398a8fe5eaa5fe22e 100644 (file)
@@ -229,14 +229,15 @@ static void catc_rx_done(struct urb *urb)
        u8 *pkt_start = urb->transfer_buffer;
        struct sk_buff *skb;
        int pkt_len, pkt_offset = 0;
+       int status = urb->status;
 
        if (!catc->is_f5u011) {
                clear_bit(RX_RUNNING, &catc->flags);
                pkt_offset = 2;
        }
 
-       if (urb->status) {
-               dbg("rx_done, status %d, length %d", urb->status, urb->actual_length);
+       if (status) {
+               dbg("rx_done, status %d, length %d", status, urb->actual_length);
                return;
        }
 
@@ -273,12 +274,12 @@ static void catc_rx_done(struct urb *urb)
 
        if (catc->is_f5u011) {
                if (atomic_read(&catc->recq_sz)) {
-                       int status;
+                       int state;
                        atomic_dec(&catc->recq_sz);
                        dbg("getting extra packet");
                        urb->dev = catc->usbdev;
-                       if ((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
-                               dbg("submit(rx_urb) status %d", status);
+                       if ((state = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
+                               dbg("submit(rx_urb) status %d", state);
                        }
                } else {
                        clear_bit(RX_RUNNING, &catc->flags);
@@ -290,8 +291,9 @@ static void catc_irq_done(struct urb *urb)
 {
        struct catc *catc = urb->context;
        u8 *data = urb->transfer_buffer;
-       int status;
+       int status = urb->status;
        unsigned int hasdata = 0, linksts = LinkNoChange;
+       int res;
 
        if (!catc->is_f5u011) {
                hasdata = data[1] & 0x80;
@@ -307,7 +309,7 @@ static void catc_irq_done(struct urb *urb)
                        linksts = LinkBad;
        }
 
-       switch (urb->status) {
+       switch (status) {
        case 0:                 /* success */
                break;
        case -ECONNRESET:       /* unlink */
@@ -316,7 +318,7 @@ static void catc_irq_done(struct urb *urb)
                return;
        /* -EPIPE:  should clear the halt */
        default:                /* error */
-               dbg("irq_done, status %d, data %02x %02x.", urb->status, data[0], data[1]);
+               dbg("irq_done, status %d, data %02x %02x.", status, data[0], data[1]);
                goto resubmit;
        }
 
@@ -336,17 +338,17 @@ static void catc_irq_done(struct urb *urb)
                                atomic_inc(&catc->recq_sz);
                } else {
                        catc->rx_urb->dev = catc->usbdev;
-                       if ((status = usb_submit_urb(catc->rx_urb, GFP_ATOMIC)) < 0) {
-                               err("submit(rx_urb) status %d", status);
+                       if ((res = usb_submit_urb(catc->rx_urb, GFP_ATOMIC)) < 0) {
+                               err("submit(rx_urb) status %d", res);
                        }
                } 
        }
 resubmit:
-       status = usb_submit_urb (urb, GFP_ATOMIC);
-       if (status)
+       res = usb_submit_urb (urb, GFP_ATOMIC);
+       if (res)
                err ("can't resubmit intr, %s-%s, status %d",
                                catc->usbdev->bus->bus_name,
-                               catc->usbdev->devpath, status);
+                               catc->usbdev->devpath, res);
 }
 
 /*
@@ -378,9 +380,9 @@ static void catc_tx_done(struct urb *urb)
 {
        struct catc *catc = urb->context;
        unsigned long flags;
-       int r;
+       int r, status = urb->status;
 
-       if (urb->status == -ECONNRESET) {
+       if (status == -ECONNRESET) {
                dbg("Tx Reset.");
                urb->status = 0;
                catc->netdev->trans_start = jiffies;
@@ -390,8 +392,8 @@ static void catc_tx_done(struct urb *urb)
                return;
        }
 
-       if (urb->status) {
-               dbg("tx_done, status %d, length %d", urb->status, urb->actual_length);
+       if (status) {
+               dbg("tx_done, status %d, length %d", status, urb->actual_length);
                return;
        }
 
@@ -502,9 +504,10 @@ static void catc_ctrl_done(struct urb *urb)
        struct catc *catc = urb->context;
        struct ctrl_queue *q;
        unsigned long flags;
+       int status = urb->status;
 
-       if (urb->status)
-               dbg("ctrl_done, status %d, len %d.", urb->status, urb->actual_length);
+       if (status)
+               dbg("ctrl_done, status %d, len %d.", status, urb->actual_length);
 
        spin_lock_irqsave(&catc->ctrl_lock, flags);
 
index db3377dae9d5f99156cf569008ca8795dc598fed..edd244f3acb50488c031863997101ff41469c797 100644 (file)
@@ -123,10 +123,11 @@ static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value)
 static void dm_write_async_callback(struct urb *urb)
 {
        struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
+       int status = urb->status;
 
-       if (urb->status < 0)
+       if (status < 0)
                printk(KERN_DEBUG "dm_write_async_callback() failed with %d\n",
-                      urb->status);
+                      status);
 
        kfree(req);
        usb_free_urb(urb);
index c5c1aeae94fed2d90e905f2988d10a67880972c5..198ce3cf378ae2b884ce16b21a5fa1ba7a028d5c 100644 (file)
@@ -663,10 +663,9 @@ static int hso_net_open(struct net_device *net)
        odev->rx_buf_missing = sizeof(struct iphdr);
        spin_unlock_irqrestore(&odev->net_lock, flags);
 
-       hso_start_net_device(odev->parent);
-
        /* We are up and running. */
        set_bit(HSO_NET_RUNNING, &odev->flags);
+       hso_start_net_device(odev->parent);
 
        /* Tell the kernel we are ready to start receiving from it */
        netif_start_queue(net);
index fdbf3be24fda499e5065b7b3c691ade64f56397e..2ee034f70d1c61a1cfd0cbb799f02485ce654bdc 100644 (file)
@@ -516,8 +516,9 @@ static void int_callback(struct urb *u)
 {
        struct kaweth_device *kaweth = u->context;
        int act_state;
+       int status = u->status;
 
-       switch (u->status) {
+       switch (status) {
        case 0:                 /* success */
                break;
        case -ECONNRESET:       /* unlink */
@@ -598,6 +599,7 @@ static void kaweth_usb_receive(struct urb *urb)
 {
        struct kaweth_device *kaweth = urb->context;
        struct net_device *net = kaweth->net;
+       int status = urb->status;
 
        int count = urb->actual_length;
        int count2 = urb->transfer_buffer_length;
@@ -606,7 +608,7 @@ static void kaweth_usb_receive(struct urb *urb)
 
        struct sk_buff *skb;
 
-       if(unlikely(urb->status == -ECONNRESET || urb->status == -ESHUTDOWN))
+       if(unlikely(status == -ECONNRESET || status == -ESHUTDOWN))
        /* we are killed - set a flag and wake the disconnect handler */
        {
                kaweth->end = 1;
@@ -621,10 +623,10 @@ static void kaweth_usb_receive(struct urb *urb)
        }
        spin_unlock(&kaweth->device_lock);
 
-       if(urb->status && urb->status != -EREMOTEIO && count != 1) {
+       if(status && status != -EREMOTEIO && count != 1) {
                err("%s RX status: %d count: %d packet_len: %d",
                            net->name,
-                          urb->status,
+                          status,
                           count,
                           (int)pkt_len);
                kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
@@ -775,10 +777,11 @@ static void kaweth_usb_transmit_complete(struct urb *urb)
 {
        struct kaweth_device *kaweth = urb->context;
        struct sk_buff *skb = kaweth->tx_skb;
+       int status = urb->status;
 
-       if (unlikely(urb->status != 0))
-               if (urb->status != -ENOENT)
-                       dbg("%s: TX status %d.", kaweth->net->name, urb->status);
+       if (unlikely(status != 0))
+               if (status != -ENOENT)
+                       dbg("%s: TX status %d.", kaweth->net->name, status);
 
        netif_wake_queue(kaweth->net);
        dev_kfree_skb_irq(skb);
index bbcc76ae3c9cde15298c9079ef7542d82c9a89b8..5385d66b306ebd284ac973e87a9209b4b7aa89ff 100644 (file)
@@ -115,10 +115,11 @@ static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, void *data)
 static void mcs7830_async_cmd_callback(struct urb *urb)
 {
        struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
+       int status = urb->status;
 
-       if (urb->status < 0)
+       if (status < 0)
                printk(KERN_DEBUG "%s() failed with %d\n",
-                      __func__, urb->status);
+                      __func__, status);
 
        kfree(req);
        usb_free_urb(urb);
index 075e8e94225e29aae6f4ed9a0c13bcc358392d31..166880c113d6718ad00b87f75f0b84caa93867b3 100644 (file)
@@ -99,11 +99,12 @@ static int update_eth_regs_async(pegasus_t *);
 static void ctrl_callback(struct urb *urb)
 {
        pegasus_t *pegasus = urb->context;
+       int status = urb->status;
 
        if (!pegasus)
                return;
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                if (pegasus->flags & ETH_REGS_CHANGE) {
                        pegasus->flags &= ~ETH_REGS_CHANGE;
@@ -119,7 +120,7 @@ static void ctrl_callback(struct urb *urb)
        default:
                if (netif_msg_drv(pegasus) && printk_ratelimit())
                        dev_dbg(&pegasus->intf->dev, "%s, status %d\n",
-                               __func__, urb->status);
+                               __func__, status);
        }
        pegasus->flags &= ~ETH_REGS_CHANGED;
        wake_up(&pegasus->ctrl_wait);
@@ -611,6 +612,7 @@ static void read_bulk_callback(struct urb *urb)
        pegasus_t *pegasus = urb->context;
        struct net_device *net;
        int rx_status, count = urb->actual_length;
+       int status = urb->status;
        u8 *buf = urb->transfer_buffer;
        __u16 pkt_len;
 
@@ -621,7 +623,7 @@ static void read_bulk_callback(struct urb *urb)
        if (!netif_device_present(net) || !netif_running(net))
                return;
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                break;
        case -ETIME:
@@ -639,11 +641,11 @@ static void read_bulk_callback(struct urb *urb)
        case -ECONNRESET:
        case -ESHUTDOWN:
                if (netif_msg_ifdown(pegasus))
-                       pr_debug("%s: rx unlink, %d\n", net->name, urb->status);
+                       pr_debug("%s: rx unlink, %d\n", net->name, status);
                return;
        default:
                if (netif_msg_rx_err(pegasus))
-                       pr_debug("%s: RX status %d\n", net->name, urb->status);
+                       pr_debug("%s: RX status %d\n", net->name, status);
                goto goon;
        }
 
@@ -769,6 +771,7 @@ static void write_bulk_callback(struct urb *urb)
 {
        pegasus_t *pegasus = urb->context;
        struct net_device *net;
+       int status = urb->status;
 
        if (!pegasus)
                return;
@@ -778,7 +781,7 @@ static void write_bulk_callback(struct urb *urb)
        if (!netif_device_present(net) || !netif_running(net))
                return;
 
-       switch (urb->status) {
+       switch (status) {
        case -EPIPE:
                /* FIXME schedule_work() to clear the tx halt */
                netif_stop_queue(net);
@@ -790,11 +793,11 @@ static void write_bulk_callback(struct urb *urb)
        case -ECONNRESET:
        case -ESHUTDOWN:
                if (netif_msg_ifdown(pegasus))
-                       pr_debug("%s: tx unlink, %d\n", net->name, urb->status);
+                       pr_debug("%s: tx unlink, %d\n", net->name, status);
                return;
        default:
                if (netif_msg_tx_err(pegasus))
-                       pr_info("%s: TX status %d\n", net->name, urb->status);
+                       pr_info("%s: TX status %d\n", net->name, status);
                /* FALL THROUGH */
        case 0:
                break;
@@ -808,13 +811,13 @@ static void intr_callback(struct urb *urb)
 {
        pegasus_t *pegasus = urb->context;
        struct net_device *net;
-       int status;
+       int res, status = urb->status;
 
        if (!pegasus)
                return;
        net = pegasus->net;
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                break;
        case -ECONNRESET:       /* unlink */
@@ -827,7 +830,7 @@ static void intr_callback(struct urb *urb)
                 */
                if (netif_msg_timer(pegasus))
                        pr_debug("%s: intr status %d\n", net->name,
-                                       urb->status);
+                                       status);
        }
 
        if (urb->actual_length >= 6) {
@@ -854,12 +857,12 @@ static void intr_callback(struct urb *urb)
                pegasus->stats.rx_missed_errors += ((d[3] & 0x7f) << 8) | d[4];
        }
 
-       status = usb_submit_urb(urb, GFP_ATOMIC);
-       if (status == -ENODEV)
+       res = usb_submit_urb(urb, GFP_ATOMIC);
+       if (res == -ENODEV)
                netif_device_detach(pegasus->net);
-       if (status && netif_msg_timer(pegasus))
+       if (res && netif_msg_timer(pegasus))
                printk(KERN_ERR "%s: can't resubmit interrupt urb, %d\n",
-                               net->name, status);
+                               net->name, res);
 }
 
 static void pegasus_tx_timeout(struct net_device *net)
index 6133401ebc67c258aff5ca98f51a40cf9219f488..d8664bf18c0000bd77a93426d39a10e0f48b6589 100644 (file)
@@ -212,8 +212,9 @@ static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
 static void ctrl_callback(struct urb *urb)
 {
        rtl8150_t *dev;
+       int status = urb->status;
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                break;
        case -EINPROGRESS:
@@ -221,7 +222,7 @@ static void ctrl_callback(struct urb *urb)
        case -ENOENT:
                break;
        default:
-               dev_warn(&urb->dev->dev, "ctrl urb status %d\n", urb->status);
+               dev_warn(&urb->dev->dev, "ctrl urb status %d\n", status);
        }
        dev = urb->context;
        clear_bit(RX_REG_SET, &dev->flags);
@@ -424,7 +425,8 @@ static void read_bulk_callback(struct urb *urb)
        struct sk_buff *skb;
        struct net_device *netdev;
        u16 rx_stat;
-       int status;
+       int status = urb->status;
+       int result;
 
        dev = urb->context;
        if (!dev)
@@ -435,7 +437,7 @@ static void read_bulk_callback(struct urb *urb)
        if (!netif_device_present(netdev))
                return;
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                break;
        case -ENOENT:
@@ -444,7 +446,7 @@ static void read_bulk_callback(struct urb *urb)
                dev_warn(&urb->dev->dev, "may be reset is needed?..\n");
                goto goon;
        default:
-               dev_warn(&urb->dev->dev, "Rx status %d\n", urb->status);
+               dev_warn(&urb->dev->dev, "Rx status %d\n", status);
                goto goon;
        }
 
@@ -474,10 +476,10 @@ static void read_bulk_callback(struct urb *urb)
 goon:
        usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
                      dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
-       status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC);
-       if (status == -ENODEV)
+       result = usb_submit_urb(dev->rx_urb, GFP_ATOMIC);
+       if (result == -ENODEV)
                netif_device_detach(dev->netdev);
-       else if (status) {
+       else if (result) {
                set_bit(RX_URB_FAIL, &dev->flags);
                goto resched;
        } else {
@@ -530,6 +532,7 @@ tlsched:
 static void write_bulk_callback(struct urb *urb)
 {
        rtl8150_t *dev;
+       int status = urb->status;
 
        dev = urb->context;
        if (!dev)
@@ -537,9 +540,9 @@ static void write_bulk_callback(struct urb *urb)
        dev_kfree_skb_irq(dev->tx_skb);
        if (!netif_device_present(dev->netdev))
                return;
-       if (urb->status)
+       if (status)
                dev_info(&urb->dev->dev, "%s: Tx status %d\n",
-                        dev->netdev->name, urb->status);
+                        dev->netdev->name, status);
        dev->netdev->trans_start = jiffies;
        netif_wake_queue(dev->netdev);
 }
@@ -548,12 +551,13 @@ static void intr_callback(struct urb *urb)
 {
        rtl8150_t *dev;
        __u8 *d;
-       int status;
+       int status = urb->status;
+       int res;
 
        dev = urb->context;
        if (!dev)
                return;
-       switch (urb->status) {
+       switch (status) {
        case 0:                 /* success */
                break;
        case -ECONNRESET:       /* unlink */
@@ -563,7 +567,7 @@ static void intr_callback(struct urb *urb)
        /* -EPIPE:  should clear the halt */
        default:
                dev_info(&urb->dev->dev, "%s: intr status %d\n",
-                        dev->netdev->name, urb->status);
+                        dev->netdev->name, status);
                goto resubmit;
        }
 
@@ -591,13 +595,13 @@ static void intr_callback(struct urb *urb)
        }
 
 resubmit:
-       status = usb_submit_urb (urb, GFP_ATOMIC);
-       if (status == -ENODEV)
+       res = usb_submit_urb (urb, GFP_ATOMIC);
+       if (res == -ENODEV)
                netif_device_detach(dev->netdev);
-       else if (status)
+       else if (res)
                err ("can't resubmit intr, %s-%s/input0, status %d",
                                dev->udev->bus->bus_name,
-                               dev->udev->devpath, status);
+                               dev->udev->devpath, res);
 }
 
 static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message)
index fed22ffedd574c9fd53ce6e211a4846952907c41..5574abe29c73b64c63d0e123e132f3afb762e7f3 100644 (file)
@@ -311,9 +311,10 @@ static void smsc95xx_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
 {
        struct usb_context *usb_context = urb->context;
        struct usbnet *dev = usb_context->dev;
+       int status = urb->status;
 
-       if (urb->status < 0)
-               devwarn(dev, "async callback failed with %d", urb->status);
+       if (status < 0)
+               devwarn(dev, "async callback failed with %d", status);
 
        complete(&usb_context->notify);
 
index 8d405c83df8b8b882e2df8294e3567d8083269ca..ac07cc6e3cb214eb7a56336205836e0b50bdfb1c 100644 (file)
@@ -589,7 +589,7 @@ static int rhine_napipoll(struct napi_struct *napi, int budget)
        work_done = rhine_rx(dev, budget);
 
        if (work_done < budget) {
-               netif_rx_complete(dev, napi);
+               netif_rx_complete(napi);
 
                iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow |
                          IntrRxDropped | IntrRxNoBuf | IntrTxAborted |
@@ -1318,7 +1318,7 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance)
                                  IntrPCIErr | IntrStatsMax | IntrLinkChange,
                                  ioaddr + IntrEnable);
 
-                       netif_rx_schedule(dev, &rp->napi);
+                       netif_rx_schedule(&rp->napi);
                }
 
                if (intr_status & (IntrTxErrSummary | IntrTxDone)) {
index 71ca29cc184d84e4c4fdd0cbbda8656c3da6801a..b7004ff36451764278e47eac267ffb4cd6bcd4bf 100644 (file)
@@ -374,9 +374,9 @@ static void skb_recv_done(struct virtqueue *rvq)
 {
        struct virtnet_info *vi = rvq->vdev->priv;
        /* Schedule NAPI, Suppress further interrupts if successful. */
-       if (netif_rx_schedule_prep(vi->dev, &vi->napi)) {
+       if (netif_rx_schedule_prep(&vi->napi)) {
                rvq->vq_ops->disable_cb(rvq);
-               __netif_rx_schedule(vi->dev, &vi->napi);
+               __netif_rx_schedule(&vi->napi);
        }
 }
 
@@ -402,11 +402,11 @@ again:
 
        /* Out of packets? */
        if (received < budget) {
-               netif_rx_complete(vi->dev, napi);
+               netif_rx_complete(napi);
                if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq))
                    && napi_schedule_prep(napi)) {
                        vi->rvq->vq_ops->disable_cb(vi->rvq);
-                       __netif_rx_schedule(vi->dev, napi);
+                       __netif_rx_schedule(napi);
                        goto again;
                }
        }
@@ -580,9 +580,9 @@ static int virtnet_open(struct net_device *dev)
         * won't get another interrupt, so process any outstanding packets
         * now.  virtnet_poll wants re-enable the queue, so we disable here.
         * We synchronize against interrupts via NAPI_STATE_SCHED */
-       if (netif_rx_schedule_prep(dev, &vi->napi)) {
+       if (netif_rx_schedule_prep(&vi->napi)) {
                vi->rvq->vq_ops->disable_cb(vi->rvq);
-               __netif_rx_schedule(dev, &vi->napi);
+               __netif_rx_schedule(&vi->napi);
        }
        return 0;
 }
index 0bcc0b5f22d7ef06b9890a0eb9a53ef65ba7cce4..08b3536944fe034544c74dc2470d7745393b89aa 100644 (file)
@@ -341,7 +341,7 @@ static int sca_poll(struct napi_struct *napi, int budget)
                received = sca_rx_done(port, budget);
 
        if (received < budget) {
-               netif_rx_complete(port->netdev, napi);
+               netif_rx_complete(napi);
                enable_intr(port);
        }
 
@@ -359,7 +359,7 @@ static irqreturn_t sca_intr(int irq, void *dev_id)
                if (port && (isr0 & (i ? 0x08002200 : 0x00080022))) {
                        handled = 1;
                        disable_intr(port);
-                       netif_rx_schedule(port->netdev, &port->napi);
+                       netif_rx_schedule(&port->napi);
                }
        }
 
index 13df1191b070095a763cbf3abf420483e1cfae0e..183ffc8e62cadc4b6b78c339d7a8ec0c4febf481 100644 (file)
@@ -1350,4 +1350,9 @@ static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
        return retval;
 }
 
+static inline int ath5k_pad_size(int hdrlen)
+{
+       return (hdrlen < 24) ? 0 : hdrlen & 3;
+}
+
 #endif
index 0e4317010ed079c816b2e7969d6ca124021bd418..4af2607deec09ad9582e2aa488723b461daf8416 100644 (file)
@@ -1668,7 +1668,7 @@ ath5k_tasklet_rx(unsigned long data)
        struct ath5k_desc *ds;
        int ret;
        int hdrlen;
-       int pad;
+       int padsize;
 
        spin_lock(&sc->rxbuflock);
        if (list_empty(&sc->rxbuf)) {
@@ -1753,16 +1753,19 @@ accept:
 
                skb_put(skb, rs.rs_datalen);
 
-               /*
-                * the hardware adds a padding to 4 byte boundaries between
-                * the header and the payload data if the header length is
-                * not multiples of 4 - remove it
-                */
+               /* The MAC header is padded to have 32-bit boundary if the
+                * packet payload is non-zero. The general calculation for
+                * padsize would take into account odd header lengths:
+                * padsize = (4 - hdrlen % 4) % 4; However, since only
+                * even-length headers are used, padding can only be 0 or 2
+                * bytes and we can optimize this a bit. In addition, we must
+                * not try to remove padding from short control frames that do
+                * not have payload. */
                hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-               if (hdrlen & 3) {
-                       pad = hdrlen % 4;
-                       memmove(skb->data + pad, skb->data, hdrlen);
-                       skb_pull(skb, pad);
+               padsize = ath5k_pad_size(hdrlen);
+               if (padsize) {
+                       memmove(skb->data + padsize, skb->data, hdrlen);
+                       skb_pull(skb, padsize);
                }
 
                /*
@@ -2623,7 +2626,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        struct ath5k_buf *bf;
        unsigned long flags;
        int hdrlen;
-       int pad;
+       int padsize;
 
        ath5k_debug_dump_skb(sc, skb, "TX  ", 1);
 
@@ -2635,15 +2638,16 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
         * if this is not the case we add the padding after the header
         */
        hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-       if (hdrlen & 3) {
-               pad = hdrlen % 4;
-               if (skb_headroom(skb) < pad) {
+       padsize = ath5k_pad_size(hdrlen);
+       if (padsize) {
+
+               if (skb_headroom(skb) < padsize) {
                        ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough"
-                               " headroom to pad %d\n", hdrlen, pad);
+                                 " headroom to pad %d\n", hdrlen, padsize);
                        return -1;
                }
-               skb_push(skb, pad);
-               memmove(skb->data, skb->data+pad, hdrlen);
+               skb_push(skb, padsize);
+               memmove(skb->data, skb->data+padsize, hdrlen);
        }
 
        spin_lock_irqsave(&sc->txbuflock, flags);
index 5e362a7a362007aec0c8bf6800de1d97a587166d..b40a9287a39a8a3be2fd8888c2f5dd8fde484511 100644 (file)
@@ -71,7 +71,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
        /* Verify and set frame length */
 
        /* remove padding we might have added before */
-       frame_len = pkt_len - (hdr_len & 3) + FCS_LEN;
+       frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN;
 
        if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
                return -EINVAL;
@@ -202,7 +202,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
        /* Verify and set frame length */
 
        /* remove padding we might have added before */
-       frame_len = pkt_len - (hdr_len & 3) + FCS_LEN;
+       frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN;
 
        if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
                return -EINVAL;
index e38f0331cfd5e335c7707fb6e256287f331871d8..4ca2aed236e090d081e6649f019cf81da86273c0 100644 (file)
@@ -701,6 +701,7 @@ struct ath_softc {
        struct ath_hal *sc_ah;
        void __iomem *mem;
        spinlock_t sc_resetlock;
+       struct mutex mutex;
 
        u8 sc_curbssid[ETH_ALEN];
        u8 sc_myaddr[ETH_ALEN];
index 02e1771bb274d9150b462ba05669f2ab3fa6670e..191eec50dc751c1fff9142f76d7960a5eb4c23db 100644 (file)
@@ -61,8 +61,7 @@ static void bus_read_cachesize(struct ath_softc *sc, int *csz)
 
 static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
 {
-       if (!sc->sc_curaid)
-               sc->cur_rate_table = sc->hw_rate_table[mode];
+       sc->cur_rate_table = sc->hw_rate_table[mode];
        /*
         * All protection frames are transmited at 2Mb/s for
         * 11g, otherwise at 1Mb/s.
@@ -623,37 +622,40 @@ static int ath_get_channel(struct ath_softc *sc,
        return -1;
 }
 
-/* ext_chan_offset: (-1, 0, 1) (below, none, above) */
-
 static u32 ath_get_extchanmode(struct ath_softc *sc,
                               struct ieee80211_channel *chan,
-                              int ext_chan_offset,
-                              enum ath9k_ht_macmode tx_chan_width)
+                              enum nl80211_channel_type channel_type)
 {
        u32 chanmode = 0;
 
        switch (chan->band) {
        case IEEE80211_BAND_2GHZ:
-               if ((ext_chan_offset == 0) &&
-                   (tx_chan_width == ATH9K_HT_MACMODE_20))
+               switch(channel_type) {
+               case NL80211_CHAN_NO_HT:
+               case NL80211_CHAN_HT20:
                        chanmode = CHANNEL_G_HT20;
-               if ((ext_chan_offset == 1) &&
-                   (tx_chan_width == ATH9K_HT_MACMODE_2040))
+                       break;
+               case NL80211_CHAN_HT40PLUS:
                        chanmode = CHANNEL_G_HT40PLUS;
-               if ((ext_chan_offset == -1) &&
-                   (tx_chan_width == ATH9K_HT_MACMODE_2040))
+                       break;
+               case NL80211_CHAN_HT40MINUS:
                        chanmode = CHANNEL_G_HT40MINUS;
+                       break;
+               }
                break;
        case IEEE80211_BAND_5GHZ:
-               if ((ext_chan_offset == 0) &&
-                   (tx_chan_width == ATH9K_HT_MACMODE_20))
+               switch(channel_type) {
+               case NL80211_CHAN_NO_HT:
+               case NL80211_CHAN_HT20:
                        chanmode = CHANNEL_A_HT20;
-               if ((ext_chan_offset == 1) &&
-                   (tx_chan_width == ATH9K_HT_MACMODE_2040))
+                       break;
+               case NL80211_CHAN_HT40PLUS:
                        chanmode = CHANNEL_A_HT40PLUS;
-               if ((ext_chan_offset == -1) &&
-                   (tx_chan_width == ATH9K_HT_MACMODE_2040))
+                       break;
+               case NL80211_CHAN_HT40MINUS:
                        chanmode = CHANNEL_A_HT40MINUS;
+                       break;
+               }
                break;
        default:
                break;
@@ -662,13 +664,6 @@ static u32 ath_get_extchanmode(struct ath_softc *sc,
        return chanmode;
 }
 
-static void ath_key_reset(struct ath_softc *sc, u16 keyix, int freeslot)
-{
-       ath9k_hw_keyreset(sc->sc_ah, keyix);
-       if (freeslot)
-               clear_bit(keyix, sc->sc_keymap);
-}
-
 static int ath_keyset(struct ath_softc *sc, u16 keyix,
               struct ath9k_keyval *hk, const u8 mac[ETH_ALEN])
 {
@@ -680,21 +675,20 @@ static int ath_keyset(struct ath_softc *sc, u16 keyix,
        return status != false;
 }
 
-static int ath_setkey_tkip(struct ath_softc *sc,
-                          struct ieee80211_key_conf *key,
+static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
                           struct ath9k_keyval *hk,
                           const u8 *addr)
 {
-       u8 *key_rxmic = NULL;
-       u8 *key_txmic = NULL;
+       const u8 *key_rxmic;
+       const u8 *key_txmic;
 
-       key_txmic = key->key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
-       key_rxmic = key->key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
+       key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
+       key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
 
        if (addr == NULL) {
                /* Group key installation */
-               memcpy(hk->kv_mic,  key_rxmic, sizeof(hk->kv_mic));
-               return ath_keyset(sc, key->keyidx, hk, addr);
+               memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
+               return ath_keyset(sc, keyix, hk, addr);
        }
        if (!sc->sc_splitmic) {
                /*
@@ -703,14 +697,14 @@ static int ath_setkey_tkip(struct ath_softc *sc,
                 */
                memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
                memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
-               return ath_keyset(sc, key->keyidx, hk, addr);
+               return ath_keyset(sc, keyix, hk, addr);
        }
        /*
         * TX key goes at first index, RX key at +32.
         * The hal handles the MIC keys at index+64.
         */
        memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
-       if (!ath_keyset(sc, key->keyidx, hk, NULL)) {
+       if (!ath_keyset(sc, keyix, hk, NULL)) {
                /* Txmic entry failed. No need to proceed further */
                DPRINTF(sc, ATH_DBG_KEYCACHE,
                        "Setting TX MIC Key Failed\n");
@@ -719,18 +713,97 @@ static int ath_setkey_tkip(struct ath_softc *sc,
 
        memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
        /* XXX delete tx key on failure? */
-       return ath_keyset(sc, key->keyidx+32, hk, addr);
+       return ath_keyset(sc, keyix + 32, hk, addr);
+}
+
+static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc)
+{
+       int i;
+
+       for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 2; i++) {
+               if (test_bit(i, sc->sc_keymap) ||
+                   test_bit(i + 64, sc->sc_keymap))
+                       continue; /* At least one part of TKIP key allocated */
+               if (sc->sc_splitmic &&
+                   (test_bit(i + 32, sc->sc_keymap) ||
+                    test_bit(i + 64 + 32, sc->sc_keymap)))
+                       continue; /* At least one part of TKIP key allocated */
+
+               /* Found a free slot for a TKIP key */
+               return i;
+       }
+       return -1;
+}
+
+static int ath_reserve_key_cache_slot(struct ath_softc *sc)
+{
+       int i;
+
+       /* First, try to find slots that would not be available for TKIP. */
+       if (sc->sc_splitmic) {
+               for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 4; i++) {
+                       if (!test_bit(i, sc->sc_keymap) &&
+                           (test_bit(i + 32, sc->sc_keymap) ||
+                            test_bit(i + 64, sc->sc_keymap) ||
+                            test_bit(i + 64 + 32, sc->sc_keymap)))
+                               return i;
+                       if (!test_bit(i + 32, sc->sc_keymap) &&
+                           (test_bit(i, sc->sc_keymap) ||
+                            test_bit(i + 64, sc->sc_keymap) ||
+                            test_bit(i + 64 + 32, sc->sc_keymap)))
+                               return i + 32;
+                       if (!test_bit(i + 64, sc->sc_keymap) &&
+                           (test_bit(i , sc->sc_keymap) ||
+                            test_bit(i + 32, sc->sc_keymap) ||
+                            test_bit(i + 64 + 32, sc->sc_keymap)))
+                               return i + 64;
+                       if (!test_bit(i + 64 + 32, sc->sc_keymap) &&
+                           (test_bit(i, sc->sc_keymap) ||
+                            test_bit(i + 32, sc->sc_keymap) ||
+                            test_bit(i + 64, sc->sc_keymap)))
+                               return i + 64 + 32;
+               }
+       } else {
+               for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 2; i++) {
+                       if (!test_bit(i, sc->sc_keymap) &&
+                           test_bit(i + 64, sc->sc_keymap))
+                               return i;
+                       if (test_bit(i, sc->sc_keymap) &&
+                           !test_bit(i + 64, sc->sc_keymap))
+                               return i + 64;
+               }
+       }
+
+       /* No partially used TKIP slots, pick any available slot */
+       for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax; i++) {
+               /* Do not allow slots that could be needed for TKIP group keys
+                * to be used. This limitation could be removed if we know that
+                * TKIP will not be used. */
+               if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
+                       continue;
+               if (sc->sc_splitmic) {
+                       if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
+                               continue;
+                       if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
+                               continue;
+               }
+
+               if (!test_bit(i, sc->sc_keymap))
+                       return i; /* Found a free slot for a key */
+       }
+
+       /* No free slot found */
+       return -1;
 }
 
 static int ath_key_config(struct ath_softc *sc,
                          const u8 *addr,
                          struct ieee80211_key_conf *key)
 {
-       struct ieee80211_vif *vif;
        struct ath9k_keyval hk;
        const u8 *mac = NULL;
        int ret = 0;
-       enum nl80211_iftype opmode;
+       int idx;
 
        memset(&hk, 0, sizeof(hk));
 
@@ -748,65 +821,69 @@ static int ath_key_config(struct ath_softc *sc,
                return -EINVAL;
        }
 
-       hk.kv_len  = key->keylen;
+       hk.kv_len = key->keylen;
        memcpy(hk.kv_val, key->key, key->keylen);
 
-       if (!sc->sc_vaps[0])
-               return -EIO;
-
-       vif = sc->sc_vaps[0];
-       opmode = vif->type;
+       if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+               /* For now, use the default keys for broadcast keys. This may
+                * need to change with virtual interfaces. */
+               idx = key->keyidx;
+       } else if (key->keyidx) {
+               struct ieee80211_vif *vif;
 
-       /*
-        *  Strategy:
-        *   For STA mc tx, we will not setup a key at
-        *   all since we never tx mc.
-        *
-        *   For STA mc rx, we will use the keyID.
-        *
-        *   For ADHOC mc tx, we will use the keyID, and no macaddr.
-        *
-        *   For ADHOC mc rx, we will alloc a slot and plumb the mac of
-        *   the peer node.
-        *   BUT we will plumb a cleartext key so that we can do
-        *   per-Sta default key table lookup in software.
-        */
-       if (is_broadcast_ether_addr(addr)) {
-               switch (opmode) {
-               case NL80211_IFTYPE_STATION:
-                       /* default key:  could be group WPA key
-                        * or could be static WEP key */
-                       mac = NULL;
-                       break;
-               case NL80211_IFTYPE_ADHOC:
-                       break;
-               case NL80211_IFTYPE_AP:
-                       break;
-               default:
-                       ASSERT(0);
-                       break;
-               }
+               mac = addr;
+               vif = sc->sc_vaps[0];
+               if (vif->type != NL80211_IFTYPE_AP) {
+                       /* Only keyidx 0 should be used with unicast key, but
+                        * allow this for client mode for now. */
+                       idx = key->keyidx;
+               } else
+                       return -EIO;
        } else {
                mac = addr;
+               if (key->alg == ALG_TKIP)
+                       idx = ath_reserve_key_cache_slot_tkip(sc);
+               else
+                       idx = ath_reserve_key_cache_slot(sc);
+               if (idx < 0)
+                       return -EIO; /* no free key cache entries */
        }
 
        if (key->alg == ALG_TKIP)
-               ret = ath_setkey_tkip(sc, key, &hk, mac);
+               ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac);
        else
-               ret = ath_keyset(sc, key->keyidx, &hk, mac);
+               ret = ath_keyset(sc, idx, &hk, mac);
 
        if (!ret)
                return -EIO;
 
-       return 0;
+       set_bit(idx, sc->sc_keymap);
+       if (key->alg == ALG_TKIP) {
+               set_bit(idx + 64, sc->sc_keymap);
+               if (sc->sc_splitmic) {
+                       set_bit(idx + 32, sc->sc_keymap);
+                       set_bit(idx + 64 + 32, sc->sc_keymap);
+               }
+       }
+
+       return idx;
 }
 
 static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
 {
-       int freeslot;
+       ath9k_hw_keyreset(sc->sc_ah, key->hw_key_idx);
+       if (key->hw_key_idx < IEEE80211_WEP_NKID)
+               return;
+
+       clear_bit(key->hw_key_idx, sc->sc_keymap);
+       if (key->alg != ALG_TKIP)
+               return;
 
-       freeslot = (key->keyidx >= 4) ? 1 : 0;
-       ath_key_reset(sc, key->keyidx, freeslot);
+       clear_bit(key->hw_key_idx + 64, sc->sc_keymap);
+       if (sc->sc_splitmic) {
+               clear_bit(key->hw_key_idx + 32, sc->sc_keymap);
+               clear_bit(key->hw_key_idx + 64 + 32, sc->sc_keymap);
+       }
 }
 
 static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info)
@@ -829,45 +906,15 @@ static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info)
        ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
 }
 
-static void ath9k_ht_conf(struct ath_softc *sc,
-                         struct ieee80211_bss_conf *bss_conf)
-{
-       if (sc->hw->conf.ht.enabled) {
-               if (bss_conf->ht.width_40_ok)
-                       sc->tx_chan_width = ATH9K_HT_MACMODE_2040;
-               else
-                       sc->tx_chan_width = ATH9K_HT_MACMODE_20;
-
-               ath9k_hw_set11nmac2040(sc->sc_ah, sc->tx_chan_width);
-
-               DPRINTF(sc, ATH_DBG_CONFIG,
-                       "BSS Changed HT, chanwidth: %d\n", sc->tx_chan_width);
-       }
-}
-
-static inline int ath_sec_offset(u8 ext_offset)
-{
-       if (ext_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE)
-               return 0;
-       else if (ext_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
-               return 1;
-       else if (ext_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW)
-               return -1;
-
-       return 0;
-}
-
 static void ath9k_bss_assoc_info(struct ath_softc *sc,
                                 struct ieee80211_vif *vif,
                                 struct ieee80211_bss_conf *bss_conf)
 {
-       struct ieee80211_hw *hw = sc->hw;
-       struct ieee80211_channel *curchan = hw->conf.channel;
        struct ath_vap *avp = (void *)vif->drv_priv;
-       int pos;
 
        if (bss_conf->assoc) {
-               DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d\n", bss_conf->aid);
+               DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n",
+                       bss_conf->aid, sc->sc_curbssid);
 
                /* New association, store aid */
                if (avp->av_opmode == NL80211_IFTYPE_STATION) {
@@ -886,40 +933,6 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
                sc->sc_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
                sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
 
-               /* Update chainmask */
-               ath_update_chainmask(sc, hw->conf.ht.enabled);
-
-               DPRINTF(sc, ATH_DBG_CONFIG,
-                       "bssid %pM aid 0x%x\n",
-                       sc->sc_curbssid, sc->sc_curaid);
-
-               pos = ath_get_channel(sc, curchan);
-               if (pos == -1) {
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "Invalid channel: %d\n", curchan->center_freq);
-                       return;
-               }
-
-               if (hw->conf.ht.enabled) {
-                       int offset =
-                               ath_sec_offset(bss_conf->ht.secondary_channel_offset);
-                       sc->tx_chan_width = (bss_conf->ht.width_40_ok) ?
-                               ATH9K_HT_MACMODE_2040 : ATH9K_HT_MACMODE_20;
-
-                       sc->sc_ah->ah_channels[pos].chanmode =
-                               ath_get_extchanmode(sc, curchan,
-                                                   offset, sc->tx_chan_width);
-               } else {
-                       sc->sc_ah->ah_channels[pos].chanmode =
-                               (curchan->band == IEEE80211_BAND_2GHZ) ?
-                               CHANNEL_G : CHANNEL_A;
-               }
-
-               /* set h/w channel */
-               if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0)
-                       DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel: %d\n",
-                               curchan->center_freq);
-
                /* Start ANI */
                mod_timer(&sc->sc_ani.timer,
                        jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
@@ -1291,9 +1304,6 @@ static void ath_detach(struct ath_softc *sc)
        ath_deinit_leds(sc);
 
        ieee80211_unregister_hw(hw);
-
-       ath_rate_control_unregister();
-
        ath_rx_cleanup(sc);
        ath_tx_cleanup(sc);
 
@@ -1326,6 +1336,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
                printk(KERN_ERR "Unable to create debugfs files\n");
 
        spin_lock_init(&sc->sc_resetlock);
+       mutex_init(&sc->mutex);
        tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
        tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
                     (unsigned long)sc);
@@ -1362,18 +1373,6 @@ static int ath_init(u16 devid, struct ath_softc *sc)
         */
        for (i = 0; i < sc->sc_keymax; i++)
                ath9k_hw_keyreset(ah, (u16) i);
-       /*
-        * Mark key cache slots associated with global keys
-        * as in use.  If we knew TKIP was not to be used we
-        * could leave the +32, +64, and +32+64 slots free.
-        * XXX only for splitmic.
-        */
-       for (i = 0; i < IEEE80211_WEP_NKID; i++) {
-               set_bit(i, sc->sc_keymap);
-               set_bit(i + 32, sc->sc_keymap);
-               set_bit(i + 64, sc->sc_keymap);
-               set_bit(i + 32 + 64, sc->sc_keymap);
-       }
 
        /* Collect the channel list using the default country code */
 
@@ -1574,15 +1573,7 @@ static int ath_attach(u16 devid, struct ath_softc *sc)
        hw->sta_data_size = sizeof(struct ath_node);
        hw->vif_data_size = sizeof(struct ath_vap);
 
-       /* Register rate control */
        hw->rate_control_algorithm = "ath9k_rate_control";
-       error = ath_rate_control_register();
-       if (error != 0) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to register rate control algorithm: %d\n", error);
-               ath_rate_control_unregister();
-               goto bad;
-       }
 
        if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) {
                setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
@@ -1615,10 +1606,6 @@ static int ath_attach(u16 devid, struct ath_softc *sc)
 #endif
 
        error = ieee80211_register_hw(hw);
-       if (error != 0) {
-               ath_rate_control_unregister();
-               goto bad;
-       }
 
        /* Initialize LED control */
        ath_init_leds(sc);
@@ -1626,7 +1613,6 @@ static int ath_attach(u16 devid, struct ath_softc *sc)
        return 0;
 detach:
        ath_detach(sc);
-bad:
        return error;
 }
 
@@ -2146,7 +2132,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
        struct ath_softc *sc = hw->priv;
        struct ieee80211_conf *conf = &hw->conf;
 
-       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+       mutex_lock(&sc->mutex);
+       if (changed & (IEEE80211_CONF_CHANGE_CHANNEL |
+                      IEEE80211_CONF_CHANGE_HT)) {
                struct ieee80211_channel *curchan = hw->conf.channel;
                int pos;
 
@@ -2157,6 +2145,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
                if (pos == -1) {
                        DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n",
                                curchan->center_freq);
+                       mutex_unlock(&sc->mutex);
                        return -EINVAL;
                }
 
@@ -2165,29 +2154,29 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
                        (curchan->band == IEEE80211_BAND_2GHZ) ?
                        CHANNEL_G : CHANNEL_A;
 
-               if ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) &&
-                   (conf->ht.enabled)) {
-                       sc->tx_chan_width = (!!conf->ht.sec_chan_offset) ?
-                               ATH9K_HT_MACMODE_2040 : ATH9K_HT_MACMODE_20;
+               if (conf->ht.enabled) {
+                       if (conf->ht.channel_type == NL80211_CHAN_HT40PLUS ||
+                           conf->ht.channel_type == NL80211_CHAN_HT40MINUS)
+                               sc->tx_chan_width = ATH9K_HT_MACMODE_2040;
 
                        sc->sc_ah->ah_channels[pos].chanmode =
                                ath_get_extchanmode(sc, curchan,
-                                                   conf->ht.sec_chan_offset,
-                                                   sc->tx_chan_width);
+                                                   conf->ht.channel_type);
                }
 
                if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) {
                        DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n");
+                       mutex_unlock(&sc->mutex);
                        return -EINVAL;
                }
-       }
 
-       if (changed & IEEE80211_CONF_CHANGE_HT)
                ath_update_chainmask(sc, conf->ht.enabled);
+       }
 
        if (changed & IEEE80211_CONF_CHANGE_POWER)
                sc->sc_config.txpowlimit = 2 * conf->power_level;
 
+       mutex_unlock(&sc->mutex);
        return 0;
 }
 
@@ -2371,18 +2360,17 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
        switch (cmd) {
        case SET_KEY:
                ret = ath_key_config(sc, addr, key);
-               if (!ret) {
-                       set_bit(key->keyidx, sc->sc_keymap);
-                       key->hw_key_idx = key->keyidx;
+               if (ret >= 0) {
+                       key->hw_key_idx = ret;
                        /* push IV and Michael MIC generation to stack */
                        key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
                        if (key->alg == ALG_TKIP)
                                key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+                       ret = 0;
                }
                break;
        case DISABLE_KEY:
                ath_key_delete(sc, key);
-               clear_bit(key->keyidx, sc->sc_keymap);
                break;
        default:
                ret = -EINVAL;
@@ -2417,9 +2405,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
                        sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
        }
 
-       if (changed & BSS_CHANGED_HT)
-               ath9k_ht_conf(sc, bss_conf);
-
        if (changed & BSS_CHANGED_ASSOC) {
                DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
                        bss_conf->assoc);
@@ -2780,11 +2765,24 @@ static struct pci_driver ath_pci_driver = {
 
 static int __init init_ath_pci(void)
 {
+       int error;
+
        printk(KERN_INFO "%s: %s\n", dev_info, ATH_PCI_VERSION);
 
+       /* Register rate control algorithm */
+       error = ath_rate_control_register();
+       if (error != 0) {
+               printk(KERN_ERR
+                       "Unable to register rate control algorithm: %d\n",
+                       error);
+               ath_rate_control_unregister();
+               return error;
+       }
+
        if (pci_register_driver(&ath_pci_driver) < 0) {
                printk(KERN_ERR
                        "ath_pci: No devices found, driver not installed.\n");
+               ath_rate_control_unregister();
                pci_unregister_driver(&ath_pci_driver);
                return -ENODEV;
        }
@@ -2795,6 +2793,7 @@ module_init(init_ath_pci);
 
 static void __exit exit_ath_pci(void)
 {
+       ath_rate_control_unregister();
        pci_unregister_driver(&ath_pci_driver);
        printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
 }
index 0ae5988e0b65215e587e9df543508a6149bf81dc..04ab457a8faa3f3bce73692b583a61866c72e6e2 100644 (file)
@@ -1498,7 +1498,8 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
        __le16 fc = hdr->frame_control;
 
        /* lowest rate for management and multicast/broadcast frames */
-       if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) {
+       if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
+           !sta) {
                tx_info->control.rates[0].idx = rate_lowest_index(sband, sta);
                tx_info->control.rates[0].count =
                        is_multicast_ether_addr(hdr->addr1) ? 1 : ATH_MGT_TXMAXTRY;
index f2327d8e9c28ed60bf81d7c03da47037373d83f5..462e08c3d09dc4cf18693f4e39c383a7dc34c580 100644 (file)
@@ -111,33 +111,6 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len)
        return skb;
 }
 
-static int ath_rate2idx(struct ath_softc *sc, int rate)
-{
-       int i = 0, cur_band, n_rates;
-       struct ieee80211_hw *hw = sc->hw;
-
-       cur_band = hw->conf.channel->band;
-       n_rates = sc->sbands[cur_band].n_bitrates;
-
-       for (i = 0; i < n_rates; i++) {
-               if (sc->sbands[cur_band].bitrates[i].bitrate == rate)
-                       break;
-       }
-
-       /*
-        * NB:mac80211 validates rx rate index against the supported legacy rate
-        * index only (should be done against ht rates also), return the highest
-        * legacy rate index for rx rate which does not match any one of the
-        * supported basic and extended rates to make mac80211 happy.
-        * The following hack will be cleaned up once the issue with
-        * the rx rate index validation in mac80211 is fixed.
-        */
-       if (i == n_rates)
-               return n_rates - 1;
-
-       return i;
-}
-
 /*
  * For Decrypt or Demic errors, we only mark packet status here and always push
  * up the frame up to let mac80211 handle the actual error case, be it no
@@ -147,9 +120,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
                          struct ieee80211_rx_status *rx_status, bool *decrypt_error,
                          struct ath_softc *sc)
 {
-       struct ath_rate_table *rate_table = sc->cur_rate_table;
        struct ieee80211_hdr *hdr;
-       int ratekbps, rix;
        u8 ratecode;
        __le16 fc;
 
@@ -204,15 +175,36 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
        }
 
        ratecode = ds->ds_rxstat.rs_rate;
-       rix = rate_table->rateCodeToIndex[ratecode];
-       ratekbps = rate_table->info[rix].ratekbps;
 
-       /* HT rate */
        if (ratecode & 0x80) {
+               /* HT rate */
+               rx_status->flag |= RX_FLAG_HT;
                if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040)
-                       ratekbps = (ratekbps * 27) / 13;
+                       rx_status->flag |= RX_FLAG_40MHZ;
                if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI)
-                       ratekbps = (ratekbps * 10) / 9;
+                       rx_status->flag |= RX_FLAG_SHORT_GI;
+               rx_status->rate_idx = ratecode & 0x7f;
+       } else {
+               int i = 0, cur_band, n_rates;
+               struct ieee80211_hw *hw = sc->hw;
+
+               cur_band = hw->conf.channel->band;
+               n_rates = sc->sbands[cur_band].n_bitrates;
+
+               for (i = 0; i < n_rates; i++) {
+                       if (sc->sbands[cur_band].bitrates[i].hw_value ==
+                           ratecode) {
+                               rx_status->rate_idx = i;
+                               break;
+                       }
+
+                       if (sc->sbands[cur_band].bitrates[i].hw_value_short ==
+                           ratecode) {
+                               rx_status->rate_idx = i;
+                               rx_status->flag |= RX_FLAG_SHORTPRE;
+                               break;
+                       }
+               }
        }
 
        rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
@@ -220,7 +212,6 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
        rx_status->freq =  sc->hw->conf.channel->center_freq;
        rx_status->noise = sc->sc_ani.sc_noise_floor;
        rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi;
-       rx_status->rate_idx = ath_rate2idx(sc, (ratekbps / 100));
        rx_status->antenna = ds->ds_rxstat.rs_antenna;
 
        /* at 45 you will be able to use MCS 15 reliably. A more elaborate
@@ -528,6 +519,15 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
                if (!skb)
                        continue;
 
+               /*
+                * Synchronize the DMA transfer with CPU before
+                * 1. accessing the frame
+                * 2. requeueing the same buffer to h/w
+                */
+               pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr,
+                               sc->rx.bufsize,
+                               PCI_DMA_FROMDEVICE);
+
                /*
                 * If we're asked to flush receive queue, directly
                 * chain it back at the queue without processing it.
@@ -556,10 +556,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
                if (!requeue_skb)
                        goto requeue;
 
-               /* Sync and unmap the frame */
-               pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr,
-                                           sc->rx.bufsize,
-                                           PCI_DMA_FROMDEVICE);
+               /* Unmap the frame */
                pci_unmap_single(sc->pdev, bf->bf_buf_addr,
                                 sc->rx.bufsize,
                                 PCI_DMA_FROMDEVICE);
index f9c309ed3a2d22e170738d0e2156598fdaf5eee2..3bfc3b90f2569013092e82959a03bfebdf39b979 100644 (file)
@@ -106,6 +106,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
        struct ieee80211_hw *hw = sc->hw;
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
        struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+       int hdrlen, padsize;
 
        DPRINTF(sc, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
 
@@ -125,7 +126,26 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
                tx_info->flags |= IEEE80211_TX_STAT_ACK;
        }
 
-       tx_info->status.rates[0].count = tx_status->retries + 1;
+       tx_info->status.rates[0].count = tx_status->retries;
+       if (tx_info->status.rates[0].flags & IEEE80211_TX_RC_MCS) {
+               /* Change idx from internal table index to MCS index */
+               int idx = tx_info->status.rates[0].idx;
+               struct ath_rate_table *rate_table = sc->cur_rate_table;
+               if (idx >= 0 && idx < rate_table->rate_cnt)
+                       tx_info->status.rates[0].idx =
+                               rate_table->info[idx].ratecode & 0x7f;
+       }
+
+       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+       padsize = hdrlen & 3;
+       if (padsize && hdrlen >= 24) {
+               /*
+                * Remove MAC header padding before giving the frame back to
+                * mac80211.
+                */
+               memmove(skb->data + padsize, skb->data, hdrlen);
+               skb_pull(skb, padsize);
+       }
 
        ieee80211_tx_status(hw, skb);
 }
index 06a01da801604c91dcf92408871f622e2ccd947d..e04fc91f569ea573f3c9d3dfad8551b710d98c32 100644 (file)
@@ -731,6 +731,7 @@ static void b43_add_dynamic_debug(struct b43_wldev *dev)
        add_dyn_dbg("debug_pwork_stop", B43_DBG_PWORK_STOP, 0);
        add_dyn_dbg("debug_lo", B43_DBG_LO, 0);
        add_dyn_dbg("debug_firmware", B43_DBG_FIRMWARE, 0);
+       add_dyn_dbg("debug_keys", B43_DBG_KEYS, 0);
 
 #undef add_dyn_dbg
 }
index 22ffd02ba554806a8625319b5c2fd2aeae1cdcba..7886cbe2d1d19276f22e3a974dd4d7e44a55347b 100644 (file)
@@ -12,6 +12,7 @@ enum b43_dyndbg {             /* Dynamic debugging features */
        B43_DBG_PWORK_STOP,
        B43_DBG_LO,
        B43_DBG_FIRMWARE,
+       B43_DBG_KEYS,
        __B43_NR_DYNDBG,
 };
 
index ba7a5ab7fe1d8f9c44bd5d961bff1b06a4eb8bda..7b31a327b24a33e643be1021360af7fdcb8273da 100644 (file)
@@ -992,6 +992,52 @@ static void b43_clear_keys(struct b43_wldev *dev)
                b43_key_clear(dev, i);
 }
 
+static void b43_dump_keymemory(struct b43_wldev *dev)
+{
+       unsigned int i, index, offset;
+       DECLARE_MAC_BUF(macbuf);
+       u8 mac[ETH_ALEN];
+       u16 algo;
+       u32 rcmta0;
+       u16 rcmta1;
+       u64 hf;
+       struct b43_key *key;
+
+       if (!b43_debug(dev, B43_DBG_KEYS))
+               return;
+
+       hf = b43_hf_read(dev);
+       b43dbg(dev->wl, "Hardware key memory dump:  USEDEFKEYS=%u\n",
+              !!(hf & B43_HF_USEDEFKEYS));
+       for (index = 0; index < dev->max_nr_keys; index++) {
+               key = &(dev->key[index]);
+               printk(KERN_DEBUG "Key slot %02u: %s",
+                      index, (key->keyconf == NULL) ? " " : "*");
+               offset = dev->ktp + (index * B43_SEC_KEYSIZE);
+               for (i = 0; i < B43_SEC_KEYSIZE; i += 2) {
+                       u16 tmp = b43_shm_read16(dev, B43_SHM_SHARED, offset + i);
+                       printk("%02X%02X", (tmp & 0xFF), ((tmp >> 8) & 0xFF));
+               }
+
+               algo = b43_shm_read16(dev, B43_SHM_SHARED,
+                                     B43_SHM_SH_KEYIDXBLOCK + (index * 2));
+               printk("   Algo: %04X/%02X", algo, key->algorithm);
+
+               if (index >= 4) {
+                       rcmta0 = b43_shm_read32(dev, B43_SHM_RCMTA,
+                                               ((index - 4) * 2) + 0);
+                       rcmta1 = b43_shm_read16(dev, B43_SHM_RCMTA,
+                                               ((index - 4) * 2) + 1);
+                       *((__le32 *)(&mac[0])) = cpu_to_le32(rcmta0);
+                       *((__le16 *)(&mac[4])) = cpu_to_le16(rcmta1);
+                       printk("   MAC: %s",
+                              print_mac(macbuf, mac));
+               } else
+                       printk("   DEFAULT KEY");
+               printk("\n");
+       }
+}
+
 void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags)
 {
        u32 macctl;
@@ -3324,7 +3370,6 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
        unsigned long flags;
        int antenna;
        int err = 0;
-       u32 savedirqs;
 
        mutex_lock(&wl->mutex);
 
@@ -3335,24 +3380,14 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
        dev = wl->current_dev;
        phy = &dev->phy;
 
+       b43_mac_suspend(dev);
+
        if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
                b43_set_retry_limits(dev, conf->short_frame_max_tx_count,
                                          conf->long_frame_max_tx_count);
        changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS;
        if (!changed)
-               goto out_unlock_mutex;
-
-       /* Disable IRQs while reconfiguring the device.
-        * This makes it possible to drop the spinlock throughout
-        * the reconfiguration process. */
-       spin_lock_irqsave(&wl->irq_lock, flags);
-       if (b43_status(dev) < B43_STAT_STARTED) {
-               spin_unlock_irqrestore(&wl->irq_lock, flags);
-               goto out_unlock_mutex;
-       }
-       savedirqs = b43_interrupt_disable(dev, B43_IRQ_ALL);
-       spin_unlock_irqrestore(&wl->irq_lock, flags);
-       b43_synchronize_irq(dev);
+               goto out_mac_enable;
 
        /* Switch to the requested channel.
         * The firmware takes care of races with the TX handler. */
@@ -3399,11 +3434,9 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
                }
        }
 
-       spin_lock_irqsave(&wl->irq_lock, flags);
-       b43_interrupt_enable(dev, savedirqs);
-       mmiowb();
-       spin_unlock_irqrestore(&wl->irq_lock, flags);
-      out_unlock_mutex:
+out_mac_enable:
+       b43_mac_enable(dev);
+out_unlock_mutex:
        mutex_unlock(&wl->mutex);
 
        return err;
@@ -3461,27 +3494,12 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev;
-       struct b43_phy *phy;
-       unsigned long flags;
-       u32 savedirqs;
 
        mutex_lock(&wl->mutex);
 
        dev = wl->current_dev;
-       phy = &dev->phy;
-
-       /* Disable IRQs while reconfiguring the device.
-        * This makes it possible to drop the spinlock throughout
-        * the reconfiguration process. */
-       spin_lock_irqsave(&wl->irq_lock, flags);
-       if (b43_status(dev) < B43_STAT_STARTED) {
-               spin_unlock_irqrestore(&wl->irq_lock, flags);
+       if (!dev || b43_status(dev) < B43_STAT_STARTED)
                goto out_unlock_mutex;
-       }
-       savedirqs = b43_interrupt_disable(dev, B43_IRQ_ALL);
-       spin_unlock_irqrestore(&wl->irq_lock, flags);
-       b43_synchronize_irq(dev);
-
        b43_mac_suspend(dev);
 
        if (changed & BSS_CHANGED_BASIC_RATES)
@@ -3495,13 +3513,7 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
        }
 
        b43_mac_enable(dev);
-
-       spin_lock_irqsave(&wl->irq_lock, flags);
-       b43_interrupt_enable(dev, savedirqs);
-       /* XXX: why? */
-       mmiowb();
-       spin_unlock_irqrestore(&wl->irq_lock, flags);
- out_unlock_mutex:
+out_unlock_mutex:
        mutex_unlock(&wl->mutex);
 
        return;
@@ -3599,15 +3611,18 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        default:
                B43_WARN_ON(1);
        }
+
 out_unlock:
-       spin_unlock_irqrestore(&wl->irq_lock, flags);
-       mutex_unlock(&wl->mutex);
        if (!err) {
                b43dbg(wl, "%s hardware based encryption for keyidx: %d, "
                       "mac: %pM\n",
                       cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
                       addr);
+               b43_dump_keymemory(dev);
        }
+       spin_unlock_irqrestore(&wl->irq_lock, flags);
+       mutex_unlock(&wl->mutex);
+
        return err;
 }
 
index af37abccccb39e4f3ca7f7c1bcd465ef5fc10ac1..026b61c03fb9fb4432492bc8ddad32a617d72b6a 100644 (file)
@@ -178,13 +178,27 @@ void b43_phy_unlock(struct b43_wldev *dev)
                b43_power_saving_ctl_bits(dev, 0);
 }
 
+static inline void assert_mac_suspended(struct b43_wldev *dev)
+{
+       if (!B43_DEBUG)
+               return;
+       if ((b43_status(dev) >= B43_STAT_INITIALIZED) &&
+           (dev->mac_suspended <= 0)) {
+               b43dbg(dev->wl, "PHY/RADIO register access with "
+                      "enabled MAC.\n");
+               dump_stack();
+       }
+}
+
 u16 b43_radio_read(struct b43_wldev *dev, u16 reg)
 {
+       assert_mac_suspended(dev);
        return dev->phy.ops->radio_read(dev, reg);
 }
 
 void b43_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 {
+       assert_mac_suspended(dev);
        dev->phy.ops->radio_write(dev, reg, value);
 }
 
@@ -208,11 +222,13 @@ void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set)
 
 u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
 {
+       assert_mac_suspended(dev);
        return dev->phy.ops->phy_read(dev, reg);
 }
 
 void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
 {
+       assert_mac_suspended(dev);
        dev->phy.ops->phy_write(dev, reg, value);
 }
 
@@ -280,8 +296,10 @@ void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state)
                state = RFKILL_STATE_SOFT_BLOCKED;
        }
 
+       b43_mac_suspend(dev);
        phy->ops->software_rfkill(dev, state);
        phy->radio_on = (state == RFKILL_STATE_UNBLOCKED);
+       b43_mac_enable(dev);
 }
 
 /**
index 232181f6333c453eb6d0f030c07d60da1d0f2c73..3b1d673796cccb2b3ace45ce2f43916cfe796f6c 100644 (file)
@@ -3047,6 +3047,8 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev)
        int rfatt, bbatt;
        u8 tx_control;
 
+       b43_mac_suspend(dev);
+
        spin_lock_irq(&dev->wl->irq_lock);
 
        /* Calculate the new attenuation values. */
@@ -3103,6 +3105,8 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev)
                          gphy->tx_control);
        b43_radio_unlock(dev);
        b43_phy_unlock(dev);
+
+       b43_mac_enable(dev);
 }
 
 static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev,
@@ -3215,9 +3219,9 @@ static void b43_gphy_op_pwork_15sec(struct b43_wldev *dev)
        struct b43_phy *phy = &dev->phy;
        struct b43_phy_g *gphy = phy->g;
 
+       b43_mac_suspend(dev);
        //TODO: update_aci_moving_average
        if (gphy->aci_enable && gphy->aci_wlan_automatic) {
-               b43_mac_suspend(dev);
                if (!gphy->aci_enable && 1 /*TODO: not scanning? */ ) {
                        if (0 /*TODO: bunch of conditions */ ) {
                                phy->ops->interf_mitigation(dev,
@@ -3227,12 +3231,12 @@ static void b43_gphy_op_pwork_15sec(struct b43_wldev *dev)
                           if (/*(aci_average > 1000) &&*/ !b43_gphy_aci_scan(dev))
                                phy->ops->interf_mitigation(dev, B43_INTERFMODE_NONE);
                }
-               b43_mac_enable(dev);
        } else if (gphy->interfmode == B43_INTERFMODE_NONWLAN &&
                   phy->rev == 1) {
                //TODO: implement rev1 workaround
        }
        b43_lo_g_maintanance_work(dev);
+       b43_mac_enable(dev);
 }
 
 static void b43_gphy_op_pwork_60sec(struct b43_wldev *dev)
index d0c9bdcf393ae209bf852e410a907849805076ec..8fdb34222c0a4f3e3ba8c11644fc429ed6de7300 100644 (file)
@@ -2482,7 +2482,6 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
 
        frame_size = iwl3945_fill_beacon_frame(priv,
                                tx_beacon_cmd->frame,
-                               iwl3945_broadcast_addr,
                                sizeof(frame->u) - sizeof(*tx_beacon_cmd));
 
        BUG_ON(frame_size > MAX_MPDU_SIZE);
index ec6084c8fd134fb0da9a366721b474aa7732a7bf..2c0ddc5110c6b1611e631239a8ef84a16c8e0539 100644 (file)
@@ -405,12 +405,6 @@ struct iwl3945_rx_queue {
 
 #define SCAN_INTERVAL 100
 
-#define MAX_A_CHANNELS  252
-#define MIN_A_CHANNELS  7
-
-#define MAX_B_CHANNELS  14
-#define MIN_B_CHANNELS  1
-
 #define STATUS_HCMD_ACTIVE     0       /* host command in progress */
 #define STATUS_HCMD_SYNC_ACTIVE        1       /* sync host command in progress */
 #define STATUS_INT_ENABLED     2
@@ -590,8 +584,7 @@ extern int iwl3945_send_cmd_pdu(struct iwl3945_priv *priv, u8 id, u16 len,
 extern int __must_check iwl3945_send_cmd(struct iwl3945_priv *priv,
                struct iwl3945_host_cmd *cmd);
 extern unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
-                                       struct ieee80211_hdr *hdr,
-                                       const u8 *dest, int left);
+                                       struct ieee80211_hdr *hdr,int left);
 extern int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv,
                                         struct iwl3945_rx_queue *q);
 extern int iwl3945_send_statistics_request(struct iwl3945_priv *priv);
index a7e6e32bd4890dfc529ec9cfaf9dd51c5071b310..5a72bc0377ded292dcfd7048b9fbfc86373eab4e 100644 (file)
@@ -426,7 +426,6 @@ static void iwl4965_nic_config(struct iwl_priv *priv)
 
 static int iwl4965_apm_stop_master(struct iwl_priv *priv)
 {
-       int ret = 0;
        unsigned long flags;
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -434,16 +433,13 @@ static int iwl4965_apm_stop_master(struct iwl_priv *priv)
        /* set stop master bit */
        iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
 
-       ret = iwl_poll_direct_bit(priv, CSR_RESET,
+       iwl_poll_direct_bit(priv, CSR_RESET,
                        CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
-       if (ret < 0)
-               goto out;
 
-out:
        spin_unlock_irqrestore(&priv->lock, flags);
        IWL_DEBUG_INFO("stop master\n");
 
-       return ret;
+       return 0;
 }
 
 static void iwl4965_apm_stop(struct iwl_priv *priv)
@@ -2354,7 +2350,7 @@ module_param_named(disable, iwl4965_mod_params.disable, int, 0444);
 MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
 module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, 0444);
 MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
-module_param_named(debug, iwl4965_mod_params.debug, int, 0444);
+module_param_named(debug, iwl4965_mod_params.debug, uint, 0444);
 MODULE_PARM_DESC(debug, "debug output mask");
 module_param_named(
        disable_hw_scan, iwl4965_mod_params.disable_hw_scan, int, 0444);
index 2344de945974a15e6d76519d9665aad50eef4d87..66d053d28a7470dbb395dd57202edb224cd36b15 100644 (file)
@@ -73,7 +73,6 @@ static const u16 iwl5000_default_queue_to_tx_fifo[] = {
 /* FIXME: same implementation as 4965 */
 static int iwl5000_apm_stop_master(struct iwl_priv *priv)
 {
-       int ret = 0;
        unsigned long flags;
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -81,16 +80,13 @@ static int iwl5000_apm_stop_master(struct iwl_priv *priv)
        /* set stop master bit */
        iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
 
-       ret = iwl_poll_direct_bit(priv, CSR_RESET,
+       iwl_poll_direct_bit(priv, CSR_RESET,
                                  CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
-       if (ret < 0)
-               goto out;
 
-out:
        spin_unlock_irqrestore(&priv->lock, flags);
        IWL_DEBUG_INFO("stop master\n");
 
-       return ret;
+       return 0;
 }
 
 
@@ -1623,7 +1619,7 @@ MODULE_PARM_DESC(disable50,
 module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, 0444);
 MODULE_PARM_DESC(swcrypto50,
                  "using software crypto engine (default 0 [hardware])\n");
-module_param_named(debug50, iwl50_mod_params.debug, int, 0444);
+module_param_named(debug50, iwl50_mod_params.debug, uint, 0444);
 MODULE_PARM_DESC(debug50, "50XX debug output mask");
 module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, 0444);
 MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series");
index 37b892044a188bcec71ac256dcbb0b2b443dc244..f3f17929ca0bb1546721f0a1a22e8b7fe2a6dc8d 100644 (file)
@@ -836,6 +836,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
            (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate !=
             hw->wiphy->bands[info->band]->bitrates[info->status.rates[0].idx].bitrate)) {
                IWL_DEBUG_RATE("initial rate does not match 0x%x\n", tx_rate);
+               /* the last LQ command could failed so the LQ in ucode not
+                * the same in driver sync up
+                */
+               iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
                goto out;
        }
 
@@ -2167,6 +2171,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
        struct iwl_priv *priv = (struct iwl_priv *)priv_r;
        struct ieee80211_conf *conf = &priv->hw->conf;
        struct iwl_lq_sta *lq_sta = priv_sta;
+       u16 mask_bit = 0;
 
        lq_sta->flush_timer = 0;
        lq_sta->supp_rates = sta->supp_rates[sband->band];
@@ -2200,16 +2205,6 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
                priv->assoc_station_added = 1;
        }
 
-       /* Find highest tx rate supported by hardware and destination station */
-       lq_sta->last_txrate_idx = 3;
-       for (i = 0; i < sband->n_bitrates; i++)
-               if (sta->supp_rates[sband->band] & BIT(i))
-                       lq_sta->last_txrate_idx = i;
-
-       /* For MODE_IEEE80211A, skip over cck rates in global rate table */
-       if (sband->band == IEEE80211_BAND_5GHZ)
-               lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
-
        lq_sta->is_dup = 0;
        lq_sta->is_green = rs_use_green(priv, conf);
        lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
@@ -2248,6 +2243,17 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
        lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
        lq_sta->drv = priv;
 
+       /* Find highest tx rate supported by hardware and destination station */
+       mask_bit = sta->supp_rates[sband->band] & lq_sta->active_legacy_rate;
+       lq_sta->last_txrate_idx = 3;
+       for (i = 0; i < sband->n_bitrates; i++)
+               if (mask_bit & BIT(i))
+                       lq_sta->last_txrate_idx = i;
+
+       /* For MODE_IEEE80211A, skip over cck rates in global rate table */
+       if (sband->band == IEEE80211_BAND_5GHZ)
+               lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
+
        rs_initialize_lq(priv, conf, sta, lq_sta);
 }
 
index 2f5e86e129163d2051e0415afe2867331ec6ffa5..5da6b35cd26dbfa52da035a6ed78b871957b5c42 100644 (file)
@@ -371,7 +371,7 @@ static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
 
 static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
                                          struct ieee80211_hdr *hdr,
-                                         const u8 *dest, int left)
+                                         int left)
 {
        if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
            ((priv->iw_mode != NL80211_IFTYPE_ADHOC) &&
@@ -424,7 +424,6 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
        tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 
        frame_size = iwl_fill_beacon_frame(priv, tx_beacon_cmd->frame,
-                               iwl_bcast_addr,
                                sizeof(frame->u) - sizeof(*tx_beacon_cmd));
 
        BUG_ON(frame_size > MAX_MPDU_SIZE);
@@ -515,19 +514,27 @@ static void iwl_ht_conf(struct iwl_priv *priv,
        iwl_conf->supported_chan_width =
                !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
 
-       iwl_conf->extension_chan_offset = bss_conf->ht.secondary_channel_offset;
+       /*
+        * XXX: The HT configuration needs to be moved into iwl_mac_config()
+        *      to be done there correctly.
+        */
+
+       iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
+       if (priv->hw->conf.ht.channel_type == NL80211_CHAN_HT40MINUS)
+               iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+       else if(priv->hw->conf.ht.channel_type == NL80211_CHAN_HT40PLUS)
+               iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+
        /* If no above or below channel supplied disable FAT channel */
        if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE &&
-           iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW) {
-               iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
+           iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW)
                iwl_conf->supported_chan_width = 0;
-       }
 
        iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
 
        memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16);
 
-       iwl_conf->tx_chan_width = bss_conf->ht.width_40_ok;
+       iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0;
        iwl_conf->ht_protection =
                bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
        iwl_conf->non_GF_STA_present =
@@ -1103,16 +1110,6 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
        priv->cfg->ops->lib->rx_handler_setup(priv);
 }
 
-/*
- * this should be called while priv->lock is locked
-*/
-static void __iwl_rx_replenish(struct iwl_priv *priv)
-{
-       iwl_rx_allocate(priv);
-       iwl_rx_queue_restock(priv);
-}
-
-
 /**
  * iwl_rx_handle - Main entry function for receiving responses from uCode
  *
@@ -1221,7 +1218,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
                        count++;
                        if (count >= 8) {
                                priv->rxq.read = i;
-                               __iwl_rx_replenish(priv);
+                               iwl_rx_queue_restock(priv);
                                count = 0;
                        }
                }
@@ -3335,7 +3332,7 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
 
 /*
  * The following adds a new attribute to the sysfs representation
- * of this device driver (i.e. a new file in /sys/bus/pci/drivers/iwl/)
+ * of this device driver (i.e. a new file in /sys/class/net/wlan0/device/)
  * used for controlling the debug level.
  *
  * See the level definitions in iwl for details.
@@ -3421,7 +3418,11 @@ static ssize_t show_tx_power(struct device *d,
                             struct device_attribute *attr, char *buf)
 {
        struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
-       return sprintf(buf, "%d\n", priv->tx_power_user_lmt);
+
+       if (!iwl_is_ready_rf(priv))
+               return sprintf(buf, "off\n");
+       else
+               return sprintf(buf, "%d\n", priv->tx_power_user_lmt);
 }
 
 static ssize_t store_tx_power(struct device *d,
index 7956e08736143aa7abfb68284c900d8448bae3fb..f836ecc55758a4d4ab12bf0a796fbd17b9ef2556 100644 (file)
  * INIT calibrations framework
  *****************************************************************************/
 
+struct statistics_general_data {
+       u32 beacon_silence_rssi_a;
+       u32 beacon_silence_rssi_b;
+       u32 beacon_silence_rssi_c;
+       u32 beacon_energy_a;
+       u32 beacon_energy_b;
+       u32 beacon_energy_c;
+};
+
 int iwl_send_calib_results(struct iwl_priv *priv)
 {
        int ret = 0;
index 60e79d9bd725c81b80668be8e7d9f941c47963c4..52966ffbef6ec6231bfbb18fc2228572faec23a6 100644 (file)
@@ -2418,6 +2418,8 @@ struct statistics_rx_ht_phy {
        __le32 reserved2;
 } __attribute__ ((packed));
 
+#define INTERFERENCE_DATA_AVAILABLE      __constant_cpu_to_le32(1)
+
 struct statistics_rx_non_phy {
        __le32 bogus_cts;       /* CTS received when not expecting CTS */
        __le32 bogus_ack;       /* ACK received when not expecting ACK */
index 08b842f85768336abe8a84b4e0df6292414929d4..7c3a20a986bbd3567a6ed7c9102206e0d81e9aa1 100644 (file)
@@ -154,7 +154,7 @@ struct iwl_ops {
 struct iwl_mod_params {
        int disable;            /* def: 0 = enable radio */
        int sw_crypto;          /* def: 0 = using hardware encryption */
-       int debug;              /* def: 0 = minimal debug log messages */
+       u32 debug;              /* def: 0 = minimal debug log messages */
        int disable_hw_scan;    /* def: 0 = use h/w scan */
        int num_of_queues;      /* def: HW dependent */
        int num_of_ampdu_queues;/* def: HW dependent */
index e4c264b4f7b0e469633f1284745b5ab6288c26c0..56c13b458de7fc7571298591ec3d2eb2b20bfc27 100644 (file)
@@ -96,28 +96,25 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
 #endif                         /* CONFIG_IWLWIFI_DEBUGFS */
 
 /*
- * To use the debug system;
+ * To use the debug system:
  *
  * If you are defining a new debug classification, simply add it to the #define
- * list here in the form of:
+ * list here in the form of
  *
  * #define IWL_DL_xxxx VALUE
  *
- * shifting value to the left one bit from the previous entry.  xxxx should be
- * the name of the classification (for example, WEP)
+ * where xxxx should be the name of the classification (for example, WEP).
  *
  * You then need to either add a IWL_xxxx_DEBUG() macro definition for your
  * classification, or use IWL_DEBUG(IWL_DL_xxxx, ...) whenever you want
  * to send output to that classification.
  *
- * To add your debug level to the list of levels seen when you perform
+ * The active debug levels can be accessed via files
  *
- * % cat /sys/class/net/wlanX/device/debug_level
+ *     /sys/module/iwlagn/parameters/debug{50}
+ *     /sys/class/net/wlan0/device/debug_level
  *
- * you simply need to add your entry to the iwl_debug_levels array.
- *
- * If you do not see debug_level in  /sys/class/net/wlanX/device/debug_level
- * then you do not have CONFIG_IWLWIFI_DEBUG defined in your kernel config file
+ * when CONFIG_IWLWIFI_DEBUG=y.
  */
 
 #define IWL_DL_INFO            (1 << 0)
index eaf0c9cc33a594b24f49cfdca0f487cb4859a9f4..0468fcc1ea98ed58d42e6988cb248a7a162a3589 100644 (file)
@@ -323,14 +323,6 @@ struct iwl_rx_queue {
 
 #define IWL_SUPPORTED_RATES_IE_LEN         8
 
-#define SCAN_INTERVAL 100
-
-#define MAX_A_CHANNELS  252
-#define MIN_A_CHANNELS  7
-
-#define MAX_B_CHANNELS  14
-#define MIN_B_CHANNELS  1
-
 #define MAX_TID_COUNT        9
 
 #define IWL_INVALID_RATE     0xFF
@@ -496,8 +488,6 @@ struct iwl_sensitivity_ranges {
 };
 
 
-#define IWL_FAT_CHANNEL_52 BIT(IEEE80211_BAND_5GHZ)
-
 #define KELVIN_TO_CELSIUS(x) ((x)-273)
 #define CELSIUS_TO_KELVIN(x) ((x)+273)
 
@@ -546,9 +536,6 @@ struct iwl_hw_params {
        const struct iwl_sensitivity_ranges *sens;
 };
 
-#define HT_SHORT_GI_20MHZ      (1 << 0)
-#define HT_SHORT_GI_40MHZ      (1 << 1)
-
 
 /******************************************************************************
  *
@@ -590,15 +577,15 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge)
 }
 
 
-struct iwl_priv;
-
-
 struct iwl_dma_ptr {
        dma_addr_t dma;
        void *addr;
        size_t size;
 };
 
+#define HT_SHORT_GI_20MHZ      (1 << 0)
+#define HT_SHORT_GI_40MHZ      (1 << 1)
+
 #define IWL_CHANNEL_WIDTH_20MHZ   0
 #define IWL_CHANNEL_WIDTH_40MHZ   1
 
@@ -613,7 +600,6 @@ struct iwl_dma_ptr {
 #define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000
 
 /* Sensitivity and chain noise calibration */
-#define INTERFERENCE_DATA_AVAILABLE    __constant_cpu_to_le32(1)
 #define INITIALIZATION_VALUE           0xFFFF
 #define CAL_NUM_OF_BEACONS             20
 #define MAXIMUM_ALLOWED_PATHLOSS       15
@@ -666,15 +652,6 @@ enum iwl4965_calib_enabled_state {
        IWL_CALIB_ENABLED = 1,
 };
 
-struct statistics_general_data {
-       u32 beacon_silence_rssi_a;
-       u32 beacon_silence_rssi_b;
-       u32 beacon_silence_rssi_c;
-       u32 beacon_energy_a;
-       u32 beacon_energy_b;
-       u32 beacon_energy_c;
-};
-
 
 /*
  * enum iwl_calib
index 998ac19716965244c4786dfb9da377fd469ee1b8..0a92e7431adaa023cc6a6916cdf454406c0ca6fc 100644 (file)
@@ -87,17 +87,18 @@ static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs)
 #define iwl_read32(p, o) _iwl_read32(p, o)
 #endif
 
+#define IWL_POLL_INTERVAL 10   /* microseconds */
 static inline int _iwl_poll_bit(struct iwl_priv *priv, u32 addr,
                                u32 bits, u32 mask, int timeout)
 {
-       int i = 0;
+       int t = 0;
 
        do {
                if ((_iwl_read32(priv, addr) & mask) == (bits & mask))
-                       return i;
-               udelay(10);
-               i += 10;
-       } while (i < timeout);
+                       return t;
+               udelay(IWL_POLL_INTERVAL);
+               t += IWL_POLL_INTERVAL;
+       } while (t < timeout);
 
        return -ETIMEDOUT;
 }
index dce32ff8dec1185b8fb2d4f4b6ced6c94c87f505..11eccd7d268c2946cc13715ee93160314b8fa48a 100644 (file)
@@ -292,7 +292,7 @@ static int iwl_get_blink_rate(struct iwl_priv *priv)
                        if (tpt  > (blink_tbl[i].tpt * IWL_1MB_RATE))
                                break;
 
-       IWL_DEBUG_LED("LED BLINK IDX=%d", i);
+       IWL_DEBUG_LED("LED BLINK IDX=%d\n", i);
        return i;
 }
 
index 919a775121e47fb5dffe5fbd5be085f2232cb115..c5f1aa0feac8c49ecb635e44b7b89e1c98681158 100644 (file)
@@ -244,25 +244,31 @@ void iwl_rx_allocate(struct iwl_priv *priv)
        struct list_head *element;
        struct iwl_rx_mem_buffer *rxb;
        unsigned long flags;
-       spin_lock_irqsave(&rxq->lock, flags);
-       while (!list_empty(&rxq->rx_used)) {
+
+       while (1) {
+               spin_lock_irqsave(&rxq->lock, flags);
+
+               if (list_empty(&rxq->rx_used)) {
+                       spin_unlock_irqrestore(&rxq->lock, flags);
+                       return;
+               }
                element = rxq->rx_used.next;
                rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+               list_del(element);
+
+               spin_unlock_irqrestore(&rxq->lock, flags);
 
                /* Alloc a new receive buffer */
                rxb->skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
-                               __GFP_NOWARN | GFP_ATOMIC);
+                                    GFP_KERNEL);
                if (!rxb->skb) {
-                       if (net_ratelimit())
-                               printk(KERN_CRIT DRV_NAME
-                                      ": Can not allocate SKB buffers\n");
+                       printk(KERN_CRIT DRV_NAME
+                                  "Can not allocate SKB buffers\n");
                        /* We don't reschedule replenish work here -- we will
                         * call the restock method and if it still needs
                         * more buffers it will schedule replenish */
                        break;
                }
-               priv->alloc_rxb_skb++;
-               list_del(element);
 
                /* Get physical address of RB/SKB */
                rxb->real_dma_addr = pci_map_single(
@@ -276,12 +282,15 @@ void iwl_rx_allocate(struct iwl_priv *priv)
                rxb->aligned_dma_addr = ALIGN(rxb->real_dma_addr, 256);
                skb_reserve(rxb->skb, rxb->aligned_dma_addr - rxb->real_dma_addr);
 
+               spin_lock_irqsave(&rxq->lock, flags);
+
                list_add_tail(&rxb->list, &rxq->rx_free);
                rxq->free_count++;
+               priv->alloc_rxb_skb++;
+
+               spin_unlock_irqrestore(&rxq->lock, flags);
        }
-       spin_unlock_irqrestore(&rxq->lock, flags);
 }
-EXPORT_SYMBOL(iwl_rx_allocate);
 
 void iwl_rx_replenish(struct iwl_priv *priv)
 {
index 1e7cd8d9039ea1d2e2e3c8a4c15ac9262e5e9a3a..b0ee86c6268501754651206d88b87fdcfceb2401 100644 (file)
@@ -645,7 +645,7 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
                                  struct iwl_tx_cmd *tx_cmd,
                                  struct ieee80211_tx_info *info,
                                  struct ieee80211_hdr *hdr,
-                                 int is_unicast, u8 std_id)
+                                 u8 std_id)
 {
        __le16 fc = hdr->frame_control;
        __le32 tx_flags = tx_cmd->tx_flags;
@@ -834,7 +834,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        u16 len, len_org;
        u16 seq_number = 0;
        __le16 fc;
-       u8 hdr_len, unicast;
+       u8 hdr_len;
        u8 sta_id;
        u8 wait_write_ptr = 0;
        u8 tid = 0;
@@ -854,8 +854,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
                goto drop_unlock;
        }
 
-       unicast = !is_multicast_ether_addr(hdr->addr1);
-
        fc = hdr->frame_control;
 
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -994,7 +992,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        len = (u16)skb->len;
        tx_cmd->len = cpu_to_le16(len);
        /* TODO need this for burst mode later on */
-       iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, unicast, sta_id);
+       iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
 
        /* set is_hcca to 0; it probably will never be implemented */
        iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0);
index 352ccac7187b078c8a5e4904f515de92f5b393e5..d64580805d6efbef7cb48a5bafec23ca02f55f6d 100644 (file)
@@ -65,7 +65,7 @@ static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv,
 
 /* module parameters */
 static int iwl3945_param_disable_hw_scan; /* def: 0 = use 3945's h/w scan */
-static int iwl3945_param_debug;    /* def: 0 = minimal debug log messages */
+static u32 iwl3945_param_debug;    /* def: 0 = minimal debug log messages */
 static int iwl3945_param_disable;  /* def: 0 = enable radio */
 static int iwl3945_param_antenna;  /* def: 0 = both antennas (use diversity) */
 int iwl3945_param_hwcrypto;        /* def: 0 = use software encryption */
@@ -1402,7 +1402,7 @@ static void iwl3945_free_frame(struct iwl3945_priv *priv, struct iwl3945_frame *
 
 unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
                                struct ieee80211_hdr *hdr,
-                               const u8 *dest, int left)
+                               int left)
 {
 
        if (!iwl3945_is_associated(priv) || !priv->ibss_beacon ||
@@ -8343,7 +8343,7 @@ MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
 module_param_named(hwcrypto, iwl3945_param_hwcrypto, int, 0444);
 MODULE_PARM_DESC(hwcrypto,
                 "using hardware crypto engine (default 0 [software])\n");
-module_param_named(debug, iwl3945_param_debug, int, 0444);
+module_param_named(debug, iwl3945_param_debug, uint, 0444);
 MODULE_PARM_DESC(debug, "debug output mask");
 module_param_named(disable_hw_scan, iwl3945_param_disable_hw_scan, int, 0444);
 MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
index b54e2ea8346bf26ae5071ed39bbfe450830a980d..4519d7314f47c37677df87ca51fc4b53bfeac2fe 100644 (file)
@@ -26,6 +26,7 @@
  * if_sdio_card_to_host() to pad the data.
  */
 
+#include <linux/kernel.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
 #include <linux/netdevice.h>
@@ -581,7 +582,7 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
                                chunk_size, (chunk_size + 31) / 32 * 32);
 */
                        ret = sdio_writesb(card->func, card->ioport,
-                               chunk_buffer, (chunk_size + 31) / 32 * 32);
+                               chunk_buffer, roundup(chunk_size, 32));
                        if (ret)
                                goto release;
 
index fd5a537ac51d8a773c63d02412956644c9c4f835..f83d69e813d3a23cf46c8aefd94833147ab05d9f 100644 (file)
@@ -495,11 +495,9 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
        }
 
        if (changed & BSS_CHANGED_HT) {
-               printk(KERN_DEBUG "  %s: HT: sec_ch_offs=%d width_40_ok=%d "
-                      "op_mode=%d\n",
+               printk(KERN_DEBUG "  %s: HT: op_mode=0x%x\n",
                       wiphy_name(hw->wiphy),
-                      info->ht.secondary_channel_offset,
-                      info->ht.width_40_ok, info->ht.operation_mode);
+                      info->ht.operation_mode);
        }
 
        if (changed & BSS_CHANGED_BASIC_RATES) {
index d2dbb9e15d97bcd607691ca51c180f5108fd500c..ab79e32f0b27c495c3c20eb43310882ff1aaa8b9 100644 (file)
@@ -44,6 +44,9 @@ enum p54_control_frame_types {
        P54_CONTROL_TYPE_BT_OPTIONS = 35
 };
 
+#define P54_HDR_FLAG_CONTROL           BIT(15)
+#define P54_HDR_FLAG_CONTROL_OPSET     (BIT(15) + BIT(0))
+
 struct p54_hdr {
        __le16 flags;
        __le16 len;
@@ -54,6 +57,10 @@ struct p54_hdr {
        u8 data[0];
 } __attribute__ ((packed));
 
+#define FREE_AFTER_TX(skb)                                             \
+       ((((struct p54_hdr *) ((struct sk_buff *) skb)->data)->         \
+       flags) == cpu_to_le16(P54_HDR_FLAG_CONTROL_OPSET))
+
 struct p54_edcf_queue_param {
        __le16 aifs;
        __le16 cwmin;
@@ -61,6 +68,13 @@ struct p54_edcf_queue_param {
        __le16 txop;
 } __attribute__ ((packed));
 
+struct p54_rssi_linear_approximation {
+       s16 mul;
+       s16 add;
+       s16 longbow_unkn;
+       s16 longbow_unk2;
+};
+
 #define EEPROM_READBACK_LEN 0x3fc
 
 #define ISL38XX_DEV_FIRMWARE_ADDR 0x20000
@@ -71,11 +85,11 @@ struct p54_edcf_queue_param {
 #define FW_LM20 0x4c4d3230
 
 struct p54_common {
+       struct ieee80211_hw *hw;
        u32 rx_start;
        u32 rx_end;
        struct sk_buff_head tx_queue;
-       void (*tx)(struct ieee80211_hw *dev, struct sk_buff *skb,
-                  int free_on_tx);
+       void (*tx)(struct ieee80211_hw *dev, struct sk_buff *skb);
        int (*open)(struct ieee80211_hw *dev);
        void (*stop)(struct ieee80211_hw *dev);
        int mode;
@@ -90,6 +104,7 @@ struct p54_common {
        struct pda_channel_output_limit *output_limit;
        unsigned int output_limit_len;
        struct pda_pa_curve_data *curve_data;
+       struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS];
        unsigned int filter_flags;
        bool use_short_slot;
        u16 rxhw;
@@ -106,9 +121,7 @@ struct p54_common {
        struct ieee80211_tx_queue_stats tx_stats[8];
        struct p54_edcf_queue_param qos_params[8];
        struct ieee80211_low_level_stats stats;
-       struct timer_list stats_timer;
-       struct completion stats_comp;
-       struct sk_buff *cached_stats;
+       struct delayed_work work;
        struct sk_buff *cached_beacon;
        int noise;
        void *eeprom;
index a4e99b02af021b81f7061d4659741df6ef86860e..82354b974a04773e752307f45f393bed8a89763c 100644 (file)
@@ -335,6 +335,36 @@ static const char *p54_rf_chips[] = { "NULL", "Duette3", "Duette2",
                               "Frisbee", "Xbow", "Longbow", "NULL", "NULL" };
 static int p54_init_xbow_synth(struct ieee80211_hw *dev);
 
+static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len,
+                            u16 type)
+{
+       struct p54_common *priv = dev->priv;
+       int offset = (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) ? 2 : 0;
+       int entry_size = sizeof(struct pda_rssi_cal_entry) + offset;
+       int num_entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2;
+       int i;
+
+       if (len != (entry_size * num_entries)) {
+               printk(KERN_ERR "%s: unknown rssi calibration data packing "
+                                " type:(%x) len:%d.\n",
+                      wiphy_name(dev->wiphy), type, len);
+
+               print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE,
+                                    data, len);
+
+               printk(KERN_ERR "%s: please report this issue.\n",
+                       wiphy_name(dev->wiphy));
+               return;
+       }
+
+       for (i = 0; i < num_entries; i++) {
+               struct pda_rssi_cal_entry *cal = data +
+                                                (offset + i * entry_size);
+               priv->rssical_db[i].mul = (s16) le16_to_cpu(cal->mul);
+               priv->rssical_db[i].add = (s16) le16_to_cpu(cal->add);
+       }
+}
+
 static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
 {
        struct p54_common *priv = dev->priv;
@@ -434,6 +464,12 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
                case PDR_HARDWARE_PLATFORM_COMPONENT_ID:
                        priv->version = *(u8 *)(entry->data + 1);
                        break;
+               case PDR_RSSI_LINEAR_APPROXIMATION:
+               case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND:
+               case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED:
+                       p54_parse_rssical(dev, entry->data, data_len,
+                                         le16_to_cpu(entry->code));
+                       break;
                case PDR_END:
                        /* make it overrun */
                        entry_len = len;
@@ -453,10 +489,7 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
                case PDR_DEFAULT_COUNTRY:
                case PDR_ANTENNA_GAIN:
                case PDR_PRISM_INDIGO_PA_CALIBRATION_DATA:
-               case PDR_RSSI_LINEAR_APPROXIMATION:
-               case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND:
                case PDR_REGULATORY_POWER_LIMITS:
-               case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED:
                case PDR_RADIATED_TRANSMISSION_CORRECTION:
                case PDR_PRISM_TX_IQ_CALIBRATION:
                case PDR_BASEBAND_REGISTERS:
@@ -527,8 +560,11 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
 
 static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi)
 {
-       /* TODO: get the rssi_add & rssi_mul data from the eeprom */
-       return ((rssi * 0x83) / 64 - 400) / 4;
+       struct p54_common *priv = dev->priv;
+       int band = dev->conf.channel->band;
+
+       return ((rssi * priv->rssical_db[band].mul) / 64 +
+                        priv->rssical_db[band].add) / 4;
 }
 
 static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
@@ -589,6 +625,9 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
 
        ieee80211_rx_irqsafe(dev, skb, &rx_status);
 
+       queue_delayed_work(dev->workqueue, &priv->work,
+                          msecs_to_jiffies(P54_STATISTICS_UPDATE));
+
        return -1;
 }
 
@@ -644,7 +683,7 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
                freed = priv->rx_end - last_addr;
        __skb_unlink(skb, &priv->tx_queue);
        spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
-       kfree_skb(skb);
+       dev_kfree_skb_any(skb);
 
        if (freed >= priv->headroom + sizeof(struct p54_hdr) + 48 +
                     IEEE80211_MAX_RTS_THRESHOLD + priv->tailroom)
@@ -652,6 +691,27 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
 }
 EXPORT_SYMBOL_GPL(p54_free_skb);
 
+static struct sk_buff *p54_find_tx_entry(struct ieee80211_hw *dev,
+                                          __le32 req_id)
+{
+       struct p54_common *priv = dev->priv;
+       struct sk_buff *entry = priv->tx_queue.next;
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->tx_queue.lock, flags);
+       while (entry != (struct sk_buff *)&priv->tx_queue) {
+               struct p54_hdr *hdr = (struct p54_hdr *) entry->data;
+
+               if (hdr->req_id == req_id) {
+                       spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
+                       return entry;
+               }
+               entry = entry->next;
+       }
+       spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
+       return NULL;
+}
+
 static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct p54_common *priv = dev->priv;
@@ -696,6 +756,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
                entry_hdr = (struct p54_hdr *) entry->data;
                entry_data = (struct p54_tx_data *) entry_hdr->data;
                priv->tx_stats[entry_data->hw_queue].len--;
+               priv->stats.dot11ACKFailureCount += payload->tries - 1;
 
                if (unlikely(entry == priv->cached_beacon)) {
                        kfree_skb(entry);
@@ -775,8 +836,12 @@ static void p54_rx_stats(struct ieee80211_hw *dev, struct sk_buff *skb)
        struct p54_common *priv = dev->priv;
        struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
        struct p54_statistics *stats = (struct p54_statistics *) hdr->data;
-       u32 tsf32 = le32_to_cpu(stats->tsf32);
+       u32 tsf32;
 
+       if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED))
+               return ;
+
+       tsf32 = le32_to_cpu(stats->tsf32);
        if (tsf32 < priv->tsf_low32)
                priv->tsf_high32++;
        priv->tsf_low32 = tsf32;
@@ -786,9 +851,8 @@ static void p54_rx_stats(struct ieee80211_hw *dev, struct sk_buff *skb)
        priv->stats.dot11FCSErrorCount = le32_to_cpu(stats->rx_bad_fcs);
 
        priv->noise = p54_rssi_to_dbm(dev, le32_to_cpu(stats->noise));
-       complete(&priv->stats_comp);
 
-       mod_timer(&priv->stats_timer, jiffies + 5 * HZ);
+       p54_free_skb(dev, p54_find_tx_entry(dev, hdr->req_id));
 }
 
 static void p54_rx_trap(struct ieee80211_hw *dev, struct sk_buff *skb)
@@ -897,6 +961,8 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
                 * have a few spare slots for control frames left.
                 */
                ieee80211_stop_queues(dev);
+               queue_delayed_work(dev->workqueue, &priv->work,
+                                  msecs_to_jiffies(P54_TX_TIMEOUT));
 
                if (unlikely(left == 32)) {
                        /*
@@ -1022,7 +1088,7 @@ int p54_read_eeprom(struct ieee80211_hw *dev)
                        eeprom_hdr->v2.magic2 = 0xf;
                        memcpy(eeprom_hdr->v2.magic, (const char *)"LOCK", 4);
                }
-               priv->tx(dev, skb, 0);
+               priv->tx(dev, skb);
 
                if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) {
                        printk(KERN_ERR "%s: device does not respond!\n",
@@ -1063,7 +1129,7 @@ static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
        tim = (struct p54_tim *) skb_put(skb, sizeof(*tim));
        tim->count = 1;
        tim->entry[0] = cpu_to_le16(set ? (sta->aid | 0x8000) : sta->aid);
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        return 0;
 }
 
@@ -1081,7 +1147,7 @@ static int p54_sta_unlock(struct ieee80211_hw *dev, u8 *addr)
 
        sta = (struct p54_sta_unlock *)skb_put(skb, sizeof(*sta));
        memcpy(sta->addr, addr, ETH_ALEN);
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        return 0;
 }
 
@@ -1124,7 +1190,7 @@ static int p54_tx_cancel(struct ieee80211_hw *dev, struct sk_buff *entry)
        hdr = (void *)entry->data;
        cancel = (struct p54_txcancel *)skb_put(skb, sizeof(*cancel));
        cancel->req_id = hdr->req_id;
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        return 0;
 }
 
@@ -1353,7 +1419,11 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
        /* modifies skb->cb and with it info, so must be last! */
        if (unlikely(p54_assign_address(dev, skb, hdr, skb->len + tim_len)))
                goto err;
-       priv->tx(dev, skb, 0);
+       priv->tx(dev, skb);
+
+       queue_delayed_work(dev->workqueue, &priv->work,
+                          msecs_to_jiffies(P54_TX_FRAME_LIFETIME));
+
        return 0;
 
  err:
@@ -1428,19 +1498,19 @@ static int p54_setup_mac(struct ieee80211_hw *dev)
                setup->v2.lpf_bandwidth = cpu_to_le16(65535);
                setup->v2.osc_start_delay = cpu_to_le16(65535);
        }
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        return 0;
 }
 
-static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell,
-                   u16 frequency)
+static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell)
 {
        struct p54_common *priv = dev->priv;
        struct sk_buff *skb;
        struct p54_scan *chan;
        unsigned int i;
        void *entry;
-       __le16 freq = cpu_to_le16(frequency);
+       __le16 freq = cpu_to_le16(dev->conf.channel->center_freq);
+       int band = dev->conf.channel->band;
 
        skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*chan) +
                            sizeof(struct p54_hdr), P54_CONTROL_TYPE_SCAN,
@@ -1501,15 +1571,15 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell,
        }
 
        if (priv->fw_var < 0x500) {
-               chan->v1.rssical_mul = cpu_to_le16(130);
-               chan->v1.rssical_add = cpu_to_le16(0xfe70);
+               chan->v1_rssi.mul = cpu_to_le16(priv->rssical_db[band].mul);
+               chan->v1_rssi.add = cpu_to_le16(priv->rssical_db[band].add);
        } else {
-               chan->v2.rssical_mul = cpu_to_le16(130);
-               chan->v2.rssical_add = cpu_to_le16(0xfe70);
+               chan->v2.rssi.mul = cpu_to_le16(priv->rssical_db[band].mul);
+               chan->v2.rssi.add = cpu_to_le16(priv->rssical_db[band].add);
                chan->v2.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
                memset(chan->v2.rts_rates, 0, 8);
        }
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        return 0;
 
  err:
@@ -1535,7 +1605,7 @@ static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act)
        led->led_permanent = cpu_to_le16(link);
        led->led_temporary = cpu_to_le16(act);
        led->duration = cpu_to_le16(1000);
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        return 0;
 }
 
@@ -1575,21 +1645,7 @@ static int p54_set_edcf(struct ieee80211_hw *dev)
        edcf->flags = 0;
        memset(edcf->mapping, 0, sizeof(edcf->mapping));
        memcpy(edcf->queue, priv->qos_params, sizeof(edcf->queue));
-       priv->tx(dev, skb, 1);
-       return 0;
-}
-
-static int p54_init_stats(struct ieee80211_hw *dev)
-{
-       struct p54_common *priv = dev->priv;
-
-       priv->cached_stats = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL,
-                       sizeof(struct p54_hdr) + sizeof(struct p54_statistics),
-                       P54_CONTROL_TYPE_STAT_READBACK, GFP_KERNEL);
-       if (!priv->cached_stats)
-                       return -ENOMEM;
-
-       mod_timer(&priv->stats_timer, jiffies + HZ);
+       priv->tx(dev, skb);
        return 0;
 }
 
@@ -1684,9 +1740,6 @@ static int p54_start(struct ieee80211_hw *dev)
        P54_SET_QUEUE(priv->qos_params[2], 0x0003, 0x000f, 0x03ff, 0);
        P54_SET_QUEUE(priv->qos_params[3], 0x0007, 0x000f, 0x03ff, 0);
        err = p54_set_edcf(dev);
-       if (err)
-               goto out;
-       err = p54_init_stats(dev);
        if (err)
                goto out;
 
@@ -1698,6 +1751,8 @@ static int p54_start(struct ieee80211_hw *dev)
                goto out;
        }
 
+       queue_delayed_work(dev->workqueue, &priv->work, 0);
+
 out:
        mutex_unlock(&priv->conf_mutex);
        return err;
@@ -1710,9 +1765,7 @@ static void p54_stop(struct ieee80211_hw *dev)
 
        mutex_lock(&priv->conf_mutex);
        priv->mode = NL80211_IFTYPE_UNSPECIFIED;
-       del_timer(&priv->stats_timer);
-       p54_free_skb(dev, priv->cached_stats);
-       priv->cached_stats = NULL;
+       cancel_delayed_work_sync(&priv->work);
        if (priv->cached_beacon)
                p54_tx_cancel(dev, priv->cached_beacon);
 
@@ -1784,8 +1837,7 @@ static int p54_config(struct ieee80211_hw *dev, u32 changed)
                        goto out;
        }
        if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               ret = p54_scan(dev, P54_SCAN_EXIT, 0,
-                              conf->channel->center_freq);
+               ret = p54_scan(dev, P54_SCAN_EXIT, 0);
                if (ret)
                        goto out;
        }
@@ -1811,8 +1863,7 @@ static int p54_config_interface(struct ieee80211_hw *dev,
        }
 
        if (conf->changed & IEEE80211_IFCC_BEACON) {
-               ret = p54_scan(dev, P54_SCAN_EXIT, 0,
-                              dev->conf.channel->center_freq);
+               ret = p54_scan(dev, P54_SCAN_EXIT, 0);
                if (ret)
                        goto out;
                ret = p54_setup_mac(dev);
@@ -1885,18 +1936,33 @@ static int p54_init_xbow_synth(struct ieee80211_hw *dev)
        xbow->magic2 = cpu_to_le16(0x2);
        xbow->freq = cpu_to_le16(5390);
        memset(xbow->padding, 0, sizeof(xbow->padding));
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        return 0;
 }
 
-static void p54_statistics_timer(unsigned long data)
+static void p54_work(struct work_struct *work)
 {
-       struct ieee80211_hw *dev = (struct ieee80211_hw *) data;
-       struct p54_common *priv = dev->priv;
+       struct p54_common *priv = container_of(work, struct p54_common,
+                                              work.work);
+       struct ieee80211_hw *dev = priv->hw;
+       struct sk_buff *skb;
 
-       BUG_ON(!priv->cached_stats);
+       if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED))
+               return ;
+
+       /*
+        * TODO: walk through tx_queue and do the following tasks
+        *      1. initiate bursts.
+        *      2. cancel stuck frames / reset the device if necessary.
+        */
 
-       priv->tx(dev, priv->cached_stats, 0);
+       skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(struct p54_hdr) +
+                           sizeof(struct p54_statistics),
+                           P54_CONTROL_TYPE_STAT_READBACK, GFP_KERNEL);
+       if (!skb)
+               return ;
+
+       priv->tx(dev, skb);
 }
 
 static int p54_get_stats(struct ieee80211_hw *dev,
@@ -1904,17 +1970,7 @@ static int p54_get_stats(struct ieee80211_hw *dev,
 {
        struct p54_common *priv = dev->priv;
 
-       del_timer(&priv->stats_timer);
-       p54_statistics_timer((unsigned long)dev);
-
-       if (!wait_for_completion_interruptible_timeout(&priv->stats_comp, HZ)) {
-               printk(KERN_ERR "%s: device does not respond!\n",
-                       wiphy_name(dev->wiphy));
-               return -EBUSY;
-       }
-
        memcpy(stats, &priv->stats, sizeof(*stats));
-
        return 0;
 }
 
@@ -1946,8 +2002,7 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev,
                        priv->basic_rate_mask = info->basic_rates;
                p54_setup_mac(dev);
                if (priv->fw_var >= 0x500)
-                       p54_scan(dev, P54_SCAN_EXIT, 0,
-                                dev->conf.channel->center_freq);
+                       p54_scan(dev, P54_SCAN_EXIT, 0);
        }
        if (changed & BSS_CHANGED_ASSOC) {
                if (info->assoc) {
@@ -2039,7 +2094,7 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
                        [NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]), 8);
        }
 
-       priv->tx(dev, skb, 1);
+       priv->tx(dev, skb);
        mutex_unlock(&priv->conf_mutex);
        return 0;
 }
@@ -2072,6 +2127,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
                return NULL;
 
        priv = dev->priv;
+       priv->hw = dev;
        priv->mode = NL80211_IFTYPE_UNSPECIFIED;
        priv->basic_rate_mask = 0x15f;
        skb_queue_head_init(&priv->tx_queue);
@@ -2107,9 +2163,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
 
        mutex_init(&priv->conf_mutex);
        init_completion(&priv->eeprom_comp);
-       init_completion(&priv->stats_comp);
-       setup_timer(&priv->stats_timer, p54_statistics_timer,
-               (unsigned long)dev);
+       INIT_DELAYED_WORK(&priv->work, p54_work);
 
        return dev;
 }
@@ -2118,8 +2172,6 @@ EXPORT_SYMBOL_GPL(p54_init_common);
 void p54_free_common(struct ieee80211_hw *dev)
 {
        struct p54_common *priv = dev->priv;
-       del_timer(&priv->stats_timer);
-       kfree_skb(priv->cached_stats);
        kfree(priv->iq_autocal);
        kfree(priv->output_limit);
        kfree(priv->curve_data);
index 5a68fdae77305f31e3710e77c39d6f9a4114f72a..f5729de83fe118eaeb36ea55c9f9cecdacd2c40b 100644 (file)
@@ -84,9 +84,6 @@ struct bootrec_desc {
 #define BR_CODE_END_OF_BRA             0xFF0000FF
 #define LEGACY_BR_CODE_END_OF_BRA      0xFFFFFFFF
 
-#define P54_HDR_FLAG_CONTROL           BIT(15)
-#define P54_HDR_FLAG_CONTROL_OPSET     (BIT(15) + BIT(0))
-
 #define P54_HDR_FLAG_DATA_ALIGN                BIT(14)
 #define P54_HDR_FLAG_DATA_OUT_PROMISC  BIT(0)
 #define P54_HDR_FLAG_DATA_OUT_TIMESTAMP BIT(1)
@@ -178,6 +175,11 @@ struct pda_pa_curve_data {
        u8 data[0];
 } __attribute__ ((packed));
 
+struct pda_rssi_cal_entry {
+       __le16 mul;
+       __le16 add;
+} __attribute__ ((packed));
+
 /*
  * this defines the PDR codes used to build PDAs as defined in document
  * number 553155. The current implementation mirrors version 1.1 of the
@@ -355,6 +357,11 @@ struct p54_tx_data {
        u8 align[0];
 } __attribute__ ((packed));
 
+/* unit is ms */
+#define P54_TX_FRAME_LIFETIME 2000
+#define P54_TX_TIMEOUT 4000
+#define P54_STATISTICS_UPDATE 5000
+
 #define P54_FILTER_TYPE_NONE           0
 #define P54_FILTER_TYPE_STATION                BIT(0)
 #define P54_FILTER_TYPE_IBSS           BIT(1)
@@ -424,22 +431,18 @@ struct p54_scan {
        u8 dup_16qam;
        u8 dup_64qam;
        union {
-               struct {
-                       __le16 rssical_mul;
-                       __le16 rssical_add;
-               } v1 __attribute__ ((packed));
+               struct pda_rssi_cal_entry v1_rssi;
 
                struct {
                        __le32 basic_rate_mask;
                        u8 rts_rates[8];
-                       __le16 rssical_mul;
-                       __le16 rssical_add;
+                       struct pda_rssi_cal_entry rssi;
                } v2 __attribute__ ((packed));
        } __attribute__ ((packed));
 } __attribute__ ((packed));
 
-#define P54_SCAN_V1_LEN (sizeof(struct p54_scan)-12)
-#define P54_SCAN_V2_LEN (sizeof(struct p54_scan))
+#define P54_SCAN_V1_LEN 0x70
+#define P54_SCAN_V2_LEN 0x7c
 
 struct p54_led {
        __le16 mode;
index c28220e401b94578c85f1f25b243f464232d1cf3..aa367a0ddc49139ac51a097730a0f464d97c24e0 100644 (file)
@@ -227,7 +227,9 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
 
        while (i != idx) {
                desc = &ring[i];
-               p54_free_skb(dev, tx_buf[i]);
+               if (tx_buf[i])
+                       if (FREE_AFTER_TX((struct sk_buff *) tx_buf[i]))
+                               p54_free_skb(dev, tx_buf[i]);
                tx_buf[i] = NULL;
 
                pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
@@ -298,8 +300,7 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id)
        return reg ? IRQ_HANDLED : IRQ_NONE;
 }
 
-static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
-                   int free_on_tx)
+static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct p54p_priv *priv = dev->priv;
        struct p54p_ring_control *ring_control = priv->ring_control;
@@ -314,6 +315,7 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
        idx = le32_to_cpu(ring_control->host_idx[1]);
        i = idx % ARRAY_SIZE(ring_control->tx_data);
 
+       priv->tx_buf_data[i] = skb;
        mapping = pci_map_single(priv->pdev, skb->data, skb->len,
                                 PCI_DMA_TODEVICE);
        desc = &ring_control->tx_data[i];
@@ -324,10 +326,6 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
 
        wmb();
        ring_control->host_idx[1] = cpu_to_le32(idx + 1);
-
-       if (free_on_tx)
-               priv->tx_buf_data[i] = skb;
-
        spin_unlock_irqrestore(&priv->lock, flags);
 
        P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
index c2789e53b9845629f8d9b5eaef9e2f37febdda13..c44a200059d21c4ce0aae4a6f66b2e61af73984e 100644 (file)
@@ -138,22 +138,16 @@ static void p54u_rx_cb(struct urb *urb)
        }
 }
 
-static void p54u_tx_reuse_skb_cb(struct urb *urb)
-{
-       struct sk_buff *skb = urb->context;
-       struct p54u_priv *priv = (struct p54u_priv *)((struct ieee80211_hw *)
-               usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)))->priv;
-
-       skb_pull(skb, priv->common.tx_hdr_len);
-}
-
-static void p54u_tx_free_skb_cb(struct urb *urb)
+static void p54u_tx_cb(struct urb *urb)
 {
        struct sk_buff *skb = urb->context;
        struct ieee80211_hw *dev = (struct ieee80211_hw *)
                usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+       struct p54u_priv *priv = dev->priv;
 
-       p54_free_skb(dev, skb);
+       skb_pull(skb, priv->common.tx_hdr_len);
+       if (FREE_AFTER_TX(skb))
+               p54_free_skb(dev, skb);
 }
 
 static void p54u_tx_dummy_cb(struct urb *urb) { }
@@ -213,8 +207,7 @@ static int p54u_init_urbs(struct ieee80211_hw *dev)
        return ret;
 }
 
-static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb,
-                        int free_on_tx)
+static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct p54u_priv *priv = dev->priv;
        struct urb *addr_urb, *data_urb;
@@ -236,9 +229,7 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb,
                          p54u_tx_dummy_cb, dev);
        usb_fill_bulk_urb(data_urb, priv->udev,
                          usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
-                         skb->data, skb->len,
-                         free_on_tx ? p54u_tx_free_skb_cb :
-                                      p54u_tx_reuse_skb_cb, skb);
+                         skb->data, skb->len, p54u_tx_cb, skb);
 
        usb_anchor_urb(addr_urb, &priv->submitted);
        err = usb_submit_urb(addr_urb, GFP_ATOMIC);
@@ -273,8 +264,7 @@ static __le32 p54u_lm87_chksum(const __le32 *data, size_t length)
        return cpu_to_le32(chk);
 }
 
-static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb,
-                        int free_on_tx)
+static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct p54u_priv *priv = dev->priv;
        struct urb *data_urb;
@@ -293,9 +283,7 @@ static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb,
 
        usb_fill_bulk_urb(data_urb, priv->udev,
                          usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
-                         skb->data, skb->len,
-                         free_on_tx ? p54u_tx_free_skb_cb :
-                                      p54u_tx_reuse_skb_cb, skb);
+                         skb->data, skb->len, p54u_tx_cb, skb);
 
        usb_anchor_urb(data_urb, &priv->submitted);
        if (usb_submit_urb(data_urb, GFP_ATOMIC)) {
@@ -306,14 +294,15 @@ static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb,
        usb_free_urb(data_urb);
 }
 
-static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb,
-                           int free_on_tx)
+static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct p54u_priv *priv = dev->priv;
        struct urb *int_urb, *data_urb;
        struct net2280_tx_hdr *hdr;
        struct net2280_reg_write *reg;
        int err = 0;
+       __le32 addr = ((struct p54_hdr *) skb->data)->req_id;
+       __le16 len = cpu_to_le16(skb->len);
 
        reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
        if (!reg)
@@ -338,8 +327,8 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb,
 
        hdr = (void *)skb_push(skb, sizeof(*hdr));
        memset(hdr, 0, sizeof(*hdr));
-       hdr->device_addr = ((struct p54_hdr *)skb->data)->req_id;
-       hdr->len = cpu_to_le16(skb->len + sizeof(struct p54_hdr));
+       hdr->len = len;
+       hdr->device_addr = addr;
 
        usb_fill_bulk_urb(int_urb, priv->udev,
                usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
@@ -354,9 +343,7 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb,
 
        usb_fill_bulk_urb(data_urb, priv->udev,
                          usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
-                         skb->data, skb->len,
-                         free_on_tx ? p54u_tx_free_skb_cb :
-                                      p54u_tx_reuse_skb_cb, skb);
+                         skb->data, skb->len, p54u_tx_cb, skb);
 
        usb_anchor_urb(int_urb, &priv->submitted);
        err = usb_submit_urb(int_urb, GFP_ATOMIC);
index 74f5449b7924a01e4d0c8d3caa4fd739734da232..00ce3ef39abe6e496de43fa10edaf3e3dd97858a 100644 (file)
@@ -213,7 +213,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
        urb = usb_alloc_urb(0, GFP_ATOMIC);
        if (!urb) {
                kfree_skb(skb);
-               return 0;
+               return -ENOMEM;
        }
 
        flags = skb->len;
@@ -281,7 +281,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
        }
        usb_free_urb(urb);
 
-       return 0;
+       return rc;
 }
 
 static void rtl8187_rx_cb(struct urb *urb)
@@ -294,15 +294,16 @@ static void rtl8187_rx_cb(struct urb *urb)
        int rate, signal;
        u32 flags;
        u32 quality;
+       unsigned long f;
 
-       spin_lock(&priv->rx_queue.lock);
+       spin_lock_irqsave(&priv->rx_queue.lock, f);
        if (skb->next)
                __skb_unlink(skb, &priv->rx_queue);
        else {
-               spin_unlock(&priv->rx_queue.lock);
+               spin_unlock_irqrestore(&priv->rx_queue.lock, f);
                return;
        }
-       spin_unlock(&priv->rx_queue.lock);
+       spin_unlock_irqrestore(&priv->rx_queue.lock, f);
        skb_put(skb, urb->actual_length);
 
        if (unlikely(urb->status)) {
@@ -942,7 +943,6 @@ static int rtl8187_start(struct ieee80211_hw *dev)
 static void rtl8187_stop(struct ieee80211_hw *dev)
 {
        struct rtl8187_priv *priv = dev->priv;
-       struct rtl8187_rx_info *info;
        struct sk_buff *skb;
        u32 reg;
 
@@ -961,10 +961,6 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
        rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF);
        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 
-       while ((skb = skb_dequeue(&priv->rx_queue))) {
-               info = (struct rtl8187_rx_info *)skb->cb;
-               kfree_skb(skb);
-       }
        while ((skb = skb_dequeue(&priv->b_tx_status.queue)))
                dev_kfree_skb_any(skb);
 
index fe376fde4e897ec7fd096fcc8f337e3405a75905..761635be9104f155af6978a72a8283ebec2cde9e 100644 (file)
@@ -196,7 +196,7 @@ static void rx_refill_timeout(unsigned long data)
 {
        struct net_device *dev = (struct net_device *)data;
        struct netfront_info *np = netdev_priv(dev);
-       netif_rx_schedule(dev, &np->napi);
+       netif_rx_schedule(&np->napi);
 }
 
 static int netfront_tx_slot_available(struct netfront_info *np)
@@ -328,7 +328,7 @@ static int xennet_open(struct net_device *dev)
                xennet_alloc_rx_buffers(dev);
                np->rx.sring->rsp_event = np->rx.rsp_cons + 1;
                if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
-                       netif_rx_schedule(dev, &np->napi);
+                       netif_rx_schedule(&np->napi);
        }
        spin_unlock_bh(&np->rx_lock);
 
@@ -979,7 +979,7 @@ err:
 
                RING_FINAL_CHECK_FOR_RESPONSES(&np->rx, more_to_do);
                if (!more_to_do)
-                       __netif_rx_complete(dev, napi);
+                       __netif_rx_complete(napi);
 
                local_irq_restore(flags);
        }
@@ -1310,7 +1310,7 @@ static irqreturn_t xennet_interrupt(int irq, void *dev_id)
                xennet_tx_buf_gc(dev);
                /* Under tx_lock: protects access to rx shared-ring indexes. */
                if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
-                       netif_rx_schedule(dev, &np->napi);
+                       netif_rx_schedule(&np->napi);
        }
 
        spin_unlock_irqrestore(&np->tx_lock, flags);
index e73a61449ad6dacabc99a2e2372252b8732396fe..b0ef274e00319d575082168ef3bb763fdf6447b9 100644 (file)
@@ -305,6 +305,8 @@ enum dcbnl_bcn_attrs{
        DCB_BCN_ATTR_RP_7,
        DCB_BCN_ATTR_RP_ALL,
 
+       DCB_BCN_ATTR_BCNA_0,
+       DCB_BCN_ATTR_BCNA_1,
        DCB_BCN_ATTR_ALPHA,
        DCB_BCN_ATTR_BETA,
        DCB_BCN_ATTR_GD,
index 58856b6737fb65087d88bfe15d2b7fe129262581..41e1224651cf98dacc97acf74d999a7c89233ec4 100644 (file)
@@ -1555,8 +1555,7 @@ static inline u32 netif_msg_init(int debug_value, int default_msg_enable_bits)
 }
 
 /* Test if receive needs to be scheduled but only if up */
-static inline int netif_rx_schedule_prep(struct net_device *dev,
-                                        struct napi_struct *napi)
+static inline int netif_rx_schedule_prep(struct napi_struct *napi)
 {
        return napi_schedule_prep(napi);
 }
@@ -1564,27 +1563,24 @@ static inline int netif_rx_schedule_prep(struct net_device *dev,
 /* Add interface to tail of rx poll list. This assumes that _prep has
  * already been called and returned 1.
  */
-static inline void __netif_rx_schedule(struct net_device *dev,
-                                      struct napi_struct *napi)
+static inline void __netif_rx_schedule(struct napi_struct *napi)
 {
        __napi_schedule(napi);
 }
 
 /* Try to reschedule poll. Called by irq handler. */
 
-static inline void netif_rx_schedule(struct net_device *dev,
-                                    struct napi_struct *napi)
+static inline void netif_rx_schedule(struct napi_struct *napi)
 {
-       if (netif_rx_schedule_prep(dev, napi))
-               __netif_rx_schedule(dev, napi);
+       if (netif_rx_schedule_prep(napi))
+               __netif_rx_schedule(napi);
 }
 
 /* Try to reschedule poll. Called by dev->poll() after netif_rx_complete().  */
-static inline int netif_rx_reschedule(struct net_device *dev,
-                                     struct napi_struct *napi)
+static inline int netif_rx_reschedule(struct napi_struct *napi)
 {
        if (napi_schedule_prep(napi)) {
-               __netif_rx_schedule(dev, napi);
+               __netif_rx_schedule(napi);
                return 1;
        }
        return 0;
@@ -1593,8 +1589,7 @@ static inline int netif_rx_reschedule(struct net_device *dev,
 /* same as netif_rx_complete, except that local_irq_save(flags)
  * has already been issued
  */
-static inline void __netif_rx_complete(struct net_device *dev,
-                                      struct napi_struct *napi)
+static inline void __netif_rx_complete(struct napi_struct *napi)
 {
        __napi_complete(napi);
 }
@@ -1604,8 +1599,7 @@ static inline void __netif_rx_complete(struct net_device *dev,
  * it completes the work. The device cannot be out of poll list at this
  * moment, it is BUG().
  */
-static inline void netif_rx_complete(struct net_device *dev,
-                                    struct napi_struct *napi)
+static inline void netif_rx_complete(struct napi_struct *napi)
 {
        napi_complete(napi);
 }
index 04d4516f9c712e91f4aaf541015c93d61abd9b25..e86ed59f9ad59b25317ce2be2f084a73063704c5 100644 (file)
@@ -201,13 +201,13 @@ enum nl80211_commands {
  * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming)
  * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters
  * @NL80211_ATTR_WIPHY_FREQ: frequency of the selected channel in MHz
- * @NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET: included with NL80211_ATTR_WIPHY_FREQ
+ * @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ
  *     if HT20 or HT40 are allowed (i.e., 802.11n disabled if not included):
- *     NL80211_SEC_CHAN_NO_HT = HT not allowed (i.e., same as not including
+ *     NL80211_CHAN_NO_HT = HT not allowed (i.e., same as not including
  *             this attribute)
- *     NL80211_SEC_CHAN_DISABLED = HT20 only
- *     NL80211_SEC_CHAN_BELOW = secondary channel is below the primary channel
- *     NL80211_SEC_CHAN_ABOVE = secondary channel is above the primary channel
+ *     NL80211_CHAN_HT20 = HT20 only
+ *     NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel
+ *     NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel
  *
  * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on
  * @NL80211_ATTR_IFNAME: network interface name
@@ -344,7 +344,7 @@ enum nl80211_attrs {
 
        NL80211_ATTR_WIPHY_TXQ_PARAMS,
        NL80211_ATTR_WIPHY_FREQ,
-       NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET,
+       NL80211_ATTR_WIPHY_CHANNEL_TYPE,
 
        /* add attributes here, update the policy in nl80211.c */
 
@@ -424,6 +424,32 @@ enum nl80211_sta_flags {
        NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1
 };
 
+/**
+ * enum nl80211_rate_info - bitrate information
+ *
+ * These attribute types are used with %NL80211_STA_INFO_TXRATE
+ * when getting information about the bitrate of a station.
+ *
+ * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved
+ * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s)
+ * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8)
+ * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate
+ * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval
+ * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined
+ * @__NL80211_RATE_INFO_AFTER_LAST: internal use
+ */
+enum nl80211_rate_info {
+       __NL80211_RATE_INFO_INVALID,
+       NL80211_RATE_INFO_BITRATE,
+       NL80211_RATE_INFO_MCS,
+       NL80211_RATE_INFO_40_MHZ_WIDTH,
+       NL80211_RATE_INFO_SHORT_GI,
+
+       /* keep last */
+       __NL80211_RATE_INFO_AFTER_LAST,
+       NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST - 1
+};
+
 /**
  * enum nl80211_sta_info - station information
  *
@@ -436,6 +462,9 @@ enum nl80211_sta_flags {
  * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station)
  * @__NL80211_STA_INFO_AFTER_LAST: internal
  * @NL80211_STA_INFO_MAX: highest possible station info attribute
+ * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm)
+ * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute
+ *     containing info as possible, see &enum nl80211_sta_info_txrate.
  */
 enum nl80211_sta_info {
        __NL80211_STA_INFO_INVALID,
@@ -445,6 +474,8 @@ enum nl80211_sta_info {
        NL80211_STA_INFO_LLID,
        NL80211_STA_INFO_PLID,
        NL80211_STA_INFO_PLINK_STATE,
+       NL80211_STA_INFO_SIGNAL,
+       NL80211_STA_INFO_TX_BITRATE,
 
        /* keep last */
        __NL80211_STA_INFO_AFTER_LAST,
@@ -774,10 +805,10 @@ enum nl80211_txq_q {
        NL80211_TXQ_Q_BK
 };
 
-enum nl80211_sec_chan_offset {
-       NL80211_SEC_CHAN_NO_HT /* No HT */,
-       NL80211_SEC_CHAN_DISABLED /* HT20 only */,
-       NL80211_SEC_CHAN_BELOW /* HT40- */,
-       NL80211_SEC_CHAN_ABOVE /* HT40+ */
+enum nl80211_channel_type {
+       NL80211_CHAN_NO_HT,
+       NL80211_CHAN_HT20,
+       NL80211_CHAN_HT40MINUS,
+       NL80211_CHAN_HT40PLUS
 };
 #endif /* __LINUX_NL80211_H */
index a0c0bf19496ca40d3a6a6e2fa5b9c2bed2ba3487..23c0ab74ded63bfbc9f57a36751872be3e195f77 100644 (file)
@@ -169,6 +169,9 @@ struct station_parameters {
  * @STATION_INFO_LLID: @llid filled
  * @STATION_INFO_PLID: @plid filled
  * @STATION_INFO_PLINK_STATE: @plink_state filled
+ * @STATION_INFO_SIGNAL: @signal filled
+ * @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled
+ *  (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs)
  */
 enum station_info_flags {
        STATION_INFO_INACTIVE_TIME      = 1<<0,
@@ -177,6 +180,39 @@ enum station_info_flags {
        STATION_INFO_LLID               = 1<<3,
        STATION_INFO_PLID               = 1<<4,
        STATION_INFO_PLINK_STATE        = 1<<5,
+       STATION_INFO_SIGNAL             = 1<<6,
+       STATION_INFO_TX_BITRATE         = 1<<7,
+};
+
+/**
+ * enum station_info_rate_flags - bitrate info flags
+ *
+ * Used by the driver to indicate the specific rate transmission
+ * type for 802.11n transmissions.
+ *
+ * @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled
+ * @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission
+ * @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval
+ */
+enum rate_info_flags {
+       RATE_INFO_FLAGS_MCS             = 1<<0,
+       RATE_INFO_FLAGS_40_MHZ_WIDTH    = 1<<1,
+       RATE_INFO_FLAGS_SHORT_GI        = 1<<2,
+};
+
+/**
+ * struct rate_info - bitrate information
+ *
+ * Information about a receiving or transmitting bitrate
+ *
+ * @flags: bitflag of flags from &enum rate_info_flags
+ * @mcs: mcs index if struct describes a 802.11n bitrate
+ * @legacy: bitrate in 100kbit/s for 802.11abg
+ */
+struct rate_info {
+       u8 flags;
+       u8 mcs;
+       u16 legacy;
 };
 
 /**
@@ -191,6 +227,8 @@ enum station_info_flags {
  * @llid: mesh local link id
  * @plid: mesh peer link id
  * @plink_state: mesh peer link state
+ * @signal: signal strength of last received packet in dBm
+ * @txrate: current unicast bitrate to this station
  */
 struct station_info {
        u32 filled;
@@ -200,6 +238,8 @@ struct station_info {
        u16 llid;
        u16 plid;
        u8 plink_state;
+       s8 signal;
+       struct rate_info txrate;
 };
 
 /**
@@ -523,7 +563,7 @@ struct cfg80211_ops {
 
        int     (*set_channel)(struct wiphy *wiphy,
                               struct ieee80211_channel *chan,
-                              enum nl80211_sec_chan_offset);
+                              enum nl80211_channel_type channel_type);
 };
 
 /* temporary wext handlers */
index 91e0a3d7faf236c1c0c3e54e0336dee366e74acb..775cfc8055bed122d9e54f30b83c186cccf3a185 100644 (file)
@@ -26,7 +26,7 @@
  */
 struct dcbnl_rtnl_ops {
        u8   (*getstate)(struct net_device *);
-       void (*setstate)(struct net_device *, u8);
+       u8   (*setstate)(struct net_device *, u8);
        void (*getpermhwaddr)(struct net_device *, u8 *);
        void (*setpgtccfgtx)(struct net_device *, int, u8, u8, u8, u8);
        void (*setpgbwgcfgtx)(struct net_device *, int, u8);
index 3025ae17ddbeb46207ca71e88b3d31d6aaad44a8..94c852d47d0f8d5c7d033279bf2f67ca3fd861dd 100644 (file)
@@ -135,9 +135,11 @@ struct dongle_reg {
 
 /* 
  * Per-packet information we need to hide inside sk_buff 
- * (must not exceed 48 bytes, check with struct sk_buff) 
+ * (must not exceed 48 bytes, check with struct sk_buff)
+ * The default_qdisc_pad field is a temporary hack.
  */
 struct irda_skb_cb {
+       unsigned int default_qdisc_pad;
        magic_t magic;       /* Be sure that we can trust the information */
        __u32   next_speed;  /* The Speed to be set *after* this frame */
        __u16   mtt;         /* Minimum turn around time */
index 046ce692a906a4e81c038ad789221963103b4f21..b3bd00a9d9928ce228c1e3d6e855cdf8a9b17682 100644 (file)
@@ -165,14 +165,9 @@ enum ieee80211_bss_change {
 
 /**
  * struct ieee80211_bss_ht_conf - BSS's changing HT configuration
- * @secondary_channel_offset: secondary channel offset, uses
- *     %IEEE80211_HT_PARAM_CHA_SEC_ values
- * @width_40_ok: indicates that 40 MHz bandwidth may be used for TX
  * @operation_mode: HT operation mode (like in &struct ieee80211_ht_info)
  */
 struct ieee80211_bss_ht_conf {
-       u8 secondary_channel_offset;
-       bool width_40_ok;
        u16 operation_mode;
 };
 
@@ -441,6 +436,9 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
  *     is valid. This is useful in monitor mode and necessary for beacon frames
  *     to enable IBSS merging.
  * @RX_FLAG_SHORTPRE: Short preamble was used for this frame
+ * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index
+ * @RX_FLAG_40MHZ: HT40 (40 MHz) was used
+ * @RX_FLAG_SHORT_GI: Short guard interval was used
  */
 enum mac80211_rx_flags {
        RX_FLAG_MMIC_ERROR      = 1<<0,
@@ -451,7 +449,10 @@ enum mac80211_rx_flags {
        RX_FLAG_FAILED_FCS_CRC  = 1<<5,
        RX_FLAG_FAILED_PLCP_CRC = 1<<6,
        RX_FLAG_TSFT            = 1<<7,
-       RX_FLAG_SHORTPRE        = 1<<8
+       RX_FLAG_SHORTPRE        = 1<<8,
+       RX_FLAG_HT              = 1<<9,
+       RX_FLAG_40MHZ           = 1<<10,
+       RX_FLAG_SHORT_GI        = 1<<11,
 };
 
 /**
@@ -471,7 +472,8 @@ enum mac80211_rx_flags {
  * @noise: noise when receiving this frame, in dBm.
  * @qual: overall signal quality indication, in percent (0-100).
  * @antenna: antenna used
- * @rate_idx: index of data rate into band's supported rates
+ * @rate_idx: index of data rate into band's supported rates or MCS index if
+ *     HT rates are use (RX_FLAG_HT)
  * @flag: %RX_FLAG_*
  */
 struct ieee80211_rx_status {
@@ -508,9 +510,7 @@ static inline int __deprecated __IEEE80211_CONF_SHORT_SLOT_TIME(void)
 
 struct ieee80211_ht_conf {
        bool enabled;
-       int sec_chan_offset; /* 0 = HT40 disabled; -1 = HT40 enabled, secondary
-                             * channel below primary; 1 = HT40 enabled,
-                             * secondary channel above primary */
+       enum nl80211_channel_type channel_type;
 };
 
 /**
@@ -854,6 +854,11 @@ enum ieee80211_tkip_key_type {
  *
  * @IEEE80211_HW_AMPDU_AGGREGATION:
  *     Hardware supports 11n A-MPDU aggregation.
+ *
+ * @IEEE80211_HW_NO_STACK_DYNAMIC_PS:
+ *     Hardware which has dynamic power save support, meaning
+ *     that power save is enabled in idle periods, and don't need support
+ *     from stack.
  */
 enum ieee80211_hw_flags {
        IEEE80211_HW_RX_INCLUDES_FCS                    = 1<<1,
@@ -866,6 +871,7 @@ enum ieee80211_hw_flags {
        IEEE80211_HW_NOISE_DBM                          = 1<<8,
        IEEE80211_HW_SPECTRUM_MGMT                      = 1<<9,
        IEEE80211_HW_AMPDU_AGGREGATION                  = 1<<10,
+       IEEE80211_HW_NO_STACK_DYNAMIC_PS                = 1<<11,
 };
 
 /**
index 46b7764f17740d5b2484ddf6d2c706c2218db305..8a6150a3f4c74a5a6a150947c5e1ff6ec494eca9 100644 (file)
@@ -332,7 +332,7 @@ static inline int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen)
  */
 static inline int nlmsg_ok(const struct nlmsghdr *nlh, int remaining)
 {
-       return (remaining >= sizeof(struct nlmsghdr) &&
+       return (remaining >= (int) sizeof(struct nlmsghdr) &&
                nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&
                nlh->nlmsg_len <= remaining);
 }
index f205b10f0ab95f05ec3cef5aea549991c4f0f0d7..b259fc5798fb2f909fda0cc80be04d906b3879cc 100644 (file)
@@ -118,6 +118,8 @@ enum sctp_optname {
 #define SCTP_PEER_AUTH_CHUNKS SCTP_PEER_AUTH_CHUNKS
        SCTP_LOCAL_AUTH_CHUNKS,         /* Read only */
 #define SCTP_LOCAL_AUTH_CHUNKS SCTP_LOCAL_AUTH_CHUNKS
+       SCTP_GET_ASSOC_NUMBER,          /* Read only */
+#define SCTP_GET_ASSOC_NUMBER SCTP_GET_ASSOC_NUMBER
 
 
        /* Internal Socket Options. Some of the sctp library functions are 
index 71193a6b10e6bb8ec67d3d1bb09bd1fd9be6bf31..89a3bbdfca3fe96e786044ed8ea8b5022ab4e5b1 100644 (file)
@@ -593,6 +593,8 @@ static const struct header_ops vlan_header_ops = {
        .parse   = eth_header_parse,
 };
 
+static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops;
+
 static int vlan_dev_init(struct net_device *dev)
 {
        struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
@@ -619,11 +621,11 @@ static int vlan_dev_init(struct net_device *dev)
        if (real_dev->features & NETIF_F_HW_VLAN_TX) {
                dev->header_ops      = real_dev->header_ops;
                dev->hard_header_len = real_dev->hard_header_len;
-               dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit;
+               dev->netdev_ops         = &vlan_netdev_accel_ops;
        } else {
                dev->header_ops      = &vlan_header_ops;
                dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN;
-               dev->hard_start_xmit = vlan_dev_hard_start_xmit;
+               dev->netdev_ops         = &vlan_netdev_ops;
        }
 
        if (is_vlan_dev(real_dev))
@@ -704,6 +706,22 @@ static const struct net_device_ops vlan_netdev_ops = {
        .ndo_uninit             = vlan_dev_uninit,
        .ndo_open               = vlan_dev_open,
        .ndo_stop               = vlan_dev_stop,
+       .ndo_start_xmit =  vlan_dev_hard_start_xmit,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = vlan_dev_set_mac_address,
+       .ndo_set_rx_mode        = vlan_dev_set_rx_mode,
+       .ndo_set_multicast_list = vlan_dev_set_rx_mode,
+       .ndo_change_rx_flags    = vlan_dev_change_rx_flags,
+       .ndo_do_ioctl           = vlan_dev_ioctl,
+};
+
+static const struct net_device_ops vlan_netdev_accel_ops = {
+       .ndo_change_mtu         = vlan_dev_change_mtu,
+       .ndo_init               = vlan_dev_init,
+       .ndo_uninit             = vlan_dev_uninit,
+       .ndo_open               = vlan_dev_open,
+       .ndo_stop               = vlan_dev_stop,
+       .ndo_start_xmit =  vlan_dev_hwaccel_hard_start_xmit,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = vlan_dev_set_mac_address,
        .ndo_set_rx_mode        = vlan_dev_set_rx_mode,
index c3f0027173789c56ef5af3ef9a98536449e0b7e1..5abce07fb50a195b1f280af8dbe588e2fefc2d6c 100644 (file)
@@ -815,9 +815,6 @@ static int atif_ioctl(int cmd, void __user *arg)
                                return -EPERM;
                        if (sa->sat_family != AF_APPLETALK)
                                return -EINVAL;
-                       if (!atif)
-                               return -EADDRNOTAVAIL;
-
                        /*
                         * for now, we only support proxy AARP on ELAP;
                         * we should be able to do it for LocalTalk, too.
index 37c640d1c3fd9d103a86f0445d40d0b220a833a2..acd84fd524b856c25cf1f7c40560c3a6726d7236 100644 (file)
@@ -1781,8 +1781,6 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s)
        if (err < 0)
                return;
 
-       __module_get(nsock->ops->owner);
-
        /* Set our callbacks */
        nsock->sk->sk_data_ready   = rfcomm_l2data_ready;
        nsock->sk->sk_state_change = rfcomm_l2state_change;
index 048cf1197872fca60dc12317b3dd8ccd0b11236f..daca72e6b37b12e7c8ea4d4ee5fa59e01cac1b59 100644 (file)
@@ -3745,11 +3745,13 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
 {
        int err;
        struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
-       const struct net_device_ops *ops = dev->netdev_ops;
+       const struct net_device_ops *ops;
 
        if (!dev)
                return -ENODEV;
 
+       ops = dev->netdev_ops;
+
        switch (cmd) {
                case SIOCSIFFLAGS:      /* Set interface flags */
                        return dev_change_flags(dev, ifr->ifr_flags);
index a1254061629f55a1ed3b74cc0b0ac1848ecb9224..5dbfe5fdc0d63970071945a1059d5032281071ed 100644 (file)
@@ -140,6 +140,8 @@ static struct nla_policy dcbnl_bcn_nest[DCB_BCN_ATTR_MAX + 1] = {
        [DCB_BCN_ATTR_RP_6]         = {.type = NLA_U8},
        [DCB_BCN_ATTR_RP_7]         = {.type = NLA_U8},
        [DCB_BCN_ATTR_RP_ALL]       = {.type = NLA_FLAG},
+       [DCB_BCN_ATTR_BCNA_0]       = {.type = NLA_U32},
+       [DCB_BCN_ATTR_BCNA_1]       = {.type = NLA_U32},
        [DCB_BCN_ATTR_ALPHA]        = {.type = NLA_U32},
        [DCB_BCN_ATTR_BETA]         = {.type = NLA_U32},
        [DCB_BCN_ATTR_GD]           = {.type = NLA_U32},
@@ -714,9 +716,8 @@ static int dcbnl_setstate(struct net_device *netdev, struct nlattr **tb,
 
        value = nla_get_u8(tb[DCB_ATTR_STATE]);
 
-       netdev->dcbnl_ops->setstate(netdev, value);
-
-       ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_SSTATE, DCB_ATTR_STATE,
+       ret = dcbnl_reply(netdev->dcbnl_ops->setstate(netdev, value),
+                         RTM_SETDCB, DCB_CMD_SSTATE, DCB_ATTR_STATE,
                          pid, seq, flags);
 
        return ret;
@@ -923,7 +924,7 @@ static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlattr **tb,
                        goto err_bcn;
        }
 
-       for (i = DCB_BCN_ATTR_ALPHA; i <= DCB_BCN_ATTR_RI; i++) {
+       for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) {
                if (!getall && !bcn_tb[i])
                        continue;
 
@@ -981,7 +982,7 @@ static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlattr **tb,
                        data[i]->nla_type - DCB_BCN_ATTR_RP_0, value_byte);
        }
 
-       for (i = DCB_BCN_ATTR_ALPHA; i <= DCB_BCN_ATTR_RI; i++) {
+       for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) {
                if (data[i] == NULL)
                        continue;
                value_int = nla_get_u32(data[i]);
index 664ff0ee1c8347d0276aa81a632cb5048f70c559..743f5542d65a6385c7ae423ddb49d4c69daaeaee 100644 (file)
@@ -1402,6 +1402,7 @@ EXPORT_SYMBOL_GPL(snmp_mib_free);
 #ifdef CONFIG_IP_MULTICAST
 static struct net_protocol igmp_protocol = {
        .handler =      igmp_rcv,
+       .netns_ok =     1,
 };
 #endif
 
index f92733e15c9fc3300dd1aeb66bc99e2a9da37c17..9eb6219af615af2327daef1ec461e3b1fdb16500 100644 (file)
@@ -2275,6 +2275,7 @@ int ip_check_mc(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u16 p
 
 #if defined(CONFIG_PROC_FS)
 struct igmp_mc_iter_state {
+       struct seq_net_private p;
        struct net_device *dev;
        struct in_device *in_dev;
 };
@@ -2283,11 +2284,12 @@ struct igmp_mc_iter_state {
 
 static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq)
 {
+       struct net *net = seq_file_net(seq);
        struct ip_mc_list *im = NULL;
        struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
 
        state->in_dev = NULL;
-       for_each_netdev(&init_net, state->dev) {
+       for_each_netdev(net, state->dev) {
                struct in_device *in_dev;
                in_dev = in_dev_get(state->dev);
                if (!in_dev)
@@ -2408,7 +2410,7 @@ static const struct seq_operations igmp_mc_seq_ops = {
 
 static int igmp_mc_seq_open(struct inode *inode, struct file *file)
 {
-       return seq_open_private(file, &igmp_mc_seq_ops,
+       return seq_open_net(inode, file, &igmp_mc_seq_ops,
                        sizeof(struct igmp_mc_iter_state));
 }
 
@@ -2417,10 +2419,11 @@ static const struct file_operations igmp_mc_seq_fops = {
        .open           =       igmp_mc_seq_open,
        .read           =       seq_read,
        .llseek         =       seq_lseek,
-       .release        =       seq_release_private,
+       .release        =       seq_release_net,
 };
 
 struct igmp_mcf_iter_state {
+       struct seq_net_private p;
        struct net_device *dev;
        struct in_device *idev;
        struct ip_mc_list *im;
@@ -2430,13 +2433,14 @@ struct igmp_mcf_iter_state {
 
 static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq)
 {
+       struct net *net = seq_file_net(seq);
        struct ip_sf_list *psf = NULL;
        struct ip_mc_list *im = NULL;
        struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq);
 
        state->idev = NULL;
        state->im = NULL;
-       for_each_netdev(&init_net, state->dev) {
+       for_each_netdev(net, state->dev) {
                struct in_device *idev;
                idev = in_dev_get(state->dev);
                if (unlikely(idev == NULL))
@@ -2567,7 +2571,7 @@ static const struct seq_operations igmp_mcf_seq_ops = {
 
 static int igmp_mcf_seq_open(struct inode *inode, struct file *file)
 {
-       return seq_open_private(file, &igmp_mcf_seq_ops,
+       return seq_open_net(inode, file, &igmp_mcf_seq_ops,
                        sizeof(struct igmp_mcf_iter_state));
 }
 
@@ -2576,14 +2580,41 @@ static const struct file_operations igmp_mcf_seq_fops = {
        .open           =       igmp_mcf_seq_open,
        .read           =       seq_read,
        .llseek         =       seq_lseek,
-       .release        =       seq_release_private,
+       .release        =       seq_release_net,
 };
 
-int __init igmp_mc_proc_init(void)
+static int igmp_net_init(struct net *net)
 {
-       proc_net_fops_create(&init_net, "igmp", S_IRUGO, &igmp_mc_seq_fops);
-       proc_net_fops_create(&init_net, "mcfilter", S_IRUGO, &igmp_mcf_seq_fops);
+       struct proc_dir_entry *pde;
+
+       pde = proc_net_fops_create(net, "igmp", S_IRUGO, &igmp_mc_seq_fops);
+       if (!pde)
+               goto out_igmp;
+       pde = proc_net_fops_create(net, "mcfilter", S_IRUGO, &igmp_mcf_seq_fops);
+       if (!pde)
+               goto out_mcfilter;
        return 0;
+
+out_mcfilter:
+       proc_net_remove(net, "igmp");
+out_igmp:
+       return -ENOMEM;
+}
+
+static void igmp_net_exit(struct net *net)
+{
+       proc_net_remove(net, "mcfilter");
+       proc_net_remove(net, "igmp");
+}
+
+static struct pernet_operations igmp_net_ops = {
+       .init = igmp_net_init,
+       .exit = igmp_net_exit,
+};
+
+int __init igmp_mc_proc_init(void)
+{
+       return register_pernet_subsys(&igmp_net_ops);
 }
 #endif
 
index dda42f0bd7a3b986d23be16b6f44c87333af0844..557fe16cbfb0c8498e179ddebecc2e602abf5d2e 100644 (file)
@@ -663,10 +663,14 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
        th->urg_ptr             = 0;
 
        /* The urg_mode check is necessary during a below snd_una win probe */
-       if (unlikely(tcp_urg_mode(tp) &&
-                    between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF))) {
-               th->urg_ptr             = htons(tp->snd_up - tcb->seq);
-               th->urg                 = 1;
+       if (unlikely(tcp_urg_mode(tp))) {
+               if (between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF)) {
+                       th->urg_ptr = htons(tp->snd_up - tcb->seq);
+                       th->urg = 1;
+               } else if (after(tcb->seq + 0xFFFF, tp->snd_nxt)) {
+                       th->urg_ptr = 0xFFFF;
+                       th->urg = 1;
+               }
        }
 
        tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location);
index 7912eb14eca0858047fe1b337848cf281c5d621b..9d4e4d846ec16ec978af0c95f1487e2e846f5841 100644 (file)
@@ -310,12 +310,35 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
 
        sinfo->filled = STATION_INFO_INACTIVE_TIME |
                        STATION_INFO_RX_BYTES |
-                       STATION_INFO_TX_BYTES;
+                       STATION_INFO_TX_BYTES |
+                       STATION_INFO_TX_BITRATE;
 
        sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
        sinfo->rx_bytes = sta->rx_bytes;
        sinfo->tx_bytes = sta->tx_bytes;
 
+       if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
+               sinfo->filled |= STATION_INFO_SIGNAL;
+               sinfo->signal = (s8)sta->last_signal;
+       }
+
+       sinfo->txrate.flags = 0;
+       if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
+               sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+       if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+               sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+       if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
+               sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+
+       if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) {
+               struct ieee80211_supported_band *sband;
+               sband = sta->local->hw.wiphy->bands[
+                               sta->local->hw.conf.channel->band];
+               sinfo->txrate.legacy =
+                       sband->bitrates[sta->last_tx_rate.idx].bitrate;
+       } else
+               sinfo->txrate.mcs = sta->last_tx_rate.idx;
+
        if (ieee80211_vif_is_mesh(&sdata->vif)) {
 #ifdef CONFIG_MAC80211_MESH
                sinfo->filled |= STATION_INFO_LLID |
@@ -663,6 +686,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
        struct sta_info *sta;
        struct ieee80211_sub_if_data *sdata;
        int err;
+       int layer2_update;
 
        /* Prevent a race with changing the rate control algorithm */
        if (!netif_running(dev))
@@ -693,17 +717,25 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
 
        rate_control_rate_init(sta);
 
+       layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
+               sdata->vif.type == NL80211_IFTYPE_AP;
+
        rcu_read_lock();
 
        err = sta_info_insert(sta);
        if (err) {
                /* STA has been freed */
+               if (err == -EEXIST && layer2_update) {
+                       /* Need to update layer 2 devices on reassociation */
+                       sta = sta_info_get(local, mac);
+                       if (sta)
+                               ieee80211_send_layer2_update(sta);
+               }
                rcu_read_unlock();
                return err;
        }
 
-       if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
-           sdata->vif.type == NL80211_IFTYPE_AP)
+       if (layer2_update)
                ieee80211_send_layer2_update(sta);
 
        rcu_read_unlock();
@@ -1099,12 +1131,12 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
 
 static int ieee80211_set_channel(struct wiphy *wiphy,
                                 struct ieee80211_channel *chan,
-                                enum nl80211_sec_chan_offset sec_chan_offset)
+                                enum nl80211_channel_type channel_type)
 {
        struct ieee80211_local *local = wiphy_priv(wiphy);
 
        local->oper_channel = chan;
-       local->oper_sec_chan_offset = sec_chan_offset;
+       local->oper_channel_type = channel_type;
 
        return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 }
index a1eed7032c9b628bf12e2c2f5079f3997637b6df..5f510a13b9f0a5679d3ed736efa927532fc18f2a 100644 (file)
@@ -98,6 +98,7 @@ u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_bss_ht_conf ht;
        u32 changed = 0;
        bool enable_ht = true, ht_changed;
+       enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
 
        sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
 
@@ -112,24 +113,36 @@ u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
            ieee80211_channel_to_frequency(hti->control_chan))
                enable_ht = false;
 
-       /*
-        * XXX: This is totally incorrect when there are multiple virtual
-        *      interfaces, needs to be fixed later.
-        */
-       ht_changed = local->hw.conf.ht.enabled != enable_ht;
+       if (enable_ht) {
+               channel_type = NL80211_CHAN_HT20;
+
+               if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
+                   (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
+                   (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
+                       switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
+                       case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
+                               channel_type = NL80211_CHAN_HT40PLUS;
+                               break;
+                       case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
+                               channel_type = NL80211_CHAN_HT40MINUS;
+                               break;
+                       }
+               }
+       }
+
+       ht_changed = local->hw.conf.ht.enabled != enable_ht ||
+                    channel_type != local->hw.conf.ht.channel_type;
+
+       local->oper_channel_type = channel_type;
        local->hw.conf.ht.enabled = enable_ht;
+
        if (ht_changed)
                ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT);
 
        /* disable HT */
        if (!enable_ht)
                return 0;
-       ht.secondary_channel_offset =
-               hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
-       ht.width_40_ok =
-               !(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
-               (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
-               (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY);
+
        ht.operation_mode = le16_to_cpu(hti->operation_mode);
 
        /* if bss configuration changed store the new one */
index 6f59e11d7b33a733a9cfa93f8def094ba67f38a7..f3eec989662bebb2523d4df393f608546308cc94 100644 (file)
@@ -538,6 +538,11 @@ enum {
        IEEE80211_ADDBA_MSG     = 4,
 };
 
+enum queue_stop_reason {
+       IEEE80211_QUEUE_STOP_REASON_DRIVER,
+       IEEE80211_QUEUE_STOP_REASON_PS,
+};
+
 /* maximum number of hardware queues we support. */
 #define QD_MAX_QUEUES (IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_QUEUES)
 
@@ -554,7 +559,8 @@ struct ieee80211_local {
        const struct ieee80211_ops *ops;
 
        unsigned long queue_pool[BITS_TO_LONGS(QD_MAX_QUEUES)];
-
+       unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES];
+       spinlock_t queue_stop_reason_lock;
        struct net_device *mdev; /* wmaster# - "master" 802.11 device */
        int open_count;
        int monitors, cooked_mntrs;
@@ -625,7 +631,7 @@ struct ieee80211_local {
        struct delayed_work scan_work;
        struct ieee80211_sub_if_data *scan_sdata;
        struct ieee80211_channel *oper_channel, *scan_channel;
-       enum nl80211_sec_chan_offset oper_sec_chan_offset;
+       enum nl80211_channel_type oper_channel_type;
        u8 scan_ssid[IEEE80211_MAX_SSID_LEN];
        size_t scan_ssid_len;
        struct list_head bss_list;
@@ -689,6 +695,12 @@ struct ieee80211_local {
        int wifi_wme_noack_test;
        unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
 
+       bool powersave;
+       int dynamic_ps_timeout;
+       struct work_struct dynamic_ps_enable_work;
+       struct work_struct dynamic_ps_disable_work;
+       struct timer_list dynamic_ps_timer;
+
 #ifdef CONFIG_MAC80211_DEBUGFS
        struct local_debugfsdentries {
                struct dentry *rcdir;
@@ -971,6 +983,15 @@ int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq);
 u64 ieee80211_mandatory_rates(struct ieee80211_local *local,
                              enum ieee80211_band band);
 
+void ieee80211_dynamic_ps_enable_work(struct work_struct *work);
+void ieee80211_dynamic_ps_disable_work(struct work_struct *work);
+void ieee80211_dynamic_ps_timer(unsigned long data);
+
+void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
+                                    enum queue_stop_reason reason);
+void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
+                                    enum queue_stop_reason reason);
+
 #ifdef CONFIG_MAC80211_NOINLINE
 #define debug_noinline noinline
 #else
index 6d8710327d144a298aabe7350cbd72e97a19d327..24b14363d6e70c77766c06946ba5407de122dc89 100644 (file)
@@ -195,37 +195,30 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
        struct ieee80211_channel *chan;
        int ret = 0;
        int power;
-       enum nl80211_sec_chan_offset sec_chan_offset;
+       enum nl80211_channel_type channel_type;
 
        might_sleep();
 
        if (local->sw_scanning) {
                chan = local->scan_channel;
-               sec_chan_offset = NL80211_SEC_CHAN_NO_HT;
+               channel_type = NL80211_CHAN_NO_HT;
        } else {
                chan = local->oper_channel;
-               sec_chan_offset = local->oper_sec_chan_offset;
+               channel_type = local->oper_channel_type;
        }
 
        if (chan != local->hw.conf.channel ||
-           sec_chan_offset != local->hw.conf.ht.sec_chan_offset) {
+           channel_type != local->hw.conf.ht.channel_type) {
                local->hw.conf.channel = chan;
-               switch (sec_chan_offset) {
-               case NL80211_SEC_CHAN_NO_HT:
+               local->hw.conf.ht.channel_type = channel_type;
+               switch (channel_type) {
+               case NL80211_CHAN_NO_HT:
                        local->hw.conf.ht.enabled = false;
-                       local->hw.conf.ht.sec_chan_offset = 0;
                        break;
-               case NL80211_SEC_CHAN_DISABLED:
+               case NL80211_CHAN_HT20:
+               case NL80211_CHAN_HT40MINUS:
+               case NL80211_CHAN_HT40PLUS:
                        local->hw.conf.ht.enabled = true;
-                       local->hw.conf.ht.sec_chan_offset = 0;
-                       break;
-               case NL80211_SEC_CHAN_BELOW:
-                       local->hw.conf.ht.enabled = true;
-                       local->hw.conf.ht.sec_chan_offset = -1;
-                       break;
-               case NL80211_SEC_CHAN_ABOVE:
-                       local->hw.conf.ht.enabled = true;
-                       local->hw.conf.ht.sec_chan_offset = 1;
                        break;
                }
                changed |= IEEE80211_CONF_CHANGE_CHANNEL;
@@ -348,7 +341,8 @@ static void ieee80211_tasklet_handler(unsigned long data)
                        dev_kfree_skb(skb);
                        break ;
                default:
-                       WARN_ON(1);
+                       WARN(1, "mac80211: Packet is of unknown type %d\n",
+                            skb->pkt_type);
                        dev_kfree_skb(skb);
                        break;
                }
@@ -731,8 +725,17 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 
        spin_lock_init(&local->key_lock);
 
+       spin_lock_init(&local->queue_stop_reason_lock);
+
        INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
 
+       INIT_WORK(&local->dynamic_ps_enable_work,
+                 ieee80211_dynamic_ps_enable_work);
+       INIT_WORK(&local->dynamic_ps_disable_work,
+                 ieee80211_dynamic_ps_disable_work);
+       setup_timer(&local->dynamic_ps_timer,
+                   ieee80211_dynamic_ps_timer, (unsigned long) local);
+
        sta_info_init(local);
 
        tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending,
index 290b0017ef2e7f55c8875cc5fff240f39260f059..5ba721b6a399ddadefc0924ec50ab5531efd1e5c 100644 (file)
@@ -309,7 +309,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
                mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
                                                  IEEE80211_STYPE_ASSOC_REQ);
                mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
-               mgmt->u.reassoc_req.listen_interval =
+               mgmt->u.assoc_req.listen_interval =
                                cpu_to_le16(local->hw.conf.listen_interval);
        }
 
@@ -744,6 +744,17 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
        bss_info_changed |= BSS_CHANGED_BASIC_RATES;
        ieee80211_bss_info_change_notify(sdata, bss_info_changed);
 
+       if (local->powersave) {
+               if (local->dynamic_ps_timeout > 0)
+                       mod_timer(&local->dynamic_ps_timer, jiffies +
+                                 msecs_to_jiffies(local->dynamic_ps_timeout));
+               else {
+                       conf->flags |= IEEE80211_CONF_PS;
+                       ieee80211_hw_config(local,
+                                           IEEE80211_CONF_CHANGE_PS);
+               }
+       }
+
        netif_tx_start_all_queues(sdata->dev);
        netif_carrier_on(sdata->dev);
 
@@ -812,7 +823,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
 {
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
-       u32 changed = 0;
+       u32 changed = 0, config_changed = 0;
 
        rcu_read_lock();
 
@@ -858,8 +869,18 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
        rcu_read_unlock();
 
        local->hw.conf.ht.enabled = false;
-       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT);
+       local->oper_channel_type = NL80211_CHAN_NO_HT;
+       config_changed |= IEEE80211_CONF_CHANGE_HT;
+
+       del_timer_sync(&local->dynamic_ps_timer);
+       cancel_work_sync(&local->dynamic_ps_enable_work);
 
+       if (local->hw.conf.flags & IEEE80211_CONF_PS) {
+               local->hw.conf.flags &= ~IEEE80211_CONF_PS;
+               config_changed |= IEEE80211_CONF_CHANGE_PS;
+       }
+
+       ieee80211_hw_config(local, config_changed);
        ieee80211_bss_info_change_notify(sdata, changed);
 
        rcu_read_lock();
@@ -1612,8 +1633,13 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                         * e.g: at 1 MBit that means mactime is 192 usec earlier
                         * (=24 bytes * 8 usecs/byte) than the beacon timestamp.
                         */
-                       int rate = local->hw.wiphy->bands[band]->
+                       int rate;
+                       if (rx_status->flag & RX_FLAG_HT) {
+                               rate = 65; /* TODO: HT rates */
+                       } else {
+                               rate = local->hw.wiphy->bands[band]->
                                        bitrates[rx_status->rate_idx].bitrate;
+                       }
                        rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
                } else if (local && local->ops && local->ops->get_tsf)
                        /* second best option: get current TSF */
@@ -2576,3 +2602,39 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
                ieee80211_restart_sta_timer(sdata);
        rcu_read_unlock();
 }
+
+void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
+{
+       struct ieee80211_local *local =
+               container_of(work, struct ieee80211_local,
+                            dynamic_ps_disable_work);
+
+       if (local->hw.conf.flags & IEEE80211_CONF_PS) {
+               local->hw.conf.flags &= ~IEEE80211_CONF_PS;
+               ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+       }
+
+       ieee80211_wake_queues_by_reason(&local->hw,
+                                       IEEE80211_QUEUE_STOP_REASON_PS);
+}
+
+void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
+{
+       struct ieee80211_local *local =
+               container_of(work, struct ieee80211_local,
+                            dynamic_ps_enable_work);
+
+       if (local->hw.conf.flags & IEEE80211_CONF_PS)
+               return;
+
+       local->hw.conf.flags |= IEEE80211_CONF_PS;
+
+       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+}
+
+void ieee80211_dynamic_ps_timer(unsigned long data)
+{
+       struct ieee80211_local *local = (void *) data;
+
+       queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work);
+}
index 73cf126cef499d9ed30a20b317ecf7dc8feb0302..7175ae80c36a3b3a513fd1f5040643e595401a5c 100644 (file)
@@ -123,7 +123,6 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
        /* radiotap header, set always present flags */
        rthdr->it_present =
                cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
-                           (1 << IEEE80211_RADIOTAP_RATE) |
                            (1 << IEEE80211_RADIOTAP_CHANNEL) |
                            (1 << IEEE80211_RADIOTAP_ANTENNA) |
                            (1 << IEEE80211_RADIOTAP_RX_FLAGS));
@@ -149,7 +148,19 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
        pos++;
 
        /* IEEE80211_RADIOTAP_RATE */
-       *pos = rate->bitrate / 5;
+       if (status->flag & RX_FLAG_HT) {
+               /*
+                * TODO: add following information into radiotap header once
+                * suitable fields are defined for it:
+                * - MCS index (status->rate_idx)
+                * - HT40 (status->flag & RX_FLAG_40MHZ)
+                * - short-GI (status->flag & RX_FLAG_SHORT_GI)
+                */
+               *pos = 0;
+       } else {
+               rthdr->it_present |= (1 << IEEE80211_RADIOTAP_RATE);
+               *pos = rate->bitrate / 5;
+       }
        pos++;
 
        /* IEEE80211_RADIOTAP_CHANNEL */
@@ -1849,9 +1860,15 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
                        if (!(sdata->dev->flags & IFF_PROMISC))
                                return 0;
                        rx->flags &= ~IEEE80211_RX_RA_MATCH;
-               } else if (!rx->sta)
+               } else if (!rx->sta) {
+                       int rate_idx;
+                       if (rx->status->flag & RX_FLAG_HT)
+                               rate_idx = 0; /* TODO: HT rates */
+                       else
+                               rate_idx = rx->status->rate_idx;
                        rx->sta = ieee80211_ibss_add_sta(sdata, bssid, hdr->addr2,
-                               BIT(rx->status->rate_idx));
+                               BIT(rate_idx));
+               }
                break;
        case NL80211_IFTYPE_MESH_POINT:
                if (!multicast &&
@@ -2057,7 +2074,13 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
                                        tid_agg_rx->reorder_buf[index]->cb,
                                        sizeof(status));
                                sband = local->hw.wiphy->bands[status.band];
-                               rate = &sband->bitrates[status.rate_idx];
+                               if (status.flag & RX_FLAG_HT) {
+                                       /* TODO: HT rates */
+                                       rate = sband->bitrates;
+                               } else {
+                                       rate = &sband->bitrates
+                                               [status.rate_idx];
+                               }
                                __ieee80211_rx_handle_packet(hw,
                                        tid_agg_rx->reorder_buf[index],
                                        &status, rate);
@@ -2101,7 +2124,10 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
                memcpy(&status, tid_agg_rx->reorder_buf[index]->cb,
                        sizeof(status));
                sband = local->hw.wiphy->bands[status.band];
-               rate = &sband->bitrates[status.rate_idx];
+               if (status.flag & RX_FLAG_HT)
+                       rate = sband->bitrates; /* TODO: HT rates */
+               else
+                       rate = &sband->bitrates[status.rate_idx];
                __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index],
                                             &status, rate);
                tid_agg_rx->stored_mpdu_num--;
@@ -2189,15 +2215,26 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
        }
 
        sband = local->hw.wiphy->bands[status->band];
-
-       if (!sband ||
-           status->rate_idx < 0 ||
-           status->rate_idx >= sband->n_bitrates) {
+       if (!sband) {
                WARN_ON(1);
                return;
        }
 
-       rate = &sband->bitrates[status->rate_idx];
+       if (status->flag & RX_FLAG_HT) {
+               /* rate_idx is MCS index */
+               if (WARN_ON(status->rate_idx < 0 ||
+                           status->rate_idx >= 76))
+                       return;
+               /* HT rates are not in the table - use the highest legacy rate
+                * for now since other parts of mac80211 may not yet be fully
+                * MCS aware. */
+               rate = &sband->bitrates[sband->n_bitrates - 1];
+       } else {
+               if (WARN_ON(status->rate_idx < 0 ||
+                           status->rate_idx >= sband->n_bitrates))
+                       return;
+               rate = &sband->bitrates[status->rate_idx];
+       }
 
        /*
         * key references and virtual interfaces are protected using RCU
index b098c58d216f29cb047f986aac4cc740c014212a..a4af3a124cce7d895426b9e49e36ef53a5c54601 100644 (file)
@@ -1473,6 +1473,19 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
                goto fail;
        }
 
+       if (!(local->hw.flags & IEEE80211_HW_NO_STACK_DYNAMIC_PS) &&
+           local->dynamic_ps_timeout > 0) {
+               if (local->hw.conf.flags & IEEE80211_CONF_PS) {
+                       ieee80211_stop_queues_by_reason(&local->hw,
+                                                       IEEE80211_QUEUE_STOP_REASON_PS);
+                       queue_work(local->hw.workqueue,
+                                  &local->dynamic_ps_disable_work);
+               }
+
+               mod_timer(&local->dynamic_ps_timer, jiffies +
+                         msecs_to_jiffies(local->dynamic_ps_timeout));
+       }
+
        nh_pos = skb_network_header(skb) - skb->data;
        h_pos = skb_transport_header(skb) - skb->data;
 
index 505d68f344ceb386486e7963ea425715f4804b6f..fb89e1d0aa0330ad893888c37697e6932bda47ec 100644 (file)
@@ -330,10 +330,20 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL(ieee80211_ctstoself_duration);
 
-void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
+static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
+                                  enum queue_stop_reason reason)
 {
        struct ieee80211_local *local = hw_to_local(hw);
 
+       /* we don't need to track ampdu queues */
+       if (queue < ieee80211_num_regular_queues(hw)) {
+               __clear_bit(reason, &local->queue_stop_reasons[queue]);
+
+               if (local->queue_stop_reasons[queue] != 0)
+                       /* someone still has this queue stopped */
+                       return;
+       }
+
        if (test_bit(queue, local->queues_pending)) {
                set_bit(queue, local->queues_pending_run);
                tasklet_schedule(&local->tx_pending_tasklet);
@@ -341,22 +351,74 @@ void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
                netif_wake_subqueue(local->mdev, queue);
        }
 }
+
+void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
+                                   enum queue_stop_reason reason)
+{
+       struct ieee80211_local *local = hw_to_local(hw);
+       unsigned long flags;
+
+       spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
+       __ieee80211_wake_queue(hw, queue, reason);
+       spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+}
+
+void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
+{
+       ieee80211_wake_queue_by_reason(hw, queue,
+                                      IEEE80211_QUEUE_STOP_REASON_DRIVER);
+}
 EXPORT_SYMBOL(ieee80211_wake_queue);
 
-void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
+static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
+                                  enum queue_stop_reason reason)
 {
        struct ieee80211_local *local = hw_to_local(hw);
 
+       /* we don't need to track ampdu queues */
+       if (queue < ieee80211_num_regular_queues(hw))
+               __set_bit(reason, &local->queue_stop_reasons[queue]);
+
        netif_stop_subqueue(local->mdev, queue);
 }
+
+void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
+                                   enum queue_stop_reason reason)
+{
+       struct ieee80211_local *local = hw_to_local(hw);
+       unsigned long flags;
+
+       spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
+       __ieee80211_stop_queue(hw, queue, reason);
+       spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+}
+
+void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
+{
+       ieee80211_stop_queue_by_reason(hw, queue,
+                                      IEEE80211_QUEUE_STOP_REASON_DRIVER);
+}
 EXPORT_SYMBOL(ieee80211_stop_queue);
 
-void ieee80211_stop_queues(struct ieee80211_hw *hw)
+void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
+                                   enum queue_stop_reason reason)
 {
+       struct ieee80211_local *local = hw_to_local(hw);
+       unsigned long flags;
        int i;
 
+       spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
+
        for (i = 0; i < ieee80211_num_queues(hw); i++)
-               ieee80211_stop_queue(hw, i);
+               __ieee80211_stop_queue(hw, i, reason);
+
+       spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+}
+
+void ieee80211_stop_queues(struct ieee80211_hw *hw)
+{
+       ieee80211_stop_queues_by_reason(hw,
+                                       IEEE80211_QUEUE_STOP_REASON_DRIVER);
 }
 EXPORT_SYMBOL(ieee80211_stop_queues);
 
@@ -367,12 +429,24 @@ int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
 }
 EXPORT_SYMBOL(ieee80211_queue_stopped);
 
-void ieee80211_wake_queues(struct ieee80211_hw *hw)
+void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
+                                    enum queue_stop_reason reason)
 {
+       struct ieee80211_local *local = hw_to_local(hw);
+       unsigned long flags;
        int i;
 
+       spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
+
        for (i = 0; i < hw->queues + hw->ampdu_queues; i++)
-               ieee80211_wake_queue(hw, i);
+               __ieee80211_wake_queue(hw, i, reason);
+
+       spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+}
+
+void ieee80211_wake_queues(struct ieee80211_hw *hw)
+{
+       ieee80211_wake_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_DRIVER);
 }
 EXPORT_SYMBOL(ieee80211_wake_queues);
 
@@ -641,7 +715,7 @@ int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freqMHz)
                    chan->flags & IEEE80211_CHAN_NO_IBSS)
                        return ret;
                local->oper_channel = chan;
-               local->oper_sec_chan_offset = NL80211_SEC_CHAN_NO_HT;
+               local->oper_channel_type = NL80211_CHAN_NO_HT;
 
                if (local->sw_scanning || local->hw_scanning)
                        ret = 0;
index 15428048d01a516843dcf09b9a7a26bb969bd03e..7162d5816f39146adbf65a8fac47d6bd2b11ee86 100644 (file)
@@ -830,25 +830,56 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
                                    struct iw_param *wrq,
                                    char *extra)
 {
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_conf *conf = &local->hw.conf;
+       int ret = 0, timeout = 0;
+       bool ps;
+
+       if (sdata->vif.type != NL80211_IFTYPE_STATION)
+               return -EINVAL;
 
        if (wrq->disabled) {
-               conf->flags &= ~IEEE80211_CONF_PS;
-               return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+               ps = false;
+               timeout = 0;
+               goto set;
        }
 
        switch (wrq->flags & IW_POWER_MODE) {
        case IW_POWER_ON:       /* If not specified */
        case IW_POWER_MODE:     /* If set all mask */
        case IW_POWER_ALL_R:    /* If explicitely state all */
-               conf->flags |= IEEE80211_CONF_PS;
+               ps = true;
+               break;
+       default:                /* Otherwise we ignore */
                break;
-       default:                /* Otherwise we don't support it */
-               return -EINVAL;
        }
 
-       return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+       if (wrq->flags & IW_POWER_TIMEOUT)
+               timeout = wrq->value / 1000;
+
+set:
+       if (ps == local->powersave && timeout == local->dynamic_ps_timeout)
+               return ret;
+
+       local->powersave = ps;
+       local->dynamic_ps_timeout = timeout;
+
+       if (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) {
+               if (!(local->hw.flags & IEEE80211_HW_NO_STACK_DYNAMIC_PS) &&
+                   local->dynamic_ps_timeout > 0)
+                       mod_timer(&local->dynamic_ps_timer, jiffies +
+                                 msecs_to_jiffies(local->dynamic_ps_timeout));
+               else {
+                       if (local->powersave)
+                               conf->flags |= IEEE80211_CONF_PS;
+                       else
+                               conf->flags &= ~IEEE80211_CONF_PS;
+               }
+               ret = ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+       }
+
+       return ret;
 }
 
 static int ieee80211_ioctl_giwpower(struct net_device *dev,
@@ -857,9 +888,8 @@ static int ieee80211_ioctl_giwpower(struct net_device *dev,
                                    char *extra)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct ieee80211_conf *conf = &local->hw.conf;
 
-       wrqu->power.disabled = !(conf->flags & IEEE80211_CONF_PS);
+       wrqu->power.disabled = !local->powersave;
 
        return 0;
 }
index 6bc29e8a7f32eb9190fca2e2a000099b3e1b596a..0fc4a18fd96f7d83ec21e95bc6d0740025f6a219 100644 (file)
@@ -450,7 +450,6 @@ static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
                                                 timer);
 
        wd->qdisc->flags &= ~TCQ_F_THROTTLED;
-       smp_wmb();
        __netif_schedule(qdisc_root(wd->qdisc));
 
        return HRTIMER_NORESTART;
index 7e78f1c0f35780d91825219b59751718189313c7..d876b873484852d0a1da004e51fc4198d65627de 100644 (file)
@@ -266,7 +266,6 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
        struct netem_sched_data *q = qdisc_priv(sch);
        struct sk_buff *skb;
 
-       smp_mb();
        if (sch->flags & TCQ_F_THROTTLED)
                return NULL;
 
index ab8cfee3c9ced13f5008661d2ad2044f764ada46..f3965df00559d970e4b46d871014ac9e08c8c5de 100644 (file)
@@ -281,7 +281,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        struct sfq_sched_data *q = qdisc_priv(sch);
        unsigned int hash;
        sfq_index x;
-       int ret;
+       int uninitialized_var(ret);
 
        hash = sfq_classify(skb, sch, &ret);
        if (hash == 0) {
index 9f2a3eb656e56462033f6714a74d878a0b54f52f..1c4e5d6c29c07e9c1905235d4adcd1774bee3117 100644 (file)
@@ -3689,6 +3689,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(const struct sctp_endpoint *ep,
 {
        struct sctp_chunk *chunk = arg;
        struct sctp_fwdtsn_hdr *fwdtsn_hdr;
+       struct sctp_fwdtsn_skip *skip;
        __u16 len;
        __u32 tsn;
 
@@ -3718,6 +3719,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(const struct sctp_endpoint *ep,
        if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
                goto discard_noforce;
 
+       /* Silently discard the chunk if stream-id is not valid */
+       sctp_walk_fwdtsn(skip, chunk) {
+               if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams)
+                       goto discard_noforce;
+       }
+
        sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
        if (len > sizeof(struct sctp_fwdtsn_hdr))
                sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
@@ -3749,6 +3756,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fast(
 {
        struct sctp_chunk *chunk = arg;
        struct sctp_fwdtsn_hdr *fwdtsn_hdr;
+       struct sctp_fwdtsn_skip *skip;
        __u16 len;
        __u32 tsn;
 
@@ -3778,6 +3786,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fast(
        if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
                goto gen_shutdown;
 
+       /* Silently discard the chunk if stream-id is not valid */
+       sctp_walk_fwdtsn(skip, chunk) {
+               if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams)
+                       goto gen_shutdown;
+       }
+
        sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
        if (len > sizeof(struct sctp_fwdtsn_hdr))
                sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
index a2de585888d0a53cef7e53745ccb4f033abd61a1..b14a8f33e42d6ad26a2e6fc3005943cc266d8434 100644 (file)
@@ -2404,9 +2404,9 @@ static int sctp_setsockopt_delayed_ack(struct sock *sk,
                if (params.sack_delay == 0 && params.sack_freq == 0)
                        return 0;
        } else if (optlen == sizeof(struct sctp_assoc_value)) {
-               printk(KERN_WARNING "SCTP: Use of struct sctp_sack_info "
+               printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value "
                       "in delayed_ack socket option deprecated\n");
-               printk(KERN_WARNING "SCTP: struct sctp_sack_info instead\n");
+               printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n");
                if (copy_from_user(&params, optval, optlen))
                        return -EFAULT;
 
@@ -2778,32 +2778,77 @@ static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, int op
 }
 
 /*
- * 7.1.17 Set the maximum fragrmentation size (SCTP_MAXSEG)
- *
- * This socket option specifies the maximum size to put in any outgoing
- * SCTP chunk.  If a message is larger than this size it will be
+ * 8.1.16.  Get or Set the Maximum Fragmentation Size (SCTP_MAXSEG)
+ * This option will get or set the maximum size to put in any outgoing
+ * SCTP DATA chunk.  If a message is larger than this size it will be
  * fragmented by SCTP into the specified size.  Note that the underlying
  * SCTP implementation may fragment into smaller sized chunks when the
  * PMTU of the underlying association is smaller than the value set by
- * the user.
+ * the user.  The default value for this option is '0' which indicates
+ * the user is NOT limiting fragmentation and only the PMTU will effect
+ * SCTP's choice of DATA chunk size.  Note also that values set larger
+ * than the maximum size of an IP datagram will effectively let SCTP
+ * control fragmentation (i.e. the same as setting this option to 0).
+ *
+ * The following structure is used to access and modify this parameter:
+ *
+ * struct sctp_assoc_value {
+ *   sctp_assoc_t assoc_id;
+ *   uint32_t assoc_value;
+ * };
+ *
+ * assoc_id:  This parameter is ignored for one-to-one style sockets.
+ *    For one-to-many style sockets this parameter indicates which
+ *    association the user is performing an action upon.  Note that if
+ *    this field's value is zero then the endpoints default value is
+ *    changed (effecting future associations only).
+ * assoc_value:  This parameter specifies the maximum size in bytes.
  */
 static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optlen)
 {
+       struct sctp_assoc_value params;
        struct sctp_association *asoc;
        struct sctp_sock *sp = sctp_sk(sk);
        int val;
 
-       if (optlen < sizeof(int))
+       if (optlen == sizeof(int)) {
+               printk(KERN_WARNING
+                  "SCTP: Use of int in maxseg socket option deprecated\n");
+               printk(KERN_WARNING
+                  "SCTP: Use struct sctp_assoc_value instead\n");
+               if (copy_from_user(&val, optval, optlen))
+                       return -EFAULT;
+               params.assoc_id = 0;
+       } else if (optlen == sizeof(struct sctp_assoc_value)) {
+               if (copy_from_user(&params, optval, optlen))
+                       return -EFAULT;
+               val = params.assoc_value;
+       } else
                return -EINVAL;
-       if (get_user(val, (int __user *)optval))
-               return -EFAULT;
+
        if ((val != 0) && ((val < 8) || (val > SCTP_MAX_CHUNK_LEN)))
                return -EINVAL;
-       sp->user_frag = val;
 
-       /* Update the frag_point of the existing associations. */
-       list_for_each_entry(asoc, &(sp->ep->asocs), asocs) {
-               asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu);
+       asoc = sctp_id2assoc(sk, params.assoc_id);
+       if (!asoc && params.assoc_id && sctp_style(sk, UDP))
+               return -EINVAL;
+
+       if (asoc) {
+               if (val == 0) {
+                       val = asoc->pathmtu;
+                       val -= sp->pf->af->net_header_len;
+                       val -= sizeof(struct sctphdr) +
+                                       sizeof(struct sctp_data_chunk);
+               }
+
+               asoc->frag_point = val;
+       } else {
+               sp->user_frag = val;
+
+               /* Update the frag_point of the existing associations. */
+               list_for_each_entry(asoc, &(sp->ep->asocs), asocs) {
+                       asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu);
+               }
        }
 
        return 0;
@@ -2965,14 +3010,21 @@ static int sctp_setsockopt_fragment_interleave(struct sock *sk,
 }
 
 /*
- * 7.1.25.  Set or Get the sctp partial delivery point
+ * 8.1.21.  Set or Get the SCTP Partial Delivery Point
  *       (SCTP_PARTIAL_DELIVERY_POINT)
+ *
  * This option will set or get the SCTP partial delivery point.  This
  * point is the size of a message where the partial delivery API will be
  * invoked to help free up rwnd space for the peer.  Setting this to a
- * lower value will cause partial delivery's to happen more often.  The
+ * lower value will cause partial deliveries to happen more often.  The
  * calls argument is an integer that sets or gets the partial delivery
- * point.
+ * point.  Note also that the call will fail if the user attempts to set
+ * this value larger than the socket receive buffer size.
+ *
+ * Note that any single message having a length smaller than or equal to
+ * the SCTP partial delivery point will be delivered in one single read
+ * call as long as the user provided buffer is large enough to hold the
+ * message.
  */
 static int sctp_setsockopt_partial_delivery_point(struct sock *sk,
                                                  char __user *optval,
@@ -2985,6 +3037,12 @@ static int sctp_setsockopt_partial_delivery_point(struct sock *sk,
        if (get_user(val, (int __user *)optval))
                return -EFAULT;
 
+       /* Note: We double the receive buffer from what the user sets
+        * it to be, also initial rwnd is based on rcvbuf/2.
+        */
+       if (val > (sk->sk_rcvbuf >> 1))
+               return -EINVAL;
+
        sctp_sk(sk)->pd_point = val;
 
        return 0; /* is this the right error code? */
@@ -4176,9 +4234,9 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len,
                if (copy_from_user(&params, optval, len))
                        return -EFAULT;
        } else if (len == sizeof(struct sctp_assoc_value)) {
-               printk(KERN_WARNING "SCTP: Use of struct sctp_sack_info "
+               printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value "
                       "in delayed_ack socket option deprecated\n");
-               printk(KERN_WARNING "SCTP: struct sctp_sack_info instead\n");
+               printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n");
                if (copy_from_user(&params, optval, len))
                        return -EFAULT;
        } else
@@ -5100,30 +5158,69 @@ static int sctp_getsockopt_context(struct sock *sk, int len,
 }
 
 /*
- * 7.1.17 Set the maximum fragrmentation size (SCTP_MAXSEG)
- *
- * This socket option specifies the maximum size to put in any outgoing
- * SCTP chunk.  If a message is larger than this size it will be
+ * 8.1.16.  Get or Set the Maximum Fragmentation Size (SCTP_MAXSEG)
+ * This option will get or set the maximum size to put in any outgoing
+ * SCTP DATA chunk.  If a message is larger than this size it will be
  * fragmented by SCTP into the specified size.  Note that the underlying
  * SCTP implementation may fragment into smaller sized chunks when the
  * PMTU of the underlying association is smaller than the value set by
- * the user.
+ * the user.  The default value for this option is '0' which indicates
+ * the user is NOT limiting fragmentation and only the PMTU will effect
+ * SCTP's choice of DATA chunk size.  Note also that values set larger
+ * than the maximum size of an IP datagram will effectively let SCTP
+ * control fragmentation (i.e. the same as setting this option to 0).
+ *
+ * The following structure is used to access and modify this parameter:
+ *
+ * struct sctp_assoc_value {
+ *   sctp_assoc_t assoc_id;
+ *   uint32_t assoc_value;
+ * };
+ *
+ * assoc_id:  This parameter is ignored for one-to-one style sockets.
+ *    For one-to-many style sockets this parameter indicates which
+ *    association the user is performing an action upon.  Note that if
+ *    this field's value is zero then the endpoints default value is
+ *    changed (effecting future associations only).
+ * assoc_value:  This parameter specifies the maximum size in bytes.
  */
 static int sctp_getsockopt_maxseg(struct sock *sk, int len,
                                  char __user *optval, int __user *optlen)
 {
-       int val;
+       struct sctp_assoc_value params;
+       struct sctp_association *asoc;
 
-       if (len < sizeof(int))
+       if (len == sizeof(int)) {
+               printk(KERN_WARNING
+                  "SCTP: Use of int in maxseg socket option deprecated\n");
+               printk(KERN_WARNING
+                  "SCTP: Use struct sctp_assoc_value instead\n");
+               params.assoc_id = 0;
+       } else if (len >= sizeof(struct sctp_assoc_value)) {
+               len = sizeof(struct sctp_assoc_value);
+               if (copy_from_user(&params, optval, sizeof(params)))
+                       return -EFAULT;
+       } else
                return -EINVAL;
 
-       len = sizeof(int);
+       asoc = sctp_id2assoc(sk, params.assoc_id);
+       if (!asoc && params.assoc_id && sctp_style(sk, UDP))
+               return -EINVAL;
+
+       if (asoc)
+               params.assoc_value = asoc->frag_point;
+       else
+               params.assoc_value = sctp_sk(sk)->user_frag;
 
-       val = sctp_sk(sk)->user_frag;
        if (put_user(len, optlen))
                return -EFAULT;
-       if (copy_to_user(optval, &val, len))
-               return -EFAULT;
+       if (len == sizeof(int)) {
+               if (copy_to_user(optval, &params.assoc_value, len))
+                       return -EFAULT;
+       } else {
+               if (copy_to_user(optval, &params, len))
+                       return -EFAULT;
+       }
 
        return 0;
 }
@@ -5376,6 +5473,38 @@ num:
        return 0;
 }
 
+/*
+ * 8.2.5.  Get the Current Number of Associations (SCTP_GET_ASSOC_NUMBER)
+ * This option gets the current number of associations that are attached
+ * to a one-to-many style socket.  The option value is an uint32_t.
+ */
+static int sctp_getsockopt_assoc_number(struct sock *sk, int len,
+                                   char __user *optval, int __user *optlen)
+{
+       struct sctp_sock *sp = sctp_sk(sk);
+       struct sctp_association *asoc;
+       u32 val = 0;
+
+       if (sctp_style(sk, TCP))
+               return -EOPNOTSUPP;
+
+       if (len < sizeof(u32))
+               return -EINVAL;
+
+       len = sizeof(u32);
+
+       list_for_each_entry(asoc, &(sp->ep->asocs), asocs) {
+               val++;
+       }
+
+       if (put_user(len, optlen))
+               return -EFAULT;
+       if (copy_to_user(optval, &val, len))
+               return -EFAULT;
+
+       return 0;
+}
+
 SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
                                char __user *optval, int __user *optlen)
 {
@@ -5518,6 +5647,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
                retval = sctp_getsockopt_local_auth_chunks(sk, len, optval,
                                                        optlen);
                break;
+       case SCTP_GET_ASSOC_NUMBER:
+               retval = sctp_getsockopt_assoc_number(sk, len, optval, optlen);
+               break;
        default:
                retval = -ENOPROTOOPT;
                break;
index e9d65ea2687e86539431d64426a2430b8badbccc..43021f9463f3c70f14a597d972256bac3267b9a4 100644 (file)
@@ -2306,6 +2306,7 @@ int kernel_accept(struct socket *sock, struct socket **newsock, int flags)
        }
 
        (*newsock)->ops = sock->ops;
+       __module_get((*newsock)->ops->owner);
 
 done:
        return err;
index 4335f76be71f0ebf9f1499f74d6fc7013bab31da..1e728fff474eb97bce9c983fac4afbc005f66fd1 100644 (file)
@@ -60,7 +60,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
                                      .len = BUS_ID_SIZE-1 },
        [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
        [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
-       [NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET] = { .type = NLA_U32 },
+       [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
 
        [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
        [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
@@ -362,8 +362,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
        }
 
        if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
-               enum nl80211_sec_chan_offset sec_chan_offset =
-                       NL80211_SEC_CHAN_NO_HT;
+               enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
                struct ieee80211_channel *chan;
                struct ieee80211_sta_ht_cap *ht_cap;
                u32 freq, sec_freq;
@@ -375,13 +374,13 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
 
                result = -EINVAL;
 
-               if (info->attrs[NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]) {
-                       sec_chan_offset = nla_get_u32(info->attrs[
-                                       NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]);
-                       if (sec_chan_offset != NL80211_SEC_CHAN_NO_HT &&
-                           sec_chan_offset != NL80211_SEC_CHAN_DISABLED &&
-                           sec_chan_offset != NL80211_SEC_CHAN_BELOW &&
-                           sec_chan_offset != NL80211_SEC_CHAN_ABOVE)
+               if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
+                       channel_type = nla_get_u32(info->attrs[
+                                          NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
+                       if (channel_type != NL80211_CHAN_NO_HT &&
+                           channel_type != NL80211_CHAN_HT20 &&
+                           channel_type != NL80211_CHAN_HT40PLUS &&
+                           channel_type != NL80211_CHAN_HT40MINUS)
                                goto bad_res;
                }
 
@@ -392,9 +391,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
                if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
                        goto bad_res;
 
-               if (sec_chan_offset == NL80211_SEC_CHAN_BELOW)
+               if (channel_type == NL80211_CHAN_HT40MINUS)
                        sec_freq = freq - 20;
-               else if (sec_chan_offset == NL80211_SEC_CHAN_ABOVE)
+               else if (channel_type == NL80211_CHAN_HT40PLUS)
                        sec_freq = freq + 20;
                else
                        sec_freq = 0;
@@ -402,7 +401,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
                ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
 
                /* no HT capabilities */
-               if (sec_chan_offset != NL80211_SEC_CHAN_NO_HT &&
+               if (channel_type != NL80211_CHAN_NO_HT &&
                    !ht_cap->ht_supported)
                        goto bad_res;
 
@@ -422,7 +421,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
                }
 
                result = rdev->ops->set_channel(&rdev->wiphy, chan,
-                                               sec_chan_offset);
+                                               channel_type);
                if (result)
                        goto bad_res;
        }
@@ -1091,12 +1090,46 @@ static int parse_station_flags(struct nlattr *nla, u32 *staflags)
        return 0;
 }
 
+static u16 nl80211_calculate_bitrate(struct rate_info *rate)
+{
+       int modulation, streams, bitrate;
+
+       if (!(rate->flags & RATE_INFO_FLAGS_MCS))
+               return rate->legacy;
+
+       /* the formula below does only work for MCS values smaller than 32 */
+       if (rate->mcs >= 32)
+               return 0;
+
+       modulation = rate->mcs & 7;
+       streams = (rate->mcs >> 3) + 1;
+
+       bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
+                       13500000 : 6500000;
+
+       if (modulation < 4)
+               bitrate *= (modulation + 1);
+       else if (modulation == 4)
+               bitrate *= (modulation + 2);
+       else
+               bitrate *= (modulation + 3);
+
+       bitrate *= streams;
+
+       if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
+               bitrate = (bitrate / 9) * 10;
+
+       /* do NOT round down here */
+       return (bitrate + 50000) / 100000;
+}
+
 static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
                                int flags, struct net_device *dev,
                                u8 *mac_addr, struct station_info *sinfo)
 {
        void *hdr;
-       struct nlattr *sinfoattr;
+       struct nlattr *sinfoattr, *txrate;
+       u16 bitrate;
 
        hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
        if (!hdr)
@@ -1126,7 +1159,29 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
        if (sinfo->filled & STATION_INFO_PLINK_STATE)
                NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
                            sinfo->plink_state);
+       if (sinfo->filled & STATION_INFO_SIGNAL)
+               NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
+                          sinfo->signal);
+       if (sinfo->filled & STATION_INFO_TX_BITRATE) {
+               txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
+               if (!txrate)
+                       goto nla_put_failure;
+
+               /* nl80211_calculate_bitrate will return 0 for mcs >= 32 */
+               bitrate = nl80211_calculate_bitrate(&sinfo->txrate);
+               if (bitrate > 0)
+                       NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
 
+               if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS)
+                       NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
+                                   sinfo->txrate.mcs);
+               if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
+                       NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
+               if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
+                       NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
+
+               nla_nest_end(msg, txrate);
+       }
        nla_nest_end(msg, sinfoattr);
 
        return genlmsg_end(msg, hdr);