Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
Linus Torvalds [Thu, 20 Jan 2011 04:25:45 +0000 (20:25 -0800)]
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (41 commits)
  sctp: user perfect name for Delayed SACK Timer option
  net: fix can_checksum_protocol() arguments swap
  Revert "netlink: test for all flags of the NLM_F_DUMP composite"
  gianfar: Fix misleading indentation in startup_gfar()
  net/irda/sh_irda: return to RX mode when TX error
  net offloading: Do not mask out NETIF_F_HW_VLAN_TX for vlan.
  USB CDC NCM: tx_fixup() race condition fix
  ns83820: Avoid bad pointer deref in ns83820_init_one().
  ipv6: Silence privacy extensions initialization
  bnx2x: Update bnx2x version to 1.62.00-4
  bnx2x: Fix AER setting for BCM57712
  bnx2x: Fix BCM84823 LED behavior
  bnx2x: Mark full duplex on some external PHYs
  bnx2x: Fix BCM8073/BCM8727 microcode loading
  bnx2x: LED fix for BCM8727 over BCM57712
  bnx2x: Common init will be executed only once after POR
  bnx2x: Swap BCM8073 PHY polarity if required
  iwlwifi: fix valid chain reading from EEPROM
  ath5k: fix locking in tx_complete_poll_work
  ath9k_hw: do PA offset calibration only on longcal interval
  ...

41 files changed:
drivers/net/bnx2x/bnx2x.h
drivers/net/bnx2x/bnx2x_hsi.h
drivers/net/bnx2x/bnx2x_link.c
drivers/net/bnx2x/bnx2x_reg.h
drivers/net/gianfar.c
drivers/net/irda/sh_irda.c
drivers/net/ns83820.c
drivers/net/usb/cdc_ncm.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/vmxnet3/vmxnet3_ethtool.c
drivers/net/vmxnet3/vmxnet3_int.h
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath9k/ar9002_calib.c
drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
drivers/net/wireless/ath/ath9k/ar9003_hw.c
drivers/net/wireless/ath/ath9k/htc.h
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
drivers/net/wireless/iwmc3200wifi/netdev.c
drivers/net/wireless/rt2x00/rt2x00firmware.c
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/qeth_l3_main.c
include/linux/ieee80211.h
include/net/sctp/user.h
net/batman-adv/main.h
net/batman-adv/packet.h
net/batman-adv/types.h
net/batman-adv/unicast.c
net/caif/cfcnfg.c
net/can/bcm.c
net/can/raw.c
net/core/dev.c
net/core/rtnetlink.c
net/ipv4/inet_diag.c
net/ipv6/addrconf.c
net/mac80211/agg-rx.c
net/mac80211/main.c
net/netfilter/nf_conntrack_netlink.c
net/netlink/genetlink.c
net/sctp/socket.c
net/xfrm/xfrm_user.c

index a6cd335..8e41837 100644 (file)
@@ -22,8 +22,8 @@
  * (you will need to reboot afterwards) */
 /* #define BNX2X_STOP_ON_ERROR */
 
-#define DRV_MODULE_VERSION      "1.62.00-3"
-#define DRV_MODULE_RELDATE      "2010/12/21"
+#define DRV_MODULE_VERSION      "1.62.00-4"
+#define DRV_MODULE_RELDATE      "2011/01/18"
 #define BNX2X_BC_VER            0x040200
 
 #define BNX2X_MULTI_QUEUE
index 6238d4f..548f563 100644 (file)
@@ -352,6 +352,10 @@ struct port_hw_cfg {                           /* port 0: 0x12c  port 1: 0x2bc */
 #define PORT_HW_CFG_LANE_SWAP_CFG_31203120         0x0000d8d8
        /* forced only */
 #define PORT_HW_CFG_LANE_SWAP_CFG_32103210         0x0000e4e4
+    /* Indicate whether to swap the external phy polarity */
+#define PORT_HW_CFG_SWAP_PHY_POLARITY_MASK            0x00010000
+#define PORT_HW_CFG_SWAP_PHY_POLARITY_DISABLED     0x00000000
+#define PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED      0x00010000
 
        u32 external_phy_config;
 #define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK       0xff000000
index 43b0de2..7160ec5 100644 (file)
@@ -1573,7 +1573,7 @@ static void bnx2x_set_aer_mmd_xgxs(struct link_params *params,
 
        offset = phy->addr + ser_lane;
        if (CHIP_IS_E2(bp))
-               aer_val = 0x2800 + offset - 1;
+               aer_val = 0x3800 + offset - 1;
        else
                aer_val = 0x3800 + offset;
        CL45_WR_OVER_CL22(bp, phy,
@@ -3166,7 +3166,23 @@ u8 bnx2x_set_led(struct link_params *params,
                if (!vars->link_up)
                        break;
        case LED_MODE_ON:
-               if (SINGLE_MEDIA_DIRECT(params)) {
+               if (params->phy[EXT_PHY1].type ==
+                   PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727 &&
+                   CHIP_IS_E2(bp) && params->num_phys == 2) {
+                       /**
+                       * This is a work-around for E2+8727 Configurations
+                       */
+                       if (mode == LED_MODE_ON ||
+                               speed == SPEED_10000){
+                               REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
+                               REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
+
+                               tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
+                               EMAC_WR(bp, EMAC_REG_EMAC_LED,
+                                       (tmp | EMAC_LED_OVERRIDE));
+                               return rc;
+                       }
+               } else if (SINGLE_MEDIA_DIRECT(params)) {
                        /**
                        * This is a work-around for HW issue found when link
                        * is up in CL73
@@ -3854,11 +3870,14 @@ static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
                           pause_result);
        }
 }
-
-static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
+static u8 bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
                                              struct bnx2x_phy *phy,
                                              u8 port)
 {
+       u32 count = 0;
+       u16 fw_ver1, fw_msgout;
+       u8 rc = 0;
+
        /* Boot port from external ROM  */
        /* EDC grst */
        bnx2x_cl45_write(bp, phy,
@@ -3888,14 +3907,45 @@ static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
                       MDIO_PMA_REG_GEN_CTRL,
                       MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
 
-       /* wait for 120ms for code download via SPI port */
-       msleep(120);
+       /* Delay 100ms per the PHY specifications */
+       msleep(100);
+
+       /* 8073 sometimes taking longer to download */
+       do {
+               count++;
+               if (count > 300) {
+                       DP(NETIF_MSG_LINK,
+                                "bnx2x_8073_8727_external_rom_boot port %x:"
+                                "Download failed. fw version = 0x%x\n",
+                                port, fw_ver1);
+                       rc = -EINVAL;
+                       break;
+               }
+
+               bnx2x_cl45_read(bp, phy,
+                               MDIO_PMA_DEVAD,
+                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
+               bnx2x_cl45_read(bp, phy,
+                               MDIO_PMA_DEVAD,
+                               MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
+
+               msleep(1);
+       } while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
+                       ((fw_msgout & 0xff) != 0x03 && (phy->type ==
+                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)));
 
        /* Clear ser_boot_ctl bit */
        bnx2x_cl45_write(bp, phy,
                       MDIO_PMA_DEVAD,
                       MDIO_PMA_REG_MISC_CTRL1, 0x0000);
        bnx2x_save_bcm_spirom_ver(bp, phy, port);
+
+       DP(NETIF_MSG_LINK,
+                "bnx2x_8073_8727_external_rom_boot port %x:"
+                "Download complete. fw version = 0x%x\n",
+                port, fw_ver1);
+
+       return rc;
 }
 
 static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp,
@@ -4108,6 +4158,25 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy,
 
        DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
 
+       /**
+        * If this is forced speed, set to KR or KX (all other are not
+        * supported)
+        */
+       /* Swap polarity if required - Must be done only in non-1G mode */
+       if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
+               /* Configure the 8073 to swap _P and _N of the KR lines */
+               DP(NETIF_MSG_LINK, "Swapping polarity for the 8073\n");
+               /* 10G Rx/Tx and 1G Tx signal polarity swap */
+               bnx2x_cl45_read(bp, phy,
+                               MDIO_PMA_DEVAD,
+                               MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
+               bnx2x_cl45_write(bp, phy,
+                                MDIO_PMA_DEVAD,
+                                MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
+                                (val | (3<<9)));
+       }
+
+
        /* Enable CL37 BAM */
        if (REG_RD(bp, params->shmem_base +
                         offsetof(struct shmem_region, dev_info.
@@ -4314,8 +4383,32 @@ static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
        }
 
        if (link_up) {
+               /* Swap polarity if required */
+               if (params->lane_config &
+                   PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
+                       /* Configure the 8073 to swap P and N of the KR lines */
+                       bnx2x_cl45_read(bp, phy,
+                                       MDIO_XS_DEVAD,
+                                       MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
+                       /**
+                       * Set bit 3 to invert Rx in 1G mode and clear this bit
+                       * when it`s in 10G mode.
+                       */
+                       if (vars->line_speed == SPEED_1000) {
+                               DP(NETIF_MSG_LINK, "Swapping 1G polarity for"
+                                             "the 8073\n");
+                               val1 |= (1<<3);
+                       } else
+                               val1 &= ~(1<<3);
+
+                       bnx2x_cl45_write(bp, phy,
+                                        MDIO_XS_DEVAD,
+                                        MDIO_XS_REG_8073_RX_CTRL_PCIE,
+                                        val1);
+               }
                bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
                bnx2x_8073_resolve_fc(phy, params, vars);
+               vars->duplex = DUPLEX_FULL;
        }
        return link_up;
 }
@@ -5062,6 +5155,7 @@ static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
                else
                        vars->line_speed = SPEED_10000;
                bnx2x_ext_phy_resolve_fc(phy, params, vars);
+               vars->duplex = DUPLEX_FULL;
        }
        return link_up;
 }
@@ -5758,8 +5852,11 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
                DP(NETIF_MSG_LINK, "port %x: External link is down\n",
                           params->port);
        }
-       if (link_up)
+       if (link_up) {
                bnx2x_ext_phy_resolve_fc(phy, params, vars);
+               vars->duplex = DUPLEX_FULL;
+               DP(NETIF_MSG_LINK, "duplex = 0x%x\n", vars->duplex);
+       }
 
        if ((DUAL_MEDIA(params)) &&
            (phy->req_line_speed == SPEED_1000)) {
@@ -5875,10 +5972,26 @@ static void bnx2x_848xx_set_led(struct bnx2x *bp,
                         MDIO_PMA_REG_8481_LED2_MASK,
                         0x18);
 
+       /* Select activity source by Tx and Rx, as suggested by PHY AE */
        bnx2x_cl45_write(bp, phy,
                         MDIO_PMA_DEVAD,
                         MDIO_PMA_REG_8481_LED3_MASK,
-                        0x0040);
+                        0x0006);
+
+       /* Select the closest activity blink rate to that in 10/100/1000 */
+       bnx2x_cl45_write(bp, phy,
+                       MDIO_PMA_DEVAD,
+                       MDIO_PMA_REG_8481_LED3_BLINK,
+                       0);
+
+       bnx2x_cl45_read(bp, phy,
+                       MDIO_PMA_DEVAD,
+                       MDIO_PMA_REG_84823_CTL_LED_CTL_1, &val);
+       val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/
+
+       bnx2x_cl45_write(bp, phy,
+                        MDIO_PMA_DEVAD,
+                        MDIO_PMA_REG_84823_CTL_LED_CTL_1, val);
 
        /* 'Interrupt Mask' */
        bnx2x_cl45_write(bp, phy,
@@ -6126,6 +6239,7 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
        /* Check link 10G */
        if (val2 & (1<<11)) {
                vars->line_speed = SPEED_10000;
+               vars->duplex = DUPLEX_FULL;
                link_up = 1;
                bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
        } else { /* Check Legacy speed link */
@@ -6489,6 +6603,7 @@ static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
                                MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
                                &val2);
                vars->line_speed = SPEED_10000;
+               vars->duplex = DUPLEX_FULL;
                DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
                           val2, (val2 & (1<<14)));
                bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
@@ -7663,7 +7778,6 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp,
 
        /* PART2 - Download firmware to both phys */
        for (port = PORT_MAX - 1; port >= PORT_0; port--) {
-               u16 fw_ver1;
                if (CHIP_IS_E2(bp))
                        port_of_path = 0;
                else
@@ -7671,19 +7785,9 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp,
 
                DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
                           phy_blk[port]->addr);
-               bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
-                                                 port_of_path);
-
-               bnx2x_cl45_read(bp, phy_blk[port],
-                             MDIO_PMA_DEVAD,
-                             MDIO_PMA_REG_ROM_VER1, &fw_ver1);
-               if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
-                       DP(NETIF_MSG_LINK,
-                                "bnx2x_8073_common_init_phy port %x:"
-                                "Download failed. fw version = 0x%x\n",
-                                port, fw_ver1);
+               if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
+                                                     port_of_path))
                        return -EINVAL;
-               }
 
                /* Only set bit 10 = 1 (Tx power down) */
                bnx2x_cl45_read(bp, phy_blk[port],
@@ -7848,27 +7952,17 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp,
        }
        /* PART2 - Download firmware to both phys */
        for (port = PORT_MAX - 1; port >= PORT_0; port--) {
-               u16 fw_ver1;
                 if (CHIP_IS_E2(bp))
                        port_of_path = 0;
                else
                        port_of_path = port;
                DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
                           phy_blk[port]->addr);
-               bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
-                                                 port_of_path);
-               bnx2x_cl45_read(bp, phy_blk[port],
-                             MDIO_PMA_DEVAD,
-                             MDIO_PMA_REG_ROM_VER1, &fw_ver1);
-               if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
-                       DP(NETIF_MSG_LINK,
-                                "bnx2x_8727_common_init_phy port %x:"
-                                "Download failed. fw version = 0x%x\n",
-                                port, fw_ver1);
+               if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
+                                                     port_of_path))
                        return -EINVAL;
