Esempio n. 1
0
static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
	PSTxDesc head_td;
	u32 dma_idx = TYPE_AC0DMA;
	unsigned long flags;

	spin_lock_irqsave(&priv->lock, flags);

	if (!ieee80211_is_data(hdr->frame_control))
		dma_idx = TYPE_TXDMA0;

	if (AVAIL_TD(priv, dma_idx) < 1) {
		spin_unlock_irqrestore(&priv->lock, flags);
		return -ENOMEM;
	}

	head_td = priv->apCurrTD[dma_idx];

	head_td->m_td1TD1.byTCR = 0;

	head_td->pTDInfo->skb = skb;

	priv->iTDUsed[dma_idx]++;

	/* Take ownership */
	wmb();
	head_td->m_td0TD0.f1Owner = OWNED_BY_NIC;

	/* get Next */
	wmb();
	priv->apCurrTD[dma_idx] = head_td->next;

	spin_unlock_irqrestore(&priv->lock, flags);

	vnt_generate_fifo_header(priv, dma_idx, head_td, skb);

	if (MACbIsRegBitsOn(priv->PortOffset, MAC_REG_PSCTL, PSCTL_PS))
		MACbPSWakeup(priv->PortOffset);

	spin_lock_irqsave(&priv->lock, flags);

	priv->bPWBitOn = false;

	/* Set TSR1 & ReqCount in TxDescHead */
	head_td->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU);
	head_td->m_td1TD1.wReqCount =
			cpu_to_le16((u16)head_td->pTDInfo->dwReqCount);

	head_td->buff_addr = cpu_to_le32(head_td->pTDInfo->skb_dma);

	if (dma_idx == TYPE_AC0DMA) {
		head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB;

		MACvTransmitAC0(priv->PortOffset);
	} else {
		MACvTransmit0(priv->PortOffset);
	}

	spin_unlock_irqrestore(&priv->lock, flags);

	return 0;
}
Esempio n. 2
0
static  irqreturn_t  device_intr(int irq,  void *dev_instance)
{
	struct vnt_private *pDevice = dev_instance;
	int             max_count = 0;
	unsigned long dwMIBCounter = 0;
	unsigned char byOrgPageSel = 0;
	int             handled = 0;
	unsigned long flags;

	MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);

	if (pDevice->dwIsr == 0)
		return IRQ_RETVAL(handled);

	if (pDevice->dwIsr == 0xffffffff) {
		pr_debug("dwIsr = 0xffff\n");
		return IRQ_RETVAL(handled);
	}

	handled = 1;
	MACvIntDisable(pDevice->PortOffset);

	spin_lock_irqsave(&pDevice->lock, flags);

	//Make sure current page is 0
	VNSvInPortB(pDevice->PortOffset + MAC_REG_PAGE1SEL, &byOrgPageSel);
	if (byOrgPageSel == 1)
		MACvSelectPage0(pDevice->PortOffset);
	else
		byOrgPageSel = 0;

	MACvReadMIBCounter(pDevice->PortOffset, &dwMIBCounter);
	// TBD....
	// Must do this after doing rx/tx, cause ISR bit is slow
	// than RD/TD write back
	// update ISR counter
	STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic, dwMIBCounter);
	while (pDevice->dwIsr != 0) {
		STAvUpdateIsrStatCounter(&pDevice->scStatistic, pDevice->dwIsr);
		MACvWriteISR(pDevice->PortOffset, pDevice->dwIsr);

		if (pDevice->dwIsr & ISR_FETALERR) {
			pr_debug(" ISR_FETALERR\n");
			VNSvOutPortB(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, 0);
			VNSvOutPortW(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPECTI);
			device_error(pDevice, pDevice->dwIsr);
		}

		if (pDevice->dwIsr & ISR_TBTT) {
			if (pDevice->vif &&
			    pDevice->op_mode != NL80211_IFTYPE_ADHOC)
				vnt_check_bb_vga(pDevice);

			pDevice->bBeaconSent = false;
			if (pDevice->bEnablePSMode)
				PSbIsNextTBTTWakeUp((void *)pDevice);

			if ((pDevice->op_mode == NL80211_IFTYPE_AP ||
			    pDevice->op_mode == NL80211_IFTYPE_ADHOC) &&
			    pDevice->vif->bss_conf.enable_beacon) {
				MACvOneShotTimer1MicroSec(pDevice->PortOffset,
							  (pDevice->vif->bss_conf.beacon_int - MAKE_BEACON_RESERVED) << 10);
			}

			/* TODO: adhoc PS mode */

		}

		if (pDevice->dwIsr & ISR_BNTX) {
			if (pDevice->op_mode == NL80211_IFTYPE_ADHOC) {
				pDevice->bIsBeaconBufReadySet = false;
				pDevice->cbBeaconBufReadySetCnt = 0;
			}

			pDevice->bBeaconSent = true;
		}

		if (pDevice->dwIsr & ISR_RXDMA0)
			max_count += device_rx_srv(pDevice, TYPE_RXDMA0);

		if (pDevice->dwIsr & ISR_RXDMA1)
			max_count += device_rx_srv(pDevice, TYPE_RXDMA1);

		if (pDevice->dwIsr & ISR_TXDMA0)
			max_count += device_tx_srv(pDevice, TYPE_TXDMA0);

		if (pDevice->dwIsr & ISR_AC0DMA)
			max_count += device_tx_srv(pDevice, TYPE_AC0DMA);

		if (pDevice->dwIsr & ISR_SOFTTIMER1) {
			if (pDevice->vif) {
				if (pDevice->vif->bss_conf.enable_beacon)
					vnt_beacon_make(pDevice, pDevice->vif);
			}
		}

		/* If both buffers available wake the queue */
		if (pDevice->vif) {
			if (AVAIL_TD(pDevice, TYPE_TXDMA0) &&
			    AVAIL_TD(pDevice, TYPE_AC0DMA) &&
			    ieee80211_queue_stopped(pDevice->hw, 0))
				ieee80211_wake_queues(pDevice->hw);
		}

		MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);

		MACvReceive0(pDevice->PortOffset);
		MACvReceive1(pDevice->PortOffset);

		if (max_count > pDevice->sOpts.int_works)
			break;
	}

	if (byOrgPageSel == 1)
		MACvSelectPage1(pDevice->PortOffset);

	spin_unlock_irqrestore(&pDevice->lock, flags);

	MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);

	return IRQ_RETVAL(handled);
}
Esempio n. 3
0
static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
	struct vnt_tx_desc *head_td;
	u32 dma_idx;
	unsigned long flags;

	spin_lock_irqsave(&priv->lock, flags);

	if (ieee80211_is_data(hdr->frame_control))
		dma_idx = TYPE_AC0DMA;
	else
		dma_idx = TYPE_TXDMA0;

	if (AVAIL_TD(priv, dma_idx) < 1) {
		spin_unlock_irqrestore(&priv->lock, flags);
		ieee80211_stop_queues(priv->hw);
		return -ENOMEM;
	}

	head_td = priv->apCurrTD[dma_idx];

	head_td->td1.tcr = 0;

	head_td->td_info->skb = skb;

	if (dma_idx == TYPE_AC0DMA)
		head_td->td_info->flags = TD_FLAGS_NETIF_SKB;

	priv->apCurrTD[dma_idx] = head_td->next;

	spin_unlock_irqrestore(&priv->lock, flags);

	vnt_generate_fifo_header(priv, dma_idx, head_td, skb);

	spin_lock_irqsave(&priv->lock, flags);

	priv->bPWBitOn = false;

	/* Set TSR1 & ReqCount in TxDescHead */
	head_td->td1.tcr |= (TCR_STP | TCR_EDP | EDMSDU);
	head_td->td1.req_count = cpu_to_le16(head_td->td_info->req_count);

	head_td->buff_addr = cpu_to_le32(head_td->td_info->buf_dma);

	/* Poll Transmit the adapter */
	wmb();
	head_td->td0.owner = OWNED_BY_NIC;
	wmb(); /* second memory barrier */

	if (head_td->td_info->flags & TD_FLAGS_NETIF_SKB)
		MACvTransmitAC0(priv->PortOffset);
	else
		MACvTransmit0(priv->PortOffset);

	priv->iTDUsed[dma_idx]++;

	spin_unlock_irqrestore(&priv->lock, flags);

	return 0;
}
Esempio n. 4
0
static void vnt_interrupt_process(struct vnt_private *priv)
{
	struct ieee80211_low_level_stats *low_stats = &priv->low_stats;
	int             max_count = 0;
	u32 mib_counter;
	u32 isr;
	unsigned long flags;

	MACvReadISR(priv->PortOffset, &isr);

	if (isr == 0)
		return;

	if (isr == 0xffffffff) {
		pr_debug("isr = 0xffff\n");
		return;
	}

	MACvIntDisable(priv->PortOffset);

	spin_lock_irqsave(&priv->lock, flags);

	/* Read low level stats */
	MACvReadMIBCounter(priv->PortOffset, &mib_counter);

	low_stats->dot11RTSSuccessCount += mib_counter & 0xff;
	low_stats->dot11RTSFailureCount += (mib_counter >> 8) & 0xff;
	low_stats->dot11ACKFailureCount += (mib_counter >> 16) & 0xff;
	low_stats->dot11FCSErrorCount += (mib_counter >> 24) & 0xff;

	/*
	 * TBD....
	 * Must do this after doing rx/tx, cause ISR bit is slow
	 * than RD/TD write back
	 * update ISR counter
	 */
	while (isr && priv->vif) {
		MACvWriteISR(priv->PortOffset, isr);

		if (isr & ISR_FETALERR) {
			pr_debug(" ISR_FETALERR\n");
			VNSvOutPortB(priv->PortOffset + MAC_REG_SOFTPWRCTL, 0);
			VNSvOutPortW(priv->PortOffset +
				     MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPECTI);
			device_error(priv, isr);
		}

		if (isr & ISR_TBTT) {
			if (priv->op_mode != NL80211_IFTYPE_ADHOC)
				vnt_check_bb_vga(priv);

			priv->bBeaconSent = false;
			if (priv->bEnablePSMode)
				PSbIsNextTBTTWakeUp((void *)priv);

			if ((priv->op_mode == NL80211_IFTYPE_AP ||
			    priv->op_mode == NL80211_IFTYPE_ADHOC) &&
			    priv->vif->bss_conf.enable_beacon) {
				MACvOneShotTimer1MicroSec(priv->PortOffset,
							  (priv->vif->bss_conf.beacon_int - MAKE_BEACON_RESERVED) << 10);
			}

			/* TODO: adhoc PS mode */

		}

		if (isr & ISR_BNTX) {
			if (priv->op_mode == NL80211_IFTYPE_ADHOC) {
				priv->bIsBeaconBufReadySet = false;
				priv->cbBeaconBufReadySetCnt = 0;
			}

			priv->bBeaconSent = true;
		}

		if (isr & ISR_RXDMA0)
			max_count += device_rx_srv(priv, TYPE_RXDMA0);

		if (isr & ISR_RXDMA1)
			max_count += device_rx_srv(priv, TYPE_RXDMA1);

		if (isr & ISR_TXDMA0)
			max_count += device_tx_srv(priv, TYPE_TXDMA0);

		if (isr & ISR_AC0DMA)
			max_count += device_tx_srv(priv, TYPE_AC0DMA);

		if (isr & ISR_SOFTTIMER1) {
			if (priv->vif->bss_conf.enable_beacon)
				vnt_beacon_make(priv, priv->vif);
		}

		/* If both buffers available wake the queue */
		if (AVAIL_TD(priv, TYPE_TXDMA0) &&
		    AVAIL_TD(priv, TYPE_AC0DMA) &&
		    ieee80211_queue_stopped(priv->hw, 0))
			ieee80211_wake_queues(priv->hw);

		MACvReadISR(priv->PortOffset, &isr);

		MACvReceive0(priv->PortOffset);
		MACvReceive1(priv->PortOffset);

		if (max_count > priv->sOpts.int_works)
			break;
	}

	spin_unlock_irqrestore(&priv->lock, flags);

	MACvIntEnable(priv->PortOffset, IMR_MASK_VALUE);
}
Esempio n. 5
0
/*
 * Description:
 *      Relay packet.  Return TRUE if packet is copy to DMA1
 *
 * Parameters:
 *  In:
 *      pDevice             -
 *      pbySkbData          - rx packet skb data
 *  Out:
 *      TURE, FALSE
 *
 * Return Value: TRUE if packet duplicate; otherwise FALSE
 *
 */
BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeIndex)
{
    PSMgmtObject    pMgmt = pDevice->pMgmt;
    PSTxDesc        pHeadTD, pLastTD;
    UINT            cbFrameBodySize;
    UINT            uMACfragNum;
    BYTE            byPktType;
    BOOL            bNeedEncryption = FALSE;
    SKeyItem        STempKey;
    PSKeyItem       pTransmitKey = NULL;
    UINT            cbHeaderSize;
    UINT            ii;
    PBYTE           pbyBSSID;




    if (AVAIL_TD(pDevice, TYPE_AC0DMA)<=0) {
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Relay can't allocate TD1..\n");
        return FALSE;
    }

    pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA];

    pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);

    memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)pbySkbData, U_HEADER_LEN);

    cbFrameBodySize = uDataLen - U_HEADER_LEN;

    if (ntohs(pDevice->sTxEthHeader.wType) > MAX_DATA_LEN) {
        cbFrameBodySize += 8;
    }

    if (pDevice->bEncryptionEnable == TRUE) {
        bNeedEncryption = TRUE;

        // get group key
        pbyBSSID = pDevice->abyBroadcastAddr;
        if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
            pTransmitKey = NULL;
            DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
        } else {
            DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
        }
    }

    if (pDevice->bEnableHostWEP) {
        if (uNodeIndex >= 0) {
            pTransmitKey = &STempKey;
            pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
            pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
            pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
            pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
            pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
            memcpy(pTransmitKey->abyKey,
                &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
                pTransmitKey->uKeyLength
                );
        }
    }

    uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader);

    if (uMACfragNum > AVAIL_TD(pDevice,TYPE_AC0DMA)) {
        return FALSE;
    }
    byPktType = (BYTE)pDevice->byPacketType;

    if (pDevice->bFixRate) {
        if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
            if (pDevice->uConnectionRate >= RATE_11M) {
                pDevice->wCurrentRate = RATE_11M;
            } else {
                pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
            }
        } else {
            if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) &&
                (pDevice->uConnectionRate <= RATE_6M)) {
                pDevice->wCurrentRate = RATE_6M;
            } else {
                if (pDevice->uConnectionRate >= RATE_54M)
                    pDevice->wCurrentRate = RATE_54M;
                else
                    pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
            }
        }
    }
    else {
        pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
    }

    if (pDevice->wCurrentRate <= RATE_11M)
        byPktType = PK_TYPE_11B;

    vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption,
                        cbFrameBodySize, TYPE_AC0DMA, pHeadTD,
                        &pDevice->sTxEthHeader, pbySkbData, pTransmitKey, uNodeIndex,
                        &uMACfragNum,
                        &cbHeaderSize
                        );

    if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
        // Disable PS
        MACbPSWakeup(pDevice->PortOffset);
    }

    pDevice->bPWBitOn = FALSE;

    pLastTD = pHeadTD;
    for (ii = 0; ii < uMACfragNum; ii++) {
        // Poll Transmit the adapter
        wmb();
        pHeadTD->m_td0TD0.f1Owner=OWNED_BY_NIC;
        wmb();
        if (ii == (uMACfragNum - 1))
            pLastTD = pHeadTD;
        pHeadTD = pHeadTD->next;
    }

    pLastTD->pTDInfo->skb = 0;
    pLastTD->pTDInfo->byFlags = 0;

    pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD;

    MACvTransmitAC0(pDevice->PortOffset);

    return TRUE;
}