00001
00015 #include <stdio.h>
00016
00017 #include "ksz8851snl.h"
00018 #include "ksz8851snl_spi.h"
00019 #include "em_assert.h"
00020
00021 #include "lwip/sys.h"
00022 #include "lwipopts.h"
00023 #include "debug.h"
00024
00025 #ifndef LWIP4EFM32
00026 #error "lwiopts.h for EFM32 are not included"
00027 #endif
00028
00029
00030 #define MARL 0x10
00031 #define MARM 0x12
00032 #define MARH 0x14
00033 #define OBCR 0x20
00034 #define GRR 0x26
00035 #define TXCR 0x70
00036 #define RXCR1 0x74
00037 #define RXCR2 0x76
00038 #define TXMIR 0x78
00039 #define RXFHSR 0x7C
00040 #define RXFHBCR 0x7E
00041 #define TXQCR 0x80
00042 #define RXQCR 0x82
00043 #define TXFDPR 0x84
00044 #define RXFDPR 0x86
00045 #define IER 0x90
00046 #define ISR 0x92
00047 #define RXFCTR 0x9C
00048 #define TXNTFSR 0x9E
00049 #define FCLWR 0xB0
00050 #define FCHWR 0xB2
00051 #define CIDER 0xC0
00052 #define IACR 0xC8
00053 #define IADLR 0xD0
00054 #define IADHR 0xD2
00055 #define PMECR 0xD4
00056 #define PHYRR 0xD8
00057 #define P1MBCR 0xE4
00058 #define P1CR 0xF6
00059 #define P1SR 0xF8
00061 #define KSZ8851SNL_CHIP_ID 0x8870
00062 #define CHIP_ID_MASK 0xFFF0
00063 #define ONE_FRAME_THRES 0x0001
00064 #define FD_PTR_AUTO_INC 0x4000
00065 #define CLEAR_INT 0xFFFF
00066 #define NO_INT 0x0000
00067 #define TX_MEM_AVAIL_MASK 0x1FFF
00068 #define FRAME_ID_MASK 0x003F
00069 #define CHECKSUM_VALID_FRAME_MASK 0x3C17
00073 #define VALID_FRAME_MASK 0x8000
00076 #define RX_BYTE_CNT_MASK 0x0FFF
00077 #define LSB_MASK 0x00FF
00078 #define MSB_POS 0x0008
00079 #define TX_INT_on_COMPLETION 0x8000
00080 #define WORD_SIZE 0x0004
00081 #define EXTRA_SIZE 0x0008
00082 #define BLOCKING_RECEIVE 0
00083 #define WATERMARK_6KB 0x0600
00084 #define WATERMARK_4KB 0x0400
00085
00086 #define HIGH_QMU_MAC_H 0x00
00087 #define HIGH_QMU_MAC_L 0x0B
00088 #define MID_QMU_MAC_H 0x57
00089 #define BYTE_MASK 0x00FF
00090 #define BYTE_SIZE 0x0008
00092
00093
00095 #define TX_FLOW_CTRL_ICMP_CHECKSUM 0x0100
00096
00097 #define TX_FLOW_CTRL_TCP_CHECKSUM 0x0040
00098
00099 #define TX_FLOW_CTRL_IP_CHECKSUM 0x0020
00100
00101 #define TX_FLOW_CTRL_FLUSH_QUEUE 0x0010
00102
00103 #define TX_FLOW_CTRL_FLOW_ENABLE 0x0008
00104
00105 #define TX_FLOW_CTRL_PAD_ENABLE 0x0004
00106
00107 #define TX_FLOW_CTRL_CRC_ENABLE 0x0002
00108
00109 #define TX_FLOW_CTRL_ENABLE 0x0001
00110
00112 #define TX_FLOW_CTRL_CONFIG (TX_FLOW_CTRL_ICMP_CHECKSUM | \
00113 TX_FLOW_CTRL_TCP_CHECKSUM | \
00114 TX_FLOW_CTRL_IP_CHECKSUM | \
00115 TX_FLOW_CTRL_FLOW_ENABLE | \
00116 TX_FLOW_CTRL_PAD_ENABLE | \
00117 TX_FLOW_CTRL_CRC_ENABLE)
00118
00119
00121 #define TXQ_AUTO_ENQUEUE 0x0004
00122
00123 #define TXQ_MEM_AVAILABLE_INT 0x0002
00124
00125 #define TXQ_ENQUEUE 0x0001
00126
00127
00128
00130 #define RX_FLOW_CTRL_FLUSH_QUEUE 0x8000
00131
00132 #define RX_FLOW_CTRL_UDP_CHECKSUM 0x4000
00133
00134 #define RX_FLOW_CTRL_TCP_CHECKSUM 0x2000
00135
00136 #define RX_FLOW_CTRL_IP_CHECKSUM 0x1000
00137
00138 #define RX_FLOW_CTRL_MAC_FILTER 0x0800
00139
00140 #define RX_FLOW_CTRL_FLOW_ENENABLE 0x0400
00141
00142 #define RX_FLOW_CTRL_BAD_PACKET 0x0200
00143
00144 #define RX_FLOW_CTRL_BROADCAST_ENABLE 0x0080
00145
00146 #define RX_FLOW_CTRL_MULTICAST_ENABLE 0x0040
00147
00148 #define RX_FLOW_CTRL_UNICAST_ENABLE 0x0020
00149
00150 #define RX_FLOW_CTRL_PROMISCUOUS_MODE 0x0012
00151
00152 #define RX_FLOW_CTRL_RX_ALL 0x0010
00153
00154 #define RX_FLOW_CTRL_INVERSE_FILTER 0x0002
00155
00156 #define RX_FLOW_CTRL_RX_ENABLE 0x0001
00157
00159 #define RX_FLOW_CTRL1_CONFIG (RX_FLOW_CTRL_UDP_CHECKSUM | \
00160 RX_FLOW_CTRL_TCP_CHECKSUM | \
00161 RX_FLOW_CTRL_IP_CHECKSUM | \
00162 RX_FLOW_CTRL_MAC_FILTER | \
00163 RX_FLOW_CTRL_FLOW_ENENABLE | \
00164 RX_FLOW_CTRL_BROADCAST_ENABLE | \
00165 RX_FLOW_CTRL_UNICAST_ENABLE)
00166
00167
00168
00170 #define RX_FLOW_CTRL_BURST_LEN_MASK 0x00E0
00171
00172 #define RX_FLOW_CTRL_BURST_LEN_4 0x0000
00173
00174 #define RX_FLOW_CTRL_BURST_LEN_8 0x0020
00175
00176 #define RX_FLOW_CTRL_BURST_LEN_16 0x0040
00177
00178 #define RX_FLOW_CTRL_BURST_LEN_32 0x0060
00179
00180 #define RX_FLOW_CTRL_BURST_LEN_FRAME 0x0080
00181
00182 #define RX_FLOW_CTRL_IPV6_UDP_FRAG_PASS 0x0010
00183
00184 #define RX_FLOW_CTRL_IPV6_UDP_ZERO_PASS 0x0008
00185
00186 #define RX_FLOW_CTRL_UDP_LITE_CHECKSUM 0x0004
00187
00188 #define RX_FLOW_CTRL_ICMP_CHECKSUM 0x0002
00189
00190 #define RX_FLOW_CTRL_BLOCK_MAC 0x0001
00191
00193 #define RX_FLOW_CTRL2_CONFIG (RX_FLOW_CTRL_IPV6_UDP_FRAG_PASS | \
00194 RX_FLOW_CTRL_UDP_LITE_CHECKSUM | \
00195 RX_FLOW_CTRL_ICMP_CHECKSUM | \
00196 RX_FLOW_CTRL_BURST_LEN_FRAME)
00197
00198
00200 #define RXQ_ON_TIME_INT 0x1000
00201
00202 #define RXQ_ON_BYTE_CNT_INT 0x0800
00203
00204 #define RXQ_ON_FRAME_CNT_INT 0x0400
00205
00206 #define RXQ_TWOBYTE_OFFSET 0x0200
00207
00208 #define RXQ_EN_ON_TIME_INT 0x0080
00209
00210 #define RXQ_EN_ON_BYTE_CNT_INT 0x0040
00211
00212 #define RXQ_EN_ON_FRAME_CNT_INT 0x0020
00213
00214 #define RXQ_AUTO_DEQUEUE 0x0010
00215
00216 #define RXQ_START_DMA 0x0008
00217
00218 #define RXQ_RELEASE_ERROR_FRAME 0x0001
00219
00221 #define RXQ_CMD_CONFIG (RXQ_EN_ON_FRAME_CNT_INT | \
00222 RXQ_AUTO_DEQUEUE)
00223
00224
00226 #define PORT1_AN_DONE 0x0040
00227
00228 #define PORT1_LINK_GOOD 0x0020
00229
00230
00232 #define PORT1_LED_OFF 0x8000
00233
00234 #define PORT1_TX_DISABLE 0x4000
00235
00236 #define PORT1_AUTO_NEG_RESTART 0x2000
00237
00238 #define PORT1_POWER_DOWN 0x0800
00239
00240 #define PORT1_AUTO_MDIX_DISABLE 0x0400
00241
00242 #define PORT1_FORCE_MDIX 0x0200
00243
00244 #define PORT1_AUTO_NEG_ENABLE 0x0080
00245
00246 #define PORT1_FORCE_100_MBIT 0x0040
00247
00248 #define PORT1_FORCE_FULL_DUPLEX 0x0020
00249
00250 #define PORT1_AUTO_NEG_FLOW_CTRL 0x0010
00251
00252 #define PORT1_AUTO_NEG_100BTX_FD 0x0008
00253
00254 #define PORT1_AUTO_NEG_100BTX 0x0004
00255
00256 #define PORT1_AUTO_NEG_10BT_FD 0x0002
00257
00258 #define PORT1_AUTO_NEG_10BT 0x0001
00259
00261 #define PORT1_CONFIG (PORT1_AUTO_NEG_ENABLE | \
00262 PORT1_FORCE_100_MBIT | \
00263 PORT1_FORCE_FULL_DUPLEX | \
00264 PORT1_AUTO_NEG_FLOW_CTRL | \
00265 PORT1_AUTO_NEG_100BTX_FD | \
00266 PORT1_AUTO_NEG_100BTX | \
00267 PORT1_AUTO_NEG_10BT_FD | \
00268 PORT1_AUTO_NEG_10BT )
00269
00270
00272 #define QMU_MODULE_SOFT_RESET 0x0002
00273
00274 #define GLOBAL_SOFT_RESET 0x0001
00275
00277 #define PHY_RESET 0x0001
00278
00279
00281 #define DIGITAL_LOOPBACK 0x4000
00282
00283 #define FORCE_100 0x2000
00284
00285 #define AUTO_NEG 0x1000
00286
00287 #define RESTART_AUTO_NEG 0x0200
00288
00289 #define FORCE_FULL_DUPLEX 0x0100
00290
00292 #define TX_MEMORY_WAIT_MS 500
00293
00295 #define FRAME_COUNT_THRESHOLD 1
00296
00298 #define MIB_MASK 0x1C00
00299 #define MIB_RxByte 0x00
00300 #define MIB_XXX 0x01
00301 #define MIB_RxUndersizePkt 0x02
00302 #define MIB_RxFragments 0x03
00303 #define MIB_RxOversize 0x04
00304 #define MIB_RxJabbers 0x05
00305 #define MIB_RxSymbolError 0x06
00306 #define MIB_RxCRCError 0x07
00307 #define MIB_RxAlignmentError 0x08
00308 #define MIB_RxControl8808Pkts 0x09
00309 #define MIB_RxPausePkts 0x0A
00310 #define MIB_RxBroadcast 0x0B
00311 #define MIB_RxMulticast 0x0C
00312 #define MIB_RxUnicast 0x0D
00313 #define MIB_Rx64Octets 0x0E
00314 #define MIB_Rx65to127Octets 0x0F
00315 #define MIB_Rx128to255Octets 0x10
00316 #define MIB_Rx256to511Octets 0x11
00317 #define MIB_Rx512to1023Octets 0x12
00318 #define MIB_Rx1024to1521Octets 0x13
00319 #define MIB_Rx1522to2000Octets 0x14
00320 #define MIB_TxByte 0x15
00321 #define MIB_TxLateCollision 0x16
00322 #define MIB_TxPausePkts 0x17
00323 #define MIB_TxBroadcastPkts 0x18
00324 #define MIB_TxMulticastPkts 0x19
00325 #define MIB_TxUnicastPkts 0x1A
00326 #define MIB_TxDeferred 0x1B
00327 #define MIB_TxTotalCollision 0x1C
00328 #define MIB_TxExcessiveCollision 0x1D
00329 #define MIB_TxSingleCollision 0x1E
00330 #define MIB_TxMultipleCollision 0x1F
00333 #define READ_UNSAFE_REGISTERS 0
00334
00335 static uint16_t frameId = 0;
00336 static uint8_t macAddress[6];
00337 static uint16_t rxFrameCount;
00338 static uint32_t interruptCnt = 0;
00350 static KSZ8851SLN_mib_t mibCounters;
00351
00352
00362 static uint32_t MIBCountersRead(uint16_t offset)
00363 {
00364 uint16_t data;
00365 uint32_t counter;
00366
00367 data = MIB_MASK | offset;
00368 KSZ8851SNL_SPI_WriteRegister(IACR, data);
00369 counter = KSZ8851SNL_SPI_ReadRegister(IADLR);
00370 counter |= KSZ8851SNL_SPI_ReadRegister(IADHR) << 16;
00371
00372 return counter;
00373 }
00374
00375
00382 void KSZ8851SNL_MIBCountersUpdate(void)
00383 {
00384 mibCounters.RxByteCnt += MIBCountersRead(MIB_RxByte);
00385 mibCounters.RxUndersizePktCnt += MIBCountersRead(MIB_RxUndersizePkt);
00386 mibCounters.RxFragmentsCnt += MIBCountersRead(MIB_RxFragments);
00387 mibCounters.RxOversizeCnt += MIBCountersRead(MIB_RxOversize);
00388 mibCounters.RxJabbersCnt += MIBCountersRead(MIB_RxJabbers);
00389 mibCounters.RxSymbolErrorCnt += MIBCountersRead(MIB_RxSymbolError);
00390 mibCounters.RxCRCErrorCnt += MIBCountersRead(MIB_RxCRCError);
00391 mibCounters.RxPausePktsCnt += MIBCountersRead(MIB_RxPausePkts);
00392 mibCounters.RxBroadcastCnt += MIBCountersRead(MIB_RxBroadcast);
00393 mibCounters.RxMulticastCnt += MIBCountersRead(MIB_RxMulticast);
00394 mibCounters.RxUnicastCnt += MIBCountersRead(MIB_RxUnicast);
00395 mibCounters.TxByteCnt += MIBCountersRead(MIB_TxByte);
00396 mibCounters.TxPausePktsCnt += MIBCountersRead(MIB_TxPausePkts);
00397 mibCounters.TxBroadcastPktsCnt += MIBCountersRead(MIB_TxBroadcastPkts);
00398 mibCounters.TxMulticastPktsCnt += MIBCountersRead(MIB_TxMulticastPkts);
00399 mibCounters.TxUnicastPktsCnt += MIBCountersRead(MIB_TxUnicastPkts);
00400 mibCounters.TxDeferredCnt += MIBCountersRead(MIB_TxDeferred);
00401 mibCounters.TxTotalCollisionCnt += MIBCountersRead(MIB_TxTotalCollision);
00402 }
00403
00404
00409 void KSZ8851SNL_MIBCountersDump(void)
00410 {
00411 printf("####################### MIB COUNTER DUMP ########################\n");
00412 printf("MIB_RxByteCnt = %lu\n", mibCounters.RxByteCnt);
00413 printf("MIB_RxUndersizePktCnt = %lu\n", mibCounters.RxUndersizePktCnt);
00414 printf("MIB_RxFragmentsCnt = %lu\n", mibCounters.RxFragmentsCnt);
00415 printf("MIB_RxOversizeCnt = %lu\n", mibCounters.RxOversizeCnt);
00416 printf("MIB_RxJabbersCnt = %lu\n", mibCounters.RxJabbersCnt);
00417 printf("MIB_RxSymbolErrorCnt = %lu\n", mibCounters.RxSymbolErrorCnt);
00418 printf("MIB_RxCRCErrorCnt = %lu\n", mibCounters.RxCRCErrorCnt);
00419 printf("MIB_RxPausePktsCnt = %lu\n", mibCounters.RxPausePktsCnt);
00420 printf("MIB_RxBroadcastCnt = %lu\n", mibCounters.RxBroadcastCnt);
00421 printf("MIB_RxMulticastCnt = %lu\n", mibCounters.RxMulticastCnt);
00422 printf("MIB_RxUnicastCnt = %lu\n", mibCounters.RxUnicastCnt);
00423 printf("MIB_TxByteCnt = %lu\n", mibCounters.TxByteCnt);
00424 printf("MIB_TxPausePktsCnt = %lu\n", mibCounters.TxPausePktsCnt);
00425 printf("MIB_TxBroadcastPktsCnt = %lu\n", mibCounters.TxBroadcastPktsCnt);
00426 printf("MIB_TxMulticastPktsCnt = %lu\n", mibCounters.TxMulticastPktsCnt);
00427 printf("MIB_TxUnicastPktsCnt = %lu\n", mibCounters.TxUnicastPktsCnt);
00428 printf("MIB_TxDeferredCnt = %lu\n", mibCounters.TxDeferredCnt);
00429 printf("MIB_TxTotalCollisionCnt = %lu\n", mibCounters.TxTotalCollisionCnt);
00430 printf("#################################################################\n");
00431 }
00432
00433
00437 void KSZ8851SNL_AllRegistersDump(void)
00438 {
00439 printf("###################### ALL REGISTER DUMP ########################\n");
00440 int i;
00441 for (i = 0x00; i < 0xFF; i += 0x02)
00442 {
00443 if ((i % 8 == 0) && (i > 0))
00444 {
00445 printf("\n");
00446 }
00447 printf("REG[0x%02X]=0x%04X ", i, KSZ8851SNL_SPI_ReadRegister(i));
00448 }
00449 printf("\n");
00450 printf("#################################################################\n");
00451 }
00452
00453
00457 void KSZ8851SNL_RegistersDump(void)
00458 {
00459 printf("##################### SPECIAL REGISTER DUMP ######################\n");
00460 printf("MARL [0x%02X]=0x%04X\n", MARL, KSZ8851SNL_SPI_ReadRegister(MARL));
00461 printf("MARM [0x%02X]=0x%04X\n", MARM, KSZ8851SNL_SPI_ReadRegister(MARM));
00462 printf("MARH [0x%02X]=0x%04X\n", MARH, KSZ8851SNL_SPI_ReadRegister(MARH));
00463 printf("OBCR [0x%02X]=0x%04X\n", OBCR, KSZ8851SNL_SPI_ReadRegister(OBCR));
00464 printf("GRR [0x%02X]=0x%04X\n", GRR, KSZ8851SNL_SPI_ReadRegister(GRR));
00465 printf("TXCR [0x%02X]=0x%04X\n", TXCR, KSZ8851SNL_SPI_ReadRegister(TXCR));
00466 printf("RXCR1 [0x%02X]=0x%04X\n", RXCR1, KSZ8851SNL_SPI_ReadRegister(RXCR1));
00467 printf("RXCR2 [0x%02X]=0x%04X\n", RXCR2, KSZ8851SNL_SPI_ReadRegister(RXCR2));
00468 printf("TXMIR [0x%02X]=0x%04X\n", TXMIR, KSZ8851SNL_SPI_ReadRegister(TXMIR));
00469 #if (READ_UNSAFE_REGISTERS)
00470 printf("RXFHSR[0x%02X]=0x%04X\n", RXFHSR, KSZ8851SNL_SPI_ReadRegister(RXFHSR));
00471 #endif
00472 printf("TXQCR [0x%02X]=0x%04X\n", TXQCR, KSZ8851SNL_SPI_ReadRegister(TXQCR));
00473 printf("RXQCR [0x%02X]=0x%04X\n", RXQCR, KSZ8851SNL_SPI_ReadRegister(RXQCR));
00474 printf("TXFDPR[0x%02X]=0x%04X\n", TXFDPR, KSZ8851SNL_SPI_ReadRegister(TXFDPR));
00475 printf("RXFDPR[0x%02X]=0x%04X\n", RXFDPR, KSZ8851SNL_SPI_ReadRegister(RXFDPR));
00476 printf("IER [0x%02X]=0x%04X\n", IER, KSZ8851SNL_SPI_ReadRegister(IER));
00477 printf("ISR [0x%02X]=0x%04X\n", ISR, KSZ8851SNL_SPI_ReadRegister(ISR));
00478 printf("RXFCTR[0x%02X]=0x%04X\n", RXFCTR, KSZ8851SNL_SPI_ReadRegister(RXFCTR));
00479 #if (READ_UNSAFE_REGISTERS)
00480 printf("TXNTFSR[0x%02X]=0x%04X\n", TXNTFSR, KSZ8851SNL_SPI_ReadRegister(TXNTFSR));
00481 #endif
00482 printf("CIDER [0x%02X]=0x%04X\n", CIDER, KSZ8851SNL_SPI_ReadRegister(CIDER));
00483 printf("PHYRR [0x%02X]=0x%04X\n", PHYRR, KSZ8851SNL_SPI_ReadRegister(PHYRR));
00484 printf("P1MBCR[0x%02X]=0x%04X\n", P1MBCR, KSZ8851SNL_SPI_ReadRegister(P1MBCR));
00485 printf("P1CR [0x%02X]=0x%04X\n", P1CR, KSZ8851SNL_SPI_ReadRegister(P1CR));
00486 printf("#################################################################\n");
00487 }
00488
00489
00492 void KSZ8851SNL_IntEnable(void)
00493 {
00494 if (interruptCnt)
00495 {
00496 interruptCnt--;
00497 }
00498 if (interruptCnt == 0)
00499 {
00500
00501 KSZ8851SNL_SPI_WriteRegister(IER, KSZ8851SNL_INT_ENABLE_MASK);
00502 }
00503 }
00504
00505
00508 void KSZ8851SNL_IntDisable(void)
00509 {
00510 KSZ8851SNL_SPI_WriteRegister(IER, NO_INT);
00511 interruptCnt++;
00512 }
00513
00514
00521 void KSZ8851SNL_IntClear(uint16_t flags)
00522 {
00523 KSZ8851SNL_SPI_WriteRegister(ISR, flags);
00524 }
00525
00526
00529 uint16_t KSZ8851SNL_IntGet(void)
00530 {
00531 return KSZ8851SNL_SPI_ReadRegister(ISR);
00532 }
00533
00534
00541 void KSZ8851SNL_PMECRStatusClear(uint16_t flags)
00542 {
00543 uint16_t status = KSZ8851SNL_SPI_ReadRegister(PMECR) | flags;
00544 KSZ8851SNL_SPI_WriteRegister(PMECR, status);
00545 }
00546
00547
00550 uint16_t KSZ8851SNL_RXQCRGet(void)
00551 {
00552 return KSZ8851SNL_SPI_ReadRegister(RXQCR);
00553 }
00554
00555
00558 void KSZ8851SNL_FrameCounterSet(void)
00559 {
00560
00561 uint16_t rxftr = KSZ8851SNL_SPI_ReadRegister(RXFCTR);
00562
00563 rxFrameCount = rxftr >> MSB_POS;
00564 }
00565
00566
00569 void KSZ8851SNL_TxQueueReset(void)
00570 {
00571 uint16_t data;
00572
00573 data = KSZ8851SNL_SPI_ReadRegister(TXCR);
00574
00575 data &= ~TX_FLOW_CTRL_ENABLE;
00576 KSZ8851SNL_SPI_WriteRegister(TXCR, data);
00577
00578 data |= TX_FLOW_CTRL_FLUSH_QUEUE;
00579 KSZ8851SNL_SPI_WriteRegister(TXCR, data);
00580
00581 data &= ~TX_FLOW_CTRL_FLUSH_QUEUE;
00582 KSZ8851SNL_SPI_WriteRegister(TXCR, data);
00583
00584 data |= TX_FLOW_CTRL_ENABLE;
00585 KSZ8851SNL_SPI_WriteRegister(TXCR, data);
00586 }
00587
00588
00591 void KSZ8851SNL_RxQueueReset(void)
00592 {
00593 uint16_t data;
00594
00595 data = KSZ8851SNL_SPI_ReadRegister(RXCR1);
00596
00597 data &= ~RX_FLOW_CTRL_RX_ENABLE;
00598 KSZ8851SNL_SPI_WriteRegister(RXCR1, data);
00599
00600 KSZ8851SNL_SPI_WriteRegister(RXCR1, data);
00601
00602 data &= ~RX_FLOW_CTRL_FLUSH_QUEUE;
00603 KSZ8851SNL_SPI_WriteRegister(RXCR1, data);
00604
00605 data |= RX_FLOW_CTRL_RX_ENABLE;
00606 KSZ8851SNL_SPI_WriteRegister(RXCR1, data);
00607 }
00608
00609
00612 uint16_t KSZ8851SNL_FrameCounterGet(void)
00613 {
00614 return rxFrameCount;
00615 }
00616
00617
00620 void KSZ8851SNL_Init(void)
00621 {
00622 uint16_t data;
00623
00624
00625 KSZ8851SNL_SPI_Init();
00626
00627
00628 KSZ8851SNL_SPI_WriteRegister(PHYRR, PHY_RESET);
00629
00630
00631 data = KSZ8851SNL_SPI_ReadRegister(GRR);
00632 data &= ~GLOBAL_SOFT_RESET;
00633 KSZ8851SNL_SPI_WriteRegister(GRR, data);
00634
00635
00636 data = KSZ8851SNL_SPI_ReadRegister(GRR);
00637 data &= ~GLOBAL_SOFT_RESET;
00638 KSZ8851SNL_SPI_WriteRegister(GRR, data);
00639
00640
00641 data = KSZ8851SNL_SPI_ReadRegister(CIDER);
00642
00643
00644
00645
00646
00647
00648 EFM_ASSERT((data & CHIP_ID_MASK) == KSZ8851SNL_CHIP_ID);
00649
00650
00651 KSZ8851SNL_MacAddressGet(macAddress);
00652
00653 KSZ8851SNL_SPI_WriteRegister(MARH, (macAddress[0] << 8) | macAddress[1]);
00654 KSZ8851SNL_SPI_WriteRegister(MARM, (macAddress[2] << 8) | macAddress[3]);
00655 KSZ8851SNL_SPI_WriteRegister(MARL, (macAddress[4] << 8) | macAddress[5]);
00656
00657
00658 KSZ8851SNL_SPI_WriteRegister(TXFDPR, FD_PTR_AUTO_INC);
00659
00660
00661
00662
00663
00664
00665
00666 KSZ8851SNL_SPI_WriteRegister(TXCR, TX_FLOW_CTRL_CONFIG);
00667
00668
00669 KSZ8851SNL_SPI_WriteRegister(RXFDPR, FD_PTR_AUTO_INC);
00670
00671
00672 KSZ8851SNL_SPI_WriteRegister(RXFCTR, FRAME_COUNT_THRESHOLD);
00673
00674
00675
00676 data = 0xA00;
00677 KSZ8851SNL_SPI_WriteRegister(FCLWR, data);
00678
00679
00680
00681
00682
00683
00684
00685 KSZ8851SNL_SPI_WriteRegister(RXCR1, RX_FLOW_CTRL1_CONFIG);
00686
00687
00688
00689
00690
00691
00692 KSZ8851SNL_SPI_WriteRegister(RXCR2, RX_FLOW_CTRL2_CONFIG);
00693
00694
00695
00696
00697
00698
00699 KSZ8851SNL_SPI_WriteRegister(RXQCR, RXQ_CMD_CONFIG);
00700
00701
00702 KSZ8851SNL_SPI_WriteRegister(P1CR, PORT1_CONFIG | PORT1_AUTO_NEG_RESTART);
00703
00704
00705 KSZ8851SNL_SPI_WriteRegister(ISR, CLEAR_INT);
00706 }
00707
00708
00709
00712 void KSZ8851SNL_Enable(void)
00713 {
00714 uint16_t data;
00715
00716 KSZ8851SNL_SPI_WriteRegister(IER, KSZ8851SNL_INT_ENABLE_MASK);
00717
00718
00719 data = KSZ8851SNL_SPI_ReadRegister(TXCR);
00720 data |= TX_FLOW_CTRL_ENABLE;
00721 KSZ8851SNL_SPI_WriteRegister(TXCR, data);
00722
00723
00724 data = KSZ8851SNL_SPI_ReadRegister(RXCR1);
00725 data |= RX_FLOW_CTRL_RX_ENABLE;
00726 KSZ8851SNL_SPI_WriteRegister(RXCR1, data);
00727 }
00728
00729
00730
00737 bool KSZ8851SNL_TransmitBegin(uint16_t length)
00738 {
00739 uint16_t txmir;
00740 uint16_t data, reqSize;
00741 uint8_t outbuf[4];
00742
00743
00744 while (KSZ8851SNL_SPI_ReadRegister(TXQCR) & TXQ_ENQUEUE)
00745 {
00746 ;
00747 }
00748
00749
00750
00751
00752
00753
00754
00755
00756 reqSize = length + 12;
00757 txmir = KSZ8851SNL_SPI_ReadRegister(TXMIR) & TX_MEM_AVAIL_MASK;
00758 LWIP_DEBUGF(NETIF_DEBUG, ("KSZ8851SNL_LongTransmitInit: txmir =%hu reqSize = %hu \n", txmir, reqSize));
00759
00760 if (txmir < reqSize)
00761 {
00762
00763 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_LEVEL_WARNING, ("Not enough TXQ Memory, available=%u required=%u\n", txmir, reqSize));
00764 return false;
00765 }
00766
00767 LWIP_DEBUGF(NETIF_DEBUG, ("KSZ8851SNL_LongTransmitInit: Memory available > txmir =%hu reqSize = %hu \n", txmir, reqSize));
00768
00769 data = KSZ8851SNL_SPI_ReadRegister(RXQCR) | RXQ_START_DMA;
00770 KSZ8851SNL_SPI_WriteRegister(RXQCR, data);
00771
00772
00773 outbuf[0] = (frameId++ & FRAME_ID_MASK);
00774 outbuf[1] = 0x80;
00775 outbuf[2] = length & LSB_MASK;
00776 outbuf[3] = length >> MSB_POS;
00777
00778
00779 KSZ8851SNL_SPI_WriteFifoBegin();
00780 KSZ8851SNL_SPI_WriteFifo(4, outbuf);
00781
00782 return true;
00783 }
00784
00785
00786
00801 void KSZ8851SNL_Transmit(uint16_t length, const uint8_t *buffer)
00802 {
00803 EFM_ASSERT(buffer != NULL);
00804 KSZ8851SNL_SPI_WriteFifo(length, buffer);
00805 }
00806
00807
00819 void KSZ8851SNL_TransmitEnd(uint16_t length)
00820 {
00821 uint16_t data;
00822 uint16_t padding;
00823 uint8_t dummy[4] = {0x00};
00824
00825
00826 if (length % 4)
00827 {
00828 padding = 4 - (length % 4);
00829 KSZ8851SNL_SPI_WriteFifo(padding, dummy);
00830 }
00831
00832
00833 KSZ8851SNL_SPI_WriteFifoEnd();
00834
00835
00836 data = KSZ8851SNL_SPI_ReadRegister(RXQCR) & (~RXQ_START_DMA);
00837 KSZ8851SNL_SPI_WriteRegister(RXQCR, data);
00838
00839
00840 data = KSZ8851SNL_SPI_ReadRegister(TXQCR) | TXQ_ENQUEUE;
00841 KSZ8851SNL_SPI_WriteRegister(TXQCR, data);
00842 }
00843
00844
00848 static void ReleaseIncosistentFrame(void)
00849 {
00850 uint16_t data;
00851
00852 data = KSZ8851SNL_SPI_ReadRegister(RXQCR) | RXQ_RELEASE_ERROR_FRAME;
00853 KSZ8851SNL_SPI_WriteRegister(RXQCR, data);
00854
00855
00856 while (KSZ8851SNL_SPI_ReadRegister(RXQCR) & RXQ_RELEASE_ERROR_FRAME)
00857 {
00858 ;
00859 }
00860 }
00861
00862
00875 uint16_t KSZ8851SNL_Receive(uint16_t length, uint8_t *buffer)
00876 {
00877 uint16_t data;
00878 uint16_t rxStatus;
00879 uint16_t rxPacketLength;
00880 uint16_t frameLength;
00881 uint16_t bytesToRead;
00882
00883 EFM_ASSERT(buffer != NULL);
00884
00885 while (rxFrameCount > 0)
00886 {
00887 rxFrameCount--;
00888
00889 rxStatus = KSZ8851SNL_SPI_ReadRegister(RXFHSR);
00890
00891
00892 if ((!(rxStatus & VALID_FRAME_MASK)) || (rxStatus & CHECKSUM_VALID_FRAME_MASK))
00893 {
00894
00895 ReleaseIncosistentFrame();
00896
00897 continue;
00898 }
00899 else
00900 {
00901
00902 rxPacketLength = KSZ8851SNL_SPI_ReadRegister(RXFHBCR) & RX_BYTE_CNT_MASK;
00903
00904
00905 bytesToRead = 4 * ((rxPacketLength + 3) >> 2);
00906 LWIP_DEBUGF(NETIF_DEBUG, ("KSZ8851SNL_Receive: rxPacketLength=%u, bytesToRead=%u \n", rxPacketLength, bytesToRead));
00907 if ((bytesToRead > length) || (rxPacketLength <= 4))
00908 {
00909
00910 ReleaseIncosistentFrame();
00911
00912 continue;
00913 }
00914
00915
00916
00917
00918
00919 KSZ8851SNL_SPI_WriteRegister(RXFDPR, 0x0004 | FD_PTR_AUTO_INC);
00920
00921
00922 data = KSZ8851SNL_SPI_ReadRegister(RXQCR) | RXQ_START_DMA;
00923 KSZ8851SNL_SPI_WriteRegister(RXQCR, data);
00924
00925
00926 KSZ8851SNL_SPI_ReadFifo(bytesToRead, buffer);
00927
00928
00929 data = KSZ8851SNL_SPI_ReadRegister(RXQCR) & (~RXQ_START_DMA);
00930 KSZ8851SNL_SPI_WriteRegister(RXQCR, data);
00931
00932
00933 frameLength = rxPacketLength - 4;
00934 return frameLength;
00935 }
00936 }
00937 return 0;
00938 }
00939
00940
00950 void KSZ8851SNL_MacAddressGet(uint8_t *macAddress)
00951 {
00952 int i;
00953
00954 EFM_ASSERT(macAddress != NULL);
00955
00956
00957 macAddress[0] = HIGH_QMU_MAC_H;
00958 macAddress[1] = HIGH_QMU_MAC_L;
00959 macAddress[2] = MID_QMU_MAC_H;
00960
00961
00962 for (i = 0; i < 3; i++)
00963 {
00964 macAddress[5 - i] = (DEVINFO->UNIQUEL & (BYTE_MASK << i * BYTE_SIZE)) >> i * BYTE_SIZE;
00965 }
00966 }
00967
00968
00971 uint16_t KSZ8851SNL_PHYStatusGet(void)
00972 {
00973 return KSZ8851SNL_SPI_ReadRegister(P1SR);
00974 }