-               }
-       }
 
+       }
        return 0;
 }
 
@@ -7916,6 +8010,7 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
                         u32 shmem2_base_path[], u32 chip_id)
 {
        u8 rc = 0;
+       u32 phy_ver;
        u8 phy_index;
        u32 ext_phy_type, ext_phy_config;
        DP(NETIF_MSG_LINK, "Begin common phy init\n");
@@ -7923,6 +8018,16 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
        if (CHIP_REV_IS_EMUL(bp))
                return 0;
 
+       /* Check if common init was already done */
+       phy_ver = REG_RD(bp, shmem_base_path[0] +
+                        offsetof(struct shmem_region,
+                                 port_mb[PORT_0].ext_phy_fw_version));
+       if (phy_ver) {
+               DP(NETIF_MSG_LINK, "Not doing common init; phy ver is 0x%x\n",
+                              phy_ver);
+               return 0;
+       }
+
        /* Read the ext_phy_type for arbitrary port(0) */
        for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
              phy_index++) {
index c939683..e01330b 100644 (file)
@@ -6194,7 +6194,11 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER       0x0000
 #define MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER                0x0100
 #define MDIO_CTL_REG_84823_MEDIA_FIBER_1G                      0x1000
+#define MDIO_CTL_REG_84823_USER_CTRL_REG               0x4005
+#define MDIO_CTL_REG_84823_USER_CTRL_CMS               0x0080
 
+#define MDIO_PMA_REG_84823_CTL_LED_CTL_1               0xa8e3
+#define MDIO_PMA_REG_84823_LED3_STRETCH_EN             0x0080
 
 #define IGU_FUNC_BASE                  0x0400
 
index 119aa20..5ed8f9f 100644 (file)
@@ -1920,7 +1920,7 @@ int startup_gfar(struct net_device *ndev)
                if (err) {
                        for (j = 0; j < i; j++)
                                free_grp_irqs(&priv->gfargrp[j]);
-                               goto irq_fail;
+                       goto irq_fail;
                }
        }
 
index 9e3f4f5..4488bd5 100644 (file)
@@ -635,7 +635,7 @@ static int sh_irda_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
 
        ret = sh_irda_set_baudrate(self, speed);
        if (ret < 0)
-               return ret;
+               goto sh_irda_hard_xmit_end;
 
        self->tx_buff.len = 0;
        if (skb->len) {
@@ -652,11 +652,21 @@ static int sh_irda_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
 
                sh_irda_write(self, IRTFLR, self->tx_buff.len);
                sh_irda_write(self, IRTCTR, ARMOD | TE);
-       }
+       } else
+               goto sh_irda_hard_xmit_end;
 
        dev_kfree_skb(skb);
 
        return 0;
+
+sh_irda_hard_xmit_end:
+       sh_irda_set_baudrate(self, 9600);
+       netif_wake_queue(self->ndev);
+       sh_irda_rcv_ctrl(self, 1);
+       dev_kfree_skb(skb);
+
+       return ret;
+
 }
 
 static int sh_irda_ioctl(struct net_device *ndev, struct ifreq *ifreq, int cmd)
index 84134c7..a41b2cf 100644 (file)
@@ -1988,12 +1988,11 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev,
        }
 
        ndev = alloc_etherdev(sizeof(struct ns83820));
-       dev = PRIV(ndev);
-
        err = -ENOMEM;
-       if (!dev)
+       if (!ndev)
                goto out;
 
+       dev = PRIV(ndev);
        dev->ndev = ndev;
 
        spin_lock_init(&dev->rx_info.lock);
index d776c4a..04e8ce1 100644 (file)
@@ -54,7 +54,7 @@
 #include <linux/usb/usbnet.h>
 #include <linux/usb/cdc.h>
 
-#define        DRIVER_VERSION                          "30-Nov-2010"
+#define        DRIVER_VERSION                          "17-Jan-2011"
 
 /* CDC NCM subclass 3.2.1 */
 #define USB_CDC_NCM_NDP16_LENGTH_MIN           0x10
@@ -868,15 +868,19 @@ static void cdc_ncm_tx_timeout(unsigned long arg)
        if (ctx->tx_timer_pending != 0) {
                ctx->tx_timer_pending--;
                restart = 1;
-       } else
+       } else {
                restart = 0;
+       }
 
        spin_unlock(&ctx->mtx);
 
-       if (restart)
+       if (restart) {
+               spin_lock(&ctx->mtx);
                cdc_ncm_tx_timeout_start(ctx);
-       else if (ctx->netdev != NULL)
+               spin_unlock(&ctx->mtx);
+       } else if (ctx->netdev != NULL) {
                usbnet_start_xmit(NULL, ctx->netdev);
+       }
 }
 
 static struct sk_buff *
@@ -900,7 +904,6 @@ cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
        skb_out = cdc_ncm_fill_tx_frame(ctx, skb);
        if (ctx->tx_curr_skb != NULL)
                need_timer = 1;
-       spin_unlock(&ctx->mtx);
 
        /* Start timer, if there is a remaining skb */
        if (need_timer)
@@ -908,6 +911,8 @@ cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
 
        if (skb_out)
                dev->net->stats.tx_packets += ctx->tx_curr_frame_num;
