aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c99
1 files changed, 70 insertions, 29 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 172f7561643a..3216aa5e705e 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -1239,8 +1239,11 @@ struct i40e_mac_filter *i40e_put_mac_in_vlan(struct i40e_vsi *vsi, u8 *macaddr,
1239 * i40e_rm_default_mac_filter - Remove the default MAC filter set by NVM 1239 * i40e_rm_default_mac_filter - Remove the default MAC filter set by NVM
1240 * @vsi: the PF Main VSI - inappropriate for any other VSI 1240 * @vsi: the PF Main VSI - inappropriate for any other VSI
1241 * @macaddr: the MAC address 1241 * @macaddr: the MAC address
1242 *
1243 * Some older firmware configurations set up a default promiscuous VLAN
1244 * filter that needs to be removed.
1242 **/ 1245 **/
1243static void i40e_rm_default_mac_filter(struct i40e_vsi *vsi, u8 *macaddr) 1246static int i40e_rm_default_mac_filter(struct i40e_vsi *vsi, u8 *macaddr)
1244{ 1247{
1245 struct i40e_aqc_remove_macvlan_element_data element; 1248 struct i40e_aqc_remove_macvlan_element_data element;
1246 struct i40e_pf *pf = vsi->back; 1249 struct i40e_pf *pf = vsi->back;
@@ -1248,15 +1251,18 @@ static void i40e_rm_default_mac_filter(struct i40e_vsi *vsi, u8 *macaddr)
1248 1251
1249 /* Only appropriate for the PF main VSI */ 1252 /* Only appropriate for the PF main VSI */
1250 if (vsi->type != I40E_VSI_MAIN) 1253 if (vsi->type != I40E_VSI_MAIN)
1251 return; 1254 return -EINVAL;
1252 1255
1256 memset(&element, 0, sizeof(element));
1253 ether_addr_copy(element.mac_addr, macaddr); 1257 ether_addr_copy(element.mac_addr, macaddr);
1254 element.vlan_tag = 0; 1258 element.vlan_tag = 0;
1255 element.flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH | 1259 element.flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH |
1256 I40E_AQC_MACVLAN_DEL_IGNORE_VLAN; 1260 I40E_AQC_MACVLAN_DEL_IGNORE_VLAN;
1257 aq_ret = i40e_aq_remove_macvlan(&pf->hw, vsi->seid, &element, 1, NULL); 1261 aq_ret = i40e_aq_remove_macvlan(&pf->hw, vsi->seid, &element, 1, NULL);
1258 if (aq_ret) 1262 if (aq_ret)
1259 dev_err(&pf->pdev->dev, "Could not remove default MAC-VLAN\n"); 1263 return -ENOENT;
1264
1265 return 0;
1260} 1266}
1261 1267
1262/** 1268/**
@@ -1385,18 +1391,30 @@ static int i40e_set_mac(struct net_device *netdev, void *p)
1385{ 1391{
1386 struct i40e_netdev_priv *np = netdev_priv(netdev); 1392 struct i40e_netdev_priv *np = netdev_priv(netdev);
1387 struct i40e_vsi *vsi = np->vsi; 1393 struct i40e_vsi *vsi = np->vsi;
1394 struct i40e_pf *pf = vsi->back;
1395 struct i40e_hw *hw = &pf->hw;
1388 struct sockaddr *addr = p; 1396 struct sockaddr *addr = p;
1389 struct i40e_mac_filter *f; 1397 struct i40e_mac_filter *f;
1390 1398
1391 if (!is_valid_ether_addr(addr->sa_data)) 1399 if (!is_valid_ether_addr(addr->sa_data))
1392 return -EADDRNOTAVAIL; 1400 return -EADDRNOTAVAIL;
1393 1401
1394 netdev_info(netdev, "set mac address=%pM\n", addr->sa_data); 1402 if (ether_addr_equal(netdev->dev_addr, addr->sa_data)) {
1403 netdev_info(netdev, "already using mac address %pM\n",
1404 addr->sa_data);
1405 return 0;
1406 }
1395 1407
1396 if (test_bit(__I40E_DOWN, &vsi->back->state) || 1408 if (test_bit(__I40E_DOWN, &vsi->back->state) ||
1397 test_bit(__I40E_RESET_RECOVERY_PENDING, &vsi->back->state)) 1409 test_bit(__I40E_RESET_RECOVERY_PENDING, &vsi->back->state))
1398 return -EADDRNOTAVAIL; 1410 return -EADDRNOTAVAIL;
1399 1411
1412 if (ether_addr_equal(hw->mac.addr, addr->sa_data))
1413 netdev_info(netdev, "returning to hw mac address %pM\n",
1414 hw->mac.addr);
1415 else
1416 netdev_info(netdev, "set new mac address %pM\n", addr->sa_data);
1417
1400 if (vsi->type == I40E_VSI_MAIN) { 1418 if (vsi->type == I40E_VSI_MAIN) {
1401 i40e_status ret; 1419 i40e_status ret;
1402 ret = i40e_aq_mac_address_write(&vsi->back->hw, 1420 ret = i40e_aq_mac_address_write(&vsi->back->hw,
@@ -1410,25 +1428,34 @@ static int i40e_set_mac(struct net_device *netdev, void *p)
1410 } 1428 }
1411 } 1429 }
1412 1430
1413 f = i40e_find_mac(vsi, addr->sa_data, false, true); 1431 if (ether_addr_equal(netdev->dev_addr, hw->mac.addr)) {
1414 if (!f) { 1432 struct i40e_aqc_remove_macvlan_element_data element;
1415 /* In order to be sure to not drop any packets, add the
1416 * new address first then delete the old one.
1417 */
1418 f = i40e_add_filter(vsi, addr->sa_data, I40E_VLAN_ANY,
1419 false, false);
1420 if (!f)
1421 return -ENOMEM;
1422 1433
1423 i40e_sync_vsi_filters(vsi); 1434 memset(&element, 0, sizeof(element));
1435 ether_addr_copy(element.mac_addr, netdev->dev_addr);
1436 element.flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH;
1437 i40e_aq_remove_macvlan(&pf->hw, vsi->seid, &element, 1, NULL);
1438 } else {
1424 i40e_del_filter(vsi, netdev->dev_addr, I40E_VLAN_ANY, 1439 i40e_del_filter(vsi, netdev->dev_addr, I40E_VLAN_ANY,
1425 false, false); 1440 false, false);
1426 i40e_sync_vsi_filters(vsi);
1427 } 1441 }
1428 1442
1429 f->is_laa = true; 1443 if (ether_addr_equal(addr->sa_data, hw->mac.addr)) {
1430 if (!ether_addr_equal(netdev->dev_addr, addr->sa_data)) 1444 struct i40e_aqc_add_macvlan_element_data element;
1431 ether_addr_copy(netdev->dev_addr, addr->sa_data); 1445
1446 memset(&element, 0, sizeof(element));
1447 ether_addr_copy(element.mac_addr, hw->mac.addr);
1448 element.flags = cpu_to_le16(I40E_AQC_MACVLAN_ADD_PERFECT_MATCH);
1449 i40e_aq_add_macvlan(&pf->hw, vsi->seid, &element, 1, NULL);
1450 } else {
1451 f = i40e_add_filter(vsi, addr->sa_data, I40E_VLAN_ANY,
1452 false, false);
1453 if (f)
1454 f->is_laa = true;
1455 }
1456
1457 i40e_sync_vsi_filters(vsi);
1458 ether_addr_copy(netdev->dev_addr, addr->sa_data);
1432 1459
1433 return 0; 1460 return 0;
1434} 1461}
@@ -1796,9 +1823,8 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
1796 kfree(add_list); 1823 kfree(add_list);
1797 add_list = NULL; 1824 add_list = NULL;
1798 1825
1799 if (add_happened && (!aq_ret)) { 1826 if (add_happened && aq_ret &&
1800 /* do nothing */; 1827 pf->hw.aq.asq_last_status != I40E_AQ_RC_EINVAL) {
1801 } else if (add_happened && (aq_ret)) {
1802 dev_info(&pf->pdev->dev, 1828 dev_info(&pf->pdev->dev,
1803 "add filter failed, err %d, aq_err %d\n", 1829 "add filter failed, err %d, aq_err %d\n",
1804 aq_ret, pf->hw.aq.asq_last_status); 1830 aq_ret, pf->hw.aq.asq_last_status);
@@ -7512,14 +7538,14 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
7512 if (vsi->type == I40E_VSI_MAIN) { 7538 if (vsi->type == I40E_VSI_MAIN) {
7513 SET_NETDEV_DEV(netdev, &pf->pdev->dev); 7539 SET_NETDEV_DEV(netdev, &pf->pdev->dev);
7514 ether_addr_copy(mac_addr, hw->mac.perm_addr); 7540 ether_addr_copy(mac_addr, hw->mac.perm_addr);
7515 /* The following two steps are necessary to prevent reception 7541 /* The following steps are necessary to prevent reception
7516 * of tagged packets - by default the NVM loads a MAC-VLAN 7542 * of tagged packets - some older NVM configurations load a
7517 * filter that will accept any tagged packet. This is to 7543 * default a MAC-VLAN filter that accepts any tagged packet
7518 * prevent that during normal operations until a specific 7544 * which must be replaced by a normal filter.
7519 * VLAN tag filter has been set.
7520 */ 7545 */
7521 i40e_rm_default_mac_filter(vsi, mac_addr); 7546 if (!i40e_rm_default_mac_filter(vsi, mac_addr))
7522 i40e_add_filter(vsi, mac_addr, I40E_VLAN_ANY, false, true); 7547 i40e_add_filter(vsi, mac_addr,
7548 I40E_VLAN_ANY, false, true);
7523 } else { 7549 } else {
7524 /* relate the VSI_VMDQ name to the VSI_MAIN name */ 7550 /* relate the VSI_VMDQ name to the VSI_MAIN name */
7525 snprintf(netdev->name, IFNAMSIZ, "%sv%%d", 7551 snprintf(netdev->name, IFNAMSIZ, "%sv%%d",
@@ -7735,7 +7761,22 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
7735 f_count++; 7761 f_count++;
7736 7762
7737 if (f->is_laa && vsi->type == I40E_VSI_MAIN) { 7763 if (f->is_laa && vsi->type == I40E_VSI_MAIN) {
7738 i40e_aq_mac_address_write(&vsi->back->hw, 7764 struct i40e_aqc_remove_macvlan_element_data element;
7765
7766 memset(&element, 0, sizeof(element));
7767 ether_addr_copy(element.mac_addr, f->macaddr);
7768 element.flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH;
7769 ret = i40e_aq_remove_macvlan(hw, vsi->seid,
7770 &element, 1, NULL);
7771 if (ret) {
7772 /* some older FW has a different default */
7773 element.flags |=
7774 I40E_AQC_MACVLAN_DEL_IGNORE_VLAN;
7775 i40e_aq_remove_macvlan(hw, vsi->seid,
7776 &element, 1, NULL);
7777 }
7778
7779 i40e_aq_mac_address_write(hw,
7739 I40E_AQC_WRITE_TYPE_LAA_WOL, 7780 I40E_AQC_WRITE_TYPE_LAA_WOL,
7740 f->macaddr, NULL); 7781 f->macaddr, NULL);
7741 } 7782 }