aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/netxen/netxen_nic.h6
-rw-r--r--drivers/net/netxen/netxen_nic_init.c8
-rw-r--r--drivers/net/netxen/netxen_nic_main.c103
3 files changed, 107 insertions, 10 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index f744d291218a..196b660e1d91 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -940,6 +940,11 @@ typedef struct nx_mac_list_s {
940 uint8_t mac_addr[ETH_ALEN+2]; 940 uint8_t mac_addr[ETH_ALEN+2];
941} nx_mac_list_t; 941} nx_mac_list_t;
942 942
943struct nx_vlan_ip_list {
944 struct list_head list;
945 u32 ip_addr;
946};
947
943/* 948/*
944 * Interrupt coalescing defaults. The defaults are for 1500 MTU. It is 949 * Interrupt coalescing defaults. The defaults are for 1500 MTU. It is
945 * adjusted based on configured MTU. 950 * adjusted based on configured MTU.
@@ -1165,6 +1170,7 @@ struct netxen_adapter {
1165 struct net_device *netdev; 1170 struct net_device *netdev;
1166 struct pci_dev *pdev; 1171 struct pci_dev *pdev;
1167 struct list_head mac_list; 1172 struct list_head mac_list;
1173 struct list_head vlan_ip_list;
1168 1174
1169 spinlock_t tx_clean_lock; 1175 spinlock_t tx_clean_lock;
1170 1176
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index e8993a76a080..d6c6357de6aa 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -26,6 +26,7 @@
26#include <linux/netdevice.h> 26#include <linux/netdevice.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/if_vlan.h>
29#include "netxen_nic.h" 30#include "netxen_nic.h"
30#include "netxen_nic_hw.h" 31#include "netxen_nic_hw.h"
31 32
@@ -1619,6 +1620,7 @@ netxen_process_lro(struct netxen_adapter *adapter,
1619 int index; 1620 int index;
1620 u16 lro_length, length, data_offset; 1621 u16 lro_length, length, data_offset;
1621 u32 seq_number; 1622 u32 seq_number;
1623 u8 vhdr_len;
1622 1624
1623 if (unlikely(ring > adapter->max_rds_rings)) 1625 if (unlikely(ring > adapter->max_rds_rings))
1624 return NULL; 1626 return NULL;
@@ -1652,8 +1654,10 @@ netxen_process_lro(struct netxen_adapter *adapter,
1652 skb_pull(skb, l2_hdr_offset); 1654 skb_pull(skb, l2_hdr_offset);
1653 skb->protocol = eth_type_trans(skb, netdev); 1655 skb->protocol = eth_type_trans(skb, netdev);
1654 1656
1655 iph = (struct iphdr *)skb->data; 1657 if (skb->protocol == htons(ETH_P_8021Q))
1656 th = (struct tcphdr *)(skb->data + (iph->ihl << 2)); 1658 vhdr_len = VLAN_HLEN;
1659 iph = (struct iphdr *)(skb->data + vhdr_len);
1660 th = (struct tcphdr *)((skb->data + vhdr_len) + (iph->ihl << 2));
1657 1661
1658 length = (iph->ihl << 2) + (th->doff << 2) + lro_length; 1662 length = (iph->ihl << 2) + (th->doff << 2) + lro_length;
1659 iph->tot_len = htons(length); 1663 iph->tot_len = htons(length);
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index f574edff7fcb..8c7fc32d781f 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -91,7 +91,8 @@ static irqreturn_t netxen_intr(int irq, void *data);
91static irqreturn_t netxen_msi_intr(int irq, void *data); 91static irqreturn_t netxen_msi_intr(int irq, void *data);
92static irqreturn_t netxen_msix_intr(int irq, void *data); 92static irqreturn_t netxen_msix_intr(int irq, void *data);
93 93
94static void netxen_config_indev_addr(struct net_device *dev, unsigned long); 94static void netxen_free_vlan_ip_list(struct netxen_adapter *);
95static void netxen_restore_indev_addr(struct net_device *dev, unsigned long);
95static struct rtnl_link_stats64 *netxen_nic_get_stats(struct net_device *dev, 96static struct rtnl_link_stats64 *netxen_nic_get_stats(struct net_device *dev,
96 struct rtnl_link_stats64 *stats); 97 struct rtnl_link_stats64 *stats);
97static int netxen_nic_set_mac(struct net_device *netdev, void *p); 98static int netxen_nic_set_mac(struct net_device *netdev, void *p);
@@ -1359,6 +1360,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1359 1360
1360 spin_lock_init(&adapter->tx_clean_lock); 1361 spin_lock_init(&adapter->tx_clean_lock);
1361 INIT_LIST_HEAD(&adapter->mac_list); 1362 INIT_LIST_HEAD(&adapter->mac_list);
1363 INIT_LIST_HEAD(&adapter->vlan_ip_list);
1362 1364
1363 err = netxen_setup_pci_map(adapter); 1365 err = netxen_setup_pci_map(adapter);
1364 if (err) 1366 if (err)
@@ -1481,6 +1483,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
1481 1483
1482 cancel_work_sync(&adapter->tx_timeout_task); 1484 cancel_work_sync(&adapter->tx_timeout_task);
1483 1485
1486 netxen_free_vlan_ip_list(adapter);
1484 netxen_nic_detach(adapter); 1487 netxen_nic_detach(adapter);
1485 1488
1486 nx_decr_dev_ref_cnt(adapter); 1489 nx_decr_dev_ref_cnt(adapter);
@@ -1563,7 +1566,7 @@ static int netxen_nic_attach_func(struct pci_dev *pdev)
1563 if (err) 1566 if (err)
1564 goto err_out_detach; 1567 goto err_out_detach;
1565 1568
1566 netxen_config_indev_addr(netdev, NETDEV_UP); 1569 netxen_restore_indev_addr(netdev, NETDEV_UP);
1567 } 1570 }
1568 1571
1569 netif_device_attach(netdev); 1572 netif_device_attach(netdev);
@@ -2374,7 +2377,7 @@ netxen_attach_work(struct work_struct *work)
2374 goto done; 2377 goto done;
2375 } 2378 }
2376 2379
2377 netxen_config_indev_addr(netdev, NETDEV_UP); 2380 netxen_restore_indev_addr(netdev, NETDEV_UP);
2378 } 2381 }
2379 2382
2380 netif_device_attach(netdev); 2383 netif_device_attach(netdev);
@@ -2848,10 +2851,70 @@ netxen_destip_supported(struct netxen_adapter *adapter)
2848} 2851}
2849 2852
2850static void 2853static void
2851netxen_config_indev_addr(struct net_device *dev, unsigned long event) 2854netxen_free_vlan_ip_list(struct netxen_adapter *adapter)
2855{
2856 struct nx_vlan_ip_list *cur;
2857 struct list_head *head = &adapter->vlan_ip_list;
2858
2859 while (!list_empty(head)) {
2860 cur = list_entry(head->next, struct nx_vlan_ip_list, list);
2861 netxen_config_ipaddr(adapter, cur->ip_addr, NX_IP_DOWN);
2862 list_del(&cur->list);
2863 kfree(cur);
2864 }
2865
2866}
2867static void
2868netxen_list_config_vlan_ip(struct netxen_adapter *adapter,
2869 struct in_ifaddr *ifa, unsigned long event)
2870{
2871 struct net_device *dev;
2872 struct nx_vlan_ip_list *cur, *tmp_cur;
2873 struct list_head *head;
2874
2875 dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL;
2876
2877 if (dev == NULL)
2878 return;
2879
2880 if (!is_vlan_dev(dev))
2881 return;
2882
2883 switch (event) {
2884 case NX_IP_UP:
2885 list_for_each(head, &adapter->vlan_ip_list) {
2886 cur = list_entry(head, struct nx_vlan_ip_list, list);
2887
2888 if (cur->ip_addr == ifa->ifa_address)
2889 return;
2890 }
2891
2892 cur = kzalloc(sizeof(struct nx_vlan_ip_list), GFP_ATOMIC);
2893 if (cur == NULL) {
2894 printk(KERN_ERR "%s: failed to add vlan ip to list\n",
2895 adapter->netdev->name);
2896 return;
2897 }
2898
2899 cur->ip_addr = ifa->ifa_address;
2900 list_add_tail(&cur->list, &adapter->vlan_ip_list);
2901 break;
2902 case NX_IP_DOWN:
2903 list_for_each_entry_safe(cur, tmp_cur,
2904 &adapter->vlan_ip_list, list) {
2905 if (cur->ip_addr == ifa->ifa_address) {
2906 list_del(&cur->list);
2907 kfree(cur);
2908 break;
2909 }
2910 }
2911 }
2912}
2913static void
2914netxen_config_indev_addr(struct netxen_adapter *adapter,
2915 struct net_device *dev, unsigned long event)
2852{ 2916{
2853 struct in_device *indev; 2917 struct in_device *indev;
2854 struct netxen_adapter *adapter = netdev_priv(dev);
2855 2918
2856 if (!netxen_destip_supported(adapter)) 2919 if (!netxen_destip_supported(adapter))
2857 return; 2920 return;
@@ -2865,10 +2928,12 @@ netxen_config_indev_addr(struct net_device *dev, unsigned long event)
2865 case NETDEV_UP: 2928 case NETDEV_UP:
2866 netxen_config_ipaddr(adapter, 2929 netxen_config_ipaddr(adapter,
2867 ifa->ifa_address, NX_IP_UP); 2930 ifa->ifa_address, NX_IP_UP);
2931 netxen_list_config_vlan_ip(adapter, ifa, NX_IP_UP);
2868 break; 2932 break;
2869 case NETDEV_DOWN: 2933 case NETDEV_DOWN:
2870 netxen_config_ipaddr(adapter, 2934 netxen_config_ipaddr(adapter,
2871 ifa->ifa_address, NX_IP_DOWN); 2935 ifa->ifa_address, NX_IP_DOWN);
2936 netxen_list_config_vlan_ip(adapter, ifa, NX_IP_DOWN);
2872 break; 2937 break;
2873 default: 2938 default:
2874 break; 2939 break;
@@ -2878,11 +2943,28 @@ netxen_config_indev_addr(struct net_device *dev, unsigned long event)
2878 in_dev_put(indev); 2943 in_dev_put(indev);
2879} 2944}
2880 2945
2946static void
2947netxen_restore_indev_addr(struct net_device *netdev, unsigned long event)
2948
2949{
2950 struct netxen_adapter *adapter = netdev_priv(netdev);
2951 struct nx_vlan_ip_list *pos, *tmp_pos;
2952 unsigned long ip_event;
2953
2954 ip_event = (event == NETDEV_UP) ? NX_IP_UP : NX_IP_DOWN;
2955 netxen_config_indev_addr(adapter, netdev, event);
2956
2957 list_for_each_entry_safe(pos, tmp_pos, &adapter->vlan_ip_list, list) {
2958 netxen_config_ipaddr(adapter, pos->ip_addr, ip_event);
2959 }
2960}
2961
2881static int netxen_netdev_event(struct notifier_block *this, 2962static int netxen_netdev_event(struct notifier_block *this,
2882 unsigned long event, void *ptr) 2963 unsigned long event, void *ptr)
2883{ 2964{
2884 struct netxen_adapter *adapter; 2965 struct netxen_adapter *adapter;
2885 struct net_device *dev = (struct net_device *)ptr; 2966 struct net_device *dev = (struct net_device *)ptr;
2967 struct net_device *orig_dev = dev;
2886 2968
2887recheck: 2969recheck:
2888 if (dev == NULL) 2970 if (dev == NULL)
@@ -2904,7 +2986,7 @@ recheck:
2904 if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) 2986 if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
2905 goto done; 2987 goto done;
2906 2988
2907 netxen_config_indev_addr(dev, event); 2989 netxen_config_indev_addr(adapter, orig_dev, event);
2908done: 2990done:
2909 return NOTIFY_DONE; 2991 return NOTIFY_DONE;
2910} 2992}
@@ -2921,7 +3003,7 @@ netxen_inetaddr_event(struct notifier_block *this,
2921 dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL; 3003 dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL;
2922 3004
2923recheck: 3005recheck:
2924 if (dev == NULL || !netif_running(dev)) 3006 if (dev == NULL)
2925 goto done; 3007 goto done;
2926 3008
2927 if (dev->priv_flags & IFF_802_1Q_VLAN) { 3009 if (dev->priv_flags & IFF_802_1Q_VLAN) {
@@ -2943,9 +3025,11 @@ recheck:
2943 switch (event) { 3025 switch (event) {
2944 case NETDEV_UP: 3026 case NETDEV_UP:
2945 netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_UP); 3027 netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_UP);
3028 netxen_list_config_vlan_ip(adapter, ifa, NX_IP_UP);
2946 break; 3029 break;
2947 case NETDEV_DOWN: 3030 case NETDEV_DOWN:
2948 netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_DOWN); 3031 netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_DOWN);
3032 netxen_list_config_vlan_ip(adapter, ifa, NX_IP_DOWN);
2949 break; 3033 break;
2950 default: 3034 default:
2951 break; 3035 break;
@@ -2964,7 +3048,10 @@ static struct notifier_block netxen_inetaddr_cb = {
2964}; 3048};
2965#else 3049#else
2966static void 3050static void
2967netxen_config_indev_addr(struct net_device *dev, unsigned long event) 3051netxen_restore_indev_addr(struct net_device *dev, unsigned long event)
3052{ }
3053static void
3054netxen_free_vlan_ip_list(struct netxen_adapter *adapter)
2968{ } 3055{ }
2969#endif 3056#endif
2970 3057