void usb_cdc_ecm_rx(uint8_t ep, uint8_t stat) { int len; int ip_length; int i; uint16_t eth_hdr_type; //printf("cdc ecm rx ep-state=%x state=%d transferred=%d",stat,rndisRxState,rndisRxTransferCount); switch (rndisRxState) { case RNDIS_RX_IDLE: rndisRxTransferCount = 0; rndisRxPacketSize = 0; /* it may increase later */ /* hopefully, it follows the header immediately... */ if (receive_packet == 0) { if (RING_IS_FULL(receive_ring_head, receive_ring_tail, RECEIVE_RING_SIZE)) { rndisRxState = RNDIS_RX_DROP; DBG("usb_eth_rx: receive ring is full, head=%d, tail=%d",receive_ring_head, receive_ring_tail); len = usbRead(ep, NULL, 64); } else { rndisRxState = RNDIS_RX_RECV; receive_packet = &receive_ring[receive_ring_tail]; packet_init(receive_packet); len = usbRead(ep, receive_packet->data , 64); rndisRxTransferCount += len; } } break; case RNDIS_RX_DROP: len = usbRead(ep, NULL, 64); //ETH_DEV_DBG_INFO("rndis rx read %d bytes more in drop state",len); if (len >= 0) rndisRxTransferCount += len; break; case RNDIS_RX_RECV: len = usbRead(ep, (receive_packet->data) + rndisRxTransferCount, 64 /* maybe we need to limit this */); if (len >= 0) rndisRxTransferCount += len; break; } if (len < 64) { /* a short packet terminates the Ethernet frame */ rndisRxPackets++; DBG("cdc ecm rx done with a packet (%d bytes)",rndisRxTransferCount); //for (i=0; i<rndisRxPacketSize; i++) DBG("%d %02x",i,(receive_packet->data)[i]); //if (rndisRxPacketSize==54) while(1); if (rndisRxState == RNDIS_RX_RECV) { receive_packet->size = rndisRxTransferCount; receive_packet = 0; RING_INC(receive_ring_tail, RECEIVE_RING_SIZE); } rndisRxState = RNDIS_RX_IDLE; } }
void usb_eth_rx(uint8_t ep, uint8_t stat) { int len; int ip_length; uint16_t eth_hdr_type; if (receive_packet == 0) { if (RING_IS_FULL(receive_ring_head, receive_ring_tail, RECEIVE_RING_SIZE)) { ETH_DEV_DBG_ERROR("usb_eth_rx: receive ring is full, head=%d, tail=%d", receive_ring_head, receive_ring_tail); return; } receive_packet = &receive_ring[receive_ring_tail]; packet_init(receive_packet); } if (receive_packet->transferred < PACKET_SIZE) { len = usbRead(ep, &receive_packet->data[0] + receive_packet->transferred, PACKET_SIZE - receive_packet->transferred); } else { /* discard the bytes */ len = usbRead(ep, 0, 0); } receive_packet->transferred += len; ETH_DEV_DBG_INFO("usb_eth_rx: read %d bytes, head=%d, tail=%d", len, receive_ring_head, receive_ring_tail); if (receive_packet->transferred < UIP_LLH_LEN) { /* ethernet header was not received yet got some garbage which we need to ignore */ ETH_DEV_DBG_ERROR("got part of packet with %d bytes", receive_packet->transferred); receive_packet->transferred = 0; return; } if (receive_packet->size == 0) { eth_hdr_type = (receive_packet->data[0xc] << 8) | receive_packet->data[0xd]; if (eth_hdr_type == UIP_ETHTYPE_IP) { ip_length = receive_packet->data[0x10]*0xff + receive_packet->data[0x11]; receive_packet->size = ip_length + UIP_LLH_LEN; } else if (eth_hdr_type == UIP_ETHTYPE_ARP) { receive_packet->size = receive_packet->transferred; } else { ETH_DEV_DBG_ERROR("Unknown ethernet frame 0x%x", eth_hdr_type); receive_packet->size = receive_packet->transferred; } } if (receive_packet->transferred >= receive_packet->size) { if (receive_packet->transferred >= receive_packet->size) { if (receive_packet->transferred >= PACKET_SIZE) { ETH_DEV_DBG_ERROR("Discarding packet of size %d", receive_packet->transferred); packet_init(receive_packet); receive_packet = 0; } else { ETH_DEV_DBG_INFO("Received packet of size %d", receive_packet->transferred); receive_packet = 0; RING_INC(receive_ring_tail, RECEIVE_RING_SIZE); } } } }
void usb_rndis_rx(uint8_t ep, uint8_t stat) { int len; int ip_length; int i; uint16_t eth_hdr_type; if (!(stat & EP_STATUS_DATA)) { ETH_DEV_DBG_ERROR("rndis rx, no data..."); return; } //DBG("rndis rx ep-state=%x state=%d packetsize=%d transferred=%d",stat,rndisRxState,rndisRxPacketSize,rndisRxTransferCount); switch (rndisRxState) { case RNDIS_RX_IDLE: //if (rndisRxState == RNDIS_RX_IDLE) { len = usbRead(ep, rndisPacketHeader, 64); if (len==1 && rndisPacketHeader[0] == 0) { DBG("single byte USB packet (this is normal for rndis"); return; } if (len < 44) { ETH_DEV_DBG_ERROR("Whoops, USB packet length shorter than RNDIS message header (only %d bytes)",len); return; } uint32_t type = uint32FromLittleEndian(rndisPacketHeader); uint32_t rndislen = uint32FromLittleEndian(rndisPacketHeader+4); uint32_t dataoff = uint32FromLittleEndian(rndisPacketHeader+8); uint32_t datalen = uint32FromLittleEndian(rndisPacketHeader+12); uint32_t ooboff = uint32FromLittleEndian(rndisPacketHeader+16); uint32_t ooblen = uint32FromLittleEndian(rndisPacketHeader+20); uint32_t numoob = uint32FromLittleEndian(rndisPacketHeader+24); uint32_t perpacket_infooff = uint32FromLittleEndian(rndisPacketHeader+28); uint32_t perpacket_infolen = uint32FromLittleEndian(rndisPacketHeader+32); //DBG("rndis rx type=%x len=%d dataoff=%d datalen=%d ooblen=%d numoob=%d perpacket_infooff=%d perpacket_infolen=%d", // type,len,dataoff,datalen,ooblen,numoob,perpacket_infooff,perpacket_infolen); if (type != 1) while(1); rndisRxTransferCount = 0; rndisRxPacketSize = datalen; /* hopefully, it follows the header immediately... */ if (receive_packet == 0) { if (RING_IS_FULL(receive_ring_head, receive_ring_tail, RECEIVE_RING_SIZE)) { DBG("usb_eth_rx: receive ring is full, head=%d, tail=%d",receive_ring_head, receive_ring_tail); rndisRxState = RNDIS_RX_DROP; for (i=0; i<(len-44); i++) { rndisRxTransferCount++; } } else { rndisRxState = RNDIS_RX_RECV; receive_packet = &receive_ring[receive_ring_tail]; packet_init(receive_packet); for (i=0; i<(len-44); i++) { (receive_packet->data)[ rndisRxTransferCount ] = rndisPacketHeader[44+i]; rndisRxTransferCount++; } } } break; case RNDIS_RX_DROP: //if (rndisRxState == RNDIS_RX_DROP) { len = usbRead(ep, NULL, rndisRxPacketSize - rndisRxTransferCount); //ETH_DEV_DBG_INFO("rndis rx read %d bytes more in drop state",len); if (len >= 0) rndisRxTransferCount += len; break; // } case RNDIS_RX_RECV: //if (rndisRxState == RNDIS_RX_RECV) { //DBG("rndis rx recv read from endpoint"); len = usbRead(ep, (receive_packet->data) + rndisRxTransferCount, rndisRxPacketSize - rndisRxTransferCount); //DBG("rndis rx read %d bytes more in recv state",len); if (len >= 0) rndisRxTransferCount += len; break; } if (rndisRxTransferCount == rndisRxPacketSize) { rndisRxPackets++; DBG("rndis rx done with a packet (%d bytes)",rndisRxPacketSize); //for (i=0; i<rndisRxPacketSize; i++) DBG("%d %02x",i,(receive_packet->data)[i]); //if (rndisRxPacketSize==54) while(1); if (rndisRxState == RNDIS_RX_RECV) { receive_packet->size = rndisRxPacketSize; receive_packet = 0; RING_INC(receive_ring_tail, RECEIVE_RING_SIZE); xxx = 1; } rndisRxState = RNDIS_RX_IDLE; } }