diff options
author | Dhananjay Phadke <dhananjay@netxen.com> | 2009-07-26 16:07:37 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-07-27 13:55:19 -0400 |
commit | 6598b169b856793f8f9b80a3f3c5a48f5eaf40e3 (patch) | |
tree | 94ac7225b638d8bea654e1acc7eb3df1fe6f052c /drivers/net/netxen/netxen_nic_main.c | |
parent | 68b3cae0824b98d1f469a80cc65dcaab81771f45 (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.c | 126 |
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 | ||
43 | MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver"); | 44 | MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver"); |
44 | MODULE_LICENSE("GPL"); | 45 | MODULE_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 | |||
1786 | static int | ||
1787 | netxen_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 | |||
1798 | static 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 | |||
1805 | recheck: | ||
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); | ||
1845 | done: | ||
1846 | return NOTIFY_DONE; | ||
1847 | } | ||
1848 | |||
1849 | static int | ||
1850 | netxen_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 | |||
1860 | recheck: | ||
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 | |||
1891 | done: | ||
1892 | return NOTIFY_DONE; | ||
1893 | } | ||
1894 | |||
1895 | static struct notifier_block netxen_netdev_cb = { | ||
1896 | .notifier_call = netxen_netdev_event, | ||
1897 | }; | ||
1898 | |||
1899 | static struct notifier_block netxen_inetaddr_cb = { | ||
1900 | .notifier_call = netxen_inetaddr_event, | ||
1901 | }; | ||
1902 | |||
1783 | static struct pci_driver netxen_driver = { | 1903 | static 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); | |||
1808 | static void __exit netxen_exit_module(void) | 1931 | static 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 | ||