Пример #1
0
/****************************************************************************************
 *                               dummyPktReqCB                                          *
 ****************************************************************************************
DESCRIPTION: Callback for the TWD_OWN_EVENT_DUMMY_PKT_REQ event - transmits a dummy
             packet

INPUT:      - hTxMgmtQ      - Handle to the TxMgmtQ module
            - str			- Buffer containing the event data
            - strLen        - Event data length
OUTPUT:
RETURN:    void.\n
****************************************************************************************/
void dummyPktReqCB(TI_HANDLE hTxMgmtQ, char* str , TI_UINT32 strLen)
{
	TTxMgmtQ *pTxMgmtQ = (TTxMgmtQ*)hTxMgmtQ;
    TTxCtrlBlk* pTxCtrlBlk;
    void* pPayload;
    const TI_UINT16 uDummyPktBufLen = 1400;
    TI_STATUS status;

    /* Allocate control block for dummy packet */
    pTxCtrlBlk = TWD_txCtrlBlk_Alloc(pTxMgmtQ->hTWD);
    if (NULL == pTxCtrlBlk) {
        TRACE0(pTxMgmtQ->hReport, REPORT_SEVERITY_ERROR, "dummyPktReqCB: TxCtrlBlk allocation failed!\n");
        return;
    }

    /* Allocate payload buffer */
    pPayload  = txCtrl_AllocPacketBuffer(pTxMgmtQ->hTxCtrl, pTxCtrlBlk, WLAN_HDR_LEN + uDummyPktBufLen);
    if (NULL == pPayload)
    {
        TRACE0(pTxMgmtQ->hReport, REPORT_SEVERITY_ERROR, "dummyPktReqCB: Packet buffer allocation failed!\n");
        TWD_txCtrlBlk_Free (pTxMgmtQ->hTWD, pTxCtrlBlk);
        return;
    }

	/* Set packet parameters */
    {
		pTxCtrlBlk->tTxDescriptor.startTime = os_timeStampMs(pTxMgmtQ->hOs);

		/* Mark as a Dummy Blocks Packet */
		pTxCtrlBlk->tTxPktParams.uPktType = TX_PKT_TYPE_DUMMY_BLKS;

		BUILD_TX_TWO_BUF_PKT_BDL (pTxCtrlBlk, pTxCtrlBlk->aPktHdr, WLAN_HDR_LEN, pPayload, uDummyPktBufLen);
    }

    pTxMgmtQ->tDbgCounters.uDummyPackets++;

    /* Enqueue packet in the management-queues and run the scheduler. */
    status = txMgmtQ_Xmit(pTxMgmtQ, pTxCtrlBlk, TI_FALSE);

    if (TI_NOK == status)
    {
        TRACE0(pTxMgmtQ->hReport, REPORT_SEVERITY_ERROR, "dummyPktReqCB: xmit failed!\n");
    }
}
TI_STATUS txDataQ_InsertPacket (TI_HANDLE hTxDataQ, TTxCtrlBlk *pPktCtrlBlk, TI_UINT8 uPacketDtag)
{
	TTxDataQ        *pTxDataQ = (TTxDataQ *)hTxDataQ;
	TEthernetHeader *pEthHead = (TEthernetHeader *)(pPktCtrlBlk->tTxnStruct.aBuf[0]);
	TI_STATUS        eStatus;
	TI_UINT32        uQueId;
	TI_UINT32        uQueSize;
	txCtrl_t         *pTxCtrl = (txCtrl_t *)(pTxDataQ->hTxCtrl);
	TI_BOOL          bRequestSchedule = TI_FALSE;
	TI_BOOL          bStopNetStack = TI_FALSE;
	CL_TRACE_START_L3();

	/* If packet is EAPOL or from the generic Ethertype, forward it to the Mgmt-Queue and exit */
	if ((HTOWLANS(pEthHead->type) == ETHERTYPE_EAPOL) ||
	        (HTOWLANS(pEthHead->type) == pTxCtrl->genericEthertype)) {
		pPktCtrlBlk->tTxPktParams.uPktType = TX_PKT_TYPE_EAPOL;

		return txMgmtQ_Xmit (pTxDataQ->hTxMgmtQ, pPktCtrlBlk, TI_TRUE);
		/* Note: The last parameter indicates that we are running in external context */
	}

	pPktCtrlBlk->tTxPktParams.uPktType = TX_PKT_TYPE_ETHER;

	/* Enter critical section to protect classifier data and queue access */
	context_EnterCriticalSection (pTxDataQ->hContext);

	/* Call the Classify function to set the TID field */
	if (txDataClsfr_ClassifyTxPacket (hTxDataQ, pPktCtrlBlk, uPacketDtag) != TI_OK) {
#ifdef TI_DBG
		pTxDataQ->uClsfrMismatchCount++;
		TRACE0(pTxDataQ->hReport, REPORT_SEVERITY_WARNING, "txDataQueue_xmit: No matching classifier found \n");
#endif /* TI_DBG */
	}

	/* Enqueue the packet in the appropriate Queue */
	uQueId = aTidToQueueTable[pPktCtrlBlk->tTxDescriptor.tid];
	eStatus = que_Enqueue (pTxDataQ->aQueues[uQueId], (TI_HANDLE)pPktCtrlBlk);

	/* Get number of packets in current queue */
	uQueSize = que_Size (pTxDataQ->aQueues[uQueId]);

	/* If the current queue is not stopped */
	if (pTxDataQ->aQueueBusy[uQueId] == TI_FALSE) {
		/* If the queue has the desired number of packets, request switch to driver context for handling them */
		if (uQueSize == pTxDataQ->aTxSendPaceThresh[uQueId]) {
			tmr_StopTimer (pTxDataQ->hTxSendPaceTimer);
			bRequestSchedule = TI_TRUE;
		}
		/* If below Tx-Send pacing threshold, start timer to trigger packets handling if expired */
		else if (uQueSize < pTxDataQ->aTxSendPaceThresh[uQueId]) {
			tmr_StartTimer (pTxDataQ->hTxSendPaceTimer,
			                txDataQ_TxSendPaceTimeout,
			                hTxDataQ,
			                TX_SEND_PACE_TIMEOUT_MSEC,
			                TI_FALSE);
		}
	}

	/* If allowed to stop network stack and the queue is full, indicate to stop network and
	      to schedule Tx handling (both are executed below, outside the critical section!) */
	if ((pTxDataQ->bStopNetStackTx) && (uQueSize == pTxDataQ->aQueueMaxSize[uQueId])) {
		pTxDataQ->aNetStackQueueStopped[uQueId] = TI_TRUE;
		bRequestSchedule = TI_TRUE;
		bStopNetStack = TI_TRUE;
	}

	/* Leave critical section */
	context_LeaveCriticalSection (pTxDataQ->hContext);

	/* If needed, schedule Tx handling */
	if (bRequestSchedule) {
		context_RequestSchedule (pTxDataQ->hContext, pTxDataQ->uContextId);
	}

	/* If needed, stop the network stack Tx */
	if (bStopNetStack) {
		/* Stop the network stack from sending Tx packets as we have at least one date queue full.
		Note that in some of the OS's (e.g Win Mobile) it is implemented by blocking the thread*/
		wlanDrvIf_StopTx (pTxDataQ->hOs);
	}

	if (eStatus != TI_OK) {
		/* If the packet can't be queued drop it */
		txCtrl_FreePacket (pTxDataQ->hTxCtrl, pPktCtrlBlk, TI_NOK);
#ifdef TI_DBG
		pTxDataQ->aQueueCounters[uQueId].uDroppedPacket++;
#endif /* TI_DBG */
	} else {
#ifdef TI_DBG
		pTxDataQ->aQueueCounters[uQueId].uEnqueuePacket++;
#endif /* TI_DBG */
	}

	CL_TRACE_END_L3 ("tiwlan_drv.ko", "INHERIT", "TX", "");

	return eStatus;
}
Пример #3
0
TI_STATUS txDataQ_InsertPacket (TI_HANDLE hTxDataQ, TTxCtrlBlk *pPktCtrlBlk, TI_UINT8 uPacketDtag, TIntraBssBridge *pIntraBssBridgeParam)
{
	TTxDataQ        *pTxDataQ = (TTxDataQ *)hTxDataQ;
	TEthernetHeader *pEthHead = (TEthernetHeader *)(pPktCtrlBlk->tTxnStruct.aBuf[0]);
	TI_STATUS        eStatus;
	TI_UINT32        uQueId;
	TI_UINT32        uQueSize;
	txCtrl_t         *pTxCtrl = (txCtrl_t *)(pTxDataQ->hTxCtrl);
	TI_BOOL          bRequestSchedule = TI_FALSE;
	TI_BOOL          bStopNetStack = TI_FALSE;
	TDataLinkQ       *pLinkQ;
	TI_UINT32        uHlid;

	/* If packet is EAPOL or from the generic Ethertype, forward it to the Mgmt-Queue and exit */
	if ((HTOWLANS(pEthHead->type) == ETHERTYPE_EAPOL) ||
	    (HTOWLANS(pEthHead->type) == pTxCtrl->genericEthertype)) {
		pPktCtrlBlk->tTxPktParams.uPktType = TX_PKT_TYPE_EAPOL;

		return txMgmtQ_Xmit (pTxDataQ->hTxMgmtQ, pPktCtrlBlk, TI_TRUE);
		/* Note: The last parameter indicates that we are running in external context */
	}

	/* Find link id by destination MAC address, if not found drop the packet */
	/* use Intra Bss bridge params*/
	if(!pIntraBssBridgeParam) {
		if (TI_UNLIKELY(MAC_MULTICAST(pEthHead->dst))) {
			uHlid = pTxDataQ->uBcastHlid;
		} else {
			if (txDataQ_LinkMacFind( hTxDataQ, &uHlid, pEthHead->dst) != TI_OK) {
				/* If the packet can't be queued drop it */
				txCtrl_FreePacket (pTxDataQ->hTxCtrl, pPktCtrlBlk, TI_NOK);
				pTxDataQ->uLinkNotFoundCount++;
				return TI_NOK;
			}
		}
	} else {
		uHlid = pIntraBssBridgeParam->uParam;
	}
	pPktCtrlBlk->tTxDescriptor.hlid = uHlid;

	pLinkQ = &pTxDataQ->aDataLinkQ[uHlid]; /* Link queues */

	pPktCtrlBlk->tTxPktParams.uPktType = TX_PKT_TYPE_ETHER;
	/*  set encryption bit */
	if (pLinkQ->bEncrypt) {
		SET_PKT_TYPE_ENCRYPT(pPktCtrlBlk);
	}

	/* Enter critical section to protect classifier data and queue access */
	context_EnterCriticalSection (pTxDataQ->hContext);

	/* Call the Classify function to set the TID field */
	if (txDataClsfr_ClassifyTxPacket (hTxDataQ, pPktCtrlBlk, uPacketDtag) != TI_OK) {
#ifdef TI_DBG
		pTxDataQ->uClsfrMismatchCount++;
#endif /* TI_DBG */
	}

	uQueId = aTidToQueueTable[pPktCtrlBlk->tTxDescriptor.tid];

	/* Check resources per LINK and per AC */
	if (txDataQ_AllocCheckResources( hTxDataQ, pPktCtrlBlk) != TI_OK) {
#ifdef TI_DBG
		pLinkQ->aQueueCounters[uQueId].uDroppedPacket++;
		pTxDataQ->uNoResourcesCount++;
#endif /* TI_DBG */

		/* Leave critical section */
		context_LeaveCriticalSection (pTxDataQ->hContext);
		/* If the packet can't be queued drop it - Should be out of the critical section */
		/* !!! This call should be out of the critical section */
		txCtrl_FreePacket (pTxDataQ->hTxCtrl, pPktCtrlBlk, TI_NOK);
		return TI_NOK;
	}

	/* Enqueue the packet in the appropriate Queue */
	eStatus = que_Enqueue (pLinkQ->aQueues[uQueId], (TI_HANDLE)pPktCtrlBlk);

	/* Get number of packets in current queue */
	uQueSize = que_Size (pLinkQ->aQueues[uQueId]);

	/* If the current queue is not stopped */
	if (pTxDataQ->aQueueBusy[uQueId] == TI_FALSE) {
		/* If the queue has the desired number of packets, request switch to driver context for handling them */
		if (uQueSize == pTxDataQ->aTxSendPaceThresh[uQueId]) {
			tmr_StopTimer (pTxDataQ->hTxSendPaceTimer);
			bRequestSchedule = TI_TRUE;
		}
		/* If below Tx-Send pacing threshold, start timer to trigger packets handling if expired */
		else if (uQueSize < pTxDataQ->aTxSendPaceThresh[uQueId]) {
			tmr_StartTimer (pTxDataQ->hTxSendPaceTimer,
			                txDataQ_TxSendPaceTimeout,
			                hTxDataQ,
			                TX_SEND_PACE_TIMEOUT_MSEC,
			                TI_FALSE);
		}
	}

	/* If allowed to stop network stack and the queue is full, indicate to stop network and
	      to schedule Tx handling (both are executed below, outside the critical section!) */
	if ((pTxDataQ->bStopNetStackTx) && (uQueSize == pTxDataQ->aQueueMaxSize[uQueId])) {
		pLinkQ->aNetStackQueueStopped[uQueId] = TI_TRUE;
		bRequestSchedule = TI_TRUE;
		bStopNetStack = TI_TRUE;
	}

	/* Leave critical section */
	context_LeaveCriticalSection (pTxDataQ->hContext);

	/* If needed, schedule Tx handling */
	if (bRequestSchedule) {
		context_RequestSchedule (pTxDataQ->hContext, pTxDataQ->uContextId);
	}

	/* If needed, stop the network stack Tx */
	if (bStopNetStack) {
		/* Stop the network stack from sending Tx packets as we have at least one date queue full.
		Note that in some of the OS's (e.g Win Mobile) it is implemented by blocking the thread! */
		wlanDrvIf_StopTx (pTxDataQ->hOs);
	}

	if (eStatus != TI_OK) {
		/* If the packet can't be queued drop it */
		txCtrl_FreePacket (pTxDataQ->hTxCtrl, pPktCtrlBlk, TI_NOK);
#ifdef TI_DBG
		pLinkQ->aQueueCounters[uQueId].uDroppedPacket++;
#endif /* TI_DBG */
	} else {
#ifdef TI_DBG
		pLinkQ->aQueueCounters[uQueId].uEnqueuePacket++;
#endif /* TI_DBG */
	}


	return eStatus;
}
Пример #4
0
TI_STATUS mlmeBuilder_sendFrame(TI_HANDLE hMlme, 
							 dot11MgmtSubType_e type, 
							 TI_UINT8   *pDataBuff, 
							 TI_UINT32  dataLen,
							 TI_UINT8	setWepOpt)
{
	mlme_t			*pHandle = (mlme_t*)hMlme;
	TI_STATUS		status;
    TTxCtrlBlk      *pPktCtrlBlk;
    TI_UINT8        *pPktBuffer;
	TMacAddr		daBssid, saBssid;
	dot11_mgmtHeader_t	*pDot11Header;

	/* Allocate a TxCtrlBlk and data buffer (large enough for the max management packet) */
    pPktCtrlBlk = TWD_txCtrlBlk_Alloc (pHandle->hTWD);
	if (pPktCtrlBlk == NULL)
		return TI_NOK;

    pPktBuffer  = txCtrl_AllocPacketBuffer (pHandle->hTxCtrl, 
                                            pPktCtrlBlk, 
                                            MAX_MANAGEMENT_FRAME_BODY_LEN + WLAN_HDR_LEN);
    if (pPktBuffer == NULL)
    {
        TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR , ": No memory\n");
        TWD_txCtrlBlk_Free (pHandle->hTWD, pPktCtrlBlk);
        return TI_NOK;
    }
	
	pDot11Header = (dot11_mgmtHeader_t *)(pPktCtrlBlk->aPktHdr);

	status = mlmeBuilder_buildFrameCtrl (pHandle, type, (TI_UINT16 *)&pDot11Header->fc, setWepOpt);
	if (status != TI_OK)
	{
        txCtrl_FreePacket (pHandle->hTxCtrl, pPktCtrlBlk, TI_NOK);
		return TI_NOK;
	}

    status = ctrlData_getParamBssid(pHandle->hCtrlData, CTRL_DATA_CURRENT_BSSID_PARAM, daBssid);
	if (status != TI_OK)
	{
        txCtrl_FreePacket (pHandle->hTxCtrl, pPktCtrlBlk, TI_NOK);
		return TI_NOK;
	}

	/* copy destination mac address */
	MAC_COPY (pDot11Header->DA, daBssid);

    status = ctrlData_getParamMacAddr(pHandle->hCtrlData, saBssid);
	if (status != TI_OK)
	{
        txCtrl_FreePacket (pHandle->hTxCtrl, pPktCtrlBlk, TI_NOK);
		return TI_NOK;
	}

	/* copy source mac address */
	MAC_COPY (pDot11Header->SA, saBssid);

	/* copy BSSID (destination mac address) */
	MAC_COPY (pDot11Header->BSSID, daBssid);

	if (pDataBuff != NULL)
	{
		os_memoryCopy (pHandle->hOs, pPktBuffer, pDataBuff, dataLen);
	}

    /* Update packet parameters (start-time, length, pkt-type) */
    pPktCtrlBlk->tTxDescriptor.startTime = os_timeStampMs (pHandle->hOs);
    pPktCtrlBlk->tTxPktParams.uPktType   = TX_PKT_TYPE_MGMT;
    BUILD_TX_TWO_BUF_PKT_BDL (pPktCtrlBlk, (TI_UINT8 *)pDot11Header, WLAN_HDR_LEN, pPktBuffer, dataLen)

	/* Enqueue packet in the mgmt-queues and run the scheduler. */
	status = txMgmtQ_Xmit (pHandle->hTxMgmtQ, pPktCtrlBlk, TI_FALSE);

	return status;
}
Пример #5
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;
}