提交 2c5645cf 编写于 作者: C Christopher Leech 提交者: Jeff Garzik

ixgbe: Implement HAVE_SET_RX_MODE

Implement HAVE_SET_RX_MODE in the driver for MC and UC lists.
Signed-off-by: NChristopher Leech <christopher.leech@intel.com>
Signed-off-by: NPeter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: NJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: NJeff Garzik <jgarzik@redhat.com>
上级 9da09bb1
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
......@@ -36,6 +36,8 @@
#define IXGBE_82598_MAX_TX_QUEUES 32
#define IXGBE_82598_MAX_RX_QUEUES 64
#define IXGBE_82598_RAR_ENTRIES 16
#define IXGBE_82598_MC_TBL_SIZE 128
#define IXGBE_82598_VFT_TBL_SIZE 128
static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw);
static s32 ixgbe_get_link_settings_82598(struct ixgbe_hw *hw, u32 *speed,
......@@ -60,7 +62,9 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
{
hw->mac.num_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
hw->mac.num_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
hw->mac.num_rx_addrs = IXGBE_82598_RAR_ENTRIES;
hw->mac.mcft_size = IXGBE_82598_MC_TBL_SIZE;
hw->mac.vft_size = IXGBE_82598_VFT_TBL_SIZE;
hw->mac.num_rar_entries = IXGBE_82598_RAR_ENTRIES;
/* PHY ops are filled in by default properly for Fiber only */
if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) {
......
......@@ -661,7 +661,7 @@ s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vind,
static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
{
u32 i;
u32 rar_entries = hw->mac.num_rx_addrs;
u32 rar_entries = hw->mac.num_rar_entries;
/*
* If the current mac address is valid, assume it is a software override
......@@ -705,12 +705,113 @@ static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
hw_dbg(hw, " Clearing MTA\n");
for (i = 0; i < IXGBE_MC_TBL_SIZE; i++)
for (i = 0; i < hw->mac.mcft_size; i++)
IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0);
return 0;
}
/**
* ixgbe_add_uc_addr - Adds a secondary unicast address.
* @hw: pointer to hardware structure
* @addr: new address
*
* Adds it to unused receive address register or goes into promiscuous mode.
**/
void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr)
{
u32 rar_entries = hw->mac.num_rar_entries;
u32 rar;
hw_dbg(hw, " UC Addr = %.2X %.2X %.2X %.2X %.2X %.2X\n",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
/*
* Place this address in the RAR if there is room,
* else put the controller into promiscuous mode
*/
if (hw->addr_ctrl.rar_used_count < rar_entries) {
rar = hw->addr_ctrl.rar_used_count -
hw->addr_ctrl.mc_addr_in_rar_count;
ixgbe_set_rar(hw, rar, addr, 0, IXGBE_RAH_AV);
hw_dbg(hw, "Added a secondary address to RAR[%d]\n", rar);
hw->addr_ctrl.rar_used_count++;
} else {
hw->addr_ctrl.overflow_promisc++;
}
hw_dbg(hw, "ixgbe_add_uc_addr Complete\n");
}
/**
* ixgbe_update_uc_addr_list - Updates MAC list of secondary addresses
* @hw: pointer to hardware structure
* @addr_list: the list of new addresses
* @addr_count: number of addresses
* @next: iterator function to walk the address list
*
* The given list replaces any existing list. Clears the secondary addrs from
* receive address registers. Uses unused receive address registers for the
* first secondary addresses, and falls back to promiscuous mode as needed.
*
* Drivers using secondary unicast addresses must set user_set_promisc when
* manually putting the device into promiscuous mode.
**/
s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list,
u32 addr_count, ixgbe_mc_addr_itr next)
{
u8 *addr;
u32 i;
u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc;
u32 uc_addr_in_use;
u32 fctrl;
u32 vmdq;
/*
* Clear accounting of old secondary address list,
* don't count RAR[0]
*/
uc_addr_in_use = hw->addr_ctrl.rar_used_count -
hw->addr_ctrl.mc_addr_in_rar_count - 1;
hw->addr_ctrl.rar_used_count -= uc_addr_in_use;
hw->addr_ctrl.overflow_promisc = 0;
/* Zero out the other receive addresses */
hw_dbg(hw, "Clearing RAR[1-%d]\n", uc_addr_in_use);
for (i = 1; i <= uc_addr_in_use; i++) {
IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
}
/* Add the new addresses */
for (i = 0; i < addr_count; i++) {
hw_dbg(hw, " Adding the secondary addresses:\n");
addr = next(hw, &addr_list, &vmdq);
ixgbe_add_uc_addr(hw, addr);
}
if (hw->addr_ctrl.overflow_promisc) {
/* enable promisc if not already in overflow or set by user */
if (!old_promisc_setting && !hw->addr_ctrl.user_set_promisc) {
hw_dbg(hw, " Entering address overflow promisc mode\n");
fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
fctrl |= IXGBE_FCTRL_UPE;
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
}
} else {
/* only disable if set by overflow, not by user */
if (old_promisc_setting && !hw->addr_ctrl.user_set_promisc) {
hw_dbg(hw, " Leaving address overflow promisc mode\n");
fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
fctrl &= ~IXGBE_FCTRL_UPE;
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
}
}
hw_dbg(hw, "ixgbe_update_uc_addr_list Complete\n");
return 0;
}
/**
* ixgbe_mta_vector - Determines bit-vector in multicast table to set
* @hw: pointer to hardware structure
......@@ -794,7 +895,7 @@ static void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
**/
static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr)
{
u32 rar_entries = hw->mac.num_rx_addrs;
u32 rar_entries = hw->mac.num_rar_entries;
hw_dbg(hw, " MC Addr =%.2X %.2X %.2X %.2X %.2X %.2X\n",
mc_addr[0], mc_addr[1], mc_addr[2],
......@@ -823,7 +924,7 @@ static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr)
* @hw: pointer to hardware structure
* @mc_addr_list: the list of new multicast addresses
* @mc_addr_count: number of addresses
* @pad: number of bytes between addresses in the list
* @next: iterator function to walk the multicast address list
*
* The given list replaces any existing list. Clears the MC addrs from receive
* address registers and the multicast table. Uses unsed receive address
......@@ -831,10 +932,11 @@ static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr)
* multicast table.
**/
s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
u32 mc_addr_count, u32 pad)
u32 mc_addr_count, ixgbe_mc_addr_itr next)
{
u32 i;
u32 rar_entries = hw->mac.num_rx_addrs;
u32 rar_entries = hw->mac.num_rar_entries;
u32 vmdq;
/*
* Set the new number of MC addresses that we are being requested to
......@@ -854,14 +956,13 @@ s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
/* Clear the MTA */
hw_dbg(hw, " Clearing MTA\n");
for (i = 0; i < IXGBE_MC_TBL_SIZE; i++)
for (i = 0; i < hw->mac.mcft_size; i++)
IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0);
/* Add the new addresses */
for (i = 0; i < mc_addr_count; i++) {
hw_dbg(hw, " Adding the multicast addresses:\n");
ixgbe_add_mc_addr(hw, mc_addr_list +
(i * (IXGBE_ETH_LENGTH_OF_ADDRESS + pad)));
ixgbe_add_mc_addr(hw, next(hw, &mc_addr_list, &vmdq));
}
/* Enable mta */
......@@ -884,11 +985,11 @@ static s32 ixgbe_clear_vfta(struct ixgbe_hw *hw)
u32 offset;
u32 vlanbyte;
for (offset = 0; offset < IXGBE_VLAN_FILTER_TBL_SIZE; offset++)
for (offset = 0; offset < hw->mac.vft_size; offset++)
IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
for (vlanbyte = 0; vlanbyte < 4; vlanbyte++)
for (offset = 0; offset < IXGBE_VLAN_FILTER_TBL_SIZE; offset++)
for (offset = 0; offset < hw->mac.vft_size; offset++)
IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset),
0);
......
......@@ -47,7 +47,9 @@ s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val);
s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vind,
u32 enable_addr);
s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
u32 mc_addr_count, u32 pad);
u32 mc_addr_count, ixgbe_mc_addr_itr next);
s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *uc_addr_list,
u32 mc_addr_count, ixgbe_mc_addr_itr next);
s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on);
s32 ixgbe_validate_mac_addr(u8 *mac_addr);
......
......@@ -1619,23 +1619,37 @@ static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
}
}
static u8 *ixgbe_addr_list_itr(struct ixgbe_hw *hw, u8 **mc_addr_ptr, u32 *vmdq)
{
struct dev_mc_list *mc_ptr;
u8 *addr = *mc_addr_ptr;
*vmdq = 0;
mc_ptr = container_of(addr, struct dev_mc_list, dmi_addr[0]);
if (mc_ptr->next)
*mc_addr_ptr = mc_ptr->next->dmi_addr;
else
*mc_addr_ptr = NULL;
return addr;
}
/**
* ixgbe_set_multi - Multicast and Promiscuous mode set
* ixgbe_set_rx_mode - Unicast, Multicast and Promiscuous mode set
* @netdev: network interface device structure
*
* The set_multi entry point is called whenever the multicast address
* list or the network interface flags are updated. This routine is
* responsible for configuring the hardware for proper multicast,
* promiscuous mode, and all-multi behavior.
* The set_rx_method entry point is called whenever the unicast/multicast
* address list or the network interface flags are updated. This routine is
* responsible for configuring the hardware for proper unicast, multicast and
* promiscuous mode.
**/
static void ixgbe_set_multi(struct net_device *netdev)
static void ixgbe_set_rx_mode(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
struct dev_mc_list *mc_ptr;
u8 *mta_list;
u32 fctrl, vlnctrl;
int i;
u8 *addr_list = NULL;
int addr_count = 0;
/* Check for Promiscuous and All Multicast modes */
......@@ -1643,6 +1657,7 @@ static void ixgbe_set_multi(struct net_device *netdev)
vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
if (netdev->flags & IFF_PROMISC) {
hw->addr_ctrl.user_set_promisc = 1;
fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
vlnctrl &= ~IXGBE_VLNCTRL_VFE;
} else {
......@@ -1653,33 +1668,25 @@ static void ixgbe_set_multi(struct net_device *netdev)
fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
}
vlnctrl |= IXGBE_VLNCTRL_VFE;
hw->addr_ctrl.user_set_promisc = 0;
}
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
if (netdev->mc_count) {
mta_list = kcalloc(netdev->mc_count, ETH_ALEN, GFP_ATOMIC);
if (!mta_list)
return;
/* Shared function expects packed array of only addresses. */
mc_ptr = netdev->mc_list;
for (i = 0; i < netdev->mc_count; i++) {
if (!mc_ptr)
break;
memcpy(mta_list + (i * ETH_ALEN), mc_ptr->dmi_addr,
ETH_ALEN);
mc_ptr = mc_ptr->next;
}
ixgbe_update_mc_addr_list(hw, mta_list, i, 0);
kfree(mta_list);
} else {
ixgbe_update_mc_addr_list(hw, NULL, 0, 0);
}
/* reprogram secondary unicast list */
addr_count = netdev->uc_count;
if (addr_count)
addr_list = netdev->uc_list->dmi_addr;
ixgbe_update_uc_addr_list(hw, addr_list, addr_count,
ixgbe_addr_list_itr);
/* reprogram multicast list */
addr_count = netdev->mc_count;
if (addr_count)
addr_list = netdev->mc_list->dmi_addr;
ixgbe_update_mc_addr_list(hw, addr_list, addr_count,
ixgbe_addr_list_itr);
}
static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
......@@ -1723,7 +1730,7 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
struct net_device *netdev = adapter->netdev;
int i;
ixgbe_set_multi(netdev);
ixgbe_set_rx_mode(netdev);
ixgbe_restore_vlan(adapter);
......@@ -3508,7 +3515,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
netdev->stop = &ixgbe_close;
netdev->hard_start_xmit = &ixgbe_xmit_frame;
netdev->get_stats = &ixgbe_get_stats;
netdev->set_multicast_list = &ixgbe_set_multi;
netdev->set_rx_mode = &ixgbe_set_rx_mode;
netdev->set_multicast_list = &ixgbe_set_rx_mode;
netdev->set_mac_address = &ixgbe_set_mac;
netdev->change_mtu = &ixgbe_change_mtu;
ixgbe_set_ethtool_ops(netdev);
......
......@@ -822,10 +822,6 @@
#define IXGBE_RAH_VIND_SHIFT 18
#define IXGBE_RAH_AV 0x80000000
/* Filters */
#define IXGBE_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bits) */
#define IXGBE_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
/* Header split receive */
#define IXGBE_RFCTL_ISCSI_DIS 0x00000001
#define IXGBE_RFCTL_ISCSI_DWC_MASK 0x0000003E
......@@ -1167,6 +1163,8 @@ struct ixgbe_addr_filter_info {
u32 rar_used_count;
u32 mc_addr_in_rar_count;
u32 mta_in_use;
u32 overflow_promisc;
bool user_set_promisc;
};
/* Flow control parameters */
......@@ -1242,6 +1240,10 @@ struct ixgbe_hw_stats {
/* forward declaration */
struct ixgbe_hw;
/* iterator type for walking multicast address lists */
typedef u8* (*ixgbe_mc_addr_itr) (struct ixgbe_hw *hw, u8 **mc_addr_ptr,
u32 *vmdq);
struct ixgbe_mac_operations {
s32 (*reset)(struct ixgbe_hw *);
enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
......@@ -1263,9 +1265,11 @@ struct ixgbe_mac_info {
u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
u8 perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
s32 mc_filter_type;
u32 mcft_size;
u32 vft_size;
u32 num_rar_entries;
u32 num_rx_queues;
u32 num_tx_queues;
u32 num_rx_addrs;
u32 link_attach_type;
u32 link_mode_select;
bool link_settings_loaded;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部