diff options
author | Jiri Pirko <jpirko@redhat.com> | 2011-07-20 00:54:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-07-21 16:47:56 -0400 |
commit | 892ef5d85259e193505d553c10237fd5dc9a3d0d (patch) | |
tree | 9d755e3311ce8592b8b23cf5928431f107e7902c /drivers | |
parent | dc437974af52e78f2736543dfee94cc385dae6e9 (diff) |
cxgb3: do vlan cleanup
- unify vlan and nonvlan rx path
- kill pi->vlan_grp and vlan_rx_register
- allow to turn on/off rx/tx vlan accel via ethtool (set_features)
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/cxgb3/adapter.h | 2 | ||||
-rw-r--r-- | drivers/net/cxgb3/cxgb3_main.c | 51 | ||||
-rw-r--r-- | drivers/net/cxgb3/cxgb3_offload.c | 9 | ||||
-rw-r--r-- | drivers/net/cxgb3/sge.c | 35 |
4 files changed, 49 insertions, 48 deletions
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index 7300de5a142..8b395b53733 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h | |||
@@ -45,7 +45,6 @@ | |||
45 | #include "t3cdev.h" | 45 | #include "t3cdev.h" |
46 | #include <asm/io.h> | 46 | #include <asm/io.h> |
47 | 47 | ||
48 | struct vlan_group; | ||
49 | struct adapter; | 48 | struct adapter; |
50 | struct sge_qset; | 49 | struct sge_qset; |
51 | struct port_info; | 50 | struct port_info; |
@@ -66,7 +65,6 @@ struct iscsi_config { | |||
66 | 65 | ||
67 | struct port_info { | 66 | struct port_info { |
68 | struct adapter *adapter; | 67 | struct adapter *adapter; |
69 | struct vlan_group *vlan_grp; | ||
70 | struct sge_qset *qs; | 68 | struct sge_qset *qs; |
71 | u8 port_id; | 69 | u8 port_id; |
72 | u8 nqsets; | 70 | u8 nqsets; |
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 9081ce03714..93b41a7ac17 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -2532,25 +2532,51 @@ static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p) | |||
2532 | } | 2532 | } |
2533 | } | 2533 | } |
2534 | 2534 | ||
2535 | static void vlan_rx_register(struct net_device *dev, struct vlan_group *grp) | 2535 | static void cxgb_vlan_mode(struct net_device *dev, u32 features) |
2536 | { | 2536 | { |
2537 | struct port_info *pi = netdev_priv(dev); | 2537 | struct port_info *pi = netdev_priv(dev); |
2538 | struct adapter *adapter = pi->adapter; | 2538 | struct adapter *adapter = pi->adapter; |
2539 | 2539 | ||
2540 | pi->vlan_grp = grp; | 2540 | if (adapter->params.rev > 0) { |
2541 | if (adapter->params.rev > 0) | 2541 | t3_set_vlan_accel(adapter, 1 << pi->port_id, |
2542 | t3_set_vlan_accel(adapter, 1 << pi->port_id, grp != NULL); | 2542 | features & NETIF_F_HW_VLAN_RX); |
2543 | else { | 2543 | } else { |
2544 | /* single control for all ports */ | 2544 | /* single control for all ports */ |
2545 | unsigned int i, have_vlans = 0; | 2545 | unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX; |
2546 | |||
2546 | for_each_port(adapter, i) | 2547 | for_each_port(adapter, i) |
2547 | have_vlans |= adap2pinfo(adapter, i)->vlan_grp != NULL; | 2548 | have_vlans |= |
2549 | adapter->port[i]->features & NETIF_F_HW_VLAN_RX; | ||
2548 | 2550 | ||
2549 | t3_set_vlan_accel(adapter, 1, have_vlans); | 2551 | t3_set_vlan_accel(adapter, 1, have_vlans); |
2550 | } | 2552 | } |
2551 | t3_synchronize_rx(adapter, pi); | 2553 | t3_synchronize_rx(adapter, pi); |
2552 | } | 2554 | } |
2553 | 2555 | ||
2556 | static u32 cxgb_fix_features(struct net_device *dev, u32 features) | ||
2557 | { | ||
2558 | /* | ||
2559 | * Since there is no support for separate rx/tx vlan accel | ||
2560 | * enable/disable make sure tx flag is always in same state as rx. | ||
2561 | */ | ||
2562 | if (features & NETIF_F_HW_VLAN_RX) | ||
2563 | features |= NETIF_F_HW_VLAN_TX; | ||
2564 | else | ||
2565 | features &= ~NETIF_F_HW_VLAN_TX; | ||
2566 | |||
2567 | return features; | ||
2568 | } | ||
2569 | |||
2570 | static int cxgb_set_features(struct net_device *dev, u32 features) | ||
2571 | { | ||
2572 | u32 changed = dev->features ^ features; | ||
2573 | |||
2574 | if (changed & NETIF_F_HW_VLAN_RX) | ||
2575 | cxgb_vlan_mode(dev, features); | ||
2576 | |||
2577 | return 0; | ||
2578 | } | ||
2579 | |||
2554 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2580 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2555 | static void cxgb_netpoll(struct net_device *dev) | 2581 | static void cxgb_netpoll(struct net_device *dev) |
2556 | { | 2582 | { |
@@ -3131,7 +3157,8 @@ static const struct net_device_ops cxgb_netdev_ops = { | |||
3131 | .ndo_do_ioctl = cxgb_ioctl, | 3157 | .ndo_do_ioctl = cxgb_ioctl, |
3132 | .ndo_change_mtu = cxgb_change_mtu, | 3158 | .ndo_change_mtu = cxgb_change_mtu, |
3133 | .ndo_set_mac_address = cxgb_set_mac_addr, | 3159 | .ndo_set_mac_address = cxgb_set_mac_addr, |
3134 | .ndo_vlan_rx_register = vlan_rx_register, | 3160 | .ndo_fix_features = cxgb_fix_features, |
3161 | .ndo_set_features = cxgb_set_features, | ||
3135 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3162 | #ifdef CONFIG_NET_POLL_CONTROLLER |
3136 | .ndo_poll_controller = cxgb_netpoll, | 3163 | .ndo_poll_controller = cxgb_netpoll, |
3137 | #endif | 3164 | #endif |
@@ -3263,9 +3290,8 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
3263 | netdev->mem_start = mmio_start; | 3290 | netdev->mem_start = mmio_start; |
3264 | netdev->mem_end = mmio_start + mmio_len - 1; | 3291 | netdev->mem_end = mmio_start + mmio_len - 1; |
3265 | netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | | 3292 | netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | |
3266 | NETIF_F_TSO | NETIF_F_RXCSUM; | 3293 | NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_RX; |
3267 | netdev->features |= netdev->hw_features | | 3294 | netdev->features |= netdev->hw_features | NETIF_F_HW_VLAN_TX; |
3268 | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | ||
3269 | if (pci_using_dac) | 3295 | if (pci_using_dac) |
3270 | netdev->features |= NETIF_F_HIGHDMA; | 3296 | netdev->features |= NETIF_F_HIGHDMA; |
3271 | 3297 | ||
@@ -3329,6 +3355,9 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
3329 | err = sysfs_create_group(&adapter->port[0]->dev.kobj, | 3355 | err = sysfs_create_group(&adapter->port[0]->dev.kobj, |
3330 | &cxgb3_attr_group); | 3356 | &cxgb3_attr_group); |
3331 | 3357 | ||
3358 | for_each_port(adapter, i) | ||
3359 | cxgb_vlan_mode(adapter->port[i], adapter->port[i]->features); | ||
3360 | |||
3332 | print_port_info(adapter, ai); | 3361 | print_port_info(adapter, ai); |
3333 | return 0; | 3362 | return 0; |
3334 | 3363 | ||
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index fa1b450af82..32636a1d62a 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c | |||
@@ -176,16 +176,13 @@ static struct net_device *get_iff_from_mac(struct adapter *adapter, | |||
176 | int i; | 176 | int i; |
177 | 177 | ||
178 | for_each_port(adapter, i) { | 178 | for_each_port(adapter, i) { |
179 | struct vlan_group *grp; | ||
180 | struct net_device *dev = adapter->port[i]; | 179 | struct net_device *dev = adapter->port[i]; |
181 | const struct port_info *p = netdev_priv(dev); | ||
182 | 180 | ||
183 | if (!memcmp(dev->dev_addr, mac, ETH_ALEN)) { | 181 | if (!memcmp(dev->dev_addr, mac, ETH_ALEN)) { |
184 | if (vlan && vlan != VLAN_VID_MASK) { | 182 | if (vlan && vlan != VLAN_VID_MASK) { |
185 | grp = p->vlan_grp; | 183 | rcu_read_lock(); |
186 | dev = NULL; | 184 | dev = __vlan_find_dev_deep(dev, vlan); |
187 | if (grp) | 185 | rcu_read_unlock(); |
188 | dev = vlan_group_get_device(grp, vlan); | ||
189 | } else if (netif_is_bond_slave(dev)) { | 186 | } else if (netif_is_bond_slave(dev)) { |
190 | while (dev->master) | 187 | while (dev->master) |
191 | dev = dev->master; | 188 | dev = dev->master; |
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 76bf5892b96..d6fa1777a34 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c | |||
@@ -2028,28 +2028,11 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq, | |||
2028 | skb_checksum_none_assert(skb); | 2028 | skb_checksum_none_assert(skb); |
2029 | skb_record_rx_queue(skb, qs - &adap->sge.qs[pi->first_qset]); | 2029 | skb_record_rx_queue(skb, qs - &adap->sge.qs[pi->first_qset]); |
2030 | 2030 | ||
2031 | if (unlikely(p->vlan_valid)) { | 2031 | if (p->vlan_valid) { |
2032 | struct vlan_group *grp = pi->vlan_grp; | ||
2033 | |||
2034 | qs->port_stats[SGE_PSTAT_VLANEX]++; | 2032 | qs->port_stats[SGE_PSTAT_VLANEX]++; |
2035 | if (likely(grp)) | 2033 | __vlan_hwaccel_put_tag(skb, ntohs(p->vlan)); |
2036 | if (lro) | 2034 | } |
2037 | vlan_gro_receive(&qs->napi, grp, | 2035 | if (rq->polling) { |
2038 | ntohs(p->vlan), skb); | ||
2039 | else { | ||
2040 | if (unlikely(pi->iscsic.flags)) { | ||
2041 | unsigned short vtag = ntohs(p->vlan) & | ||
2042 | VLAN_VID_MASK; | ||
2043 | skb->dev = vlan_group_get_device(grp, | ||
2044 | vtag); | ||
2045 | cxgb3_process_iscsi_prov_pack(pi, skb); | ||
2046 | } | ||
2047 | __vlan_hwaccel_rx(skb, grp, ntohs(p->vlan), | ||
2048 | rq->polling); | ||
2049 | } | ||
2050 | else | ||
2051 | dev_kfree_skb_any(skb); | ||
2052 | } else if (rq->polling) { | ||
2053 | if (lro) | 2036 | if (lro) |
2054 | napi_gro_receive(&qs->napi, skb); | 2037 | napi_gro_receive(&qs->napi, skb); |
2055 | else { | 2038 | else { |
@@ -2147,14 +2130,8 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, | |||
2147 | 2130 | ||
2148 | skb_record_rx_queue(skb, qs - &adap->sge.qs[pi->first_qset]); | 2131 | skb_record_rx_queue(skb, qs - &adap->sge.qs[pi->first_qset]); |
2149 | 2132 | ||
2150 | if (unlikely(cpl->vlan_valid)) { | 2133 | if (cpl->vlan_valid) |
2151 | struct vlan_group *grp = pi->vlan_grp; | 2134 | __vlan_hwaccel_put_tag(skb, ntohs(cpl->vlan)); |
2152 | |||
2153 | if (likely(grp != NULL)) { | ||
2154 | vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan)); | ||
2155 | return; | ||
2156 | } | ||
2157 | } | ||
2158 | napi_gro_frags(&qs->napi); | 2135 | napi_gro_frags(&qs->napi); |
2159 | } | 2136 | } |
2160 | 2137 | ||