1 /******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
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
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
13 * The full GNU General Public License is included in this distribution in the
14 * file called LICENSE.
16 * Contact Information:
17 * wlanfae <wlanfae@realtek.com>
18 ******************************************************************************/
19 #if (defined(RTL8192E) || defined(RTL8190P))
22 #include "r8192E_hw.h"
23 #include "r8192E_cmdpkt.h"
24 /*---------------------------Define Local Constant---------------------------*/
26 #define CMPK_DEBOUNCE_CNT 1
27 #define CMPK_PRINT(Address)\
32 memcpy(temp, Address, 40);\
33 for (i = 0; i <40; i+=4)\
34 printk("\r\n %08x", temp[i]);\
37 /*---------------------------Define functions---------------------------------*/
38 extern bool cmpk_message_handle_tx(
39 struct net_device
*dev
,
40 u8
* code_virtual_address
,
45 bool rt_status
= true;
46 struct r8192_priv
*priv
= rtllib_priv(dev
);
48 u16 frag_length
= 0, frag_offset
= 0;
49 rt_firmware
*pfirmware
= priv
->pFirmware
;
51 unsigned char *seg_ptr
;
55 PTX_FWINFO_8190PCI pTxFwInfo
= NULL
;
57 RT_TRACE(COMP_CMDPKT
,"%s(),buffer_len is %d\n",__func__
,buffer_len
);
58 firmware_init_param(dev
);
59 frag_threshold
= pfirmware
->cmdpacket_frag_thresold
;
62 if ((buffer_len
- frag_offset
) > frag_threshold
) {
63 frag_length
= frag_threshold
;
67 frag_length
=(u16
)(buffer_len
- frag_offset
);
71 skb
= dev_alloc_skb(frag_length
+ priv
->rtllib
->tx_headroom
+ 4);
78 memcpy((unsigned char *)(skb
->cb
),&dev
,sizeof(dev
));
79 tcb_desc
= (cb_desc
*)(skb
->cb
+ MAX_DEV_ADDR_SIZE
);
80 tcb_desc
->queue_index
= TXCMD_QUEUE
;
81 tcb_desc
->bCmdOrInit
= DESC_PACKET_TYPE_NORMAL
;
82 tcb_desc
->bLastIniPkt
= bLastIniPkt
;
83 tcb_desc
->pkt_size
= frag_length
;
85 seg_ptr
= skb_put(skb
, priv
->rtllib
->tx_headroom
);
86 pTxFwInfo
= (PTX_FWINFO_8190PCI
)seg_ptr
;
87 memset(pTxFwInfo
,0,sizeof(TX_FWINFO_8190PCI
));
88 memset(pTxFwInfo
,0x12,8);
90 seg_ptr
= skb_put(skb
, frag_length
);
91 memcpy(seg_ptr
, code_virtual_address
, (u32
)frag_length
);
93 priv
->rtllib
->softmac_hard_start_xmit(skb
,dev
);
95 code_virtual_address
+= frag_length
;
96 frag_offset
+= frag_length
;
98 }while(frag_offset
< buffer_len
);
100 write_nic_byte(dev
, TPPoll
, TPPoll_CQ
);
103 } /* CMPK_Message_Handle_Tx */
106 cmpk_count_txstatistic(
107 struct net_device
*dev
,
108 cmpk_txfb_t
*pstx_fb
)
110 struct r8192_priv
*priv
= rtllib_priv(dev
);
112 RT_RF_POWER_STATE rtState
;
114 pAdapter
->HalFunc
.GetHwRegHandler(pAdapter
, HW_VAR_RF_STATE
, (pu1Byte
)(&rtState
));
116 if (rtState
== eRfOff
)
123 if (pAdapter
->bInHctTest
)
128 priv
->stats
.txfeedbackok
++;
129 priv
->stats
.txoktotal
++;
130 priv
->stats
.txokbytestotal
+= pstx_fb
->pkt_length
;
131 priv
->stats
.txokinperiod
++;
133 if (pstx_fb
->pkt_type
== PACKET_MULTICAST
)
135 priv
->stats
.txmulticast
++;
136 priv
->stats
.txbytesmulticast
+= pstx_fb
->pkt_length
;
138 else if (pstx_fb
->pkt_type
== PACKET_BROADCAST
)
140 priv
->stats
.txbroadcast
++;
141 priv
->stats
.txbytesbroadcast
+= pstx_fb
->pkt_length
;
145 priv
->stats
.txunicast
++;
146 priv
->stats
.txbytesunicast
+= pstx_fb
->pkt_length
;
151 priv
->stats
.txfeedbackfail
++;
152 priv
->stats
.txerrtotal
++;
153 priv
->stats
.txerrbytestotal
+= pstx_fb
->pkt_length
;
155 if (pstx_fb
->pkt_type
== PACKET_MULTICAST
)
157 priv
->stats
.txerrmulticast
++;
159 else if (pstx_fb
->pkt_type
== PACKET_BROADCAST
)
161 priv
->stats
.txerrbroadcast
++;
165 priv
->stats
.txerrunicast
++;
169 priv
->stats
.txretrycount
+= pstx_fb
->retry_cnt
;
170 priv
->stats
.txfeedbackretry
+= pstx_fb
->retry_cnt
;
172 } /* cmpk_CountTxStatistic */
177 cmpk_handle_tx_feedback(
178 struct net_device
*dev
,
181 struct r8192_priv
*priv
= rtllib_priv(dev
);
182 cmpk_txfb_t rx_tx_fb
; /* */
184 priv
->stats
.txfeedback
++;
187 memcpy((u8
*)&rx_tx_fb
, pmsg
, sizeof(cmpk_txfb_t
));
188 cmpk_count_txstatistic(dev
, &rx_tx_fb
);
190 } /* cmpk_Handle_Tx_Feedback */
193 cmdpkt_beacontimerinterrupt_819xusb(
194 struct net_device
*dev
197 struct r8192_priv
*priv
= rtllib_priv(dev
);
200 if ((priv
->rtllib
->current_network
.mode
== IEEE_A
) ||
201 (priv
->rtllib
->current_network
.mode
== IEEE_N_5G
) ||
202 ((priv
->rtllib
->current_network
.mode
== IEEE_N_24G
) && (!priv
->rtllib
->pHTInfo
->bCurSuppCCK
)))
205 DMESG("send beacon frame tx rate is 6Mbpm\n");
210 DMESG("send beacon frame tx rate is 1Mbpm\n");
219 cmpk_handle_interrupt_status(
220 struct net_device
*dev
,
223 cmpk_intr_sta_t rx_intr_status
; /* */
224 struct r8192_priv
*priv
= rtllib_priv(dev
);
226 DMESG("---> cmpk_Handle_Interrupt_Status()\n");
229 rx_intr_status
.length
= pmsg
[1];
230 if (rx_intr_status
.length
!= (sizeof(cmpk_intr_sta_t
) - 2))
232 DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n");
237 if ( priv
->rtllib
->iw_mode
== IW_MODE_ADHOC
)
239 rx_intr_status
.interrupt_status
= *((u32
*)(pmsg
+ 4));
241 DMESG("interrupt status = 0x%x\n", rx_intr_status
.interrupt_status
);
243 if (rx_intr_status
.interrupt_status
& ISR_TxBcnOk
)
245 priv
->rtllib
->bibsscoordinator
= true;
246 priv
->stats
.txbeaconokint
++;
248 else if (rx_intr_status
.interrupt_status
& ISR_TxBcnErr
)
250 priv
->rtllib
->bibsscoordinator
= false;
251 priv
->stats
.txbeaconerr
++;
254 if (rx_intr_status
.interrupt_status
& ISR_BcnTimerIntr
)
256 cmdpkt_beacontimerinterrupt_819xusb(dev
);
263 DMESG("<---- cmpk_handle_interrupt_status()\n");
265 } /* cmpk_handle_interrupt_status */
269 cmpk_handle_query_config_rx(
270 struct net_device
*dev
,
273 cmpk_query_cfg_t rx_query_cfg
; /* */
276 rx_query_cfg
.cfg_action
= (pmsg
[4] & 0x80000000)>>31;
277 rx_query_cfg
.cfg_type
= (pmsg
[4] & 0x60) >> 5;
278 rx_query_cfg
.cfg_size
= (pmsg
[4] & 0x18) >> 3;
279 rx_query_cfg
.cfg_page
= (pmsg
[6] & 0x0F) >> 0;
280 rx_query_cfg
.cfg_offset
= pmsg
[7];
281 rx_query_cfg
.value
= (pmsg
[8] << 24) | (pmsg
[9] << 16) |
282 (pmsg
[10] << 8) | (pmsg
[11] << 0);
283 rx_query_cfg
.mask
= (pmsg
[12] << 24) | (pmsg
[13] << 16) |
284 (pmsg
[14] << 8) | (pmsg
[15] << 0);
286 } /* cmpk_Handle_Query_Config_Rx */
289 static void cmpk_count_tx_status( struct net_device
*dev
,
290 cmpk_tx_status_t
*pstx_status
)
292 struct r8192_priv
*priv
= rtllib_priv(dev
);
296 RT_RF_POWER_STATE rtstate
;
298 pAdapter
->HalFunc
.GetHwRegHandler(pAdapter
, HW_VAR_RF_STATE
, (pu1Byte
)(&rtState
));
300 if (rtState
== eRfOff
)
306 priv
->stats
.txfeedbackok
+= pstx_status
->txok
;
307 priv
->stats
.txoktotal
+= pstx_status
->txok
;
309 priv
->stats
.txfeedbackfail
+= pstx_status
->txfail
;
310 priv
->stats
.txerrtotal
+= pstx_status
->txfail
;
312 priv
->stats
.txretrycount
+= pstx_status
->txretry
;
313 priv
->stats
.txfeedbackretry
+= pstx_status
->txretry
;
316 priv
->stats
.txmulticast
+= pstx_status
->txmcok
;
317 priv
->stats
.txbroadcast
+= pstx_status
->txbcok
;
318 priv
->stats
.txunicast
+= pstx_status
->txucok
;
320 priv
->stats
.txerrmulticast
+= pstx_status
->txmcfail
;
321 priv
->stats
.txerrbroadcast
+= pstx_status
->txbcfail
;
322 priv
->stats
.txerrunicast
+= pstx_status
->txucfail
;
324 priv
->stats
.txbytesmulticast
+= pstx_status
->txmclength
;
325 priv
->stats
.txbytesbroadcast
+= pstx_status
->txbclength
;
326 priv
->stats
.txbytesunicast
+= pstx_status
->txuclength
;
328 priv
->stats
.last_packet_rate
= pstx_status
->rate
;
329 } /* cmpk_CountTxStatus */
334 cmpk_handle_tx_status(
335 struct net_device
*dev
,
338 cmpk_tx_status_t rx_tx_sts
; /* */
340 memcpy((void*)&rx_tx_sts
, (void*)pmsg
, sizeof(cmpk_tx_status_t
));
341 cmpk_count_tx_status(dev
, &rx_tx_sts
);
347 cmpk_handle_tx_rate_history(
348 struct net_device
*dev
,
351 cmpk_tx_rahis_t
*ptxrate
;
353 u16 length
= sizeof(cmpk_tx_rahis_t
);
355 struct r8192_priv
*priv
= rtllib_priv(dev
);
359 pAdapter
->HalFunc
.GetHwRegHandler(pAdapter
, HW_VAR_RF_STATE
, (pu1Byte
)(&rtState
));
361 if (rtState
== eRfOff
)
369 for (i
= 0; i
< (length
/4); i
++)
373 temp1
= ptemp
[i
]&0x0000FFFF;
374 temp2
= ptemp
[i
]>>16;
375 ptemp
[i
] = (temp1
<<16)|temp2
;
378 ptxrate
= (cmpk_tx_rahis_t
*)pmsg
;
380 if (ptxrate
== NULL
)
385 for (i
= 0; i
< 16; i
++)
388 priv
->stats
.txrate
.cck
[i
] += ptxrate
->cck
[i
];
391 priv
->stats
.txrate
.ofdm
[i
] += ptxrate
->ofdm
[i
];
393 for (j
= 0; j
< 4; j
++)
394 priv
->stats
.txrate
.ht_mcs
[j
][i
] += ptxrate
->ht_mcs
[j
][i
];
401 cmpk_message_handle_rx(
402 struct net_device
*dev
,
403 struct rtllib_rx_stats
*pstats
)
405 struct r8192_priv
*priv
= rtllib_priv(dev
);
407 u8 cmd_length
, exe_cnt
= 0;
411 RT_TRACE(COMP_CMDPKT
, "---->cmpk_message_handle_rx()\n");
413 if (/*(prfd->queue_id != CMPK_RX_QUEUE_ID) || */(pstats
== NULL
))
415 /* Print error message. */
416 /*RT_TRACE(COMP_SEND, DebugLevel,
417 ("\n\r[CMPK]-->Err queue id or pointer"));*/
421 total_length
= pstats
->Length
;
423 pcmd_buff
= pstats
->virtual_address
;
425 element_id
= pcmd_buff
[0];
427 while (total_length
> 0 || exe_cnt
++ >100)
429 element_id
= pcmd_buff
[0];
431 switch (element_id
) {
433 RT_TRACE(COMP_CMDPKT
, "---->cmpk_message_handle_rx():RX_TX_FEEDBACK\n");
434 cmpk_handle_tx_feedback (dev
, pcmd_buff
);
435 cmd_length
= CMPK_RX_TX_FB_SIZE
;
437 case RX_INTERRUPT_STATUS
:
438 RT_TRACE(COMP_CMDPKT
, "---->cmpk_message_handle_rx():RX_INTERRUPT_STATUS\n");
439 cmpk_handle_interrupt_status(dev
, pcmd_buff
);
440 cmd_length
= sizeof(cmpk_intr_sta_t
);
442 case BOTH_QUERY_CONFIG
:
443 RT_TRACE(COMP_CMDPKT
, "---->cmpk_message_handle_rx():BOTH_QUERY_CONFIG\n");
444 cmpk_handle_query_config_rx(dev
, pcmd_buff
);
445 cmd_length
= CMPK_BOTH_QUERY_CONFIG_SIZE
;
448 RT_TRACE(COMP_CMDPKT
, "---->cmpk_message_handle_rx():RX_TX_STATUS\n");
449 cmpk_handle_tx_status(dev
, pcmd_buff
);
450 cmd_length
= CMPK_RX_TX_STS_SIZE
;
452 case RX_TX_PER_PKT_FEEDBACK
:
453 RT_TRACE(COMP_CMDPKT
, "---->cmpk_message_handle_rx():RX_TX_PER_PKT_FEEDBACK\n");
454 cmd_length
= CMPK_RX_TX_FB_SIZE
;
456 case RX_TX_RATE_HISTORY
:
457 RT_TRACE(COMP_CMDPKT
, "---->cmpk_message_handle_rx():RX_TX_HISTORY\n");
458 cmpk_handle_tx_rate_history(dev
, pcmd_buff
);
459 cmd_length
= CMPK_TX_RAHIS_SIZE
;
463 RT_TRACE(COMP_CMDPKT
, "---->cmpk_message_handle_rx():unknow CMD Element\n");
467 priv
->stats
.rxcmdpkt
[element_id
]++;
469 total_length
-= cmd_length
;
470 pcmd_buff
+= cmd_length
;
474 RT_TRACE(COMP_CMDPKT
, "<----cmpk_message_handle_rx()\n");