diff options
Diffstat (limited to 'drivers/net')
88 files changed, 948 insertions, 878 deletions
diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index 7d253686ed0..5ba4bab6d43 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -485,9 +485,7 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev) printk(KERN_DEBUG "%s: burped during tx load.\n", dev->name); spin_lock_irqsave(&lp->lock, flags); - } - while (1); - + } while (1); } /** @@ -612,7 +610,8 @@ static irqreturn_t el_interrupt(int irq, void *dev_id) dev->stats.tx_packets++; if (el_debug > 6) printk(KERN_DEBUG " Tx succeeded %s\n", - (txsr & TX_RDY) ? "." : "but tx is busy!"); + (txsr & TX_RDY) ? "." : + "but tx is busy!"); /* * This is safe the interrupt is atomic WRT itself. */ @@ -693,7 +692,8 @@ static void el_receive(struct net_device *dev) if (pkt_len < 60 || pkt_len > 1536) { if (el_debug) - printk(KERN_DEBUG "%s: bogus packet, length=%d\n", dev->name, pkt_len); + printk(KERN_DEBUG "%s: bogus packet, length=%d\n", + dev->name, pkt_len); dev->stats.rx_over_errors++; return; } @@ -711,7 +711,8 @@ static void el_receive(struct net_device *dev) outw(0x00, GP_LOW); if (skb == NULL) { - printk(KERN_INFO "%s: Memory squeeze, dropping packet.\n", dev->name); + printk(KERN_INFO "%s: Memory squeeze, dropping packet.\n", + dev->name); dev->stats.rx_dropped++; return; } else { @@ -748,7 +749,8 @@ static void el_reset(struct net_device *dev) if (el_debug > 2) printk(KERN_INFO "3c501 reset..."); outb(AX_RESET, AX_CMD); /* Reset the chip */ - outb(AX_LOOP, AX_CMD); /* Aux control, irq and loopback enabled */ + /* Aux control, irq and loopback enabled */ + outb(AX_LOOP, AX_CMD); { int i; for (i = 0; i < 6; i++) /* Set the station address. */ diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a0f0e605d63..fe7b5ec0970 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2366,15 +2366,15 @@ config GELIC_NET module will be called ps3_gelic. config GELIC_WIRELESS - bool "PS3 Wireless support" - depends on GELIC_NET - select WIRELESS_EXT - help - This option adds the support for the wireless feature of PS3. - If you have the wireless-less model of PS3 or have no plan to - use wireless feature, disabling this option saves memory. As - the driver automatically distinguishes the models, you can - safely enable this option even if you have a wireless-less model. + bool "PS3 Wireless support" + depends on GELIC_NET + select WIRELESS_EXT + help + This option adds the support for the wireless feature of PS3. + If you have the wireless-less model of PS3 or have no plan to + use wireless feature, disabling this option saves memory. As + the driver automatically distinguishes the models, you can + safely enable this option even if you have a wireless-less model. config GIANFAR tristate "Gianfar Ethernet" @@ -2519,7 +2519,7 @@ config CHELSIO_T3 config EHEA tristate "eHEA Ethernet support" - depends on IBMEBUS && INET + depends on IBMEBUS && INET && SPARSEMEM select INET_LRO ---help--- This driver supports the IBM pSeries eHEA ethernet adapter. diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c index 5136d94923a..b1448637107 100644 --- a/drivers/net/ac3200.c +++ b/drivers/net/ac3200.c @@ -369,7 +369,7 @@ MODULE_PARM_DESC(mem, "Memory base address(es)"); MODULE_DESCRIPTION("Ansel AC3200 EISA ethernet driver"); MODULE_LICENSE("GPL"); -int __init init_module(void) +static int __init ac3200_module_init(void) { struct net_device *dev; int this_dev, found = 0; @@ -404,8 +404,7 @@ static void cleanup_card(struct net_device *dev) iounmap(ei_status.mem); } -void __exit -cleanup_module(void) +static void __exit ac3200_module_exit(void) { int this_dev; @@ -418,4 +417,6 @@ cleanup_module(void) } } } +module_init(ac3200_module_init); +module_exit(ac3200_module_exit); #endif /* MODULE */ diff --git a/drivers/net/apne.c b/drivers/net/apne.c index c12cbdf368b..47a8275d396 100644 --- a/drivers/net/apne.c +++ b/drivers/net/apne.c @@ -569,7 +569,7 @@ static irqreturn_t apne_interrupt(int irq, void *dev_id) #ifdef MODULE static struct net_device *apne_dev; -int __init init_module(void) +static int __init apne_module_init(void) { apne_dev = apne_probe(-1); if (IS_ERR(apne_dev)) @@ -577,7 +577,7 @@ int __init init_module(void) return 0; } -void __exit cleanup_module(void) +static void __exit apne_module_exit(void) { unregister_netdev(apne_dev); @@ -591,7 +591,8 @@ void __exit cleanup_module(void) free_netdev(apne_dev); } - +module_init(apne_module_init); +module_exit(apne_module_exit); #endif static int init_pcmcia(void) diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c index 6ab2c2d4d67..fef5560bc7a 100644 --- a/drivers/net/appletalk/ltpc.c +++ b/drivers/net/appletalk/ltpc.c @@ -1252,7 +1252,7 @@ module_param(irq, int, 0); module_param(dma, int, 0); -int __init init_module(void) +static int __init ltpc_module_init(void) { if(io == 0) printk(KERN_NOTICE @@ -1263,6 +1263,7 @@ int __init init_module(void) return PTR_ERR(dev_ltpc); return 0; } +module_init(ltpc_module_init); #endif static void __exit ltpc_cleanup(void) diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c index cc4610db639..02cb8f1c114 100644 --- a/drivers/net/arcnet/capmode.c +++ b/drivers/net/arcnet/capmode.c @@ -80,17 +80,19 @@ void arcnet_cap_init(void) #ifdef MODULE -int __init init_module(void) +static int __init capmode_module_init(void) { printk(VERSION); arcnet_cap_init(); return 0; } -void cleanup_module(void) +static void __exit capmode_module_exit(void) { arcnet_unregister_proto(&capmode_proto); } +module_init(capmode_module_init); +module_exit(capmode_module_exit); MODULE_LICENSE("GPL"); #endif /* MODULE */ diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index b74dbeef805..13c293b286d 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c @@ -336,8 +336,6 @@ struct lance_addr { /***************************** Prototypes *****************************/ -static int addr_accessible( volatile void *regp, int wordflag, int - writeflag ); static unsigned long lance_probe1( struct net_device *dev, struct lance_addr *init_rec ); static int lance_open( struct net_device *dev ); @@ -406,7 +404,8 @@ struct net_device * __init atarilance_probe(int unit) /* Derived from hwreg_present() in atari/config.c: */ -static int __init addr_accessible( volatile void *regp, int wordflag, int writeflag ) +static noinline int __init addr_accessible(volatile void *regp, int wordflag, + int writeflag) { int ret; long flags; diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c index 9200ee59d85..129b8b3aa77 100644 --- a/drivers/net/atl1/atl1_main.c +++ b/drivers/net/atl1/atl1_main.c @@ -1765,15 +1765,12 @@ static irqreturn_t atl1_intr(int irq, void *data) { struct atl1_adapter *adapter = netdev_priv(data); u32 status; - u8 update_rx; int max_ints = 10; status = adapter->cmb.cmb->int_stats; if (!status) return IRQ_NONE; - update_rx = 0; - do { /* clear CMB interrupt status at once */ adapter->cmb.cmb->int_stats = 0; diff --git a/drivers/net/b44.c b/drivers/net/b44.c index ea2a2b548e3..25f1337cd02 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -2082,6 +2082,11 @@ static int __devinit b44_get_invariants(struct b44 *bp) addr = sdev->bus->sprom.et0mac; bp->phy_addr = sdev->bus->sprom.et0phyaddr; } + /* Some ROMs have buggy PHY addresses with the high + * bits set (sign extension?). Truncate them to a + * valid PHY address. */ + bp->phy_addr &= 0x1F; + memcpy(bp->dev->dev_addr, addr, 6); if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){ diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index 8af142ccf37..de32b3fba32 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c @@ -63,8 +63,8 @@ #include "bnx2x.h" #include "bnx2x_init.h" -#define DRV_MODULE_VERSION "1.40.22" -#define DRV_MODULE_RELDATE "2007/11/27" +#define DRV_MODULE_VERSION "1.42.3" +#define DRV_MODULE_RELDATE "2008/3/9" #define BNX2X_BC_VER 0x040200 /* Time in jiffies before concluding the transmitter is hung. */ @@ -8008,38 +8008,6 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver, cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt); - switch (cmd->port) { - case PORT_TP: - if (!(bp->supported & SUPPORTED_TP)) { - DP(NETIF_MSG_LINK, "TP not supported\n"); - return -EINVAL; - } - - if (bp->phy_flags & PHY_XGXS_FLAG) { - bnx2x_link_reset(bp); - bnx2x_link_settings_supported(bp, SWITCH_CFG_1G); - bnx2x_phy_deassert(bp); - } - break; - - case PORT_FIBRE: - if (!(bp->supported & SUPPORTED_FIBRE)) { - DP(NETIF_MSG_LINK, "FIBRE not supported\n"); - return -EINVAL; - } - - if (!(bp->phy_flags & PHY_XGXS_FLAG)) { - bnx2x_link_reset(bp); - bnx2x_link_settings_supported(bp, SWITCH_CFG_10G); - bnx2x_phy_deassert(bp); - } - break; - - default: - DP(NETIF_MSG_LINK, "Unknown port type\n"); - return -EINVAL; - } - if (cmd->autoneg == AUTONEG_ENABLE) { if (!(bp->supported & SUPPORTED_Autoneg)) { DP(NETIF_MSG_LINK, "Aotoneg not supported\n"); diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index cb3c6faa788..d16e0e1d2b3 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -310,7 +310,7 @@ static inline int __check_agg_selection_timer(struct port *port) */ static inline void __get_rx_machine_lock(struct port *port) { - spin_lock(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); + spin_lock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); } /** @@ -320,7 +320,7 @@ static inline void __get_rx_machine_lock(struct port *port) */ static inline void __release_rx_machine_lock(struct port *port) { - spin_unlock(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); + spin_unlock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); } /** diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index b57bc9467db..3f58c3d0b71 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -678,12 +678,8 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon } if (!list_empty(&bond->vlan_list)) { - unsigned short vlan_id; - int res = vlan_get_tag(skb, &vlan_id); - if (!res) { + if (!vlan_get_tag(skb, &client_info->vlan_id)) client_info->tag = 1; - client_info->vlan_id = vlan_id; - } } if (!client_info->assigned) { diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 0942d82f7cb..0f0675319e9 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -383,7 +383,7 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr) */ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev) { - unsigned short vlan_id; + unsigned short uninitialized_var(vlan_id); if (!list_empty(&bond->vlan_list) && !(slave_dev->features & NETIF_F_HW_VLAN_TX) && @@ -4528,8 +4528,7 @@ static void bond_free_all(void) netif_tx_unlock_bh(bond_dev); /* Release the bonded slaves */ bond_release_all(bond_dev); - bond_deinit(bond_dev); - unregister_netdevice(bond_dev); + bond_destroy(bond); } #ifdef CONFIG_PROC_FS diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 67ccad69d44..a3c74e20aa5 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -22,8 +22,8 @@ #include "bond_3ad.h" #include "bond_alb.h" -#define DRV_VERSION "3.2.4" -#define DRV_RELDATE "January 28, 2008" +#define DRV_VERSION "3.2.5" +#define DRV_RELDATE "March 21, 2008" #define DRV_NAME "bonding" #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 979f3fc5e76..98a6bbd11d4 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -557,9 +557,9 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q) for (i = 0; i < SGE_RXQ_PER_SET; ++i) if (q->fl[i].desc) { - spin_lock(&adapter->sge.reg_lock); + spin_lock_irq(&adapter->sge.reg_lock); t3_sge_disable_fl(adapter, q->fl[i].cntxt_id); - spin_unlock(&adapter->sge.reg_lock); + spin_unlock_irq(&adapter->sge.reg_lock); free_rx_bufs(pdev, &q->fl[i]); kfree(q->fl[i].sdesc); dma_free_coherent(&pdev->dev, @@ -570,9 +570,9 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q) for (i = 0; i < SGE_TXQ_PER_SET; ++i) if (q->txq[i].desc) { - spin_lock(&adapter->sge.reg_lock); + spin_lock_irq(&adapter->sge.reg_lock); t3_sge_enable_ecntxt(adapter, q->txq[i].cntxt_id, 0); - spin_unlock(&adapter->sge.reg_lock); + spin_unlock_irq(&adapter->sge.reg_lock); if (q->txq[i].sdesc) { free_tx_desc(adapter, &q->txq[i], q->txq[i].in_use); @@ -586,9 +586,9 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q) } if (q->rspq.desc) { - spin_lock(&adapter->sge.reg_lock); + spin_lock_irq(&adapter->sge.reg_lock); t3_sge_disable_rspcntxt(adapter, q->rspq.cntxt_id); - spin_unlock(&adapter->sge.reg_lock); + spin_unlock_irq(&adapter->sge.reg_lock); dma_free_coherent(&pdev->dev, q->rspq.size * sizeof(struct rsp_desc), q->rspq.desc, q->rspq.phys_addr); @@ -1107,9 +1107,15 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) } q->in_use += ndesc; - if (unlikely(credits - ndesc < q->stop_thres)) - if (USE_GTS || !should_restart_tx(q)) - t3_stop_queue(dev, qs, q); + if (unlikely(credits - ndesc < q->stop_thres)) { + t3_stop_queue(dev, qs, q); + + if (should_restart_tx(q) && + test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) { + q->restarts++; + netif_wake_queue(dev); + } + } gen = q->gen; q->unacked += ndesc; @@ -2661,7 +2667,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports, (16 * 1024) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) : MAX_FRAME_SIZE + 2 + sizeof(struct cpl_rx_pkt); - spin_lock(&adapter->sge.reg_lock); + spin_lock_irq(&adapter->sge.reg_lock); /* FL threshold comparison uses < */ ret = t3_sge_init_rspcntxt(adapter, q->rspq.cntxt_id, irq_vec_idx, @@ -2705,7 +2711,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports, goto err_unlock; } - spin_unlock(&adapter->sge.reg_lock); + spin_unlock_irq(&adapter->sge.reg_lock); q->adap = adapter; q->netdev = dev; @@ -2722,7 +2728,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports, return 0; err_unlock: - spin_unlock(&adapter->sge.reg_lock); + spin_unlock_irq(&adapter->sge.reg_lock); err: t3_free_qset(adapter, q); return ret; diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 1fe305ca2cf..b09a53de1c5 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -798,8 +798,6 @@ dm9000_init_dm9000(struct net_device *dev) /* Set address filter table */ dm9000_hash_table(dev); - /* Activate DM9000 */ - iow(db, DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); /* Enable TX/RX interrupt mask */ iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM); @@ -1197,6 +1195,7 @@ dm9000_hash_table(struct net_device *dev) int i, oft; u32 hash_val; u16 hash_table[4]; + u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN; unsigned long flags; dm9000_dbg(db, 1, "entering %s\n", __func__); @@ -1213,6 +1212,12 @@ dm9000_hash_table(struct net_device *dev) /* broadcast address */ hash_table[3] = 0x8000; + if (dev->flags & IFF_PROMISC) + rcr |= RCR_PRMSC; + + if (dev->flags & IFF_ALLMULTI) + rcr |= RCR_ALL; + /* the multicast address in Hash Table : 64 bits */ for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { hash_val = ether_crc_le(6, mcptr->dmi_addr) & 0x3f; @@ -1225,6 +1230,7 @@ dm9000_hash_table(struct net_device *dev) iow(db, oft++, hash_table[i] >> 8); } + iow(db, DM9000_RCR, rcr); spin_unlock_irqrestore(&db->lock, flags); } diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 36ba6dc96ac..2d139ec7977 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -960,7 +960,7 @@ static void e100_get_defaults(struct nic *nic) /* Template for a freshly allocated RFD */ nic->blank_rfd.command = 0; - nic->blank_rfd.rbd = 0xFFFFFFFF; + nic->blank_rfd.rbd = cpu_to_le32(0xFFFFFFFF); nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN); /* MII setup */ @@ -2782,16 +2782,13 @@ static void __devexit e100_remove(struct pci_dev *pdev) } } -#ifdef CONFIG_PM static int e100_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); if (netif_running(netdev)) - napi_disable(&nic->napi); - del_timer_sync(&nic->watchdog); - netif_carrier_off(nic->netdev); + e100_down(nic); netif_device_detach(netdev); pci_save_state(pdev); @@ -2804,14 +2801,13 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state) pci_enable_wake(pdev, PCI_D3cold, 0); } - free_irq(pdev->irq, netdev); - pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3hot); return 0; } +#ifdef CONFIG_PM static int e100_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); @@ -2832,26 +2828,7 @@ static int e100_resume(struct pci_dev *pdev) static void e100_shutdown(struct pci_dev *pdev) { - struct net_device *netdev = pci_get_drvdata(pdev); - struct nic *nic = netdev_priv(netdev); - - if (netif_running(netdev)) - napi_disable(&nic->napi); - del_timer_sync(&nic->watchdog); - netif_carrier_off(nic->netdev); - - if ((nic->flags & wol_magic) | e100_asf(nic)) { - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); - } else { - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); - } - - free_irq(pdev->irq, netdev); - - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); + e100_suspend(pdev, PMSG_SUSPEND); } /* ------------------ PCI Error Recovery infrastructure -------------- */ diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 7c4ead35cfa..93b7fb24696 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -40,7 +40,7 @@ #include <asm/io.h> #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0087" +#define DRV_VERSION "EHEA_0089" /* eHEA capability flags */ #define DLPAR_PORT_ADD_REM 1 diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 21af674b764..07c742dd3f0 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -3108,7 +3108,7 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, dev->vlan_rx_add_vid = ehea_vlan_rx_add_vid; dev->vlan_rx_kill_vid = ehea_vlan_rx_kill_vid; dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO - | NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_TX + | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER | NETIF_F_LLTX; dev->tx_timeout = &ehea_tx_watchdog; diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index 0809a6a5a28..46a90e9ec56 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c @@ -900,7 +900,7 @@ static void enc28j60_hw_rx(struct net_device *ndev) if (RSV_GETBIT(rxstat, RSV_LENCHECKERR)) ndev->stats.rx_frame_errors++; } else { - skb = dev_alloc_skb(len); + skb = dev_alloc_skb(len + NET_IP_ALIGN); if (!skb) { if (netif_msg_rx_err(priv)) dev_err(&ndev->dev, @@ -908,6 +908,7 @@ static void enc28j60_hw_rx(struct net_device *ndev) ndev->stats.rx_dropped++; } else { skb->dev = ndev; + skb_reserve(skb, NET_IP_ALIGN); /* copy the packet from the receive buffer */ enc28j60_mem_read(priv, priv->next_pk_ptr + sizeof(rsv), len, skb_put(skb, len)); diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 0b365b8d947..76118ddd104 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -131,8 +131,8 @@ IIIa. Ring buffers IVb. References -http://www.smsc.com/main/datasheets/83c171.pdf -http://www.smsc.com/main/datasheets/83c175.pdf +http://www.smsc.com/main/tools/discontinued/83c171.pdf +http://www.smsc.com/main/tools/discontinued/83c175.pdf http://scyld.com/expert/NWay.html http://www.national.com/pf/DP/DP83840A.html @@ -227,7 +227,12 @@ static const u16 media2miictl[16] = { 0, 0x0C00, 0x0C00, 0x2000, 0x0100, 0x2100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -/* The EPIC100 Rx and Tx buffer descriptors. */ +/* + * The EPIC100 Rx and Tx buffer descriptors. Note that these + * really ARE host-endian; it's not a misannotation. We tell + * the card to byteswap them internally on big-endian hosts - + * look for #ifdef CONFIG_BIG_ENDIAN in epic_open(). + */ struct epic_tx_desc { u32 txstatus; @@ -418,7 +423,7 @@ static int __devinit epic_init_one (struct pci_dev *pdev, /* Note: the '175 does not have a serial EEPROM. */ for (i = 0; i < 3; i++) - ((u16 *)dev->dev_addr)[i] = le16_to_cpu(inw(ioaddr + LAN0 + i*4)); + ((__le16 *)dev->dev_addr)[i] = cpu_to_le16(inw(ioaddr + LAN0 + i*4)); if (debug > 2) { dev_printk(KERN_DEBUG, &pdev->dev, "EEPROM contents:\n"); @@ -682,7 +687,8 @@ static int epic_open(struct net_device *dev) if (ep->chip_flags & MII_PWRDWN) outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL); -#if defined(__powerpc__) || defined(__sparc__) /* Big endian */ + /* Tell the chip to byteswap descriptors on big-endian hosts */ +#ifdef CONFIG_BIG_ENDIAN outl(0x4432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); inl(ioaddr + GENCTL); outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); @@ -695,7 +701,7 @@ static int epic_open(struct net_device *dev) udelay(20); /* Looks like EPII needs that if you want reliable RX init. FIXME: pci posting bug? */ for (i = 0; i < 3; i++) - outl(cpu_to_le16(((u16*)dev->dev_addr)[i]), ioaddr + LAN0 + i*4); + outl(le16_to_cpu(((__le16*)dev->dev_addr)[i]), ioaddr + LAN0 + i*4); ep->tx_threshold = TX_FIFO_THRESH; outl(ep->tx_threshold, ioaddr + TxThresh); @@ -798,7 +804,7 @@ static void epic_restart(struct net_device *dev) for (i = 16; i > 0; i--) outl(0x0008, ioaddr + TEST1); -#if defined(__powerpc__) || defined(__sparc__) /* Big endian */ +#ifdef CONFIG_BIG_ENDIAN outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); #else outl(0x0412 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); @@ -808,7 +814,7 @@ static void epic_restart(struct net_device *dev) outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL); for (i = 0; i < 3; i++) - outl(cpu_to_le16(((u16*)dev->dev_addr)[i]), ioaddr + LAN0 + i*4); + outl(le16_to_cpu(((__le16*)dev->dev_addr)[i]), ioaddr + LAN0 + i*4); ep->tx_threshold = TX_FIFO_THRESH; outl(ep->tx_threshold, ioaddr + TxThresh); @@ -919,7 +925,7 @@ static void epic_init_ring(struct net_device *dev) /* Initialize all Rx descriptors. */ for (i = 0; i < RX_RING_SIZE; i++) { ep->rx_ring[i].rxstatus = 0; - ep->rx_ring[i].buflength = cpu_to_le32(ep->rx_buf_sz); + ep->rx_ring[i].buflength = ep->rx_buf_sz; ep->rx_ring[i].next = ep->rx_ring_dma + (i+1)*sizeof(struct epic_rx_desc); ep->rx_skbuff[i] = NULL; @@ -936,7 +942,7 @@ static void epic_init_ring(struct net_device *dev) skb_reserve(skb, 2); /* 16 byte align the IP header. */ ep->rx_ring[i].bufaddr = pci_map_single(ep->pci_dev, skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); - ep->rx_ring[i].rxstatus = cpu_to_le32(DescOwn); + ep->rx_ring[i].rxstatus = DescOwn; } ep->dirty_rx = (unsigned int)(i - RX_RING_SIZE); @@ -974,20 +980,20 @@ static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev) ep->tx_ring[entry].bufaddr = pci_map_single(ep->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE); if (free_count < TX_QUEUE_LEN/2) {/* Typical path */ - ctrl_word = cpu_to_le32(0x100000); /* No interrupt */ + ctrl_word = 0x100000; /* No interrupt */ } else if (free_count == TX_QUEUE_LEN/2) { - ctrl_word = cpu_to_le32(0x140000); /* Tx-done intr. */ + ctrl_word = 0x140000; /* Tx-done intr. */ } else if (free_count < TX_QUEUE_LEN - 1) { - ctrl_word = cpu_to_le32(0x100000); /* No Tx-done intr. */ + ctrl_word = 0x100000; /* No Tx-done intr. */ } else { /* Leave room for an additional entry. */ - ctrl_word = cpu_to_le32(0x140000); /* Tx-done intr. */ + ctrl_word = 0x140000; /* Tx-done intr. */ ep->tx_full = 1; } - ep->tx_ring[entry].buflength = ctrl_word | cpu_to_le32(skb->len); + ep->tx_ring[entry].buflength = ctrl_word | skb->len; ep->tx_ring[entry].txstatus = ((skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN) << 16) - | cpu_to_le32(DescOwn); + | DescOwn; ep->cur_tx++; if (ep->tx_full) @@ -1041,7 +1047,7 @@ static void epic_tx(struct net_device *dev, struct epic_private *ep) for (dirty_tx = ep->dirty_tx; cur_tx - dirty_tx > 0; dirty_tx++) { struct sk_buff *skb; int entry = dirty_tx % TX_RING_SIZE; - int txstatus = le32_to_cpu(ep->tx_ring[entry].txstatus); + int txstatus = ep->tx_ring[entry].txstatus; if (txstatus & DescOwn) break; /* It still hasn't been Txed */ @@ -1163,8 +1169,8 @@ static int epic_rx(struct net_device *dev, int budget) rx_work_limit = budget; /* If we own the next entry, it's a new packet. Send it up. */ - while ((ep->rx_ring[entry].rxstatus & cpu_to_le32(DescOwn)) == 0) { - int status = le32_to_cpu(ep->rx_ring[entry].rxstatus); + while ((ep->rx_ring[entry].rxstatus & DescOwn) == 0) { + int status = ep->rx_ring[entry].rxstatus; if (debug > 4) printk(KERN_DEBUG " epic_rx() status was %8.8x.\n", status); @@ -1238,7 +1244,8 @@ static int epic_rx(struct net_device *dev, int budget) skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); work_done++; } - ep->rx_ring[entry].rxstatus = cpu_to_le32(DescOwn); + /* AV: shouldn't we add a barrier here? */ + ep->rx_ring[entry].rxstatus = DescOwn; } return work_done; } diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 0fbf1bbbaee..d7a3ea88edd 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1253,7 +1253,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev) /* Setup interrupt handlers. */ for (idp = id; idp->name; idp++) { - if (request_irq(idp->irq, idp->handler, 0, idp->name, dev) != 0) + if (request_irq(idp->irq, idp->handler, IRQF_DISABLED, idp->name, dev) != 0) printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, idp->irq); } @@ -1382,7 +1382,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev) /* Setup interrupt handlers. */ for (idp = id; idp->name; idp++) { - if (request_irq(b+idp->irq, fec_enet_interrupt, 0, idp->name, dev) != 0) + if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name, dev) != 0) printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq); } @@ -1553,7 +1553,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev) /* Setup interrupt handlers. */ for (idp = id; idp->name; idp++) { - if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0) + if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name,dev) != 0) printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq); } @@ -1680,7 +1680,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev) /* Setup interrupt handlers. */ for (idp = id; idp->name; idp++) { - if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0) + if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name,dev) != 0) printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq); } diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c index 1837584c450..6a3ac4ea97e 100644 --- a/drivers/net/fec_mpc52xx_phy.c +++ b/drivers/net/fec_mpc52xx_phy.c @@ -109,7 +109,8 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_i int irq = irq_of_parse_and_map(child, 0); if (irq != NO_IRQ) { const u32 *id = of_get_property(child, "reg", NULL); - bus->irq[*id] = irq; + if (id) + bus->irq[*id] = irq; } } diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 801b4d9cd97..6f7e3fde9e7 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -184,6 +184,7 @@ #define DEV_HAS_PAUSEFRAME_TX_V1 0x08000 /* device supports tx pause frames version 1 */ #define DEV_HAS_PAUSEFRAME_TX_V2 0x10000 /* device supports tx pause frames version 2 */ #define DEV_HAS_PAUSEFRAME_TX_V3 0x20000 /* device supports tx pause frames version 3 */ +#define DEV_NEED_TX_LIMIT 0x40000 /* device needs to limit tx */ enum { NvRegIrqStatus = 0x000, @@ -635,6 +636,8 @@ union ring_type { #define NV_RESTART_TX 0x1 #define NV_RESTART_RX 0x2 +#define NV_TX_LIMIT_COUNT 16 + /* statistics */ struct nv_ethtool_str { char name[ETH_GSTRING_LEN]; @@ -743,6 +746,8 @@ struct nv_skb_map { struct sk_buff *skb; dma_addr_t dma; unsigned int dma_len; + struct ring_desc_ex *first_tx_desc; + struct nv_skb_map *next_tx_ctx; }; /* @@ -827,6 +832,10 @@ struct fe_priv { union ring_type tx_ring; u32 tx_flags; int tx_ring_size; + int tx_limit; + u32 tx_pkts_in_progress; + struct nv_skb_map *tx_change_owner; + struct nv_skb_map *tx_end_flip; int tx_stop; /* vlan fields */ @@ -1707,6 +1716,9 @@ static void nv_init_tx(struct net_device *dev) np->last_tx.ex = &np->tx_ring.ex[np->tx_ring_size-1]; np->get_tx_ctx = np->put_tx_ctx = np->first_tx_ctx = np->tx_skb; np->last_tx_ctx = &np->tx_skb[np->tx_ring_size-1]; + np->tx_pkts_in_progress = 0; + np->tx_change_owner = NULL; + np->tx_end_flip = NULL; for (i = 0; i < np->tx_ring_size; i++) { if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { @@ -1720,6 +1732,9 @@ static void nv_init_tx(struct net_device *dev) } np->tx_skb[i].skb = NULL; np->tx_skb[i].dma = 0; + np->tx_skb[i].dma_len = 0; + np->tx_skb[i].first_tx_desc = NULL; + np->tx_skb[i].next_tx_ctx = NULL; } } @@ -1771,7 +1786,14 @@ static void nv_drain_tx(struct net_device *dev) } if (nv_release_txskb(dev, &np->tx_skb[i])) dev->stats.tx_dropped++; + np->tx_skb[i].dma = 0; + np->tx_skb[i].dma_len = 0; + np->tx_skb[i].first_tx_desc = NULL; + np->tx_skb[i].next_tx_ctx = NULL; } + np->tx_pkts_in_progress = 0; + np->tx_change_owner = NULL; + np->tx_end_flip = NULL; } static void nv_drain_rx(struct net_device *dev) @@ -1948,6 +1970,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) struct ring_desc_ex* start_tx; struct ring_desc_ex* prev_tx; struct nv_skb_map* prev_tx_ctx; + struct nv_skb_map* start_tx_ctx; /* add fragments to entries count */ for (i = 0; i < fragments; i++) { @@ -1965,6 +1988,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) } start_tx = put_tx = np->put_tx.ex; + start_tx_ctx = np->put_tx_ctx; /* setup the header buffer */ do { @@ -2037,6 +2061,26 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) spin_lock_irq(&np->lock); + if (np->tx_limit) { + /* Limit the number of outstanding tx. Setup all fragments, but + * do not set the VALID bit on the first descriptor. Save a pointer + * to that descriptor and also for next skb_map element. + */ + + if (np->tx_pkts_in_progress == NV_TX_LIMIT_COUNT) { + if (!np->tx_change_owner) + np->tx_change_owner = start_tx_ctx; + + /* remove VALID bit */ + tx_flags &= ~NV_TX2_VALID; + start_tx_ctx->first_tx_desc = start_tx; + start_tx_ctx->next_tx_ctx = np->put_tx_ctx; + np->tx_end_flip = np->put_tx_ctx; + } else { + np->tx_pkts_in_progress++; + } + } + /* set tx flags */ start_tx->flaglen |= cpu_to_le32(tx_flags | tx_flags_extra); np->put_tx.ex = put_tx; @@ -2060,6 +2104,25 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } +static inline void nv_tx_flip_ownership(struct net_device *dev) +{ + struct fe_priv *np = netdev_priv(dev); + + np->tx_pkts_in_progress--; + if (np->tx_change_owner) { + __le32 flaglen = le32_to_cpu(np->tx_change_owner->first_tx_desc->flaglen); + flaglen |= NV_TX2_VALID; + np->tx_change_owner->first_tx_desc->flaglen = cpu_to_le32(flaglen); + np->tx_pkts_in_progress++; + + np->tx_change_owner = np->tx_change_owner->next_tx_ctx; + if (np->tx_change_owner == np->tx_end_flip) + np->tx_change_owner = NULL; + + writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); + } +} + /* * nv_tx_done: check for completed packets, release the skbs. * @@ -2147,6 +2210,10 @@ static void nv_tx_done_optimized(struct net_device *dev, int limit) dev->stats.tx_packets++; dev_kfree_skb_any(np->get_tx_ctx->skb); np->get_tx_ctx->skb = NULL; + + if (np->tx_limit) { + nv_tx_flip_ownership(dev); + } } if (unlikely(np->get_tx.ex++ == np->last_tx.ex)) np->get_tx.ex = np->first_tx.ex; @@ -5333,6 +5400,21 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->need_linktimer = 0; } + /* Limit the number of tx's outstanding for hw bug */ + if (id->driver_data & DEV_NEED_TX_LIMIT) { + np->tx_limit = 1; + if ((id->device == PCI_DEVICE_ID_NVIDIA_NVENET_32 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_33 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_34 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_35 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_36 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_37 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_38 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_39) && + pci_dev->revision >= 0xA2) + np->tx_limit = 0; + } + /* clear phy state and temporarily halt phy interrupts */ writel(0, base + NvRegMIIMask); phystate = readl(base + NvRegAdapterControl); @@ -5563,19 +5645,19 @@ static struct pci_device_id pci_tbl[] = { }, { /* CK804 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT, }, { /* CK804 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT, }, { /* MCP04 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT, }, { /* MCP04 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT, }, { /* MCP51 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12), @@ -5587,11 +5669,11 @@ static struct pci_device_id pci_tbl[] = { }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT, }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16), @@ -5611,19 +5693,19 @@ static struct pci_device_id pci_tbl[] = { }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_NEED_TX_LIMIT, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24), @@ -5659,35 +5741,35 @@ static struct pci_device_id pci_tbl[] = { }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, }, {0,}, }; diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index e6c69f77259..0789802d59e 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -143,6 +143,10 @@ static inline void emac_report_timeout_error(struct emac_instance *dev, #define STOP_TIMEOUT_1000 13 #define STOP_TIMEOUT_1000_JUMBO 73 +static unsigned char default_mcast_addr[] = { + 0x01, 0x80, 0xC2, 0x00, 0x00, 0x01 +}; + /* Please, keep in sync with struct ibm_emac_stats/ibm_emac_error_stats */ static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = { "rx_packets", "rx_bytes", "tx_packets", "tx_bytes", "rx_packets_csum", @@ -618,6 +622,9 @@ static int emac_configure(struct emac_instance *dev) if (emac_phy_gpcs(dev->phy.mode)) emac_mii_reset_phy(&dev->phy); + /* Required for Pause packet support in EMAC */ + dev_mc_add(ndev, default_mcast_addr, sizeof(default_mcast_addr), 1); + return 0; } diff --git a/drivers/net/ibm_newemac/tah.c b/drivers/net/ibm_newemac/tah.c index 96417adec32..b023d10d7e1 100644 --- a/drivers/net/ibm_newemac/tah.c +++ b/drivers/net/ibm_newemac/tah.c @@ -155,6 +155,10 @@ static int __devexit tah_remove(struct of_device *ofdev) static struct of_device_id tah_match[] = { { + .compatible = "ibm,tah", + }, + /* For backward compat with old DT */ + { .type = "tah", }, {}, diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 15949d3df17..af233b59153 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -35,6 +35,7 @@ #include <linux/moduleparam.h> #include <net/pkt_sched.h> #include <net/net_namespace.h> +#include <linux/lockdep.h> #define TX_TIMEOUT (2*HZ) @@ -227,6 +228,16 @@ static struct rtnl_link_ops ifb_link_ops __read_mostly = { module_param(numifbs, int, 0); MODULE_PARM_DESC(numifbs, "Number of ifb devices"); +/* + * dev_ifb->queue_lock is usually taken after dev->ingress_lock, + * reversely to e.g. qdisc_lock_tree(). It should be safe until + * ifb doesn't take dev->queue_lock with dev_ifb->ingress_lock. + * But lockdep should know that ifb has different locks from dev. + */ +static struct lock_class_key ifb_queue_lock_key; +static struct lock_class_key ifb_ingress_lock_key; + + static int __init ifb_init_one(int index) { struct net_device *dev_ifb; @@ -246,6 +257,10 @@ static int __init ifb_init_one(int index) err = register_netdevice(dev_ifb); if (err < 0) goto err; + + lockdep_set_class(&dev_ifb->queue_lock, &ifb_queue_lock_key); + lockdep_set_class(&dev_ifb->ingress_lock, &ifb_ingress_lock_key); + return 0; err: diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h index 6604d96bd56..76ea846663d 100644 --- a/drivers/net/igb/e1000_82575.h +++ b/drivers/net/igb/e1000_82575.h @@ -61,28 +61,28 @@ /* Receive Descriptor - Advanced */ union e1000_adv_rx_desc { struct { - u64 pkt_addr; /* Packet buffer address */ - u64 hdr_addr; /* Header buffer address */ + __le64 pkt_addr; /* Packet buffer address */ + __le64 hdr_addr; /* Header buffer address */ } read; struct { struct { struct { - u16 pkt_info; /* RSS type, Packet type */ - u16 hdr_info; /* Split Header, - * header buffer length */ + __le16 pkt_info; /* RSS type, Packet type */ + __le16 hdr_info; /* Split Header, + * header buffer length */ } lo_dword; union { - u32 rss; /* RSS Hash */ + __le32 rss; /* RSS Hash */ struct { - u16 ip_id; /* IP id */ - u16 csum; /* Packet Checksum */ + __le16 ip_id; /* IP id */ + __le16 csum; /* Packet Checksum */ } csum_ip; } hi_dword; } lower; struct { - u32 status_error; /* ext status/error */ - u16 length; /* Packet length */ - u16 vlan; /* VLAN tag */ + __le32 status_error; /* ext status/error */ + __le16 length; /* Packet length */ + __le16 vlan; /* VLAN tag */ } upper; } wb; /* writeback */ }; @@ -97,14 +97,14 @@ union e1000_adv_rx_desc { /* Transmit Descriptor - Advanced */ union e1000_adv_tx_desc { struct { - u64 buffer_addr; /* Address of descriptor's data buf */ - u32 cmd_type_len; - u32 olinfo_status; + __le64 buffer_addr; /* Address of descriptor's data buf */ + __le32 cmd_type_len; + __le32 olinfo_status; } read; struct { - u64 rsvd; /* Reserved */ - u32 nxtseq_seed; - u32 status; + __le64 rsvd; /* Reserved */ + __le32 nxtseq_seed; + __le32 status; } wb; }; @@ -119,10 +119,10 @@ union e1000_adv_tx_desc { /* Context descriptors */ struct e1000_adv_tx_context_desc { - u32 vlan_macip_lens; - u32 seqnum_seed; - u32 type_tucmd_mlhl; - u32 mss_l4len_idx; + __le32 vlan_macip_lens; + __le32 seqnum_seed; + __le32 type_tucmd_mlhl; + __le32 mss_l4len_idx; }; #define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */ diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h index 161fb68764a..7b2c70a3b8c 100644 --- a/drivers/net/igb/e1000_hw.h +++ b/drivers/net/igb/e1000_hw.h @@ -143,35 +143,35 @@ enum e1000_fc_type { /* Receive Descriptor */ struct e1000_rx_desc { - u64 buffer_addr; /* Address of the descriptor's data buffer */ - u16 length; /* Length of data DMAed into data buffer */ - u16 csum; /* Packet checksum */ + __le64 buffer_addr; /* Address of the descriptor's data buffer */ + __le16 length; /* Length of data DMAed into data buffer */ + __le16 csum; /* Packet checksum */ u8 status; /* Descriptor status */ u8 errors; /* Descriptor Errors */ - u16 special; + __le16 special; }; /* Receive Descriptor - Extended */ union e1000_rx_desc_extended { struct { - u64 buffer_addr; - u64 reserved; + __le64 buffer_addr; + __le64 reserved; } read; struct { struct { - u32 mrq; /* Multiple Rx Queues */ + __le32 mrq; /* Multiple Rx Queues */ union { - u32 rss; /* RSS Hash */ + __le32 rss; /* RSS Hash */ struct { - u16 ip_id; /* IP id */ - u16 csum; /* Packet Checksum */ + __le16 ip_id; /* IP id */ + __le16 csum; /* Packet Checksum */ } csum_ip; } hi_dword; } lower; struct { - u32 status_error; /* ext status/error */ - u16 length; - u16 vlan; /* VLAN tag */ + __le32 status_error; /* ext status/error */ + __le16 length; + __le16 vlan; /* VLAN tag */ } upper; } wb; /* writeback */ }; @@ -181,49 +181,49 @@ union e1000_rx_desc_extended { union e1000_rx_desc_packet_split { struct { /* one buffer for protocol header(s), three data buffers */ - u64 buffer_addr[MAX_PS_BUFFERS]; + __le64 buffer_addr[MAX_PS_BUFFERS]; } read; struct { struct { - u32 mrq; /* Multiple Rx Queues */ + __le32 mrq; /* Multiple Rx Queues */ union { - u32 rss; /* RSS Hash */ + __le32 rss; /* RSS Hash */ struct { - u16 ip_id; /* IP id */ - u16 csum; /* Packet Checksum */ + __le16 ip_id; /* IP id */ + __le16 csum; /* Packet Checksum */ } csum_ip; } hi_dword; } lower; struct { - u32 status_error; /* ext status/error */ - u16 length0; /* length of buffer 0 */ - u16 vlan; /* VLAN tag */ + __le32 status_error; /* ext status/error */ + __le16 length0; /* length of buffer 0 */ + __le16 vlan; /* VLAN tag */ } middle; struct { - u16 header_status; - u16 length[3]; /* length of buffers 1-3 */ + __le16 header_status; + __le16 length[3]; /* length of buffers 1-3 */ } upper; - u64 reserved; + __le64 reserved; } wb; /* writeback */ }; /* Transmit Descriptor */ struct e1000_tx_desc { - u64 buffer_addr; /* Address of the descriptor's data buffer */ + __le64 buffer_addr; /* Address of the descriptor's data buffer */ union { - u32 data; + __le32 data; struct { - u16 length; /* Data buffer length */ + __le16 length; /* Data buffer length */ u8 cso; /* Checksum offset */ u8 cmd; /* Descriptor control */ } flags; } lower; union { - u32 data; + __le32 data; struct { u8 status; /* Descriptor status */ u8 css; /* Checksum start */ - u16 special; + __le16 special; } fields; } upper; }; @@ -231,49 +231,49 @@ struct e1000_tx_desc { /* Offload Context Descriptor */ struct e1000_context_desc { union { - u32 ip_config; + __le32 ip_config; struct { u8 ipcss; /* IP checksum start */ u8 ipcso; /* IP checksum offset */ - u16 ipcse; /* IP checksum end */ + __le16 ipcse; /* IP checksum end */ } ip_fields; } lower_setup; union { - u32 tcp_config; + __le32 tcp_config; struct { u8 tucss; /* TCP checksum start */ u8 tucso; /* TCP checksum offset */ - u16 tucse; /* TCP checksum end */ + __le16 tucse; /* TCP checksum end */ } tcp_fields; } upper_setup; - u32 cmd_and_length; + __le32 cmd_and_length; union { - u32 data; + __le32 data; struct { u8 status; /* Descriptor status */ u8 hdr_len; /* Header length */ - u16 mss; /* Maximum segment size */ + __le16 mss; /* Maximum segment size */ } fields; } tcp_seg_setup; }; /* Offload data descriptor */ struct e1000_data_desc { - u64 buffer_addr; /* Address of the descriptor's buffer address */ + __le64 buffer_addr; /* Address of the descriptor's buffer address */ union { - u32 data; + __le32 data; struct { - u16 length; /* Data buffer length */ + __le16 length; /* Data buffer length */ u8 typ_len_ext; u8 cmd; } flags; } lower; union { - u32 data; + __le32 data; struct { u8 status; /* Descriptor status */ u8 popts; /* Packet Options */ - u16 special; + __le16 special; } fields; } upper; }; diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 6a1f2309209..aaee02e9e3f 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -31,7 +31,6 @@ #include <linux/vmalloc.h> #include <linux/pagemap.h> #include <linux/netdevice.h> -#include <linux/tcp.h> #include <linux/ipv6.h> #include <net/checksum.h> #include <net/ip6_checksum.h> @@ -2484,10 +2483,24 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter, tu_cmd |= (E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT); if (skb->ip_summed == CHECKSUM_PARTIAL) { - if (skb->protocol == htons(ETH_P_IP)) + switch (skb->protocol) { + case __constant_htons(ETH_P_IP): tu_cmd |= E1000_ADVTXD_TUCMD_IPV4; - if (skb->sk && (skb->sk->sk_protocol == IPPROTO_TCP)) - tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP; + if (ip_hdr(skb)->protocol == IPPROTO_TCP) + tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP; + break; + case __constant_htons(ETH_P_IPV6): + /* XXX what about other V6 headers?? */ + if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) + tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP; + break; + default: + if (unlikely(net_ratelimit())) + dev_warn(&adapter->pdev->dev, + "partial checksum but proto=%x!\n", + skb->protocol); + break; + } } context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd); @@ -3241,6 +3254,13 @@ quit_polling: return 1; } + +static inline u32 get_head(struct igb_ring *tx_ring) +{ + void *end = (struct e1000_tx_desc *)tx_ring->desc + tx_ring->count; + return le32_to_cpu(*(volatile __le32 *)end); +} + /** * igb_clean_tx_irq - Reclaim resources after transmit completes * @adapter: board private structure @@ -3262,9 +3282,7 @@ static bool igb_clean_tx_irq(struct igb_adapter *adapter, unsigned int total_bytes = 0, total_packets = 0; rmb(); - head = *(volatile u32 *)((struct e1000_tx_desc *)tx_ring->desc - + tx_ring->count); - head = le32_to_cpu(head); + head = get_head(tx_ring); i = tx_ring->next_to_clean; while (1) { while (i != head) { @@ -3299,9 +3317,7 @@ static bool igb_clean_tx_irq(struct igb_adapter *adapter, } oldhead = head; rmb(); - head = *(volatile u32 *)((struct e1000_tx_desc *)tx_ring->desc - + tx_ring->count); - head = le32_to_cpu(head); + head = get_head(tx_ring); if (head == oldhead) goto done_cleaning; } /* while (1) */ @@ -3375,7 +3391,7 @@ done_cleaning: * @vlan: descriptor vlan field as written by hardware (no le/be conversion) * @skb: pointer to sk_buff to be indicated to stack **/ -static void igb_receive_skb(struct igb_adapter *adapter, u8 status, u16 vlan, +static void igb_receive_skb(struct igb_adapter *adapter, u8 status, __le16 vlan, struct sk_buff *skb) { if (adapter->vlgrp && (status & E1000_RXD_STAT_VP)) @@ -3439,8 +3455,8 @@ static bool igb_clean_rx_irq_adv(struct igb_adapter *adapter, * that case, it fills the header buffer and spills the rest * into the page. */ - hlen = le16_to_cpu((rx_desc->wb.lower.lo_dword.hdr_info & - E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT); + hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) & + E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT; if (hlen > adapter->rx_ps_hdr_size) hlen = adapter->rx_ps_hdr_size; diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index 373f72cdbe8..1f25263dc7e 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -1221,7 +1221,8 @@ static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3) } #endif -static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +static int __devinit ioc3_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) { unsigned int sw_physid1, sw_physid2; struct net_device *dev = NULL; diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 5e5d9b527ed..9b358f61ed7 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -472,7 +472,6 @@ static int ipg_config_autoneg(struct net_device *dev) unsigned int txflowcontrol; unsigned int rxflowcontrol; unsigned int fullduplex; - unsigned int gig; u32 mac_ctrl_val; u32 asicctrl; u8 phyctrl; @@ -489,7 +488,6 @@ static int ipg_config_autoneg(struct net_device *dev) fullduplex = 0; txflowcontrol = 0; rxflowcontrol = 0; - gig = 0; /* To accomodate a problem in 10Mbps operation, * set a global flag if PHY running in 10Mbps mode. @@ -511,7 +509,6 @@ static int ipg_config_autoneg(struct net_device *dev) break; case IPG_PC_LINK_SPEED_1000MBPS: printk("1000Mbps.\n"); - gig = 1; break; default: printk("undefined!\n"); @@ -1900,8 +1897,13 @@ static int ipg_nic_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Specify the TFC field within the TFD. */ txfd->tfc |= cpu_to_le64(IPG_TFC_WORDALIGNDISABLED | - (IPG_TFC_FRAMEID & cpu_to_le64(sp->tx_current)) | + (IPG_TFC_FRAMEID & sp->tx_current) | (IPG_TFC_FRAGCOUNT & (1 << 24))); + /* + * 16--17 (WordAlign) <- 3 (disable), + * 0--15 (FrameId) <- sp->tx_current, + * 24--27 (FragCount) <- 1 + */ /* Request TxComplete interrupts at an interval defined * by the constant IPG_FRAMESBETWEENTXCOMPLETES. diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 269e6f805f4..6738b4d097f 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -2088,14 +2088,12 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter) struct ixgb_buffer *buffer_info; struct sk_buff *skb; unsigned int i; - int num_group_tail_writes; long cleancount; i = rx_ring->next_to_use; buffer_info = &rx_ring->buffer_info[i]; cleancount = IXGB_DESC_UNUSED(rx_ring); - num_group_tail_writes = IXGB_RX_BUFFER_WRITE; /* leave three descriptors unused */ while(--cleancount > 2) { diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 23d0a4afe0e..c2095ce531c 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2133,7 +2133,7 @@ static void ixgbe_watchdog(unsigned long data) (link_speed == IXGBE_LINK_SPEED_10GB_FULL ? "10 Gbps" : (link_speed == IXGBE_LINK_SPEED_1GB_FULL ? - "1 Gpbs" : "unknown speed")), + "1 Gbps" : "unknown speed")), ((FLOW_RX && FLOW_TX) ? "RX/TX" : (FLOW_RX ? "RX" : (FLOW_TX ? "TX" : "None")))); diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index b528ce77c40..771139e283a 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -2104,6 +2104,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR( "Rabeeh Khoury, Assaf Hoffman, Matthew Dharm, Manish Lachwani" " and Dale Farnsworth"); MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX"); +MODULE_ALIAS("platform:mv643xx_eth"); /* * The second part is the low level driver of the gigE ethernet ports. diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c index b569c90da4b..de0de744a8f 100644 --- a/drivers/net/ne2k-pci.c +++ b/drivers/net/ne2k-pci.c @@ -535,9 +535,9 @@ static void ne2k_pci_block_input(struct net_device *dev, int count, if (count & 3) { buf += count & ~3; if (count & 2) { - u16 *b = (u16 *)buf; + __le16 *b = (__le16 *)buf; - *b++ = le16_to_cpu(inw(NE_BASE + NE_DATAPORT)); + *b++ = cpu_to_le16(inw(NE_BASE + NE_DATAPORT)); buf = (char *)b; } if (count & 1) @@ -600,9 +600,9 @@ static void ne2k_pci_block_output(struct net_device *dev, int count, if (count & 3) { buf += count & ~3; if (count & 2) { - u16 *b = (u16 *)buf; + __le16 *b = (__le16 *)buf; - outw(cpu_to_le16(*b++), NE_BASE + NE_DATAPORT); + outw(le16_to_cpu(*b++), NE_BASE + NE_DATAPORT); buf = (char *)b; } } diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 2bc5eaae141..7f20a03623a 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -85,7 +85,7 @@ (sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count) #define RCV_BUFFSIZE \ (sizeof(struct netxen_rx_buffer) * rcv_desc->max_rx_desc_count) -#define find_diff_among(a,b,range) ((a)<=(b)?((b)-(a)):((b)+(range)-(a))) +#define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a))) #define NETXEN_NETDEV_STATUS 0x1 #define NETXEN_RCV_PRODUCER_OFFSET 0 @@ -204,7 +204,7 @@ enum { ? RCV_DESC_LRO : \ (RCV_DESC_NORMAL))) -#define MAX_CMD_DESCRIPTORS 1024 +#define MAX_CMD_DESCRIPTORS 4096 #define MAX_RCV_DESCRIPTORS 16384 #define MAX_CMD_DESCRIPTORS_HOST (MAX_CMD_DESCRIPTORS / 4) #define MAX_RCV_DESCRIPTORS_1G (MAX_RCV_DESCRIPTORS / 4) @@ -818,15 +818,8 @@ struct netxen_adapter_stats { u64 badskblen; u64 nocmddescriptor; u64 polled; - u64 uphappy; - u64 updropped; - u64 uplcong; - u64 uphcong; - u64 upmcong; - u64 updunno; - u64 skbfreed; + u64 rxdropped; u64 txdropped; - u64 txnullskb; u64 csummed; u64 no_rcv; u64 rxbytes; @@ -842,7 +835,6 @@ struct netxen_rcv_desc_ctx { u32 flags; u32 producer; u32 rcv_pending; /* Num of bufs posted in phantom */ - u32 rcv_free; /* Num of bufs in free list */ dma_addr_t phys_addr; struct pci_dev *phys_pdev; struct rcv_desc *desc_head; /* address of rx ring in Phantom */ @@ -889,8 +881,6 @@ struct netxen_adapter { int mtu; int portnum; - spinlock_t tx_lock; - spinlock_t lock; struct work_struct watchdog_task; struct timer_list watchdog_timer; struct work_struct tx_timeout_task; @@ -899,16 +889,12 @@ struct netxen_adapter { u32 cmd_producer; __le32 *cmd_consumer; - u32 last_cmd_consumer; + u32 max_tx_desc_count; u32 max_rx_desc_count; u32 max_jumbo_rx_desc_count; u32 max_lro_rx_desc_count; - /* Num of instances active on cmd buffer ring */ - u32 proc_cmd_buf_counter; - - u32 num_threads, total_threads; /*Use to keep track of xmit threads */ u32 flags; u32 irq; @@ -942,6 +928,7 @@ struct netxen_adapter { struct pci_dev *ctx_desc_pdev; dma_addr_t ctx_desc_phys_addr; int intr_scheme; + int msi_mode; int (*enable_phy_interrupts) (struct netxen_adapter *); int (*disable_phy_interrupts) (struct netxen_adapter *); void (*handle_phy_intr) (struct netxen_adapter *); @@ -1075,12 +1062,10 @@ void netxen_tso_check(struct netxen_adapter *adapter, struct cmd_desc_type0 *desc, struct sk_buff *skb); int netxen_nic_hw_resources(struct netxen_adapter *adapter); void netxen_nic_clear_stats(struct netxen_adapter *adapter); -int netxen_nic_rx_has_work(struct netxen_adapter *adapter); -int netxen_nic_tx_has_work(struct netxen_adapter *adapter); void netxen_watchdog_task(struct work_struct *work); void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid); -int netxen_process_cmd_ring(unsigned long data); +int netxen_process_cmd_ring(struct netxen_adapter *adapter); u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max); void netxen_nic_set_multi(struct net_device *netdev); int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 7a876f4b8db..6e98d830eef 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -64,15 +64,7 @@ static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = { {"bad_skb_len", NETXEN_NIC_STAT(stats.badskblen)}, {"no_cmd_desc", NETXEN_NIC_STAT(stats.nocmddescriptor)}, {"polled", NETXEN_NIC_STAT(stats.polled)}, - {"uphappy", NETXEN_NIC_STAT(stats.uphappy)}, - {"updropped", NETXEN_NIC_STAT(stats.updropped)}, - {"uplcong", NETXEN_NIC_STAT(stats.uplcong)}, - {"uphcong", NETXEN_NIC_STAT(stats.uphcong)}, - {"upmcong", NETXEN_NIC_STAT(stats.upmcong)}, - {"updunno", NETXEN_NIC_STAT(stats.updunno)}, - {"skb_freed", NETXEN_NIC_STAT(stats.skbfreed)}, {"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)}, - {"tx_null_skb", NETXEN_NIC_STAT(stats.txnullskb)}, {"csummed", NETXEN_NIC_STAT(stats.csummed)}, {"no_rcv", NETXEN_NIC_STAT(stats.no_rcv)}, {"rx_bytes", NETXEN_NIC_STAT(stats.rxbytes)}, diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index d72f8f8fcb5..160f605e58d 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h @@ -456,6 +456,12 @@ enum { #define ISR_INT_MASK_SLOW (NETXEN_PCIX_PS_REG(PCIX_INT_MASK)) #define ISR_INT_TARGET_STATUS (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS)) #define ISR_INT_TARGET_MASK (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK)) +#define ISR_INT_TARGET_STATUS_F1 (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F1)) +#define ISR_INT_TARGET_MASK_F1 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F1)) +#define ISR_INT_TARGET_STATUS_F2 (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F2)) +#define ISR_INT_TARGET_MASK_F2 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F2)) +#define ISR_INT_TARGET_STATUS_F3 (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F3)) +#define ISR_INT_TARGET_MASK_F3 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F3)) #define NETXEN_PCI_MAPSIZE 128 #define NETXEN_PCI_DDR_NET (0x00000000UL) @@ -662,6 +668,12 @@ enum { #define PCIX_TARGET_STATUS (0x10118) #define PCIX_TARGET_MASK (0x10128) +#define PCIX_TARGET_STATUS_F1 (0x10160) +#define PCIX_TARGET_MASK_F1 (0x10170) +#define PCIX_TARGET_STATUS_F2 (0x10164) +#define PCIX_TARGET_MASK_F2 (0x10174) +#define PCIX_TARGET_STATUS_F3 (0x10168) +#define PCIX_TARGET_MASK_F3 (0x10178) #define PCIX_MSI_F0 (0x13000) #define PCIX_MSI_F1 (0x13004) diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 01355701bf8..05748ca6f21 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -398,6 +398,8 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW)); printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netxen_nic_driver_name, adapter->intr_scheme); + adapter->msi_mode = readl( + NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_FW)); DPRINTK(INFO, "Receive Peg ready too. starting stuff\n"); addr = netxen_alloc(adapter->ahw.pdev, diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 9e38bcb3fba..45fa33e0cb9 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -145,6 +145,8 @@ int netxen_init_firmware(struct netxen_adapter *adapter) /* Window 1 call */ writel(INTR_SCHEME_PERPORT, NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_HOST)); + writel(MSI_MODE_MULTIFUNC, + NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_HOST)); writel(MPORT_MULTI_FUNCTION_MODE, NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE)); writel(PHAN_INITIALIZE_ACK, @@ -183,7 +185,6 @@ void netxen_initialize_adapter_sw(struct netxen_adapter *adapter) for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { struct netxen_rx_buffer *rx_buf; rcv_desc = &adapter->recv_ctx[ctxid].rcv_desc[ring]; - rcv_desc->rcv_free = rcv_desc->max_rx_desc_count; rcv_desc->begin_alloc = 0; rx_buf = rcv_desc->rx_buf_arr; num_rx_bufs = rcv_desc->max_rx_desc_count; @@ -974,28 +975,6 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) return 0; } -int netxen_nic_rx_has_work(struct netxen_adapter *adapter) -{ - int ctx; - - for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { - struct netxen_recv_context *recv_ctx = - &(adapter->recv_ctx[ctx]); - u32 consumer; - struct status_desc *desc_head; - struct status_desc *desc; - - consumer = recv_ctx->status_rx_consumer; - desc_head = recv_ctx->rcv_status_desc_head; - desc = &desc_head[consumer]; - - if (netxen_get_sts_owner(desc) & STATUS_OWNER_HOST) - return 1; - } - - return 0; -} - static int netxen_nic_check_temp(struct netxen_adapter *adapter) { struct net_device *netdev = adapter->netdev; @@ -1038,7 +1017,6 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter) void netxen_watchdog_task(struct work_struct *work) { - struct net_device *netdev; struct netxen_adapter *adapter = container_of(work, struct netxen_adapter, watchdog_task); @@ -1048,20 +1026,6 @@ void netxen_watchdog_task(struct work_struct *work) if (adapter->handle_phy_intr) adapter->handle_phy_intr(adapter); - netdev = adapter->netdev; - if ((netif_running(netdev)) && !netif_carrier_ok(netdev) && - netxen_nic_link_ok(adapter) ) { - printk(KERN_INFO "%s %s (port %d), Link is up\n", - netxen_nic_driver_name, netdev->name, adapter->portnum); - netif_carrier_on(netdev); - netif_wake_queue(netdev); - } else if(!(netif_running(netdev)) && netif_carrier_ok(netdev)) { - printk(KERN_ERR "%s %s Link is Down\n", - netxen_nic_driver_name, netdev->name); - netif_carrier_off(netdev); - netif_stop_queue(netdev); - } - mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); } @@ -1125,7 +1089,7 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, skb = (struct sk_buff *)buffer->skb; if (likely(adapter->rx_csum && - netxen_get_sts_status(sts_data) == STATUS_CKSUM_OK)) { + netxen_get_sts_status(sts_data) == STATUS_CKSUM_OK)) { adapter->stats.csummed++; skb->ip_summed = CHECKSUM_UNNECESSARY; } else @@ -1142,40 +1106,8 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, skb->protocol = eth_type_trans(skb, netdev); ret = netif_receive_skb(skb); - - /* - * RH: Do we need these stats on a regular basis. Can we get it from - * Linux stats. - */ - switch (ret) { - case NET_RX_SUCCESS: - adapter->stats.uphappy++; - break; - - case NET_RX_CN_LOW: - adapter->stats.uplcong++; - break; - - case NET_RX_CN_MOD: - adapter->stats.upmcong++; - break; - - case NET_RX_CN_HIGH: - adapter->stats.uphcong++; - break; - - case NET_RX_DROP: - adapter->stats.updropped++; - break; - - default: - adapter->stats.updunno++; - break; - } - netdev->last_rx = jiffies; - rcv_desc->rcv_free++; rcv_desc->rcv_pending--; /* @@ -1200,13 +1132,6 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) u32 producer = 0; int count = 0, ring; - DPRINTK(INFO, "procesing receive\n"); - /* - * we assume in this case that there is only one port and that is - * port #1...changes need to be done in firmware to indicate port - * number as part of the descriptor. This way we will be able to get - * the netdev which is associated with that device. - */ while (count < max) { desc = &desc_head[consumer]; if (!(netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)) { @@ -1219,11 +1144,8 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1); count++; } - if (count) { - for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { - netxen_post_rx_buffers_nodb(adapter, ctxid, ring); - } - } + for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) + netxen_post_rx_buffers_nodb(adapter, ctxid, ring); /* update the consumer index in phantom */ if (count) { @@ -1233,108 +1155,60 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) /* Window = 1 */ writel(consumer, NETXEN_CRB_NORMALIZE(adapter, - recv_crb_registers[adapter->portnum]. + recv_crb_registers[adapter->portnum]. crb_rcv_status_consumer)); - wmb(); } return count; } /* Process Command status ring */ -int netxen_process_cmd_ring(unsigned long data) +int netxen_process_cmd_ring(struct netxen_adapter *adapter) { - u32 last_consumer; - u32 consumer; - struct netxen_adapter *adapter = (struct netxen_adapter *)data; - int count1 = 0; - int count2 = 0; + u32 last_consumer, consumer; + int count = 0, i; struct netxen_cmd_buffer *buffer; - struct pci_dev *pdev; + struct pci_dev *pdev = adapter->pdev; + struct net_device *netdev = adapter->netdev; struct netxen_skb_frag *frag; - u32 i; - int done; + int done = 0; - spin_lock(&adapter->tx_lock); last_consumer = adapter->last_cmd_consumer; - DPRINTK(INFO, "procesing xmit complete\n"); - /* we assume in this case that there is only one port and that is - * port #1...changes need to be done in firmware to indicate port - * number as part of the descriptor. This way we will be able to get - * the netdev which is associated with that device. - */ - consumer = le32_to_cpu(*(adapter->cmd_consumer)); - if (last_consumer == consumer) { /* Ring is empty */ - DPRINTK(INFO, "last_consumer %d == consumer %d\n", - last_consumer, consumer); - spin_unlock(&adapter->tx_lock); - return 1; - } - - adapter->proc_cmd_buf_counter++; - /* - * Not needed - does not seem to be used anywhere. - * adapter->cmd_consumer = consumer; - */ - spin_unlock(&adapter->tx_lock); - while ((last_consumer != consumer) && (count1 < MAX_STATUS_HANDLE)) { + while (last_consumer != consumer) { buffer = &adapter->cmd_buf_arr[last_consumer]; - pdev = adapter->pdev; if (buffer->skb) { frag = &buffer->frag_array[0]; pci_unmap_single(pdev, frag->dma, frag->length, PCI_DMA_TODEVICE); frag->dma = 0ULL; for (i = 1; i < buffer->frag_count; i++) { - DPRINTK(INFO, "getting fragment no %d\n", i); frag++; /* Get the next frag */ pci_unmap_page(pdev, frag->dma, frag->length, PCI_DMA_TODEVICE); frag->dma = 0ULL; } - adapter->stats.skbfreed++; + adapter->stats.xmitfinished++; dev_kfree_skb_any(buffer->skb); buffer->skb = NULL; - } else if (adapter->proc_cmd_buf_counter == 1) { - adapter->stats.txnullskb++; - } - if (unlikely(netif_queue_stopped(adapter->netdev) - && netif_carrier_ok(adapter->netdev)) - && ((jiffies - adapter->netdev->trans_start) > - adapter->netdev->watchdog_timeo)) { - SCHEDULE_WORK(&adapter->tx_timeout_task); } last_consumer = get_next_index(last_consumer, adapter->max_tx_desc_count); - count1++; + if (++count >= MAX_STATUS_HANDLE) + break; } - count2 = 0; - spin_lock(&adapter->tx_lock); - if ((--adapter->proc_cmd_buf_counter) == 0) { + if (count) { adapter->last_cmd_consumer = last_consumer; - while ((adapter->last_cmd_consumer != consumer) - && (count2 < MAX_STATUS_HANDLE)) { - buffer = - &adapter->cmd_buf_arr[adapter->last_cmd_consumer]; - count2++; - if (buffer->skb) - break; - else - adapter->last_cmd_consumer = - get_next_index(adapter->last_cmd_consumer, - adapter->max_tx_desc_count); - } - } - if (count1 || count2) { - if (netif_queue_stopped(adapter->netdev) - && (adapter->flags & NETXEN_NETDEV_STATUS)) { - netif_wake_queue(adapter->netdev); - adapter->flags &= ~NETXEN_NETDEV_STATUS; + smp_mb(); + if (netif_queue_stopped(netdev) && netif_running(netdev)) { + netif_tx_lock(netdev); + netif_wake_queue(netdev); + smp_mb(); + netif_tx_unlock(netdev); } } /* @@ -1350,16 +1224,9 @@ int netxen_process_cmd_ring(unsigned long data) * There is still a possible race condition and the host could miss an * interrupt. The card has to take care of this. */ - if (adapter->last_cmd_consumer == consumer && - (((adapter->cmd_producer + 1) % - adapter->max_tx_desc_count) == adapter->last_cmd_consumer)) { - consumer = le32_to_cpu(*(adapter->cmd_consumer)); - } - done = (adapter->last_cmd_consumer == consumer); + consumer = le32_to_cpu(*(adapter->cmd_consumer)); + done = (last_consumer == consumer); - spin_unlock(&adapter->tx_lock); - DPRINTK(INFO, "last consumer is %d in %s\n", last_consumer, - __FUNCTION__); return (done); } @@ -1433,8 +1300,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) rcv_desc->begin_alloc = index; rcv_desc->rcv_pending += count; rcv_desc->producer = producer; - if (rcv_desc->rcv_free >= 32) { - rcv_desc->rcv_free = 0; /* Window = 1 */ writel((producer - 1) & (rcv_desc->max_rx_desc_count - 1), @@ -1458,8 +1323,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) writel(msg, DB_NORMALIZE(adapter, NETXEN_RCV_PRODUCER_OFFSET)); - wmb(); - } } } @@ -1523,8 +1386,6 @@ static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, rcv_desc->begin_alloc = index; rcv_desc->rcv_pending += count; rcv_desc->producer = producer; - if (rcv_desc->rcv_free >= 32) { - rcv_desc->rcv_free = 0; /* Window = 1 */ writel((producer - 1) & (rcv_desc->max_rx_desc_count - 1), @@ -1534,21 +1395,9 @@ static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, rcv_desc_crb[ringid]. crb_rcv_producer_offset)); wmb(); - } } } -int netxen_nic_tx_has_work(struct netxen_adapter *adapter) -{ - if (find_diff_among(adapter->last_cmd_consumer, - adapter->cmd_producer, - adapter->max_tx_desc_count) > 0) - return 1; - - return 0; -} - - void netxen_nic_clear_stats(struct netxen_adapter *adapter) { memset(&adapter->stats, 0, sizeof(adapter->stats)); diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c index 48a404aa66c..c81313b717b 100644 --- a/drivers/net/netxen/netxen_nic_isr.c +++ b/drivers/net/netxen/netxen_nic_isr.c @@ -59,7 +59,7 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) /* packet transmit problems */ stats->tx_errors = adapter->stats.nocmddescriptor; /* no space in linux buffers */ - stats->rx_dropped = adapter->stats.updropped; + stats->rx_dropped = adapter->stats.rxdropped; /* no space available in linux */ stats->tx_dropped = adapter->stats.txdropped; @@ -193,14 +193,14 @@ int netxen_nic_link_ok(struct netxen_adapter *adapter) void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) { struct net_device *netdev = adapter->netdev; - u32 val, val1; + u32 val; /* WINDOW = 1 */ val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); val >>= (physical_port[adapter->portnum] * 8); - val1 = val & 0xff; + val &= 0xff; - if (adapter->ahw.xg_linkup == 1 && val1 != XG_LINK_UP) { + if (adapter->ahw.xg_linkup == 1 && val != XG_LINK_UP) { printk(KERN_INFO "%s: %s NIC Link is down\n", netxen_nic_driver_name, netdev->name); adapter->ahw.xg_linkup = 0; @@ -208,16 +208,7 @@ void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) netif_carrier_off(netdev); netif_stop_queue(netdev); } - /* read twice to clear sticky bits */ - /* WINDOW = 0 */ - netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1); - netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1); - - if ((val & 0xffb) != 0xffb) { - printk(KERN_INFO "%s ISR: Sync/Align BAD: 0x%08x\n", - netxen_nic_driver_name, val1); - } - } else if (adapter->ahw.xg_linkup == 0 && val1 == XG_LINK_UP) { + } else if (adapter->ahw.xg_linkup == 0 && val == XG_LINK_UP) { printk(KERN_INFO "%s: %s NIC Link is up\n", netxen_nic_driver_name, netdev->name); adapter->ahw.xg_linkup = 1; diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 9737eae5ef1..a8fb439a4d0 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -63,12 +63,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *, struct net_device *); static void netxen_tx_timeout(struct net_device *netdev); static void netxen_tx_timeout_task(struct work_struct *work); static void netxen_watchdog(unsigned long); -static int netxen_handle_int(struct netxen_adapter *, struct net_device *); static int netxen_nic_poll(struct napi_struct *napi, int budget); #ifdef CONFIG_NET_POLL_CONTROLLER static void netxen_nic_poll_controller(struct net_device *netdev); #endif static irqreturn_t netxen_intr(int irq, void *data); +static irqreturn_t netxen_msi_intr(int irq, void *data); int physical_port[] = {0, 1, 2, 3}; @@ -149,33 +149,30 @@ static void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, #define ADAPTER_LIST_SIZE 12 +static uint32_t msi_tgt_status[4] = { + ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1, + ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3 +}; + +static uint32_t sw_int_mask[4] = { + CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1, + CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3 +}; + static void netxen_nic_disable_int(struct netxen_adapter *adapter) { - uint32_t mask = 0x7ff; + u32 mask = 0x7ff; int retries = 32; + int port = adapter->portnum; + int pci_fn = adapter->ahw.pci_func; - DPRINTK(1, INFO, "Entered ISR Disable \n"); - - switch (adapter->portnum) { - case 0: - writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0)); - break; - case 1: - writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1)); - break; - case 2: - writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2)); - break; - case 3: - writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3)); - break; - } + if (adapter->msi_mode != MSI_MODE_MULTIFUNC) + writel(0x0, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port])); if (adapter->intr_scheme != -1 && adapter->intr_scheme != INTR_SCHEME_PERPORT) writel(mask,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); - /* Window = 0 or 1 */ if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { do { writel(0xffffffff, @@ -190,14 +187,18 @@ static void netxen_nic_disable_int(struct netxen_adapter *adapter) printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n", netxen_nic_driver_name); } + } else { + if (adapter->msi_mode == MSI_MODE_MULTIFUNC) { + writel(0xffffffff, PCI_OFFSET_SECOND_RANGE(adapter, + msi_tgt_status[pci_fn])); + } } - - DPRINTK(1, INFO, "Done with Disable Int\n"); } static void netxen_nic_enable_int(struct netxen_adapter *adapter) { u32 mask; + int port = adapter->portnum; DPRINTK(1, INFO, "Entered ISR Enable \n"); @@ -218,20 +219,7 @@ static void netxen_nic_enable_int(struct netxen_adapter *adapter) writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); } - switch (adapter->portnum) { - case 0: - writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0)); - break; - case 1: - writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1)); - break; - case 2: - writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2)); - break; - case 3: - writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3)); - break; - } + writel(0x1, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port])); if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { mask = 0xbff; @@ -328,7 +316,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->ahw.pdev = pdev; adapter->ahw.pci_func = pci_func_id; - spin_lock_init(&adapter->tx_lock); /* remap phys address */ mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ @@ -401,6 +388,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* this will be read from FW later */ adapter->intr_scheme = -1; + adapter->msi_mode = -1; /* This will be reset for mezz cards */ adapter->portnum = pci_func_id; @@ -415,7 +403,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->set_mac_address = netxen_nic_set_mac; netdev->change_mtu = netxen_nic_change_mtu; netdev->tx_timeout = netxen_tx_timeout; - netdev->watchdog_timeo = HZ; + netdev->watchdog_timeo = 2*HZ; netxen_nic_change_mtu(netdev, netdev->mtu); @@ -543,7 +531,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->watchdog_timer.data = (unsigned long)adapter; INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); adapter->ahw.pdev = pdev; - adapter->proc_cmd_buf_counter = 0; adapter->ahw.revision_id = pdev->revision; /* make sure Window == 1 */ @@ -833,6 +820,8 @@ static int netxen_nic_open(struct net_device *netdev) struct netxen_adapter *adapter = (struct netxen_adapter *)netdev->priv; int err = 0; int ctx, ring; + irq_handler_t handler; + unsigned long flags = IRQF_SAMPLE_RANDOM; if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) { err = netxen_init_firmware(adapter); @@ -856,9 +845,14 @@ static int netxen_nic_open(struct net_device *netdev) netxen_post_rx_buffers(adapter, ctx, ring); } adapter->irq = adapter->ahw.pdev->irq; - err = request_irq(adapter->ahw.pdev->irq, netxen_intr, - IRQF_SHARED|IRQF_SAMPLE_RANDOM, netdev->name, - adapter); + if (adapter->flags & NETXEN_NIC_MSI_ENABLED) + handler = netxen_msi_intr; + else { + flags |= IRQF_SHARED; + handler = netxen_intr; + } + err = request_irq(adapter->irq, handler, + flags, netdev->name, adapter); if (err) { printk(KERN_ERR "request_irq failed with: %d\n", err); netxen_free_hw_resources(adapter); @@ -867,21 +861,12 @@ static int netxen_nic_open(struct net_device *netdev) adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; } - if (!adapter->driver_mismatch) - mod_timer(&adapter->watchdog_timer, jiffies); - - napi_enable(&adapter->napi); - - netxen_nic_enable_int(adapter); - /* Done here again so that even if phantom sw overwrote it, * we set it */ if (adapter->init_port && adapter->init_port(adapter, adapter->portnum) != 0) { - del_timer_sync(&adapter->watchdog_timer); printk(KERN_ERR "%s: Failed to initialize port %d\n", netxen_nic_driver_name, adapter->portnum); - napi_disable(&adapter->napi); return -EIO; } if (adapter->macaddr_set) @@ -894,6 +879,12 @@ static int netxen_nic_open(struct net_device *netdev) adapter->set_mtu(adapter, netdev->mtu); if (!adapter->driver_mismatch) + mod_timer(&adapter->watchdog_timer, jiffies); + + napi_enable(&adapter->napi); + netxen_nic_enable_int(adapter); + + if (!adapter->driver_mismatch) netif_start_queue(netdev); return 0; @@ -958,41 +949,17 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) struct netxen_skb_frag *buffrag; unsigned int i; - u32 producer = 0; + u32 producer, consumer; u32 saved_producer = 0; struct cmd_desc_type0 *hwdesc; int k; struct netxen_cmd_buffer *pbuf = NULL; - static int dropped_packet = 0; int frag_count; - u32 local_producer = 0; - u32 max_tx_desc_count = 0; - u32 last_cmd_consumer = 0; int no_of_desc; + u32 num_txd = adapter->max_tx_desc_count; - adapter->stats.xmitcalled++; frag_count = skb_shinfo(skb)->nr_frags + 1; - if (unlikely(skb->len <= 0)) { - dev_kfree_skb_any(skb); - adapter->stats.badskblen++; - return NETDEV_TX_OK; - } - - if (frag_count > MAX_BUFFERS_PER_CMD) { - printk("%s: %s netxen_nic_xmit_frame: frag_count (%d) " - "too large, can handle only %d frags\n", - netxen_nic_driver_name, netdev->name, - frag_count, MAX_BUFFERS_PER_CMD); - adapter->stats.txdropped++; - if ((++dropped_packet & 0xff) == 0xff) - printk("%s: %s droppped packets = %d\n", - netxen_nic_driver_name, netdev->name, - dropped_packet); - - return NETDEV_TX_OK; - } - /* There 4 fragments per descriptor */ no_of_desc = (frag_count + 3) >> 2; if (netdev->features & NETIF_F_TSO) { @@ -1007,27 +974,16 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } } - spin_lock_bh(&adapter->tx_lock); - if (adapter->total_threads >= MAX_XMIT_PRODUCERS) { - goto out_requeue; - } - local_producer = adapter->cmd_producer; - k = adapter->cmd_producer; - max_tx_desc_count = adapter->max_tx_desc_count; - last_cmd_consumer = adapter->last_cmd_consumer; - if ((k + no_of_desc) >= - ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count : - last_cmd_consumer)) { - goto out_requeue; + producer = adapter->cmd_producer; + smp_mb(); + consumer = adapter->last_cmd_consumer; + if ((no_of_desc+2) > find_diff_among(producer, consumer, num_txd)) { + netif_stop_queue(netdev); + smp_mb(); + return NETDEV_TX_BUSY; } - k = get_index_range(k, max_tx_desc_count, no_of_desc); - adapter->cmd_producer = k; - adapter->total_threads++; - adapter->num_threads++; - spin_unlock_bh(&adapter->tx_lock); /* Copy the descriptors into the hardware */ - producer = local_producer; saved_producer = producer; hwdesc = &hw->cmd_desc_head[producer]; memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); @@ -1067,8 +1023,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) /* move to next desc. if there is a need */ if ((i & 0x3) == 0) { k = 0; - producer = get_next_index(producer, - adapter->max_tx_desc_count); + producer = get_next_index(producer, num_txd); hwdesc = &hw->cmd_desc_head[producer]; memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); pbuf = &adapter->cmd_buf_arr[producer]; @@ -1086,7 +1041,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) buffrag->dma = temp_dma; buffrag->length = temp_len; - DPRINTK(INFO, "for loop. i=%d k=%d\n", i, k); switch (k) { case 0: hwdesc->buffer1_length = cpu_to_le16(temp_len); @@ -1107,7 +1061,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } frag++; } - producer = get_next_index(producer, adapter->max_tx_desc_count); + producer = get_next_index(producer, num_txd); /* might change opcode to TX_TCP_LSO */ netxen_tso_check(adapter, &hw->cmd_desc_head[saved_producer], skb); @@ -1134,7 +1088,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) /* copy the first 64 bytes */ memcpy(((void *)hwdesc) + 2, (void *)(skb->data), first_hdr_len); - producer = get_next_index(producer, max_tx_desc_count); + producer = get_next_index(producer, num_txd); if (more_hdr) { hwdesc = &hw->cmd_desc_head[producer]; @@ -1147,35 +1101,19 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) hwdesc, (hdr_len - first_hdr_len)); - producer = get_next_index(producer, max_tx_desc_count); + producer = get_next_index(producer, num_txd); } } - spin_lock_bh(&adapter->tx_lock); + adapter->cmd_producer = producer; adapter->stats.txbytes += skb->len; - /* Code to update the adapter considering how many producer threads - are currently working */ - if ((--adapter->num_threads) == 0) { - /* This is the last thread */ - u32 crb_producer = adapter->cmd_producer; - netxen_nic_update_cmd_producer(adapter, crb_producer); - wmb(); - adapter->total_threads = 0; - } + netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer); - adapter->stats.xmitfinished++; + adapter->stats.xmitcalled++; netdev->trans_start = jiffies; - spin_unlock_bh(&adapter->tx_lock); return NETDEV_TX_OK; - -out_requeue: - netif_stop_queue(netdev); - adapter->flags |= NETXEN_NETDEV_STATUS; - - spin_unlock_bh(&adapter->tx_lock); - return NETDEV_TX_BUSY; } static void netxen_watchdog(unsigned long v) @@ -1200,87 +1138,60 @@ static void netxen_tx_timeout_task(struct work_struct *work) printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", netxen_nic_driver_name, adapter->netdev->name); - netxen_nic_close(adapter->netdev); - netxen_nic_open(adapter->netdev); + netxen_nic_disable_int(adapter); + napi_disable(&adapter->napi); + adapter->netdev->trans_start = jiffies; + + napi_enable(&adapter->napi); + netxen_nic_enable_int(adapter); netif_wake_queue(adapter->netdev); } -static int -netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) +static inline void +netxen_handle_int(struct netxen_adapter *adapter) { - u32 ret = 0; - - DPRINTK(INFO, "Entered handle ISR\n"); - adapter->stats.ints++; - netxen_nic_disable_int(adapter); - - if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) { - if (netif_rx_schedule_prep(netdev, &adapter->napi)) { - /* - * Interrupts are already disabled. - */ - __netif_rx_schedule(netdev, &adapter->napi); - } else { - static unsigned int intcount = 0; - if ((++intcount & 0xfff) == 0xfff) - DPRINTK(KERN_ERR - "%s: %s interrupt %d while in poll\n", - netxen_nic_driver_name, netdev->name, - intcount); - } - ret = 1; - } - - if (ret == 0) { - netxen_nic_enable_int(adapter); - } - - return ret; + napi_schedule(&adapter->napi); } -/* - * netxen_intr - Interrupt Handler - * @irq: interrupt number - * data points to adapter stucture (which may be handling more than 1 port - */ irqreturn_t netxen_intr(int irq, void *data) { struct netxen_adapter *adapter = data; - struct net_device *netdev = adapter->netdev; u32 our_int = 0; - if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { - our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); - /* not our interrupt */ - if ((our_int & (0x80 << adapter->portnum)) == 0) - return IRQ_NONE; - } + our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); + /* not our interrupt */ + if ((our_int & (0x80 << adapter->portnum)) == 0) + return IRQ_NONE; if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { /* claim interrupt */ - if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { - writel(our_int & ~((u32)(0x80 << adapter->portnum)), + writel(our_int & ~((u32)(0x80 << adapter->portnum)), NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); - } } - if (netif_running(netdev)) - netxen_handle_int(adapter, netdev); + netxen_handle_int(adapter); return IRQ_HANDLED; } +irqreturn_t netxen_msi_intr(int irq, void *data) +{ + struct netxen_adapter *adapter = data; + + netxen_handle_int(adapter); + return IRQ_HANDLED; +} + static int netxen_nic_poll(struct napi_struct *napi, int budget) { struct netxen_adapter *adapter = container_of(napi, struct netxen_adapter, napi); - struct net_device *netdev = adapter->netdev; - int done = 1; + int tx_complete; int ctx; int work_done; - DPRINTK(INFO, "polling for %d descriptors\n", *budget); + tx_complete = netxen_process_cmd_ring(adapter); work_done = 0; for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { @@ -1300,16 +1211,8 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) budget / MAX_RCV_CTX); } - if (work_done >= budget) - done = 0; - - if (netxen_process_cmd_ring((unsigned long)adapter) == 0) - done = 0; - - DPRINTK(INFO, "new work_done: %d work_to_do: %d\n", - work_done, work_to_do); - if (done) { - netif_rx_complete(netdev, napi); + if ((work_done < budget) && tx_complete) { + netif_rx_complete(adapter->netdev, &adapter->napi); netxen_nic_enable_int(adapter); } diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h index ffa3b7215ce..a566b50f36f 100644 --- a/drivers/net/netxen/netxen_nic_phan_reg.h +++ b/drivers/net/netxen/netxen_nic_phan_reg.h @@ -126,8 +126,11 @@ */ #define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8) #define CRB_NIC_CAPABILITIES_FW NETXEN_NIC_REG(0x1dc) +#define CRB_NIC_MSI_MODE_HOST NETXEN_NIC_REG(0x270) +#define CRB_NIC_MSI_MODE_FW NETXEN_NIC_REG(0x274) #define INTR_SCHEME_PERPORT 0x1 +#define MSI_MODE_MULTIFUNC 0x1 /* used for ethtool tests */ #define CRB_SCRATCHPAD_TEST NETXEN_NIC_REG(0x280) diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index e8a63e483a2..ce95c5d168f 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -1268,7 +1268,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id) } } - if (interrupts && ei_debug) + if (interrupts && ei_debug > 3) { handled = 1; if (nr_serviced >= MAX_SERVICE) diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index f4ca0591231..3ac8529bb92 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -67,6 +67,7 @@ config REALTEK_PHY config FIXED_PHY bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs" + depends on PHYLIB=y ---help--- Adds the platform "fixed" MDIO Bus to cover the boards that use PHYs that are not connected to the real MDIO bus. diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c index 7ed632db00d..d926168bc78 100644 --- a/drivers/net/phy/davicom.c +++ b/drivers/net/phy/davicom.c @@ -37,6 +37,7 @@ #define MII_DM9161_SCR 0x10 #define MII_DM9161_SCR_INIT 0x0610 +#define MII_DM9161_SCR_RMII 0x0100 /* DM9161 Interrupt Register */ #define MII_DM9161_INTR 0x15 @@ -103,7 +104,7 @@ static int dm9161_config_aneg(struct phy_device *phydev) static int dm9161_config_init(struct phy_device *phydev) { - int err; + int err, temp; /* Isolate the PHY */ err = phy_write(phydev, MII_BMCR, BMCR_ISOLATE); @@ -111,9 +112,19 @@ static int dm9161_config_init(struct phy_device *phydev) if (err < 0) return err; - /* Do not bypass the scrambler/descrambler */ - err = phy_write(phydev, MII_DM9161_SCR, MII_DM9161_SCR_INIT); + switch (phydev->interface) { + case PHY_INTERFACE_MODE_MII: + temp = MII_DM9161_SCR_INIT; + break; + case PHY_INTERFACE_MODE_RMII: + temp = MII_DM9161_SCR_INIT | MII_DM9161_SCR_RMII; + break; + default: + return -EINVAL; + } + /* Do not bypass the scrambler/descrambler */ + err = phy_write(phydev, MII_DM9161_SCR, temp); if (err < 0) return err; diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index f0574073a2a..33539917e9b 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -58,9 +58,25 @@ #define MII_M1111_RX_DELAY 0x80 #define MII_M1111_TX_DELAY 0x2 #define MII_M1111_PHY_EXT_SR 0x1b -#define MII_M1111_HWCFG_MODE_MASK 0xf -#define MII_M1111_HWCFG_MODE_RGMII 0xb + +#define MII_M1111_HWCFG_MODE_MASK 0xf +#define MII_M1111_HWCFG_MODE_COPPER_RGMII 0xb +#define MII_M1111_HWCFG_MODE_FIBER_RGMII 0x3 #define MII_M1111_HWCFG_MODE_SGMII_NO_CLK 0x4 +#define MII_M1111_HWCFG_FIBER_COPPER_AUTO 0x8000 +#define MII_M1111_HWCFG_FIBER_COPPER_RES 0x2000 + +#define MII_M1111_COPPER 0 +#define MII_M1111_FIBER 1 + +#define MII_M1011_PHY_STATUS 0x11 +#define MII_M1011_PHY_STATUS_1000 0x8000 +#define MII_M1011_PHY_STATUS_100 0x4000 +#define MII_M1011_PHY_STATUS_SPD_MASK 0xc000 +#define MII_M1011_PHY_STATUS_FULLDUPLEX 0x2000 +#define MII_M1011_PHY_STATUS_RESOLVED 0x0800 +#define MII_M1011_PHY_STATUS_LINK 0x0400 + MODULE_DESCRIPTION("Marvell PHY driver"); MODULE_AUTHOR("Andy Fleming"); @@ -141,12 +157,22 @@ static int marvell_config_aneg(struct phy_device *phydev) static int m88e1111_config_init(struct phy_device *phydev) { int err; + int temp; + int mode; + + /* Enable Fiber/Copper auto selection */ + temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); + temp |= MII_M1111_HWCFG_FIBER_COPPER_AUTO; + phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); + + temp = phy_read(phydev, MII_BMCR); + temp |= BMCR_RESET; + phy_write(phydev, MII_BMCR, temp); if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) { - int temp; temp = phy_read(phydev, MII_M1111_PHY_EXT_CR); if (temp < 0) @@ -171,7 +197,13 @@ static int m88e1111_config_init(struct phy_device *phydev) return temp; temp &= ~(MII_M1111_HWCFG_MODE_MASK); - temp |= MII_M1111_HWCFG_MODE_RGMII; + + mode = phy_read(phydev, MII_M1111_PHY_EXT_CR); + + if (mode & MII_M1111_HWCFG_FIBER_COPPER_RES) + temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII; + else + temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII; err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); if (err < 0) @@ -262,6 +294,93 @@ static int m88e1145_config_init(struct phy_device *phydev) return 0; } +/* marvell_read_status + * + * Generic status code does not detect Fiber correctly! + * Description: + * Check the link, then figure out the current state + * by comparing what we advertise with what the link partner + * advertises. Start by checking the gigabit possibilities, + * then move on to 10/100. + */ +static int marvell_read_status(struct phy_device *phydev) +{ + int adv; + int err; + int lpa; + int status = 0; + + /* Update the link, but return if there + * was an error */ + err = genphy_update_link(phydev); + if (err) + return err; + + if (AUTONEG_ENABLE == phydev->autoneg) { + status = phy_read(phydev, MII_M1011_PHY_STATUS); + if (status < 0) + return status; + + lpa = phy_read(phydev, MII_LPA); + if (lpa < 0) + return lpa; + + adv = phy_read(phydev, MII_ADVERTISE); + if (adv < 0) + return adv; + + lpa &= adv; + + if (status & MII_M1011_PHY_STATUS_FULLDUPLEX) + phydev->duplex = DUPLEX_FULL; + else + phydev->duplex = DUPLEX_HALF; + + status = status & MII_M1011_PHY_STATUS_SPD_MASK; + phydev->pause = phydev->asym_pause = 0; + + switch (status) { + case MII_M1011_PHY_STATUS_1000: + phydev->speed = SPEED_1000; + break; + + case MII_M1011_PHY_STATUS_100: + phydev->speed = SPEED_100; + break; + + default: + phydev->speed = SPEED_10; + break; + } + + if (phydev->duplex == DUPLEX_FULL) { + phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; + phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; + } + } else { + int bmcr = phy_read(phydev, MII_BMCR); + + if (bmcr < 0) + return bmcr; + + if (bmcr & BMCR_FULLDPLX) + phydev->duplex = DUPLEX_FULL; + else + phydev->duplex = DUPLEX_HALF; + + if (bmcr & BMCR_SPEED1000) + phydev->speed = SPEED_1000; + else if (bmcr & BMCR_SPEED100) + phydev->speed = SPEED_100; + else + phydev->speed = SPEED_10; + + phydev->pause = phydev->asym_pause = 0; + } + + return 0; +} + static struct phy_driver marvell_drivers[] = { { .phy_id = 0x01410c60, @@ -296,7 +415,7 @@ static struct phy_driver marvell_drivers[] = { .flags = PHY_HAS_INTERRUPT, .config_init = &m88e1111_config_init, .config_aneg = &marvell_config_aneg, - .read_status = &genphy_read_status, + .read_status = &marvell_read_status, .ack_interrupt = &marvell_ack_interrupt, .config_intr = &marvell_config_intr, .driver = { .owner = THIS_MODULE }, diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index e0b072d9fdb..3d10ca050b7 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -302,14 +302,14 @@ pppol2tp_session_find(struct pppol2tp_tunnel *tunnel, u16 session_id) struct pppol2tp_session *session; struct hlist_node *walk; - read_lock(&tunnel->hlist_lock); + read_lock_bh(&tunnel->hlist_lock); hlist_for_each_entry(session, walk, session_list, hlist) { if (session->tunnel_addr.s_session == session_id) { - read_unlock(&tunnel->hlist_lock); + read_unlock_bh(&tunnel->hlist_lock); return session; } } - read_unlock(&tunnel->hlist_lock); + read_unlock_bh(&tunnel->hlist_lock); return NULL; } @@ -320,14 +320,14 @@ static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id) { struct pppol2tp_tunnel *tunnel = NULL; - read_lock(&pppol2tp_tunnel_list_lock); + read_lock_bh(&pppol2tp_tunnel_list_lock); list_for_each_entry(tunnel, &pppol2tp_tunnel_list, list) { if (tunnel->stats.tunnel_id == tunnel_id) { - read_unlock(&pppol2tp_tunnel_list_lock); + read_unlock_bh(&pppol2tp_tunnel_list_lock); return tunnel; } } - read_unlock(&pppol2tp_tunnel_list_lock); + read_unlock_bh(&pppol2tp_tunnel_list_lock); return NULL; } @@ -342,10 +342,11 @@ static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id) static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_buff *skb) { struct sk_buff *skbp; + struct sk_buff *tmp; u16 ns = PPPOL2TP_SKB_CB(skb)->ns; - spin_lock(&session->reorder_q.lock); - skb_queue_walk(&session->reorder_q, skbp) { + spin_lock_bh(&session->reorder_q.lock); + skb_queue_walk_safe(&session->reorder_q, skbp, tmp) { if (PPPOL2TP_SKB_CB(skbp)->ns > ns) { __skb_insert(skb, skbp->prev, skbp, &session->reorder_q); PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG, @@ -360,7 +361,7 @@ static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_ __skb_queue_tail(&session->reorder_q, skb); out: - spin_unlock(&session->reorder_q.lock); + spin_unlock_bh(&session->reorder_q.lock); } /* Dequeue a single skb. @@ -371,10 +372,9 @@ static void pppol2tp_recv_dequeue_skb(struct pppol2tp_session *session, struct s int length = PPPOL2TP_SKB_CB(skb)->length; struct sock *session_sock = NULL; - /* We're about to requeue the skb, so unlink it and return resources + /* We're about to requeue the skb, so return resources * to its current owner (a socket receive buffer). */ - skb_unlink(skb, &session->reorder_q); skb_orphan(skb); tunnel->stats.rx_packets++; @@ -442,7 +442,7 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session) * expect to send up next, dequeue it and any other * in-sequence packets behind it. */ - spin_lock(&session->reorder_q.lock); + spin_lock_bh(&session->reorder_q.lock); skb_queue_walk_safe(&session->reorder_q, skb, tmp) { if (time_after(jiffies, PPPOL2TP_SKB_CB(skb)->expires)) { session->stats.rx_seq_discards++; @@ -455,6 +455,7 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session) skb_queue_len(&session->reorder_q)); __skb_unlink(skb, &session->reorder_q); kfree_skb(skb); + sock_put(session->sock); continue; } @@ -469,13 +470,18 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session) goto out; } } - spin_unlock(&session->reorder_q.lock); + __skb_unlink(skb, &session->reorder_q); + + /* Process the skb. We release the queue lock while we + * do so to let other contexts process the queue. + */ + spin_unlock_bh(&session->reorder_q.lock); pppol2tp_recv_dequeue_skb(session, skb); - spin_lock(&session->reorder_q.lock); + spin_lock_bh(&session->reorder_q.lock); } out: - spin_unlock(&session->reorder_q.lock); + spin_unlock_bh(&session->reorder_q.lock); } /* Internal receive frame. Do the real work of receiving an L2TP data frame @@ -1058,7 +1064,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) /* Get routing info from the tunnel socket */ dst_release(skb->dst); - skb->dst = sk_dst_get(sk_tun); + skb->dst = dst_clone(__sk_dst_get(sk_tun)); skb_orphan(skb); skb->sk = sk_tun; @@ -1106,10 +1112,12 @@ static void pppol2tp_tunnel_closeall(struct pppol2tp_tunnel *tunnel) PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, "%s: closing all sessions...\n", tunnel->name); - write_lock(&tunnel->hlist_lock); + write_lock_bh(&tunnel->hlist_lock); for (hash = 0; hash < PPPOL2TP_HASH_SIZE; hash++) { again: hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) { + struct sk_buff *skb; + session = hlist_entry(walk, struct pppol2tp_session, hlist); sk = session->sock; @@ -1126,7 +1134,7 @@ again: * disappear as we're jumping between locks. */ sock_hold(sk); - write_unlock(&tunnel->hlist_lock); + write_unlock_bh(&tunnel->hlist_lock); lock_sock(sk); if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) { @@ -1138,7 +1146,10 @@ again: /* Purge any queued data */ skb_queue_purge(&sk->sk_receive_queue); skb_queue_purge(&sk->sk_write_queue); - skb_queue_purge(&session->reorder_q); + while ((skb = skb_dequeue(&session->reorder_q))) { + kfree_skb(skb); + sock_put(sk); + } release_sock(sk); sock_put(sk); @@ -1148,11 +1159,11 @@ again: * list so we are guaranteed to make forward * progress. */ - write_lock(&tunnel->hlist_lock); + write_lock_bh(&tunnel->hlist_lock); goto again; } } - write_unlock(&tunnel->hlist_lock); + write_unlock_bh(&tunnel->hlist_lock); } /* Really kill the tunnel. @@ -1161,9 +1172,9 @@ again: static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel) { /* Remove from socket list */ - write_lock(&pppol2tp_tunnel_list_lock); + write_lock_bh(&pppol2tp_tunnel_list_lock); list_del_init(&tunnel->list); - write_unlock(&pppol2tp_tunnel_list_lock); + write_unlock_bh(&pppol2tp_tunnel_list_lock); atomic_dec(&pppol2tp_tunnel_count); kfree(tunnel); @@ -1239,9 +1250,9 @@ static void pppol2tp_session_destruct(struct sock *sk) /* Delete the session socket from the * hash */ - write_lock(&tunnel->hlist_lock); + write_lock_bh(&tunnel->hlist_lock); hlist_del_init(&session->hlist); - write_unlock(&tunnel->hlist_lock); + write_unlock_bh(&tunnel->hlist_lock); atomic_dec(&pppol2tp_session_count); } @@ -1386,9 +1397,9 @@ static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id, /* Add tunnel to our list */ INIT_LIST_HEAD(&tunnel->list); - write_lock(&pppol2tp_tunnel_list_lock); + write_lock_bh(&pppol2tp_tunnel_list_lock); list_add(&tunnel->list, &pppol2tp_tunnel_list); - write_unlock(&pppol2tp_tunnel_list_lock); + write_unlock_bh(&pppol2tp_tunnel_list_lock); atomic_inc(&pppol2tp_tunnel_count); /* Bump the reference count. The tunnel context is deleted @@ -1593,11 +1604,11 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, sk->sk_user_data = session; /* Add session to the tunnel's hash list */ - write_lock(&tunnel->hlist_lock); + write_lock_bh(&tunnel->hlist_lock); hlist_add_head(&session->hlist, pppol2tp_session_id_hash(tunnel, session->tunnel_addr.s_session)); - write_unlock(&tunnel->hlist_lock); + write_unlock_bh(&tunnel->hlist_lock); atomic_inc(&pppol2tp_session_count); @@ -2199,7 +2210,7 @@ static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, str int next = 0; int i; - read_lock(&tunnel->hlist_lock); + read_lock_bh(&tunnel->hlist_lock); for (i = 0; i < PPPOL2TP_HASH_SIZE; i++) { hlist_for_each_entry(session, walk, &tunnel->session_hlist[i], hlist) { if (curr == NULL) { @@ -2217,7 +2228,7 @@ static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, str } } out: - read_unlock(&tunnel->hlist_lock); + read_unlock_bh(&tunnel->hlist_lock); if (!found) session = NULL; @@ -2228,13 +2239,13 @@ static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_tunnel *curr) { struct pppol2tp_tunnel *tunnel = NULL; - read_lock(&pppol2tp_tunnel_list_lock); + read_lock_bh(&pppol2tp_tunnel_list_lock); if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) { goto out; } tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list); out: - read_unlock(&pppol2tp_tunnel_list_lock); + read_unlock_bh(&pppol2tp_tunnel_list_lock); return tunnel; } diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index daf5abab953..ddbc6e475e2 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c @@ -1644,13 +1644,24 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl) } /* put them in the newtork_list */ - scan_info = wl->buf; - scan_info_size = 0; - i = 0; - while (scan_info_size < data_len) { + for (i = 0, scan_info_size = 0, scan_info = wl->buf; + scan_info_size < data_len; + i++, scan_info_size += be16_to_cpu(scan_info->size), + scan_info = (void *)scan_info + be16_to_cpu(scan_info->size)) { pr_debug("%s:size=%d bssid=%s scan_info=%p\n", __func__, be16_to_cpu(scan_info->size), print_mac(mac, &scan_info->bssid[2]), scan_info); + + /* + * The wireless firmware may return invalid channel 0 and/or + * invalid rate if the AP emits zero length SSID ie. As this + * scan information is useless, ignore it + */ + if (!be16_to_cpu(scan_info->channel) || !scan_info->rate[0]) { + pr_debug("%s: invalid scan info\n", __func__); + continue; + } + found = 0; oldest = NULL; list_for_each_entry(target, &wl->network_list, list) { @@ -1687,10 +1698,6 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl) GFP_KERNEL); if (!target->hwinfo) { pr_info("%s: kzalloc failed\n", __func__); - i++; - scan_info_size += be16_to_cpu(scan_info->size); - scan_info = (void *)scan_info + - be16_to_cpu(scan_info->size); continue; } /* copy hw scan info */ @@ -1709,10 +1716,6 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl) if (scan_info->ext_rate[r]) target->rate_ext_len++; list_move_tail(&target->list, &wl->network_list); - /* bump pointer */ - i++; - scan_info_size += be16_to_cpu(scan_info->size); - scan_info = (void *)scan_info + be16_to_cpu(scan_info->size); } memset(&data, 0, sizeof(data)); wireless_send_event(port_to_netdev(wl_port(wl)), SIOCGIWSCAN, &data, @@ -2389,6 +2392,8 @@ static struct net_device *gelic_wl_alloc(struct gelic_card *card) if (!netdev) return NULL; + strcpy(netdev->name, "wlan%d"); + port = netdev_priv(netdev); port->netdev = netdev; port->card = card; diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 19184e486ae..169edc15492 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -239,7 +239,8 @@ static void r6040_free_txbufs(struct net_device *dev) for (i = 0; i < TX_DCNT; i++) { if (lp->tx_insert_ptr->skb_ptr) { - pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf, + pci_unmap_single(lp->pdev, + le32_to_cpu(lp->tx_insert_ptr->buf), MAX_BUF_SIZE, PCI_DMA_TODEVICE); dev_kfree_skb(lp->tx_insert_ptr->skb_ptr); lp->rx_insert_ptr->skb_ptr = NULL; @@ -255,7 +256,8 @@ static void r6040_free_rxbufs(struct net_device *dev) for (i = 0; i < RX_DCNT; i++) { if (lp->rx_insert_ptr->skb_ptr) { - pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf, + pci_unmap_single(lp->pdev, + le32_to_cpu(lp->rx_insert_ptr->buf), MAX_BUF_SIZE, PCI_DMA_FROMDEVICE); dev_kfree_skb(lp->rx_insert_ptr->skb_ptr); lp->rx_insert_ptr->skb_ptr = NULL; @@ -542,7 +544,7 @@ static int r6040_rx(struct net_device *dev, int limit) skb_ptr->dev = priv->dev; /* Do not count the CRC */ skb_put(skb_ptr, descptr->len - 4); - pci_unmap_single(priv->pdev, descptr->buf, + pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf), MAX_BUF_SIZE, PCI_DMA_FROMDEVICE); skb_ptr->protocol = eth_type_trans(skb_ptr, priv->dev); /* Send to upper layer */ @@ -585,7 +587,7 @@ static void r6040_tx(struct net_device *dev) if (descptr->status & 0x8000) break; /* Not complete */ skb_ptr = descptr->skb_ptr; - pci_unmap_single(priv->pdev, descptr->buf, + pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf), skb_ptr->len, PCI_DMA_TODEVICE); /* Free buffer */ dev_kfree_skb_irq(skb_ptr); diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 6179a0a2032..3c915b82e19 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -1088,7 +1088,7 @@ static int s2io_print_pci_mode(struct s2io_nic *nic) * '-1' on failure */ -int init_tti(struct s2io_nic *nic, int link) +static int init_tti(struct s2io_nic *nic, int link) { struct XENA_dev_config __iomem *bar0 = nic->bar0; register u64 val64 = 0; @@ -4172,6 +4172,9 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) dev->trans_start = jiffies; spin_unlock_irqrestore(&fifo->tx_lock, flags); + if (sp->config.intr_type == MSI_X) + tx_intr_handler(fifo); + return 0; pci_map_failed: stats->pci_map_fail_cnt++; diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 186eb8ebfda..2e26dced13a 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -3199,12 +3199,14 @@ static int skge_poll(struct napi_struct *napi, int to_do) skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), CSR_START); if (work_done < to_do) { - spin_lock_irq(&hw->hw_lock); + unsigned long flags; + + spin_lock_irqsave(&hw->hw_lock, flags); __netif_rx_complete(dev, napi); hw->intr_mask |= napimask[skge->port]; skge_write32(hw, B0_IMSK, hw->intr_mask); skge_read32(hw, B0_IMSK); - spin_unlock_irq(&hw->hw_lock); + spin_unlock_irqrestore(&hw->hw_lock, flags); } return work_done; diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 51d4134b37b..98a832a7553 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -92,14 +92,14 @@ #define SMC_insw(a, r, p, l) insw ((unsigned long *)((a) + (r)), p, l) # endif /* check if the mac in reg is valid */ -#define SMC_GET_MAC_ADDR(addr) \ +#define SMC_GET_MAC_ADDR(lp, addr) \ do { \ unsigned int __v; \ - __v = SMC_inw(ioaddr, ADDR0_REG); \ + __v = SMC_inw(ioaddr, ADDR0_REG(lp)); \ addr[0] = __v; addr[1] = __v >> 8; \ - __v = SMC_inw(ioaddr, ADDR1_REG); \ + __v = SMC_inw(ioaddr, ADDR1_REG(lp)); \ addr[2] = __v; addr[3] = __v >> 8; \ - __v = SMC_inw(ioaddr, ADDR2_REG); \ + __v = SMC_inw(ioaddr, ADDR2_REG(lp)); \ addr[4] = __v; addr[5] = __v >> 8; \ if (*(u32 *)(&addr[0]) == 0xFFFFFFFF) { \ random_ether_addr(addr); \ diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 97212799c51..4291458955e 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -912,7 +912,7 @@ static int gem_poll(struct napi_struct *napi, int budget) * rx ring - must call napi_disable(), which * schedule_timeout()'s if polling is already disabled. */ - work_done += gem_rx(gp, budget); + work_done += gem_rx(gp, budget - work_done); if (work_done >= budget) return work_done; diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 26ffb67f1da..f9ef8bd8b11 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -64,8 +64,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.87" -#define DRV_MODULE_RELDATE "December 20, 2007" +#define DRV_MODULE_VERSION "3.88" +#define DRV_MODULE_RELDATE "March 20, 2008" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -11841,7 +11841,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) } if (!is_valid_ether_addr(&dev->dev_addr[0])) { -#ifdef CONFIG_SPARC64 +#ifdef CONFIG_SPARC if (!tg3_get_default_macaddr_sparc(tp)) return 0; #endif diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index 8909050b8ea..5f1c5072b96 100644 --- a/drivers/net/tokenring/smctr.c +++ b/drivers/net/tokenring/smctr.c @@ -3413,7 +3413,7 @@ static int smctr_make_tx_status_code(struct net_device *dev, tsv->svi = TRANSMIT_STATUS_CODE; tsv->svl = S_TRANSMIT_STATUS_CODE; - tsv->svv[0] = ((tx_fstatus & 0x0100 >> 6) || IBM_PASS_SOURCE_ADDR); + tsv->svv[0] = ((tx_fstatus & 0x0100 >> 6) | IBM_PASS_SOURCE_ADDR); /* Stripped frame status of Transmitted Frame */ tsv->svv[1] = tx_fstatus & 0xff; diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 77d9dd7ea34..1b5edd646a8 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -842,7 +842,7 @@ static inline int de_is_running (struct de_private *de) static void de_stop_rxtx (struct de_private *de) { u32 macmode; - unsigned int work = 1000; + unsigned int i = 1300/100; macmode = dr32(MacMode); if (macmode & RxTx) { @@ -850,10 +850,14 @@ static void de_stop_rxtx (struct de_private *de) dr32(MacMode); } - while (--work > 0) { + /* wait until in-flight frame completes. + * Max time @ 10BT: 1500*8b/10Mbps == 1200us (+ 100us margin) + * Typically expect this loop to end in < 50 us on 100BT. + */ + while (--i) { if (!de_is_running(de)) return; - cpu_relax(); + udelay(100); } printk(KERN_WARNING "%s: timeout expired stopping DMA\n", de->dev->name); @@ -910,7 +914,8 @@ static void de_set_media (struct de_private *de) unsigned media = de->media_type; u32 macmode = dr32(MacMode); - BUG_ON(de_is_running(de)); + if (de_is_running(de)) + printk(KERN_WARNING "%s: chip is running while changing media!\n", de->dev->name); if (de->de21040) dw32(CSR11, FULL_DUPLEX_MAGIC); diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 038c1ef94d2..7b816a03295 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -663,7 +663,11 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file, case SIOCSIFHWADDR: { /* try to set the actual net device's hw address */ - int ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr); + int ret; + + rtnl_lock(); + ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr); + rtnl_unlock(); if (ret == 0) { /** Set the character device's hardware address. This is used when diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index fba0811d260..8cc316653a3 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -154,8 +154,8 @@ static struct ucc_geth_info ugeth_primary_info = { .rxQoSMode = UCC_GETH_QOS_MODE_DEFAULT, .aufc = UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE, .padAndCrc = MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC, - .numThreadsTx = UCC_GETH_NUM_OF_THREADS_4, - .numThreadsRx = UCC_GETH_NUM_OF_THREADS_4, + .numThreadsTx = UCC_GETH_NUM_OF_THREADS_1, + .numThreadsRx = UCC_GETH_NUM_OF_THREADS_1, .riscTx = QE_RISC_ALLOCATION_RISC1_AND_RISC2, .riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2, }; @@ -3975,6 +3975,8 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ug_info->uf_info.utfs = UCC_GETH_UTFS_GIGA_INIT; ug_info->uf_info.utfet = UCC_GETH_UTFET_GIGA_INIT; ug_info->uf_info.utftt = UCC_GETH_UTFTT_GIGA_INIT; + ug_info->numThreadsTx = UCC_GETH_NUM_OF_THREADS_4; + ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4; } /* Set the bus id */ diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 4b131a6c6b7..0343b00cf1f 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -341,7 +341,7 @@ static void dm9601_set_multicast(struct net_device *net) /* We use the 20 byte dev->data for our 8 byte filter buffer * to avoid allocating memory that is tricky to free later */ u8 *hashes = (u8 *) & dev->data; - u8 rx_ctl = 0x01; + u8 rx_ctl = 0x31; memset(hashes, 0x00, DM_MCAST_SIZE); hashes[DM_MCAST_SIZE - 1] |= 0x80; /* broadcast address */ @@ -562,6 +562,10 @@ static const struct usb_device_id products[] = { USB_DEVICE(0x0a46, 0x8515), /* ADMtek ADM8515 USB NIC */ .driver_info = (unsigned long)&dm9601_info, }, + { + USB_DEVICE(0x0a47, 0x9601), /* Hirose USB-100 */ + .driver_info = (unsigned long)&dm9601_info, + }, {}, // END }; diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index a61324757b1..369c731114b 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c @@ -16,10 +16,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -// #define DEBUG // error path messages, extra info -// #define VERBOSE // more; success messages - #include <linux/module.h> #include <linux/init.h> #include <linux/netdevice.h> @@ -287,7 +283,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) struct rndis_set_c *set_c; struct rndis_halt *halt; } u; - u32 tmp, *phym; + u32 tmp, phym_unspec, *phym; int reply_len; unsigned char *bp; @@ -318,6 +314,14 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) net->hard_header_len += sizeof (struct rndis_data_hdr); dev->hard_mtu = net->mtu + net->hard_header_len; + dev->maxpacket = usb_maxpacket(dev->udev, dev->out, 1); + if (dev->maxpacket == 0) { + if (netif_msg_probe(dev)) + dev_dbg(&intf->dev, "dev->maxpacket can't be 0\n"); + retval = -EINVAL; + goto fail_and_release; + } + dev->rx_urb_size = dev->hard_mtu + (dev->maxpacket + 1); dev->rx_urb_size &= ~(dev->maxpacket - 1); u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size); @@ -359,12 +363,15 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) goto halt_fail_and_release; /* Check physical medium */ + phym = NULL; reply_len = sizeof *phym; retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM, 0, (void **) &phym, &reply_len); - if (retval != 0) + if (retval != 0 || !phym) { /* OID is optional so don't fail here. */ - *phym = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED; + phym_unspec = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED; + phym = &phym_unspec; + } if ((flags & FLAG_RNDIS_PHYM_WIRELESS) && *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { if (netif_msg_probe(dev)) diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index 7e1f00131f9..df56a518691 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -376,7 +376,7 @@ static int alloc_all_urbs(rtl8150_t * dev) return 0; } dev->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!dev->intr_urb) { + if (!dev->ctrl_urb) { usb_free_urb(dev->rx_urb); usb_free_urb(dev->tx_urb); usb_free_urb(dev->intr_urb); diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 19fd4cb0ddf..b58472cf76f 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -203,8 +203,11 @@ again: if (received < budget) { netif_rx_complete(vi->dev, napi); if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq)) - && netif_rx_reschedule(vi->dev, napi)) + && napi_schedule_prep(napi)) { + vi->rvq->vq_ops->disable_cb(vi->rvq); + __netif_rx_schedule(vi->dev, napi); goto again; + } } return received; @@ -278,10 +281,11 @@ again: pr_debug("%s: virtio not prepared to send\n", dev->name); netif_stop_queue(dev); - /* Activate callback for using skbs: if this fails it + /* Activate callback for using skbs: if this returns false it * means some were used in the meantime. */ if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { - printk("Unlikely: restart svq failed\n"); + printk("Unlikely: restart svq race\n"); + vi->svq->vq_ops->disable_cb(vi->svq); netif_start_queue(dev); goto again; } @@ -294,6 +298,15 @@ again: return 0; } +#ifdef CONFIG_NET_POLL_CONTROLLER +static void virtnet_netpoll(struct net_device *dev) +{ + struct virtnet_info *vi = netdev_priv(dev); + + napi_schedule(&vi->napi); +} +#endif + static int virtnet_open(struct net_device *dev) { struct virtnet_info *vi = netdev_priv(dev); @@ -336,6 +349,9 @@ static int virtnet_probe(struct virtio_device *vdev) dev->stop = virtnet_close; dev->hard_start_xmit = start_xmit; dev->features = NETIF_F_HIGHDMA; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = virtnet_netpoll; +#endif SET_NETDEV_DEV(dev, &vdev->dev); /* Do we support "hardware" checksums? */ diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index cf27bf40d36..547368e9633 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c @@ -2024,6 +2024,7 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) struct fstioc_write wrthdr; struct fstioc_info info; unsigned long flags; + void *buf; dbg(DBG_IOCTL, "ioctl: %x, %p\n", cmd, ifr->ifr_data); @@ -2065,16 +2066,22 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return -ENXIO; } - /* Now copy the data to the card. - * This will probably break on some architectures. - * I'll fix it when I have something to test on. - */ - if (copy_from_user(card->mem + wrthdr.offset, + /* Now copy the data to the card. */ + + buf = kmalloc(wrthdr.size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + if (copy_from_user(buf, ifr->ifr_data + sizeof (struct fstioc_write), wrthdr.size)) { + kfree(buf); return -EFAULT; } + memcpy_toio(card->mem + wrthdr.offset, buf, wrthdr.size); + kfree(buf); + /* Writes to the memory of a card in the reset state constitute * a download */ diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index 15d5c58e57b..e59255a155a 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c @@ -751,7 +751,7 @@ upload_data( struct net_device *dev, unsigned framelen, unsigned frameno, } -static __inline void +static inline void send_complete( struct net_local *nl ) { #ifdef CONFIG_SBNI_MULTILINE diff --git a/drivers/net/wireless/arlan-proc.c b/drivers/net/wireless/arlan-proc.c index c6e70dbc5de..2ab1d59870f 100644 --- a/drivers/net/wireless/arlan-proc.c +++ b/drivers/net/wireless/arlan-proc.c @@ -1202,13 +1202,6 @@ static ctl_table arlan_table[MAX_ARLANS + 1] = { .ctl_name = 0 } }; #endif -#else - -static ctl_table arlan_table[MAX_ARLANS + 1] = -{ - { .ctl_name = 0 } -}; -#endif // static int mmtu = 1234; @@ -1233,7 +1226,6 @@ static ctl_table arlan_root_table[] = //}; -#ifdef CONFIG_PROC_FS static struct ctl_table_header *arlan_device_sysctl_header; int __init init_arlan_proc(void) diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c index c2de2d958e8..01757436353 100644 --- a/drivers/net/wireless/ath5k/hw.c +++ b/drivers/net/wireless/ath5k/hw.c @@ -427,6 +427,8 @@ void ath5k_hw_detach(struct ath5k_hw *ah) { ATH5K_TRACE(ah->ah_sc); + __set_bit(ATH_STAT_INVALID, ah->ah_sc->status); + if (ah->ah_rf_banks != NULL) kfree(ah->ah_rf_banks); diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c index e38ed0fe72e..7fca2ebc747 100644 --- a/drivers/net/wireless/b43/debugfs.c +++ b/drivers/net/wireless/b43/debugfs.c @@ -618,6 +618,7 @@ void b43_debugfs_remove_device(struct b43_wldev *dev) kfree(e); } +/* Called with IRQs disabled. */ void b43_debugfs_log_txstat(struct b43_wldev *dev, const struct b43_txstatus *status) { @@ -629,8 +630,7 @@ void b43_debugfs_log_txstat(struct b43_wldev *dev, if (!e) return; log = &e->txstatlog; - B43_WARN_ON(!irqs_disabled()); - spin_lock(&log->lock); + spin_lock(&log->lock); /* IRQs are already disabled. */ i = log->end + 1; if (i == B43_NR_LOGGED_TXSTATUS) i = 0; diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 3dfb28a34be..cfbc1a26f60 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -560,7 +560,7 @@ static int b43_dmacontroller_tx_reset(struct b43_wldev *dev, u16 mmio_base, /* Check if a DMA mapping address is invalid. */ static bool b43_dma_mapping_error(struct b43_dmaring *ring, dma_addr_t addr, - size_t buffersize) + size_t buffersize, bool dma_to_device) { if (unlikely(dma_mapping_error(addr))) return 1; @@ -568,11 +568,11 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, switch (ring->type) { case B43_DMA_30BIT: if ((u64)addr + buffersize > (1ULL << 30)) - return 1; + goto address_error; break; case B43_DMA_32BIT: if ((u64)addr + buffersize > (1ULL << 32)) - return 1; + goto address_error; break; case B43_DMA_64BIT: /* Currently we can't have addresses beyond @@ -582,6 +582,12 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, /* The address is OK. */ return 0; + +address_error: + /* We can't support this address. Unmap it again. */ + unmap_descbuffer(ring, addr, buffersize, dma_to_device); + + return 1; } static int setup_rx_descbuffer(struct b43_dmaring *ring, @@ -599,7 +605,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, if (unlikely(!skb)) return -ENOMEM; dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); - if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) { + if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { /* ugh. try to realloc in zone_dma */ gfp_flags |= GFP_DMA; @@ -612,7 +618,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, ring->rx_buffersize, 0); } - if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) { + if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { dev_kfree_skb_any(skb); return -EIO; } @@ -852,7 +858,8 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, b43_txhdr_size(dev), DMA_TO_DEVICE); - if (b43_dma_mapping_error(ring, dma_test, b43_txhdr_size(dev))) { + if (b43_dma_mapping_error(ring, dma_test, + b43_txhdr_size(dev), 1)) { /* ugh realloc */ kfree(ring->txhdr_cache); ring->txhdr_cache = kcalloc(nr_slots, @@ -867,7 +874,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, DMA_TO_DEVICE); if (b43_dma_mapping_error(ring, dma_test, - b43_txhdr_size(dev))) + b43_txhdr_size(dev), 1)) goto err_kfree_txhdr_cache; } @@ -1189,7 +1196,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring, meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, hdrsize, 1); - if (b43_dma_mapping_error(ring, meta_hdr->dmaaddr, hdrsize)) { + if (b43_dma_mapping_error(ring, meta_hdr->dmaaddr, hdrsize, 1)) { ring->current_slot = old_top_slot; ring->used_slots = old_used_slots; return -EIO; @@ -1208,7 +1215,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring, meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); /* create a bounce buffer in zone_dma on mapping failure. */ - if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len)) { + if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); if (!bounce_skb) { ring->current_slot = old_top_slot; @@ -1222,7 +1229,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring, skb = bounce_skb; meta->skb = skb; meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); - if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len)) { + if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { ring->current_slot = old_top_slot; ring->used_slots = old_used_slots; err = -EIO; @@ -1337,6 +1344,7 @@ out_unlock: return err; } +/* Called with IRQs disabled. */ void b43_dma_handle_txstatus(struct b43_wldev *dev, const struct b43_txstatus *status) { @@ -1349,8 +1357,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, ring = parse_cookie(dev, status->cookie, &slot); if (unlikely(!ring)) return; - B43_WARN_ON(!irqs_disabled()); - spin_lock(&ring->lock); + + spin_lock(&ring->lock); /* IRQs are already disabled. */ B43_WARN_ON(!ring->tx); ops = ring->ops; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 51dfce16178..c73a75b24cd 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2049,7 +2049,6 @@ void b43_mac_enable(struct b43_wldev *dev) { dev->mac_suspended--; B43_WARN_ON(dev->mac_suspended < 0); - B43_WARN_ON(irqs_disabled()); if (dev->mac_suspended == 0) { b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) @@ -2075,7 +2074,6 @@ void b43_mac_suspend(struct b43_wldev *dev) u32 tmp; might_sleep(); - B43_WARN_ON(irqs_disabled()); B43_WARN_ON(dev->mac_suspended < 0); if (dev->mac_suspended == 0) { diff --git a/drivers/net/wireless/b43/phy.c b/drivers/net/wireless/b43/phy.c index 71507b260b6..575c5436ebd 100644 --- a/drivers/net/wireless/b43/phy.c +++ b/drivers/net/wireless/b43/phy.c @@ -860,7 +860,7 @@ static void b43_phy_ww(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_OFDM(0xBB), (b43_phy_read(dev, B43_PHY_OFDM(0xBB)) & 0xF000) | 0x0053); b43_phy_write(dev, B43_PHY_OFDM61, - (b43_phy_read(dev, B43_PHY_OFDM61 & 0xFE1F)) | 0x0120); + (b43_phy_read(dev, B43_PHY_OFDM61) & 0xFE1F) | 0x0120); b43_phy_write(dev, B43_PHY_OFDM(0x13), (b43_phy_read(dev, B43_PHY_OFDM(0x13)) & 0x0FFF) | 0x3000); b43_phy_write(dev, B43_PHY_OFDM(0x14), diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index c39de422e22..5f3f34e1dbf 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -3829,7 +3829,7 @@ static void b43legacy_print_driverinfo(void) #ifdef CONFIG_B43LEGACY_DMA feat_dma = "D"; #endif - printk(KERN_INFO "Broadcom 43xx driver loaded " + printk(KERN_INFO "Broadcom 43xx-legacy driver loaded " "[ Features: %s%s%s%s%s, Firmware-ID: " B43legacy_SUPPORTED_FIRMWARE_ID " ]\n", feat_pci, feat_leds, feat_rfkill, feat_pio, feat_dma); diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index d1af938b9aa..b79a35a40ab 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -20,7 +20,7 @@ config IWL4965 runs. If you want to compile the driver as a module ( = code which can be - inserted in and remvoed from the running kernel whenever you want), + inserted in and removed from the running kernel whenever you want), say M here and read <file:Documentation/kbuild/modules.txt>. The module will be called iwl4965.ko. @@ -101,7 +101,7 @@ config IWL3945 runs. If you want to compile the driver as a module ( = code which can be - inserted in and remvoed from the running kernel whenever you want), + inserted in and removed from the running kernel whenever you want), say M here and read <file:Documentation/kbuild/modules.txt>. The module will be called iwl3945.ko. diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 40b71bc2c4a..cbaeaf18649 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -6206,11 +6206,11 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv) /* At this point, the NIC is initialized and operational */ priv->notif_missed_beacons = 0; - set_bit(STATUS_READY, &priv->status); iwl3945_reg_txpower_periodic(priv); IWL_DEBUG_INFO("ALIVE processing complete.\n"); + set_bit(STATUS_READY, &priv->status); wake_up_interruptible(&priv->wait_command_queue); if (priv->error_recovering) @@ -8706,7 +8706,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e return err; } -static void iwl3945_pci_remove(struct pci_dev *pdev) +static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) { struct iwl3945_priv *priv = pci_get_drvdata(pdev); struct list_head *p, *q; diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index a23d4798653..60ec29eab85 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -6628,11 +6628,11 @@ static void iwl4965_alive_start(struct iwl4965_priv *priv) /* At this point, the NIC is initialized and operational */ priv->notif_missed_beacons = 0; - set_bit(STATUS_READY, &priv->status); iwl4965_rf_kill_ct_config(priv); IWL_DEBUG_INFO("ALIVE processing complete.\n"); + set_bit(STATUS_READY, &priv->status); wake_up_interruptible(&priv->wait_command_queue); if (priv->error_recovering) @@ -9282,7 +9282,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e return err; } -static void iwl4965_pci_remove(struct pci_dev *pdev) +static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) { struct iwl4965_priv *priv = pci_get_drvdata(pdev); struct list_head *p, *q; diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 159216a9190..f0ef7081bde 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -562,9 +562,7 @@ int lbs_process_rx_command(struct lbs_private *priv) } resp = (void *)priv->upld_buf; - - curcmd = le16_to_cpu(resp->command); - + curcmd = le16_to_cpu(priv->cur_cmd->cmdbuf->command); respcmd = le16_to_cpu(resp->command); result = le16_to_cpu(resp->result); @@ -572,15 +570,15 @@ int lbs_process_rx_command(struct lbs_private *priv) respcmd, le16_to_cpu(resp->seqnum), priv->upld_len, jiffies); lbs_deb_hex(LBS_DEB_HOST, "CMD_RESP", (void *) resp, priv->upld_len); - if (resp->seqnum != resp->seqnum) { + if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) { lbs_pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n", - le16_to_cpu(resp->seqnum), le16_to_cpu(resp->seqnum)); + le16_to_cpu(resp->seqnum), le16_to_cpu(priv->cur_cmd->cmdbuf->seqnum)); spin_unlock_irqrestore(&priv->driver_lock, flags); ret = -1; goto done; } if (respcmd != CMD_RET(curcmd) && - respcmd != CMD_802_11_ASSOCIATE && curcmd != CMD_RET_802_11_ASSOCIATE) { + respcmd != CMD_RET_802_11_ASSOCIATE && curcmd != CMD_802_11_ASSOCIATE) { lbs_pr_info("Invalid CMD_RESP %x to command %x!\n", respcmd, curcmd); spin_unlock_irqrestore(&priv->driver_lock, flags); ret = -1; diff --git a/drivers/net/wireless/p54common.c b/drivers/net/wireless/p54common.c index 5cda49aff3a..d191e055a78 100644 --- a/drivers/net/wireless/p54common.c +++ b/drivers/net/wireless/p54common.c @@ -166,18 +166,23 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) struct p54_common *priv = dev->priv; struct eeprom_pda_wrap *wrap = NULL; struct pda_entry *entry; - int i = 0; unsigned int data_len, entry_len; void *tmp; int err; + u8 *end = (u8 *)eeprom + len; wrap = (struct eeprom_pda_wrap *) eeprom; - entry = (void *)wrap->data + wrap->len; - i += 2; - i += le16_to_cpu(entry->len)*2; - while (i < len) { + entry = (void *)wrap->data + le16_to_cpu(wrap->len); + + /* verify that at least the entry length/code fits */ + while ((u8 *)entry <= end - sizeof(*entry)) { entry_len = le16_to_cpu(entry->len); data_len = ((entry_len - 1) << 1); + + /* abort if entry exceeds whole structure */ + if ((u8 *)entry + sizeof(*entry) + data_len > end) + break; + switch (le16_to_cpu(entry->code)) { case PDR_MAC_ADDRESS: SET_IEEE80211_PERM_ADDR(dev, entry->data); @@ -249,13 +254,12 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) priv->version = *(u8 *)(entry->data + 1); break; case PDR_END: - i = len; + /* make it overrun */ + entry_len = len; break; } entry = (void *)entry + (entry_len + 1)*2; - i += 2; - i += entry_len*2; } if (!priv->iq_autocal || !priv->output_limit || !priv->curve_data) { diff --git a/drivers/net/wireless/p54common.h b/drivers/net/wireless/p54common.h index a721334e20d..b67ff34e26f 100644 --- a/drivers/net/wireless/p54common.h +++ b/drivers/net/wireless/p54common.h @@ -53,10 +53,10 @@ struct pda_entry { } __attribute__ ((packed)); struct eeprom_pda_wrap { - u32 magic; - u16 pad; - u16 len; - u32 arm_opcode; + __le32 magic; + __le16 pad; + __le16 len; + __le32 arm_opcode; u8 data[0]; } __attribute__ ((packed)); diff --git a/drivers/net/wireless/p54usb.c b/drivers/net/wireless/p54usb.c index e7d4aee8799..98ddbb3b327 100644 --- a/drivers/net/wireless/p54usb.c +++ b/drivers/net/wireless/p54usb.c @@ -63,6 +63,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */ {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */ {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ + {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */ {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */ {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index d9460aed1f2..10b776c1adc 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -260,7 +260,7 @@ struct NDIS_802_11_KEY { __le32 KeyLength; u8 Bssid[6]; u8 Padding[6]; - __le64 KeyRSC; + u8 KeyRSC[8]; u8 KeyMaterial[32]; } __attribute__((packed)); @@ -1508,7 +1508,7 @@ static int rndis_iw_set_encode_ext(struct net_device *dev, struct usbnet *usbdev = dev->priv; struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); struct NDIS_802_11_KEY ndis_key; - int i, keyidx, ret; + int keyidx, ret; u8 *addr; keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX; @@ -1543,9 +1543,7 @@ static int rndis_iw_set_encode_ext(struct net_device *dev, ndis_key.KeyIndex = cpu_to_le32(keyidx); if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { - for (i = 0; i < 6; i++) - ndis_key.KeyRSC |= - cpu_to_le64(ext->rx_seq[i] << (i * 8)); + memcpy(ndis_key.KeyRSC, ext->rx_seq, 6); ndis_key.KeyIndex |= cpu_to_le32(1 << 29); } diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 05927b908f8..6c725422af5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -620,6 +620,9 @@ struct rt2x00_dev { * This will only be compiled in when required. */ #ifdef CONFIG_RT2X00_LIB_RFKILL +unsigned long rfkill_state; +#define RFKILL_STATE_ALLOCATED 1 +#define RFKILL_STATE_REGISTERED 2 struct rfkill *rfkill; struct input_polled_dev *poll_dev; #endif /* CONFIG_RT2X00_LIB_RFKILL */ diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 0d51f478bcd..bd305f7f3ef 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1098,7 +1098,7 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) return; /* - * Unregister rfkill. + * Unregister extra components. */ rt2x00rfkill_unregister(rt2x00dev); @@ -1139,17 +1139,12 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) __set_bit(DEVICE_INITIALIZED, &rt2x00dev->flags); /* - * Register the rfkill handler. + * Register the extra components. */ - status = rt2x00rfkill_register(rt2x00dev); - if (status) - goto exit_unitialize; + rt2x00rfkill_register(rt2x00dev); return 0; -exit_unitialize: - rt2x00lib_uninitialize(rt2x00dev); - exit: rt2x00lib_free_ring_entries(rt2x00dev); @@ -1313,15 +1308,9 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) } /* - * Allocatie rfkill. - */ - retval = rt2x00rfkill_allocate(rt2x00dev); - if (retval) - goto exit; - - /* - * Open the debugfs entry. + * Register extra components. */ + rt2x00rfkill_allocate(rt2x00dev); rt2x00debug_register(rt2x00dev); __set_bit(DEVICE_PRESENT, &rt2x00dev->flags); @@ -1350,13 +1339,9 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) rt2x00lib_uninitialize(rt2x00dev); /* - * Close debugfs entry. + * Free extra components */ rt2x00debug_deregister(rt2x00dev); - - /* - * Free rfkill - */ rt2x00rfkill_free(rt2x00dev); /* @@ -1395,11 +1380,15 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) __set_bit(DEVICE_STARTED_SUSPEND, &rt2x00dev->flags); /* - * Disable radio and unitialize all items - * that must be recreated on resume. + * Disable radio. */ rt2x00lib_stop(rt2x00dev); rt2x00lib_uninitialize(rt2x00dev); + + /* + * Suspend/disable extra components. + */ + rt2x00rfkill_suspend(rt2x00dev); rt2x00debug_deregister(rt2x00dev); exit: @@ -1422,9 +1411,10 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) NOTICE(rt2x00dev, "Waking up.\n"); /* - * Open the debugfs entry. + * Restore/enable extra components. */ rt2x00debug_register(rt2x00dev); + rt2x00rfkill_resume(rt2x00dev); /* * Only continue if mac80211 had open interfaces. diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 1adbd28e097..ce58c654ade 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -100,28 +100,36 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, * RFkill handlers. */ #ifdef CONFIG_RT2X00_LIB_RFKILL -int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev); +void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev); void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev); -int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev); +void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev); void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev); +void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev); +void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev); #else -static inline int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) +static inline void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) { - return 0; } static inline void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) { } -static inline int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) +static inline void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) { - return 0; } static inline void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) { } + +static inline void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev) +{ +} + +static inline void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev) +{ +} #endif /* CONFIG_RT2X00_LIB_RFKILL */ #endif /* RT2X00LIB_H */ diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c index 34a96d44e30..f9557759620 100644 --- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c +++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c @@ -69,56 +69,81 @@ static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev) } } -int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) +void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) { - int retval; - - if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) - return 0; + if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) || + !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) + return; - retval = rfkill_register(rt2x00dev->rfkill); - if (retval) { + if (rfkill_register(rt2x00dev->rfkill)) { ERROR(rt2x00dev, "Failed to register rfkill handler.\n"); - return retval; + return; } - retval = input_register_polled_device(rt2x00dev->poll_dev); - if (retval) { + if (input_register_polled_device(rt2x00dev->poll_dev)) { ERROR(rt2x00dev, "Failed to register polled device.\n"); rfkill_unregister(rt2x00dev->rfkill); - return retval; + return; } + __set_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state); + /* * Force initial poll which will detect the initial device state, * and correctly sends the signal to the rfkill layer about this * state. */ rt2x00rfkill_poll(rt2x00dev->poll_dev); - - return 0; } void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) { - if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) + if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) || + !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state)) return; input_unregister_polled_device(rt2x00dev->poll_dev); rfkill_unregister(rt2x00dev->rfkill); + + __clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state); } -int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) +static struct input_polled_dev * +rt2x00rfkill_allocate_polldev(struct rt2x00_dev *rt2x00dev) { - struct device *device = wiphy_dev(rt2x00dev->hw->wiphy); + struct input_polled_dev *poll_dev; + + poll_dev = input_allocate_polled_device(); + if (!poll_dev) + return NULL; + + poll_dev->private = rt2x00dev; + poll_dev->poll = rt2x00rfkill_poll; + poll_dev->poll_interval = RFKILL_POLL_INTERVAL; + + poll_dev->input->name = rt2x00dev->ops->name; + poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy); + poll_dev->input->id.bustype = BUS_HOST; + poll_dev->input->id.vendor = 0x1814; + poll_dev->input->id.product = rt2x00dev->chip.rt; + poll_dev->input->id.version = rt2x00dev->chip.rev; + poll_dev->input->dev.parent = wiphy_dev(rt2x00dev->hw->wiphy); + poll_dev->input->evbit[0] = BIT(EV_KEY); + set_bit(KEY_WLAN, poll_dev->input->keybit); + + return poll_dev; +} +void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) +{ if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) - return 0; + return; - rt2x00dev->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); + rt2x00dev->rfkill = + rfkill_allocate(wiphy_dev(rt2x00dev->hw->wiphy), RFKILL_TYPE_WLAN); if (!rt2x00dev->rfkill) { ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n"); - goto exit; + return; } rt2x00dev->rfkill->name = rt2x00dev->ops->name; @@ -126,40 +151,49 @@ int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) rt2x00dev->rfkill->state = -1; rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio; - rt2x00dev->poll_dev = input_allocate_polled_device(); + rt2x00dev->poll_dev = rt2x00rfkill_allocate_polldev(rt2x00dev); if (!rt2x00dev->poll_dev) { ERROR(rt2x00dev, "Failed to allocate polled device.\n"); - goto exit_free_rfkill; + rfkill_free(rt2x00dev->rfkill); + rt2x00dev->rfkill = NULL; + return; } - rt2x00dev->poll_dev->private = rt2x00dev; - rt2x00dev->poll_dev->poll = rt2x00rfkill_poll; - rt2x00dev->poll_dev->poll_interval = RFKILL_POLL_INTERVAL; + return; +} - rt2x00dev->poll_dev->input->name = rt2x00dev->ops->name; - rt2x00dev->poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy); - rt2x00dev->poll_dev->input->id.bustype = BUS_HOST; - rt2x00dev->poll_dev->input->id.vendor = 0x1814; - rt2x00dev->poll_dev->input->id.product = rt2x00dev->chip.rt; - rt2x00dev->poll_dev->input->id.version = rt2x00dev->chip.rev; - rt2x00dev->poll_dev->input->dev.parent = device; - rt2x00dev->poll_dev->input->evbit[0] = BIT(EV_KEY); - set_bit(KEY_WLAN, rt2x00dev->poll_dev->input->keybit); +void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) +{ + if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) || + !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) + return; - return 0; + input_free_polled_device(rt2x00dev->poll_dev); + rt2x00dev->poll_dev = NULL; -exit_free_rfkill: rfkill_free(rt2x00dev->rfkill); - -exit: - return -ENOMEM; + rt2x00dev->rfkill = NULL; } -void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) +void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev) { - if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) + if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) || + !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) return; input_free_polled_device(rt2x00dev->poll_dev); - rfkill_free(rt2x00dev->rfkill); + rt2x00dev->poll_dev = NULL; +} + +void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev) +{ + if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) || + !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) + return; + + rt2x00dev->poll_dev = rt2x00rfkill_allocate_polldev(rt2x00dev); + if (!rt2x00dev->poll_dev) { + ERROR(rt2x00dev, "Failed to allocate polled device.\n"); + return; + } } diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index e808db98f2f..93ea212fedd 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2302,9 +2302,9 @@ static void rt61pci_configure_filter(struct ieee80211_hw *hw, * Apply some rules to the filters: * - Some filters imply different filters to be set. * - Some things we can't filter out at all. + * - Multicast filter seems to kill broadcast traffic so never use it. */ - if (mc_count) - *total_flags |= FIF_ALLMULTI; + *total_flags |= FIF_ALLMULTI; if (*total_flags & FIF_OTHER_BSS || *total_flags & FIF_PROMISC_IN_BSS) *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 4fac2d414d8..3909cf42f47 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1869,9 +1869,9 @@ static void rt73usb_configure_filter(struct ieee80211_hw *hw, * Apply some rules to the filters: * - Some filters imply different filters to be set. * - Some things we can't filter out at all. + * - Multicast filter seems to kill broadcast traffic so never use it. */ - if (mc_count) - *total_flags |= FIF_ALLMULTI; + *total_flags |= FIF_ALLMULTI; if (*total_flags & FIF_OTHER_BSS || *total_flags & FIF_PROMISC_IN_BSS) *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; @@ -2095,9 +2095,12 @@ static struct usb_device_id rt73usb_device_table[] = { { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, /* Conceptronic */ { USB_DEVICE(0x14b2, 0x3c22), USB_DEVICE_DATA(&rt73usb_ops) }, + /* Corega */ + { USB_DEVICE(0x07aa, 0x002e), USB_DEVICE_DATA(&rt73usb_ops) }, /* D-Link */ { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) }, /* Gemtek */ { USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) }, /* Gigabyte */ diff --git a/drivers/net/wireless/wavelan_cs.h b/drivers/net/wireless/wavelan_cs.h index fabc63ee153..2e4bfe4147c 100644 --- a/drivers/net/wireless/wavelan_cs.h +++ b/drivers/net/wireless/wavelan_cs.h @@ -309,7 +309,7 @@ struct mmw_t #define MMW_EXT_ANT_INTERNAL 0x00 /* Internal antenna */ #define MMW_EXT_ANT_EXTERNAL 0x03 /* External antenna */ #define MMW_EXT_ANT_IQ_TEST 0x1C /* IQ test pattern (set to 0) */ -}; +} __attribute__((packed)); /* Size for structure checking (if padding is correct) */ #define MMW_SIZE 37 |