diff options
Diffstat (limited to 'drivers/net/cxgb3/cxgb3_main.c')
| -rw-r--r-- | drivers/net/cxgb3/cxgb3_main.c | 51 | 
1 files changed, 40 insertions, 11 deletions
| 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; | 
