aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorNarender Kumar <narender.kumar@qlogic.com>2009-08-23 04:35:09 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-23 22:00:20 -0400
commit1bb482f8a46000f77577948ff1c350275bba7dc9 (patch)
tree3003df5a4414af44af0756f670531d9445bad397 /drivers/net
parent8fea0f0db87a4aaed41a93eed147af61cc5f9e3f (diff)
netxen: ethtool statistics and control for LRO
Add ethtool -K knob to control LRO in firmware. LRO path is completely separated from GRO, LRO packets are still fed with netif_receive_skb(). Also fix ethtool statistics to include LRO packets. Also use correct message type while configuring interrupt coalescing. 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.h22
-rw-r--r--drivers/net/netxen/netxen_nic_ctx.c2
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c27
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c56
-rw-r--r--drivers/net/netxen/netxen_nic_init.c7
-rw-r--r--drivers/net/netxen/netxen_nic_main.c8
6 files changed, 114 insertions, 8 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 5abb41e2d02c..fa43aa059c43 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -576,7 +576,8 @@ struct netxen_adapter_stats {
576 u64 rxdropped; 576 u64 rxdropped;
577 u64 txdropped; 577 u64 txdropped;
578 u64 csummed; 578 u64 csummed;
579 u64 no_rcv; 579 u64 rx_pkts;
580 u64 lro_pkts;
580 u64 rxbytes; 581 u64 rxbytes;
581 u64 txbytes; 582 u64 txbytes;
582}; 583};
@@ -958,7 +959,8 @@ typedef struct {
958#define NX_NIC_H2C_OPCODE_PROXY_STOP_DONE 20 959#define NX_NIC_H2C_OPCODE_PROXY_STOP_DONE 20
959#define NX_NIC_H2C_OPCODE_GET_LINKEVENT 21 960#define NX_NIC_H2C_OPCODE_GET_LINKEVENT 21
960#define NX_NIC_C2C_OPCODE 22 961#define NX_NIC_C2C_OPCODE 22
961#define NX_NIC_H2C_OPCODE_LAST 23 962#define NX_NIC_H2C_OPCODE_CONFIG_HW_LRO 24
963#define NX_NIC_H2C_OPCODE_LAST 25
962 964
963/* 965/*
964 * Firmware --> Driver 966 * Firmware --> Driver
@@ -984,6 +986,19 @@ typedef struct {
984#define VPORT_MISS_MODE_ACCEPT_ALL 1 /* accept all packets */ 986#define VPORT_MISS_MODE_ACCEPT_ALL 1 /* accept all packets */
985#define VPORT_MISS_MODE_ACCEPT_MULTI 2 /* accept unmatched multicast */ 987#define VPORT_MISS_MODE_ACCEPT_MULTI 2 /* accept unmatched multicast */
986 988
989#define NX_NIC_LRO_REQUEST_FIRST 0
990#define NX_NIC_LRO_REQUEST_ADD_FLOW 1
991#define NX_NIC_LRO_REQUEST_DELETE_FLOW 2
992#define NX_NIC_LRO_REQUEST_TIMER 3
993#define NX_NIC_LRO_REQUEST_CLEANUP 4
994#define NX_NIC_LRO_REQUEST_ADD_FLOW_SCHEDULED 5
995#define NX_TOE_LRO_REQUEST_ADD_FLOW 6
996#define NX_TOE_LRO_REQUEST_ADD_FLOW_RESPONSE 7
997#define NX_TOE_LRO_REQUEST_DELETE_FLOW 8
998#define NX_TOE_LRO_REQUEST_DELETE_FLOW_RESPONSE 9
999#define NX_TOE_LRO_REQUEST_TIMER 10
1000#define NX_NIC_LRO_REQUEST_LAST 11
1001
987#define NX_FW_CAPABILITY_LINK_NOTIFICATION (1 << 5) 1002#define NX_FW_CAPABILITY_LINK_NOTIFICATION (1 << 5)
988#define NX_FW_CAPABILITY_SWITCHING (1 << 6) 1003#define NX_FW_CAPABILITY_SWITCHING (1 << 6)
989#define NX_FW_CAPABILITY_PEXQ (1 << 7) 1004#define NX_FW_CAPABILITY_PEXQ (1 << 7)
@@ -1064,6 +1079,7 @@ typedef struct {
1064 1079
1065#define NETXEN_NIC_MSI_ENABLED 0x02 1080#define NETXEN_NIC_MSI_ENABLED 0x02
1066#define NETXEN_NIC_MSIX_ENABLED 0x04 1081#define NETXEN_NIC_MSIX_ENABLED 0x04
1082#define NETXEN_NIC_LRO_ENABLED 0x08
1067#define NETXEN_IS_MSI_FAMILY(adapter) \ 1083#define NETXEN_IS_MSI_FAMILY(adapter) \
1068 ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED)) 1084 ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED))
1069 1085
@@ -1290,6 +1306,8 @@ void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup);
1290 1306
1291int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu); 1307int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu);
1292int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); 1308int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
1309int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable);
1310int netxen_send_lro_cleanup(struct netxen_adapter *adapter);
1293 1311
1294int netxen_nic_set_mac(struct net_device *netdev, void *p); 1312int netxen_nic_set_mac(struct net_device *netdev, void *p);
1295struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); 1313struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index 412d65829d20..9e0469643d34 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -203,8 +203,6 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
203 203
204 cap = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN); 204 cap = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN);
205 cap |= (NX_CAP0_JUMBO_CONTIGUOUS | NX_CAP0_LRO_CONTIGUOUS); 205 cap |= (NX_CAP0_JUMBO_CONTIGUOUS | NX_CAP0_LRO_CONTIGUOUS);
206 if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)
207 cap |= NX_CAP0_HW_LRO;
208 206
209 prq->capabilities[0] = cpu_to_le32(cap); 207 prq->capabilities[0] = cpu_to_le32(cap);
210 prq->host_int_crb_mode = 208 prq->host_int_crb_mode =
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index 39a308c363c7..db66e7053b99 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -57,7 +57,8 @@ static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = {
57 {"rx_dropped", NETXEN_NIC_STAT(stats.rxdropped)}, 57 {"rx_dropped", NETXEN_NIC_STAT(stats.rxdropped)},
58 {"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)}, 58 {"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)},
59 {"csummed", NETXEN_NIC_STAT(stats.csummed)}, 59 {"csummed", NETXEN_NIC_STAT(stats.csummed)},
60 {"no_rcv", NETXEN_NIC_STAT(stats.no_rcv)}, 60 {"rx_pkts", NETXEN_NIC_STAT(stats.rx_pkts)},
61 {"lro_pkts", NETXEN_NIC_STAT(stats.lro_pkts)},
61 {"rx_bytes", NETXEN_NIC_STAT(stats.rxbytes)}, 62 {"rx_bytes", NETXEN_NIC_STAT(stats.rxbytes)},
62 {"tx_bytes", NETXEN_NIC_STAT(stats.txbytes)}, 63 {"tx_bytes", NETXEN_NIC_STAT(stats.txbytes)},
63}; 64};
@@ -941,6 +942,28 @@ static int netxen_get_intr_coalesce(struct net_device *netdev,
941 return 0; 942 return 0;
942} 943}
943 944
945static int netxen_nic_set_flags(struct net_device *netdev, u32 data)
946{
947 struct netxen_adapter *adapter = netdev_priv(netdev);
948 int hw_lro;
949
950 if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO))
951 return -EINVAL;
952
953 ethtool_op_set_flags(netdev, data);
954
955 hw_lro = (data & ETH_FLAG_LRO) ? NETXEN_NIC_LRO_ENABLED : 0;
956
957 if (netxen_config_hw_lro(adapter, hw_lro))
958 return -EIO;
959
960 if ((hw_lro == 0) && netxen_send_lro_cleanup(adapter))
961 return -EIO;
962
963
964 return 0;
965}
966
944struct ethtool_ops netxen_nic_ethtool_ops = { 967struct ethtool_ops netxen_nic_ethtool_ops = {
945 .get_settings = netxen_nic_get_settings, 968 .get_settings = netxen_nic_get_settings,
946 .set_settings = netxen_nic_set_settings, 969 .set_settings = netxen_nic_set_settings,
@@ -968,4 +991,6 @@ struct ethtool_ops netxen_nic_ethtool_ops = {
968 .set_rx_csum = netxen_nic_set_rx_csum, 991 .set_rx_csum = netxen_nic_set_rx_csum,
969 .get_coalesce = netxen_get_intr_coalesce, 992 .get_coalesce = netxen_get_intr_coalesce,
970 .set_coalesce = netxen_set_intr_coalesce, 993 .set_coalesce = netxen_set_intr_coalesce,
994 .get_flags = ethtool_op_get_flags,
995 .set_flags = netxen_nic_set_flags,
971}; 996};
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 673dcf5ea53d..965f783d39f2 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -643,7 +643,7 @@ int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
643 643
644 memset(&req, 0, sizeof(nx_nic_req_t)); 644 memset(&req, 0, sizeof(nx_nic_req_t));
645 645
646 req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23); 646 req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
647 647
648 word = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16); 648 word = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16);
649 req.req_hdr = cpu_to_le64(word); 649 req.req_hdr = cpu_to_le64(word);
@@ -659,6 +659,35 @@ int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
659 return rv; 659 return rv;
660} 660}
661 661
662int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable)
663{
664 nx_nic_req_t req;
665 u64 word;
666 int rv = 0;
667
668 if ((adapter->flags & NETXEN_NIC_LRO_ENABLED) == enable)
669 return 0;
670
671 memset(&req, 0, sizeof(nx_nic_req_t));
672
673 req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
674
675 word = NX_NIC_H2C_OPCODE_CONFIG_HW_LRO | ((u64)adapter->portnum << 16);
676 req.req_hdr = cpu_to_le64(word);
677
678 req.words[0] = cpu_to_le64(enable);
679
680 rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
681 if (rv != 0) {
682 printk(KERN_ERR "ERROR. Could not send "
683 "configure hw lro request\n");
684 }
685
686 adapter->flags ^= NETXEN_NIC_LRO_ENABLED;
687
688 return rv;
689}
690
662#define RSS_HASHTYPE_IP_TCP 0x3 691#define RSS_HASHTYPE_IP_TCP 0x3
663 692
664int netxen_config_rss(struct netxen_adapter *adapter, int enable) 693int netxen_config_rss(struct netxen_adapter *adapter, int enable)
@@ -752,6 +781,29 @@ int netxen_linkevent_request(struct netxen_adapter *adapter, int enable)
752 return rv; 781 return rv;
753} 782}
754 783
784int netxen_send_lro_cleanup(struct netxen_adapter *adapter)
785{
786 nx_nic_req_t req;
787 u64 word;
788 int rv;
789
790 memset(&req, 0, sizeof(nx_nic_req_t));
791 req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
792
793 word = NX_NIC_H2C_OPCODE_LRO_REQUEST |
794 ((u64)adapter->portnum << 16) |
795 ((u64)NX_NIC_LRO_REQUEST_CLEANUP << 56) ;
796
797 req.req_hdr = cpu_to_le64(word);
798
799 rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
800 if (rv != 0) {
801 printk(KERN_ERR "%s: could not cleanup lro flows\n",
802 adapter->netdev->name);
803 }
804 return rv;
805}
806
755/* 807/*
756 * netxen_nic_change_mtu - Change the Maximum Transfer Unit 808 * netxen_nic_change_mtu - Change the Maximum Transfer Unit
757 * @returns 0 on success, negative on failure 809 * @returns 0 on success, negative on failure
@@ -2066,6 +2118,8 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
2066 2118
2067 if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222)) 2119 if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222))
2068 adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1); 2120 adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
2121
2122 adapter->flags &= ~NETXEN_NIC_LRO_ENABLED;
2069} 2123}
2070 2124
2071int 2125int
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index e8bdbf9fefbb..c3609e422876 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -1277,7 +1277,7 @@ netxen_process_rcv(struct netxen_adapter *adapter,
1277 1277
1278 napi_gro_receive(&sds_ring->napi, skb); 1278 napi_gro_receive(&sds_ring->napi, skb);
1279 1279
1280 adapter->stats.no_rcv++; 1280 adapter->stats.rx_pkts++;
1281 adapter->stats.rxbytes += length; 1281 adapter->stats.rxbytes += length;
1282 1282
1283 return buffer; 1283 return buffer;
@@ -1350,8 +1350,13 @@ netxen_process_lro(struct netxen_adapter *adapter,
1350 th->psh = push; 1350 th->psh = push;
1351 th->seq = htonl(seq_number); 1351 th->seq = htonl(seq_number);
1352 1352
1353 length = skb->len;
1354
1353 netif_receive_skb(skb); 1355 netif_receive_skb(skb);
1354 1356
1357 adapter->stats.lro_pkts++;
1358 adapter->stats.rxbytes += length;
1359
1355 return buffer; 1360 return buffer;
1356} 1361}
1357 1362
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 4e3fb30d66fe..de67e42a2971 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -892,6 +892,9 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
892 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 892 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
893 netxen_config_intr_coalesce(adapter); 893 netxen_config_intr_coalesce(adapter);
894 894
895 if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)
896 netxen_config_hw_lro(adapter, NETXEN_NIC_LRO_ENABLED);
897
895 netxen_napi_enable(adapter); 898 netxen_napi_enable(adapter);
896 899
897 if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION) 900 if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION)
@@ -1077,6 +1080,9 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
1077 if (adapter->capabilities & NX_FW_CAPABILITY_FVLANTX) 1080 if (adapter->capabilities & NX_FW_CAPABILITY_FVLANTX)
1078 netdev->features |= (NETIF_F_HW_VLAN_TX); 1081 netdev->features |= (NETIF_F_HW_VLAN_TX);
1079 1082
1083 if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)
1084 netdev->features |= NETIF_F_LRO;
1085
1080 netdev->irq = adapter->msix_entries[0].vector; 1086 netdev->irq = adapter->msix_entries[0].vector;
1081 1087
1082 err = netxen_napi_add(adapter, netdev); 1088 err = netxen_napi_add(adapter, netdev);
@@ -1812,7 +1818,7 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
1812 1818
1813 memset(stats, 0, sizeof(*stats)); 1819 memset(stats, 0, sizeof(*stats));
1814 1820
1815 stats->rx_packets = adapter->stats.no_rcv; 1821 stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts;
1816 stats->tx_packets = adapter->stats.xmitfinished; 1822 stats->tx_packets = adapter->stats.xmitfinished;
1817 stats->rx_bytes = adapter->stats.rxbytes; 1823 stats->rx_bytes = adapter->stats.rxbytes;
1818 stats->tx_bytes = adapter->stats.txbytes; 1824 stats->tx_bytes = adapter->stats.txbytes;