aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe
diff options
context:
space:
mode:
authorEmil Tantilov <emil.s.tantilov@intel.com>2011-02-18 03:58:27 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-03-03 06:25:37 -0500
commit80960ab040dd6b3a82bfb2db9b1aaf5d6ccffbb7 (patch)
tree9df969d6a9db5681084651b5f81e1f3d6f1bfc75 /drivers/net/ixgbe
parentb60c5dd31b053d008110a80aa4089d64cee60e8f (diff)
ixgbe: rework ixgbe MTA handling to not drop packets
This change modifies the ixgbe drivers so that it will not drop the multicast filters while updating them. Instead it uses an intermediate table to store the filter and then writes that filter to the hardware. Based on original patch from Dave Boutcher <daveboutcher@gmail.com> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com> Reported-by: Dave Boutcher <daveboutcher@gmail.com> Tested-by: Stephen Ko <stephen.s.ko@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ixgbe')
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c68
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h3
2 files changed, 11 insertions, 60 deletions
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 882a35092024..b94634f41689 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -46,8 +46,6 @@ static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
46static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); 46static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
47static void ixgbe_release_eeprom(struct ixgbe_hw *hw); 47static void ixgbe_release_eeprom(struct ixgbe_hw *hw);
48 48
49static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index);
50static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index);
51static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); 49static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
52static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); 50static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
53static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num); 51static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
@@ -1310,38 +1308,6 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)
1310} 1308}
1311 1309
1312/** 1310/**
1313 * ixgbe_enable_rar - Enable Rx address register
1314 * @hw: pointer to hardware structure
1315 * @index: index into the RAR table
1316 *
1317 * Enables the select receive address register.
1318 **/
1319static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index)
1320{
1321 u32 rar_high;
1322
1323 rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
1324 rar_high |= IXGBE_RAH_AV;
1325 IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
1326}
1327
1328/**
1329 * ixgbe_disable_rar - Disable Rx address register
1330 * @hw: pointer to hardware structure
1331 * @index: index into the RAR table
1332 *
1333 * Disables the select receive address register.
1334 **/
1335static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index)
1336{
1337 u32 rar_high;
1338
1339 rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
1340 rar_high &= (~IXGBE_RAH_AV);
1341 IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
1342}
1343
1344/**
1345 * ixgbe_init_rx_addrs_generic - Initializes receive address filters. 1311 * ixgbe_init_rx_addrs_generic - Initializes receive address filters.
1346 * @hw: pointer to hardware structure 1312 * @hw: pointer to hardware structure
1347 * 1313 *
@@ -1387,7 +1353,6 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
1387 } 1353 }
1388 1354
1389 /* Clear the MTA */ 1355 /* Clear the MTA */
1390 hw->addr_ctrl.mc_addr_in_rar_count = 0;
1391 hw->addr_ctrl.mta_in_use = 0; 1356 hw->addr_ctrl.mta_in_use = 0;
1392 IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); 1357 IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
1393 1358
@@ -1421,8 +1386,7 @@ static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
1421 * else put the controller into promiscuous mode 1386 * else put the controller into promiscuous mode
1422 */ 1387 */
1423 if (hw->addr_ctrl.rar_used_count < rar_entries) { 1388 if (hw->addr_ctrl.rar_used_count < rar_entries) {
1424 rar = hw->addr_ctrl.rar_used_count - 1389 rar = hw->addr_ctrl.rar_used_count;
1425 hw->addr_ctrl.mc_addr_in_rar_count;
1426 hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); 1390 hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
1427 hw_dbg(hw, "Added a secondary address to RAR[%d]\n", rar); 1391 hw_dbg(hw, "Added a secondary address to RAR[%d]\n", rar);
1428 hw->addr_ctrl.rar_used_count++; 1392 hw->addr_ctrl.rar_used_count++;
@@ -1551,7 +1515,6 @@ static void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
1551 u32 vector; 1515 u32 vector;
1552 u32 vector_bit; 1516 u32 vector_bit;
1553 u32 vector_reg; 1517 u32 vector_reg;
1554 u32 mta_reg;
1555 1518
1556 hw->addr_ctrl.mta_in_use++; 1519 hw->addr_ctrl.mta_in_use++;
1557 1520
@@ -1569,9 +1532,7 @@ static void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
1569 */ 1532 */
1570 vector_reg = (vector >> 5) & 0x7F; 1533 vector_reg = (vector >> 5) & 0x7F;
1571 vector_bit = vector & 0x1F; 1534 vector_bit = vector & 0x1F;
1572 mta_reg = IXGBE_READ_REG(hw, IXGBE_MTA(vector_reg)); 1535 hw->mac.mta_shadow[vector_reg] |= (1 << vector_bit);
1573 mta_reg |= (1 << vector_bit);
1574 IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
1575} 1536}
1576 1537
1577/** 1538/**
@@ -1597,18 +1558,21 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw,
1597 hw->addr_ctrl.num_mc_addrs = netdev_mc_count(netdev); 1558 hw->addr_ctrl.num_mc_addrs = netdev_mc_count(netdev);
1598 hw->addr_ctrl.mta_in_use = 0; 1559 hw->addr_ctrl.mta_in_use = 0;
1599 1560
1600 /* Clear the MTA */ 1561 /* Clear mta_shadow */
1601 hw_dbg(hw, " Clearing MTA\n"); 1562 hw_dbg(hw, " Clearing MTA\n");
1602 for (i = 0; i < hw->mac.mcft_size; i++) 1563 memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
1603 IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0);
1604 1564
1605 /* Add the new addresses */ 1565 /* Update mta shadow */
1606 netdev_for_each_mc_addr(ha, netdev) { 1566 netdev_for_each_mc_addr(ha, netdev) {
1607 hw_dbg(hw, " Adding the multicast addresses:\n"); 1567 hw_dbg(hw, " Adding the multicast addresses:\n");
1608 ixgbe_set_mta(hw, ha->addr); 1568 ixgbe_set_mta(hw, ha->addr);
1609 } 1569 }
1610 1570
1611 /* Enable mta */ 1571 /* Enable mta */
1572 for (i = 0; i < hw->mac.mcft_size; i++)
1573 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_MTA(0), i,
1574 hw->mac.mta_shadow[i]);
1575
1612 if (hw->addr_ctrl.mta_in_use > 0) 1576 if (hw->addr_ctrl.mta_in_use > 0)
1613 IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, 1577 IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL,
1614 IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type); 1578 IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type);
@@ -1625,15 +1589,8 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw,
1625 **/ 1589 **/
1626s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw) 1590s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
1627{ 1591{
1628 u32 i;
1629 u32 rar_entries = hw->mac.num_rar_entries;
1630 struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; 1592 struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
1631 1593
1632 if (a->mc_addr_in_rar_count > 0)
1633 for (i = (rar_entries - a->mc_addr_in_rar_count);
1634 i < rar_entries; i++)
1635 ixgbe_enable_rar(hw, i);
1636
1637 if (a->mta_in_use > 0) 1594 if (a->mta_in_use > 0)
1638 IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE | 1595 IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE |
1639 hw->mac.mc_filter_type); 1596 hw->mac.mc_filter_type);
@@ -1649,15 +1606,8 @@ s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
1649 **/ 1606 **/
1650s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw) 1607s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
1651{ 1608{
1652 u32 i;
1653 u32 rar_entries = hw->mac.num_rar_entries;
1654 struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; 1609 struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
1655 1610
1656 if (a->mc_addr_in_rar_count > 0)
1657 for (i = (rar_entries - a->mc_addr_in_rar_count);
1658 i < rar_entries; i++)
1659 ixgbe_disable_rar(hw, i);
1660
1661 if (a->mta_in_use > 0) 1611 if (a->mta_in_use > 0)
1662 IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); 1612 IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
1663 1613
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index b1ae185ae516..f6d0d4d98dd4 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -2358,7 +2358,6 @@ enum ixgbe_bus_width {
2358struct ixgbe_addr_filter_info { 2358struct ixgbe_addr_filter_info {
2359 u32 num_mc_addrs; 2359 u32 num_mc_addrs;
2360 u32 rar_used_count; 2360 u32 rar_used_count;
2361 u32 mc_addr_in_rar_count;
2362 u32 mta_in_use; 2361 u32 mta_in_use;
2363 u32 overflow_promisc; 2362 u32 overflow_promisc;
2364 bool uc_set_promisc; 2363 bool uc_set_promisc;
@@ -2570,6 +2569,8 @@ struct ixgbe_mac_info {
2570 u16 wwnn_prefix; 2569 u16 wwnn_prefix;
2571 /* prefix for World Wide Port Name (WWPN) */ 2570 /* prefix for World Wide Port Name (WWPN) */
2572 u16 wwpn_prefix; 2571 u16 wwpn_prefix;
2572#define IXGBE_MAX_MTA 128
2573 u32 mta_shadow[IXGBE_MAX_MTA];
2573 s32 mc_filter_type; 2574 s32 mc_filter_type;
2574 u32 mcft_size; 2575 u32 mcft_size;
2575 u32 vft_size; 2576 u32 vft_size;