Commit 2d064c06 authored by Alexander Duyck's avatar Alexander Duyck Committed by Jeff Garzik
Browse files

igb: add 82576 MAC support

parent 0024fd00
Loading
Loading
Loading
Loading
+195 −13
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@

#include <linux/types.h>
#include <linux/slab.h>
#include <linux/if_ether.h>

#include "e1000_mac.h"
#include "e1000_82575.h"
@@ -45,7 +46,6 @@ static s32 igb_get_cfg_done_82575(struct e1000_hw *);
static s32  igb_init_hw_82575(struct e1000_hw *);
static s32  igb_phy_hw_reset_sgmii_82575(struct e1000_hw *);
static s32  igb_read_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16 *);
static void igb_rar_set_82575(struct e1000_hw *, u8 *, u32);
static s32  igb_reset_hw_82575(struct e1000_hw *);
static s32  igb_set_d0_lplu_state_82575(struct e1000_hw *, bool);
static s32  igb_setup_copper_link_82575(struct e1000_hw *);
@@ -84,6 +84,12 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
	case E1000_DEV_ID_82575GB_QUAD_COPPER:
		mac->type = e1000_82575;
		break;
	case E1000_DEV_ID_82576:
	case E1000_DEV_ID_82576_FIBER:
	case E1000_DEV_ID_82576_SERDES:
	case E1000_DEV_ID_82576_QUAD_COPPER:
		mac->type = e1000_82576;
		break;
	default:
		return -E1000_ERR_MAC_INIT;
		break;
@@ -128,6 +134,8 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
	mac->mta_reg_count = 128;
	/* Set rar entry count */
	mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
	if (mac->type == e1000_82576)
		mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
	/* Set if part includes ASF firmware */
	mac->asf_firmware_present = true;
	/* Set if manageability features are enabled. */
@@ -700,7 +708,6 @@ static s32 igb_check_for_link_82575(struct e1000_hw *hw)

	return ret_val;
}

/**
 *  igb_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex
 *  @hw: pointer to the HW structure
@@ -757,18 +764,129 @@ static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed,
}

/**
 *  igb_rar_set_82575 - Set receive address register
 *  igb_init_rx_addrs_82575 - Initialize receive address's
 *  @hw: pointer to the HW structure
 *  @rar_count: receive address registers
 *
 *  Setups the receive address registers by setting the base receive address
 *  register to the devices MAC address and clearing all the other receive
 *  address registers to 0.
 **/
static void igb_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count)
{
	u32 i;
	u8 addr[6] = {0,0,0,0,0,0};
	/*
	 * This function is essentially the same as that of
	 * e1000_init_rx_addrs_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.
	 */

	hw_dbg("e1000_init_rx_addrs_82575");

	/* Setup the receive address */
	hw_dbg("Programming MAC Address into RAR[0]\n");
	hw->mac.ops.rar_set(hw, hw->mac.addr, 0);

	/* Zero out the other (rar_entry_count - 1) receive addresses */
	hw_dbg("Clearing RAR[1-%u]\n", rar_count-1);
	for (i = 1; i < rar_count; i++)
	    hw->mac.ops.rar_set(hw, addr, i);
}

/**
 *  igb_update_mc_addr_list_82575 - 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_82575(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);
		hw->mac.ops.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
 *  @addr: pointer to the receive address
 *  @index: receive address array register
 *
 *  Sets the receive address array register at index to the address passed
 *  in by addr.
 *  In the case of fiber serdes, shut down optics and PCS on driver unload
 *  when management pass thru is not enabled.
 **/
static void igb_rar_set_82575(struct e1000_hw *hw, u8 *addr, u32 index)
void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw)
{
	if (index < E1000_RAR_ENTRIES_82575)
		igb_rar_set(hw, addr, index);
	u32 reg;

	if (hw->mac.type != e1000_82576 ||
	    (hw->phy.media_type != e1000_media_type_fiber &&
	     hw->phy.media_type != e1000_media_type_internal_serdes))
		return;

	/* if the management interface is not enabled, then power down */
	if (!igb_enable_mng_pass_thru(hw)) {
		/* Disable PCS to turn off link */
		reg = rd32(E1000_PCS_CFG0);
		reg &= ~E1000_PCS_CFG_PCS_EN;
		wr32(E1000_PCS_CFG0, reg);

		/* shutdown the laser */
		reg = rd32(E1000_CTRL_EXT);
		reg |= E1000_CTRL_EXT_SDP7_DATA;
		wr32(E1000_CTRL_EXT, reg);

		/* flush the write to verify completion */
		wrfl();
		msleep(1);
	}

	return;
}
@@ -854,7 +972,7 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw)
	igb_clear_vfta(hw);

	/* Setup the receive address */
	igb_init_rx_addrs(hw, rar_count);
	igb_init_rx_addrs_82575(hw, rar_count);
	/* Zero out the Multicast HASH table */
	hw_dbg("Zeroing the MTA\n");
	for (i = 0; i < mac->mta_reg_count; i++)
