diff options
Diffstat (limited to 'drivers/net/ethernet/emulex/benet/be_main.c')
| -rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 34 | 
1 files changed, 22 insertions, 12 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 7e1633bf5a22..1a7f8ad7b9c6 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -275,8 +275,7 @@ static int be_dev_mac_add(struct be_adapter *adapter, u8 *mac)  	/* Check if mac has already been added as part of uc-list */  	for (i = 0; i < adapter->uc_macs; i++) { -		if (ether_addr_equal((u8 *)&adapter->uc_list[i * ETH_ALEN], -				     mac)) { +		if (ether_addr_equal(adapter->uc_list[i].mac, mac)) {  			/* mac already added, skip addition */  			adapter->pmac_id[0] = adapter->pmac_id[i + 1];  			return 0; @@ -319,6 +318,13 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)  	if (ether_addr_equal(addr->sa_data, adapter->dev_mac))  		return 0; +	/* BE3 VFs without FILTMGMT privilege are not allowed to set its MAC +	 * address +	 */ +	if (BEx_chip(adapter) && be_virtfn(adapter) && +	    !check_privilege(adapter, BE_PRIV_FILTMGMT)) +		return -EPERM; +  	/* if device is not running, copy MAC to netdev->dev_addr */  	if (!netif_running(netdev))  		goto done; @@ -1655,14 +1661,12 @@ static void be_clear_mc_list(struct be_adapter *adapter)  static int be_uc_mac_add(struct be_adapter *adapter, int uc_idx)  { -	if (ether_addr_equal((u8 *)&adapter->uc_list[uc_idx * ETH_ALEN], -			     adapter->dev_mac)) { +	if (ether_addr_equal(adapter->uc_list[uc_idx].mac, adapter->dev_mac)) {  		adapter->pmac_id[uc_idx + 1] = adapter->pmac_id[0];  		return 0;  	} -	return be_cmd_pmac_add(adapter, -			       (u8 *)&adapter->uc_list[uc_idx * ETH_ALEN], +	return be_cmd_pmac_add(adapter, adapter->uc_list[uc_idx].mac,  			       adapter->if_handle,  			       &adapter->pmac_id[uc_idx + 1], 0);  } @@ -1698,9 +1702,8 @@ static void be_set_uc_list(struct be_adapter *adapter)  	}  	if (adapter->update_uc_list) { -		i = 1; /* First slot is claimed by the Primary MAC */ -  		/* cache the uc-list in adapter array */ +		i = 0;  		netdev_for_each_uc_addr(ha, netdev) {  			ether_addr_copy(adapter->uc_list[i].mac, ha->addr);  			i++; @@ -3613,7 +3616,11 @@ static void be_rx_qs_destroy(struct be_adapter *adapter)  static void be_disable_if_filters(struct be_adapter *adapter)  { -	be_dev_mac_del(adapter, adapter->pmac_id[0]); +	/* Don't delete MAC on BE3 VFs without FILTMGMT privilege  */ +	if (!BEx_chip(adapter) || !be_virtfn(adapter) || +	    check_privilege(adapter, BE_PRIV_FILTMGMT)) +		be_dev_mac_del(adapter, adapter->pmac_id[0]); +  	be_clear_uc_list(adapter);  	be_clear_mc_list(adapter); @@ -3766,8 +3773,9 @@ static int be_enable_if_filters(struct be_adapter *adapter)  	if (status)  		return status; -	/* For BE3 VFs, the PF programs the initial MAC address */ -	if (!(BEx_chip(adapter) && be_virtfn(adapter))) { +	/* Don't add MAC on BE3 VFs without FILTMGMT privilege */ +	if (!BEx_chip(adapter) || !be_virtfn(adapter) || +	    check_privilege(adapter, BE_PRIV_FILTMGMT)) {  		status = be_dev_mac_add(adapter, adapter->netdev->dev_addr);  		if (status)  			return status; @@ -5155,7 +5163,9 @@ static netdev_features_t be_features_check(struct sk_buff *skb,  	    skb->inner_protocol_type != ENCAP_TYPE_ETHER ||  	    skb->inner_protocol != htons(ETH_P_TEB) ||  	    skb_inner_mac_header(skb) - skb_transport_header(skb) != -	    sizeof(struct udphdr) + sizeof(struct vxlanhdr)) +		sizeof(struct udphdr) + sizeof(struct vxlanhdr) || +	    !adapter->vxlan_port || +	    udp_hdr(skb)->dest != adapter->vxlan_port)  		return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);  	return features;  | 
