aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen
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
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')
-rw-r--r--drivers/net/netxen/netxen_nic.h5
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c24
-rw-r--r--drivers/net/netxen/netxen_nic_init.c52
-rw-r--r--drivers/net/netxen/netxen_nic_main.c126
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);
1443int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32); 1447int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32);
1444int netxen_config_intr_coalesce(struct netxen_adapter *adapter); 1448int netxen_config_intr_coalesce(struct netxen_adapter *adapter);
1445int netxen_config_rss(struct netxen_adapter *adapter, int enable); 1449int netxen_config_rss(struct netxen_adapter *adapter, int enable);
1450int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd);
1446int netxen_linkevent_request(struct netxen_adapter *adapter, int enable); 1451int netxen_linkevent_request(struct netxen_adapter *adapter, int enable);
1447void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup); 1452void 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
709int 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
709int netxen_linkevent_request(struct netxen_adapter *adapter, int enable) 733int 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
883void netxen_request_firmware(struct netxen_adapter *adapter) 883static int
884netxen_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
898request_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
902void 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
917request_fw: 916request_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
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