/** * \fn wlanDrvIf_Xmit * \brief Packets transmission * * The network stack calls this function in order to transmit a packet * through the WLAN interface. * The packet is inserted to the drver Tx queues and its handling is continued * after switching to the driver context. * * \note * \param skb - The Linux packet buffer structure * \param dev - The driver network-interface handle * \return 0 (= OK) * \sa */ static int wlanDrvIf_Xmit (struct sk_buff *skb, struct net_device *dev) { TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev); if ( drv->tCommon.eDriverState != DRV_STATE_RUNNING ) return -ENODEV; return xmit_Bridge(skb, dev, NULL); }
/** * \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; }
/** * \fn wlanDrvIf_Xmit * \brief Packets transmission * * The network stack calls this function in order to transmit a packet * through the WLAN interface. * The packet is inserted to the drver Tx queues and its handling is continued * after switching to the driver context. * * \note * \param skb - The Linux packet buffer structure * \param dev - The driver network-interface handle * \return 0 (= OK) * \sa */ static int wlanDrvIf_Xmit (struct sk_buff *skb, struct net_device *dev) { return xmit_Bridge(skb, dev, NULL); }