netxen: fix ip addr hashing after firmware reset
Reprogram local IP addresses after firmware is reset
or after resuming from suspend.
Signed-off-by: Amit Kumar Salecha <amit@netxen.com>
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 4989436..7038e1b 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -86,6 +86,8 @@
static irqreturn_t netxen_msi_intr(int irq, void *data);
static irqreturn_t netxen_msix_intr(int irq, void *data);
+static void netxen_config_indev_addr(struct net_device *dev, unsigned long);
+
/* PCI Device ID Table */
#define ENTRY(device) \
{PCI_DEVICE(PCI_VENDOR_ID_NETXEN, (device)), \
@@ -1411,6 +1413,8 @@
goto err_out_detach;
netif_device_attach(netdev);
+
+ netxen_config_indev_addr(netdev, NETDEV_UP);
}
netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
@@ -2057,6 +2061,7 @@
goto done;
}
+ netxen_config_indev_addr(netdev, NETDEV_UP);
}
netif_device_attach(netdev);
@@ -2282,36 +2287,18 @@
return 1;
}
-static int netxen_netdev_event(struct notifier_block *this,
- unsigned long event, void *ptr)
+static void
+netxen_config_indev_addr(struct net_device *dev, unsigned long event)
{
- struct netxen_adapter *adapter;
- struct net_device *dev = (struct net_device *)ptr;
struct in_device *indev;
+ struct netxen_adapter *adapter = netdev_priv(dev);
-recheck:
- if (dev == NULL)
- goto done;
-
- if (dev->priv_flags & IFF_802_1Q_VLAN) {
- dev = vlan_dev_real_dev(dev);
- goto recheck;
- }
-
- if (!is_netxen_netdev(dev))
- goto done;
-
- adapter = netdev_priv(dev);
-
- if (!adapter || !netxen_destip_supported(adapter))
- goto done;
-
- if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
- goto done;
+ if (netxen_destip_supported(adapter))
+ return;
indev = in_dev_get(dev);
if (!indev)
- goto done;
+ return;
for_ifa(indev) {
switch (event) {
@@ -2329,6 +2316,36 @@
} endfor_ifa(indev);
in_dev_put(indev);
+ return;
+}
+
+static int netxen_netdev_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct netxen_adapter *adapter;
+ struct net_device *dev = (struct net_device *)ptr;
+
+recheck:
+ if (dev == NULL)
+ goto done;
+
+ if (dev->priv_flags & IFF_802_1Q_VLAN) {
+ dev = vlan_dev_real_dev(dev);
+ goto recheck;
+ }
+
+ if (!is_netxen_netdev(dev))
+ goto done;
+
+ adapter = netdev_priv(dev);
+
+ if (!adapter)
+ goto done;
+
+ if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+ goto done;
+
+ netxen_config_indev_addr(dev, event);
done:
return NOTIFY_DONE;
}