|
@@ -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;
|
|
|
|