📄 bcm570x.c
字号:
return (LM_STATUS_SUCCESS); if (len > MAX_PACKET_SIZE){ printf ("eth%d: xmit frame discarded, too big!, size = %d\n", pUmDevice->index, len); return (LM_STATUS_FAILURE); } skbnew = bcm570xPktAlloc(pUmDevice->index, MAX_PACKET_SIZE); if (skbnew == NULL) { pUmDevice->tx_full = 1; printf ("eth%d: out of transmit buffers", pUmDevice->index); return (LM_STATUS_FAILURE); } /* New packet values */ pUmPacket->skbuff = skbnew; pUmPacket->lm_packet.u.Tx.FragCount = 1; return (LM_STATUS_SUCCESS);}LM_STATUSMM_IndicateRxPackets(PLM_DEVICE_BLOCK pDevice){ PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice; pUmDevice->rx_pkt = 1; return LM_STATUS_SUCCESS;}LM_STATUSMM_IndicateTxPackets(PLM_DEVICE_BLOCK pDevice){ PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice; PLM_PACKET pPacket; PUM_PACKET pUmPacket; void *skb; while ( TRUE ) { pPacket = (PLM_PACKET) QQ_PopHead(&pDevice->TxPacketXmittedQ.Container); if (pPacket == 0) break; pUmPacket = (PUM_PACKET) pPacket; skb = (void*)pUmPacket->skbuff; /* * Free MBLK if we transmitted a fragmented packet or a * non-fragmented packet straight from the VxWorks * buffer pool. If packet was copied to a local transmit * buffer, then there's no MBUF to free, just free * the transmit buffer back to the cluster pool. */ if (skb) bcm570xPktFree (pUmDevice->index, skb); pUmPacket->skbuff = 0; QQ_PushTail(&pDevice->TxPacketFreeQ.Container, pPacket); pUmDevice->tx_pkt = 1; } if (pUmDevice->tx_full) { if (QQ_GetEntryCnt(&pDevice->TxPacketFreeQ.Container) >= (QQ_GetSize(&pDevice->TxPacketFreeQ.Container) >> 1)) pUmDevice->tx_full = 0; } return LM_STATUS_SUCCESS;}/* * Scan an MBUF chain until we reach fragment number "frag" * Return its length and physical address. */void MM_MapTxDma ( PLM_DEVICE_BLOCK pDevice, struct _LM_PACKET *pPacket, T3_64BIT_HOST_ADDR *paddr, LM_UINT32 *len, int frag){ PUM_PACKET pUmPacket = (PUM_PACKET) pPacket; *len = pPacket->PacketSize; MM_SetT3Addr(paddr, (dma_addr_t) pUmPacket->skbuff);}/* * Convert an mbuf address, a CPU local virtual address, * to a physical address as seen from a PCI device. Store the * result at paddr. */void MM_MapRxDma( PLM_DEVICE_BLOCK pDevice, struct _LM_PACKET *pPacket, T3_64BIT_HOST_ADDR *paddr){ PUM_PACKET pUmPacket = (PUM_PACKET) pPacket; MM_SetT3Addr(paddr, (dma_addr_t) pUmPacket->skbuff);}voidMM_SetAddr (LM_PHYSICAL_ADDRESS *paddr, dma_addr_t addr){#if (BITS_PER_LONG == 64) paddr->High = ((unsigned long) addr) >> 32; paddr->Low = ((unsigned long) addr) & 0xffffffff;#else paddr->High = 0; paddr->Low = (unsigned long) addr;#endif}voidMM_SetT3Addr(T3_64BIT_HOST_ADDR *paddr, dma_addr_t addr){ unsigned long baddr = (unsigned long) addr;#if (BITS_PER_LONG == 64) set_64bit_addr(paddr, baddr & 0xffffffff, baddr >> 32);#else set_64bit_addr(paddr, baddr, 0);#endif}/* * This combination of `inline' and `extern' has almost the effect of a * macro. The way to use it is to put a function definition in a header * file with these keywords, and put another copy of the definition * (lacking `inline' and `extern') in a library file. The definition in * the header file will cause most calls to the function to be inlined. * If any uses of the function remain, they will refer to the single copy * in the library. */voidatomic_set(atomic_t* entry, int val){ entry->counter = val;}intatomic_read(atomic_t* entry){ return entry->counter;}voidatomic_inc(atomic_t* entry){ if(entry) entry->counter++;}voidatomic_dec(atomic_t* entry){ if(entry) entry->counter--;}voidatomic_sub(int a, atomic_t* entry){ if(entry) entry->counter -= a;}voidatomic_add(int a, atomic_t* entry){ if(entry) entry->counter += a;}/******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/voidQQ_InitQueue(PQQ_CONTAINER pQueue,unsigned int QueueSize) { pQueue->Head = 0; pQueue->Tail = 0; pQueue->Size = QueueSize+1; atomic_set(&pQueue->EntryCnt, 0);} /* QQ_InitQueue *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/charQQ_Full(PQQ_CONTAINER pQueue) { unsigned int NewHead; NewHead = (pQueue->Head + 1) % pQueue->Size; return(NewHead == pQueue->Tail);} /* QQ_Full *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/charQQ_Empty(PQQ_CONTAINER pQueue) { return(pQueue->Head == pQueue->Tail);} /* QQ_Empty *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/unsigned intQQ_GetSize(PQQ_CONTAINER pQueue) { return pQueue->Size;} /* QQ_GetSize *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/unsigned intQQ_GetEntryCnt(PQQ_CONTAINER pQueue) { return atomic_read(&pQueue->EntryCnt);} /* QQ_GetEntryCnt *//******************************************************************************//* Description: *//* *//* Return: *//* TRUE entry was added successfully. *//* FALSE queue is full. *//******************************************************************************/charQQ_PushHead(PQQ_CONTAINER pQueue,PQQ_ENTRY pEntry) { unsigned int Head; Head = (pQueue->Head + 1) % pQueue->Size;#if !defined(QQ_NO_OVERFLOW_CHECK) if(Head == pQueue->Tail) { return 0; } /* if */#endif /* QQ_NO_OVERFLOW_CHECK */ pQueue->Array[pQueue->Head] = pEntry; wmb(); pQueue->Head = Head; atomic_inc(&pQueue->EntryCnt); return -1;} /* QQ_PushHead *//******************************************************************************//* Description: *//* *//* Return: *//* TRUE entry was added successfully. *//* FALSE queue is full. *//******************************************************************************/charQQ_PushTail(PQQ_CONTAINER pQueue,PQQ_ENTRY pEntry) { unsigned int Tail; Tail = pQueue->Tail; if(Tail == 0) { Tail = pQueue->Size; } /* if */ Tail--;#if !defined(QQ_NO_OVERFLOW_CHECK) if(Tail == pQueue->Head) { return 0; } /* if */#endif /* QQ_NO_OVERFLOW_CHECK */ pQueue->Array[Tail] = pEntry; wmb(); pQueue->Tail = Tail; atomic_inc(&pQueue->EntryCnt); return -1;} /* QQ_PushTail *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/PQQ_ENTRYQQ_PopHead(PQQ_CONTAINER pQueue) { unsigned int Head; PQQ_ENTRY Entry; Head = pQueue->Head;#if !defined(QQ_NO_UNDERFLOW_CHECK) if(Head == pQueue->Tail) { return (PQQ_ENTRY) 0; } /* if */#endif /* QQ_NO_UNDERFLOW_CHECK */ if(Head == 0) { Head = pQueue->Size; } /* if */ Head--; Entry = pQueue->Array[Head]; membar(); pQueue->Head = Head; atomic_dec(&pQueue->EntryCnt); return Entry;} /* QQ_PopHead *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/PQQ_ENTRYQQ_PopTail(PQQ_CONTAINER pQueue) { unsigned int Tail; PQQ_ENTRY Entry; Tail = pQueue->Tail;#if !defined(QQ_NO_UNDERFLOW_CHECK) if(Tail == pQueue->Head) { return (PQQ_ENTRY) 0; } /* if */#endif /* QQ_NO_UNDERFLOW_CHECK */ Entry = pQueue->Array[Tail]; membar(); pQueue->Tail = (Tail + 1) % pQueue->Size; atomic_dec(&pQueue->EntryCnt); return Entry;} /* QQ_PopTail *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/PQQ_ENTRYQQ_GetHead( PQQ_CONTAINER pQueue, unsigned int Idx){ if(Idx >= atomic_read(&pQueue->EntryCnt)) { return (PQQ_ENTRY) 0; } if(pQueue->Head > Idx) { Idx = pQueue->Head - Idx; } else { Idx = pQueue->Size - (Idx - pQueue->Head); } Idx--; return pQueue->Array[Idx];}/******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/PQQ_ENTRYQQ_GetTail( PQQ_CONTAINER pQueue, unsigned int Idx){ if(Idx >= atomic_read(&pQueue->EntryCnt)) { return (PQQ_ENTRY) 0; } Idx += pQueue->Tail; if(Idx >= pQueue->Size) { Idx = Idx - pQueue->Size; } return pQueue->Array[Idx];}#endif /* CFG_CMD_NET, !CONFIG_NET_MULTI, CONFIG_BCM570x */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -