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 | |
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')
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 5 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 24 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 52 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 126 |
4 files changed, 182 insertions, 25 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index f86e05047d19..6b9e759d3523 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -380,6 +380,7 @@ struct rcv_desc { | |||
380 | }; | 380 | }; |
381 | 381 | ||
382 | /* opcode field in status_desc */ | 382 | /* opcode field in status_desc */ |
383 | #define NETXEN_NIC_SYN_OFFLOAD 0x03 | ||
383 | #define NETXEN_NIC_RXPKT_DESC 0x04 | 384 | #define NETXEN_NIC_RXPKT_DESC 0x04 |
384 | #define NETXEN_OLD_RXPKT_DESC 0x3f | 385 | #define NETXEN_OLD_RXPKT_DESC 0x3f |
385 | #define NETXEN_NIC_RESPONSE_DESC 0x05 | 386 | #define NETXEN_NIC_RESPONSE_DESC 0x05 |
@@ -1078,6 +1079,9 @@ typedef struct { | |||
1078 | 1079 | ||
1079 | #define NX_MAC_EVENT 0x1 | 1080 | #define NX_MAC_EVENT 0x1 |
1080 | 1081 | ||
1082 | #define NX_IP_UP 2 | ||
1083 | #define NX_IP_DOWN 3 | ||
1084 | |||
1081 | /* | 1085 | /* |
1082 | * Driver --> Firmware | 1086 | * Driver --> Firmware |
1083 | */ | 1087 | */ |
@@ -1443,6 +1447,7 @@ void netxen_p3_free_mac_list(struct netxen_adapter *adapter); | |||
1443 | int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32); | 1447 | int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32); |
1444 | int netxen_config_intr_coalesce(struct netxen_adapter *adapter); | 1448 | int netxen_config_intr_coalesce(struct netxen_adapter *adapter); |
1445 | int netxen_config_rss(struct netxen_adapter *adapter, int enable); | 1449 | int netxen_config_rss(struct netxen_adapter *adapter, int enable); |
1450 | int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd); | ||
1446 | int netxen_linkevent_request(struct netxen_adapter *adapter, int enable); | 1451 | int netxen_linkevent_request(struct netxen_adapter *adapter, int enable); |
1447 | void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup); | 1452 | void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup); |
1448 | 1453 | ||
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 3c614c3cc62b..088611bb5bdb 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -706,6 +706,30 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable) | |||
706 | return rv; | 706 | return rv; |
707 | } | 707 | } |
708 | 708 | ||
709 | int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd) | ||
710 | { | ||
711 | nx_nic_req_t req; | ||
712 | u64 word; | ||
713 | int rv; | ||
714 | |||
715 | memset(&req, 0, sizeof(nx_nic_req_t)); | ||
716 | req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23); | ||
717 | |||
718 | word = NX_NIC_H2C_OPCODE_CONFIG_IPADDR | ((u64)adapter->portnum << 16); | ||
719 | req.req_hdr = cpu_to_le64(word); | ||
720 | |||
721 | req.words[0] = cpu_to_le64(cmd); | ||
722 | req.words[1] = cpu_to_le64(ip); | ||
723 | |||
724 | rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); | ||
725 | if (rv != 0) { | ||
726 | printk(KERN_ERR "%s: could not notify %s IP 0x%x reuqest\n", | ||
727 | adapter->netdev->name, | ||
728 | (cmd == NX_IP_UP) ? "Add" : "Remove", ip); | ||
729 | } | ||
730 | return rv; | ||
731 | } | ||
732 | |||
709 | int netxen_linkevent_request(struct netxen_adapter *adapter, int enable) | 733 | int netxen_linkevent_request(struct netxen_adapter *adapter, int enable) |
710 | { | 734 | { |
711 | nx_nic_req_t req; | 735 | nx_nic_req_t req; |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 847f78b18688..5d7a2c453363 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -880,22 +880,10 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | |||
880 | return 0; | 880 | return 0; |
881 | } | 881 | } |
882 | 882 | ||
883 | void netxen_request_firmware(struct netxen_adapter *adapter) | 883 | static int |
884 | netxen_p3_has_mn(struct netxen_adapter *adapter) | ||
884 | { | 885 | { |
885 | u32 capability, flashed_ver; | 886 | u32 capability, flashed_ver; |
886 | u8 fw_type; | ||
887 | struct pci_dev *pdev = adapter->pdev; | ||
888 | int rc = 0; | ||
889 | |||
890 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | ||
891 | fw_type = NX_P2_MN_ROMIMAGE; | ||
892 | goto request_fw; | ||
893 | } else { | ||
894 | fw_type = NX_P3_CT_ROMIMAGE; | ||
895 | goto request_fw; | ||
896 | } | ||
897 | |||
898 | request_mn: | ||
899 | capability = 0; | 887 | capability = 0; |
900 | 888 | ||
901 | netxen_rom_fast_read(adapter, | 889 | netxen_rom_fast_read(adapter, |
@@ -903,23 +891,35 @@ request_mn: | |||
903 | flashed_ver = NETXEN_DECODE_VERSION(flashed_ver); | 891 | flashed_ver = NETXEN_DECODE_VERSION(flashed_ver); |
904 | 892 | ||
905 | if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) { | 893 | if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) { |
894 | |||
906 | capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY); | 895 | capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY); |
907 | if (capability & NX_PEG_TUNE_MN_PRESENT) { | 896 | if (capability & NX_PEG_TUNE_MN_PRESENT) |
908 | fw_type = NX_P3_MN_ROMIMAGE; | 897 | return 1; |
909 | goto request_fw; | 898 | } |
910 | } | 899 | return 0; |
900 | } | ||
901 | |||
902 | void netxen_request_firmware(struct netxen_adapter *adapter) | ||
903 | { | ||
904 | u8 fw_type; | ||
905 | struct pci_dev *pdev = adapter->pdev; | ||
906 | int rc = 0; | ||
907 | |||
908 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | ||
909 | fw_type = NX_P2_MN_ROMIMAGE; | ||
910 | goto request_fw; | ||
911 | } | 911 | } |
912 | 912 | ||
913 | fw_type = NX_FLASH_ROMIMAGE; | 913 | fw_type = netxen_p3_has_mn(adapter) ? |
914 | adapter->fw = NULL; | 914 | NX_P3_MN_ROMIMAGE : NX_P3_CT_ROMIMAGE; |
915 | goto done; | ||
916 | 915 | ||
917 | request_fw: | 916 | request_fw: |
918 | rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev); | 917 | rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev); |
919 | if (rc != 0) { | 918 | if (rc != 0) { |
920 | if (fw_type == NX_P3_CT_ROMIMAGE) { | 919 | if (fw_type == NX_P3_MN_ROMIMAGE) { |
921 | msleep(1); | 920 | msleep(1); |
922 | goto request_mn; | 921 | fw_type = NX_P3_CT_ROMIMAGE; |
922 | goto request_fw; | ||
923 | } | 923 | } |
924 | 924 | ||
925 | fw_type = NX_FLASH_ROMIMAGE; | 925 | fw_type = NX_FLASH_ROMIMAGE; |
@@ -931,9 +931,10 @@ request_fw: | |||
931 | if (rc != 0) { | 931 | if (rc != 0) { |
932 | release_firmware(adapter->fw); | 932 | release_firmware(adapter->fw); |
933 | 933 | ||
934 | if (fw_type == NX_P3_CT_ROMIMAGE) { | 934 | if (fw_type == NX_P3_MN_ROMIMAGE) { |
935 | msleep(1); | 935 | msleep(1); |
936 | goto request_mn; | 936 | fw_type = NX_P3_CT_ROMIMAGE; |
937 | goto request_fw; | ||
937 | } | 938 | } |
938 | 939 | ||
939 | fw_type = NX_FLASH_ROMIMAGE; | 940 | fw_type = NX_FLASH_ROMIMAGE; |
@@ -1292,6 +1293,7 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max) | |||
1292 | switch (opcode) { | 1293 | switch (opcode) { |
1293 | case NETXEN_NIC_RXPKT_DESC: | 1294 | case NETXEN_NIC_RXPKT_DESC: |
1294 | case NETXEN_OLD_RXPKT_DESC: | 1295 | case NETXEN_OLD_RXPKT_DESC: |
1296 | case NETXEN_NIC_SYN_OFFLOAD: | ||
1295 | break; | 1297 | break; |
1296 | case NETXEN_NIC_RESPONSE_DESC: | 1298 | case NETXEN_NIC_RESPONSE_DESC: |
1297 | netxen_handle_fw_message(desc_cnt, consumer, sds_ring); | 1299 | netxen_handle_fw_message(desc_cnt, consumer, sds_ring); |
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 | ||