Author: yongari
Date: Wed Jun 22 00:17:48 2011
New Revision: 223388
URL: http://svn.freebsd.org/changeset/base/223388

Log:
  MFC r221818:
    Add initial BCM5719 support. TSO and jumbo frame was intentionally
    disabled for BCM5719 A0 revision due to known hardware errata.
    Many thanks to Broadcom for continuing support of FreeBSD.
  
    Submitted by:       Geans Pin at Broadcom

Modified:
  stable/7/sys/dev/bge/if_bge.c
  stable/7/sys/dev/bge/if_bgereg.h
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/dev/bge/if_bge.c
==============================================================================
--- stable/7/sys/dev/bge/if_bge.c       Wed Jun 22 00:16:40 2011        
(r223387)
+++ stable/7/sys/dev/bge/if_bge.c       Wed Jun 22 00:17:48 2011        
(r223388)
@@ -171,6 +171,7 @@ static const struct bge_type {
        { BCOM_VENDORID,        BCOM_DEVICEID_BCM5715S },
        { BCOM_VENDORID,        BCOM_DEVICEID_BCM5717 },
        { BCOM_VENDORID,        BCOM_DEVICEID_BCM5718 },
+       { BCOM_VENDORID,        BCOM_DEVICEID_BCM5719 },
        { BCOM_VENDORID,        BCOM_DEVICEID_BCM5720 },
        { BCOM_VENDORID,        BCOM_DEVICEID_BCM5721 },
        { BCOM_VENDORID,        BCOM_DEVICEID_BCM5722 },
@@ -299,6 +300,7 @@ static const struct bge_revision {
        { BGE_CHIPID_BCM5715_A3,        "BCM5715 A3" },
        { BGE_CHIPID_BCM5717_A0,        "BCM5717 A0" },
        { BGE_CHIPID_BCM5717_B0,        "BCM5717 B0" },
+       { BGE_CHIPID_BCM5719_A0,        "BCM5719 A0" },
        { BGE_CHIPID_BCM5755_A0,        "BCM5755 A0" },
        { BGE_CHIPID_BCM5755_A1,        "BCM5755 A1" },
        { BGE_CHIPID_BCM5755_A2,        "BCM5755 A2" },
@@ -346,6 +348,7 @@ static const struct bge_revision const b
        { BGE_ASICREV_BCM57765,         "unknown BCM57765" },
        { BGE_ASICREV_BCM57780,         "unknown BCM57780" },
        { BGE_ASICREV_BCM5717,          "unknown BCM5717" },
+       { BGE_ASICREV_BCM5719,          "unknown BCM5719" },
 
        { 0, NULL }
 };
@@ -1481,6 +1484,14 @@ bge_chipinit(struct bge_softc *sc)
                dma_rw_ctl &= ~BGE_PCIDMARWCTL_DIS_CACHE_ALIGNMENT;
                if (sc->bge_chipid == BGE_CHIPID_BCM57765_A0)
                        dma_rw_ctl &= ~BGE_PCIDMARWCTL_CRDRDR_RDMA_MRRS_MSK;
+               /*
+                * Enable HW workaround for controllers that misinterpret
+                * a status tag update and leave interrupts permanently
+                * disabled.
+                */
+               if (sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
+                   sc->bge_asicrev != BGE_ASICREV_BCM57765)
+                       dma_rw_ctl |= BGE_PCIDMARWCTL_TAGGED_STATUS_WA;
        }
        pci_write_config(sc->bge_dev, BGE_PCI_DMA_RW_CTL, dma_rw_ctl, 4);
 
@@ -1537,7 +1548,7 @@ bge_blockinit(struct bge_softc *sc)
        struct bge_rcb *rcb;
        bus_size_t vrcb;
        bge_hostaddr taddr;
-       uint32_t val;
+       uint32_t dmactl, val;
        int i, limit;
 
        /*
@@ -1594,8 +1605,16 @@ bge_blockinit(struct bge_softc *sc)
        CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_HIWAT, 10);
 
        /* Enable buffer manager */
