1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include "../wifi.h"
27#include "../pci.h"
28#include "../base.h"
29#include "reg.h"
30#include "def.h"
31#include "fw.h"
32
33static void _rtl92s_fw_set_rqpn(struct ieee80211_hw *hw)
34{
35 struct rtl_priv *rtlpriv = rtl_priv(hw);
36
37 rtl_write_dword(rtlpriv, RQPN, 0xffffffff);
38 rtl_write_dword(rtlpriv, RQPN + 4, 0xffffffff);
39 rtl_write_byte(rtlpriv, RQPN + 8, 0xff);
40 rtl_write_byte(rtlpriv, RQPN + 0xB, 0x80);
41}
42
43static bool _rtl92s_firmware_enable_cpu(struct ieee80211_hw *hw)
44{
45 struct rtl_priv *rtlpriv = rtl_priv(hw);
46 u32 ichecktime = 200;
47 u16 tmpu2b;
48 u8 tmpu1b, cpustatus = 0;
49
50 _rtl92s_fw_set_rqpn(hw);
51
52
53 tmpu1b = rtl_read_byte(rtlpriv, SYS_CLKR);
54
55 rtl_write_byte(rtlpriv, SYS_CLKR, (tmpu1b | SYS_CPU_CLKSEL));
56
57 tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
58 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | FEN_CPUEN));
59
60
61 do {
62 cpustatus = rtl_read_byte(rtlpriv, TCR);
63 if (cpustatus & IMEM_RDY) {
64 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
65 "IMEM Ready after CPU has refilled\n");
66 break;
67 }
68
69 udelay(100);
70 } while (ichecktime--);
71
72 if (!(cpustatus & IMEM_RDY))
73 return false;
74
75 return true;
76}
77
78static enum fw_status _rtl92s_firmware_get_nextstatus(
79 enum fw_status fw_currentstatus)
80{
81 enum fw_status next_fwstatus = 0;
82
83 switch (fw_currentstatus) {
84 case FW_STATUS_INIT:
85 next_fwstatus = FW_STATUS_LOAD_IMEM;
86 break;
87 case FW_STATUS_LOAD_IMEM:
88 next_fwstatus = FW_STATUS_LOAD_EMEM;
89 break;
90 case FW_STATUS_LOAD_EMEM:
91 next_fwstatus = FW_STATUS_LOAD_DMEM;
92 break;
93 case FW_STATUS_LOAD_DMEM:
94 next_fwstatus = FW_STATUS_READY;
95 break;
96 default:
97 break;
98 }
99
100 return next_fwstatus;
101}
102
103static u8 _rtl92s_firmware_header_map_rftype(struct ieee80211_hw *hw)
104{
105 struct rtl_priv *rtlpriv = rtl_priv(hw);
106 struct rtl_phy *rtlphy = &(rtlpriv->phy);
107
108 switch (rtlphy->rf_type) {
109 case RF_1T1R:
110 return 0x11;
111 case RF_1T2R:
112 return 0x12;
113 case RF_2T2R:
114 return 0x22;
115 default:
116 pr_err("Unknown RF type(%x)\n", rtlphy->rf_type);
117 break;
118 }
119 return 0x22;
120}
121
122static void _rtl92s_firmwareheader_priveupdate(struct ieee80211_hw *hw,
123 struct fw_priv *pfw_priv)
124{
125
126 pfw_priv->rf_config = _rtl92s_firmware_header_map_rftype(hw);
127}
128
129
130
131static bool _rtl92s_cmd_send_packet(struct ieee80211_hw *hw,
132 struct sk_buff *skb, u8 last)
133{
134 struct rtl_priv *rtlpriv = rtl_priv(hw);
135 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
136 struct rtl8192_tx_ring *ring;
137 struct rtl_tx_desc *pdesc;
138 unsigned long flags;
139 u8 idx = 0;
140
141 ring = &rtlpci->tx_ring[TXCMD_QUEUE];
142
143 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
144
145 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
146 pdesc = &ring->desc[idx];
147 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
148 __skb_queue_tail(&ring->queue, skb);
149
150 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
151
152 return true;
153}
154
155static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw,
156 u8 *code_virtual_address, u32 buffer_len)
157{
158 struct rtl_priv *rtlpriv = rtl_priv(hw);
159 struct sk_buff *skb;
160 struct rtl_tcb_desc *tcb_desc;
161 unsigned char *seg_ptr;
162 u16 frag_threshold = MAX_FIRMWARE_CODE_SIZE;
163 u16 frag_length, frag_offset = 0;
164 u16 extra_descoffset = 0;
165 u8 last_inipkt = 0;
166
167 _rtl92s_fw_set_rqpn(hw);
168
169 if (buffer_len >= MAX_FIRMWARE_CODE_SIZE) {
170 pr_err("Size over FIRMWARE_CODE_SIZE!\n");
171 return false;
172 }
173
174 extra_descoffset = 0;
175
176 do {
177 if ((buffer_len - frag_offset) > frag_threshold) {
178 frag_length = frag_threshold + extra_descoffset;
179 } else {
180 frag_length = (u16)(buffer_len - frag_offset +
181 extra_descoffset);
182 last_inipkt = 1;
183 }
184
185
186
187 skb = dev_alloc_skb(frag_length);
188 if (!skb)
189 return false;
190 skb_reserve(skb, extra_descoffset);
191 seg_ptr = skb_put_data(skb,
192 code_virtual_address + frag_offset,
193 (u32)(frag_length - extra_descoffset));
194
195 tcb_desc = (struct rtl_tcb_desc *)(skb->cb);
196 tcb_desc->queue_index = TXCMD_QUEUE;
197 tcb_desc->cmd_or_init = DESC_PACKET_TYPE_INIT;
198 tcb_desc->last_inipkt = last_inipkt;
199
200 _rtl92s_cmd_send_packet(hw, skb, last_inipkt);
201
202 frag_offset += (frag_length - extra_descoffset);
203
204 } while (frag_offset < buffer_len);
205
206 rtl_write_byte(rtlpriv, TP_POLL, TPPOLL_CQ);
207
208 return true ;
209}
210
211static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
212 u8 loadfw_status)
213{
214 struct rtl_priv *rtlpriv = rtl_priv(hw);
215 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
216 struct rt_firmware *firmware = (struct rt_firmware *)rtlhal->pfirmware;
217 u32 tmpu4b;
218 u8 cpustatus = 0;
219 short pollingcnt = 1000;
220 bool rtstatus = true;
221
222 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
223 "LoadStaus(%d)\n", loadfw_status);
224
225 firmware->fwstatus = (enum fw_status)loadfw_status;
226
227 switch (loadfw_status) {
228 case FW_STATUS_LOAD_IMEM:
229
230 do {
231 cpustatus = rtl_read_byte(rtlpriv, TCR);
232 if (cpustatus & IMEM_CODE_DONE)
233 break;
234 udelay(5);
235 } while (pollingcnt--);
236
237 if (!(cpustatus & IMEM_CHK_RPT) || (pollingcnt <= 0)) {
238 pr_err("FW_STATUS_LOAD_IMEM FAIL CPU, Status=%x\n",
239 cpustatus);
240 goto status_check_fail;
241 }
242 break;
243
244 case FW_STATUS_LOAD_EMEM:
245
246
247 do {
248 cpustatus = rtl_read_byte(rtlpriv, TCR);
249 if (cpustatus & EMEM_CODE_DONE)
250 break;
251 udelay(5);
252 } while (pollingcnt--);
253
254 if (!(cpustatus & EMEM_CHK_RPT) || (pollingcnt <= 0)) {
255 pr_err("FW_STATUS_LOAD_EMEM FAIL CPU, Status=%x\n",
256 cpustatus);
257 goto status_check_fail;
258 }
259
260
261 rtstatus = _rtl92s_firmware_enable_cpu(hw);
262 if (!rtstatus) {
263 pr_err("Enable CPU fail!\n");
264 goto status_check_fail;
265 }
266 break;
267
268 case FW_STATUS_LOAD_DMEM:
269
270 do {
271 cpustatus = rtl_read_byte(rtlpriv, TCR);
272 if (cpustatus & DMEM_CODE_DONE)
273 break;
274 udelay(5);
275 } while (pollingcnt--);
276
277 if (!(cpustatus & DMEM_CODE_DONE) || (pollingcnt <= 0)) {
278 pr_err("Polling DMEM code done fail ! cpustatus(%#x)\n",
279 cpustatus);
280 goto status_check_fail;
281 }
282
283 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
284 "DMEM code download success, cpustatus(%#x)\n",
285 cpustatus);
286
287
288
289 pollingcnt = 2000;
290 do {
291 cpustatus = rtl_read_byte(rtlpriv, TCR);
292 if (cpustatus & FWRDY)
293 break;
294 udelay(40);
295 } while (pollingcnt--);
296
297 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
298 "Polling Load Firmware ready, cpustatus(%x)\n",
299 cpustatus);
300
301 if (((cpustatus & LOAD_FW_READY) != LOAD_FW_READY) ||
302 (pollingcnt <= 0)) {
303 pr_err("Polling Load Firmware ready fail ! cpustatus(%x)\n",
304 cpustatus);
305 goto status_check_fail;
306 }
307
308
309
310 tmpu4b = rtl_read_dword(rtlpriv, TCR);
311 rtl_write_dword(rtlpriv, TCR, (tmpu4b & (~TCR_ICV)));
312
313 tmpu4b = rtl_read_dword(rtlpriv, RCR);
314 rtl_write_dword(rtlpriv, RCR, (tmpu4b | RCR_APPFCS |
315 RCR_APP_ICV | RCR_APP_MIC));
316
317 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
318 "Current RCR settings(%#x)\n", tmpu4b);
319
320
321 rtl_write_byte(rtlpriv, LBKMD_SEL, LBK_NORMAL);
322 break;
323
324 default:
325 pr_err("Unknown status check!\n");
326 rtstatus = false;
327 break;
328 }
329
330status_check_fail:
331 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
332 "loadfw_status(%d), rtstatus(%x)\n",
333 loadfw_status, rtstatus);
334 return rtstatus;
335}
336
337int rtl92s_download_fw(struct ieee80211_hw *hw)
338{
339 struct rtl_priv *rtlpriv = rtl_priv(hw);
340 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
341 struct rt_firmware *firmware = NULL;
342 struct fw_hdr *pfwheader;
343 struct fw_priv *pfw_priv = NULL;
344 u8 *puc_mappedfile = NULL;
345 u32 ul_filelength = 0;
346 u8 fwhdr_size = RT_8192S_FIRMWARE_HDR_SIZE;
347 u8 fwstatus = FW_STATUS_INIT;
348 bool rtstatus = true;
349
350 if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
351 return 1;
352
353 firmware = (struct rt_firmware *)rtlhal->pfirmware;
354 firmware->fwstatus = FW_STATUS_INIT;
355
356 puc_mappedfile = firmware->sz_fw_tmpbuffer;
357
358
359 firmware->pfwheader = (struct fw_hdr *) puc_mappedfile;
360 pfwheader = firmware->pfwheader;
361 firmware->firmwareversion = byte(pfwheader->version, 0);
362 firmware->pfwheader->fwpriv.hci_sel = 1;
363
364 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
365 "signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n",
366 pfwheader->signature,
367 pfwheader->version, pfwheader->dmem_size,
368 pfwheader->img_imem_size, pfwheader->img_sram_size);
369
370
371 if ((pfwheader->img_imem_size == 0) || (pfwheader->img_imem_size >
372 sizeof(firmware->fw_imem))) {
373 pr_err("memory for data image is less than IMEM required\n");
374 goto fail;
375 } else {
376 puc_mappedfile += fwhdr_size;
377
378 memcpy(firmware->fw_imem, puc_mappedfile,
379 pfwheader->img_imem_size);
380 firmware->fw_imem_len = pfwheader->img_imem_size;
381 }
382
383
384 if (pfwheader->img_sram_size > sizeof(firmware->fw_emem)) {
385 pr_err("memory for data image is less than EMEM required\n");
386 goto fail;
387 } else {
388 puc_mappedfile += firmware->fw_imem_len;
389
390 memcpy(firmware->fw_emem, puc_mappedfile,
391 pfwheader->img_sram_size);
392 firmware->fw_emem_len = pfwheader->img_sram_size;
393 }
394
395
396 fwstatus = _rtl92s_firmware_get_nextstatus(firmware->fwstatus);
397 while (fwstatus != FW_STATUS_READY) {
398
399 switch (fwstatus) {
400 case FW_STATUS_LOAD_IMEM:
401 puc_mappedfile = firmware->fw_imem;
402 ul_filelength = firmware->fw_imem_len;
403 break;
404 case FW_STATUS_LOAD_EMEM:
405 puc_mappedfile = firmware->fw_emem;
406 ul_filelength = firmware->fw_emem_len;
407 break;
408 case FW_STATUS_LOAD_DMEM:
409
410 pfwheader = firmware->pfwheader;
411 pfw_priv = &pfwheader->fwpriv;
412 _rtl92s_firmwareheader_priveupdate(hw, pfw_priv);
413 puc_mappedfile = (u8 *)(firmware->pfwheader) +
414 RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE;
415 ul_filelength = fwhdr_size -
416 RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE;
417 break;
418 default:
419 pr_err("Unexpected Download step!!\n");
420 goto fail;
421 }
422
423
424 rtstatus = _rtl92s_firmware_downloadcode(hw, puc_mappedfile,
425 ul_filelength);
426
427 if (!rtstatus) {
428 pr_err("fail!\n");
429 goto fail;
430 }
431
432
433 rtstatus = _rtl92s_firmware_checkready(hw, fwstatus);
434 if (!rtstatus) {
435 pr_err("rtl8192se: firmware fail!\n");
436 goto fail;
437 }
438
439 fwstatus = _rtl92s_firmware_get_nextstatus(firmware->fwstatus);
440 }
441
442 return rtstatus;
443fail:
444 return 0;
445}
446
447static u32 _rtl92s_fill_h2c_cmd(struct sk_buff *skb, u32 h2cbufferlen,
448 u32 cmd_num, u32 *pelement_id, u32 *pcmd_len,
449 u8 **pcmb_buffer, u8 *cmd_start_seq)
450{
451 u32 totallen = 0, len = 0, tx_desclen = 0;
452 u32 pre_continueoffset = 0;
453 u8 *ph2c_buffer;
454 u8 i = 0;
455
456 do {
457
458 len = H2C_TX_CMD_HDR_LEN + N_BYTE_ALIGMENT(pcmd_len[i], 8);
459
460
461 if (h2cbufferlen < totallen + len + tx_desclen)
462 break;
463
464
465 ph2c_buffer = skb_put(skb, (u32)len);
466 memset((ph2c_buffer + totallen + tx_desclen), 0, len);
467
468
469 SET_BITS_TO_LE_4BYTE((ph2c_buffer + totallen + tx_desclen),
470 0, 16, pcmd_len[i]);
471
472
473 SET_BITS_TO_LE_4BYTE((ph2c_buffer + totallen + tx_desclen),
474 16, 8, pelement_id[i]);
475
476
477 *cmd_start_seq = *cmd_start_seq % 0x80;
478 SET_BITS_TO_LE_4BYTE((ph2c_buffer + totallen + tx_desclen),
479 24, 7, *cmd_start_seq);
480 ++*cmd_start_seq;
481
482
483 memcpy((ph2c_buffer + totallen + tx_desclen +
484 H2C_TX_CMD_HDR_LEN), pcmb_buffer[i], pcmd_len[i]);
485
486
487
488 if (i < cmd_num - 1)
489 SET_BITS_TO_LE_4BYTE((ph2c_buffer + pre_continueoffset),
490 31, 1, 1);
491
492 pre_continueoffset = totallen;
493
494 totallen += len;
495 } while (++i < cmd_num);
496
497 return totallen;
498}
499
500static u32 _rtl92s_get_h2c_cmdlen(u32 h2cbufferlen, u32 cmd_num, u32 *pcmd_len)
501{
502 u32 totallen = 0, len = 0, tx_desclen = 0;
503 u8 i = 0;
504
505 do {
506
507 len = H2C_TX_CMD_HDR_LEN + N_BYTE_ALIGMENT(pcmd_len[i], 8);
508
509
510 if (h2cbufferlen < totallen + len + tx_desclen)
511 break;
512
513 totallen += len;
514 } while (++i < cmd_num);
515
516 return totallen + tx_desclen;
517}
518
519static bool _rtl92s_firmware_set_h2c_cmd(struct ieee80211_hw *hw, u8 h2c_cmd,
520 u8 *pcmd_buffer)
521{
522 struct rtl_priv *rtlpriv = rtl_priv(hw);
523 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
524 struct rtl_tcb_desc *cb_desc;
525 struct sk_buff *skb;
526 u32 element_id = 0;
527 u32 cmd_len = 0;
528 u32 len;
529
530 switch (h2c_cmd) {
531 case FW_H2C_SETPWRMODE:
532 element_id = H2C_SETPWRMODE_CMD ;
533 cmd_len = sizeof(struct h2c_set_pwrmode_parm);
534 break;
535 case FW_H2C_JOINBSSRPT:
536 element_id = H2C_JOINBSSRPT_CMD;
537 cmd_len = sizeof(struct h2c_joinbss_rpt_parm);
538 break;
539 case FW_H2C_WOWLAN_UPDATE_GTK:
540 element_id = H2C_WOWLAN_UPDATE_GTK_CMD;
541 cmd_len = sizeof(struct h2c_wpa_two_way_parm);
542 break;
543 case FW_H2C_WOWLAN_UPDATE_IV:
544 element_id = H2C_WOWLAN_UPDATE_IV_CMD;
545 cmd_len = sizeof(unsigned long long);
546 break;
547 case FW_H2C_WOWLAN_OFFLOAD:
548 element_id = H2C_WOWLAN_FW_OFFLOAD;
549 cmd_len = sizeof(u8);
550 break;
551 default:
552 break;
553 }
554
555 len = _rtl92s_get_h2c_cmdlen(MAX_TRANSMIT_BUFFER_SIZE, 1, &cmd_len);
556 skb = dev_alloc_skb(len);
557 if (!skb)
558 return false;
559 cb_desc = (struct rtl_tcb_desc *)(skb->cb);
560 cb_desc->queue_index = TXCMD_QUEUE;
561 cb_desc->cmd_or_init = DESC_PACKET_TYPE_NORMAL;
562 cb_desc->last_inipkt = false;
563
564 _rtl92s_fill_h2c_cmd(skb, MAX_TRANSMIT_BUFFER_SIZE, 1, &element_id,
565 &cmd_len, &pcmd_buffer, &rtlhal->h2c_txcmd_seq);
566 _rtl92s_cmd_send_packet(hw, skb, false);
567 rtlpriv->cfg->ops->tx_polling(hw, TXCMD_QUEUE);
568
569 return true;
570}
571
572void rtl92s_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 Mode)
573{
574 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
575 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
576 struct h2c_set_pwrmode_parm pwrmode;
577 u16 max_wakeup_period = 0;
578
579 pwrmode.mode = Mode;
580 pwrmode.flag_low_traffic_en = 0;
581 pwrmode.flag_lpnav_en = 0;
582 pwrmode.flag_rf_low_snr_en = 0;
583 pwrmode.flag_dps_en = 0;
584 pwrmode.bcn_rx_en = 0;
585 pwrmode.bcn_to = 0;
586 SET_BITS_TO_LE_2BYTE((u8 *)(&pwrmode) + 8, 0, 16,
587 mac->vif->bss_conf.beacon_int);
588 pwrmode.app_itv = 0;
589 pwrmode.awake_bcn_itvl = ppsc->reg_max_lps_awakeintvl;
590 pwrmode.smart_ps = 1;
591 pwrmode.bcn_pass_period = 10;
592
593
594 if (pwrmode.mode == FW_PS_MIN_MODE)
595 max_wakeup_period = mac->vif->bss_conf.beacon_int;
596 else if (pwrmode.mode == FW_PS_MAX_MODE)
597 max_wakeup_period = mac->vif->bss_conf.beacon_int *
598 mac->vif->bss_conf.dtim_period;
599
600 if (max_wakeup_period >= 500)
601 pwrmode.bcn_pass_cnt = 1;
602 else if ((max_wakeup_period >= 300) && (max_wakeup_period < 500))
603 pwrmode.bcn_pass_cnt = 2;
604 else if ((max_wakeup_period >= 200) && (max_wakeup_period < 300))
605 pwrmode.bcn_pass_cnt = 3;
606 else if ((max_wakeup_period >= 20) && (max_wakeup_period < 200))
607 pwrmode.bcn_pass_cnt = 5;
608 else
609 pwrmode.bcn_pass_cnt = 1;
610
611 _rtl92s_firmware_set_h2c_cmd(hw, FW_H2C_SETPWRMODE, (u8 *)&pwrmode);
612
613}
614
615void rtl92s_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw,
616 u8 mstatus, u8 ps_qosinfo)
617{
618 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
619 struct h2c_joinbss_rpt_parm joinbss_rpt;
620
621 joinbss_rpt.opmode = mstatus;
622 joinbss_rpt.ps_qos_info = ps_qosinfo;
623 joinbss_rpt.bssid[0] = mac->bssid[0];
624 joinbss_rpt.bssid[1] = mac->bssid[1];
625 joinbss_rpt.bssid[2] = mac->bssid[2];
626 joinbss_rpt.bssid[3] = mac->bssid[3];
627 joinbss_rpt.bssid[4] = mac->bssid[4];
628 joinbss_rpt.bssid[5] = mac->bssid[5];
629 SET_BITS_TO_LE_2BYTE((u8 *)(&joinbss_rpt) + 8, 0, 16,
630 mac->vif->bss_conf.beacon_int);
631 SET_BITS_TO_LE_2BYTE((u8 *)(&joinbss_rpt) + 10, 0, 16, mac->assoc_id);
632
633 _rtl92s_firmware_set_h2c_cmd(hw, FW_H2C_JOINBSSRPT, (u8 *)&joinbss_rpt);
634}
635
636