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; }
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); }
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; }
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); }
/* * 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; }