Add untested support for Ice Lake and Cannon Lake Ethernet to em(4).
The only path difference compared to spt for cnp is not taking
'SPT Si errata workaround to avoid data corruption'.  The flash access
and everything else looks identical to spt in FreeBSD and Linux.

Index: if_em.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em.c,v
retrieving revision 1.338
diff -u -p -r1.338 if_em.c
--- if_em.c     10 Mar 2018 04:41:36 -0000      1.338
+++ if_em.c     10 Mar 2018 04:45:13 -0000
@@ -152,10 +152,18 @@ const struct pci_matchid em_devices[] = 
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_LM3 },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_LM4 },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_LM5 },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_LM6 },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_LM7 },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_LM8 },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_LM9 },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V2 },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V4 },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V5 },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V6 },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V7 },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V8 },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V9 },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_COPPER },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_FIBER },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_SERDES },
@@ -451,6 +459,7 @@ em_attach(struct device *parent, struct 
                case em_pch2lan:
                case em_pch_lpt:
                case em_pch_spt:
+               case em_pch_cnp:
                case em_80003es2lan:
                        /* 9K Jumbo Frame size */
                        sc->hw.max_frame_size = 9234;
@@ -862,6 +871,7 @@ em_init(void *arg)
        case em_pch2lan:
        case em_pch_lpt:
        case em_pch_spt:
+       case em_pch_cnp:
                pba = E1000_PBA_26K;
                break;
        default:
@@ -1526,7 +1536,7 @@ em_stop(void *arg, int softonly)
 
        if (!softonly)
                em_disable_intr(sc);
-       if (sc->hw.mac_type == em_pch_spt)
+       if (sc->hw.mac_type >= em_pch_spt)
                em_flush_desc_rings(sc);
        if (!softonly)
                em_reset_hw(&sc->hw);
@@ -1589,7 +1599,7 @@ em_legacy_irq_quirk_spt(struct em_softc 
        uint32_t        reg;
 
        /* Legacy interrupt: SPT needs a quirk. */
-       if (sc->hw.mac_type != em_pch_spt)
+       if (sc->hw.mac_type != em_pch_spt && sc->hw.mac_type != em_pch_cnp)
                return;
        if (sc->legacy_irq == 0)
                return;
@@ -1660,7 +1670,7 @@ em_allocate_pci_resources(struct em_soft
 
        sc->osdep.em_flashoffset = 0;
        /* for ICH8 and family we need to find the flash memory */
-       if (sc->hw.mac_type == em_pch_spt) {
+       if (sc->hw.mac_type >= em_pch_spt) {
                sc->osdep.flash_bus_space_tag = sc->osdep.mem_bus_space_tag;
                sc->osdep.flash_bus_space_handle = 
sc->osdep.mem_bus_space_handle;
                sc->osdep.em_flashbase = 0;
@@ -1769,7 +1779,7 @@ em_hardware_init(struct em_softc *sc)
        u_int16_t rx_buffer_size;
 
        INIT_DEBUGOUT("em_hardware_init: begin");
-       if (sc->hw.mac_type == em_pch_spt)
+       if (sc->hw.mac_type >= em_pch_spt)
                em_flush_desc_rings(sc);
        /* Issue a global reset */
        em_reset_hw(&sc->hw);
Index: if_em_hw.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em_hw.c,v
retrieving revision 1.96
diff -u -p -r1.96 if_em_hw.c
--- if_em_hw.c  10 Mar 2018 04:41:36 -0000      1.96
+++ if_em_hw.c  10 Mar 2018 04:45:16 -0000
@@ -627,6 +627,16 @@ em_set_mac_type(struct em_hw *hw)
        case E1000_DEV_ID_PCH_SPT_I219_V5:
                hw->mac_type = em_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:
+               hw->mac_type = em_pch_cnp;
+               break;
        case E1000_DEV_ID_EP80579_LAN_1:
                hw->mac_type = em_icp_xxxx;
                hw->icp_xxxx_port_num = 0;
@@ -658,6 +668,7 @@ em_set_mac_type(struct em_hw *hw)
        case em_pch2lan:
        case em_pch_lpt:
        case em_pch_spt:
+       case em_pch_cnp:
                hw->swfwhw_semaphore_present = TRUE;
                hw->asf_firmware_present = TRUE;
                break;
@@ -755,6 +766,7 @@ em_set_media_type(struct em_hw *hw)
                case em_pch2lan:
                case em_pch_lpt:
                case em_pch_spt:
+               case em_pch_cnp:
                case em_82573:
                case em_82574:
                        /*
@@ -913,6 +925,7 @@ em_reset_hw(struct em_hw *hw)
        case em_pch2lan:
        case em_pch_lpt:
        case em_pch_spt:
+       case em_pch_cnp:
                if (!hw->phy_reset_disable &&
                    em_check_phy_reset_block(hw) == E1000_SUCCESS) {
                        /*
@@ -1162,6 +1175,7 @@ em_initialize_hardware_bits(struct em_hw
                case em_pch2lan:
                case em_pch_lpt:
                case em_pch_spt:
+               case em_pch_cnp:
                        if (hw->mac_type == em_ich8lan)
                                /* Set TARC0 bits 29 and 28 */
                                reg_tarc0 |= 0x30000000;
@@ -1423,7 +1437,8 @@ em_init_hw(struct em_hw *hw)
        if (hw->mac_type == em_pchlan ||
                hw->mac_type == em_pch2lan ||
                hw->mac_type == em_pch_lpt ||
-               hw->mac_type == em_pch_spt) {
+               hw->mac_type == em_pch_spt ||
+               hw->mac_type == em_pch_cnp) {
                /*
                 * The MAC-PHY interconnect may still be in SMBus mode
                 * after Sx->S0.  Toggle the LANPHYPC Value bit to force
@@ -1636,6 +1651,7 @@ em_init_hw(struct em_hw *hw)
        case em_pch2lan:
        case em_pch_lpt:
        case em_pch_spt:
+       case em_pch_cnp:
                ctrl = E1000_READ_REG(hw, TXDCTL1);
                ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | 
                    E1000_TXDCTL_FULL_TX_DESC_WB;
@@ -1768,6 +1784,7 @@ em_setup_link(struct em_hw *hw)
                case em_pch2lan:
                case em_pch_lpt:
                case em_pch_spt:
+               case em_pch_cnp:
                case em_82573:
                case em_82574:
                        hw->fc = E1000_FC_FULL;
@@ -2219,7 +2236,8 @@ em_copper_link_igp_setup(struct em_hw *h
        if (hw->mac_type == em_pchlan ||
                hw->mac_type == em_pch2lan ||
                hw->mac_type == em_pch_lpt ||
-               hw->mac_type == em_pch_spt)
+               hw->mac_type == em_pch_spt ||
+               hw->mac_type == em_pch_cnp)
                ret_val = em_set_lplu_state_pchlan(hw, FALSE);
        else
                ret_val = em_set_d0_lplu_state(hw, FALSE);
@@ -2492,7 +2510,8 @@ em_copper_link_mgp_setup(struct em_hw *h
        if (hw->mac_type == em_pchlan ||
                hw->mac_type == em_pch2lan ||
                hw->mac_type == em_pch_lpt ||
-               hw->mac_type == em_pch_spt)
+               hw->mac_type == em_pch_spt ||
+               hw->mac_type == em_pch_cnp)
                ret_val = em_set_lplu_state_pchlan(hw, FALSE);
 
        /* Enable CRS on TX. This must be set for half-duplex operation. */
@@ -2964,6 +2983,7 @@ em_setup_copper_link(struct em_hw *hw)
        case em_pch2lan:
        case em_pch_lpt:
        case em_pch_spt:
+       case em_pch_cnp:
                /*
                 * Set the mac to wait the maximum time between each
                 * iteration and increase the max iterations when polling the
@@ -4132,7 +4152,8 @@ em_check_for_link(struct em_hw *hw)
                        /* Enable/Disable EEE after link up */
                        if (hw->mac_type == em_pch2lan ||
                            hw->mac_type == em_pch_lpt ||
-                           hw->mac_type == em_pch_spt) {
+                           hw->mac_type == em_pch_spt ||
+                           hw->mac_type == em_pch_cnp) {
                                ret_val = em_set_eee_pchlan(hw);
                                if (ret_val)
                                        return ret_val;
@@ -4918,7 +4939,8 @@ em_read_phy_reg(struct em_hw *hw, uint32
        if (hw->mac_type == em_pchlan ||
                hw->mac_type == em_pch2lan ||
                hw->mac_type == em_pch_lpt ||
-               hw->mac_type == em_pch_spt)
+               hw->mac_type == em_pch_spt ||
+               hw->mac_type == em_pch_cnp)
                return (em_access_phy_reg_hv(hw, reg_addr, phy_data, TRUE));
 
        if (((hw->mac_type == em_80003es2lan) || (hw->mac_type == em_82575)) &&
@@ -5031,7 +5053,8 @@ em_read_phy_reg_ex(struct em_hw *hw, uin
                }
                *phy_data = (uint16_t) mdic;
 
-               if (hw->mac_type == em_pch2lan || hw->mac_type == em_pch_lpt || 
hw->mac_type == em_pch_spt)
+               if (hw->mac_type == em_pch2lan || hw->mac_type == em_pch_lpt ||
+                   hw->mac_type == em_pch_spt || hw->mac_type == em_pch_cnp)
                        usec_delay(100);
        } else {
                /*
@@ -5083,7 +5106,8 @@ em_write_phy_reg(struct em_hw *hw, uint3
        if (hw->mac_type == em_pchlan ||
                hw->mac_type == em_pch2lan ||
                hw->mac_type == em_pch_lpt ||
-               hw->mac_type == em_pch_spt)
+               hw->mac_type == em_pch_spt ||
+               hw->mac_type == em_pch_cnp)
                return (em_access_phy_reg_hv(hw, reg_addr, &phy_data, FALSE));
 
        if (em_swfw_sync_acquire(hw, hw->swfw))
@@ -5183,7 +5207,8 @@ em_write_phy_reg_ex(struct em_hw *hw, ui
                        return -E1000_ERR_PHY;
                }
 
-               if (hw->mac_type == em_pch2lan || hw->mac_type == em_pch_lpt || 
hw->mac_type == em_pch_spt)
+               if (hw->mac_type == em_pch2lan || hw->mac_type == em_pch_lpt ||
+                   hw->mac_type == em_pch_spt || hw->mac_type == em_pch_cnp)
                        usec_delay(100);
        } else {
                /*
@@ -5673,6 +5698,7 @@ em_match_gig_phy(struct em_hw *hw)
                break;
        case em_pch_lpt:
        case em_pch_spt:
+       case em_pch_cnp:
                if (hw->phy_id == I217_E_PHY_ID)
                        match = TRUE;
                break;
@@ -6001,6 +6027,7 @@ em_init_eeprom_params(struct em_hw *hw)
                        break;
                }
        case em_pch_spt:
+       case em_pch_cnp:
                {
                        int32_t         i = 0;
                        uint32_t        flash_size = EM_READ_REG(hw, 0xc /* 
STRAP */);
@@ -6715,6 +6742,7 @@ em_validate_eeprom_checksum(struct em_hw
                switch (hw->mac_type) {
                case em_pch_lpt:
                case em_pch_spt:
+               case em_pch_cnp:
                        word = EEPROM_COMPAT;
                        valid_csum_mask = EEPROM_COMPAT_VALID_CSUM;
                        break;
@@ -7376,7 +7404,8 @@ em_init_rx_addrs(struct em_hw *hw)
        uint32_t rar_num;
        DEBUGFUNC("em_init_rx_addrs");
 
-       if (hw->mac_type == em_pch_lpt || hw->mac_type == em_pch_spt || 
hw->mac_type == em_pch2lan)
+       if (hw->mac_type == em_pch_lpt || hw->mac_type == em_pch_spt ||
+           hw->mac_type == em_pch_cnp || hw->mac_type == em_pch2lan)
                if (em_phy_no_cable_workaround(hw))
                        printf(" ...failed to apply em_phy_no_cable_"
                            "workaround.\n");
@@ -7933,7 +7962,8 @@ em_clear_hw_cntrs(struct em_hw *hw)
            hw->mac_type == em_ich9lan ||
            hw->mac_type == em_ich10lan ||
            hw->mac_type == em_pchlan ||
-           (hw->mac_type != em_pch2lan && hw->mac_type != em_pch_lpt && 
hw->mac_type != em_pch_spt))
+           (hw->mac_type != em_pch2lan && hw->mac_type != em_pch_lpt &&
+            hw->mac_type != em_pch_spt && hw->mac_type != em_pch_cnp))
                return;
 
        temp = E1000_READ_REG(hw, ICRXPTC);
@@ -8076,6 +8106,7 @@ em_get_bus_info(struct em_hw *hw)
        case em_pch2lan:
        case em_pch_lpt:
        case em_pch_spt:
+       case em_pch_cnp:
                hw->bus_type = em_bus_type_pci_express;
                hw->bus_speed = em_bus_speed_2500;
                hw->bus_width = em_bus_width_pciex_1;
@@ -9269,6 +9300,7 @@ em_get_auto_rd_done(struct em_hw *hw)
        case em_pch2lan:
        case em_pch_lpt:
        case em_pch_spt:
+       case em_pch_cnp:
                while (timeout) {
                        if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD)
                                break;
@@ -9635,6 +9667,7 @@ em_valid_nvm_bank_detect_ich8lan(struct 
 
        switch (hw->mac_type) {
        case em_pch_spt:
+       case em_pch_cnp:
                bank1_offset = hw->flash_bank_size * 2;
                act_offset = E1000_ICH_NVM_SIG_WORD * 2;
 
@@ -9730,7 +9763,7 @@ em_read_eeprom_spt(struct em_hw *hw, uin
         * each read.
         */
 
-       if (hw->mac_type != em_pch_spt)
+       if (hw->mac_type < em_pch_spt)
                return -E1000_ERR_EEPROM;
 
        error = em_get_software_flag(hw);
@@ -9824,7 +9857,7 @@ em_read_eeprom_ich8(struct em_hw *hw, ui
         * each read.
         */
 
-       if (hw->mac_type == em_pch_spt)
+       if (hw->mac_type >= em_pch_spt)
                return em_read_eeprom_spt(hw, offset, words, data);
 
        error = em_get_software_flag(hw);
@@ -9931,7 +9964,7 @@ em_ich8_cycle_init(struct em_hw *hw)
        int32_t i = 0;
        DEBUGFUNC("em_ich8_cycle_init");
 
-       if (hw->mac_type == em_pch_spt)
+       if (hw->mac_type >= em_pch_spt)
                hsfsts.regval = E1000_READ_ICH_FLASH_REG32(hw,
                    ICH_FLASH_HSFSTS) & 0xFFFFUL;
        else
@@ -9948,7 +9981,7 @@ em_ich8_cycle_init(struct em_hw *hw)
        /* Clear DAEL in Hw status by writing a 1 */
        hsfsts.hsf_status.flcerr = 1;
        hsfsts.hsf_status.dael = 1;
-       if (hw->mac_type == em_pch_spt)
+       if (hw->mac_type >= em_pch_spt)
                E1000_WRITE_ICH_FLASH_REG32(hw, ICH_FLASH_HSFSTS,
                    hsfsts.regval & 0xFFFFUL);
        else
@@ -9973,7 +10006,7 @@ em_ich8_cycle_init(struct em_hw *hw)
                 */
                /* Begin by setting Flash Cycle Done. */
                hsfsts.hsf_status.flcdone = 1;
-               if (hw->mac_type == em_pch_spt)
+               if (hw->mac_type >= em_pch_spt)
                        E1000_WRITE_ICH_FLASH_REG32(hw, ICH_FLASH_HSFSTS,
                            hsfsts.regval & 0xFFFFUL);
                else
@@ -9986,7 +10019,7 @@ em_ich8_cycle_init(struct em_hw *hw)
                 * chance to end before giving up.
                 */
                for (i = 0; i < ICH_FLASH_COMMAND_TIMEOUT; i++) {
-                       if (hw->mac_type == em_pch_spt)
+                       if (hw->mac_type >= em_pch_spt)
                                hsfsts.regval = E1000_READ_ICH_FLASH_REG32(
                                    hw, ICH_FLASH_HSFSTS) & 0xFFFFUL;
                        else
@@ -10004,7 +10037,7 @@ em_ich8_cycle_init(struct em_hw *hw)
                         * timeout, now set the Flash Cycle Done.
                         */
                        hsfsts.hsf_status.flcdone = 1;
-                       if (hw->mac_type == em_pch_spt)
+                       if (hw->mac_type >= em_pch_spt)
                                E1000_WRITE_ICH_FLASH_REG32(hw,
                                    ICH_FLASH_HSFSTS, hsfsts.regval & 0xFFFFUL);
                        else
@@ -10031,7 +10064,7 @@ em_ich8_flash_cycle(struct em_hw *hw, ui
        uint32_t i = 0;
 
        /* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */
-       if (hw->mac_type == em_pch_spt)
+       if (hw->mac_type >= em_pch_spt)
                hsflctl.regval = E1000_READ_ICH_FLASH_REG32(hw,
                    ICH_FLASH_HSFSTS) >> 16;
        else
@@ -10039,7 +10072,7 @@ em_ich8_flash_cycle(struct em_hw *hw, ui
                    ICH_FLASH_HSFCTL);
        hsflctl.hsf_ctrl.flcgo = 1;
 
-       if (hw->mac_type == em_pch_spt)
+       if (hw->mac_type >= em_pch_spt)
                E1000_WRITE_ICH_FLASH_REG32(hw, ICH_FLASH_HSFSTS,
                    (uint32_t)hsflctl.regval << 16);
        else
@@ -10048,7 +10081,7 @@ em_ich8_flash_cycle(struct em_hw *hw, ui
 
        /* wait till FDONE bit is set to 1 */
        do {
-               if (hw->mac_type == em_pch_spt)
+               if (hw->mac_type >= em_pch_spt)
                        hsfsts.regval = E1000_READ_ICH_FLASH_REG32(hw,
                            ICH_FLASH_HSFSTS) & 0xFFFFUL;
                else
@@ -10164,7 +10197,7 @@ em_read_ich8_data32(struct em_hw *hw, ui
        uint32_t  count = 0;
        DEBUGFUNC("em_read_ich8_data32");
 
-       if (hw->mac_type != em_pch_spt)
+       if (hw->mac_type < em_pch_spt)
                return error;
        if (offset > ICH_FLASH_LINEAR_ADDR_MASK)
                return error;
@@ -10251,7 +10284,7 @@ em_write_ich8_data(struct em_hw *hw, uin
        int32_t  count = 0;
        DEBUGFUNC("em_write_ich8_data");
 
-       if (hw->mac_type == em_pch_spt)
+       if (hw->mac_type >= em_pch_spt)
                return -E1000_ERR_EEPROM;
        if (size < 1 || size > 2 || data > size * 0xff ||
            index > ICH_FLASH_LINEAR_ADDR_MASK)
@@ -10330,7 +10363,7 @@ em_read_ich8_byte(struct em_hw *hw, uint
        int32_t  status = E1000_SUCCESS;
        uint16_t word = 0;
 
-       if (hw->mac_type == em_pch_spt)
+       if (hw->mac_type >= em_pch_spt)
                return -E1000_ERR_EEPROM;
        else
                status = em_read_ich8_data(hw, index, 1, &word);
@@ -10735,7 +10768,8 @@ em_init_lcd_from_nvm(struct em_hw *hw)
            hw->mac_type == em_pchlan ||
            hw->mac_type == em_pch2lan ||
            hw->mac_type == em_pch_lpt ||
-           hw->mac_type == em_pch_spt)
+           hw->mac_type == em_pch_spt ||
+           hw->mac_type == em_pch_cnp)
                sw_cfg_mask = FEXTNVM_SW_CONFIG_ICH8M;
        else
                sw_cfg_mask = FEXTNVM_SW_CONFIG;
Index: if_em_hw.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em_hw.h,v
retrieving revision 1.72
diff -u -p -r1.72 if_em_hw.h
--- if_em_hw.h  10 Mar 2018 04:35:01 -0000      1.72
+++ if_em_hw.h  10 Mar 2018 04:45:18 -0000
@@ -81,6 +81,7 @@ typedef enum {
     em_pch2lan,
     em_pch_lpt,
     em_pch_spt,
+    em_pch_cnp,
     em_num_macs
 } em_mac_type;
 

Reply via email to