hi,

looking for anyone who can test attached diff on any 82575 h/w.

this patch includes fixes sent by Atte Peltomaki, that fixed his quadport 
card. my main concern is that it removes static recognition of attached 
PHY and relies on em_detect_gig_phy(). since such changes have already 
caused a couple of problems in the past, i would love if someone, 
especially with 82575EB  could test it.

and i would appreciate a dmesg.

dms@

? DEADJOE
? em_inter
? em_pch
Index: if_em_hw.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em_hw.c,v
retrieving revision 1.45
diff -u -r1.45 if_em_hw.c
--- if_em_hw.c  9 Jan 2010 22:56:24 -0000       1.45
+++ if_em_hw.c  26 Feb 2010 02:20:16 -0000
@@ -162,6 +162,7 @@
 static uint8_t em_calculate_mng_checksum(char *, uint32_t);
 static int32_t em_configure_kmrn_for_10_100(struct em_hw *, uint16_t);
 static int32_t em_configure_kmrn_for_1000(struct em_hw *);
+static int32_t  em_set_pciex_completion_timeout(struct em_hw *hw);
 
 /* IGP cable length table */
 static const uint16_t 
@@ -639,6 +640,15 @@
                        DEBUGOUT("PCI-E Master disable polling has failed.\n");
                }
        }
+
+        /* Set the completion timeout for 82575 chips */
+        if (hw->mac_type == em_82575) {
+                ret_val = em_set_pciex_completion_timeout(hw);
+                if (ret_val) {              
+                        DEBUGOUT("PCI-E Set completion timeout has failed.\n");
+                }
+        }
+
        /* Clear interrupt mask to stop board from generating interrupts */
        DEBUGOUT("Masking off all interrupts\n");
        E1000_WRITE_REG(hw, IMC, 0xffffffff);
@@ -3859,8 +3869,12 @@
 
                E1000_WRITE_REG(hw, MDIC, mdic);
 
