2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-21 19:53:59 +08:00

e1000e: genericize the update multicast address list

Make updating the multicast address list generic for all families and
enforce the requirement to update the entire multicast table array all at
once instead of piecemeal which causes problems on some parts.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Bruce Allan 2010-01-13 02:05:38 +00:00 committed by David S. Miller
parent f4d2dd4cd4
commit ab8932f3e8
5 changed files with 27 additions and 89 deletions

View File

@ -1233,32 +1233,6 @@ static s32 e1000_led_on_82574(struct e1000_hw *hw)
return 0;
}
/**
* e1000_update_mc_addr_list_82571 - Update Multicast addresses
* @hw: pointer to the HW structure
* @mc_addr_list: array of multicast addresses to program
* @mc_addr_count: number of multicast addresses to program
* @rar_used_count: the first RAR register free to program
* @rar_count: total number of supported Receive Address Registers
*
* Updates the Receive Address Registers and Multicast Table Array.
* The caller must have a packed mc_addr_list of multicast addresses.
* The parameter rar_count will usually be hw->mac.rar_entry_count
* unless there are workarounds that change this.
**/
static void e1000_update_mc_addr_list_82571(struct e1000_hw *hw,
u8 *mc_addr_list,
u32 mc_addr_count,
u32 rar_used_count,
u32 rar_count)
{
if (e1000e_get_laa_state_82571(hw))
rar_count--;
e1000e_update_mc_addr_list_generic(hw, mc_addr_list, mc_addr_count,
rar_used_count, rar_count);
}
/**
* e1000_setup_link_82571 - Setup flow control and link settings
* @hw: pointer to the HW structure
@ -1731,7 +1705,7 @@ static struct e1000_mac_operations e82571_mac_ops = {
/* .get_link_up_info: media type dependent */
/* .led_on: mac type dependent */
.led_off = e1000e_led_off_generic,
.update_mc_addr_list = e1000_update_mc_addr_list_82571,
.update_mc_addr_list = e1000e_update_mc_addr_list_generic,
.write_vfta = e1000_write_vfta_generic,
.clear_vfta = e1000_clear_vfta_82571,
.reset_hw = e1000_reset_hw_82571,

View File

@ -518,9 +518,7 @@ extern void e1000_clear_vfta_generic(struct e1000_hw *hw);
extern void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
extern void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
u8 *mc_addr_list,
u32 mc_addr_count,
u32 rar_used_count,
u32 rar_count);
u32 mc_addr_count);
extern void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
extern s32 e1000e_set_fc_watermarks(struct e1000_hw *hw);
extern void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop);

View File

@ -753,7 +753,7 @@ struct e1000_mac_operations {
s32 (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
s32 (*led_on)(struct e1000_hw *);
s32 (*led_off)(struct e1000_hw *);
void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32, u32, u32);
void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);
s32 (*reset_hw)(struct e1000_hw *);
s32 (*init_hw)(struct e1000_hw *);
s32 (*setup_link)(struct e1000_hw *);
@ -819,6 +819,10 @@ struct e1000_mac_info {
u16 ifs_ratio;
u16 ifs_step_size;
u16 mta_reg_count;
/* Maximum size of the MTA register table in all supported adapters */
#define MAX_MTA_REG 128
u32 mta_shadow[MAX_MTA_REG];
u16 rar_entry_count;
u8 forced_speed_duplex;

View File

@ -340,62 +340,34 @@ static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
* @hw: pointer to the HW structure
* @mc_addr_list: array of multicast addresses to program
* @mc_addr_count: number of multicast addresses to program
* @rar_used_count: the first RAR register free to program
* @rar_count: total number of supported Receive Address Registers
*
* Updates the Receive Address Registers and Multicast Table Array.
* Updates entire Multicast Table Array.
* The caller must have a packed mc_addr_list of multicast addresses.
* The parameter rar_count will usually be hw->mac.rar_entry_count
* unless there are workarounds that change this.
**/
void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count,
u32 rar_used_count, u32 rar_count)
u8 *mc_addr_list, u32 mc_addr_count)
{
u32 i;
u32 *mcarray = kzalloc(hw->mac.mta_reg_count * sizeof(u32), GFP_ATOMIC);
u32 hash_value, hash_bit, hash_reg;
int i;
if (!mcarray) {
printk(KERN_ERR "multicast array memory allocation failed\n");
return;
}
/* clear mta_shadow */
memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
/*
* Load the first set of multicast addresses into the exact
* filters (RAR). If there are not enough to fill the RAR
* array, clear the filters.
*/
for (i = rar_used_count; i < rar_count; i++) {
if (mc_addr_count) {
e1000e_rar_set(hw, mc_addr_list, i);
mc_addr_count--;
mc_addr_list += ETH_ALEN;
} else {
E1000_WRITE_REG_ARRAY(hw, E1000_RA, i << 1, 0);
e1e_flush();
E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1) + 1, 0);
e1e_flush();
}
}
/* Load any remaining multicast addresses into the hash table. */
for (; mc_addr_count > 0; mc_addr_count--) {
u32 hash_value, hash_reg, hash_bit, mta;
/* update mta_shadow from mc_addr_list */
for (i = 0; (u32) i < mc_addr_count; i++) {
hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
e_dbg("Hash value = 0x%03X\n", hash_value);
hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
hash_bit = hash_value & 0x1F;
mta = (1 << hash_bit);
mcarray[hash_reg] |= mta;
mc_addr_list += ETH_ALEN;
hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
mc_addr_list += (ETH_ALEN);
}
/* write the hash table completely */
for (i = 0; i < hw->mac.mta_reg_count; i++)
E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, mcarray[i]);
/* replace the entire MTA table */
for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]);
e1e_flush();
kfree(mcarray);
}
/**

View File

@ -2536,22 +2536,14 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
* @hw: pointer to the HW structure
* @mc_addr_list: array of multicast addresses to program
* @mc_addr_count: number of multicast addresses to program
* @rar_used_count: the first RAR register free to program
* @rar_count: total number of supported Receive Address Registers
*
* Updates the Receive Address Registers and Multicast Table Array.
* Updates the Multicast Table Array.
* The caller must have a packed mc_addr_list of multicast addresses.
* The parameter rar_count will usually be hw->mac.rar_entry_count
* unless there are workarounds that change this. Currently no func pointer
* exists and all implementations are handled in the generic version of this
* function.
**/
static void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list,
u32 mc_addr_count, u32 rar_used_count,
u32 rar_count)
u32 mc_addr_count)
{
hw->mac.ops.update_mc_addr_list(hw, mc_addr_list, mc_addr_count,
rar_used_count, rar_count);
hw->mac.ops.update_mc_addr_list(hw, mc_addr_list, mc_addr_count);
}
/**
@ -2567,7 +2559,6 @@ static void e1000_set_multi(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
struct e1000_mac_info *mac = &hw->mac;
struct dev_mc_list *mc_ptr;
u8 *mta_list;
u32 rctl;
@ -2609,15 +2600,14 @@ static void e1000_set_multi(struct net_device *netdev)
mc_ptr = mc_ptr->next;
}
e1000_update_mc_addr_list(hw, mta_list, i, 1,
mac->rar_entry_count);
e1000_update_mc_addr_list(hw, mta_list, i);
kfree(mta_list);
} else {
/*
* if we're called from probe, we might not have
* anything to do here, so clear out the list
*/
e1000_update_mc_addr_list(hw, NULL, 0, 1, mac->rar_entry_count);
e1000_update_mc_addr_list(hw, NULL, 0);
}
}