diff options
62 files changed, 604 insertions, 594 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 2f70e5c10ae4..f1ed75cef6a4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -2110,7 +2110,7 @@ M: reinette.chatre@intel.com | |||
| 2110 | L: linux-wireless@vger.kernel.org | 2110 | L: linux-wireless@vger.kernel.org |
| 2111 | L: ipw3945-devel@lists.sourceforge.net | 2111 | L: ipw3945-devel@lists.sourceforge.net |
| 2112 | W: http://intellinuxwireless.org | 2112 | W: http://intellinuxwireless.org |
| 2113 | T: git git://intellinuxwireless.org/repos/iwlwifi | 2113 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/rchatre/iwlwifi-2.6.git |
| 2114 | S: Supported | 2114 | S: Supported |
| 2115 | 2115 | ||
| 2116 | IOC3 ETHERNET DRIVER | 2116 | IOC3 ETHERNET DRIVER |
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 1e8f41a99511..1d43bdfc20c4 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c | |||
| @@ -256,11 +256,7 @@ static struct net_device_stats *uml_net_get_stats(struct net_device *dev) | |||
| 256 | 256 | ||
| 257 | static void uml_net_set_multicast_list(struct net_device *dev) | 257 | static void uml_net_set_multicast_list(struct net_device *dev) |
| 258 | { | 258 | { |
| 259 | if (dev->flags & IFF_PROMISC) | 259 | return; |
| 260 | return; | ||
| 261 | else if (dev->mc_count) | ||
| 262 | dev->flags |= IFF_ALLMULTI; | ||
| 263 | else dev->flags &= ~IFF_ALLMULTI; | ||
| 264 | } | 260 | } |
| 265 | 261 | ||
| 266 | static void uml_net_tx_timeout(struct net_device *dev) | 262 | static void uml_net_tx_timeout(struct net_device *dev) |
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index ea2a2b548e3c..25f1337cd02c 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
| @@ -2082,6 +2082,11 @@ static int __devinit b44_get_invariants(struct b44 *bp) | |||
| 2082 | addr = sdev->bus->sprom.et0mac; | 2082 | addr = sdev->bus->sprom.et0mac; |
| 2083 | bp->phy_addr = sdev->bus->sprom.et0phyaddr; | 2083 | bp->phy_addr = sdev->bus->sprom.et0phyaddr; |
| 2084 | } | 2084 | } |
| 2085 | /* Some ROMs have buggy PHY addresses with the high | ||
| 2086 | * bits set (sign extension?). Truncate them to a | ||
| 2087 | * valid PHY address. */ | ||
| 2088 | bp->phy_addr &= 0x1F; | ||
| 2089 | |||
| 2085 | memcpy(bp->dev->dev_addr, addr, 6); | 2090 | memcpy(bp->dev->dev_addr, addr, 6); |
| 2086 | 2091 | ||
| 2087 | if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){ | 2092 | if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){ |
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index cb3c6faa7888..d16e0e1d2b30 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) | |||
| 310 | */ | 310 | */ |
| 311 | static inline void __get_rx_machine_lock(struct port *port) | 311 | static inline void __get_rx_machine_lock(struct port *port) |
| 312 | { | 312 | { |
| 313 | spin_lock(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); | 313 | spin_lock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); |
| 314 | } | 314 | } |
| 315 | 315 | ||
| 316 | /** | 316 | /** |
| @@ -320,7 +320,7 @@ static inline void __get_rx_machine_lock(struct port *port) | |||
| 320 | */ | 320 | */ |
| 321 | static inline void __release_rx_machine_lock(struct port *port) | 321 | static inline void __release_rx_machine_lock(struct port *port) |
| 322 | { | 322 | { |
| 323 | spin_unlock(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); | 323 | spin_unlock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); |
| 324 | } | 324 | } |
| 325 | 325 | ||
| 326 | /** | 326 | /** |
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index b57bc9467dbe..3f58c3d0b710 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 | |||
| 678 | } | 678 | } |
| 679 | 679 | ||
| 680 | if (!list_empty(&bond->vlan_list)) { | 680 | if (!list_empty(&bond->vlan_list)) { |
| 681 | unsigned short vlan_id; | 681 | if (!vlan_get_tag(skb, &client_info->vlan_id)) |
| 682 | int res = vlan_get_tag(skb, &vlan_id); | ||
| 683 | if (!res) { | ||
| 684 | client_info->tag = 1; | 682 | client_info->tag = 1; |
| 685 | client_info->vlan_id = vlan_id; | ||
| 686 | } | ||
| 687 | } | 683 | } |
| 688 | 684 | ||
| 689 | if (!client_info->assigned) { | 685 | if (!client_info->assigned) { |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 0942d82f7cbf..0f0675319e9c 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) | |||
| 383 | */ | 383 | */ |
| 384 | int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev) | 384 | int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev) |
| 385 | { | 385 | { |
| 386 | unsigned short vlan_id; | 386 | unsigned short uninitialized_var(vlan_id); |
| 387 | 387 | ||
| 388 | if (!list_empty(&bond->vlan_list) && | 388 | if (!list_empty(&bond->vlan_list) && |
| 389 | !(slave_dev->features & NETIF_F_HW_VLAN_TX) && | 389 | !(slave_dev->features & NETIF_F_HW_VLAN_TX) && |
| @@ -4528,8 +4528,7 @@ static void bond_free_all(void) | |||
| 4528 | netif_tx_unlock_bh(bond_dev); | 4528 | netif_tx_unlock_bh(bond_dev); |
| 4529 | /* Release the bonded slaves */ | 4529 | /* Release the bonded slaves */ |
| 4530 | bond_release_all(bond_dev); | 4530 | bond_release_all(bond_dev); |
| 4531 | bond_deinit(bond_dev); | 4531 | bond_destroy(bond); |
| 4532 | unregister_netdevice(bond_dev); | ||
| 4533 | } | 4532 | } |
| 4534 | 4533 | ||
| 4535 | #ifdef CONFIG_PROC_FS | 4534 | #ifdef CONFIG_PROC_FS |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 67ccad69d445..a3c74e20aa53 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
| @@ -22,8 +22,8 @@ | |||
| 22 | #include "bond_3ad.h" | 22 | #include "bond_3ad.h" |
| 23 | #include "bond_alb.h" | 23 | #include "bond_alb.h" |
| 24 | 24 | ||
| 25 | #define DRV_VERSION "3.2.4" | 25 | #define DRV_VERSION "3.2.5" |
| 26 | #define DRV_RELDATE "January 28, 2008" | 26 | #define DRV_RELDATE "March 21, 2008" |
| 27 | #define DRV_NAME "bonding" | 27 | #define DRV_NAME "bonding" |
| 28 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" | 28 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" |
| 29 | 29 | ||
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index db586870c5f4..98a6bbd11d4c 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) | |||
| 557 | 557 | ||
| 558 | for (i = 0; i < SGE_RXQ_PER_SET; ++i) | 558 | for (i = 0; i < SGE_RXQ_PER_SET; ++i) |
| 559 | if (q->fl[i].desc) { | 559 | if (q->fl[i].desc) { |
| 560 | spin_lock(&adapter->sge.reg_lock); | 560 | spin_lock_irq(&adapter->sge.reg_lock); |
| 561 | t3_sge_disable_fl(adapter, q->fl[i].cntxt_id); | 561 | t3_sge_disable_fl(adapter, q->fl[i].cntxt_id); |
| 562 | spin_unlock(&adapter->sge.reg_lock); | 562 | spin_unlock_irq(&adapter->sge.reg_lock); |
| 563 | free_rx_bufs(pdev, &q->fl[i]); | 563 | free_rx_bufs(pdev, &q->fl[i]); |
| 564 | kfree(q->fl[i].sdesc); | 564 | kfree(q->fl[i].sdesc); |
| 565 | dma_free_coherent(&pdev->dev, | 565 | dma_free_coherent(&pdev->dev, |
| @@ -570,9 +570,9 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q) | |||
| 570 | 570 | ||
| 571 | for (i = 0; i < SGE_TXQ_PER_SET; ++i) | 571 | for (i = 0; i < SGE_TXQ_PER_SET; ++i) |
| 572 | if (q->txq[i].desc) { | 572 | if (q->txq[i].desc) { |
| 573 | spin_lock(&adapter->sge.reg_lock); | 573 | spin_lock_irq(&adapter->sge.reg_lock); |
| 574 | t3_sge_enable_ecntxt(adapter, q->txq[i].cntxt_id, 0); | 574 | t3_sge_enable_ecntxt(adapter, q->txq[i].cntxt_id, 0); |
| 575 | spin_unlock(&adapter->sge.reg_lock); | 575 | spin_unlock_irq(&adapter->sge.reg_lock); |
| 576 | if (q->txq[i].sdesc) { | 576 | if (q->txq[i].sdesc) { |
| 577 | free_tx_desc(adapter, &q->txq[i], | 577 | free_tx_desc(adapter, &q->txq[i], |
| 578 | q->txq[i].in_use); | 578 | q->txq[i].in_use); |
| @@ -586,9 +586,9 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q) | |||
| 586 | } | 586 | } |
| 587 | 587 | ||
| 588 | if (q->rspq.desc) { | 588 | if (q->rspq.desc) { |
| 589 | spin_lock(&adapter->sge.reg_lock); | 589 | spin_lock_irq(&adapter->sge.reg_lock); |
| 590 | t3_sge_disable_rspcntxt(adapter, q->rspq.cntxt_id); | 590 | t3_sge_disable_rspcntxt(adapter, q->rspq.cntxt_id); |
| 591 | spin_unlock(&adapter->sge.reg_lock); | 591 | spin_unlock_irq(&adapter->sge.reg_lock); |
| 592 | dma_free_coherent(&pdev->dev, | 592 | dma_free_coherent(&pdev->dev, |
| 593 | q->rspq.size * sizeof(struct rsp_desc), | 593 | q->rspq.size * sizeof(struct rsp_desc), |
| 594 | q->rspq.desc, q->rspq.phys_addr); | 594 | q->rspq.desc, q->rspq.phys_addr); |
| @@ -2667,7 +2667,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports, | |||
| 2667 | (16 * 1024) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) : | 2667 | (16 * 1024) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) : |
| 2668 | MAX_FRAME_SIZE + 2 + sizeof(struct cpl_rx_pkt); | 2668 | MAX_FRAME_SIZE + 2 + sizeof(struct cpl_rx_pkt); |
| 2669 | 2669 | ||
| 2670 | spin_lock(&adapter->sge.reg_lock); | 2670 | spin_lock_irq(&adapter->sge.reg_lock); |
| 2671 | 2671 | ||
| 2672 | /* FL threshold comparison uses < */ | 2672 | /* FL threshold comparison uses < */ |
| 2673 | ret = t3_sge_init_rspcntxt(adapter, q->rspq.cntxt_id, irq_vec_idx, | 2673 | ret = t3_sge_init_rspcntxt(adapter, q->rspq.cntxt_id, irq_vec_idx, |
| @@ -2711,7 +2711,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports, | |||
| 2711 | goto err_unlock; | 2711 | goto err_unlock; |
| 2712 | } | 2712 | } |
| 2713 | 2713 | ||
| 2714 | spin_unlock(&adapter->sge.reg_lock); | 2714 | spin_unlock_irq(&adapter->sge.reg_lock); |
| 2715 | 2715 | ||
| 2716 | q->adap = adapter; | 2716 | q->adap = adapter; |
| 2717 | q->netdev = dev; | 2717 | q->netdev = dev; |
| @@ -2728,7 +2728,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports, | |||
| 2728 | return 0; | 2728 | return 0; |
| 2729 | 2729 | ||
| 2730 | err_unlock: | 2730 | err_unlock: |
| 2731 | spin_unlock(&adapter->sge.reg_lock); | 2731 | spin_unlock_irq(&adapter->sge.reg_lock); |
| 2732 | err: | 2732 | err: |
| 2733 | t3_free_qset(adapter, q); | 2733 | t3_free_qset(adapter, q); |
| 2734 | return ret; | 2734 | return ret; |
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 1fe305ca2cf0..b09a53de1c53 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c | |||
| @@ -798,8 +798,6 @@ dm9000_init_dm9000(struct net_device *dev) | |||
| 798 | /* Set address filter table */ | 798 | /* Set address filter table */ |
| 799 | dm9000_hash_table(dev); | 799 | dm9000_hash_table(dev); |
| 800 | 800 | ||
| 801 | /* Activate DM9000 */ | ||
| 802 | iow(db, DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); | ||
| 803 | /* Enable TX/RX interrupt mask */ | 801 | /* Enable TX/RX interrupt mask */ |
| 804 | iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM); | 802 | iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM); |
| 805 | 803 | ||
| @@ -1197,6 +1195,7 @@ dm9000_hash_table(struct net_device *dev) | |||
| 1197 | int i, oft; | 1195 | int i, oft; |
| 1198 | u32 hash_val; | 1196 | u32 hash_val; |
| 1199 | u16 hash_table[4]; | 1197 | u16 hash_table[4]; |
| 1198 | u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN; | ||
| 1200 | unsigned long flags; | 1199 | unsigned long flags; |
| 1201 | 1200 | ||
| 1202 | dm9000_dbg(db, 1, "entering %s\n", __func__); | 1201 | dm9000_dbg(db, 1, "entering %s\n", __func__); |
| @@ -1213,6 +1212,12 @@ dm9000_hash_table(struct net_device *dev) | |||
| 1213 | /* broadcast address */ | 1212 | /* broadcast address */ |
| 1214 | hash_table[3] = 0x8000; | 1213 | hash_table[3] = 0x8000; |
| 1215 | 1214 | ||
| 1215 | if (dev->flags & IFF_PROMISC) | ||
| 1216 | rcr |= RCR_PRMSC; | ||
| 1217 | |||
| 1218 | if (dev->flags & IFF_ALLMULTI) | ||
| 1219 | rcr |= RCR_ALL; | ||
| 1220 | |||
| 1216 | /* the multicast address in Hash Table : 64 bits */ | 1221 | /* the multicast address in Hash Table : 64 bits */ |
| 1217 | for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { | 1222 | for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { |
| 1218 | hash_val = ether_crc_le(6, mcptr->dmi_addr) & 0x3f; | 1223 | hash_val = ether_crc_le(6, mcptr->dmi_addr) & 0x3f; |
| @@ -1225,6 +1230,7 @@ dm9000_hash_table(struct net_device *dev) | |||
| 1225 | iow(db, oft++, hash_table[i] >> 8); | 1230 | iow(db, oft++, hash_table[i] >> 8); |
| 1226 | } | 1231 | } |
| 1227 | 1232 | ||
| 1233 | iow(db, DM9000_RCR, rcr); | ||
| 1228 | spin_unlock_irqrestore(&db->lock, flags); | 1234 | spin_unlock_irqrestore(&db->lock, flags); |
| 1229 | } | 1235 | } |
| 1230 | 1236 | ||
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index cdf3090a1885..2d139ec79777 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
| @@ -960,7 +960,7 @@ static void e100_get_defaults(struct nic *nic) | |||
| 960 | 960 | ||
| 961 | /* Template for a freshly allocated RFD */ | 961 | /* Template for a freshly allocated RFD */ |
| 962 | nic->blank_rfd.command = 0; | 962 | nic->blank_rfd.command = 0; |
| 963 | nic->blank_rfd.rbd = 0xFFFFFFFF; | 963 | nic->blank_rfd.rbd = cpu_to_le32(0xFFFFFFFF); |
| 964 | nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN); | 964 | nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN); |
| 965 | 965 | ||
| 966 | /* MII setup */ | 966 | /* MII setup */ |
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 7c4ead35cfa2..93b7fb246960 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h | |||
| @@ -40,7 +40,7 @@ | |||
| 40 | #include <asm/io.h> | 40 | #include <asm/io.h> |
| 41 | 41 | ||
| 42 | #define DRV_NAME "ehea" | 42 | #define DRV_NAME "ehea" |
| 43 | #define DRV_VERSION "EHEA_0087" | 43 | #define DRV_VERSION "EHEA_0089" |
| 44 | 44 | ||
| 45 | /* eHEA capability flags */ | 45 | /* eHEA capability flags */ |
| 46 | #define DLPAR_PORT_ADD_REM 1 | 46 | #define DLPAR_PORT_ADD_REM 1 |
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 21af674b764e..07c742dd3f09 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, | |||
| 3108 | dev->vlan_rx_add_vid = ehea_vlan_rx_add_vid; | 3108 | dev->vlan_rx_add_vid = ehea_vlan_rx_add_vid; |
| 3109 | dev->vlan_rx_kill_vid = ehea_vlan_rx_kill_vid; | 3109 | dev->vlan_rx_kill_vid = ehea_vlan_rx_kill_vid; |
| 3110 | dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO | 3110 | dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO |
| 3111 | | NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_TX | 3111 | | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX |
| 3112 | | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER | 3112 | | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER |
| 3113 | | NETIF_F_LLTX; | 3113 | | NETIF_F_LLTX; |
| 3114 | dev->tx_timeout = &ehea_tx_watchdog; | 3114 | dev->tx_timeout = &ehea_tx_watchdog; |
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h index 6604d96bd567..76ea846663db 100644 --- a/drivers/net/igb/e1000_82575.h +++ b/drivers/net/igb/e1000_82575.h | |||
| @@ -61,28 +61,28 @@ | |||
| 61 | /* Receive Descriptor - Advanced */ | 61 | /* Receive Descriptor - Advanced */ |
| 62 | union e1000_adv_rx_desc { | 62 | union e1000_adv_rx_desc { |
| 63 | struct { | 63 | struct { |
| 64 | u64 pkt_addr; /* Packet buffer address */ | 64 | __le64 pkt_addr; /* Packet buffer address */ |
| 65 | u64 hdr_addr; /* Header buffer address */ | 65 | __le64 hdr_addr; /* Header buffer address */ |
| 66 | } read; | 66 | } read; |
| 67 | struct { | 67 | struct { |
| 68 | struct { | 68 | struct { |
| 69 | struct { | 69 | struct { |
| 70 | u16 pkt_info; /* RSS type, Packet type */ | 70 | __le16 pkt_info; /* RSS type, Packet type */ |
| 71 | u16 hdr_info; /* Split Header, | 71 | __le16 hdr_info; /* Split Header, |
| 72 | * header buffer length */ | 72 | * header buffer length */ |
| 73 | } lo_dword; | 73 | } lo_dword; |
| 74 | union { | 74 | union { |
| 75 | u32 rss; /* RSS Hash */ | 75 | __le32 rss; /* RSS Hash */ |
| 76 | struct { | 76 | struct { |
| 77 | u16 ip_id; /* IP id */ | 77 | __le16 ip_id; /* IP id */ |
| 78 | u16 csum; /* Packet Checksum */ | 78 | __le16 csum; /* Packet Checksum */ |
| 79 | } csum_ip; | 79 | } csum_ip; |
| 80 | } hi_dword; | 80 | } hi_dword; |
| 81 | } lower; | 81 | } lower; |
| 82 | struct { | 82 | struct { |
| 83 | u32 status_error; /* ext status/error */ | 83 | __le32 status_error; /* ext status/error */ |
| 84 | u16 length; /* Packet length */ | 84 | __le16 length; /* Packet length */ |
| 85 | u16 vlan; /* VLAN tag */ | 85 | __le16 vlan; /* VLAN tag */ |
| 86 | } upper; | 86 | } upper; |
| 87 | } wb; /* writeback */ | 87 | } wb; /* writeback */ |
| 88 | }; | 88 | }; |
| @@ -97,14 +97,14 @@ union e1000_adv_rx_desc { | |||
| 97 | /* Transmit Descriptor - Advanced */ | 97 | /* Transmit Descriptor - Advanced */ |
| 98 | union e1000_adv_tx_desc { | 98 | union e1000_adv_tx_desc { |
| 99 | struct { | 99 | struct { |
| 100 | u64 buffer_addr; /* Address of descriptor's data buf */ | 100 | __le64 buffer_addr; /* Address of descriptor's data buf */ |
| 101 | u32 cmd_type_len; | 101 | __le32 cmd_type_len; |
| 102 | u32 olinfo_status; | 102 | __le32 olinfo_status; |
| 103 | } read; | 103 | } read; |
| 104 | struct { | 104 | struct { |
| 105 | u64 rsvd; /* Reserved */ | 105 | __le64 rsvd; /* Reserved */ |
| 106 | u32 nxtseq_seed; | 106 | __le32 nxtseq_seed; |
| 107 | u32 status; | 107 | __le32 status; |
| 108 | } wb; | 108 | } wb; |
| 109 | }; | 109 | }; |
| 110 | 110 | ||
| @@ -119,10 +119,10 @@ union e1000_adv_tx_desc { | |||
| 119 | 119 | ||
| 120 | /* Context descriptors */ | 120 | /* Context descriptors */ |
| 121 | struct e1000_adv_tx_context_desc { | 121 | struct e1000_adv_tx_context_desc { |
| 122 | u32 vlan_macip_lens; | 122 | __le32 vlan_macip_lens; |
| 123 | u32 seqnum_seed; | 123 | __le32 seqnum_seed; |
| 124 | u32 type_tucmd_mlhl; | 124 | __le32 type_tucmd_mlhl; |
| 125 | u32 mss_l4len_idx; | 125 | __le32 mss_l4len_idx; |
| 126 | }; | 126 | }; |
| 127 | 127 | ||
| 128 | #define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */ | 128 | #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 161fb68764af..7b2c70a3b8cc 100644 --- a/drivers/net/igb/e1000_hw.h +++ b/drivers/net/igb/e1000_hw.h | |||
| @@ -143,35 +143,35 @@ enum e1000_fc_type { | |||
| 143 | 143 | ||
| 144 | /* Receive Descriptor */ | 144 | /* Receive Descriptor */ |
| 145 | struct e1000_rx_desc { | 145 | struct e1000_rx_desc { |
| 146 | u64 buffer_addr; /* Address of the descriptor's data buffer */ | 146 | __le64 buffer_addr; /* Address of the descriptor's data buffer */ |
| 147 | u16 length; /* Length of data DMAed into data buffer */ | 147 | __le16 length; /* Length of data DMAed into data buffer */ |
| 148 | u16 csum; /* Packet checksum */ | 148 | __le16 csum; /* Packet checksum */ |
| 149 | u8 status; /* Descriptor status */ | 149 | u8 status; /* Descriptor status */ |
| 150 | u8 errors; /* Descriptor Errors */ | 150 | u8 errors; /* Descriptor Errors */ |
| 151 | u16 special; | 151 | __le16 special; |
| 152 | }; | 152 | }; |
| 153 | 153 | ||
| 154 | /* Receive Descriptor - Extended */ | 154 | /* Receive Descriptor - Extended */ |
| 155 | union e1000_rx_desc_extended { | 155 | union e1000_rx_desc_extended { |
| 156 | struct { | 156 | struct { |
| 157 | u64 buffer_addr; | 157 | __le64 buffer_addr; |
| 158 | u64 reserved; | 158 | __le64 reserved; |
| 159 | } read; | 159 | } read; |
| 160 | struct { | 160 | struct { |
| 161 | struct { | 161 | struct { |
| 162 | u32 mrq; /* Multiple Rx Queues */ | 162 | __le32 mrq; /* Multiple Rx Queues */ |
| 163 | union { | 163 | union { |
| 164 | u32 rss; /* RSS Hash */ | 164 | __le32 rss; /* RSS Hash */ |
| 165 | struct { | 165 | struct { |
| 166 | u16 ip_id; /* IP id */ | 166 | __le16 ip_id; /* IP id */ |
| 167 | u16 csum; /* Packet Checksum */ | 167 | __le16 csum; /* Packet Checksum */ |
| 168 | } csum_ip; | 168 | } csum_ip; |
| 169 | } hi_dword; | 169 | } hi_dword; |
| 170 | } lower; | 170 | } lower; |
| 171 | struct { | 171 | struct { |
| 172 | u32 status_error; /* ext status/error */ | 172 | __le32 status_error; /* ext status/error */ |
| 173 | u16 length; | 173 | __le16 length; |
| 174 | u16 vlan; /* VLAN tag */ | 174 | __le16 vlan; /* VLAN tag */ |
| 175 | } upper; | 175 | } upper; |
| 176 | } wb; /* writeback */ | 176 | } wb; /* writeback */ |
| 177 | }; | 177 | }; |
| @@ -181,49 +181,49 @@ union e1000_rx_desc_extended { | |||
| 181 | union e1000_rx_desc_packet_split { | 181 | union e1000_rx_desc_packet_split { |
| 182 | struct { | 182 | struct { |
| 183 | /* one buffer for protocol header(s), three data buffers */ | 183 | /* one buffer for protocol header(s), three data buffers */ |
| 184 | u64 buffer_addr[MAX_PS_BUFFERS]; | 184 | __le64 buffer_addr[MAX_PS_BUFFERS]; |
| 185 | } read; | 185 | } read; |
| 186 | struct { | 186 | struct { |
| 187 | struct { | 187 | struct { |
| 188 | u32 mrq; /* Multiple Rx Queues */ | 188 | __le32 mrq; /* Multiple Rx Queues */ |
| 189 | union { | 189 | union { |
| 190 | u32 rss; /* RSS Hash */ | 190 | __le32 rss; /* RSS Hash */ |
| 191 | struct { | 191 | struct { |
| 192 | u16 ip_id; /* IP id */ | 192 | __le16 ip_id; /* IP id */ |
| 193 | u16 csum; /* Packet Checksum */ | 193 | __le16 csum; /* Packet Checksum */ |
| 194 | } csum_ip; | 194 | } csum_ip; |
| 195 | } hi_dword; | 195 | } hi_dword; |
| 196 | } lower; | 196 | } lower; |
| 197 | struct { | 197 | struct { |
| 198 | u32 status_error; /* ext status/error */ | 198 | __le32 status_error; /* ext status/error */ |
| 199 | u16 length0; /* length of buffer 0 */ | 199 | __le16 length0; /* length of buffer 0 */ |
| 200 | u16 vlan; /* VLAN tag */ | 200 | __le16 vlan; /* VLAN tag */ |
| 201 | } middle; | 201 | } middle; |
| 202 | struct { | 202 | struct { |
| 203 | u16 header_status; | 203 | __le16 header_status; |
| 204 | u16 length[3]; /* length of buffers 1-3 */ | 204 | __le16 length[3]; /* length of buffers 1-3 */ |
| 205 | } upper; | 205 | } upper; |
| 206 | u64 reserved; | 206 | __le64 reserved; |
| 207 | } wb; /* writeback */ | 207 | } wb; /* writeback */ |
| 208 | }; | 208 | }; |
| 209 | 209 | ||
| 210 | /* Transmit Descriptor */ | 210 | /* Transmit Descriptor */ |
| 211 | struct e1000_tx_desc { | 211 | struct e1000_tx_desc { |
| 212 | u64 buffer_addr; /* Address of the descriptor's data buffer */ | 212 | __le64 buffer_addr; /* Address of the descriptor's data buffer */ |
| 213 | union { | 213 | union { |
| 214 | u32 data; | 214 | __le32 data; |
| 215 | struct { | 215 | struct { |
| 216 | u16 length; /* Data buffer length */ | 216 | __le16 length; /* Data buffer length */ |
| 217 | u8 cso; /* Checksum offset */ | 217 | u8 cso; /* Checksum offset */ |
| 218 | u8 cmd; /* Descriptor control */ | 218 | u8 cmd; /* Descriptor control */ |
| 219 | } flags; | 219 | } flags; |
| 220 | } lower; | 220 | } lower; |
| 221 | union { | 221 | union { |
| 222 | u32 data; | 222 | __le32 data; |
| 223 | struct { | 223 | struct { |
| 224 | u8 status; /* Descriptor status */ | 224 | u8 status; /* Descriptor status */ |
| 225 | u8 css; /* Checksum start */ | 225 | u8 css; /* Checksum start */ |
| 226 | u16 special; | 226 | __le16 special; |
| 227 | } fields; | 227 | } fields; |
| 228 | } upper; | 228 | } upper; |
| 229 | }; | 229 | }; |
| @@ -231,49 +231,49 @@ struct e1000_tx_desc { | |||
| 231 | /* Offload Context Descriptor */ | 231 | /* Offload Context Descriptor */ |
| 232 | struct e1000_context_desc { | 232 | struct e1000_context_desc { |
| 233 | union { | 233 | union { |
| 234 | u32 ip_config; | 234 | __le32 ip_config; |
| 235 | struct { | 235 | struct { |
| 236 | u8 ipcss; /* IP checksum start */ | 236 | u8 ipcss; /* IP checksum start */ |
| 237 | u8 ipcso; /* IP checksum offset */ | 237 | u8 ipcso; /* IP checksum offset */ |
| 238 | u16 ipcse; /* IP checksum end */ | 238 | __le16 ipcse; /* IP checksum end */ |
| 239 | } ip_fields; | 239 | } ip_fields; |
| 240 | } lower_setup; | 240 | } lower_setup; |
| 241 | union { | 241 | union { |
| 242 | u32 tcp_config; | 242 | __le32 tcp_config; |
| 243 | struct { | 243 | struct { |
| 244 | u8 tucss; /* TCP checksum start */ | 244 | u8 tucss; /* TCP checksum start */ |
| 245 | u8 tucso; /* TCP checksum offset */ | 245 | u8 tucso; /* TCP checksum offset */ |
| 246 | u16 tucse; /* TCP checksum end */ | 246 | __le16 tucse; /* TCP checksum end */ |
| 247 | } tcp_fields; | 247 | } tcp_fields; |
| 248 | } upper_setup; | 248 | } upper_setup; |
| 249 | u32 cmd_and_length; | 249 | __le32 cmd_and_length; |
| 250 | union { | 250 | union { |
| 251 | u32 data; | 251 | __le32 data; |
| 252 | struct { | 252 | struct { |
| 253 | u8 status; /* Descriptor status */ | 253 | u8 status; /* Descriptor status */ |
| 254 | u8 hdr_len; /* Header length */ | 254 | u8 hdr_len; /* Header length */ |
| 255 | u16 mss; /* Maximum segment size */ | 255 | __le16 mss; /* Maximum segment size */ |
| 256 | } fields; | 256 | } fields; |
| 257 | } tcp_seg_setup; | 257 | } tcp_seg_setup; |
| 258 | }; | 258 | }; |
| 259 | 259 | ||
| 260 | /* Offload data descriptor */ | 260 | /* Offload data descriptor */ |
| 261 | struct e1000_data_desc { | 261 | struct e1000_data_desc { |
| 262 | u64 buffer_addr; /* Address of the descriptor's buffer address */ | 262 | __le64 buffer_addr; /* Address of the descriptor's buffer address */ |
| 263 | union { | 263 | union { |
| 264 | u32 data; | 264 | __le32 data; |
| 265 | struct { | 265 | struct { |
| 266 | u16 length; /* Data buffer length */ | 266 | __le16 length; /* Data buffer length */ |
| 267 | u8 typ_len_ext; | 267 | u8 typ_len_ext; |
| 268 | u8 cmd; | 268 | u8 cmd; |
| 269 | } flags; | 269 | } flags; |
| 270 | } lower; | 270 | } lower; |
| 271 | union { | 271 | union { |
| 272 | u32 data; | 272 | __le32 data; |
| 273 | struct { | 273 | struct { |
| 274 | u8 status; /* Descriptor status */ | 274 | u8 status; /* Descriptor status */ |
| 275 | u8 popts; /* Packet Options */ | 275 | u8 popts; /* Packet Options */ |
| 276 | u16 special; | 276 | __le16 special; |
| 277 | } fields; | 277 | } fields; |
| 278 | } upper; | 278 | } upper; |
| 279 | }; | 279 | }; |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 928ce8287e69..aaee02e9e3f0 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
| @@ -3254,6 +3254,13 @@ quit_polling: | |||
| 3254 | 3254 | ||
| 3255 | return 1; | 3255 | return 1; |
| 3256 | } | 3256 | } |
| 3257 | |||
| 3258 | static inline u32 get_head(struct igb_ring *tx_ring) | ||
| 3259 | { | ||
| 3260 | void *end = (struct e1000_tx_desc *)tx_ring->desc + tx_ring->count; | ||
| 3261 | return le32_to_cpu(*(volatile __le32 *)end); | ||
| 3262 | } | ||
| 3263 | |||
| 3257 | /** | 3264 | /** |
| 3258 | * igb_clean_tx_irq - Reclaim resources after transmit completes | 3265 | * igb_clean_tx_irq - Reclaim resources after transmit completes |
| 3259 | * @adapter: board private structure | 3266 | * @adapter: board private structure |
| @@ -3275,9 +3282,7 @@ static bool igb_clean_tx_irq(struct igb_adapter *adapter, | |||
| 3275 | unsigned int total_bytes = 0, total_packets = 0; | 3282 | unsigned int total_bytes = 0, total_packets = 0; |
| 3276 | 3283 | ||
| 3277 | rmb(); | 3284 | rmb(); |
| 3278 | head = *(volatile u32 *)((struct e1000_tx_desc *)tx_ring->desc | 3285 | head = get_head(tx_ring); |
| 3279 | + tx_ring->count); | ||
| 3280 | head = le32_to_cpu(head); | ||
| 3281 | i = tx_ring->next_to_clean; | 3286 | i = tx_ring->next_to_clean; |
| 3282 | while (1) { | 3287 | while (1) { |
| 3283 | while (i != head) { | 3288 | while (i != head) { |
| @@ -3312,9 +3317,7 @@ static bool igb_clean_tx_irq(struct igb_adapter *adapter, | |||
| 3312 | } | 3317 | } |
| 3313 | oldhead = head; | 3318 | oldhead = head; |
| 3314 | rmb(); | 3319 | rmb(); |
| 3315 | head = *(volatile u32 *)((struct e1000_tx_desc *)tx_ring->desc | 3320 | head = get_head(tx_ring); |
| 3316 | + tx_ring->count); | ||
| 3317 | head = le32_to_cpu(head); | ||
| 3318 | if (head == oldhead) | 3321 | if (head == oldhead) |
| 3319 | goto done_cleaning; | 3322 | goto done_cleaning; |
| 3320 | } /* while (1) */ | 3323 | } /* while (1) */ |
| @@ -3388,7 +3391,7 @@ done_cleaning: | |||
| 3388 | * @vlan: descriptor vlan field as written by hardware (no le/be conversion) | 3391 | * @vlan: descriptor vlan field as written by hardware (no le/be conversion) |
| 3389 | * @skb: pointer to sk_buff to be indicated to stack | 3392 | * @skb: pointer to sk_buff to be indicated to stack |
| 3390 | **/ | 3393 | **/ |
| 3391 | static void igb_receive_skb(struct igb_adapter *adapter, u8 status, u16 vlan, | 3394 | static void igb_receive_skb(struct igb_adapter *adapter, u8 status, __le16 vlan, |
| 3392 | struct sk_buff *skb) | 3395 | struct sk_buff *skb) |
| 3393 | { | 3396 | { |
| 3394 | if (adapter->vlgrp && (status & E1000_RXD_STAT_VP)) | 3397 | if (adapter->vlgrp && (status & E1000_RXD_STAT_VP)) |
| @@ -3452,8 +3455,8 @@ static bool igb_clean_rx_irq_adv(struct igb_adapter *adapter, | |||
| 3452 | * that case, it fills the header buffer and spills the rest | 3455 | * that case, it fills the header buffer and spills the rest |
| 3453 | * into the page. | 3456 | * into the page. |
| 3454 | */ | 3457 | */ |
| 3455 | hlen = le16_to_cpu((rx_desc->wb.lower.lo_dword.hdr_info & | 3458 | hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) & |
| 3456 | E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT); | 3459 | E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT; |
| 3457 | if (hlen > adapter->rx_ps_hdr_size) | 3460 | if (hlen > adapter->rx_ps_hdr_size) |
| 3458 | hlen = adapter->rx_ps_hdr_size; | 3461 | hlen = adapter->rx_ps_hdr_size; |
| 3459 | 3462 | ||
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 269e6f805f47..6738b4d097fe 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) | |||
| 2088 | struct ixgb_buffer *buffer_info; | 2088 | struct ixgb_buffer *buffer_info; |
| 2089 | struct sk_buff *skb; | 2089 | struct sk_buff *skb; |
| 2090 | unsigned int i; | 2090 | unsigned int i; |
| 2091 | int num_group_tail_writes; | ||
| 2092 | long cleancount; | 2091 | long cleancount; |
| 2093 | 2092 | ||
| 2094 | i = rx_ring->next_to_use; | 2093 | i = rx_ring->next_to_use; |
| 2095 | buffer_info = &rx_ring->buffer_info[i]; | 2094 | buffer_info = &rx_ring->buffer_info[i]; |
| 2096 | cleancount = IXGB_DESC_UNUSED(rx_ring); | 2095 | cleancount = IXGB_DESC_UNUSED(rx_ring); |
| 2097 | 2096 | ||
| 2098 | num_group_tail_writes = IXGB_RX_BUFFER_WRITE; | ||
| 2099 | 2097 | ||
| 2100 | /* leave three descriptors unused */ | 2098 | /* leave three descriptors unused */ |
| 2101 | while(--cleancount > 2) { | 2099 | while(--cleancount > 2) { |
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 2bc5eaae141f..7f20a03623a0 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
| @@ -85,7 +85,7 @@ | |||
| 85 | (sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count) | 85 | (sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count) |
| 86 | #define RCV_BUFFSIZE \ | 86 | #define RCV_BUFFSIZE \ |
| 87 | (sizeof(struct netxen_rx_buffer) * rcv_desc->max_rx_desc_count) | 87 | (sizeof(struct netxen_rx_buffer) * rcv_desc->max_rx_desc_count) |
| 88 | #define find_diff_among(a,b,range) ((a)<=(b)?((b)-(a)):((b)+(range)-(a))) | 88 | #define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a))) |
| 89 | 89 | ||
| 90 | #define NETXEN_NETDEV_STATUS 0x1 | 90 | #define NETXEN_NETDEV_STATUS 0x1 |
| 91 | #define NETXEN_RCV_PRODUCER_OFFSET 0 | 91 | #define NETXEN_RCV_PRODUCER_OFFSET 0 |
| @@ -204,7 +204,7 @@ enum { | |||
| 204 | ? RCV_DESC_LRO : \ | 204 | ? RCV_DESC_LRO : \ |
| 205 | (RCV_DESC_NORMAL))) | 205 | (RCV_DESC_NORMAL))) |
| 206 | 206 | ||
| 207 | #define MAX_CMD_DESCRIPTORS 1024 | 207 | #define MAX_CMD_DESCRIPTORS 4096 |
| 208 | #define MAX_RCV_DESCRIPTORS 16384 | 208 | #define MAX_RCV_DESCRIPTORS 16384 |
| 209 | #define MAX_CMD_DESCRIPTORS_HOST (MAX_CMD_DESCRIPTORS / 4) | 209 | #define MAX_CMD_DESCRIPTORS_HOST (MAX_CMD_DESCRIPTORS / 4) |
| 210 | #define MAX_RCV_DESCRIPTORS_1G (MAX_RCV_DESCRIPTORS / 4) | 210 | #define MAX_RCV_DESCRIPTORS_1G (MAX_RCV_DESCRIPTORS / 4) |
| @@ -818,15 +818,8 @@ struct netxen_adapter_stats { | |||
| 818 | u64 badskblen; | 818 | u64 badskblen; |
| 819 | u64 nocmddescriptor; | 819 | u64 nocmddescriptor; |
| 820 | u64 polled; | 820 | u64 polled; |
| 821 | u64 uphappy; | 821 | u64 rxdropped; |
| 822 | u64 updropped; | ||
| 823 | u64 uplcong; | ||
| 824 | u64 uphcong; | ||
| 825 | u64 upmcong; | ||
| 826 | u64 updunno; | ||
| 827 | u64 skbfreed; | ||
| 828 | u64 txdropped; | 822 | u64 txdropped; |
| 829 | u64 txnullskb; | ||
| 830 | u64 csummed; | 823 | u64 csummed; |
| 831 | u64 no_rcv; | 824 | u64 no_rcv; |
| 832 | u64 rxbytes; | 825 | u64 rxbytes; |
| @@ -842,7 +835,6 @@ struct netxen_rcv_desc_ctx { | |||
| 842 | u32 flags; | 835 | u32 flags; |
| 843 | u32 producer; | 836 | u32 producer; |
| 844 | u32 rcv_pending; /* Num of bufs posted in phantom */ | 837 | u32 rcv_pending; /* Num of bufs posted in phantom */ |
| 845 | u32 rcv_free; /* Num of bufs in free list */ | ||
| 846 | dma_addr_t phys_addr; | 838 | dma_addr_t phys_addr; |
| 847 | struct pci_dev *phys_pdev; | 839 | struct pci_dev *phys_pdev; |
| 848 | struct rcv_desc *desc_head; /* address of rx ring in Phantom */ | 840 | struct rcv_desc *desc_head; /* address of rx ring in Phantom */ |
| @@ -889,8 +881,6 @@ struct netxen_adapter { | |||
| 889 | int mtu; | 881 | int mtu; |
| 890 | int portnum; | 882 | int portnum; |
| 891 | 883 | ||
| 892 | spinlock_t tx_lock; | ||
| 893 | spinlock_t lock; | ||
| 894 | struct work_struct watchdog_task; | 884 | struct work_struct watchdog_task; |
| 895 | struct timer_list watchdog_timer; | 885 | struct timer_list watchdog_timer; |
| 896 | struct work_struct tx_timeout_task; | 886 | struct work_struct tx_timeout_task; |
| @@ -899,16 +889,12 @@ struct netxen_adapter { | |||
| 899 | 889 | ||
| 900 | u32 cmd_producer; | 890 | u32 cmd_producer; |
| 901 | __le32 *cmd_consumer; | 891 | __le32 *cmd_consumer; |
| 902 | |||
| 903 | u32 last_cmd_consumer; | 892 | u32 last_cmd_consumer; |
| 893 | |||
| 904 | u32 max_tx_desc_count; | 894 | u32 max_tx_desc_count; |
| 905 | u32 max_rx_desc_count; | 895 | u32 max_rx_desc_count; |
| 906 | u32 max_jumbo_rx_desc_count; | 896 | u32 max_jumbo_rx_desc_count; |
| 907 | u32 max_lro_rx_desc_count; | 897 | u32 max_lro_rx_desc_count; |
| 908 | /* Num of instances active on cmd buffer ring */ | ||
| 909 | u32 proc_cmd_buf_counter; | ||
| 910 | |||
| 911 | u32 num_threads, total_threads; /*Use to keep track of xmit threads */ | ||
| 912 | 898 | ||
| 913 | u32 flags; | 899 | u32 flags; |
| 914 | u32 irq; | 900 | u32 irq; |
| @@ -942,6 +928,7 @@ struct netxen_adapter { | |||
| 942 | struct pci_dev *ctx_desc_pdev; | 928 | struct pci_dev *ctx_desc_pdev; |
| 943 | dma_addr_t ctx_desc_phys_addr; | 929 | dma_addr_t ctx_desc_phys_addr; |
| 944 | int intr_scheme; | 930 | int intr_scheme; |
| 931 | int msi_mode; | ||
| 945 | int (*enable_phy_interrupts) (struct netxen_adapter *); | 932 | int (*enable_phy_interrupts) (struct netxen_adapter *); |
| 946 | int (*disable_phy_interrupts) (struct netxen_adapter *); | 933 | int (*disable_phy_interrupts) (struct netxen_adapter *); |
| 947 | void (*handle_phy_intr) (struct netxen_adapter *); | 934 | void (*handle_phy_intr) (struct netxen_adapter *); |
| @@ -1075,12 +1062,10 @@ void netxen_tso_check(struct netxen_adapter *adapter, | |||
| 1075 | struct cmd_desc_type0 *desc, struct sk_buff *skb); | 1062 | struct cmd_desc_type0 *desc, struct sk_buff *skb); |
| 1076 | int netxen_nic_hw_resources(struct netxen_adapter *adapter); | 1063 | int netxen_nic_hw_resources(struct netxen_adapter *adapter); |
| 1077 | void netxen_nic_clear_stats(struct netxen_adapter *adapter); | 1064 | void netxen_nic_clear_stats(struct netxen_adapter *adapter); |
| 1078 | int netxen_nic_rx_has_work(struct netxen_adapter *adapter); | ||
| 1079 | int netxen_nic_tx_has_work(struct netxen_adapter *adapter); | ||
| 1080 | void netxen_watchdog_task(struct work_struct *work); | 1065 | void netxen_watchdog_task(struct work_struct *work); |
| 1081 | void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, | 1066 | void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, |
| 1082 | u32 ringid); | 1067 | u32 ringid); |
| 1083 | int netxen_process_cmd_ring(unsigned long data); | 1068 | int netxen_process_cmd_ring(struct netxen_adapter *adapter); |
| 1084 | u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max); | 1069 | u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max); |
| 1085 | void netxen_nic_set_multi(struct net_device *netdev); | 1070 | void netxen_nic_set_multi(struct net_device *netdev); |
| 1086 | int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); | 1071 | 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 7a876f4b8db2..6e98d830eefb 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[] = { | |||
| 64 | {"bad_skb_len", NETXEN_NIC_STAT(stats.badskblen)}, | 64 | {"bad_skb_len", NETXEN_NIC_STAT(stats.badskblen)}, |
| 65 | {"no_cmd_desc", NETXEN_NIC_STAT(stats.nocmddescriptor)}, | 65 | {"no_cmd_desc", NETXEN_NIC_STAT(stats.nocmddescriptor)}, |
| 66 | {"polled", NETXEN_NIC_STAT(stats.polled)}, | 66 | {"polled", NETXEN_NIC_STAT(stats.polled)}, |
| 67 | {"uphappy", NETXEN_NIC_STAT(stats.uphappy)}, | ||
| 68 | {"updropped", NETXEN_NIC_STAT(stats.updropped)}, | ||
| 69 | {"uplcong", NETXEN_NIC_STAT(stats.uplcong)}, | ||
| 70 | {"uphcong", NETXEN_NIC_STAT(stats.uphcong)}, | ||
| 71 | {"upmcong", NETXEN_NIC_STAT(stats.upmcong)}, | ||
| 72 | {"updunno", NETXEN_NIC_STAT(stats.updunno)}, | ||
| 73 | {"skb_freed", NETXEN_NIC_STAT(stats.skbfreed)}, | ||
| 74 | {"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)}, | 67 | {"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)}, |
| 75 | {"tx_null_skb", NETXEN_NIC_STAT(stats.txnullskb)}, | ||
| 76 | {"csummed", NETXEN_NIC_STAT(stats.csummed)}, | 68 | {"csummed", NETXEN_NIC_STAT(stats.csummed)}, |
| 77 | {"no_rcv", NETXEN_NIC_STAT(stats.no_rcv)}, | 69 | {"no_rcv", NETXEN_NIC_STAT(stats.no_rcv)}, |
| 78 | {"rx_bytes", NETXEN_NIC_STAT(stats.rxbytes)}, | 70 | {"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 d72f8f8fcb50..160f605e58db 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h | |||
| @@ -456,6 +456,12 @@ enum { | |||
| 456 | #define ISR_INT_MASK_SLOW (NETXEN_PCIX_PS_REG(PCIX_INT_MASK)) | 456 | #define ISR_INT_MASK_SLOW (NETXEN_PCIX_PS_REG(PCIX_INT_MASK)) |
| 457 | #define ISR_INT_TARGET_STATUS (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS)) | 457 | #define ISR_INT_TARGET_STATUS (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS)) |
| 458 | #define ISR_INT_TARGET_MASK (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK)) | 458 | #define ISR_INT_TARGET_MASK (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK)) |
| 459 | #define ISR_INT_TARGET_STATUS_F1 (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F1)) | ||
| 460 | #define ISR_INT_TARGET_MASK_F1 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F1)) | ||
| 461 | #define ISR_INT_TARGET_STATUS_F2 (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F2)) | ||
| 462 | #define ISR_INT_TARGET_MASK_F2 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F2)) | ||
| 463 | #define ISR_INT_TARGET_STATUS_F3 (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F3)) | ||
| 464 | #define ISR_INT_TARGET_MASK_F3 (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F3)) | ||
| 459 | 465 | ||
| 460 | #define NETXEN_PCI_MAPSIZE 128 | 466 | #define NETXEN_PCI_MAPSIZE 128 |
| 461 | #define NETXEN_PCI_DDR_NET (0x00000000UL) | 467 | #define NETXEN_PCI_DDR_NET (0x00000000UL) |
| @@ -662,6 +668,12 @@ enum { | |||
| 662 | 668 | ||
| 663 | #define PCIX_TARGET_STATUS (0x10118) | 669 | #define PCIX_TARGET_STATUS (0x10118) |
| 664 | #define PCIX_TARGET_MASK (0x10128) | 670 | #define PCIX_TARGET_MASK (0x10128) |
| 671 | #define PCIX_TARGET_STATUS_F1 (0x10160) | ||
| 672 | #define PCIX_TARGET_MASK_F1 (0x10170) | ||
| 673 | #define PCIX_TARGET_STATUS_F2 (0x10164) | ||
| 674 | #define PCIX_TARGET_MASK_F2 (0x10174) | ||
| 675 | #define PCIX_TARGET_STATUS_F3 (0x10168) | ||
| 676 | #define PCIX_TARGET_MASK_F3 (0x10178) | ||
| 665 | 677 | ||
| 666 | #define PCIX_MSI_F0 (0x13000) | 678 | #define PCIX_MSI_F0 (0x13000) |
| 667 | #define PCIX_MSI_F1 (0x13004) | 679 | #define PCIX_MSI_F1 (0x13004) |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 01355701bf8e..05748ca6f216 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) | |||
| 398 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW)); | 398 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW)); |
| 399 | printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netxen_nic_driver_name, | 399 | printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netxen_nic_driver_name, |
| 400 | adapter->intr_scheme); | 400 | adapter->intr_scheme); |
| 401 | adapter->msi_mode = readl( | ||
| 402 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_FW)); | ||
| 401 | DPRINTK(INFO, "Receive Peg ready too. starting stuff\n"); | 403 | DPRINTK(INFO, "Receive Peg ready too. starting stuff\n"); |
| 402 | 404 | ||
| 403 | addr = netxen_alloc(adapter->ahw.pdev, | 405 | 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 9e38bcb3fba9..45fa33e0cb90 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) | |||
| 145 | /* Window 1 call */ | 145 | /* Window 1 call */ |
| 146 | writel(INTR_SCHEME_PERPORT, | 146 | writel(INTR_SCHEME_PERPORT, |
| 147 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_HOST)); | 147 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_HOST)); |
| 148 | writel(MSI_MODE_MULTIFUNC, | ||
| 149 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_HOST)); | ||
| 148 | writel(MPORT_MULTI_FUNCTION_MODE, | 150 | writel(MPORT_MULTI_FUNCTION_MODE, |
| 149 | NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE)); | 151 | NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE)); |
| 150 | writel(PHAN_INITIALIZE_ACK, | 152 | writel(PHAN_INITIALIZE_ACK, |
| @@ -183,7 +185,6 @@ void netxen_initialize_adapter_sw(struct netxen_adapter *adapter) | |||
| 183 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | 185 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { |
| 184 | struct netxen_rx_buffer *rx_buf; | 186 | struct netxen_rx_buffer *rx_buf; |
| 185 | rcv_desc = &adapter->recv_ctx[ctxid].rcv_desc[ring]; | 187 | rcv_desc = &adapter->recv_ctx[ctxid].rcv_desc[ring]; |
| 186 | rcv_desc->rcv_free = rcv_desc->max_rx_desc_count; | ||
| 187 | rcv_desc->begin_alloc = 0; | 188 | rcv_desc->begin_alloc = 0; |
| 188 | rx_buf = rcv_desc->rx_buf_arr; | 189 | rx_buf = rcv_desc->rx_buf_arr; |
| 189 | num_rx_bufs = rcv_desc->max_rx_desc_count; | 190 | num_rx_bufs = rcv_desc->max_rx_desc_count; |
| @@ -974,28 +975,6 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) | |||
| 974 | return 0; | 975 | return 0; |
| 975 | } | 976 | } |
| 976 | 977 | ||
| 977 | int netxen_nic_rx_has_work(struct netxen_adapter *adapter) | ||
| 978 | { | ||
| 979 | int ctx; | ||
| 980 | |||
| 981 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | ||
| 982 | struct netxen_recv_context *recv_ctx = | ||
| 983 | &(adapter->recv_ctx[ctx]); | ||
| 984 | u32 consumer; | ||
| 985 | struct status_desc *desc_head; | ||
| 986 | struct status_desc *desc; | ||
| 987 | |||
| 988 | consumer = recv_ctx->status_rx_consumer; | ||
| 989 | desc_head = recv_ctx->rcv_status_desc_head; | ||
| 990 | desc = &desc_head[consumer]; | ||
| 991 | |||
| 992 | if (netxen_get_sts_owner(desc) & STATUS_OWNER_HOST) | ||
| 993 | return 1; | ||
| 994 | } | ||
| 995 | |||
| 996 | return 0; | ||
| 997 | } | ||
| 998 | |||
| 999 | static int netxen_nic_check_temp(struct netxen_adapter *adapter) | 978 | static int netxen_nic_check_temp(struct netxen_adapter *adapter) |
| 1000 | { | 979 | { |
| 1001 | struct net_device *netdev = adapter->netdev; | 980 | struct net_device *netdev = adapter->netdev; |
| @@ -1038,7 +1017,6 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter) | |||
| 1038 | 1017 | ||
| 1039 | void netxen_watchdog_task(struct work_struct *work) | 1018 | void netxen_watchdog_task(struct work_struct *work) |
| 1040 | { | 1019 | { |
| 1041 | struct net_device *netdev; | ||
| 1042 | struct netxen_adapter *adapter = | 1020 | struct netxen_adapter *adapter = |
| 1043 | container_of(work, struct netxen_adapter, watchdog_task); | 1021 | container_of(work, struct netxen_adapter, watchdog_task); |
| 1044 | 1022 | ||
| @@ -1048,20 +1026,6 @@ void netxen_watchdog_task(struct work_struct *work) | |||
| 1048 | if (adapter->handle_phy_intr) | 1026 | if (adapter->handle_phy_intr) |
| 1049 | adapter->handle_phy_intr(adapter); | 1027 | adapter->handle_phy_intr(adapter); |
| 1050 | 1028 | ||
| 1051 | netdev = adapter->netdev; | ||
| 1052 | if ((netif_running(netdev)) && !netif_carrier_ok(netdev) && | ||
| 1053 | netxen_nic_link_ok(adapter) ) { | ||
| 1054 | printk(KERN_INFO "%s %s (port %d), Link is up\n", | ||
| 1055 | netxen_nic_driver_name, netdev->name, adapter->portnum); | ||
| 1056 | netif_carrier_on(netdev); | ||
| 1057 | netif_wake_queue(netdev); | ||
| 1058 | } else if(!(netif_running(netdev)) && netif_carrier_ok(netdev)) { | ||
| 1059 | printk(KERN_ERR "%s %s Link is Down\n", | ||
| 1060 | netxen_nic_driver_name, netdev->name); | ||
| 1061 | netif_carrier_off(netdev); | ||
| 1062 | netif_stop_queue(netdev); | ||
| 1063 | } | ||
| 1064 | |||
| 1065 | mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); | 1029 | mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); |
| 1066 | } | 1030 | } |
| 1067 | 1031 | ||
| @@ -1125,7 +1089,7 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, | |||
| 1125 | skb = (struct sk_buff *)buffer->skb; | 1089 | skb = (struct sk_buff *)buffer->skb; |
| 1126 | 1090 | ||
| 1127 | if (likely(adapter->rx_csum && | 1091 | if (likely(adapter->rx_csum && |
| 1128 | netxen_get_sts_status(sts_data) == STATUS_CKSUM_OK)) { | 1092 | netxen_get_sts_status(sts_data) == STATUS_CKSUM_OK)) { |
| 1129 | adapter->stats.csummed++; | 1093 | adapter->stats.csummed++; |
| 1130 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1094 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
| 1131 | } else | 1095 | } else |
| @@ -1142,40 +1106,8 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, | |||
| 1142 | skb->protocol = eth_type_trans(skb, netdev); | 1106 | skb->protocol = eth_type_trans(skb, netdev); |
| 1143 | 1107 | ||
| 1144 | ret = netif_receive_skb(skb); | 1108 | ret = netif_receive_skb(skb); |
| 1145 | |||
| 1146 | /* | ||
| 1147 | * RH: Do we need these stats on a regular basis. Can we get it from | ||
| 1148 | * Linux stats. | ||
| 1149 | */ | ||
| 1150 | switch (ret) { | ||
| 1151 | case NET_RX_SUCCESS: | ||
| 1152 | adapter->stats.uphappy++; | ||
| 1153 | break; | ||
| 1154 | |||
| 1155 | case NET_RX_CN_LOW: | ||
| 1156 | adapter->stats.uplcong++; | ||
| 1157 | break; | ||
| 1158 | |||
| 1159 | case NET_RX_CN_MOD: | ||
| 1160 | adapter->stats.upmcong++; | ||
| 1161 | break; | ||
| 1162 | |||
| 1163 | case NET_RX_CN_HIGH: | ||
| 1164 | adapter->stats.uphcong++; | ||
| 1165 | break; | ||
| 1166 | |||
| 1167 | case NET_RX_DROP: | ||
| 1168 | adapter->stats.updropped++; | ||
| 1169 | break; | ||
| 1170 | |||
| 1171 | default: | ||
| 1172 | adapter->stats.updunno++; | ||
| 1173 | break; | ||
| 1174 | } | ||
| 1175 | |||
| 1176 | netdev->last_rx = jiffies; | 1109 | netdev->last_rx = jiffies; |
| 1177 | 1110 | ||
| 1178 | rcv_desc->rcv_free++; | ||
| 1179 | rcv_desc->rcv_pending--; | 1111 | rcv_desc->rcv_pending--; |
| 1180 | 1112 | ||
| 1181 | /* | 1113 | /* |
| @@ -1200,13 +1132,6 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) | |||
| 1200 | u32 producer = 0; | 1132 | u32 producer = 0; |
| 1201 | int count = 0, ring; | 1133 | int count = 0, ring; |
| 1202 | 1134 | ||
| 1203 | DPRINTK(INFO, "procesing receive\n"); | ||
| 1204 | /* | ||
| 1205 | * we assume in this case that there is only one port and that is | ||
| 1206 | * port #1...changes need to be done in firmware to indicate port | ||
| 1207 | * number as part of the descriptor. This way we will be able to get | ||
| 1208 | * the netdev which is associated with that device. | ||
| 1209 | */ | ||
| 1210 | while (count < max) { | 1135 | while (count < max) { |
| 1211 | desc = &desc_head[consumer]; | 1136 | desc = &desc_head[consumer]; |
| 1212 | if (!(netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)) { | 1137 | 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) | |||
| 1219 | consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1); | 1144 | consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1); |
| 1220 | count++; | 1145 | count++; |
| 1221 | } | 1146 | } |
| 1222 | if (count) { | 1147 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) |
| 1223 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | 1148 | netxen_post_rx_buffers_nodb(adapter, ctxid, ring); |
| 1224 | netxen_post_rx_buffers_nodb(adapter, ctxid, ring); | ||
| 1225 | } | ||
| 1226 | } | ||
| 1227 | 1149 | ||
| 1228 | /* update the consumer index in phantom */ | 1150 | /* update the consumer index in phantom */ |
| 1229 | if (count) { | 1151 | if (count) { |
| @@ -1233,108 +1155,60 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) | |||
| 1233 | /* Window = 1 */ | 1155 | /* Window = 1 */ |
| 1234 | writel(consumer, | 1156 | writel(consumer, |
| 1235 | NETXEN_CRB_NORMALIZE(adapter, | 1157 | NETXEN_CRB_NORMALIZE(adapter, |
| 1236 | recv_crb_registers[adapter->portnum]. | 1158 | recv_crb_registers[adapter->portnum]. |
| 1237 | crb_rcv_status_consumer)); | 1159 | crb_rcv_status_consumer)); |
| 1238 | wmb(); | ||
| 1239 | } | 1160 | } |
| 1240 | 1161 | ||
| 1241 | return count; | 1162 | return count; |
| 1242 | } | 1163 | } |
| 1243 | 1164 | ||
| 1244 | /* Process Command status ring */ | 1165 | /* Process Command status ring */ |
| 1245 | int netxen_process_cmd_ring(unsigned long data) | 1166 | int netxen_process_cmd_ring(struct netxen_adapter *adapter) |
| 1246 | { | 1167 | { |
| 1247 | u32 last_consumer; | 1168 | u32 last_consumer, consumer; |
| 1248 | u32 consumer; | 1169 | int count = 0, i; |
| 1249 | struct netxen_adapter *adapter = (struct netxen_adapter *)data; | ||
| 1250 | int count1 = 0; | ||
| 1251 | int count2 = 0; | ||
| 1252 | struct netxen_cmd_buffer *buffer; | 1170 | struct netxen_cmd_buffer *buffer; |
| 1253 | struct pci_dev *pdev; | 1171 | struct pci_dev *pdev = adapter->pdev; |
| 1172 | struct net_device *netdev = adapter->netdev; | ||
| 1254 | struct netxen_skb_frag *frag; | 1173 | struct netxen_skb_frag *frag; |
| 1255 | u32 i; | 1174 | int done = 0; |
| 1256 | int done; | ||
| 1257 | 1175 | ||
| 1258 | spin_lock(&adapter->tx_lock); | ||
| 1259 | last_consumer = adapter->last_cmd_consumer; | 1176 | last_consumer = adapter->last_cmd_consumer; |
| 1260 | DPRINTK(INFO, "procesing xmit complete\n"); | ||
| 1261 | /* we assume in this case that there is only one port and that is | ||
| 1262 | * port #1...changes need to be done in firmware to indicate port | ||
| 1263 | * number as part of the descriptor. This way we will be able to get | ||
| 1264 | * the netdev which is associated with that device. | ||
| 1265 | */ | ||
| 1266 | |||
| 1267 | consumer = le32_to_cpu(*(adapter->cmd_consumer)); | 1177 | consumer = le32_to_cpu(*(adapter->cmd_consumer)); |
| 1268 | if (last_consumer == consumer) { /* Ring is empty */ | ||
| 1269 | DPRINTK(INFO, "last_consumer %d == consumer %d\n", | ||
| 1270 | last_consumer, consumer); | ||
| 1271 | spin_unlock(&adapter->tx_lock); | ||
| 1272 | return 1; | ||
| 1273 | } | ||
| 1274 | |||
| 1275 | adapter->proc_cmd_buf_counter++; | ||
| 1276 | /* | ||
| 1277 | * Not needed - does not seem to be used anywhere. | ||
| 1278 | * adapter->cmd_consumer = consumer; | ||
| 1279 | */ | ||
| 1280 | spin_unlock(&adapter->tx_lock); | ||
| 1281 | 1178 | ||
| 1282 | while ((last_consumer != consumer) && (count1 < MAX_STATUS_HANDLE)) { | 1179 | while (last_consumer != consumer) { |
| 1283 | buffer = &adapter->cmd_buf_arr[last_consumer]; | 1180 | buffer = &adapter->cmd_buf_arr[last_consumer]; |
| 1284 | pdev = adapter->pdev; | ||
| 1285 | if (buffer->skb) { | 1181 | if (buffer->skb) { |
| 1286 | frag = &buffer->frag_array[0]; | 1182 | frag = &buffer->frag_array[0]; |
| 1287 | pci_unmap_single(pdev, frag->dma, frag->length, | 1183 | pci_unmap_single(pdev, frag->dma, frag->length, |
| 1288 | PCI_DMA_TODEVICE); | 1184 | PCI_DMA_TODEVICE); |
| 1289 | frag->dma = 0ULL; | 1185 | frag->dma = 0ULL; |
| 1290 | for (i = 1; i < buffer->frag_count; i++) { | 1186 | for (i = 1; i < buffer->frag_count; i++) { |
| 1291 | DPRINTK(INFO, "getting fragment no %d\n", i); | ||
| 1292 | frag++; /* Get the next frag */ | 1187 | frag++; /* Get the next frag */ |
| 1293 | pci_unmap_page(pdev, frag->dma, frag->length, | 1188 | pci_unmap_page(pdev, frag->dma, frag->length, |
| 1294 | PCI_DMA_TODEVICE); | 1189 | PCI_DMA_TODEVICE); |
| 1295 | frag->dma = 0ULL; | 1190 | frag->dma = 0ULL; |
| 1296 | } | 1191 | } |
| 1297 | 1192 | ||
| 1298 | adapter->stats.skbfreed++; | 1193 | adapter->stats.xmitfinished++; |
| 1299 | dev_kfree_skb_any(buffer->skb); | 1194 | dev_kfree_skb_any(buffer->skb); |
| 1300 | buffer->skb = NULL; | 1195 | buffer->skb = NULL; |
| 1301 | } else if (adapter->proc_cmd_buf_counter == 1) { | ||
| 1302 | adapter->stats.txnullskb++; | ||
| 1303 | } | ||
| 1304 | if (unlikely(netif_queue_stopped(adapter->netdev) | ||
| 1305 | && netif_carrier_ok(adapter->netdev)) | ||
| 1306 | && ((jiffies - adapter->netdev->trans_start) > | ||
| 1307 | adapter->netdev->watchdog_timeo)) { | ||
| 1308 | SCHEDULE_WORK(&adapter->tx_timeout_task); | ||
| 1309 | } | 1196 | } |
| 1310 | 1197 | ||
| 1311 | last_consumer = get_next_index(last_consumer, | 1198 | last_consumer = get_next_index(last_consumer, |
| 1312 | adapter->max_tx_desc_count); | 1199 | adapter->max_tx_desc_count); |
| 1313 | count1++; | 1200 | if (++count >= MAX_STATUS_HANDLE) |
| 1201 | break; | ||
| 1314 | } | 1202 | } |
| 1315 | 1203 | ||
| 1316 | count2 = 0; | 1204 | if (count) { |
| 1317 | spin_lock(&adapter->tx_lock); | ||
| 1318 | if ((--adapter->proc_cmd_buf_counter) == 0) { | ||
| 1319 | adapter->last_cmd_consumer = last_consumer; | 1205 | adapter->last_cmd_consumer = last_consumer; |
| 1320 | while ((adapter->last_cmd_consumer != consumer) | 1206 | smp_mb(); |
| 1321 | && (count2 < MAX_STATUS_HANDLE)) { | 1207 | if (netif_queue_stopped(netdev) && netif_running(netdev)) { |
| 1322 | buffer = | 1208 | netif_tx_lock(netdev); |
| 1323 | &adapter->cmd_buf_arr[adapter->last_cmd_consumer]; | 1209 | netif_wake_queue(netdev); |
| 1324 | count2++; | 1210 | smp_mb(); |
| 1325 | if (buffer->skb) | 1211 | netif_tx_unlock(netdev); |
| 1326 | break; | ||
| 1327 | else | ||
| 1328 | adapter->last_cmd_consumer = | ||
| 1329 | get_next_index(adapter->last_cmd_consumer, | ||
| 1330 | adapter->max_tx_desc_count); | ||
| 1331 | } | ||
| 1332 | } | ||
| 1333 | if (count1 || count2) { | ||
| 1334 | if (netif_queue_stopped(adapter->netdev) | ||
| 1335 | && (adapter->flags & NETXEN_NETDEV_STATUS)) { | ||
| 1336 | netif_wake_queue(adapter->netdev); | ||
| 1337 | adapter->flags &= ~NETXEN_NETDEV_STATUS; | ||
| 1338 | } | 1212 | } |
| 1339 | } | 1213 | } |
| 1340 | /* | 1214 | /* |
| @@ -1350,16 +1224,9 @@ int netxen_process_cmd_ring(unsigned long data) | |||
| 1350 | * There is still a possible race condition and the host could miss an | 1224 | * There is still a possible race condition and the host could miss an |
| 1351 | * interrupt. The card has to take care of this. | 1225 | * interrupt. The card has to take care of this. |
| 1352 | */ | 1226 | */ |
| 1353 | if (adapter->last_cmd_consumer == consumer && | 1227 | consumer = le32_to_cpu(*(adapter->cmd_consumer)); |
| 1354 | (((adapter->cmd_producer + 1) % | 1228 | done = (last_consumer == consumer); |
| 1355 | adapter->max_tx_desc_count) == adapter->last_cmd_consumer)) { | ||
| 1356 | consumer = le32_to_cpu(*(adapter->cmd_consumer)); | ||
| 1357 | } | ||
| 1358 | done = (adapter->last_cmd_consumer == consumer); | ||
| 1359 | 1229 | ||
| 1360 | spin_unlock(&adapter->tx_lock); | ||
| 1361 | DPRINTK(INFO, "last consumer is %d in %s\n", last_consumer, | ||
| 1362 | __FUNCTION__); | ||
| 1363 | return (done); | 1230 | return (done); |
| 1364 | } | 1231 | } |
| 1365 | 1232 | ||
| @@ -1433,8 +1300,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) | |||
| 1433 | rcv_desc->begin_alloc = index; | 1300 | rcv_desc->begin_alloc = index; |
| 1434 | rcv_desc->rcv_pending += count; | 1301 | rcv_desc->rcv_pending += count; |
| 1435 | rcv_desc->producer = producer; | 1302 | rcv_desc->producer = producer; |
| 1436 | if (rcv_desc->rcv_free >= 32) { | ||
| 1437 | rcv_desc->rcv_free = 0; | ||
| 1438 | /* Window = 1 */ | 1303 | /* Window = 1 */ |
| 1439 | writel((producer - 1) & | 1304 | writel((producer - 1) & |
| 1440 | (rcv_desc->max_rx_desc_count - 1), | 1305 | (rcv_desc->max_rx_desc_count - 1), |
| @@ -1458,8 +1323,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) | |||
| 1458 | writel(msg, | 1323 | writel(msg, |
| 1459 | DB_NORMALIZE(adapter, | 1324 | DB_NORMALIZE(adapter, |
| 1460 | NETXEN_RCV_PRODUCER_OFFSET)); | 1325 | NETXEN_RCV_PRODUCER_OFFSET)); |
| 1461 | wmb(); | ||
| 1462 | } | ||
| 1463 | } | 1326 | } |
| 1464 | } | 1327 | } |
| 1465 | 1328 | ||
| @@ -1523,8 +1386,6 @@ static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, | |||
| 1523 | rcv_desc->begin_alloc = index; | 1386 | rcv_desc->begin_alloc = index; |
| 1524 | rcv_desc->rcv_pending += count; | 1387 | rcv_desc->rcv_pending += count; |
| 1525 | rcv_desc->producer = producer; | 1388 | rcv_desc->producer = producer; |
| 1526 | if (rcv_desc->rcv_free >= 32) { | ||
| 1527 | rcv_desc->rcv_free = 0; | ||
| 1528 | /* Window = 1 */ | 1389 | /* Window = 1 */ |
| 1529 | writel((producer - 1) & | 1390 | writel((producer - 1) & |
| 1530 | (rcv_desc->max_rx_desc_count - 1), | 1391 | (rcv_desc->max_rx_desc_count - 1), |
| @@ -1534,21 +1395,9 @@ static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, | |||
| 1534 | rcv_desc_crb[ringid]. | 1395 | rcv_desc_crb[ringid]. |
| 1535 | crb_rcv_producer_offset)); | 1396 | crb_rcv_producer_offset)); |
| 1536 | wmb(); | 1397 | wmb(); |
| 1537 | } | ||
| 1538 | } | 1398 | } |
| 1539 | } | 1399 | } |
| 1540 | 1400 | ||
| 1541 | int netxen_nic_tx_has_work(struct netxen_adapter *adapter) | ||
| 1542 | { | ||
| 1543 | if (find_diff_among(adapter->last_cmd_consumer, | ||
| 1544 | adapter->cmd_producer, | ||
| 1545 | adapter->max_tx_desc_count) > 0) | ||
| 1546 | return 1; | ||
| 1547 | |||
| 1548 | return 0; | ||
| 1549 | } | ||
| 1550 | |||
| 1551 | |||
| 1552 | void netxen_nic_clear_stats(struct netxen_adapter *adapter) | 1401 | void netxen_nic_clear_stats(struct netxen_adapter *adapter) |
| 1553 | { | 1402 | { |
| 1554 | memset(&adapter->stats, 0, sizeof(adapter->stats)); | 1403 | 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 48a404aa66ce..c81313b717bd 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) | |||
| 59 | /* packet transmit problems */ | 59 | /* packet transmit problems */ |
| 60 | stats->tx_errors = adapter->stats.nocmddescriptor; | 60 | stats->tx_errors = adapter->stats.nocmddescriptor; |
| 61 | /* no space in linux buffers */ | 61 | /* no space in linux buffers */ |
| 62 | stats->rx_dropped = adapter->stats.updropped; | 62 | stats->rx_dropped = adapter->stats.rxdropped; |
| 63 | /* no space available in linux */ | 63 | /* no space available in linux */ |
| 64 | stats->tx_dropped = adapter->stats.txdropped; | 64 | stats->tx_dropped = adapter->stats.txdropped; |
| 65 | 65 | ||
| @@ -193,14 +193,14 @@ int netxen_nic_link_ok(struct netxen_adapter *adapter) | |||
| 193 | void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) | 193 | void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) |
| 194 | { | 194 | { |
| 195 | struct net_device *netdev = adapter->netdev; | 195 | struct net_device *netdev = adapter->netdev; |
| 196 | u32 val, val1; | 196 | u32 val; |
| 197 | 197 | ||
| 198 | /* WINDOW = 1 */ | 198 | /* WINDOW = 1 */ |
| 199 | val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); | 199 | val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); |
| 200 | val >>= (physical_port[adapter->portnum] * 8); | 200 | val >>= (physical_port[adapter->portnum] * 8); |
| 201 | val1 = val & 0xff; | 201 | val &= 0xff; |
| 202 | 202 | ||
| 203 | if (adapter->ahw.xg_linkup == 1 && val1 != XG_LINK_UP) { | 203 | if (adapter->ahw.xg_linkup == 1 && val != XG_LINK_UP) { |
| 204 | printk(KERN_INFO "%s: %s NIC Link is down\n", | 204 | printk(KERN_INFO "%s: %s NIC Link is down\n", |
| 205 | netxen_nic_driver_name, netdev->name); | 205 | netxen_nic_driver_name, netdev->name); |
| 206 | adapter->ahw.xg_linkup = 0; | 206 | adapter->ahw.xg_linkup = 0; |
| @@ -208,16 +208,7 @@ void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) | |||
| 208 | netif_carrier_off(netdev); | 208 | netif_carrier_off(netdev); |
| 209 | netif_stop_queue(netdev); | 209 | netif_stop_queue(netdev); |
| 210 | } | 210 | } |
| 211 | /* read twice to clear sticky bits */ | 211 | } else if (adapter->ahw.xg_linkup == 0 && val == XG_LINK_UP) { |
| 212 | /* WINDOW = 0 */ | ||
| 213 | netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1); | ||
| 214 | netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1); | ||
| 215 | |||
| 216 | if ((val & 0xffb) != 0xffb) { | ||
| 217 | printk(KERN_INFO "%s ISR: Sync/Align BAD: 0x%08x\n", | ||
| 218 | netxen_nic_driver_name, val1); | ||
| 219 | } | ||
| 220 | } else if (adapter->ahw.xg_linkup == 0 && val1 == XG_LINK_UP) { | ||
| 221 | printk(KERN_INFO "%s: %s NIC Link is up\n", | 212 | printk(KERN_INFO "%s: %s NIC Link is up\n", |
| 222 | netxen_nic_driver_name, netdev->name); | 213 | netxen_nic_driver_name, netdev->name); |
| 223 | adapter->ahw.xg_linkup = 1; | 214 | adapter->ahw.xg_linkup = 1; |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 9737eae5ef11..a8fb439a4d03 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 *); | |||
| 63 | static void netxen_tx_timeout(struct net_device *netdev); | 63 | static void netxen_tx_timeout(struct net_device *netdev); |
| 64 | static void netxen_tx_timeout_task(struct work_struct *work); | 64 | static void netxen_tx_timeout_task(struct work_struct *work); |
| 65 | static void netxen_watchdog(unsigned long); | 65 | static void netxen_watchdog(unsigned long); |
| 66 | static int netxen_handle_int(struct netxen_adapter *, struct net_device *); | ||
| 67 | static int netxen_nic_poll(struct napi_struct *napi, int budget); | 66 | static int netxen_nic_poll(struct napi_struct *napi, int budget); |
| 68 | #ifdef CONFIG_NET_POLL_CONTROLLER | 67 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 69 | static void netxen_nic_poll_controller(struct net_device *netdev); | 68 | static void netxen_nic_poll_controller(struct net_device *netdev); |
| 70 | #endif | 69 | #endif |
| 71 | static irqreturn_t netxen_intr(int irq, void *data); | 70 | static irqreturn_t netxen_intr(int irq, void *data); |
| 71 | static irqreturn_t netxen_msi_intr(int irq, void *data); | ||
| 72 | 72 | ||
| 73 | int physical_port[] = {0, 1, 2, 3}; | 73 | int physical_port[] = {0, 1, 2, 3}; |
| 74 | 74 | ||
| @@ -149,33 +149,30 @@ static void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, | |||
| 149 | 149 | ||
| 150 | #define ADAPTER_LIST_SIZE 12 | 150 | #define ADAPTER_LIST_SIZE 12 |
| 151 | 151 | ||
| 152 | static uint32_t msi_tgt_status[4] = { | ||
| 153 | ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1, | ||
| 154 | ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3 | ||
| 155 | }; | ||
| 156 | |||
| 157 | static uint32_t sw_int_mask[4] = { | ||
| 158 | CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1, | ||
| 159 | CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3 | ||
| 160 | }; | ||
| 161 | |||
| 152 | static void netxen_nic_disable_int(struct netxen_adapter *adapter) | 162 | static void netxen_nic_disable_int(struct netxen_adapter *adapter) |
| 153 | { | 163 | { |
| 154 | uint32_t mask = 0x7ff; | 164 | u32 mask = 0x7ff; |
| 155 | int retries = 32; | 165 | int retries = 32; |
| 166 | int port = adapter->portnum; | ||
| 167 | int pci_fn = adapter->ahw.pci_func; | ||
| 156 | 168 | ||
| 157 | DPRINTK(1, INFO, "Entered ISR Disable \n"); | 169 | if (adapter->msi_mode != MSI_MODE_MULTIFUNC) |
| 158 | 170 | writel(0x0, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port])); | |
| 159 | switch (adapter->portnum) { | ||
| 160 | case 0: | ||
| 161 | writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0)); | ||
| 162 | break; | ||
| 163 | case 1: | ||
| 164 | writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1)); | ||
| 165 | break; | ||
| 166 | case 2: | ||
| 167 | writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2)); | ||
| 168 | break; | ||
| 169 | case 3: | ||
| 170 | writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3)); | ||
| 171 | break; | ||
| 172 | } | ||
| 173 | 171 | ||
| 174 | if (adapter->intr_scheme != -1 && | 172 | if (adapter->intr_scheme != -1 && |
| 175 | adapter->intr_scheme != INTR_SCHEME_PERPORT) | 173 | adapter->intr_scheme != INTR_SCHEME_PERPORT) |
| 176 | writel(mask,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); | 174 | writel(mask,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); |
| 177 | 175 | ||
| 178 | /* Window = 0 or 1 */ | ||
| 179 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 176 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { |
| 180 | do { | 177 | do { |
| 181 | writel(0xffffffff, | 178 | writel(0xffffffff, |
| @@ -190,14 +187,18 @@ static void netxen_nic_disable_int(struct netxen_adapter *adapter) | |||
| 190 | printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n", | 187 | printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n", |
| 191 | netxen_nic_driver_name); | 188 | netxen_nic_driver_name); |
| 192 | } | 189 | } |
| 190 | } else { | ||
| 191 | if (adapter->msi_mode == MSI_MODE_MULTIFUNC) { | ||
| 192 | writel(0xffffffff, PCI_OFFSET_SECOND_RANGE(adapter, | ||
| 193 | msi_tgt_status[pci_fn])); | ||
| 194 | } | ||
| 193 | } | 195 | } |
| 194 | |||
| 195 | DPRINTK(1, INFO, "Done with Disable Int\n"); | ||
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | static void netxen_nic_enable_int(struct netxen_adapter *adapter) | 198 | static void netxen_nic_enable_int(struct netxen_adapter *adapter) |
| 199 | { | 199 | { |
| 200 | u32 mask; | 200 | u32 mask; |
| 201 | int port = adapter->portnum; | ||
| 201 | 202 | ||
| 202 | DPRINTK(1, INFO, "Entered ISR Enable \n"); | 203 | DPRINTK(1, INFO, "Entered ISR Enable \n"); |
| 203 | 204 | ||
| @@ -218,20 +219,7 @@ static void netxen_nic_enable_int(struct netxen_adapter *adapter) | |||
| 218 | writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); | 219 | writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); |
| 219 | } | 220 | } |
| 220 | 221 | ||
| 221 | switch (adapter->portnum) { | 222 | writel(0x1, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port])); |
| 222 | case 0: | ||
| 223 | writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0)); | ||
| 224 | break; | ||
| 225 | case 1: | ||
| 226 | writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1)); | ||
| 227 | break; | ||
| 228 | case 2: | ||
| 229 | writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2)); | ||
| 230 | break; | ||
| 231 | case 3: | ||
| 232 | writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3)); | ||
| 233 | break; | ||
| 234 | } | ||
| 235 | 223 | ||
| 236 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 224 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { |
| 237 | mask = 0xbff; | 225 | mask = 0xbff; |
| @@ -328,7 +316,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 328 | 316 | ||
| 329 | adapter->ahw.pdev = pdev; | 317 | adapter->ahw.pdev = pdev; |
| 330 | adapter->ahw.pci_func = pci_func_id; | 318 | adapter->ahw.pci_func = pci_func_id; |
| 331 | spin_lock_init(&adapter->tx_lock); | ||
| 332 | 319 | ||
| 333 | /* remap phys address */ | 320 | /* remap phys address */ |
| 334 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ | 321 | 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) | |||
| 401 | 388 | ||
| 402 | /* this will be read from FW later */ | 389 | /* this will be read from FW later */ |
| 403 | adapter->intr_scheme = -1; | 390 | adapter->intr_scheme = -1; |
| 391 | adapter->msi_mode = -1; | ||
| 404 | 392 | ||
| 405 | /* This will be reset for mezz cards */ | 393 | /* This will be reset for mezz cards */ |
| 406 | adapter->portnum = pci_func_id; | 394 | adapter->portnum = pci_func_id; |
| @@ -415,7 +403,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 415 | netdev->set_mac_address = netxen_nic_set_mac; | 403 | netdev->set_mac_address = netxen_nic_set_mac; |
| 416 | netdev->change_mtu = netxen_nic_change_mtu; | 404 | netdev->change_mtu = netxen_nic_change_mtu; |
| 417 | netdev->tx_timeout = netxen_tx_timeout; | 405 | netdev->tx_timeout = netxen_tx_timeout; |
| 418 | netdev->watchdog_timeo = HZ; | 406 | netdev->watchdog_timeo = 2*HZ; |
| 419 | 407 | ||
| 420 | netxen_nic_change_mtu(netdev, netdev->mtu); | 408 | netxen_nic_change_mtu(netdev, netdev->mtu); |
| 421 | 409 | ||
| @@ -543,7 +531,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 543 | adapter->watchdog_timer.data = (unsigned long)adapter; | 531 | adapter->watchdog_timer.data = (unsigned long)adapter; |
| 544 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); | 532 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); |
| 545 | adapter->ahw.pdev = pdev; | 533 | adapter->ahw.pdev = pdev; |
| 546 | adapter->proc_cmd_buf_counter = 0; | ||
| 547 | adapter->ahw.revision_id = pdev->revision; | 534 | adapter->ahw.revision_id = pdev->revision; |
| 548 | 535 | ||
| 549 | /* make sure Window == 1 */ | 536 | /* make sure Window == 1 */ |
| @@ -833,6 +820,8 @@ static int netxen_nic_open(struct net_device *netdev) | |||
| 833 | struct netxen_adapter *adapter = (struct netxen_adapter *)netdev->priv; | 820 | struct netxen_adapter *adapter = (struct netxen_adapter *)netdev->priv; |
| 834 | int err = 0; | 821 | int err = 0; |
| 835 | int ctx, ring; | 822 | int ctx, ring; |
| 823 | irq_handler_t handler; | ||
| 824 | unsigned long flags = IRQF_SAMPLE_RANDOM; | ||
| 836 | 825 | ||
| 837 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) { | 826 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) { |
| 838 | err = netxen_init_firmware(adapter); | 827 | err = netxen_init_firmware(adapter); |
| @@ -856,9 +845,14 @@ static int netxen_nic_open(struct net_device *netdev) | |||
| 856 | netxen_post_rx_buffers(adapter, ctx, ring); | 845 | netxen_post_rx_buffers(adapter, ctx, ring); |
| 857 | } | 846 | } |
| 858 | adapter->irq = adapter->ahw.pdev->irq; | 847 | adapter->irq = adapter->ahw.pdev->irq; |
| 859 | err = request_irq(adapter->ahw.pdev->irq, netxen_intr, | 848 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) |
| 860 | IRQF_SHARED|IRQF_SAMPLE_RANDOM, netdev->name, | 849 | handler = netxen_msi_intr; |
| 861 | adapter); | 850 | else { |
| 851 | flags |= IRQF_SHARED; | ||
| 852 | handler = netxen_intr; | ||
| 853 | } | ||
| 854 | err = request_irq(adapter->irq, handler, | ||
| 855 | flags, netdev->name, adapter); | ||
| 862 | if (err) { | 856 | if (err) { |
| 863 | printk(KERN_ERR "request_irq failed with: %d\n", err); | 857 | printk(KERN_ERR "request_irq failed with: %d\n", err); |
| 864 | netxen_free_hw_resources(adapter); | 858 | netxen_free_hw_resources(adapter); |
| @@ -867,21 +861,12 @@ static int netxen_nic_open(struct net_device *netdev) | |||
| 867 | 861 | ||
| 868 | adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; | 862 | adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; |
| 869 | } | 863 | } |
| 870 | if (!adapter->driver_mismatch) | ||
| 871 | mod_timer(&adapter->watchdog_timer, jiffies); | ||
| 872 | |||
| 873 | napi_enable(&adapter->napi); | ||
| 874 | |||
| 875 | netxen_nic_enable_int(adapter); | ||
| 876 | |||
| 877 | /* Done here again so that even if phantom sw overwrote it, | 864 | /* Done here again so that even if phantom sw overwrote it, |
| 878 | * we set it */ | 865 | * we set it */ |
| 879 | if (adapter->init_port | 866 | if (adapter->init_port |
| 880 | && adapter->init_port(adapter, adapter->portnum) != 0) { | 867 | && adapter->init_port(adapter, adapter->portnum) != 0) { |
| 881 | del_timer_sync(&adapter->watchdog_timer); | ||
| 882 | printk(KERN_ERR "%s: Failed to initialize port %d\n", | 868 | printk(KERN_ERR "%s: Failed to initialize port %d\n", |
| 883 | netxen_nic_driver_name, adapter->portnum); | 869 | netxen_nic_driver_name, adapter->portnum); |
| 884 | napi_disable(&adapter->napi); | ||
| 885 | return -EIO; | 870 | return -EIO; |
| 886 | } | 871 | } |
| 887 | if (adapter->macaddr_set) | 872 | if (adapter->macaddr_set) |
| @@ -894,6 +879,12 @@ static int netxen_nic_open(struct net_device *netdev) | |||
| 894 | adapter->set_mtu(adapter, netdev->mtu); | 879 | adapter->set_mtu(adapter, netdev->mtu); |
| 895 | 880 | ||
| 896 | if (!adapter->driver_mismatch) | 881 | if (!adapter->driver_mismatch) |
| 882 | mod_timer(&adapter->watchdog_timer, jiffies); | ||
| 883 | |||
| 884 | napi_enable(&adapter->napi); | ||
| 885 | netxen_nic_enable_int(adapter); | ||
| 886 | |||
| 887 | if (!adapter->driver_mismatch) | ||
| 897 | netif_start_queue(netdev); | 888 | netif_start_queue(netdev); |
| 898 | 889 | ||
| 899 | return 0; | 890 | return 0; |
| @@ -958,41 +949,17 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
| 958 | struct netxen_skb_frag *buffrag; | 949 | struct netxen_skb_frag *buffrag; |
| 959 | unsigned int i; | 950 | unsigned int i; |
| 960 | 951 | ||
| 961 | u32 producer = 0; | 952 | u32 producer, consumer; |
| 962 | u32 saved_producer = 0; | 953 | u32 saved_producer = 0; |
| 963 | struct cmd_desc_type0 *hwdesc; | 954 | struct cmd_desc_type0 *hwdesc; |
| 964 | int k; | 955 | int k; |
| 965 | struct netxen_cmd_buffer *pbuf = NULL; | 956 | struct netxen_cmd_buffer *pbuf = NULL; |
| 966 | static int dropped_packet = 0; | ||
| 967 | int frag_count; | 957 | int frag_count; |
| 968 | u32 local_producer = 0; | ||
| 969 | u32 max_tx_desc_count = 0; | ||
| 970 | u32 last_cmd_consumer = 0; | ||
| 971 | int no_of_desc; | 958 | int no_of_desc; |
| 959 | u32 num_txd = adapter->max_tx_desc_count; | ||
| 972 | 960 | ||
| 973 | adapter->stats.xmitcalled++; | ||
| 974 | frag_count = skb_shinfo(skb)->nr_frags + 1; | 961 | frag_count = skb_shinfo(skb)->nr_frags + 1; |
| 975 | 962 | ||
| 976 | if (unlikely(skb->len <= 0)) { | ||
| 977 | dev_kfree_skb_any(skb); | ||
| 978 | adapter->stats.badskblen++; | ||
| 979 | return NETDEV_TX_OK; | ||
| 980 | } | ||
| 981 | |||
| 982 | if (frag_count > MAX_BUFFERS_PER_CMD) { | ||
| 983 | printk("%s: %s netxen_nic_xmit_frame: frag_count (%d) " | ||
| 984 | "too large, can handle only %d frags\n", | ||
| 985 | netxen_nic_driver_name, netdev->name, | ||
| 986 | frag_count, MAX_BUFFERS_PER_CMD); | ||
| 987 | adapter->stats.txdropped++; | ||
| 988 | if ((++dropped_packet & 0xff) == 0xff) | ||
| 989 | printk("%s: %s droppped packets = %d\n", | ||
| 990 | netxen_nic_driver_name, netdev->name, | ||
| 991 | dropped_packet); | ||
| 992 | |||
| 993 | return NETDEV_TX_OK; | ||
| 994 | } | ||
| 995 | |||
| 996 | /* There 4 fragments per descriptor */ | 963 | /* There 4 fragments per descriptor */ |
| 997 | no_of_desc = (frag_count + 3) >> 2; | 964 | no_of_desc = (frag_count + 3) >> 2; |
| 998 | if (netdev->features & NETIF_F_TSO) { | 965 | if (netdev->features & NETIF_F_TSO) { |
| @@ -1007,27 +974,16 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
| 1007 | } | 974 | } |
| 1008 | } | 975 | } |
| 1009 | 976 | ||
| 1010 | spin_lock_bh(&adapter->tx_lock); | 977 | producer = adapter->cmd_producer; |
| 1011 | if (adapter->total_threads >= MAX_XMIT_PRODUCERS) { | 978 | smp_mb(); |
| 1012 | goto out_requeue; | 979 | consumer = adapter->last_cmd_consumer; |
| 1013 | } | 980 | if ((no_of_desc+2) > find_diff_among(producer, consumer, num_txd)) { |
| 1014 | local_producer = adapter->cmd_producer; | 981 | netif_stop_queue(netdev); |
| 1015 | k = adapter->cmd_producer; | 982 | smp_mb(); |
| 1016 | max_tx_desc_count = adapter->max_tx_desc_count; | 983 | return NETDEV_TX_BUSY; |
| 1017 | last_cmd_consumer = adapter->last_cmd_consumer; | ||
| 1018 | if ((k + no_of_desc) >= | ||
| 1019 | ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count : | ||
| 1020 | last_cmd_consumer)) { | ||
| 1021 | goto out_requeue; | ||
| 1022 | } | 984 | } |
| 1023 | k = get_index_range(k, max_tx_desc_count, no_of_desc); | ||
| 1024 | adapter->cmd_producer = k; | ||
| 1025 | adapter->total_threads++; | ||
| 1026 | adapter->num_threads++; | ||
| 1027 | 985 | ||
| 1028 | spin_unlock_bh(&adapter->tx_lock); | ||
| 1029 | /* Copy the descriptors into the hardware */ | 986 | /* Copy the descriptors into the hardware */ |
| 1030 | producer = local_producer; | ||
| 1031 | saved_producer = producer; | 987 | saved_producer = producer; |
| 1032 | hwdesc = &hw->cmd_desc_head[producer]; | 988 | hwdesc = &hw->cmd_desc_head[producer]; |
| 1033 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); | 989 | 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) | |||
| 1067 | /* move to next desc. if there is a need */ | 1023 | /* move to next desc. if there is a need */ |
| 1068 | if ((i & 0x3) == 0) { | 1024 | if ((i & 0x3) == 0) { |
| 1069 | k = 0; | 1025 | k = 0; |
| 1070 | producer = get_next_index(producer, | 1026 | producer = get_next_index(producer, num_txd); |
| 1071 | adapter->max_tx_desc_count); | ||
| 1072 | hwdesc = &hw->cmd_desc_head[producer]; | 1027 | hwdesc = &hw->cmd_desc_head[producer]; |
| 1073 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); | 1028 | memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); |
| 1074 | pbuf = &adapter->cmd_buf_arr[producer]; | 1029 | pbuf = &adapter->cmd_buf_arr[producer]; |
| @@ -1086,7 +1041,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
| 1086 | buffrag->dma = temp_dma; | 1041 | buffrag->dma = temp_dma; |
| 1087 | buffrag->length = temp_len; | 1042 | buffrag->length = temp_len; |
| 1088 | 1043 | ||
| 1089 | DPRINTK(INFO, "for loop. i=%d k=%d\n", i, k); | ||
| 1090 | switch (k) { | 1044 | switch (k) { |
| 1091 | case 0: | 1045 | case 0: |
| 1092 | hwdesc->buffer1_length = cpu_to_le16(temp_len); | 1046 | 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) | |||
| 1107 | } | 1061 | } |
| 1108 | frag++; | 1062 | frag++; |
| 1109 | } | 1063 | } |
| 1110 | producer = get_next_index(producer, adapter->max_tx_desc_count); | 1064 | producer = get_next_index(producer, num_txd); |
| 1111 | 1065 | ||
| 1112 | /* might change opcode to TX_TCP_LSO */ | 1066 | /* might change opcode to TX_TCP_LSO */ |
| 1113 | netxen_tso_check(adapter, &hw->cmd_desc_head[saved_producer], skb); | 1067 | 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) | |||
| 1134 | /* copy the first 64 bytes */ | 1088 | /* copy the first 64 bytes */ |
| 1135 | memcpy(((void *)hwdesc) + 2, | 1089 | memcpy(((void *)hwdesc) + 2, |
| 1136 | (void *)(skb->data), first_hdr_len); | 1090 | (void *)(skb->data), first_hdr_len); |
| 1137 | producer = get_next_index(producer, max_tx_desc_count); | 1091 | producer = get_next_index(producer, num_txd); |
| 1138 | 1092 | ||
| 1139 | if (more_hdr) { | 1093 | if (more_hdr) { |
| 1140 | hwdesc = &hw->cmd_desc_head[producer]; | 1094 | hwdesc = &hw->cmd_desc_head[producer]; |
| @@ -1147,35 +1101,19 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
| 1147 | hwdesc, | 1101 | hwdesc, |
| 1148 | (hdr_len - | 1102 | (hdr_len - |
| 1149 | first_hdr_len)); | 1103 | first_hdr_len)); |
| 1150 | producer = get_next_index(producer, max_tx_desc_count); | 1104 | producer = get_next_index(producer, num_txd); |
| 1151 | } | 1105 | } |
| 1152 | } | 1106 | } |
| 1153 | 1107 | ||
| 1154 | spin_lock_bh(&adapter->tx_lock); | 1108 | adapter->cmd_producer = producer; |
| 1155 | adapter->stats.txbytes += skb->len; | 1109 | adapter->stats.txbytes += skb->len; |
| 1156 | 1110 | ||
| 1157 | /* Code to update the adapter considering how many producer threads | 1111 | netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer); |
| 1158 | are currently working */ | ||
| 1159 | if ((--adapter->num_threads) == 0) { | ||
| 1160 | /* This is the last thread */ | ||
| 1161 | u32 crb_producer = adapter->cmd_producer; | ||
| 1162 | netxen_nic_update_cmd_producer(adapter, crb_producer); | ||
| 1163 | wmb(); | ||
| 1164 | adapter->total_threads = 0; | ||
| 1165 | } | ||
| 1166 | 1112 | ||
| 1167 | adapter->stats.xmitfinished++; | 1113 | adapter->stats.xmitcalled++; |
| 1168 | netdev->trans_start = jiffies; | 1114 | netdev->trans_start = jiffies; |
| 1169 | 1115 | ||
| 1170 | spin_unlock_bh(&adapter->tx_lock); | ||
| 1171 | return NETDEV_TX_OK; | 1116 | return NETDEV_TX_OK; |
| 1172 | |||
| 1173 | out_requeue: | ||
| 1174 | netif_stop_queue(netdev); | ||
| 1175 | adapter->flags |= NETXEN_NETDEV_STATUS; | ||
| 1176 | |||
| 1177 | spin_unlock_bh(&adapter->tx_lock); | ||
| 1178 | return NETDEV_TX_BUSY; | ||
| 1179 | } | 1117 | } |
| 1180 | 1118 | ||
| 1181 | static void netxen_watchdog(unsigned long v) | 1119 | static void netxen_watchdog(unsigned long v) |
| @@ -1200,87 +1138,60 @@ static void netxen_tx_timeout_task(struct work_struct *work) | |||
| 1200 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", | 1138 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", |
| 1201 | netxen_nic_driver_name, adapter->netdev->name); | 1139 | netxen_nic_driver_name, adapter->netdev->name); |
| 1202 | 1140 | ||
| 1203 | netxen_nic_close(adapter->netdev); | 1141 | netxen_nic_disable_int(adapter); |
| 1204 | netxen_nic_open(adapter->netdev); | 1142 | napi_disable(&adapter->napi); |
| 1143 | |||
| 1205 | adapter->netdev->trans_start = jiffies; | 1144 | adapter->netdev->trans_start = jiffies; |
| 1145 | |||
| 1146 | napi_enable(&adapter->napi); | ||
| 1147 | netxen_nic_enable_int(adapter); | ||
| 1206 | netif_wake_queue(adapter->netdev); | 1148 | netif_wake_queue(adapter->netdev); |
| 1207 | } | 1149 | } |
| 1208 | 1150 | ||
| 1209 | static int | 1151 | static inline void |
| 1210 | netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) | 1152 | netxen_handle_int(struct netxen_adapter *adapter) |
| 1211 | { | 1153 | { |
| 1212 | u32 ret = 0; | ||
| 1213 | |||
| 1214 | DPRINTK(INFO, "Entered handle ISR\n"); | ||
| 1215 | adapter->stats.ints++; | ||
| 1216 | |||
| 1217 | netxen_nic_disable_int(adapter); | 1154 | netxen_nic_disable_int(adapter); |
| 1218 | 1155 | napi_schedule(&adapter->napi); | |
| 1219 | if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) { | ||
| 1220 | if (netif_rx_schedule_prep(netdev, &adapter->napi)) { | ||
| 1221 | /* | ||
| 1222 | * Interrupts are already disabled. | ||
| 1223 | */ | ||
| 1224 | __netif_rx_schedule(netdev, &adapter->napi); | ||
| 1225 | } else { | ||
| 1226 | static unsigned int intcount = 0; | ||
| 1227 | if ((++intcount & 0xfff) == 0xfff) | ||
| 1228 | DPRINTK(KERN_ERR | ||
| 1229 | "%s: %s interrupt %d while in poll\n", | ||
| 1230 | netxen_nic_driver_name, netdev->name, | ||
| 1231 | intcount); | ||
| 1232 | } | ||
| 1233 | ret = 1; | ||
| 1234 | } | ||
| 1235 | |||
| 1236 | if (ret == 0) { | ||
| 1237 | netxen_nic_enable_int(adapter); | ||
| 1238 | } | ||
| 1239 | |||
| 1240 | return ret; | ||
| 1241 | } | 1156 | } |
| 1242 | 1157 | ||
| 1243 | /* | ||
| 1244 | * netxen_intr - Interrupt Handler | ||
| 1245 | * @irq: interrupt number | ||
| 1246 | * data points to adapter stucture (which may be handling more than 1 port | ||
| 1247 | */ | ||
| 1248 | irqreturn_t netxen_intr(int irq, void *data) | 1158 | irqreturn_t netxen_intr(int irq, void *data) |
| 1249 | { | 1159 | { |
| 1250 | struct netxen_adapter *adapter = data; | 1160 | struct netxen_adapter *adapter = data; |
| 1251 | struct net_device *netdev = adapter->netdev; | ||
| 1252 | u32 our_int = 0; | 1161 | u32 our_int = 0; |
| 1253 | 1162 | ||
| 1254 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 1163 | our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); |
| 1255 | our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); | 1164 | /* not our interrupt */ |
| 1256 | /* not our interrupt */ | 1165 | if ((our_int & (0x80 << adapter->portnum)) == 0) |
| 1257 | if ((our_int & (0x80 << adapter->portnum)) == 0) | 1166 | return IRQ_NONE; |
| 1258 | return IRQ_NONE; | ||
| 1259 | } | ||
| 1260 | 1167 | ||
| 1261 | if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { | 1168 | if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { |
| 1262 | /* claim interrupt */ | 1169 | /* claim interrupt */ |
| 1263 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 1170 | writel(our_int & ~((u32)(0x80 << adapter->portnum)), |
| 1264 | writel(our_int & ~((u32)(0x80 << adapter->portnum)), | ||
| 1265 | NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); | 1171 | NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); |
| 1266 | } | ||
| 1267 | } | 1172 | } |
| 1268 | 1173 | ||
| 1269 | if (netif_running(netdev)) | 1174 | netxen_handle_int(adapter); |
| 1270 | netxen_handle_int(adapter, netdev); | ||
| 1271 | 1175 | ||
| 1272 | return IRQ_HANDLED; | 1176 | return IRQ_HANDLED; |
| 1273 | } | 1177 | } |
| 1274 | 1178 | ||
| 1179 | irqreturn_t netxen_msi_intr(int irq, void *data) | ||
| 1180 | { | ||
| 1181 | struct netxen_adapter *adapter = data; | ||
| 1182 | |||
| 1183 | netxen_handle_int(adapter); | ||
| 1184 | return IRQ_HANDLED; | ||
| 1185 | } | ||
| 1186 | |||
| 1275 | static int netxen_nic_poll(struct napi_struct *napi, int budget) | 1187 | static int netxen_nic_poll(struct napi_struct *napi, int budget) |
| 1276 | { | 1188 | { |
| 1277 | struct netxen_adapter *adapter = container_of(napi, struct netxen_adapter, napi); | 1189 | struct netxen_adapter *adapter = container_of(napi, struct netxen_adapter, napi); |
| 1278 | struct net_device *netdev = adapter->netdev; | 1190 | int tx_complete; |
| 1279 | int done = 1; | ||
| 1280 | int ctx; | 1191 | int ctx; |
| 1281 | int work_done; | 1192 | int work_done; |
| 1282 | 1193 | ||
| 1283 | DPRINTK(INFO, "polling for %d descriptors\n", *budget); | 1194 | tx_complete = netxen_process_cmd_ring(adapter); |
| 1284 | 1195 | ||
| 1285 | work_done = 0; | 1196 | work_done = 0; |
| 1286 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { | 1197 | for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { |
| @@ -1300,16 +1211,8 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) | |||
| 1300 | budget / MAX_RCV_CTX); | 1211 | budget / MAX_RCV_CTX); |
| 1301 | } | 1212 | } |
| 1302 | 1213 | ||
| 1303 | if (work_done >= budget) | 1214 | if ((work_done < budget) && tx_complete) { |
| 1304 | done = 0; | 1215 | netif_rx_complete(adapter->netdev, &adapter->napi); |
| 1305 | |||
| 1306 | if (netxen_process_cmd_ring((unsigned long)adapter) == 0) | ||
| 1307 | done = 0; | ||
| 1308 | |||
| 1309 | DPRINTK(INFO, "new work_done: %d work_to_do: %d\n", | ||
| 1310 | work_done, work_to_do); | ||
| 1311 | if (done) { | ||
| 1312 | netif_rx_complete(netdev, napi); | ||
| 1313 | netxen_nic_enable_int(adapter); | 1216 | netxen_nic_enable_int(adapter); |
| 1314 | } | 1217 | } |
| 1315 | 1218 | ||
diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h index ffa3b7215ce8..a566b50f36f5 100644 --- a/drivers/net/netxen/netxen_nic_phan_reg.h +++ b/drivers/net/netxen/netxen_nic_phan_reg.h | |||
| @@ -126,8 +126,11 @@ | |||
| 126 | */ | 126 | */ |
| 127 | #define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8) | 127 | #define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8) |
| 128 | #define CRB_NIC_CAPABILITIES_FW NETXEN_NIC_REG(0x1dc) | 128 | #define CRB_NIC_CAPABILITIES_FW NETXEN_NIC_REG(0x1dc) |
| 129 | #define CRB_NIC_MSI_MODE_HOST NETXEN_NIC_REG(0x270) | ||
| 130 | #define CRB_NIC_MSI_MODE_FW NETXEN_NIC_REG(0x274) | ||
| 129 | 131 | ||
| 130 | #define INTR_SCHEME_PERPORT 0x1 | 132 | #define INTR_SCHEME_PERPORT 0x1 |
| 133 | #define MSI_MODE_MULTIFUNC 0x1 | ||
| 131 | 134 | ||
| 132 | /* used for ethtool tests */ | 135 | /* used for ethtool tests */ |
| 133 | #define CRB_SCRATCHPAD_TEST NETXEN_NIC_REG(0x280) | 136 | #define CRB_SCRATCHPAD_TEST NETXEN_NIC_REG(0x280) |
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index f0574073a2a3..33539917e9b8 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c | |||
| @@ -58,9 +58,25 @@ | |||
| 58 | #define MII_M1111_RX_DELAY 0x80 | 58 | #define MII_M1111_RX_DELAY 0x80 |
| 59 | #define MII_M1111_TX_DELAY 0x2 | 59 | #define MII_M1111_TX_DELAY 0x2 |
| 60 | #define MII_M1111_PHY_EXT_SR 0x1b | 60 | #define MII_M1111_PHY_EXT_SR 0x1b |
| 61 | #define MII_M1111_HWCFG_MODE_MASK 0xf | 61 | |
| 62 | #define MII_M1111_HWCFG_MODE_RGMII 0xb | 62 | #define MII_M1111_HWCFG_MODE_MASK 0xf |
| 63 | #define MII_M1111_HWCFG_MODE_COPPER_RGMII 0xb | ||
| 64 | #define MII_M1111_HWCFG_MODE_FIBER_RGMII 0x3 | ||
| 63 | #define MII_M1111_HWCFG_MODE_SGMII_NO_CLK 0x4 | 65 | #define MII_M1111_HWCFG_MODE_SGMII_NO_CLK 0x4 |
| 66 | #define MII_M1111_HWCFG_FIBER_COPPER_AUTO 0x8000 | ||
| 67 | #define MII_M1111_HWCFG_FIBER_COPPER_RES 0x2000 | ||
| 68 | |||
| 69 | #define MII_M1111_COPPER 0 | ||
| 70 | #define MII_M1111_FIBER 1 | ||
| 71 | |||
| 72 | #define MII_M1011_PHY_STATUS 0x11 | ||
| 73 | #define MII_M1011_PHY_STATUS_1000 0x8000 | ||
| 74 | #define MII_M1011_PHY_STATUS_100 0x4000 | ||
| 75 | #define MII_M1011_PHY_STATUS_SPD_MASK 0xc000 | ||
| 76 | #define MII_M1011_PHY_STATUS_FULLDUPLEX 0x2000 | ||
| 77 | #define MII_M1011_PHY_STATUS_RESOLVED 0x0800 | ||
| 78 | #define MII_M1011_PHY_STATUS_LINK 0x0400 | ||
| 79 | |||
| 64 | 80 | ||
| 65 | MODULE_DESCRIPTION("Marvell PHY driver"); | 81 | MODULE_DESCRIPTION("Marvell PHY driver"); |
| 66 | MODULE_AUTHOR("Andy Fleming"); | 82 | MODULE_AUTHOR("Andy Fleming"); |
| @@ -141,12 +157,22 @@ static int marvell_config_aneg(struct phy_device *phydev) | |||
| 141 | static int m88e1111_config_init(struct phy_device *phydev) | 157 | static int m88e1111_config_init(struct phy_device *phydev) |
| 142 | { | 158 | { |
| 143 | int err; | 159 | int err; |
| 160 | int temp; | ||
| 161 | int mode; | ||
| 162 | |||
| 163 | /* Enable Fiber/Copper auto selection */ | ||
| 164 | temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); | ||
| 165 | temp |= MII_M1111_HWCFG_FIBER_COPPER_AUTO; | ||
| 166 | phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); | ||
| 167 | |||
| 168 | temp = phy_read(phydev, MII_BMCR); | ||
| 169 | temp |= BMCR_RESET; | ||
| 170 | phy_write(phydev, MII_BMCR, temp); | ||
| 144 | 171 | ||
| 145 | if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || | 172 | if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || |
| 146 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || | 173 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || |
| 147 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || | 174 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || |
| 148 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) { | 175 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) { |
| 149 | int temp; | ||
| 150 | 176 | ||
| 151 | temp = phy_read(phydev, MII_M1111_PHY_EXT_CR); | 177 | temp = phy_read(phydev, MII_M1111_PHY_EXT_CR); |
| 152 | if (temp < 0) | 178 | if (temp < 0) |
| @@ -171,7 +197,13 @@ static int m88e1111_config_init(struct phy_device *phydev) | |||
| 171 | return temp; | 197 | return temp; |
| 172 | 198 | ||
| 173 | temp &= ~(MII_M1111_HWCFG_MODE_MASK); | 199 | temp &= ~(MII_M1111_HWCFG_MODE_MASK); |
| 174 | temp |= MII_M1111_HWCFG_MODE_RGMII; | 200 | |
| 201 | mode = phy_read(phydev, MII_M1111_PHY_EXT_CR); | ||
| 202 | |||
| 203 | if (mode & MII_M1111_HWCFG_FIBER_COPPER_RES) | ||
| 204 | temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII; | ||
| 205 | else | ||
| 206 | temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII; | ||
| 175 | 207 | ||
| 176 | err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); | 208 | err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); |
| 177 | if (err < 0) | 209 | if (err < 0) |
| @@ -262,6 +294,93 @@ static int m88e1145_config_init(struct phy_device *phydev) | |||
| 262 | return 0; | 294 | return 0; |
| 263 | } | 295 | } |
| 264 | 296 | ||
| 297 | /* marvell_read_status | ||
| 298 | * | ||
| 299 | * Generic status code does not detect Fiber correctly! | ||
| 300 | * Description: | ||
| 301 | * Check the link, then figure out the current state | ||
| 302 | * by comparing what we advertise with what the link partner | ||
| 303 | * advertises. Start by checking the gigabit possibilities, | ||
| 304 | * then move on to 10/100. | ||
| 305 | */ | ||
| 306 | static int marvell_read_status(struct phy_device *phydev) | ||
| 307 | { | ||
| 308 | int adv; | ||
| 309 | int err; | ||
| 310 | int lpa; | ||
| 311 | int status = 0; | ||
| 312 | |||
| 313 | /* Update the link, but return if there | ||
| 314 | * was an error */ | ||
| 315 | err = genphy_update_link(phydev); | ||
| 316 | if (err) | ||
| 317 | return err; | ||
| 318 | |||
| 319 | if (AUTONEG_ENABLE == phydev->autoneg) { | ||
| 320 | status = phy_read(phydev, MII_M1011_PHY_STATUS); | ||
| 321 | if (status < 0) | ||
| 322 | return status; | ||
| 323 | |||
| 324 | lpa = phy_read(phydev, MII_LPA); | ||
| 325 | if (lpa < 0) | ||
| 326 | return lpa; | ||
| 327 | |||
| 328 | adv = phy_read(phydev, MII_ADVERTISE); | ||
| 329 | if (adv < 0) | ||
| 330 | return adv; | ||
| 331 | |||
| 332 | lpa &= adv; | ||
| 333 | |||
| 334 | if (status & MII_M1011_PHY_STATUS_FULLDUPLEX) | ||
| 335 | phydev->duplex = DUPLEX_FULL; | ||
| 336 | else | ||
| 337 | phydev->duplex = DUPLEX_HALF; | ||
| 338 | |||
| 339 | status = status & MII_M1011_PHY_STATUS_SPD_MASK; | ||
| 340 | phydev->pause = phydev->asym_pause = 0; | ||
| 341 | |||
| 342 | switch (status) { | ||
| 343 | case MII_M1011_PHY_STATUS_1000: | ||
| 344 | phydev->speed = SPEED_1000; | ||
| 345 | break; | ||
| 346 | |||
| 347 | case MII_M1011_PHY_STATUS_100: | ||
| 348 | phydev->speed = SPEED_100; | ||
| 349 | break; | ||
| 350 | |||
| 351 | default: | ||
| 352 | phydev->speed = SPEED_10; | ||
| 353 | break; | ||
| 354 | } | ||
| 355 | |||
| 356 | if (phydev->duplex == DUPLEX_FULL) { | ||
| 357 | phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; | ||
| 358 | phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; | ||
| 359 | } | ||
| 360 | } else { | ||
| 361 | int bmcr = phy_read(phydev, MII_BMCR); | ||
| 362 | |||
| 363 | if (bmcr < 0) | ||
| 364 | return bmcr; | ||
| 365 | |||
| 366 | if (bmcr & BMCR_FULLDPLX) | ||
| 367 | phydev->duplex = DUPLEX_FULL; | ||
| 368 | else | ||
| 369 | phydev->duplex = DUPLEX_HALF; | ||
| 370 | |||
| 371 | if (bmcr & BMCR_SPEED1000) | ||
| 372 | phydev->speed = SPEED_1000; | ||
| 373 | else if (bmcr & BMCR_SPEED100) | ||
| 374 | phydev->speed = SPEED_100; | ||
| 375 | else | ||
| 376 | phydev->speed = SPEED_10; | ||
| 377 | |||
| 378 | phydev->pause = phydev->asym_pause = 0; | ||
| 379 | } | ||
| 380 | |||
| 381 | return 0; | ||
| 382 | } | ||
| 383 | |||
| 265 | static struct phy_driver marvell_drivers[] = { | 384 | static struct phy_driver marvell_drivers[] = { |
| 266 | { | 385 | { |
| 267 | .phy_id = 0x01410c60, | 386 | .phy_id = 0x01410c60, |
| @@ -296,7 +415,7 @@ static struct phy_driver marvell_drivers[] = { | |||
| 296 | .flags = PHY_HAS_INTERRUPT, | 415 | .flags = PHY_HAS_INTERRUPT, |
| 297 | .config_init = &m88e1111_config_init, | 416 | .config_init = &m88e1111_config_init, |
| 298 | .config_aneg = &marvell_config_aneg, | 417 | .config_aneg = &marvell_config_aneg, |
| 299 | .read_status = &genphy_read_status, | 418 | .read_status = &marvell_read_status, |
| 300 | .ack_interrupt = &marvell_ack_interrupt, | 419 | .ack_interrupt = &marvell_ack_interrupt, |
| 301 | .config_intr = &marvell_config_intr, | 420 | .config_intr = &marvell_config_intr, |
| 302 | .driver = { .owner = THIS_MODULE }, | 421 | .driver = { .owner = THIS_MODULE }, |
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index c72787adeba3..3c915b82e199 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
| @@ -4172,6 +4172,9 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 4172 | dev->trans_start = jiffies; | 4172 | dev->trans_start = jiffies; |
| 4173 | spin_unlock_irqrestore(&fifo->tx_lock, flags); | 4173 | spin_unlock_irqrestore(&fifo->tx_lock, flags); |
| 4174 | 4174 | ||
| 4175 | if (sp->config.intr_type == MSI_X) | ||
| 4176 | tx_intr_handler(fifo); | ||
| 4177 | |||
| 4175 | return 0; | 4178 | return 0; |
| 4176 | pci_map_failed: | 4179 | pci_map_failed: |
| 4177 | stats->pci_map_fail_cnt++; | 4180 | stats->pci_map_fail_cnt++; |
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 186eb8ebfda6..2e26dced13a1 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) | |||
| 3199 | skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), CSR_START); | 3199 | skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), CSR_START); |
| 3200 | 3200 | ||
| 3201 | if (work_done < to_do) { | 3201 | if (work_done < to_do) { |
| 3202 | spin_lock_irq(&hw->hw_lock); | 3202 | unsigned long flags; |
| 3203 | |||
| 3204 | spin_lock_irqsave(&hw->hw_lock, flags); | ||
| 3203 | __netif_rx_complete(dev, napi); | 3205 | __netif_rx_complete(dev, napi); |
| 3204 | hw->intr_mask |= napimask[skge->port]; | 3206 | hw->intr_mask |= napimask[skge->port]; |
| 3205 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 3207 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
| 3206 | skge_read32(hw, B0_IMSK); | 3208 | skge_read32(hw, B0_IMSK); |
| 3207 | spin_unlock_irq(&hw->hw_lock); | 3209 | spin_unlock_irqrestore(&hw->hw_lock, flags); |
| 3208 | } | 3210 | } |
| 3209 | 3211 | ||
| 3210 | return work_done; | 3212 | return work_done; |
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 51d4134b37b1..98a832a75539 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h | |||
| @@ -92,14 +92,14 @@ | |||
| 92 | #define SMC_insw(a, r, p, l) insw ((unsigned long *)((a) + (r)), p, l) | 92 | #define SMC_insw(a, r, p, l) insw ((unsigned long *)((a) + (r)), p, l) |
| 93 | # endif | 93 | # endif |
| 94 | /* check if the mac in reg is valid */ | 94 | /* check if the mac in reg is valid */ |
| 95 | #define SMC_GET_MAC_ADDR(addr) \ | 95 | #define SMC_GET_MAC_ADDR(lp, addr) \ |
| 96 | do { \ | 96 | do { \ |
| 97 | unsigned int __v; \ | 97 | unsigned int __v; \ |
| 98 | __v = SMC_inw(ioaddr, ADDR0_REG); \ | 98 | __v = SMC_inw(ioaddr, ADDR0_REG(lp)); \ |
| 99 | addr[0] = __v; addr[1] = __v >> 8; \ | 99 | addr[0] = __v; addr[1] = __v >> 8; \ |
| 100 | __v = SMC_inw(ioaddr, ADDR1_REG); \ | 100 | __v = SMC_inw(ioaddr, ADDR1_REG(lp)); \ |
| 101 | addr[2] = __v; addr[3] = __v >> 8; \ | 101 | addr[2] = __v; addr[3] = __v >> 8; \ |
| 102 | __v = SMC_inw(ioaddr, ADDR2_REG); \ | 102 | __v = SMC_inw(ioaddr, ADDR2_REG(lp)); \ |
| 103 | addr[4] = __v; addr[5] = __v >> 8; \ | 103 | addr[4] = __v; addr[5] = __v >> 8; \ |
| 104 | if (*(u32 *)(&addr[0]) == 0xFFFFFFFF) { \ | 104 | if (*(u32 *)(&addr[0]) == 0xFFFFFFFF) { \ |
| 105 | random_ether_addr(addr); \ | 105 | random_ether_addr(addr); \ |
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index 8909050b8ea7..5f1c5072b96f 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, | |||
| 3413 | tsv->svi = TRANSMIT_STATUS_CODE; | 3413 | tsv->svi = TRANSMIT_STATUS_CODE; |
| 3414 | tsv->svl = S_TRANSMIT_STATUS_CODE; | 3414 | tsv->svl = S_TRANSMIT_STATUS_CODE; |
| 3415 | 3415 | ||
| 3416 | tsv->svv[0] = ((tx_fstatus & 0x0100 >> 6) || IBM_PASS_SOURCE_ADDR); | 3416 | tsv->svv[0] = ((tx_fstatus & 0x0100 >> 6) | IBM_PASS_SOURCE_ADDR); |
| 3417 | 3417 | ||
| 3418 | /* Stripped frame status of Transmitted Frame */ | 3418 | /* Stripped frame status of Transmitted Frame */ |
| 3419 | tsv->svv[1] = tx_fstatus & 0xff; | 3419 | tsv->svv[1] = tx_fstatus & 0xff; |
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 4b131a6c6b70..0343b00cf1fd 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) | |||
| 341 | /* We use the 20 byte dev->data for our 8 byte filter buffer | 341 | /* We use the 20 byte dev->data for our 8 byte filter buffer |
| 342 | * to avoid allocating memory that is tricky to free later */ | 342 | * to avoid allocating memory that is tricky to free later */ |
| 343 | u8 *hashes = (u8 *) & dev->data; | 343 | u8 *hashes = (u8 *) & dev->data; |
| 344 | u8 rx_ctl = 0x01; | 344 | u8 rx_ctl = 0x31; |
| 345 | 345 | ||
| 346 | memset(hashes, 0x00, DM_MCAST_SIZE); | 346 | memset(hashes, 0x00, DM_MCAST_SIZE); |
| 347 | hashes[DM_MCAST_SIZE - 1] |= 0x80; /* broadcast address */ | 347 | hashes[DM_MCAST_SIZE - 1] |= 0x80; /* broadcast address */ |
| @@ -562,6 +562,10 @@ static const struct usb_device_id products[] = { | |||
| 562 | USB_DEVICE(0x0a46, 0x8515), /* ADMtek ADM8515 USB NIC */ | 562 | USB_DEVICE(0x0a46, 0x8515), /* ADMtek ADM8515 USB NIC */ |
| 563 | .driver_info = (unsigned long)&dm9601_info, | 563 | .driver_info = (unsigned long)&dm9601_info, |
| 564 | }, | 564 | }, |
| 565 | { | ||
| 566 | USB_DEVICE(0x0a47, 0x9601), /* Hirose USB-100 */ | ||
| 567 | .driver_info = (unsigned long)&dm9601_info, | ||
| 568 | }, | ||
| 565 | {}, // END | 569 | {}, // END |
| 566 | }; | 570 | }; |
| 567 | 571 | ||
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index 727547a28992..369c731114b3 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c | |||
| @@ -283,7 +283,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) | |||
| 283 | struct rndis_set_c *set_c; | 283 | struct rndis_set_c *set_c; |
| 284 | struct rndis_halt *halt; | 284 | struct rndis_halt *halt; |
| 285 | } u; | 285 | } u; |
| 286 | u32 tmp, *phym; | 286 | u32 tmp, phym_unspec, *phym; |
| 287 | int reply_len; | 287 | int reply_len; |
| 288 | unsigned char *bp; | 288 | unsigned char *bp; |
| 289 | 289 | ||
| @@ -363,12 +363,15 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) | |||
| 363 | goto halt_fail_and_release; | 363 | goto halt_fail_and_release; |
| 364 | 364 | ||
| 365 | /* Check physical medium */ | 365 | /* Check physical medium */ |
| 366 | phym = NULL; | ||
| 366 | reply_len = sizeof *phym; | 367 | reply_len = sizeof *phym; |
| 367 | retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM, | 368 | retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM, |
| 368 | 0, (void **) &phym, &reply_len); | 369 | 0, (void **) &phym, &reply_len); |
| 369 | if (retval != 0) | 370 | if (retval != 0 || !phym) { |
| 370 | /* OID is optional so don't fail here. */ | 371 | /* OID is optional so don't fail here. */ |
| 371 | *phym = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED; | 372 | phym_unspec = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED; |
| 373 | phym = &phym_unspec; | ||
| 374 | } | ||
| 372 | if ((flags & FLAG_RNDIS_PHYM_WIRELESS) && | 375 | if ((flags & FLAG_RNDIS_PHYM_WIRELESS) && |
| 373 | *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { | 376 | *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { |
| 374 | if (netif_msg_probe(dev)) | 377 | if (netif_msg_probe(dev)) |
diff --git a/drivers/net/wireless/arlan-proc.c b/drivers/net/wireless/arlan-proc.c index c6e70dbc5de8..2ab1d59870f4 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] = | |||
| 1202 | { .ctl_name = 0 } | 1202 | { .ctl_name = 0 } |
| 1203 | }; | 1203 | }; |
| 1204 | #endif | 1204 | #endif |
| 1205 | #else | ||
| 1206 | |||
| 1207 | static ctl_table arlan_table[MAX_ARLANS + 1] = | ||
| 1208 | { | ||
| 1209 | { .ctl_name = 0 } | ||
| 1210 | }; | ||
| 1211 | #endif | ||
| 1212 | 1205 | ||
| 1213 | 1206 | ||
| 1214 | // static int mmtu = 1234; | 1207 | // static int mmtu = 1234; |
| @@ -1233,7 +1226,6 @@ static ctl_table arlan_root_table[] = | |||
| 1233 | //}; | 1226 | //}; |
| 1234 | 1227 | ||
| 1235 | 1228 | ||
| 1236 | #ifdef CONFIG_PROC_FS | ||
| 1237 | static struct ctl_table_header *arlan_device_sysctl_header; | 1229 | static struct ctl_table_header *arlan_device_sysctl_header; |
| 1238 | 1230 | ||
| 1239 | int __init init_arlan_proc(void) | 1231 | int __init init_arlan_proc(void) |
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c index e38ed0fe72e9..7fca2ebc747f 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) | |||
| 618 | kfree(e); | 618 | kfree(e); |
| 619 | } | 619 | } |
| 620 | 620 | ||
| 621 | /* Called with IRQs disabled. */ | ||
| 621 | void b43_debugfs_log_txstat(struct b43_wldev *dev, | 622 | void b43_debugfs_log_txstat(struct b43_wldev *dev, |
| 622 | const struct b43_txstatus *status) | 623 | const struct b43_txstatus *status) |
| 623 | { | 624 | { |
| @@ -629,8 +630,7 @@ void b43_debugfs_log_txstat(struct b43_wldev *dev, | |||
| 629 | if (!e) | 630 | if (!e) |
| 630 | return; | 631 | return; |
| 631 | log = &e->txstatlog; | 632 | log = &e->txstatlog; |
| 632 | B43_WARN_ON(!irqs_disabled()); | 633 | spin_lock(&log->lock); /* IRQs are already disabled. */ |
| 633 | spin_lock(&log->lock); | ||
| 634 | i = log->end + 1; | 634 | i = log->end + 1; |
| 635 | if (i == B43_NR_LOGGED_TXSTATUS) | 635 | if (i == B43_NR_LOGGED_TXSTATUS) |
| 636 | i = 0; | 636 | i = 0; |
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 3dfb28a34be9..cfbc1a26f601 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, | |||
| 560 | /* Check if a DMA mapping address is invalid. */ | 560 | /* Check if a DMA mapping address is invalid. */ |
| 561 | static bool b43_dma_mapping_error(struct b43_dmaring *ring, | 561 | static bool b43_dma_mapping_error(struct b43_dmaring *ring, |
| 562 | dma_addr_t addr, | 562 | dma_addr_t addr, |
| 563 | size_t buffersize) | 563 | size_t buffersize, bool dma_to_device) |
| 564 | { | 564 | { |
| 565 | if (unlikely(dma_mapping_error(addr))) | 565 | if (unlikely(dma_mapping_error(addr))) |
| 566 | return 1; | 566 | return 1; |
| @@ -568,11 +568,11 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, | |||
| 568 | switch (ring->type) { | 568 | switch (ring->type) { |
| 569 | case B43_DMA_30BIT: | 569 | case B43_DMA_30BIT: |
| 570 | if ((u64)addr + buffersize > (1ULL << 30)) | 570 | if ((u64)addr + buffersize > (1ULL << 30)) |
| 571 | return 1; | 571 | goto address_error; |
| 572 | break; | 572 | break; |
| 573 | case B43_DMA_32BIT: | 573 | case B43_DMA_32BIT: |
| 574 | if ((u64)addr + buffersize > (1ULL << 32)) | 574 | if ((u64)addr + buffersize > (1ULL << 32)) |
| 575 | return 1; | 575 | goto address_error; |
| 576 | break; | 576 | break; |
| 577 | case B43_DMA_64BIT: | 577 | case B43_DMA_64BIT: |
| 578 | /* Currently we can't have addresses beyond | 578 | /* Currently we can't have addresses beyond |
| @@ -582,6 +582,12 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, | |||
| 582 | 582 | ||
| 583 | /* The address is OK. */ | 583 | /* The address is OK. */ |
| 584 | return 0; | 584 | return 0; |
| 585 | |||
| 586 | address_error: | ||
| 587 | /* We can't support this address. Unmap it again. */ | ||
| 588 | unmap_descbuffer(ring, addr, buffersize, dma_to_device); | ||
| 589 | |||
| 590 | return 1; | ||
| 585 | } | 591 | } |
| 586 | 592 | ||
| 587 | static int setup_rx_descbuffer(struct b43_dmaring *ring, | 593 | static int setup_rx_descbuffer(struct b43_dmaring *ring, |
| @@ -599,7 +605,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, | |||
| 599 | if (unlikely(!skb)) | 605 | if (unlikely(!skb)) |
| 600 | return -ENOMEM; | 606 | return -ENOMEM; |
| 601 | dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); | 607 | dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); |
| 602 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) { | 608 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { |
| 603 | /* ugh. try to realloc in zone_dma */ | 609 | /* ugh. try to realloc in zone_dma */ |
| 604 | gfp_flags |= GFP_DMA; | 610 | gfp_flags |= GFP_DMA; |
| 605 | 611 | ||
| @@ -612,7 +618,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, | |||
| 612 | ring->rx_buffersize, 0); | 618 | ring->rx_buffersize, 0); |
| 613 | } | 619 | } |
| 614 | 620 | ||
| 615 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) { | 621 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { |
| 616 | dev_kfree_skb_any(skb); | 622 | dev_kfree_skb_any(skb); |
| 617 | return -EIO; | 623 | return -EIO; |
| 618 | } | 624 | } |
| @@ -852,7 +858,8 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
| 852 | b43_txhdr_size(dev), | 858 | b43_txhdr_size(dev), |
| 853 | DMA_TO_DEVICE); | 859 | DMA_TO_DEVICE); |
| 854 | 860 | ||
| 855 | if (b43_dma_mapping_error(ring, dma_test, b43_txhdr_size(dev))) { | 861 | if (b43_dma_mapping_error(ring, dma_test, |
| 862 | b43_txhdr_size(dev), 1)) { | ||
| 856 | /* ugh realloc */ | 863 | /* ugh realloc */ |
| 857 | kfree(ring->txhdr_cache); | 864 | kfree(ring->txhdr_cache); |
| 858 | ring->txhdr_cache = kcalloc(nr_slots, | 865 | ring->txhdr_cache = kcalloc(nr_slots, |
| @@ -867,7 +874,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
| 867 | DMA_TO_DEVICE); | 874 | DMA_TO_DEVICE); |
| 868 | 875 | ||
| 869 | if (b43_dma_mapping_error(ring, dma_test, | 876 | if (b43_dma_mapping_error(ring, dma_test, |
| 870 | b43_txhdr_size(dev))) | 877 | b43_txhdr_size(dev), 1)) |
| 871 | goto err_kfree_txhdr_cache; | 878 | goto err_kfree_txhdr_cache; |
| 872 | } | 879 | } |
| 873 | 880 | ||
| @@ -1189,7 +1196,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring, | |||
| 1189 | 1196 | ||
| 1190 | meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, | 1197 | meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, |
| 1191 | hdrsize, 1); | 1198 | hdrsize, 1); |
| 1192 | if (b43_dma_mapping_error(ring, meta_hdr->dmaaddr, hdrsize)) { | 1199 | if (b43_dma_mapping_error(ring, meta_hdr->dmaaddr, hdrsize, 1)) { |
| 1193 | ring->current_slot = old_top_slot; | 1200 | ring->current_slot = old_top_slot; |
| 1194 | ring->used_slots = old_used_slots; | 1201 | ring->used_slots = old_used_slots; |
| 1195 | return -EIO; | 1202 | return -EIO; |
| @@ -1208,7 +1215,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring, | |||
| 1208 | 1215 | ||
| 1209 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); | 1216 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); |
| 1210 | /* create a bounce buffer in zone_dma on mapping failure. */ | 1217 | /* create a bounce buffer in zone_dma on mapping failure. */ |
| 1211 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len)) { | 1218 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { |
| 1212 | bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); | 1219 | bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); |
| 1213 | if (!bounce_skb) { | 1220 | if (!bounce_skb) { |
| 1214 | ring->current_slot = old_top_slot; | 1221 | ring->current_slot = old_top_slot; |
| @@ -1222,7 +1229,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring, | |||
| 1222 | skb = bounce_skb; | 1229 | skb = bounce_skb; |
| 1223 | meta->skb = skb; | 1230 | meta->skb = skb; |
| 1224 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); | 1231 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); |
| 1225 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len)) { | 1232 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { |
| 1226 | ring->current_slot = old_top_slot; | 1233 | ring->current_slot = old_top_slot; |
| 1227 | ring->used_slots = old_used_slots; | 1234 | ring->used_slots = old_used_slots; |
| 1228 | err = -EIO; | 1235 | err = -EIO; |
| @@ -1337,6 +1344,7 @@ out_unlock: | |||
| 1337 | return err; | 1344 | return err; |
| 1338 | } | 1345 | } |
| 1339 | 1346 | ||
| 1347 | /* Called with IRQs disabled. */ | ||
| 1340 | void b43_dma_handle_txstatus(struct b43_wldev *dev, | 1348 | void b43_dma_handle_txstatus(struct b43_wldev *dev, |
| 1341 | const struct b43_txstatus *status) | 1349 | const struct b43_txstatus *status) |
| 1342 | { | 1350 | { |
| @@ -1349,8 +1357,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, | |||
| 1349 | ring = parse_cookie(dev, status->cookie, &slot); | 1357 | ring = parse_cookie(dev, status->cookie, &slot); |
| 1350 | if (unlikely(!ring)) | 1358 | if (unlikely(!ring)) |
| 1351 | return; | 1359 | return; |
| 1352 | B43_WARN_ON(!irqs_disabled()); | 1360 | |
| 1353 | spin_lock(&ring->lock); | 1361 | spin_lock(&ring->lock); /* IRQs are already disabled. */ |
| 1354 | 1362 | ||
| 1355 | B43_WARN_ON(!ring->tx); | 1363 | B43_WARN_ON(!ring->tx); |
| 1356 | ops = ring->ops; | 1364 | ops = ring->ops; |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 51dfce16178a..c73a75b24cd6 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) | |||
| 2049 | { | 2049 | { |
| 2050 | dev->mac_suspended--; | 2050 | dev->mac_suspended--; |
| 2051 | B43_WARN_ON(dev->mac_suspended < 0); | 2051 | B43_WARN_ON(dev->mac_suspended < 0); |
| 2052 | B43_WARN_ON(irqs_disabled()); | ||
| 2053 | if (dev->mac_suspended == 0) { | 2052 | if (dev->mac_suspended == 0) { |
| 2054 | b43_write32(dev, B43_MMIO_MACCTL, | 2053 | b43_write32(dev, B43_MMIO_MACCTL, |
| 2055 | b43_read32(dev, B43_MMIO_MACCTL) | 2054 | b43_read32(dev, B43_MMIO_MACCTL) |
| @@ -2075,7 +2074,6 @@ void b43_mac_suspend(struct b43_wldev *dev) | |||
| 2075 | u32 tmp; | 2074 | u32 tmp; |
| 2076 | 2075 | ||
| 2077 | might_sleep(); | 2076 | might_sleep(); |
| 2078 | B43_WARN_ON(irqs_disabled()); | ||
| 2079 | B43_WARN_ON(dev->mac_suspended < 0); | 2077 | B43_WARN_ON(dev->mac_suspended < 0); |
| 2080 | 2078 | ||
| 2081 | if (dev->mac_suspended == 0) { | 2079 | if (dev->mac_suspended == 0) { |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index d1af938b9aa6..b79a35a40ab6 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
| @@ -20,7 +20,7 @@ config IWL4965 | |||
| 20 | runs. | 20 | runs. |
| 21 | 21 | ||
| 22 | If you want to compile the driver as a module ( = code which can be | 22 | If you want to compile the driver as a module ( = code which can be |
| 23 | inserted in and remvoed from the running kernel whenever you want), | 23 | inserted in and removed from the running kernel whenever you want), |
| 24 | say M here and read <file:Documentation/kbuild/modules.txt>. The | 24 | say M here and read <file:Documentation/kbuild/modules.txt>. The |
| 25 | module will be called iwl4965.ko. | 25 | module will be called iwl4965.ko. |
| 26 | 26 | ||
| @@ -101,7 +101,7 @@ config IWL3945 | |||
| 101 | runs. | 101 | runs. |
| 102 | 102 | ||
| 103 | If you want to compile the driver as a module ( = code which can be | 103 | If you want to compile the driver as a module ( = code which can be |
| 104 | inserted in and remvoed from the running kernel whenever you want), | 104 | inserted in and removed from the running kernel whenever you want), |
| 105 | say M here and read <file:Documentation/kbuild/modules.txt>. The | 105 | say M here and read <file:Documentation/kbuild/modules.txt>. The |
| 106 | module will be called iwl3945.ko. | 106 | module will be called iwl3945.ko. |
| 107 | 107 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 40b71bc2c4a4..cbaeaf186494 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) | |||
| 6206 | 6206 | ||
| 6207 | /* At this point, the NIC is initialized and operational */ | 6207 | /* At this point, the NIC is initialized and operational */ |
| 6208 | priv->notif_missed_beacons = 0; | 6208 | priv->notif_missed_beacons = 0; |
| 6209 | set_bit(STATUS_READY, &priv->status); | ||
| 6210 | 6209 | ||
| 6211 | iwl3945_reg_txpower_periodic(priv); | 6210 | iwl3945_reg_txpower_periodic(priv); |
| 6212 | 6211 | ||
| 6213 | IWL_DEBUG_INFO("ALIVE processing complete.\n"); | 6212 | IWL_DEBUG_INFO("ALIVE processing complete.\n"); |
| 6213 | set_bit(STATUS_READY, &priv->status); | ||
| 6214 | wake_up_interruptible(&priv->wait_command_queue); | 6214 | wake_up_interruptible(&priv->wait_command_queue); |
| 6215 | 6215 | ||
| 6216 | if (priv->error_recovering) | 6216 | if (priv->error_recovering) |
| @@ -8706,7 +8706,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
| 8706 | return err; | 8706 | return err; |
| 8707 | } | 8707 | } |
| 8708 | 8708 | ||
| 8709 | static void iwl3945_pci_remove(struct pci_dev *pdev) | 8709 | static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) |
| 8710 | { | 8710 | { |
| 8711 | struct iwl3945_priv *priv = pci_get_drvdata(pdev); | 8711 | struct iwl3945_priv *priv = pci_get_drvdata(pdev); |
| 8712 | struct list_head *p, *q; | 8712 | struct list_head *p, *q; |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index a23d4798653b..60ec29eab85a 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) | |||
| 6628 | 6628 | ||
| 6629 | /* At this point, the NIC is initialized and operational */ | 6629 | /* At this point, the NIC is initialized and operational */ |
| 6630 | priv->notif_missed_beacons = 0; | 6630 | priv->notif_missed_beacons = 0; |
| 6631 | set_bit(STATUS_READY, &priv->status); | ||
| 6632 | 6631 | ||
| 6633 | iwl4965_rf_kill_ct_config(priv); | 6632 | iwl4965_rf_kill_ct_config(priv); |
| 6634 | 6633 | ||
| 6635 | IWL_DEBUG_INFO("ALIVE processing complete.\n"); | 6634 | IWL_DEBUG_INFO("ALIVE processing complete.\n"); |
| 6635 | set_bit(STATUS_READY, &priv->status); | ||
| 6636 | wake_up_interruptible(&priv->wait_command_queue); | 6636 | wake_up_interruptible(&priv->wait_command_queue); |
| 6637 | 6637 | ||
| 6638 | if (priv->error_recovering) | 6638 | if (priv->error_recovering) |
| @@ -9282,7 +9282,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
| 9282 | return err; | 9282 | return err; |
| 9283 | } | 9283 | } |
| 9284 | 9284 | ||
| 9285 | static void iwl4965_pci_remove(struct pci_dev *pdev) | 9285 | static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) |
| 9286 | { | 9286 | { |
| 9287 | struct iwl4965_priv *priv = pci_get_drvdata(pdev); | 9287 | struct iwl4965_priv *priv = pci_get_drvdata(pdev); |
| 9288 | struct list_head *p, *q; | 9288 | struct list_head *p, *q; |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 8103d41a1543..3909cf42f472 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
| @@ -2095,6 +2095,8 @@ static struct usb_device_id rt73usb_device_table[] = { | |||
| 2095 | { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, | 2095 | { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, |
| 2096 | /* Conceptronic */ | 2096 | /* Conceptronic */ |
| 2097 | { USB_DEVICE(0x14b2, 0x3c22), USB_DEVICE_DATA(&rt73usb_ops) }, | 2097 | { USB_DEVICE(0x14b2, 0x3c22), USB_DEVICE_DATA(&rt73usb_ops) }, |
| 2098 | /* Corega */ | ||
| 2099 | { USB_DEVICE(0x07aa, 0x002e), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2098 | /* D-Link */ | 2100 | /* D-Link */ |
| 2099 | { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, | 2101 | { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, |
| 2100 | { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, | 2102 | { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, |
diff --git a/drivers/net/wireless/wavelan_cs.h b/drivers/net/wireless/wavelan_cs.h index fabc63ee153c..2e4bfe4147c6 100644 --- a/drivers/net/wireless/wavelan_cs.h +++ b/drivers/net/wireless/wavelan_cs.h | |||
| @@ -309,7 +309,7 @@ struct mmw_t | |||
| 309 | #define MMW_EXT_ANT_INTERNAL 0x00 /* Internal antenna */ | 309 | #define MMW_EXT_ANT_INTERNAL 0x00 /* Internal antenna */ |
| 310 | #define MMW_EXT_ANT_EXTERNAL 0x03 /* External antenna */ | 310 | #define MMW_EXT_ANT_EXTERNAL 0x03 /* External antenna */ |
| 311 | #define MMW_EXT_ANT_IQ_TEST 0x1C /* IQ test pattern (set to 0) */ | 311 | #define MMW_EXT_ANT_IQ_TEST 0x1C /* IQ test pattern (set to 0) */ |
| 312 | }; | 312 | } __attribute__((packed)); |
| 313 | 313 | ||
| 314 | /* Size for structure checking (if padding is correct) */ | 314 | /* Size for structure checking (if padding is correct) */ |
| 315 | #define MMW_SIZE 37 | 315 | #define MMW_SIZE 37 |
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index ebbfb509822e..64a5f0120b52 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h | |||
| @@ -218,6 +218,10 @@ extern unsigned long neigh_rand_reach_time(unsigned long base); | |||
| 218 | extern void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p, | 218 | extern void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p, |
| 219 | struct sk_buff *skb); | 219 | struct sk_buff *skb); |
| 220 | extern struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev, int creat); | 220 | extern struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev, int creat); |
| 221 | extern struct pneigh_entry *__pneigh_lookup(struct neigh_table *tbl, | ||
| 222 | struct net *net, | ||
| 223 | const void *key, | ||
| 224 | struct net_device *dev); | ||
| 221 | extern int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev); | 225 | extern int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev); |
| 222 | 226 | ||
| 223 | extern void neigh_app_ns(struct neighbour *n); | 227 | extern void neigh_app_ns(struct neighbour *n); |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 619c53bc3cd2..0d255ae008b6 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
| @@ -204,6 +204,7 @@ struct xfrm_state | |||
| 204 | * transformer. */ | 204 | * transformer. */ |
| 205 | const struct xfrm_type *type; | 205 | const struct xfrm_type *type; |
| 206 | struct xfrm_mode *inner_mode; | 206 | struct xfrm_mode *inner_mode; |
| 207 | struct xfrm_mode *inner_mode_iaf; | ||
| 207 | struct xfrm_mode *outer_mode; | 208 | struct xfrm_mode *outer_mode; |
| 208 | 209 | ||
| 209 | /* Security context */ | 210 | /* Security context */ |
| @@ -387,6 +388,27 @@ enum { | |||
| 387 | extern int xfrm_register_mode(struct xfrm_mode *mode, int family); | 388 | extern int xfrm_register_mode(struct xfrm_mode *mode, int family); |
| 388 | extern int xfrm_unregister_mode(struct xfrm_mode *mode, int family); | 389 | extern int xfrm_unregister_mode(struct xfrm_mode *mode, int family); |
| 389 | 390 | ||
| 391 | static inline int xfrm_af2proto(unsigned int family) | ||
| 392 | { | ||
| 393 | switch(family) { | ||
| 394 | case AF_INET: | ||
| 395 | return IPPROTO_IPIP; | ||
| 396 | case AF_INET6: | ||
| 397 | return IPPROTO_IPV6; | ||
| 398 | default: | ||
| 399 | return 0; | ||
| 400 | } | ||
| 401 | } | ||
| 402 | |||
| 403 | static inline struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto) | ||
| 404 | { | ||
| 405 | if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) || | ||
| 406 | (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6)) | ||
| 407 | return x->inner_mode; | ||
| 408 | else | ||
| 409 | return x->inner_mode_iaf; | ||
| 410 | } | ||
| 411 | |||
| 390 | struct xfrm_tmpl | 412 | struct xfrm_tmpl |
| 391 | { | 413 | { |
| 392 | /* id in template is interpreted as: | 414 | /* id in template is interpreted as: |
| @@ -530,6 +552,9 @@ struct xfrm_mode_skb_cb { | |||
| 530 | __be16 id; | 552 | __be16 id; |
| 531 | __be16 frag_off; | 553 | __be16 frag_off; |
| 532 | 554 | ||
| 555 | /* IP header length (excluding options or extension headers). */ | ||
| 556 | u8 ihl; | ||
| 557 | |||
| 533 | /* TOS for IPv4, class for IPv6. */ | 558 | /* TOS for IPv4, class for IPv6. */ |
| 534 | u8 tos; | 559 | u8 tos; |
| 535 | 560 | ||
| @@ -539,6 +564,9 @@ struct xfrm_mode_skb_cb { | |||
| 539 | /* Protocol for IPv4, NH for IPv6. */ | 564 | /* Protocol for IPv4, NH for IPv6. */ |
| 540 | u8 protocol; | 565 | u8 protocol; |
| 541 | 566 | ||
| 567 | /* Option length for IPv4, zero for IPv6. */ | ||
| 568 | u8 optlen; | ||
| 569 | |||
| 542 | /* Used by IPv6 only, zero for IPv4. */ | 570 | /* Used by IPv6 only, zero for IPv4. */ |
| 543 | u8 flow_lbl[3]; | 571 | u8 flow_lbl[3]; |
| 544 | }; | 572 | }; |
| @@ -1253,6 +1281,7 @@ extern int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, | |||
| 1253 | extern int xfrm_input_resume(struct sk_buff *skb, int nexthdr); | 1281 | extern int xfrm_input_resume(struct sk_buff *skb, int nexthdr); |
| 1254 | extern int xfrm_output_resume(struct sk_buff *skb, int err); | 1282 | extern int xfrm_output_resume(struct sk_buff *skb, int err); |
| 1255 | extern int xfrm_output(struct sk_buff *skb); | 1283 | extern int xfrm_output(struct sk_buff *skb); |
| 1284 | extern int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb); | ||
| 1256 | extern int xfrm4_extract_header(struct sk_buff *skb); | 1285 | extern int xfrm4_extract_header(struct sk_buff *skb); |
| 1257 | extern int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb); | 1286 | extern int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb); |
| 1258 | extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi, | 1287 | extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi, |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 8fbcefe10c9f..480ea90e7dcd 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
| @@ -660,7 +660,7 @@ static int vlan_dev_init(struct net_device *dev) | |||
| 660 | int subclass = 0; | 660 | int subclass = 0; |
| 661 | 661 | ||
| 662 | /* IFF_BROADCAST|IFF_MULTICAST; ??? */ | 662 | /* IFF_BROADCAST|IFF_MULTICAST; ??? */ |
| 663 | dev->flags = real_dev->flags & ~IFF_UP; | 663 | dev->flags = real_dev->flags & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI); |
| 664 | dev->iflink = real_dev->ifindex; | 664 | dev->iflink = real_dev->ifindex; |
| 665 | dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) | | 665 | dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) | |
| 666 | (1<<__LINK_STATE_DORMANT))) | | 666 | (1<<__LINK_STATE_DORMANT))) | |
diff --git a/net/ax25/TODO b/net/ax25/TODO index 4089c49e45cc..69fb4e368d92 100644 --- a/net/ax25/TODO +++ b/net/ax25/TODO | |||
| @@ -9,10 +9,6 @@ being used. | |||
| 9 | Routes to a device being taken down might be deleted by ax25_rt_device_down | 9 | Routes to a device being taken down might be deleted by ax25_rt_device_down |
| 10 | but added by somebody else before the device has been deleted fully. | 10 | but added by somebody else before the device has been deleted fully. |
| 11 | 11 | ||
| 12 | Massive amounts of lock_kernel / unlock_kernel are just a temporary solution to | ||
| 13 | get around the removal of SOCKOPS_WRAP. A serious locking strategy has to be | ||
| 14 | implemented. | ||
| 15 | |||
| 16 | The ax25_rt_find_route synopsys is pervert but I somehow had to deal with | 12 | The ax25_rt_find_route synopsys is pervert but I somehow had to deal with |
| 17 | the race caused by the static variable in it's previous implementation. | 13 | the race caused by the static variable in it's previous implementation. |
| 18 | 14 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index fcdf03cf3b3f..460e7f99ce3e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -3329,7 +3329,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd) | |||
| 3329 | return -EOPNOTSUPP; | 3329 | return -EOPNOTSUPP; |
| 3330 | 3330 | ||
| 3331 | case SIOCADDMULTI: | 3331 | case SIOCADDMULTI: |
| 3332 | if (!dev->set_multicast_list || | 3332 | if ((!dev->set_multicast_list && !dev->set_rx_mode) || |
| 3333 | ifr->ifr_hwaddr.sa_family != AF_UNSPEC) | 3333 | ifr->ifr_hwaddr.sa_family != AF_UNSPEC) |
| 3334 | return -EINVAL; | 3334 | return -EINVAL; |
| 3335 | if (!netif_device_present(dev)) | 3335 | if (!netif_device_present(dev)) |
| @@ -3338,7 +3338,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd) | |||
| 3338 | dev->addr_len, 1); | 3338 | dev->addr_len, 1); |
| 3339 | 3339 | ||
| 3340 | case SIOCDELMULTI: | 3340 | case SIOCDELMULTI: |
| 3341 | if (!dev->set_multicast_list || | 3341 | if ((!dev->set_multicast_list && !dev->set_rx_mode) || |
| 3342 | ifr->ifr_hwaddr.sa_family != AF_UNSPEC) | 3342 | ifr->ifr_hwaddr.sa_family != AF_UNSPEC) |
| 3343 | return -EINVAL; | 3343 | return -EINVAL; |
| 3344 | if (!netif_device_present(dev)) | 3344 | if (!netif_device_present(dev)) |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index d9a02b2cc289..19b8e003f150 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
| @@ -466,6 +466,28 @@ out_neigh_release: | |||
| 466 | goto out; | 466 | goto out; |
| 467 | } | 467 | } |
| 468 | 468 | ||
| 469 | struct pneigh_entry *__pneigh_lookup(struct neigh_table *tbl, | ||
| 470 | struct net *net, const void *pkey, struct net_device *dev) | ||
| 471 | { | ||
| 472 | struct pneigh_entry *n; | ||
| 473 | int key_len = tbl->key_len; | ||
| 474 | u32 hash_val = *(u32 *)(pkey + key_len - 4); | ||
| 475 | |||
| 476 | hash_val ^= (hash_val >> 16); | ||
| 477 | hash_val ^= hash_val >> 8; | ||
| 478 | hash_val ^= hash_val >> 4; | ||
| 479 | hash_val &= PNEIGH_HASHMASK; | ||
| 480 | |||
| 481 | for (n = tbl->phash_buckets[hash_val]; n; n = n->next) { | ||
| 482 | if (!memcmp(n->key, pkey, key_len) && | ||
| 483 | (n->net == net) && | ||
| 484 | (n->dev == dev || !n->dev)) | ||
| 485 | break; | ||
| 486 | } | ||
| 487 | |||
| 488 | return n; | ||
| 489 | } | ||
| 490 | |||
| 469 | struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, | 491 | struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, |
| 470 | struct net *net, const void *pkey, | 492 | struct net *net, const void *pkey, |
| 471 | struct net_device *dev, int creat) | 493 | struct net_device *dev, int creat) |
| @@ -2803,6 +2825,7 @@ EXPORT_SYMBOL(neigh_table_init_no_netlink); | |||
| 2803 | EXPORT_SYMBOL(neigh_update); | 2825 | EXPORT_SYMBOL(neigh_update); |
| 2804 | EXPORT_SYMBOL(pneigh_enqueue); | 2826 | EXPORT_SYMBOL(pneigh_enqueue); |
| 2805 | EXPORT_SYMBOL(pneigh_lookup); | 2827 | EXPORT_SYMBOL(pneigh_lookup); |
| 2828 | EXPORT_SYMBOL_GPL(__pneigh_lookup); | ||
| 2806 | 2829 | ||
| 2807 | #ifdef CONFIG_ARPD | 2830 | #ifdef CONFIG_ARPD |
| 2808 | EXPORT_SYMBOL(neigh_app_ns); | 2831 | EXPORT_SYMBOL(neigh_app_ns); |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index a13c074dac09..a944e8053e28 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
| @@ -591,7 +591,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
| 591 | } | 591 | } |
| 592 | 592 | ||
| 593 | if (xfrm_decode_session_reverse(skb_in, &fl, AF_INET)) | 593 | if (xfrm_decode_session_reverse(skb_in, &fl, AF_INET)) |
| 594 | goto out_unlock; | 594 | goto ende; |
| 595 | 595 | ||
| 596 | if (inet_addr_type(net, fl.fl4_src) == RTN_LOCAL) | 596 | if (inet_addr_type(net, fl.fl4_src) == RTN_LOCAL) |
| 597 | err = __ip_route_output_key(net, &rt2, &fl); | 597 | err = __ip_route_output_key(net, &rt2, &fl); |
| @@ -601,7 +601,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
| 601 | 601 | ||
| 602 | fl2.fl4_dst = fl.fl4_src; | 602 | fl2.fl4_dst = fl.fl4_src; |
| 603 | if (ip_route_output_key(net, &rt2, &fl2)) | 603 | if (ip_route_output_key(net, &rt2, &fl2)) |
| 604 | goto out_unlock; | 604 | goto ende; |
| 605 | 605 | ||
| 606 | /* Ugh! */ | 606 | /* Ugh! */ |
| 607 | odst = skb_in->dst; | 607 | odst = skb_in->dst; |
| @@ -614,7 +614,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
| 614 | } | 614 | } |
| 615 | 615 | ||
| 616 | if (err) | 616 | if (err) |
| 617 | goto out_unlock; | 617 | goto ende; |
| 618 | 618 | ||
| 619 | err = xfrm_lookup((struct dst_entry **)&rt2, &fl, NULL, | 619 | err = xfrm_lookup((struct dst_entry **)&rt2, &fl, NULL, |
| 620 | XFRM_LOOKUP_ICMP); | 620 | XFRM_LOOKUP_ICMP); |
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c index b47030ba162b..9c798abce736 100644 --- a/net/ipv4/xfrm4_mode_beet.c +++ b/net/ipv4/xfrm4_mode_beet.c | |||
| @@ -39,13 +39,11 @@ static void xfrm4_beet_make_header(struct sk_buff *skb) | |||
| 39 | static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) | 39 | static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) |
| 40 | { | 40 | { |
| 41 | struct ip_beet_phdr *ph; | 41 | struct ip_beet_phdr *ph; |
| 42 | struct iphdr *iph, *top_iph; | 42 | struct iphdr *top_iph; |
| 43 | int hdrlen, optlen; | 43 | int hdrlen, optlen; |
| 44 | 44 | ||
| 45 | iph = ip_hdr(skb); | ||
| 46 | |||
| 47 | hdrlen = 0; | 45 | hdrlen = 0; |
| 48 | optlen = iph->ihl * 4 - sizeof(*iph); | 46 | optlen = XFRM_MODE_SKB_CB(skb)->optlen; |
| 49 | if (unlikely(optlen)) | 47 | if (unlikely(optlen)) |
| 50 | hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4); | 48 | hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4); |
| 51 | 49 | ||
| @@ -53,11 +51,12 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 53 | hdrlen); | 51 | hdrlen); |
| 54 | skb->mac_header = skb->network_header + | 52 | skb->mac_header = skb->network_header + |
| 55 | offsetof(struct iphdr, protocol); | 53 | offsetof(struct iphdr, protocol); |
| 56 | skb->transport_header = skb->network_header + sizeof(*iph); | 54 | skb->transport_header = skb->network_header + sizeof(*top_iph); |
| 57 | 55 | ||
| 58 | xfrm4_beet_make_header(skb); | 56 | xfrm4_beet_make_header(skb); |
| 59 | 57 | ||
| 60 | ph = (struct ip_beet_phdr *)__skb_pull(skb, sizeof(*iph) - hdrlen); | 58 | ph = (struct ip_beet_phdr *) |
| 59 | __skb_pull(skb, XFRM_MODE_SKB_CB(skb)->ihl - hdrlen); | ||
| 61 | 60 | ||
| 62 | top_iph = ip_hdr(skb); | 61 | top_iph = ip_hdr(skb); |
| 63 | 62 | ||
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c index 8dee617ee900..584e6d74e3a9 100644 --- a/net/ipv4/xfrm4_mode_tunnel.c +++ b/net/ipv4/xfrm4_mode_tunnel.c | |||
| @@ -41,7 +41,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 41 | top_iph->ihl = 5; | 41 | top_iph->ihl = 5; |
| 42 | top_iph->version = 4; | 42 | top_iph->version = 4; |
| 43 | 43 | ||
| 44 | top_iph->protocol = x->inner_mode->afinfo->proto; | 44 | top_iph->protocol = xfrm_af2proto(skb->dst->ops->family); |
| 45 | 45 | ||
| 46 | /* DS disclosed */ | 46 | /* DS disclosed */ |
| 47 | top_iph->tos = INET_ECN_encapsulate(XFRM_MODE_SKB_CB(skb)->tos, | 47 | top_iph->tos = INET_ECN_encapsulate(XFRM_MODE_SKB_CB(skb)->tos, |
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index d5a58a818021..8c3180adddbf 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c | |||
| @@ -56,7 +56,7 @@ int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 56 | { | 56 | { |
| 57 | int err; | 57 | int err; |
| 58 | 58 | ||
| 59 | err = x->inner_mode->afinfo->extract_output(x, skb); | 59 | err = xfrm_inner_extract_output(x, skb); |
| 60 | if (err) | 60 | if (err) |
| 61 | return err; | 61 | return err; |
| 62 | 62 | ||
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c index fdeebe68a379..07735ed280d7 100644 --- a/net/ipv4/xfrm4_state.c +++ b/net/ipv4/xfrm4_state.c | |||
| @@ -52,10 +52,12 @@ int xfrm4_extract_header(struct sk_buff *skb) | |||
| 52 | { | 52 | { |
| 53 | struct iphdr *iph = ip_hdr(skb); | 53 | struct iphdr *iph = ip_hdr(skb); |
| 54 | 54 | ||
| 55 | XFRM_MODE_SKB_CB(skb)->ihl = sizeof(*iph); | ||
| 55 | XFRM_MODE_SKB_CB(skb)->id = iph->id; | 56 | XFRM_MODE_SKB_CB(skb)->id = iph->id; |
| 56 | XFRM_MODE_SKB_CB(skb)->frag_off = iph->frag_off; | 57 | XFRM_MODE_SKB_CB(skb)->frag_off = iph->frag_off; |
| 57 | XFRM_MODE_SKB_CB(skb)->tos = iph->tos; | 58 | XFRM_MODE_SKB_CB(skb)->tos = iph->tos; |
| 58 | XFRM_MODE_SKB_CB(skb)->ttl = iph->ttl; | 59 | XFRM_MODE_SKB_CB(skb)->ttl = iph->ttl; |
| 60 | XFRM_MODE_SKB_CB(skb)->optlen = iph->ihl * 4 - sizeof(*iph); | ||
| 59 | memset(XFRM_MODE_SKB_CB(skb)->flow_lbl, 0, | 61 | memset(XFRM_MODE_SKB_CB(skb)->flow_lbl, 0, |
| 60 | sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl)); | 62 | sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl)); |
| 61 | 63 | ||
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 51557c27a0cd..452a2ac4eec8 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -676,6 +676,20 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb) | |||
| 676 | } | 676 | } |
| 677 | } | 677 | } |
| 678 | 678 | ||
| 679 | static struct pneigh_entry *pndisc_check_router(struct net_device *dev, | ||
| 680 | struct in6_addr *addr, int *is_router) | ||
| 681 | { | ||
| 682 | struct pneigh_entry *n; | ||
| 683 | |||
| 684 | read_lock_bh(&nd_tbl.lock); | ||
| 685 | n = __pneigh_lookup(&nd_tbl, &init_net, addr, dev); | ||
| 686 | if (n != NULL) | ||
| 687 | *is_router = (n->flags & NTF_ROUTER); | ||
| 688 | read_unlock_bh(&nd_tbl.lock); | ||
| 689 | |||
| 690 | return n; | ||
| 691 | } | ||
| 692 | |||
| 679 | static void ndisc_recv_ns(struct sk_buff *skb) | 693 | static void ndisc_recv_ns(struct sk_buff *skb) |
| 680 | { | 694 | { |
| 681 | struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb); | 695 | struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb); |
| @@ -692,7 +706,7 @@ static void ndisc_recv_ns(struct sk_buff *skb) | |||
| 692 | struct pneigh_entry *pneigh = NULL; | 706 | struct pneigh_entry *pneigh = NULL; |
| 693 | int dad = ipv6_addr_any(saddr); | 707 | int dad = ipv6_addr_any(saddr); |
| 694 | int inc; | 708 | int inc; |
| 695 | int is_router; | 709 | int is_router = 0; |
| 696 | 710 | ||
| 697 | if (ipv6_addr_is_multicast(&msg->target)) { | 711 | if (ipv6_addr_is_multicast(&msg->target)) { |
| 698 | ND_PRINTK2(KERN_WARNING | 712 | ND_PRINTK2(KERN_WARNING |
| @@ -790,8 +804,8 @@ static void ndisc_recv_ns(struct sk_buff *skb) | |||
| 790 | if (ipv6_chk_acast_addr(dev, &msg->target) || | 804 | if (ipv6_chk_acast_addr(dev, &msg->target) || |
| 791 | (idev->cnf.forwarding && | 805 | (idev->cnf.forwarding && |
| 792 | (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) && | 806 | (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) && |
| 793 | (pneigh = pneigh_lookup(&nd_tbl, &init_net, | 807 | (pneigh = pndisc_check_router(dev, &msg->target, |
| 794 | &msg->target, dev, 0)) != NULL)) { | 808 | &is_router)) != NULL)) { |
| 795 | if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) && | 809 | if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) && |
| 796 | skb->pkt_type != PACKET_HOST && | 810 | skb->pkt_type != PACKET_HOST && |
| 797 | inc != 0 && | 811 | inc != 0 && |
| @@ -812,7 +826,7 @@ static void ndisc_recv_ns(struct sk_buff *skb) | |||
| 812 | goto out; | 826 | goto out; |
| 813 | } | 827 | } |
| 814 | 828 | ||
| 815 | is_router = !!(pneigh ? pneigh->flags & NTF_ROUTER : idev->cnf.forwarding); | 829 | is_router = !!(pneigh ? is_router : idev->cnf.forwarding); |
| 816 | 830 | ||
| 817 | if (dad) { | 831 | if (dad) { |
| 818 | struct in6_addr maddr; | 832 | struct in6_addr maddr; |
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c index 0527d11c1ae3..d6ce400f585f 100644 --- a/net/ipv6/xfrm6_mode_beet.c +++ b/net/ipv6/xfrm6_mode_beet.c | |||
| @@ -45,6 +45,7 @@ static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 45 | skb->mac_header = skb->network_header + | 45 | skb->mac_header = skb->network_header + |
| 46 | offsetof(struct ipv6hdr, nexthdr); | 46 | offsetof(struct ipv6hdr, nexthdr); |
| 47 | skb->transport_header = skb->network_header + sizeof(*top_iph); | 47 | skb->transport_header = skb->network_header + sizeof(*top_iph); |
| 48 | __skb_pull(skb, XFRM_MODE_SKB_CB(skb)->ihl); | ||
| 48 | 49 | ||
| 49 | xfrm6_beet_make_header(skb); | 50 | xfrm6_beet_make_header(skb); |
| 50 | 51 | ||
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c index 0c742faaa30b..e20529b4c825 100644 --- a/net/ipv6/xfrm6_mode_tunnel.c +++ b/net/ipv6/xfrm6_mode_tunnel.c | |||
| @@ -45,7 +45,7 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 45 | 45 | ||
| 46 | memcpy(top_iph->flow_lbl, XFRM_MODE_SKB_CB(skb)->flow_lbl, | 46 | memcpy(top_iph->flow_lbl, XFRM_MODE_SKB_CB(skb)->flow_lbl, |
| 47 | sizeof(top_iph->flow_lbl)); | 47 | sizeof(top_iph->flow_lbl)); |
| 48 | top_iph->nexthdr = x->inner_mode->afinfo->proto; | 48 | top_iph->nexthdr = xfrm_af2proto(skb->dst->ops->family); |
| 49 | 49 | ||
| 50 | dsfield = XFRM_MODE_SKB_CB(skb)->tos; | 50 | dsfield = XFRM_MODE_SKB_CB(skb)->tos; |
| 51 | dsfield = INET_ECN_encapsulate(dsfield, dsfield); | 51 | dsfield = INET_ECN_encapsulate(dsfield, dsfield); |
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index 79ccfb080733..0af823cf7f1f 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c | |||
| @@ -62,7 +62,7 @@ int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 62 | { | 62 | { |
| 63 | int err; | 63 | int err; |
| 64 | 64 | ||
| 65 | err = x->inner_mode->afinfo->extract_output(x, skb); | 65 | err = xfrm_inner_extract_output(x, skb); |
| 66 | if (err) | 66 | if (err) |
| 67 | return err; | 67 | return err; |
| 68 | 68 | ||
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index dc817e035e23..ff1e1db8e236 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c | |||
| @@ -174,10 +174,12 @@ int xfrm6_extract_header(struct sk_buff *skb) | |||
| 174 | { | 174 | { |
| 175 | struct ipv6hdr *iph = ipv6_hdr(skb); | 175 | struct ipv6hdr *iph = ipv6_hdr(skb); |
| 176 | 176 | ||
| 177 | XFRM_MODE_SKB_CB(skb)->ihl = sizeof(*iph); | ||
| 177 | XFRM_MODE_SKB_CB(skb)->id = 0; | 178 | XFRM_MODE_SKB_CB(skb)->id = 0; |
| 178 | XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF); | 179 | XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF); |
| 179 | XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph); | 180 | XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph); |
| 180 | XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit; | 181 | XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit; |
| 182 | XFRM_MODE_SKB_CB(skb)->optlen = 0; | ||
| 181 | memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl, | 183 | memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl, |
| 182 | sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl)); | 184 | sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl)); |
| 183 | 185 | ||
diff --git a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h index bc2e15ce7004..7873c392ab4c 100644 --- a/net/irda/irnet/irnet.h +++ b/net/irda/irnet/irnet.h | |||
| @@ -405,7 +405,7 @@ typedef struct irnet_socket | |||
| 405 | /* "pppd" interact directly with us on a /dev/ file */ | 405 | /* "pppd" interact directly with us on a /dev/ file */ |
| 406 | struct file * file; /* File descriptor of this instance */ | 406 | struct file * file; /* File descriptor of this instance */ |
| 407 | /* TTY stuff - to keep "pppd" happy */ | 407 | /* TTY stuff - to keep "pppd" happy */ |
| 408 | struct termios termios; /* Various tty flags */ | 408 | struct ktermios termios; /* Various tty flags */ |
| 409 | /* Stuff for the control channel */ | 409 | /* Stuff for the control channel */ |
| 410 | int event_index; /* Last read in the event log */ | 410 | int event_index; /* Last read in the event log */ |
| 411 | 411 | ||
diff --git a/net/key/af_key.c b/net/key/af_key.c index 8b5f486ac80f..e9ef9af4a53b 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
| @@ -1219,7 +1219,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, | |||
| 1219 | x->sel.prefixlen_s = addr->sadb_address_prefixlen; | 1219 | x->sel.prefixlen_s = addr->sadb_address_prefixlen; |
| 1220 | } | 1220 | } |
| 1221 | 1221 | ||
| 1222 | if (!x->sel.family) | 1222 | if (x->props.mode == XFRM_MODE_TRANSPORT) |
| 1223 | x->sel.family = x->props.family; | 1223 | x->sel.family = x->props.family; |
| 1224 | 1224 | ||
| 1225 | if (ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1]) { | 1225 | if (ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1]) { |
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 62188c6a06dd..75279402ccf4 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
| @@ -84,14 +84,21 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq) | |||
| 84 | 84 | ||
| 85 | int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb) | 85 | int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb) |
| 86 | { | 86 | { |
| 87 | struct xfrm_mode *inner_mode = x->inner_mode; | ||
| 87 | int err; | 88 | int err; |
| 88 | 89 | ||
| 89 | err = x->outer_mode->afinfo->extract_input(x, skb); | 90 | err = x->outer_mode->afinfo->extract_input(x, skb); |
| 90 | if (err) | 91 | if (err) |
| 91 | return err; | 92 | return err; |
| 92 | 93 | ||
| 93 | skb->protocol = x->inner_mode->afinfo->eth_proto; | 94 | if (x->sel.family == AF_UNSPEC) { |
| 94 | return x->inner_mode->input2(x, skb); | 95 | inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); |
| 96 | if (inner_mode == NULL) | ||
| 97 | return -EAFNOSUPPORT; | ||
| 98 | } | ||
| 99 | |||
| 100 | skb->protocol = inner_mode->afinfo->eth_proto; | ||
| 101 | return inner_mode->input2(x, skb); | ||
| 95 | } | 102 | } |
| 96 | EXPORT_SYMBOL(xfrm_prepare_input); | 103 | EXPORT_SYMBOL(xfrm_prepare_input); |
| 97 | 104 | ||
| @@ -101,6 +108,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
| 101 | __be32 seq; | 108 | __be32 seq; |
| 102 | struct xfrm_state *x; | 109 | struct xfrm_state *x; |
| 103 | xfrm_address_t *daddr; | 110 | xfrm_address_t *daddr; |
| 111 | struct xfrm_mode *inner_mode; | ||
| 104 | unsigned int family; | 112 | unsigned int family; |
| 105 | int decaps = 0; | 113 | int decaps = 0; |
| 106 | int async = 0; | 114 | int async = 0; |
| @@ -207,7 +215,15 @@ resume: | |||
| 207 | 215 | ||
| 208 | XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; | 216 | XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; |
| 209 | 217 | ||
| 210 | if (x->inner_mode->input(x, skb)) { | 218 | inner_mode = x->inner_mode; |
| 219 | |||
| 220 | if (x->sel.family == AF_UNSPEC) { | ||
| 221 | inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); | ||
| 222 | if (inner_mode == NULL) | ||
| 223 | goto drop; | ||
| 224 | } | ||
| 225 | |||
| 226 | if (inner_mode->input(x, skb)) { | ||
| 211 | XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMODEERROR); | 227 | XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMODEERROR); |
| 212 | goto drop; | 228 | goto drop; |
| 213 | } | 229 | } |
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index 569d377932c4..2519129c6d21 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c | |||
| @@ -124,7 +124,7 @@ int xfrm_output_resume(struct sk_buff *skb, int err) | |||
| 124 | if (!x) | 124 | if (!x) |
| 125 | return dst_output(skb); | 125 | return dst_output(skb); |
| 126 | 126 | ||
| 127 | err = nf_hook(x->inner_mode->afinfo->family, | 127 | err = nf_hook(skb->dst->ops->family, |
| 128 | NF_INET_POST_ROUTING, skb, | 128 | NF_INET_POST_ROUTING, skb, |
| 129 | NULL, skb->dst->dev, xfrm_output2); | 129 | NULL, skb->dst->dev, xfrm_output2); |
| 130 | if (unlikely(err != 1)) | 130 | if (unlikely(err != 1)) |
| @@ -193,4 +193,20 @@ int xfrm_output(struct sk_buff *skb) | |||
| 193 | 193 | ||
| 194 | return xfrm_output2(skb); | 194 | return xfrm_output2(skb); |
| 195 | } | 195 | } |
| 196 | |||
| 197 | int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb) | ||
| 198 | { | ||
| 199 | struct xfrm_mode *inner_mode; | ||
| 200 | if (x->sel.family == AF_UNSPEC) | ||
| 201 | inner_mode = xfrm_ip2inner_mode(x, | ||
| 202 | xfrm_af2proto(skb->dst->ops->family)); | ||
| 203 | else | ||
| 204 | inner_mode = x->inner_mode; | ||
| 205 | |||
| 206 | if (inner_mode == NULL) | ||
| 207 | return -EAFNOSUPPORT; | ||
| 208 | return inner_mode->afinfo->extract_output(x, skb); | ||
| 209 | } | ||
| 210 | |||
| 196 | EXPORT_SYMBOL_GPL(xfrm_output); | 211 | EXPORT_SYMBOL_GPL(xfrm_output); |
| 212 | EXPORT_SYMBOL_GPL(xfrm_inner_extract_output); | ||
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 7ba65e82941c..58f1f9347b54 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
| @@ -388,6 +388,8 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x) | |||
| 388 | kfree(x->coaddr); | 388 | kfree(x->coaddr); |
| 389 | if (x->inner_mode) | 389 | if (x->inner_mode) |
| 390 | xfrm_put_mode(x->inner_mode); | 390 | xfrm_put_mode(x->inner_mode); |
| 391 | if (x->inner_mode_iaf) | ||
| 392 | xfrm_put_mode(x->inner_mode_iaf); | ||
| 391 | if (x->outer_mode) | 393 | if (x->outer_mode) |
| 392 | xfrm_put_mode(x->outer_mode); | 394 | xfrm_put_mode(x->outer_mode); |
| 393 | if (x->type) { | 395 | if (x->type) { |
| @@ -523,6 +525,8 @@ struct xfrm_state *xfrm_state_alloc(void) | |||
| 523 | x->lft.hard_packet_limit = XFRM_INF; | 525 | x->lft.hard_packet_limit = XFRM_INF; |
| 524 | x->replay_maxage = 0; | 526 | x->replay_maxage = 0; |
| 525 | x->replay_maxdiff = 0; | 527 | x->replay_maxdiff = 0; |
| 528 | x->inner_mode = NULL; | ||
| 529 | x->inner_mode_iaf = NULL; | ||
| 526 | spin_lock_init(&x->lock); | 530 | spin_lock_init(&x->lock); |
| 527 | } | 531 | } |
| 528 | return x; | 532 | return x; |
| @@ -796,7 +800,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
| 796 | selector. | 800 | selector. |
| 797 | */ | 801 | */ |
| 798 | if (x->km.state == XFRM_STATE_VALID) { | 802 | if (x->km.state == XFRM_STATE_VALID) { |
| 799 | if (!xfrm_selector_match(&x->sel, fl, x->sel.family) || | 803 | if ((x->sel.family && !xfrm_selector_match(&x->sel, fl, x->sel.family)) || |
| 800 | !security_xfrm_state_pol_flow_match(x, pol, fl)) | 804 | !security_xfrm_state_pol_flow_match(x, pol, fl)) |
| 801 | continue; | 805 | continue; |
| 802 | if (!best || | 806 | if (!best || |
| @@ -1944,6 +1948,7 @@ int xfrm_state_mtu(struct xfrm_state *x, int mtu) | |||
| 1944 | int xfrm_init_state(struct xfrm_state *x) | 1948 | int xfrm_init_state(struct xfrm_state *x) |
| 1945 | { | 1949 | { |
| 1946 | struct xfrm_state_afinfo *afinfo; | 1950 | struct xfrm_state_afinfo *afinfo; |
| 1951 | struct xfrm_mode *inner_mode; | ||
| 1947 | int family = x->props.family; | 1952 | int family = x->props.family; |
| 1948 | int err; | 1953 | int err; |
| 1949 | 1954 | ||
| @@ -1962,13 +1967,48 @@ int xfrm_init_state(struct xfrm_state *x) | |||
| 1962 | goto error; | 1967 | goto error; |
| 1963 | 1968 | ||
| 1964 | err = -EPROTONOSUPPORT; | 1969 | err = -EPROTONOSUPPORT; |
| 1965 | x->inner_mode = xfrm_get_mode(x->props.mode, x->sel.family); | ||
| 1966 | if (x->inner_mode == NULL) | ||
| 1967 | goto error; | ||
| 1968 | 1970 | ||
| 1969 | if (!(x->inner_mode->flags & XFRM_MODE_FLAG_TUNNEL) && | 1971 | if (x->sel.family != AF_UNSPEC) { |
| 1970 | family != x->sel.family) | 1972 | inner_mode = xfrm_get_mode(x->props.mode, x->sel.family); |
| 1971 | goto error; | 1973 | if (inner_mode == NULL) |
| 1974 | goto error; | ||
| 1975 | |||
| 1976 | if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL) && | ||
| 1977 | family != x->sel.family) { | ||
| 1978 | xfrm_put_mode(inner_mode); | ||
| 1979 | goto error; | ||
| 1980 | } | ||
| 1981 | |||
| 1982 | x->inner_mode = inner_mode; | ||
| 1983 | } else { | ||
| 1984 | struct xfrm_mode *inner_mode_iaf; | ||
| 1985 | |||
| 1986 | inner_mode = xfrm_get_mode(x->props.mode, AF_INET); | ||
| 1987 | if (inner_mode == NULL) | ||
| 1988 | goto error; | ||
| 1989 | |||
| 1990 | if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL)) { | ||
| 1991 | xfrm_put_mode(inner_mode); | ||
| 1992 | goto error; | ||
| 1993 | } | ||
| 1994 | |||
| 1995 | inner_mode_iaf = xfrm_get_mode(x->props.mode, AF_INET6); | ||
| 1996 | if (inner_mode_iaf == NULL) | ||
| 1997 | goto error; | ||
| 1998 | |||
| 1999 | if (!(inner_mode_iaf->flags & XFRM_MODE_FLAG_TUNNEL)) { | ||
| 2000 | xfrm_put_mode(inner_mode_iaf); | ||
| 2001 | goto error; | ||
| 2002 | } | ||
| 2003 | |||
| 2004 | if (x->props.family == AF_INET) { | ||
| 2005 | x->inner_mode = inner_mode; | ||
| 2006 | x->inner_mode_iaf = inner_mode_iaf; | ||
| 2007 | } else { | ||
| 2008 | x->inner_mode = inner_mode_iaf; | ||
| 2009 | x->inner_mode_iaf = inner_mode; | ||
| 2010 | } | ||
| 2011 | } | ||
| 1972 | 2012 | ||
| 1973 | x->type = xfrm_get_type(x->id.proto, family); | 2013 | x->type = xfrm_get_type(x->id.proto, family); |
| 1974 | if (x->type == NULL) | 2014 | if (x->type == NULL) |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index f971ca5645f8..5d96f2728dc6 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -288,12 +288,9 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info * | |||
| 288 | memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr)); | 288 | memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr)); |
| 289 | x->props.flags = p->flags; | 289 | x->props.flags = p->flags; |
| 290 | 290 | ||
| 291 | /* | 291 | if (x->props.mode == XFRM_MODE_TRANSPORT) |
| 292 | * Set inner address family if the KM left it as zero. | ||
| 293 | * See comment in validate_tmpl. | ||
| 294 | */ | ||
| 295 | if (!x->sel.family) | ||
| 296 | x->sel.family = p->family; | 292 | x->sel.family = p->family; |
| 293 | |||
| 297 | } | 294 | } |
| 298 | 295 | ||
| 299 | /* | 296 | /* |
