/** 
 * \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);
	TTxCtrlBlk *  pPktCtrlBlk;
	int status;

	CL_TRACE_START_L1();

	os_profile (drv, 0, 0);
	drv->stats.tx_packets++;
	drv->stats.tx_bytes += skb->len;

	/* Allocate a TxCtrlBlk for the Tx packet and save timestamp, length and packet handle */
	pPktCtrlBlk = TWD_txCtrlBlk_Alloc (drv->tCommon.hTWD);

	pPktCtrlBlk->tTxDescriptor.startTime    = os_timeStampMs(drv); /* remove use of skb->tstamp.off_usec */
	pPktCtrlBlk->tTxDescriptor.length       = skb->len;
	pPktCtrlBlk->tTxPktParams.pInputPkt     = skb;

	/* Point the first BDL buffer to the Ethernet header, and the second buffer to the rest of the packet */
	pPktCtrlBlk->tTxnStruct.aBuf[0] = skb->data;
	pPktCtrlBlk->tTxnStruct.aLen[0] = ETHERNET_HDR_LEN;
	pPktCtrlBlk->tTxnStruct.aBuf[1] = skb->data + ETHERNET_HDR_LEN;
	pPktCtrlBlk->tTxnStruct.aLen[1] = (TI_UINT16)skb->len - ETHERNET_HDR_LEN;
	pPktCtrlBlk->tTxnStruct.aLen[2] = 0;

	/* Send the packet to the driver for transmission. */
	status = txDataQ_InsertPacket (drv->tCommon.hTxDataQ, pPktCtrlBlk,(TI_UINT8)skb->priority);

	/* If failed (queue full or driver not running), drop the packet. */
    if (status != TI_OK)
    {
        drv->stats.tx_errors++;
    }
	os_profile (drv, 1, 0);

	CL_TRACE_END_L1("tiwlan_drv.ko", "OS", "TX", "");

	return 0;
}
Beispiel #2
0
static int xmit_Bridge (struct sk_buff *skb, struct net_device *dev, TIntraBssBridge *pBssBridgeParam)
{
    TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);
    TTxCtrlBlk *  pPktCtrlBlk;
    TEthernetHeader *pEthHead = (TEthernetHeader *)(skb->data);
    int status;

    CL_TRACE_START_L1();

    os_profile (drv, 0, 0);
    drv->stats.tx_packets++;
    drv->stats.tx_bytes += skb->len;

    /* Allocate a TxCtrlBlk for the Tx packet and save timestamp, length and packet handle */
    pPktCtrlBlk = TWD_txCtrlBlk_Alloc (drv->tCommon.hTWD);
    if (pPktCtrlBlk == NULL)
    {
        drv->stats.tx_errors++;
        os_profile (drv, 1, 0);
        CL_TRACE_END_L1("tiwlan_drv.ko", "OS", "TX", "");
        return 0;
    }

    /* Set interface type according to net device interface number */
    if (drv->tCommon.eIfRole == IF_ROLE_TYPE_AP) 
        SET_PKT_TYPE_IF_ROLE_AP(pPktCtrlBlk);
    else
        SET_PKT_TYPE_IF_ROLE_STA(pPktCtrlBlk);
    pPktCtrlBlk->tTxDescriptor.startTime    = os_timeStampMs(drv); /* remove use of skb->tstamp.off_usec */
    pPktCtrlBlk->tTxDescriptor.length       = skb->len;
    pPktCtrlBlk->tTxPktParams.pInputPkt     = skb;

    /* Check MGMT packet from hostapd, forward it to the Mgmt-Queue and exit without ethernet header */
    if (HTOWLANS(pEthHead->type) == AP_MGMT_ETH_TYPE)
    {
        /* Copy WLAN header into aPktHdr - format for MGMT packets */
        memcpy (pPktCtrlBlk->aPktHdr, skb->data + ETHERNET_HDR_LEN , WLAN_HDR_LEN );

        /* Skip ethernet header, send as management frame */
        pPktCtrlBlk->tTxPktParams.uPktType = TX_PKT_TYPE_MGMT;
        pPktCtrlBlk->tTxnStruct.aBuf[0] = (TI_UINT8 *)pPktCtrlBlk->aPktHdr;
        pPktCtrlBlk->tTxnStruct.aLen[0] = WLAN_HDR_LEN;
        pPktCtrlBlk->tTxnStruct.aBuf[1] = skb->data + ETHERNET_HDR_LEN + WLAN_HDR_LEN;
        pPktCtrlBlk->tTxnStruct.aLen[1] = (TI_UINT16)skb->len - ETHERNET_HDR_LEN - WLAN_HDR_LEN;
        pPktCtrlBlk->tTxnStruct.aLen[2] = 0;
        pPktCtrlBlk->tTxPktParams.uInputPktLen = skb->len;
        pPktCtrlBlk->tTxDescriptor.length = (TI_UINT16)((pPktCtrlBlk->tTxnStruct.aLen[0]) + (pPktCtrlBlk->tTxnStruct.aLen[1]));

        status = txMgmtQ_Xmit (drv->tCommon.hTxMgmtQ, pPktCtrlBlk, TI_TRUE);
    }
    else

    {
    /* Point the first BDL buffer to the Ethernet header, and the second buffer to the rest of the packet */
    pPktCtrlBlk->tTxnStruct.aBuf[0] = skb->data;
    pPktCtrlBlk->tTxnStruct.aLen[0] = ETHERNET_HDR_LEN;
    pPktCtrlBlk->tTxnStruct.aBuf[1] = skb->data + ETHERNET_HDR_LEN;
    pPktCtrlBlk->tTxnStruct.aLen[1] = (TI_UINT16)skb->len - ETHERNET_HDR_LEN;
    pPktCtrlBlk->tTxnStruct.aLen[2] = 0;

    /* Send the packet to the driver for transmission. */
    status = txDataQ_InsertPacket (drv->tCommon.hTxDataQ, pPktCtrlBlk,(TI_UINT8)skb->priority, pBssBridgeParam);
    }

    /* If failed (queue full or driver not running), drop the packet. */
    if (status != TI_OK)
    {
        drv->stats.tx_errors++;
    }
    os_profile (drv, 1, 0);

    CL_TRACE_END_L1("tiwlan_drv.ko", "OS", "TX", "");

    return 0;
}