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