📄 lan91c111.c
字号:
/* Change the Enqueued head */
dev->m_TxEnqueuedHead = (ADI_ETHER_BUFFER*)tmp_q_ele->pNext;
dev->m_TxEnqueuedCount--;
if (dev->m_TxEnqueuedCount == 0)
{
dev->m_TxEnqueuedTail = NULL;
cont = 0;
}
/* Add the packet to dequeued list*/
if (dev->m_TxDequeuedCount)
dev->m_TxDequeuedTail->pNext = (ADI_ETHER_BUFFER*)tmp_q_ele;
else
dev->m_TxDequeuedHead = tmp_q_ele;
//No matter what this is also the tail.
dev->m_TxDequeuedTail = tmp_q_ele;
//And tail->next should point to NULL
tmp_q_ele->pNext = NULL;
dev->m_TxDequeuedCount++;
}
}
}
if (dev->DCBHandle != NULL) {
result = adi_dcb_Post(dev->DCBHandle,ik_ivg13,dev->DMCallback,dev->DeviceHandle,ADI_ETHER_EVENT_FRAME_XMIT,dev->m_TxDequeuedHead->CallbackParameter);
} else {
(dev->DMCallback)(dev->DeviceHandle,ADI_ETHER_EVENT_FRAME_XMIT,dev->m_TxDequeuedHead->CallbackParameter);
result = ADI_DCB_RESULT_SUCCESS;
}
//if (result == ADI_DCB_RESULT_SUCCESS) {
//## what happens if a packet is trasnmitted while in the callback
dev->m_TxDequeuedHead = NULL;
dev->m_TxDequeuedTail = NULL;
dev->m_TxDequeuedCount = 0;
//}
EXIT_CRTICIAL_REGION();
return mr;
}
/******************************************************************************
* Get MAC address in the SMSC
*****************************************************************************/
static void GetMacAddr(unsigned char *mac_addr)
{
volatile unsigned short addr;
volatile unsigned short page;
page = _inpw(BSR_REG);
_outpw(BSR_REG, 1);
addr = _inpw(ADDR0_REG); // get MAC addr
mac_addr[0] = addr & 0xFF;
mac_addr[1] = addr >> 8;
addr = _inpw(ADDR1_REG); // get MAC addr
mac_addr[2] = addr & 0xFF;
mac_addr[3] = addr >> 8;
addr = _inpw(ADDR2_REG); // get MAC addr
mac_addr[4] = addr & 0xFF;
mac_addr[5] = addr >> 8;
_outpw(BSR_REG, page);
return;
}
/******************************************************************************
* Set MAC address in the SMSC
*****************************************************************************/
static void SetupMacAddr(unsigned char *mac_addr)
{
unsigned short page;
short wtmp;
// save old page
page = _inpw(BSR_REG);
// select bank 1
_outpw(BSR_REG, 1);
// Set EEPROM Store
_outpw(CTL_REG,CTL_EEPROM_SELECT | CTL_STORE);
wtmp = (((mac_addr[1])<<8)|(mac_addr[0]));
_outpw(ADDR0_REG, wtmp);
wtmp = (((mac_addr[3])<<8)|(mac_addr[2]));
_outpw(ADDR1_REG, wtmp);
wtmp = (((mac_addr[5])<<8)|(mac_addr[4]));
_outpw(ADDR2_REG, wtmp);
// restore bank
_outpw(BSR_REG, page);
return;
}
/******************************************************************************
*
* Configures the PF/IMASK/IAR settings associated with the driver.
*
*****************************************************************************/
static int SetDevicePFConfig(ADI_ETHER_LAN91C111_DATA *dev)
{
unsigned int iar2_mask;
*pEBIU_AMGCTL = 0xF;
// Init EBIU
if ((*pEBIU_SDSTAT & 0x8))
{
*pEBIU_SDRRC = 0x397;
*pEBIU_SDBCTL = 0x13;
*pEBIU_SDGCTL = 0x8011998D;
}
// Default PF configuration is PF9
//
if(dev->pf == 0)
dev->pf = PF9;
csync();
ssync();
// Clear off any pending interrupts
*pFIO_DIR = 0x0;
*pFIO_POLAR = 0x0;
*pFIO_MASKB_C = dev->pf;
ssync();
*pFIO_MASKB_S = dev->pf;
*pFIO_INEN = dev->pf;
return 1;
}
/*********************************************************************
*
* Function: pddOpen
*
* Description: Opens the Network Driver and does initialization.
*
*********************************************************************/
static u32 adi_pdd_Open( // Open a device
ADI_DEV_MANAGER_HANDLE ManagerHandle, // device manager handle
u32 DeviceNumber, // device number
ADI_DEV_DEVICE_HANDLE DeviceHandle, // device handle
ADI_DEV_PDD_HANDLE *pPDDHandle, // pointer to PDD handle location
ADI_DEV_DIRECTION Direction, // data direction
void *pCriticalRegionArg, // critical region imask storage location
ADI_DMA_MANAGER_HANDLE DMAHandle, // handle to the DMA manager
ADI_DCB_HANDLE DCBHandle, // callback handle
ADI_DCB_CALLBACK_FN DMCallback // device manager callback function
)
{
u32 Result; // return value
void *CriticalResult;
ADI_ETHER_LAN91C111_DATA *dev= &EtherDev;
// check for errors if required
#ifdef ADI_ETHER_ERROR_CHECKING_ENABLED
if (DeviceNumber > 0) { // check the device number
return (ADI_DEV_RESULT_BAD_DEVICE_NUMBER);
}
#endif
// insure the device the client wants is available
Result = ADI_DEV_RESULT_DEVICE_IN_USE;
//CriticalResult = adi_int_EnterCriticalRegion(pCriticalRegionArg);
// Open the device
if(!dev->Open)
{
// initialize the device settings
memset(dev,0,sizeof(ADI_ETHER_LAN91C111_DATA));
dev->CriticalData = pCriticalRegionArg;
dev->DeviceHandle = DeviceHandle;
dev->DCBHandle = DCBHandle;
dev->DMCallback = DMCallback;
dev->Direction = Direction;
dev->Started = false;
// default ivg levels
dev->RXIVG = ik_ivg8;
dev->TXIVG = ik_ivg8;
dev->ERRIVG = ik_ivg8;
//set PF configuration
SetDevicePFConfig(dev);
dev->Open = true;
Result = ADI_DEV_RESULT_SUCCESS;
}
// exit critical region
//
//adi_int_ExitCriticalRegion(CriticalResult);
if (Result != ADI_DEV_RESULT_SUCCESS) return (Result);
*pPDDHandle = (ADI_DEV_PDD_HANDLE *)&EtherDev;
return(ADI_DEV_RESULT_SUCCESS);
}
/*********************************************************************
*
* Function: pddRead
*
* Description: Gives list of read buffers to the driver
*
*********************************************************************/
static u32 adi_pdd_Read( // Reads data or queues an inbound buffer to a device
ADI_DEV_PDD_HANDLE PDDHandle, // PDD handle
ADI_DEV_BUFFER_TYPE BufferType, // buffer type
ADI_DEV_BUFFER *pBuffer // pointer to buffer
)
{
u32 Result; // return value
ADI_ETHER_LAN91C111_DATA *dev = (ADI_ETHER_LAN91C111_DATA *)PDDHandle;
// check for errors if required
#if defined(ADI_ETHER_DEBUG)
if ((Result = ValidatePDDHandle(PDDHandle)) != ADI_DEV_RESULT_SUCCESS) return (Result);
if (BufferType != DEV_1D) {
return (ADI_DEV_BUFFER_TYPE_INCOMPATIBLE);
}
#endif
QueueNewRcvFrames((void*)PDDHandle,(ADI_ETHER_BUFFER*)pBuffer);
return(ADI_DEV_RESULT_SUCCESS);
}
/*********************************************************************
*
* Function: pddClose
*
* Description: Closes the driver and releases any memory
*
*********************************************************************/
static u32 adi_pdd_Close( // Closes a device
ADI_DEV_PDD_HANDLE PDDHandle // PDD handle
)
{
ADI_ETHER_LAN91C111_DATA *dev = (ADI_ETHER_LAN91C111_DATA *)PDDHandle;
u32 Result = ADI_DEV_RESULT_SUCCESS; // return value
bool active=true;
// check for errors if required
#if defined(ADI_ETHER_DEBUG)
if ((Result = ValidatePDDHandle(PDDHandle)) != ADI_DEV_RESULT_SUCCESS) return (Result);
#endif
dev->Closing = true;
dev->Open = false;
if (dev->Started) {
dev->Started = false;
// wait for the current frames to complete
}
// return
return(Result);
}
/*********************************************************************
*
* Function: pddWrite
*
* Description: Sends packet over the physical channel
*
*********************************************************************/
static u32 adi_pdd_Write( // Writes data or queues an outbound buffer to a device
ADI_DEV_PDD_HANDLE PDDHandle, // PDD handle
ADI_DEV_BUFFER_TYPE BufferType, // buffer type
ADI_DEV_BUFFER *pBuffer // pointer to buffer
)
{
u32 Result; // return value
ADI_ETHER_LAN91C111_DATA *dev = (ADI_ETHER_LAN91C111_DATA *)PDDHandle;
// check for errors if required
#if defined(ADI_ETHER_DEBUG)
if ((Result = ValidatePDDHandle(PDDHandle)) != ADI_DEV_RESULT_SUCCESS) return (Result);
if (BufferType != DEV_1D) {
return (ADI_DEV_BUFFER_TYPE_INCOMPATIBLE);
}
if (!dev->Start) {
return ADI_DEV_RESULT_INVALID_SEQUENCE;
}
#endif
QueueNewXmtFrames((void*)PDDHandle,(ADI_ETHER_BUFFER*)pBuffer);
return(ADI_DEV_RESULT_SUCCESS);
}
/*********************************************************************
*
* Function: pddControl
*
* Description: List of I/O control commands to the driver
*
*********************************************************************/
static u32 adi_pdd_Control( // Sets or senses a device specific parameter
ADI_DEV_PDD_HANDLE PDDHandle, // PDD handle
u32 Command, // command ID
void *pArg // pointer to argument
)
{
u32 Result; // return value
ADI_ETHER_LAN91C111_DATA *dev = (ADI_ETHER_LAN91C111_DATA *)PDDHandle;
ADI_ETHER_MEM_SIZES *msizes;
ADI_ETHER_SUPPLY_MEM *memsup;
int maxbuf,i;
u32 *prefix;
ADI_ETHER_BUFFER_COUNTS *bufcnts;
ADI_ETHER_IVG_MAPPING *ivgs;
// check for errors if required
#if defined(ADI_ETHER_DEBUG)
if ((Result = ValidatePDDHandle(PDDHandle)) != ADI_DEV_RESULT_SUCCESS) return (Result);
if (BufferType != DEV_1D) {
return (ADI_DEV_BUFFER_TYPE_INCOMPATIBLE);
}
#endif
// avoid casts
Result = ADI_DEV_RESULT_SUCCESS;
// CASEOF (Command ID)
switch (Command) {
case ADI_DEV_CMD_SET_DATAFLOW:
// enable or disable accordingly
dev->FlowEnabled = (int)pArg;
break;
case ADI_DEV_CMD_GET_PERIPHERAL_DMA_SUPPORT:
// no we dont want peripheral DMA suppot
(*(int *)pArg) = false;
break;
case ADI_ETHER_CMD_MEM_SIZES:
msizes = (ADI_ETHER_MEM_SIZES *)pArg;
msizes->BaseMemSize = sizeof(ADI_ETHER_STATISTICS_COUNTS);
msizes->MemPerRecv = 0;
msizes->MemPerXmit = 0;
break;
case ADI_ETHER_CMD_SUPPLY_MEM:
memsup = (ADI_ETHER_SUPPLY_MEM *)pArg;
if (memsup->BaseMemLength < sizeof(ADI_ETHER_STATISTICS_COUNTS)) {
Result = ADI_DEV_RESULT_NO_MEMORY;
} else {
dev->Stats = memsup->BaseMem;
memset(dev->Stats,0,sizeof(ADI_ETHER_STATISTICS_COUNTS));
}
break;
case ADI_ETHER_CMD_GET_MAC_ADDR:
GetMacAddr((unsigned char *)pArg);
break;
case ADI_ETHER_CMD_SET_MAC_ADDR:
SetupMacAddr((unsigned char *)pArg);
// store mac in an internel variable
memcpy(dev->phyAddr,(unsigned char*)pArg,6);
break;
case ADI_ETHER_CMD_GET_STATISTICS:
memcpy(pArg,dev->Stats,sizeof(ADI_ETHER_STATISTICS_COUNTS));
break;
case ADI_ETHER_CMD_GET_BUFFER_PREFIX:
prefix = (u32 *)pArg;
*prefix = 0;
break;
case ADI_ETHER_CMD_UNPROCESSED_BUFFER_COUNTS:
bufcnts = (ADI_ETHER_BUFFER_COUNTS *)pArg;
bufcnts->RcvrBufferCnt = dev->m_RxEnqueuedCount;
bufcnts->XmitBufferCnt = dev->m_TxEnqueuedCount;
break;
case ADI_ETHER_CMD_GET_MIN_RECV_BUFSIZE:
prefix = (u32 *)pArg;
*prefix = MAX_RCVE_FRAME;
break;
case ADI_ETHER_CMD_USBLAN_USE_IVG:
ivgs = (ADI_ETHER_IVG_MAPPING *)pArg;
dev->RXIVG = (interrupt_kind)ivgs->RxIVG;
dev->TXIVG = (interrupt_kind)ivgs->TxIVG;
dev->ERRIVG = (interrupt_kind)ivgs->ErrIVG;
break;
case ADI_ETHER_CMD_USBLAN_USE_DMA:
Result = ADI_DEV_RESULT_NOT_SUPPORTED;
break;
case ADI_ETHER_CMD_GEN_CHKSUMS:
Result = ADI_DEV_RESULT_NOT_SUPPORTED;
break;
case ADI_ETHER_CMD_SET_SPEED: // Default Auto Nego mode
i = (int)pArg;
if ((i <= 0) || (i > 2)) {
Result = ADI_DEV_RESULT_NOT_SUPPORTED;
} else {
dev->Port100 = (i == 2);
dev->Auto = false;
}
break;
case ADI_ETHER_CMD_SET_FULL_DUPLEX:
i = (int)(pArg);
dev->FullDuplex = (i!=0);
dev->Auto = false;
break;
case ADI_ETHER_CMD_SET_NEGOTIATE:
i = (int)(pArg);
dev->Auto = (i!=0);
break;
case ADI_DEV_CMD_SET_DATAFLOW_METHOD:
break;
case ADI_ETHER_CMD_SET_LOOPBACK:
i = (int)(pArg);
dev->Loopback = (i!=0);
if (dev->Started) {
// change the phy
u16 cur;
cur = LAN91C111_read_phy_register(PHY_CNTL_REG);
if (dev->Loopback) {
cur |= (1 << 14); // enable TX->RX loopback
} else {
cur &= (~(1 << 14));
}
LAN91C111_write_phy_register(PHY_CNTL_REG,cur);
}
break;
case ADI_ETHER_CMD_GET_PHY_REGS:
{
short *arg = (short *)pArg;
int ic;
for (ic=0;ic<=PHY_MASK_REG;ic++) arg[ic] = LAN91C111_read_phy_register(ic);
}
break;
case ADI_ETHER_CMD_BUFFERS_IN_CACHE:
i = (int)(pArg);
dev->Cache = (i!=0);
break;
case ADI_ETHER_CMD_START:
if (dev->RxStarted) {
StartMac(PDDHandle);
} else {
Result = ADI_DEV_RESULT_INVALID_SEQUENCE;
}
break;
case ADI_DEV_CMD_TABLE:
break;
case ADI_DEV_CMD_END:
break;
default:
smsc_sleep(0);
// we don't understand this command
Result = ADI_DEV_RESULT_NOT_SUPPORTED;
}
// return
return(Result);
}
/**************************************************************************
*
* Lan91c111 entry point
*
**************************************************************************/
ADI_DEV_PDD_ENTRY_POINT ADI_ETHER_USBLAN_Entrypoint = {
adi_pdd_Open,
adi_pdd_Close,
adi_pdd_Read,
adi_pdd_Write,
adi_pdd_Control
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -