staging: rtl8192e: Convert typedef cmpk_intr_sta_t to struct cmpk_intr_sta
[firefly-linux-kernel-4.4.55.git] / drivers / staging / rtl8192e / r8192E_cmdpkt.c
1 /******************************************************************************
2  * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3  *
4  * This program is distributed in the hope that it will be useful, but WITHOUT
5  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
7  * more details.
8  *
9  * You should have received a copy of the GNU General Public License along with
10  * this program; if not, write to the Free Software Foundation, Inc.,
11  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
12  *
13  * The full GNU General Public License is included in this distribution in the
14  * file called LICENSE.
15  *
16  * Contact Information:
17  * wlanfae <wlanfae@realtek.com>
18 ******************************************************************************/
19
20 #include "rtl_core.h"
21 #include "r8192E_hw.h"
22 #include "r8192E_cmdpkt.h"
23 /*---------------------------Define Local Constant---------------------------*/
24 /* Debug constant*/
25 #define         CMPK_DEBOUNCE_CNT                       1
26 #define         CMPK_PRINT(Address)\
27 {\
28         unsigned char   i;\
29         u32     temp[10];\
30         \
31         memcpy(temp, Address, 40);\
32         for (i = 0; i <40; i+=4)\
33                 printk("\r\n %08x", temp[i]);\
34 }\
35
36 /*---------------------------Define functions---------------------------------*/
37  extern bool cmpk_message_handle_tx(
38         struct net_device *dev,
39         u8*     code_virtual_address,
40         u32     packettype,
41         u32     buffer_len)
42 {
43
44         bool                            rt_status = true;
45         struct r8192_priv       *priv = rtllib_priv(dev);
46         u16                             frag_threshold;
47         u16                             frag_length = 0, frag_offset = 0;
48         rt_firmware             *pfirmware = priv->pFirmware;
49         struct sk_buff          *skb;
50         unsigned char           *seg_ptr;
51         cb_desc                 *tcb_desc;
52         u8                              bLastIniPkt;
53
54         struct tx_fwinfo_8190pci *pTxFwInfo = NULL;
55
56         RT_TRACE(COMP_CMDPKT,"%s(),buffer_len is %d\n",__func__,buffer_len);
57         firmware_init_param(dev);
58         frag_threshold = pfirmware->cmdpacket_frag_thresold;
59
60         do {
61                 if ((buffer_len - frag_offset) > frag_threshold) {
62                         frag_length = frag_threshold ;
63                         bLastIniPkt = 0;
64
65                 } else {
66                         frag_length =(u16)(buffer_len - frag_offset);
67                         bLastIniPkt = 1;
68                 }
69
70                 skb  = dev_alloc_skb(frag_length + priv->rtllib->tx_headroom + 4);
71
72                 if (skb == NULL) {
73                         rt_status = false;
74                         goto Failed;
75                 }
76
77                 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
78                 tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
79                 tcb_desc->queue_index = TXCMD_QUEUE;
80                 tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_NORMAL;
81                 tcb_desc->bLastIniPkt = bLastIniPkt;
82                 tcb_desc->pkt_size = frag_length;
83
84                 seg_ptr = skb_put(skb, priv->rtllib->tx_headroom);
85                 pTxFwInfo = (struct tx_fwinfo_8190pci *)seg_ptr;
86                 memset(pTxFwInfo,0,sizeof(struct tx_fwinfo_8190pci));
87                 memset(pTxFwInfo,0x12,8);
88
89                 seg_ptr = skb_put(skb, frag_length);
90                 memcpy(seg_ptr, code_virtual_address, (u32)frag_length);
91
92                 priv->rtllib->softmac_hard_start_xmit(skb,dev);
93
94                 code_virtual_address += frag_length;
95                 frag_offset += frag_length;
96
97         }while(frag_offset < buffer_len);
98
99         write_nic_byte(dev, TPPoll, TPPoll_CQ);
100 Failed:
101         return rt_status;
102 }       /* CMPK_Message_Handle_Tx */
103
104 static  void
105 cmpk_count_txstatistic(
106         struct net_device *dev,
107         struct cmpk_txfb *pstx_fb)
108 {
109         struct r8192_priv *priv = rtllib_priv(dev);
110 #ifdef ENABLE_PS
111         RT_RF_POWER_STATE       rtState;
112
113         pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
114
115         if (rtState == eRfOff)
116                 return;
117 #endif
118
119         if (pstx_fb->tok) {
120                 priv->stats.txfeedbackok++;
121                 priv->stats.txoktotal++;
122                 priv->stats.txokbytestotal += pstx_fb->pkt_length;
123                 priv->stats.txokinperiod++;
124
125                 if (pstx_fb->pkt_type == PACKET_MULTICAST) {
126                         priv->stats.txmulticast++;
127                         priv->stats.txbytesmulticast += pstx_fb->pkt_length;
128                 } else if (pstx_fb->pkt_type == PACKET_BROADCAST) {
129                         priv->stats.txbroadcast++;
130                         priv->stats.txbytesbroadcast += pstx_fb->pkt_length;
131                 } else {
132                         priv->stats.txunicast++;
133                         priv->stats.txbytesunicast += pstx_fb->pkt_length;
134                 }
135         } else {
136                 priv->stats.txfeedbackfail++;
137                 priv->stats.txerrtotal++;
138                 priv->stats.txerrbytestotal += pstx_fb->pkt_length;
139
140                 if (pstx_fb->pkt_type == PACKET_MULTICAST)
141                         priv->stats.txerrmulticast++;
142                 else if (pstx_fb->pkt_type == PACKET_BROADCAST)
143                         priv->stats.txerrbroadcast++;
144                 else
145                         priv->stats.txerrunicast++;
146         }
147
148         priv->stats.txretrycount += pstx_fb->retry_cnt;
149         priv->stats.txfeedbackretry += pstx_fb->retry_cnt;
150
151 }       /* cmpk_CountTxStatistic */
152
153
154
155 static  void
156 cmpk_handle_tx_feedback(
157         struct net_device *dev,
158         u8      *       pmsg)
159 {
160         struct r8192_priv *priv = rtllib_priv(dev);
161         struct cmpk_txfb rx_tx_fb;      /* */
162
163         priv->stats.txfeedback++;
164
165
166         memcpy((u8*)&rx_tx_fb, pmsg, sizeof(struct cmpk_txfb));
167         cmpk_count_txstatistic(dev, &rx_tx_fb);
168
169 }       /* cmpk_Handle_Tx_Feedback */
170
171 void
172 cmdpkt_beacontimerinterrupt_819xusb(
173         struct net_device *dev
174 )
175 {
176         struct r8192_priv *priv = rtllib_priv(dev);
177         u16 tx_rate;
178         {
179                 if ((priv->rtllib->current_network.mode == IEEE_A)  ||
180                         (priv->rtllib->current_network.mode == IEEE_N_5G) ||
181                         ((priv->rtllib->current_network.mode == IEEE_N_24G)  && (!priv->rtllib->pHTInfo->bCurSuppCCK)))
182                 {
183                         tx_rate = 60;
184                         DMESG("send beacon frame  tx rate is 6Mbpm\n");
185                 }
186                 else
187                 {
188                         tx_rate =10;
189                         DMESG("send beacon frame  tx rate is 1Mbpm\n");
190                 }
191
192
193         }
194
195 }
196
197 static  void
198 cmpk_handle_interrupt_status(
199         struct net_device *dev,
200         u8*     pmsg)
201 {
202         struct cmpk_intr_sta rx_intr_status;    /* */
203         struct r8192_priv *priv = rtllib_priv(dev);
204
205         DMESG("---> cmpk_Handle_Interrupt_Status()\n");
206
207
208         rx_intr_status.length = pmsg[1];
209         if (rx_intr_status.length != (sizeof(struct cmpk_intr_sta) - 2))
210         {
211                 DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n");
212                 return;
213         }
214
215
216         if (    priv->rtllib->iw_mode == IW_MODE_ADHOC)
217         {
218                 rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4));
219
220                 DMESG("interrupt status = 0x%x\n", rx_intr_status.interrupt_status);
221
222                 if (rx_intr_status.interrupt_status & ISR_TxBcnOk)
223                 {
224                         priv->rtllib->bibsscoordinator = true;
225                         priv->stats.txbeaconokint++;
226                 }
227                 else if (rx_intr_status.interrupt_status & ISR_TxBcnErr)
228                 {
229                         priv->rtllib->bibsscoordinator = false;
230                         priv->stats.txbeaconerr++;
231                 }
232
233                 if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr)
234                 {
235                         cmdpkt_beacontimerinterrupt_819xusb(dev);
236                 }
237
238         }
239
240
241
242         DMESG("<---- cmpk_handle_interrupt_status()\n");
243
244 }       /* cmpk_handle_interrupt_status */
245
246
247 static  void
248 cmpk_handle_query_config_rx(
249         struct net_device *dev,
250         u8*        pmsg)
251 {
252         cmpk_query_cfg_t        rx_query_cfg;   /* */
253
254
255         rx_query_cfg.cfg_action         = (pmsg[4] & 0x80000000)>>31;
256         rx_query_cfg.cfg_type           = (pmsg[4] & 0x60) >> 5;
257         rx_query_cfg.cfg_size           = (pmsg[4] & 0x18) >> 3;
258         rx_query_cfg.cfg_page           = (pmsg[6] & 0x0F) >> 0;
259         rx_query_cfg.cfg_offset                 = pmsg[7];
260         rx_query_cfg.value                      = (pmsg[8] << 24) | (pmsg[9] << 16) |
261                                                                   (pmsg[10] << 8) | (pmsg[11] << 0);
262         rx_query_cfg.mask                       = (pmsg[12] << 24) | (pmsg[13] << 16) |
263                                                                   (pmsg[14] << 8) | (pmsg[15] << 0);
264
265 }       /* cmpk_Handle_Query_Config_Rx */
266
267
268 static  void    cmpk_count_tx_status(   struct net_device *dev,
269                                                                         cmpk_tx_status_t        *pstx_status)
270 {
271         struct r8192_priv *priv = rtllib_priv(dev);
272
273 #ifdef ENABLE_PS
274
275         RT_RF_POWER_STATE       rtstate;
276
277         pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
278
279         if (rtState == eRfOff)
280         {
281                 return;
282         }
283 #endif
284
285         priv->stats.txfeedbackok        += pstx_status->txok;
286         priv->stats.txoktotal           += pstx_status->txok;
287
288         priv->stats.txfeedbackfail      += pstx_status->txfail;
289         priv->stats.txerrtotal          += pstx_status->txfail;
290
291         priv->stats.txretrycount                += pstx_status->txretry;
292         priv->stats.txfeedbackretry     += pstx_status->txretry;
293
294
295         priv->stats.txmulticast += pstx_status->txmcok;
296         priv->stats.txbroadcast += pstx_status->txbcok;
297         priv->stats.txunicast           += pstx_status->txucok;
298
299         priv->stats.txerrmulticast      += pstx_status->txmcfail;
300         priv->stats.txerrbroadcast      += pstx_status->txbcfail;
301         priv->stats.txerrunicast        += pstx_status->txucfail;
302
303         priv->stats.txbytesmulticast    += pstx_status->txmclength;
304         priv->stats.txbytesbroadcast    += pstx_status->txbclength;
305         priv->stats.txbytesunicast              += pstx_status->txuclength;
306
307         priv->stats.last_packet_rate            = pstx_status->rate;
308 }       /* cmpk_CountTxStatus */
309
310
311
312 static  void
313 cmpk_handle_tx_status(
314         struct net_device *dev,
315         u8*        pmsg)
316 {
317         cmpk_tx_status_t        rx_tx_sts;      /* */
318
319         memcpy((void*)&rx_tx_sts, (void*)pmsg, sizeof(cmpk_tx_status_t));
320         cmpk_count_tx_status(dev, &rx_tx_sts);
321
322 }
323
324
325 static  void
326 cmpk_handle_tx_rate_history(
327         struct net_device *dev,
328         u8*        pmsg)
329 {
330         cmpk_tx_rahis_t *ptxrate;
331         u8                              i, j;
332         u16                             length = sizeof(cmpk_tx_rahis_t);
333         u32                             *ptemp;
334         struct r8192_priv *priv = rtllib_priv(dev);
335
336
337 #ifdef ENABLE_PS
338         pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
339
340         if (rtState == eRfOff)
341         {
342                 return;
343         }
344 #endif
345
346         ptemp = (u32 *)pmsg;
347
348         for (i = 0; i < (length/4); i++)
349         {
350                 u16      temp1, temp2;
351
352                 temp1 = ptemp[i]&0x0000FFFF;
353                 temp2 = ptemp[i]>>16;
354                 ptemp[i] = (temp1<<16)|temp2;
355         }
356
357         ptxrate = (cmpk_tx_rahis_t *)pmsg;
358
359         if (ptxrate == NULL )
360         {
361                 return;
362         }
363
364         for (i = 0; i < 16; i++)
365         {
366                 if (i < 4)
367                         priv->stats.txrate.cck[i] += ptxrate->cck[i];
368
369                 if (i< 8)
370                         priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i];
371
372                 for (j = 0; j < 4; j++)
373                         priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i];
374         }
375
376 }
377
378
379 extern  u32
380 cmpk_message_handle_rx(
381         struct net_device *dev,
382         struct rtllib_rx_stats *pstats)
383 {
384         struct r8192_priv *priv = rtllib_priv(dev);
385         int                     total_length;
386         u8                      cmd_length, exe_cnt = 0;
387         u8                      element_id;
388         u8                      *pcmd_buff;
389
390         RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx()\n");
391
392         if (/*(prfd->queue_id != CMPK_RX_QUEUE_ID) || */(pstats== NULL))
393         {
394                 /* Print error message. */
395                 /*RT_TRACE(COMP_SEND, DebugLevel,
396                                 ("\n\r[CMPK]-->Err queue id or pointer"));*/
397                 return 0;
398         }
399
400         total_length = pstats->Length;
401
402         pcmd_buff = pstats->virtual_address;
403
404         element_id = pcmd_buff[0];
405
406         while (total_length > 0 || exe_cnt++ >100)
407         {
408                 element_id = pcmd_buff[0];
409
410                 switch (element_id) {
411                 case RX_TX_FEEDBACK:
412                         RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():RX_TX_FEEDBACK\n");
413                         cmpk_handle_tx_feedback (dev, pcmd_buff);
414                         cmd_length = CMPK_RX_TX_FB_SIZE;
415                         break;
416                 case RX_INTERRUPT_STATUS:
417                         RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():RX_INTERRUPT_STATUS\n");
418                         cmpk_handle_interrupt_status(dev, pcmd_buff);
419                         cmd_length = sizeof(struct cmpk_intr_sta);
420                         break;
421                 case BOTH_QUERY_CONFIG:
422                         RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():BOTH_QUERY_CONFIG\n");
423                         cmpk_handle_query_config_rx(dev, pcmd_buff);
424                         cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE;
425                         break;
426                 case RX_TX_STATUS:
427                         RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():RX_TX_STATUS\n");
428                         cmpk_handle_tx_status(dev, pcmd_buff);
429                         cmd_length = CMPK_RX_TX_STS_SIZE;
430                         break;
431                 case RX_TX_PER_PKT_FEEDBACK:
432                         RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():RX_TX_PER_PKT_FEEDBACK\n");
433                         cmd_length = CMPK_RX_TX_FB_SIZE;
434                         break;
435                 case RX_TX_RATE_HISTORY:
436                         RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():RX_TX_HISTORY\n");
437                         cmpk_handle_tx_rate_history(dev, pcmd_buff);
438                         cmd_length = CMPK_TX_RAHIS_SIZE;
439                         break;
440                 default:
441
442                         RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():unknow CMD Element\n");
443                         return 1;
444                 }
445
446                 priv->stats.rxcmdpkt[element_id]++;
447
448                 total_length -= cmd_length;
449                 pcmd_buff    += cmd_length;
450         }
451         return  1;
452
453         RT_TRACE(COMP_CMDPKT, "<----cmpk_message_handle_rx()\n");
454 }