1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "r8192E.h"
25#include "r8192E_hw.h"
26#include "r819xE_cmdpkt.h"
27
28
29
30
31
32
33
34
35RT_STATUS cmpk_message_handle_tx(
36 struct r8192_priv *priv,
37 u8* code_virtual_address,
38 u32 packettype,
39 u32 buffer_len)
40{
41 RT_STATUS rt_status = RT_STATUS_SUCCESS;
42 u16 frag_threshold;
43 u16 frag_length = 0, frag_offset = 0;
44 rt_firmware *pfirmware = priv->pFirmware;
45 struct sk_buff *skb;
46 unsigned char *seg_ptr;
47 cb_desc *tcb_desc;
48 u8 bLastIniPkt;
49
50 PTX_FWINFO_8190PCI pTxFwInfo = NULL;
51 int i;
52
53 RT_TRACE(COMP_CMDPKT,"%s(),buffer_len is %d\n",__FUNCTION__,buffer_len);
54 firmware_init_param(priv);
55
56 frag_threshold = pfirmware->cmdpacket_frag_thresold;
57 do {
58 if((buffer_len - frag_offset) > frag_threshold) {
59 frag_length = frag_threshold ;
60 bLastIniPkt = 0;
61
62 } else {
63 frag_length =(u16)(buffer_len - frag_offset);
64 bLastIniPkt = 1;
65
66 }
67
68
69
70
71 skb = dev_alloc_skb(frag_length + priv->ieee80211->tx_headroom + 4);
72 if(skb == NULL) {
73 rt_status = RT_STATUS_FAILURE;
74 goto Failed;
75 }
76
77 tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
78 tcb_desc->queue_index = TXCMD_QUEUE;
79 tcb_desc->bCmdOrInit = packettype;
80 tcb_desc->bLastIniPkt = bLastIniPkt;
81 tcb_desc->pkt_size = frag_length;
82
83
84 seg_ptr = skb_put(skb, priv->ieee80211->tx_headroom);
85
86 pTxFwInfo = (PTX_FWINFO_8190PCI)seg_ptr;
87 memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
88 memset(pTxFwInfo,0x12,8);
89
90 seg_ptr +=sizeof(TX_FWINFO_8190PCI);
91
92
93
94
95
96 seg_ptr = skb_tail_pointer(skb);
97 for(i=0 ; i < frag_length; i+=4) {
98 *seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0;
99 *seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0;
100 *seg_ptr++ = ((i+2)<frag_length)?code_virtual_address[i+1]:0;
101 *seg_ptr++ = ((i+3)<frag_length)?code_virtual_address[i+0]:0;
102 }
103 skb_put(skb, i);
104 priv->ieee80211->softmac_hard_start_xmit(skb, priv->ieee80211);
105
106 code_virtual_address += frag_length;
107 frag_offset += frag_length;
108
109 }while(frag_offset < buffer_len);
110
111Failed:
112 return rt_status;
113}
114
115static void cmpk_count_txstatistic(struct r8192_priv *priv, cmpk_txfb_t *pstx_fb)
116{
117#ifdef ENABLE_PS
118 RT_RF_POWER_STATE rtState;
119
120 pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
121
122
123
124
125 if (rtState == eRfOff)
126 {
127 return;
128 }
129#endif
130
131#ifdef TODO
132 if(pAdapter->bInHctTest)
133 return;
134#endif
135
136
137
138 if (pstx_fb->tok)
139 {
140 priv->stats.txoktotal++;
141
142
143 if (pstx_fb->pkt_type != PACKET_MULTICAST &&
144 pstx_fb->pkt_type != PACKET_BROADCAST) {
145 priv->stats.txbytesunicast += pstx_fb->pkt_length;
146 }
147 }
148}
149
150
151
152
153
154
155
156
157
158
159static void cmpk_handle_tx_feedback(struct r8192_priv *priv, u8 *pmsg)
160{
161 cmpk_txfb_t rx_tx_fb;
162
163 priv->stats.txfeedback++;
164
165 memcpy((u8*)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t));
166
167 cmpk_count_txstatistic(priv, &rx_tx_fb);
168}
169
170
171
172
173
174
175
176
177static void cmpk_handle_interrupt_status(struct r8192_priv *priv, u8 *pmsg)
178{
179 cmpk_intr_sta_t rx_intr_status;
180
181 DMESG("---> cmpk_Handle_Interrupt_Status()\n");
182
183
184
185
186
187
188
189 rx_intr_status.length = pmsg[1];
190 if (rx_intr_status.length != (sizeof(cmpk_intr_sta_t) - 2))
191 {
192 DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n");
193 return;
194 }
195
196
197
198 if( priv->ieee80211->iw_mode == IW_MODE_ADHOC)
199 {
200
201 rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4));
202
203
204 DMESG("interrupt status = 0x%x\n", rx_intr_status.interrupt_status);
205
206 if (rx_intr_status.interrupt_status & ISR_TxBcnOk)
207 {
208 priv->ieee80211->bibsscoordinator = true;
209 priv->stats.txbeaconokint++;
210 }
211 else if (rx_intr_status.interrupt_status & ISR_TxBcnErr)
212 {
213 priv->ieee80211->bibsscoordinator = false;
214 priv->stats.txbeaconerr++;
215 }
216 }
217
218
219
220
221 DMESG("<---- cmpk_handle_interrupt_status()\n");
222
223}
224
225
226
227
228
229
230
231
232static void cmpk_handle_query_config_rx(struct r8192_priv *priv, u8 *pmsg)
233{
234 cmpk_query_cfg_t rx_query_cfg;
235
236
237
238
239
240
241
242
243
244
245 rx_query_cfg.cfg_action = (pmsg[4] & 0x80000000)>>31;
246 rx_query_cfg.cfg_type = (pmsg[4] & 0x60) >> 5;
247 rx_query_cfg.cfg_size = (pmsg[4] & 0x18) >> 3;
248 rx_query_cfg.cfg_page = (pmsg[6] & 0x0F) >> 0;
249 rx_query_cfg.cfg_offset = pmsg[7];
250 rx_query_cfg.value = (pmsg[8] << 24) | (pmsg[9] << 16) |
251 (pmsg[10] << 8) | (pmsg[11] << 0);
252 rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) |
253 (pmsg[14] << 8) | (pmsg[15] << 0);
254
255}
256
257
258
259
260
261
262static void cmpk_count_tx_status(struct r8192_priv *priv, cmpk_tx_status_t *pstx_status)
263{
264
265#ifdef ENABLE_PS
266
267 RT_RF_POWER_STATE rtstate;
268
269 pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
270
271
272
273
274 if (rtState == eRfOff)
275 {
276 return;
277 }
278#endif
279
280 priv->stats.txfeedbackok += pstx_status->txok;
281 priv->stats.txoktotal += pstx_status->txok;
282
283 priv->stats.txbytesunicast += pstx_status->txuclength;
284}
285
286
287
288
289
290
291
292static void cmpk_handle_tx_status(struct r8192_priv *priv, u8 *pmsg)
293{
294 cmpk_tx_status_t rx_tx_sts;
295
296 memcpy((void*)&rx_tx_sts, (void*)pmsg, sizeof(cmpk_tx_status_t));
297
298 cmpk_count_tx_status(priv, &rx_tx_sts);
299
300}
301
302
303
304static void cmpk_handle_tx_rate_history(struct r8192_priv *priv, u8 *pmsg)
305{
306 u8 i;
307 u16 length = sizeof(cmpk_tx_rahis_t);
308 u32 *ptemp;
309
310#ifdef ENABLE_PS
311 pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
312
313
314
315
316 if (rtState == eRfOff)
317 {
318 return;
319 }
320#endif
321
322 ptemp = (u32 *)pmsg;
323
324
325
326
327
328 for (i = 0; i < (length/4); i++)
329 {
330 u16 temp1, temp2;
331
332 temp1 = ptemp[i]&0x0000FFFF;
333 temp2 = ptemp[i]>>16;
334 ptemp[i] = (temp1<<16)|temp2;
335 }
336}
337
338
339
340
341
342
343
344
345
346u32 cmpk_message_handle_rx(struct r8192_priv *priv, struct ieee80211_rx_stats *pstats)
347{
348
349 int total_length;
350 u8 cmd_length, exe_cnt = 0;
351 u8 element_id;
352 u8 *pcmd_buff;
353
354 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx()\n");
355
356
357
358 if ((pstats== NULL))
359 {
360
361
362
363 return 0;
364 }
365
366
367 total_length = pstats->Length;
368
369
370 pcmd_buff = pstats->virtual_address;
371
372
373 element_id = pcmd_buff[0];
374
375
376
377
378
379
380
381 while (total_length > 0 || exe_cnt++ >100)
382 {
383
384 element_id = pcmd_buff[0];
385
386 switch(element_id)
387 {
388 case RX_TX_FEEDBACK:
389
390 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_FEEDBACK\n");
391 cmpk_handle_tx_feedback(priv, pcmd_buff);
392 cmd_length = CMPK_RX_TX_FB_SIZE;
393 break;
394
395 case RX_INTERRUPT_STATUS:
396
397 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_INTERRUPT_STATUS\n");
398 cmpk_handle_interrupt_status(priv, pcmd_buff);
399 cmd_length = sizeof(cmpk_intr_sta_t);
400 break;
401
402 case BOTH_QUERY_CONFIG:
403
404 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():BOTH_QUERY_CONFIG\n");
405 cmpk_handle_query_config_rx(priv, pcmd_buff);
406 cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE;
407 break;
408
409 case RX_TX_STATUS:
410
411 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_STATUS\n");
412 cmpk_handle_tx_status(priv, pcmd_buff);
413 cmd_length = CMPK_RX_TX_STS_SIZE;
414 break;
415
416 case RX_TX_PER_PKT_FEEDBACK:
417
418
419
420 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_PER_PKT_FEEDBACK\n");
421 cmd_length = CMPK_RX_TX_FB_SIZE;
422 break;
423
424 case RX_TX_RATE_HISTORY:
425
426
427 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_HISTORY\n");
428 cmpk_handle_tx_rate_history(priv, pcmd_buff);
429 cmd_length = CMPK_TX_RAHIS_SIZE;
430 break;
431
432 default:
433
434 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():unknown CMD Element\n");
435 return 1;
436 }
437
438 total_length -= cmd_length;
439 pcmd_buff += cmd_length;
440 }
441 return 1;
442
443 RT_TRACE(COMP_EVENTS, "<----cmpk_message_handle_rx()\n");
444}
445