diff options
Diffstat (limited to 'drivers/net')
39 files changed, 703 insertions, 258 deletions
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c index 448487e22fa3..a740053d3af3 100644 --- a/drivers/net/arm/ixp4xx_eth.c +++ b/drivers/net/arm/ixp4xx_eth.c | |||
@@ -338,12 +338,12 @@ static int ixp4xx_mdio_register(void) | |||
338 | if (cpu_is_ixp43x()) { | 338 | if (cpu_is_ixp43x()) { |
339 | /* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */ | 339 | /* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */ |
340 | if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEC_ETH)) | 340 | if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEC_ETH)) |
341 | return -ENOSYS; | 341 | return -ENODEV; |
342 | mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT; | 342 | mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT; |
343 | } else { | 343 | } else { |
344 | /* All MII PHY accesses use NPE-B Ethernet registers */ | 344 | /* All MII PHY accesses use NPE-B Ethernet registers */ |
345 | if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0)) | 345 | if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0)) |
346 | return -ENOSYS; | 346 | return -ENODEV; |
347 | mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT; | 347 | mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT; |
348 | } | 348 | } |
349 | 349 | ||
@@ -1174,7 +1174,7 @@ static int __devinit eth_init_one(struct platform_device *pdev) | |||
1174 | regs_phys = IXP4XX_EthC_BASE_PHYS; | 1174 | regs_phys = IXP4XX_EthC_BASE_PHYS; |
1175 | break; | 1175 | break; |
1176 | default: | 1176 | default: |
1177 | err = -ENOSYS; | 1177 | err = -ENODEV; |
1178 | goto err_free; | 1178 | goto err_free; |
1179 | } | 1179 | } |
1180 | 1180 | ||
@@ -1189,15 +1189,10 @@ static int __devinit eth_init_one(struct platform_device *pdev) | |||
1189 | goto err_free; | 1189 | goto err_free; |
1190 | } | 1190 | } |
1191 | 1191 | ||
1192 | if (register_netdev(dev)) { | ||
1193 | err = -EIO; | ||
1194 | goto err_npe_rel; | ||
1195 | } | ||
1196 | |||
1197 | port->mem_res = request_mem_region(regs_phys, REGS_SIZE, dev->name); | 1192 | port->mem_res = request_mem_region(regs_phys, REGS_SIZE, dev->name); |
1198 | if (!port->mem_res) { | 1193 | if (!port->mem_res) { |
1199 | err = -EBUSY; | 1194 | err = -EBUSY; |
1200 | goto err_unreg; | 1195 | goto err_npe_rel; |
1201 | } | 1196 | } |
1202 | 1197 | ||
1203 | port->plat = plat; | 1198 | port->plat = plat; |
@@ -1215,20 +1210,25 @@ static int __devinit eth_init_one(struct platform_device *pdev) | |||
1215 | snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, "0", plat->phy); | 1210 | snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, "0", plat->phy); |
1216 | port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0, | 1211 | port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0, |
1217 | PHY_INTERFACE_MODE_MII); | 1212 | PHY_INTERFACE_MODE_MII); |
1218 | if (IS_ERR(port->phydev)) { | 1213 | if ((err = IS_ERR(port->phydev))) |
1219 | printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); | 1214 | goto err_free_mem; |
1220 | return PTR_ERR(port->phydev); | ||
1221 | } | ||
1222 | 1215 | ||
1223 | port->phydev->irq = PHY_POLL; | 1216 | port->phydev->irq = PHY_POLL; |
1224 | 1217 | ||
1218 | if ((err = register_netdev(dev))) | ||
1219 | goto err_phy_dis; | ||
1220 | |||
1225 | printk(KERN_INFO "%s: MII PHY %i on %s\n", dev->name, plat->phy, | 1221 | printk(KERN_INFO "%s: MII PHY %i on %s\n", dev->name, plat->phy, |
1226 | npe_name(port->npe)); | 1222 | npe_name(port->npe)); |
1227 | 1223 | ||
1228 | return 0; | 1224 | return 0; |
1229 | 1225 | ||
1230 | err_unreg: | 1226 | err_phy_dis: |
1231 | unregister_netdev(dev); | 1227 | phy_disconnect(port->phydev); |
1228 | err_free_mem: | ||
1229 | npe_port_tab[NPE_ID(port->id)] = NULL; | ||
1230 | platform_set_drvdata(pdev, NULL); | ||
1231 | release_resource(port->mem_res); | ||
1232 | err_npe_rel: | 1232 | err_npe_rel: |
1233 | npe_release(port->npe); | 1233 | npe_release(port->npe); |
1234 | err_free: | 1234 | err_free: |
@@ -1242,6 +1242,7 @@ static int __devexit eth_remove_one(struct platform_device *pdev) | |||
1242 | struct port *port = netdev_priv(dev); | 1242 | struct port *port = netdev_priv(dev); |
1243 | 1243 | ||
1244 | unregister_netdev(dev); | 1244 | unregister_netdev(dev); |
1245 | phy_disconnect(port->phydev); | ||
1245 | npe_port_tab[NPE_ID(port->id)] = NULL; | 1246 | npe_port_tab[NPE_ID(port->id)] = NULL; |
1246 | platform_set_drvdata(pdev, NULL); | 1247 | platform_set_drvdata(pdev, NULL); |
1247 | npe_release(port->npe); | 1248 | npe_release(port->npe); |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index d47839184a06..b0cb29d4cc01 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -54,8 +54,8 @@ | |||
54 | 54 | ||
55 | #define DRV_MODULE_NAME "bnx2" | 55 | #define DRV_MODULE_NAME "bnx2" |
56 | #define PFX DRV_MODULE_NAME ": " | 56 | #define PFX DRV_MODULE_NAME ": " |
57 | #define DRV_MODULE_VERSION "2.0.0" | 57 | #define DRV_MODULE_VERSION "2.0.1" |
58 | #define DRV_MODULE_RELDATE "April 2, 2009" | 58 | #define DRV_MODULE_RELDATE "May 6, 2009" |
59 | #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-4.6.16.fw" | 59 | #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-4.6.16.fw" |
60 | #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-4.6.16.fw" | 60 | #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-4.6.16.fw" |
61 | #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-4.6.17.fw" | 61 | #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-4.6.17.fw" |
@@ -2600,6 +2600,7 @@ bnx2_get_hw_tx_cons(struct bnx2_napi *bnapi) | |||
2600 | /* Tell compiler that status block fields can change. */ | 2600 | /* Tell compiler that status block fields can change. */ |
2601 | barrier(); | 2601 | barrier(); |
2602 | cons = *bnapi->hw_tx_cons_ptr; | 2602 | cons = *bnapi->hw_tx_cons_ptr; |
2603 | barrier(); | ||
2603 | if (unlikely((cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT)) | 2604 | if (unlikely((cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT)) |
2604 | cons++; | 2605 | cons++; |
2605 | return cons; | 2606 | return cons; |
@@ -2879,6 +2880,7 @@ bnx2_get_hw_rx_cons(struct bnx2_napi *bnapi) | |||
2879 | /* Tell compiler that status block fields can change. */ | 2880 | /* Tell compiler that status block fields can change. */ |
2880 | barrier(); | 2881 | barrier(); |
2881 | cons = *bnapi->hw_rx_cons_ptr; | 2882 | cons = *bnapi->hw_rx_cons_ptr; |
2883 | barrier(); | ||
2882 | if (unlikely((cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT)) | 2884 | if (unlikely((cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT)) |
2883 | cons++; | 2885 | cons++; |
2884 | return cons; | 2886 | return cons; |
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 553a89919778..46d312bedfb8 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -1706,10 +1706,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave | |||
1706 | * Called with RTNL | 1706 | * Called with RTNL |
1707 | */ | 1707 | */ |
1708 | int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr) | 1708 | int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr) |
1709 | __releases(&bond->curr_slave_lock) | ||
1710 | __releases(&bond->lock) | ||
1711 | __acquires(&bond->lock) | 1709 | __acquires(&bond->lock) |
1712 | __acquires(&bond->curr_slave_lock) | 1710 | __releases(&bond->lock) |
1713 | { | 1711 | { |
1714 | struct bonding *bond = netdev_priv(bond_dev); | 1712 | struct bonding *bond = netdev_priv(bond_dev); |
1715 | struct sockaddr *sa = addr; | 1713 | struct sockaddr *sa = addr; |
@@ -1745,9 +1743,6 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr) | |||
1745 | } | 1743 | } |
1746 | } | 1744 | } |
1747 | 1745 | ||
1748 | write_unlock_bh(&bond->curr_slave_lock); | ||
1749 | read_unlock(&bond->lock); | ||
1750 | |||
1751 | if (swap_slave) { | 1746 | if (swap_slave) { |
1752 | alb_swap_mac_addr(bond, swap_slave, bond->curr_active_slave); | 1747 | alb_swap_mac_addr(bond, swap_slave, bond->curr_active_slave); |
1753 | alb_fasten_mac_swap(bond, swap_slave, bond->curr_active_slave); | 1748 | alb_fasten_mac_swap(bond, swap_slave, bond->curr_active_slave); |
@@ -1755,16 +1750,15 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr) | |||
1755 | alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr, | 1750 | alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr, |
1756 | bond->alb_info.rlb_enabled); | 1751 | bond->alb_info.rlb_enabled); |
1757 | 1752 | ||
1753 | read_lock(&bond->lock); | ||
1758 | alb_send_learning_packets(bond->curr_active_slave, bond_dev->dev_addr); | 1754 | alb_send_learning_packets(bond->curr_active_slave, bond_dev->dev_addr); |
1759 | if (bond->alb_info.rlb_enabled) { | 1755 | if (bond->alb_info.rlb_enabled) { |
1760 | /* inform clients mac address has changed */ | 1756 | /* inform clients mac address has changed */ |
1761 | rlb_req_update_slave_clients(bond, bond->curr_active_slave); | 1757 | rlb_req_update_slave_clients(bond, bond->curr_active_slave); |
1762 | } | 1758 | } |
1759 | read_unlock(&bond->lock); | ||
1763 | } | 1760 | } |
1764 | 1761 | ||
1765 | read_lock(&bond->lock); | ||
1766 | write_lock_bh(&bond->curr_slave_lock); | ||
1767 | |||
1768 | return 0; | 1762 | return 0; |
1769 | } | 1763 | } |
1770 | 1764 | ||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 63369b6b14d4..74824028f85c 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -2213,33 +2213,24 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in | |||
2213 | { | 2213 | { |
2214 | struct bonding *bond = netdev_priv(bond_dev); | 2214 | struct bonding *bond = netdev_priv(bond_dev); |
2215 | struct slave *slave; | 2215 | struct slave *slave; |
2216 | int i, found = 0; | 2216 | int i, res = -ENODEV; |
2217 | |||
2218 | if (info->slave_id < 0) { | ||
2219 | return -ENODEV; | ||
2220 | } | ||
2221 | 2217 | ||
2222 | read_lock(&bond->lock); | 2218 | read_lock(&bond->lock); |
2223 | 2219 | ||
2224 | bond_for_each_slave(bond, slave, i) { | 2220 | bond_for_each_slave(bond, slave, i) { |
2225 | if (i == (int)info->slave_id) { | 2221 | if (i == (int)info->slave_id) { |
2226 | found = 1; | 2222 | res = 0; |
2223 | strcpy(info->slave_name, slave->dev->name); | ||
2224 | info->link = slave->link; | ||
2225 | info->state = slave->state; | ||
2226 | info->link_failure_count = slave->link_failure_count; | ||
2227 | break; | 2227 | break; |
2228 | } | 2228 | } |
2229 | } | 2229 | } |
2230 | 2230 | ||
2231 | read_unlock(&bond->lock); | 2231 | read_unlock(&bond->lock); |
2232 | 2232 | ||
2233 | if (found) { | 2233 | return res; |
2234 | strcpy(info->slave_name, slave->dev->name); | ||
2235 | info->link = slave->link; | ||
2236 | info->state = slave->state; | ||
2237 | info->link_failure_count = slave->link_failure_count; | ||
2238 | } else { | ||
2239 | return -ENODEV; | ||
2240 | } | ||
2241 | |||
2242 | return 0; | ||
2243 | } | 2234 | } |
2244 | 2235 | ||
2245 | /*-------------------------------- Monitoring -------------------------------*/ | 2236 | /*-------------------------------- Monitoring -------------------------------*/ |
@@ -5167,16 +5158,15 @@ int bond_create(char *name, struct bond_params *params) | |||
5167 | up_write(&bonding_rwsem); | 5158 | up_write(&bonding_rwsem); |
5168 | rtnl_unlock(); /* allows sysfs registration of net device */ | 5159 | rtnl_unlock(); /* allows sysfs registration of net device */ |
5169 | res = bond_create_sysfs_entry(netdev_priv(bond_dev)); | 5160 | res = bond_create_sysfs_entry(netdev_priv(bond_dev)); |
5170 | if (res < 0) { | 5161 | if (res < 0) |
5171 | rtnl_lock(); | 5162 | goto out_unreg; |
5172 | down_write(&bonding_rwsem); | ||
5173 | bond_deinit(bond_dev); | ||
5174 | unregister_netdevice(bond_dev); | ||
5175 | goto out_rtnl; | ||
5176 | } | ||
5177 | 5163 | ||
5178 | return 0; | 5164 | return 0; |
5179 | 5165 | ||
5166 | out_unreg: | ||
5167 | rtnl_lock(); | ||
5168 | down_write(&bonding_rwsem); | ||
5169 | unregister_netdevice(bond_dev); | ||
5180 | out_bond: | 5170 | out_bond: |
5181 | bond_deinit(bond_dev); | 5171 | bond_deinit(bond_dev); |
5182 | out_netdev: | 5172 | out_netdev: |
@@ -5191,7 +5181,6 @@ static int __init bonding_init(void) | |||
5191 | { | 5181 | { |
5192 | int i; | 5182 | int i; |
5193 | int res; | 5183 | int res; |
5194 | struct bonding *bond; | ||
5195 | 5184 | ||
5196 | printk(KERN_INFO "%s", version); | 5185 | printk(KERN_INFO "%s", version); |
5197 | 5186 | ||
@@ -5222,13 +5211,6 @@ static int __init bonding_init(void) | |||
5222 | 5211 | ||
5223 | goto out; | 5212 | goto out; |
5224 | err: | 5213 | err: |
5225 | list_for_each_entry(bond, &bond_dev_list, bond_list) { | ||
5226 | bond_work_cancel_all(bond); | ||
5227 | destroy_workqueue(bond->wq); | ||
5228 | } | ||
5229 | |||
5230 | bond_destroy_sysfs(); | ||
5231 | |||
5232 | rtnl_lock(); | 5214 | rtnl_lock(); |
5233 | bond_free_all(); | 5215 | bond_free_all(); |
5234 | rtnl_unlock(); | 5216 | rtnl_unlock(); |
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index e1bd690ff831..4f68aeb2679a 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c | |||
@@ -3779,7 +3779,7 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, | |||
3779 | 3779 | ||
3780 | adapter->params.info = ai; | 3780 | adapter->params.info = ai; |
3781 | adapter->params.nports = ai->nports0 + ai->nports1; | 3781 | adapter->params.nports = ai->nports0 + ai->nports1; |
3782 | adapter->params.chan_map = !!ai->nports0 | (!!ai->nports1 << 1); | 3782 | adapter->params.chan_map = (!!ai->nports0) | (!!ai->nports1 << 1); |
3783 | adapter->params.rev = t3_read_reg(adapter, A_PL_REV); | 3783 | adapter->params.rev = t3_read_reg(adapter, A_PL_REV); |
3784 | /* | 3784 | /* |
3785 | * We used to only run the "adapter check task" once a second if | 3785 | * We used to only run the "adapter check task" once a second if |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 5c0b457c7868..0f9ee1348552 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -2728,7 +2728,7 @@ static void __devexit e100_remove(struct pci_dev *pdev) | |||
2728 | #define E100_82552_SMARTSPEED 0x14 /* SmartSpeed Ctrl register */ | 2728 | #define E100_82552_SMARTSPEED 0x14 /* SmartSpeed Ctrl register */ |
2729 | #define E100_82552_REV_ANEG 0x0200 /* Reverse auto-negotiation */ | 2729 | #define E100_82552_REV_ANEG 0x0200 /* Reverse auto-negotiation */ |
2730 | #define E100_82552_ANEG_NOW 0x0400 /* Auto-negotiate now */ | 2730 | #define E100_82552_ANEG_NOW 0x0400 /* Auto-negotiate now */ |
2731 | static int e100_suspend(struct pci_dev *pdev, pm_message_t state) | 2731 | static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake) |
2732 | { | 2732 | { |
2733 | struct net_device *netdev = pci_get_drvdata(pdev); | 2733 | struct net_device *netdev = pci_get_drvdata(pdev); |
2734 | struct nic *nic = netdev_priv(netdev); | 2734 | struct nic *nic = netdev_priv(netdev); |
@@ -2749,19 +2749,32 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2749 | E100_82552_SMARTSPEED, smartspeed | | 2749 | E100_82552_SMARTSPEED, smartspeed | |
2750 | E100_82552_REV_ANEG | E100_82552_ANEG_NOW); | 2750 | E100_82552_REV_ANEG | E100_82552_ANEG_NOW); |
2751 | } | 2751 | } |
2752 | if (pci_enable_wake(pdev, PCI_D3cold, true)) | 2752 | *enable_wake = true; |
2753 | pci_enable_wake(pdev, PCI_D3hot, true); | ||
2754 | } else { | 2753 | } else { |
2755 | pci_enable_wake(pdev, PCI_D3hot, false); | 2754 | *enable_wake = false; |
2756 | } | 2755 | } |
2757 | 2756 | ||
2758 | pci_disable_device(pdev); | 2757 | pci_disable_device(pdev); |
2759 | pci_set_power_state(pdev, PCI_D3hot); | 2758 | } |
2760 | 2759 | ||
2761 | return 0; | 2760 | static int __e100_power_off(struct pci_dev *pdev, bool wake) |
2761 | { | ||
2762 | if (wake) { | ||
2763 | return pci_prepare_to_sleep(pdev); | ||
2764 | } else { | ||
2765 | pci_wake_from_d3(pdev, false); | ||
2766 | return pci_set_power_state(pdev, PCI_D3hot); | ||
2767 | } | ||
2762 | } | 2768 | } |
2763 | 2769 | ||
2764 | #ifdef CONFIG_PM | 2770 | #ifdef CONFIG_PM |
2771 | static int e100_suspend(struct pci_dev *pdev, pm_message_t state) | ||
2772 | { | ||
2773 | bool wake; | ||
2774 | __e100_shutdown(pdev, &wake); | ||
2775 | return __e100_power_off(pdev, wake); | ||
2776 | } | ||
2777 | |||
2765 | static int e100_resume(struct pci_dev *pdev) | 2778 | static int e100_resume(struct pci_dev *pdev) |
2766 | { | 2779 | { |
2767 | struct net_device *netdev = pci_get_drvdata(pdev); | 2780 | struct net_device *netdev = pci_get_drvdata(pdev); |
@@ -2792,7 +2805,10 @@ static int e100_resume(struct pci_dev *pdev) | |||
2792 | 2805 | ||
2793 | static void e100_shutdown(struct pci_dev *pdev) | 2806 | static void e100_shutdown(struct pci_dev *pdev) |
2794 | { | 2807 | { |
2795 | e100_suspend(pdev, PMSG_SUSPEND); | 2808 | bool wake; |
2809 | __e100_shutdown(pdev, &wake); | ||
2810 | if (system_state == SYSTEM_POWER_OFF) | ||
2811 | __e100_power_off(pdev, wake); | ||
2796 | } | 2812 | } |
2797 | 2813 | ||
2798 | /* ------------------ PCI Error Recovery infrastructure -------------- */ | 2814 | /* ------------------ PCI Error Recovery infrastructure -------------- */ |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 6a46ceed9436..b1419e21b46b 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -3738,7 +3738,7 @@ static irqreturn_t e1000_intr(int irq, void *data) | |||
3738 | struct e1000_hw *hw = &adapter->hw; | 3738 | struct e1000_hw *hw = &adapter->hw; |
3739 | u32 rctl, icr = er32(ICR); | 3739 | u32 rctl, icr = er32(ICR); |
3740 | 3740 | ||
3741 | if (unlikely((!icr) || test_bit(__E1000_RESETTING, &adapter->flags))) | 3741 | if (unlikely((!icr) || test_bit(__E1000_DOWN, &adapter->flags))) |
3742 | return IRQ_NONE; /* Not our interrupt */ | 3742 | return IRQ_NONE; /* Not our interrupt */ |
3743 | 3743 | ||
3744 | /* IMS will not auto-mask if INT_ASSERTED is not set, and if it is | 3744 | /* IMS will not auto-mask if INT_ASSERTED is not set, and if it is |
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 6e317caf429c..16a41389575a 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <asm/io.h> | 40 | #include <asm/io.h> |
41 | 41 | ||
42 | #define DRV_NAME "ehea" | 42 | #define DRV_NAME "ehea" |
43 | #define DRV_VERSION "EHEA_0100" | 43 | #define DRV_VERSION "EHEA_0101" |
44 | 44 | ||
45 | /* eHEA capability flags */ | 45 | /* eHEA capability flags */ |
46 | #define DLPAR_PORT_ADD_REM 1 | 46 | #define DLPAR_PORT_ADD_REM 1 |
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 604c844d0769..b22dab9153f6 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -545,14 +545,17 @@ static inline struct sk_buff *get_skb_by_index(struct sk_buff **skb_array, | |||
545 | x &= (arr_len - 1); | 545 | x &= (arr_len - 1); |
546 | 546 | ||
547 | pref = skb_array[x]; | 547 | pref = skb_array[x]; |
548 | prefetchw(pref); | 548 | if (pref) { |
549 | prefetchw(pref + EHEA_CACHE_LINE); | 549 | prefetchw(pref); |
550 | 550 | prefetchw(pref + EHEA_CACHE_LINE); | |
551 | pref = (skb_array[x]->data); | 551 | |
552 | prefetch(pref); | 552 | pref = (skb_array[x]->data); |
553 | prefetch(pref + EHEA_CACHE_LINE); | 553 | prefetch(pref); |
554 | prefetch(pref + EHEA_CACHE_LINE * 2); | 554 | prefetch(pref + EHEA_CACHE_LINE); |
555 | prefetch(pref + EHEA_CACHE_LINE * 3); | 555 | prefetch(pref + EHEA_CACHE_LINE * 2); |
556 | prefetch(pref + EHEA_CACHE_LINE * 3); | ||
557 | } | ||
558 | |||
556 | skb = skb_array[skb_index]; | 559 | skb = skb_array[skb_index]; |
557 | skb_array[skb_index] = NULL; | 560 | skb_array[skb_index] = NULL; |
558 | return skb; | 561 | return skb; |
@@ -569,12 +572,14 @@ static inline struct sk_buff *get_skb_by_index_ll(struct sk_buff **skb_array, | |||
569 | x &= (arr_len - 1); | 572 | x &= (arr_len - 1); |
570 | 573 | ||
571 | pref = skb_array[x]; | 574 | pref = skb_array[x]; |
572 | prefetchw(pref); | 575 | if (pref) { |
573 | prefetchw(pref + EHEA_CACHE_LINE); | 576 | prefetchw(pref); |
577 | prefetchw(pref + EHEA_CACHE_LINE); | ||
574 | 578 | ||
575 | pref = (skb_array[x]->data); | 579 | pref = (skb_array[x]->data); |
576 | prefetchw(pref); | 580 | prefetchw(pref); |
577 | prefetchw(pref + EHEA_CACHE_LINE); | 581 | prefetchw(pref + EHEA_CACHE_LINE); |
582 | } | ||
578 | 583 | ||
579 | skb = skb_array[wqe_index]; | 584 | skb = skb_array[wqe_index]; |
580 | skb_array[wqe_index] = NULL; | 585 | skb_array[wqe_index] = NULL; |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 11d5db16ed9c..f9a846b1b92f 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -1880,6 +1880,7 @@ static void nv_init_tx(struct net_device *dev) | |||
1880 | np->tx_pkts_in_progress = 0; | 1880 | np->tx_pkts_in_progress = 0; |
1881 | np->tx_change_owner = NULL; | 1881 | np->tx_change_owner = NULL; |
1882 | np->tx_end_flip = NULL; | 1882 | np->tx_end_flip = NULL; |
1883 | np->tx_stop = 0; | ||
1883 | 1884 | ||
1884 | for (i = 0; i < np->tx_ring_size; i++) { | 1885 | for (i = 0; i < np->tx_ring_size; i++) { |
1885 | if (!nv_optimized(np)) { | 1886 | if (!nv_optimized(np)) { |
@@ -2530,6 +2531,8 @@ static void nv_tx_timeout(struct net_device *dev) | |||
2530 | struct fe_priv *np = netdev_priv(dev); | 2531 | struct fe_priv *np = netdev_priv(dev); |
2531 | u8 __iomem *base = get_hwbase(dev); | 2532 | u8 __iomem *base = get_hwbase(dev); |
2532 | u32 status; | 2533 | u32 status; |
2534 | union ring_type put_tx; | ||
2535 | int saved_tx_limit; | ||
2533 | 2536 | ||
2534 | if (np->msi_flags & NV_MSI_X_ENABLED) | 2537 | if (np->msi_flags & NV_MSI_X_ENABLED) |
2535 | status = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK; | 2538 | status = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK; |
@@ -2589,24 +2592,32 @@ static void nv_tx_timeout(struct net_device *dev) | |||
2589 | /* 1) stop tx engine */ | 2592 | /* 1) stop tx engine */ |
2590 | nv_stop_tx(dev); | 2593 | nv_stop_tx(dev); |
2591 | 2594 | ||
2592 | /* 2) check that the packets were not sent already: */ | 2595 | /* 2) complete any outstanding tx and do not give HW any limited tx pkts */ |
2596 | saved_tx_limit = np->tx_limit; | ||
2597 | np->tx_limit = 0; /* prevent giving HW any limited pkts */ | ||
2598 | np->tx_stop = 0; /* prevent waking tx queue */ | ||
2593 | if (!nv_optimized(np)) | 2599 | if (!nv_optimized(np)) |
2594 | nv_tx_done(dev, np->tx_ring_size); | 2600 | nv_tx_done(dev, np->tx_ring_size); |
2595 | else | 2601 | else |
2596 | nv_tx_done_optimized(dev, np->tx_ring_size); | 2602 | nv_tx_done_optimized(dev, np->tx_ring_size); |
2597 | 2603 | ||
2598 | /* 3) if there are dead entries: clear everything */ | 2604 | /* save current HW postion */ |
2599 | if (np->get_tx_ctx != np->put_tx_ctx) { | 2605 | if (np->tx_change_owner) |
2600 | printk(KERN_DEBUG "%s: tx_timeout: dead entries!\n", dev->name); | 2606 | put_tx.ex = np->tx_change_owner->first_tx_desc; |
2601 | nv_drain_tx(dev); | 2607 | else |
2602 | nv_init_tx(dev); | 2608 | put_tx = np->put_tx; |
2603 | setup_hw_rings(dev, NV_SETUP_TX_RING); | ||
2604 | } | ||
2605 | 2609 | ||
2606 | netif_wake_queue(dev); | 2610 | /* 3) clear all tx state */ |
2611 | nv_drain_tx(dev); | ||
2612 | nv_init_tx(dev); | ||
2613 | |||
2614 | /* 4) restore state to current HW position */ | ||
2615 | np->get_tx = np->put_tx = put_tx; | ||
2616 | np->tx_limit = saved_tx_limit; | ||
2607 | 2617 | ||
2608 | /* 4) restart tx engine */ | 2618 | /* 5) restart tx engine */ |
2609 | nv_start_tx(dev); | 2619 | nv_start_tx(dev); |
2620 | netif_wake_queue(dev); | ||
2610 | spin_unlock_irq(&np->lock); | 2621 | spin_unlock_irq(&np->lock); |
2611 | } | 2622 | } |
2612 | 2623 | ||
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 08c801490c72..e25343588fc7 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -2006,7 +2006,7 @@ static void igb_setup_rctl(struct igb_adapter *adapter) | |||
2006 | struct e1000_hw *hw = &adapter->hw; | 2006 | struct e1000_hw *hw = &adapter->hw; |
2007 | u32 rctl; | 2007 | u32 rctl; |
2008 | u32 srrctl = 0; | 2008 | u32 srrctl = 0; |
2009 | int i, j; | 2009 | int i; |
2010 | 2010 | ||
2011 | rctl = rd32(E1000_RCTL); | 2011 | rctl = rd32(E1000_RCTL); |
2012 | 2012 | ||
@@ -2071,8 +2071,6 @@ static void igb_setup_rctl(struct igb_adapter *adapter) | |||
2071 | if (adapter->vfs_allocated_count) { | 2071 | if (adapter->vfs_allocated_count) { |
2072 | u32 vmolr; | 2072 | u32 vmolr; |
2073 | 2073 | ||
2074 | j = adapter->rx_ring[0].reg_idx; | ||
2075 | |||
2076 | /* set all queue drop enable bits */ | 2074 | /* set all queue drop enable bits */ |
2077 | wr32(E1000_QDE, ALL_QUEUES); | 2075 | wr32(E1000_QDE, ALL_QUEUES); |
2078 | srrctl |= E1000_SRRCTL_DROP_EN; | 2076 | srrctl |= E1000_SRRCTL_DROP_EN; |
@@ -2080,16 +2078,16 @@ static void igb_setup_rctl(struct igb_adapter *adapter) | |||
2080 | /* disable queue 0 to prevent tail write w/o re-config */ | 2078 | /* disable queue 0 to prevent tail write w/o re-config */ |
2081 | wr32(E1000_RXDCTL(0), 0); | 2079 | wr32(E1000_RXDCTL(0), 0); |
2082 | 2080 | ||
2083 | vmolr = rd32(E1000_VMOLR(j)); | 2081 | vmolr = rd32(E1000_VMOLR(adapter->vfs_allocated_count)); |
2084 | if (rctl & E1000_RCTL_LPE) | 2082 | if (rctl & E1000_RCTL_LPE) |
2085 | vmolr |= E1000_VMOLR_LPE; | 2083 | vmolr |= E1000_VMOLR_LPE; |
2086 | if (adapter->num_rx_queues > 0) | 2084 | if (adapter->num_rx_queues > 1) |
2087 | vmolr |= E1000_VMOLR_RSSE; | 2085 | vmolr |= E1000_VMOLR_RSSE; |
2088 | wr32(E1000_VMOLR(j), vmolr); | 2086 | wr32(E1000_VMOLR(adapter->vfs_allocated_count), vmolr); |
2089 | } | 2087 | } |
2090 | 2088 | ||
2091 | for (i = 0; i < adapter->num_rx_queues; i++) { | 2089 | for (i = 0; i < adapter->num_rx_queues; i++) { |
2092 | j = adapter->rx_ring[i].reg_idx; | 2090 | int j = adapter->rx_ring[i].reg_idx; |
2093 | wr32(E1000_SRRCTL(j), srrctl); | 2091 | wr32(E1000_SRRCTL(j), srrctl); |
2094 | } | 2092 | } |
2095 | 2093 | ||
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 5567519676d5..186a65069b33 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c | |||
@@ -50,7 +50,6 @@ static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw); | |||
50 | static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index); | 50 | static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index); |
51 | static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index); | 51 | static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index); |
52 | static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); | 52 | static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); |
53 | static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr); | ||
54 | static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); | 53 | static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); |
55 | 54 | ||
56 | /** | 55 | /** |
@@ -1377,8 +1376,7 @@ s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, | |||
1377 | * Clear accounting of old secondary address list, | 1376 | * Clear accounting of old secondary address list, |
1378 | * don't count RAR[0] | 1377 | * don't count RAR[0] |
1379 | */ | 1378 | */ |
1380 | uc_addr_in_use = hw->addr_ctrl.rar_used_count - | 1379 | uc_addr_in_use = hw->addr_ctrl.rar_used_count - 1; |
1381 | hw->addr_ctrl.mc_addr_in_rar_count - 1; | ||
1382 | hw->addr_ctrl.rar_used_count -= uc_addr_in_use; | 1380 | hw->addr_ctrl.rar_used_count -= uc_addr_in_use; |
1383 | hw->addr_ctrl.overflow_promisc = 0; | 1381 | hw->addr_ctrl.overflow_promisc = 0; |
1384 | 1382 | ||
@@ -1493,40 +1491,6 @@ static void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr) | |||
1493 | } | 1491 | } |
1494 | 1492 | ||
1495 | /** | 1493 | /** |
1496 | * ixgbe_add_mc_addr - Adds a multicast address. | ||
1497 | * @hw: pointer to hardware structure | ||
1498 | * @mc_addr: new multicast address | ||
1499 | * | ||
1500 | * Adds it to unused receive address register or to the multicast table. | ||
1501 | **/ | ||
1502 | static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr) | ||
1503 | { | ||
1504 | u32 rar_entries = hw->mac.num_rar_entries; | ||
1505 | u32 rar; | ||
1506 | |||
1507 | hw_dbg(hw, " MC Addr =%.2X %.2X %.2X %.2X %.2X %.2X\n", | ||
1508 | mc_addr[0], mc_addr[1], mc_addr[2], | ||
1509 | mc_addr[3], mc_addr[4], mc_addr[5]); | ||
1510 | |||
1511 | /* | ||
1512 | * Place this multicast address in the RAR if there is room, | ||
1513 | * else put it in the MTA | ||
1514 | */ | ||
1515 | if (hw->addr_ctrl.rar_used_count < rar_entries) { | ||
1516 | /* use RAR from the end up for multicast */ | ||
1517 | rar = rar_entries - hw->addr_ctrl.mc_addr_in_rar_count - 1; | ||
1518 | hw->mac.ops.set_rar(hw, rar, mc_addr, 0, IXGBE_RAH_AV); | ||
1519 | hw_dbg(hw, "Added a multicast address to RAR[%d]\n", rar); | ||
1520 | hw->addr_ctrl.rar_used_count++; | ||
1521 | hw->addr_ctrl.mc_addr_in_rar_count++; | ||
1522 | } else { | ||
1523 | ixgbe_set_mta(hw, mc_addr); | ||
1524 | } | ||
1525 | |||
1526 | hw_dbg(hw, "ixgbe_add_mc_addr Complete\n"); | ||
1527 | } | ||
1528 | |||
1529 | /** | ||
1530 | * ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses | 1494 | * ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses |
1531 | * @hw: pointer to hardware structure | 1495 | * @hw: pointer to hardware structure |
1532 | * @mc_addr_list: the list of new multicast addresses | 1496 | * @mc_addr_list: the list of new multicast addresses |
@@ -1542,7 +1506,6 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, | |||
1542 | u32 mc_addr_count, ixgbe_mc_addr_itr next) | 1506 | u32 mc_addr_count, ixgbe_mc_addr_itr next) |
1543 | { | 1507 | { |
1544 | u32 i; | 1508 | u32 i; |
1545 | u32 rar_entries = hw->mac.num_rar_entries; | ||
1546 | u32 vmdq; | 1509 | u32 vmdq; |
1547 | 1510 | ||
1548 | /* | 1511 | /* |
@@ -1550,18 +1513,8 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, | |||
1550 | * use. | 1513 | * use. |
1551 | */ | 1514 | */ |
1552 | hw->addr_ctrl.num_mc_addrs = mc_addr_count; | 1515 | hw->addr_ctrl.num_mc_addrs = mc_addr_count; |
1553 | hw->addr_ctrl.rar_used_count -= hw->addr_ctrl.mc_addr_in_rar_count; | ||
1554 | hw->addr_ctrl.mc_addr_in_rar_count = 0; | ||
1555 | hw->addr_ctrl.mta_in_use = 0; | 1516 | hw->addr_ctrl.mta_in_use = 0; |
1556 | 1517 | ||
1557 | /* Zero out the other receive addresses. */ | ||
1558 | hw_dbg(hw, "Clearing RAR[%d-%d]\n", hw->addr_ctrl.rar_used_count, | ||
1559 | rar_entries - 1); | ||
1560 | for (i = hw->addr_ctrl.rar_used_count; i < rar_entries; i++) { | ||
1561 | IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0); | ||
1562 | IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0); | ||
1563 | } | ||
1564 | |||
1565 | /* Clear the MTA */ | 1518 | /* Clear the MTA */ |
1566 | hw_dbg(hw, " Clearing MTA\n"); | 1519 | hw_dbg(hw, " Clearing MTA\n"); |
1567 | for (i = 0; i < hw->mac.mcft_size; i++) | 1520 | for (i = 0; i < hw->mac.mcft_size; i++) |
@@ -1570,7 +1523,7 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, | |||
1570 | /* Add the new addresses */ | 1523 | /* Add the new addresses */ |
1571 | for (i = 0; i < mc_addr_count; i++) { | 1524 | for (i = 0; i < mc_addr_count; i++) { |
1572 | hw_dbg(hw, " Adding the multicast addresses:\n"); | 1525 | hw_dbg(hw, " Adding the multicast addresses:\n"); |
1573 | ixgbe_add_mc_addr(hw, next(hw, &mc_addr_list, &vmdq)); | 1526 | ixgbe_set_mta(hw, next(hw, &mc_addr_list, &vmdq)); |
1574 | } | 1527 | } |
1575 | 1528 | ||
1576 | /* Enable mta */ | 1529 | /* Enable mta */ |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 01884256f4c9..07e778d3e5d2 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -3646,6 +3646,8 @@ static int ixgbe_resume(struct pci_dev *pdev) | |||
3646 | 3646 | ||
3647 | ixgbe_reset(adapter); | 3647 | ixgbe_reset(adapter); |
3648 | 3648 | ||
3649 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0); | ||
3650 | |||
3649 | if (netif_running(netdev)) { | 3651 | if (netif_running(netdev)) { |
3650 | err = ixgbe_open(adapter->netdev); | 3652 | err = ixgbe_open(adapter->netdev); |
3651 | if (err) | 3653 | if (err) |
@@ -4575,7 +4577,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
4575 | const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data]; | 4577 | const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data]; |
4576 | static int cards_found; | 4578 | static int cards_found; |
4577 | int i, err, pci_using_dac; | 4579 | int i, err, pci_using_dac; |
4578 | u16 pm_value = 0; | ||
4579 | u32 part_num, eec; | 4580 | u32 part_num, eec; |
4580 | 4581 | ||
4581 | err = pci_enable_device(pdev); | 4582 | err = pci_enable_device(pdev); |
@@ -4763,11 +4764,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
4763 | 4764 | ||
4764 | switch (pdev->device) { | 4765 | switch (pdev->device) { |
4765 | case IXGBE_DEV_ID_82599_KX4: | 4766 | case IXGBE_DEV_ID_82599_KX4: |
4766 | #define IXGBE_PCIE_PMCSR 0x44 | 4767 | adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | |
4767 | adapter->wol = IXGBE_WUFC_MAG; | 4768 | IXGBE_WUFC_MC | IXGBE_WUFC_BC); |
4768 | pci_read_config_word(pdev, IXGBE_PCIE_PMCSR, &pm_value); | ||
4769 | pci_write_config_word(pdev, IXGBE_PCIE_PMCSR, | ||
4770 | (pm_value | (1 << 8))); | ||
4771 | break; | 4769 | break; |
4772 | default: | 4770 | default: |
4773 | adapter->wol = 0; | 4771 | adapter->wol = 0; |
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index 438678ab2a10..7bcc49de1637 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c | |||
@@ -583,7 +583,7 @@ int mlx4_en_start_port(struct net_device *dev) | |||
583 | err = mlx4_en_activate_cq(priv, cq); | 583 | err = mlx4_en_activate_cq(priv, cq); |
584 | if (err) { | 584 | if (err) { |
585 | mlx4_err(mdev, "Failed activating Rx CQ\n"); | 585 | mlx4_err(mdev, "Failed activating Rx CQ\n"); |
586 | goto rx_err; | 586 | goto cq_err; |
587 | } | 587 | } |
588 | for (j = 0; j < cq->size; j++) | 588 | for (j = 0; j < cq->size; j++) |
589 | cq->buf[j].owner_sr_opcode = MLX4_CQE_OWNER_MASK; | 589 | cq->buf[j].owner_sr_opcode = MLX4_CQE_OWNER_MASK; |
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 0cbb78ca7b29..9ee873e872b3 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c | |||
@@ -610,6 +610,10 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv, | |||
610 | used_frags = mlx4_en_complete_rx_desc(priv, rx_desc, skb_frags, | 610 | used_frags = mlx4_en_complete_rx_desc(priv, rx_desc, skb_frags, |
611 | skb_shinfo(skb)->frags, | 611 | skb_shinfo(skb)->frags, |
612 | page_alloc, length); | 612 | page_alloc, length); |
613 | if (unlikely(!used_frags)) { | ||
614 | kfree_skb(skb); | ||
615 | return NULL; | ||
616 | } | ||
613 | skb_shinfo(skb)->nr_frags = used_frags; | 617 | skb_shinfo(skb)->nr_frags = used_frags; |
614 | 618 | ||
615 | /* Copy headers into the skb linear buffer */ | 619 | /* Copy headers into the skb linear buffer */ |
@@ -947,7 +951,6 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, | |||
947 | if (err) { | 951 | if (err) { |
948 | mlx4_err(mdev, "Failed to allocate qp #%d\n", qpn); | 952 | mlx4_err(mdev, "Failed to allocate qp #%d\n", qpn); |
949 | goto out; | 953 | goto out; |
950 | return err; | ||
951 | } | 954 | } |
952 | qp->event = mlx4_en_sqp_event; | 955 | qp->event = mlx4_en_sqp_event; |
953 | 956 | ||
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 102bac90a302..30bea9689694 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c | |||
@@ -976,7 +976,7 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev) | |||
976 | nreq = err; | 976 | nreq = err; |
977 | goto retry; | 977 | goto retry; |
978 | } | 978 | } |
979 | 979 | kfree(entries); | |
980 | goto no_msi; | 980 | goto no_msi; |
981 | } | 981 | } |
982 | 982 | ||
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index b3185bf2c158..a400d7115f78 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -393,12 +393,12 @@ struct mv643xx_eth_private { | |||
393 | struct work_struct tx_timeout_task; | 393 | struct work_struct tx_timeout_task; |
394 | 394 | ||
395 | struct napi_struct napi; | 395 | struct napi_struct napi; |
396 | u8 oom; | ||
396 | u8 work_link; | 397 | u8 work_link; |
397 | u8 work_tx; | 398 | u8 work_tx; |
398 | u8 work_tx_end; | 399 | u8 work_tx_end; |
399 | u8 work_rx; | 400 | u8 work_rx; |
400 | u8 work_rx_refill; | 401 | u8 work_rx_refill; |
401 | u8 work_rx_oom; | ||
402 | 402 | ||
403 | int skb_size; | 403 | int skb_size; |
404 | struct sk_buff_head rx_recycle; | 404 | struct sk_buff_head rx_recycle; |
@@ -661,7 +661,7 @@ static int rxq_refill(struct rx_queue *rxq, int budget) | |||
661 | dma_get_cache_alignment() - 1); | 661 | dma_get_cache_alignment() - 1); |
662 | 662 | ||
663 | if (skb == NULL) { | 663 | if (skb == NULL) { |
664 | mp->work_rx_oom |= 1 << rxq->index; | 664 | mp->oom = 1; |
665 | goto oom; | 665 | goto oom; |
666 | } | 666 | } |
667 | 667 | ||
@@ -1255,7 +1255,6 @@ static void mib_counters_update(struct mv643xx_eth_private *mp) | |||
1255 | 1255 | ||
1256 | spin_lock_bh(&mp->mib_counters_lock); | 1256 | spin_lock_bh(&mp->mib_counters_lock); |
1257 | p->good_octets_received += mib_read(mp, 0x00); | 1257 | p->good_octets_received += mib_read(mp, 0x00); |
1258 | p->good_octets_received += (u64)mib_read(mp, 0x04) << 32; | ||
1259 | p->bad_octets_received += mib_read(mp, 0x08); | 1258 | p->bad_octets_received += mib_read(mp, 0x08); |
1260 | p->internal_mac_transmit_err += mib_read(mp, 0x0c); | 1259 | p->internal_mac_transmit_err += mib_read(mp, 0x0c); |
1261 | p->good_frames_received += mib_read(mp, 0x10); | 1260 | p->good_frames_received += mib_read(mp, 0x10); |
@@ -1269,7 +1268,6 @@ static void mib_counters_update(struct mv643xx_eth_private *mp) | |||
1269 | p->frames_512_to_1023_octets += mib_read(mp, 0x30); | 1268 | p->frames_512_to_1023_octets += mib_read(mp, 0x30); |
1270 | p->frames_1024_to_max_octets += mib_read(mp, 0x34); | 1269 | p->frames_1024_to_max_octets += mib_read(mp, 0x34); |
1271 | p->good_octets_sent += mib_read(mp, 0x38); | 1270 | p->good_octets_sent += mib_read(mp, 0x38); |
1272 | p->good_octets_sent += (u64)mib_read(mp, 0x3c) << 32; | ||
1273 | p->good_frames_sent += mib_read(mp, 0x40); | 1271 | p->good_frames_sent += mib_read(mp, 0x40); |
1274 | p->excessive_collision += mib_read(mp, 0x44); | 1272 | p->excessive_collision += mib_read(mp, 0x44); |
1275 | p->multicast_frames_sent += mib_read(mp, 0x48); | 1273 | p->multicast_frames_sent += mib_read(mp, 0x48); |
@@ -2167,8 +2165,10 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget) | |||
2167 | 2165 | ||
2168 | mp = container_of(napi, struct mv643xx_eth_private, napi); | 2166 | mp = container_of(napi, struct mv643xx_eth_private, napi); |
2169 | 2167 | ||
2170 | mp->work_rx_refill |= mp->work_rx_oom; | 2168 | if (unlikely(mp->oom)) { |
2171 | mp->work_rx_oom = 0; | 2169 | mp->oom = 0; |
2170 | del_timer(&mp->rx_oom); | ||
2171 | } | ||
2172 | 2172 | ||
2173 | work_done = 0; | 2173 | work_done = 0; |
2174 | while (work_done < budget) { | 2174 | while (work_done < budget) { |
@@ -2182,8 +2182,10 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget) | |||
2182 | continue; | 2182 | continue; |
2183 | } | 2183 | } |
2184 | 2184 | ||
2185 | queue_mask = mp->work_tx | mp->work_tx_end | | 2185 | queue_mask = mp->work_tx | mp->work_tx_end | mp->work_rx; |
2186 | mp->work_rx | mp->work_rx_refill; | 2186 | if (likely(!mp->oom)) |
2187 | queue_mask |= mp->work_rx_refill; | ||
2188 | |||
2187 | if (!queue_mask) { | 2189 | if (!queue_mask) { |
2188 | if (mv643xx_eth_collect_events(mp)) | 2190 | if (mv643xx_eth_collect_events(mp)) |
2189 | continue; | 2191 | continue; |
@@ -2204,7 +2206,7 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget) | |||
2204 | txq_maybe_wake(mp->txq + queue); | 2206 | txq_maybe_wake(mp->txq + queue); |
2205 | } else if (mp->work_rx & queue_mask) { | 2207 | } else if (mp->work_rx & queue_mask) { |
2206 | work_done += rxq_process(mp->rxq + queue, work_tbd); | 2208 | work_done += rxq_process(mp->rxq + queue, work_tbd); |
2207 | } else if (mp->work_rx_refill & queue_mask) { | 2209 | } else if (!mp->oom && (mp->work_rx_refill & queue_mask)) { |
2208 | work_done += rxq_refill(mp->rxq + queue, work_tbd); | 2210 | work_done += rxq_refill(mp->rxq + queue, work_tbd); |
2209 | } else { | 2211 | } else { |
2210 | BUG(); | 2212 | BUG(); |
@@ -2212,7 +2214,7 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget) | |||
2212 | } | 2214 | } |
2213 | 2215 | ||
2214 | if (work_done < budget) { | 2216 | if (work_done < budget) { |
2215 | if (mp->work_rx_oom) | 2217 | if (mp->oom) |
2216 | mod_timer(&mp->rx_oom, jiffies + (HZ / 10)); | 2218 | mod_timer(&mp->rx_oom, jiffies + (HZ / 10)); |
2217 | napi_complete(napi); | 2219 | napi_complete(napi); |
2218 | wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT); | 2220 | wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT); |
@@ -2372,7 +2374,7 @@ static int mv643xx_eth_open(struct net_device *dev) | |||
2372 | rxq_refill(mp->rxq + i, INT_MAX); | 2374 | rxq_refill(mp->rxq + i, INT_MAX); |
2373 | } | 2375 | } |
2374 | 2376 | ||
2375 | if (mp->work_rx_oom) { | 2377 | if (mp->oom) { |
2376 | mp->rx_oom.expires = jiffies + (HZ / 10); | 2378 | mp->rx_oom.expires = jiffies + (HZ / 10); |
2377 | add_timer(&mp->rx_oom); | 2379 | add_timer(&mp->rx_oom); |
2378 | } | 2380 | } |
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c index eb66f658f9d1..7d83896b8c26 100644 --- a/drivers/net/ne2k-pci.c +++ b/drivers/net/ne2k-pci.c | |||
@@ -374,18 +374,17 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev, | |||
374 | dev->ethtool_ops = &ne2k_pci_ethtool_ops; | 374 | dev->ethtool_ops = &ne2k_pci_ethtool_ops; |
375 | NS8390_init(dev, 0); | 375 | NS8390_init(dev, 0); |
376 | 376 | ||
377 | memcpy(dev->dev_addr, SA_prom, 6); | ||
378 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | ||
379 | |||
377 | i = register_netdev(dev); | 380 | i = register_netdev(dev); |
378 | if (i) | 381 | if (i) |
379 | goto err_out_free_netdev; | 382 | goto err_out_free_netdev; |
380 | 383 | ||
381 | for(i = 0; i < 6; i++) | ||
382 | dev->dev_addr[i] = SA_prom[i]; | ||
383 | printk("%s: %s found at %#lx, IRQ %d, %pM.\n", | 384 | printk("%s: %s found at %#lx, IRQ %d, %pM.\n", |
384 | dev->name, pci_clone_list[chip_idx].name, ioaddr, dev->irq, | 385 | dev->name, pci_clone_list[chip_idx].name, ioaddr, dev->irq, |
385 | dev->dev_addr); | 386 | dev->dev_addr); |
386 | 387 | ||
387 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | ||
388 | |||
389 | return 0; | 388 | return 0; |
390 | 389 | ||
391 | err_out_free_netdev: | 390 | err_out_free_netdev: |
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index eceadf787a67..bf4af5248cb7 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c | |||
@@ -664,7 +664,7 @@ static int netconsole_netdev_event(struct notifier_block *this, | |||
664 | struct netconsole_target *nt; | 664 | struct netconsole_target *nt; |
665 | struct net_device *dev = ptr; | 665 | struct net_device *dev = ptr; |
666 | 666 | ||
667 | if (!(event == NETDEV_CHANGENAME)) | 667 | if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER)) |
668 | goto done; | 668 | goto done; |
669 | 669 | ||
670 | spin_lock_irqsave(&target_list_lock, flags); | 670 | spin_lock_irqsave(&target_list_lock, flags); |
@@ -675,6 +675,15 @@ static int netconsole_netdev_event(struct notifier_block *this, | |||
675 | case NETDEV_CHANGENAME: | 675 | case NETDEV_CHANGENAME: |
676 | strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ); | 676 | strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ); |
677 | break; | 677 | break; |
678 | case NETDEV_UNREGISTER: | ||
679 | if (!nt->enabled) | ||
680 | break; | ||
681 | netpoll_cleanup(&nt->np); | ||
682 | nt->enabled = 0; | ||
683 | printk(KERN_INFO "netconsole: network logging stopped" | ||
684 | ", interface %s unregistered\n", | ||
685 | dev->name); | ||
686 | break; | ||
678 | } | 687 | } |
679 | } | 688 | } |
680 | netconsole_target_put(nt); | 689 | netconsole_target_put(nt); |
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 8ee21030e9ac..dfc6cf765fbd 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
@@ -180,6 +180,20 @@ config USB_NET_CDCETHER | |||
180 | IEEE 802 "local assignment" bit is set in the address, a "usbX" | 180 | IEEE 802 "local assignment" bit is set in the address, a "usbX" |
181 | name is used instead. | 181 | name is used instead. |
182 | 182 | ||
183 | config USB_NET_CDC_EEM | ||
184 | tristate "CDC EEM support" | ||
185 | depends on USB_USBNET && EXPERIMENTAL | ||
186 | help | ||
187 | This option supports devices conforming to the Communication Device | ||
188 | Class (CDC) Ethernet Emulation Model, a specification that's easy to | ||
189 | implement in device firmware. The CDC EEM specifications are available | ||
190 | from <http://www.usb.org/>. | ||
191 | |||
192 | This driver creates an interface named "ethX", where X depends on | ||
193 | what other networking devices you have in use. However, if the | ||
194 | IEEE 802 "local assignment" bit is set in the address, a "usbX" | ||
195 | name is used instead. | ||
196 | |||
183 | config USB_NET_DM9601 | 197 | config USB_NET_DM9601 |
184 | tristate "Davicom DM9601 based USB 1.1 10/100 ethernet devices" | 198 | tristate "Davicom DM9601 based USB 1.1 10/100 ethernet devices" |
185 | depends on USB_USBNET | 199 | depends on USB_USBNET |
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index 88a87eeb376a..c8aef62cf2b7 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile | |||
@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_RTL8150) += rtl8150.o | |||
9 | obj-$(CONFIG_USB_HSO) += hso.o | 9 | obj-$(CONFIG_USB_HSO) += hso.o |
10 | obj-$(CONFIG_USB_NET_AX8817X) += asix.o | 10 | obj-$(CONFIG_USB_NET_AX8817X) += asix.o |
11 | obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o | 11 | obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o |
12 | obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o | ||
12 | obj-$(CONFIG_USB_NET_DM9601) += dm9601.o | 13 | obj-$(CONFIG_USB_NET_DM9601) += dm9601.o |
13 | obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o | 14 | obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o |
14 | obj-$(CONFIG_USB_NET_GL620A) += gl620a.o | 15 | obj-$(CONFIG_USB_NET_GL620A) += gl620a.o |
diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c new file mode 100644 index 000000000000..80e01778dd3b --- /dev/null +++ b/drivers/net/usb/cdc_eem.c | |||
@@ -0,0 +1,381 @@ | |||
1 | /* | ||
2 | * USB CDC EEM network interface driver | ||
3 | * Copyright (C) 2009 Oberthur Technologies | ||
4 | * by Omar Laazimani, Olivier Condemine | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/netdevice.h> | ||
24 | #include <linux/etherdevice.h> | ||
25 | #include <linux/ctype.h> | ||
26 | #include <linux/ethtool.h> | ||
27 | #include <linux/workqueue.h> | ||
28 | #include <linux/mii.h> | ||
29 | #include <linux/usb.h> | ||
30 | #include <linux/crc32.h> | ||
31 | #include <linux/usb/cdc.h> | ||
32 | #include <linux/usb/usbnet.h> | ||
33 | |||
34 | |||
35 | /* | ||
36 | * This driver is an implementation of the CDC "Ethernet Emulation | ||
37 | * Model" (EEM) specification, which encapsulates Ethernet frames | ||
38 | * for transport over USB using a simpler USB device model than the | ||
39 | * previous CDC "Ethernet Control Model" (ECM, or "CDC Ethernet"). | ||
40 | * | ||
41 | * For details, see www.usb.org/developers/devclass_docs/CDC_EEM10.pdf | ||
42 | * | ||
43 | * This version has been tested with GIGAntIC WuaoW SIM Smart Card on 2.6.24, | ||
44 | * 2.6.27 and 2.6.30rc2 kernel. | ||
45 | * It has also been validated on Openmoko Om 2008.12 (based on 2.6.24 kernel). | ||
46 | * build on 23-April-2009 | ||
47 | */ | ||
48 | |||
49 | #define EEM_HEAD 2 /* 2 byte header */ | ||
50 | |||
51 | /*-------------------------------------------------------------------------*/ | ||
52 | |||
53 | static void eem_linkcmd_complete(struct urb *urb) | ||
54 | { | ||
55 | dev_kfree_skb(urb->context); | ||
56 | usb_free_urb(urb); | ||
57 | } | ||
58 | |||
59 | static void eem_linkcmd(struct usbnet *dev, struct sk_buff *skb) | ||
60 | { | ||
61 | struct urb *urb; | ||
62 | int status; | ||
63 | |||
64 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
65 | if (!urb) | ||
66 | goto fail; | ||
67 | |||
68 | usb_fill_bulk_urb(urb, dev->udev, dev->out, | ||
69 | skb->data, skb->len, eem_linkcmd_complete, skb); | ||
70 | |||
71 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
72 | if (status) { | ||
73 | usb_free_urb(urb); | ||
74 | fail: | ||
75 | dev_kfree_skb(skb); | ||
76 | devwarn(dev, "link cmd failure\n"); | ||
77 | return; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | static int eem_bind(struct usbnet *dev, struct usb_interface *intf) | ||
82 | { | ||
83 | int status = 0; | ||
84 | |||
85 | status = usbnet_get_endpoints(dev, intf); | ||
86 | if (status < 0) { | ||
87 | usb_set_intfdata(intf, NULL); | ||
88 | usb_driver_release_interface(driver_of(intf), intf); | ||
89 | return status; | ||
90 | } | ||
91 | |||
92 | /* no jumbogram (16K) support for now */ | ||
93 | |||
94 | dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN; | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | /* | ||
100 | * EEM permits packing multiple Ethernet frames into USB transfers | ||
101 | * (a "bundle"), but for TX we don't try to do that. | ||
102 | */ | ||
103 | static struct sk_buff *eem_tx_fixup(struct usbnet *dev, struct sk_buff *skb, | ||
104 | gfp_t flags) | ||
105 | { | ||
106 | struct sk_buff *skb2 = NULL; | ||
107 | u16 len = skb->len; | ||
108 | u32 crc = 0; | ||
109 | int padlen = 0; | ||
110 | |||
111 | /* When ((len + EEM_HEAD + ETH_FCS_LEN) % dev->maxpacket) is | ||
112 | * zero, stick two bytes of zero length EEM packet on the end. | ||
113 | * Else the framework would add invalid single byte padding, | ||
114 | * since it can't know whether ZLPs will be handled right by | ||
115 | * all the relevant hardware and software. | ||
116 | */ | ||
117 | if (!((len + EEM_HEAD + ETH_FCS_LEN) % dev->maxpacket)) | ||
118 | padlen += 2; | ||
119 | |||
120 | if (!skb_cloned(skb)) { | ||
121 | int headroom = skb_headroom(skb); | ||
122 | int tailroom = skb_tailroom(skb); | ||
123 | |||
124 | if ((tailroom >= ETH_FCS_LEN + padlen) | ||
125 | && (headroom >= EEM_HEAD)) | ||
126 | goto done; | ||
127 | |||
128 | if ((headroom + tailroom) | ||
129 | > (EEM_HEAD + ETH_FCS_LEN + padlen)) { | ||
130 | skb->data = memmove(skb->head + | ||
131 | EEM_HEAD, | ||
132 | skb->data, | ||
133 | skb->len); | ||
134 | skb_set_tail_pointer(skb, len); | ||
135 | goto done; | ||
136 | } | ||
137 | } | ||
138 | |||
139 | skb2 = skb_copy_expand(skb, EEM_HEAD, ETH_FCS_LEN + padlen, flags); | ||
140 | if (!skb2) | ||
141 | return NULL; | ||
142 | |||
143 | dev_kfree_skb_any(skb); | ||
144 | skb = skb2; | ||
145 | |||
146 | done: | ||
147 | /* we don't use the "no Ethernet CRC" option */ | ||
148 | crc = crc32_le(~0, skb->data, skb->len); | ||
149 | crc = ~crc; | ||
150 | |||
151 | put_unaligned_le32(crc, skb_put(skb, 4)); | ||
152 | |||
153 | /* EEM packet header format: | ||
154 | * b0..13: length of ethernet frame | ||
155 | * b14: bmCRC (1 == valid Ethernet CRC) | ||
156 | * b15: bmType (0 == data) | ||
157 | */ | ||
158 | len = skb->len; | ||
159 | put_unaligned_le16(BIT(14) | len, skb_push(skb, 2)); | ||
160 | |||
161 | /* Bundle a zero length EEM packet if needed */ | ||
162 | if (padlen) | ||
163 | put_unaligned_le16(0, skb_put(skb, 2)); | ||
164 | |||
165 | return skb; | ||
166 | } | ||
167 | |||
168 | static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | ||
169 | { | ||
170 | /* | ||
171 | * Our task here is to strip off framing, leaving skb with one | ||
172 | * data frame for the usbnet framework code to process. But we | ||
173 | * may have received multiple EEM payloads, or command payloads. | ||
174 | * So we must process _everything_ as if it's a header, except | ||
175 | * maybe the last data payload | ||
176 | * | ||
177 | * REVISIT the framework needs updating so that when we consume | ||
178 | * all payloads (the last or only message was a command, or a | ||
179 | * zero length EEM packet) that is not accounted as an rx_error. | ||
180 | */ | ||
181 | do { | ||
182 | struct sk_buff *skb2 = NULL; | ||
183 | u16 header; | ||
184 | u16 len = 0; | ||
185 | |||
186 | /* incomplete EEM header? */ | ||
187 | if (skb->len < EEM_HEAD) | ||
188 | return 0; | ||
189 | |||
190 | /* | ||
191 | * EEM packet header format: | ||
192 | * b0..14: EEM type dependant (Data or Command) | ||
193 | * b15: bmType | ||
194 | */ | ||
195 | header = get_unaligned_le16(skb->data); | ||
196 | skb_pull(skb, EEM_HEAD); | ||
197 | |||
198 | /* | ||
199 | * The bmType bit helps to denote when EEM | ||
200 | * packet is data or command : | ||
201 | * bmType = 0 : EEM data payload | ||
202 | * bmType = 1 : EEM (link) command | ||
203 | */ | ||
204 | if (header & BIT(15)) { | ||
205 | u16 bmEEMCmd; | ||
206 | |||
207 | /* | ||
208 | * EEM (link) command packet: | ||
209 | * b0..10: bmEEMCmdParam | ||
210 | * b11..13: bmEEMCmd | ||
211 | * b14: bmReserved (must be 0) | ||
212 | * b15: 1 (EEM command) | ||
213 | */ | ||
214 | if (header & BIT(14)) { | ||
215 | devdbg(dev, "reserved command %04x\n", header); | ||
216 | continue; | ||
217 | } | ||
218 | |||
219 | bmEEMCmd = (header >> 11) & 0x7; | ||
220 | switch (bmEEMCmd) { | ||
221 | |||
222 | /* Responding to echo requests is mandatory. */ | ||
223 | case 0: /* Echo command */ | ||
224 | len = header & 0x7FF; | ||
225 | |||
226 | /* bogus command? */ | ||
227 | if (skb->len < len) | ||
228 | return 0; | ||
229 | |||
230 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
231 | if (unlikely(!skb2)) | ||
232 | goto next; | ||
233 | skb_trim(skb2, len); | ||
234 | put_unaligned_le16(BIT(15) | (1 << 11) | len, | ||
235 | skb_push(skb2, 2)); | ||
236 | eem_linkcmd(dev, skb2); | ||
237 | break; | ||
238 | |||
239 | /* | ||
240 | * Host may choose to ignore hints. | ||
241 | * - suspend: peripheral ready to suspend | ||
242 | * - response: suggest N millisec polling | ||
243 | * - response complete: suggest N sec polling | ||
244 | */ | ||
245 | case 2: /* Suspend hint */ | ||
246 | case 3: /* Response hint */ | ||
247 | case 4: /* Response complete hint */ | ||
248 | continue; | ||
249 | |||
250 | /* | ||
251 | * Hosts should never receive host-to-peripheral | ||
252 | * or reserved command codes; or responses to an | ||
253 | * echo command we didn't send. | ||
254 | */ | ||
255 | case 1: /* Echo response */ | ||
256 | case 5: /* Tickle */ | ||
257 | default: /* reserved */ | ||
258 | devwarn(dev, "unexpected link command %d\n", | ||
259 | bmEEMCmd); | ||
260 | continue; | ||
261 | } | ||
262 | |||
263 | } else { | ||
264 | u32 crc, crc2; | ||
265 | int is_last; | ||
266 | |||
267 | /* zero length EEM packet? */ | ||
268 | if (header == 0) | ||
269 | continue; | ||
270 | |||
271 | /* | ||
272 | * EEM data packet header : | ||
273 | * b0..13: length of ethernet frame | ||
274 | * b14: bmCRC | ||
275 | * b15: 0 (EEM data) | ||
276 | */ | ||
277 | len = header & 0x3FFF; | ||
278 | |||
279 | /* bogus EEM payload? */ | ||
280 | if (skb->len < len) | ||
281 | return 0; | ||
282 | |||
283 | /* bogus ethernet frame? */ | ||
284 | if (len < (ETH_HLEN + ETH_FCS_LEN)) | ||
285 | goto next; | ||
286 | |||
287 | /* | ||
288 | * Treat the last payload differently: framework | ||
289 | * code expects our "fixup" to have stripped off | ||
290 | * headers, so "skb" is a data packet (or error). | ||
291 | * Else if it's not the last payload, keep "skb" | ||
292 | * for further processing. | ||
293 | */ | ||
294 | is_last = (len == skb->len); | ||
295 | if (is_last) | ||
296 | skb2 = skb; | ||
297 | else { | ||
298 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
299 | if (unlikely(!skb2)) | ||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | crc = get_unaligned_le32(skb2->data | ||
304 | + len - ETH_FCS_LEN); | ||
305 | skb_trim(skb2, len - ETH_FCS_LEN); | ||
306 | |||
307 | /* | ||
308 | * The bmCRC helps to denote when the CRC field in | ||
309 | * the Ethernet frame contains a calculated CRC: | ||
310 | * bmCRC = 1 : CRC is calculated | ||
311 | * bmCRC = 0 : CRC = 0xDEADBEEF | ||
312 | */ | ||
313 | if (header & BIT(14)) | ||
314 | crc2 = ~crc32_le(~0, skb2->data, len); | ||
315 | else | ||
316 | crc2 = 0xdeadbeef; | ||
317 | |||
318 | if (is_last) | ||
319 | return crc == crc2; | ||
320 | |||
321 | if (unlikely(crc != crc2)) { | ||
322 | dev->stats.rx_errors++; | ||
323 | dev_kfree_skb_any(skb2); | ||
324 | } else | ||
325 | usbnet_skb_return(dev, skb2); | ||
326 | } | ||
327 | |||
328 | next: | ||
329 | skb_pull(skb, len); | ||
330 | } while (skb->len); | ||
331 | |||
332 | return 1; | ||
333 | } | ||
334 | |||
335 | static const struct driver_info eem_info = { | ||
336 | .description = "CDC EEM Device", | ||
337 | .flags = FLAG_ETHER, | ||
338 | .bind = eem_bind, | ||
339 | .rx_fixup = eem_rx_fixup, | ||
340 | .tx_fixup = eem_tx_fixup, | ||
341 | }; | ||
342 | |||
343 | /*-------------------------------------------------------------------------*/ | ||
344 | |||
345 | static const struct usb_device_id products[] = { | ||
346 | { | ||
347 | USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_EEM, | ||
348 | USB_CDC_PROTO_EEM), | ||
349 | .driver_info = (unsigned long) &eem_info, | ||
350 | }, | ||
351 | { | ||
352 | /* EMPTY == end of list */ | ||
353 | }, | ||
354 | }; | ||
355 | MODULE_DEVICE_TABLE(usb, products); | ||
356 | |||
357 | static struct usb_driver eem_driver = { | ||
358 | .name = "cdc_eem", | ||
359 | .id_table = products, | ||
360 | .probe = usbnet_probe, | ||
361 | .disconnect = usbnet_disconnect, | ||
362 | .suspend = usbnet_suspend, | ||
363 | .resume = usbnet_resume, | ||
364 | }; | ||
365 | |||
366 | |||
367 | static int __init eem_init(void) | ||
368 | { | ||
369 | return usb_register(&eem_driver); | ||
370 | } | ||
371 | module_init(eem_init); | ||
372 | |||
373 | static void __exit eem_exit(void) | ||
374 | { | ||
375 | usb_deregister(&eem_driver); | ||
376 | } | ||
377 | module_exit(eem_exit); | ||
378 | |||
379 | MODULE_AUTHOR("Omar Laazimani <omar.oberthur@gmail.com>"); | ||
380 | MODULE_DESCRIPTION("USB CDC EEM"); | ||
381 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index dc1665326592..5a7283372b53 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c | |||
@@ -941,6 +941,16 @@ static int smsc95xx_reset(struct usbnet *dev) | |||
941 | if (netif_msg_ifup(dev)) | 941 | if (netif_msg_ifup(dev)) |
942 | devdbg(dev, "ID_REV = 0x%08x", read_buf); | 942 | devdbg(dev, "ID_REV = 0x%08x", read_buf); |
943 | 943 | ||
944 | /* Configure GPIO pins as LED outputs */ | ||
945 | write_buf = LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED | | ||
946 | LED_GPIO_CFG_FDX_LED; | ||
947 | ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, write_buf); | ||
948 | if (ret < 0) { | ||
949 | devwarn(dev, "Failed to write LED_GPIO_CFG register, ret=%d", | ||
950 | ret); | ||
951 | return ret; | ||
952 | } | ||
953 | |||
944 | /* Init Tx */ | 954 | /* Init Tx */ |
945 | write_buf = 0; | 955 | write_buf = 0; |
946 | ret = smsc95xx_write_reg(dev, FLOW, write_buf); | 956 | ret = smsc95xx_write_reg(dev, FLOW, write_buf); |
@@ -1231,6 +1241,11 @@ static const struct usb_device_id products[] = { | |||
1231 | USB_DEVICE(0x0424, 0x9500), | 1241 | USB_DEVICE(0x0424, 0x9500), |
1232 | .driver_info = (unsigned long) &smsc95xx_info, | 1242 | .driver_info = (unsigned long) &smsc95xx_info, |
1233 | }, | 1243 | }, |
1244 | { | ||
1245 | /* SMSC9512/9514 USB Hub & Ethernet Device */ | ||
1246 | USB_DEVICE(0x0424, 0xec00), | ||
1247 | .driver_info = (unsigned long) &smsc95xx_info, | ||
1248 | }, | ||
1234 | { }, /* END */ | 1249 | { }, /* END */ |
1235 | }; | 1250 | }; |
1236 | MODULE_DEVICE_TABLE(usb, products); | 1251 | MODULE_DEVICE_TABLE(usb, products); |
diff --git a/drivers/net/usb/smsc95xx.h b/drivers/net/usb/smsc95xx.h index 66b5c84f302e..86bc44977fbd 100644 --- a/drivers/net/usb/smsc95xx.h +++ b/drivers/net/usb/smsc95xx.h | |||
@@ -99,6 +99,9 @@ | |||
99 | #define PM_CTL_WUPS_MULTI_ (0x00000003) | 99 | #define PM_CTL_WUPS_MULTI_ (0x00000003) |
100 | 100 | ||
101 | #define LED_GPIO_CFG (0x24) | 101 | #define LED_GPIO_CFG (0x24) |
102 | #define LED_GPIO_CFG_SPD_LED (0x01000000) | ||
103 | #define LED_GPIO_CFG_LNK_LED (0x00100000) | ||
104 | #define LED_GPIO_CFG_FDX_LED (0x00010000) | ||
102 | 105 | ||
103 | #define GPIO_CFG (0x28) | 106 | #define GPIO_CFG (0x28) |
104 | 107 | ||
diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 015db1cece72..8e56fcf0a0e3 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c | |||
@@ -210,14 +210,11 @@ rx_drop: | |||
210 | 210 | ||
211 | static struct net_device_stats *veth_get_stats(struct net_device *dev) | 211 | static struct net_device_stats *veth_get_stats(struct net_device *dev) |
212 | { | 212 | { |
213 | struct veth_priv *priv; | 213 | struct veth_priv *priv = netdev_priv(dev); |
214 | struct net_device_stats *dev_stats; | 214 | struct net_device_stats *dev_stats = &dev->stats; |
215 | int cpu; | 215 | unsigned int cpu; |
216 | struct veth_net_stats *stats; | 216 | struct veth_net_stats *stats; |
217 | 217 | ||
218 | priv = netdev_priv(dev); | ||
219 | dev_stats = &dev->stats; | ||
220 | |||
221 | dev_stats->rx_packets = 0; | 218 | dev_stats->rx_packets = 0; |
222 | dev_stats->tx_packets = 0; | 219 | dev_stats->tx_packets = 0; |
223 | dev_stats->rx_bytes = 0; | 220 | dev_stats->rx_bytes = 0; |
@@ -225,16 +222,17 @@ static struct net_device_stats *veth_get_stats(struct net_device *dev) | |||
225 | dev_stats->tx_dropped = 0; | 222 | dev_stats->tx_dropped = 0; |
226 | dev_stats->rx_dropped = 0; | 223 | dev_stats->rx_dropped = 0; |
227 | 224 | ||
228 | for_each_online_cpu(cpu) { | 225 | if (priv->stats) |
229 | stats = per_cpu_ptr(priv->stats, cpu); | 226 | for_each_online_cpu(cpu) { |
227 | stats = per_cpu_ptr(priv->stats, cpu); | ||
230 | 228 | ||
231 | dev_stats->rx_packets += stats->rx_packets; | 229 | dev_stats->rx_packets += stats->rx_packets; |
232 | dev_stats->tx_packets += stats->tx_packets; | 230 | dev_stats->tx_packets += stats->tx_packets; |
233 | dev_stats->rx_bytes += stats->rx_bytes; | 231 | dev_stats->rx_bytes += stats->rx_bytes; |
234 | dev_stats->tx_bytes += stats->tx_bytes; | 232 | dev_stats->tx_bytes += stats->tx_bytes; |
235 | dev_stats->tx_dropped += stats->tx_dropped; | 233 | dev_stats->tx_dropped += stats->tx_dropped; |
236 | dev_stats->rx_dropped += stats->rx_dropped; | 234 | dev_stats->rx_dropped += stats->rx_dropped; |
237 | } | 235 | } |
238 | 236 | ||
239 | return dev_stats; | 237 | return dev_stats; |
240 | } | 238 | } |
@@ -261,6 +259,8 @@ static int veth_close(struct net_device *dev) | |||
261 | netif_carrier_off(dev); | 259 | netif_carrier_off(dev); |
262 | netif_carrier_off(priv->peer); | 260 | netif_carrier_off(priv->peer); |
263 | 261 | ||
262 | free_percpu(priv->stats); | ||
263 | priv->stats = NULL; | ||
264 | return 0; | 264 | return 0; |
265 | } | 265 | } |
266 | 266 | ||
@@ -291,15 +291,6 @@ static int veth_dev_init(struct net_device *dev) | |||
291 | return 0; | 291 | return 0; |
292 | } | 292 | } |
293 | 293 | ||
294 | static void veth_dev_free(struct net_device *dev) | ||
295 | { | ||
296 | struct veth_priv *priv; | ||
297 | |||
298 | priv = netdev_priv(dev); | ||
299 | free_percpu(priv->stats); | ||
300 | free_netdev(dev); | ||
301 | } | ||
302 | |||
303 | static const struct net_device_ops veth_netdev_ops = { | 294 | static const struct net_device_ops veth_netdev_ops = { |
304 | .ndo_init = veth_dev_init, | 295 | .ndo_init = veth_dev_init, |
305 | .ndo_open = veth_open, | 296 | .ndo_open = veth_open, |
@@ -317,7 +308,7 @@ static void veth_setup(struct net_device *dev) | |||
317 | dev->netdev_ops = &veth_netdev_ops; | 308 | dev->netdev_ops = &veth_netdev_ops; |
318 | dev->ethtool_ops = &veth_ethtool_ops; | 309 | dev->ethtool_ops = &veth_ethtool_ops; |
319 | dev->features |= NETIF_F_LLTX; | 310 | dev->features |= NETIF_F_LLTX; |
320 | dev->destructor = veth_dev_free; | 311 | dev->destructor = free_netdev; |
321 | } | 312 | } |
322 | 313 | ||
323 | /* | 314 | /* |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 9c82a39497e5..4d1d47953fc6 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -616,10 +616,11 @@ static int virtnet_open(struct net_device *dev) | |||
616 | static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd, | 616 | static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd, |
617 | struct scatterlist *data, int out, int in) | 617 | struct scatterlist *data, int out, int in) |
618 | { | 618 | { |
619 | struct scatterlist sg[VIRTNET_SEND_COMMAND_SG_MAX + 2]; | 619 | struct scatterlist *s, sg[VIRTNET_SEND_COMMAND_SG_MAX + 2]; |
620 | struct virtio_net_ctrl_hdr ctrl; | 620 | struct virtio_net_ctrl_hdr ctrl; |
621 | virtio_net_ctrl_ack status = ~0; | 621 | virtio_net_ctrl_ack status = ~0; |
622 | unsigned int tmp; | 622 | unsigned int tmp; |
623 | int i; | ||
623 | 624 | ||
624 | if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) { | 625 | if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) { |
625 | BUG(); /* Caller should know better */ | 626 | BUG(); /* Caller should know better */ |
@@ -637,7 +638,8 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd, | |||
637 | sg_init_table(sg, out + in); | 638 | sg_init_table(sg, out + in); |
638 | 639 | ||
639 | sg_set_buf(&sg[0], &ctrl, sizeof(ctrl)); | 640 | sg_set_buf(&sg[0], &ctrl, sizeof(ctrl)); |
640 | memcpy(&sg[1], data, sizeof(struct scatterlist) * (out + in - 2)); | 641 | for_each_sg(data, s, out + in - 2, i) |
642 | sg_set_buf(&sg[i + 1], sg_virt(s), s->length); | ||
641 | sg_set_buf(&sg[out + in - 1], &status, sizeof(status)); | 643 | sg_set_buf(&sg[out + in - 1], &status, sizeof(status)); |
642 | 644 | ||
643 | if (vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi) != 0) | 645 | if (vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi) != 0) |
@@ -692,7 +694,7 @@ static void virtnet_set_rx_mode(struct net_device *dev) | |||
692 | promisc = ((dev->flags & IFF_PROMISC) != 0); | 694 | promisc = ((dev->flags & IFF_PROMISC) != 0); |
693 | allmulti = ((dev->flags & IFF_ALLMULTI) != 0); | 695 | allmulti = ((dev->flags & IFF_ALLMULTI) != 0); |
694 | 696 | ||
695 | sg_set_buf(sg, &promisc, sizeof(promisc)); | 697 | sg_init_one(sg, &promisc, sizeof(promisc)); |
696 | 698 | ||
697 | if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX, | 699 | if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX, |
698 | VIRTIO_NET_CTRL_RX_PROMISC, | 700 | VIRTIO_NET_CTRL_RX_PROMISC, |
@@ -700,7 +702,7 @@ static void virtnet_set_rx_mode(struct net_device *dev) | |||
700 | dev_warn(&dev->dev, "Failed to %sable promisc mode.\n", | 702 | dev_warn(&dev->dev, "Failed to %sable promisc mode.\n", |
701 | promisc ? "en" : "dis"); | 703 | promisc ? "en" : "dis"); |
702 | 704 | ||
703 | sg_set_buf(sg, &allmulti, sizeof(allmulti)); | 705 | sg_init_one(sg, &allmulti, sizeof(allmulti)); |
704 | 706 | ||
705 | if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX, | 707 | if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX, |
706 | VIRTIO_NET_CTRL_RX_ALLMULTI, | 708 | VIRTIO_NET_CTRL_RX_ALLMULTI, |
@@ -716,6 +718,8 @@ static void virtnet_set_rx_mode(struct net_device *dev) | |||
716 | return; | 718 | return; |
717 | } | 719 | } |
718 | 720 | ||
721 | sg_init_table(sg, 2); | ||
722 | |||
719 | /* Store the unicast list and count in the front of the buffer */ | 723 | /* Store the unicast list and count in the front of the buffer */ |
720 | mac_data->entries = dev->uc_count; | 724 | mac_data->entries = dev->uc_count; |
721 | addr = dev->uc_list; | 725 | addr = dev->uc_list; |
@@ -744,24 +748,24 @@ static void virtnet_set_rx_mode(struct net_device *dev) | |||
744 | kfree(buf); | 748 | kfree(buf); |
745 | } | 749 | } |
746 | 750 | ||
747 | static void virnet_vlan_rx_add_vid(struct net_device *dev, u16 vid) | 751 | static void virtnet_vlan_rx_add_vid(struct net_device *dev, u16 vid) |
748 | { | 752 | { |
749 | struct virtnet_info *vi = netdev_priv(dev); | 753 | struct virtnet_info *vi = netdev_priv(dev); |
750 | struct scatterlist sg; | 754 | struct scatterlist sg; |
751 | 755 | ||
752 | sg_set_buf(&sg, &vid, sizeof(vid)); | 756 | sg_init_one(&sg, &vid, sizeof(vid)); |
753 | 757 | ||
754 | if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, | 758 | if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, |
755 | VIRTIO_NET_CTRL_VLAN_ADD, &sg, 1, 0)) | 759 | VIRTIO_NET_CTRL_VLAN_ADD, &sg, 1, 0)) |
756 | dev_warn(&dev->dev, "Failed to add VLAN ID %d.\n", vid); | 760 | dev_warn(&dev->dev, "Failed to add VLAN ID %d.\n", vid); |
757 | } | 761 | } |
758 | 762 | ||
759 | static void virnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid) | 763 | static void virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid) |
760 | { | 764 | { |
761 | struct virtnet_info *vi = netdev_priv(dev); | 765 | struct virtnet_info *vi = netdev_priv(dev); |
762 | struct scatterlist sg; | 766 | struct scatterlist sg; |
763 | 767 | ||
764 | sg_set_buf(&sg, &vid, sizeof(vid)); | 768 | sg_init_one(&sg, &vid, sizeof(vid)); |
765 | 769 | ||
766 | if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, | 770 | if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, |
767 | VIRTIO_NET_CTRL_VLAN_DEL, &sg, 1, 0)) | 771 | VIRTIO_NET_CTRL_VLAN_DEL, &sg, 1, 0)) |
@@ -794,8 +798,8 @@ static const struct net_device_ops virtnet_netdev = { | |||
794 | .ndo_set_mac_address = virtnet_set_mac_address, | 798 | .ndo_set_mac_address = virtnet_set_mac_address, |
795 | .ndo_set_rx_mode = virtnet_set_rx_mode, | 799 | .ndo_set_rx_mode = virtnet_set_rx_mode, |
796 | .ndo_change_mtu = virtnet_change_mtu, | 800 | .ndo_change_mtu = virtnet_change_mtu, |
797 | .ndo_vlan_rx_add_vid = virnet_vlan_rx_add_vid, | 801 | .ndo_vlan_rx_add_vid = virtnet_vlan_rx_add_vid, |
798 | .ndo_vlan_rx_kill_vid = virnet_vlan_rx_kill_vid, | 802 | .ndo_vlan_rx_kill_vid = virtnet_vlan_rx_kill_vid, |
799 | #ifdef CONFIG_NET_POLL_CONTROLLER | 803 | #ifdef CONFIG_NET_POLL_CONTROLLER |
800 | .ndo_poll_controller = virtnet_netpoll, | 804 | .ndo_poll_controller = virtnet_netpoll, |
801 | #endif | 805 | #endif |
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index 3bf7d3f447db..765a7f5d6aa4 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c | |||
@@ -1249,7 +1249,7 @@ static int __devinit hss_init_one(struct platform_device *pdev) | |||
1249 | return -ENOMEM; | 1249 | return -ENOMEM; |
1250 | 1250 | ||
1251 | if ((port->npe = npe_request(0)) == NULL) { | 1251 | if ((port->npe = npe_request(0)) == NULL) { |
1252 | err = -ENOSYS; | 1252 | err = -ENODEV; |
1253 | goto err_free; | 1253 | goto err_free; |
1254 | } | 1254 | } |
1255 | 1255 | ||
@@ -1311,7 +1311,7 @@ static int __init hss_init_module(void) | |||
1311 | if ((ixp4xx_read_feature_bits() & | 1311 | if ((ixp4xx_read_feature_bits() & |
1312 | (IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS)) != | 1312 | (IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS)) != |
1313 | (IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS)) | 1313 | (IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS)) |
1314 | return -ENOSYS; | 1314 | return -ENODEV; |
1315 | 1315 | ||
1316 | spin_lock_init(&npe_lock); | 1316 | spin_lock_init(&npe_lock); |
1317 | 1317 | ||
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index c36d3a3d655f..d73475739127 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -6501,7 +6501,10 @@ static int airo_get_encode(struct net_device *dev, | |||
6501 | 6501 | ||
6502 | /* Copy the key to the user buffer */ | 6502 | /* Copy the key to the user buffer */ |
6503 | dwrq->length = get_wep_key(local, index, &buf[0], sizeof(buf)); | 6503 | dwrq->length = get_wep_key(local, index, &buf[0], sizeof(buf)); |
6504 | memcpy(extra, buf, dwrq->length); | 6504 | if (dwrq->length != -1) |
6505 | memcpy(extra, buf, dwrq->length); | ||
6506 | else | ||
6507 | dwrq->length = 0; | ||
6505 | 6508 | ||
6506 | return 0; | 6509 | return 0; |
6507 | } | 6510 | } |
@@ -6659,7 +6662,10 @@ static int airo_get_encodeext(struct net_device *dev, | |||
6659 | 6662 | ||
6660 | /* Copy the key to the user buffer */ | 6663 | /* Copy the key to the user buffer */ |
6661 | ext->key_len = get_wep_key(local, idx, &buf[0], sizeof(buf)); | 6664 | ext->key_len = get_wep_key(local, idx, &buf[0], sizeof(buf)); |
6662 | memcpy(extra, buf, ext->key_len); | 6665 | if (ext->key_len != -1) |
6666 | memcpy(extra, buf, ext->key_len); | ||
6667 | else | ||
6668 | ext->key_len = 0; | ||
6663 | 6669 | ||
6664 | return 0; | 6670 | return 0; |
6665 | } | 6671 | } |
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index a08bc8a4fb69..32df27a9c7a2 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -214,7 +214,7 @@ static struct pci_driver ath5k_pci_driver = { | |||
214 | * Prototypes - MAC 802.11 stack related functions | 214 | * Prototypes - MAC 802.11 stack related functions |
215 | */ | 215 | */ |
216 | static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); | 216 | static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); |
217 | static int ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel); | 217 | static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); |
218 | static int ath5k_reset_wake(struct ath5k_softc *sc); | 218 | static int ath5k_reset_wake(struct ath5k_softc *sc); |
219 | static int ath5k_start(struct ieee80211_hw *hw); | 219 | static int ath5k_start(struct ieee80211_hw *hw); |
220 | static void ath5k_stop(struct ieee80211_hw *hw); | 220 | static void ath5k_stop(struct ieee80211_hw *hw); |
@@ -1038,16 +1038,13 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | |||
1038 | if (chan->center_freq != sc->curchan->center_freq || | 1038 | if (chan->center_freq != sc->curchan->center_freq || |
1039 | chan->hw_value != sc->curchan->hw_value) { | 1039 | chan->hw_value != sc->curchan->hw_value) { |
1040 | 1040 | ||
1041 | sc->curchan = chan; | ||
1042 | sc->curband = &sc->sbands[chan->band]; | ||
1043 | |||
1044 | /* | 1041 | /* |
1045 | * To switch channels clear any pending DMA operations; | 1042 | * To switch channels clear any pending DMA operations; |
1046 | * wait long enough for the RX fifo to drain, reset the | 1043 | * wait long enough for the RX fifo to drain, reset the |
1047 | * hardware at the new frequency, and then re-enable | 1044 | * hardware at the new frequency, and then re-enable |
1048 | * the relevant bits of the h/w. | 1045 | * the relevant bits of the h/w. |
1049 | */ | 1046 | */ |
1050 | return ath5k_reset(sc, true, true); | 1047 | return ath5k_reset(sc, chan); |
1051 | } | 1048 | } |
1052 | 1049 | ||
1053 | return 0; | 1050 | return 0; |
@@ -2314,7 +2311,7 @@ ath5k_init(struct ath5k_softc *sc) | |||
2314 | sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | | 2311 | sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | |
2315 | AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | | 2312 | AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | |
2316 | AR5K_INT_FATAL | AR5K_INT_GLOBAL; | 2313 | AR5K_INT_FATAL | AR5K_INT_GLOBAL; |
2317 | ret = ath5k_reset(sc, false, false); | 2314 | ret = ath5k_reset(sc, NULL); |
2318 | if (ret) | 2315 | if (ret) |
2319 | goto done; | 2316 | goto done; |
2320 | 2317 | ||
@@ -2599,18 +2596,25 @@ drop_packet: | |||
2599 | return NETDEV_TX_OK; | 2596 | return NETDEV_TX_OK; |
2600 | } | 2597 | } |
2601 | 2598 | ||
2599 | /* | ||
2600 | * Reset the hardware. If chan is not NULL, then also pause rx/tx | ||
2601 | * and change to the given channel. | ||
2602 | */ | ||
2602 | static int | 2603 | static int |
2603 | ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel) | 2604 | ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) |
2604 | { | 2605 | { |
2605 | struct ath5k_hw *ah = sc->ah; | 2606 | struct ath5k_hw *ah = sc->ah; |
2606 | int ret; | 2607 | int ret; |
2607 | 2608 | ||
2608 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); | 2609 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); |
2609 | 2610 | ||
2610 | if (stop) { | 2611 | if (chan) { |
2611 | ath5k_hw_set_imr(ah, 0); | 2612 | ath5k_hw_set_imr(ah, 0); |
2612 | ath5k_txq_cleanup(sc); | 2613 | ath5k_txq_cleanup(sc); |
2613 | ath5k_rx_stop(sc); | 2614 | ath5k_rx_stop(sc); |
2615 | |||
2616 | sc->curchan = chan; | ||
2617 | sc->curband = &sc->sbands[chan->band]; | ||
2614 | } | 2618 | } |
2615 | ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true); | 2619 | ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true); |
2616 | if (ret) { | 2620 | if (ret) { |
@@ -2648,7 +2652,7 @@ ath5k_reset_wake(struct ath5k_softc *sc) | |||
2648 | { | 2652 | { |
2649 | int ret; | 2653 | int ret; |
2650 | 2654 | ||
2651 | ret = ath5k_reset(sc, true, true); | 2655 | ret = ath5k_reset(sc, sc->curchan); |
2652 | if (!ret) | 2656 | if (!ret) |
2653 | ieee80211_wake_queues(sc->hw); | 2657 | ieee80211_wake_queues(sc->hw); |
2654 | 2658 | ||
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c index 9770bb3d40f9..4904a07e4b59 100644 --- a/drivers/net/wireless/ath5k/debug.c +++ b/drivers/net/wireless/ath5k/debug.c | |||
@@ -424,7 +424,7 @@ ath5k_debug_dump_bands(struct ath5k_softc *sc) | |||
424 | 424 | ||
425 | for (b = 0; b < IEEE80211_NUM_BANDS; b++) { | 425 | for (b = 0; b < IEEE80211_NUM_BANDS; b++) { |
426 | struct ieee80211_supported_band *band = &sc->sbands[b]; | 426 | struct ieee80211_supported_band *band = &sc->sbands[b]; |
427 | char bname[5]; | 427 | char bname[6]; |
428 | switch (band->band) { | 428 | switch (band->band) { |
429 | case IEEE80211_BAND_2GHZ: | 429 | case IEEE80211_BAND_2GHZ: |
430 | strcpy(bname, "2 GHz"); | 430 | strcpy(bname, "2 GHz"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index edfa5e149f71..bd438d8acf55 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -101,8 +101,8 @@ struct iwl_cfg iwl6000_2agn_cfg = { | |||
101 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, | 101 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, |
102 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 102 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
103 | .mod_params = &iwl50_mod_params, | 103 | .mod_params = &iwl50_mod_params, |
104 | .valid_tx_ant = ANT_BC, | 104 | .valid_tx_ant = ANT_AB, |
105 | .valid_rx_ant = ANT_BC, | 105 | .valid_rx_ant = ANT_AB, |
106 | .need_pll_cfg = false, | 106 | .need_pll_cfg = false, |
107 | }; | 107 | }; |
108 | 108 | ||
@@ -117,8 +117,8 @@ struct iwl_cfg iwl6050_2agn_cfg = { | |||
117 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, | 117 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, |
118 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 118 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
119 | .mod_params = &iwl50_mod_params, | 119 | .mod_params = &iwl50_mod_params, |
120 | .valid_tx_ant = ANT_BC, | 120 | .valid_tx_ant = ANT_AB, |
121 | .valid_rx_ant = ANT_BC, | 121 | .valid_rx_ant = ANT_AB, |
122 | .need_pll_cfg = false, | 122 | .need_pll_cfg = false, |
123 | }; | 123 | }; |
124 | 124 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1ef4192207a5..3bb28db4a40f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -3636,7 +3636,9 @@ static struct pci_device_id iwl_hw_card_ids[] = { | |||
3636 | {IWL_PCI_DEVICE(0x0085, 0x1112, iwl6000_2ag_cfg)}, | 3636 | {IWL_PCI_DEVICE(0x0085, 0x1112, iwl6000_2ag_cfg)}, |
3637 | {IWL_PCI_DEVICE(0x0082, 0x1122, iwl6000_2ag_cfg)}, | 3637 | {IWL_PCI_DEVICE(0x0082, 0x1122, iwl6000_2ag_cfg)}, |
3638 | {IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)}, | 3638 | {IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)}, |
3639 | {IWL_PCI_DEVICE(0x422C, PCI_ANY_ID, iwl6000_2agn_cfg)}, | ||
3639 | {IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)}, | 3640 | {IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)}, |
3641 | {IWL_PCI_DEVICE(0x4239, PCI_ANY_ID, iwl6000_2agn_cfg)}, | ||
3640 | {IWL_PCI_DEVICE(0x0082, PCI_ANY_ID, iwl6000_2agn_cfg)}, | 3642 | {IWL_PCI_DEVICE(0x0082, PCI_ANY_ID, iwl6000_2agn_cfg)}, |
3641 | {IWL_PCI_DEVICE(0x0085, PCI_ANY_ID, iwl6000_3agn_cfg)}, | 3643 | {IWL_PCI_DEVICE(0x0085, PCI_ANY_ID, iwl6000_3agn_cfg)}, |
3642 | {IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)}, | 3644 | {IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)}, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 23644cf884f1..e7c65c4f741b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -925,11 +925,11 @@ void iwl_bg_scan_completed(struct work_struct *work) | |||
925 | 925 | ||
926 | IWL_DEBUG_SCAN(priv, "SCAN complete scan\n"); | 926 | IWL_DEBUG_SCAN(priv, "SCAN complete scan\n"); |
927 | 927 | ||
928 | ieee80211_scan_completed(priv->hw, false); | ||
929 | |||
928 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 930 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
929 | return; | 931 | return; |
930 | 932 | ||
931 | ieee80211_scan_completed(priv->hw, false); | ||
932 | |||
933 | /* Since setting the TXPOWER may have been deferred while | 933 | /* Since setting the TXPOWER may have been deferred while |
934 | * performing the scan, fire one off */ | 934 | * performing the scan, fire one off */ |
935 | mutex_lock(&priv->mutex); | 935 | mutex_lock(&priv->mutex); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 5798fe49c771..44ab03a12e40 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -719,6 +719,14 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, | |||
719 | { | 719 | { |
720 | unsigned long flags; | 720 | unsigned long flags; |
721 | int ret = 0; | 721 | int ret = 0; |
722 | __le16 key_flags = 0; | ||
723 | |||
724 | key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); | ||
725 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); | ||
726 | key_flags &= ~STA_KEY_FLG_INVALID; | ||
727 | |||
728 | if (sta_id == priv->hw_params.bcast_sta_id) | ||
729 | key_flags |= STA_KEY_MULTICAST_MSK; | ||
722 | 730 | ||
723 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | 731 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; |
724 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | 732 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; |
@@ -738,6 +746,9 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, | |||
738 | WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, | 746 | WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, |
739 | "no space for a new key"); | 747 | "no space for a new key"); |
740 | 748 | ||
749 | priv->stations[sta_id].sta.key.key_flags = key_flags; | ||
750 | |||
751 | |||
741 | /* This copy is acutally not needed: we get the key with each TX */ | 752 | /* This copy is acutally not needed: we get the key with each TX */ |
742 | memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); | 753 | memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); |
743 | 754 | ||
@@ -754,9 +765,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv, | |||
754 | { | 765 | { |
755 | u8 sta_id = IWL_INVALID_STATION; | 766 | u8 sta_id = IWL_INVALID_STATION; |
756 | unsigned long flags; | 767 | unsigned long flags; |
757 | __le16 key_flags = 0; | ||
758 | int i; | 768 | int i; |
759 | DECLARE_MAC_BUF(mac); | ||
760 | 769 | ||
761 | sta_id = iwl_find_station(priv, addr); | 770 | sta_id = iwl_find_station(priv, addr); |
762 | if (sta_id == IWL_INVALID_STATION) { | 771 | if (sta_id == IWL_INVALID_STATION) { |
@@ -771,16 +780,8 @@ void iwl_update_tkip_key(struct iwl_priv *priv, | |||
771 | return; | 780 | return; |
772 | } | 781 | } |
773 | 782 | ||
774 | key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); | ||
775 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); | ||
776 | key_flags &= ~STA_KEY_FLG_INVALID; | ||
777 | |||
778 | if (sta_id == priv->hw_params.bcast_sta_id) | ||
779 | key_flags |= STA_KEY_MULTICAST_MSK; | ||
780 | |||
781 | spin_lock_irqsave(&priv->sta_lock, flags); | 783 | spin_lock_irqsave(&priv->sta_lock, flags); |
782 | 784 | ||
783 | priv->stations[sta_id].sta.key.key_flags = key_flags; | ||
784 | priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; | 785 | priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; |
785 | 786 | ||
786 | for (i = 0; i < 5; i++) | 787 | for (i = 0; i < 5; i++) |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 617c4235d971..4cce66133500 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -1694,7 +1694,6 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
1694 | rxq->free_count = 0; | 1694 | rxq->free_count = 0; |
1695 | spin_unlock_irqrestore(&rxq->lock, flags); | 1695 | spin_unlock_irqrestore(&rxq->lock, flags); |
1696 | } | 1696 | } |
1697 | EXPORT_SYMBOL(iwl3945_rx_queue_reset); | ||
1698 | 1697 | ||
1699 | /* | 1698 | /* |
1700 | * this should be called while priv->lock is locked | 1699 | * this should be called while priv->lock is locked |
@@ -1745,7 +1744,6 @@ static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rx | |||
1745 | rxq->bd = NULL; | 1744 | rxq->bd = NULL; |
1746 | rxq->rb_stts = NULL; | 1745 | rxq->rb_stts = NULL; |
1747 | } | 1746 | } |
1748 | EXPORT_SYMBOL(iwl3945_rx_queue_free); | ||
1749 | 1747 | ||
1750 | 1748 | ||
1751 | /* Convert linear signal-to-noise ratio into dB */ | 1749 | /* Convert linear signal-to-noise ratio into dB */ |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index db91db776508..bebf735cd4bd 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -2558,6 +2558,11 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2558 | mutex_init(&priv->command_lock); | 2558 | mutex_init(&priv->command_lock); |
2559 | spin_lock_init(&priv->stats_lock); | 2559 | spin_lock_init(&priv->stats_lock); |
2560 | 2560 | ||
2561 | /* because rndis_command() sleeps we need to use workqueue */ | ||
2562 | priv->workqueue = create_singlethread_workqueue("rndis_wlan"); | ||
2563 | INIT_WORK(&priv->work, rndis_wext_worker); | ||
2564 | INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats); | ||
2565 | |||
2561 | /* try bind rndis_host */ | 2566 | /* try bind rndis_host */ |
2562 | retval = generic_rndis_bind(usbdev, intf, FLAG_RNDIS_PHYM_WIRELESS); | 2567 | retval = generic_rndis_bind(usbdev, intf, FLAG_RNDIS_PHYM_WIRELESS); |
2563 | if (retval < 0) | 2568 | if (retval < 0) |
@@ -2603,16 +2608,17 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2603 | disassociate(usbdev, 1); | 2608 | disassociate(usbdev, 1); |
2604 | netif_carrier_off(usbdev->net); | 2609 | netif_carrier_off(usbdev->net); |
2605 | 2610 | ||
2606 | /* because rndis_command() sleeps we need to use workqueue */ | ||
2607 | priv->workqueue = create_singlethread_workqueue("rndis_wlan"); | ||
2608 | INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats); | ||
2609 | queue_delayed_work(priv->workqueue, &priv->stats_work, | 2611 | queue_delayed_work(priv->workqueue, &priv->stats_work, |
2610 | round_jiffies_relative(STATS_UPDATE_JIFFIES)); | 2612 | round_jiffies_relative(STATS_UPDATE_JIFFIES)); |
2611 | INIT_WORK(&priv->work, rndis_wext_worker); | ||
2612 | 2613 | ||
2613 | return 0; | 2614 | return 0; |
2614 | 2615 | ||
2615 | fail: | 2616 | fail: |
2617 | cancel_delayed_work_sync(&priv->stats_work); | ||
2618 | cancel_work_sync(&priv->work); | ||
2619 | flush_workqueue(priv->workqueue); | ||
2620 | destroy_workqueue(priv->workqueue); | ||
2621 | |||
2616 | kfree(priv); | 2622 | kfree(priv); |
2617 | return retval; | 2623 | return retval; |
2618 | } | 2624 | } |
diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h index 9718f61809cf..edeff82a4d06 100644 --- a/drivers/net/wireless/rtl818x/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187.h | |||
@@ -120,6 +120,12 @@ struct rtl8187_priv { | |||
120 | __le64 buf; | 120 | __le64 buf; |
121 | struct sk_buff_head queue; | 121 | struct sk_buff_head queue; |
122 | } b_tx_status; /* This queue is used by both -b and non-b devices */ | 122 | } b_tx_status; /* This queue is used by both -b and non-b devices */ |
123 | struct mutex io_mutex; | ||
124 | union { | ||
125 | u8 bits8; | ||
126 | __le16 bits16; | ||
127 | __le32 bits32; | ||
128 | } *io_dmabuf; | ||
123 | }; | 129 | }; |
124 | 130 | ||
125 | void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); | 131 | void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); |
@@ -129,10 +135,14 @@ static inline u8 rtl818x_ioread8_idx(struct rtl8187_priv *priv, | |||
129 | { | 135 | { |
130 | u8 val; | 136 | u8 val; |
131 | 137 | ||
138 | mutex_lock(&priv->io_mutex); | ||
132 | usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), | 139 | usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), |
133 | RTL8187_REQ_GET_REG, RTL8187_REQT_READ, | 140 | RTL8187_REQ_GET_REG, RTL8187_REQT_READ, |
134 | (unsigned long)addr, idx & 0x03, &val, | 141 | (unsigned long)addr, idx & 0x03, |
135 | sizeof(val), HZ / 2); | 142 | &priv->io_dmabuf->bits8, sizeof(val), HZ / 2); |
143 | |||
144 | val = priv->io_dmabuf->bits8; | ||
145 | mutex_unlock(&priv->io_mutex); | ||
136 | 146 | ||
137 | return val; | 147 | return val; |
138 | } | 148 | } |
@@ -147,10 +157,14 @@ static inline u16 rtl818x_ioread16_idx(struct rtl8187_priv *priv, | |||
147 | { | 157 | { |
148 | __le16 val; | 158 | __le16 val; |
149 | 159 | ||
160 | mutex_lock(&priv->io_mutex); | ||
150 | usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), | 161 | usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), |
151 | RTL8187_REQ_GET_REG, RTL8187_REQT_READ, | 162 | RTL8187_REQ_GET_REG, RTL8187_REQT_READ, |
152 | (unsigned long)addr, idx & 0x03, &val, | 163 | (unsigned long)addr, idx & 0x03, |
153 | sizeof(val), HZ / 2); | 164 | &priv->io_dmabuf->bits16, sizeof(val), HZ / 2); |
165 | |||
166 | val = priv->io_dmabuf->bits16; | ||
167 | mutex_unlock(&priv->io_mutex); | ||
154 | 168 | ||
155 | return le16_to_cpu(val); | 169 | return le16_to_cpu(val); |
156 | } | 170 | } |
@@ -165,10 +179,14 @@ static inline u32 rtl818x_ioread32_idx(struct rtl8187_priv *priv, | |||
165 | { | 179 | { |
166 | __le32 val; | 180 | __le32 val; |
167 | 181 | ||
182 | mutex_lock(&priv->io_mutex); | ||
168 | usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), | 183 | usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), |
169 | RTL8187_REQ_GET_REG, RTL8187_REQT_READ, | 184 | RTL8187_REQ_GET_REG, RTL8187_REQT_READ, |
170 | (unsigned long)addr, idx & 0x03, &val, | 185 | (unsigned long)addr, idx & 0x03, |
171 | sizeof(val), HZ / 2); | 186 | &priv->io_dmabuf->bits32, sizeof(val), HZ / 2); |
187 | |||
188 | val = priv->io_dmabuf->bits32; | ||
189 | mutex_unlock(&priv->io_mutex); | ||
172 | 190 | ||
173 | return le32_to_cpu(val); | 191 | return le32_to_cpu(val); |
174 | } | 192 | } |
@@ -181,10 +199,15 @@ static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr) | |||
181 | static inline void rtl818x_iowrite8_idx(struct rtl8187_priv *priv, | 199 | static inline void rtl818x_iowrite8_idx(struct rtl8187_priv *priv, |
182 | u8 *addr, u8 val, u8 idx) | 200 | u8 *addr, u8 val, u8 idx) |
183 | { | 201 | { |
202 | mutex_lock(&priv->io_mutex); | ||
203 | |||
204 | priv->io_dmabuf->bits8 = val; | ||
184 | usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), | 205 | usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), |
185 | RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, | 206 | RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, |
186 | (unsigned long)addr, idx & 0x03, &val, | 207 | (unsigned long)addr, idx & 0x03, |
187 | sizeof(val), HZ / 2); | 208 | &priv->io_dmabuf->bits8, sizeof(val), HZ / 2); |
209 | |||
210 | mutex_unlock(&priv->io_mutex); | ||
188 | } | 211 | } |
189 | 212 | ||
190 | static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val) | 213 | static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val) |
@@ -195,12 +218,15 @@ static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val) | |||
195 | static inline void rtl818x_iowrite16_idx(struct rtl8187_priv *priv, | 218 | static inline void rtl818x_iowrite16_idx(struct rtl8187_priv *priv, |
196 | __le16 *addr, u16 val, u8 idx) | 219 | __le16 *addr, u16 val, u8 idx) |
197 | { | 220 | { |
198 | __le16 buf = cpu_to_le16(val); | 221 | mutex_lock(&priv->io_mutex); |
199 | 222 | ||
223 | priv->io_dmabuf->bits16 = cpu_to_le16(val); | ||
200 | usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), | 224 | usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), |
201 | RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, | 225 | RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, |
202 | (unsigned long)addr, idx & 0x03, &buf, sizeof(buf), | 226 | (unsigned long)addr, idx & 0x03, |
203 | HZ / 2); | 227 | &priv->io_dmabuf->bits16, sizeof(val), HZ / 2); |
228 | |||
229 | mutex_unlock(&priv->io_mutex); | ||
204 | } | 230 | } |
205 | 231 | ||
206 | static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr, | 232 | static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr, |
@@ -212,12 +238,15 @@ static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr, | |||
212 | static inline void rtl818x_iowrite32_idx(struct rtl8187_priv *priv, | 238 | static inline void rtl818x_iowrite32_idx(struct rtl8187_priv *priv, |
213 | __le32 *addr, u32 val, u8 idx) | 239 | __le32 *addr, u32 val, u8 idx) |
214 | { | 240 | { |
215 | __le32 buf = cpu_to_le32(val); | 241 | mutex_lock(&priv->io_mutex); |
216 | 242 | ||
243 | priv->io_dmabuf->bits32 = cpu_to_le32(val); | ||
217 | usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), | 244 | usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), |
218 | RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, | 245 | RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, |
219 | (unsigned long)addr, idx & 0x03, &buf, sizeof(buf), | 246 | (unsigned long)addr, idx & 0x03, |
220 | HZ / 2); | 247 | &priv->io_dmabuf->bits32, sizeof(val), HZ / 2); |
248 | |||
249 | mutex_unlock(&priv->io_mutex); | ||
221 | } | 250 | } |
222 | 251 | ||
223 | static inline void rtl818x_iowrite32(struct rtl8187_priv *priv, __le32 *addr, | 252 | static inline void rtl818x_iowrite32(struct rtl8187_priv *priv, __le32 *addr, |
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index fd81884b9c7d..bac6cfba6abd 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c | |||
@@ -1329,6 +1329,14 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1329 | priv = dev->priv; | 1329 | priv = dev->priv; |
1330 | priv->is_rtl8187b = (id->driver_info == DEVICE_RTL8187B); | 1330 | priv->is_rtl8187b = (id->driver_info == DEVICE_RTL8187B); |
1331 | 1331 | ||
1332 | /* allocate "DMA aware" buffer for register accesses */ | ||
1333 | priv->io_dmabuf = kmalloc(sizeof(*priv->io_dmabuf), GFP_KERNEL); | ||
1334 | if (!priv->io_dmabuf) { | ||
1335 | err = -ENOMEM; | ||
1336 | goto err_free_dev; | ||
1337 | } | ||
1338 | mutex_init(&priv->io_mutex); | ||
1339 | |||
1332 | SET_IEEE80211_DEV(dev, &intf->dev); | 1340 | SET_IEEE80211_DEV(dev, &intf->dev); |
1333 | usb_set_intfdata(intf, dev); | 1341 | usb_set_intfdata(intf, dev); |
1334 | priv->udev = udev; | 1342 | priv->udev = udev; |
@@ -1495,7 +1503,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1495 | err = ieee80211_register_hw(dev); | 1503 | err = ieee80211_register_hw(dev); |
1496 | if (err) { | 1504 | if (err) { |
1497 | printk(KERN_ERR "rtl8187: Cannot register device\n"); | 1505 | printk(KERN_ERR "rtl8187: Cannot register device\n"); |
1498 | goto err_free_dev; | 1506 | goto err_free_dmabuf; |
1499 | } | 1507 | } |
1500 | mutex_init(&priv->conf_mutex); | 1508 | mutex_init(&priv->conf_mutex); |
1501 | skb_queue_head_init(&priv->b_tx_status.queue); | 1509 | skb_queue_head_init(&priv->b_tx_status.queue); |
@@ -1506,6 +1514,8 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1506 | 1514 | ||
1507 | return 0; | 1515 | return 0; |
1508 | 1516 | ||
1517 | err_free_dmabuf: | ||
1518 | kfree(priv->io_dmabuf); | ||
1509 | err_free_dev: | 1519 | err_free_dev: |
1510 | ieee80211_free_hw(dev); | 1520 | ieee80211_free_hw(dev); |
1511 | usb_set_intfdata(intf, NULL); | 1521 | usb_set_intfdata(intf, NULL); |
@@ -1526,6 +1536,7 @@ static void __devexit rtl8187_disconnect(struct usb_interface *intf) | |||
1526 | priv = dev->priv; | 1536 | priv = dev->priv; |
1527 | usb_reset_device(priv->udev); | 1537 | usb_reset_device(priv->udev); |
1528 | usb_put_dev(interface_to_usbdev(intf)); | 1538 | usb_put_dev(interface_to_usbdev(intf)); |
1539 | kfree(priv->io_dmabuf); | ||
1529 | ieee80211_free_hw(dev); | 1540 | ieee80211_free_hw(dev); |
1530 | } | 1541 | } |
1531 | 1542 | ||
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c index 78df281b297a..a09819386a1e 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c +++ b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c | |||
@@ -88,9 +88,15 @@ static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data) | |||
88 | rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); | 88 | rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); |
89 | udelay(10); | 89 | udelay(10); |
90 | 90 | ||
91 | mutex_lock(&priv->io_mutex); | ||
92 | |||
93 | priv->io_dmabuf->bits16 = data; | ||
91 | usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), | 94 | usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), |
92 | RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, | 95 | RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, |
93 | addr, 0x8225, &data, sizeof(data), HZ / 2); | 96 | addr, 0x8225, &priv->io_dmabuf->bits16, sizeof(data), |
97 | HZ / 2); | ||
98 | |||
99 | mutex_unlock(&priv->io_mutex); | ||
94 | 100 | ||
95 | rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); | 101 | rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); |
96 | udelay(10); | 102 | udelay(10); |