aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorNarender Kumar <narender.kumar@qlogic.com>2009-08-24 15:23:28 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-26 18:29:21 -0400
commitfa3ce355c1bf1a83b843420228202fd6f8023ad3 (patch)
treeb8ebdbc86bfa36215d9cfc1f2920a44f3b0e4ae3 /drivers/net
parent3ad4467ca43e7a2556e26e4e304faf3385048834 (diff)
netxen: bridged mode optimizations
When the interface is put in bridged mode, destination mac addresses are unknown to firmware. So packets take a slow path (lower priority) in firmware reducing performance. Firmware can cache limited number of remote unicast mac addresses for certain interval, if "dynamic mac learning" mode is enabled. Driver needs to enable this "mac learning" mode in firmware. Currently this is done through net device class sysfs entry, possibly this can also be done upon netlink notifications to from bridge. Signed-off-by: Narender Kumar <narender.kumar@qlogic.com> Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/netxen/netxen_nic.h3
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c31
-rw-r--r--drivers/net/netxen/netxen_nic_main.c84
3 files changed, 116 insertions, 2 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 63e2f793ae0e..449d3511628f 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -964,6 +964,7 @@ typedef struct {
964#define NX_NIC_H2C_OPCODE_PROXY_STOP_DONE 20 964#define NX_NIC_H2C_OPCODE_PROXY_STOP_DONE 20
965#define NX_NIC_H2C_OPCODE_GET_LINKEVENT 21 965#define NX_NIC_H2C_OPCODE_GET_LINKEVENT 21
966#define NX_NIC_C2C_OPCODE 22 966#define NX_NIC_C2C_OPCODE 22
967#define NX_NIC_H2C_OPCODE_CONFIG_BRIDGING 23
967#define NX_NIC_H2C_OPCODE_CONFIG_HW_LRO 24 968#define NX_NIC_H2C_OPCODE_CONFIG_HW_LRO 24
968#define NX_NIC_H2C_OPCODE_LAST 25 969#define NX_NIC_H2C_OPCODE_LAST 25
969 970
@@ -1085,6 +1086,7 @@ typedef struct {
1085#define NETXEN_NIC_MSI_ENABLED 0x02 1086#define NETXEN_NIC_MSI_ENABLED 0x02
1086#define NETXEN_NIC_MSIX_ENABLED 0x04 1087#define NETXEN_NIC_MSIX_ENABLED 0x04
1087#define NETXEN_NIC_LRO_ENABLED 0x08 1088#define NETXEN_NIC_LRO_ENABLED 0x08
1089#define NETXEN_NIC_BRIDGE_ENABLED 0X10
1088#define NETXEN_IS_MSI_FAMILY(adapter) \ 1090#define NETXEN_IS_MSI_FAMILY(adapter) \
1089 ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED)) 1091 ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED))
1090 1092
@@ -1332,6 +1334,7 @@ void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup);
1332int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu); 1334int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu);
1333int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); 1335int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
1334int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable); 1336int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable);
1337int netxen_config_bridged_mode(struct netxen_adapter *adapter, int enable);
1335int netxen_send_lro_cleanup(struct netxen_adapter *adapter); 1338int netxen_send_lro_cleanup(struct netxen_adapter *adapter);
1336 1339
1337int netxen_nic_set_mac(struct net_device *netdev, void *p); 1340int netxen_nic_set_mac(struct net_device *netdev, void *p);
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 1a8ad62e12ee..db510cee8094 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -794,6 +794,37 @@ int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable)
794 return rv; 794 return rv;
795} 795}
796 796
797int netxen_config_bridged_mode(struct netxen_adapter *adapter, int enable)
798{
799 nx_nic_req_t req;
800 u64 word;
801 int rv = 0;
802
803 if (!!(adapter->flags & NETXEN_NIC_BRIDGE_ENABLED) == enable)
804 return rv;
805
806 memset(&req, 0, sizeof(nx_nic_req_t));
807
808 req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
809
810 word = NX_NIC_H2C_OPCODE_CONFIG_BRIDGING |
811 ((u64)adapter->portnum << 16);
812 req.req_hdr = cpu_to_le64(word);
813
814 req.words[0] = cpu_to_le64(enable);
815
816 rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
817 if (rv != 0) {
818 printk(KERN_ERR "ERROR. Could not send "
819 "configure bridge mode request\n");
820 }
821
822 adapter->flags ^= NETXEN_NIC_BRIDGE_ENABLED;
823
824 return rv;
825}
826
827
797#define RSS_HASHTYPE_IP_TCP 0x3 828#define RSS_HASHTYPE_IP_TCP 0x3
798 829
799int netxen_config_rss(struct netxen_adapter *adapter, int enable) 830int netxen_config_rss(struct netxen_adapter *adapter, int enable)
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index bd4589f1d469..fab51d16f5fb 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -71,6 +71,10 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget);
71#ifdef CONFIG_NET_POLL_CONTROLLER 71#ifdef CONFIG_NET_POLL_CONTROLLER
72static void netxen_nic_poll_controller(struct net_device *netdev); 72static void netxen_nic_poll_controller(struct net_device *netdev);
73#endif 73#endif
74
75static void netxen_create_sysfs_entries(struct netxen_adapter *adapter);
76static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter);
77
74static irqreturn_t netxen_intr(int irq, void *data); 78static irqreturn_t netxen_intr(int irq, void *data);
75static irqreturn_t netxen_msi_intr(int irq, void *data); 79static irqreturn_t netxen_msi_intr(int irq, void *data);
76static irqreturn_t netxen_msix_intr(int irq, void *data); 80static irqreturn_t netxen_msix_intr(int irq, void *data);
@@ -94,8 +98,6 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
94 98
95MODULE_DEVICE_TABLE(pci, netxen_pci_tbl); 99MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
96 100
97static void netxen_watchdog(unsigned long);
98
99static uint32_t crb_cmd_producer[4] = { 101static uint32_t crb_cmd_producer[4] = {
100 CRB_CMD_PRODUCER_OFFSET, CRB_CMD_PRODUCER_OFFSET_1, 102 CRB_CMD_PRODUCER_OFFSET, CRB_CMD_PRODUCER_OFFSET_1,
101 CRB_CMD_PRODUCER_OFFSET_2, CRB_CMD_PRODUCER_OFFSET_3 103 CRB_CMD_PRODUCER_OFFSET_2, CRB_CMD_PRODUCER_OFFSET_3
@@ -995,6 +997,8 @@ netxen_nic_attach(struct netxen_adapter *adapter)
995 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 997 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
996 netxen_nic_init_coalesce_defaults(adapter); 998 netxen_nic_init_coalesce_defaults(adapter);
997 999
1000 netxen_create_sysfs_entries(adapter);
1001
998 adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; 1002 adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
999 return 0; 1003 return 0;
1000 1004
@@ -1012,6 +1016,8 @@ netxen_nic_detach(struct netxen_adapter *adapter)
1012 if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) 1016 if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
1013 return; 1017 return;
1014 1018
1019 netxen_remove_sysfs_entries(adapter);
1020
1015 netxen_free_hw_resources(adapter); 1021 netxen_free_hw_resources(adapter);
1016 netxen_release_rx_buffers(adapter); 1022 netxen_release_rx_buffers(adapter);
1017 netxen_nic_free_irq(adapter); 1023 netxen_nic_free_irq(adapter);
@@ -1959,6 +1965,80 @@ static void netxen_nic_poll_controller(struct net_device *netdev)
1959} 1965}
1960#endif 1966#endif
1961 1967
1968static ssize_t
1969netxen_store_bridged_mode(struct device *dev,
1970 struct device_attribute *attr, const char *buf, size_t len)
1971{
1972 struct net_device *net = to_net_dev(dev);
1973 struct netxen_adapter *adapter = netdev_priv(net);
1974 unsigned long new;
1975 int ret = -EINVAL;
1976
1977 if (!(adapter->capabilities & NX_FW_CAPABILITY_BDG))
1978 goto err_out;
1979
1980 if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
1981 goto err_out;
1982
1983 if (strict_strtoul(buf, 2, &new))
1984 goto err_out;
1985
1986 if (!netxen_config_bridged_mode(adapter, !!new))
1987 ret = len;
1988
1989err_out:
1990 return ret;
1991}
1992
1993static ssize_t
1994netxen_show_bridged_mode(struct device *dev,
1995 struct device_attribute *attr, char *buf)
1996{
1997 struct net_device *net = to_net_dev(dev);
1998 struct netxen_adapter *adapter;
1999 int bridged_mode = 0;
2000
2001 adapter = netdev_priv(net);
2002
2003 if (adapter->capabilities & NX_FW_CAPABILITY_BDG)
2004 bridged_mode = !!(adapter->flags & NETXEN_NIC_BRIDGE_ENABLED);
2005
2006 return sprintf(buf, "%d\n", bridged_mode);
2007}
2008
2009static struct device_attribute dev_attr_bridged_mode = {
2010 .attr = {.name = "bridged_mode", .mode = (S_IRUGO | S_IWUSR)},
2011 .show = netxen_show_bridged_mode,
2012 .store = netxen_store_bridged_mode,
2013};
2014
2015static void
2016netxen_create_sysfs_entries(struct netxen_adapter *adapter)
2017{
2018 struct net_device *netdev = adapter->netdev;
2019 struct device *dev = &netdev->dev;
2020
2021 if (adapter->capabilities & NX_FW_CAPABILITY_BDG) {
2022 /* bridged_mode control */
2023 if (device_create_file(dev, &dev_attr_bridged_mode)) {
2024 dev_warn(&netdev->dev,
2025 "failed to create bridged_mode sysfs entry\n");
2026 }
2027 }
2028}
2029
2030static void
2031netxen_remove_sysfs_entries(struct netxen_adapter *adapter)
2032{
2033 struct net_device *netdev = adapter->netdev;
2034 struct device *dev = &netdev->dev;
2035
2036 if (adapter->capabilities & NX_FW_CAPABILITY_BDG)
2037 device_remove_file(dev, &dev_attr_bridged_mode);
2038}
2039
2040static void netxen_watchdog(unsigned long);
2041
1962#ifdef CONFIG_INET 2042#ifdef CONFIG_INET
1963 2043
1964#define is_netxen_netdev(dev) (dev->netdev_ops == &netxen_netdev_ops) 2044#define is_netxen_netdev(dev) (dev->netdev_ops == &netxen_netdev_ops)