+
+       spin_unlock(&ctx->mtx);
        return skb_out;
 
 error:
@@ -1020,8 +1025,8 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
                if (((offset + temp) > actlen) ||
                    (temp > CDC_NCM_MAX_DATAGRAM_SIZE) || (temp < ETH_HLEN)) {
                        pr_debug("invalid frame detected (ignored)"
-                               "offset[%u]=%u, length=%u, skb=%p\n",
-                                                       x, offset, temp, skb_in);
+                                       "offset[%u]=%u, length=%u, skb=%p\n",
+                                       x, offset, temp, skb_in);
                        if (!x)
                                goto error;
                        break;
index d143e8b..cc14b4a 100644 (file)
@@ -48,6 +48,9 @@ static atomic_t devices_found;
 static int enable_mq = 1;
 static int irq_share_mode;
 
+static void
+vmxnet3_write_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac);
+
 /*
  *    Enable/Disable the given intr
  */
@@ -139,9 +142,13 @@ vmxnet3_check_link(struct vmxnet3_adapter *adapter, bool affectTxQueue)
 {
        u32 ret;
        int i;
+       unsigned long flags;
 
+       spin_lock_irqsave(&adapter->cmd_lock, flags);
        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
        ret = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
+       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
+
        adapter->link_speed = ret >> 16;
        if (ret & 1) { /* Link is up. */
                printk(KERN_INFO "%s: NIC Link is Up %d Mbps\n",
@@ -183,8 +190,10 @@ vmxnet3_process_events(struct vmxnet3_adapter *adapter)
 
        /* Check if there is an error on xmit/recv queues */
        if (events & (VMXNET3_ECR_TQERR | VMXNET3_ECR_RQERR)) {
+               spin_lock(&adapter->cmd_lock);
                VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
                                       VMXNET3_CMD_GET_QUEUE_STATUS);
+               spin_unlock(&adapter->cmd_lock);
 
                for (i = 0; i < adapter->num_tx_queues; i++)
                        if (adapter->tqd_start[i].status.stopped)
@@ -804,30 +813,25 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
                                   skb_transport_header(skb))->doff * 4;
                ctx->copy_size = ctx->eth_ip_hdr_size + ctx->l4_hdr_size;
        } else {
-               unsigned int pull_size;
-
                if (skb->ip_summed == CHECKSUM_PARTIAL) {
                        ctx->eth_ip_hdr_size = skb_checksum_start_offset(skb);
 
                        if (ctx->ipv4) {
                                struct iphdr *iph = (struct iphdr *)
                                                    skb_network_header(skb);
-                               if (iph->protocol == IPPROTO_TCP) {
-                                       pull_size = ctx->eth_ip_hdr_size +
-                                                   sizeof(struct tcphdr);
-
-                                       if (unlikely(!pskb_may_pull(skb,
-                                                               pull_size))) {
-                                               goto err;
-                                       }
+                               if (iph->protocol == IPPROTO_TCP)
                                        ctx->l4_hdr_size = ((struct tcphdr *)
                                           skb_transport_header(skb))->doff * 4;
-                               } else if (iph->protocol == IPPROTO_UDP) {
+                               else if (iph->protocol == IPPROTO_UDP)
+                                       /*
+                                        * Use tcp header size so that bytes to
+                                        * be copied are more than required by
+                                        * the device.
+                                        */
                                        ctx->l4_hdr_size =
-                                                       sizeof(struct udphdr);
-                               } else {
+                                                       sizeof(struct tcphdr);
+                               else
                                        ctx->l4_hdr_size = 0;
-                               }
                        } else {
                                /* for simplicity, don't copy L4 headers */
                                ctx->l4_hdr_size = 0;
@@ -1859,18 +1863,14 @@ vmxnet3_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
        struct Vmxnet3_DriverShared *shared = adapter->shared;
        u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
+       unsigned long flags;
 
        if (grp) {
                /* add vlan rx stripping. */
                if (adapter->netdev->features & NETIF_F_HW_VLAN_RX) {
                        int i;
-                       struct Vmxnet3_DSDevRead *devRead = &shared->devRead;
                        adapter->vlan_grp = grp;
 
-                       /* update FEATURES to device */
-                       devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
-                       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
-                                              VMXNET3_CMD_UPDATE_FEATURE);
                        /*
                         *  Clear entire vfTable; then enable untagged pkts.
                         *  Note: setting one entry in vfTable to non-zero turns
@@ -1880,8 +1880,10 @@ vmxnet3_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
                                vfTable[i] = 0;
 
                        VMXNET3_SET_VFTABLE_ENTRY(vfTable, 0);
+                       spin_lock_irqsave(&adapter->cmd_lock, flags);
                        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
                                               VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+                       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
                } else {
                        printk(KERN_ERR "%s: vlan_rx_register when device has "
                               "no NETIF_F_HW_VLAN_RX\n", netdev->name);
@@ -1900,13 +1902,10 @@ vmxnet3_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
                                 */
                                vfTable[i] = 0;
                        }
+                       spin_lock_irqsave(&adapter->cmd_lock, flags);
                        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
                                               VMXNET3_CMD_UPDATE_VLAN_FILTERS);
-
-                       /* update FEATURES to device */
-                       devRead->misc.uptFeatures &= ~UPT1_F_RXVLAN;
-                       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
-                                              VMXNET3_CMD_UPDATE_FEATURE);
+                       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
                }
        }
 }
@@ -1939,10 +1938,13 @@ vmxnet3_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
 {
        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
        u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
+       unsigned long flags;
 
        VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid);
+       spin_lock_irqsave(&adapter->cmd_lock, flags);
        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
                               VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
 }
 
 
@@ -1951,10 +1953,13 @@ vmxnet3_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
 {
        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
        u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
+       unsigned long flags;
 
        VMXNET3_CLEAR_VFTABLE_ENTRY(vfTable, vid);
+       spin_lock_irqsave(&adapter->cmd_lock, flags);
        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
                               VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
 }
 
 
@@ -1985,6 +1990,7 @@ static void
 vmxnet3_set_mc(struct net_device *netdev)
 {
        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       unsigned long flags;
        struct Vmxnet3_RxFilterConf *rxConf =
                                        &adapter->shared->devRead.rxFilterConf;
        u8 *new_table = NULL;
@@ -2020,6 +2026,7 @@ vmxnet3_set_mc(struct net_device *netdev)
                rxConf->mfTablePA = 0;
        }
 
+       spin_lock_irqsave(&adapter->cmd_lock, flags);
        if (new_mode != rxConf->rxMode) {
                rxConf->rxMode = cpu_to_le32(new_mode);
                VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
@@ -2028,6 +2035,7 @@ vmxnet3_set_mc(struct net_device *netdev)
 
        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
                               VMXNET3_CMD_UPDATE_MAC_FILTERS);
+       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
 
        kfree(new_table);
 }
@@ -2080,10 +2088,8 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter)
                devRead->misc.uptFeatures |= UPT1_F_LRO;
                devRead->misc.maxNumRxSG = cpu_to_le16(1 + MAX_SKB_FRAGS);
        }
-       if ((adapter->netdev->features & NETIF_F_HW_VLAN_RX) &&
-           adapter->vlan_grp) {
+       if (adapter->netdev->features & NETIF_F_HW_VLAN_RX)
                devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
-       }
 
        devRead->misc.mtu = cpu_to_le32(adapter->netdev->mtu);
        devRead->misc.queueDescPA = cpu_to_le64(adapter->queue_desc_pa);
@@ -2168,6 +2174,8 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter)
        /* rx filter settings */
        devRead->rxFilterConf.rxMode = 0;
        vmxnet3_restore_vlan(adapter);
+       vmxnet3_write_mac_addr(adapter, adapter->netdev->dev_addr);
+
        /* the rest are already zeroed */
 }
 
@@ -2177,6 +2185,7 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter)
 {
        int err, i;
        u32 ret;
+       unsigned long flags;
 
        dev_dbg(&adapter->netdev->dev, "%s: skb_buf_size %d, rx_buf_per_pkt %d,"
                " ring sizes %u %u %u\n", adapter->netdev->name,
@@ -2206,9 +2215,11 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter)
                               adapter->shared_pa));
        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAH, VMXNET3_GET_ADDR_HI(
                               adapter->shared_pa));
+       spin_lock_irqsave(&adapter->cmd_lock, flags);
        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
                               VMXNET3_CMD_ACTIVATE_DEV);
        ret = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
+       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
 
        if (ret != 0) {
                printk(KERN_ERR "Failed to activate dev %s: error %u\n",
@@ -2255,7 +2266,10 @@ rq_err:
 void
 vmxnet3_reset_dev(struct vmxnet3_adapter *adapter)
 {
+       unsigned long flags;
+       spin_lock_irqsave(&adapter->cmd_lock, flags);
        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
+       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
 }
 
 
@@ -2263,12 +2277,15 @@ int
 vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter)
 {
        int i;
+       unsigned long flags;
        if (test_and_set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state))
                return 0;
 
 
+       spin_lock_irqsave(&adapter->cmd_lock, flags);
        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
                               VMXNET3_CMD_QUIESCE_DEV);
+       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
        vmxnet3_disable_all_intrs(adapter);
 
        for (i = 0; i < adapter->num_rx_queues; i++)
@@ -2426,7 +2443,7 @@ vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter)
        sz = adapter->rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN;
        ring0_size = adapter->rx_queue[0].rx_ring[0].size;
        ring0_size = (ring0_size + sz - 1) / sz * sz;
