X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fnet%2Fcxgb3%2Fcxgb3_main.c;fp=drivers%2Fnet%2Fcxgb3%2Fcxgb3_main.c;h=93b41a7ac175cc49f76c147b3f0a1d953e50b9bd;hb=892ef5d85259e193505d553c10237fd5dc9a3d0d;hp=9081ce037149ce77cd231d8e77021cec641a3c52;hpb=dc437974af52e78f2736543dfee94cc385dae6e9;p=pandora-kernel.git diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 9081ce037149..93b41a7ac175 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) } } -static void vlan_rx_register(struct net_device *dev, struct vlan_group *grp) +static void cxgb_vlan_mode(struct net_device *dev, u32 features) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; - pi->vlan_grp = grp; - if (adapter->params.rev > 0) - t3_set_vlan_accel(adapter, 1 << pi->port_id, grp != NULL); - else { + if (adapter->params.rev > 0) { + t3_set_vlan_accel(adapter, 1 << pi->port_id, + features & NETIF_F_HW_VLAN_RX); + } else { /* single control for all ports */ - unsigned int i, have_vlans = 0; + unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX; + for_each_port(adapter, i) - have_vlans |= adap2pinfo(adapter, i)->vlan_grp != NULL; + have_vlans |= + adapter->port[i]->features & NETIF_F_HW_VLAN_RX; t3_set_vlan_accel(adapter, 1, have_vlans); } t3_synchronize_rx(adapter, pi); } +static u32 cxgb_fix_features(struct net_device *dev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + +static int cxgb_set_features(struct net_device *dev, u32 features) +{ + u32 changed = dev->features ^ features; + + if (changed & NETIF_F_HW_VLAN_RX) + cxgb_vlan_mode(dev, features); + + return 0; +} + #ifdef CONFIG_NET_POLL_CONTROLLER static void cxgb_netpoll(struct net_device *dev) { @@ -3131,7 +3157,8 @@ static const struct net_device_ops cxgb_netdev_ops = { .ndo_do_ioctl = cxgb_ioctl, .ndo_change_mtu = cxgb_change_mtu, .ndo_set_mac_address = cxgb_set_mac_addr, - .ndo_vlan_rx_register = vlan_rx_register, + .ndo_fix_features = cxgb_fix_features, + .ndo_set_features = cxgb_set_features, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = cxgb_netpoll, #endif @@ -3263,9 +3290,8 @@ static int __devinit init_one(struct pci_dev *pdev, netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len - 1; netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_TSO | NETIF_F_RXCSUM; - netdev->features |= netdev->hw_features | - NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_RX; + netdev->features |= netdev->hw_features | NETIF_F_HW_VLAN_TX; if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; @@ -3329,6 +3355,9 @@ static int __devinit init_one(struct pci_dev *pdev, err = sysfs_create_group(&adapter->port[0]->dev.kobj, &cxgb3_attr_group); + for_each_port(adapter, i) + cxgb_vlan_mode(adapter->port[i], adapter->port[i]->features); + print_port_info(adapter, ai); return 0;