From 8dba599d89711b4f731fcc1d135de5ffd69eb360 Mon Sep 17 00:00:00 2001 From: Florian Schilhabel Date: Sat, 6 Mar 2010 20:45:25 +0100 Subject: [PATCH] staging: rtl8192su: cleanup of r819xU_cmdpkt.c, r819xU_cmdpkt.c Signed-off-by: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/r819xU_cmdpkt.c | 1216 ++++++++++++----------------- drivers/staging/rtl8192su/r819xU_cmdpkt.h | 390 +++++---- 2 files changed, 690 insertions(+), 916 deletions(-) rewrite drivers/staging/rtl8192su/r819xU_cmdpkt.c (67%) rewrite drivers/staging/rtl8192su/r819xU_cmdpkt.h (96%) diff --git a/drivers/staging/rtl8192su/r819xU_cmdpkt.c b/drivers/staging/rtl8192su/r819xU_cmdpkt.c dissimilarity index 67% index 3ebfe79bb66..9b377bae47b 100644 --- a/drivers/staging/rtl8192su/r819xU_cmdpkt.c +++ b/drivers/staging/rtl8192su/r819xU_cmdpkt.c @@ -1,717 +1,499 @@ -/****************************************************************************** - - (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved. - - Module: r819xusb_cmdpkt.c (RTL8190 TX/RX command packet handler Source C File) - - Note: The module is responsible for handling TX and RX command packet. - 1. TX : Send set and query configuration command packet. - 2. RX : Receive tx feedback, beacon state, query configuration - command packet. - - Function: - - Export: - - Abbrev: - - History: - Data Who Remark - - 05/06/2008 amy Create initial version porting from windows driver. - -******************************************************************************/ -#include "r8192U.h" -#include "r819xU_cmdpkt.h" -/*---------------------------Define Local Constant---------------------------*/ -/* Debug constant*/ -#define CMPK_DEBOUNCE_CNT 1 -/* 2007/10/24 MH Add for printing a range of data. */ -#define CMPK_PRINT(Address)\ -{\ - unsigned char i;\ - u32 temp[10];\ - \ - memcpy(temp, Address, 40);\ - for (i = 0; i <40; i+=4)\ - printk("\r\n %08x", temp[i]);\ -}\ -/*---------------------------Define functions---------------------------------*/ - -bool -SendTxCommandPacket( - struct net_device *dev, - void* pData, - u32 DataLen - ) -{ - bool rtStatus = true; - struct r8192_priv *priv = ieee80211_priv(dev); - struct sk_buff *skb; - cb_desc *tcb_desc; - unsigned char *ptr_buf; - //bool bLastInitPacket = false; - - //PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); - - //Get TCB and local buffer from common pool. (It is shared by CmdQ, MgntQ, and USB coalesce DataQ) - skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + DataLen + 4); - memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev)); - tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE); - tcb_desc->queue_index = TXCMD_QUEUE; - tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_NORMAL; - tcb_desc->bLastIniPkt = 0; - skb_reserve(skb, USB_HWDESC_HEADER_LEN); - ptr_buf = skb_put(skb, DataLen); - memset(ptr_buf,0,DataLen); - memcpy(ptr_buf,pData,DataLen); - tcb_desc->txbuf_size= (u16)DataLen; - - if(!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)|| - (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\ - (priv->ieee80211->queue_stop) ) { - RT_TRACE(COMP_FIRMWARE,"===================NULL packet==================================> tx full!\n"); - skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb); - } else { - priv->ieee80211->softmac_hard_start_xmit(skb,dev); - } - - //PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); - return rtStatus; -} - -/*----------------------------------------------------------------------------- - * Function: cmpk_message_handle_tx() - * - * Overview: Driver internal module can call the API to send message to - * firmware side. For example, you can send a debug command packet. - * Or you can send a request for FW to modify RLX4181 LBUS HW bank. - * Otherwise, you can change MAC/PHT/RF register by firmware at - * run time. We do not support message more than one segment now. - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 05/06/2008 amy porting from windows code. - * - *---------------------------------------------------------------------------*/ - extern bool cmpk_message_handle_tx( - struct net_device *dev, - u8* codevirtualaddress, - u32 packettype, - u32 buffer_len) -{ - - bool rt_status = true; - return rt_status; -} /* CMPK_Message_Handle_Tx */ - -/*----------------------------------------------------------------------------- - * Function: cmpk_counttxstatistic() - * - * Overview: - * - * Input: PADAPTER pAdapter - . - * CMPK_TXFB_T *psTx_FB - . - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 05/12/2008 amy Create Version 0 porting from windows code. - * - *---------------------------------------------------------------------------*/ -static void -cmpk_count_txstatistic( - struct net_device *dev, - cmpk_txfb_t *pstx_fb) -{ - struct r8192_priv *priv = ieee80211_priv(dev); -#ifdef ENABLE_PS - RT_RF_POWER_STATE rtState; - - pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); - - // When RF is off, we should not count the packet for hw/sw synchronize - // reason, ie. there may be a duration while sw switch is changed and hw - // switch is being changed. 2006.12.04, by shien chang. - if (rtState == eRfOff) - { - return; - } -#endif - -#ifdef TODO - if(pAdapter->bInHctTest) - return; -#endif - /* We can not know the packet length and transmit type: broadcast or uni - or multicast. So the relative statistics must be collected in tx - feedback info. */ - if (pstx_fb->tok) - { - priv->stats.txfeedbackok++; - priv->stats.txoktotal++; - priv->stats.txokbytestotal += pstx_fb->pkt_length; - priv->stats.txokinperiod++; - - /* We can not make sure broadcast/multicast or unicast mode. */ - if (pstx_fb->pkt_type == PACKET_MULTICAST) - { - priv->stats.txmulticast++; - priv->stats.txbytesmulticast += pstx_fb->pkt_length; - } - else if (pstx_fb->pkt_type == PACKET_BROADCAST) - { - priv->stats.txbroadcast++; - priv->stats.txbytesbroadcast += pstx_fb->pkt_length; - } - else - { - priv->stats.txunicast++; - priv->stats.txbytesunicast += pstx_fb->pkt_length; - } - } - else - { - priv->stats.txfeedbackfail++; - priv->stats.txerrtotal++; - priv->stats.txerrbytestotal += pstx_fb->pkt_length; - - /* We can not make sure broadcast/multicast or unicast mode. */ - if (pstx_fb->pkt_type == PACKET_MULTICAST) - { - priv->stats.txerrmulticast++; - } - else if (pstx_fb->pkt_type == PACKET_BROADCAST) - { - priv->stats.txerrbroadcast++; - } - else - { - priv->stats.txerrunicast++; - } - } - - priv->stats.txretrycount += pstx_fb->retry_cnt; - priv->stats.txfeedbackretry += pstx_fb->retry_cnt; - -} /* cmpk_CountTxStatistic */ - - - -/*----------------------------------------------------------------------------- - * Function: cmpk_handle_tx_feedback() - * - * Overview: The function is responsible for extract the message inside TX - * feedbck message from firmware. It will contain dedicated info in - * ws-06-0063-rtl8190-command-packet-specification. Please - * refer to chapter "TX Feedback Element". We have to read 20 bytes - * in the command packet. - * - * Input: struct net_device * dev - * u8 * pmsg - Msg Ptr of the command packet. - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 05/08/2008 amy Create Version 0 porting from windows code. - * - *---------------------------------------------------------------------------*/ -static void -cmpk_handle_tx_feedback( - struct net_device *dev, - u8 * pmsg) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - cmpk_txfb_t rx_tx_fb; /* */ - - priv->stats.txfeedback++; - - /* 0. Display received message. */ - //cmpk_Display_Message(CMPK_RX_TX_FB_SIZE, pMsg); - - /* 1. Extract TX feedback info from RFD to temp structure buffer. */ - - /* 2007/07/05 MH Use pointer to transfer structure memory. */ - //memcpy((UINT8 *)&rx_tx_fb, pMsg, sizeof(CMPK_TXFB_T)); - memcpy((u8*)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t)); - /* 2. Use tx feedback info to count TX statistics. */ - cmpk_count_txstatistic(dev, &rx_tx_fb); - - /* 2007/01/17 MH Comment previous method for TX statistic function. */ - /* Collect info TX feedback packet to fill TCB. */ - /* We can not know the packet length and transmit type: broadcast or uni - or multicast. */ - //CountTxStatistics( pAdapter, &tcb ); - -} /* cmpk_Handle_Tx_Feedback */ - -void -cmdpkt_beacontimerinterrupt_819xusb( - struct net_device *dev -) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u16 tx_rate; - { - // - // 070117, rcnjko: 87B have to S/W beacon for DTM encryption_cmn. - // - if(priv->ieee80211->current_network.mode == IEEE_A || - priv->ieee80211->current_network.mode == IEEE_N_5G || - (priv->ieee80211->current_network.mode == IEEE_N_24G && (!priv->ieee80211->pHTInfo->bCurSuppCCK))) - { - tx_rate = 60; - DMESG("send beacon frame tx rate is 6Mbpm\n"); - } - else - { - tx_rate =10; - DMESG("send beacon frame tx rate is 1Mbpm\n"); - } - - rtl819xusb_beacon_tx(dev,tx_rate); // HW Beacon - - } - -} - - - - -/*----------------------------------------------------------------------------- - * Function: cmpk_handle_interrupt_status() - * - * Overview: The function is responsible for extract the message from - * firmware. It will contain dedicated info in - * ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc. - * Please refer to chapter "Interrupt Status Element". - * - * Input: struct net_device *dev, - * u8* pmsg - Message Pointer of the command packet. - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 05/12/2008 amy Add this for rtl8192 porting from windows code. - * - *---------------------------------------------------------------------------*/ -static void -cmpk_handle_interrupt_status( - struct net_device *dev, - u8* pmsg) -{ - cmpk_intr_sta_t rx_intr_status; /* */ - struct r8192_priv *priv = ieee80211_priv(dev); - - DMESG("---> cmpk_Handle_Interrupt_Status()\n"); - - /* 0. Display received message. */ - //cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg); - - /* 1. Extract TX feedback info from RFD to temp structure buffer. */ - /* It seems that FW use big endian(MIPS) and DRV use little endian in - windows OS. So we have to read the content byte by byte or transfer - endian type before copy the message copy. */ - //rx_bcn_state.Element_ID = pMsg[0]; - //rx_bcn_state.Length = pMsg[1]; - rx_intr_status.length = pmsg[1]; - if (rx_intr_status.length != (sizeof(cmpk_intr_sta_t) - 2)) - { - DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n"); - return; - } - - - // Statistics of beacon for ad-hoc mode. - if( priv->ieee80211->iw_mode == IW_MODE_ADHOC) - { - //2 maybe need endian transform? - rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4)); - //rx_intr_status.InterruptStatus = N2H4BYTE(*((UINT32 *)(pMsg + 4))); - - DMESG("interrupt status = 0x%x\n", rx_intr_status.interrupt_status); - - if (rx_intr_status.interrupt_status & ISR_TxBcnOk) - { - priv->ieee80211->bibsscoordinator = true; - priv->stats.txbeaconokint++; - } - else if (rx_intr_status.interrupt_status & ISR_TxBcnErr) - { - priv->ieee80211->bibsscoordinator = false; - priv->stats.txbeaconerr++; - } - - if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr) - { - cmdpkt_beacontimerinterrupt_819xusb(dev); - } - - } - - // Other informations in interrupt status we need? - - - DMESG("<---- cmpk_handle_interrupt_status()\n"); - -} /* cmpk_handle_interrupt_status */ - - -/*----------------------------------------------------------------------------- - * Function: cmpk_handle_query_config_rx() - * - * Overview: The function is responsible for extract the message from - * firmware. It will contain dedicated info in - * ws-06-0063-rtl8190-command-packet-specification. Please - * refer to chapter "Beacon State Element". - * - * Input: u8 * pmsg - Message Pointer of the command packet. - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 05/12/2008 amy Create Version 0 porting from windows code. - * - *---------------------------------------------------------------------------*/ -static void -cmpk_handle_query_config_rx( - struct net_device *dev, - u8* pmsg) -{ - cmpk_query_cfg_t rx_query_cfg; /* */ - - /* 0. Display received message. */ - //cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg); - - /* 1. Extract TX feedback info from RFD to temp structure buffer. */ - /* It seems that FW use big endian(MIPS) and DRV use little endian in - windows OS. So we have to read the content byte by byte or transfer - endian type before copy the message copy. */ - //rx_query_cfg.Element_ID = pMsg[0]; - //rx_query_cfg.Length = pMsg[1]; - rx_query_cfg.cfg_action = (pmsg[4] & 0x80000000)>>31; - rx_query_cfg.cfg_type = (pmsg[4] & 0x60) >> 5; - rx_query_cfg.cfg_size = (pmsg[4] & 0x18) >> 3; - rx_query_cfg.cfg_page = (pmsg[6] & 0x0F) >> 0; - rx_query_cfg.cfg_offset = pmsg[7]; - rx_query_cfg.value = (pmsg[8] << 24) | (pmsg[9] << 16) | - (pmsg[10] << 8) | (pmsg[11] << 0); - rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) | - (pmsg[14] << 8) | (pmsg[15] << 0); - -} /* cmpk_Handle_Query_Config_Rx */ - - -/*----------------------------------------------------------------------------- - * Function: cmpk_count_tx_status() - * - * Overview: Count aggregated tx status from firmwar of one type rx command - * packet element id = RX_TX_STATUS. - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 05/12/2008 amy Create Version 0 porting from windows code. - * - *---------------------------------------------------------------------------*/ -static void cmpk_count_tx_status( struct net_device *dev, - cmpk_tx_status_t *pstx_status) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - -#ifdef ENABLE_PS - - RT_RF_POWER_STATE rtstate; - - pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); - - // When RF is off, we should not count the packet for hw/sw synchronize - // reason, ie. there may be a duration while sw switch is changed and hw - // switch is being changed. 2006.12.04, by shien chang. - if (rtState == eRfOff) - { - return; - } -#endif - - priv->stats.txfeedbackok += pstx_status->txok; - priv->stats.txoktotal += pstx_status->txok; - - priv->stats.txfeedbackfail += pstx_status->txfail; - priv->stats.txerrtotal += pstx_status->txfail; - - priv->stats.txretrycount += pstx_status->txretry; - priv->stats.txfeedbackretry += pstx_status->txretry; - - //pAdapter->TxStats.NumTxOkBytesTotal += psTx_FB->pkt_length; - //pAdapter->TxStats.NumTxErrBytesTotal += psTx_FB->pkt_length; - //pAdapter->MgntInfo.LinkDetectInfo.NumTxOkInPeriod++; - - priv->stats.txmulticast += pstx_status->txmcok; - priv->stats.txbroadcast += pstx_status->txbcok; - priv->stats.txunicast += pstx_status->txucok; - - priv->stats.txerrmulticast += pstx_status->txmcfail; - priv->stats.txerrbroadcast += pstx_status->txbcfail; - priv->stats.txerrunicast += pstx_status->txucfail; - - priv->stats.txbytesmulticast += pstx_status->txmclength; - priv->stats.txbytesbroadcast += pstx_status->txbclength; - priv->stats.txbytesunicast += pstx_status->txuclength; - - priv->stats.last_packet_rate = pstx_status->rate; -} /* cmpk_CountTxStatus */ - - - -/*----------------------------------------------------------------------------- - * Function: cmpk_handle_tx_status() - * - * Overview: Firmware add a new tx feedback status to reduce rx command - * packet buffer operation load. - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 05/12/2008 amy Create Version 0 porting from windows code. - * - *---------------------------------------------------------------------------*/ -static void -cmpk_handle_tx_status( - struct net_device *dev, - u8* pmsg) -{ - cmpk_tx_status_t rx_tx_sts; /* */ - - memcpy((void*)&rx_tx_sts, (void*)pmsg, sizeof(cmpk_tx_status_t)); - /* 2. Use tx feedback info to count TX statistics. */ - cmpk_count_tx_status(dev, &rx_tx_sts); - -} /* cmpk_Handle_Tx_Status */ - - -/*----------------------------------------------------------------------------- - * Function: cmpk_handle_tx_rate_history() - * - * Overview: Firmware add a new tx rate history - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 05/12/2008 amy Create Version 0 porting from windows code. - * - *---------------------------------------------------------------------------*/ -static void -cmpk_handle_tx_rate_history( - struct net_device *dev, - u8* pmsg) -{ - cmpk_tx_rahis_t *ptxrate; -// RT_RF_POWER_STATE rtState; - u8 i, j; - u16 length = sizeof(cmpk_tx_rahis_t); - u32 *ptemp; - struct r8192_priv *priv = ieee80211_priv(dev); - - -#ifdef ENABLE_PS - pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); - - // When RF is off, we should not count the packet for hw/sw synchronize - // reason, ie. there may be a duration while sw switch is changed and hw - // switch is being changed. 2006.12.04, by shien chang. - if (rtState == eRfOff) - { - return; - } -#endif - - ptemp = (u32 *)pmsg; - - // - // Do endian transfer to word alignment(16 bits) for windows system. - // You must do different endian transfer for linux and MAC OS - // - for (i = 0; i < (length/4); i++) - { - u16 temp1, temp2; - - temp1 = ptemp[i]&0x0000FFFF; - temp2 = ptemp[i]>>16; - ptemp[i] = (temp1<<16)|temp2; - } - - ptxrate = (cmpk_tx_rahis_t *)pmsg; - - if (ptxrate == NULL ) - { - return; - } - - for (i = 0; i < 16; i++) - { - // Collect CCK rate packet num - if (i < 4) - priv->stats.txrate.cck[i] += ptxrate->cck[i]; - - // Collect OFDM rate packet num - if (i< 8) - priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i]; - - for (j = 0; j < 4; j++) - priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i]; - } - -} /* cmpk_Handle_Tx_Rate_History */ - - -/*----------------------------------------------------------------------------- - * Function: cmpk_message_handle_rx() - * - * Overview: In the function, we will capture different RX command packet - * info. Every RX command packet element has different message - * length and meaning in content. We only support three type of RX - * command packet now. Please refer to document - * ws-06-0063-rtl8190-command-packet-specification. - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 05/06/2008 amy Create Version 0 porting from windows code. - * - *---------------------------------------------------------------------------*/ -extern u32 -cmpk_message_handle_rx( - struct net_device *dev, - struct ieee80211_rx_stats *pstats) -{ -// u32 debug_level = DBG_LOUD; - struct r8192_priv *priv = ieee80211_priv(dev); - int total_length; - u8 cmd_length, exe_cnt = 0; - u8 element_id; - u8 *pcmd_buff; - - /* 0. Check inpt arguments. If is is a command queue message or pointer is - null. */ - if (/*(prfd->queue_id != CMPK_RX_QUEUE_ID) || */(pstats== NULL)) - { - /* Print error message. */ - /*RT_TRACE(COMP_SEND, DebugLevel, - ("\n\r[CMPK]-->Err queue id or pointer"));*/ - return 0; /* This is not a command packet. */ - } - - /* 1. Read received command packet message length from RFD. */ - total_length = pstats->Length; - - /* 2. Read virtual address from RFD. */ - pcmd_buff = pstats->virtual_address; - - /* 3. Read command pakcet element id and length. */ - element_id = pcmd_buff[0]; - /*RT_TRACE(COMP_SEND, DebugLevel, - ("\n\r[CMPK]-->element ID=%d Len=%d", element_id, total_length));*/ - - /* 4. Check every received command packet conent according to different - element type. Because FW may aggregate RX command packet to minimize - transmit time between DRV and FW.*/ - // Add a counter to prevent to locked in the loop too long - while (total_length > 0 || exe_cnt++ >100) - { - /* 2007/01/17 MH We support aggregation of different cmd in the same packet. */ - element_id = pcmd_buff[0]; - - switch(element_id) - { - case RX_TX_FEEDBACK: - cmpk_handle_tx_feedback (dev, pcmd_buff); - cmd_length = CMPK_RX_TX_FB_SIZE; - break; - - case RX_INTERRUPT_STATUS: - cmpk_handle_interrupt_status(dev, pcmd_buff); - cmd_length = sizeof(cmpk_intr_sta_t); - break; - - case BOTH_QUERY_CONFIG: - cmpk_handle_query_config_rx(dev, pcmd_buff); - cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE; - break; - - case RX_TX_STATUS: - cmpk_handle_tx_status(dev, pcmd_buff); - cmd_length = CMPK_RX_TX_STS_SIZE; - break; - - case RX_TX_PER_PKT_FEEDBACK: - // You must at lease add a switch case element here, - // Otherwise, we will jump to default case. - //DbgPrint("CCX Test\r\n"); - cmd_length = CMPK_RX_TX_FB_SIZE; - break; - - case RX_TX_RATE_HISTORY: - //DbgPrint(" rx tx rate history\r\n"); - cmpk_handle_tx_rate_history(dev, pcmd_buff); - cmd_length = CMPK_TX_RAHIS_SIZE; - break; - - default: - - RT_TRACE(COMP_ERR, "---->cmpk_message_handle_rx():unknown CMD Element\n"); - return 1; /* This is a command packet. */ - } - // 2007/01/22 MH Display received rx command packet info. - //cmpk_Display_Message(cmd_length, pcmd_buff); - - // 2007/01/22 MH Add to display tx statistic. - //cmpk_DisplayTxStatistic(pAdapter); - - /* 2007/03/09 MH Collect sidderent cmd element pkt num. */ - priv->stats.rxcmdpkt[element_id]++; - - total_length -= cmd_length; - pcmd_buff += cmd_length; - } /* while (total_length > 0) */ - return 1; /* This is a command packet. */ - -} /* CMPK_Message_Handle_Rx */ +/* + * (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved. + * + * Module: r819xusb_cmdpkt.c + * (RTL8190 TX/RX command packet handler Source C File) + * + * Note: The module is responsible for handling TX and RX command packet. + * 1.TX: Send set and query configuration command packet. + * 2.RX: Receive tx feedback, beacon state, query configuration, command packet. + */ +#include "r8192U.h" +#include "r819xU_cmdpkt.h" + +bool SendTxCommandPacket(struct net_device *dev, void *pData, u32 DataLen) +{ + bool rtStatus = true; + struct r8192_priv *priv = ieee80211_priv(dev); + struct sk_buff *skb; + cb_desc *tcb_desc; + unsigned char *ptr_buf; + + /* PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); */ + + /* + * Get TCB and local buffer from common pool. + * (It is shared by CmdQ, MgntQ, and USB coalesce DataQ) + */ + skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + DataLen + 4); + memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); + tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + tcb_desc->queue_index = TXCMD_QUEUE; + tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_NORMAL; + tcb_desc->bLastIniPkt = 0; + skb_reserve(skb, USB_HWDESC_HEADER_LEN); + ptr_buf = skb_put(skb, DataLen); + memset(ptr_buf, 0, DataLen); + memcpy(ptr_buf, pData, DataLen); + tcb_desc->txbuf_size = (u16)DataLen; + + if (!priv->ieee80211->check_nic_enough_desc(dev, tcb_desc->queue_index) || + (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) || + (priv->ieee80211->queue_stop)) { + RT_TRACE(COMP_FIRMWARE, "NULL packet => tx full\n"); + skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb); + } else { + priv->ieee80211->softmac_hard_start_xmit(skb, dev); + } + + //PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); + return rtStatus; +} + +/* + * Function: cmpk_message_handle_tx() + * + * Overview: Driver internal module can call the API to send message to + * firmware side. For example, you can send a debug command packet. + * Or you can send a request for FW to modify RLX4181 LBUS HW bank. + * Otherwise, you can change MAC/PHT/RF register by firmware at + * run time. We do not support message more than one segment now. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + */ + extern bool cmpk_message_handle_tx( + struct net_device *dev, + u8 *codevirtualaddress, + u32 packettype, + u32 buffer_len) +{ + bool rt_status = true; + return rt_status; +} + +/* + * Function: cmpk_counttxstatistic() + */ +static void +cmpk_count_txstatistic(struct net_device *dev, cmpk_txfb_t *pstx_fb) +{ + struct r8192_priv *priv = ieee80211_priv(dev); +#ifdef ENABLE_PS + RT_RF_POWER_STATE rtState; + + pAdapter->HalFunc.GetHwRegHandler(pAdapter, + HW_VAR_RF_STATE, + (pu1Byte)(&rtState)); + + /* + * When RF is off, we should not count the packet for hw/sw synchronize + * reason, ie. there may be a duration while sw switch is changed and hw + * switch is being changed. + */ + if (rtState == eRfOff) + return; +#endif + +#ifdef TODO + if (pAdapter->bInHctTest) + return; +#endif + /* + * We can not know the packet length and transmit type: + * broadcast or uni or multicast. + * So the relative statistics must be collected in tx feedback info + */ + if (pstx_fb->tok) { + priv->stats.txfeedbackok++; + priv->stats.txoktotal++; + priv->stats.txokbytestotal += pstx_fb->pkt_length; + priv->stats.txokinperiod++; + /* We can not make sure broadcast/multicast or unicast mode. */ + if (pstx_fb->pkt_type == PACKET_MULTICAST) { + priv->stats.txmulticast++; + priv->stats.txbytesmulticast += pstx_fb->pkt_length; + } else if (pstx_fb->pkt_type == PACKET_BROADCAST) { + priv->stats.txbroadcast++; + priv->stats.txbytesbroadcast += pstx_fb->pkt_length; + } else { + priv->stats.txunicast++; + priv->stats.txbytesunicast += pstx_fb->pkt_length; + } + } else { + priv->stats.txfeedbackfail++; + priv->stats.txerrtotal++; + priv->stats.txerrbytestotal += pstx_fb->pkt_length; + /* We can not make sure broadcast/multicast or unicast mode. */ + if (pstx_fb->pkt_type == PACKET_MULTICAST) + priv->stats.txerrmulticast++; + else if (pstx_fb->pkt_type == PACKET_BROADCAST) + priv->stats.txerrbroadcast++; + else + priv->stats.txerrunicast++; + } + priv->stats.txretrycount += pstx_fb->retry_cnt; + priv->stats.txfeedbackretry += pstx_fb->retry_cnt; +} + +/* + * Function: cmpk_handle_tx_feedback() + * + * Overview: The function is responsible for extract the message inside TX + * feedbck message from firmware. It will contain dedicated info in + * ws-06-0063-rtl8190-command-packet-specification. Please + * refer to chapter "TX Feedback Element". We have to read 20 bytes + * in the command packet. + * + * Input: struct net_device * dev + * u8 *pmsg - Msg Ptr of the command packet. + * + * Output: NONE + * + * Return: NONE + */ +static void cmpk_handle_tx_feedback(struct net_device *dev, u8 *pmsg) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + cmpk_txfb_t rx_tx_fb; + + priv->stats.txfeedback++; + + /* 1. Extract TX feedback info from RFD to temp structure buffer. */ + memcpy((u8 *)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t)); + + /* 2. Use tx feedback info to count TX statistics. */ + cmpk_count_txstatistic(dev, &rx_tx_fb); +} + +void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u16 tx_rate; + + if (priv->ieee80211->current_network.mode == IEEE_A || + priv->ieee80211->current_network.mode == IEEE_N_5G || + (priv->ieee80211->current_network.mode == IEEE_N_24G && + (!priv->ieee80211->pHTInfo->bCurSuppCCK))) { + tx_rate = 60; + DMESG("send beacon frame tx rate is 6Mbpm\n"); + } else { + tx_rate = 10; + DMESG("send beacon frame tx rate is 1Mbpm\n"); + } + rtl819xusb_beacon_tx(dev, tx_rate); /* HW Beacon */ +} + +/* + * Function: cmpk_handle_interrupt_status() + * + * Overview: The function is responsible for extract the message from + * firmware. It will contain dedicated info in + * ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc. + * Please refer to chapter "Interrupt Status Element". + * + * Input: struct net_device *dev, + * u8* pmsg - Message Pointer of the command packet. + * + * Output: NONE + * + * Return: NONE + */ +static void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg) +{ + cmpk_intr_sta_t rx_intr_status; /* */ + struct r8192_priv *priv = ieee80211_priv(dev); + + DMESG("---> cmpk_Handle_Interrupt_Status()\n"); + + /* 1. Extract TX feedback info from RFD to temp structure buffer. */ + rx_intr_status.length = pmsg[1]; + if (rx_intr_status.length != (sizeof(cmpk_intr_sta_t) - 2)) { + DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n"); + return; + } + /* Statistics of beacon for ad-hoc mode. */ + if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) { + //2 maybe need endian transform? + rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4)); + //rx_intr_status.InterruptStatus = N2H4BYTE(*((UINT32 *)(pMsg + 4))); + + DMESG("interrupt status = 0x%x\n", rx_intr_status.interrupt_status); + + if (rx_intr_status.interrupt_status & ISR_TxBcnOk) { + priv->ieee80211->bibsscoordinator = true; + priv->stats.txbeaconokint++; + } else if (rx_intr_status.interrupt_status & ISR_TxBcnErr) { + priv->ieee80211->bibsscoordinator = false; + priv->stats.txbeaconerr++; + } + + if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr) + cmdpkt_beacontimerinterrupt_819xusb(dev); + } + /* Other informations in interrupt status we need? */ + DMESG("<---- cmpk_handle_interrupt_status()\n"); +} + +/* + * Function: cmpk_handle_query_config_rx() + * + * Overview: The function is responsible for extract the message from + * firmware. It will contain dedicated info in + * ws-06-0063-rtl8190-command-packet-specification + * Please refer to chapter "Beacon State Element". + * + * Input: u8 * pmsg - Message Pointer of the command packet. + * + * Output: NONE + * + * Return: NONE + * + */ +static void cmpk_handle_query_config_rx(struct net_device *dev, u8 *pmsg) +{ + cmpk_query_cfg_t rx_query_cfg; + /* + * Extract TX feedback info from RFD to temp structure buffer. + */ + rx_query_cfg.cfg_action = (pmsg[4] & 0x80000000) >> 31; + rx_query_cfg.cfg_type = (pmsg[4] & 0x60) >> 5; + rx_query_cfg.cfg_size = (pmsg[4] & 0x18) >> 3; + rx_query_cfg.cfg_page = (pmsg[6] & 0x0F) >> 0; + rx_query_cfg.cfg_offset = pmsg[7]; + rx_query_cfg.value = (pmsg[8] << 24) | (pmsg[9] << 16) | + (pmsg[10] << 8) | (pmsg[11] << 0); + rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) | + (pmsg[14] << 8) | (pmsg[15] << 0); +} + +/* + * Function: cmpk_count_tx_status() + * + * Overview: Count aggregated tx status from firmware of one type rx command + * packet element id = RX_TX_STATUS. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + */ +static void cmpk_count_tx_status(struct net_device *dev, + cmpk_tx_status_t *pstx_status) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + +#ifdef ENABLE_PS + + RT_RF_POWER_STATE rtstate; + + pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); + + /* + * When RF is off, we should not count the packet for hw/sw synchronize + * reason, ie. there may be a duration while sw switch is changed and hw + * switch is being changed. + */ + if (rtState == eRfOff) + return; +#endif + + priv->stats.txfeedbackok += pstx_status->txok; + priv->stats.txoktotal += pstx_status->txok; + + priv->stats.txfeedbackfail += pstx_status->txfail; + priv->stats.txerrtotal += pstx_status->txfail; + + priv->stats.txretrycount += pstx_status->txretry; + priv->stats.txfeedbackretry += pstx_status->txretry; + + priv->stats.txmulticast += pstx_status->txmcok; + priv->stats.txbroadcast += pstx_status->txbcok; + priv->stats.txunicast += pstx_status->txucok; + + priv->stats.txerrmulticast += pstx_status->txmcfail; + priv->stats.txerrbroadcast += pstx_status->txbcfail; + priv->stats.txerrunicast += pstx_status->txucfail; + + priv->stats.txbytesmulticast += pstx_status->txmclength; + priv->stats.txbytesbroadcast += pstx_status->txbclength; + priv->stats.txbytesunicast += pstx_status->txuclength; + + priv->stats.last_packet_rate = pstx_status->rate; +} + +/* + * Function: cmpk_handle_tx_status() + * + * Overview: Firmware add a new tx feedback status to reduce rx command + * packet buffer operation load. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + */ +static void +cmpk_handle_tx_status(struct net_device *dev, u8 *pmsg) +{ + cmpk_tx_status_t rx_tx_sts; + + memcpy((void *)&rx_tx_sts, (void *)pmsg, sizeof(cmpk_tx_status_t)); + /* 2. Use tx feedback info to count TX statistics. */ + cmpk_count_tx_status(dev, &rx_tx_sts); +} + +/* + * Function: cmpk_handle_tx_rate_history() + * + * Overview: Firmware add a new tx rate history + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + */ +static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg) +{ + cmpk_tx_rahis_t *ptxrate; + u8 i, j; + u16 length = sizeof(cmpk_tx_rahis_t); + u32 *ptemp; + struct r8192_priv *priv = ieee80211_priv(dev); + +#ifdef ENABLE_PS + pAdapter->HalFunc.GetHwRegHandler(pAdapter, + HW_VAR_RF_STATE, + (pu1Byte)(&rtState)); + /* + * When RF is off, we should not count the packet for hw/sw synchronize + * reason, ie. there may be a duration while sw switch is changed and hw + * switch is being changed. + */ + if (rtState == eRfOff) + return; +#endif + ptemp = (u32 *)pmsg; + + /* + * Do endian transfer to word alignment(16 bits) for windows system. + * You must do different endian transfer for linux and MAC OS + */ + for (i = 0; i < (length/4); i++) { + u16 temp1, temp2; + temp1 = ptemp[i] & 0x0000FFFF; + temp2 = ptemp[i] >> 16; + ptemp[i] = (temp1 << 16) | temp2; + } + + ptxrate = (cmpk_tx_rahis_t *)pmsg; + + if (ptxrate == NULL) + return; + + for (i = 0; i < 16; i++) { + /* Collect CCK rate packet num */ + if (i < 4) + priv->stats.txrate.cck[i] += ptxrate->cck[i]; + /* Collect OFDM rate packet num */ + if (i < 8) + priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i]; + for (j = 0; j < 4; j++) + priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i]; + } + +} + +/* + * Function: cmpk_message_handle_rx() + * + * Overview: In the function, we will capture different RX command packet + * info. Every RX command packet element has different message + * length and meaning in content. We only support three type of RX + * command packet now. Please refer to document + * ws-06-0063-rtl8190-command-packet-specification. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + */ +extern u32 +cmpk_message_handle_rx( + struct net_device *dev, + struct ieee80211_rx_stats *pstats) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + int total_length; + u8 cmd_length, exe_cnt = 0; + u8 element_id; + u8 *pcmd_buff; + + /* + * 0. Check input arguments. + * If is is a command queue message or pointer is null + */ + if ((pstats == NULL)) + return 0; /* This is not a command packet. */ + + /* 1. Read received command packet message length from RFD. */ + total_length = pstats->Length; + + /* 2. Read virtual address from RFD. */ + pcmd_buff = pstats->virtual_address; + + /* 3. Read command pakcet element id and length. */ + element_id = pcmd_buff[0]; + + /* + * 4. Check every received command packet conent according to different + * element type. Because FW may aggregate RX command packet to minimize + * transmit time between DRV and FW. + */ + + /* Add a counter to prevent to locked in the loop too long */ + while (total_length > 0 || exe_cnt++ > 100) { + /* We support aggregation of different cmd in the same packet */ + element_id = pcmd_buff[0]; + switch (element_id) { + case RX_TX_FEEDBACK: + cmpk_handle_tx_feedback(dev, pcmd_buff); + cmd_length = CMPK_RX_TX_FB_SIZE; + break; + case RX_INTERRUPT_STATUS: + cmpk_handle_interrupt_status(dev, pcmd_buff); + cmd_length = sizeof(cmpk_intr_sta_t); + break; + case BOTH_QUERY_CONFIG: + cmpk_handle_query_config_rx(dev, pcmd_buff); + cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE; + break; + case RX_TX_STATUS: + cmpk_handle_tx_status(dev, pcmd_buff); + cmd_length = CMPK_RX_TX_STS_SIZE; + break; + case RX_TX_PER_PKT_FEEDBACK: + cmd_length = CMPK_RX_TX_FB_SIZE; + break; + case RX_TX_RATE_HISTORY: + cmpk_handle_tx_rate_history(dev, pcmd_buff); + cmd_length = CMPK_TX_RAHIS_SIZE; + break; + default: + RT_TRACE(COMP_ERR, "(%s): unknown CMD Element\n", + __func__); + return 1; /* This is a command packet. */ + } + priv->stats.rxcmdpkt[element_id]++; + total_length -= cmd_length; + pcmd_buff += cmd_length; + } + return 1; /* This is a command packet. */ +} diff --git a/drivers/staging/rtl8192su/r819xU_cmdpkt.h b/drivers/staging/rtl8192su/r819xU_cmdpkt.h dissimilarity index 96% index cced8e0d278..d3c56155188 100644 --- a/drivers/staging/rtl8192su/r819xU_cmdpkt.h +++ b/drivers/staging/rtl8192su/r819xU_cmdpkt.h @@ -1,199 +1,191 @@ -#ifndef R819XUSB_CMDPKT_H -#define R819XUSB_CMDPKT_H -/* Different command packet have dedicated message length and definition. */ -#define CMPK_RX_TX_FB_SIZE sizeof(cmpk_txfb_t) //20 -#define CMPK_TX_SET_CONFIG_SIZE sizeof(cmpk_set_cfg_t) //16 -#define CMPK_BOTH_QUERY_CONFIG_SIZE sizeof(cmpk_set_cfg_t) //16 -#define CMPK_RX_TX_STS_SIZE sizeof(cmpk_tx_status_t)// -#define CMPK_RX_DBG_MSG_SIZE sizeof(cmpk_rx_dbginfo_t)// -#define CMPK_TX_RAHIS_SIZE sizeof(cmpk_tx_rahis_t) - -/* 2008/05/08 amy For USB constant. */ -#define ISR_TxBcnOk BIT27 // Transmit Beacon OK -#define ISR_TxBcnErr BIT26 // Transmit Beacon Error -#define ISR_BcnTimerIntr BIT13 // Beacon Timer Interrupt - -/* Define element ID of command packet. */ - -/*------------------------------Define structure----------------------------*/ -/* Define different command packet structure. */ -/* 1. RX side: TX feedback packet. */ -typedef struct tag_cmd_pkt_tx_feedback -{ - // DWORD 0 - u8 element_id; /* Command packet type. */ - u8 length; /* Command packet length. */ - /* 2007/07/05 MH Change tx feedback info field. */ - /*------TX Feedback Info Field */ - u8 TID:4; /* */ - u8 fail_reason:3; /* */ - u8 tok:1; /* Transmit ok. */ - u8 reserve1:4; /* */ - u8 pkt_type:2; /* */ - u8 bandwidth:1; /* */ - u8 qos_pkt:1; /* */ - - // DWORD 1 - u8 reserve2; /* */ - /*------TX Feedback Info Field */ - u8 retry_cnt; /* */ - u16 pkt_id; /* */ - - // DWORD 3 - u16 seq_num; /* */ - u8 s_rate; /* Start rate. */ - u8 f_rate; /* Final rate. */ - - // DWORD 4 - u8 s_rts_rate; /* */ - u8 f_rts_rate; /* */ - u16 pkt_length; /* */ - - // DWORD 5 - u16 reserve3; /* */ - u16 duration; /* */ -}cmpk_txfb_t; - -/* 2. RX side: Interrupt status packet. It includes Beacon State, - Beacon Timer Interrupt and other useful informations in MAC ISR Reg. */ -typedef struct tag_cmd_pkt_interrupt_status -{ - u8 element_id; /* Command packet type. */ - u8 length; /* Command packet length. */ - u16 reserve; - u32 interrupt_status; /* Interrupt Status. */ -}cmpk_intr_sta_t; - - -/* 3. TX side: Set configuration packet. */ -typedef struct tag_cmd_pkt_set_configuration -{ - u8 element_id; /* Command packet type. */ - u8 length; /* Command packet length. */ - u16 reserve1; /* */ - u8 cfg_reserve1:3; - u8 cfg_size:2; /* Configuration info. */ - u8 cfg_type:2; /* Configuration info. */ - u8 cfg_action:1; /* Configuration info. */ - u8 cfg_reserve2; /* Configuration info. */ - u8 cfg_page:4; /* Configuration info. */ - u8 cfg_reserve3:4; /* Configuration info. */ - u8 cfg_offset; /* Configuration info. */ - u32 value; /* */ - u32 mask; /* */ -}cmpk_set_cfg_t; - -/* 4. Both side : TX/RX query configuraton packet. The query structure is the - same as set configuration. */ -#define cmpk_query_cfg_t cmpk_set_cfg_t - -/* 5. Multi packet feedback status. */ -typedef struct tag_tx_stats_feedback // PJ quick rxcmd 09042007 -{ - // For endian transfer --> Driver will not the same as firmware structure. - // DW 0 - u16 reserve1; - u8 length; // Command packet length - u8 element_id; // Command packet type - - // DW 1 - u16 txfail; // Tx Fail count - u16 txok; // Tx ok count - - // DW 2 - u16 txmcok; // tx multicast - u16 txretry; // Tx Retry count - - // DW 3 - u16 txucok; // tx unicast - u16 txbcok; // tx broadcast - - // DW 4 - u16 txbcfail; // - u16 txmcfail; // - - // DW 5 - u16 reserve2; // - u16 txucfail; // - - // DW 6-8 - u32 txmclength; - u32 txbclength; - u32 txuclength; - - // DW 9 - u16 reserve3_23; - u8 reserve3_1; - u8 rate; -}__attribute__((packed)) cmpk_tx_status_t; - -/* 6. Debug feedback message. */ -/* 2007/10/23 MH Define RX debug message */ -typedef struct tag_rx_debug_message_feedback -{ - // For endian transfer --> for driver - // DW 0 - u16 reserve1; - u8 length; // Command packet length - u8 element_id; // Command packet type - - // DW 1-?? - // Variable debug message. - -}cmpk_rx_dbginfo_t; - -/* 2008/03/20 MH Define transmit rate history. For big endian format. */ -typedef struct tag_tx_rate_history -{ - // For endian transfer --> for driver - // DW 0 - u8 element_id; // Command packet type - u8 length; // Command packet length - u16 reserved1; - - // DW 1-2 CCK rate counter - u16 cck[4]; - - // DW 3-6 - u16 ofdm[8]; - - // DW 7-14 - //UINT16 MCS_BW0_SG0[16]; - - // DW 15-22 - //UINT16 MCS_BW1_SG0[16]; - - // DW 23-30 - //UINT16 MCS_BW0_SG1[16]; - - // DW 31-38 - //UINT16 MCS_BW1_SG1[16]; - - // DW 7-14 BW=0 SG=0 - // DW 15-22 BW=1 SG=0 - // DW 23-30 BW=0 SG=1 - // DW 31-38 BW=1 SG=1 - u16 ht_mcs[4][16]; - -}__attribute__((packed)) cmpk_tx_rahis_t; - -typedef enum tag_command_packet_directories -{ - RX_TX_FEEDBACK = 0, - RX_INTERRUPT_STATUS = 1, - TX_SET_CONFIG = 2, - BOTH_QUERY_CONFIG = 3, - RX_TX_STATUS = 4, - RX_DBGINFO_FEEDBACK = 5, - RX_TX_PER_PKT_FEEDBACK = 6, - RX_TX_RATE_HISTORY = 7, - RX_CMD_ELE_MAX -}cmpk_element_e; - -extern bool cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, u32 packettype, u32 buffer_len); - -extern u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats * pstats); -extern bool SendTxCommandPacket( struct net_device *dev, void* pData, u32 DataLen); - - -#endif +#ifndef R819XUSB_CMDPKT_H +#define R819XUSB_CMDPKT_H + +/* + * Different command packets have dedicated message length and definition. + */ +#define CMPK_RX_TX_FB_SIZE sizeof(cmpk_txfb_t) /* 20 */ +#define CMPK_TX_SET_CONFIG_SIZE sizeof(cmpk_set_cfg_t) /* 16 */ +#define CMPK_BOTH_QUERY_CONFIG_SIZE sizeof(cmpk_set_cfg_t) /* 16 */ +#define CMPK_RX_TX_STS_SIZE sizeof(cmpk_tx_status_t) +#define CMPK_RX_DBG_MSG_SIZE sizeof(cmpk_rx_dbginfo_t) +#define CMPK_TX_RAHIS_SIZE sizeof(cmpk_tx_rahis_t) + +/* For USB constant. */ +#define ISR_TxBcnOk BIT27 /* Transmit Beacon OK */ +#define ISR_TxBcnErr BIT26 /* Transmit Beacon Error */ +#define ISR_BcnTimerIntr BIT13 /* Beacon Timer Interrupt */ + +/* + * Define different command packet structures + * + * 1. RX side: TX feedback packet. + */ +typedef struct tag_cmd_pkt_tx_feedback { + /* DWORD 0 */ + u8 element_id; /* Command packet type. */ + u8 length; /* Command packet length. */ + /* TX Feedback Info Field */ + u8 TID:4; + u8 fail_reason:3; + u8 tok:1; /* Transmit ok. */ + u8 reserve1:4; + u8 pkt_type:2; + u8 bandwidth:1; + u8 qos_pkt:1; + + /* DWORD 1 */ + u8 reserve2; + /* TX Feedback Info Field */ + u8 retry_cnt; + u16 pkt_id; + + /* DWORD 3 */ + u16 seq_num; + u8 s_rate; /* Start rate. */ + u8 f_rate; /* Final rate. */ + + /* DWORD 4 */ + u8 s_rts_rate; + u8 f_rts_rate; + u16 pkt_length; + + /* DWORD 5 */ + u16 reserve3; + u16 duration; +} cmpk_txfb_t; + +/* + * 2. RX side: Interrupt status packet. + * It includes Beacon State, Beacon Timer Interrupt + * and other useful informations in MAC ISR Reg. + */ +typedef struct tag_cmd_pkt_interrupt_status { + u8 element_id; /* Command packet type. */ + u8 length; /* Command packet length. */ + u16 reserve; + u32 interrupt_status; /* Interrupt Status. */ +} cmpk_intr_sta_t; + + +/* + * 3. TX side: Set configuration packet. + */ +typedef struct tag_cmd_pkt_set_configuration { + u8 element_id; /* Command packet type. */ + u8 length; /* Command packet length. */ + u16 reserve1; + u8 cfg_reserve1:3; + u8 cfg_size:2; /* Configuration info. */ + u8 cfg_type:2; /* Configuration info. */ + u8 cfg_action:1; /* Configuration info. */ + u8 cfg_reserve2; /* Configuration info. */ + u8 cfg_page:4; /* Configuration info. */ + u8 cfg_reserve3:4; /* Configuration info. */ + u8 cfg_offset; /* Configuration info. */ + u32 value; + u32 mask; +} cmpk_set_cfg_t; + +/* + * 4. Both side : TX/RX query configuraton packet. + * The query structure is the same as set configuration. + */ +#define cmpk_query_cfg_t cmpk_set_cfg_t + +/* + * 5. Multi packet feedback status. + */ +typedef struct tag_tx_stats_feedback { + /* + * For endian transfer + * Driver will not the same as firmware structure. + */ + /* DW 0 */ + u16 reserve1; + u8 length; /* Command packet length */ + u8 element_id; /* Command packet type */ + + /* DW 1 */ + u16 txfail; /* Tx Fail count */ + u16 txok; /* Tx ok count */ + + /* DW 2 */ + u16 txmcok; /* tx multicast */ + u16 txretry; /* Tx Retry count */ + + /* DW 3 */ + u16 txucok; /* tx unicast */ + u16 txbcok; /* tx broadcast */ + + /* DW 4 */ + u16 txbcfail; + u16 txmcfail; + + /* DW 5 */ + u16 reserve2; + u16 txucfail; + + /* DW 6-8 */ + u32 txmclength; + u32 txbclength; + u32 txuclength; + + /* DW 9 */ + u16 reserve3_23; + u8 reserve3_1; + u8 rate; +} __attribute__((packed)) cmpk_tx_status_t; + +/* + * 6. Debug feedback message. + */ +typedef struct tag_rx_debug_message_feedback { + /* For endian transfer --> for driver */ + /* DW 0 */ + u16 reserve1; + u8 length; /* Command packet length */ + u8 element_id; /* Command packet type */ +} cmpk_rx_dbginfo_t; + +/* + * Define transmit rate history. For big endian format. + */ +typedef struct tag_tx_rate_history { + /* For endian transfer --> for driver */ + /* DW 0 */ + u8 element_id; /* Command packet type */ + u8 length; /* Command packet length */ + u16 reserved1; + /* DW 1-2 CCK rate counter */ + u16 cck[4]; + /* DW 3-6 */ + u16 ofdm[8]; + u16 ht_mcs[4][16]; +} __attribute__((packed)) cmpk_tx_rahis_t; + +typedef enum tag_command_packet_directories { + RX_TX_FEEDBACK = 0, + RX_INTERRUPT_STATUS = 1, + TX_SET_CONFIG = 2, + BOTH_QUERY_CONFIG = 3, + RX_TX_STATUS = 4, + RX_DBGINFO_FEEDBACK = 5, + RX_TX_PER_PKT_FEEDBACK = 6, + RX_TX_RATE_HISTORY = 7, + RX_CMD_ELE_MAX +} cmpk_element_e; + +extern bool cmpk_message_handle_tx(struct net_device *dev, + u8 *codevirtualaddress, + u32 packettype, + u32 buffer_len); + +extern u32 cmpk_message_handle_rx(struct net_device *dev, + struct ieee80211_rx_stats *pstats); + +extern bool SendTxCommandPacket(struct net_device *dev, + void *pData, + u32 DataLen); + +#endif -- 2.11.4.GIT