-       ring0_size = min_t(u32, rq->rx_ring[0].size, VMXNET3_RX_RING_MAX_SIZE /
+       ring0_size = min_t(u32, ring0_size, VMXNET3_RX_RING_MAX_SIZE /
                           sz * sz);
        ring1_size = adapter->rx_queue[0].rx_ring[1].size;
        comp_size = ring0_size + ring1_size;
@@ -2695,7 +2712,7 @@ vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter,
                        break;
                } else {
                        /* If fails to enable required number of MSI-x vectors
-                        * try enabling 3 of them. One each for rx, tx and event
+                        * try enabling minimum number of vectors required.
                         */
                        vectors = vector_threshold;
                        printk(KERN_ERR "Failed to enable %d MSI-X for %s, try"
@@ -2718,9 +2735,11 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter)
        u32 cfg;
 
        /* intr settings */
+       spin_lock(&adapter->cmd_lock);
        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
                               VMXNET3_CMD_GET_CONF_INTR);
        cfg = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
+       spin_unlock(&adapter->cmd_lock);
        adapter->intr.type = cfg & 0x3;
        adapter->intr.mask_mode = (cfg >> 2) & 0x3;
 
@@ -2755,7 +2774,7 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter)
                 */
                if (err == VMXNET3_LINUX_MIN_MSIX_VECT) {
                        if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE
-                           || adapter->num_rx_queues != 2) {
+                           || adapter->num_rx_queues != 1) {
                                adapter->share_intr = VMXNET3_INTR_TXSHARE;
                                printk(KERN_ERR "Number of rx queues : 1\n");
                                adapter->num_rx_queues = 1;
@@ -2905,6 +2924,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
        adapter->netdev = netdev;
        adapter->pdev = pdev;
 
+       spin_lock_init(&adapter->cmd_lock);
        adapter->shared = pci_alloc_consistent(adapter->pdev,
                          sizeof(struct Vmxnet3_DriverShared),
                          &adapter->shared_pa);
@@ -3108,11 +3128,15 @@ vmxnet3_suspend(struct device *device)
        u8 *arpreq;
        struct in_device *in_dev;
        struct in_ifaddr *ifa;
+       unsigned long flags;
        int i = 0;
 
        if (!netif_running(netdev))
                return 0;
 
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               napi_disable(&adapter->rx_queue[i].napi);
+
        vmxnet3_disable_all_intrs(adapter);
        vmxnet3_free_irqs(adapter);
        vmxnet3_free_intr_resources(adapter);
@@ -3188,8 +3212,10 @@ skip_arp:
        adapter->shared->devRead.pmConfDesc.confPA = cpu_to_le64(virt_to_phys(
                                                                 pmConf));
 
+       spin_lock_irqsave(&adapter->cmd_lock, flags);
        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
                               VMXNET3_CMD_UPDATE_PMCFG);
+       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
 
        pci_save_state(pdev);
        pci_enable_wake(pdev, pci_choose_state(pdev, PMSG_SUSPEND),
@@ -3204,7 +3230,8 @@ skip_arp:
 static int
 vmxnet3_resume(struct device *device)
 {
-       int err;
+       int err, i = 0;
+       unsigned long flags;
        struct pci_dev *pdev = to_pci_dev(device);
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
@@ -3232,10 +3259,14 @@ vmxnet3_resume(struct device *device)
 
        pci_enable_wake(pdev, PCI_D0, 0);
 
+       spin_lock_irqsave(&adapter->cmd_lock, flags);
        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
                               VMXNET3_CMD_UPDATE_PMCFG);
+       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
        vmxnet3_alloc_intr_resources(adapter);
        vmxnet3_request_irqs(adapter);
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               napi_enable(&adapter->rx_queue[i].napi);
        vmxnet3_enable_all_intrs(adapter);
 
        return 0;
index 8e17fc8..81254be 100644 (file)
@@ -45,6 +45,7 @@ static int
 vmxnet3_set_rx_csum(struct net_device *netdev, u32 val)
 {
        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       unsigned long flags;
 
        if (adapter->rxcsum != val) {
                adapter->rxcsum = val;
@@ -56,8 +57,10 @@ vmxnet3_set_rx_csum(struct net_device *netdev, u32 val)
                                adapter->shared->devRead.misc.uptFeatures &=
                                ~UPT1_F_RXCSUM;
 
+                       spin_lock_irqsave(&adapter->cmd_lock, flags);
                        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
                                               VMXNET3_CMD_UPDATE_FEATURE);
+                       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
                }
        }
        return 0;
