📄 bcm570x.c
字号:
pUmDevice->rx_curr_coalesce_frames = pDevice->RxMaxCoalescedFrames; pDevice->StatsCoalescingTicks = stats_coalesce_ticks[index]; if (pDevice->StatsCoalescingTicks > MAX_STATS_COALESCING_TICKS) pDevice->StatsCoalescingTicks = MAX_STATS_COALESCING_TICKS; } else { pUmDevice->rx_curr_coalesce_frames = DEFAULT_RX_MAX_COALESCED_FRAMES; pUmDevice->rx_curr_coalesce_ticks = DEFAULT_RX_COALESCING_TICKS; } pDevice->TxCoalescingTicks = tx_coalesce_ticks[index]; if (pDevice->TxCoalescingTicks > MAX_TX_COALESCING_TICKS) pDevice->TxCoalescingTicks = MAX_TX_COALESCING_TICKS; pDevice->TxMaxCoalescedFrames = tx_max_coalesce_frames[index]; if (pDevice->TxMaxCoalescedFrames > MAX_TX_MAX_COALESCED_FRAMES) pDevice->TxMaxCoalescedFrames = MAX_TX_MAX_COALESCED_FRAMES; if (enable_wol[index]) { pDevice->WakeUpModeCap = LM_WAKE_UP_MODE_MAGIC_PACKET; pDevice->WakeUpMode = LM_WAKE_UP_MODE_MAGIC_PACKET; } pDevice->NicSendBd = TRUE; /* Don't update status blocks during interrupt */ pDevice->RxCoalescingTicksDuringInt = 0; pDevice->TxCoalescingTicksDuringInt = 0; return LM_STATUS_SUCCESS;}LM_STATUS MM_StartTxDma (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket){ PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice; printf ("Start TX DMA: dev=%d packet @0x%x\n", (int)pUmDevice->index, (unsigned int)pPacket); return LM_STATUS_SUCCESS;}LM_STATUS MM_CompleteTxDma (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket){ PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice; printf ("Complete TX DMA: dev=%d packet @0x%x\n", (int)pUmDevice->index, (unsigned int)pPacket); return LM_STATUS_SUCCESS;}LM_STATUS MM_IndicateStatus (PLM_DEVICE_BLOCK pDevice, LM_STATUS Status){ char buf[128]; char lcd[4]; PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice; LM_FLOW_CONTROL flow_control; pUmDevice->delayed_link_ind = 0; memset (lcd, 0x0, 4); if (Status == LM_STATUS_LINK_DOWN) { sprintf (buf, "eth%d: %s: NIC Link is down\n", pUmDevice->index, pUmDevice->name); lcd[0] = 'L'; lcd[1] = 'N'; lcd[2] = 'K'; lcd[3] = '?'; } else if (Status == LM_STATUS_LINK_ACTIVE) { sprintf (buf, "eth%d:%s: ", pUmDevice->index, pUmDevice->name); if (pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) { strcat (buf, "1000 Mbps "); lcd[0] = '1'; lcd[1] = 'G'; lcd[2] = 'B'; } else if (pDevice->LineSpeed == LM_LINE_SPEED_100MBPS) { strcat (buf, "100 Mbps "); lcd[0] = '1'; lcd[1] = '0'; lcd[2] = '0'; } else if (pDevice->LineSpeed == LM_LINE_SPEED_10MBPS) { strcat (buf, "10 Mbps "); lcd[0] = '1'; lcd[1] = '0'; lcd[2] = ' '; } if (pDevice->DuplexMode == LM_DUPLEX_MODE_FULL) { strcat (buf, "full duplex"); lcd[3] = 'F'; } else { strcat (buf, "half duplex"); lcd[3] = 'H'; } strcat (buf, " link up"); flow_control = pDevice->FlowControl & (LM_FLOW_CONTROL_RECEIVE_PAUSE | LM_FLOW_CONTROL_TRANSMIT_PAUSE); if (flow_control) { if (flow_control & LM_FLOW_CONTROL_RECEIVE_PAUSE) { strcat (buf, ", receive "); if (flow_control & LM_FLOW_CONTROL_TRANSMIT_PAUSE) strcat (buf, " & transmit "); } else { strcat (buf, ", transmit "); } strcat (buf, "flow control ON"); } else { strcat (buf, ", flow control OFF"); } strcat (buf, "\n"); printf ("%s", buf); }#if 0 sysLedDsply (lcd[0], lcd[1], lcd[2], lcd[3]);#endif return LM_STATUS_SUCCESS;}LM_STATUS MM_FreeRxBuffer (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket){ PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice; PUM_PACKET pUmPacket; void *skb; pUmPacket = (PUM_PACKET) pPacket; if ((skb = pUmPacket->skbuff)) bcm570xPktFree (pUmDevice->index, skb); pUmPacket->skbuff = 0; return LM_STATUS_SUCCESS;}unsigned long MM_AnGetCurrentTime_us (PAN_STATE_INFO pAnInfo){ return get_timer (0);}/* * Transform an MBUF chain into a single MBUF. * This routine will fail if the amount of data in the * chain overflows a transmit buffer. In that case, * the incoming MBUF chain will be freed. This routine can * also fail by not being able to allocate a new MBUF (including * cluster and mbuf headers). In that case the failure is * non-fatal. The incoming cluster chain is not freed, giving * the caller the choice of whether to try a retransmit later. */LM_STATUS MM_CoalesceTxBuffer (PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket){ PUM_PACKET pUmPacket = (PUM_PACKET) pPacket; PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice; void *skbnew; int len = 0; if (len == 0) 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_STATUS MM_IndicateRxPackets (PLM_DEVICE_BLOCK pDevice){ PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) pDevice; pUmDevice->rx_pkt = 1; return LM_STATUS_SUCCESS;}LM_STATUS MM_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);}void MM_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}void MM_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. */void atomic_set (atomic_t * entry, int val){ entry->counter = val;}int atomic_read (atomic_t * entry){ return entry->counter;}void atomic_inc (atomic_t * entry){ if (entry) entry->counter++;}void atomic_dec (atomic_t * entry){ if (entry) entry->counter--;}void atomic_sub (int a, atomic_t * entry){ if (entry) entry->counter -= a;}void atomic_add (int a, atomic_t * entry){ if (entry) entry->counter += a;}/******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/void QQ_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: *//******************************************************************************/char QQ_Full (PQQ_CONTAINER pQueue){ unsigned int NewHead; NewHead = (pQueue->Head + 1) % pQueue->Size; return (NewHead == pQueue->Tail);} /* QQ_Full *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/char QQ_Empty (PQQ_CONTAINER pQueue){ return (pQueue->Head == pQueue->Tail);} /* QQ_Empty *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/unsigned int QQ_GetSize (PQQ_CONTAINER pQueue){ return pQueue->Size;} /* QQ_GetSize *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/unsigned int QQ_GetEntryCnt (PQQ_CONTAINER pQueue){ return atomic_read (&pQueue->EntryCnt);} /* QQ_GetEntryCnt *//******************************************************************************//* Description: *//* *//* Return: *//* TRUE entry was added successfully. *//* FALSE queue is full. *//******************************************************************************/char QQ_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. *//******************************************************************************/char QQ_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_ENTRY QQ_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_ENTRY QQ_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_ENTRY QQ_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_ENTRY QQ_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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -