aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShannon Nelson <shannon.nelson@intel.com>2014-07-29 00:01:50 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-08-27 03:51:38 -0400
commit30650cc552cf9a60fa80a205693c6f76f7a00549 (patch)
tree624698d4e138c16f8088a24ca1b500d27ba99e30
parentf905dd62be8853644357044a455f83e63e8c68ef (diff)
i40e: quiet complaints when removing default MAC VLAN filter and make set_mac reversible
Older firmware has an incorrect MAC VLAN filter that needs to be replaced at startup, and now newer firmware doesn't have this problem. With this change we no longer complain if the remove fails, and we only add the new filter if the remove succeeded. Setting a new LAA worked the first time, but didn't work well in successive operations, including returning to the HW default address. This simplifies the code that was trying to be too smart. Lastly, this pulls the hardware default mac address out into separate handling code and keeps the broadcast filtering from getting munged. Change-ID: I1f54b002def04ffef2546febb9a4044385452f85 Signed-off-by: Shannon Nelson <shannon.nelson@intel.com> Tested-by: Jim Young <jamesx.m.young@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-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 }