194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/****************************************************************************** 294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. 394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * 494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * This program is distributed in the hope that it will be useful, but WITHOUT 594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * more details. 894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * 994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * You should have received a copy of the GNU General Public License along with 1094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * this program; if not, write to the Free Software Foundation, Inc., 1194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 1294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * 1394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * The full GNU General Public License is included in this distribution in the 1494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * file called LICENSE. 1594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * 1694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Contact Information: 1794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * wlanfae <wlanfae@realtek.com> 1894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger******************************************************************************/ 1994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 2094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include "rtl_core.h" 2194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include "r8192E_hw.h" 2294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include "r8192E_cmdpkt.h" 2394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/*---------------------------Define Local Constant---------------------------*/ 2494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/* Debug constant*/ 2594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#define CMPK_DEBOUNCE_CNT 1 2694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#define CMPK_PRINT(Address)\ 2794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{\ 2894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger unsigned char i;\ 2994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 temp[10];\ 3094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger \ 3194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger memcpy(temp, Address, 40);\ 32ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger for (i = 0; i < 40; i += 4)\ 33ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger printk(KERN_INFO "\r\n %08x", temp[i]);\ 34ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger} 3594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 3694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/*---------------------------Define functions---------------------------------*/ 3749aab5fd9df153a73992afa7cc386661d759c8e3Larry Fingerbool cmpk_message_handle_tx( 3894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct net_device *dev, 39ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger u8 *code_virtual_address, 4094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 packettype, 4194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 buffer_len) 4294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 4394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 4494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger bool rt_status = true; 45e3e3762996b7c089c44db5ace166563e66957bd0Larry Finger struct r8192_priv *priv = rtllib_priv(dev); 4694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u16 frag_threshold; 4794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u16 frag_length = 0, frag_offset = 0; 485aca114d91e726db89d28e56f260b811cc76a3ddLarry Finger struct rt_firmware *pfirmware = priv->pFirmware; 4994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct sk_buff *skb; 5094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger unsigned char *seg_ptr; 513b83db43ccbb26863f38caccc1e7fae370f31e57Larry Finger struct cb_desc *tcb_desc; 5294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u8 bLastIniPkt; 5394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 54a07dc3d145334fec51f1b773a47e84cd1d36c3ecLarry Finger struct tx_fwinfo_8190pci *pTxFwInfo = NULL; 5594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 56ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger RT_TRACE(COMP_CMDPKT, "%s(),buffer_len is %d\n", __func__, buffer_len); 5794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger firmware_init_param(dev); 5894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger frag_threshold = pfirmware->cmdpacket_frag_thresold; 5994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 6094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger do { 6194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if ((buffer_len - frag_offset) > frag_threshold) { 6294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger frag_length = frag_threshold ; 6394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger bLastIniPkt = 0; 6494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 6594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else { 66ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger frag_length = (u16)(buffer_len - frag_offset); 6794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger bLastIniPkt = 1; 6894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 6994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 70ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger skb = dev_alloc_skb(frag_length + 71ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger priv->rtllib->tx_headroom + 4); 7294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 7394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (skb == NULL) { 7494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger rt_status = false; 7594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger goto Failed; 7694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 7794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 78ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); 793b83db43ccbb26863f38caccc1e7fae370f31e57Larry Finger tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); 8094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tcb_desc->queue_index = TXCMD_QUEUE; 8194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_NORMAL; 8294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tcb_desc->bLastIniPkt = bLastIniPkt; 8394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tcb_desc->pkt_size = frag_length; 8494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 8594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger seg_ptr = skb_put(skb, priv->rtllib->tx_headroom); 86a07dc3d145334fec51f1b773a47e84cd1d36c3ecLarry Finger pTxFwInfo = (struct tx_fwinfo_8190pci *)seg_ptr; 87ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger memset(pTxFwInfo, 0, sizeof(struct tx_fwinfo_8190pci)); 88ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger memset(pTxFwInfo, 0x12, 8); 8994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 9094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger seg_ptr = skb_put(skb, frag_length); 9194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger memcpy(seg_ptr, code_virtual_address, (u32)frag_length); 9294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 93ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger priv->rtllib->softmac_hard_start_xmit(skb, dev); 9494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 9594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger code_virtual_address += frag_length; 9694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger frag_offset += frag_length; 9794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 98ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger } while (frag_offset < buffer_len); 9994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 10094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger write_nic_byte(dev, TPPoll, TPPoll_CQ); 10194a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerFailed: 10294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return rt_status; 10394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} /* CMPK_Message_Handle_Tx */ 10494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 10594a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void 10694a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingercmpk_count_txstatistic( 10794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct net_device *dev, 108d3ab7211bd49b4df8e1469f73aa17662319d6c66Larry Finger struct cmpk_txfb *pstx_fb) 10994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 11094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct r8192_priv *priv = rtllib_priv(dev); 11194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#ifdef ENABLE_PS 112de7c885a248ad79380bf1b3425738e436a7790ffLarry Finger enum rt_rf_power_state rtState; 11394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 114ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, 115ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger (pu1Byte)(&rtState)); 11694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 11794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (rtState == eRfOff) 11894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return; 11994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#endif 12094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 121cb76215448947ddcc133c4b1c2ff2d4a77e851e0Mike McCormack if (pstx_fb->tok) { 12294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txfeedbackok++; 12394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txoktotal++; 12494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txokbytestotal += pstx_fb->pkt_length; 12594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txokinperiod++; 12694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 127cb76215448947ddcc133c4b1c2ff2d4a77e851e0Mike McCormack if (pstx_fb->pkt_type == PACKET_MULTICAST) { 12894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txmulticast++; 12994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txbytesmulticast += pstx_fb->pkt_length; 130cb76215448947ddcc133c4b1c2ff2d4a77e851e0Mike McCormack } else if (pstx_fb->pkt_type == PACKET_BROADCAST) { 13194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txbroadcast++; 13294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txbytesbroadcast += pstx_fb->pkt_length; 133cb76215448947ddcc133c4b1c2ff2d4a77e851e0Mike McCormack } else { 13494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txunicast++; 13594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txbytesunicast += pstx_fb->pkt_length; 13694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 137cb76215448947ddcc133c4b1c2ff2d4a77e851e0Mike McCormack } else { 13894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txfeedbackfail++; 13994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txerrtotal++; 14094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txerrbytestotal += pstx_fb->pkt_length; 14194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 14294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (pstx_fb->pkt_type == PACKET_MULTICAST) 14394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txerrmulticast++; 14494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (pstx_fb->pkt_type == PACKET_BROADCAST) 14594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txerrbroadcast++; 14694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 14794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txerrunicast++; 14894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 14994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 15094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txretrycount += pstx_fb->retry_cnt; 15194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txfeedbackretry += pstx_fb->retry_cnt; 15294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 15394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} /* cmpk_CountTxStatistic */ 15494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 15594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 15694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 157ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Fingerstatic void cmpk_handle_tx_feedback(struct net_device *dev, u8 *pmsg) 15894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 15994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct r8192_priv *priv = rtllib_priv(dev); 160d3ab7211bd49b4df8e1469f73aa17662319d6c66Larry Finger struct cmpk_txfb rx_tx_fb; /* */ 16194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 16294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txfeedback++; 16394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 16494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 165ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger memcpy((u8 *)&rx_tx_fb, pmsg, sizeof(struct cmpk_txfb)); 16694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger cmpk_count_txstatistic(dev, &rx_tx_fb); 16794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 16894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} /* cmpk_Handle_Tx_Feedback */ 16994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 17049aab5fd9df153a73992afa7cc386661d759c8e3Larry Fingerstatic void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev) 17194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 17294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct r8192_priv *priv = rtllib_priv(dev); 17394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u16 tx_rate; 17494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 175ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger if ((priv->rtllib->current_network.mode == IEEE_A) || 176ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger (priv->rtllib->current_network.mode == IEEE_N_5G) || 177ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger ((priv->rtllib->current_network.mode == IEEE_N_24G) && 178ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger (!priv->rtllib->pHTInfo->bCurSuppCCK))) { 179ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger tx_rate = 60; 180ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger DMESG("send beacon frame tx rate is 6Mbpm\n"); 181ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger } else { 182ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger tx_rate = 10; 183ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger DMESG("send beacon frame tx rate is 1Mbpm\n"); 18494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 18594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 18694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 18794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 188ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Fingerstatic void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg) 18994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 190a76d98497eb5b8f2ad723cfcaa58d6f7653243afLarry Finger struct cmpk_intr_sta rx_intr_status; /* */ 19194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct r8192_priv *priv = rtllib_priv(dev); 19294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 19394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger DMESG("---> cmpk_Handle_Interrupt_Status()\n"); 19494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 19594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 19694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger rx_intr_status.length = pmsg[1]; 197ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger if (rx_intr_status.length != (sizeof(struct cmpk_intr_sta) - 2)) { 19894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n"); 19994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return; 20094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 20194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 20294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 203ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger if (priv->rtllib->iw_mode == IW_MODE_ADHOC) { 20494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4)); 20594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 206ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger DMESG("interrupt status = 0x%x\n", 207ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger rx_intr_status.interrupt_status); 20894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 209ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger if (rx_intr_status.interrupt_status & ISR_TxBcnOk) { 21094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->rtllib->bibsscoordinator = true; 21194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txbeaconokint++; 212ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger } else if (rx_intr_status.interrupt_status & ISR_TxBcnErr) { 21394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->rtllib->bibsscoordinator = false; 21494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txbeaconerr++; 21594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 21694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 21794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr) 21894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger cmdpkt_beacontimerinterrupt_819xusb(dev); 21994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 22094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 22194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger DMESG("<---- cmpk_handle_interrupt_status()\n"); 22294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 22394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} /* cmpk_handle_interrupt_status */ 22494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 22594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 226ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Fingerstatic void cmpk_handle_query_config_rx(struct net_device *dev, u8 *pmsg) 22794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 22894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger cmpk_query_cfg_t rx_query_cfg; /* */ 22994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 23094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 231ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger rx_query_cfg.cfg_action = (pmsg[4] & 0x80000000)>>31; 232ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger rx_query_cfg.cfg_type = (pmsg[4] & 0x60) >> 5; 233ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger rx_query_cfg.cfg_size = (pmsg[4] & 0x18) >> 3; 234ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger rx_query_cfg.cfg_page = (pmsg[6] & 0x0F) >> 0; 235ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger rx_query_cfg.cfg_offset = pmsg[7]; 236ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger rx_query_cfg.value = (pmsg[8] << 24) | (pmsg[9] << 16) | 237ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger (pmsg[10] << 8) | (pmsg[11] << 0); 238ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) | 239ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger (pmsg[14] << 8) | (pmsg[15] << 0); 24094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 24194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} /* cmpk_Handle_Query_Config_Rx */ 24294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 24394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 244ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Fingerstatic void cmpk_count_tx_status(struct net_device *dev, 245ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger struct cmpk_tx_status *pstx_status) 24694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 24794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct r8192_priv *priv = rtllib_priv(dev); 24894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 24994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#ifdef ENABLE_PS 25094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 251de7c885a248ad79380bf1b3425738e436a7790ffLarry Finger enum rt_rf_power_state rtstate; 25294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 253ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, 254ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger (pu1Byte)(&rtState)); 25594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 25694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (rtState == eRfOff) 25794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return; 25894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#endif 25994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 26094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txfeedbackok += pstx_status->txok; 26194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txoktotal += pstx_status->txok; 26294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 26394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txfeedbackfail += pstx_status->txfail; 26494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txerrtotal += pstx_status->txfail; 26594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 26694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txretrycount += pstx_status->txretry; 26794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txfeedbackretry += pstx_status->txretry; 26894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 26994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 27094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txmulticast += pstx_status->txmcok; 27194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txbroadcast += pstx_status->txbcok; 27294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txunicast += pstx_status->txucok; 27394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 27494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txerrmulticast += pstx_status->txmcfail; 27594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txerrbroadcast += pstx_status->txbcfail; 27694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txerrunicast += pstx_status->txucfail; 27794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 27894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txbytesmulticast += pstx_status->txmclength; 27994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txbytesbroadcast += pstx_status->txbclength; 28094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txbytesunicast += pstx_status->txuclength; 28194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 28294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.last_packet_rate = pstx_status->rate; 28394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} /* cmpk_CountTxStatus */ 28494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 28594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 28694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 287ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Fingerstatic void cmpk_handle_tx_status(struct net_device *dev, u8 *pmsg) 28894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 2897f6aa06ca2155dd1e6ca62f5ca81c09fbb9a8cb3Larry Finger struct cmpk_tx_status rx_tx_sts; /* */ 29094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 291ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger memcpy((void *)&rx_tx_sts, (void *)pmsg, sizeof(struct cmpk_tx_status)); 29294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger cmpk_count_tx_status(dev, &rx_tx_sts); 29394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 29494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 295ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Fingerstatic void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg) 29694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 2971b419253af60f87c6844c17ef0c0b24d0676cf26Larry Finger struct cmpk_tx_rahis *ptxrate; 298ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger u8 i, j; 2991b419253af60f87c6844c17ef0c0b24d0676cf26Larry Finger u16 length = sizeof(struct cmpk_tx_rahis); 300ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger u32 *ptemp; 30194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct r8192_priv *priv = rtllib_priv(dev); 30294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 30394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 30494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#ifdef ENABLE_PS 305ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, 306ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger (pu1Byte)(&rtState)); 30794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 30894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (rtState == eRfOff) 30994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return; 31094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#endif 31194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 31294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ptemp = (u32 *)pmsg; 31394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 314ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger for (i = 0; i < (length / 4); i++) { 31594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u16 temp1, temp2; 31694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 317ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger temp1 = ptemp[i] & 0x0000FFFF; 318ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger temp2 = ptemp[i] >> 16; 319ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger ptemp[i] = (temp1 << 16) | temp2; 32094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 32194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 3221b419253af60f87c6844c17ef0c0b24d0676cf26Larry Finger ptxrate = (struct cmpk_tx_rahis *)pmsg; 32394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 324ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger if (ptxrate == NULL) 32594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return; 32694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 327ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger for (i = 0; i < 16; i++) { 32894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (i < 4) 32994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txrate.cck[i] += ptxrate->cck[i]; 33094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 331ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger if (i < 8) 33294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i]; 33394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 33494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger for (j = 0; j < 4; j++) 335ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger priv->stats.txrate.ht_mcs[j][i] += 336ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger ptxrate->ht_mcs[j][i]; 33794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 33894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 33994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 34094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 34194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 34249aab5fd9df153a73992afa7cc386661d759c8e3Larry Fingeru32 cmpk_message_handle_rx(struct net_device *dev, 34349aab5fd9df153a73992afa7cc386661d759c8e3Larry Finger struct rtllib_rx_stats *pstats) 34494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 34594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct r8192_priv *priv = rtllib_priv(dev); 34694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int total_length; 34794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u8 cmd_length, exe_cnt = 0; 34894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u8 element_id; 34994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u8 *pcmd_buff; 35094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 35194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx()\n"); 35294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 353ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger if (pstats == NULL) { 35494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* Print error message. */ 35594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /*RT_TRACE(COMP_SEND, DebugLevel, 35694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ("\n\r[CMPK]-->Err queue id or pointer"));*/ 35794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return 0; 35894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 35994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 36094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger total_length = pstats->Length; 36194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 36294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pcmd_buff = pstats->virtual_address; 36394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 36494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger element_id = pcmd_buff[0]; 36594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 366ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger while (total_length > 0 || exe_cnt++ > 100) { 36794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger element_id = pcmd_buff[0]; 36894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 36994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger switch (element_id) { 37094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case RX_TX_FEEDBACK: 371ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():" 372ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger "RX_TX_FEEDBACK\n"); 373ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger cmpk_handle_tx_feedback(dev, pcmd_buff); 37494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger cmd_length = CMPK_RX_TX_FB_SIZE; 37594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 37694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case RX_INTERRUPT_STATUS: 377ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():" 378ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger "RX_INTERRUPT_STATUS\n"); 37994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger cmpk_handle_interrupt_status(dev, pcmd_buff); 380a76d98497eb5b8f2ad723cfcaa58d6f7653243afLarry Finger cmd_length = sizeof(struct cmpk_intr_sta); 38194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 38294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case BOTH_QUERY_CONFIG: 383ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():" 384ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger "BOTH_QUERY_CONFIG\n"); 38594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger cmpk_handle_query_config_rx(dev, pcmd_buff); 38694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE; 38794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 38894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case RX_TX_STATUS: 389ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():" 390ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger "RX_TX_STATUS\n"); 39194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger cmpk_handle_tx_status(dev, pcmd_buff); 39294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger cmd_length = CMPK_RX_TX_STS_SIZE; 39394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 39494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case RX_TX_PER_PKT_FEEDBACK: 395ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():" 396ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger "RX_TX_PER_PKT_FEEDBACK\n"); 39794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger cmd_length = CMPK_RX_TX_FB_SIZE; 39894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 39994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case RX_TX_RATE_HISTORY: 400ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():" 401ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger "RX_TX_HISTORY\n"); 40294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger cmpk_handle_tx_rate_history(dev, pcmd_buff); 40394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger cmd_length = CMPK_TX_RAHIS_SIZE; 40494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 40594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger default: 40694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 407ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():" 408ac513a88a072b23452ca96a86f18ba8b9c0d85cdLarry Finger "unknow CMD Element\n"); 40994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return 1; 41094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 41194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 41294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger priv->stats.rxcmdpkt[element_id]++; 41394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 41494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger total_length -= cmd_length; 41594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pcmd_buff += cmd_length; 41694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 41794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return 1; 41894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 419