Author: yongari
Date: Fri Oct 28 01:04:40 2011
New Revision: 226871
URL: http://svn.freebsd.org/changeset/base/226871

Log:
  Add initial BCM5720 support.
  Many thanks to Broadcom for continuing support of FreeBSD.
  
  Submitted by: Geans Pin at Broadcom (initial version)
  H/W donated by:       Broadcom

Modified:
  head/sys/dev/bge/if_bge.c
  head/sys/dev/bge/if_bgereg.h

Modified: head/sys/dev/bge/if_bge.c
==============================================================================
--- head/sys/dev/bge/if_bge.c   Fri Oct 28 00:40:19 2011        (r226870)
+++ head/sys/dev/bge/if_bge.c   Fri Oct 28 01:04:40 2011        (r226871)
@@ -301,6 +301,7 @@ static const struct bge_revision {
        { BGE_CHIPID_BCM5717_A0,        "BCM5717 A0" },
        { BGE_CHIPID_BCM5717_B0,        "BCM5717 B0" },
        { BGE_CHIPID_BCM5719_A0,        "BCM5719 A0" },
+       { BGE_CHIPID_BCM5720_A0,        "BCM5720 A0" },
        { BGE_CHIPID_BCM5755_A0,        "BCM5755 A0" },
        { BGE_CHIPID_BCM5755_A1,        "BCM5755 A1" },
        { BGE_CHIPID_BCM5755_A2,        "BCM5755 A2" },
@@ -349,6 +350,7 @@ static const struct bge_revision const b
        { BGE_ASICREV_BCM57780,         "unknown BCM57780" },
        { BGE_ASICREV_BCM5717,          "unknown BCM5717" },
        { BGE_ASICREV_BCM5719,          "unknown BCM5719" },
+       { BGE_ASICREV_BCM5720,          "unknown BCM5720" },
 
        { 0, NULL }
 };
@@ -437,6 +439,7 @@ static int bge_init_tx_ring(struct bge_s
 
 static int bge_chipinit(struct bge_softc *);
 static int bge_blockinit(struct bge_softc *);
+static uint32_t bge_dma_swap_options(struct bge_softc *);
 
 static int bge_has_eaddr(struct bge_softc *);
 static uint32_t bge_readmem_ind(struct bge_softc *, int);
@@ -1381,13 +1384,31 @@ bge_stop_fw(struct bge_softc *sc)
        }
 }
 
+static uint32_t
+bge_dma_swap_options(struct bge_softc *sc)
+{
+       uint32_t dma_options;
+
+       dma_options = BGE_MODECTL_WORDSWAP_NONFRAME |
+           BGE_MODECTL_BYTESWAP_DATA | BGE_MODECTL_WORDSWAP_DATA;
+#if BYTE_ORDER == BIG_ENDIAN
+       dma_options |= BGE_MODECTL_BYTESWAP_NONFRAME;
+#endif
+       if ((sc)->bge_asicrev == BGE_ASICREV_BCM5720)
+               dma_options |= BGE_MODECTL_BYTESWAP_B2HRX_DATA |
+                   BGE_MODECTL_WORDSWAP_B2HRX_DATA | BGE_MODECTL_B2HRX_ENABLE |
+                   BGE_MODECTL_HTX2B_ENABLE;
+
+       return (dma_options);
+}
+
 /*
  * Do endian, PCI and DMA initialization.
  */
 static int
 bge_chipinit(struct bge_softc *sc)
 {
-       uint32_t dma_rw_ctl, misc_ctl;
+       uint32_t dma_rw_ctl, misc_ctl, mode_ctl;
        uint16_t val;
        int i;
 
@@ -1505,9 +1526,8 @@ bge_chipinit(struct bge_softc *sc)
        /*
         * Set up general mode register.
         */
-       CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS |
-           BGE_MODECTL_MAC_ATTN_INTR | BGE_MODECTL_HOST_SEND_BDS |
-           BGE_MODECTL_TX_NO_PHDR_CSUM);
+       mode_ctl = bge_dma_swap_options(sc) | BGE_MODECTL_MAC_ATTN_INTR |
+           BGE_MODECTL_HOST_SEND_BDS | BGE_MODECTL_TX_NO_PHDR_CSUM;
 
        /*
         * BCM5701 B5 have a bug causing data corruption when using
@@ -1517,13 +1537,15 @@ bge_chipinit(struct bge_softc *sc)
         */
        if (sc->bge_asicrev == BGE_ASICREV_BCM5701 &&
            sc->bge_chipid == BGE_CHIPID_BCM5701_B5)