-       CSR_WRITE_4(sc, BGE_BMAN_MODE,
-           BGE_BMANMODE_ENABLE | BGE_BMANMODE_LOMBUF_ATTN);
+       val = BGE_BMANMODE_ENABLE | BGE_BMANMODE_LOMBUF_ATTN;
+       /*
+        * Change the arbitration algorithm of TXMBUF read request to
+        * round-robin instead of priority based for BCM5719.  When
+        * TXFIFO is almost empty, RDMA will hold its request until
+        * TXFIFO is not almost empty.
+        */
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
+               val |= BGE_BMANMODE_NO_TX_UNDERRUN;
+       CSR_WRITE_4(sc, BGE_BMAN_MODE, val);
 
        /* Poll for buffer manager start indication */
        for (i = 0; i < BGE_TIMEOUT; i++) {
@@ -1692,7 +1711,8 @@ bge_blockinit(struct bge_softc *sc)
                rcb->bge_maxlen_flags =
                    BGE_RCB_MAXLEN_FLAGS(BGE_MAX_FRAMELEN, 0);
        }
-       if (sc->bge_asicrev == BGE_ASICREV_BCM5717)
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
+           sc->bge_asicrev == BGE_ASICREV_BCM5719)
                rcb->bge_nicaddr = BGE_STD_RX_RINGS_5717;
        else
                rcb->bge_nicaddr = BGE_STD_RX_RINGS;
@@ -1724,7 +1744,8 @@ bge_blockinit(struct bge_softc *sc)
                    BUS_DMASYNC_PREREAD);
                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)
+               if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
+                   sc->bge_asicrev == BGE_ASICREV_BCM5719)
                        rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS_5717;
                else
                        rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS;
@@ -1812,7 +1833,8 @@ bge_blockinit(struct bge_softc *sc)
        BGE_HOSTADDR(taddr, sc->bge_ldata.bge_tx_ring_paddr);
        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)
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
+           sc->bge_asicrev == BGE_ASICREV_BCM5719)
                RCB_WRITE_4(sc, vrcb, bge_nicaddr, BGE_SEND_RING_5717);
        else
                RCB_WRITE_4(sc, vrcb, bge_nicaddr,
@@ -1825,7 +1847,8 @@ bge_blockinit(struct bge_softc *sc)
         * 'ring diabled' bit in the flags field of all the receive
         * return ring control blocks, located in NIC memory.
         */
-       if (sc->bge_asicrev == BGE_ASICREV_BCM5717) {
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
+           sc->bge_asicrev == BGE_ASICREV_BCM5719) {
                /* Should be 17, use 16 until we get an SRAM map. */
                limit = 16;
        } else if (!BGE_IS_5705_PLUS(sc))
@@ -2029,15 +2052,35 @@ bge_blockinit(struct bge_softc *sc)
            sc->bge_asicrev == BGE_ASICREV_BCM5785 ||
            sc->bge_asicrev == BGE_ASICREV_BCM57780 ||
            BGE_IS_5717_PLUS(sc)) {
+               dmactl = CSR_READ_4(sc, BGE_RDMA_RSRVCTRL);
+               /*
+                * Adjust tx margin to prevent TX data corruption and
+                * fix internal FIFO overflow.
+                */
+               if (sc->bge_asicrev == BGE_ASICREV_BCM5719) {
+                       dmactl &= ~(BGE_RDMA_RSRVCTRL_FIFO_LWM_MASK |
+                           BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK |
+                           BGE_RDMA_RSRVCTRL_TXMRGN_MASK);
+                       dmactl |= BGE_RDMA_RSRVCTRL_FIFO_LWM_1_5K |
+                           BGE_RDMA_RSRVCTRL_FIFO_HWM_1_5K |
+                           BGE_RDMA_RSRVCTRL_TXMRGN_320B;
+               }
                /*
                 * Enable fix for read DMA FIFO overruns.
                 * The fix is to limit the number of RX BDs
                 * the hardware would fetch at a fime.
                 */
-               CSR_WRITE_4(sc, BGE_RDMA_RSRVCTRL,
-                   CSR_READ_4(sc, BGE_RDMA_RSRVCTRL) |
+               CSR_WRITE_4(sc, BGE_RDMA_RSRVCTRL, dmactl |
                    BGE_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
        }
+
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5719) {
+               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 |
+                   BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K);
+       }
+
        CSR_WRITE_4(sc, BGE_RDMA_MODE, val);
        DELAY(40);
 
