Index: if_xge.c =================================================================== RCS file: /cvs/src/sys/dev/pci/if_xge.c,v retrieving revision 1.67 diff -u -p -u -r1.67 if_xge.c --- if_xge.c 25 Nov 2015 03:09:59 -0000 1.67 +++ if_xge.c 22 Apr 2016 07:09:29 -0000 @@ -120,7 +120,7 @@ * Magic to fix a bug when the MAC address cannot be read correctly. * This came from the Linux driver. */ -static uint64_t fix_mac[] = { +static const uint64_t xge_fix_mac[] = { 0x0060000000000000ULL, 0x0060600000000000ULL, 0x0040600000000000ULL, 0x0000600000000000ULL, 0x0020600000000000ULL, 0x0060600000000000ULL, @@ -141,8 +141,7 @@ static uint64_t fix_mac[] = { * Constants to be programmed into Hercules's registers, to configure * the XGXS transciever. */ -#define END_SIGN 0x0 -static uint64_t herc_dtx_cfg[] = { +static const uint64_t xge_herc_dtx_cfg[] = { 0x8000051536750000ULL, 0x80000515367500E0ULL, 0x8000051536750004ULL, 0x80000515367500E4ULL, @@ -154,8 +153,17 @@ static uint64_t herc_dtx_cfg[] = { 0x80020515F2100000ULL, 0x80020515F21000E0ULL, 0x80020515F2100004ULL, 0x80020515F21000E4ULL, +}; + +static const uint64_t xge_xena_dtx_cfg[] = { + 0x8000051500000000ULL, 0x80000515000000E0ULL, + 0x80000515D9350004ULL, 0x80000515D93500E4ULL, - END_SIGN + 0x8001051500000000ULL, 0x80010515000000E0ULL, + 0x80010515001E0004ULL, 0x80010515001E00E4ULL, + + 0x8002051500000000ULL, 0x80020515000000E0ULL, + 0x80020515F2100004ULL, 0x80020515F21000E4ULL, }; struct xge_softc { @@ -230,42 +238,74 @@ int xge_intr(void *); static inline void pif_wcsr(struct xge_softc *sc, bus_size_t csr, uint64_t val) { +#if defined(__LP64__) + bus_space_write_raw_8(sc->sc_st, sc->sc_sh, csr, val); +#else uint32_t lval, hval; lval = val&0xffffffff; hval = val>>32; - bus_space_write_4(sc->sc_st, sc->sc_sh, csr, lval); - bus_space_write_4(sc->sc_st, sc->sc_sh, csr+4, hval); +#if BYTE_ORDER == LITTLE_ENDIAN + bus_space_write_raw_4(sc->sc_st, sc->sc_sh, csr, lval); + bus_space_write_raw_4(sc->sc_st, sc->sc_sh, csr+4, hval); +#else + bus_space_write_raw_4(sc->sc_st, sc->sc_sh, csr+4, lval); + bus_space_write_raw_4(sc->sc_st, sc->sc_sh, csr, hval); +#endif +#endif } static inline uint64_t pif_rcsr(struct xge_softc *sc, bus_size_t csr) { - uint64_t val, val2; + uint64_t val; +#if defined(__LP64__) + val = bus_space_read_raw_8(sc->sc_st, sc->sc_sh, csr); +#else + uint64_t val2; - val = bus_space_read_4(sc->sc_st, sc->sc_sh, csr); - val2 = bus_space_read_4(sc->sc_st, sc->sc_sh, csr+4); + val = bus_space_read_raw_4(sc->sc_st, sc->sc_sh, csr); + val2 = bus_space_read_raw_4(sc->sc_st, sc->sc_sh, csr+4); +#if BYTE_ORDER == LITTLE_ENDIAN val |= (val2 << 32); +#else + val = (val << 32 | val2); +#endif +#endif return (val); } static inline void txp_wcsr(struct xge_softc *sc, bus_size_t csr, uint64_t val) { +#if defined(__LP64__) + bus_space_write_raw_8(sc->sc_txt, sc->sc_txh, csr, val); +#else uint32_t lval, hval; lval = val&0xffffffff; hval = val>>32; - bus_space_write_4(sc->sc_txt, sc->sc_txh, csr, lval); - bus_space_write_4(sc->sc_txt, sc->sc_txh, csr+4, hval); +#if BYTE_ORDER == LITTLE_ENDIAN + bus_space_write_raw_4(sc->sc_txt, sc->sc_txh, csr, lval); + bus_space_write_raw_4(sc->sc_txt, sc->sc_txh, csr+4, hval); +#else + bus_space_write_raw_4(sc->sc_txt, sc->sc_txh, csr, hval); + bus_space_write_raw_4(sc->sc_txt, sc->sc_txh, csr+4, lval); +#endif +#endif } - static inline void pif_wkey(struct xge_softc *sc, bus_size_t csr, uint64_t val) { +#if defined(__LP64__) + if (sc->xge_type == XGE_TYPE_XENA) + PIF_WCSR(RMAC_CFG_KEY, RMAC_KEY_VALUE); + + bus_space_write_raw_8(sc->sc_st, sc->sc_sh, csr, val); +#else uint32_t lval, hval; lval = val&0xffffffff; @@ -274,12 +314,20 @@ pif_wkey(struct xge_softc *sc, bus_size_ if (sc->xge_type == XGE_TYPE_XENA) PIF_WCSR(RMAC_CFG_KEY, RMAC_KEY_VALUE); - bus_space_write_4(sc->sc_st, sc->sc_sh, csr, lval); +#if BYTE_ORDER == LITTLE_ENDIAN + bus_space_write_raw_4(sc->sc_st, sc->sc_sh, csr, lval); +#else + bus_space_write_raw_4(sc->sc_st, sc->sc_sh, csr, hval); +#endif if (sc->xge_type == XGE_TYPE_XENA) PIF_WCSR(RMAC_CFG_KEY, RMAC_KEY_VALUE); - - bus_space_write_4(sc->sc_st, sc->sc_sh, csr+4, hval); +#if BYTE_ORDER == LITTLE_ENDIAN + bus_space_write_raw_4(sc->sc_st, sc->sc_sh, csr+4, hval); +#else + bus_space_write_raw_4(sc->sc_st, sc->sc_sh, csr+4, lval); +#endif +#endif } struct cfattach xge_ca = { @@ -360,6 +408,7 @@ xge_attach(struct device *parent, struct /* Save PCI config space */ for (i = 0; i < XGE_PCISIZE_XENA; i += 4) sc->sc_pciregs[i/4] = pci_conf_read(pa->pa_pc, pa->pa_tag, i); + sc->sc_pciregs[i/4] = pci_conf_read(pa->pa_pc, pa->pa_tag, i); } #if BYTE_ORDER == LITTLE_ENDIAN @@ -368,13 +417,17 @@ xge_attach(struct device *parent, struct PIF_WCSR(SWAPPER_CTRL, val); PIF_WCSR(SWAPPER_CTRL, val); #endif - if ((val = PIF_RCSR(PIF_RD_SWAPPER_Fb)) != SWAPPER_MAGIC) { - printf(": failed configuring endian, %llx != %llx!\n", + printf(": failed configuring endian (read), %llx != %llx!\n", (unsigned long long)val, SWAPPER_MAGIC); - return; } + PIF_WCSR(XMSI_ADDRESS, SWAPPER_MAGIC); + if ((val = PIF_RCSR(XMSI_ADDRESS)) != SWAPPER_MAGIC) { + printf(": failed configuring endian (write), %llx != %llx!\n", + (unsigned long long)val, SWAPPER_MAGIC); + } + /* * Fix for all "FFs" MAC address problems observed on * Alpha platforms. Not needed for Herc. @@ -385,8 +438,8 @@ xge_attach(struct device *parent, struct * Resolve it by writing some magics to GPIO_CONTROL and * force a chip reset to read in the serial eeprom again. */ - for (i = 0; i < nitems(fix_mac); i++) { - PIF_WCSR(GPIO_CONTROL, fix_mac[i]); + for (i = 0; i < nitems(xge_fix_mac); i++) { + PIF_WCSR(GPIO_CONTROL, xge_fix_mac[i]); PIF_RCSR(GPIO_CONTROL); } @@ -409,7 +462,14 @@ xge_attach(struct device *parent, struct #endif if ((val = PIF_RCSR(PIF_RD_SWAPPER_Fb)) != SWAPPER_MAGIC) { - printf(": failed configuring endian2, %llx != %llx!\n", + printf(": failed configuring endian2 (read), %llx != %llx!\n", + (unsigned long long)val, SWAPPER_MAGIC); + return; + } + + PIF_WCSR(XMSI_ADDRESS, SWAPPER_MAGIC); + if ((val = PIF_RCSR(XMSI_ADDRESS)) != SWAPPER_MAGIC) { + printf(": failed configuring endian2 (write), %llx != %llx!\n", (unsigned long long)val, SWAPPER_MAGIC); return; } @@ -756,12 +816,13 @@ xge_init(struct ifnet *ifp) */ PIF_WCSR(TX_TRAFFIC_MASK, 0); PIF_WCSR(RX_TRAFFIC_MASK, 0); - PIF_WCSR(GENERAL_INT_MASK, 0); PIF_WCSR(TXPIC_INT_MASK, 0); PIF_WCSR(RXPIC_INT_MASK, 0); PIF_WCSR(MAC_INT_MASK, MAC_TMAC_INT); /* only from RMAC */ + PIF_WCSR(MAC_RMAC_ERR_REG, RMAC_LINK_STATE_CHANGE_INT); PIF_WCSR(MAC_RMAC_ERR_MASK, ~RMAC_LINK_STATE_CHANGE_INT); + PIF_WCSR(GENERAL_INT_MASK, 0); xge_setpromisc(sc); @@ -818,7 +879,7 @@ xge_intr(void *pv) while ((PIF_RCSR(ADAPTER_STATUS) & QUIESCENT) != QUIESCENT) ; PIF_WCSR(MAC_RMAC_ERR_REG, RMAC_LINK_STATE_CHANGE_INT); - + val = PIF_RCSR(ADAPTER_STATUS); if ((val & (RMAC_REMOTE_FAULT|RMAC_LOCAL_FAULT)) == 0) xge_enable(sc); /* Only if link restored */ @@ -1321,6 +1382,8 @@ xge_add_rxbuf(struct xge_softc *sc, int bus_dmamap_unload(sc->sc_dmat, sc->sc_rxm[id]); sc->sc_rxb[id] = m[0]; + m_adj(m[0], ETHER_ALIGN); + error = bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_rxm[id], m[0], BUS_DMA_READ|BUS_DMA_NOWAIT); if (error) @@ -1354,100 +1417,24 @@ xge_add_rxbuf(struct xge_softc *sc, int int xge_setup_xgxs_xena(struct xge_softc *sc) { - /* The magic numbers are described in the users guide */ - - /* Writing to MDIO 0x8000 (Global Config 0) */ - PIF_WCSR(DTX_CONTROL, 0x8000051500000000ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x80000515000000E0ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x80000515D93500E4ULL); DELAY(50); - - /* Writing to MDIO 0x8000 (Global Config 1) */ - PIF_WCSR(DTX_CONTROL, 0x8001051500000000ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x80010515000000e0ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x80010515001e00e4ULL); DELAY(50); - - /* Reset the Gigablaze */ - PIF_WCSR(DTX_CONTROL, 0x8002051500000000ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x80020515000000E0ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x80020515F21000E4ULL); DELAY(50); - - /* read the pole settings */ - PIF_WCSR(DTX_CONTROL, 0x8000051500000000ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x80000515000000e0ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x80000515000000ecULL); DELAY(50); - - PIF_WCSR(DTX_CONTROL, 0x8001051500000000ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x80010515000000e0ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x80010515000000ecULL); DELAY(50); - - PIF_WCSR(DTX_CONTROL, 0x8002051500000000ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x80020515000000e0ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x80020515000000ecULL); DELAY(50); - - /* Workaround for TX Lane XAUI initialization error. - Read Xpak PHY register 24 for XAUI lane status */ - PIF_WCSR(DTX_CONTROL, 0x0018040000000000ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x00180400000000e0ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x00180400000000ecULL); DELAY(50); - - /* - * Reading the MDIO control with value 0x1804001c0F001c - * means the TxLanes were already in sync - * Reading the MDIO control with value 0x1804000c0x001c - * means some TxLanes are not in sync where x is a 4-bit - * value representing each lanes - */ -#if 0 - val = PIF_RCSR(MDIO_CONTROL); - if (val != 0x1804001c0F001cULL) { - printf("%s: MDIO_CONTROL: %llx != %llx\n", - XNAME, val, 0x1804001c0F001cULL); - return (1); - } -#endif - - /* Set and remove the DTE XS INTLoopBackN */ - PIF_WCSR(DTX_CONTROL, 0x0000051500000000ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x00000515604000e0ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x00000515604000e4ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x00000515204000e4ULL); DELAY(50); - PIF_WCSR(DTX_CONTROL, 0x00000515204000ecULL); DELAY(50); + int i = 0; -#if 0 - /* Reading the DTX control register Should be 0x5152040001c */ - val = PIF_RCSR(DTX_CONTROL); - if (val != 0x5152040001cULL) { - printf("%s: DTX_CONTROL: %llx != %llx\n", - XNAME, val, 0x5152040001cULL); - return (1); + for (i = 0; i < nitems(xge_xena_dtx_cfg); i++) { + PIF_WCSR(DTX_CONTROL, xge_xena_dtx_cfg[i]); + DELAY(100); } -#endif - PIF_WCSR(MDIO_CONTROL, 0x0018040000000000ULL); DELAY(50); - PIF_WCSR(MDIO_CONTROL, 0x00180400000000e0ULL); DELAY(50); - PIF_WCSR(MDIO_CONTROL, 0x00180400000000ecULL); DELAY(50); - -#if 0 - /* Reading the MIOD control should be 0x1804001c0f001c */ - val = PIF_RCSR(MDIO_CONTROL); - if (val != 0x1804001c0f001cULL) { - printf("%s: MDIO_CONTROL2: %llx != %llx\n", - XNAME, val, 0x1804001c0f001cULL); - return (1); - } -#endif return (0); } int xge_setup_xgxs_herc(struct xge_softc *sc) { - int dtx_cnt = 0; + int i = 0; - while (herc_dtx_cfg[dtx_cnt] != END_SIGN) { - PIF_WCSR(DTX_CONTROL, herc_dtx_cfg[dtx_cnt]); + for (i = 0; i < nitems(xge_herc_dtx_cfg); i++) { + PIF_WCSR(DTX_CONTROL, xge_herc_dtx_cfg[i]); DELAY(100); - dtx_cnt++; } return (0); Index: if_xgereg.h =================================================================== RCS file: /cvs/src/sys/dev/pci/if_xgereg.h,v retrieving revision 1.4 diff -u -p -u -r1.4 if_xgereg.h --- if_xgereg.h 27 Feb 2007 22:39:39 -0000 1.4 +++ if_xgereg.h 22 Apr 2016 07:09:29 -0000 @@ -135,6 +135,8 @@ #define PIF_RD_SWAPPER_Fb PCIXB(0x110) #define SWAPPER_MAGIC 0x0123456789abcdefULL +#define XMSI_ADDRESS PCIXB(0x160) + /* Stats registers */ #define STAT_CFG PCIXB(0x1d0) #define STAT_ADDR PCIXB(0x1d8)