@@ -68,76 +71,78 @@ vmxnet3_set_rx_csum(struct net_device *netdev, u32 val)
 static const struct vmxnet3_stat_desc
 vmxnet3_tq_dev_stats[] = {
        /* description,         offset */
-       { "TSO pkts tx",        offsetof(struct UPT1_TxStats, TSOPktsTxOK) },
-       { "TSO bytes tx",       offsetof(struct UPT1_TxStats, TSOBytesTxOK) },
-       { "ucast pkts tx",      offsetof(struct UPT1_TxStats, ucastPktsTxOK) },
-       { "ucast bytes tx",     offsetof(struct UPT1_TxStats, ucastBytesTxOK) },
-       { "mcast pkts tx",      offsetof(struct UPT1_TxStats, mcastPktsTxOK) },
-       { "mcast bytes tx",     offsetof(struct UPT1_TxStats, mcastBytesTxOK) },
-       { "bcast pkts tx",      offsetof(struct UPT1_TxStats, bcastPktsTxOK) },
-       { "bcast bytes tx",     offsetof(struct UPT1_TxStats, bcastBytesTxOK) },
-       { "pkts tx err",        offsetof(struct UPT1_TxStats, pktsTxError) },
-       { "pkts tx discard",    offsetof(struct UPT1_TxStats, pktsTxDiscard) },
+       { "Tx Queue#",        0 },
+       { "  TSO pkts tx",      offsetof(struct UPT1_TxStats, TSOPktsTxOK) },
+       { "  TSO bytes tx",     offsetof(struct UPT1_TxStats, TSOBytesTxOK) },
+       { "  ucast pkts tx",    offsetof(struct UPT1_TxStats, ucastPktsTxOK) },
+       { "  ucast bytes tx",   offsetof(struct UPT1_TxStats, ucastBytesTxOK) },
+       { "  mcast pkts tx",    offsetof(struct UPT1_TxStats, mcastPktsTxOK) },
+       { "  mcast bytes tx",   offsetof(struct UPT1_TxStats, mcastBytesTxOK) },
+       { "  bcast pkts tx",    offsetof(struct UPT1_TxStats, bcastPktsTxOK) },
+       { "  bcast bytes tx",   offsetof(struct UPT1_TxStats, bcastBytesTxOK) },
+       { "  pkts tx err",      offsetof(struct UPT1_TxStats, pktsTxError) },
+       { "  pkts tx discard",  offsetof(struct UPT1_TxStats, pktsTxDiscard) },
 };
 
 /* per tq stats maintained by the driver */
 static const struct vmxnet3_stat_desc
 vmxnet3_tq_driver_stats[] = {
        /* description,         offset */
-       {"drv dropped tx total", offsetof(struct vmxnet3_tq_driver_stats,
-                                       drop_total) },
-       { "   too many frags",  offsetof(struct vmxnet3_tq_driver_stats,
-                                       drop_too_many_frags) },
-       { "   giant hdr",       offsetof(struct vmxnet3_tq_driver_stats,
-                                       drop_oversized_hdr) },
-       { "   hdr err",         offsetof(struct vmxnet3_tq_driver_stats,
-                                       drop_hdr_inspect_err) },
-       { "   tso",             offsetof(struct vmxnet3_tq_driver_stats,
-                                       drop_tso) },
-       { "ring full",          offsetof(struct vmxnet3_tq_driver_stats,
-                                       tx_ring_full) },
-       { "pkts linearized",    offsetof(struct vmxnet3_tq_driver_stats,
-                                       linearized) },
-       { "hdr cloned",         offsetof(struct vmxnet3_tq_driver_stats,
-                                       copy_skb_header) },
-       { "giant hdr",          offsetof(struct vmxnet3_tq_driver_stats,
-                                       oversized_hdr) },
+       {"  drv dropped tx total",      offsetof(struct vmxnet3_tq_driver_stats,
+                                                drop_total) },
+       { "     too many frags", offsetof(struct vmxnet3_tq_driver_stats,
+                                         drop_too_many_frags) },
+       { "     giant hdr",     offsetof(struct vmxnet3_tq_driver_stats,
+                                        drop_oversized_hdr) },
+       { "     hdr err",       offsetof(struct vmxnet3_tq_driver_stats,
+                                        drop_hdr_inspect_err) },
+       { "     tso",           offsetof(struct vmxnet3_tq_driver_stats,
+                                        drop_tso) },
+       { "  ring full",        offsetof(struct vmxnet3_tq_driver_stats,
+                                        tx_ring_full) },
+       { "  pkts linearized",  offsetof(struct vmxnet3_tq_driver_stats,
+                                        linearized) },
+       { "  hdr cloned",       offsetof(struct vmxnet3_tq_driver_stats,
+                                        copy_skb_header) },
+       { "  giant hdr",        offsetof(struct vmxnet3_tq_driver_stats,
+                                        oversized_hdr) },
 };
 
 /* per rq stats maintained by the device */
 static const struct vmxnet3_stat_desc
 vmxnet3_rq_dev_stats[] = {
-       { "LRO pkts rx",        offsetof(struct UPT1_RxStats, LROPktsRxOK) },
-       { "LRO byte rx",        offsetof(struct UPT1_RxStats, LROBytesRxOK) },
-       { "ucast pkts rx",      offsetof(struct UPT1_RxStats, ucastPktsRxOK) },
-       { "ucast bytes rx",     offsetof(struct UPT1_RxStats, ucastBytesRxOK) },
-       { "mcast pkts rx",      offsetof(struct UPT1_RxStats, mcastPktsRxOK) },
-       { "mcast bytes rx",     offsetof(struct UPT1_RxStats, mcastBytesRxOK) },
-       { "bcast pkts rx",      offsetof(struct UPT1_RxStats, bcastPktsRxOK) },
-       { "bcast bytes rx",     offsetof(struct UPT1_RxStats, bcastBytesRxOK) },
-       { "pkts rx out of buf", offsetof(struct UPT1_RxStats, pktsRxOutOfBuf) },
-       { "pkts rx err",        offsetof(struct UPT1_RxStats, pktsRxError) },
+       { "Rx Queue#",        0 },
+       { "  LRO pkts rx",      offsetof(struct UPT1_RxStats, LROPktsRxOK) },
+       { "  LRO byte rx",      offsetof(struct UPT1_RxStats, LROBytesRxOK) },
+       { "  ucast pkts rx",    offsetof(struct UPT1_RxStats, ucastPktsRxOK) },
+       { "  ucast bytes rx",   offsetof(struct UPT1_RxStats, ucastBytesRxOK) },
+       { "  mcast pkts rx",    offsetof(struct UPT1_RxStats, mcastPktsRxOK) },
+       { "  mcast bytes rx",   offsetof(struct UPT1_RxStats, mcastBytesRxOK) },
+       { "  bcast pkts rx",    offsetof(struct UPT1_RxStats, bcastPktsRxOK) },
+       { "  bcast bytes rx",   offsetof(struct UPT1_RxStats, bcastBytesRxOK) },
+       { "  pkts rx OOB",      offsetof(struct UPT1_RxStats, pktsRxOutOfBuf) },
+       { "  pkts rx err",      offsetof(struct UPT1_RxStats, pktsRxError) },
 };
 
 /* per rq stats maintained by the driver */
 static const struct vmxnet3_stat_desc
 vmxnet3_rq_driver_stats[] = {
        /* description,         offset */
-       { "drv dropped rx total", offsetof(struct vmxnet3_rq_driver_stats,
-                                          drop_total) },
-       { "   err",            offsetof(struct vmxnet3_rq_driver_stats,
-                                       drop_err) },
-       { "   fcs",            offsetof(struct vmxnet3_rq_driver_stats,
-                                       drop_fcs) },
-       { "rx buf alloc fail", offsetof(struct vmxnet3_rq_driver_stats,
-                                       rx_buf_alloc_failure) },
+       { "  drv dropped rx total", offsetof(struct vmxnet3_rq_driver_stats,
+                                            drop_total) },
+       { "     err",           offsetof(struct vmxnet3_rq_driver_stats,
+                                        drop_err) },
+       { "     fcs",           offsetof(struct vmxnet3_rq_driver_stats,
+                                        drop_fcs) },
+       { "  rx buf alloc fail", offsetof(struct vmxnet3_rq_driver_stats,
+                                         rx_buf_alloc_failure) },
 };
 
 /* gloabl stats maintained by the driver */
 static const struct vmxnet3_stat_desc
 vmxnet3_global_stats[] = {
        /* description,         offset */
-       { "tx timeout count",   offsetof(struct vmxnet3_adapter,
+       { "tx timeout count",   offsetof(struct vmxnet3_adapter,
                                         tx_timeout_count) }
 };
 
@@ -151,12 +156,15 @@ vmxnet3_get_stats(struct net_device *netdev)
        struct UPT1_TxStats *devTxStats;
        struct UPT1_RxStats *devRxStats;
        struct net_device_stats *net_stats = &netdev->stats;
+       unsigned long flags;
        int i;
 
        adapter = netdev_priv(netdev);
 
        /* Collect the dev stats into the shared area */
+       spin_lock_irqsave(&adapter->cmd_lock, flags);
        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
+       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
 
        memset(net_stats, 0, sizeof(*net_stats));
        for (i = 0; i < adapter->num_tx_queues; i++) {
@@ -193,12 +201,15 @@ vmxnet3_get_stats(struct net_device *netdev)
 static int
 vmxnet3_get_sset_count(struct net_device *netdev, int sset)
 {
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
        switch (sset) {
        case ETH_SS_STATS:
-               return ARRAY_SIZE(vmxnet3_tq_dev_stats) +
-                       ARRAY_SIZE(vmxnet3_tq_driver_stats) +
-                       ARRAY_SIZE(vmxnet3_rq_dev_stats) +
-                       ARRAY_SIZE(vmxnet3_rq_driver_stats) +
+               return (ARRAY_SIZE(vmxnet3_tq_dev_stats) +
+                       ARRAY_SIZE(vmxnet3_tq_driver_stats)) *
+                      adapter->num_tx_queues +
+                      (ARRAY_SIZE(vmxnet3_rq_dev_stats) +
+                       ARRAY_SIZE(vmxnet3_rq_driver_stats)) *
+                      adapter->num_rx_queues +
                        ARRAY_SIZE(vmxnet3_global_stats);
        default:
                return -EOPNOTSUPP;
@@ -206,10 +217,16 @@ vmxnet3_get_sset_count(struct net_device *netdev, int sset)
 }
 
 
+/* Should be multiple of 4 */
+#define NUM_TX_REGS    8
+#define NUM_RX_REGS    12
+
 static int
 vmxnet3_get_regs_len(struct net_device *netdev)
 {
-       return 20 * sizeof(u32);
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       return (adapter->num_tx_queues * NUM_TX_REGS * sizeof(u32) +
+               adapter->num_rx_queues * NUM_RX_REGS * sizeof(u32));
 }
 
 
@@ -240,29 +257,37 @@ vmxnet3_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
 static void
 vmxnet3_get_strings(struct net_device *netdev, u32 stringset, u8 *buf)
 {
+        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
        if (stringset == ETH_SS_STATS) {
-               int i;
-
-               for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++) {
-                       memcpy(buf, vmxnet3_tq_dev_stats[i].desc,
-                              ETH_GSTRING_LEN);
-                       buf += ETH_GSTRING_LEN;
-               }
-               for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++) {
-                       memcpy(buf, vmxnet3_tq_driver_stats[i].desc,
-                              ETH_GSTRING_LEN);
-                       buf += ETH_GSTRING_LEN;
-               }
-               for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++) {
-                       memcpy(buf, vmxnet3_rq_dev_stats[i].desc,
-                              ETH_GSTRING_LEN);
-                       buf += ETH_GSTRING_LEN;
+               int i, j;
+               for (j = 0; j < adapter->num_tx_queues; j++) {
+                       for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++) {
+                               memcpy(buf, vmxnet3_tq_dev_stats[i].desc,
+                                      ETH_GSTRING_LEN);
+                               buf += ETH_GSTRING_LEN;
+                       }
+                       for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats);
+                            i++) {
+                               memcpy(buf, vmxnet3_tq_driver_stats[i].desc,
+                                      ETH_GSTRING_LEN);
+                               buf += ETH_GSTRING_LEN;
+                       }
                }
-               for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++) {
-                       memcpy(buf, vmxnet3_rq_driver_stats[i].desc,
-                              ETH_GSTRING_LEN);
-                       buf += ETH_GSTRING_LEN;
+
+               for (j = 0; j < adapter->num_rx_queues; j++) {
+                       for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++) {
+                               memcpy(buf, vmxnet3_rq_dev_stats[i].desc,
+                                      ETH_GSTRING_LEN);
+                               buf += ETH_GSTRING_LEN;
+                       }
+                       for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats);
+                            i++) {
+                               memcpy(buf, vmxnet3_rq_driver_stats[i].desc,
+                                      ETH_GSTRING_LEN);
+                               buf += ETH_GSTRING_LEN;
+                       }
                }
+
                for (i = 0; i < ARRAY_SIZE(vmxnet3_global_stats); i++) {
                        memcpy(buf, vmxnet3_global_stats[i].desc,
                                ETH_GSTRING_LEN);
@@ -277,6 +302,7 @@ vmxnet3_set_flags(struct net_device *netdev, u32 data)
        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
        u8 lro_requested = (data & ETH_FLAG_LRO) == 0 ? 0 : 1;
        u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1;
+       unsigned long flags;
 
        if (data & ~ETH_FLAG_LRO)
                return -EOPNOTSUPP;
@@ -292,8 +318,10 @@ vmxnet3_set_flags(struct net_device *netdev, u32 data)
                else
                        adapter->shared->devRead.misc.uptFeatures &=
                                                        ~UPT1_F_LRO;
+               spin_lock_irqsave(&adapter->cmd_lock, flags);
                VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
                                       VMXNET3_CMD_UPDATE_FEATURE);
+               spin_unlock_irqrestore(&adapter->cmd_lock, flags);
        }
        return 0;
 }