@@ -1113,6 +1231,70 @@ static bool igb_sgmii_active_82575(struct e1000_hw *hw)
	return ret_val;
}

/**
 *  igb_translate_register_82576 - Translate the proper register offset
 *  @reg: e1000 register to be read
 *
 *  Registers in 82576 are located in different offsets than other adapters
 *  even though they function in the same manner.  This function takes in
 *  the name of the register to read and returns the correct offset for
 *  82576 silicon.
 **/
u32 igb_translate_register_82576(u32 reg)
{
	/*
	 * Some of the Kawela registers are located at different
	 * offsets than they are in older adapters.
	 * Despite the difference in location, the registers
	 * function in the same manner.
	 */
	switch (reg) {
	case E1000_TDBAL(0):
		reg = 0x0E000;
		break;
	case E1000_TDBAH(0):
		reg = 0x0E004;
		break;
	case E1000_TDLEN(0):
		reg = 0x0E008;
		break;
	case E1000_TDH(0):
		reg = 0x0E010;
		break;
	case E1000_TDT(0):
		reg = 0x0E018;
		break;
	case E1000_TXDCTL(0):
		reg = 0x0E028;
		break;
	case E1000_RDBAL(0):
		reg = 0x0C000;
		break;
	case E1000_RDBAH(0):
		reg = 0x0C004;
		break;
	case E1000_RDLEN(0):
		reg = 0x0C008;
		break;
	case E1000_RDH(0):
		reg = 0x0C010;
		break;
	case E1000_RDT(0):
		reg = 0x0C018;
		break;
	case E1000_RXDCTL(0):
		reg = 0x0C028;
		break;
	case E1000_SRRCTL(0):
		reg = 0x0C00C;
		break;
	default:
		break;
	}

	return reg;
}