-               BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_FORCE_PCI32);
+               mode_ctl |= BGE_MODECTL_FORCE_PCI32;
 
        /*
         * Tell the firmware the driver is running
         */
        if (sc->bge_asf_mode & ASF_STACKUP)
-               BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
+               mode_ctl |= BGE_MODECTL_STACKUP;
+
+       CSR_WRITE_4(sc, BGE_MODE_CTL, mode_ctl);
 
        /*
         * Disable memory write invalidate.  Apparently it is not supported
@@ -1583,8 +1605,7 @@ bge_blockinit(struct bge_softc *sc)
        }
 
        /* Configure mbuf pool watermarks */
-       if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
-           sc->bge_asicrev == BGE_ASICREV_BCM57765) {
+       if (BGE_IS_5717_PLUS(sc)) {
                CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
                if (sc->bge_ifp->if_mtu > ETHERMTU) {
                        CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x7e);
@@ -1719,7 +1740,8 @@ bge_blockinit(struct bge_softc *sc)
                    BGE_RCB_MAXLEN_FLAGS(BGE_MAX_FRAMELEN, 0);
        }
        if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
-           sc->bge_asicrev == BGE_ASICREV_BCM5719)
+           sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+           sc->bge_asicrev == BGE_ASICREV_BCM5720)
                rcb->bge_nicaddr = BGE_STD_RX_RINGS_5717;
        else
                rcb->bge_nicaddr = BGE_STD_RX_RINGS;
@@ -1752,7 +1774,8 @@ bge_blockinit(struct bge_softc *sc)
                rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(0,
                    BGE_RCB_FLAG_USE_EXT_RX_BD | BGE_RCB_FLAG_RING_DISABLED);
                if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
-                   sc->bge_asicrev == BGE_ASICREV_BCM5719)
+                   sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+                   sc->bge_asicrev == BGE_ASICREV_BCM5720)
                        rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS_5717;
                else
                        rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS;
@@ -1841,7 +1864,8 @@ bge_blockinit(struct bge_softc *sc)
        RCB_WRITE_4(sc, vrcb, bge_hostaddr.bge_addr_hi, taddr.bge_addr_hi);
        RCB_WRITE_4(sc, vrcb, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo);
        if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
-           sc->bge_asicrev == BGE_ASICREV_BCM5719)
+           sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+           sc->bge_asicrev == BGE_ASICREV_BCM5720)
                RCB_WRITE_4(sc, vrcb, bge_nicaddr, BGE_SEND_RING_5717);
        else
                RCB_WRITE_4(sc, vrcb, bge_nicaddr,
@@ -1855,7 +1879,8 @@ bge_blockinit(struct bge_softc *sc)
         * return ring control blocks, located in NIC memory.
         */
        if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
-           sc->bge_asicrev == BGE_ASICREV_BCM5719) {
+           sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+           sc->bge_asicrev == BGE_ASICREV_BCM5720) {
                /* Should be 17, use 16 until we get an SRAM map. */
                limit = 16;
        } else if (!BGE_IS_5705_PLUS(sc))
@@ -1899,7 +1924,11 @@ bge_blockinit(struct bge_softc *sc)
            BGE_TX_BACKOFF_SEED_MASK);
 
        /* Set inter-packet gap */
-       CSR_WRITE_4(sc, BGE_TX_LENGTHS, 0x2620);
+       val = 0x2620;
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5720)
+               val |= CSR_READ_4(sc, BGE_TX_LENGTHS) &
+                   (BGE_TXLEN_JMB_FRM_LEN_MSK | BGE_TXLEN_CNT_DN_VAL_MSK);
+       CSR_WRITE_4(sc, BGE_TX_LENGTHS, val);
 
        /*
         * Specify which ring to use for packets that don't match
@@ -2054,6 +2083,11 @@ bge_blockinit(struct bge_softc *sc)
                    sc->bge_asicrev == BGE_ASICREV_BCM57780)
                        val |= BGE_RDMAMODE_TSO6_ENABLE;
        }
+
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5720)
+               val |= CSR_READ_4(sc, BGE_RDMA_MODE) &
+                       BGE_RDMAMODE_H2BNC_VLAN_DET;
+
        if (sc->bge_asicrev == BGE_ASICREV_BCM5761 ||
            sc->bge_asicrev == BGE_ASICREV_BCM5784 ||
            sc->bge_asicrev == BGE_ASICREV_BCM5785 ||
@@ -2064,7 +2098,8 @@ bge_blockinit(struct bge_softc *sc)
                 * Adjust tx margin to prevent TX data corruption and
                 * fix internal FIFO overflow.
                 */
