?? ether_cs8900.c~
字號(hào):
unsigned i = 0;//util_printf("the reg INTCNTRL is 0x%X\n", readreg(INTCNTRL));//util_printf("the reg RECVCONF is 0x%X\n", readreg(RECVCONF));//util_printf("the reg RECVCNTRL is 0x%X\n", readreg(RECVCNTRL)); i=readreg(PP_ChipID);if (i != CHIP_EISA_ID_SIG) { util_printf("cs89x0.c: No CrystalLan device found. 0x%X\n", i); return; } else{ util_printf("The ID of CS8900 is 0x%X\n", i); }//util_printf("The PRODUCT_ID_ADD of CS8900 is 0x%X\n", readreg(PRODUCT_ID_ADD));util_printf("The PP_SelfST of CS8900 is 0x%X\n", readreg(PP_SelfST));util_printf("The PP_SelfCTL of CS8900 is 0x%X\n", readreg(PP_SelfCTL));util_printf("The PP_LineCTL of CS8900 is 0x%X\n", readreg(PP_LineCTL));util_printf("The PP_LineST of CS8900 is 0x%X\n", readreg(PP_LineST));util_printf("The PP_BusST of CS8900 is 0x%X\n", readreg(PP_BusST));util_printf("The PP_TxEvent of CS8900 is 0x%X\n", readreg(PP_TxEvent));util_printf("The PP_RxMiss of CS8900 is 0x%X\n", readreg(PP_RxMiss));util_printf("The PP_TxCol of CS8900 is 0x%X\n", readreg(PP_TxCol));#ifdef BSPCONF_BTLDR_CS8900_DEBUG last_readreg_addr=0; last_readreg_data=0;#endif writereg(LINECNTRL,0x0000); // go offline writereg(SELFCNTRL,0x0055); // reset. while (!(readreg(SELFSTATUS)&0x0080)) { ; //wait }}/****************************** Routine: Description: ******************************/static void chip_mac_assign(unsigned char *mac_array){ short s; s = mac_array[0] | (mac_array[1] << 8); writereg(MACREG1,s); s = mac_array[2] | (mac_array[3] << 8); writereg(MACREG2,s); s = mac_array[4] | (mac_array[5] << 8); writereg(MACREG3,s);}/****************************** Routine: Description: Polls the chip until a chip packet is recieved containing an ether frame and then xfers the data field portion of the received ether frame to the client's supplied datagram buffer and then sets the client's num_bytes variable appropriately. ******************************/static void chip_read_data_polled(void *datagram, // in/out unsigned short *num_bytes) // in/out{ #define RxOK 0x0100 #define RxBROADCAST 0x0800 unsigned short i; unsigned short RxStatus, RxLength; while (1) { while (1) { // loop here until the bit goes high indicating // that the chip has a non broadcast incoming packet for us. i=readreg(RECVEVENT); if ((i & RxOK) && ! (i & RxBROADCAST)) { break; } }#ifdef BSPCONF_BTLDR_CS8900_DEBUG util_printf("received a packet \n");#endif // Next, repeatively read from the receive port to // pick up the packet; the packet is actually proceeded // by a status word and a length word, the same two // words that would also be returned from a readreg(RXSTATUS) // and readreg(RXLENGTH), but we might as well get them this // way instead: RxStatus = inw(RECVPORT); RxLength = inw(RECVPORT); if (RxStatus & 0x7080) { // Error: Either the Extradata, Runt, CRCerror, or Dribble bit was set. // Ignore this packet and loop back around to pick up another. } else { // --Normal Path-- // First read out the ether header that proceeds the frame data field. We'll // temporarily put this in the client's buffer and then immediately overwrite // it with the frame data field that we really want to deliver to the client. insw(RECVPORT, (unsigned short *)datagram, (sizeof(ether_hdr_t)>>1)); if (RxLength > sizeof(ether_hdr_t)) { // sanity check // --Normal Path-- RxLength -= sizeof(ether_hdr_t); // adjust length to reflect data field only. // Now load the client's buffer with the frame's data field. insw(RECVPORT, (unsigned short *)datagram, RxLength>>1); if (RxLength & 1) { // Odd length; get that last byte. ((unsigned char *)datagram)[RxLength-1] = (unsigned char)inw(RECVPORT); } *num_bytes = RxLength;#ifdef BSPCONF_BTLDR_CS8900_DEBUG util_dump_memory((unsigned int) datagram, RxLength);#endif break; // return to client } } }}/****************************** Routine: Description: Package up the client's datagram into an Ether frame which is then loaded into the chip for transmission on the physical wire. Note: wire collisions are handled by the chip itself. ******************************/static void chip_send_data(submit_mode mode, // in char *device_MAC, // in char *server_MAC, // in void *datagram, // in/out unsigned short *num_bytes) // in/out{ #define TxMask 0x87C0 // All error bits plus the TkOK bit. #define TxErrMask 0x84C0 // All error bits minus the TkOK bit. #define TX_AFTER_381 0x0040 #define TX_AFTER_ALL 0x00C0 #define RDY_FOR_TX_NOW 0x0100 ether_hdr_t *ethdatagram; unsigned short ethfrm_len, *data, status; unsigned char d_MAC[6], s_MAC[6]; int i; while (1) { util_fill_MAC(d_MAC,device_MAC); util_fill_MAC(s_MAC,server_MAC); // Add the eth header. // Recall that the client has provided the space for us to // back the pointer up like this and add our header. ethdatagram = (ether_hdr_t *)(datagram - sizeof(ether_hdr_t)); // Next, build the ether frame header. // Notice that our header does not include the 8 byte preamble // of alternating 1s and 0s since the chip will provide those // bits automatically as part of interfacing with the wire. // chip also does the crc generation for us and appends it to // tail end of our data as it heads out the wire. for (i=0; i<6; i++) { ethdatagram->dest_addr[i] = s_MAC[i]; ethdatagram->src_addr[i] = d_MAC[i]; } ethdatagram->frame_type = 0x0000; // IP code as per /etc/protocols // Hmmm???? // well 0x0000 is what I thought it should be anyways, but as I // trace other packets moving about the network I see that they // use the value 0x8000 although I don't understand the signifcance // of that just yet. In the meantime it does seem to work beter // to use that value. so... override previous setting now... ethdatagram->frame_type = htons(0x0800); // override, see comment above. ethfrm_len = *num_bytes + sizeof(ether_hdr_t); if (ethfrm_len < 61) { // *debug*, Get to the bottom of this one. // Special case, at the moment I can't get the chip to send // out ether packets smaller than this minimum amount. If it // drops below it then pad it and assume that the destination // server will just ignore the extra bytes. I happen to know // that Tftp servers do, for example. ethfrm_len = 61; } data = (unsigned short *)ethdatagram; // Initiate the Transmit#ifdef BSPCONF_BTLDR_CS8900_DEBUG util_printf("sending a packet \n"); util_printf("buffer = 0x%X, len = 0x%x\n",data,ethfrm_len); // *revisit-skranz* temp only. util_printf("sizeof ether_hdr_t = 0x%x\n",sizeof(ether_hdr_t)); // *revisit-skranz* temp only. util_printf("sizeof ip_hdr_t = 0x%x\n",sizeof(ip_hdr_t)); // *revisit-skranz* temp only. util_printf("sizeof udp_hdr_t = 0x%x\n",sizeof(udp_hdr_t)); // *revisit-skranz* temp only.#endif status = readreg(XMITEVENT); // clear any existing xmit status bits before starting new xmit. outw(TXCMDPORT,TX_AFTER_381); outw(TXLENPORT,ethfrm_len); while (0 == (readreg(BUSSTATUS) & RDY_FOR_TX_NOW)) { // Wait here until the chip performs the internal chip // mem allocation needed to hold our ether frame packet. }#ifdef BSPCONF_BTLDR_CS8900_DEBUG util_dump_memory((unsigned int) data, ethfrm_len);#endif // on the wire she goes.... outsw(XMITPORT,data,(ethfrm_len+1)>>1); status = readreg(XMITEVENT); // read new xmit status bits. while (0 == (status & TxMask)) { // Wait here until the chip performs the transmission. // When complete, or if aborted, then at least one bit // in TxMask set will go high. status = readreg(XMITEVENT); // read new xmit status bits. } if (0 == (status & TxErrMask)) { // It had completed without an error bits being set. // We won't have to resend our packet. The only bit that // must have been set is the TkOK; good. break; }#ifdef BSPCONF_BTLDR_CS8900_DEBUG util_printf("Bad xmit attempting; status = 0x%x; retrying... \n",status);#endif }}/****************************** Routine: Description: See ether.h for more info. ******************************/void ether_init(void){ chip_reset(); // TF 030630 - removed so chip isn't touched until // TFTP is used (which causes chip_reset to be called)}/****************************** Routine: Description: See ether.h for more info. ******************************/void ether_submit(submit_mode mode, // in char *device_MAC, // in char *server_MAC, // in void *datagram, // in/out unsigned short *num_bytes) // in/out{ // --Stage one-- switch(mode) { case SEND: case SEND_AND_GET_REPLY: chip_send_data(mode, // in device_MAC, // in server_MAC, // in datagram, // in num_bytes); // in break; case RECV: // See "Stage two" below. break; case FLUSH: { unsigned char d_MAC[6]; util_fill_MAC(d_MAC,device_MAC); chip_reset(); chip_mac_assign(d_MAC); chip_online(); } break; default: SYSTEM_FATAL("Logic Error"); break; } // --Stage two-- switch(mode) { case RECV: case SEND_AND_GET_REPLY: chip_read_data_polled(datagram, // out num_bytes); // out break; default: break; }}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -