hi,

this diff adds support for i82674L gigabit controller, added new phy type (BME1000) which is in most aspects compatible with M88. i've been running this diff on one machine for last
weekend and seems to work fine.

regards
sfires

Index: if_em.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em.c,v
retrieving revision 1.212
diff -u -p -r1.212 if_em.c
--- if_em.c     5 Jun 2009 16:27:40 -0000       1.212
+++ if_em.c     17 Jun 2009 18:45:46 -0000
@@ -116,6 +116,7 @@ const struct pci_matchid em_devices[] =
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82573L_PL_1 },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82573L_PL_2 },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82573V_PM },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82574L },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82575EB_COPPER },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82575EB_SERDES },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82575GB_QUAD_CPR },
@@ -331,6 +332,7 @@ em_attach(struct device *parent, struct
                case em_82572:
                case em_82575:
                case em_ich9lan:
+               case em_82574:
                case em_80003es2lan:    /* Limit Jumbo Frame size */
                        sc->hw.max_frame_size = 9234;
                        break;
@@ -694,6 +696,9 @@ em_init(void *arg)
        case em_82573: /* 82573: Total Packet Buffer is 32K */
                /* Jumbo frames not supported */
                pba = E1000_PBA_12K; /* 12K for Rx, 20K for Tx */
+               break;
+       case em_82574: /* Total Packet Buffer is 40k */
+               pba = E1000_PBA_30K; /* 30K for Rx, 10K for Tx */
                break;
        case em_ich8lan:
                pba = E1000_PBA_8K;
Index: if_em_hw.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em_hw.c,v
retrieving revision 1.33
diff -u -p -r1.33 if_em_hw.c
--- if_em_hw.c  4 Jun 2009 05:08:43 -0000       1.33
+++ if_em_hw.c  17 Jun 2009 18:45:48 -0000
@@ -220,6 +220,11 @@ em_set_phy_type(struct em_hw *hw)
     case IFE_C_E_PHY_ID:
         hw->phy_type = em_phy_ife;
         break;
+    case BME1000_E_PHY_ID:
+        if (hw->phy_revision == 1){
+            hw->phy_type = em_phy_bm;
+            break;
+        }
     case GG82563_E_PHY_ID:
         if (hw->mac_type == em_80003es2lan) {
             hw->phy_type = em_phy_gg82563;
@@ -440,6 +445,9 @@ em_set_mac_type(struct em_hw *hw)
     case E1000_DEV_ID_82573V_PM:
         hw->mac_type = em_82573;
         break;
+    case E1000_DEV_ID_82574L:
+        hw->mac_type = em_82574;
+        break;
     case E1000_DEV_ID_82575EB_PT:
     case E1000_DEV_ID_82575EB_PF:
     case E1000_DEV_ID_82575GB_QP:
@@ -492,6 +500,7 @@ em_set_mac_type(struct em_hw *hw)
     case em_82571:
     case em_82572:
     case em_82573:
+    case em_82574:
         hw->eeprom_semaphore_present = TRUE;
         /* FALLTHROUGH */
     case em_82541:
@@ -543,6 +552,7 @@ em_set_media_type(struct em_hw *hw)
         case em_ich8lan:
         case em_ich9lan:
         case em_82573:
+        case em_82574:
/* The STATUS_TBIMODE bit is reserved or reused for the this
              * device.
              */
@@ -626,7 +636,7 @@ em_reset_hw(struct em_hw *hw)

     /* Must acquire the MDIO ownership before MAC reset.
      * Ownership defaults to firmware after a reset. */
-    if (hw->mac_type == em_82573) {
+    if ((hw->mac_type == em_82573) || (hw->mac_type == em_82574)) {
         timeout = 10;

         extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
@@ -723,6 +733,7 @@ em_reset_hw(struct em_hw *hw)
             msec_delay(20);
             break;
         case em_82573:
+        case em_82574:
             if (em_is_onboard_nvm_eeprom(hw) == FALSE) {
                 usec_delay(10);
                 ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
@@ -826,6 +837,7 @@ em_initialize_hardware_bits(struct em_hw
                 E1000_WRITE_REG(hw, TARC1, reg_tarc1);
                 break;
             case em_82573:
+            case em_82574:
                 reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
                 reg_ctrl = E1000_READ_REG(hw, CTRL);

@@ -1023,7 +1035,7 @@ em_init_hw(struct em_hw *hw)
         E1000_WRITE_REG(hw, TXDCTL, ctrl);
     }

-    if (hw->mac_type == em_82573) {
+    if ((hw->mac_type == em_82573) || (hw->mac_type == em_82574)) {
         em_enable_tx_pkt_filtering(hw);
     }

@@ -1063,7 +1075,7 @@ em_init_hw(struct em_hw *hw)
         break;
     }

-    if (hw->mac_type == em_82573) {
+    if ((hw->mac_type == em_82573) || (hw->mac_type == em_82574)) {
         uint32_t gcr = E1000_READ_REG(hw, GCR);
         gcr |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
         E1000_WRITE_REG(hw, GCR, gcr);
@@ -1175,6 +1187,7 @@ em_setup_link(struct em_hw *hw)
         case em_ich8lan:
         case em_ich9lan:
         case em_82573:
+        case em_82574:
             hw->fc = E1000_FC_FULL;
             break;
         default:
@@ -1801,8 +1814,10 @@ em_copper_link_mgp_setup(struct em_hw *h
     if (ret_val)
         return ret_val;

-    phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
-
+    /* For BM PHY this bit is downshift enable */
+    if (hw->phy_type != em_phy_bm)
+        phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+
     /* Options:
      *   MDI/MDI-X = 0 (default)
      *   0 - Auto for all speeds
@@ -1837,11 +1852,17 @@ em_copper_link_mgp_setup(struct em_hw *h
     phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
     if (hw->disable_polarity_correction == 1)
         phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
+
+    /* Enable downshift on BM (disabled by default) */
+    if (hw->phy_type == em_phy_bm)
+        phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT;
+
     ret_val = em_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
     if (ret_val)
         return ret_val;

-    if (hw->phy_revision < M88E1011_I_REV_4) {
+    if ((hw->phy_type == em_phy_m88) &&
+       (hw->phy_revision < M88E1011_I_REV_4)) {
         /* Force TX_CLK in the Extended PHY Specific Control Register
          * to 25MHz clock.
          */
@@ -1873,6 +1894,18 @@ em_copper_link_mgp_setup(struct em_hw *h
         }
     }

+    if ((hw->phy_type == em_phy_bm) && (hw->phy_revision == 1)) {
+       /* Set PHY page 0, register 29 to 0x0003 */
+ ret_val = em_write_phy_reg(hw, BM_REG_BIAS1, 0x0003); /* bias enabling register, this is supposed to lower BER for gig conection */
+       if (ret_val)
+            return ret_val;;
+
+        /* Set PHY page 0, register 30 to 0x0000 */
+ ret_val = em_write_phy_reg(hw, BM_REG_BIAS2, 0x0000); /* bias enabling register, this is supposed to lower BER for gig conection */
+        if (ret_val)
+            return ret_val;
+    }
+
     /* SW Reset the PHY so all changes take effect */
     ret_val = em_phy_reset(hw);
     if (ret_val) {
@@ -2054,7 +2087,8 @@ em_setup_copper_link(struct em_hw *hw)
         ret_val = em_copper_link_igp_setup(hw);
         if (ret_val)
             return ret_val;
-    } else if (hw->phy_type == em_phy_m88) {
+    } else if (hw->phy_type == em_phy_m88 ||
+               hw->phy_type == em_phy_bm) {
         ret_val = em_copper_link_mgp_setup(hw);
         if (ret_val)
             return ret_val;
@@ -2411,7 +2445,8 @@ em_phy_force_speed_duplex(struct em_hw *
     E1000_WRITE_REG(hw, CTRL, ctrl);

     if ((hw->phy_type == em_phy_m88) ||
-        (hw->phy_type == em_phy_gg82563)) {
+        (hw->phy_type == em_phy_gg82563) ||
+        (hw->phy_type == em_phy_bm)) {
ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
         if (ret_val)
             return ret_val;
@@ -2493,7 +2528,8 @@ em_phy_force_speed_duplex(struct em_hw *
         }
         if ((i == 0) &&
            ((hw->phy_type == em_phy_m88) ||
-            (hw->phy_type == em_phy_gg82563))) {
+            (hw->phy_type == em_phy_gg82563) ||
+            (hw->phy_type == em_phy_bm))) {
/* We didn't get link. Reset the DSP and wait again for link. */
             ret_val = em_phy_reset_dsp(hw);
             if (ret_val) {
@@ -2518,7 +2554,8 @@ em_phy_force_speed_duplex(struct em_hw *
         }
     }

-    if (hw->phy_type == em_phy_m88) {
+    if (hw->phy_type == em_phy_m88 ||
+        hw->phy_type == em_phy_bm) {
/* Because we reset the PHY above, we need to re-force TX_CLK in the * Extended PHY Specific Control Register to 25MHz clock. This value
          * defaults back to a 2.5MHz clock when the PHY is reset.
@@ -3563,7 +3600,14 @@ em_read_phy_reg(struct em_hw *hw,
                 return ret_val;
             }
         }
-    }
+ } else if ((hw->phy_type == em_phy_bm) && (hw->phy_revision == 1)) {
+       if (reg_addr > MAX_PHY_MULTI_PAGE_REG) {
+ ret_val = em_write_phy_reg_ex(hw, BM_PHY_PAGE_SELECT, (uint16_t) ((uint16_t)reg_addr >> PHY_PAGE_SHIFT) );
+           if (ret_val)
+               return ret_val;
+       }
+    }
+

     ret_val = em_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
                                     phy_data);
@@ -3701,7 +3745,13 @@ em_write_phy_reg(struct em_hw *hw, uint3
                 return ret_val;
             }
         }
-    }
+ } else if ((hw->phy_type == em_phy_bm) && (hw->phy_revision == 1)) {
+       if (reg_addr > MAX_PHY_MULTI_PAGE_REG) {
+ ret_val = em_write_phy_reg_ex(hw, BM_PHY_PAGE_SELECT, (uint16_t) ((uint16_t)reg_addr >> PHY_PAGE_SHIFT) );
+           if (ret_val)
+               return ret_val;
+       }
+    }

     ret_val = em_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
                                      phy_data);
@@ -4118,6 +4168,9 @@ em_detect_gig_phy(struct em_hw *hw)
     case em_82573:
         if (hw->phy_id == M88E1111_I_PHY_ID) match = TRUE;
         break;
+    case em_82574:
+        if (hw->phy_id == BME1000_E_PHY_ID) match = TRUE;
+        break;
     case em_80003es2lan:
         if (hw->phy_id == GG82563_E_PHY_ID) match = TRUE;
         break;
@@ -4263,6 +4316,7 @@ em_init_eeprom_params(struct em_hw *hw)
         eeprom->use_eewr = FALSE;
         break;
     case em_82573:
+    case em_82574:
         eeprom->type = em_eeprom_spi;
         eeprom->opcode_bits = 8;
         eeprom->delay_usec = 1;
@@ -4515,7 +4569,7 @@ em_acquire_eeprom(struct em_hw *hw)
         return -E1000_ERR_SWFW_SYNC;
     eecd = E1000_READ_REG(hw, EECD);

-    if (hw->mac_type != em_82573) {
+    if ((hw->mac_type != em_82573) || (hw->mac_type == em_82574)) {
         /* Request EEPROM Access */
         if (hw->mac_type > em_82544) {
             eecd |= E1000_EECD_REQ;
@@ -4923,7 +4977,7 @@ em_is_onboard_nvm_eeprom(struct em_hw *h
     if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan)
         return FALSE;

-    if (hw->mac_type == em_82573) {
+    if ((hw->mac_type == em_82573) || (hw->mac_type == em_82574)) {
         eecd = E1000_READ_REG(hw, EECD);

         /* Isolate bits 15 & 16 */
@@ -4954,7 +5008,7 @@ em_validate_eeprom_checksum(struct em_hw

     DEBUGFUNC("em_validate_eeprom_checksum");

-    if ((hw->mac_type == em_82573) &&
+    if (((hw->mac_type == em_82573) || (hw->mac_type == em_82574)) &&
         (em_is_onboard_nvm_eeprom(hw) == FALSE)) {
/* Check bit 4 of word 10h. If it is 0, firmware is done updating
          * 10h-12h.  Checksum may need to be fixed. */
@@ -5080,7 +5134,7 @@ em_write_eeprom(struct em_hw *hw,
         return -E1000_ERR_EEPROM;
     }

-    /* 82573 writes only through eewr */
+    /* 82573/4 writes only through eewr */
     if (eeprom->use_eewr == TRUE)
         return em_write_eeprom_eewr(hw, offset, words, data);

@@ -5280,7 +5334,7 @@ em_commit_shadow_ram(struct em_hw *hw)
     uint8_t high_byte = 0;
     boolean_t sector_write_failed = FALSE;

-    if (hw->mac_type == em_82573) {
+    if ((hw->mac_type == em_82573) && (hw->mac_type == em_82574)) {
/* The flop register will be used to determine if flash type is STM */
         flop = E1000_READ_REG(hw, FLOP);
         for (i=0; i < attempts; i++) {
@@ -5826,7 +5880,7 @@ em_clear_vfta(struct em_hw *hw)
     if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan)
         return;

-    if (hw->mac_type == em_82573) {
+    if ((hw->mac_type == em_82573) && (hw->mac_type == em_82574)) {
         if (hw->mng_cookie.vlan_id != 0) {
/* The VFTA is a 4096b bit-field, each identifying a single VLAN
              * ID.  The following operations determine which 32b entry
@@ -6129,6 +6183,7 @@ em_get_bus_info(struct em_hw *hw)
     case em_82571:
     case em_82572:
     case em_82573:
+    case em_82574:
     case em_82575:
     case em_80003es2lan:
         hw->bus_type = em_bus_type_pci_express;
@@ -7279,6 +7334,7 @@ em_get_auto_rd_done(struct em_hw *hw)
     case em_82571:
     case em_82572:
     case em_82573:
+    case em_82574:
     case em_82575:
     case em_80003es2lan:
     case em_ich8lan:
@@ -7300,7 +7356,7 @@ em_get_auto_rd_done(struct em_hw *hw)
/* PHY configuration from NVM just starts after EECD_AUTO_RD sets to high. * Need to wait for PHY configuration completion before accessing NVM
      * and PHY. */
-    if (hw->mac_type == em_82573)
+    if ((hw->mac_type == em_82573) || (hw->mac_type == em_82574 ))
         msec_delay(25);

     return E1000_SUCCESS;
Index: if_em_hw.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em_hw.h,v
retrieving revision 1.29
diff -u -p -r1.29 if_em_hw.h
--- if_em_hw.h  4 Jun 2009 05:08:43 -0000       1.29
+++ if_em_hw.h  17 Jun 2009 18:45:49 -0000
@@ -67,6 +67,7 @@ typedef enum {
     em_82571,
     em_82572,
     em_82573,
+    em_82574,
     em_82575,
     em_80003es2lan,
     em_ich8lan,
@@ -228,6 +229,7 @@ typedef enum {
     em_phy_gg82563,
     em_phy_igp_3,
     em_phy_ife,
+    em_phy_bm,         /* phy used in i82574L, ICH10 and some ICH9 */
     em_phy_undefined = 0xFF
 } em_phy_type;

@@ -518,6 +520,7 @@ int32_t em_check_phy_reset_block(struct
 #define E1000_DEV_ID_82576_SERDES       0x10E7
 #define E1000_DEV_ID_82576_QUAD_COPPER  0x10E8
 #define E1000_DEV_ID_82576_NS           0x150A
+#define E1000_DEV_ID_82574L             0x10D3

 #define NODE_ADDRESS_SIZE 6
 #define ETH_LENGTH_OF_ADDRESS 6
@@ -2596,6 +2599,12 @@ struct em_host_command_info {
#define M88E1000_PHY_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */ #define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */

+/* BME1000 PHY Specific Control Register */
+#define BME1000_PSCR_ENABLE_DOWNSHIFT 0x0800 /* 1 = enable downshift */
+#define BM_PHY_PAGE_SELECT                22   /* Page Select for BM */
+#define BM_REG_BIAS1                      29
+#define BM_REG_BIAS2                      30
+
 #define IGP01E1000_IEEE_REGS_PAGE  0x0000
 #define IGP01E1000_IEEE_RESTART_AUTONEG 0x3300
 #define IGP01E1000_IEEE_FORCE_GIGA      0x0140
@@ -3169,6 +3178,8 @@ struct em_host_command_info {
 #define M88E1111_I_PHY_ID  0x01410CC0
 #define L1LXT971A_PHY_ID   0x001378E0
 #define GG82563_E_PHY_ID   0x01410CA0
+#define BME1000_E_PHY_ID   0x01410CB0
+

 /* Bits...
  * 15-5: page

Reply via email to