summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/if_nep.c172
1 files changed, 151 insertions, 21 deletions
diff --git a/sys/dev/pci/if_nep.c b/sys/dev/pci/if_nep.c
index 5444b4a618f..60747f302fc 100644
--- a/sys/dev/pci/if_nep.c
+++ b/sys/dev/pci/if_nep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_nep.c,v 1.9 2015/01/03 19:08:40 kettenis Exp $ */
+/* $OpenBSD: if_nep.c,v 1.10 2015/01/03 23:14:33 kettenis Exp $ */
/*
* Copyright (c) 2014, 2015 Mark Kettenis
*
@@ -201,13 +201,55 @@ extern void myetheraddr(u_char *);
#define LINK_FAULT_CNT(port) (FZC_MAC + 0x00180 + (port) * 0x06000)
#define XMAC_SM_REG(port) (FZC_MAC + 0x001a8 + (port) * 0x06000)
-#define BMAC_ADDR0(port) (FZC_MAC + 0x00100 + ((port) - 2) * 0x04000)
-#define BMAC_ADDR1(port) (FZC_MAC + 0x00108 + ((port) - 2) * 0x04000)
-#define BMAC_ADDR2(port) (FZC_MAC + 0x00110 + ((port) - 2) * 0x04000)
-
-#define PCS_MII_CTL(port) (FZC_MAC + 0x04000 + (port) * 0x06000)
+#define TXMAC_SW_RST(port) (FZC_MAC + 0x0c000 + ((port) - 2) * 0x04000)
+#define TXMAC_SW_RST_SW_RST (1ULL << 0)
+#define RXMAC_SW_RST(port) (FZC_MAC + 0x0c008 + ((port) - 2) * 0x04000)
+#define RXMAC_SW_RST_SW_RST (1ULL << 0)
+#define TXMAC_CONFIG(port) (FZC_MAC + 0x0c060 + ((port) - 2) * 0x04000)
+#define TXMAC_CONFIG_TX_ENABLE (1ULL << 0)
+#define RXMAC_CONFIG(port) (FZC_MAC + 0x0c068 + ((port) - 2) * 0x04000)
+#define RXMAC_CONFIG_ERROR_CHK_DIS (1ULL << 7)
+#define RXMAC_CONFIG_ADDR_FILTER_EN (1ULL << 6)
+#define RXMAC_CONFIG_HASH_FILTER_EN (1ULL << 5)
+#define RXMAC_CONFIG_PROMISCUOUS_GROUP (1ULL << 4)
+#define RXMAC_CONFIG_PROMISCUOUS (1ULL << 3)
+#define RXMAC_CONFIG_STRIP_FCS (1ULL << 2)
+#define RXMAC_CONFIG_STRIP_PAD (1ULL << 1)
+#define RXMAC_CONFIG_RX_ENABLE (1ULL << 0)
+#define MAC_XIF_CONFIG(port) (FZC_MAC + 0x0c078 + ((port) - 2) * 0x04000)
+#define MAC_XIF_CONFIG_SEL_CLK_25MHZ (1ULL << 7)
+#define MAC_XIF_CONFIG_GMII_MODE (1ULL << 3)
+#define MAC_XIF_CONFIG_LOOPBACK (1ULL << 1)
+#define MAC_XIF_CONFIG_TX_OUTPUT_EN (1ULL << 0)
+#define BMAC_MIN(port) (FZC_MAC + 0x0c0a0 + ((port) - 2) * 0x04000)
+#define BMAC_MAX(port) (FZC_MAC + 0x0c0a8 + ((port) - 2) * 0x04000)
+#define BMAC_MAX_BURST_SHIFT 16
+#define MAC_PA_SIZE(port) (FZC_MAC + 0x0c0b0 + ((port) - 2) * 0x04000)
+#define MAC_CTRL_TYPE(port) (FZC_MAC + 0x0c0b8 + ((port) - 2) * 0x04000)
+#define BMAC_ADDR0(port) (FZC_MAC + 0x0c100 + ((port) - 2) * 0x04000)
+#define BMAC_ADDR1(port) (FZC_MAC + 0x0c108 + ((port) - 2) * 0x04000)
+#define BMAC_ADDR2(port) (FZC_MAC + 0x0c110 + ((port) - 2) * 0x04000)
+
+#define MAC_ADDR_FILT0(port) (FZC_MAC + 0x0c298 + ((port) - 2) * 0x04000)
+#define MAC_ADDR_FILT1(port) (FZC_MAC + 0x0c2a0 + ((port) - 2) * 0x04000)
+#define MAC_ADDR_FILT2(port) (FZC_MAC + 0x0c2a8 + ((port) - 2) * 0x04000)
+#define MAC_ADDR_FILT12_MASK(port) (FZC_MAC + 0x0c2b0 + ((port) - 2) * 0x04000)
+#define MAC_ADDR_FILT00_MASK(port) (FZC_MAC + 0x0c2b8 + ((port) - 2) * 0x04000)
+
+#define MAC_HASH_TBL0(port) (FZC_MAC + 0x0c2c0 + ((port) - 2) * 0x04000)
+#define MAC_HASH_TBL(port, i) (MAC_HASH_TBL0(port) + (i) * 0x00008)
+
+#define RXMAC_FRM_CNT(port) (FZC_MAC + 0x0c370 + ((port) - 2) * 0x04000)
+#define BMAC_ALTAD_CMPEN(port) (FZC_MAC + 0x0c3f8 + ((port) - 2) * 0x04000)
+
+#define BMAC_HOST_INFO0(port) (FZC_MAC + 0x0c400 + ((port) - 2) * 0x04000)
+#define BMAC_HOST_INFO(port, i) (BMAC_HOST_INFO0(port) + (i) * 0x00008)
+
+#define PCS_PORT_OFFSET(port) ((port < 2) ? ((port) * 0x06000) : \
+ (0x02000 + (port) * 0x4000))
+#define PCS_MII_CTL(port) (FZC_MAC + 0x04000 + PCS_PORT_OFFSET(port))
#define PCS_MII_CTL_RESET (1ULL << 15)
-#define PCS_DPATH_MODE(port) (FZC_MAC + 0x040a0 + (port) * 0x06000)
+#define PCS_DPATH_MODE(port) (FZC_MAC + 0x040a0 + PCS_PORT_OFFSET(port))
#define PCS_DPATH_MODE_MII (1ULL << 1)
#define MIF_FRAME_OUTPUT (FZC_MAC + 0x16018)
@@ -701,7 +743,30 @@ nep_xmac_mii_statchg(struct nep_softc *sc)
void
nep_bmac_mii_statchg(struct nep_softc *sc)
{
- printf("%s\n", __func__);
+ struct mii_data *mii = &sc->sc_mii;
+ uint64_t val;
+
+ val = nep_read(sc, MAC_XIF_CONFIG(sc->sc_port));
+
+ if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX)
+ val |= MAC_XIF_CONFIG_SEL_CLK_25MHZ;
+ else
+ val &= MAC_XIF_CONFIG_SEL_CLK_25MHZ;
+
+ if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
+ IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX)
+ val |= MAC_XIF_CONFIG_GMII_MODE;
+ else
+ val &= ~MAC_XIF_CONFIG_GMII_MODE;
+
+ if (mii->mii_media_active & IFM_LOOP)
+ val |= MAC_XIF_CONFIG_LOOPBACK;
+ else
+ val &= ~MAC_XIF_CONFIG_LOOPBACK;
+
+ val |= MAC_XIF_CONFIG_TX_OUTPUT_EN;
+
+ nep_write(sc, MAC_XIF_CONFIG(sc->sc_port), val);
}
int
@@ -991,7 +1056,7 @@ nep_init_rx_xmac(struct nep_softc *sc)
break;
}
if (n == 0)
- printf("timeout resetting Tx MAC\n");
+ printf("timeout resetting Rx MAC\n");
addr0 = (sc->sc_lladdr[4] << 8) | sc->sc_lladdr[5];
addr1 = (sc->sc_lladdr[2] << 8) | sc->sc_lladdr[3];
@@ -1019,6 +1084,29 @@ void
nep_init_rx_bmac(struct nep_softc *sc)
{
uint64_t addr0, addr1, addr2;
+ uint64_t val;
+ int n, i;
+
+ nep_write(sc, RXMAC_SW_RST(sc->sc_port), RXMAC_SW_RST_SW_RST);
+ n = 1000;
+ while (--n) {
+ val = nep_read(sc, RXMAC_SW_RST(sc->sc_port));
+ if ((val & RXMAC_SW_RST_SW_RST) == 0)
+ break;
+ }
+ if (n == 0)
+ printf("timeout resetting Rx MAC\n");
+
+ val = nep_read(sc, RXMAC_CONFIG(sc->sc_port));
+ val &= ~RXMAC_CONFIG_ERROR_CHK_DIS;
+ val &= ~RXMAC_CONFIG_PROMISCUOUS;
+ val &= ~RXMAC_CONFIG_PROMISCUOUS_GROUP;
+ val &= ~RXMAC_CONFIG_ADDR_FILTER_EN;
+ val &= ~RXMAC_CONFIG_HASH_FILTER_EN;
+ val &= ~RXMAC_CONFIG_STRIP_FCS;
+ val &= ~RXMAC_CONFIG_STRIP_PAD;
+ val &= ~RXMAC_CONFIG_RX_ENABLE;
+ nep_write(sc, RXMAC_CONFIG(sc->sc_port), val);
addr0 = (sc->sc_lladdr[4] << 8) | sc->sc_lladdr[5];
addr1 = (sc->sc_lladdr[2] << 8) | sc->sc_lladdr[3];
@@ -1026,6 +1114,20 @@ nep_init_rx_bmac(struct nep_softc *sc)
nep_write(sc, BMAC_ADDR0(sc->sc_port), addr0);
nep_write(sc, BMAC_ADDR1(sc->sc_port), addr1);
nep_write(sc, BMAC_ADDR2(sc->sc_port), addr2);
+
+ nep_write(sc, BMAC_ALTAD_CMPEN(sc->sc_port), 1);
+
+ nep_write(sc, MAC_ADDR_FILT0(sc->sc_port), 0);
+ nep_write(sc, MAC_ADDR_FILT1(sc->sc_port), 0);
+ nep_write(sc, MAC_ADDR_FILT2(sc->sc_port), 0);
+ nep_write(sc, MAC_ADDR_FILT12_MASK(sc->sc_port), 0);
+ nep_write(sc, MAC_ADDR_FILT00_MASK(sc->sc_port), 0);
+
+ for (i = 0; i < 16; i++)
+ nep_write(sc, MAC_HASH_TBL(sc->sc_port, i), 0);
+
+ for (i = 0; i < 9; i++)
+ nep_write(sc, BMAC_HOST_INFO(sc->sc_port, i), sc->sc_port);
}
void
@@ -1145,6 +1247,24 @@ nep_init_tx_xmac(struct nep_softc *sc)
void
nep_init_tx_bmac(struct nep_softc *sc)
{
+ uint64_t val;
+ int n;
+
+ nep_write(sc, TXMAC_SW_RST(sc->sc_port), TXMAC_SW_RST_SW_RST);
+ n = 1000;
+ while (--n) {
+ val = nep_read(sc, TXMAC_SW_RST(sc->sc_port));
+ if ((val & TXMAC_SW_RST_SW_RST) == 0)
+ break;
+ }
+ if (n == 0)
+ printf("timeout resetting Tx MAC\n");
+
+ nep_write(sc, BMAC_MIN(sc->sc_port), 0x40);
+ nep_write(sc, BMAC_MAX(sc->sc_port), ETHER_MAX_LEN |
+ (ETHER_MAX_LEN << BMAC_MAX_BURST_SHIFT));
+ nep_write(sc, MAC_CTRL_TYPE(sc->sc_port), 0x8808);
+ nep_write(sc, MAC_PA_SIZE(sc->sc_port), 0x7);
}
void
@@ -1175,7 +1295,7 @@ nep_init_tx_channel(struct nep_softc *sc, int chan)
break;
}
if (n == 0)
- printf("timeout resetting Tx dma\n");
+ printf("timeout resetting Tx DMA\n");
nep_write(sc, TX_LOG_MASK1(chan), 0);
nep_write(sc, TX_LOG_VALUE1(chan), 0);
@@ -1263,20 +1383,20 @@ nep_up(struct nep_softc *sc)
val = nep_read(sc, XMAC_CONFIG(sc->sc_port));
val &= ~XMAC_CONFIG_SEL_POR_CLK_SRC;
nep_write(sc, XMAC_CONFIG(sc->sc_port), val);
+ }
- nep_write(sc, PCS_DPATH_MODE(sc->sc_port), PCS_DPATH_MODE_MII);
+ nep_write(sc, PCS_DPATH_MODE(sc->sc_port), PCS_DPATH_MODE_MII);
+ val = nep_read(sc, PCS_MII_CTL(sc->sc_port));
+ val |= PCS_MII_CTL_RESET;
+ nep_write(sc, PCS_MII_CTL(sc->sc_port), val);
+ n = 1000;
+ while (--n) {
val = nep_read(sc, PCS_MII_CTL(sc->sc_port));
- val |= PCS_MII_CTL_RESET;
- nep_write(sc, PCS_MII_CTL(sc->sc_port), val);
- n = 1000;
- while (--n) {
- val = nep_read(sc, PCS_MII_CTL(sc->sc_port));
- if ((val & PCS_MII_CTL_RESET) == 0)
- break;
- }
- if (n == 0)
- printf("timeout resetting PCS\n");
+ if ((val & PCS_MII_CTL_RESET) == 0)
+ break;
}
+ if (n == 0)
+ printf("timeout resetting PCS\n");
nep_init_rx_mac(sc);
nep_init_rx_channel(sc, sc->sc_port);
@@ -1295,6 +1415,14 @@ nep_up(struct nep_softc *sc)
val = nep_read(sc, XMAC_CONFIG(sc->sc_port));
val |= XMAC_CONFIG_TX_ENABLE;
nep_write(sc, XMAC_CONFIG(sc->sc_port), val);
+ } else {
+ val = nep_read(sc, RXMAC_CONFIG(sc->sc_port));
+ val |= RXMAC_CONFIG_RX_ENABLE;
+ nep_write(sc, RXMAC_CONFIG(sc->sc_port), val);
+
+ val = nep_read(sc, TXMAC_CONFIG(sc->sc_port));
+ val |= TXMAC_CONFIG_TX_ENABLE;
+ nep_write(sc, TXMAC_CONFIG(sc->sc_port), val);
}
val = nep_read(sc, RXDMA_CFIG1(sc->sc_port));
@@ -1370,6 +1498,8 @@ nep_encap(struct nep_softc *sc, struct mbuf **m0, int *idx)
// nep_read(sc, XRXMAC_STATUS(sc->sc_port)));
// printf("RXMAC_BT_CNT: %llx\n",
// nep_read(sc, RXMAC_BT_CNT(sc->sc_port)));
+// printf("RXMAC_FRM_CNT: %llx\n",
+// nep_read(sc, RXMAC_FRM_CNT(sc->sc_port)));
// printf("TXMAC_FRM_CNT: %llx\n",
// nep_read(sc, TXMAC_FRM_CNT(sc->sc_port)));
// printf("TXMAC_BYTE_CNT: %llx\n",