@@ -303,30 +331,41 @@ vmxnet3_get_ethtool_stats(struct net_device *netdev,
                          struct ethtool_stats *stats, u64  *buf)
 {
        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       unsigned long flags;
        u8 *base;
        int i;
        int j = 0;
 
+       spin_lock_irqsave(&adapter->cmd_lock, flags);
        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
+       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
 
        /* this does assume each counter is 64-bit wide */
-/* TODO change this for multiple queues */
-
-       base = (u8 *)&adapter->tqd_start[j].stats;
-       for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++)
-               *buf++ = *(u64 *)(base + vmxnet3_tq_dev_stats[i].offset);
-
-       base = (u8 *)&adapter->tx_queue[j].stats;
-       for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++)
-               *buf++ = *(u64 *)(base + vmxnet3_tq_driver_stats[i].offset);
-
-       base = (u8 *)&adapter->rqd_start[j].stats;
-       for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++)
-               *buf++ = *(u64 *)(base + vmxnet3_rq_dev_stats[i].offset);
+       for (j = 0; j < adapter->num_tx_queues; j++) {
+               base = (u8 *)&adapter->tqd_start[j].stats;
+               *buf++ = (u64)j;
+               for (i = 1; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++)
+                       *buf++ = *(u64 *)(base +
+                                         vmxnet3_tq_dev_stats[i].offset);
+
+               base = (u8 *)&adapter->tx_queue[j].stats;
+               for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++)
+                       *buf++ = *(u64 *)(base +
+                                         vmxnet3_tq_driver_stats[i].offset);
+       }
 
-       base = (u8 *)&adapter->rx_queue[j].stats;
-       for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++)
-               *buf++ = *(u64 *)(base + vmxnet3_rq_driver_stats[i].offset);
+       for (j = 0; j < adapter->num_tx_queues; j++) {
+               base = (u8 *)&adapter->rqd_start[j].stats;
+               *buf++ = (u64) j;
+               for (i = 1; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++)
+                       *buf++ = *(u64 *)(base +
+                                         vmxnet3_rq_dev_stats[i].offset);
+
+               base = (u8 *)&adapter->rx_queue[j].stats;
+               for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++)
+                       *buf++ = *(u64 *)(base +
+                                         vmxnet3_rq_driver_stats[i].offset);
+       }
 
        base = (u8 *)adapter;
        for (i = 0; i < ARRAY_SIZE(vmxnet3_global_stats); i++)
@@ -339,7 +378,7 @@ vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p)
 {
        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
        u32 *buf = p;
-       int i = 0;
+       int i = 0, j = 0;
 
        memset(p, 0, vmxnet3_get_regs_len(netdev));
 
@@ -348,31 +387,35 @@ vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p)
        /* Update vmxnet3_get_regs_len if we want to dump more registers */
 
        /* make each ring use multiple of 16 bytes */
-/* TODO change this for multiple queues */
-       buf[0] = adapter->tx_queue[i].tx_ring.next2fill;
-       buf[1] = adapter->tx_queue[i].tx_ring.next2comp;
-       buf[2] = adapter->tx_queue[i].tx_ring.gen;
-       buf[3] = 0;
-
-       buf[4] = adapter->tx_queue[i].comp_ring.next2proc;
-       buf[5] = adapter->tx_queue[i].comp_ring.gen;
-       buf[6] = adapter->tx_queue[i].stopped;
-       buf[7] = 0;
-
-       buf[8] = adapter->rx_queue[i].rx_ring[0].next2fill;
-       buf[9] = adapter->rx_queue[i].rx_ring[0].next2comp;
-       buf[10] = adapter->rx_queue[i].rx_ring[0].gen;
-       buf[11] = 0;
-
-       buf[12] = adapter->rx_queue[i].rx_ring[1].next2fill;
-       buf[13] = adapter->rx_queue[i].rx_ring[1].next2comp;
-       buf[14] = adapter->rx_queue[i].rx_ring[1].gen;
-       buf[15] = 0;
-
-       buf[16] = adapter->rx_queue[i].comp_ring.next2proc;
-       buf[17] = adapter->rx_queue[i].comp_ring.gen;
-       buf[18] = 0;
-       buf[19] = 0;
+       for (i = 0; i < adapter->num_tx_queues; i++) {
+               buf[j++] = adapter->tx_queue[i].tx_ring.next2fill;
+               buf[j++] = adapter->tx_queue[i].tx_ring.next2comp;
+               buf[j++] = adapter->tx_queue[i].tx_ring.gen;
+               buf[j++] = 0;
+
+               buf[j++] = adapter->tx_queue[i].comp_ring.next2proc;
+               buf[j++] = adapter->tx_queue[i].comp_ring.gen;
+               buf[j++] = adapter->tx_queue[i].stopped;
+               buf[j++] = 0;
+       }
+
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               buf[j++] = adapter->rx_queue[i].rx_ring[0].next2fill;
+               buf[j++] = adapter->rx_queue[i].rx_ring[0].next2comp;
+               buf[j++] = adapter->rx_queue[i].rx_ring[0].gen;
+               buf[j++] = 0;
+
+               buf[j++] = adapter->rx_queue[i].rx_ring[1].next2fill;
+               buf[j++] = adapter->rx_queue[i].rx_ring[1].next2comp;
+               buf[j++] = adapter->rx_queue[i].rx_ring[1].gen;
+               buf[j++] = 0;
+
+               buf[j++] = adapter->rx_queue[i].comp_ring.next2proc;
+               buf[j++] = adapter->rx_queue[i].comp_ring.gen;
+               buf[j++] = 0;
+               buf[j++] = 0;
+       }
+
 }
 
 
@@ -574,6 +617,7 @@ vmxnet3_set_rss_indir(struct net_device *netdev,
                      const struct ethtool_rxfh_indir *p)
 {
        unsigned int i;
+       unsigned long flags;
        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
        struct UPT1_RSSConf *rssConf = adapter->rss_conf;
 
@@ -592,8 +636,10 @@ vmxnet3_set_rss_indir(struct net_device *netdev,
        for (i = 0; i < rssConf->indTableSize; i++)
                rssConf->indTable[i] = p->ring_index[i];
 
+       spin_lock_irqsave(&adapter->cmd_lock, flags);
        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
                               VMXNET3_CMD_UPDATE_RSSIDT);
+       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
 
        return 0;
 
index 7fadeed..fb5d245 100644 (file)
 /*
  * Version numbers
  */
-#define VMXNET3_DRIVER_VERSION_STRING   "1.0.16.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING   "1.0.25.0-k"
 
 /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM      0x01001000
+#define VMXNET3_DRIVER_VERSION_NUM      0x01001900
 
 #if defined(CONFIG_PCI_MSI)
        /* RSS only makes sense if MSI-X is supported. */
@@ -289,7 +289,7 @@ struct vmxnet3_rx_queue {
 
 #define VMXNET3_LINUX_MAX_MSIX_VECT     (VMXNET3_DEVICE_MAX_TX_QUEUES + \
                                         VMXNET3_DEVICE_MAX_RX_QUEUES + 1)
-#define VMXNET3_LINUX_MIN_MSIX_VECT     3    /* 1 for each : tx, rx and event */
+#define VMXNET3_LINUX_MIN_MSIX_VECT     2 /* 1 for tx-rx pair and 1 for event */
 
 
 struct vmxnet3_intr {
@@ -317,6 +317,7 @@ struct vmxnet3_adapter {
        struct vmxnet3_rx_queue         rx_queue[VMXNET3_DEVICE_MAX_RX_QUEUES];
        struct vlan_group               *vlan_grp;
        struct vmxnet3_intr             intr;
+       spinlock_t                      cmd_lock;
        struct Vmxnet3_DriverShared     *shared;
        struct Vmxnet3_PMConf           *pm_conf;
        struct Vmxnet3_TxQueueDesc      *tqd_start;     /* all tx queue desc */
index 019a74d..09ae4ef 100644 (file)
@@ -2294,6 +2294,8 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
        int i;
        bool needreset = false;
 
+       mutex_lock(&sc->lock);
+
        for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
                if (sc->txqs[i].setup) {
                        txq = &sc->txqs[i];
@@ -2321,6 +2323,8 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
                ath5k_reset(sc, NULL, true);
        }
 
+       mutex_unlock(&sc->lock);
+
        ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
                msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT));
 }
index ea2e7d7..5e300bd 100644 (file)
@@ -679,10 +679,6 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah,
 
        /* Do NF cal only at longer intervals */
        if (longcal || nfcal_pending) {
-               /* Do periodic PAOffset Cal */
-               ar9002_hw_pa_cal(ah, false);
-               ar9002_hw_olc_temp_compensation(ah);
-
                /*
                 * Get the value from the previous NF cal and update
                 * history buffer.
@@ -697,8 +693,12 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah,
                        ath9k_hw_loadnf(ah, ah->curchan);
                }
 
-               if (longcal)
+               if (longcal) {
                        ath9k_hw_start_nfcal(ah, false);
+                       /* Do periodic PAOffset Cal */
+                       ar9002_hw_pa_cal(ah, false);
+                       ar9002_hw_olc_temp_compensation(ah);
+               }
        }
 
        return iscaldone;
index 81f9cf2..9ecca93 100644 (file)
@@ -1842,7 +1842,7 @@ static const u32 ar9300_2p2_soc_preamble[][2] = {
 
 static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2[][2] = {
        /* Addr      allmodes  */
-       {0x00004040, 0x08212e5e},
+       {0x00004040, 0x0821265e},
        {0x00004040, 0x0008003b},
        {0x00004044, 0x00000000},
 };
index 6137634..06fb2c8 100644 (file)
@@ -146,8 +146,8 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
                /* Sleep Setting */
 
                INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
-                               ar9300PciePhy_clkreq_enable_L1_2p2,
-                               ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p2),
+                               ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
+                               ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
                                2);
 
                /* Fast clock modal settings */
