?? dm9000end.c
字號:
return (EINVAL);
bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->end),
END_HADDR_LEN(&pDrvCtrl->end));
break;
case EIOCGADDR:
DRV_LOG (DRV_DEBUG_LOAD, "EIOCGADDR", 1, 2, 3, 4, 5, 6);
if (data == NULL)
return (EINVAL);
bcopy ((char *)END_HADDR(&pDrvCtrl->end), (char *)data,
END_HADDR_LEN(&pDrvCtrl->end));
break;
case EIOCSFLAGS:
DRV_LOG (DRV_DEBUG_LOAD, "EIOCSFLAGS", 1, 2, 3, 4, 5, 6);
value = (long)data;
if (value < 0)
{
value = -(--value);
END_FLAGS_CLR (&pDrvCtrl->end, value);
}
else
{
END_FLAGS_SET (&pDrvCtrl->end, value);
}
dm9000Config (pDrvCtrl);
break;
case EIOCGFLAGS:
DRV_LOG (DRV_DEBUG_LOAD, "EIOCGFLAGS", 1, 2, 3, 4, 5, 6);
*(int *)data = END_FLAGS_GET(&pDrvCtrl->end);
break;
case EIOCPOLLSTART: /* Begin polled operation */
DRV_LOG (DRV_DEBUG_LOAD, "begin polled operation", 1, 2, 3, 4, 5, 6);
dm9000PollStart (pDrvCtrl);
break;
case EIOCPOLLSTOP: /* End polled operation */
DRV_LOG (DRV_DEBUG_LOAD, "end polled operation", 1, 2, 3, 4, 5, 6);
dm9000PollStop (pDrvCtrl);
break;
case EIOCGMIB2: /* return MIB information */
DRV_LOG (DRV_DEBUG_LOAD, "return MIB information", 1, 2, 3, 4, 5, 6);
if (data == NULL)
return (EINVAL);
bcopy((char *)&pDrvCtrl->end.mib2Tbl,
(char *)data,
sizeof(pDrvCtrl->end.mib2Tbl));
break;
case EIOCGFBUF: /* return minimum First Buffer for chaining */
DRV_LOG (DRV_DEBUG_LOAD, "return minimun first buffer for chaining", 1, 2, 3, 4, 5, 6);
if (data == NULL)
return (EINVAL);
*(int *)data = DM9000_MIN_FBUF;
break;
default:
DRV_LOG (DRV_DEBUG_LOAD, "error", 1, 2, 3, 4, 5, 6);
error = EINVAL;
}
return (error);
}
/******************************************************************************
*
* dm9000Mode - configure the interface mode
*
* mode:
* #define DM9000_10MHD 0x00
* #define DM9000_100MHD 0x01
* #define DM9000_10MFD 0x04
* #define DM9000_100MFD 0x05
* #define DM9000_AUTO 0x08
* #define DM9008A 0x10
* #define DM900xA_PECL 0x15
* RETURNS: N/A.
*/
void dm9000Mode( END_DEVICE *pDrvCtrl, int mode, int reset )
{
if( pDrvCtrl != 0 )
{
printf("pDrvCtrl->op_mode = %d\n",(int)(pDrvCtrl->op_mode) );
pDrvCtrl->op_mode = (UCHAR)mode;
printf("pDrvCtrl->op_mode = %d\n",(int)(pDrvCtrl->op_mode) );
if( reset != 0 )
{
dm9000Reset( pDrvCtrl );
dm9000Config( pDrvCtrl );
}
}
else
{
printf("DrvCtrl->op_mode = %d\n",(int)(DrvCtrl->op_mode) );
DrvCtrl->op_mode = (UCHAR)mode;
printf("DrvCtrl->op_mode = %d\n",(int)(DrvCtrl->op_mode) );
if( reset != 0 )
{
dm9000Reset( DrvCtrl );
dm9000Config( DrvCtrl );
}
}
}
/******************************************************************************
*
* dm9000Config - reconfigure the interface under us.
*
* Reconfigure the interface setting promiscuous mode, and changing the
* multicast interface list.
*
* RETURNS: N/A.
*/
static void dm9000Config( END_DEVICE *pDrvCtrl ) /* device to be re-configured */
{
/* Set promiscuous mode if it's asked for. */
DRV_LOG (DRV_DEBUG_LOAD, "dm9000Config()", 1, 2, 3, 4, 5, 6);
if (END_FLAGS_GET(&pDrvCtrl->end) & IFF_PROMISC)
{
DRV_LOG (DRV_DEBUG_IOCTL, "Setting promiscuous mode on!",
1, 2, 3, 4, 5, 6);
}
else
{
DRV_LOG (DRV_DEBUG_IOCTL, "Setting promiscuous mode off!",
1, 2, 3, 4, 5, 6);
}
/* Set up address filter for multicasting. */
if (END_MULTI_LST_CNT(&pDrvCtrl->end) > 0)
{
dm9000AddrFilterSet (pDrvCtrl);
dm9000_hash_table( pDrvCtrl );
}
/* TODO - shutdown device completely */
/* TODO - reset all device counters/pointers, etc. */
/* TODO - initialise the hardware according to flags */
dmfe_config_dm9000( pDrvCtrl, 2 );
DRV_LOG (DRV_DEBUG_LOAD, "dm9000Config() done", 1, 2, 3, 4, 5, 6);
return;
}
static void dm9000needreset( END_DEVICE *pDrvCtrl )
{
int oldv;
DRV_LOG (DRV_DEBUG_STATUS, "dm9000needreset()", 1, 2, 3, 4, 5, 6);
oldv = intLock();
pDrvCtrl->device_wait_reset = 0;
dm9000Reset( pDrvCtrl );
dm9000Config( pDrvCtrl );
intUnlock( oldv );
}
/******************************************************************************
*
* dm9000AddrFilterSet - set the address filter for multicast addresses
*
* This routine goes through all of the multicast addresses on the list
* of addresses (added with the endAddrAdd() routine) and sets the
* device's filter correctly.
*
* RETURNS: N/A.
*/
void dm9000AddrFilterSet( END_DEVICE *pDrvCtrl )
{
int i;
unsigned long crc;
unsigned long hash_table[4];
ETHER_MULTI* pCurr;
pDrvCtrl->mcastFilter[0] = 0;
pDrvCtrl->mcastFilter[1] = 0;
pDrvCtrl->mcastFilter[2] = 0;
pDrvCtrl->mcastFilter[3] = 0;
pDrvCtrl->mcastFilter[4] = 0;
pDrvCtrl->mcastFilter[5] = 0;
pDrvCtrl->mcastFilter[6] = 0;
pDrvCtrl->mcastFilter[7] = 0;
for(i=0;i<4;i++)hash_table[i]=0;
hash_table[3]=0x8000;
/* broadcast address */
/*pDrvCtrl->mcastFilter[7] = 0x80; */ /*mabe [6] */
/* the multicast address in Hash Table : 64 bits */
pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->end);
while (pCurr != NULL)
{
/* TODO - set up the multicast list */
crc = cal_CRC(((unsigned char *)&pCurr->addr), 6, 0 )&0x3f;
hash_table[crc/16] |= (unsigned short) 1 << (crc % 16);
pCurr = END_MULTI_LST_NEXT(pCurr);
}
pDrvCtrl->mcastFilter[0] |= hash_table[0]&0xff;
pDrvCtrl->mcastFilter[1] |= (hash_table[0]>>8)&0xff;
pDrvCtrl->mcastFilter[2] |= hash_table[1]&0xff;
pDrvCtrl->mcastFilter[3] |= (hash_table[1]>>8)&0xff;
pDrvCtrl->mcastFilter[4] |= hash_table[2]&0xff;
pDrvCtrl->mcastFilter[5] |= (hash_table[2]>>8)&0xff;
pDrvCtrl->mcastFilter[6] |= hash_table[3]&0xff;
pDrvCtrl->mcastFilter[7] |= (hash_table[3]>>8)&0xff;
}
/*******************************************************************************
*
* dm9000PollRcv - routine to receive a packet in polled mode.
*
* This routine is called by a user to try and get a packet from the
* device.
*
* RETURNS: OK upon success. EAGAIN is returned when no packet is available.
*/
static STATUS dm9000PollRcv( END_DEVICE *pDrvCtrl, /* device to be polled */
M_BLK_ID pMblk ) /* ptr to buffer */
{
u_short stat;
char* pPacket;
int len;
PKT skb;
DRV_LOG (DRV_DEBUG_POLL_RX, "dm9000PollRcv", 1, 2, 3, 4, 5, 6);
stat = dm9000StatusRead (pDrvCtrl);
/* TODO - If no packet is available return immediately */
if( !(stat&DM9000_RXRDY) )
{
DRV_LOG (DRV_DEBUG_POLL_RX, "dm9000PollRcv no data", 1,
2, 3, 4, 5, 6);
return (EAGAIN);
}
pPacket = NULL; /* DUMMY CODE */
len = 64; /* DUMMY CODE */
/* Upper layer must provide a valid buffer. */
if ((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT)))
{
DRV_LOG (DRV_DEBUG_POLL_RX, "PRX bad mblk", 1, 2, 3, 4, 5, 6);
return (EAGAIN);
}
/* TODO - clear any status bits that may be set. */
/* TODO - Check packet and device for errors */
END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);
/* TODO - Process device packet into net buffer */
skb.len = 0;
skb.pData = pMblk->m_data;
if( dmfe_packet_receive( &skb, pDrvCtrl ) )
{
DRV_LOG (DRV_DEBUG_POLL_RX, "packet receive FAIL", 1, 2, 3, 4, 5, 6);
return (EAGAIN);
}
/* bcopy (pPacket, pMblk->m_data, len); */
pMblk->mBlkHdr.mFlags |= M_PKTHDR; /* set the packet header */
pMblk->mBlkHdr.mLen = len; /* set the data len */
pMblk->mBlkPktHdr.len = len; /* set the total len */
/* TODO - Done with packet, clean up and give it to the device. */
DRV_LOG (DRV_DEBUG_POLL_RX, "dm9000PollRcv OK", 1, 2, 3, 4, 5, 6);
DRV_LOG (DRV_DEBUG_POLL_RX, "dm9000PollRcv OK", 1, 2, 3, 4, 5, 6);
return (OK);
}
/*******************************************************************************
*
* dm9000PollSend - routine to send a packet in polled mode.
*
* This routine is called by a user to try and send a packet on the
* device.
*
* RETURNS: OK upon success. EAGAIN if device is busy.
*/
static STATUS dm9000PollSend( END_DEVICE *pDrvCtrl, /* device to be polled */
M_BLK_ID pMblk ) /* packet to send */
{
int len;
u_short stat;
PKT skb;
int oldv;
DRV_LOG (DRV_DEBUG_POLL_TX, "dm9000PollSend", 1, 2, 3, 4, 5, 6);
/* TODO - test to see if tx is busy */
stat = dm9000StatusRead (pDrvCtrl); /* dummy code */
if ((stat & (DM9000_TINT|DM9000_TFULL)) == 0)
return ((STATUS) EAGAIN);
/* TODO - Process the net buffer into a device transmit packet */
/* TODO - transmit packet */
len = netMblkToBufCopy (pMblk, (char*)(pDrvCtrl->txBuf), NULL);
len = max (len, ETHERSMALL);
skb.len = len;
skb.pData = (char*)pDrvCtrl->txBuf;
oldv = intLock();
dmfe_start_xmit( &skb, pDrvCtrl );
intUnlock( oldv );
/* Bump the statistic counter. */
END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);
/* Free the data if it was accepted by device */
netMblkClFree (pMblk);
DRV_LOG (DRV_DEBUG_POLL_TX, "leaving dm9000PollSend", 1, 2, 3, 4, 5, 6);
return (OK);
}
/*****************************************************************************
*
* dm9000MCastAdd - add a multicast address for the device
*
* This routine adds a multicast address to whatever the driver
* is already listening for. It then resets the address filter.
*
* RETURNS: OK or ERROR.
*/
static STATUS dm9000MCastAdd( END_DEVICE *pDrvCtrl, /* device pointer */
char* pAddress ) /* new address to add */
{
int error;
int oldv=intLock();
DRV_LOG (DRV_DEBUG_LOAD, "dm9000MCastAdd()", 1, 2, 3, 4, 5, 6);
if (etherMultiAdd (&pDrvCtrl->end.multiList,
pAddress) == ENETRESET)
{
dm9000AddrFilterSet (pDrvCtrl);
dm9000_hash_table( pDrvCtrl );
}
intUnlock(oldv);
return (OK);
}
/*****************************************************************************
*
* dm9000MCastDel - delete a multicast address for the device
*
* This routine removes a multicast address from whatever the driver
* is listening for. It then resets the address filter.
*
* RETURNS: OK or ERROR.
*/
static STATUS dm9000MCastDel( END_DEVICE *pDrvCtrl, /* device pointer */
char *pAddress ) /* address to be deleted */
{
int error;
int oldv=intLock();
DRV_LOG (DRV_DEBUG_LOAD, "dm9000MCastDel()", 1, 2, 3, 4, 5, 6);
if (etherMultiDel (&pDrvCtrl->end.multiList,
(char *)pAddress) == ENETRESET)
{
dm9000AddrFilterSet (pDrvCtrl);
dm9000_hash_table( pDrvCtrl );
}
intUnlock(oldv);
return (OK);
}
/*****************************************************************************
*
* dm9000MCastGet - get the multicast address list for the device
*
* This routine gets the multicast list of whatever the driver
* is already listening for.
*
* RETURNS: OK or ERROR.
*/
static STATUS dm9000MCastGet( END_DEVICE *pDrvCtrl, /* device pointer */
MULTI_TABLE *pTable ) /* address table to be filled in */
{
DRV_LOG (DRV_DEBUG_LOAD, "dm9000MCastGet()", 1, 2, 3, 4, 5, 6);
return (etherMultiGet (&pDrvCtrl->end.multiList, pTable));
}
/*******************************************************************************
*
* dm9000Stop - stop the device
*
* This function calls BSP functions to disconnect interrupts and stop
* the device from operating in interrupt mode.
*
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -