int devnet_xmit(uchar *dst, uchar proto, uchar *data, int nbytes, int whichifc) { int framesize; int n = 0, i; uchar *tptr; ulong ifc_shift_offset = (whichifc & 0xFFF) << 4; ulong savedSR; //@@printf("in devnet_xmit, sending [%d] bytes to [%s], proto [%d], via ifc [%d]\n", nbytes, dst, proto, whichifc); /* Save SR, then disable intrs: */ savedSR = getpsr(); splhi(); /* Save the dst for future use */ for (i = 0; i < 16; i++) { *(NIC_DST + ifc_shift_offset + i) = *(dst + i); } /* Write 16 byte src_addr */ for (i = 0; i < 16; i++) { *(NIC_TDR + ifc_shift_offset) = *(NIC_OUI + i); } n += 16; /* Write 16 byte dst_addr */ for (i = 0; i < 16; i++) { *(NIC_TDR + ifc_shift_offset) = *(dst + i); //printf("devnet_xmit(), *(dst+i) = [%d]\n", *(dst+i)); } n += 16; /* Write 4 byte payloadlen */ *(NIC_TDR + ifc_shift_offset) = (nbytes >> 24) & 0xFF; *(NIC_TDR + ifc_shift_offset) = (nbytes >> 16) & 0xFF; *(NIC_TDR + ifc_shift_offset) = (nbytes >> 8) & 0xFF; *(NIC_TDR + ifc_shift_offset) = (nbytes >> 0) & 0xFF; n += 4; /* Write 1 byte nexthdr */ *(NIC_TDR + ifc_shift_offset) = proto; n += 1; /* */ /* The 32 bit cksum added by hw */ /* is not counted as part of fsz */ /* */ framesize = devnet_getmaxfsz(whichifc); /* Write data */ tptr = data; for (i = 0; (i < nbytes) && (n < framesize); i++) { *(NIC_TDR + ifc_shift_offset) = *tptr++; n++; } /* if nbytes+header size was more than a frame, recurse */ if (nbytes + 16 + 16 + 4 + 1 > framesize) { printf( "Warning!!! devnet_xmit recursing: nbytes+header = %d, framesize = %d\n", nbytes + 16 + 16 + 4 + 1, framesize); devnet_xmit(dst, proto, tptr, nbytes - i, whichifc); } else while (n < framesize) { /* Send padding */ *(NIC_TDR + ifc_shift_offset) = 0; n++; } /* Restore SR */ spldone(savedSR); /* */ /* If frame could'nt be sent, LSB */ /* of NIC_NSR will be 1, return -1 */ /* */ return -((*(NIC_NSR + ifc_shift_offset)) & 0x1); }
//BUG: we curretnly make the mac layer pass in the length of the destination address, so we can support multiple // mac layers with different address sizes. Currently, the simulator maintains a 16+1 (NIC_ADDR_LEN) character // string format address. When the MAC layer probes the NIC_OUI, it currently gets a string, which is // fine for now, but we neeed to clean this implementation up int devmac_xmit(uchar *dst, int dstaddrlen, uchar *header, uchar *data, int headerlen, int nbytes, int whichifc) { int max_framesize; int n = 0, i; uchar frame_cksum[2]; ulong ifc_shift_offset = (whichifc & 0xFFF) << 4; ulong savedSR; //print("in devmac_xmit, sending [%d] bytes to [%s], proto [%d], via ifc [%d]\n", nbytes, dst, proto, whichifc); /* Save SR, then disable intrs: */ savedSR = getpsr(); splhi(); /* */ /* The 32 bit cksum added by hw */ /* is not counted as part of fsz */ /* */ max_framesize = devmac_getmaxfsz(whichifc); /* Save the dst for future use */ for (i = 0; i < min(16, dstaddrlen); i++) { *(NIC_DST+ifc_shift_offset+i) = dst[i]; } *(NIC_DST+ifc_shift_offset+i) = '\0'; /* Write MAC layer header */ for (i = 0; i < headerlen && (n < max_framesize); i++) { *(NIC_TDR+ifc_shift_offset) = header[i]; n++; } /* Write data */ for (i = 0; (i < nbytes) && (n < max_framesize); i++) { *(NIC_TDR+ifc_shift_offset) = data[i]; n++; } /* Write checksum */ devmac_cksum(header, data, headerlen, nbytes, &frame_cksum[0]); for (i = 0; i < 2; i++) { *(NIC_TDR+ifc_shift_offset) = frame_cksum[i]; n++; } /* */ /* The current frame size is calculated from */ /* number of bytes in the TDR at this point */ /* */ devmac_ctl(NIC_NCR_WRITE, NIC_CMD_TRANSMIT, whichifc); /* Restore SR */ spldone(savedSR); /* */ /* If frame could'nt be sent, LSB */ /* of NIC_NSR will be 1, return -1 */ /* */ return -((*(NIC_NSR+ifc_shift_offset)) & 0x1); }