-               if (sc->bge_asicrev == BGE_ASICREV_BCM5719) {
+               if (sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+                   sc->bge_asicrev == BGE_ASICREV_BCM5720) {
                        dmactl &= ~(BGE_RDMA_RSRVCTRL_FIFO_LWM_MASK |
                            BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK |
                            BGE_RDMA_RSRVCTRL_TXMRGN_MASK);
@@ -2081,7 +2116,8 @@ bge_blockinit(struct bge_softc *sc)
                    BGE_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
        }
 
-       if (sc->bge_asicrev == BGE_ASICREV_BCM5719) {
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+           sc->bge_asicrev == BGE_ASICREV_BCM5720) {
                CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL,
                    CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL) |
                    BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K |
@@ -2240,6 +2276,7 @@ bge_probe(device_t dev)
                                case BCOM_DEVICEID_BCM5717:
                                case BCOM_DEVICEID_BCM5718:
                                case BCOM_DEVICEID_BCM5719:
+                               case BCOM_DEVICEID_BCM5720:
                                        id = pci_read_config(dev,
                                            BGE_PCI_GEN2_PRODID_ASICREV, 4);
                                        break;
@@ -2764,6 +2801,7 @@ bge_attach(device_t dev)
                case BCOM_DEVICEID_BCM5717:
                case BCOM_DEVICEID_BCM5718:
                case BCOM_DEVICEID_BCM5719:
+               case BCOM_DEVICEID_BCM5720:
                        sc->bge_chipid = pci_read_config(dev,
                            BGE_PCI_GEN2_PRODID_ASICREV, 4);
                        break;
@@ -2795,12 +2833,14 @@ bge_attach(device_t dev)
          * BCM5704  |   1   |   X   |   1   |   X   |
          * BCM5717  |   1   |   8   |   2   |   9   |
          * BCM5719  |   1   |   8   |   2   |   9   |
+         * BCM5720  |   1   |   8   |   2   |   9   |
          *
          * Other addresses may respond but they are not
          * IEEE compliant PHYs and should be ignored.
          */
        if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
-           sc->bge_asicrev == BGE_ASICREV_BCM5719) {
+           sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+           sc->bge_asicrev == BGE_ASICREV_BCM5720) {
                f = pci_get_function(dev);
                if (sc->bge_chipid == BGE_CHIPID_BCM5717_A0) {
                        if (CSR_READ_4(sc, BGE_SGDIG_STS) &
@@ -2835,6 +2875,7 @@ bge_attach(device_t dev)
        switch (sc->bge_asicrev) {
        case BGE_ASICREV_BCM5717:
        case BGE_ASICREV_BCM5719:
+       case BGE_ASICREV_BCM5720:
        case BGE_ASICREV_BCM57765:
                sc->bge_flags |= BGE_FLAG_5717_PLUS | BGE_FLAG_5755_PLUS |
                    BGE_FLAG_575X_PLUS | BGE_FLAG_5705_PLUS | BGE_FLAG_JUMBO |
@@ -2890,6 +2931,7 @@ bge_attach(device_t dev)
            sc->bge_asicrev != BGE_ASICREV_BCM5906 &&
            sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
            sc->bge_asicrev != BGE_ASICREV_BCM5719 &&
+           sc->bge_asicrev != BGE_ASICREV_BCM5720 &&
            sc->bge_asicrev != BGE_ASICREV_BCM5785 &&
            sc->bge_asicrev != BGE_ASICREV_BCM57765 &&
            sc->bge_asicrev != BGE_ASICREV_BCM57780) {
@@ -3010,7 +3052,8 @@ bge_attach(device_t dev)
                 */
                sc->bge_flags |= BGE_FLAG_PCIE;
                sc->bge_expcap = reg;
-               if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
+               if (sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+                   sc->bge_asicrev == BGE_ASICREV_BCM5720)
                        pci_set_max_read_req(dev, 2048);
                else if (pci_get_max_read_req(dev) != 4096)
                        pci_set_max_read_req(dev, 4096);
@@ -3596,8 +3639,7 @@ bge_reset(struct bge_softc *sc)
        }
 
        /* Fix up byte swapping. */
-       CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS |
-           BGE_MODECTL_BYTESWAP_DATA);
+       CSR_WRITE_4(sc, BGE_MODE_CTL, bge_dma_swap_options(sc));
 
        /* Tell the ASF firmware we are up */
        if (sc->bge_asf_mode & ASF_STACKUP)
@@ -3628,6 +3670,10 @@ bge_reset(struct bge_softc *sc)
        }
        DELAY(10000);
 
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5720)
+               BGE_CLRBIT(sc, BGE_CPMU_CLCK_ORIDE,
+                   CPMU_CLCK_ORIDE_MAC_ORIDE_EN);
+
        return (0);
 }
 