index 1ce506f..780ac5e 100644 (file)
@@ -78,7 +78,7 @@ struct tx_frame_hdr {
        u8 node_idx;
        u8 vif_idx;
        u8 tidno;
-       u32 flags; /* ATH9K_HTC_TX_* */
+       __be32 flags; /* ATH9K_HTC_TX_* */
        u8 key_type;
        u8 keyix;
        u8 reserved[26];
index 33f3602..7a5ffca 100644 (file)
@@ -113,6 +113,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
 
        if (ieee80211_is_data(fc)) {
                struct tx_frame_hdr tx_hdr;
+               u32 flags = 0;
                u8 *qc;
 
                memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
@@ -136,13 +137,14 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
                /* Check for RTS protection */
                if (priv->hw->wiphy->rts_threshold != (u32) -1)
                        if (skb->len > priv->hw->wiphy->rts_threshold)
-                               tx_hdr.flags |= ATH9K_HTC_TX_RTSCTS;
+                               flags |= ATH9K_HTC_TX_RTSCTS;
 
                /* CTS-to-self */
-               if (!(tx_hdr.flags & ATH9K_HTC_TX_RTSCTS) &&
+               if (!(flags & ATH9K_HTC_TX_RTSCTS) &&
                    (priv->op_flags & OP_PROTECT_ENABLE))
-                       tx_hdr.flags |= ATH9K_HTC_TX_CTSONLY;
+                       flags |= ATH9K_HTC_TX_CTSONLY;
 
+               tx_hdr.flags = cpu_to_be32(flags);
                tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
                if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
                        tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
index 97906dd..14ceb4d 100644 (file)
@@ -168,7 +168,7 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv)
                /* not using .cfg overwrite */
                radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
                priv->cfg->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
-               priv->cfg->valid_rx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
+               priv->cfg->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg);
                if (!priv->cfg->valid_tx_ant || !priv->cfg->valid_rx_ant) {
                        IWL_ERR(priv, "Invalid chain (0X%x, 0X%x)\n",
                                priv->cfg->valid_tx_ant,
index 13a69eb..5091d77 100644 (file)
@@ -126,6 +126,7 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev,
        ndev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES);
        if (!ndev) {
                dev_err(dev, "no memory for network device instance\n");
+               ret = -ENOMEM;
                goto out_priv;
        }
 
@@ -138,6 +139,7 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev,
                                    GFP_KERNEL);
        if (!iwm->umac_profile) {
                dev_err(dev, "Couldn't alloc memory for profile\n");
+               ret = -ENOMEM;
                goto out_profile;
        }
 
index f0e1eb7..be0ff78 100644 (file)
@@ -58,6 +58,7 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
 
        if (!fw || !fw->size || !fw->data) {
                ERROR(rt2x00dev, "Failed to read Firmware.\n");
+               release_firmware(fw);
                return -ENOENT;
        }
 
index 7a7a1b6..2ac8f6a 100644 (file)
@@ -831,12 +831,14 @@ tx_drop:
        return NETDEV_TX_OK;
 }
 
-static int qeth_l2_open(struct net_device *dev)
+static int __qeth_l2_open(struct net_device *dev)
 {
        struct qeth_card *card = dev->ml_priv;
        int rc = 0;
 
        QETH_CARD_TEXT(card, 4, "qethopen");
+       if (card->state == CARD_STATE_UP)
+               return rc;
        if (card->state != CARD_STATE_SOFTSETUP)
                return -ENODEV;
 
@@ -857,6 +859,18 @@ static int qeth_l2_open(struct net_device *dev)
        return rc;
 }
 
+static int qeth_l2_open(struct net_device *dev)
+{
+       struct qeth_card *card = dev->ml_priv;
+
+       QETH_CARD_TEXT(card, 5, "qethope_");
+       if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
+               QETH_CARD_TEXT(card, 3, "openREC");
+               return -ERESTARTSYS;
+       }
+       return __qeth_l2_open(dev);
+}
+
 static int qeth_l2_stop(struct net_device *dev)
 {
        struct qeth_card *card = dev->ml_priv;
@@ -1046,7 +1060,7 @@ contin:
        if (recover_flag == CARD_STATE_RECOVER) {
                if (recovery_mode &&
                    card->info.type != QETH_CARD_TYPE_OSN) {
-                       qeth_l2_open(card->dev);
+                       __qeth_l2_open(card->dev);
                } else {
                        rtnl_lock();
                        dev_open(card->dev);
index e227e46..d09b0c4 100644 (file)
@@ -2998,7 +2998,9 @@ static inline void qeth_l3_hdr_csum(struct qeth_card *card,
         */
        if (iph->protocol == IPPROTO_UDP)
                hdr->hdr.l3.ext_flags |= QETH_HDR_EXT_UDP;
-       hdr->hdr.l3.ext_flags |= QETH_HDR_EXT_CSUM_TRANSP_REQ;
+       hdr->hdr.l3.ext_flags |= QETH_HDR_EXT_CSUM_TRANSP_REQ |
+               QETH_HDR_EXT_CSUM_HDR_REQ;
+       iph->check = 0;
        if (card->options.performance_stats)
                card->perf_stats.tx_csum++;
 }
@@ -3240,12 +3242,14 @@ tx_drop:
        return NETDEV_TX_OK;
 }
 
-static int qeth_l3_open(struct net_device *dev)
+static int __qeth_l3_open(struct net_device *dev)
 {
        struct qeth_card *card = dev->ml_priv;
        int rc = 0;
 
        QETH_CARD_TEXT(card, 4, "qethopen");
+       if (card->state == CARD_STATE_UP)
+               return rc;
        if (card->state != CARD_STATE_SOFTSETUP)
                return -ENODEV;
        card->data.state = CH_STATE_UP;
@@ -3260,6 +3264,18 @@ static int qeth_l3_open(struct net_device *dev)
        return rc;
 }
 
+static int qeth_l3_open(struct net_device *dev)
+{
+       struct qeth_card *card = dev->ml_priv;
+
+       QETH_CARD_TEXT(card, 5, "qethope_");
+       if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
+               QETH_CARD_TEXT(card, 3, "openREC");
+               return -ERESTARTSYS;
+       }
+       return __qeth_l3_open(dev);
+}
+
 static int qeth_l3_stop(struct net_device *dev)
 {
        struct qeth_card *card = dev->ml_priv;
@@ -3564,7 +3580,7 @@ contin:
                netif_carrier_off(card->dev);
        if (recover_flag == CARD_STATE_RECOVER) {
                if (recovery_mode)
-                       qeth_l3_open(card->dev);
+                       __qeth_l3_open(card->dev);
                else {
                        rtnl_lock();
                        dev_open(card->dev);
index 6042228..294169e 100644 (file)
@@ -959,7 +959,7 @@ struct ieee80211_ht_info {
 /* block-ack parameters */
 #define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
 #define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
-#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0
+#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFC0
 #define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
 #define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
 
index 2a128c8..e73ebda 100644 (file)
@@ -78,6 +78,7 @@ typedef __s32 sctp_assoc_t;
 #define SCTP_GET_PEER_ADDR_INFO        15
 #define SCTP_DELAYED_ACK_TIME  16
 #define SCTP_DELAYED_ACK SCTP_DELAYED_ACK_TIME
+#define SCTP_DELAYED_SACK SCTP_DELAYED_ACK_TIME
 #define SCTP_CONTEXT   17
 #define SCTP_FRAGMENT_INTERLEAVE       18
 #define SCTP_PARTIAL_DELIVERY_POINT    19 /* Set/Get partial delivery point */
index d4d9926..65106fb 100644 (file)
@@ -151,9 +151,9 @@ int debug_log(struct bat_priv *bat_priv, char *fmt, ...);
        }                                                       \
        while (0)
 #else /* !CONFIG_BATMAN_ADV_DEBUG */
-static inline void bat_dbg(char type __attribute__((unused)),
-                          struct bat_priv *bat_priv __attribute__((unused)),
-                          char *fmt __attribute__((unused)), ...)
+static inline void bat_dbg(char type __always_unused,
+                          struct bat_priv *bat_priv __always_unused,
+                          char *fmt __always_unused, ...)
 {
 }
 #endif
index b49fdf7..2284e81 100644 (file)
@@ -63,7 +63,7 @@ struct batman_packet {
        uint8_t  num_hna;
        uint8_t  gw_flags;  /* flags related to gateway class */
        uint8_t  align;
-} __attribute__((packed));
+} __packed;
 
 #define BAT_PACKET_LEN sizeof(struct batman_packet)
 
@@ -76,7 +76,7 @@ struct icmp_packet {
        uint8_t  orig[6];
        uint16_t seqno;
        uint8_t  uid;
-} __attribute__((packed));
+} __packed;
 
 #define BAT_RR_LEN 16
 
@@ -93,14 +93,14 @@ struct icmp_packet_rr {
        uint8_t  uid;
        uint8_t  rr_cur;
        uint8_t  rr[BAT_RR_LEN][ETH_ALEN];
-} __attribute__((packed));
+} __packed;
 
 struct unicast_packet {
        uint8_t  packet_type;
        uint8_t  version;  /* batman version field */
        uint8_t  dest[6];
        uint8_t  ttl;
-} __attribute__((packed));
+} __packed;
 
 struct unicast_frag_packet {
        uint8_t  packet_type;
@@ -110,7 +110,7 @@ struct unicast_frag_packet {
        uint8_t  flags;
        uint8_t  orig[6];
        uint16_t seqno;
-} __attribute__((packed));
+} __packed;
 
 struct bcast_packet {
        uint8_t  packet_type;
@@ -118,7 +118,7 @@ struct bcast_packet {
        uint8_t  orig[6];
        uint8_t  ttl;
        uint32_t seqno;
-} __attribute__((packed));
+} __packed;
 
 struct vis_packet {
        uint8_t  packet_type;
@@ -131,6 +131,6 @@ struct vis_packet {
                                  * neighbors */
        uint8_t  target_orig[6]; /* who should receive this packet */
        uint8_t  sender_orig[6]; /* who sent or rebroadcasted this packet */
-} __attribute__((packed));
+} __packed;
 
 #endif /* _NET_BATMAN_ADV_PACKET_H_ */
