Пример #1
0
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);
}