summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2018-11-30 13:04:56 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2018-11-30 13:04:56 +0000
commit0ab0c69ec646299a62509ae4f83cd6fd04829575 (patch)
tree304f1099408b6fc0e2a844a1330391e2ad902a65
parentcc78e0e8a9ef1c3c42ba267e1850ca73fa4e0395 (diff)
parent416f8d72824083126c8e231fbb5f4b3a8249ace8 (diff)
downloadillumos-joyent-0ab0c69ec646299a62509ae4f83cd6fd04829575.tar.gz
[illumos-gate merge]
commit 416f8d72824083126c8e231fbb5f4b3a8249ace8 9990 loader.efi: check the presence of WaitForKey commit 5bb0bdfe588c5df0f63ff8ac292cd608a5f4492a 9950 Need support for Intel I219 v6-v9
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/efi_console.c127
-rw-r--r--usr/src/pkg/manifests/driver-network-e1000g.mf16
-rw-r--r--usr/src/uts/common/io/e1000api/README.illumos6
-rw-r--r--usr/src/uts/common/io/e1000api/e1000_api.c11
-rw-r--r--usr/src/uts/common/io/e1000api/e1000_hw.h28
-rw-r--r--usr/src/uts/common/io/e1000api/e1000_ich8lan.c76
-rw-r--r--usr/src/uts/common/io/e1000g/e1000g_main.c21
7 files changed, 198 insertions, 87 deletions
diff --git a/usr/src/boot/sys/boot/efi/libefi/efi_console.c b/usr/src/boot/sys/boot/efi/libefi/efi_console.c
index 4bf1944a32..2f504431f3 100644
--- a/usr/src/boot/sys/boot/efi/libefi/efi_console.c
+++ b/usr/src/boot/sys/boot/efi/libefi/efi_console.c
@@ -41,8 +41,7 @@ static SIMPLE_INPUT_INTERFACE *conin;
#define MAXARGS 8
#define KEYBUFSZ 10
static unsigned keybuf[KEYBUFSZ]; /* keybuf for extended codes */
-
-static int pending;
+static int key_pending;
static int args[MAXARGS], argc;
static int fg_c, bg_c;
@@ -494,69 +493,119 @@ efi_cons_putchar(struct console *cp __attribute((unused)), int c)
#endif
}
-int
-efi_cons_getchar(struct console *cp __attribute((unused)))
+static int
+keybuf_getchar(void)
{
- EFI_INPUT_KEY key;
- EFI_STATUS status;
- int i, c;
+ int i, c = 0;
for (i = 0; i < KEYBUFSZ; i++) {
if (keybuf[i] != 0) {
c = keybuf[i];
keybuf[i] = 0;
- return (c);
+ break;
}
}
- pending = 0;
+ return (c);
+}
- status = conin->ReadKeyStroke(conin, &key);
- if (status == EFI_NOT_READY)
- return (-1);
+static bool
+keybuf_ischar(void)
+{
+ int i;
- switch (key.ScanCode) {
+ for (i = 0; i < KEYBUFSZ; i++) {
+ if (keybuf[i] != 0)
+ return (true);
+ }
+ return (false);
+}
+
+/*
+ * We are not reading input before keybuf is empty, so we are safe
+ * just to fill keybuf from the beginning.
+ */
+static void
+keybuf_inschar(EFI_INPUT_KEY *key)
+{
+
+ switch (key->ScanCode) {
case 0x1: /* UP */
- keybuf[0] = '[';
- keybuf[1] = 'A';
- return (0x1b); /* esc */
+ keybuf[0] = 0x1b; /* esc */
+ keybuf[1] = '[';
+ keybuf[2] = 'A';
+ break;
case 0x2: /* DOWN */
- keybuf[0] = '[';
- keybuf[1] = 'B';
- return (0x1b); /* esc */
+ keybuf[0] = 0x1b; /* esc */
+ keybuf[1] = '[';
+ keybuf[2] = 'B';
+ break;
case 0x3: /* RIGHT */
- keybuf[0] = '[';
- keybuf[1] = 'C';
- return (0x1b); /* esc */
+ keybuf[0] = 0x1b; /* esc */
+ keybuf[1] = '[';
+ keybuf[2] = 'C';
+ break;
case 0x4: /* LEFT */
- keybuf[0] = '[';
- keybuf[1] = 'D';
- return (0x1b); /* esc */
- case 0x17: /* ESC */
- return (0x1b); /* esc */
+ keybuf[0] = 0x1b; /* esc */
+ keybuf[1] = '[';
+ keybuf[2] = 'D';
+ break;
+ case 0x17:
+ keybuf[0] = 0x1b; /* esc */
+ break;
+ default:
+ keybuf[0] = key->UnicodeChar;
+ break;
}
+}
- /* this can return */
- return (key.UnicodeChar);
+static bool
+efi_readkey(void)
+{
+ EFI_STATUS status;
+ EFI_INPUT_KEY key;
+
+ status = conin->ReadKeyStroke(conin, &key);
+ if (status == EFI_SUCCESS) {
+ keybuf_inschar(&key);
+ return (true);
+ }
+ return (false);
}
int
-efi_cons_poll(struct console *cp __attribute((unused)))
+efi_cons_getchar(struct console *cp __attribute((unused)))
{
- int i;
+ int c;
- for (i = 0; i < KEYBUFSZ; i++) {
- if (keybuf[i] != 0)
- return (1);
- }
+ if ((c = keybuf_getchar()) != 0)
+ return (c);
+
+ key_pending = 0;
+
+ if (efi_readkey())
+ return (keybuf_getchar());
+
+ return (-1);
+}
- if (pending)
+int
+efi_cons_poll(struct console *cp __attribute((unused)))
+{
+ if (keybuf_ischar() || key_pending)
return (1);
- /* This can clear the signaled state. */
- pending = BS->CheckEvent(conin->WaitForKey) == EFI_SUCCESS;
+ /*
+ * Some EFI implementation (u-boot for example) do not support
+ * WaitForKey().
+ * CheckEvent() can clear the signaled state.
+ */
+ if (conin->WaitForKey == NULL)
+ key_pending = efi_readkey();
+ else
+ key_pending = BS->CheckEvent(conin->WaitForKey) == EFI_SUCCESS;
- return (pending);
+ return (key_pending);
}
/* Plain direct access to EFI OutputString(). */
diff --git a/usr/src/pkg/manifests/driver-network-e1000g.mf b/usr/src/pkg/manifests/driver-network-e1000g.mf
index 727cb7a8e0..10373021ac 100644
--- a/usr/src/pkg/manifests/driver-network-e1000g.mf
+++ b/usr/src/pkg/manifests/driver-network-e1000g.mf
@@ -147,9 +147,17 @@ driver name=e1000g clone_perms="e1000g 0666 root sys" perms="* 0666 root sys" \
alias=pci8086,15b7 \
alias=pci8086,15b8 \
alias=pci8086,15b9 \
+ alias=pci8086,15bb \
+ alias=pci8086,15bc \
+ alias=pci8086,15bd \
+ alias=pci8086,15be \
alias=pci8086,15d6 \
alias=pci8086,15d7 \
alias=pci8086,15d8 \
+ alias=pci8086,15df \
+ alias=pci8086,15e0 \
+ alias=pci8086,15e1 \
+ alias=pci8086,15e2 \
alias=pci8086,15e3 \
alias=pci8086,294c \
alias=pci8086,f0fe \
@@ -215,9 +223,17 @@ driver name=e1000g clone_perms="e1000g 0666 root sys" perms="* 0666 root sys" \
alias=pciex8086,15b7 \
alias=pciex8086,15b8 \
alias=pciex8086,15b9 \
+ alias=pciex8086,15bb \
+ alias=pciex8086,15bc \
+ alias=pciex8086,15bd \
+ alias=pciex8086,15be \
alias=pciex8086,15d6 \
alias=pciex8086,15d7 \
alias=pciex8086,15d8 \
+ alias=pciex8086,15df \
+ alias=pciex8086,15e0 \
+ alias=pciex8086,15e1 \
+ alias=pciex8086,15e2 \
alias=pciex8086,15e3 \
alias=pciex8086,294c \
alias=pciex8086,f0fe
diff --git a/usr/src/uts/common/io/e1000api/README.illumos b/usr/src/uts/common/io/e1000api/README.illumos
index b4335b1470..37cecd0d4d 100644
--- a/usr/src/uts/common/io/e1000api/README.illumos
+++ b/usr/src/uts/common/io/e1000api/README.illumos
@@ -45,6 +45,12 @@ are. DO NOT just blindly copy over new common code. There is more work that
needs to be done in terms of changed interfaces and expectations for the
drivers.
+# Support for Ice Lake and Cannon Lake
+
+Due to several changes that have been made to the core e1000 code in
+FreeBSD that's specific to changes for iflib, a whole sale update was
+not done and instead support was manually merged based on Intel.
+
# e1000_defines.h
In e1000_defines.h we add the following three definitions which are not
diff --git a/usr/src/uts/common/io/e1000api/e1000_api.c b/usr/src/uts/common/io/e1000api/e1000_api.c
index 52e260950d..45dbbfc817 100644
--- a/usr/src/uts/common/io/e1000api/e1000_api.c
+++ b/usr/src/uts/common/io/e1000api/e1000_api.c
@@ -310,6 +310,16 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_PCH_SPT_I219_V5:
mac->type = e1000_pch_spt;
break;
+ case E1000_DEV_ID_PCH_CNP_I219_LM6:
+ case E1000_DEV_ID_PCH_CNP_I219_V6:
+ case E1000_DEV_ID_PCH_CNP_I219_LM7:
+ case E1000_DEV_ID_PCH_CNP_I219_V7:
+ case E1000_DEV_ID_PCH_ICP_I219_LM8:
+ case E1000_DEV_ID_PCH_ICP_I219_V8:
+ case E1000_DEV_ID_PCH_ICP_I219_LM9:
+ case E1000_DEV_ID_PCH_ICP_I219_V9:
+ mac->type = e1000_pch_cnp;
+ break;
case E1000_DEV_ID_82575EB_COPPER:
case E1000_DEV_ID_82575EB_FIBER_SERDES:
case E1000_DEV_ID_82575GB_QUAD_COPPER:
@@ -461,6 +471,7 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
e1000_init_function_pointers_ich8lan(hw);
break;
case e1000_82575:
diff --git a/usr/src/uts/common/io/e1000api/e1000_hw.h b/usr/src/uts/common/io/e1000api/e1000_hw.h
index 98931b74cb..ff9f1ff442 100644
--- a/usr/src/uts/common/io/e1000api/e1000_hw.h
+++ b/usr/src/uts/common/io/e1000api/e1000_hw.h
@@ -146,6 +146,14 @@ struct e1000_hw;
#define E1000_DEV_ID_PCH_SPT_I219_V4 0x15D8
#define E1000_DEV_ID_PCH_SPT_I219_LM5 0x15E3
#define E1000_DEV_ID_PCH_SPT_I219_V5 0x15D6
+#define E1000_DEV_ID_PCH_CNP_I219_LM6 0x15BD
+#define E1000_DEV_ID_PCH_CNP_I219_V6 0x15BE
+#define E1000_DEV_ID_PCH_CNP_I219_LM7 0x15BB
+#define E1000_DEV_ID_PCH_CNP_I219_V7 0x15BC
+#define E1000_DEV_ID_PCH_ICP_I219_LM8 0x15DF
+#define E1000_DEV_ID_PCH_ICP_I219_V8 0x15E0
+#define E1000_DEV_ID_PCH_ICP_I219_LM9 0x15E1
+#define E1000_DEV_ID_PCH_ICP_I219_V9 0x15E2
#define E1000_DEV_ID_82576 0x10C9
#define E1000_DEV_ID_82576_FIBER 0x10E6
#define E1000_DEV_ID_82576_SERDES 0x10E7
@@ -205,6 +213,13 @@ struct e1000_hw;
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN2 6
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN3 9
+/*
+ * This enumeration represents all of the different kinds of MAC chips that are
+ * used by both the e1000g and igb drivers. The ordering here is important as
+ * certain classes of MACs are very similar, but have minor differences and so
+ * are compared based on the ordering here. Changing the order here should not
+ * be done arbitrarily.
+ */
enum e1000_mac_type {
e1000_undefined = 0,
e1000_82542,
@@ -225,6 +240,13 @@ enum e1000_mac_type {
e1000_82574,
e1000_82583,
e1000_80003es2lan,
+ /*
+ * The following MACs all share the ich8 style of hardware and are
+ * implemented in ich8, though some are a little more different than
+ * others. The pch_lpt, pch_spt, and pch_cnp family are a bit more
+ * different than the others and just have slight variants in behavior
+ * between them. They are ordered based on release.
+ */
e1000_ich8lan,
e1000_ich9lan,
e1000_ich10lan,
@@ -232,6 +254,12 @@ enum e1000_mac_type {
e1000_pch2lan,
e1000_pch_lpt,
e1000_pch_spt,
+ e1000_pch_cnp,
+ /*
+ * After this point all MACs are used by the igb(7D) driver as opposed
+ * to e1000g(7D). If a new MAC is specific to e1000g series of devices,
+ * then it should be added above this.
+ */
e1000_82575,
e1000_82576,
e1000_82580,
diff --git a/usr/src/uts/common/io/e1000api/e1000_ich8lan.c b/usr/src/uts/common/io/e1000api/e1000_ich8lan.c
index a08aed6c3c..966e176afd 100644
--- a/usr/src/uts/common/io/e1000api/e1000_ich8lan.c
+++ b/usr/src/uts/common/io/e1000api/e1000_ich8lan.c
@@ -243,8 +243,7 @@ static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw)
if (ret_val)
return FALSE;
out:
- if ((hw->mac.type == e1000_pch_lpt) ||
- (hw->mac.type == e1000_pch_spt)) {
+ if (hw->mac.type >= e1000_pch_lpt) {
/* Only unforce SMBus if ME is not active */
if (!(E1000_READ_REG(hw, E1000_FWSM) &
E1000_ICH_FWSM_FW_VALID)) {
@@ -345,6 +344,7 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
switch (hw->mac.type) {
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
if (e1000_phy_is_accessible_pchlan(hw))
break;
@@ -493,6 +493,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
/* In case the PHY needs to be in mdio slow mode,
* set slow mode and try to get the PHY id again.
*/
@@ -641,7 +642,7 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
nvm->type = e1000_nvm_flash_sw;
- if (hw->mac.type == e1000_pch_spt) {
+ if (hw->mac.type >= e1000_pch_spt) {
/* in SPT, gfpreg doesn't exist. NVM size is taken from the
* STRAP register. This is because in SPT the GbE Flash region
* is no longer accessed through the flash registers. Instead,
@@ -701,7 +702,7 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
/* Function Pointers */
nvm->ops.acquire = e1000_acquire_nvm_ich8lan;
nvm->ops.release = e1000_release_nvm_ich8lan;
- if (hw->mac.type == e1000_pch_spt) {
+ if (hw->mac.type >= e1000_pch_spt) {
nvm->ops.read = e1000_read_nvm_spt;
nvm->ops.update = e1000_update_nvm_checksum_spt;
} else {
@@ -794,6 +795,7 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
/* fall-through */
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
/* multicast address update for pch2 */
mac->ops.update_mc_addr_list =
e1000_update_mc_addr_list_pch2lan;
@@ -815,8 +817,7 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
break;
}
- if ((mac->type == e1000_pch_lpt) ||
- (mac->type == e1000_pch_spt)) {
+ if (mac->type >= e1000_pch_lpt) {
mac->rar_entry_count = E1000_PCH_LPT_RAR_ENTRIES;
mac->ops.rar_set = e1000_rar_set_pch_lpt;
mac->ops.setup_physical_interface = e1000_setup_copper_link_pch_lpt;
@@ -1576,9 +1577,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
* aggressive resulting in many collisions. To avoid this, increase
* the IPG and reduce Rx latency in the PHY.
*/
- if (((hw->mac.type == e1000_pch2lan) ||
- (hw->mac.type == e1000_pch_lpt) ||
- (hw->mac.type == e1000_pch_spt)) && link) {
+ if ((hw->mac.type >= e1000_pch2lan) && link) {
u16 speed, duplex;
e1000_get_speed_and_duplex_copper_generic(hw, &speed, &duplex);
@@ -1589,7 +1588,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
tipg_reg |= 0xFF;
/* Reduce Rx latency in analog PHY */
emi_val = 0;
- } else if (hw->mac.type == e1000_pch_spt &&
+ } else if (hw->mac.type >= e1000_pch_spt &&
duplex == FULL_DUPLEX && speed != SPEED_1000) {
tipg_reg |= 0xC;
emi_val = 1;
@@ -1611,8 +1610,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
emi_addr = I217_RX_CONFIG;
ret_val = e1000_write_emi_reg_locked(hw, emi_addr, emi_val);
- if (hw->mac.type == e1000_pch_lpt ||
- hw->mac.type == e1000_pch_spt) {
+ if (hw->mac.type >= e1000_pch_lpt) {
u16 phy_reg;
hw->phy.ops.read_reg_locked(hw, I217_PLL_CLOCK_GATE_REG,
@@ -1641,7 +1639,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
if (ret_val)
return ret_val;
- if (hw->mac.type == e1000_pch_spt) {
+ if (hw->mac.type >= e1000_pch_spt) {
u16 data;
u16 ptr_gap;
@@ -1690,8 +1688,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
* on power up.
* Set the Beacon Duration for I217 to 8 usec
*/
- if ((hw->mac.type == e1000_pch_lpt) ||
- (hw->mac.type == e1000_pch_spt)) {
+ if (hw->mac.type >= e1000_pch_lpt) {
u32 mac_reg;
mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM4);
@@ -1709,8 +1706,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
if (ret_val)
return ret_val;
}
- if ((hw->mac.type == e1000_pch_lpt) ||
- (hw->mac.type == e1000_pch_spt)) {
+ if (hw->mac.type >= e1000_pch_lpt) {
/* Set platform power management values for
* Latency Tolerance Reporting (LTR)
* Optimized Buffer Flush/Fill (OBFF)
@@ -1723,7 +1719,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
/* Clear link partner's EEE ability */
hw->dev_spec.ich8lan.eee_lp_ability = 0;
- /* FEXTNVM6 K1-off workaround */
+ /* FEXTNVM6 K1-off workaround - for SPT only */
if (hw->mac.type == e1000_pch_spt) {
u32 pcieanacfg = E1000_READ_REG(hw, E1000_PCIEANACFG);
u32 fextnvm6 = E1000_READ_REG(hw, E1000_FEXTNVM6);
@@ -1831,6 +1827,7 @@ void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw)
case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
hw->phy.ops.init_params = e1000_init_phy_params_pchlan;
break;
default:
@@ -2295,6 +2292,7 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
break;
default:
@@ -3412,6 +3410,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
switch (hw->mac.type) {
case e1000_pch_spt:
+ case e1000_pch_cnp:
bank1_offset = nvm->flash_bank_size;
act_offset = E1000_ICH_NVM_SIG_WORD;
@@ -3671,7 +3670,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
/* Clear FCERR and DAEL in hw status by writing 1 */
hsfsts.hsf_status.flcerr = 1;
hsfsts.hsf_status.dael = 1;
- if (hw->mac.type == e1000_pch_spt)
+ if (hw->mac.type >= e1000_pch_spt)
E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
hsfsts.regval & 0xFFFF);
else
@@ -3691,7 +3690,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
* Begin by setting Flash Cycle Done.
*/
hsfsts.hsf_status.flcdone = 1;
- if (hw->mac.type == e1000_pch_spt)
+ if (hw->mac.type >= e1000_pch_spt)
E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
hsfsts.regval & 0xFFFF);
else
@@ -3718,7 +3717,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
* now set the Flash Cycle Done.
*/
hsfsts.hsf_status.flcdone = 1;
- if (hw->mac.type == e1000_pch_spt)
+ if (hw->mac.type >= e1000_pch_spt)
E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
hsfsts.regval & 0xFFFF);
else
@@ -3748,13 +3747,13 @@ static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout)
DEBUGFUNC("e1000_flash_cycle_ich8lan");
/* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */
- if (hw->mac.type == e1000_pch_spt)
+ if (hw->mac.type >= e1000_pch_spt)
hsflctl.regval = E1000_READ_FLASH_REG(hw, ICH_FLASH_HSFSTS)>>16;
else
hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
hsflctl.hsf_ctrl.flcgo = 1;
- if (hw->mac.type == e1000_pch_spt)
+ if (hw->mac.type >= e1000_pch_spt)
E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
hsflctl.regval << 16);
else
@@ -3837,7 +3836,7 @@ static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset,
/* In SPT, only 32 bits access is supported,
* so this function should not be called.
*/
- if (hw->mac.type == e1000_pch_spt)
+ if (hw->mac.type >= e1000_pch_spt)
return -E1000_ERR_NVM;
else
ret_val = e1000_read_flash_data_ich8lan(hw, offset, 1, &word);
@@ -3945,9 +3944,8 @@ static s32 e1000_read_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset,
DEBUGFUNC("e1000_read_flash_data_ich8lan");
- if (offset > ICH_FLASH_LINEAR_ADDR_MASK ||
- hw->mac.type != e1000_pch_spt)
- return -E1000_ERR_NVM;
+ if (offset > ICH_FLASH_LINEAR_ADDR_MASK && hw->mac.type < e1000_pch_spt)
+ return -E1000_ERR_NVM;
flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) +
hw->nvm.flash_base_addr);
@@ -4387,6 +4385,7 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
switch (hw->mac.type) {
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
word = NVM_COMPAT;
valid_csum_mask = NVM_COMPAT_VALID_CSUM;
break;
@@ -4434,7 +4433,7 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
DEBUGFUNC("e1000_write_ich8_data");
- if (hw->mac.type == e1000_pch_spt) {
+ if (hw->mac.type >= e1000_pch_spt) {
if (size != 4 || offset > ICH_FLASH_LINEAR_ADDR_MASK)
return -E1000_ERR_NVM;
} else {
@@ -4454,9 +4453,9 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
/* In SPT, This register is in Lan memory space, not
* flash. Therefore, only 32 bit access is supported
*/
- if (hw->mac.type == e1000_pch_spt)
+ if (hw->mac.type >= e1000_pch_spt)
hsflctl.regval =
- E1000_READ_FLASH_REG(hw, ICH_FLASH_HSFSTS)>>16;
+ E1000_READ_FLASH_REG(hw, ICH_FLASH_HSFSTS) >> 16;
else
hsflctl.regval =
E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
@@ -4468,7 +4467,7 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
* not flash. Therefore, only 32 bit access is
* supported
*/
- if (hw->mac.type == e1000_pch_spt)
+ if (hw->mac.type >= e1000_pch_spt)
E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
hsflctl.regval << 16);
else
@@ -4530,7 +4529,7 @@ static s32 e1000_write_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset,
DEBUGFUNC("e1000_write_flash_data32_ich8lan");
- if (hw->mac.type == e1000_pch_spt) {
+ if (hw->mac.type >= e1000_pch_spt) {
if (offset > ICH_FLASH_LINEAR_ADDR_MASK)
return -E1000_ERR_NVM;
}
@@ -4546,7 +4545,7 @@ static s32 e1000_write_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset,
/* In SPT, This register is in Lan memory space, not
* flash. Therefore, only 32 bit access is supported
*/
- if (hw->mac.type == e1000_pch_spt)
+ if (hw->mac.type >= e1000_pch_spt)
hsflctl.regval = E1000_READ_FLASH_REG(hw,
ICH_FLASH_HSFSTS)
>> 16;
@@ -4561,7 +4560,7 @@ static s32 e1000_write_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset,
* not flash. Therefore, only 32 bit access is
* supported
*/
- if (hw->mac.type == e1000_pch_spt)
+ if (hw->mac.type >= e1000_pch_spt)
E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
hsflctl.regval << 16);
else
@@ -4763,7 +4762,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
/* Write a value 11 (block Erase) in Flash
* Cycle field in hw flash control
*/
- if (hw->mac.type == e1000_pch_spt)
+ if (hw->mac.type >= e1000_pch_spt)
hsflctl.regval =
E1000_READ_FLASH_REG(hw,
ICH_FLASH_HSFSTS)>>16;
@@ -4773,7 +4772,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
ICH_FLASH_HSFCTL);
hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE;
- if (hw->mac.type == e1000_pch_spt)
+ if (hw->mac.type >= e1000_pch_spt)
E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
hsflctl.regval << 16);
else
@@ -5211,8 +5210,7 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_RFCTL, reg);
/* Enable ECC on Lynxpoint */
- if ((hw->mac.type == e1000_pch_lpt) ||
- (hw->mac.type == e1000_pch_spt)) {
+ if (hw->mac.type >= e1000_pch_lpt) {
reg = E1000_READ_REG(hw, E1000_PBECCSTS);
reg |= E1000_PBECCSTS_ECC_ENABLE;
E1000_WRITE_REG(hw, E1000_PBECCSTS, reg);
@@ -5645,7 +5643,7 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)
(device_id == E1000_DEV_ID_PCH_LPTLP_I218_V) ||
(device_id == E1000_DEV_ID_PCH_I218_LM3) ||
(device_id == E1000_DEV_ID_PCH_I218_V3) ||
- (hw->mac.type == e1000_pch_spt)) {
+ (hw->mac.type >= e1000_pch_spt)) {
u32 fextnvm6 = E1000_READ_REG(hw, E1000_FEXTNVM6);
E1000_WRITE_REG(hw, E1000_FEXTNVM6,
diff --git a/usr/src/uts/common/io/e1000g/e1000g_main.c b/usr/src/uts/common/io/e1000g/e1000g_main.c
index de4ebc2971..a2bdebc06e 100644
--- a/usr/src/uts/common/io/e1000g/e1000g_main.c
+++ b/usr/src/uts/common/io/e1000g/e1000g_main.c
@@ -25,7 +25,7 @@
/*
* Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2017, Joyent, Inc.
+ * Copyright (c) 2018, Joyent, Inc.
*/
/*
@@ -711,6 +711,7 @@ e1000g_regs_map(struct e1000g *Adapter)
}
break;
case e1000_pch_spt:
+ case e1000_pch_cnp:
/*
* On the SPT, the device flash is actually in BAR0, not a
* separate BAR. Therefore we end up setting the
@@ -780,7 +781,7 @@ e1000g_regs_map(struct e1000g *Adapter)
regs_map_fail:
if (osdep->reg_handle != NULL)
ddi_regs_map_free(&osdep->reg_handle);
- if (osdep->ich_flash_handle != NULL && hw->mac.type != e1000_pch_spt)
+ if (osdep->ich_flash_handle != NULL && hw->mac.type < e1000_pch_spt)
ddi_regs_map_free(&osdep->ich_flash_handle);
return (DDI_FAILURE);
}
@@ -909,6 +910,7 @@ e1000g_setup_max_mtu(struct e1000g *Adapter)
case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
+ case e1000_pch_cnp:
Adapter->max_mtu = MAXIMUM_MTU_9K;
break;
/* types with a special limit */
@@ -1147,7 +1149,7 @@ e1000g_unattach(dev_info_t *devinfo, struct e1000g *Adapter)
if (Adapter->osdep.reg_handle != NULL)
ddi_regs_map_free(&Adapter->osdep.reg_handle);
if (Adapter->osdep.ich_flash_handle != NULL &&
- Adapter->shared.mac.type != e1000_pch_spt)
+ Adapter->shared.mac.type < e1000_pch_spt)
ddi_regs_map_free(&Adapter->osdep.ich_flash_handle);
if (Adapter->osdep.io_reg_handle != NULL)
ddi_regs_map_free(&Adapter->osdep.io_reg_handle);
@@ -1486,6 +1488,8 @@ e1000g_init(struct e1000g *Adapter)
pba = E1000_PBA_26K;
} else if (hw->mac.type == e1000_pch_spt) {
pba = E1000_PBA_26K;
+ } else if (hw->mac.type == e1000_pch_cnp) {
+ pba = E1000_PBA_26K;
} else {
/*
* Total FIFO is 40K
@@ -1712,10 +1716,10 @@ e1000g_link_up(struct e1000g *Adapter)
case e1000_media_type_copper:
if (hw->mac.get_link_status) {
/*
- * SPT devices need a bit of extra time before we ask
- * them.
+ * SPT and newer devices need a bit of extra time before
+ * we ask them.
*/
- if (hw->mac.type == e1000_pch_spt)
+ if (hw->mac.type >= e1000_pch_spt)
msec_delay(50);
(void) e1000_check_for_link(hw);
if ((E1000_READ_REG(hw, E1000_STATUS) &
@@ -2076,7 +2080,7 @@ e1000g_stop(struct e1000g *Adapter, boolean_t global)
* rings are flushed before we do anything else. This must be done
* before we release DMA resources.
*/
- if (Adapter->shared.mac.type == e1000_pch_spt)
+ if (Adapter->shared.mac.type >= e1000_pch_spt)
e1000g_flush_desc_rings(Adapter);
if (global) {
@@ -2536,8 +2540,7 @@ e1000g_init_unicst(struct e1000g *Adapter)
* additional registers are available. If the value is 2-7, only
* that number are available.
*/
- if (hw->mac.type == e1000_pch_lpt ||
- hw->mac.type == e1000_pch_spt) {
+ if (hw->mac.type >= e1000_pch_lpt) {
uint32_t locked, rar;
locked = E1000_READ_REG(hw, E1000_FWSM) &