TI_BOOL os_receivePacket(TI_HANDLE OsContext, void *pRxDesc ,void *pPacket, TI_UINT16 Length) { TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext; unsigned char *pdata = (unsigned char *)((TI_UINT32)pPacket & ~(TI_UINT32)0x3); rx_head_t *rx_head = (rx_head_t *)(pdata - WSPI_PAD_BYTES - RX_HEAD_LEN_ALIGNED); struct sk_buff *skb = rx_head->skb; #ifdef TI_DBG if ((TI_UINT32)pPacket & 0x3) { if ((TI_UINT32)pPacket - (TI_UINT32)skb->data != 2) { printk("os_receivePacket() address error skb=0x%x skb->data=0x%x pPacket=0x%x !!!\n",(int)skb, (int)skb->data, (int)pPacket); } } else { if ((TI_UINT32)skb->data != (TI_UINT32)pPacket) { printk("os_receivePacket() address error skb=0x%x skb->data=0x%x pPacket=0x%x !!!\n",(int)skb, (int)skb->data, (int)pPacket); } } if (Length != RX_ETH_PKT_LEN(pPacket)) { printk("os_receivePacket() Length=%d != RX_ETH_PKT_LEN(pPacket)=%d!!!\n",(int)Length, RX_ETH_PKT_LEN(pPacket)); } #endif /* printk("-->> os_receivePacket() pPacket=0x%x Length=%d skb=0x%x skb->data=0x%x skb->head=0x%x skb->len=%d\n", (int)pPacket, (int)Length, (int)skb, (int)skb->data, (int)skb->head, (int)skb->len); */ /* Use skb_reserve, it updates both skb->data and skb->tail. */ skb->data = RX_ETH_PKT_DATA(pPacket); skb->tail = skb->data; skb_put(skb, RX_ETH_PKT_LEN(pPacket)); /* printk("-->> os_receivePacket() skb=0x%x skb->data=0x%x skb->head=0x%x skb->len=%d\n", (int)skb, (int)skb->data, (int)skb->head, (int)skb->len); */ ti_nodprintf(TIWLAN_LOG_INFO, "os_receivePacket - Received EAPOL len-%d\n", WBUF_LEN(pWbuf)); skb->dev = drv->netdev; skb->protocol = eth_type_trans(skb, drv->netdev); skb->ip_summed = CHECKSUM_NONE; drv->stats.rx_packets++; drv->stats.rx_bytes += skb->len; /* Send the skb to the TCP stack. * it responsibly of the Linux kernel to free the skb */ { CL_TRACE_START_L1(); os_wake_lock_timeout_enable(drv); netif_rx_ni(skb); /* Note: Don't change this trace (needed to exclude OS processing from Rx CPU utilization) */ CL_TRACE_END_L1("tiwlan_drv.ko", "OS", "RX", ""); } return TI_TRUE; }
/** * \fn wlanDrvIf_receivePacket * \brief Receive packet from from lower level * */ TI_BOOL wlanDrvIf_receivePacket(TI_HANDLE OsContext, void *pRxDesc ,void *pPacket, TI_UINT16 Length, TIntraBssBridge *pBridgeDecision) { TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext; unsigned char *pdata = (unsigned char *)((TI_UINT32)pRxDesc & ~(TI_UINT32)0x3); rx_head_t *rx_head = (rx_head_t *)(pdata - WSPI_PAD_BYTES - RX_HEAD_LEN_ALIGNED); struct sk_buff *skb = rx_head->skb; struct sk_buff *new_skb; EIntraBssBridgeDecision eBridge = INTRA_BSS_BRIDGE_NO_BRIDGE; skb->data = pPacket; skb_put(skb, Length); skb->dev = drv->netdev; drv->stats.rx_packets++; drv->stats.rx_bytes += skb->len; /* Intra BSS bridge section */ if(pBridgeDecision != NULL) { eBridge = pBridgeDecision->eDecision; } if(INTRA_BSS_BRIDGE_NO_BRIDGE == eBridge) { /* Forward packet to network stack*/ CL_TRACE_START_L1(); skb->protocol = eth_type_trans(skb, drv->netdev); skb->ip_summed = CHECKSUM_NONE; netif_rx_ni(skb); /* Note: Don't change this trace (needed to exclude OS processing from Rx CPU utilization) */ CL_TRACE_END_L1("tiwlan_drv.ko", "OS", "RX", ""); } else if( INTRA_BSS_BRIDGE_UNICAST == eBridge) { /* Send packet to Tx */ TRACE2(drv->tCommon.hReport, REPORT_SEVERITY_WARNING, " wlanDrvIf_receivePacket() Unicast Bridge data=0x%x len=%d \n", RX_ETH_PKT_DATA(pPacket), RX_ETH_PKT_LEN(pPacket)); xmit_Bridge (skb, pDrvStaticHandle->netdev, pBridgeDecision); } else /* Broadcast/Multicast packet*/ { /* Duplicate packet*/ new_skb = skb_clone(skb, GFP_ATOMIC); skb->protocol = eth_type_trans(skb, drv->netdev); skb->ip_summed = CHECKSUM_NONE; netif_rx_ni(skb); if(new_skb) { xmit_Bridge (new_skb, pDrvStaticHandle->netdev, pBridgeDecision); } else { printk (KERN_ERR "%s: skb_clone failed\n", __FUNCTION__); return TI_FALSE; } } return TI_TRUE; }