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