Page MenuHomeFreeBSD

D60539.id189268.diff
No OneTemporary

D60539.id189268.diff

Index: sys/dev/mgb/if_mgb.h
===================================================================
--- sys/dev/mgb/if_mgb.h
+++ sys/dev/mgb/if_mgb.h
@@ -33,6 +33,7 @@
#define MGB_MICROCHIP_VENDOR_ID 0x1055
#define MGB_LAN7430_DEVICE_ID 0x7430
#define MGB_LAN7431_DEVICE_ID 0x7431
+#define MGB_PCI11414_DEVICE_ID 0xA041
#define MGB_TIMEOUT (500)
@@ -85,6 +86,19 @@
#define MGB_PHY_RESET 0x10
#define MGB_PHY_READY 0x80
+/* Strap configuration */
+#define STRAP_READ 0x0C
+#define STRAP_READ_USE_RMII_EN (1 << 23)
+#define STRAP_READ_USE_SGMII_EN (1 << 22)
+#define STRAP_READ_RMII_EN (1 << 7)
+#define STRAP_READ_SGMII_EN (1 << 6)
+#define STRAP_READ_SGMII_REFCLK (1 << 5)
+#define STRAP_READ_SGMII_2_5G (1 << 4)
+#define STRAP_READ_BASE_X (1 << 3)
+#define STRAP_READ_RGMII_TXC_DELAY_EN (1 << 2)
+#define STRAP_READ_RGMII_RXC_DELAY_EN (1 << 1)
+#define STRAP_READ_ADV_PM_DISABLE (1 << 0)
+
/** FIFO Controller **/
#define MGB_FCT_TX_CTL 0xC4
#define MGB_FCT_RX_CTL 0xAC
@@ -129,7 +143,7 @@
*
**/
/* In linux driver these numbers are 50 and 65 for tx and rx .... */
-#define MGB_DMA_RING_SIZE 16 /* in programming guide, this number is 100 */
+#define MGB_DMA_RING_SIZE 1024 /* in programming guide, this number is 100 */
#define MGB_DMA_MAXSEGS 32
#define MGB_DMA_REG(reg, _channel) ((reg) | ((_channel) << 6))
#define MGB_DMA_RING_LIST_SIZE \
@@ -193,6 +207,22 @@
#define MGB_MII_WRITE 0x2
#define MGB_MII_BUSY 0x1
+#define SGMII_ACC 0x720
+#define SGMII_ACC_SGMII_BZY (1 << 31)
+#define SGMII_ACC_SGMII_WR (1 << 30)
+#define SGMII_ACC_SGMII_MMD_SHIFT 16
+#define SGMII_ACC_SGMII_MMD_MASK 0xf0000
+#define SGMII_ACC_SGMII_MMD_VSR (1 << 15)
+#define SGMII_ACC_SGMII_ADDR_SHIFT 0
+#define SGMII_ACC_SGMII_ADDR_MASK 0xffff
+#define SGMII_DATA 0x724
+#define SGMII_DATA_SHIFT 0
+#define SGMII_DATA_MASK 0xffff
+#define SGMII_CTL 0x728
+#define SGMII_CTL_SGMII_ENABLE (1 << 31)
+#define SGMII_CTL_LINK_STATUS_SOURCE (1 << 8)
+#define SGMII_CTL_SGMII_POWER_DN (1 << 1)
+
/** Interrupt registers **/
#define MGB_INTR_STS 0x780
#define MGB_INTR_SET 0x784 /* This triggers a particular interrupt */
@@ -324,6 +354,7 @@
struct mgb_ring_data rx_ring_data;
struct mgb_ring_data tx_ring_data;
+ bool sgmii_en;
};
#endif /* _IF_MGB_H_ */
Index: sys/dev/mgb/if_mgb.c
===================================================================
--- sys/dev/mgb/if_mgb.c
+++ sys/dev/mgb/if_mgb.c
@@ -91,6 +91,8 @@
"Microchip LAN7430 PCIe Gigabit Ethernet Controller"),
PVID(MGB_MICROCHIP_VENDOR_ID, MGB_LAN7431_DEVICE_ID,
"Microchip LAN7431 PCIe Gigabit Ethernet Controller"),
+ PVID(MGB_MICROCHIP_VENDOR_ID, MGB_PCI11414_DEVICE_ID,
+ "Microchip PCI11414 PCIe Gigabit Ethernet Controller"),
PVID_END
};
@@ -328,14 +330,48 @@
return (&mgb_sctx_init);
}
+static int
+mgb_mii_attach(struct mgb_softc *sc)
+{
+ struct mii_data *miid;
+ if_softc_ctx_t scctx;
+ int phyaddr;
+ int error;
+
+ scctx = iflib_get_softc_ctx(sc->ctx);
+
+ switch (pci_get_device(sc->dev)) {
+ case MGB_LAN7430_DEVICE_ID:
+ phyaddr = 1;
+ break;
+ case MGB_LAN7431_DEVICE_ID:
+ default:
+ phyaddr = MII_PHY_ANY;
+ break;
+ }
+
+ /* XXX: Would be nice(r) if locked methods were here */
+ error = mii_attach(sc->dev, &sc->miibus, iflib_get_ifp(sc->ctx),
+ mgb_media_change, mgb_media_status,
+ BMSR_DEFCAPMASK, phyaddr, MII_OFFSET_ANY, MIIF_DOPAUSE);
+ if (error != 0) {
+ device_printf(sc->dev, "Failed to attach MII interface\n");
+ return (error);
+ }
+
+ miid = device_get_softc(sc->miibus);
+ scctx->isc_media = &miid->mii_media;
+
+ return (0);
+}
+
static int
mgb_attach_pre(if_ctx_t ctx)
{
struct mgb_softc *sc;
if_softc_ctx_t scctx;
- int error, phyaddr, rid;
+ int error, rid;
struct ether_addr hwaddr;
- struct mii_data *miid;
sc = iflib_get_softc(ctx);
sc->ctx = ctx;
@@ -395,28 +431,12 @@
goto fail;
}
- switch (pci_get_device(sc->dev)) {
- case MGB_LAN7430_DEVICE_ID:
- phyaddr = 1;
- break;
- case MGB_LAN7431_DEVICE_ID:
- default:
- phyaddr = MII_PHY_ANY;
- break;
- }
-
- /* XXX: Would be nice(r) if locked methods were here */
- error = mii_attach(sc->dev, &sc->miibus, iflib_get_ifp(ctx),
- mgb_media_change, mgb_media_status,
- BMSR_DEFCAPMASK, phyaddr, MII_OFFSET_ANY, MIIF_DOPAUSE);
- if (error != 0) {
- device_printf(sc->dev, "Failed to attach MII interface\n");
- goto fail;
+ if (!sc->sgmii_en) {
+ error = mgb_mii_attach(sc);
+ if (error)
+ goto fail;
}
- miid = device_get_softc(sc->miibus);
- scctx->isc_media = &miid->mii_media;
-
scctx->isc_msix_bar = pci_msix_table_bar(sc->dev);
/** Setup PBA BAR **/
rid = pci_msix_pba_bar(sc->dev);
@@ -447,6 +467,9 @@
CSR_WRITE_REG(sc, MGB_INTR_VEC_TX_MAP, 0);
CSR_WRITE_REG(sc, MGB_INTR_VEC_OTHER_MAP, 0);
+ if (sc->sgmii_en)
+ iflib_link_state_change(ctx, LINK_STATE_UP, IF_Mbps(1000));
+
return (0);
fail:
@@ -598,8 +621,8 @@
int error;
sc = iflib_get_softc(ctx);
- miid = device_get_softc(sc->miibus);
- device_printf(sc->dev, "running init ...\n");
+ if (bootverbose)
+ device_printf(sc->dev, "running init ...\n");
mgb_dma_init(sc);
@@ -610,6 +633,10 @@
MGB_RFE_ALLOW_MULTICAST |
MGB_RFE_ALLOW_UNICAST);
+ if (sc->sgmii_en)
+ return;
+
+ miid = device_get_softc(sc->miibus);
error = mii_mediachg(miid);
/* Not much we can do if this fails. */
if (error)
@@ -963,6 +990,7 @@
struct mgb_ring_desc *txd;
bus_dma_segment_t *segs;
qidx_t pidx, nsegs;
+ uint32_t ctl;
int i;
KASSERT(ipi->ipi_qsidx == 0,
@@ -976,23 +1004,20 @@
/* For each seg, create a descriptor */
for (i = 0; i < nsegs; ++i) {
- KASSERT(nsegs == 1, ("Multisegment packet !!!!!\n"));
txd = &rdata->ring[pidx];
- txd->ctl = htole32(
- (segs[i].ds_len & MGB_DESC_CTL_BUFLEN_MASK ) |
- /*
- * XXX: This will be wrong in the multipacket case
- * I suspect FS should be for the first packet and
- * LS should be for the last packet
- */
- MGB_TX_DESC_CTL_FS | MGB_TX_DESC_CTL_LS |
- MGB_DESC_CTL_FCS);
+ ctl = (segs[i].ds_len & MGB_DESC_CTL_BUFLEN_MASK) |
+ MGB_DESC_CTL_FCS;
+ if (i == 0)
+ ctl |= MGB_TX_DESC_CTL_FS;
+ if (i == (nsegs - 1))
+ ctl |= MGB_TX_DESC_CTL_LS | 0x04000000;
+ txd->ctl = htole32(ctl);
txd->addr.low = htole32(CSR_TRANSLATE_ADDR_LOW32(
segs[i].ds_addr));
txd->addr.high = htole32(CSR_TRANSLATE_ADDR_HIGH32(
segs[i].ds_addr));
txd->sts = htole32(
- (segs[i].ds_len << 16) & MGB_DESC_FRAME_LEN_MASK);
+ (ipi->ipi_len << 16) & MGB_DESC_FRAME_LEN_MASK);
pidx = MGB_NEXT_RING_IDX(pidx);
}
ipi->ipi_new_pidx = pidx;
@@ -1187,7 +1212,8 @@
id_rev = CSR_READ_REG(sc, 0);
dev_id = id_rev >> 16;
if (dev_id == MGB_LAN7430_DEVICE_ID ||
- dev_id == MGB_LAN7431_DEVICE_ID) {
+ dev_id == MGB_LAN7431_DEVICE_ID ||
+ dev_id == MGB_PCI11414_DEVICE_ID) {
return (0);
} else {
device_printf(sc->dev, "ID check failed.\n");
@@ -1446,7 +1472,11 @@
static int
mgb_hw_init(struct mgb_softc *sc)
{
- int error = 0;
+ uint32_t sgmii_ctl;
+ uint32_t reg;
+ int error;
+
+ error = 0;
error = mgb_hw_reset(sc);
if (error != 0)
@@ -1458,6 +1488,19 @@
if (error != 0)
goto fail;
+ /* Enable SGMII if needed. */
+ reg = CSR_READ_REG(sc, STRAP_READ);
+ if (bootverbose)
+ device_printf(sc->dev, "strap %x\n", reg);
+ if ((reg & STRAP_READ_USE_SGMII_EN) != 0 &&
+ (reg & STRAP_READ_SGMII_EN) != 0) {
+ sgmii_ctl = CSR_READ_REG(sc, SGMII_CTL);
+ sgmii_ctl |= SGMII_CTL_SGMII_ENABLE;
+ sgmii_ctl &= ~SGMII_CTL_SGMII_POWER_DN;
+ CSR_WRITE_REG(sc, SGMII_CTL, sgmii_ctl);
+ sc->sgmii_en = true;
+ }
+
error = mgb_dmac_reset(sc);
if (error != 0)
goto fail;
@@ -1519,7 +1562,7 @@
* XXX: Datasheets states delay should be > 5 microseconds
* for device reset.
*/
- DELAY(100);
+ DELAY(10000);
val = CSR_READ_REG(sc, reg);
if ((val & set_bits) == set_bits && (val & clear_bits) == 0)
return (MGB_STS_OK);

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 12, 7:02 AM (11 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40559502
Default Alt Text
D60539.id189268.diff (7 KB)

Event Timeline