aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_main.c
diff options
context:
space:
mode:
authorDhananjay Phadke <dhananjay@netxen.com>2009-07-26 16:07:37 -0400
committerDavid S. Miller <davem@davemloft.net>2009-07-27 13:55:19 -0400
commit6598b169b856793f8f9b80a3f3c5a48f5eaf40e3 (patch)
tree94ac7225b638d8bea654e1acc7eb3df1fe6f052c /drivers/net/netxen/netxen_nic_main.c
parent68b3cae0824b98d1f469a80cc65dcaab81771f45 (diff)
netxen: enable ip addr hashing
NX3031 hardware requires local IP addresses for packet accumulation (LRO). IP address hashing is required to distinguish a local TCP flow from others (forwarded or guest). This patch adds listener for IP and netdev events and configures IP address in the firmware. 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>
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r--drivers/net/netxen/netxen_nic_main.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 4c7e4c28bf6b..b3683260a0b6 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -39,6 +39,7 @@
39#include <linux/if_vlan.h> 39#include <linux/if_vlan.h>
40#include <net/ip.h> 40#include <net/ip.h>
41#include <linux/ipv6.h> 41#include <linux/ipv6.h>
42#include <linux/inetdevice.h>
42 43
43MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver"); 44MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver");
44MODULE_LICENSE("GPL"); 45MODULE_LICENSE("GPL");
@@ -1780,6 +1781,125 @@ static void netxen_nic_poll_controller(struct net_device *netdev)
1780} 1781}
1781#endif 1782#endif
1782 1783
1784#define is_netxen_netdev(dev) (dev->netdev_ops == &netxen_netdev_ops)
1785
1786static int
1787netxen_destip_supported(struct netxen_adapter *adapter)
1788{
1789 if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
1790 return 0;
1791
1792 if (adapter->ahw.cut_through)
1793 return 0;
1794
1795 return 1;
1796}
1797
1798static int netxen_netdev_event(struct notifier_block *this,
1799 unsigned long event, void *ptr)
1800{
1801 struct netxen_adapter *adapter;
1802 struct net_device *dev = (struct net_device *)ptr;
1803 struct in_device *indev;
1804
1805recheck:
1806 if (dev == NULL)
1807 goto done;
1808
1809 if (dev->priv_flags & IFF_802_1Q_VLAN) {
1810 dev = vlan_dev_real_dev(dev);
1811 goto recheck;
1812 }
1813
1814 if (!is_netxen_netdev(dev))
1815 goto done;
1816
1817 adapter = netdev_priv(dev);
1818
1819 if (!adapter || !netxen_destip_supported(adapter))
1820 goto done;
1821
1822 if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
1823 goto done;
1824
1825 indev = in_dev_get(dev);
1826 if (!indev)
1827 goto done;
1828
1829 for_ifa(indev) {
1830 switch (event) {
1831 case NETDEV_UP:
1832 netxen_config_ipaddr(adapter,
1833 ifa->ifa_address, NX_IP_UP);
1834 break;
1835 case NETDEV_DOWN:
1836 netxen_config_ipaddr(adapter,
1837 ifa->ifa_address, NX_IP_DOWN);
1838 break;
1839 default:
1840 break;
1841 }
1842 } endfor_ifa(indev);
1843
1844 in_dev_put(indev);
1845done:
1846 return NOTIFY_DONE;
1847}
1848
1849static int
1850netxen_inetaddr_event(struct notifier_block *this,
1851 unsigned long event, void *ptr)
1852{
1853 struct netxen_adapter *adapter;
1854 struct net_device *dev;
1855
1856 struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
1857
1858 dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL;
1859
1860recheck:
1861 if (dev == NULL || !netif_running(dev))
1862 goto done;
1863
1864 if (dev->priv_flags & IFF_802_1Q_VLAN) {
1865 dev = vlan_dev_real_dev(dev);
1866 goto recheck;
1867 }
1868
1869 if (!is_netxen_netdev(dev))
1870 goto done;
1871
1872 adapter = netdev_priv(dev);
1873
1874 if (!adapter || !netxen_destip_supported(adapter))
1875 goto done;
1876
1877 if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
1878 goto done;
1879
1880 switch (event) {
1881 case NETDEV_UP:
1882 netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_UP);
1883 break;
1884 case NETDEV_DOWN:
1885 netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_DOWN);
1886 break;
1887 default:
1888 break;
1889 }
1890
1891done:
1892 return NOTIFY_DONE;
1893}
1894
1895static struct notifier_block netxen_netdev_cb = {
1896 .notifier_call = netxen_netdev_event,
1897};
1898
1899static struct notifier_block netxen_inetaddr_cb = {
1900 .notifier_call = netxen_inetaddr_event,
1901};
1902
1783static struct pci_driver netxen_driver = { 1903static struct pci_driver netxen_driver = {
1784 .name = netxen_nic_driver_name, 1904 .name = netxen_nic_driver_name,
1785 .id_table = netxen_pci_tbl, 1905 .id_table = netxen_pci_tbl,
@@ -1800,6 +1920,9 @@ static int __init netxen_init_module(void)
1800 if ((netxen_workq = create_singlethread_workqueue("netxen")) == NULL) 1920 if ((netxen_workq = create_singlethread_workqueue("netxen")) == NULL)
1801 return -ENOMEM; 1921 return -ENOMEM;
1802 1922
1923 register_netdevice_notifier(&netxen_netdev_cb);
1924 register_inetaddr_notifier(&netxen_inetaddr_cb);
1925
1803 return pci_register_driver(&netxen_driver); 1926 return pci_register_driver(&netxen_driver);
1804} 1927}
1805 1928
@@ -1808,6 +1931,9 @@ module_init(netxen_init_module);
1808static void __exit netxen_exit_module(void) 1931static void __exit netxen_exit_module(void)
1809{ 1932{
1810 pci_unregister_driver(&netxen_driver); 1933 pci_unregister_driver(&netxen_driver);
1934
1935 unregister_inetaddr_notifier(&netxen_inetaddr_cb);
1936 unregister_netdevice_notifier(&netxen_netdev_cb);
1811 destroy_workqueue(netxen_workq); 1937 destroy_workqueue(netxen_workq);
1812} 1938}
1813 1939