index 97cb23d..bf3f6f5 100644 (file)
@@ -246,13 +246,13 @@ struct vis_info {
        /* this packet might be part of the vis send queue. */
        struct sk_buff *skb_packet;
        /* vis_info may follow here*/
-} __attribute__((packed));
+} __packed;
 
 struct vis_info_entry {
        uint8_t  src[ETH_ALEN];
        uint8_t  dest[ETH_ALEN];
        uint8_t  quality;       /* quality = 0 means HNA */
-} __attribute__((packed));
+} __packed;
 
 struct recvlist_node {
        struct list_head list;
index dc2e28b..ee41fef 100644 (file)
@@ -229,10 +229,12 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
        if (!bat_priv->primary_if)
                goto dropped;
 
-       unicast_packet = (struct unicast_packet *) skb->data;
+       frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len);
+       if (!frag_skb)
+               goto dropped;
 
+       unicast_packet = (struct unicast_packet *) skb->data;
        memcpy(&tmp_uc, unicast_packet, uc_hdr_len);
-       frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len);
        skb_split(skb, frag_skb, data_len / 2);
 
        if (my_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 ||
index 21ede14..c665de7 100644 (file)
@@ -191,6 +191,7 @@ int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer)
        struct cflayer *servl = NULL;
        struct cfcnfg_phyinfo *phyinfo = NULL;
        u8 phyid = 0;
+
        caif_assert(adap_layer != NULL);
        channel_id = adap_layer->id;
        if (adap_layer->dn == NULL || channel_id == 0) {
@@ -199,16 +200,16 @@ int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer)
                goto end;
        }
        servl = cfmuxl_remove_uplayer(cnfg->mux, channel_id);
-       if (servl == NULL)
-               goto end;
-       layer_set_up(servl, NULL);
-       ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer);
        if (servl == NULL) {
                pr_err("PROTOCOL ERROR - Error removing service_layer Channel_Id(%d)",
                       channel_id);
                ret = -EINVAL;
                goto end;
        }
+       layer_set_up(servl, NULL);
+       ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer);
+       if (ret)
+               goto end;
        caif_assert(channel_id == servl->id);
        if (adap_layer->dn != NULL) {
                phyid = cfsrvl_getphyid(adap_layer->dn);
index 9d5e8ac..092dc88 100644 (file)
@@ -1256,6 +1256,9 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
                struct sockaddr_can *addr =
                        (struct sockaddr_can *)msg->msg_name;
 
+               if (msg->msg_namelen < sizeof(*addr))
+                       return -EINVAL;
+
                if (addr->can_family != AF_CAN)
                        return -EINVAL;
 
index e88f610..883e9d7 100644 (file)
@@ -649,6 +649,9 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
                struct sockaddr_can *addr =
                        (struct sockaddr_can *)msg->msg_name;
 
+               if (msg->msg_namelen < sizeof(*addr))
+                       return -EINVAL;
+
                if (addr->can_family != AF_CAN)
                        return -EINVAL;
 
index 54277df..7c6a46f 100644 (file)
@@ -2001,7 +2001,7 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol)
 
 static int harmonize_features(struct sk_buff *skb, __be16 protocol, int features)
 {
-       if (!can_checksum_protocol(protocol, features)) {
+       if (!can_checksum_protocol(features, protocol)) {
                features &= ~NETIF_F_ALL_CSUM;
                features &= ~NETIF_F_SG;
        } else if (illegal_highdma(skb->dev, skb)) {
@@ -2023,13 +2023,13 @@ int netif_skb_features(struct sk_buff *skb)
                return harmonize_features(skb, protocol, features);
        }
 
-       features &= skb->dev->vlan_features;
+       features &= (skb->dev->vlan_features | NETIF_F_HW_VLAN_TX);
 
        if (protocol != htons(ETH_P_8021Q)) {
                return harmonize_features(skb, protocol, features);
        } else {
                features &= NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST |
-                               NETIF_F_GEN_CSUM;
+                               NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_TX;
                return harmonize_features(skb, protocol, features);
        }
 }
index a5f7535..750db57 100644 (file)
@@ -1820,7 +1820,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN))
                return -EPERM;
 
-       if (kind == 2 && (nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) {
+       if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
                struct sock *rtnl;
                rtnl_dumpit_func dumpit;
 
index 2746c1f..2ada171 100644 (file)
@@ -858,7 +858,7 @@ static int inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
            nlmsg_len(nlh) < hdrlen)
                return -EINVAL;
 
-       if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) {
+       if (nlh->nlmsg_flags & NLM_F_DUMP) {
                if (nlmsg_attrlen(nlh, hdrlen)) {
                        struct nlattr *attr;
 
index 5b189c9..24a1cf1 100644 (file)
@@ -420,9 +420,6 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
            dev->type == ARPHRD_TUNNEL6 ||
            dev->type == ARPHRD_SIT ||
            dev->type == ARPHRD_NONE) {
-               printk(KERN_INFO
-                      "%s: Disabled Privacy Extensions\n",
-                      dev->name);
                ndev->cnf.use_tempaddr = -1;
        } else {
                in6_dev_hold(ndev);
index f138b19..227ca82 100644 (file)
@@ -185,8 +185,6 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
                                     struct ieee80211_mgmt *mgmt,
                                     size_t len)
 {
-       struct ieee80211_hw *hw = &local->hw;
-       struct ieee80211_conf *conf = &hw->conf;
        struct tid_ampdu_rx *tid_agg_rx;
        u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
        u8 dialog_token;
@@ -231,13 +229,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
                goto end_no_lock;
        }
        /* determine default buffer size */
-       if (buf_size == 0) {
-               struct ieee80211_supported_band *sband;
-
-               sband = local->hw.wiphy->bands[conf->channel->band];
-               buf_size = IEEE80211_MIN_AMPDU_BUF;
-               buf_size = buf_size << sband->ht_cap.ampdu_factor;
-       }
+       if (buf_size == 0)
+               buf_size = IEEE80211_MAX_AMPDU_BUF;
 
 
        /* examine state machine */
index 485d36b..a46ff06 100644 (file)
@@ -39,6 +39,8 @@ module_param(ieee80211_disable_40mhz_24ghz, bool, 0644);
 MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz,
                 "Disable 40MHz support in the 2.4GHz band");
 
+static struct lock_class_key ieee80211_rx_skb_queue_class;
+
 void ieee80211_configure_filter(struct ieee80211_local *local)
 {
        u64 mc;
@@ -569,7 +571,15 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
        spin_lock_init(&local->filter_lock);
        spin_lock_init(&local->queue_stop_reason_lock);
 
-       skb_queue_head_init(&local->rx_skb_queue);
+       /*
+        * The rx_skb_queue is only accessed from tasklets,
+        * but other SKB queues are used from within IRQ
+        * context. Therefore, this one needs a different
+        * locking class so our direct, non-irq-safe use of
+        * the queue's lock doesn't throw lockdep warnings.
+        */
+       skb_queue_head_init_class(&local->rx_skb_queue,
+                                 &ieee80211_rx_skb_queue_class);
 
        INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
 
index 2b7eef3..93297aa 100644 (file)
@@ -924,7 +924,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
        u16 zone;
        int err;
 
-       if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP)
+       if (nlh->nlmsg_flags & NLM_F_DUMP)
                return netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table,
                                          ctnetlink_done);
 
@@ -1787,7 +1787,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
        u16 zone;
        int err;
 
-       if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) {
+       if (nlh->nlmsg_flags & NLM_F_DUMP) {
                return netlink_dump_start(ctnl, skb, nlh,
                                          ctnetlink_exp_dump_table,
                                          ctnetlink_exp_done);
index f83cb37..1781d99 100644 (file)
@@ -519,7 +519,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
            security_netlink_recv(skb, CAP_NET_ADMIN))
                return -EPERM;
 
-       if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) {
+       if (nlh->nlmsg_flags & NLM_F_DUMP) {
                if (ops->dumpit == NULL)
                        return -EOPNOTSUPP;
 
index a09b0dd..8e02550 100644 (file)
@@ -3428,7 +3428,7 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
                retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen);
                break;
 
-       case SCTP_DELAYED_ACK:
+       case SCTP_DELAYED_SACK:
                retval = sctp_setsockopt_delayed_ack(sk, optval, optlen);
                break;
        case SCTP_PARTIAL_DELIVERY_POINT:
@@ -5333,7 +5333,7 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
                retval = sctp_getsockopt_peer_addr_params(sk, len, optval,
                                                          optlen);
                break;
-       case SCTP_DELAYED_ACK:
+       case SCTP_DELAYED_SACK:
                retval = sctp_getsockopt_delayed_ack(sk, len, optval,
                                                          optlen);
                break;
index d5e1e0b..6129196 100644 (file)
@@ -2189,7 +2189,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 
        if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||
             type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) &&
-           (nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) {
+           (nlh->nlmsg_flags & NLM_F_DUMP)) {
                if (link->dump == NULL)
                        return -EINVAL;