void bcm_robo_mii_rx(UINT8 *b, int *l) { M_BLK_ID pMblk; int s; int n = 10; *l = 0; while(*l == 0) { pMblk = robo_txrx_info.rx_head; if (pMblk != NULL) { s = intLock(); robo_txrx_info.rx_head = pMblk->mBlkHdr.mNextPkt; if (robo_txrx_info.rx_head == NULL) { robo_txrx_info.rx_tail = NULL; } intUnlock(s); *l = pMblk->mBlkPktHdr.len; netMblkToBufCopy(pMblk, b, NULL); netMblkClChainFree(pMblk); #ifdef ROBO_TXRX_DEBUG ROBO_TXRX_PRINT("DeQueued a packet %08x len = %d\n", (int)pMblk, *l, 3, 4, 5, 6); #endif } else { /* Wait for a packet */ /* semTake(robo_txrx_info.rx_sem); */ taskDelay(1); if (!(n--)) break; } } }
void et_drv_mii_rx(int unit, UINT8 *b, int *l) { M_BLK_ID pMblk; int s; int n = 10; *l = 0; while(*l == 0) { pMblk = et_drv_txrx_info[unit].rx_head; if (pMblk != NULL) { s = intLock(); et_drv_txrx_info[unit].rx_head = pMblk->mBlkHdr.mNextPkt; if (et_drv_txrx_info[unit].rx_head == NULL) { et_drv_txrx_info[unit].rx_tail = NULL; } intUnlock(s); *l = pMblk->mBlkPktHdr.len; netMblkToBufCopy(pMblk, (char *)b, NULL); netMblkClChainFree(pMblk); ET_DRV_TXRX_PRINT("DeQueued a packet %08x len = %d\n", (int)pMblk, *l, 3, 4, 5, 6); } else { /* Wait for a packet */ /* semTake(et_drv_txrx_info.rx_sem); */ taskDelay(1); if (!(n--)) break; } } }
LOCAL BOOL roboRecv(void *netCallbackId, long type, M_BLK_ID pMblk, void *pSpareData) { UINT8 *buf; robo_txrx_info.rx_cnt++; #if 0 /* Adjust the data ptr and len to get back the ETH header */ pMblk->mBlkHdr.mData -= LINK_HDR_LEN; pMblk->mBlkHdr.mLen += LINK_HDR_LEN; pMblk->mBlkPktHdr.len += LINK_HDR_LEN; #endif #ifdef ROBO_TXRX_DEBUG logMsg("Received a packet %08x\n", (int)pMblk, 2, 3, 4, 5, 6); if (robo_txrx_debug & ROBO_TXRX_DEBUG_F) { robo_txrx_print_packet(pMblk); } #endif if (robo_txrx_info.queue_rx_pkts) { if (robo_txrx_info.rx_cb != NULL) { #ifdef ROBO_TXRX_DEBUG ROBO_TXRX_PRINT("Received a packet %08x\n", (int)pMblk, 2, 3, 4, 5, 6); #endif robo_txrx_info.rx_cb(pMblk, pMblk->mBlkPktHdr.len); } else { netMblkClChainFree(pMblk); } } else { /* copy the packet and pass it to the application (TCL) */ /* */ if (robo_txrx_info.rx_cb != NULL) { buf = robo_txrx_info.rx_alloc(pMblk->mBlkPktHdr.len); if (buf != NULL) { netMblkToBufCopy(pMblk, buf, NULL); robo_txrx_info.rx_cb(buf, pMblk->mBlkPktHdr.len); } else { robo_txrx_info.rx_out_of_mem++; } } /* */ /* copy the packet and pass it to the application (TCL) */ netMblkClChainFree(pMblk); } return (1); }
LOCAL BOOL nptEtherInputHookRtn ( void * pCallBackId, /* Sent down in muxTkBind(); same as pSpare as in muxBind() */ long type, /* SNARF */ M_BLK_ID pMblk, /* Received frame (with link-level header). */ void * pSpareData /* Extra protocol data */ ) { HOOK_ENTRY * pHookEnt = (HOOK_ENTRY*) pCallBackId; char devName[32]; char packetData [ETHERMTU + SIZEOF_ETHERHEADER]; struct ifnet fakeIF; extern LIST inputHookList; int flags; int len; END_OBJ* pEnd=PCOOKIE_TO_ENDOBJ(pHookEnt->pCookie); int ifHdrLen=0; bzero ( (char *)&fakeIF, sizeof (fakeIF)); fakeIF.if_name = &devName[0]; strcpy (fakeIF.if_name, pEnd->devObject.name); fakeIF.if_unit = pEnd->devObject.unit; muxIoctl (pHookEnt->pCookie, EIOCGFLAGS, (caddr_t)&flags); fakeIF.if_flags = flags; /* Get the Link Level header length . */ if (muxIoctl (pHookEnt->pCookie, EIOCGHDRLEN, (caddr_t)&ifHdrLen) != OK) fakeIF.if_hdrlen = 0; else fakeIF.if_hdrlen = (UCHAR)ifHdrLen; len = netMblkToBufCopy(pMblk, (char *)packetData, NULL); for (pHookEnt = (HOOK_ENTRY *)lstFirst (&inputHookList); pHookEnt != NULL; pHookEnt = (HOOK_ENTRY *)lstNext (&pHookEnt->node)) { if ( (* pHookEnt->routine) (&fakeIF, packetData, len)) { netMblkClChainFree (pMblk); /* hook has consumed the packet */ return (TRUE); } } return (FALSE); }
LOCAL BOOL et_drvRecv(void *pCookie, long type, M_BLK_ID pMblk, LL_HDR_INFO * pLinkHdrInfo, void *pSpareData) { int rv = -1, unit; UINT8 *buf; for (unit = 0 ; unit < ETH_MAX_UNITS; unit++) { if ((void *)et_drv_txrx_info[unit].et_drvMuxBindID == pCookie) { break; } } if (unit == ETH_MAX_UNITS) { return FALSE; } et_drv_txrx_info[unit].rx_cnt++; #ifdef ET_DRV_TXRX_DEBUG if (et_drv_txrx_debug & ET_DRV_TXRX_DEBUG_F) { et_drv_txrx_print_packet(pMblk); } #endif if (et_drv_txrx_info[unit].rx_cb != NULL) { if (et_drv_txrx_info[unit].rx_alloc != NULL) { buf = et_drv_txrx_info[unit].rx_alloc(pMblk->mBlkPktHdr.len); if (buf != NULL) { netMblkToBufCopy(pMblk,(char *)buf, NULL); rv = et_drv_txrx_info[unit].rx_cb(unit, buf, pMblk->mBlkPktHdr.len, et_drv_txrx_info[unit].cookie); } else { et_drv_txrx_info[unit].rx_out_of_mem++; } } else { rv = et_drv_txrx_info[unit].rx_cb(unit, pMblk->mBlkHdr.mData, pMblk->mBlkPktHdr.len, et_drv_txrx_info[unit].cookie); } } netMblkClChainFree(pMblk); return (rv == 0)? TRUE : FALSE; }
LOCAL STATUS NetdrvSend(END_DEVICE * pDrvCtrl, M_BLK_ID pMblk) { unsigned char *pucPktData=NULL; uint32 len = 0; uint32 ulPort = -1; ULONG ulRet=OK; unsigned int unit = 0; int i; /* taskDelay(0); */ #ifdef BOOTROM_DEBUG PRINTF_DEBUG2("NetdrvSend\n"); /* DEL_ME */ #endif /* END_TX_SEM_TAKE(&pDrvCtrl->end, WAIT_FOREVER); */ if (pMblk->mBlkPktHdr.len > NETDRV_CL_LEN - 4) { ulRet = ERROR; goto sendErr; } pucPktData = sal_dma_alloc(NETDRV_CL_LEN, "pucPktData"); if (NULL==pucPktData) { ulRet = ERROR; goto sendErr; } /* memset(pucPktData, 0, NETDRV_CL_LEN); */ len = (ULONG)netMblkToBufCopy(pMblk, pucPktData, NULL); len = max(ETHERSMALL, len); for (unit = 0; unit < _n_devices; unit++) { if (pkt_bcm_tx(unit, pucPktData, len) != 0) { /* Synchronous TX */ printf("ERROR: fail to tx pkt unit %d\n", unit); ulRet = ERROR; goto sendErr; } } g_ulPktSend++; sendErr: netMblkClChainFree (pMblk); /* for the packet already sending, we don't want to free them */ if (NULL!=pucPktData) { cacheDmaFree(pucPktData); pucPktData = NULL; } /* END_TX_SEM_GIVE(&pDrvCtrl->end); */ /* Bump the statistic counter. */ END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1); return ulRet; }
STATUS socend_send(_END_OBJ_PAR *p, M_BLK_ID mb) /* * Function: socend_send * Purpose: SENS send packet interface to SOC device. * Parameters: p - pointer to VxWorks end_obj structure for device * mb - mBlk containing packet. * Returns: OK/ERROR * * Notes: Since since we don't have scatter/gather capability right * now, we must copy up the data into one clustered buffer. * If Possible, we simply hand off the buffer. */ { int rv; struct end_object *eo = (struct end_object *)p; socend_t *se = (socend_t *)eo->devObject.pDevice; char *packet; int l; enet_hdr_t *eh; void *cookie; bcm_pkt_t *pkt; if (NULL == (pkt = sal_alloc(sizeof(bcm_pkt_t), "bcm pkt"))) { return(ENOMEM); } /* * If there is more than one cluster, we must allocate another * buffer and copy the data. * * Note: Requires entire ethernet header to be in first mblk. */ if (mb->mBlkHdr.mNext|| !ENET_TAGGED((enet_hdr_t *)mb->mBlkHdr.mData)) { if (SOC_IS_ESW(se->se_unit)) { socend_packet_alloc(se->se_unit,SOC_END_PK_SZ, 0, (void*)&packet); } else { packet = soc_cm_salloc(se->se_unit, SOC_END_PK_SZ, "SOCEND_TX"); } if (NULL == (packet)) { END_ERR_ADD(eo, MIB2_OUT_ERRS, +1); netMblkClChainFree(mb); return(ENOMEM); } cookie = NULL; /* * If packet is not tagged, build a tag now. */ eh = (enet_hdr_t *)packet; if (!ENET_TAGGED((enet_hdr_t *)mb->mBlkHdr.mData)) { /* Set COS to default here */ l = ENET_TAG_SIZE + netMblkToBufCopy(mb, packet + ENET_TAG_SIZE, NULL); /* Copy MAC addresses */ sal_memcpy(eh, mb->mBlkHdr.mData, sizeof(sal_mac_addr_t) * 2); /* Set VLAN info */ eh->en_tag_tpid = htons(ENET_DEFAULT_TPID); eh->en_tag_ctrl = htons(VLAN_CTRL(0,0,se->se_vlan)); eh->en_tag_len = ((enet_hdr_t *)mb->mBlkHdr.mData)->en_untagged_len; } else { /* Just copy entire packet */ /* Extract priority and map to COS here */ l = netMblkToBufCopy(mb, packet, NULL); } if (set_target_broadcast && sal_memcmp(eh->en_dhost, eh->en_shost, 6) == 0) { sal_memcpy(eh->en_dhost, mac_ones, 6); } netMblkClChainFree(mb); /* Free MBLK */ } else { l = mb->mBlkHdr.mLen; packet = mb->mBlkHdr.mData; cookie = (void *)mb; } #if defined(BROADCOM_DEBUG) if (LOG_CHECK(BSL_LS_SYS_END | BSL_INFO) && LOG_CHECK(BSL_LS_SOC_PACKET | BSL_INFO)) { d_packet_format("socend TX", DECODE_ETHER, packet, l, NULL); } #endif /* defined(BROADCOM_DEBUG) */ if (snoop_ip_tx != NULL) { snoop_ip_tx(se->se_unit, packet, l); } sal_memset(pkt, 0, sizeof(bcm_pkt_t)); pkt->pkt_data = &(pkt->_pkt_data); pkt->_pkt_data.len = l; pkt->_pkt_data.data = (uint8 *)packet; pkt->blk_count = 1; pkt->unit = se->se_unit; pkt->pkt_len = l; SOC_PBMP_CLEAR(pkt->tx_pbmp); SOC_PBMP_CLEAR(pkt->tx_upbmp); SOC_PBMP_CLEAR(pkt->tx_l3pbmp); /* get tx_pbmp, tx_upbmp */ eh = (enet_hdr_t *)packet; rv = _socend_l2_lookup(se->se_unit, eh->en_dhost, VLAN_CTRL_ID(se->se_vlan), pkt); if(rv == ERROR){ LOG_CLI((BSL_META("socend_send : can't get egress port(s) by _socend_l2_lookup.\n"))); return(ERROR); } pkt->cookie = cookie; pkt->call_back = socend_send_done; pkt->flags &= ~BCM_TX_CRC_FLD; pkt->flags |= BCM_TX_CRC_APPEND; if ((rv = bcm_tx(se->se_unit, pkt, cookie)) != BCM_E_NONE) { LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META("bcm_tx failed: Unit %d: %s\n"), se->se_unit, bcm_errmsg(rv))); return(ERROR); } return(OK); }
STATUS wdbEndTx ( void * pDev, struct mbuf * pMbuf ) { WDB_END_PKT_DEV *pPktDev = pDev; struct mbuf* pFirstMbuf = pMbuf; #ifdef WDB_NPT_CAPABLE int sendStatus = 0; char * dstMacAddr = NULL; #else int len = 0; #endif WDB_NPT_CAPABLE if (wdbEndDebug) logMsg ("entering send\n", 1, 2, 3, 4, 5, 6); if (pMbuf == NULL) return (ERROR); if (pPktDev->outputBusy) { wdbMbufChainFree (pFirstMbuf); return (EAGAIN); } else pPktDev->outputBusy = TRUE; if (wdbEndDebug) logMsg ("About to enter the copy loop!\n", 1, 2, 3, 4, 5, 6); /* Make sure we know that the outgoing buffer is clean/empty */ pPktDev->pOutBlk->mBlkHdr.mLen = 0; pPktDev->pOutBlk->mBlkHdr.mData = pPktDev->pOutBlk->pClBlk->clNode.pClBuf; /* increment the data pointer so that muxAddressForm can prepend header */ pPktDev->pOutBlk->mBlkHdr.mData += SIZEOF_ETHERHEADER; #ifndef WDB_NPT_CAPABLE /* First place the addressing information into the packet. */ muxAddressForm (pPktDev->pCookie, pPktDev->pOutBlk, pPktDev->srcAddr, pPktDev->lastHAddr); len = pPktDev->pOutBlk->mBlkHdr.mLen; if (wdbEndDebug) logMsg ("About to check length!\n", 1, 2, 3, 4, 5, 6); if (len == 0) { wdbMbufChainFree (pFirstMbuf); pPktDev->outputBusy = FALSE; if (wdbEndDebug) logMsg ("Wrong length!\n", 1, 2, 3, 4, 5, 6); return (EAGAIN); } if (wdbEndDebug) logMsg ("hdr length:%d\n", len, 2, 3, 4, 5, 6); pPktDev->pOutBlk->mBlkHdr.mLen = len + netMblkToBufCopy (pMbuf, pPktDev->pOutBlk->mBlkHdr.mData + len, NULL); pPktDev->pOutBlk->mBlkPktHdr.len = pPktDev->pOutBlk->mBlkHdr.mLen; if (wdbEndDebug) logMsg ("OutBlk: %x:%x:%x:%x:%x:%x\n", pPktDev->pOutBlk->mBlkHdr.mData[0], pPktDev->pOutBlk->mBlkHdr.mData[1], pPktDev->pOutBlk->mBlkHdr.mData[2], pPktDev->pOutBlk->mBlkHdr.mData[3], pPktDev->pOutBlk->mBlkHdr.mData[4], pPktDev->pOutBlk->mBlkHdr.mData[5]); #else pPktDev->pOutBlk->mBlkHdr.mLen = netMblkToBufCopy (pMbuf, pPktDev->pOutBlk->mBlkHdr.mData, NULL); pPktDev->pOutBlk->mBlkPktHdr.len = pPktDev->pOutBlk->mBlkHdr.mLen; #endif /* WDB_NPT_CAPABLE */ if (wdbEndDebug) logMsg ("Data copied !\n", 1, 2, 3, 4, 5, 6); wdbMbufChainFree (pFirstMbuf); if (wdbEndDebug) logMsg ("About to send a packet!\n", 1, 2, 3, 4, 5, 6); #ifdef WDB_NPT_CAPABLE dstMacAddr = pPktDev->lastHAddr->mBlkHdr.mData; #endif /* WDB_NPT_CAPABLE */ #ifndef STANDALONE_AGENT /* if we are in polled mode, transmit the packet in a loop */ if (pPktDev->mode == WDB_COMM_MODE_POLL) { #ifndef WDB_NPT_CAPABLE muxPollSend (pPktDev->pCookie, pPktDev->pOutBlk); #else sendStatus = muxTkPollSend (pPktDev->pCookie, pPktDev->pOutBlk, dstMacAddr, htons(ETHERTYPE_IP), NULL); if (sendStatus != OK) { pPktDev->outputBusy = FALSE; if (wdbEndDebug) logMsg ("Wrong length!\n", 1, 2, 3, 4, 5, 6); return (EAGAIN); } #endif /* WDB_NPT_CAPABLE */ if (wdbEndDebug) logMsg ("Sent polled packet!\n", 1, 2, 3, 4, 5, 6); } else { #ifndef WDB_NPT_CAPABLE if (muxSend (pPktDev->pCookie, pPktDev->pOutBlk) == OK) #else if (muxTkSend (pPktDev->pCookie, pPktDev->pOutBlk, dstMacAddr, htons(ETHERTYPE_IP), NULL) == OK) #endif /* WDB_NPT_CAPABLE */ { END_OBJ * pEnd; if (wdbEndDebug) logMsg ("Sent regular packet!\n", 1, 2, 3, 4, 5, 6); /*pEnd = (END_OBJ *)pPktDev->pCookie;*/ pEnd = PCOOKIE_TO_ENDOBJ(pPktDev->pCookie); if ((pPktDev->pOutBlk = wdbEndMblkClGet (pEnd, pEnd->mib2Tbl.ifMtu)) == NULL) return (ERROR); pPktDev->pOutBlk->mBlkHdr.mFlags |= M_PKTHDR; } else { if (wdbEndDebug) logMsg ("Could not send regular packet!\n", 1, 2, 3, 4, 5, 6); } } #else /* STANDALONE_AGENT */ if (muxPollSend (pPktDev->pCookie, pPktDev->pOutBlk) == ERROR) { if (wdbEndDebug); logMsg ("Could not send regular packet!\n", 1, 2, 3, 4, 5, 6); } else { if (wdbEndDebug) logMsg ("Sent polled packet!\n", 1, 2, 3, 4, 5, 6); } #endif /* STANDALONE_AGENT */ wdbEndOutputFree (pPktDev); return (OK); }