📄 lan91c111.c
字号:
}
}
else if (stat == ISQ_TRANSMITTER_EVENT )
{
ADI_G(("states ISQ_TRANSMITTER_EVENT\n"));
dev->LAN_state.last_IRQ_serviced = IM_TX_INT;
//VDK_PostSemaphore(ksem_netsend);
LAN91C111_tx(dev);
}
else if (stat == ISQ_BUFFER_EVENT )
{
if(st&READY_FOR_TX)
{
dev->LAN_state.alloc_success = CS89X0_ALLOC_SUCE;
ADI_G(("ready for tx\n"));
}
if(st&TX_UNDERRUN)
{
ADI_G(("tx under run\n"));
dev->send_underrun++;
if (dev->send_underrun == 3) dev->send_cmd = TX_AFTER_381;
else if (dev->send_underrun == 6) dev->send_cmd = TX_AFTER_ALL;
}
ADI_G(("states ISQ_BUFFER_EVENT\n"));
}
else if (stat == TX_UNDERRUN )
{
printf(("states TX_UNDERRUN\n"));
}
else if (stat == ISQ_RX_MISS_EVENT )
{
printf(("states ISQ_RX_MISS_EVENT\n"));
}
else if (stat == ISQ_TX_COL_EVENT )
{
printf(("states ISQ_TX_COL_EVENT\n"));
}
else
printf(("states ISO ??\n"));
st = readword(dev, ISQ_PORT);
// read the status flag and mask it
stat= st & mask;
}
// no need Acknowledge interrupt?
//ACK_LAN_INT(dev->pf);
return 1;
}
/******************************************************************************
* LAN Initialization routine
*****************************************************************************/
static SetPhy(ADI_ETHER_LAN91C111_DATA *dev)
{
return 1;
}
void PPI_DMA_ISR();
static int StartMac(ADI_ETHER_LAN91C111_DATA *dev)
{
int i;
net_open (dev);
printf("start mac :%02x-%02x-%02x-%02x-%02x-%02x\n",dev->phyAddr[0],dev->phyAddr[0],dev->phyAddr[1],
dev->phyAddr[2],dev->phyAddr[3],dev->phyAddr[4],dev->phyAddr[5]);
for (i=0; i < ETH_ALEN/2; i++)
writereg(dev, PP_IA+i*2, dev->phyAddr[i*2] | (dev->phyAddr[i*2+1] << 8));
adi_int_CECHook(dev->RXIVG,(ADI_INT_HANDLER_FN)LAN91C111_InterruptHandler,dev,false); //false
//adi_int_CECHook(ik_ivg8,(ADI_INT_HANDLER_FN)PPI_DMA_ISR,0,false); //false
SetDevicePFConfig(dev);
adi_int_SICSetIVG(ADI_INT_PFB,dev->RXIVG);
adi_int_SICEnable(ADI_INT_PFB);
//adi_int_SICSetIVG(ADI_INT_DMA0_PPI,ik_ivg8);
//adi_int_SICEnable(ADI_INT_DMA0_PPI);
ADI_G(("register interrupt handler\n"));
return 1;
}
#pragma optimize_for_speed
static int QueueNewRcvFrames(ADI_ETHER_LAN91C111_DATA *dev,ADI_ETHER_BUFFER *bufs)
{
ADI_ETHER_BUFFER *tmp_q_ele;
void *CriticalResult;
if (bufs == NULL)
return (0);
ENTER_CRITICAL_REGION();
//CriticalResult = adi_int_EnterCriticalRegion(dev->CriticalData);
tmp_q_ele = bufs;
tmp_q_ele->ProcessedFlag = 0;
if (dev->m_RxEnqueuedCount)
dev->m_RxEnqueuedTail->pNext = (ADI_ETHER_BUFFER*)tmp_q_ele;
else
dev->m_RxEnqueuedHead = tmp_q_ele;
//We have attached one
dev->m_RxEnqueuedCount++;
//Now look for rest
while (tmp_q_ele->pNext != NULL)
{
// increment the count
dev->m_RxEnqueuedCount++;
tmp_q_ele = (ADI_ETHER_BUFFER*)tmp_q_ele->pNext;
tmp_q_ele->ProcessedFlag = 0;
}
//Amd update tail
dev->m_RxEnqueuedTail = tmp_q_ele;
dev->RxStarted = 1;
EXIT_CRTICIAL_REGION();
//adi_int_ExitCriticalRegion(CriticalResult);
return 1;
}
#pragma section("Merge")
static int QueueNewXmtFrames(ADI_ETHER_LAN91C111_DATA *dev,ADI_ETHER_BUFFER *bufs)
{
int mr = 0;
ADI_ETHER_BUFFER *tmp_q_ele;
ADI_DCB_RESULT result;
int ses = 0;
unsigned char status;
// if the incoming element is NULL throw an error
if (bufs == NULL)
{
printf("what\n");
return (0);
}
// printf("0x%x\n",xmt_list);
ping++;
ENTER_CRITICAL_REGION();
//CriticalResult = adi_int_EnterCriticalRegion(dev->CriticalData);
tmp_q_ele = bufs;
tmp_q_ele->ProcessedFlag = 0;
if (dev->m_TxEnqueuedCount)
dev->m_TxEnqueuedTail->pNext = (ADI_ETHER_BUFFER*)tmp_q_ele;
else
dev->m_TxEnqueuedHead = tmp_q_ele;
//We have attached one
dev->m_TxEnqueuedCount++;
//Now look for rest
while (tmp_q_ele->pNext != NULL)
{
// increment the count
dev->m_TxEnqueuedCount++;
tmp_q_ele = (ADI_ETHER_BUFFER*)tmp_q_ele->pNext;
tmp_q_ele->ProcessedFlag = 0;
}
//And update tail
dev->m_TxEnqueuedTail = tmp_q_ele;
/*************/
if(dev->m_TxEnqueuedCount>0)
{
// printf("%d\n",dev->m_TxEnqueuedCount);
}
/*************/
{
int cont = 1;
while(cont)
{
//VDK_PendSemaphore(ksem_netsend,0);
status = LAN91C111_wait_to_send_packet(dev);
if (status == LAN91C111_TX_RETRY)
{
/* Keep the packet in the queue and retry next time */
cont = 0;
mr =0;
dev->Stats->cEMAC_TX_CNT_DEFER++;
//printf("RETRY\n");
}
else // If transmission attempt is an unrecoverable error or if it completed successfully
{
ses++;
ADI_G(("OK\n"));
dev->Stats->cEMAC_TX_CNT_OK++;
tmp_q_ele = dev->m_TxEnqueuedHead;
/* 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;
ADI_G(("DONE\n"));
}
if(cont !=0)
ADI_G(("cont = %d -----------shit",cont));
ADI_G(("\n\ping data packet @@ %d @@\n",ping));
/* 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++;
/*************/
//cont = 0;
/***********send 1 then quit?*/
}
}
}
#if 0
if(ses==0)
{
printf("dev->m_TxDequeuedHead %x\n",dev->m_TxDequeuedHead);
printf("dev->m_TxDequeuedHead->CallbackParameter%x\n",dev->m_TxDequeuedHead->CallbackParameter);
// %x dev->m_TxDequeuedHead->CallbackParameter
goto EXIT;
}
#endif
if(dev->m_TxDequeuedHead != NULL)
{
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 {
/********************* we just this *****************/
/***$$$$ corrected by lql $$$$$***/
(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:
EXIT_CRTICIAL_REGION();
return mr;
}
/******************************************************************************
* Get MAC address in the SMSC
*****************************************************************************/
static void GetMacAddr(unsigned char *mac_addr)
{
mac_addr[0] = 0x00;
mac_addr[1] = 0x11;
mac_addr[2] = 0x22;
mac_addr[3] = 0x33;
mac_addr[4] = 0x44;
mac_addr[5] = 0x55;
mac_addr[6] = 0x66;
mac_addr[7] = 0x77;
ADI_G(("sys get mac.\n"));
return;
}
/******************************************************************************
* Set MAC address in the SMSC
*****************************************************************************/
static void SetupMacAddr(unsigned char *mac_addr)
{
//
mac_addr[0] = 0x00;
mac_addr[1] = 0x11;
mac_addr[2] = 0x22;
mac_addr[3] = 0x33;
mac_addr[4] = 0x44;
mac_addr[5] = 0x55;
mac_addr[6] = 0x66;
mac_addr[7] = 0x77;
ADI_G(("set mac ,but we set no set .\n"));
return;
}
/******************************************************************************
*
* Configures the PF/IMASK/IAR settings associated with the driver.
*
*****************************************************************************/
static int SetDevicePFConfig(ADI_ETHER_LAN91C111_DATA *dev)
{
unsigned int iar2_mask;
ADI_G(("pEBIU_AMGCTL = 0xFF \n"));
*pEBIU_AMGCTL = 0xFF; // LQL
// 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 = PF0;//LQL to clear and unmask interrupt
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;
ADI_G(("unmask PF 0 \n"));
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_ivg12;
dev->TXIVG = ik_ivg12;
dev->ERRIVG = ik_ivg12;//PF interrupt
//set PF configuration
SetDevicePFConfig(dev);
dev->base_addr = CS8900_BASE;
dev->send_cmd = TX_NOW;
dev->send_underrun=0;
dev->Open = true;
dev->LAN_state.alloc_success = CS89X0_ALLOC_IDLE;
Result = ADI_DEV_RESULT_SUCCESS;
}
ADI_G(("begin probe\n"));
cs8900a_probe(dev);
// exit critical region
//
//adi_int_ExitCriticalRegion(CriticalResult);
if (Result != ADI_DEV_RESULT_SUCCESS) return (Result);
ADI_G(("CS8900 for ADI opening...\n"));
*pPDDHandle = (ADI_DEV_PDD_HANDLE *)dev;
dev_g = dev;
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;
ADI_G(("want read +++.\n"));
// 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -