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

Commit ab405612 authored by Sasha Neftin's avatar Sasha Neftin Committed by Jeff Kirsher
Browse files

igc: Add NVM support



Add code for NVM support and get MAC address, complete probe
method.

Signed-off-by: default avatarSasha Neftin <sasha.neftin@intel.com>
Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Tested-by: default avatarAaron Brown <aaron.f.brown@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent c0071c7a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -7,4 +7,4 @@

obj-$(CONFIG_IGC) += igc.o

igc-objs := igc_main.o igc_mac.o igc_i225.o igc_base.o
igc-objs := igc_main.o igc_mac.o igc_i225.o igc_base.o igc_nvm.o
+6 −0
Original line number Diff line number Diff line
@@ -131,6 +131,10 @@ enum igc_tx_flags {
	IGC_TX_FLAGS_CSUM	= 0x20,
};

enum igc_boards {
	board_base,
};

/* The largest size we can write to the descriptor is 65535.  In order to
 * maintain a power of two alignment we have to limit ourselves to 32K.
 */
@@ -342,6 +346,8 @@ struct igc_adapter {
	spinlock_t nfc_lock;

	struct igc_mac_addr *mac_table;

	struct igc_info ei;
};

/* igc_desc_unused - calculate if we have unused descriptors */
+109 −0
Original line number Diff line number Diff line
@@ -53,6 +53,22 @@ static s32 igc_set_pcie_completion_timeout(struct igc_hw *hw)
	return ret_val;
}

/**
 * igc_check_for_link_base - Check for link
 * @hw: pointer to the HW structure
 *
 * If sgmii is enabled, then use the pcs register to determine link, otherwise
 * use the generic interface for determining link.
 */
static s32 igc_check_for_link_base(struct igc_hw *hw)
{
	s32 ret_val = 0;

	ret_val = igc_check_for_copper_link(hw);

	return ret_val;
}

/**
 * igc_reset_hw_base - Reset hardware
 * @hw: pointer to the HW structure
@@ -107,12 +123,51 @@ static s32 igc_reset_hw_base(struct igc_hw *hw)
	return ret_val;
}

/**
 * igc_init_nvm_params_base - Init NVM func ptrs.
 * @hw: pointer to the HW structure
 */
static s32 igc_init_nvm_params_base(struct igc_hw *hw)
{
	struct igc_nvm_info *nvm = &hw->nvm;
	u32 eecd = rd32(IGC_EECD);
	u16 size;

	size = (u16)((eecd & IGC_EECD_SIZE_EX_MASK) >>
		     IGC_EECD_SIZE_EX_SHIFT);

	/* Added to a constant, "size" becomes the left-shift value
	 * for setting word_size.
	 */
	size += NVM_WORD_SIZE_BASE_SHIFT;

	/* Just in case size is out of range, cap it to the largest
	 * EEPROM size supported
	 */
	if (size > 15)
		size = 15;

	nvm->word_size = BIT(size);
	nvm->opcode_bits = 8;
	nvm->delay_usec = 1;

	nvm->page_size = eecd & IGC_EECD_ADDR_BITS ? 32 : 8;
	nvm->address_bits = eecd & IGC_EECD_ADDR_BITS ?
			    16 : 8;

	if (nvm->word_size == BIT(15))
		nvm->page_size = 128;

	return 0;
}

/**
 * igc_init_mac_params_base - Init MAC func ptrs.
 * @hw: pointer to the HW structure
 */
static s32 igc_init_mac_params_base(struct igc_hw *hw)
{
	struct igc_dev_spec_base *dev_spec = &hw->dev_spec._base;
	struct igc_mac_info *mac = &hw->mac;

	/* Set mta register count */
@@ -125,6 +180,10 @@ static s32 igc_init_mac_params_base(struct igc_hw *hw)
	mac->ops.acquire_swfw_sync = igc_acquire_swfw_sync_i225;
	mac->ops.release_swfw_sync = igc_release_swfw_sync_i225;

	/* Allow a single clear of the SW semaphore on I225 */
	if (mac->type == igc_i225)
		dev_spec->clear_semaphore_once = true;

	return 0;
}

@@ -142,10 +201,43 @@ static s32 igc_get_invariants_base(struct igc_hw *hw)
	if (ret_val)
		goto out;

	/* NVM initialization */
	ret_val = igc_init_nvm_params_base(hw);
	switch (hw->mac.type) {
	case igc_i225:
		ret_val = igc_init_nvm_params_i225(hw);
		break;
	default:
		break;
	}

	if (ret_val)
		goto out;

out:
	return ret_val;
}

/**
 * igc_get_link_up_info_base - Get link speed/duplex info
 * @hw: pointer to the HW structure
 * @speed: stores the current speed
 * @duplex: stores the current duplex
 *
 * This is a wrapper function, if using the serial gigabit media independent
 * interface, use PCS to retrieve the link speed and duplex information.
 * Otherwise, use the generic function to get the link speed and duplex info.
 */
static s32 igc_get_link_up_info_base(struct igc_hw *hw, u16 *speed,
				     u16 *duplex)
{
	s32 ret_val;

	ret_val = igc_get_speed_and_duplex_copper(hw, speed, duplex);

	return ret_val;
}

/**
 * igc_init_hw_base - Initialize hardware
 * @hw: pointer to the HW structure
@@ -184,6 +276,19 @@ static s32 igc_init_hw_base(struct igc_hw *hw)
	return ret_val;
}

/**
 * igc_read_mac_addr_base - Read device MAC address
 * @hw: pointer to the HW structure
 */
static s32 igc_read_mac_addr_base(struct igc_hw *hw)
{
	s32 ret_val = 0;

	ret_val = igc_read_mac_addr(hw);

	return ret_val;
}

/**
 * igc_rx_fifo_flush_base - Clean rx fifo after Rx enable
 * @hw: pointer to the HW structure
@@ -262,6 +367,10 @@ void igc_rx_fifo_flush_base(struct igc_hw *hw)

static struct igc_mac_operations igc_mac_ops_base = {
	.init_hw		= igc_init_hw_base,
	.check_for_link		= igc_check_for_link_base,
	.rar_set		= igc_rar_set,
	.read_mac_addr		= igc_read_mac_addr_base,
	.get_speed_and_duplex	= igc_get_link_up_info_base,
};

const struct igc_info igc_base_info = {
+52 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@
 */
#define IGC_RAH_AV		0x80000000 /* Receive descriptor valid */
#define IGC_RAH_POOL_1		0x00040000
#define IGC_RAL_MAC_ADDR_LEN	4
#define IGC_RAH_MAC_ADDR_LEN	2

/* Error Codes */
#define IGC_SUCCESS			0
@@ -57,9 +59,51 @@
#define IGC_SWSM_SMBI		0x00000001 /* Driver Semaphore bit */
#define IGC_SWSM_SWESMBI	0x00000002 /* FW Semaphore bit */

/* SWFW_SYNC Definitions */
#define IGC_SWFW_EEP_SM		0x1
#define IGC_SWFW_PHY0_SM	0x2

/* NVM Control */
/* Number of milliseconds for NVM auto read done after MAC reset. */
#define AUTO_READ_DONE_TIMEOUT		10
#define IGC_EECD_AUTO_RD		0x00000200  /* NVM Auto Read done */
#define IGC_EECD_REQ		0x00000040 /* NVM Access Request */
#define IGC_EECD_GNT		0x00000080 /* NVM Access Grant */
/* NVM Addressing bits based on type 0=small, 1=large */
#define IGC_EECD_ADDR_BITS		0x00000400
#define IGC_NVM_GRANT_ATTEMPTS		1000 /* NVM # attempts to gain grant */
#define IGC_EECD_SIZE_EX_MASK		0x00007800  /* NVM Size */
#define IGC_EECD_SIZE_EX_SHIFT		11
#define IGC_EECD_FLUPD_I225		0x00800000 /* Update FLASH */
#define IGC_EECD_FLUDONE_I225		0x04000000 /* Update FLASH done*/
#define IGC_EECD_FLASH_DETECTED_I225	0x00080000 /* FLASH detected */
#define IGC_FLUDONE_ATTEMPTS		20000
#define IGC_EERD_EEWR_MAX_COUNT		512 /* buffered EEPROM words rw */

/* Offset to data in NVM read/write registers */
#define IGC_NVM_RW_REG_DATA	16
#define IGC_NVM_RW_REG_DONE	2    /* Offset to READ/WRITE done bit */
#define IGC_NVM_RW_REG_START	1    /* Start operation */
#define IGC_NVM_RW_ADDR_SHIFT	2    /* Shift to the address bits */
#define IGC_NVM_POLL_READ	0    /* Flag for polling for read complete */

/* NVM Word Offsets */
#define NVM_CHECKSUM_REG		0x003F

/* For checksumming, the sum of all words in the NVM should equal 0xBABA. */
#define NVM_SUM				0xBABA

#define NVM_PBA_OFFSET_0		8
#define NVM_PBA_OFFSET_1		9
#define NVM_RESERVED_WORD		0xFFFF
#define NVM_PBA_PTR_GUARD		0xFAFA
#define NVM_WORD_SIZE_BASE_SHIFT	6

/* Collision related configuration parameters */
#define IGC_COLLISION_THRESHOLD		15
#define IGC_CT_SHIFT			4
#define IGC_COLLISION_DISTANCE		63
#define IGC_COLD_SHIFT			12

/* Device Status */
#define IGC_STATUS_FD		0x00000001      /* Full duplex.0=half,1=full */
@@ -70,6 +114,14 @@
#define IGC_STATUS_TXOFF	0x00000010      /* transmission paused */
#define IGC_STATUS_SPEED_100	0x00000040      /* Speed 100Mb/s */
#define IGC_STATUS_SPEED_1000	0x00000080      /* Speed 1000Mb/s */
#define IGC_STATUS_SPEED_2500	0x00400000	/* Speed 2.5Gb/s */

#define SPEED_10		10
#define SPEED_100		100
#define SPEED_1000		1000
#define SPEED_2500		2500
#define HALF_DUPLEX		1
#define FULL_DUPLEX		2

/* Interrupt Cause Read */
#define IGC_ICR_TXDW		BIT(0)	/* Transmit desc written back */
+3 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include "igc_regs.h"
#include "igc_defines.h"
#include "igc_mac.h"
#include "igc_nvm.h"
#include "igc_i225.h"
#include "igc_base.h"

@@ -56,6 +57,8 @@ struct igc_info {
	struct igc_nvm_operations *nvm_ops;
};

extern const struct igc_info igc_base_info;

struct igc_mac_info {
	struct igc_mac_operations ops;

Loading