Print this page
MFV: illumos-gate@5bb0bdfe588c5df0f63ff8ac292cd608a5f4492a
9950 Need support for Intel I219 v6-v9
Reviewed by: Jason King <jason.king@joyent.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Garrett D'Amore <garrett@damore.org>
Author: Robert Mustacchi <rm@joyent.com>

@@ -241,12 +241,11 @@
         }
 
         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)) {
                         /* Unforce SMBus mode in PHY */
                         hw->phy.ops.read_reg_locked(hw, CV_SMB_CTRL, &phy_reg);

@@ -343,10 +342,11 @@
          * LANPHYPC Value bit to force the interconnect to PCIe mode.
          */
         switch (hw->mac.type) {
         case e1000_pch_lpt:
         case e1000_pch_spt:
+        case e1000_pch_cnp:
                 if (e1000_phy_is_accessible_pchlan(hw))
                         break;
 
                 /* Before toggling LANPHYPC, see if PHY is accessible by
                  * forcing MAC to SMBus mode first.

@@ -491,10 +491,11 @@
                                 break;
                         /* fall-through */
                 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.
                          */
                         ret_val = e1000_set_mdio_slow_mode_hv(hw);
                         if (ret_val)

@@ -639,11 +640,11 @@
 
         DEBUGFUNC("e1000_init_nvm_params_ich8lan");
 
         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,
                  * the mechanism has changed, and the Flash region access
                  * registers are now implemented in GbE memory space.

@@ -699,11 +700,11 @@
         E1000_MUTEX_INIT(&dev_spec->swflag_mutex);
 
         /* 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 {
                 nvm->ops.read   = e1000_read_nvm_ich8lan;
                 nvm->ops.update = e1000_update_nvm_checksum_ich8lan;

@@ -792,10 +793,11 @@
                 mac->rar_entry_count = E1000_PCH2_RAR_ENTRIES;
                 mac->ops.rar_set = e1000_rar_set_pch2lan;
                 /* 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;
                 /* fall-through */
         case e1000_pchlan:

@@ -813,12 +815,11 @@
                 break;
         default:
                 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;
                 mac->ops.set_obff_timer = e1000_set_obff_timer_pch_lpt;
         }

@@ -1574,13 +1575,11 @@
 
         /* When connected at 10Mbps half-duplex, some parts are excessively
          * 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);
                 tipg_reg = E1000_READ_REG(hw, E1000_TIPG);
                 tipg_reg &= ~E1000_TIPG_IPGT_MASK;

@@ -1587,11 +1586,11 @@
 
                 if (duplex == HALF_DUPLEX && speed == SPEED_10) {
                         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;
                 } else {
                         /* Roll back the default values */

@@ -1609,12 +1608,11 @@
                         emi_addr = I82579_RX_CONFIG;
                 else
                         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,
                                                     &phy_reg);
                         phy_reg &= ~I217_PLL_CLOCK_GATE_MASK;

@@ -1639,11 +1637,11 @@
                 hw->phy.ops.release(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;
 
                         if (speed == SPEED_1000) {
                                 ret_val = hw->phy.ops.acquire(hw);

@@ -1688,12 +1686,11 @@
         /* I217 Packet Loss issue:
          * ensure that FEXTNVM4 Beacon Duration is set correctly
          * 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);
                 mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK;
                 mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC;

@@ -1707,12 +1704,11 @@
             (hw->device_id == E1000_DEV_ID_PCH_I218_V3)) {
                 ret_val = e1000_k1_workaround_lpt_lp(hw, link);
                 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)
                  */
                 ret_val = e1000_platform_pm_pch_lpt(hw, link);

@@ -1721,11 +1717,11 @@
         }
 
         /* 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);
 
                 if ((pcieanacfg & E1000_FEXTNVM6_K1_OFF_ENABLE) &&

@@ -1829,10 +1825,11 @@
                 break;
         case e1000_pchlan:
         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:
                 break;
         }

@@ -2293,10 +2290,11 @@
                 /* Fall-thru */
         case e1000_pchlan:
         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:
                 return ret_val;
         }

@@ -3410,10 +3408,11 @@
 
         DEBUGFUNC("e1000_valid_nvm_bank_detect_ich8lan");
 
         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;
 
                 /* set bank to 0 in case flash read fails */
                 *bank = 0;

@@ -3669,11 +3668,11 @@
         }
 
         /* 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
                 E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval);
 

@@ -3689,11 +3688,11 @@
                 /* There is no cycle running at present,
                  * so we can start a cycle.
                  * 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
                         E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS,
                                                 hsfsts.regval);

@@ -3716,11 +3715,11 @@
                 if (ret_val == E1000_SUCCESS) {
                         /* Successful in waiting for previous cycle to timeout,
                          * 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
                                 E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS,
                                                         hsfsts.regval);

@@ -3746,17 +3745,17 @@
         u32 i = 0;
 
         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
                 E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);
 

@@ -3835,11 +3834,11 @@
         u16 word = 0;
 
         /* 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);
 
         if (ret_val)

@@ -3943,12 +3942,11 @@
         s32 ret_val = -E1000_ERR_NVM;
         u8 count = 0;
 
         DEBUGFUNC("e1000_read_flash_data_ich8lan");
 
-                if (offset > ICH_FLASH_LINEAR_ADDR_MASK ||
-                    hw->mac.type != e1000_pch_spt)
+        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);
 
         do {

@@ -4385,10 +4383,11 @@
          * the checksum...a likely scenario.
          */
         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;
         default:
                 word = NVM_FUTURE_INIT_WORD1;

@@ -4432,11 +4431,11 @@
         s32 ret_val;
         u8 count = 0;
 
         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 {
                 if (size < 1 || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK)
                         return -E1000_ERR_NVM;

@@ -4452,13 +4451,13 @@
                 if (ret_val != E1000_SUCCESS)
                         break;
                 /* 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);
 
                 /* 0b/1b corresponds to 1 or 2 byte size, respectively. */

@@ -4466,11 +4465,11 @@
                 hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE;
                 /* 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)
                         E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
                                               hsflctl.regval << 16);
                 else
                         E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL,
                                                 hsflctl.regval);

@@ -4528,11 +4527,11 @@
         s32 ret_val;
         u8 count = 0;
 
         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;
         }
         flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) +
                              hw->nvm.flash_base_addr);

@@ -4544,11 +4543,11 @@
                         break;
 
                 /* 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;
                 else
                         hsflctl.regval = E1000_READ_FLASH_REG16(hw,

@@ -4559,11 +4558,11 @@
 
                 /* 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)
                         E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
                                               hsflctl.regval << 16);
                 else
                         E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL,
                                                 hsflctl.regval);

@@ -4761,21 +4760,21 @@
                                 return ret_val;
 
                         /* 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;
                         else
                                 hsflctl.regval =
                                     E1000_READ_FLASH_REG16(hw,
                                                            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
                                 E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL,
                                                         hsflctl.regval);

@@ -5209,12 +5208,11 @@
         if (hw->mac.type == e1000_ich8lan)
                 reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS);
         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);
 
                 reg = E1000_READ_REG(hw, E1000_CTRL);

@@ -5643,11 +5641,11 @@
 
                 if ((device_id == E1000_DEV_ID_PCH_LPTLP_I218_LM) ||
                     (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,
                                         fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK);
                 }