52#define DEV9_SMAP_ALL_INTR_MASK (SMAP_INTR_EMAC3 | SMAP_INTR_RXEND | SMAP_INTR_TXEND | SMAP_INTR_RXDNV | SMAP_INTR_TXDNV)
53#define DEV9_SMAP_INTR_MASK (SMAP_INTR_EMAC3 | SMAP_INTR_RXEND | SMAP_INTR_RXDNV | SMAP_INTR_TXDNV)
55#define DEV9_SMAP_INTR_MASK2 (SMAP_INTR_EMAC3 | SMAP_INTR_RXEND | SMAP_INTR_RXDNV)
59static const char VersionString[] =
"Version 2.26.0";
60static unsigned int ThreadPriority = 0x28;
61static unsigned int ThreadStackSize = 0x1000;
62static unsigned int EnableVerboseOutput = 0;
63static unsigned int EnableAutoNegotiation = 1;
64static unsigned int EnablePinStrapConfig = 0;
65static unsigned int SmapConfiguration = 0x5E0;
67int DisplayBanner(
void)
69 printf(
"SMAP (%s)\n", VersionString);
70 return MODULE_NO_RESIDENT_END;
73static void _smap_write_phy(
volatile u8 *emac3_regbase,
unsigned int address, u16 value)
78 PHYRegisterValue = (address & SMAP_E3_PHY_REG_ADDR_MSK) | SMAP_E3_PHY_WRITE | ((SMAP_DsPHYTER_ADDRESS & SMAP_E3_PHY_ADDR_MSK) << SMAP_E3_PHY_ADDR_BITSFT);
79 PHYRegisterValue |= ((u32)value) << SMAP_E3_PHY_DATA_BITSFT;
82 SMAP_EMAC3_SET32(SMAP_R_EMAC3_STA_CTRL, PHYRegisterValue);
91 printf(
"smap: %s: > %u ms\n",
"_smap_write_phy", i);
94static u16 _smap_read_phy(
volatile u8 *emac3_regbase,
unsigned int address)
97 u32 value, PHYRegisterValue;
100 PHYRegisterValue = (address & SMAP_E3_PHY_REG_ADDR_MSK) | SMAP_E3_PHY_READ | ((SMAP_DsPHYTER_ADDRESS & SMAP_E3_PHY_ADDR_MSK) << SMAP_E3_PHY_ADDR_BITSFT);
104 SMAP_EMAC3_SET32(SMAP_R_EMAC3_STA_CTRL, PHYRegisterValue);
110 result = (u16)(value >> SMAP_E3_PHY_DATA_BITSFT);
121 printf(
"SMAP: %s: > %u ms\n",
"_smap_read_phy", i);
126static int DisplayHelpMessage(
void)
130 printf(
"Usage: smap [<option>] [thpri=<prio>] [thstack=<stack>] [<conf>]\n"
132 " -verbose display verbose messages\n"
133 " -auto auto nego enable [default]\n"
134 " -no_auto fixed mode\n"
135 " -strap use pin-strap config\n"
136 " -no_strap do not use pin-strap config [default]\n");
141static inline void RestartAutoNegotiation(
volatile u8 *emac3_regbase, u16 bmsr)
143 if (EnableVerboseOutput)
144 DEBUG_PRINTF(
"restarting auto nego (BMCR=0x%x, BMSR=0x%x)\n", _smap_read_phy(emac3_regbase, SMAP_DsPHYTER_BMCR), bmsr);
145 _smap_write_phy(emac3_regbase, SMAP_DsPHYTER_BMCR, SMAP_PHY_BMCR_ANEN | SMAP_PHY_BMCR_RSAN);
151 unsigned int LinkSpeed100M, LinkFDX, FlowControlEnabled, AutoNegoRetries;
153 u16 RegDump[6], value, value2;
154 volatile u8 *emac3_regbase;
157 if (EnableVerboseOutput != 0)
158 DEBUG_PRINTF(
"Resetting PHY\n");
160 _smap_write_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMCR, SMAP_PHY_BMCR_RST);
161 for (i = 0; _smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMCR) & SMAP_PHY_BMCR_RST; i++) {
163 DEBUG_PRINTF(
"PHY reset error\n");
166 if (SmapDrivPrivData->NetDevStopFlag)
172 if (!EnableAutoNegotiation) {
173 if (EnableVerboseOutput != 0)
174 DEBUG_PRINTF(
"no auto mode (conf=0x%x)\n", SmapConfiguration);
176 LinkSpeed100M = 0 < (SmapConfiguration & 0x180);
177 value = LinkSpeed100M << 13;
178 if (SmapConfiguration & 0x140)
179 value |= SMAP_PHY_BMCR_DUPM;
180 _smap_write_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMCR, value);
183 DEBUG_PRINTF(
"Waiting Valid Link for %dMbps\n", LinkSpeed100M ? 100 : 10);
188 if (SmapDrivPrivData->NetDevStopFlag)
191 if (_smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMSR) &
SMAP_PHY_BMSR_LINK)
194 SmapDrivPrivData->LinkStatus = 0;
197 SmapDrivPrivData->LinkStatus = 1;
199 if (!EnablePinStrapConfig) {
200 _smap_write_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMCR, 0);
201 value = _smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMSR);
202 if (!(value & 0x4000))
203 SmapConfiguration = SmapConfiguration & 0xFFFFFEFF;
204 if (!(value & 0x2000))
205 SmapConfiguration = SmapConfiguration & 0xFFFFFF7F;
206 if (!(value & 0x1000))
207 SmapConfiguration = SmapConfiguration & 0xFFFFFFBF;
208 if (!(value & 0x0800))
209 SmapConfiguration = SmapConfiguration & 0xFFFFFFDF;
211 DEBUG_PRINTF(
"no strap mode (conf=0x%x, bmsr=0x%x)\n", SmapConfiguration, value);
213 value = _smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_ANAR);
214 value = (SmapConfiguration & 0x5E0) | (value & 0x1F);
215 DEBUG_PRINTF(
"anar=0x%x\n", value);
216 _smap_write_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_ANAR, value);
217 _smap_write_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMCR, SMAP_PHY_BMCR_ANEN | SMAP_PHY_BMCR_RSAN);
219 if (!(_smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMCR) & SMAP_PHY_BMCR_ANEN)) {
224 DEBUG_PRINTF(
"auto mode (BMCR=0x%x ANAR=0x%x)\n", _smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMCR), _smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_ANAR));
226 RepeatAutoNegoProcess:
227 for (AutoNegoRetries = 0; AutoNegoRetries < 3; AutoNegoRetries++) {
228 for (i = 0; i < 3; i++) {
229 DelayThread(1000000);
230 if (SmapDrivPrivData->NetDevStopFlag)
234 value = _smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMSR);
237 for (i = 0; !(_smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMSR) &
SMAP_PHY_BMSR_LINK); i++) {
239 if (SmapDrivPrivData->NetDevStopFlag)
247 SmapDrivPrivData->LinkStatus = 1;
250 RestartAutoNegotiation(SmapDrivPrivData->emac3_regbase, value);
252 RestartAutoNegotiation(SmapDrivPrivData->emac3_regbase, value);
256 if (AutoNegoRetries >= 3) {
257 if (EnableVerboseOutput)
258 DEBUG_PRINTF(
"waiting valid link for 100Mbps Half-Duplex\n");
260 _smap_write_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMCR, SMAP_PHY_BMCR_100M);
261 DelayThread(1000000);
262 if (SmapDrivPrivData->NetDevStopFlag)
265 for (i = 0; !(_smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMSR) &
SMAP_PHY_BMSR_LINK); i++) {
267 if (SmapDrivPrivData->NetDevStopFlag)
274 if (EnableVerboseOutput)
275 DEBUG_PRINTF(
"waiting valid link for 10Mbps Half-Duplex\n");
277 _smap_write_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMCR, SMAP_PHY_BMCR_10M);
278 DelayThread(1000000);
279 if (SmapDrivPrivData->NetDevStopFlag)
282 for (i = 0; !(_smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMSR) &
SMAP_PHY_BMSR_LINK); i++) {
284 if (SmapDrivPrivData->NetDevStopFlag)
291 goto RepeatAutoNegoProcess;
293 SmapDrivPrivData->LinkStatus = 1;
295 SmapDrivPrivData->LinkStatus = 1;
299 for (i = 0; i < 6; i++)
300 RegDump[i] = _smap_read_phy(SmapDrivPrivData->emac3_regbase, i);
302 if (EnableVerboseOutput)
303 DEBUG_PRINTF(
"PHY: %04x %04x %04x %04x %04x %04x\n", RegDump[SMAP_DsPHYTER_BMCR], RegDump[SMAP_DsPHYTER_BMSR], RegDump[SMAP_DsPHYTER_PHYIDR1], RegDump[SMAP_DsPHYTER_PHYIDR2], RegDump[SMAP_DsPHYTER_ANAR], RegDump[SMAP_DsPHYTER_ANLPAR]);
306 if (RegDump[SMAP_DsPHYTER_PHYIDR1] == SMAP_PHY_IDR1_VAL && (RegDump[SMAP_DsPHYTER_PHYIDR2] & SMAP_PHY_IDR2_MSK) == SMAP_PHY_IDR2_VAL) {
307 if (EnableAutoNegotiation) {
308 _smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_FCSCR);
309 _smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_RECR);
311 value = _smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_FCSCR);
312 value2 = _smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_RECR);
313 if ((value2 != 0) || (value >= 0x11)) {
314 if (EnableVerboseOutput)
315 DEBUG_PRINTF(
"FCSCR=%d RECR=%d\n", value, value2);
316 _smap_write_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMCR, 0);
321 DEBUG_PRINTF(
"PHY chip: DP83846A%d\n", (RegDump[SMAP_DsPHYTER_PHYIDR2] & SMAP_PHY_IDR2_REV_MSK) + 1);
324 if (!EnableAutoNegotiation) {
325 if ((RegDump[SMAP_DsPHYTER_BMCR] & (SMAP_PHY_BMCR_DUPM | SMAP_PHY_BMCR_100M)) == 0)
332 if ((RegDump[SMAP_DsPHYTER_PHYIDR2] & SMAP_PHY_IDR2_REV_MSK) == 0) {
333 _smap_write_phy(SmapDrivPrivData->emac3_regbase, 0x13, 1);
334 _smap_write_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_PHYCTRL, 0x1898);
335 _smap_write_phy(SmapDrivPrivData->emac3_regbase, 0x1F, 0);
336 _smap_write_phy(SmapDrivPrivData->emac3_regbase, 0x1D, 0x5040);
337 _smap_write_phy(SmapDrivPrivData->emac3_regbase, 0x1E, 0x8C);
338 _smap_write_phy(SmapDrivPrivData->emac3_regbase, 0x13, 0);
343 FlowControlEnabled = 0;
344 if (RegDump[SMAP_DsPHYTER_BMCR] & SMAP_PHY_BMCR_ANEN) {
345 value = RegDump[SMAP_DsPHYTER_ANAR] & RegDump[SMAP_DsPHYTER_ANLPAR];
346 LinkSpeed100M = 0 < (value & 0x180);
347 LinkFDX = 0 < (value & 0x140);
349 FlowControlEnabled = 0 < (value & 0x400);
351 LinkSpeed100M = RegDump[SMAP_DsPHYTER_BMCR] >> 13 & 1;
352 LinkFDX = RegDump[SMAP_DsPHYTER_BMCR] >> 8 & 1;
353 FlowControlEnabled = SmapConfiguration >> 10 & 1;
357 result = LinkFDX ? 8 : 4;
359 result = LinkFDX ? 2 : 1;
361 SmapDrivPrivData->LinkMode = result;
362 if (FlowControlEnabled)
363 SmapDrivPrivData->LinkMode |= 0x40;
365 DEBUG_PRINTF(
"%s %s Duplex Mode %s Flow Control\n", LinkSpeed100M ?
"100BaseTX" :
"10BaseT", LinkFDX ?
"Full" :
"Half", FlowControlEnabled ?
"with" :
"without");
367 emac3_regbase = SmapDrivPrivData->emac3_regbase;
368 emac3_value = SMAP_EMAC3_GET32(SMAP_R_EMAC3_MODE1) & 0x67FFFFFF;
370 emac3_value |= SMAP_E3_FDX_ENABLE;
371 if (FlowControlEnabled)
373 SMAP_EMAC3_SET32(SMAP_R_EMAC3_MODE1, emac3_value);
379static unsigned int LinkCheckTimerCB(
struct SmapDriverData *SmapDrivPrivData)
381 iSetEventFlag(SmapDrivPrivData->Dev9IntrEventFlag, SMAP_EVENT_LINK_CHECK);
382 return SmapDrivPrivData->LinkCheckTimer.lo;
392 while (SmapDrivPrivData->NumPacketsInTx > 0) {
393 ctrl_stat = tx_bd[SmapDrivPrivData->TxDNVBDIndex % SMAP_BD_MAX_ENTRY].ctrl_stat;
396 for (i = 0; i < 16; i++)
397 if ((ctrl_stat >> i) & 1)
398 SmapDrivPrivData->RuntimeStats.TxErrorCount++;
400 SmapDrivPrivData->RuntimeStats.TxDroppedFrameCount++;
402 SmapDrivPrivData->RuntimeStats.TxFrameLOSSCRCount++;
404 SmapDrivPrivData->RuntimeStats.TxFrameEDEFERCount++;
406 SmapDrivPrivData->RuntimeStats.TxFrameCollisionCount++;
408 SmapDrivPrivData->RuntimeStats.TxFrameUnderrunCount++;
414 SmapDrivPrivData->TxBufferSpaceAvailable += (tx_bd[SmapDrivPrivData->TxDNVBDIndex & (SMAP_BD_MAX_ENTRY - 1)].length + 3) & ~3;
415 SmapDrivPrivData->TxDNVBDIndex++;
416 SmapDrivPrivData->NumPacketsInTx--;
423static void CheckLinkStatus(
struct SmapDriverData *SmapDrivPrivData)
425 if (!(_smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMSR) &
SMAP_PHY_BMSR_LINK)) {
427 SmapDrivPrivData->LinkStatus = 0;
428 SMapCommonLinkStateDown(SmapDrivPrivData);
429 InitPHY(SmapDrivPrivData);
432 if (SmapDrivPrivData->LinkStatus)
433 SMapCommonLinkStateUp(SmapDrivPrivData);
437#ifdef SMAP_RX_PACKETS_POLLING_MODE
438static unsigned int RxIntrPollingTimerCB(
struct SmapDriverData *SmapDrivPrivData)
440 iSetEventFlag(SmapDrivPrivData->Dev9IntrEventFlag, SMAP_EVENT_INTR);
445static void IntrHandlerThread(
struct SmapDriverData *SmapDrivPrivData)
447 unsigned int PacketCount, IntrReg;
450 volatile u8 *smap_regbase, *emac3_regbase;
454 emac3_regbase = SmapDrivPrivData->emac3_regbase;
455 smap_regbase = SmapDrivPrivData->smap_regbase;
459 if ((result = WaitEventFlag(SmapDrivPrivData->Dev9IntrEventFlag, SMAP_EVENT_START | SMAP_EVENT_STOP | SMAP_EVENT_INTR | SMAP_EVENT_XMIT | SMAP_EVENT_LINK_CHECK, WEF_OR | WEF_CLEAR, &EFBits)) != 0) {
460 DEBUG_PRINTF(
"WaitEventFlag -> %d\n", result);
464 if (EFBits & SMAP_EVENT_STOP) {
465 if (SmapDrivPrivData->SmapIsInitialized) {
466 SpdIntrDisable(DEV9_SMAP_INTR_MASK2);
467 SMAP_EMAC3_SET32(SMAP_R_EMAC3_MODE0, 0);
468 SmapDrivPrivData->NetDevStopFlag = 0;
469 SmapDrivPrivData->LinkStatus = 0;
470 SmapDrivPrivData->SmapIsInitialized = 0;
471 SmapDrivPrivData->SmapDriverStarted = 0;
472 SMapCommonLinkStateDown(SmapDrivPrivData);
475 if (EFBits & SMAP_EVENT_START) {
476 if (!SmapDrivPrivData->SmapIsInitialized) {
477 SmapDrivPrivData->SmapDriverStarted = 1;
478 SpdIntrEnable(DEV9_SMAP_INTR_MASK2);
479 if ((result = InitPHY(SmapDrivPrivData)) != 0)
481 if (SmapDrivPrivData->NetDevStopFlag) {
482 SmapDrivPrivData->NetDevStopFlag = 0;
486 SMAP_EMAC3_SET32(SMAP_R_EMAC3_MODE0, SMAP_E3_TXMAC_ENABLE | SMAP_E3_RXMAC_ENABLE);
488 SmapDrivPrivData->SmapIsInitialized = 1;
490 SMapCommonLinkStateUp(SmapDrivPrivData);
492 if (!SmapDrivPrivData->EnableLinkCheckTimer) {
493 USec2SysClock(1000000, &SmapDrivPrivData->LinkCheckTimer);
494 SetAlarm(&SmapDrivPrivData->LinkCheckTimer, (
void *)&LinkCheckTimerCB, SmapDrivPrivData);
495 SmapDrivPrivData->EnableLinkCheckTimer = 1;
500 if (SmapDrivPrivData->SmapIsInitialized) {
502 if (EFBits & SMAP_EVENT_INTR) {
503 if ((IntrReg = SPD_REG16(SPD_R_INTR_STAT) & DEV9_SMAP_INTR_MASK) != 0) {
509 if (IntrReg & SMAP_INTR_EMAC3) {
510 SMAP_REG16(SMAP_R_INTR_CLR) = SMAP_INTR_EMAC3;
511 SMAP_EMAC3_SET32(SMAP_R_EMAC3_INTR_STAT, SMAP_E3_INTR_TX_ERR_0 | SMAP_E3_INTR_SQE_ERR_0 | SMAP_E3_INTR_DEAD_0);
513 if (IntrReg & SMAP_INTR_RXEND) {
514 SMAP_REG16(SMAP_R_INTR_CLR) = SMAP_INTR_RXEND;
515 PacketCount = HandleRxIntr(SmapDrivPrivData);
517 if (IntrReg & SMAP_INTR_RXDNV) {
518 SMAP_REG16(SMAP_R_INTR_CLR) = SMAP_INTR_RXDNV;
519 SmapDrivPrivData->RuntimeStats.RxFrameOverrunCount++;
521 if (IntrReg & SMAP_INTR_TXDNV) {
522 SMAP_REG16(SMAP_R_INTR_CLR) = SMAP_INTR_TXDNV;
523 HandleTxIntr(SmapDrivPrivData);
524 EFBits |= SMAP_EVENT_XMIT;
529 if (EFBits & SMAP_EVENT_XMIT)
530 HandleTxReqs(SmapDrivPrivData);
532 HandleTxIntr(SmapDrivPrivData);
535#ifdef SMAP_RX_PACKETS_POLLING_MODE
536 SpdIntrEnable(SMAP_INTR_EMAC3 | SMAP_INTR_RXDNV);
538 if (PacketCount >= 1) {
542#define ETH_KB_TO_US(B) (B * 80)
544 USec2SysClock(ETH_KB_TO_US(12), &SmapDrivPrivData->RxIntrPollingTimer);
546 SetAlarm(&SmapDrivPrivData->RxIntrPollingTimer, (
void *)&RxIntrPollingTimerCB, SmapDrivPrivData);
549 SpdIntrEnable(SMAP_INTR_RXEND);
552 SpdIntrEnable(DEV9_SMAP_INTR_MASK2);
556 if (SmapDrivPrivData->NumPacketsInTx > 0) {
558 SpdIntrEnable(SMAP_INTR_TXDNV);
567 if (EFBits & SMAP_EVENT_LINK_CHECK) {
569 CheckLinkStatus(SmapDrivPrivData);
575static int Dev9IntrCb(
int flag)
580 OldGP = SetModuleGP();
585 SpdIntrDisable(DEV9_SMAP_ALL_INTR_MASK);
595static void Dev9PreDmaCbHandler(
int bcr,
int dir)
597 volatile u8 *smap_regbase;
601 SliceCount = bcr >> 16;
602 if (dir != DMAC_TO_MEM) {
603 SMAP_REG16(SMAP_R_TXFIFO_SIZE) = SliceCount;
604 SMAP_REG8(SMAP_R_TXFIFO_CTRL) = SMAP_TXFIFO_DMAEN;
606 SMAP_REG16(SMAP_R_RXFIFO_SIZE) = SliceCount;
607 SMAP_REG8(SMAP_R_RXFIFO_CTRL) = SMAP_RXFIFO_DMAEN;
611static void Dev9PostDmaCbHandler(
int bcr,
int dir)
613 volatile u8 *smap_regbase;
618 if (dir != DMAC_TO_MEM) {
619 while (SMAP_REG8(SMAP_R_TXFIFO_CTRL) & SMAP_TXFIFO_DMAEN) {};
621 while (SMAP_REG8(SMAP_R_RXFIFO_CTRL) & SMAP_RXFIFO_DMAEN) {};
625#ifdef BUILDING_SMAP_PS2IP
627int SMAPInitStart(
void)
629 volatile u8 *emac3_regbase;
634 OldGP = SetModuleGP();
640 SpdIntrEnable(DEV9_SMAP_INTR_MASK2);
642 SMAP_EMAC3_SET32(SMAP_R_EMAC3_MODE0, SMAP_E3_TXMAC_ENABLE | SMAP_E3_RXMAC_ENABLE);
670 OldGP = SetModuleGP();
687 OldGP = SetModuleGP();
698static void ClearPacketQueue(
struct SmapDriverData *SmapDrivPrivData)
704 pkt = SmapDrivPrivData->packetToSend;
705 SmapDrivPrivData->packetToSend = NULL;
709 while (SMAPCommonTxPacketNext(SmapDrivPrivData, &pkt) > 0)
710 SMAPCommonTxPacketDeQ(SmapDrivPrivData, &pkt);
719 OldGP = SetModuleGP();
737#ifdef BUILDING_SMAP_NETMAN
738static int SMAPGetLinkMode(
void)
761static int SMAPSetLinkMode(
int mode)
768 baseMode = mode & (~NETMAN_NETIF_ETH_LINK_DISABLE_PAUSE);
771 EnableAutoNegotiation = 0;
775 SmapConfiguration = 0x020;
779 SmapConfiguration = 0x040;
783 SmapConfiguration = 0x080;
787 SmapConfiguration = 0x0100;
794 SmapConfiguration = 0x1E0;
795 EnableAutoNegotiation = 1;
801 SmapConfiguration |= 0x400;
803 SetEventFlag(
SmapDriverData.Dev9IntrEventFlag, SMAP_EVENT_STOP | SMAP_EVENT_START);
812static inline int SMAPGetLinkStatus(
void)
814 return ((
SmapDriverData.SmapIsInitialized &&
SmapDriverData.LinkStatus) ? NETMAN_NETIF_ETH_LINK_STATE_UP : NETMAN_NETIF_ETH_LINK_STATE_DOWN);
817int SMAPIoctl(
unsigned int command,
void *args,
unsigned int args_len,
void *output,
unsigned int length)
823 OldGP = SetModuleGP();
831 result = SMAPGetMACAddress(output);
833 case NETMAN_NETIF_IOCTL_ETH_GET_LINK_MODE:
834 result = SMAPGetLinkMode();
836 case NETMAN_NETIF_IOCTL_GET_LINK_STATUS:
837 result = SMAPGetLinkStatus();
839 case NETMAN_NETIF_IOCTL_GET_TX_DROPPED_COUNT:
842 case NETMAN_NETIF_IOCTL_GET_RX_DROPPED_COUNT:
845 case NETMAN_NETIF_IOCTL_ETH_GET_RX_EOVERRUN_CNT:
848 case NETMAN_NETIF_IOCTL_ETH_GET_RX_EBADLEN_CNT:
851 case NETMAN_NETIF_IOCTL_ETH_GET_RX_EBADFCS_CNT:
854 case NETMAN_NETIF_IOCTL_ETH_GET_RX_EBADALIGN_CNT:
857 case NETMAN_NETIF_IOCTL_ETH_GET_TX_ELOSSCR_CNT:
860 case NETMAN_NETIF_IOCTL_ETH_GET_TX_EEDEFER_CNT:
863 case NETMAN_NETIF_IOCTL_ETH_GET_TX_ECOLL_CNT:
866 case NETMAN_NETIF_IOCTL_ETH_GET_TX_EUNDERRUN_CNT:
870 result = SMAPSetLinkMode(*(
int *)args);
872 case NETMAN_NETIF_IOCTL_ETH_GET_STATUS:
890void SMAPOutputDebugInformation(
void)
892#ifdef SMAP_ENABLE_DEBUG_INFORMATION
899 DEBUG_PRINTF(
"SMAP_R_RXFIFO_CTRL: 0x%x\n", SMAP_REG8(SMAP_R_RXFIFO_CTRL));
900 DEBUG_PRINTF(
"SMAP_R_RXFIFO_RD_PTR: 0x%x\n", SMAP_REG16(SMAP_R_RXFIFO_RD_PTR));
901 DEBUG_PRINTF(
"SMAP_R_RXFIFO_SIZE: %d\n", SMAP_REG16(SMAP_R_RXFIFO_SIZE));
902 DEBUG_PRINTF(
"SMAP_R_RXFIFO_FRAME_CNT: %d\n", SMAP_REG8(SMAP_R_RXFIFO_FRAME_CNT));
903 DEBUG_PRINTF(
"SMAP_R_RXFIFO_FRAME_DEC: %d\n", SMAP_REG8(SMAP_R_RXFIFO_FRAME_DEC));
904 DEBUG_PRINTF(
"SMAP_R_EMAC3_RxMODE: 0x%x\n", (
unsigned int)SMAP_EMAC3_GET32(SMAP_R_EMAC3_RxMODE));
905 DEBUG_PRINTF(
"SMAP_R_EMAC3_INTR_STAT: 0x%x\n", (
unsigned int)SMAP_EMAC3_GET32(SMAP_R_EMAC3_INTR_STAT));
906 DEBUG_PRINTF(
"SMAP_R_EMAC3_INTR_ENABLE: 0x%x\n", (
unsigned int)SMAP_EMAC3_GET32(SMAP_R_EMAC3_INTR_ENABLE));
908 for (i = 0; i < SMAP_BD_MAX_ENTRY; i += 1) {
910 rx_bd[i].reserved != 0 ||
911 rx_bd[i].length != 0 ||
912 rx_bd[i].pointer != 0 ||
916 (
" - rx_bd[%d]: 0x%x / 0x%x / %d / 0x%x <--\n", i, rx_bd[i].ctrl_stat, rx_bd[i].reserved, rx_bd[i].length, rx_bd[i].pointer);
919 (
" - rx_bd[%d]: 0x%x / 0x%x / %d / 0x%x\n", i, rx_bd[i].ctrl_stat, rx_bd[i].reserved, rx_bd[i].length, rx_bd[i].pointer);
923 DEBUG_PRINTF(
"RxDroppedFrameCount: %d\n", (
int)
SmapDriverData.RuntimeStats.RxDroppedFrameCount);
924 DEBUG_PRINTF(
"RxErrorCount: %d\n", (
int)
SmapDriverData.RuntimeStats.RxErrorCount);
925 DEBUG_PRINTF(
"RxFrameOverrunCount: %d\n",
SmapDriverData.RuntimeStats.RxFrameOverrunCount);
926 DEBUG_PRINTF(
"RxFrameBadLengthCount: %d\n",
SmapDriverData.RuntimeStats.RxFrameBadLengthCount);
927 DEBUG_PRINTF(
"RxFrameBadFCSCount: %d\n",
SmapDriverData.RuntimeStats.RxFrameBadFCSCount);
928 DEBUG_PRINTF(
"RxFrameBadAlignmentCount: %d\n",
SmapDriverData.RuntimeStats.RxFrameBadAlignmentCount);
929 DEBUG_PRINTF(
"TxDroppedFrameCount: %d\n", (
int)
SmapDriverData.RuntimeStats.TxDroppedFrameCount);
930 DEBUG_PRINTF(
"TxErrorCount: %d\n", (
int)
SmapDriverData.RuntimeStats.TxErrorCount);
931 DEBUG_PRINTF(
"TxFrameLOSSCRCount: %d\n",
SmapDriverData.RuntimeStats.TxFrameLOSSCRCount);
932 DEBUG_PRINTF(
"TxFrameEDEFERCount: %d\n",
SmapDriverData.RuntimeStats.TxFrameEDEFERCount);
933 DEBUG_PRINTF(
"TxFrameCollisionCount: %d\n",
SmapDriverData.RuntimeStats.TxFrameCollisionCount);
934 DEBUG_PRINTF(
"TxFrameUnderrunCount: %d\n",
SmapDriverData.RuntimeStats.TxFrameUnderrunCount);
935 DEBUG_PRINTF(
"RxAllocFail: %d\n",
SmapDriverData.RuntimeStats.RxAllocFail);
939#ifdef BUILDING_SMAP_MODULAR
947 if (hooktbl != NULL) {
948 if (hooktbl->Version != 1) {
958 .GetMACAddress = &SMAPGetMACAddress,
960 .OutputDebugInformation = &SMAPOutputDebugInformation,
961 .RegisterHook = &SMapRegisterHook,
972static inline int SetupNetDev(
void)
977#ifdef BUILDING_SMAP_NETMAN
990 EventFlagData.attr = 0;
991 EventFlagData.option = 0;
992 EventFlagData.bits = 0;
994 if ((result =
SmapDriverData.Dev9IntrEventFlag = CreateEventFlag(&EventFlagData)) < 0) {
995 DEBUG_PRINTF(
"CreateEventFlag -> %d\n", result);
999 ThreadData.attr = TH_C;
1000 ThreadData.thread = (
void *)&IntrHandlerThread;
1001 ThreadData.option = 0;
1002 ThreadData.priority = ThreadPriority;
1003 ThreadData.stacksize = ThreadStackSize;
1004 if ((result =
SmapDriverData.IntrHandlerThreadID = CreateThread(&ThreadData)) < 0) {
1005 DEBUG_PRINTF(
"CreateThread -> %d\n", result);
1011 printf(
"smap: StartThread -> %d\n", result);
1017#ifdef BUILDING_SMAP_NETMAN
1018 if ((
SmapDriverData.NetIFID = NetManRegisterNetIF(&device)) < 0) {
1019 printf(
"smap: NetManRegisterNetIF -> %d\n", result);
1030static int ParseSmapConfiguration(
const char *cmd,
unsigned int *configuration)
1032 const char *CmdStart, *DigitStart;
1033 unsigned int result, base, character, value;
1035 DigitStart = CmdStart = cmd;
1038 if (CmdStart[0] ==
'0') {
1039 if (CmdStart[1] !=
'\0') {
1040 if (CmdStart[1] ==
'x') {
1048 if (DigitStart[0] ==
'\0') {
1053 character = DigitStart[0];
1055 if (character -
'0' < 10) {
1056 value = character -
'0';
1057 }
else if (character -
'a' < 6) {
1058 value = character -
'a' - 0x57;
1065 result = result * base + value;
1066 }
while ((character = *(++DigitStart)) !=
'\0');
1067 *configuration = result;
1071 printf(
"smap: %s: %s - invalid digit\n",
"scan_number", CmdStart);
1075int smap_init(
int argc,
char *argv[])
1078 const char *CmdString;
1079 u16 eeprom_data[4], checksum16;
1083 USE_SMAP_EMAC3_REGS;
1088#ifdef BUILDING_SMAP_NETMAN
1093 if (strcmp(
"-help", *argv) == 0) {
1094 return DisplayHelpMessage();
1095 }
else if (strcmp(
"-version", *argv) == 0) {
1096 return DisplayBanner();
1097 }
else if (strcmp(
"-verbose", *argv) == 0) {
1098 EnableVerboseOutput = 1;
1099 }
else if (strcmp(
"-auto", *argv) == 0) {
1100 EnableAutoNegotiation = 1;
1101 }
else if (strcmp(
"-no_auto", *argv) == 0) {
1102 EnableAutoNegotiation = 0;
1103 }
else if (strcmp(
"-strap", *argv) == 0) {
1104 EnablePinStrapConfig = 1;
1105 }
else if (strcmp(
"-no_strap", *argv) == 0) {
1106 EnablePinStrapConfig = 0;
1107 }
else if (strncmp(
"thpri=", *argv, 6) == 0) {
1108 CmdString = &(*argv)[6];
1109 if (isdigit(CmdString[0])) {
1110 ThreadPriority = strtoul(&(*argv)[6], NULL, 10);
1111 if (ThreadPriority - 9 >= 0x73) {
1112 return DisplayHelpMessage();
1115 if ((*argv)[6] !=
'\0') {
1116 while (isdigit(*CmdString)) {
1119 if (*CmdString !=
'\0')
1120 return DisplayHelpMessage();
1123 return DisplayHelpMessage();
1124 }
else if (strncmp(
"thstack=", *argv, 8) == 0) {
1125 CmdString = &(*argv)[8];
1126 if (isdigit(CmdString[0])) {
1127 ThreadStackSize = strtoul(&(*argv)[8], NULL, 10);
1128 if ((*argv)[8] !=
'\0') {
1129 while (isdigit(*CmdString)) {
1134 if (strcmp(CmdString,
"KB") == 0)
1135 ThreadStackSize <<= 10;
1137 return DisplayHelpMessage();
1139 if (ParseSmapConfiguration(*argv, &SmapConfiguration) != 0)
1140 return DisplayHelpMessage();
1148 return DisplayHelpMessage();
1152 if ((SPD_REG16(SPD_R_REV_3) & SPD_CAPS_SMAP) == 0)
1154 if (SPD_REG16(SPD_R_REV_1) < 0x11)
1157 SpdIntrDisable(DEV9_SMAP_ALL_INTR_MASK);
1160 SMAP_REG8(SMAP_R_TXFIFO_CTRL) = SMAP_TXFIFO_RESET;
1161 for (i = 9; SMAP_REG8(SMAP_R_TXFIFO_CTRL) & SMAP_TXFIFO_RESET; i--) {
1167 SMAP_REG8(SMAP_R_RXFIFO_CTRL) = SMAP_RXFIFO_RESET;
1168 for (i = 9; SMAP_REG8(SMAP_R_RXFIFO_CTRL) & SMAP_RXFIFO_RESET; i--) {
1174 SMAP_EMAC3_SET32(SMAP_R_EMAC3_MODE0, SMAP_E3_SOFT_RESET);
1175 for (i = 9; SMAP_EMAC3_GET32(SMAP_R_EMAC3_MODE0) & SMAP_E3_SOFT_RESET; i--) {
1181 SMAP_REG8(SMAP_R_BD_MODE) = 0;
1182 for (i = 0; i < SMAP_BD_MAX_ENTRY; i++) {
1183 tx_bd[i].ctrl_stat = 0;
1184 tx_bd[i].reserved = 0;
1185 tx_bd[i].length = 0;
1186 tx_bd[i].pointer = 0;
1189 for (i = 0; i < SMAP_BD_MAX_ENTRY; i++) {
1191 rx_bd[i].reserved = 0;
1192 rx_bd[i].length = 0;
1193 rx_bd[i].pointer = 0;
1198 SMAP_REG16(SMAP_R_INTR_CLR) = DEV9_SMAP_ALL_INTR_MASK;
1201 bzero(eeprom_data, 8);
1202 if ((result = SpdGetEthernetID(eeprom_data)) < 0) {
1203 return (result == -1 ? -7 : -4);
1206 for (i = 0; i < 3; i++)
1207 checksum16 += eeprom_data[i];
1208 if (eeprom_data[0] == 0 && eeprom_data[1] == 0 && eeprom_data[2] == 0) {
1211 if (checksum16 != eeprom_data[3])
1214 SMAP_EMAC3_SET32(SMAP_R_EMAC3_MODE1, SMAP_E3_FDX_ENABLE | SMAP_E3_IGNORE_SQE | SMAP_E3_MEDIA_100M | SMAP_E3_RXFIFO_2K | SMAP_E3_TXFIFO_1K | SMAP_E3_TXREQ0_MULTI | SMAP_E3_TXREQ1_SINGLE);
1217 SMAP_EMAC3_SET32(SMAP_R_EMAC3_RxMODE, SMAP_E3_RX_STRIP_PAD | SMAP_E3_RX_STRIP_FCS | SMAP_E3_RX_INDIVID_ADDR | SMAP_E3_RX_BCAST | SMAP_E3_RX_MCAST);
1218 SMAP_EMAC3_SET32(SMAP_R_EMAC3_INTR_STAT, SMAP_E3_INTR_TX_ERR_0 | SMAP_E3_INTR_SQE_ERR_0 | SMAP_E3_INTR_DEAD_0);
1219 SMAP_EMAC3_SET32(SMAP_R_EMAC3_INTR_ENABLE, SMAP_E3_INTR_TX_ERR_0 | SMAP_E3_INTR_SQE_ERR_0 | SMAP_E3_INTR_DEAD_0);
1221 mac_address = (u16)(eeprom_data[0] >> 8 | eeprom_data[0] << 8);
1222 SMAP_EMAC3_SET32(SMAP_R_EMAC3_ADDR_HI, mac_address);
1224 mac_address = ((u16)(eeprom_data[1] >> 8 | eeprom_data[1] << 8) << 16) | (u16)(eeprom_data[2] >> 8 | eeprom_data[2] << 8);
1225 SMAP_EMAC3_SET32(SMAP_R_EMAC3_ADDR_LO, mac_address);
1227 SMAP_EMAC3_SET32(SMAP_R_EMAC3_PAUSE_TIMER, 0xFFFF);
1228 SMAP_EMAC3_SET32(SMAP_R_EMAC3_GROUP_HASH1, 0);
1229 SMAP_EMAC3_SET32(SMAP_R_EMAC3_GROUP_HASH2, 0);
1230 SMAP_EMAC3_SET32(SMAP_R_EMAC3_GROUP_HASH3, 0);
1231 SMAP_EMAC3_SET32(SMAP_R_EMAC3_GROUP_HASH4, 0);
1233 SMAP_EMAC3_SET32(SMAP_R_EMAC3_INTER_FRAME_GAP, 4);
1235 SMAP_EMAC3_SET32(SMAP_R_EMAC3_TX_THRESHOLD, (12 & SMAP_E3_TX_THRESHLD_MSK) << SMAP_E3_TX_THRESHLD_BITSFT);
1237 SMAP_EMAC3_SET32(SMAP_R_EMAC3_RX_WATERMARK, (16 & SMAP_E3_RX_LO_WATER_MSK) << SMAP_E3_RX_LO_WATER_BITSFT | (128 & SMAP_E3_RX_HI_WATER_MSK) << SMAP_E3_RX_HI_WATER_BITSFT);
1240 for (i = 2; i < 7; i++)
1241 SpdRegisterIntrHandler(i, &Dev9IntrCb);
1243 dev9RegisterPreDmaCb(1, &Dev9PreDmaCbHandler);
1244 dev9RegisterPostDmaCb(1, &Dev9PostDmaCbHandler);
1246 return SetupNetDev();
1249int SMAPGetMACAddress(u8 *buffer)
1251 u32 mac_address_lo, mac_address_hi;
1252 volatile u8 *emac3_regbase;
1259 mac_address_hi = SMAP_EMAC3_GET32(SMAP_R_EMAC3_ADDR_HI);
1260 mac_address_lo = SMAP_EMAC3_GET32(SMAP_R_EMAC3_ADDR_LO);
1264 buffer[0] = mac_address_hi >> 8;
1265 buffer[1] = mac_address_hi;
1266 buffer[2] = mac_address_lo >> 24;
1267 buffer[3] = mac_address_lo >> 16;
1268 buffer[4] = mac_address_lo >> 8;
1269 buffer[5] = mac_address_lo;
int CpuResumeIntr(int state)
int QueryIntrContext(void)
int CpuSuspendIntr(int *state)
@ NETMAN_NETIF_ETH_LINK_MODE_100M_HDX
@ NETMAN_NETIF_ETH_LINK_MODE_10M_FDX
@ NETMAN_NETIF_ETH_LINK_MODE_10M_HDX
@ NETMAN_NETIF_ETH_LINK_MODE_AUTO
@ NETMAN_NETIF_ETH_LINK_MODE_100M_FDX
@ NETMAN_NETIF_IOCTL_ETH_GET_MAC
@ NETMAN_NETIF_IOCTL_ETH_SET_LINK_MODE
#define NETMAN_NETIF_ETH_LINK_DISABLE_PAUSE
#define SMAP_BD_TX_EDEFER
#define SMAP_E3_TX_URG_REQ_BITSFT
#define SMAP_BD_TX_UNDERRUN
#define SMAP_PHY_ANAR_10_FD
#define SMAP_PHY_BMSR_ANCP
#define SMAP_E3_FLOWCTRL_ENABLE
#define SMAP_E3_PHY_OP_COMP
#define SMAP_PHY_ANAR_TX_FD
#define SMAP_E3_TX_URG_REQ_MSK
#define SMAP_PHY_10BTSCR_LOOPBACK_10_DIS
#define SMAP_PHY_BMSR_LINK
#define SMAP_PHY_10BTSCR_2
#define SMAP_E3_TX_LOW_REQ_BITSFT
#define SMAP_BD_TX_LOSSCR
#define SMAP_E3_TX_LOW_REQ_MSK