@@ -4842,6 +4888,11 @@ bge_init_locked(struct bge_softc *sc)
        mode = CSR_READ_4(sc, BGE_TX_MODE);
        if (BGE_IS_5755_PLUS(sc) || sc->bge_asicrev == BGE_ASICREV_BCM5906)
                mode |= BGE_TXMODE_MBUF_LOCKUP_FIX;
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5720) {
+               mode &= ~(BGE_TXMODE_JMB_FRM_LEN | BGE_TXMODE_CNT_DN_MODE);
+               mode |= CSR_READ_4(sc, BGE_TX_MODE) &
+                   (BGE_TXMODE_JMB_FRM_LEN | BGE_TXMODE_CNT_DN_MODE);
+       }
        /* Turn on transmitter. */
        CSR_WRITE_4(sc, BGE_TX_MODE, mode | BGE_TXMODE_ENABLE);
 

Modified: head/sys/dev/bge/if_bgereg.h
==============================================================================
--- head/sys/dev/bge/if_bgereg.h        Fri Oct 28 00:40:19 2011        
(r226870)
+++ head/sys/dev/bge/if_bgereg.h        Fri Oct 28 01:04:40 2011        
(r226871)
@@ -258,15 +258,6 @@
 #define        BGE_PCIMISCCTL_ASICREV_SHIFT    16
 
 #define        BGE_HIF_SWAP_OPTIONS    (BGE_PCIMISCCTL_ENDIAN_WORDSWAP)
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define        BGE_DMA_SWAP_OPTIONS \
-       BGE_MODECTL_WORDSWAP_NONFRAME| \
-       BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_WORDSWAP_DATA
-#else
-#define        BGE_DMA_SWAP_OPTIONS \
-       BGE_MODECTL_WORDSWAP_NONFRAME|BGE_MODECTL_BYTESWAP_NONFRAME| \
-       BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_WORDSWAP_DATA
-#endif
 
 #define        BGE_INIT \
        (BGE_HIF_SWAP_OPTIONS|BGE_PCIMISCCTL_CLEAR_INTA| \
@@ -339,6 +330,7 @@
 #define        BGE_CHIPID_BCM5717_A0           0x05717000
 #define        BGE_CHIPID_BCM5717_B0           0x05717100
 #define        BGE_CHIPID_BCM5719_A0           0x05719000
+#define        BGE_CHIPID_BCM5720_A0           0x05720000
 #define        BGE_CHIPID_BCM57765_A0          0x57785000
 #define        BGE_CHIPID_BCM57765_B0          0x57785100
 
@@ -363,6 +355,7 @@
 /* BGE_PCI_PRODID_ASICREV ASIC rev. identifiers. */
 #define        BGE_ASICREV_BCM5717             0x5717
 #define        BGE_ASICREV_BCM5719             0x5719
+#define        BGE_ASICREV_BCM5720             0x5720
 #define        BGE_ASICREV_BCM5761             0x5761
 #define        BGE_ASICREV_BCM5784             0x5784
 #define        BGE_ASICREV_BCM5785             0x5785
@@ -807,6 +800,8 @@
 #define        BGE_TXMODE_BIGBACKOFF_ENABLE    0x00000020
 #define        BGE_TXMODE_LONGPAUSE_ENABLE     0x00000040
 #define        BGE_TXMODE_MBUF_LOCKUP_FIX      0x00000100
+#define        BGE_TXMODE_JMB_FRM_LEN          0x00400000
+#define        BGE_TXMODE_CNT_DN_MODE          0x00800000
 
 /* Transmit MAC status register */
 #define        BGE_TXSTAT_RX_XOFFED            0x00000001
@@ -820,6 +815,8 @@
 #define        BGE_TXLEN_SLOTTIME              0x000000FF
 #define        BGE_TXLEN_IPG                   0x00000F00
 #define        BGE_TXLEN_CRS                   0x00003000
+#define        BGE_TXLEN_JMB_FRM_LEN_MSK       0x00FF0000
+#define        BGE_TXLEN_CNT_DN_VAL_MSK        0xFF000000
 
 /* Receive MAC mode register */
 #define        BGE_RXMODE_RESET                0x00000001
@@ -1277,6 +1274,7 @@
 #define        BGE_CPMU_LSPD_1000MB_CLK        0x360C
 #define        BGE_CPMU_LNK_AWARE_PWRMD        0x3610
 #define        BGE_CPMU_HST_ACC                0x361C
+#define        BGE_CPMU_CLCK_ORIDE             0x3624
 #define        BGE_CPMU_CLCK_STAT              0x3630
 #define        BGE_CPMU_MUTEX_REQ              0x365C
 #define        BGE_CPMU_MUTEX_GNT              0x3660
@@ -1304,6 +1302,9 @@
 #define        BGE_CPMU_HST_ACC_MACCLK_MASK    0x001F0000
 #define        BGE_CPMU_HST_ACC_MACCLK_6_25    0x00130000
 
+/* Clock Speed Override Policy register */
+#define        CPMU_CLCK_ORIDE_MAC_ORIDE_EN    0x80000000
+
 /* CPMU Clock Status register */
 #define        BGE_CPMU_CLCK_STAT_MAC_CLCK_MASK        0x001F0000
 #define        BGE_CPMU_CLCK_STAT_MAC_CLCK_62_5        0x00000000
@@ -1551,6 +1552,7 @@
 #define        BGE_RDMAMODE_MULT_DMA_RD_DIS    0x01000000
 #define        BGE_RDMAMODE_TSO4_ENABLE        0x08000000
 #define        BGE_RDMAMODE_TSO6_ENABLE        0x10000000
+#define        BGE_RDMAMODE_H2BNC_VLAN_DET     0x20000000
 
 /* Read DMA status register */
 #define        BGE_RDMASTAT_PCI_TGT_ABRT_ATTN  0x00000004
@@ -1961,14 +1963,18 @@
 #define        BGE_MODECTL_WORDSWAP_NONFRAME   0x00000004
 #define        BGE_MODECTL_BYTESWAP_DATA       0x00000010
 #define        BGE_MODECTL_WORDSWAP_DATA       0x00000020
+#define        BGE_MODECTL_BYTESWAP_B2HRX_DATA 0x00000040
+#define        BGE_MODECTL_WORDSWAP_B2HRX_DATA 0x00000080
 #define        BGE_MODECTL_NO_FRAME_CRACKING   0x00000200
 #define        BGE_MODECTL_NO_RX_CRC           0x00000400
 #define        BGE_MODECTL_RX_BADFRAMES        0x00000800
 #define        BGE_MODECTL_NO_TX_INTR          0x00002000
 #define        BGE_MODECTL_NO_RX_INTR          0x00004000
 #define        BGE_MODECTL_FORCE_PCI32         0x00008000
+#define        BGE_MODECTL_B2HRX_ENABLE        0x00008000
 #define        BGE_MODECTL_STACKUP             0x00010000
 #define        BGE_MODECTL_HOST_SEND_BDS       0x00020000
+#define        BGE_MODECTL_HTX2B_ENABLE        0x00040000
 #define        BGE_MODECTL_TX_NO_PHDR_CSUM     0x00100000
 #define        BGE_MODECTL_RX_NO_PHDR_CSUM     0x00800000
 #define        BGE_MODECTL_TX_ATTN_INTR        0x01000000
@@ -2298,7 +2304,8 @@ struct bge_status_block {
 #define        BCOM_DEVICEID_BCM5717           0x1655
 #define        BCOM_DEVICEID_BCM5718           0x1656
 #define        BCOM_DEVICEID_BCM5719           0x1657
-#define        BCOM_DEVICEID_BCM5720           0x1658
+#define        BCOM_DEVICEID_BCM5720_PP        0x1658  /* Not released to 
public. */
+#define        BCOM_DEVICEID_BCM5720           0x165F
 #define        BCOM_DEVICEID_BCM5721           0x1659
 #define        BCOM_DEVICEID_BCM5722           0x165A
 #define        BCOM_DEVICEID_BCM5723           0x165B
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to