aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
diff options
context:
space:
mode:
authorJacob Keller <jacob.e.keller@intel.com>2014-03-29 02:51:25 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-04-23 03:09:48 -0400
commit5d7daa35b9eb14b64acd208a900e44aeeee25eca (patch)
tree37685028dc69160e98000fee749417d4fae09fd6 /drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
parentb335e75bab9e578764fc7dd581b61075bfd8c655 (diff)
ixgbe: improve mac filter handling
Add mac_table API based on work done for igb, which includes functions to add and delete mac filters. This simplifies code for various entities that use MAC filters such as VMDQ, SR-IOV, MACVLAN, and such. Reported-by: Mitch Williams <mitch.a.williams@intel.com> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_main.c')
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c188
1 files changed, 148 insertions, 40 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 84044ed1914d..39a1c07258b0 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3868,13 +3868,135 @@ static int ixgbe_write_mc_addr_list(struct net_device *netdev)
3868 return -ENOMEM; 3868 return -ENOMEM;
3869 3869
3870#ifdef CONFIG_PCI_IOV 3870#ifdef CONFIG_PCI_IOV
3871 if (adapter->num_vfs) 3871 ixgbe_restore_vf_multicasts(adapter);
3872 ixgbe_restore_vf_multicasts(adapter);
3873#endif 3872#endif
3874 3873
3875 return netdev_mc_count(netdev); 3874 return netdev_mc_count(netdev);
3876} 3875}
3877 3876
3877#ifdef CONFIG_PCI_IOV
3878void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter)
3879{
3880 struct ixgbe_hw *hw = &adapter->hw;
3881 int i;
3882 for (i = 0; i < hw->mac.num_rar_entries; i++) {
3883 if (adapter->mac_table[i].state & IXGBE_MAC_STATE_IN_USE)
3884 hw->mac.ops.set_rar(hw, i, adapter->mac_table[i].addr,
3885 adapter->mac_table[i].queue,
3886 IXGBE_RAH_AV);
3887 else
3888 hw->mac.ops.clear_rar(hw, i);
3889
3890 adapter->mac_table[i].state &= ~(IXGBE_MAC_STATE_MODIFIED);
3891 }
3892}
3893#endif
3894
3895static void ixgbe_sync_mac_table(struct ixgbe_adapter *adapter)
3896{
3897 struct ixgbe_hw *hw = &adapter->hw;
3898 int i;
3899 for (i = 0; i < hw->mac.num_rar_entries; i++) {
3900 if (adapter->mac_table[i].state & IXGBE_MAC_STATE_MODIFIED) {
3901 if (adapter->mac_table[i].state &
3902 IXGBE_MAC_STATE_IN_USE)
3903 hw->mac.ops.set_rar(hw, i,
3904 adapter->mac_table[i].addr,
3905 adapter->mac_table[i].queue,
3906 IXGBE_RAH_AV);
3907 else
3908 hw->mac.ops.clear_rar(hw, i);
3909
3910 adapter->mac_table[i].state &=
3911 ~(IXGBE_MAC_STATE_MODIFIED);
3912 }
3913 }
3914}
3915
3916static void ixgbe_flush_sw_mac_table(struct ixgbe_adapter *adapter)
3917{
3918 int i;
3919 struct ixgbe_hw *hw = &adapter->hw;
3920
3921 for (i = 0; i < hw->mac.num_rar_entries; i++) {
3922 adapter->mac_table[i].state |= IXGBE_MAC_STATE_MODIFIED;
3923 adapter->mac_table[i].state &= ~IXGBE_MAC_STATE_IN_USE;
3924 memset(adapter->mac_table[i].addr, 0, ETH_ALEN);
3925 adapter->mac_table[i].queue = 0;
3926 }
3927 ixgbe_sync_mac_table(adapter);
3928}
3929
3930static int ixgbe_available_rars(struct ixgbe_adapter *adapter)
3931{
3932 struct ixgbe_hw *hw = &adapter->hw;
3933 int i, count = 0;
3934
3935 for (i = 0; i < hw->mac.num_rar_entries; i++) {
3936 if (adapter->mac_table[i].state == 0)
3937 count++;
3938 }
3939 return count;
3940}
3941
3942/* this function destroys the first RAR entry */
3943static void ixgbe_mac_set_default_filter(struct ixgbe_adapter *adapter,
3944 u8 *addr)
3945{
3946 struct ixgbe_hw *hw = &adapter->hw;
3947
3948 memcpy(&adapter->mac_table[0].addr, addr, ETH_ALEN);
3949 adapter->mac_table[0].queue = VMDQ_P(0);
3950 adapter->mac_table[0].state = (IXGBE_MAC_STATE_DEFAULT |
3951 IXGBE_MAC_STATE_IN_USE);
3952 hw->mac.ops.set_rar(hw, 0, adapter->mac_table[0].addr,
3953 adapter->mac_table[0].queue,
3954 IXGBE_RAH_AV);
3955}
3956
3957int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter, u8 *addr, u16 queue)
3958{
3959 struct ixgbe_hw *hw = &adapter->hw;
3960 int i;
3961
3962 if (is_zero_ether_addr(addr))
3963 return -EINVAL;
3964
3965 for (i = 0; i < hw->mac.num_rar_entries; i++) {
3966 if (adapter->mac_table[i].state & IXGBE_MAC_STATE_IN_USE)
3967 continue;
3968 adapter->mac_table[i].state |= (IXGBE_MAC_STATE_MODIFIED |
3969 IXGBE_MAC_STATE_IN_USE);
3970 ether_addr_copy(adapter->mac_table[i].addr, addr);
3971 adapter->mac_table[i].queue = queue;
3972 ixgbe_sync_mac_table(adapter);
3973 return i;
3974 }
3975 return -ENOMEM;
3976}
3977
3978int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter, u8 *addr, u16 queue)
3979{
3980 /* search table for addr, if found, set to 0 and sync */
3981 int i;
3982 struct ixgbe_hw *hw = &adapter->hw;
3983
3984 if (is_zero_ether_addr(addr))
3985 return -EINVAL;
3986
3987 for (i = 0; i < hw->mac.num_rar_entries; i++) {
3988 if (ether_addr_equal(addr, adapter->mac_table[i].addr) &&
3989 adapter->mac_table[i].queue == queue) {
3990 adapter->mac_table[i].state |= IXGBE_MAC_STATE_MODIFIED;
3991 adapter->mac_table[i].state &= ~IXGBE_MAC_STATE_IN_USE;
3992 memset(adapter->mac_table[i].addr, 0, ETH_ALEN);
3993 adapter->mac_table[i].queue = 0;
3994 ixgbe_sync_mac_table(adapter);
3995 return 0;
3996 }
3997 }
3998 return -ENOMEM;
3999}
3878/** 4000/**
3879 * ixgbe_write_uc_addr_list - write unicast addresses to RAR table 4001 * ixgbe_write_uc_addr_list - write unicast addresses to RAR table
3880 * @netdev: network interface device structure 4002 * @netdev: network interface device structure
@@ -3884,39 +4006,23 @@ static int ixgbe_write_mc_addr_list(struct net_device *netdev)
3884 * 0 on no addresses written 4006 * 0 on no addresses written
3885 * X on writing X addresses to the RAR table 4007 * X on writing X addresses to the RAR table
3886 **/ 4008 **/
3887static int ixgbe_write_uc_addr_list(struct net_device *netdev) 4009static int ixgbe_write_uc_addr_list(struct net_device *netdev, int vfn)
3888{ 4010{
3889 struct ixgbe_adapter *adapter = netdev_priv(netdev); 4011 struct ixgbe_adapter *adapter = netdev_priv(netdev);
3890 struct ixgbe_hw *hw = &adapter->hw;
3891 unsigned int rar_entries = hw->mac.num_rar_entries - 1;
3892 int count = 0; 4012 int count = 0;
3893 4013
3894 /* In SR-IOV/VMDQ modes significantly less RAR entries are available */
3895 if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
3896 rar_entries = IXGBE_MAX_PF_MACVLANS - 1;
3897
3898 /* return ENOMEM indicating insufficient memory for addresses */ 4014 /* return ENOMEM indicating insufficient memory for addresses */
3899 if (netdev_uc_count(netdev) > rar_entries) 4015 if (netdev_uc_count(netdev) > ixgbe_available_rars(adapter))
3900 return -ENOMEM; 4016 return -ENOMEM;
3901 4017
3902 if (!netdev_uc_empty(netdev)) { 4018 if (!netdev_uc_empty(netdev)) {
3903 struct netdev_hw_addr *ha; 4019 struct netdev_hw_addr *ha;
3904 /* return error if we do not support writing to RAR table */
3905 if (!hw->mac.ops.set_rar)
3906 return -ENOMEM;
3907
3908 netdev_for_each_uc_addr(ha, netdev) { 4020 netdev_for_each_uc_addr(ha, netdev) {
3909 if (!rar_entries) 4021 ixgbe_del_mac_filter(adapter, ha->addr, vfn);
3910 break; 4022 ixgbe_add_mac_filter(adapter, ha->addr, vfn);
3911 hw->mac.ops.set_rar(hw, rar_entries--, ha->addr,
3912 VMDQ_P(0), IXGBE_RAH_AV);
3913 count++; 4023 count++;
3914 } 4024 }
3915 } 4025 }
3916 /* write the addresses in reverse order to avoid write combining */
3917 for (; rar_entries > 0 ; rar_entries--)
3918 hw->mac.ops.clear_rar(hw, rar_entries);
3919
3920 return count; 4026 return count;
3921} 4027}
3922 4028
@@ -3975,7 +4081,7 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
3975 * sufficient space to store all the addresses then enable 4081 * sufficient space to store all the addresses then enable
3976 * unicast promiscuous mode 4082 * unicast promiscuous mode
3977 */ 4083 */
3978 count = ixgbe_write_uc_addr_list(netdev); 4084 count = ixgbe_write_uc_addr_list(netdev, VMDQ_P(0));
3979 if (count < 0) { 4085 if (count < 0) {
3980 fctrl |= IXGBE_FCTRL_UPE; 4086 fctrl |= IXGBE_FCTRL_UPE;
3981 vmolr |= IXGBE_VMOLR_ROPE; 4087 vmolr |= IXGBE_VMOLR_ROPE;
@@ -4287,20 +4393,10 @@ static void ixgbe_macvlan_set_rx_mode(struct net_device *dev, unsigned int pool,
4287 vmolr |= IXGBE_VMOLR_ROMPE; 4393 vmolr |= IXGBE_VMOLR_ROMPE;
4288 hw->mac.ops.update_mc_addr_list(hw, dev); 4394 hw->mac.ops.update_mc_addr_list(hw, dev);
4289 } 4395 }
4290 ixgbe_write_uc_addr_list(adapter->netdev); 4396 ixgbe_write_uc_addr_list(adapter->netdev, pool);
4291 IXGBE_WRITE_REG(hw, IXGBE_VMOLR(pool), vmolr); 4397 IXGBE_WRITE_REG(hw, IXGBE_VMOLR(pool), vmolr);
4292} 4398}
4293 4399
4294static void ixgbe_add_mac_filter(struct ixgbe_adapter *adapter,
4295 u8 *addr, u16 pool)
4296{
4297 struct ixgbe_hw *hw = &adapter->hw;
4298 unsigned int entry;
4299
4300 entry = hw->mac.num_rar_entries - pool;
4301 hw->mac.ops.set_rar(hw, entry, addr, VMDQ_P(pool), IXGBE_RAH_AV);
4302}
4303
4304static void ixgbe_fwd_psrtype(struct ixgbe_fwd_adapter *vadapter) 4400static void ixgbe_fwd_psrtype(struct ixgbe_fwd_adapter *vadapter)
4305{ 4401{
4306 struct ixgbe_adapter *adapter = vadapter->real_adapter; 4402 struct ixgbe_adapter *adapter = vadapter->real_adapter;
@@ -4780,7 +4876,9 @@ void ixgbe_up(struct ixgbe_adapter *adapter)
4780void ixgbe_reset(struct ixgbe_adapter *adapter) 4876void ixgbe_reset(struct ixgbe_adapter *adapter)
4781{ 4877{
4782 struct ixgbe_hw *hw = &adapter->hw; 4878 struct ixgbe_hw *hw = &adapter->hw;
4879 struct net_device *netdev = adapter->netdev;
4783 int err; 4880 int err;
4881 u8 old_addr[ETH_ALEN];
4784 4882
4785 if (ixgbe_removed(hw->hw_addr)) 4883 if (ixgbe_removed(hw->hw_addr))
4786 return; 4884 return;
@@ -4816,9 +4914,10 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
4816 } 4914 }
4817 4915
4818 clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state); 4916 clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
4819 4917 /* do not flush user set addresses */
4820 /* reprogram the RAR[0] in case user changed it. */ 4918 memcpy(old_addr, &adapter->mac_table[0].addr, netdev->addr_len);
4821 hw->mac.ops.set_rar(hw, 0, hw->mac.addr, VMDQ_P(0), IXGBE_RAH_AV); 4919 ixgbe_flush_sw_mac_table(adapter);
4920 ixgbe_mac_set_default_filter(adapter, old_addr);
4822 4921
4823 /* update SAN MAC vmdq pool selection */ 4922 /* update SAN MAC vmdq pool selection */
4824 if (hw->mac.san_mac_rar_index) 4923 if (hw->mac.san_mac_rar_index)
@@ -5064,6 +5163,10 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
5064#endif /* CONFIG_IXGBE_DCB */ 5163#endif /* CONFIG_IXGBE_DCB */
5065#endif /* IXGBE_FCOE */ 5164#endif /* IXGBE_FCOE */
5066 5165
5166 adapter->mac_table = kzalloc(sizeof(struct ixgbe_mac_addr) *
5167 hw->mac.num_rar_entries,
5168 GFP_ATOMIC);
5169
5067 /* Set MAC specific capability flags and exceptions */ 5170 /* Set MAC specific capability flags and exceptions */
5068 switch (hw->mac.type) { 5171 switch (hw->mac.type) {
5069 case ixgbe_mac_82598EB: 5172 case ixgbe_mac_82598EB:
@@ -7210,16 +7313,17 @@ static int ixgbe_set_mac(struct net_device *netdev, void *p)
7210 struct ixgbe_adapter *adapter = netdev_priv(netdev); 7313 struct ixgbe_adapter *adapter = netdev_priv(netdev);
7211 struct ixgbe_hw *hw = &adapter->hw; 7314 struct ixgbe_hw *hw = &adapter->hw;
7212 struct sockaddr *addr = p; 7315 struct sockaddr *addr = p;
7316 int ret;
7213 7317
7214 if (!is_valid_ether_addr(addr->sa_data)) 7318 if (!is_valid_ether_addr(addr->sa_data))
7215 return -EADDRNOTAVAIL; 7319 return -EADDRNOTAVAIL;
7216 7320
7321 ixgbe_del_mac_filter(adapter, hw->mac.addr, VMDQ_P(0));
7217 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); 7322 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
7218 memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len); 7323 memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
7219 7324
7220 hw->mac.ops.set_rar(hw, 0, hw->mac.addr, VMDQ_P(0), IXGBE_RAH_AV); 7325 ret = ixgbe_add_mac_filter(adapter, hw->mac.addr, VMDQ_P(0));
7221 7326 return ret > 0 ? 0 : ret;
7222 return 0;
7223} 7327}
7224 7328
7225static int 7329static int
@@ -8225,6 +8329,8 @@ skip_sriov:
8225 goto err_sw_init; 8329 goto err_sw_init;
8226 } 8330 }
8227 8331
8332 ixgbe_mac_set_default_filter(adapter, hw->mac.perm_addr);
8333
8228 setup_timer(&adapter->service_timer, &ixgbe_service_timer, 8334 setup_timer(&adapter->service_timer, &ixgbe_service_timer,
8229 (unsigned long) adapter); 8335 (unsigned long) adapter);
8230 8336
@@ -8357,6 +8463,7 @@ err_sw_init:
8357 ixgbe_disable_sriov(adapter); 8463 ixgbe_disable_sriov(adapter);
8358 adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP; 8464 adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP;
8359 iounmap(adapter->io_addr); 8465 iounmap(adapter->io_addr);
8466 kfree(adapter->mac_table);
8360err_ioremap: 8467err_ioremap:
8361 free_netdev(netdev); 8468 free_netdev(netdev);
8362err_alloc_etherdev: 8469err_alloc_etherdev:
@@ -8430,6 +8537,7 @@ static void ixgbe_remove(struct pci_dev *pdev)
8430 8537
8431 e_dev_info("complete\n"); 8538 e_dev_info("complete\n");
8432 8539
8540 kfree(adapter->mac_table);
8433 free_netdev(netdev); 8541 free_netdev(netdev);
8434 8542
8435 pci_disable_pcie_error_reporting(pdev); 8543 pci_disable_pcie_error_reporting(pdev);