-               /* Poll the ready bit to see if the MDI read completed */
-               for (i = 0; i < 64; i++) {
+               /*
+                * Poll the ready bit to see if the MDI read completed
+                * Increasing the time out as testing showed failures with
+                * the lower time out (from FreeBSD driver)
+                */
+               for (i = 0; i < 1960; i++) {
                        usec_delay(50);
                        mdic = E1000_READ_REG(hw, MDIC);
                        if (mdic & E1000_MDIC_READY)
@@ -4378,6 +4392,14 @@
                if (hw->phy_id == BME1000_E_PHY_ID)
                        match = TRUE;
                break;
+       case em_82575:
+               if (hw->phy_id == M88E1000_E_PHY_ID)
+                       match = TRUE;
+               if (hw->phy_id == IGP01E1000_I_PHY_ID)
+                       match = TRUE;
+               if (hw->phy_id == IGP03E1000_E_PHY_ID)
+                       match = TRUE;
+               break;
        case em_80003es2lan:
                if (hw->phy_id == GG82563_E_PHY_ID)
                        match = TRUE;
@@ -4405,6 +4427,7 @@
                return -E1000_ERR_CONFIG;
        }
        phy_init_status = em_set_phy_type(hw);
+       printf("PHY ID 0x%X detected (%d)\n", hw->phy_id, hw->mac_type);
 
        if ((match) && (phy_init_status == E1000_SUCCESS)) {
                DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id);
@@ -4440,12 +4463,12 @@
         * So we explicitly set the PHY values.
         */
        if (hw->mac_type == em_82571 ||
-           hw->mac_type == em_82572 ||
-           hw->mac_type == em_82575) {
+           hw->mac_type == em_82572) {
                hw->phy_id = IGP01E1000_I_PHY_ID;
                hw->phy_type = em_phy_igp_2;
                return E1000_SUCCESS;
        }
+
        /*
         * Some of the fiber cards dont have a phy, so we must exit cleanly
         * here
@@ -4599,7 +4622,6 @@
                break;
        case em_82571:
        case em_82572:
-       case em_82575:
                eeprom->type = em_eeprom_spi;
                eeprom->opcode_bits = 8;
                eeprom->delay_usec = 1;
@@ -4615,6 +4637,7 @@
                break;
        case em_82573:
        case em_82574:
+       case em_82575:
                eeprom->type = em_eeprom_spi;
                eeprom->opcode_bits = 8;
                eeprom->delay_usec = 1;
@@ -8791,4 +8814,70 @@
                }
        }
        return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ *  em_set_pciex_completion_timeout - set pci-e completion timeout
+ *
+ *  The defaults for 82575 and 82576 should be in the range of 50us to 50ms,
+ *  however the hardware default for these parts is 500us to 1ms which is less
+ *  than the 10ms recommended by the pci-e spec.  To address this we need to
+ *  increase the value to either 10ms to 200ms for capability version 1 config,
+ *  or 16ms to 55ms for version 2.
+ *
+ *  * hw - pointer to em_hw structure
+ *****************************************************************************/
+int32_t
+em_set_pciex_completion_timeout(struct em_hw *hw)
+{
+       uint32_t gcr = E1000_READ_REG(hw, GCR);
+       int32_t ret_val = E1000_SUCCESS;
+
+       /* Only take action if timeout value is not set by system BIOS */
+       if (gcr & E1000_GCR_CMPL_TMOUT_MASK)
+               goto out;
+
+       DEBUGOUT("PCIe completion timeout not set by system BIOS.");
+
+       /*
+        * If capababilities version is type 1 we can write the
+        * timeout of 10ms to 200ms through the GCR register
+        */
+
+       if (!(gcr & E1000_GCR_CAP_VER2)) {
+               gcr |= E1000_GCR_CMPL_TMOUT_10ms;
+               DEBUGOUT("PCIe capability version 1 detected, setting \
+                   completion timeout to 10ms.");
+               goto out;
+       }
+
+       /*
+        * For version 2 capabilities we need to write the config space
+        * directly in order to set the completion timeout value for
+        * 16ms to 55ms
+        *
+        * XXX: Implement em_*_pcie_cap_reg() first.
+        */
+#if 0
+       ret_val = em_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
+           &pciex_devctl2);
+
+       if (ret_val)
+               goto out;
+
+       pciex_devctl2 |= PCIE_DEVICE_CONTROL2_16ms;
+
+       ret_val = em_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
+           &pciex_devctl2); 
+#endif
+
+out:
+
+       /* Disable completion timeout resend */
+       gcr &= ~E1000_GCR_CMPL_TMOUT_RESEND;
+
+       DEBUGOUT("PCIe completion timeout resend disabled.");
+
+       E1000_WRITE_REG(hw, GCR, gcr);
+       return ret_val;
 }
Index: if_em_hw.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em_hw.h,v
retrieving revision 1.35
diff -u -r1.35 if_em_hw.h
--- if_em_hw.h  25 Nov 2009 13:28:13 -0000      1.35
+++ if_em_hw.h  26 Feb 2010 02:20:18 -0000
@@ -2238,6 +2238,11 @@
 #define E1000_GCR_TXDSCW_NO_SNOOP       0x00000010
 #define E1000_GCR_TXDSCR_NO_SNOOP       0x00000020
 
+#define E1000_GCR_CMPL_TMOUT_MASK       0x0000F000
+#define E1000_GCR_CMPL_TMOUT_10ms       0x00001000
+#define E1000_GCR_CMPL_TMOUT_RESEND     0x00010000
+#define E1000_GCR_CAP_VER2              0x00040000
+
 #define PCI_EX_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP         | \
                              E1000_GCR_RXDSCW_NO_SNOOP      | \
                              E1000_GCR_RXDSCR_NO_SNOOP      | \
@@ -2276,6 +2281,9 @@
 #define PCI_EX_LINK_STATUS           0x12
 #define PCI_EX_LINK_WIDTH_MASK       0x3F0
 #define PCI_EX_LINK_WIDTH_SHIFT      4
+
+#define PCI_EX_DEVICE_CONTROL2       0x28
+#define PCI_EX_DEVICE_CONTROL2_16ms  0x0005
 
 /* EEPROM Commands - Microwire */
 #define EEPROM_READ_OPCODE_MICROWIRE  0x6  /* EEPROM read opcode */

Reply via email to