Port-sandpoint archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Synology PPCBoot SK98 network bug fix
Hi,
> Yes, that could be the problem, indeed.
>
> Even if you didn't tell your routers/switches via IGMP that you want
> to receive multicast packets, you are receiving them anyway, because the
> NIC is in promiscious mode? :|
It appears that it almost is ;-) I tried zeroing the multicast hash list,
and that didn't make any difference that I could see. However, I've left
it in, as it didn't seem to cause any harm.
> You really must have a lot of traffic on your net.
>
> I admit that my home network is quite calm. Three or four clients
> maximum. And usually no traffic at all.
There are currently 5 machines running, and 2 switches, and the Internet
connection is via a router. This means that on any network segment there
are at least 2 multicasts or broadcasts per second (IGMP and spanning tree)
plus any other *cast traffic. The NAS is the only device on a switch port,
so there isn't any other unicast traffic. I think that we should be able to
cope with that ;-)
> The problem you describe would affect all network drivers in altboot,
> not just skg.c. No driver uses more than two descriptors.
>
> Probably it is better to define in the documentation that you need to
> provide a network with low traffic for installation.
Hmm, I think that I'd prefer to increase the number of receive descriptors.
I increased it to 16 in skg.c and had no problems loading the kernel via
NFS. Using 8 seems to be OK now too - I did have failures before, but that
was with the extra debug printout enabled.
I've attached a patch. I don't think that it will break anything. It:
o makes the number of transmit and receive descriptors into #define's,
o moves the start address of the transmit ram buffers because there are
more receive ram buffers
o iterates over the number of descriptors when setting them up
o checks all receive descriptors for the first one with CTL_OWN
o zero's the multicast filters
The code in skg_send() still assumes 2 transmit descriptors. It might be
better to fix that too?
Thanks,
J
--
My other computer also runs NetBSD / Sailing at Newbiggin
http://www.netbsd.org/ / http://www.newbigginsailingclub.org/
Index: skg.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sandpoint/stand/altboot/skg.c,v
retrieving revision 1.3
diff -u -r1.3 skg.c
--- skg.c 29 May 2011 18:06:45 -0000 1.3
+++ skg.c 30 May 2011 20:23:56 -0000
@@ -153,6 +153,10 @@
#define GPCR_RXEN 0x0800
#define YUKON_SA1 0x281c
#define YUKON_SA2 0x2828
+#define YUKON_MC1 0x2834
+#define YUKON_MC2 0x2838
+#define YUKON_MC3 0x283c
+#define YUKON_MC4 0x2840
#define YUKON_SMICR 0x2880
#define SMICR_PHYAD(x) (((x) & 0x1f) << 11)
#define SMICR_REGAD(x) (((x) & 0x1f) << 6)
@@ -173,11 +177,13 @@
#define FRAMESIZE 1536
+#define NUM_TXDESC 2
+#define NUM_RXDESC 8
struct local {
- struct desc txd[2];
- struct desc rxd[2];
- uint8_t rxstore[2][FRAMESIZE];
- unsigned csr, rx, tx, phy;
+ struct desc txd[NUM_TXDESC];
+ struct desc rxd[NUM_RXDESC];
+ uint8_t rxstore[NUM_RXDESC][FRAMESIZE];
+ unsigned csr, /*rx, */tx, phy;
uint16_t pssr, anlpar;
};
@@ -246,6 +252,12 @@
CSR_WRITE_2(l, YUKON_SA1 + i * 4,
(en[i * 2] << 8) | en[i * 2 + 1]);
+ /* zero multicast filters */
+ CSR_WRITE_2(l, YUKON_MC1, 0);
+ CSR_WRITE_2(l, YUKON_MC2, 0);
+ CSR_WRITE_2(l, YUKON_MC3, 0);
+ CSR_WRITE_2(l, YUKON_MC4, 0);
+
/* configure RX and TX MAC FIFO */
CSR_WRITE_1(l, SK_RXMF1_CTRL_TEST, RFCTL_RESET_CLEAR);
CSR_WRITE_4(l, SK_RXMF1_CTRL_TEST, RFCTL_OPERATION_ON);
@@ -274,29 +286,31 @@
CSR_WRITE_4(l, SK_RXRB1_START, 0);
CSR_WRITE_4(l, SK_RXRB1_WR_PTR, 0);
CSR_WRITE_4(l, SK_RXRB1_RD_PTR, 0);
- CSR_WRITE_4(l, SK_RXRB1_END, 0xfff);
+ CSR_WRITE_4(l, SK_RXRB1_END, 0x3fff);
CSR_WRITE_4(l, SK_RXRB1_CTLTST, RBCTL_ON);
CSR_WRITE_4(l, SK_TXRBS1_CTLTST, RBCTL_UNRESET);
CSR_WRITE_4(l, SK_TXRBS1_CTLTST, RBCTL_STORENFWD_ON);
- CSR_WRITE_4(l, SK_TXRBS1_START, 0x1000);
- CSR_WRITE_4(l, SK_TXRBS1_WR_PTR, 0x1000);
- CSR_WRITE_4(l, SK_TXRBS1_RD_PTR, 0x1000);
- CSR_WRITE_4(l, SK_TXRBS1_END, 0x1fff);
+ CSR_WRITE_4(l, SK_TXRBS1_START, 0x4000);
+ CSR_WRITE_4(l, SK_TXRBS1_WR_PTR, 0x4000);
+ CSR_WRITE_4(l, SK_TXRBS1_RD_PTR, 0x4000);
+ CSR_WRITE_4(l, SK_TXRBS1_END, 0x4fff);
CSR_WRITE_4(l, SK_TXRBS1_CTLTST, RBCTL_ON);
/* setup descriptors and BMU */
CSR_WRITE_1(l, SK_TXAR1_COUNTERCTL, TXARCTL_ON|TXARCTL_FSYNC_ON);
txd = &l->txd[0];
- txd[0].xd1 = htole32(VTOPHYS(&txd[1]));
- txd[1].xd1 = htole32(VTOPHYS(&txd[0]));
+ for (i = 0; i < NUM_TXDESC; i ++)
+ txd[i].xd1 = htole32(VTOPHYS(&txd[(i + 1) & ~NUM_TXDESC]));
rxd = &l->rxd[0];
- rxd[0].xd0 = htole32(FRAMESIZE|CTL_DEFOPC|CTL_LS|CTL_FS|CTL_OWN);
- rxd[0].xd1 = htole32(VTOPHYS(&rxd[1]));
- rxd[0].xd2 = htole32(VTOPHYS(l->rxstore[0]));
- rxd[1].xd0 = htole32(FRAMESIZE|CTL_DEFOPC|CTL_LS|CTL_FS|CTL_OWN);
- rxd[1].xd1 = htole32(VTOPHYS(&rxd[0]));
- rxd[1].xd2 = htole32(VTOPHYS(l->rxstore[1]));
+
+ for (i = 0; i < NUM_RXDESC; i ++) {
+ rxd[i].xd0 =
+ htole32(FRAMESIZE|CTL_DEFOPC|CTL_LS|CTL_FS|CTL_OWN);
+ rxd[i].xd1 = htole32(VTOPHYS(&rxd[(i + 1) & ~NUM_RXDESC]));
+ rxd[i].xd2 =
+ htole32(VTOPHYS(l->rxstore[i]));
+ }
wbinv(l, sizeof(struct local));
CSR_WRITE_4(l, SK_RXQ1_BMU_CSR,
@@ -331,6 +345,13 @@
volatile struct desc *txd;
unsigned loop;
+ DPRINTF(("sending\n"));
+ DPRINTF((">> "));
+ for (loop = 0; loop < 14; loop++) {
+ DPRINTF(("%02x ", buf[loop]));
+ }
+ DPRINTF(("\n"));
+
wbinv(buf, len);
txd = &l->txd[l->tx];
txd->xd2 = htole32(VTOPHYS(buf));
@@ -356,41 +377,46 @@
{
struct local *l = dev;
volatile struct desc *rxd;
- unsigned bound, ctl, rxstat, len;
+ unsigned loop, bound, ctl, rxstat, len;
uint8_t *ptr;
bound = 1000 * timo;
-#if 0
-printf("recving with %u sec. timeout\n", timo);
-#endif
+ DPRINTF(("recving with %u sec. timeout\n", timo));
again:
- rxd = &l->rxd[l->rx];
do {
- inv(rxd, sizeof(struct desc));
- ctl = le32toh(rxd->xd0);
- if ((ctl & CTL_OWN) == 0)
- goto gotone;
+ for (loop = 0; loop < NUM_RXDESC; loop++) {
+ rxd = &l->rxd[loop];
+ inv(rxd, sizeof(struct desc));
+ ctl = le32toh(rxd->xd0);
+ if ((ctl & CTL_OWN) == 0)
+ goto gotone;
+ }
DELAY(1000); /* 1 milli second */
} while (--bound > 0);
errno = 0;
return -1;
gotone:
rxstat = le32toh(rxd->xd4);
+ DPRINTF(("Got one rxd[%d] : rxstat = %08x\n", loop, rxstat));
if ((rxstat & RXSTAT_RXOK) == 0) {
rxd->xd0 = htole32(FRAMESIZE|CTL_DEFOPC|CTL_LS|CTL_FS|CTL_OWN);
wbinv(rxd, sizeof(struct desc));
- l->rx ^= 1;
goto again;
}
+ DPRINTF(("Parsing : ctl = %08x\n", ctl));
len = ctl & FRAMEMASK;
if (len > maxlen)
len = maxlen;
- ptr = l->rxstore[l->rx];
+ ptr = l->rxstore[loop];
inv(ptr, len);
memcpy(buf, ptr, len);
+ DPRINTF((">> "));
+ for (loop = 0; loop < 14; loop++) {
+ DPRINTF(("%02x ", buf[loop]));
+ }
+ DPRINTF(("\n"));
rxd->xd0 = htole32(FRAMESIZE|CTL_DEFOPC|CTL_LS|CTL_FS|CTL_OWN);
wbinv(rxd, sizeof(struct desc));
- l->rx ^= 1;
return len;
}
Home |
Main Index |
Thread Index |
Old Index