diff options
76 files changed, 640 insertions, 657 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 27a17069106f..fc7365cdc8da 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2101,7 +2101,7 @@ M: reinette.chatre@intel.com | |||
2101 | L: linux-wireless@vger.kernel.org | 2101 | L: linux-wireless@vger.kernel.org |
2102 | L: ipw3945-devel@lists.sourceforge.net | 2102 | L: ipw3945-devel@lists.sourceforge.net |
2103 | W: http://intellinuxwireless.org | 2103 | W: http://intellinuxwireless.org |
2104 | T: git git://intellinuxwireless.org/repos/iwlwifi | 2104 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/rchatre/iwlwifi-2.6.git |
2105 | S: Supported | 2105 | S: Supported |
2106 | 2106 | ||
2107 | IOC3 ETHERNET DRIVER | 2107 | 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 457d81f73e39..ebb539e090c3 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 b986dacf5d33..5a673725471c 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 ac688fcb27d7..ecfaf1460b1a 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 9c9bf31e5c25..c68b182af008 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c | |||
@@ -2092,14 +2092,12 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter) | |||
2092 | struct ixgb_buffer *buffer_info; | 2092 | struct ixgb_buffer *buffer_info; |
2093 | struct sk_buff *skb; | 2093 | struct sk_buff *skb; |
2094 | unsigned int i; | 2094 | unsigned int i; |
2095 | int num_group_tail_writes; | ||
2096 | long cleancount; | 2095 | long cleancount; |
2097 | 2096 | ||
2098 | i = rx_ring->next_to_use; | 2097 | i = rx_ring->next_to_use; |
2099 | buffer_info = &rx_ring->buffer_info[i]; | 2098 | buffer_info = &rx_ring->buffer_info[i]; |
2100 | cleancount = IXGB_DESC_UNUSED(rx_ring); | 2099 | cleancount = IXGB_DESC_UNUSED(rx_ring); |
2101 | 2100 | ||
2102 | num_group_tail_writes = IXGB_RX_BUFFER_WRITE; | ||
2103 | 2101 | ||
2104 | /* leave three descriptors unused */ | 2102 | /* leave three descriptors unused */ |
2105 | while(--cleancount > 2) { | 2103 | 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 86f1228c9fec..268a288e0457 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -4345,6 +4345,9 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4345 | dev->trans_start = jiffies; | 4345 | dev->trans_start = jiffies; |
4346 | spin_unlock_irqrestore(&fifo->tx_lock, flags); | 4346 | spin_unlock_irqrestore(&fifo->tx_lock, flags); |
4347 | 4347 | ||
4348 | if (sp->config.intr_type == MSI_X) | ||
4349 | tx_intr_handler(fifo); | ||
4350 | |||
4348 | return 0; | 4351 | return 0; |
4349 | pci_map_failed: | 4352 | pci_map_failed: |
4350 | stats->pci_map_fail_cnt++; | 4353 | 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 69e97a1cb1c4..8606818653f8 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h | |||
@@ -93,14 +93,14 @@ | |||
93 | #define SMC_insw(a, r, p, l) insw ((unsigned long *)((a) + (r)), p, l) | 93 | #define SMC_insw(a, r, p, l) insw ((unsigned long *)((a) + (r)), p, l) |
94 | # endif | 94 | # endif |
95 | /* check if the mac in reg is valid */ | 95 | /* check if the mac in reg is valid */ |
96 | #define SMC_GET_MAC_ADDR(addr) \ | 96 | #define SMC_GET_MAC_ADDR(lp, addr) \ |
97 | do { \ | 97 | do { \ |
98 | unsigned int __v; \ | 98 | unsigned int __v; \ |
99 | __v = SMC_inw(ioaddr, ADDR0_REG); \ | 99 | __v = SMC_inw(ioaddr, ADDR0_REG(lp)); \ |
100 | addr[0] = __v; addr[1] = __v >> 8; \ | 100 | addr[0] = __v; addr[1] = __v >> 8; \ |
101 | __v = SMC_inw(ioaddr, ADDR1_REG); \ | 101 | __v = SMC_inw(ioaddr, ADDR1_REG(lp)); \ |
102 | addr[2] = __v; addr[3] = __v >> 8; \ | 102 | addr[2] = __v; addr[3] = __v >> 8; \ |
103 | __v = SMC_inw(ioaddr, ADDR2_REG); \ | 103 | __v = SMC_inw(ioaddr, ADDR2_REG(lp)); \ |
104 | addr[4] = __v; addr[5] = __v >> 8; \ | 104 | addr[4] = __v; addr[5] = __v >> 8; \ |
105 | if (*(u32 *)(&addr[0]) == 0xFFFFFFFF) { \ | 105 | if (*(u32 *)(&addr[0]) == 0xFFFFFFFF) { \ |
106 | random_ether_addr(addr); \ | 106 | 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 81ccdfaecc58..2968bb342ea3 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 06ae1b2b3b34..21a7785cb8b6 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; | 286 | u32 tmp, phym_unspec; |
287 | __le32 *phym; | 287 | __le32 *phym; |
288 | int reply_len; | 288 | int reply_len; |
289 | unsigned char *bp; | 289 | unsigned char *bp; |
@@ -364,12 +364,15 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) | |||
364 | goto halt_fail_and_release; | 364 | goto halt_fail_and_release; |
365 | 365 | ||
366 | /* Check physical medium */ | 366 | /* Check physical medium */ |
367 | phym = NULL; | ||
367 | reply_len = sizeof *phym; | 368 | reply_len = sizeof *phym; |
368 | retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM, | 369 | retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM, |
369 | 0, (void **) &phym, &reply_len); | 370 | 0, (void **) &phym, &reply_len); |
370 | if (retval != 0) | 371 | if (retval != 0 || !phym) { |
371 | /* OID is optional so don't fail here. */ | 372 | /* OID is optional so don't fail here. */ |
372 | *phym = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED; | 373 | phym_unspec = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED; |
374 | phym = &phym_unspec; | ||
375 | } | ||
373 | if ((flags & FLAG_RNDIS_PHYM_WIRELESS) && | 376 | if ((flags & FLAG_RNDIS_PHYM_WIRELESS) && |
374 | *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { | 377 | *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { |
375 | if (netif_msg_probe(dev)) | 378 | 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 663aed4e9e05..8a9776b52daf 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -515,7 +515,7 @@ static int b43_dmacontroller_tx_reset(struct b43_wldev *dev, u16 mmio_base, | |||
515 | /* Check if a DMA mapping address is invalid. */ | 515 | /* Check if a DMA mapping address is invalid. */ |
516 | static bool b43_dma_mapping_error(struct b43_dmaring *ring, | 516 | static bool b43_dma_mapping_error(struct b43_dmaring *ring, |
517 | dma_addr_t addr, | 517 | dma_addr_t addr, |
518 | size_t buffersize) | 518 | size_t buffersize, bool dma_to_device) |
519 | { | 519 | { |
520 | if (unlikely(dma_mapping_error(addr))) | 520 | if (unlikely(dma_mapping_error(addr))) |
521 | return 1; | 521 | return 1; |
@@ -523,11 +523,11 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, | |||
523 | switch (ring->type) { | 523 | switch (ring->type) { |
524 | case B43_DMA_30BIT: | 524 | case B43_DMA_30BIT: |
525 | if ((u64)addr + buffersize > (1ULL << 30)) | 525 | if ((u64)addr + buffersize > (1ULL << 30)) |
526 | return 1; | 526 | goto address_error; |
527 | break; | 527 | break; |
528 | case B43_DMA_32BIT: | 528 | case B43_DMA_32BIT: |
529 | if ((u64)addr + buffersize > (1ULL << 32)) | 529 | if ((u64)addr + buffersize > (1ULL << 32)) |
530 | return 1; | 530 | goto address_error; |
531 | break; | 531 | break; |
532 | case B43_DMA_64BIT: | 532 | case B43_DMA_64BIT: |
533 | /* Currently we can't have addresses beyond | 533 | /* Currently we can't have addresses beyond |
@@ -537,6 +537,12 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, | |||
537 | 537 | ||
538 | /* The address is OK. */ | 538 | /* The address is OK. */ |
539 | return 0; | 539 | return 0; |
540 | |||
541 | address_error: | ||
542 | /* We can't support this address. Unmap it again. */ | ||
543 | unmap_descbuffer(ring, addr, buffersize, dma_to_device); | ||
544 | |||
545 | return 1; | ||
540 | } | 546 | } |
541 | 547 | ||
542 | static int setup_rx_descbuffer(struct b43_dmaring *ring, | 548 | static int setup_rx_descbuffer(struct b43_dmaring *ring, |
@@ -554,7 +560,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, | |||
554 | if (unlikely(!skb)) | 560 | if (unlikely(!skb)) |
555 | return -ENOMEM; | 561 | return -ENOMEM; |
556 | dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); | 562 | dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); |
557 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) { | 563 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { |
558 | /* ugh. try to realloc in zone_dma */ | 564 | /* ugh. try to realloc in zone_dma */ |
559 | gfp_flags |= GFP_DMA; | 565 | gfp_flags |= GFP_DMA; |
560 | 566 | ||
@@ -567,7 +573,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, | |||
567 | ring->rx_buffersize, 0); | 573 | ring->rx_buffersize, 0); |
568 | } | 574 | } |
569 | 575 | ||
570 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) { | 576 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { |
571 | dev_kfree_skb_any(skb); | 577 | dev_kfree_skb_any(skb); |
572 | return -EIO; | 578 | return -EIO; |
573 | } | 579 | } |
@@ -807,7 +813,8 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
807 | b43_txhdr_size(dev), | 813 | b43_txhdr_size(dev), |
808 | DMA_TO_DEVICE); | 814 | DMA_TO_DEVICE); |
809 | 815 | ||
810 | if (b43_dma_mapping_error(ring, dma_test, b43_txhdr_size(dev))) { | 816 | if (b43_dma_mapping_error(ring, dma_test, |
817 | b43_txhdr_size(dev), 1)) { | ||
811 | /* ugh realloc */ | 818 | /* ugh realloc */ |
812 | kfree(ring->txhdr_cache); | 819 | kfree(ring->txhdr_cache); |
813 | ring->txhdr_cache = kcalloc(nr_slots, | 820 | ring->txhdr_cache = kcalloc(nr_slots, |
@@ -822,7 +829,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
822 | DMA_TO_DEVICE); | 829 | DMA_TO_DEVICE); |
823 | 830 | ||
824 | if (b43_dma_mapping_error(ring, dma_test, | 831 | if (b43_dma_mapping_error(ring, dma_test, |
825 | b43_txhdr_size(dev))) | 832 | b43_txhdr_size(dev), 1)) |
826 | goto err_kfree_txhdr_cache; | 833 | goto err_kfree_txhdr_cache; |
827 | } | 834 | } |
828 | 835 | ||
@@ -1123,7 +1130,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring, | |||
1123 | 1130 | ||
1124 | meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, | 1131 | meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, |
1125 | hdrsize, 1); | 1132 | hdrsize, 1); |
1126 | if (b43_dma_mapping_error(ring, meta_hdr->dmaaddr, hdrsize)) { | 1133 | if (b43_dma_mapping_error(ring, meta_hdr->dmaaddr, hdrsize, 1)) { |
1127 | ring->current_slot = old_top_slot; | 1134 | ring->current_slot = old_top_slot; |
1128 | ring->used_slots = old_used_slots; | 1135 | ring->used_slots = old_used_slots; |
1129 | return -EIO; | 1136 | return -EIO; |
@@ -1142,7 +1149,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring, | |||
1142 | 1149 | ||
1143 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); | 1150 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); |
1144 | /* create a bounce buffer in zone_dma on mapping failure. */ | 1151 | /* create a bounce buffer in zone_dma on mapping failure. */ |
1145 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len)) { | 1152 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { |
1146 | bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); | 1153 | bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); |
1147 | if (!bounce_skb) { | 1154 | if (!bounce_skb) { |
1148 | ring->current_slot = old_top_slot; | 1155 | ring->current_slot = old_top_slot; |
@@ -1156,7 +1163,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring, | |||
1156 | skb = bounce_skb; | 1163 | skb = bounce_skb; |
1157 | meta->skb = skb; | 1164 | meta->skb = skb; |
1158 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); | 1165 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); |
1159 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len)) { | 1166 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { |
1160 | ring->current_slot = old_top_slot; | 1167 | ring->current_slot = old_top_slot; |
1161 | ring->used_slots = old_used_slots; | 1168 | ring->used_slots = old_used_slots; |
1162 | err = -EIO; | 1169 | err = -EIO; |
@@ -1339,6 +1346,7 @@ static void b43_fill_txstatus_report(struct b43_dmaring *ring, | |||
1339 | } | 1346 | } |
1340 | } | 1347 | } |
1341 | 1348 | ||
1349 | /* Called with IRQs disabled. */ | ||
1342 | void b43_dma_handle_txstatus(struct b43_wldev *dev, | 1350 | void b43_dma_handle_txstatus(struct b43_wldev *dev, |
1343 | const struct b43_txstatus *status) | 1351 | const struct b43_txstatus *status) |
1344 | { | 1352 | { |
@@ -1351,8 +1359,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, | |||
1351 | ring = parse_cookie(dev, status->cookie, &slot); | 1359 | ring = parse_cookie(dev, status->cookie, &slot); |
1352 | if (unlikely(!ring)) | 1360 | if (unlikely(!ring)) |
1353 | return; | 1361 | return; |
1354 | B43_WARN_ON(!irqs_disabled()); | 1362 | |
1355 | spin_lock(&ring->lock); | 1363 | spin_lock(&ring->lock); /* IRQs are already disabled. */ |
1356 | 1364 | ||
1357 | B43_WARN_ON(!ring->tx); | 1365 | B43_WARN_ON(!ring->tx); |
1358 | ops = ring->ops; | 1366 | ops = ring->ops; |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 6c58f8b5dcf5..a4e6a59ccac8 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -2158,7 +2158,6 @@ static void b43_mac_enable(struct b43_wldev *dev) | |||
2158 | { | 2158 | { |
2159 | dev->mac_suspended--; | 2159 | dev->mac_suspended--; |
2160 | B43_WARN_ON(dev->mac_suspended < 0); | 2160 | B43_WARN_ON(dev->mac_suspended < 0); |
2161 | B43_WARN_ON(irqs_disabled()); | ||
2162 | if (dev->mac_suspended == 0) { | 2161 | if (dev->mac_suspended == 0) { |
2163 | b43_write32(dev, B43_MMIO_MACCTL, | 2162 | b43_write32(dev, B43_MMIO_MACCTL, |
2164 | b43_read32(dev, B43_MMIO_MACCTL) | 2163 | b43_read32(dev, B43_MMIO_MACCTL) |
@@ -2184,7 +2183,6 @@ static void b43_mac_suspend(struct b43_wldev *dev) | |||
2184 | u32 tmp; | 2183 | u32 tmp; |
2185 | 2184 | ||
2186 | might_sleep(); | 2185 | might_sleep(); |
2187 | B43_WARN_ON(irqs_disabled()); | ||
2188 | B43_WARN_ON(dev->mac_suspended < 0); | 2186 | B43_WARN_ON(dev->mac_suspended < 0); |
2189 | 2187 | ||
2190 | if (dev->mac_suspended == 0) { | 2188 | if (dev->mac_suspended == 0) { |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 4bdb75ecb170..c26ca749fc1e 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -32,7 +32,7 @@ config IWL4965 | |||
32 | runs. | 32 | runs. |
33 | 33 | ||
34 | If you want to compile the driver as a module ( = code which can be | 34 | If you want to compile the driver as a module ( = code which can be |
35 | inserted in and remvoed from the running kernel whenever you want), | 35 | inserted in and removed from the running kernel whenever you want), |
36 | say M here and read <file:Documentation/kbuild/modules.txt>. The | 36 | say M here and read <file:Documentation/kbuild/modules.txt>. The |
37 | module will be called iwl4965.ko. | 37 | module will be called iwl4965.ko. |
38 | 38 | ||
@@ -118,7 +118,7 @@ config IWL3945 | |||
118 | runs. | 118 | runs. |
119 | 119 | ||
120 | If you want to compile the driver as a module ( = code which can be | 120 | If you want to compile the driver as a module ( = code which can be |
121 | inserted in and remvoed from the running kernel whenever you want), | 121 | inserted in and removed from the running kernel whenever you want), |
122 | say M here and read <file:Documentation/kbuild/modules.txt>. The | 122 | say M here and read <file:Documentation/kbuild/modules.txt>. The |
123 | module will be called iwl3945.ko. | 123 | module will be called iwl3945.ko. |
124 | 124 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index ce8a31103eee..ab635dcfd5d1 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -5857,11 +5857,11 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv) | |||
5857 | 5857 | ||
5858 | /* At this point, the NIC is initialized and operational */ | 5858 | /* At this point, the NIC is initialized and operational */ |
5859 | priv->notif_missed_beacons = 0; | 5859 | priv->notif_missed_beacons = 0; |
5860 | set_bit(STATUS_READY, &priv->status); | ||
5861 | 5860 | ||
5862 | iwl3945_reg_txpower_periodic(priv); | 5861 | iwl3945_reg_txpower_periodic(priv); |
5863 | 5862 | ||
5864 | IWL_DEBUG_INFO("ALIVE processing complete.\n"); | 5863 | IWL_DEBUG_INFO("ALIVE processing complete.\n"); |
5864 | set_bit(STATUS_READY, &priv->status); | ||
5865 | wake_up_interruptible(&priv->wait_command_queue); | 5865 | wake_up_interruptible(&priv->wait_command_queue); |
5866 | 5866 | ||
5867 | iwl3945_led_register(priv); | 5867 | iwl3945_led_register(priv); |
@@ -8175,7 +8175,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8175 | return err; | 8175 | return err; |
8176 | } | 8176 | } |
8177 | 8177 | ||
8178 | static void iwl3945_pci_remove(struct pci_dev *pdev) | 8178 | static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) |
8179 | { | 8179 | { |
8180 | struct iwl3945_priv *priv = pci_get_drvdata(pdev); | 8180 | struct iwl3945_priv *priv = pci_get_drvdata(pdev); |
8181 | struct list_head *p, *q; | 8181 | struct list_head *p, *q; |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index e487432ef56e..cf56b95dd221 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -5712,11 +5712,11 @@ static void iwl4965_alive_start(struct iwl_priv *priv) | |||
5712 | 5712 | ||
5713 | /* At this point, the NIC is initialized and operational */ | 5713 | /* At this point, the NIC is initialized and operational */ |
5714 | priv->notif_missed_beacons = 0; | 5714 | priv->notif_missed_beacons = 0; |
5715 | set_bit(STATUS_READY, &priv->status); | ||
5716 | 5715 | ||
5717 | iwl4965_rf_kill_ct_config(priv); | 5716 | iwl4965_rf_kill_ct_config(priv); |
5718 | 5717 | ||
5719 | IWL_DEBUG_INFO("ALIVE processing complete.\n"); | 5718 | IWL_DEBUG_INFO("ALIVE processing complete.\n"); |
5719 | set_bit(STATUS_READY, &priv->status); | ||
5720 | wake_up_interruptible(&priv->wait_command_queue); | 5720 | wake_up_interruptible(&priv->wait_command_queue); |
5721 | 5721 | ||
5722 | iwl_leds_register(priv); | 5722 | iwl_leds_register(priv); |
@@ -8186,7 +8186,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8186 | return err; | 8186 | return err; |
8187 | } | 8187 | } |
8188 | 8188 | ||
8189 | static void iwl4965_pci_remove(struct pci_dev *pdev) | 8189 | static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) |
8190 | { | 8190 | { |
8191 | struct iwl_priv *priv = pci_get_drvdata(pdev); | 8191 | struct iwl_priv *priv = pci_get_drvdata(pdev); |
8192 | struct list_head *p, *q; | 8192 | struct list_head *p, *q; |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 187e832bab2e..b3c846223432 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -2113,6 +2113,8 @@ static struct usb_device_id rt73usb_device_table[] = { | |||
2113 | { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, | 2113 | { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, |
2114 | /* Conceptronic */ | 2114 | /* Conceptronic */ |
2115 | { USB_DEVICE(0x14b2, 0x3c22), USB_DEVICE_DATA(&rt73usb_ops) }, | 2115 | { USB_DEVICE(0x14b2, 0x3c22), USB_DEVICE_DATA(&rt73usb_ops) }, |
2116 | /* Corega */ | ||
2117 | { USB_DEVICE(0x07aa, 0x002e), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
2116 | /* D-Link */ | 2118 | /* D-Link */ |
2117 | { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, | 2119 | { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, |
2118 | { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, | 2120 | { 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/linux/netdevice.h b/include/linux/netdevice.h index 15fa84a15c27..3b54f8a2c055 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -383,9 +383,11 @@ static inline void __napi_complete(struct napi_struct *n) | |||
383 | 383 | ||
384 | static inline void napi_complete(struct napi_struct *n) | 384 | static inline void napi_complete(struct napi_struct *n) |
385 | { | 385 | { |
386 | local_irq_disable(); | 386 | unsigned long flags; |
387 | |||
388 | local_irq_save(flags); | ||
387 | __napi_complete(n); | 389 | __napi_complete(n); |
388 | local_irq_enable(); | 390 | local_irq_restore(flags); |
389 | } | 391 | } |
390 | 392 | ||
391 | /** | 393 | /** |
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 8bec0d69b270..dc420fecafb9 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h | |||
@@ -233,6 +233,10 @@ extern unsigned long neigh_rand_reach_time(unsigned long base); | |||
233 | extern void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p, | 233 | extern void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p, |
234 | struct sk_buff *skb); | 234 | struct sk_buff *skb); |
235 | extern struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev, int creat); | 235 | extern struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev, int creat); |
236 | extern struct pneigh_entry *__pneigh_lookup(struct neigh_table *tbl, | ||
237 | struct net *net, | ||
238 | const void *key, | ||
239 | struct net_device *dev); | ||
236 | extern int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev); | 240 | extern int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev); |
237 | 241 | ||
238 | static inline | 242 | static inline |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index bed7d43932f6..b56b6a10fe5e 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -205,6 +205,7 @@ struct xfrm_state | |||
205 | * transformer. */ | 205 | * transformer. */ |
206 | const struct xfrm_type *type; | 206 | const struct xfrm_type *type; |
207 | struct xfrm_mode *inner_mode; | 207 | struct xfrm_mode *inner_mode; |
208 | struct xfrm_mode *inner_mode_iaf; | ||
208 | struct xfrm_mode *outer_mode; | 209 | struct xfrm_mode *outer_mode; |
209 | 210 | ||
210 | /* Security context */ | 211 | /* Security context */ |
@@ -388,6 +389,27 @@ enum { | |||
388 | extern int xfrm_register_mode(struct xfrm_mode *mode, int family); | 389 | extern int xfrm_register_mode(struct xfrm_mode *mode, int family); |
389 | extern int xfrm_unregister_mode(struct xfrm_mode *mode, int family); | 390 | extern int xfrm_unregister_mode(struct xfrm_mode *mode, int family); |
390 | 391 | ||
392 | static inline int xfrm_af2proto(unsigned int family) | ||
393 | { | ||
394 | switch(family) { | ||
395 | case AF_INET: | ||
396 | return IPPROTO_IPIP; | ||
397 | case AF_INET6: | ||
398 | return IPPROTO_IPV6; | ||
399 | default: | ||
400 | return 0; | ||
401 | } | ||
402 | } | ||
403 | |||
404 | static inline struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto) | ||
405 | { | ||
406 | if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) || | ||
407 | (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6)) | ||
408 | return x->inner_mode; | ||
409 | else | ||
410 | return x->inner_mode_iaf; | ||
411 | } | ||
412 | |||
391 | struct xfrm_tmpl | 413 | struct xfrm_tmpl |
392 | { | 414 | { |
393 | /* id in template is interpreted as: | 415 | /* id in template is interpreted as: |
@@ -532,6 +554,9 @@ struct xfrm_mode_skb_cb { | |||
532 | __be16 id; | 554 | __be16 id; |
533 | __be16 frag_off; | 555 | __be16 frag_off; |
534 | 556 | ||
557 | /* IP header length (excluding options or extension headers). */ | ||
558 | u8 ihl; | ||
559 | |||
535 | /* TOS for IPv4, class for IPv6. */ | 560 | /* TOS for IPv4, class for IPv6. */ |
536 | u8 tos; | 561 | u8 tos; |
537 | 562 | ||
@@ -541,6 +566,9 @@ struct xfrm_mode_skb_cb { | |||
541 | /* Protocol for IPv4, NH for IPv6. */ | 566 | /* Protocol for IPv4, NH for IPv6. */ |
542 | u8 protocol; | 567 | u8 protocol; |
543 | 568 | ||
569 | /* Option length for IPv4, zero for IPv6. */ | ||
570 | u8 optlen; | ||
571 | |||
544 | /* Used by IPv6 only, zero for IPv4. */ | 572 | /* Used by IPv6 only, zero for IPv4. */ |
545 | u8 flow_lbl[3]; | 573 | u8 flow_lbl[3]; |
546 | }; | 574 | }; |
@@ -1300,6 +1328,7 @@ extern int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, | |||
1300 | extern int xfrm_input_resume(struct sk_buff *skb, int nexthdr); | 1328 | extern int xfrm_input_resume(struct sk_buff *skb, int nexthdr); |
1301 | extern int xfrm_output_resume(struct sk_buff *skb, int err); | 1329 | extern int xfrm_output_resume(struct sk_buff *skb, int err); |
1302 | extern int xfrm_output(struct sk_buff *skb); | 1330 | extern int xfrm_output(struct sk_buff *skb); |
1331 | extern int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb); | ||
1303 | extern int xfrm4_extract_header(struct sk_buff *skb); | 1332 | extern int xfrm4_extract_header(struct sk_buff *skb); |
1304 | extern int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb); | 1333 | extern int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb); |
1305 | extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi, | 1334 | 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 e536162b1ebc..0e3b2d3e2339 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 75c3f7f4edd5..7aa01125287e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3330,7 +3330,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd) | |||
3330 | return -EOPNOTSUPP; | 3330 | return -EOPNOTSUPP; |
3331 | 3331 | ||
3332 | case SIOCADDMULTI: | 3332 | case SIOCADDMULTI: |
3333 | if (!dev->set_multicast_list || | 3333 | if ((!dev->set_multicast_list && !dev->set_rx_mode) || |
3334 | ifr->ifr_hwaddr.sa_family != AF_UNSPEC) | 3334 | ifr->ifr_hwaddr.sa_family != AF_UNSPEC) |
3335 | return -EINVAL; | 3335 | return -EINVAL; |
3336 | if (!netif_device_present(dev)) | 3336 | if (!netif_device_present(dev)) |
@@ -3339,7 +3339,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd) | |||
3339 | dev->addr_len, 1); | 3339 | dev->addr_len, 1); |
3340 | 3340 | ||
3341 | case SIOCDELMULTI: | 3341 | case SIOCDELMULTI: |
3342 | if (!dev->set_multicast_list || | 3342 | if ((!dev->set_multicast_list && !dev->set_rx_mode) || |
3343 | ifr->ifr_hwaddr.sa_family != AF_UNSPEC) | 3343 | ifr->ifr_hwaddr.sa_family != AF_UNSPEC) |
3344 | return -EINVAL; | 3344 | return -EINVAL; |
3345 | if (!netif_device_present(dev)) | 3345 | if (!netif_device_present(dev)) |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 857915a12c15..d8d0ca99c651 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 | (pneigh_net(n) == 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) |
@@ -2808,6 +2830,7 @@ EXPORT_SYMBOL(neigh_table_init_no_netlink); | |||
2808 | EXPORT_SYMBOL(neigh_update); | 2830 | EXPORT_SYMBOL(neigh_update); |
2809 | EXPORT_SYMBOL(pneigh_enqueue); | 2831 | EXPORT_SYMBOL(pneigh_enqueue); |
2810 | EXPORT_SYMBOL(pneigh_lookup); | 2832 | EXPORT_SYMBOL(pneigh_lookup); |
2833 | EXPORT_SYMBOL_GPL(__pneigh_lookup); | ||
2811 | 2834 | ||
2812 | #ifdef CONFIG_ARPD | 2835 | #ifdef CONFIG_ARPD |
2813 | EXPORT_SYMBOL(neigh_app_ns); | 2836 | EXPORT_SYMBOL(neigh_app_ns); |
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index f3ceca31aa45..4e73e5708e70 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -336,7 +336,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) | |||
336 | struct scatterlist *asg; | 336 | struct scatterlist *asg; |
337 | int err = -EINVAL; | 337 | int err = -EINVAL; |
338 | 338 | ||
339 | if (!pskb_may_pull(skb, sizeof(*esph))) | 339 | if (!pskb_may_pull(skb, sizeof(*esph) + crypto_aead_ivsize(aead))) |
340 | goto out; | 340 | goto out; |
341 | 341 | ||
342 | if (elen <= 0) | 342 | if (elen <= 0) |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 3697e0528317..803bc9f173a7 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -577,7 +577,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
577 | } | 577 | } |
578 | 578 | ||
579 | if (xfrm_decode_session_reverse(skb_in, &fl, AF_INET)) | 579 | if (xfrm_decode_session_reverse(skb_in, &fl, AF_INET)) |
580 | goto out_unlock; | 580 | goto ende; |
581 | 581 | ||
582 | if (inet_addr_type(net, fl.fl4_src) == RTN_LOCAL) | 582 | if (inet_addr_type(net, fl.fl4_src) == RTN_LOCAL) |
583 | err = __ip_route_output_key(net, &rt2, &fl); | 583 | err = __ip_route_output_key(net, &rt2, &fl); |
@@ -587,7 +587,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
587 | 587 | ||
588 | fl2.fl4_dst = fl.fl4_src; | 588 | fl2.fl4_dst = fl.fl4_src; |
589 | if (ip_route_output_key(net, &rt2, &fl2)) | 589 | if (ip_route_output_key(net, &rt2, &fl2)) |
590 | goto out_unlock; | 590 | goto ende; |
591 | 591 | ||
592 | /* Ugh! */ | 592 | /* Ugh! */ |
593 | odst = skb_in->dst; | 593 | odst = skb_in->dst; |
@@ -600,7 +600,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
600 | } | 600 | } |
601 | 601 | ||
602 | if (err) | 602 | if (err) |
603 | goto out_unlock; | 603 | goto ende; |
604 | 604 | ||
605 | err = xfrm_lookup((struct dst_entry **)&rt2, &fl, NULL, | 605 | err = xfrm_lookup((struct dst_entry **)&rt2, &fl, NULL, |
606 | XFRM_LOOKUP_ICMP); | 606 | XFRM_LOOKUP_ICMP); |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 500998a2dec1..719be29f7506 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -588,11 +588,9 @@ static int __init ip_queue_init(void) | |||
588 | } | 588 | } |
589 | 589 | ||
590 | #ifdef CONFIG_PROC_FS | 590 | #ifdef CONFIG_PROC_FS |
591 | proc = create_proc_entry(IPQ_PROC_FS_NAME, 0, init_net.proc_net); | 591 | proc = proc_create(IPQ_PROC_FS_NAME, 0, init_net.proc_net, |
592 | if (proc) { | 592 | &ip_queue_proc_fops); |
593 | proc->owner = THIS_MODULE; | 593 | if (!proc) { |
594 | proc->proc_fops = &ip_queue_proc_fops; | ||
595 | } else { | ||
596 | printk(KERN_ERR "ip_queue: failed to create proc entry\n"); | 594 | printk(KERN_ERR "ip_queue: failed to create proc entry\n"); |
597 | goto cleanup_ipqnl; | 595 | goto cleanup_ipqnl; |
598 | } | 596 | } |
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 1b10f3628390..965b08a7d738 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -167,14 +167,13 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, __be32 ip, | |||
167 | 167 | ||
168 | /* create proc dir entry */ | 168 | /* create proc dir entry */ |
169 | sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(ip)); | 169 | sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(ip)); |
170 | c->pde = create_proc_entry(buffer, S_IWUSR|S_IRUSR, | 170 | c->pde = proc_create(buffer, S_IWUSR|S_IRUSR, |
171 | clusterip_procdir); | 171 | clusterip_procdir, &clusterip_proc_fops); |
172 | if (!c->pde) { | 172 | if (!c->pde) { |
173 | kfree(c); | 173 | kfree(c); |
174 | return NULL; | 174 | return NULL; |
175 | } | 175 | } |
176 | } | 176 | } |
177 | c->pde->proc_fops = &clusterip_proc_fops; | ||
178 | c->pde->data = c; | 177 | c->pde->data = c; |
179 | #endif | 178 | #endif |
180 | 179 | ||
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c index 8e8f0425a8ed..50e06690eb5b 100644 --- a/net/ipv4/netfilter/ipt_recent.c +++ b/net/ipv4/netfilter/ipt_recent.c | |||
@@ -276,12 +276,11 @@ recent_mt_check(const char *tablename, const void *ip, | |||
276 | for (i = 0; i < ip_list_hash_size; i++) | 276 | for (i = 0; i < ip_list_hash_size; i++) |
277 | INIT_LIST_HEAD(&t->iphash[i]); | 277 | INIT_LIST_HEAD(&t->iphash[i]); |
278 | #ifdef CONFIG_PROC_FS | 278 | #ifdef CONFIG_PROC_FS |
279 | t->proc = create_proc_entry(t->name, ip_list_perms, proc_dir); | 279 | t->proc = proc_create(t->name, ip_list_perms, proc_dir, &recent_fops); |
280 | if (t->proc == NULL) { | 280 | if (t->proc == NULL) { |
281 | kfree(t); | 281 | kfree(t); |
282 | goto out; | 282 | goto out; |
283 | } | 283 | } |
284 | t->proc->proc_fops = &recent_fops; | ||
285 | t->proc->uid = ip_list_uid; | 284 | t->proc->uid = ip_list_uid; |
286 | t->proc->gid = ip_list_gid; | 285 | t->proc->gid = ip_list_gid; |
287 | t->proc->data = t; | 286 | t->proc->data = t; |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c index 9668c3a23efe..e60b885d2dcd 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | |||
@@ -395,13 +395,10 @@ int __init nf_conntrack_ipv4_compat_init(void) | |||
395 | if (!proc_exp) | 395 | if (!proc_exp) |
396 | goto err2; | 396 | goto err2; |
397 | 397 | ||
398 | proc_stat = create_proc_entry("ip_conntrack", S_IRUGO, init_net.proc_net_stat); | 398 | proc_stat = proc_create("ip_conntrack", S_IRUGO, |
399 | init_net.proc_net_stat, &ct_cpu_seq_fops); | ||
399 | if (!proc_stat) | 400 | if (!proc_stat) |
400 | goto err3; | 401 | goto err3; |
401 | |||
402 | proc_stat->proc_fops = &ct_cpu_seq_fops; | ||
403 | proc_stat->owner = THIS_MODULE; | ||
404 | |||
405 | return 0; | 402 | return 0; |
406 | 403 | ||
407 | err3: | 404 | err3: |
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/esp6.c b/net/ipv6/esp6.c index 0ec1402320ea..c6bb4c6d24b3 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -282,7 +282,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
282 | struct scatterlist *sg; | 282 | struct scatterlist *sg; |
283 | struct scatterlist *asg; | 283 | struct scatterlist *asg; |
284 | 284 | ||
285 | if (!pskb_may_pull(skb, sizeof(*esph))) { | 285 | if (!pskb_may_pull(skb, sizeof(*esph) + crypto_aead_ivsize(aead))) { |
286 | ret = -EINVAL; | 286 | ret = -EINVAL; |
287 | goto out; | 287 | goto out; |
288 | } | 288 | } |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index b4d8e331432e..e77b74edfd63 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -661,6 +661,20 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb) | |||
661 | } | 661 | } |
662 | } | 662 | } |
663 | 663 | ||
664 | static struct pneigh_entry *pndisc_check_router(struct net_device *dev, | ||
665 | struct in6_addr *addr, int *is_router) | ||
666 | { | ||
667 | struct pneigh_entry *n; | ||
668 | |||
669 | read_lock_bh(&nd_tbl.lock); | ||
670 | n = __pneigh_lookup(&nd_tbl, dev_net(dev), addr, dev); | ||
671 | if (n != NULL) | ||
672 | *is_router = (n->flags & NTF_ROUTER); | ||
673 | read_unlock_bh(&nd_tbl.lock); | ||
674 | |||
675 | return n; | ||
676 | } | ||
677 | |||
664 | static void ndisc_recv_ns(struct sk_buff *skb) | 678 | static void ndisc_recv_ns(struct sk_buff *skb) |
665 | { | 679 | { |
666 | struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb); | 680 | struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb); |
@@ -677,7 +691,7 @@ static void ndisc_recv_ns(struct sk_buff *skb) | |||
677 | struct pneigh_entry *pneigh = NULL; | 691 | struct pneigh_entry *pneigh = NULL; |
678 | int dad = ipv6_addr_any(saddr); | 692 | int dad = ipv6_addr_any(saddr); |
679 | int inc; | 693 | int inc; |
680 | int is_router; | 694 | int is_router = 0; |
681 | 695 | ||
682 | if (ipv6_addr_is_multicast(&msg->target)) { | 696 | if (ipv6_addr_is_multicast(&msg->target)) { |
683 | ND_PRINTK2(KERN_WARNING | 697 | ND_PRINTK2(KERN_WARNING |
@@ -776,8 +790,8 @@ static void ndisc_recv_ns(struct sk_buff *skb) | |||
776 | if (ipv6_chk_acast_addr(dev_net(dev), dev, &msg->target) || | 790 | if (ipv6_chk_acast_addr(dev_net(dev), dev, &msg->target) || |
777 | (idev->cnf.forwarding && | 791 | (idev->cnf.forwarding && |
778 | (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) && | 792 | (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) && |
779 | (pneigh = pneigh_lookup(&nd_tbl, dev_net(dev), | 793 | (pneigh = pndisc_check_router(dev, &msg->target, |
780 | &msg->target, dev, 0)) != NULL)) { | 794 | &is_router)) != NULL)) { |
781 | if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) && | 795 | if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) && |
782 | skb->pkt_type != PACKET_HOST && | 796 | skb->pkt_type != PACKET_HOST && |
783 | inc != 0 && | 797 | inc != 0 && |
@@ -798,7 +812,7 @@ static void ndisc_recv_ns(struct sk_buff *skb) | |||
798 | goto out; | 812 | goto out; |
799 | } | 813 | } |
800 | 814 | ||
801 | is_router = !!(pneigh ? pneigh->flags & NTF_ROUTER : idev->cnf.forwarding); | 815 | is_router = !!(pneigh ? is_router : idev->cnf.forwarding); |
802 | 816 | ||
803 | if (dad) { | 817 | if (dad) { |
804 | struct in6_addr maddr; | 818 | struct in6_addr maddr; |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index a6d30626b47c..92a36c9e5402 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
@@ -591,11 +591,9 @@ static int __init ip6_queue_init(void) | |||
591 | } | 591 | } |
592 | 592 | ||
593 | #ifdef CONFIG_PROC_FS | 593 | #ifdef CONFIG_PROC_FS |
594 | proc = create_proc_entry(IPQ_PROC_FS_NAME, 0, init_net.proc_net); | 594 | proc = proc_create(IPQ_PROC_FS_NAME, 0, init_net.proc_net, |
595 | if (proc) { | 595 | &ip6_queue_proc_fops); |
596 | proc->owner = THIS_MODULE; | 596 | if (!proc) { |
597 | proc->proc_fops = &ip6_queue_proc_fops; | ||
598 | } else { | ||
599 | printk(KERN_ERR "ip6_queue: failed to create proc entry\n"); | 597 | printk(KERN_ERR "ip6_queue: failed to create proc entry\n"); |
600 | goto cleanup_ipqnl; | 598 | goto cleanup_ipqnl; |
601 | } | 599 | } |
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 5a46bb99c3af..89884a4f23aa 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c | |||
@@ -151,10 +151,12 @@ int xfrm6_extract_header(struct sk_buff *skb) | |||
151 | { | 151 | { |
152 | struct ipv6hdr *iph = ipv6_hdr(skb); | 152 | struct ipv6hdr *iph = ipv6_hdr(skb); |
153 | 153 | ||
154 | XFRM_MODE_SKB_CB(skb)->ihl = sizeof(*iph); | ||
154 | XFRM_MODE_SKB_CB(skb)->id = 0; | 155 | XFRM_MODE_SKB_CB(skb)->id = 0; |
155 | XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF); | 156 | XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF); |
156 | XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph); | 157 | XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph); |
157 | XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit; | 158 | XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit; |
159 | XFRM_MODE_SKB_CB(skb)->optlen = 0; | ||
158 | memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl, | 160 | memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl, |
159 | sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl)); | 161 | sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl)); |
160 | 162 | ||
diff --git a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h index a00e422c822e..b001c361ad30 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 50c442fc99ce..6db58924368a 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -1251,7 +1251,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, | |||
1251 | x->sel.prefixlen_s = addr->sadb_address_prefixlen; | 1251 | x->sel.prefixlen_s = addr->sadb_address_prefixlen; |
1252 | } | 1252 | } |
1253 | 1253 | ||
1254 | if (!x->sel.family) | 1254 | if (x->props.mode == XFRM_MODE_TRANSPORT) |
1255 | x->sel.family = x->props.family; | 1255 | x->sel.family = x->props.family; |
1256 | 1256 | ||
1257 | if (ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1]) { | 1257 | if (ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1]) { |
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index a9bf6e4fd0cc..9d0b8bb4113c 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c | |||
@@ -395,7 +395,7 @@ EXPORT_SYMBOL_GPL(nf_ct_log_invalid); | |||
395 | static int __init nf_conntrack_standalone_init(void) | 395 | static int __init nf_conntrack_standalone_init(void) |
396 | { | 396 | { |
397 | #ifdef CONFIG_PROC_FS | 397 | #ifdef CONFIG_PROC_FS |
398 | struct proc_dir_entry *proc, *proc_stat; | 398 | struct proc_dir_entry *proc; |
399 | #endif | 399 | #endif |
400 | int ret = 0; | 400 | int ret = 0; |
401 | 401 | ||
@@ -407,12 +407,9 @@ static int __init nf_conntrack_standalone_init(void) | |||
407 | proc = proc_net_fops_create(&init_net, "nf_conntrack", 0440, &ct_file_ops); | 407 | proc = proc_net_fops_create(&init_net, "nf_conntrack", 0440, &ct_file_ops); |
408 | if (!proc) goto cleanup_init; | 408 | if (!proc) goto cleanup_init; |
409 | 409 | ||
410 | proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, init_net.proc_net_stat); | 410 | if (!proc_create("nf_conntrack", S_IRUGO, |
411 | if (!proc_stat) | 411 | init_net.proc_net_stat, &ct_cpu_seq_fops)) |
412 | goto cleanup_proc; | 412 | goto cleanup_proc; |
413 | |||
414 | proc_stat->proc_fops = &ct_cpu_seq_fops; | ||
415 | proc_stat->owner = THIS_MODULE; | ||
416 | #endif | 413 | #endif |
417 | #ifdef CONFIG_SYSCTL | 414 | #ifdef CONFIG_SYSCTL |
418 | nf_ct_sysctl_header = register_sysctl_paths(nf_ct_path, | 415 | nf_ct_sysctl_header = register_sysctl_paths(nf_ct_path, |
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c index cec9976aecbf..bc11d7092032 100644 --- a/net/netfilter/nf_log.c +++ b/net/netfilter/nf_log.c | |||
@@ -168,13 +168,9 @@ static const struct file_operations nflog_file_ops = { | |||
168 | int __init netfilter_log_init(void) | 168 | int __init netfilter_log_init(void) |
169 | { | 169 | { |
170 | #ifdef CONFIG_PROC_FS | 170 | #ifdef CONFIG_PROC_FS |
171 | struct proc_dir_entry *pde; | 171 | if (!proc_create("nf_log", S_IRUGO, |
172 | 172 | proc_net_netfilter, &nflog_file_ops)) | |
173 | pde = create_proc_entry("nf_log", S_IRUGO, proc_net_netfilter); | ||
174 | if (!pde) | ||
175 | return -1; | 173 | return -1; |
176 | |||
177 | pde->proc_fops = &nflog_file_ops; | ||
178 | #endif | 174 | #endif |
179 | return 0; | 175 | return 0; |
180 | } | 176 | } |
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index ddc80ea114cd..bbd26893c0c4 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c | |||
@@ -348,12 +348,9 @@ static const struct file_operations nfqueue_file_ops = { | |||
348 | int __init netfilter_queue_init(void) | 348 | int __init netfilter_queue_init(void) |
349 | { | 349 | { |
350 | #ifdef CONFIG_PROC_FS | 350 | #ifdef CONFIG_PROC_FS |
351 | struct proc_dir_entry *pde; | 351 | if (!proc_create("nf_queue", S_IRUGO, |
352 | 352 | proc_net_netfilter, &nfqueue_file_ops)) | |
353 | pde = create_proc_entry("nf_queue", S_IRUGO, proc_net_netfilter); | ||
354 | if (!pde) | ||
355 | return -1; | 353 | return -1; |
356 | pde->proc_fops = &nfqueue_file_ops; | ||
357 | #endif | 354 | #endif |
358 | return 0; | 355 | return 0; |
359 | } | 356 | } |
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index bf3f19b21fe4..b8173af8c24a 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -923,9 +923,6 @@ static const struct file_operations nful_file_ops = { | |||
923 | static int __init nfnetlink_log_init(void) | 923 | static int __init nfnetlink_log_init(void) |
924 | { | 924 | { |
925 | int i, status = -ENOMEM; | 925 | int i, status = -ENOMEM; |
926 | #ifdef CONFIG_PROC_FS | ||
927 | struct proc_dir_entry *proc_nful; | ||
928 | #endif | ||
929 | 926 | ||
930 | for (i = 0; i < INSTANCE_BUCKETS; i++) | 927 | for (i = 0; i < INSTANCE_BUCKETS; i++) |
931 | INIT_HLIST_HEAD(&instance_table[i]); | 928 | INIT_HLIST_HEAD(&instance_table[i]); |
@@ -943,11 +940,9 @@ static int __init nfnetlink_log_init(void) | |||
943 | } | 940 | } |
944 | 941 | ||
945 | #ifdef CONFIG_PROC_FS | 942 | #ifdef CONFIG_PROC_FS |
946 | proc_nful = create_proc_entry("nfnetlink_log", 0440, | 943 | if (!proc_create("nfnetlink_log", 0440, |
947 | proc_net_netfilter); | 944 | proc_net_netfilter, &nful_file_ops)) |
948 | if (!proc_nful) | ||
949 | goto cleanup_subsys; | 945 | goto cleanup_subsys; |
950 | proc_nful->proc_fops = &nful_file_ops; | ||
951 | #endif | 946 | #endif |
952 | return status; | 947 | return status; |
953 | 948 | ||
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 81fb048add88..2c9fe5c12894 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
@@ -896,9 +896,6 @@ static const struct file_operations nfqnl_file_ops = { | |||
896 | static int __init nfnetlink_queue_init(void) | 896 | static int __init nfnetlink_queue_init(void) |
897 | { | 897 | { |
898 | int i, status = -ENOMEM; | 898 | int i, status = -ENOMEM; |
899 | #ifdef CONFIG_PROC_FS | ||
900 | struct proc_dir_entry *proc_nfqueue; | ||
901 | #endif | ||
902 | 899 | ||
903 | for (i = 0; i < INSTANCE_BUCKETS; i++) | 900 | for (i = 0; i < INSTANCE_BUCKETS; i++) |
904 | INIT_HLIST_HEAD(&instance_table[i]); | 901 | INIT_HLIST_HEAD(&instance_table[i]); |
@@ -911,11 +908,9 @@ static int __init nfnetlink_queue_init(void) | |||
911 | } | 908 | } |
912 | 909 | ||
913 | #ifdef CONFIG_PROC_FS | 910 | #ifdef CONFIG_PROC_FS |
914 | proc_nfqueue = create_proc_entry("nfnetlink_queue", 0440, | 911 | if (!proc_create("nfnetlink_queue", 0440, |
915 | proc_net_netfilter); | 912 | proc_net_netfilter, &nfqnl_file_ops)) |
916 | if (!proc_nfqueue) | ||
917 | goto cleanup_subsys; | 913 | goto cleanup_subsys; |
918 | proc_nfqueue->proc_fops = &nfqnl_file_ops; | ||
919 | #endif | 914 | #endif |
920 | 915 | ||
921 | register_netdevice_notifier(&nfqnl_dev_notifier); | 916 | register_netdevice_notifier(&nfqnl_dev_notifier); |
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 5418ce59ac3a..dc29007c52cd 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c | |||
@@ -237,14 +237,14 @@ static int htable_create_v0(struct xt_hashlimit_info *minfo, int family) | |||
237 | hinfo->family = family; | 237 | hinfo->family = family; |
238 | hinfo->rnd_initialized = 0; | 238 | hinfo->rnd_initialized = 0; |
239 | spin_lock_init(&hinfo->lock); | 239 | spin_lock_init(&hinfo->lock); |
240 | hinfo->pde = create_proc_entry(minfo->name, 0, | 240 | hinfo->pde = proc_create(minfo->name, 0, |
241 | family == AF_INET ? hashlimit_procdir4 : | 241 | family == AF_INET ? hashlimit_procdir4 : |
242 | hashlimit_procdir6); | 242 | hashlimit_procdir6, |
243 | &dl_file_ops); | ||
243 | if (!hinfo->pde) { | 244 | if (!hinfo->pde) { |
244 | vfree(hinfo); | 245 | vfree(hinfo); |
245 | return -1; | 246 | return -1; |
246 | } | 247 | } |
247 | hinfo->pde->proc_fops = &dl_file_ops; | ||
248 | hinfo->pde->data = hinfo; | 248 | hinfo->pde->data = hinfo; |
249 | 249 | ||
250 | setup_timer(&hinfo->timer, htable_gc, (unsigned long )hinfo); | 250 | setup_timer(&hinfo->timer, htable_gc, (unsigned long )hinfo); |
@@ -301,14 +301,14 @@ static int htable_create(struct xt_hashlimit_mtinfo1 *minfo, | |||
301 | hinfo->rnd_initialized = 0; | 301 | hinfo->rnd_initialized = 0; |
302 | spin_lock_init(&hinfo->lock); | 302 | spin_lock_init(&hinfo->lock); |
303 | 303 | ||
304 | hinfo->pde = create_proc_entry(minfo->name, 0, | 304 | hinfo->pde = proc_create(minfo->name, 0, |
305 | family == AF_INET ? hashlimit_procdir4 : | 305 | family == AF_INET ? hashlimit_procdir4 : |
306 | hashlimit_procdir6); | 306 | hashlimit_procdir6, |
307 | &dl_file_ops); | ||
307 | if (hinfo->pde == NULL) { | 308 | if (hinfo->pde == NULL) { |
308 | vfree(hinfo); | 309 | vfree(hinfo); |
309 | return -1; | 310 | return -1; |
310 | } | 311 | } |
311 | hinfo->pde->proc_fops = &dl_file_ops; | ||
312 | hinfo->pde->data = hinfo; | 312 | hinfo->pde->data = hinfo; |
313 | 313 | ||
314 | setup_timer(&hinfo->timer, htable_gc, (unsigned long)hinfo); | 314 | setup_timer(&hinfo->timer, htable_gc, (unsigned long)hinfo); |
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 9880b792e6a5..5dcc10b93c86 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -389,6 +389,8 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x) | |||
389 | kfree(x->coaddr); | 389 | kfree(x->coaddr); |
390 | if (x->inner_mode) | 390 | if (x->inner_mode) |
391 | xfrm_put_mode(x->inner_mode); | 391 | xfrm_put_mode(x->inner_mode); |
392 | if (x->inner_mode_iaf) | ||
393 | xfrm_put_mode(x->inner_mode_iaf); | ||
392 | if (x->outer_mode) | 394 | if (x->outer_mode) |
393 | xfrm_put_mode(x->outer_mode); | 395 | xfrm_put_mode(x->outer_mode); |
394 | if (x->type) { | 396 | if (x->type) { |
@@ -525,6 +527,8 @@ struct xfrm_state *xfrm_state_alloc(void) | |||
525 | x->lft.hard_packet_limit = XFRM_INF; | 527 | x->lft.hard_packet_limit = XFRM_INF; |
526 | x->replay_maxage = 0; | 528 | x->replay_maxage = 0; |
527 | x->replay_maxdiff = 0; | 529 | x->replay_maxdiff = 0; |
530 | x->inner_mode = NULL; | ||
531 | x->inner_mode_iaf = NULL; | ||
528 | spin_lock_init(&x->lock); | 532 | spin_lock_init(&x->lock); |
529 | } | 533 | } |
530 | return x; | 534 | return x; |
@@ -802,7 +806,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
802 | selector. | 806 | selector. |
803 | */ | 807 | */ |
804 | if (x->km.state == XFRM_STATE_VALID) { | 808 | if (x->km.state == XFRM_STATE_VALID) { |
805 | if (!xfrm_selector_match(&x->sel, fl, x->sel.family) || | 809 | if ((x->sel.family && !xfrm_selector_match(&x->sel, fl, x->sel.family)) || |
806 | !security_xfrm_state_pol_flow_match(x, pol, fl)) | 810 | !security_xfrm_state_pol_flow_match(x, pol, fl)) |
807 | continue; | 811 | continue; |
808 | if (!best || | 812 | if (!best || |
@@ -1963,6 +1967,7 @@ int xfrm_state_mtu(struct xfrm_state *x, int mtu) | |||
1963 | int xfrm_init_state(struct xfrm_state *x) | 1967 | int xfrm_init_state(struct xfrm_state *x) |
1964 | { | 1968 | { |
1965 | struct xfrm_state_afinfo *afinfo; | 1969 | struct xfrm_state_afinfo *afinfo; |
1970 | struct xfrm_mode *inner_mode; | ||
1966 | int family = x->props.family; | 1971 | int family = x->props.family; |
1967 | int err; | 1972 | int err; |
1968 | 1973 | ||
@@ -1981,13 +1986,48 @@ int xfrm_init_state(struct xfrm_state *x) | |||
1981 | goto error; | 1986 | goto error; |
1982 | 1987 | ||
1983 | err = -EPROTONOSUPPORT; | 1988 | err = -EPROTONOSUPPORT; |
1984 | x->inner_mode = xfrm_get_mode(x->props.mode, x->sel.family); | ||
1985 | if (x->inner_mode == NULL) | ||
1986 | goto error; | ||
1987 | 1989 | ||
1988 | if (!(x->inner_mode->flags & XFRM_MODE_FLAG_TUNNEL) && | 1990 | if (x->sel.family != AF_UNSPEC) { |
1989 | family != x->sel.family) | 1991 | inner_mode = xfrm_get_mode(x->props.mode, x->sel.family); |
1990 | goto error; | 1992 | if (inner_mode == NULL) |
1993 | goto error; | ||
1994 | |||
1995 | if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL) && | ||
1996 | family != x->sel.family) { | ||
1997 | xfrm_put_mode(inner_mode); | ||
1998 | goto error; | ||
1999 | } | ||
2000 | |||
2001 | x->inner_mode = inner_mode; | ||
2002 | } else { | ||
2003 | struct xfrm_mode *inner_mode_iaf; | ||
2004 | |||
2005 | inner_mode = xfrm_get_mode(x->props.mode, AF_INET); | ||
2006 | if (inner_mode == NULL) | ||
2007 | goto error; | ||
2008 | |||
2009 | if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL)) { | ||
2010 | xfrm_put_mode(inner_mode); | ||
2011 | goto error; | ||
2012 | } | ||
2013 | |||
2014 | inner_mode_iaf = xfrm_get_mode(x->props.mode, AF_INET6); | ||
2015 | if (inner_mode_iaf == NULL) | ||
2016 | goto error; | ||
2017 | |||
2018 | if (!(inner_mode_iaf->flags & XFRM_MODE_FLAG_TUNNEL)) { | ||
2019 | xfrm_put_mode(inner_mode_iaf); | ||
2020 | goto error; | ||
2021 | } | ||
2022 | |||
2023 | if (x->props.family == AF_INET) { | ||
2024 | x->inner_mode = inner_mode; | ||
2025 | x->inner_mode_iaf = inner_mode_iaf; | ||
2026 | } else { | ||
2027 | x->inner_mode = inner_mode_iaf; | ||
2028 | x->inner_mode_iaf = inner_mode; | ||
2029 | } | ||
2030 | } | ||
1991 | 2031 | ||
1992 | x->type = xfrm_get_type(x->id.proto, family); | 2032 | x->type = xfrm_get_type(x->id.proto, family); |
1993 | if (x->type == NULL) | 2033 | if (x->type == NULL) |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index f5fd5b3147cc..5578c909fcf6 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 | /* |