summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2011-04-14 21:14:29 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2011-04-14 21:14:29 +0000
commit31f310c8229e9d38537aeee483beecd845fcd8c6 (patch)
tree4a4e0763b6b01d866b89abc5ca6d45cd4857fb20
parent65ec35dcddecabc9b5081a709b4af83fcebfe756 (diff)
the mechanical part of 82580 support, more to come
ok claudio@
-rw-r--r--sys/dev/pci/if_em.c15
-rw-r--r--sys/dev/pci/if_em_hw.c60
-rw-r--r--sys/dev/pci/if_em_hw.h21
3 files changed, 87 insertions, 9 deletions
diff --git a/sys/dev/pci/if_em.c b/sys/dev/pci/if_em.c
index f9b746f7677..7d1a39b6065 100644
--- a/sys/dev/pci/if_em.c
+++ b/sys/dev/pci/if_em.c
@@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
-/* $OpenBSD: if_em.c,v 1.254 2011/04/13 00:19:00 dlg Exp $ */
+/* $OpenBSD: if_em.c,v 1.255 2011/04/14 21:14:28 jsg Exp $ */
/* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */
#include <dev/pci/if_em.h>
@@ -128,6 +128,11 @@ const struct pci_matchid em_devices[] = {
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82577LM },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82578DC },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82578DM },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_COPPER },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_FIBER },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_SERDES },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_SGMII },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_COPPER_DUAL },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82583V },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH8_82567V_3 },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH8_IFE },
@@ -387,6 +392,7 @@ em_attach(struct device *parent, struct device *self, void *aux)
case em_82572:
case em_82574:
case em_82575:
+ case em_82580:
case em_ich9lan:
case em_ich10lan:
case em_80003es2lan:
@@ -731,6 +737,7 @@ em_init(void *arg)
case em_82571:
case em_82572: /* Total Packet Buffer on these is 48k */
case em_82575:
+ case em_82580:
case em_80003es2lan:
pba = E1000_PBA_32K; /* 32K for Rx, 16K for Tx */
break;
@@ -1426,7 +1433,8 @@ em_update_link_status(struct em_softc *sc)
if ((sc->link_speed == SPEED_1000) &&
((sc->hw.mac_type == em_82571) ||
(sc->hw.mac_type == em_82572) ||
- (sc->hw.mac_type == em_82575))) {
+ (sc->hw.mac_type == em_82575) ||
+ (sc->hw.mac_type == em_82580))) {
int tarc0;
tarc0 = E1000_READ_REG(&sc->hw, TARC0);
@@ -1715,7 +1723,8 @@ em_hardware_init(struct em_softc *sc)
if (!em_smart_pwr_down &&
(sc->hw.mac_type == em_82571 ||
sc->hw.mac_type == em_82572 ||
- sc->hw.mac_type == em_82575)) {
+ sc->hw.mac_type == em_82575 ||
+ sc->hw.mac_type == em_82580)) {
uint16_t phy_tmp = 0;
/* Speed up time to link by disabling smart power down */
diff --git a/sys/dev/pci/if_em_hw.c b/sys/dev/pci/if_em_hw.c
index c4d3f34f418..b029e50e32a 100644
--- a/sys/dev/pci/if_em_hw.c
+++ b/sys/dev/pci/if_em_hw.c
@@ -31,7 +31,7 @@
*******************************************************************************/
-/* $OpenBSD: if_em_hw.c,v 1.61 2011/04/04 03:49:32 william Exp $ */
+/* $OpenBSD: if_em_hw.c,v 1.62 2011/04/14 21:14:28 jsg Exp $ */
/*
* if_em_hw.c Shared functions for accessing and configuring the MAC
*/
@@ -251,6 +251,9 @@ em_set_phy_type(struct em_hw *hw)
case I82578_E_PHY_ID:
hw->phy_type = em_phy_82578;
break;
+ case I82580_I_PHY_ID:
+ hw->phy_type = em_phy_82580;
+ break;
case BME1000_E_PHY_ID:
if (hw->phy_revision == 1) {
hw->phy_type = em_phy_bm;
@@ -498,6 +501,14 @@ em_set_mac_type(struct em_hw *hw)
hw->mac_type = em_82575;
hw->initialize_hw_bits_disable = 1;
break;
+ case E1000_DEV_ID_82580_COPPER:
+ case E1000_DEV_ID_82580_FIBER:
+ case E1000_DEV_ID_82580_SERDES:
+ case E1000_DEV_ID_82580_SGMII:
+ case E1000_DEV_ID_82580_COPPER_DUAL:
+ hw->mac_type = em_82580;
+ hw->initialize_hw_bits_disable = 1;
+ break;
case E1000_DEV_ID_80003ES2LAN_COPPER_SPT:
case E1000_DEV_ID_80003ES2LAN_SERDES_SPT:
case E1000_DEV_ID_80003ES2LAN_COPPER_DPT:
@@ -565,6 +576,7 @@ em_set_mac_type(struct em_hw *hw)
break;
case em_80003es2lan:
case em_82575:
+ case em_82580:
hw->swfw_sync_present = TRUE;
/* FALLTHROUGH */
case em_82571:
@@ -601,7 +613,7 @@ em_set_media_type(struct em_hw *hw)
hw->tbi_compatibility_en = FALSE;
}
- if (hw->mac_type == em_82575) {
+ if (hw->mac_type == em_82575 || hw->mac_type == em_82580) {
hw->media_type = em_media_type_copper;
ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
@@ -703,7 +715,7 @@ em_reset_hw(struct em_hw *hw)
}
/* Set the completion timeout for 82575 chips */
- if (hw->mac_type == em_82575) {
+ if (hw->mac_type == em_82575 || hw->mac_type == em_82580) {
ret_val = em_set_pciex_completion_timeout(hw);
if (ret_val) {
DEBUGOUT("PCI-E Set completion timeout has failed.\n");
@@ -1269,6 +1281,7 @@ em_init_hw(struct em_hw *hw)
case em_82571:
case em_82572:
case em_82575:
+ case em_82580:
case em_ich8lan:
case em_ich9lan:
case em_ich10lan:
@@ -2310,6 +2323,33 @@ em_copper_link_82577_setup(struct em_hw *hw)
return E1000_SUCCESS;
}
+static int32_t
+em_copper_link_82580_setup(struct em_hw *hw)
+{
+ int32_t ret_val;
+ uint16_t phy_data;
+
+ if (hw->phy_reset_disable)
+ return E1000_SUCCESS;
+
+ ret_val = em_phy_reset(hw);
+ if (ret_val)
+ goto out;
+
+ /* Enable CRS on TX. This must be set for half-duplex operation. */
+ ret_val = em_read_phy_reg(hw, I82580_CFG_REG, &phy_data);
+ if (ret_val)
+ goto out;
+
+ phy_data |= I82580_CFG_ASSERT_CRS_ON_TX |
+ I82580_CFG_ENABLE_DOWNSHIFT;
+
+ ret_val = em_write_phy_reg(hw, I82580_CFG_REG, phy_data);
+
+out:
+ return ret_val;
+}
+
/******************************************************************************
* Setup auto-negotiation and flow control advertisements,
* and then perform auto-negotiation.
@@ -2500,6 +2540,10 @@ em_setup_copper_link(struct em_hw *hw)
ret_val = em_copper_link_82577_setup(hw);
if (ret_val)
return ret_val;
+ } else if (hw->phy_type == em_phy_82580) {
+ ret_val = em_copper_link_82580_setup(hw);
+ if (ret_val)
+ return ret_val;
}
if (hw->autoneg) {
/*
@@ -5013,6 +5057,10 @@ em_match_gig_phy(struct em_hw *hw)
if (hw->phy_id == IGP03E1000_E_PHY_ID)
match = TRUE;
break;
+ case em_82580:
+ if (hw->phy_id == I82580_I_PHY_ID)
+ match = TRUE;
+ break;
case em_80003es2lan:
if (hw->phy_id == GG82563_E_PHY_ID)
match = TRUE;
@@ -5263,6 +5311,7 @@ em_init_eeprom_params(struct em_hw *hw)
case em_82573:
case em_82574:
case em_82575:
+ case em_82580:
eeprom->type = em_eeprom_spi;
eeprom->opcode_bits = 8;
eeprom->delay_usec = 1;
@@ -6533,6 +6582,7 @@ em_read_mac_addr(struct em_hw *hw)
case em_82546_rev_3:
case em_82571:
case em_82575:
+ case em_82580:
case em_80003es2lan:
if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
hw->perm_mac_addr[5] ^= 0x01;
@@ -6580,6 +6630,8 @@ em_init_rx_addrs(struct em_hw *hw)
rar_num = E1000_RAR_ENTRIES_ICH8LAN;
if (hw->mac_type == em_ich8lan)
rar_num -= 1;
+ if (hw->mac_type == em_82580)
+ rar_num = E1000_RAR_ENTRIES_82580;
/* Zero out the other 15 receive addresses. */
DEBUGOUT("Clearing RAR[1-15]\n");
@@ -7243,6 +7295,7 @@ em_get_bus_info(struct em_hw *hw)
case em_82573:
case em_82574:
case em_82575:
+ case em_82580:
case em_80003es2lan:
hw->bus_type = em_bus_type_pci_express;
hw->bus_speed = em_bus_speed_2500;
@@ -8457,6 +8510,7 @@ em_get_auto_rd_done(struct em_hw *hw)
case em_82573:
case em_82574:
case em_82575:
+ case em_82580:
case em_80003es2lan:
case em_ich8lan:
case em_ich9lan:
diff --git a/sys/dev/pci/if_em_hw.h b/sys/dev/pci/if_em_hw.h
index 345735366de..e3857b4f708 100644
--- a/sys/dev/pci/if_em_hw.h
+++ b/sys/dev/pci/if_em_hw.h
@@ -31,7 +31,7 @@
*******************************************************************************/
-/* $OpenBSD: if_em_hw.h,v 1.48 2011/04/04 03:49:32 william Exp $ */
+/* $OpenBSD: if_em_hw.h,v 1.49 2011/04/14 21:14:28 jsg Exp $ */
/* $FreeBSD: if_em_hw.h,v 1.15 2005/05/26 23:32:02 tackerman Exp $ */
/* if_em_hw.h
@@ -70,6 +70,7 @@ typedef enum {
em_82573,
em_82574,
em_82575,
+ em_82580,
em_80003es2lan,
em_ich8lan,
em_ich9lan,
@@ -238,6 +239,7 @@ typedef enum {
em_phy_oem,
em_phy_82577,
em_phy_82578,
+ em_phy_82580,
em_phy_undefined = 0xFF
} em_phy_type;
@@ -635,8 +637,12 @@ int32_t em_check_phy_reset_block(struct em_hw *hw);
* reserve one of these spots for our directed address, allowing us room for
* E1000_RAR_ENTRIES - 1 multicast addresses.
*/
-#define E1000_RAR_ENTRIES 15
-#define E1000_RAR_ENTRIES_ICH8LAN 7
+#define E1000_RAR_ENTRIES 15
+#define E1000_RAR_ENTRIES_ICH8LAN 7
+#define E1000_RAR_ENTRIES_82575 16
+#define E1000_RAR_ENTRIES_82576 24
+#define E1000_RAR_ENTRIES_82580 24
+#define E1000_RAR_ENTRIES_I350 32
#define MIN_NUMBER_OF_DESCRIPTORS 8
#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
@@ -2735,6 +2741,14 @@ struct em_host_command_info {
#define IGP01E1000_ANALOG_REGS_PAGE 0x20C0
+/* 82580 specific PHY registers */
+#define I82580_ADDR_REG 16
+#define I82580_CFG_REG 22
+#define I82580_CFG_ASSERT_CRS_ON_TX (1 << 15)
+#define I82580_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift 100/10 */
+#define I82580_CTRL_REG 23
+#define I82580_CTRL_DOWNSHIFT_MASK (7 << 10)
+
/* Bits...
* 15-5: page
* 4-0: register offset
@@ -3278,6 +3292,7 @@ struct em_host_command_info {
#define I82577_E_PHY_ID 0x01540050
#define I82578_E_PHY_ID 0x004DD040
#define I82580_I_PHY_ID 0x015403A0
+#define I350_I_PHY_ID 0x015403B0
#define IGP04E1000_E_PHY_ID 0x02A80391
#define M88E1141_E_PHY_ID 0x01410CD0