Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 28fc06f5 authored by Alexander Duyck's avatar Alexander Duyck Committed by David S. Miller
Browse files

igb: move all multicast addresses into multicast table array



This patch moves all of the multicast addresses out of the free Receive
address registers and instead programs them all into the multicast table
array.  As a result the multicast filtering may not be as precise, but it
also greatly reduces the overhead for multicast addresses.

Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 009bc06e
Loading
Loading
Loading
Loading
+0 −59
Original line number Diff line number Diff line
@@ -797,65 +797,6 @@ static void igb_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count)
	    hw->mac.ops.rar_set(hw, addr, i);
}

/**
 *  igb_update_mc_addr_list - 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.
 **/
void igb_update_mc_addr_list(struct e1000_hw *hw,
                             u8 *mc_addr_list, u32 mc_addr_count,
                             u32 rar_used_count, u32 rar_count)
{
	u32 hash_value;
	u32 i;
	u8 addr[6] = {0,0,0,0,0,0};
	/*
	 * This function is essentially the same as that of 
	 * igb_update_mc_addr_list_generic. However it also takes care 
	 * of the special case where the register offset of the 
	 * second set of RARs begins elsewhere. This is implicitly taken care by 
	 * function e1000_rar_set_generic.
	 */

	/*
	 * 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) {
			igb_rar_set(hw, mc_addr_list, i);
			mc_addr_count--;
			mc_addr_list += ETH_ALEN;
		} else {
			igb_rar_set(hw, addr, i);
		}
	}

	/* Clear the old settings from the MTA */
	hw_dbg("Clearing MTA\n");
	for (i = 0; i < hw->mac.mta_reg_count; i++) {
		array_wr32(E1000_MTA, i, 0);
		wrfl();
	}

	/* Load any remaining multicast addresses into the hash table. */
	for (; mc_addr_count > 0; mc_addr_count--) {
		hash_value = igb_hash_mc_addr(hw, mc_addr_list);
		hw_dbg("Hash value = 0x%03X\n", hash_value);
		igb_mta_set(hw, hash_value);
		mc_addr_list += ETH_ALEN;
	}
}

/**
 *  igb_shutdown_fiber_serdes_link_82575 - Remove link during power down
 *  @hw: pointer to the HW structure
+0 −1
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@
#ifndef _E1000_82575_H_
#define _E1000_82575_H_

void igb_update_mc_addr_list(struct e1000_hw*, u8*, u32, u32, u32);
extern void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);

+4 −0
Original line number Diff line number Diff line
@@ -338,6 +338,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;
+35 −0
Original line number Diff line number Diff line
@@ -260,6 +260,41 @@ void igb_mta_set(struct e1000_hw *hw, u32 hash_value)
	wrfl();
}

/**
 *  igb_update_mc_addr_list - 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
 *
 *  Updates entire Multicast Table Array.
 *  The caller must have a packed mc_addr_list of multicast addresses.
 **/
void igb_update_mc_addr_list(struct e1000_hw *hw,
                             u8 *mc_addr_list, u32 mc_addr_count)
{
	u32 hash_value, hash_bit, hash_reg;
	int i;

	/* clear mta_shadow */
	memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));

	/* update mta_shadow from mc_addr_list */
	for (i = 0; (u32) i < mc_addr_count; i++) {
		hash_value = igb_hash_mc_addr(hw, mc_addr_list);

		hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
		hash_bit = hash_value & 0x1F;

		hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
		mc_addr_list += (ETH_ALEN);
	}

	/* replace the entire MTA table */
	for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
		array_wr32(E1000_MTA, i, hw->mac.mta_shadow[i]);
	wrfl();
}

/**
 *  igb_hash_mc_addr - Generate a multicast hash value
 *  @hw: pointer to the HW structure
+2 −0
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ s32 igb_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
				       u16 *duplex);
s32  igb_id_led_init(struct e1000_hw *hw);
s32  igb_led_off(struct e1000_hw *hw);
void igb_update_mc_addr_list(struct e1000_hw *hw,
	                     u8 *mc_addr_list, u32 mc_addr_count);
s32  igb_setup_link(struct e1000_hw *hw);
s32  igb_validate_mdi_setting(struct e1000_hw *hw);
s32  igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
Loading