@@ -2189,6 +2232,7 @@ bge_probe(device_t dev)
                                switch (pci_get_device(dev)) {
                                case BCOM_DEVICEID_BCM5717:
                                case BCOM_DEVICEID_BCM5718:
+                               case BCOM_DEVICEID_BCM5719:
                                        id = pci_read_config(dev,
                                            BGE_PCI_GEN2_PRODID_ASICREV, 4);
                                        break;
@@ -2712,6 +2756,7 @@ bge_attach(device_t dev)
                switch (pci_get_device(dev)) {
                case BCOM_DEVICEID_BCM5717:
                case BCOM_DEVICEID_BCM5718:
+               case BCOM_DEVICEID_BCM5719:
                        sc->bge_chipid = pci_read_config(dev,
                            BGE_PCI_GEN2_PRODID_ASICREV, 4);
                        break;
@@ -2742,11 +2787,13 @@ bge_attach(device_t dev)
          * BCM57XX  |   1   |   X   |   X   |   X   |
          * BCM5704  |   1   |   X   |   1   |   X   |
          * BCM5717  |   1   |   8   |   2   |   9   |
+         * BCM5719  |   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) {
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
+           sc->bge_asicrev == BGE_ASICREV_BCM5719) {
                f = pci_get_function(dev);
                if (sc->bge_chipid == BGE_CHIPID_BCM5717_A0) {
                        if (CSR_READ_4(sc, BGE_SGDIG_STS) &
@@ -2754,7 +2801,7 @@ bge_attach(device_t dev)
                                phy_addr = f + 8;
                        else
                                phy_addr = f + 1;
-               } else if (sc->bge_chipid == BGE_CHIPID_BCM5717_B0) {
+               } else {
                        if (CSR_READ_4(sc, BGE_CPMU_PHY_STRAP) &
                            BGE_CPMU_PHY_STRAP_IS_SERDES)
                                phy_addr = f + 8;
@@ -2780,11 +2827,17 @@ bge_attach(device_t dev)
        /* Save chipset family. */
        switch (sc->bge_asicrev) {
        case BGE_ASICREV_BCM5717:
+       case BGE_ASICREV_BCM5719:
                sc->bge_flags |= BGE_FLAG_SHORT_DMA_BUG;
        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 |
                    BGE_FLAG_JUMBO_FRAME;
+               if (sc->bge_asicrev == BGE_ASICREV_BCM5719 &&
+                   sc->bge_chipid == BGE_CHIPID_BCM5719_A0) {
+                       /* Jumbo frame on BCM5719 A0 does not work. */
+                       sc->bge_flags &= ~BGE_FLAG_JUMBO_FRAME;
+               }
                break;
        case BGE_ASICREV_BCM5755:
        case BGE_ASICREV_BCM5761:
@@ -2832,6 +2885,7 @@ bge_attach(device_t dev)
        if ((BGE_IS_5705_PLUS(sc)) &&
            sc->bge_asicrev != BGE_ASICREV_BCM5906 &&
            sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
+           sc->bge_asicrev != BGE_ASICREV_BCM5719 &&
            sc->bge_asicrev != BGE_ASICREV_BCM5785 &&
            sc->bge_asicrev != BGE_ASICREV_BCM57765 &&
            sc->bge_asicrev != BGE_ASICREV_BCM57780) {
@@ -2914,6 +2968,11 @@ bge_attach(device_t dev)
        if (BGE_IS_5717_PLUS(sc)) {
                /* BCM5717 requires different TSO configuration. */
                sc->bge_flags |= BGE_FLAG_TSO3;
+               if (sc->bge_asicrev == BGE_ASICREV_BCM5719 &&
+                   sc->bge_chipid == BGE_CHIPID_BCM5719_A0) {
+                       /* TSO on BCM5719 A0 does not work. */
+                       sc->bge_flags &= ~BGE_FLAG_TSO3;
+               }
        } else if (BGE_IS_5755_PLUS(sc)) {
                /*
                 * BCM5754 and BCM5787 shares the same ASIC id so
@@ -2936,7 +2995,9 @@ bge_attach(device_t dev)
                 */
                sc->bge_flags |= BGE_FLAG_PCIE;
                sc->bge_expcap = reg;
-               if (pci_get_max_read_req(dev) != 4096)
+               if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
+                       pci_set_max_read_req(dev, 2048);
+               else if (pci_get_max_read_req(dev) != 4096)
                        pci_set_max_read_req(dev, 4096);
        } else {
                /*

Modified: stable/7/sys/dev/bge/if_bgereg.h
==============================================================================
--- stable/7/sys/dev/bge/if_bgereg.h    Wed Jun 22 00:16:40 2011        
(r223387)
+++ stable/7/sys/dev/bge/if_bgereg.h    Wed Jun 22 00:17:48 2011        
(r223388)
@@ -319,6 +319,7 @@
 #define        BGE_CHIPID_BCM57780_A1          0x57780001
 #define        BGE_CHIPID_BCM5717_A0           0x05717000
 #define        BGE_CHIPID_BCM5717_B0           0x05717100
+#define        BGE_CHIPID_BCM5719_A0           0x05719000
 #define        BGE_CHIPID_BCM57765_A0          0x57785000
 #define        BGE_CHIPID_BCM57765_B0          0x57785100
 
@@ -342,6 +343,7 @@
 #define        BGE_ASICREV_USE_PRODID_REG      0x0f
 /* BGE_PCI_PRODID_ASICREV ASIC rev. identifiers. */
 #define        BGE_ASICREV_BCM5717             0x5717
+#define        BGE_ASICREV_BCM5719             0x5719
 #define        BGE_ASICREV_BCM5761             0x5761
 #define        BGE_ASICREV_BCM5784             0x5784
 #define        BGE_ASICREV_BCM5785             0x5785
@@ -385,6 +387,7 @@
 #define        BGE_PCIDMARWCTL_RD_CMD_SHIFT(x) ((x) << 24)
 #define        BGE_PCIDMARWCTL_WR_CMD_SHIFT(x) ((x) << 28)
 
+#define        BGE_PCIDMARWCTL_TAGGED_STATUS_WA        0x00000080
 #define        BGE_PCIDMARWCTL_CRDRDR_RDMA_MRRS_MSK    0x00000380
 
 #define        BGE_PCI_READ_BNDRY_DISABLE      0x00000000
@@ -1494,6 +1497,7 @@
 #define        BGE_BMANMODE_ATTN               0x00000004
 #define        BGE_BMANMODE_TESTMODE           0x00000008
 #define        BGE_BMANMODE_LOMBUF_ATTN        0x00000010
+#define        BGE_BMANMODE_NO_TX_UNDERRUN     0x80000000
 
 /* Buffer manager status register */
 #define        BGE_BMANSTAT_ERRO               0x00000004
@@ -1506,6 +1510,7 @@
 #define        BGE_RDMA_MODE                   0x4800
 #define        BGE_RDMA_STATUS                 0x4804
 #define        BGE_RDMA_RSRVCTRL               0x4900
+#define        BGE_RDMA_LSO_CRPTEN_CTRL        0x4910
 
 /* Read DMA mode register */
 #define        BGE_RDMAMODE_RESET              0x00000001
@@ -1540,6 +1545,15 @@
 
 /* Read DMA Reserved Control register */
 #define        BGE_RDMA_RSRVCTRL_FIFO_OFLW_FIX 0x00000004
+#define        BGE_RDMA_RSRVCTRL_FIFO_LWM_1_5K 0x00000C00
+#define        BGE_RDMA_RSRVCTRL_FIFO_HWM_1_5K 0x000C0000
+#define        BGE_RDMA_RSRVCTRL_TXMRGN_320B   0x28000000
+#define        BGE_RDMA_RSRVCTRL_FIFO_LWM_MASK 0x00000FF0
+#define        BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK 0x000FF000
+#define        BGE_RDMA_RSRVCTRL_TXMRGN_MASK   0xFFE00000
+
+#define        BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K     0x00030000
+#define        BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K    0x000C0000
 
 /*
  * Write DMA control registers
@@ -2261,6 +2275,7 @@ struct bge_status_block {
 #define        BCOM_DEVICEID_BCM5715S          0x1679
 #define        BCOM_DEVICEID_BCM5717           0x1655
 #define        BCOM_DEVICEID_BCM5718           0x1656
+#define        BCOM_DEVICEID_BCM5719           0x1657
 #define        BCOM_DEVICEID_BCM5720           0x1658
 #define        BCOM_DEVICEID_BCM5721           0x1659
 #define        BCOM_DEVICEID_BCM5722           0x165A
_______________________________________________
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