/**
 *  igb_reset_init_script_82575 - Inits HW defaults after reset
 *  @hw: pointer to the HW structure
@@ -1304,7 +1486,7 @@ static struct e1000_mac_operations e1000_mac_ops_82575 = {
	.reset_hw             = igb_reset_hw_82575,
	.init_hw              = igb_init_hw_82575,
	.check_for_link       = igb_check_for_link_82575,
	.rar_set              = igb_rar_set_82575,
	.rar_set              = igb_rar_set,
	.read_mac_addr        = igb_read_mac_addr_82575,
	.get_speed_and_duplex = igb_get_speed_and_duplex_copper,
};
+9 −0
Original line number Diff line number Diff line
@@ -28,9 +28,13 @@
#ifndef _E1000_82575_H_
#define _E1000_82575_H_

u32 igb_translate_register_82576(u32 reg);
void igb_update_mc_addr_list_82575(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);

#define E1000_RAR_ENTRIES_82575   16
#define E1000_RAR_ENTRIES_82576   24

/* SRRCTL bit definitions */
#define E1000_SRRCTL_BSIZEPKT_SHIFT                     10 /* Shift _right_ */
@@ -159,5 +163,10 @@ struct e1000_adv_tx_context_desc {
#define E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */

/* Additional DCA related definitions, note change in position of CPUID */
#define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */
#define E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */
#define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */
#define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */

#endif
+10 −0
Original line number Diff line number Diff line
@@ -90,6 +90,11 @@
#define E1000_I2CCMD_ERROR            0x80000000
#define E1000_MAX_SGMII_PHY_REG_ADDR  255
#define E1000_I2CCMD_PHY_TIMEOUT      200
#define E1000_IVAR_VALID              0x80
#define E1000_GPIE_NSICR              0x00000001
#define E1000_GPIE_MSIX_MODE          0x00000010
#define E1000_GPIE_EIAME              0x40000000
#define E1000_GPIE_PBA                0x80000000

/* Receive Descriptor bit definitions */
#define E1000_RXD_STAT_DD       0x01    /* Descriptor Done */
@@ -213,6 +218,7 @@
/* Device Control */
#define E1000_CTRL_FD       0x00000001  /* Full duplex.0=half; 1=full */
#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
#define E1000_CTRL_LRST     0x00000008  /* Link reset. 0=normal,1=reset */
#define E1000_CTRL_ASDE     0x00000020  /* Auto-speed detect enable */
#define E1000_CTRL_SLU      0x00000040  /* Set link up (Force Link) */
#define E1000_CTRL_ILOS     0x00000080  /* Invert Loss-Of Signal */
@@ -244,6 +250,7 @@
 */

#define E1000_CONNSW_ENRGSRC             0x4
#define E1000_PCS_CFG_PCS_EN             8
#define E1000_PCS_LCTL_FLV_LINK_UP       1
#define E1000_PCS_LCTL_FSV_100           2
#define E1000_PCS_LCTL_FSV_1000          4
@@ -253,6 +260,7 @@
#define E1000_PCS_LCTL_AN_ENABLE         0x10000
#define E1000_PCS_LCTL_AN_RESTART        0x20000
#define E1000_PCS_LCTL_AN_TIMEOUT        0x40000
#define E1000_ENABLE_SERDES_LOOPBACK     0x0410

#define E1000_PCS_LSTS_LINK_OK           1
#define E1000_PCS_LSTS_SPEED_100         2
@@ -360,6 +368,7 @@
#define E1000_PBA_16K 0x0010    /* 16KB, default TX allocation */
#define E1000_PBA_24K 0x0018
#define E1000_PBA_34K 0x0022
#define E1000_PBA_64K 0x0040    /* 64KB */

#define IFS_MAX       80
#define IFS_MIN       40
@@ -528,6 +537,7 @@
/* PHY Control Register */
#define MII_CR_FULL_DUPLEX      0x0100  /* FDX =1, half duplex =0 */
#define MII_CR_RESTART_AUTO_NEG 0x0200  /* Restart auto negotiation */
#define MII_CR_POWER_DOWN       0x0800  /* Power down */
#define MII_CR_AUTO_NEG_EN      0x1000  /* Auto Neg Enable */
#define MII_CR_LOOPBACK         0x4000  /* 0 = normal, 1 = loopback */
#define MII_CR_RESET            0x8000  /* 0 = normal, 1 = PHY reset */
+8 −0
Original line number Diff line number Diff line
@@ -38,6 +38,10 @@

struct e1000_hw;

#define E1000_DEV_ID_82576                    0x10C9
#define E1000_DEV_ID_82576_FIBER              0x10E6
#define E1000_DEV_ID_82576_SERDES             0x10E7
#define E1000_DEV_ID_82576_QUAD_COPPER        0x10E8
#define E1000_DEV_ID_82575EB_COPPER           0x10A7
#define E1000_DEV_ID_82575EB_FIBER_SERDES     0x10A9
#define E1000_DEV_ID_82575GB_QUAD_COPPER      0x10D6
@@ -50,6 +54,7 @@ struct e1000_hw;
enum e1000_mac_type {
	e1000_undefined = 0,
	e1000_82575,
	e1000_82576,
	e1000_num_macs  /* List is 1-based, so subtract 1 for true count. */
};

@@ -410,14 +415,17 @@ struct e1000_mac_operations {
	s32  (*check_for_link)(struct e1000_hw *);
	s32  (*reset_hw)(struct e1000_hw *);
	s32  (*init_hw)(struct e1000_hw *);
	bool (*check_mng_mode)(struct e1000_hw *);
	s32  (*setup_physical_interface)(struct e1000_hw *);
	void (*rar_set)(struct e1000_hw *, u8 *, u32);
	s32  (*read_mac_addr)(struct e1000_hw *);
	s32  (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *);
	void (*mta_set)(struct e1000_hw *, u32);
};

struct e1000_phy_operations {
	s32  (*acquire_phy)(struct e1000_hw *);
	s32  (*check_reset_block)(struct e1000_hw *);
	s32  (*force_speed_duplex)(struct e1000_hw *);
	s32  (*get_cfg_done)(struct e1000_hw *hw);
	s32  (*get_cable_length)(struct e1000_hw *);
+1 −2
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@

static s32 igb_set_default_fc(struct e1000_hw *hw);
static s32 igb_set_fc_watermarks(struct e1000_hw *hw);
static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);

/**
 *  igb_remove_device - Free device specific structure
@@ -360,7 +359,7 @@ void igb_update_mc_addr_list(struct e1000_hw *hw,
 *  the multicast filter table array address and new table value.  See
 *  igb_mta_set()
 **/
static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
{
	u32 hash_value, hash_mask;
	u8 bit_shift = 0;
Loading