Misc fixes to support 21041 on Qube2700:
- prepare two TX descriptors to avoid race and also use chaind mode - use a recently added pcicfgread() function to get tulip I/O address - use cobalt model id to see if we have 21041 or 21143 (XXX maybe it's better to see PCI product ID) - add code to reset SIA on 21041 - prepare and send filter setup packet on init - reduce delay in RX polling - bump version again Now netboot works fine on Qube 2700 (even without console). Yay.
This commit is contained in:
parent
55edbc2411
commit
069af26195
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: tlp.c,v 1.4 2008/03/01 20:24:25 tsutsui Exp $ */
|
/* $NetBSD: tlp.c,v 1.5 2008/03/01 20:39:25 tsutsui Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2007 The NetBSD Foundation, Inc.
|
* Copyright (c) 2007 The NetBSD Foundation, Inc.
|
||||||
@ -72,6 +72,7 @@ do { \
|
|||||||
#define T1_FS (1U<<29) /* first segment */
|
#define T1_FS (1U<<29) /* first segment */
|
||||||
#define T1_SET (1U<<27) /* "setup packet" */
|
#define T1_SET (1U<<27) /* "setup packet" */
|
||||||
#define T1_TER (1U<<25) /* end of ring mark */
|
#define T1_TER (1U<<25) /* end of ring mark */
|
||||||
|
#define T1_TCH (1U<<24) /* Second address chained */
|
||||||
#define T1_TBS_MASK 0x7ff /* segment size 10:0 */
|
#define T1_TBS_MASK 0x7ff /* segment size 10:0 */
|
||||||
#define R0_OWN (1U<<31) /* desc is empty */
|
#define R0_OWN (1U<<31) /* desc is empty */
|
||||||
#define R0_FS (1U<<30) /* first desc of frame */
|
#define R0_FS (1U<<30) /* first desc of frame */
|
||||||
@ -90,18 +91,21 @@ struct desc {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TLP_BMR 0x000 /* 0: bus mode */
|
#define TLP_BMR 0x00 /* 0: bus mode */
|
||||||
#define BMR_RST (1U<< 0) /* software reset */
|
#define BMR_RST (1U<< 0) /* software reset */
|
||||||
#define TLP_TPD 0x008 /* 1: instruct Tx to start */
|
#define BMR_BAR (1U<< 1) /* bus arbitration */
|
||||||
|
#define BMR_PBL8 (1U<<11) /* burst length 8 longword */
|
||||||
|
#define BMR_CAL8 (1U<<13) /* cache alignment 8 longword */
|
||||||
|
#define TLP_TPD 0x08 /* 1: instruct Tx to start */
|
||||||
#define TPD_POLL (1U<< 0) /* transmit poll demand */
|
#define TPD_POLL (1U<< 0) /* transmit poll demand */
|
||||||
#define TLP_RPD 0x010 /* 2: instruct Rx to start */
|
#define TLP_RPD 0x10 /* 2: instruct Rx to start */
|
||||||
#define RPD_POLL (1U<< 0) /* receive poll demand */
|
#define RPD_POLL (1U<< 0) /* receive poll demand */
|
||||||
#define TLP_RRBA 0x018 /* 3: Rx descriptor base */
|
#define TLP_RRBA 0x18 /* 3: Rx descriptor base */
|
||||||
#define TLP_TRBA 0x020 /* 4: Tx descriptor base */
|
#define TLP_TRBA 0x20 /* 4: Tx descriptor base */
|
||||||
#define TLP_STS 0x028 /* 5: status */
|
#define TLP_STS 0x28 /* 5: status */
|
||||||
#define STS_TS 0x00700000 /* Tx status */
|
#define STS_TS 0x00700000 /* Tx status */
|
||||||
#define STS_RS 0x000e0000 /* Rx status */
|
#define STS_RS 0x000e0000 /* Rx status */
|
||||||
#define TLP_OMR 0x030 /* 6: operation mode */
|
#define TLP_OMR 0x30 /* 6: operation mode */
|
||||||
#define OMR_SDP (1U<<25) /* always ON */
|
#define OMR_SDP (1U<<25) /* always ON */
|
||||||
#define OMR_PS (1U<<18) /* port select */
|
#define OMR_PS (1U<<18) /* port select */
|
||||||
#define OMR_PM (1U<< 6) /* promicuous */
|
#define OMR_PM (1U<< 6) /* promicuous */
|
||||||
@ -109,27 +113,40 @@ struct desc {
|
|||||||
#define OMR_REN (1U<< 1) /* instruct start/stop Rx */
|
#define OMR_REN (1U<< 1) /* instruct start/stop Rx */
|
||||||
#define OMR_FD (1U<< 9) /* FDX */
|
#define OMR_FD (1U<< 9) /* FDX */
|
||||||
#define TLP_IEN 0x38 /* 7: interrupt enable mask */
|
#define TLP_IEN 0x38 /* 7: interrupt enable mask */
|
||||||
#define TLP_APROM 0x048 /* 9: SEEPROM and MII management */
|
#define TLP_APROM 0x48 /* 9: SEEPROM and MII management */
|
||||||
#define SROM_RD (1U <<14) /* read operation */
|
#define SROM_RD (1U <<14) /* read operation */
|
||||||
#define SROM_WR (1U <<13) /* write openration */
|
#define SROM_WR (1U <<13) /* write openration */
|
||||||
#define SROM_SR (1U <<11) /* SEEPROM select */
|
#define SROM_SR (1U <<11) /* SEEPROM select */
|
||||||
#define TLP_CSR12 0x60 /* SIA status */
|
#define TLP_CSR12 0x60 /* SIA status */
|
||||||
|
|
||||||
|
#define TLP_CSR13 0x68 /* SIA connectivity register */
|
||||||
|
#define SIACONN_10BT 0x0000ef01 /* 10BASE-T for 21041 */
|
||||||
|
|
||||||
|
#define TLP_CSR14 0x70 /* SIA TX RX register */
|
||||||
|
#define SIATXRX_10BT 0x0000ffff /* 10BASE-T for 21041 pass 2 */
|
||||||
|
|
||||||
#define TLP_CSR15 0x78 /* SIA general register */
|
#define TLP_CSR15 0x78 /* SIA general register */
|
||||||
#define SIAGEN_MD0 (1U<<16)
|
#define SIAGEN_MD0 (1U<<16)
|
||||||
#define SIAGEN_CWE (1U<<28)
|
#define SIAGEN_CWE (1U<<28)
|
||||||
|
#define SIAGEN_10BT 0x00000000 /* 10BASE-T for 21041 */
|
||||||
|
|
||||||
|
#define TLP_SETUP_NADDR 16
|
||||||
|
#define TLP_SETUPLEN 192 /* 16 * 3 * sizeof(uint32_t) */
|
||||||
|
|
||||||
#define FRAMESIZE 1536
|
#define FRAMESIZE 1536
|
||||||
#define BUFSIZE 2048
|
#define BUFSIZE 2048
|
||||||
|
#define NTXBUF 2
|
||||||
|
#define NEXT_TXBUF(x) (((x) + 1) & (NTXBUF - 1))
|
||||||
#define NRXBUF 2
|
#define NRXBUF 2
|
||||||
#define NEXT_RXBUF(x) (((x) + 1) & (NRXBUF - 1))
|
#define NEXT_RXBUF(x) (((x) + 1) & (NRXBUF - 1))
|
||||||
|
|
||||||
struct local {
|
struct local {
|
||||||
struct desc txd;
|
struct desc txd[NTXBUF];
|
||||||
struct desc rxd[NRXBUF];
|
struct desc rxd[NRXBUF];
|
||||||
uint8_t txstore[BUFSIZE];
|
uint8_t txstore[TLP_SETUPLEN];
|
||||||
uint8_t rxstore[NRXBUF][BUFSIZE];
|
uint8_t rxstore[NRXBUF][BUFSIZE];
|
||||||
uint32_t csr, omr;
|
uint32_t csr, omr;
|
||||||
|
u_int tx;
|
||||||
u_int rx;
|
u_int rx;
|
||||||
u_int sromsft;
|
u_int sromsft;
|
||||||
u_int phy;
|
u_int phy;
|
||||||
@ -150,25 +167,33 @@ static void mii_initphy(struct local *);
|
|||||||
void *
|
void *
|
||||||
tlp_init(void *cookie)
|
tlp_init(void *cookie)
|
||||||
{
|
{
|
||||||
uint32_t val;
|
uint32_t val, tag;
|
||||||
struct local *l;
|
struct local *l;
|
||||||
struct desc *txd, *rxd;
|
struct desc *txd, *rxd;
|
||||||
uint8_t *en;
|
uint8_t *en, *p;
|
||||||
int i;
|
int i;
|
||||||
|
int is21041;
|
||||||
|
|
||||||
|
if (cobalt_id == COBALT_ID_QUBE2700)
|
||||||
|
is21041 = 1;
|
||||||
|
else
|
||||||
|
is21041 = 0;
|
||||||
|
|
||||||
l = ALLOC(struct local, CACHELINESIZE);
|
l = ALLOC(struct local, CACHELINESIZE);
|
||||||
memset(l, 0, sizeof(struct local));
|
memset(l, 0, sizeof(struct local));
|
||||||
|
|
||||||
DPRINTF(("tlp: l = %p, txd = %p, rxd[0] = %p, rxd[1] = %p\n",
|
DPRINTF(("tlp: l = %p, txd[0] = %p, txd[1] = %p\n",
|
||||||
l, &l->txd, &l->rxd[0], &l->rxd[1]));
|
l, &l->txd[0], &l->txd[1]));
|
||||||
|
DPRINTF(("tlp: rxd[0] = %p, rxd[1] = %p\n",
|
||||||
|
&l->rxd[0], &l->rxd[1]));
|
||||||
DPRINTF(("tlp: txstore = %p, rxstore[0] = %p, rxstore[1] = %p\n",
|
DPRINTF(("tlp: txstore = %p, rxstore[0] = %p, rxstore[1] = %p\n",
|
||||||
l->txstore, l->rxstore[0], l->rxstore[1]));
|
l->txstore, l->rxstore[0], l->rxstore[1]));
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
/* XXX assume tlp0 at pci0 dev 7 function 0 */
|
/* XXX assume tlp0 at pci0 dev 7 function 0 */
|
||||||
tag = (0 << 16) | ( 7 << 11) | (0 << 8);
|
tag = (0 << 16) | ( 7 << 11) | (0 << 8);
|
||||||
/* memory map is not initialized by the firmware on cobalt */
|
/* memory map is not initialized by the firmware on cobalt */
|
||||||
l->csr = MIPS_PHYS_TO_KSEG1(pcicfgread(tag, 0x10) & 0xfffffffc);
|
l->csr = MIPS_PHYS_TO_KSEG1(pcicfgread(tag, 0x10) & ~3U);
|
||||||
DPRINTF(("%s: CSR = 0x%x\n", __func__, l->csr));
|
DPRINTF(("%s: CSR = 0x%x\n", __func__, l->csr));
|
||||||
#else
|
#else
|
||||||
l->csr = MIPS_PHYS_TO_KSEG1(COBALT_TLP0_BASE);
|
l->csr = MIPS_PHYS_TO_KSEG1(COBALT_TLP0_BASE);
|
||||||
@ -181,10 +206,25 @@ tlp_init(void *cookie)
|
|||||||
DELAY(1000);
|
DELAY(1000);
|
||||||
(void)CSR_READ(l, TLP_BMR);
|
(void)CSR_READ(l, TLP_BMR);
|
||||||
|
|
||||||
|
if (is21041) {
|
||||||
|
/* reset SIA for 10BASE-T */
|
||||||
|
CSR_WRITE(l, TLP_CSR13, 0);
|
||||||
|
DELAY(1000);
|
||||||
|
CSR_WRITE(l, TLP_CSR15, SIAGEN_10BT);
|
||||||
|
CSR_WRITE(l, TLP_CSR14, SIATXRX_10BT);
|
||||||
|
CSR_WRITE(l, TLP_CSR13, SIACONN_10BT);
|
||||||
|
} else {
|
||||||
|
/* reset PHY (cobalt quirk from if_tlp_pci.c) */
|
||||||
|
CSR_WRITE(l, TLP_CSR15, SIAGEN_CWE | SIAGEN_MD0);
|
||||||
|
DELAY(10);
|
||||||
|
CSR_WRITE(l, TLP_CSR15, SIAGEN_CWE);
|
||||||
|
DELAY(10);
|
||||||
|
}
|
||||||
|
|
||||||
l->omr = OMR_PS | OMR_SDP;
|
l->omr = OMR_PS | OMR_SDP;
|
||||||
CSR_WRITE(l, TLP_OMR, l->omr);
|
CSR_WRITE(l, TLP_OMR, l->omr);
|
||||||
CSR_WRITE(l, TLP_STS, ~0);
|
|
||||||
CSR_WRITE(l, TLP_IEN, 0);
|
CSR_WRITE(l, TLP_IEN, 0);
|
||||||
|
CSR_WRITE(l, TLP_STS, ~0);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
mii_initphy(l);
|
mii_initphy(l);
|
||||||
@ -213,37 +253,51 @@ tlp_init(void *cookie)
|
|||||||
rxd[i].xd1 = htole32(R1_RCH|FRAMESIZE);
|
rxd[i].xd1 = htole32(R1_RCH|FRAMESIZE);
|
||||||
rxd[i].xd0 = htole32(R0_OWN);
|
rxd[i].xd0 = htole32(R0_OWN);
|
||||||
}
|
}
|
||||||
CSR_WRITE(l, TLP_RRBA, VTOPHYS(rxd));
|
|
||||||
|
|
||||||
/* "setup packet" to have own station address */
|
txd = &l->txd[0];
|
||||||
txd = &l->txd;
|
for (i = 0; i < NTXBUF; i++) {
|
||||||
txd->xd3 = htole32(VTOPHYS(txd));
|
txd[i].xd3 = htole32(VTOPHYS(&txd[NEXT_TXBUF(i)]));
|
||||||
|
txd[i].xd0 = htole32(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* prepare setup packet */
|
||||||
|
p = l->txstore;
|
||||||
|
memset(p, 0, TLP_SETUPLEN);
|
||||||
|
/* put broadcast first */
|
||||||
|
p[0] = p[1] = p[4] = p[5] = p[8] = p[9] = 0xff;
|
||||||
|
for (i = 1; i < TLP_SETUP_NADDR; i++) {
|
||||||
|
/* put own station address to the rest */
|
||||||
|
p[i * 12 + 0] = en[0];
|
||||||
|
p[i * 12 + 1] = en[1];
|
||||||
|
p[i * 12 + 4] = en[2];
|
||||||
|
p[i * 12 + 5] = en[3];
|
||||||
|
p[i * 12 + 8] = en[4];
|
||||||
|
p[i * 12 + 9] = en[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
txd = &l->txd[0];
|
||||||
txd->xd2 = htole32(VTOPHYS(l->txstore));
|
txd->xd2 = htole32(VTOPHYS(l->txstore));
|
||||||
txd->xd1 = htole32(T1_SET | T1_TER);
|
txd->xd1 = htole32(T1_SET | T1_TCH | TLP_SETUPLEN);
|
||||||
txd->xd0 = htole32(0);
|
txd->xd0 = htole32(T0_OWN);
|
||||||
CSR_WRITE(l, TLP_TRBA, VTOPHYS(txd));
|
|
||||||
|
|
||||||
memset(l->txstore, 0, FRAMESIZE);
|
|
||||||
|
|
||||||
/* make sure the entire descriptors transfered to memory */
|
/* make sure the entire descriptors transfered to memory */
|
||||||
wbinv(l, sizeof(struct local));
|
wbinv(l, sizeof(struct local));
|
||||||
|
|
||||||
l->rx = 0;
|
CSR_WRITE(l, TLP_RRBA, VTOPHYS(rxd));
|
||||||
l->omr |= OMR_FD | OMR_TEN | OMR_REN;
|
CSR_WRITE(l, TLP_TRBA, VTOPHYS(txd));
|
||||||
|
|
||||||
#if 1
|
l->tx = NEXT_TXBUF(0);
|
||||||
/* reset PHY (cobalt quirk from if_tlp_pci.c) */
|
l->rx = 0;
|
||||||
CSR_WRITE(l, TLP_CSR15, SIAGEN_CWE | SIAGEN_MD0);
|
l->omr |= OMR_TEN | OMR_REN;
|
||||||
DELAY(10);
|
if (!is21041)
|
||||||
CSR_WRITE(l, TLP_CSR15, SIAGEN_CWE);
|
l->omr |= OMR_FD;
|
||||||
DELAY(10);
|
|
||||||
#endif
|
/* enable Tx/Rx */
|
||||||
|
|
||||||
/* start Tx/Rx */
|
|
||||||
CSR_WRITE(l, TLP_OMR, l->omr);
|
CSR_WRITE(l, TLP_OMR, l->omr);
|
||||||
#if 0
|
/* start TX and send setup packet */
|
||||||
CSR_WRITE(l, TLP_TPD, TPD_POLL);
|
CSR_WRITE(l, TLP_TPD, TPD_POLL);
|
||||||
#endif
|
DELAY(1000);
|
||||||
|
/* start RX */
|
||||||
CSR_WRITE(l, TLP_RPD, RPD_POLL);
|
CSR_WRITE(l, TLP_RPD, RPD_POLL);
|
||||||
|
|
||||||
return l;
|
return l;
|
||||||
@ -256,23 +310,14 @@ tlp_send(void *dev, char *buf, u_int len)
|
|||||||
struct desc *txd;
|
struct desc *txd;
|
||||||
u_int loop;
|
u_int loop;
|
||||||
|
|
||||||
#if 1
|
|
||||||
wb(buf, len);
|
wb(buf, len);
|
||||||
txd = &l->txd;
|
txd = &l->txd[l->tx];
|
||||||
txd->xd3 = htole32(VTOPHYS(txd));
|
|
||||||
txd->xd2 = htole32(VTOPHYS(buf));
|
txd->xd2 = htole32(VTOPHYS(buf));
|
||||||
txd->xd1 = htole32(T1_FS | T1_LS | T1_TER | (len & T1_TBS_MASK));
|
txd->xd1 = htole32(T1_FS | T1_LS | T1_TCH | (len & T1_TBS_MASK));
|
||||||
#else
|
|
||||||
memcpy(l->txstore, buf, len);
|
|
||||||
wb(l->txstore, len);
|
|
||||||
txd = &l->txd;
|
|
||||||
txd->xd3 = htole32(VTOPHYS(txd));
|
|
||||||
txd->xd2 = htole32(VTOPHYS(l->txstore));
|
|
||||||
txd->xd1 = htole32(T1_FS | T1_LS | T1_TER | (len & T1_TBS_MASK));
|
|
||||||
#endif
|
|
||||||
txd->xd0 = htole32(T0_OWN);
|
txd->xd0 = htole32(T0_OWN);
|
||||||
wbinv(txd, sizeof(struct desc));
|
wbinv(txd, sizeof(struct desc));
|
||||||
CSR_WRITE(l, TLP_TPD, TPD_POLL);
|
CSR_WRITE(l, TLP_TPD, TPD_POLL);
|
||||||
|
l->tx = NEXT_TXBUF(l->tx);
|
||||||
loop = 100;
|
loop = 100;
|
||||||
do {
|
do {
|
||||||
if ((le32toh(txd->xd0) & T0_OWN) == 0)
|
if ((le32toh(txd->xd0) & T0_OWN) == 0)
|
||||||
@ -295,7 +340,7 @@ tlp_recv(void *dev, char *buf, u_int maxlen, u_int timo)
|
|||||||
uint32_t rxstat;
|
uint32_t rxstat;
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
|
|
||||||
bound = 1000 * timo;
|
bound = timo * 1000000;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
rxd = &l->rxd[l->rx];
|
rxd = &l->rxd[l->rx];
|
||||||
@ -304,7 +349,7 @@ tlp_recv(void *dev, char *buf, u_int maxlen, u_int timo)
|
|||||||
inv(rxd, sizeof(struct desc));
|
inv(rxd, sizeof(struct desc));
|
||||||
if ((rxstat & R0_OWN) == 0)
|
if ((rxstat & R0_OWN) == 0)
|
||||||
goto gotone;
|
goto gotone;
|
||||||
DELAY(1000); /* 1 milli second */
|
DELAY(1);
|
||||||
} while (--bound > 0);
|
} while (--bound > 0);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
CSR_WRITE(l, TLP_RPD, RPD_POLL);
|
CSR_WRITE(l, TLP_RPD, RPD_POLL);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
$NetBSD: version,v 1.7 2008/03/01 17:45:11 tsutsui Exp $
|
$NetBSD: version,v 1.8 2008/03/01 20:39:25 tsutsui Exp $
|
||||||
|
|
||||||
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
|
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
|
||||||
file is important - make sure the entries are appended on end, last item
|
file is important - make sure the entries are appended on end, last item
|
||||||
@ -11,3 +11,4 @@ is taken as the current.
|
|||||||
set default boot device accordingly
|
set default boot device accordingly
|
||||||
0.5: Add support for netboot via tlp0
|
0.5: Add support for netboot via tlp0
|
||||||
0.6: Print a cobalt model name in banner
|
0.6: Print a cobalt model name in banner
|
||||||
|
0.7: Add support for netboot via 21041 on Qube2700
|
||||||
|
Loading…
Reference in New Issue
Block a user