diff options
author | Scott Feldman <scofeldm@cisco.com> | 2008-11-22 00:26:55 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-22 00:26:55 -0500 |
commit | 86ca9db794a285f18f31ed15601696b238ccb57a (patch) | |
tree | 8b89fdd21453fcb52ea4821d160acbb3a0c37def /drivers/net/enic/enic_main.c | |
parent | 4e4fd4e485ad63a9074ff09a9b53ffc7a5c594ec (diff) |
enic: enable ethtool LRO support
Enable ethtool support for get/set_flags so LRO can be turned on/off
by fwding drivers such as the bridge driver. LRO is not compatible
with fwding drivers.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/enic/enic_main.c')
-rw-r--r-- | drivers/net/enic/enic_main.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 1c409df735d4..deddd76a550c 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c | |||
@@ -273,6 +273,8 @@ static struct ethtool_ops enic_ethtool_ops = { | |||
273 | .set_sg = ethtool_op_set_sg, | 273 | .set_sg = ethtool_op_set_sg, |
274 | .get_tso = ethtool_op_get_tso, | 274 | .get_tso = ethtool_op_get_tso, |
275 | .set_tso = enic_set_tso, | 275 | .set_tso = enic_set_tso, |
276 | .get_flags = ethtool_op_get_flags, | ||
277 | .set_flags = ethtool_op_set_flags, | ||
276 | }; | 278 | }; |
277 | 279 | ||
278 | static void enic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf) | 280 | static void enic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf) |
@@ -895,6 +897,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, | |||
895 | int skipped, void *opaque) | 897 | int skipped, void *opaque) |
896 | { | 898 | { |
897 | struct enic *enic = vnic_dev_priv(rq->vdev); | 899 | struct enic *enic = vnic_dev_priv(rq->vdev); |
900 | struct net_device *netdev = enic->netdev; | ||
898 | struct sk_buff *skb; | 901 | struct sk_buff *skb; |
899 | 902 | ||
900 | u8 type, color, eop, sop, ingress_port, vlan_stripped; | 903 | u8 type, color, eop, sop, ingress_port, vlan_stripped; |
@@ -929,7 +932,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, | |||
929 | if (net_ratelimit()) | 932 | if (net_ratelimit()) |
930 | printk(KERN_ERR PFX | 933 | printk(KERN_ERR PFX |
931 | "%s: packet error: bad FCS\n", | 934 | "%s: packet error: bad FCS\n", |
932 | enic->netdev->name); | 935 | netdev->name); |
933 | } | 936 | } |
934 | 937 | ||
935 | dev_kfree_skb_any(skb); | 938 | dev_kfree_skb_any(skb); |
@@ -943,18 +946,18 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, | |||
943 | */ | 946 | */ |
944 | 947 | ||
945 | skb_put(skb, bytes_written); | 948 | skb_put(skb, bytes_written); |
946 | skb->protocol = eth_type_trans(skb, enic->netdev); | 949 | skb->protocol = eth_type_trans(skb, netdev); |
947 | 950 | ||
948 | if (enic->csum_rx_enabled && !csum_not_calc) { | 951 | if (enic->csum_rx_enabled && !csum_not_calc) { |
949 | skb->csum = htons(checksum); | 952 | skb->csum = htons(checksum); |
950 | skb->ip_summed = CHECKSUM_COMPLETE; | 953 | skb->ip_summed = CHECKSUM_COMPLETE; |
951 | } | 954 | } |
952 | 955 | ||
953 | skb->dev = enic->netdev; | 956 | skb->dev = netdev; |
954 | 957 | ||
955 | if (enic->vlan_group && vlan_stripped) { | 958 | if (enic->vlan_group && vlan_stripped) { |
956 | 959 | ||
957 | if (ENIC_SETTING(enic, LRO) && ipv4) | 960 | if ((netdev->features & NETIF_F_LRO) && ipv4) |
958 | lro_vlan_hwaccel_receive_skb(&enic->lro_mgr, | 961 | lro_vlan_hwaccel_receive_skb(&enic->lro_mgr, |
959 | skb, enic->vlan_group, | 962 | skb, enic->vlan_group, |
960 | vlan, cq_desc); | 963 | vlan, cq_desc); |
@@ -964,7 +967,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, | |||
964 | 967 | ||
965 | } else { | 968 | } else { |
966 | 969 | ||
967 | if (ENIC_SETTING(enic, LRO) && ipv4) | 970 | if ((netdev->features & NETIF_F_LRO) && ipv4) |
968 | lro_receive_skb(&enic->lro_mgr, skb, cq_desc); | 971 | lro_receive_skb(&enic->lro_mgr, skb, cq_desc); |
969 | else | 972 | else |
970 | netif_receive_skb(skb); | 973 | netif_receive_skb(skb); |
@@ -1062,7 +1065,7 @@ static int enic_poll(struct napi_struct *napi, int budget) | |||
1062 | /* If no work done, flush all LROs and exit polling | 1065 | /* If no work done, flush all LROs and exit polling |
1063 | */ | 1066 | */ |
1064 | 1067 | ||
1065 | if (ENIC_SETTING(enic, LRO)) | 1068 | if (netdev->features & NETIF_F_LRO) |
1066 | lro_flush_all(&enic->lro_mgr); | 1069 | lro_flush_all(&enic->lro_mgr); |
1067 | 1070 | ||
1068 | netif_rx_complete(netdev, napi); | 1071 | netif_rx_complete(netdev, napi); |
@@ -1106,7 +1109,7 @@ static int enic_poll_msix(struct napi_struct *napi, int budget) | |||
1106 | /* If no work done, flush all LROs and exit polling | 1109 | /* If no work done, flush all LROs and exit polling |
1107 | */ | 1110 | */ |
1108 | 1111 | ||
1109 | if (ENIC_SETTING(enic, LRO)) | 1112 | if (netdev->features & NETIF_F_LRO) |
1110 | lro_flush_all(&enic->lro_mgr); | 1113 | lro_flush_all(&enic->lro_mgr); |
1111 | 1114 | ||
1112 | netif_rx_complete(netdev, napi); | 1115 | netif_rx_complete(netdev, napi); |
@@ -1762,13 +1765,13 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
1762 | } | 1765 | } |
1763 | 1766 | ||
1764 | /* Get available resource counts | 1767 | /* Get available resource counts |
1765 | */ | 1768 | */ |
1766 | 1769 | ||
1767 | enic_get_res_counts(enic); | 1770 | enic_get_res_counts(enic); |
1768 | 1771 | ||
1769 | /* Set interrupt mode based on resource counts and system | 1772 | /* Set interrupt mode based on resource counts and system |
1770 | * capabilities | 1773 | * capabilities |
1771 | */ | 1774 | */ |
1772 | 1775 | ||
1773 | err = enic_set_intr_mode(enic); | 1776 | err = enic_set_intr_mode(enic); |
1774 | if (err) { | 1777 | if (err) { |
@@ -1849,22 +1852,23 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
1849 | if (ENIC_SETTING(enic, TSO)) | 1852 | if (ENIC_SETTING(enic, TSO)) |
1850 | netdev->features |= NETIF_F_TSO | | 1853 | netdev->features |= NETIF_F_TSO | |
1851 | NETIF_F_TSO6 | NETIF_F_TSO_ECN; | 1854 | NETIF_F_TSO6 | NETIF_F_TSO_ECN; |
1855 | if (ENIC_SETTING(enic, LRO)) | ||
1856 | netdev->features |= NETIF_F_LRO; | ||
1852 | if (using_dac) | 1857 | if (using_dac) |
1853 | netdev->features |= NETIF_F_HIGHDMA; | 1858 | netdev->features |= NETIF_F_HIGHDMA; |
1854 | 1859 | ||
1855 | 1860 | ||
1856 | enic->csum_rx_enabled = ENIC_SETTING(enic, RXCSUM); | 1861 | enic->csum_rx_enabled = ENIC_SETTING(enic, RXCSUM); |
1857 | 1862 | ||
1858 | if (ENIC_SETTING(enic, LRO)) { | 1863 | enic->lro_mgr.max_aggr = ENIC_LRO_MAX_AGGR; |
1859 | enic->lro_mgr.max_aggr = ENIC_LRO_MAX_AGGR; | 1864 | enic->lro_mgr.max_desc = ENIC_LRO_MAX_DESC; |
1860 | enic->lro_mgr.max_desc = ENIC_LRO_MAX_DESC; | 1865 | enic->lro_mgr.lro_arr = enic->lro_desc; |
1861 | enic->lro_mgr.lro_arr = enic->lro_desc; | 1866 | enic->lro_mgr.get_skb_header = enic_get_skb_header; |
1862 | enic->lro_mgr.get_skb_header = enic_get_skb_header; | 1867 | enic->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID; |
1863 | enic->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID; | 1868 | enic->lro_mgr.dev = netdev; |
1864 | enic->lro_mgr.dev = netdev; | 1869 | enic->lro_mgr.ip_summed = CHECKSUM_COMPLETE; |
1865 | enic->lro_mgr.ip_summed = CHECKSUM_COMPLETE; | 1870 | enic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY; |
1866 | enic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY; | 1871 | |
1867 | } | ||
1868 | 1872 | ||
1869 | err = register_netdev(netdev); | 1873 | err = register_netdev(netdev); |
1870 | if (err) { | 1874 | if (err) { |