1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /****************************************************************************** |
3 | * |
4 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. |
5 | * |
6 | ******************************************************************************/ |
7 | |
8 | #include <linux/kernel.h> |
9 | #include <drv_types.h> |
10 | #include <rtw_debug.h> |
11 | #include "hal_com_h2c.h" |
12 | |
13 | #include "odm_precomp.h" |
14 | |
15 | u8 rtw_hal_data_init(struct adapter *padapter) |
16 | { |
17 | if (is_primary_adapter(padapter)) { /* if (padapter->isprimary) */ |
18 | padapter->hal_data_sz = sizeof(struct hal_com_data); |
19 | padapter->HalData = vzalloc(size: padapter->hal_data_sz); |
20 | if (!padapter->HalData) |
21 | return _FAIL; |
22 | } |
23 | return _SUCCESS; |
24 | } |
25 | |
26 | void rtw_hal_data_deinit(struct adapter *padapter) |
27 | { |
28 | if (is_primary_adapter(padapter)) { /* if (padapter->isprimary) */ |
29 | if (padapter->HalData) { |
30 | vfree(addr: padapter->HalData); |
31 | padapter->HalData = NULL; |
32 | padapter->hal_data_sz = 0; |
33 | } |
34 | } |
35 | } |
36 | |
37 | |
38 | void dump_chip_info(struct hal_version ChipVersion) |
39 | { |
40 | char buf[128]; |
41 | size_t cnt = 0; |
42 | |
43 | cnt += scnprintf(buf: buf + cnt, size: sizeof(buf) - cnt, fmt: "Chip Version Info: CHIP_8723B_%s_" , |
44 | IS_NORMAL_CHIP(ChipVersion) ? "Normal_Chip" : "Test_Chip" ); |
45 | |
46 | if (IS_CHIP_VENDOR_TSMC(ChipVersion)) |
47 | cnt += scnprintf(buf: buf + cnt, size: sizeof(buf) - cnt, fmt: "TSMC_" ); |
48 | else if (IS_CHIP_VENDOR_UMC(ChipVersion)) |
49 | cnt += scnprintf(buf: buf + cnt, size: sizeof(buf) - cnt, fmt: "UMC_" ); |
50 | else if (IS_CHIP_VENDOR_SMIC(ChipVersion)) |
51 | cnt += scnprintf(buf: buf + cnt, size: sizeof(buf) - cnt, fmt: "SMIC_" ); |
52 | |
53 | if (IS_A_CUT(ChipVersion)) |
54 | cnt += scnprintf(buf: buf + cnt, size: sizeof(buf) - cnt, fmt: "A_CUT_" ); |
55 | else if (IS_B_CUT(ChipVersion)) |
56 | cnt += scnprintf(buf: buf + cnt, size: sizeof(buf) - cnt, fmt: "B_CUT_" ); |
57 | else if (IS_C_CUT(ChipVersion)) |
58 | cnt += scnprintf(buf: buf + cnt, size: sizeof(buf) - cnt, fmt: "C_CUT_" ); |
59 | else if (IS_D_CUT(ChipVersion)) |
60 | cnt += scnprintf(buf: buf + cnt, size: sizeof(buf) - cnt, fmt: "D_CUT_" ); |
61 | else if (IS_E_CUT(ChipVersion)) |
62 | cnt += scnprintf(buf: buf + cnt, size: sizeof(buf) - cnt, fmt: "E_CUT_" ); |
63 | else if (IS_I_CUT(ChipVersion)) |
64 | cnt += scnprintf(buf: buf + cnt, size: sizeof(buf) - cnt, fmt: "I_CUT_" ); |
65 | else if (IS_J_CUT(ChipVersion)) |
66 | cnt += scnprintf(buf: buf + cnt, size: sizeof(buf) - cnt, fmt: "J_CUT_" ); |
67 | else if (IS_K_CUT(ChipVersion)) |
68 | cnt += scnprintf(buf: buf + cnt, size: sizeof(buf) - cnt, fmt: "K_CUT_" ); |
69 | else |
70 | cnt += scnprintf(buf: buf + cnt, size: sizeof(buf) - cnt, |
71 | fmt: "UNKNOWN_CUT(%d)_" , ChipVersion.CUTVersion); |
72 | |
73 | cnt += scnprintf(buf: buf + cnt, size: sizeof(buf) - cnt, fmt: "1T1R_" ); |
74 | |
75 | cnt += scnprintf(buf: buf + cnt, size: sizeof(buf) - cnt, fmt: "RomVer(%d)\n" , ChipVersion.ROMVer); |
76 | } |
77 | |
78 | |
79 | #define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 |
80 | |
81 | /* |
82 | * Description: |
83 | *Use hardware(efuse), driver parameter(registry) and default channel plan |
84 | *to decide which one should be used. |
85 | * |
86 | * Parameters: |
87 | *padapter pointer of adapter |
88 | *hw_channel_plan channel plan from HW (efuse/eeprom) |
89 | * BIT[7] software configure mode; 0:Enable, 1:disable |
90 | * BIT[6:0] Channel Plan |
91 | *sw_channel_plan channel plan from SW (registry/module param) |
92 | *def_channel_plan channel plan used when HW/SW both invalid |
93 | *AutoLoadFail efuse autoload fail or not |
94 | * |
95 | * Return: |
96 | *Final channel plan decision |
97 | * |
98 | */ |
99 | u8 hal_com_config_channel_plan( |
100 | struct adapter *padapter, |
101 | u8 hw_channel_plan, |
102 | u8 sw_channel_plan, |
103 | u8 def_channel_plan, |
104 | bool AutoLoadFail |
105 | ) |
106 | { |
107 | struct hal_com_data *pHalData; |
108 | u8 chnlPlan; |
109 | |
110 | pHalData = GET_HAL_DATA(padapter); |
111 | pHalData->bDisableSWChannelPlan = false; |
112 | chnlPlan = def_channel_plan; |
113 | |
114 | if (0xFF == hw_channel_plan) |
115 | AutoLoadFail = true; |
116 | |
117 | if (!AutoLoadFail) { |
118 | u8 hw_chnlPlan; |
119 | |
120 | hw_chnlPlan = hw_channel_plan & (~EEPROM_CHANNEL_PLAN_BY_HW_MASK); |
121 | if (rtw_is_channel_plan_valid(hw_chnlPlan)) { |
122 | if (hw_channel_plan & EEPROM_CHANNEL_PLAN_BY_HW_MASK) |
123 | pHalData->bDisableSWChannelPlan = true; |
124 | |
125 | chnlPlan = hw_chnlPlan; |
126 | } |
127 | } |
128 | |
129 | if ( |
130 | (false == pHalData->bDisableSWChannelPlan) && |
131 | rtw_is_channel_plan_valid(sw_channel_plan) |
132 | ) |
133 | chnlPlan = sw_channel_plan; |
134 | |
135 | return chnlPlan; |
136 | } |
137 | |
138 | bool HAL_IsLegalChannel(struct adapter *adapter, u32 Channel) |
139 | { |
140 | bool bLegalChannel = true; |
141 | |
142 | if ((Channel <= 14) && (Channel >= 1)) { |
143 | if (is_supported_24g(adapter->registrypriv.wireless_mode) == false) |
144 | bLegalChannel = false; |
145 | } else { |
146 | bLegalChannel = false; |
147 | } |
148 | |
149 | return bLegalChannel; |
150 | } |
151 | |
152 | u8 MRateToHwRate(u8 rate) |
153 | { |
154 | u8 ret = DESC_RATE1M; |
155 | |
156 | switch (rate) { |
157 | case MGN_1M: |
158 | ret = DESC_RATE1M; |
159 | break; |
160 | case MGN_2M: |
161 | ret = DESC_RATE2M; |
162 | break; |
163 | case MGN_5_5M: |
164 | ret = DESC_RATE5_5M; |
165 | break; |
166 | case MGN_11M: |
167 | ret = DESC_RATE11M; |
168 | break; |
169 | case MGN_6M: |
170 | ret = DESC_RATE6M; |
171 | break; |
172 | case MGN_9M: |
173 | ret = DESC_RATE9M; |
174 | break; |
175 | case MGN_12M: |
176 | ret = DESC_RATE12M; |
177 | break; |
178 | case MGN_18M: |
179 | ret = DESC_RATE18M; |
180 | break; |
181 | case MGN_24M: |
182 | ret = DESC_RATE24M; |
183 | break; |
184 | case MGN_36M: |
185 | ret = DESC_RATE36M; |
186 | break; |
187 | case MGN_48M: |
188 | ret = DESC_RATE48M; |
189 | break; |
190 | case MGN_54M: |
191 | ret = DESC_RATE54M; |
192 | break; |
193 | case MGN_MCS0: |
194 | ret = DESC_RATEMCS0; |
195 | break; |
196 | case MGN_MCS1: |
197 | ret = DESC_RATEMCS1; |
198 | break; |
199 | case MGN_MCS2: |
200 | ret = DESC_RATEMCS2; |
201 | break; |
202 | case MGN_MCS3: |
203 | ret = DESC_RATEMCS3; |
204 | break; |
205 | case MGN_MCS4: |
206 | ret = DESC_RATEMCS4; |
207 | break; |
208 | case MGN_MCS5: |
209 | ret = DESC_RATEMCS5; |
210 | break; |
211 | case MGN_MCS6: |
212 | ret = DESC_RATEMCS6; |
213 | break; |
214 | case MGN_MCS7: |
215 | ret = DESC_RATEMCS7; |
216 | break; |
217 | default: |
218 | break; |
219 | } |
220 | |
221 | return ret; |
222 | } |
223 | |
224 | u8 HwRateToMRate(u8 rate) |
225 | { |
226 | u8 ret_rate = MGN_1M; |
227 | |
228 | switch (rate) { |
229 | case DESC_RATE1M: |
230 | ret_rate = MGN_1M; |
231 | break; |
232 | case DESC_RATE2M: |
233 | ret_rate = MGN_2M; |
234 | break; |
235 | case DESC_RATE5_5M: |
236 | ret_rate = MGN_5_5M; |
237 | break; |
238 | case DESC_RATE11M: |
239 | ret_rate = MGN_11M; |
240 | break; |
241 | case DESC_RATE6M: |
242 | ret_rate = MGN_6M; |
243 | break; |
244 | case DESC_RATE9M: |
245 | ret_rate = MGN_9M; |
246 | break; |
247 | case DESC_RATE12M: |
248 | ret_rate = MGN_12M; |
249 | break; |
250 | case DESC_RATE18M: |
251 | ret_rate = MGN_18M; |
252 | break; |
253 | case DESC_RATE24M: |
254 | ret_rate = MGN_24M; |
255 | break; |
256 | case DESC_RATE36M: |
257 | ret_rate = MGN_36M; |
258 | break; |
259 | case DESC_RATE48M: |
260 | ret_rate = MGN_48M; |
261 | break; |
262 | case DESC_RATE54M: |
263 | ret_rate = MGN_54M; |
264 | break; |
265 | case DESC_RATEMCS0: |
266 | ret_rate = MGN_MCS0; |
267 | break; |
268 | case DESC_RATEMCS1: |
269 | ret_rate = MGN_MCS1; |
270 | break; |
271 | case DESC_RATEMCS2: |
272 | ret_rate = MGN_MCS2; |
273 | break; |
274 | case DESC_RATEMCS3: |
275 | ret_rate = MGN_MCS3; |
276 | break; |
277 | case DESC_RATEMCS4: |
278 | ret_rate = MGN_MCS4; |
279 | break; |
280 | case DESC_RATEMCS5: |
281 | ret_rate = MGN_MCS5; |
282 | break; |
283 | case DESC_RATEMCS6: |
284 | ret_rate = MGN_MCS6; |
285 | break; |
286 | case DESC_RATEMCS7: |
287 | ret_rate = MGN_MCS7; |
288 | break; |
289 | default: |
290 | break; |
291 | } |
292 | |
293 | return ret_rate; |
294 | } |
295 | |
296 | void HalSetBrateCfg(struct adapter *Adapter, u8 *mBratesOS, u16 *pBrateCfg) |
297 | { |
298 | u8 i, is_brate, brate; |
299 | |
300 | for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { |
301 | |
302 | is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK; |
303 | brate = mBratesOS[i] & 0x7f; |
304 | |
305 | if (is_brate) { |
306 | switch (brate) { |
307 | case IEEE80211_CCK_RATE_1MB: |
308 | *pBrateCfg |= RATE_1M; |
309 | break; |
310 | case IEEE80211_CCK_RATE_2MB: |
311 | *pBrateCfg |= RATE_2M; |
312 | break; |
313 | case IEEE80211_CCK_RATE_5MB: |
314 | *pBrateCfg |= RATE_5_5M; |
315 | break; |
316 | case IEEE80211_CCK_RATE_11MB: |
317 | *pBrateCfg |= RATE_11M; |
318 | break; |
319 | case IEEE80211_OFDM_RATE_6MB: |
320 | *pBrateCfg |= RATE_6M; |
321 | break; |
322 | case IEEE80211_OFDM_RATE_9MB: |
323 | *pBrateCfg |= RATE_9M; |
324 | break; |
325 | case IEEE80211_OFDM_RATE_12MB: |
326 | *pBrateCfg |= RATE_12M; |
327 | break; |
328 | case IEEE80211_OFDM_RATE_18MB: |
329 | *pBrateCfg |= RATE_18M; |
330 | break; |
331 | case IEEE80211_OFDM_RATE_24MB: |
332 | *pBrateCfg |= RATE_24M; |
333 | break; |
334 | case IEEE80211_OFDM_RATE_36MB: |
335 | *pBrateCfg |= RATE_36M; |
336 | break; |
337 | case IEEE80211_OFDM_RATE_48MB: |
338 | *pBrateCfg |= RATE_48M; |
339 | break; |
340 | case IEEE80211_OFDM_RATE_54MB: |
341 | *pBrateCfg |= RATE_54M; |
342 | break; |
343 | } |
344 | } |
345 | } |
346 | } |
347 | |
348 | static void _OneOutPipeMapping(struct adapter *padapter) |
349 | { |
350 | struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); |
351 | |
352 | pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */ |
353 | pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */ |
354 | pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */ |
355 | pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */ |
356 | |
357 | pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ |
358 | pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ |
359 | pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ |
360 | pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ |
361 | } |
362 | |
363 | static void _TwoOutPipeMapping(struct adapter *padapter, bool bWIFICfg) |
364 | { |
365 | struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); |
366 | |
367 | if (bWIFICfg) { /* WMM */ |
368 | |
369 | /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ |
370 | /* 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */ |
371 | /* 0:ep_0 num, 1:ep_1 num */ |
372 | |
373 | pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */ |
374 | pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */ |
375 | pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */ |
376 | pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */ |
377 | |
378 | pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ |
379 | pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ |
380 | pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ |
381 | pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ |
382 | |
383 | } else { /* typical setting */ |
384 | |
385 | |
386 | /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ |
387 | /* 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */ |
388 | /* 0:ep_0 num, 1:ep_1 num */ |
389 | |
390 | pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */ |
391 | pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */ |
392 | pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */ |
393 | pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */ |
394 | |
395 | pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ |
396 | pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ |
397 | pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ |
398 | pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ |
399 | |
400 | } |
401 | |
402 | } |
403 | |
404 | static void _ThreeOutPipeMapping(struct adapter *padapter, bool bWIFICfg) |
405 | { |
406 | struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); |
407 | |
408 | if (bWIFICfg) { /* for WMM */ |
409 | |
410 | /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ |
411 | /* 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */ |
412 | /* 0:H, 1:N, 2:L */ |
413 | |
414 | pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */ |
415 | pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */ |
416 | pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */ |
417 | pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */ |
418 | |
419 | pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ |
420 | pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ |
421 | pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ |
422 | pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ |
423 | |
424 | } else { /* typical setting */ |
425 | |
426 | |
427 | /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ |
428 | /* 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */ |
429 | /* 0:H, 1:N, 2:L */ |
430 | |
431 | pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */ |
432 | pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */ |
433 | pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */ |
434 | pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */ |
435 | |
436 | pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ |
437 | pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ |
438 | pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ |
439 | pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ |
440 | } |
441 | |
442 | } |
443 | |
444 | bool Hal_MappingOutPipe(struct adapter *padapter, u8 NumOutPipe) |
445 | { |
446 | struct registry_priv *pregistrypriv = &padapter->registrypriv; |
447 | |
448 | bool bWIFICfg = (pregistrypriv->wifi_spec) ? true : false; |
449 | |
450 | bool result = true; |
451 | |
452 | switch (NumOutPipe) { |
453 | case 2: |
454 | _TwoOutPipeMapping(padapter, bWIFICfg); |
455 | break; |
456 | case 3: |
457 | case 4: |
458 | _ThreeOutPipeMapping(padapter, bWIFICfg); |
459 | break; |
460 | case 1: |
461 | _OneOutPipeMapping(padapter); |
462 | break; |
463 | default: |
464 | result = false; |
465 | break; |
466 | } |
467 | |
468 | return result; |
469 | |
470 | } |
471 | |
472 | void hal_init_macaddr(struct adapter *adapter) |
473 | { |
474 | rtw_hal_set_hwreg(padapter: adapter, variable: HW_VAR_MAC_ADDR, val: adapter->eeprompriv.mac_addr); |
475 | } |
476 | |
477 | void rtw_init_hal_com_default_value(struct adapter *Adapter) |
478 | { |
479 | struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); |
480 | |
481 | pHalData->AntDetection = 1; |
482 | } |
483 | |
484 | /* |
485 | * C2H event format: |
486 | * Field TRIGGER CONTENT CMD_SEQ CMD_LEN CMD_ID |
487 | * BITS [127:120] [119:16] [15:8] [7:4] [3:0] |
488 | */ |
489 | |
490 | void c2h_evt_clear(struct adapter *adapter) |
491 | { |
492 | rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); |
493 | } |
494 | |
495 | /* |
496 | * C2H event format: |
497 | * Field TRIGGER CMD_LEN CONTENT CMD_SEQ CMD_ID |
498 | * BITS [127:120] [119:112] [111:16] [15:8] [7:0] |
499 | */ |
500 | s32 c2h_evt_read_88xx(struct adapter *adapter, u8 *buf) |
501 | { |
502 | s32 ret = _FAIL; |
503 | struct c2h_evt_hdr_88xx *c2h_evt; |
504 | int i; |
505 | u8 trigger; |
506 | |
507 | if (!buf) |
508 | goto exit; |
509 | |
510 | trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR); |
511 | |
512 | if (trigger == C2H_EVT_HOST_CLOSE) |
513 | goto exit; /* Not ready */ |
514 | else if (trigger != C2H_EVT_FW_CLOSE) |
515 | goto clear_evt; /* Not a valid value */ |
516 | |
517 | c2h_evt = (struct c2h_evt_hdr_88xx *)buf; |
518 | |
519 | memset(c2h_evt, 0, 16); |
520 | |
521 | c2h_evt->id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL); |
522 | c2h_evt->seq = rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX); |
523 | c2h_evt->plen = rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX); |
524 | |
525 | /* Read the content */ |
526 | for (i = 0; i < c2h_evt->plen; i++) |
527 | c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i); |
528 | |
529 | ret = _SUCCESS; |
530 | |
531 | clear_evt: |
532 | /* |
533 | * Clear event to notify FW we have read the command. |
534 | * If this field isn't clear, the FW won't update the next command message. |
535 | */ |
536 | c2h_evt_clear(adapter); |
537 | exit: |
538 | return ret; |
539 | } |
540 | |
541 | u8 rtw_get_mgntframe_raid(struct adapter *adapter, unsigned char network_type) |
542 | { |
543 | return (network_type & WIRELESS_11B) ? RATEID_IDX_B : RATEID_IDX_G; |
544 | } |
545 | |
546 | void rtw_hal_update_sta_rate_mask(struct adapter *padapter, struct sta_info *psta) |
547 | { |
548 | u8 i, limit; |
549 | u32 tx_ra_bitmap; |
550 | |
551 | if (!psta) |
552 | return; |
553 | |
554 | tx_ra_bitmap = 0; |
555 | |
556 | /* b/g mode ra_bitmap */ |
557 | for (i = 0; i < sizeof(psta->bssrateset); i++) { |
558 | if (psta->bssrateset[i]) |
559 | tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(val: psta->bssrateset[i]&0x7f); |
560 | } |
561 | |
562 | /* n mode ra_bitmap */ |
563 | if (psta->htpriv.ht_option) { |
564 | limit = 8; /* 1R */ |
565 | |
566 | for (i = 0; i < limit; i++) { |
567 | if (psta->htpriv.ht_cap.mcs.rx_mask[i/8] & BIT(i%8)) |
568 | tx_ra_bitmap |= BIT(i+12); |
569 | } |
570 | } |
571 | |
572 | psta->ra_mask = tx_ra_bitmap; |
573 | psta->init_rate = get_highest_rate_idx(mask: tx_ra_bitmap)&0x3f; |
574 | } |
575 | |
576 | void hw_var_port_switch(struct adapter *adapter) |
577 | { |
578 | } |
579 | |
580 | void SetHwReg(struct adapter *adapter, u8 variable, u8 *val) |
581 | { |
582 | struct hal_com_data *hal_data = GET_HAL_DATA(adapter); |
583 | struct dm_odm_t *odm = &(hal_data->odmpriv); |
584 | |
585 | switch (variable) { |
586 | case HW_VAR_PORT_SWITCH: |
587 | hw_var_port_switch(adapter); |
588 | break; |
589 | case HW_VAR_INIT_RTS_RATE: |
590 | rtw_warn_on(1); |
591 | break; |
592 | case HW_VAR_SEC_CFG: |
593 | { |
594 | u16 reg_scr; |
595 | |
596 | reg_scr = rtw_read16(adapter, REG_SECCFG); |
597 | rtw_write16(adapter, REG_SECCFG, val: reg_scr|SCR_CHK_KEYID|SCR_RxDecEnable|SCR_TxEncEnable); |
598 | } |
599 | break; |
600 | case HW_VAR_SEC_DK_CFG: |
601 | { |
602 | struct security_priv *sec = &adapter->securitypriv; |
603 | u8 reg_scr = rtw_read8(adapter, REG_SECCFG); |
604 | |
605 | if (val) { /* Enable default key related setting */ |
606 | reg_scr |= SCR_TXBCUSEDK; |
607 | if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X) |
608 | reg_scr |= (SCR_RxUseDK|SCR_TxUseDK); |
609 | } else /* Disable default key related setting */ |
610 | reg_scr &= ~(SCR_RXBCUSEDK|SCR_TXBCUSEDK|SCR_RxUseDK|SCR_TxUseDK); |
611 | |
612 | rtw_write8(adapter, REG_SECCFG, val: reg_scr); |
613 | } |
614 | break; |
615 | case HW_VAR_DM_FLAG: |
616 | odm->SupportAbility = *((u32 *)val); |
617 | break; |
618 | case HW_VAR_DM_FUNC_OP: |
619 | if (*((u8 *)val) == true) { |
620 | /* save dm flag */ |
621 | odm->BK_SupportAbility = odm->SupportAbility; |
622 | } else { |
623 | /* restore dm flag */ |
624 | odm->SupportAbility = odm->BK_SupportAbility; |
625 | } |
626 | break; |
627 | case HW_VAR_DM_FUNC_SET: |
628 | if (*((u32 *)val) == DYNAMIC_ALL_FUNC_ENABLE) { |
629 | struct dm_priv *dm = &hal_data->dmpriv; |
630 | dm->DMFlag = dm->InitDMFlag; |
631 | odm->SupportAbility = dm->InitODMFlag; |
632 | } else { |
633 | odm->SupportAbility |= *((u32 *)val); |
634 | } |
635 | break; |
636 | case HW_VAR_DM_FUNC_CLR: |
637 | /* |
638 | * input is already a mask to clear function |
639 | * don't invert it again! George, Lucas@20130513 |
640 | */ |
641 | odm->SupportAbility &= *((u32 *)val); |
642 | break; |
643 | case HW_VAR_AMPDU_MIN_SPACE: |
644 | /* TODO - Is something needed here? */ |
645 | break; |
646 | case HW_VAR_WIRELESS_MODE: |
647 | /* TODO - Is something needed here? */ |
648 | break; |
649 | default: |
650 | netdev_dbg(adapter->pnetdev, |
651 | FUNC_ADPT_FMT " variable(%d) not defined!\n" , |
652 | FUNC_ADPT_ARG(adapter), variable); |
653 | break; |
654 | } |
655 | } |
656 | |
657 | void GetHwReg(struct adapter *adapter, u8 variable, u8 *val) |
658 | { |
659 | struct hal_com_data *hal_data = GET_HAL_DATA(adapter); |
660 | struct dm_odm_t *odm = &(hal_data->odmpriv); |
661 | |
662 | switch (variable) { |
663 | case HW_VAR_BASIC_RATE: |
664 | *((u16 *)val) = hal_data->BasicRateSet; |
665 | break; |
666 | case HW_VAR_DM_FLAG: |
667 | *((u32 *)val) = odm->SupportAbility; |
668 | break; |
669 | default: |
670 | netdev_dbg(adapter->pnetdev, |
671 | FUNC_ADPT_FMT " variable(%d) not defined!\n" , |
672 | FUNC_ADPT_ARG(adapter), variable); |
673 | break; |
674 | } |
675 | } |
676 | |
677 | |
678 | |
679 | |
680 | u8 SetHalDefVar( |
681 | struct adapter *adapter, enum hal_def_variable variable, void *value |
682 | ) |
683 | { |
684 | struct hal_com_data *hal_data = GET_HAL_DATA(adapter); |
685 | struct dm_odm_t *odm = &(hal_data->odmpriv); |
686 | u8 bResult = _SUCCESS; |
687 | |
688 | switch (variable) { |
689 | case HAL_DEF_DBG_RX_INFO_DUMP: |
690 | |
691 | if (odm->bLinked) { |
692 | #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA |
693 | rtw_dump_raw_rssi_info(adapter); |
694 | #endif |
695 | } |
696 | break; |
697 | case HW_DEF_ODM_DBG_FLAG: |
698 | ODM_CmnInfoUpdate(pDM_Odm: odm, CmnInfo: ODM_CMNINFO_DBG_COMP, Value: *((u64 *)value)); |
699 | break; |
700 | case HW_DEF_ODM_DBG_LEVEL: |
701 | ODM_CmnInfoUpdate(pDM_Odm: odm, CmnInfo: ODM_CMNINFO_DBG_LEVEL, Value: *((u32 *)value)); |
702 | break; |
703 | case HAL_DEF_DBG_DM_FUNC: |
704 | { |
705 | u8 dm_func = *((u8 *)value); |
706 | struct dm_priv *dm = &hal_data->dmpriv; |
707 | |
708 | if (dm_func == 0) { /* disable all dynamic func */ |
709 | odm->SupportAbility = DYNAMIC_FUNC_DISABLE; |
710 | } else if (dm_func == 1) {/* disable DIG */ |
711 | odm->SupportAbility &= (~DYNAMIC_BB_DIG); |
712 | } else if (dm_func == 2) {/* disable High power */ |
713 | odm->SupportAbility &= (~DYNAMIC_BB_DYNAMIC_TXPWR); |
714 | } else if (dm_func == 3) {/* disable tx power tracking */ |
715 | odm->SupportAbility &= (~DYNAMIC_RF_CALIBRATION); |
716 | } else if (dm_func == 4) {/* disable BT coexistence */ |
717 | dm->DMFlag &= (~DYNAMIC_FUNC_BT); |
718 | } else if (dm_func == 5) {/* disable antenna diversity */ |
719 | odm->SupportAbility &= (~DYNAMIC_BB_ANT_DIV); |
720 | } else if (dm_func == 6) {/* turn on all dynamic func */ |
721 | if (!(odm->SupportAbility & DYNAMIC_BB_DIG)) { |
722 | struct dig_t *pDigTable = &odm->DM_DigTable; |
723 | pDigTable->CurIGValue = rtw_read8(adapter, addr: 0xc50); |
724 | } |
725 | dm->DMFlag |= DYNAMIC_FUNC_BT; |
726 | odm->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE; |
727 | } |
728 | } |
729 | break; |
730 | case HAL_DEF_DBG_DUMP_RXPKT: |
731 | hal_data->bDumpRxPkt = *((u8 *)value); |
732 | break; |
733 | case HAL_DEF_DBG_DUMP_TXPKT: |
734 | hal_data->bDumpTxPkt = *((u8 *)value); |
735 | break; |
736 | case HAL_DEF_ANT_DETECT: |
737 | hal_data->AntDetection = *((u8 *)value); |
738 | break; |
739 | default: |
740 | netdev_dbg(adapter->pnetdev, |
741 | "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n" , |
742 | __func__, variable); |
743 | bResult = _FAIL; |
744 | break; |
745 | } |
746 | |
747 | return bResult; |
748 | } |
749 | |
750 | u8 GetHalDefVar( |
751 | struct adapter *adapter, enum hal_def_variable variable, void *value |
752 | ) |
753 | { |
754 | struct hal_com_data *hal_data = GET_HAL_DATA(adapter); |
755 | u8 bResult = _SUCCESS; |
756 | |
757 | switch (variable) { |
758 | case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: |
759 | { |
760 | struct mlme_priv *pmlmepriv; |
761 | struct sta_priv *pstapriv; |
762 | struct sta_info *psta; |
763 | |
764 | pmlmepriv = &adapter->mlmepriv; |
765 | pstapriv = &adapter->stapriv; |
766 | psta = rtw_get_stainfo(pstapriv, hwaddr: pmlmepriv->cur_network.network.mac_address); |
767 | if (psta) |
768 | *((int *)value) = psta->rssi_stat.UndecoratedSmoothedPWDB; |
769 | } |
770 | break; |
771 | case HAL_DEF_DBG_DM_FUNC: |
772 | *((u32 *)value) = hal_data->odmpriv.SupportAbility; |
773 | break; |
774 | case HAL_DEF_DBG_DUMP_RXPKT: |
775 | *((u8 *)value) = hal_data->bDumpRxPkt; |
776 | break; |
777 | case HAL_DEF_DBG_DUMP_TXPKT: |
778 | *((u8 *)value) = hal_data->bDumpTxPkt; |
779 | break; |
780 | case HAL_DEF_ANT_DETECT: |
781 | *((u8 *)value) = hal_data->AntDetection; |
782 | break; |
783 | case HAL_DEF_MACID_SLEEP: |
784 | *(u8 *)value = false; |
785 | break; |
786 | case HAL_DEF_TX_PAGE_SIZE: |
787 | *((u32 *)value) = PAGE_SIZE_128; |
788 | break; |
789 | default: |
790 | netdev_dbg(adapter->pnetdev, |
791 | "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n" , |
792 | __func__, variable); |
793 | bResult = _FAIL; |
794 | break; |
795 | } |
796 | |
797 | return bResult; |
798 | } |
799 | |
800 | void GetHalODMVar( |
801 | struct adapter *Adapter, |
802 | enum hal_odm_variable eVariable, |
803 | void *pValue1, |
804 | void *pValue2 |
805 | ) |
806 | { |
807 | switch (eVariable) { |
808 | default: |
809 | break; |
810 | } |
811 | } |
812 | |
813 | void SetHalODMVar( |
814 | struct adapter *Adapter, |
815 | enum hal_odm_variable eVariable, |
816 | void *pValue1, |
817 | bool bSet |
818 | ) |
819 | { |
820 | struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); |
821 | struct dm_odm_t *podmpriv = &pHalData->odmpriv; |
822 | /* _irqL irqL; */ |
823 | switch (eVariable) { |
824 | case HAL_ODM_STA_INFO: |
825 | { |
826 | struct sta_info *psta = pValue1; |
827 | if (bSet) { |
828 | ODM_CmnInfoPtrArrayHook(pDM_Odm: podmpriv, CmnInfo: ODM_CMNINFO_STA_STATUS, Index: psta->mac_id, pValue: psta); |
829 | } else { |
830 | /* spin_lock_bh(&pHalData->odm_stainfo_lock); */ |
831 | ODM_CmnInfoPtrArrayHook(pDM_Odm: podmpriv, CmnInfo: ODM_CMNINFO_STA_STATUS, Index: psta->mac_id, NULL); |
832 | |
833 | /* spin_unlock_bh(&pHalData->odm_stainfo_lock); */ |
834 | } |
835 | } |
836 | break; |
837 | case HAL_ODM_P2P_STATE: |
838 | ODM_CmnInfoUpdate(pDM_Odm: podmpriv, CmnInfo: ODM_CMNINFO_WIFI_DIRECT, Value: bSet); |
839 | break; |
840 | case HAL_ODM_WIFI_DISPLAY_STATE: |
841 | ODM_CmnInfoUpdate(pDM_Odm: podmpriv, CmnInfo: ODM_CMNINFO_WIFI_DISPLAY, Value: bSet); |
842 | break; |
843 | |
844 | default: |
845 | break; |
846 | } |
847 | } |
848 | |
849 | |
850 | bool eqNByte(u8 *str1, u8 *str2, u32 num) |
851 | { |
852 | if (num == 0) |
853 | return false; |
854 | while (num > 0) { |
855 | num--; |
856 | if (str1[num] != str2[num]) |
857 | return false; |
858 | } |
859 | return true; |
860 | } |
861 | |
862 | bool GetU1ByteIntegerFromStringInDecimal(char *Str, u8 *pInt) |
863 | { |
864 | u16 i = 0; |
865 | *pInt = 0; |
866 | |
867 | while (Str[i] != '\0') { |
868 | if (Str[i] >= '0' && Str[i] <= '9') { |
869 | *pInt *= 10; |
870 | *pInt += (Str[i] - '0'); |
871 | } else |
872 | return false; |
873 | |
874 | ++i; |
875 | } |
876 | |
877 | return true; |
878 | } |
879 | |
880 | void rtw_hal_check_rxfifo_full(struct adapter *adapter) |
881 | { |
882 | struct dvobj_priv *psdpriv = adapter->dvobj; |
883 | struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; |
884 | int save_cnt = false; |
885 | |
886 | /* switch counter to RX fifo */ |
887 | /* printk("8723b or 8192e , MAC_667 set 0xf0\n"); */ |
888 | rtw_write8(adapter, REG_RXERR_RPT+3, val: rtw_read8(adapter, REG_RXERR_RPT+3)|0xf0); |
889 | save_cnt = true; |
890 | /* todo: other chips */ |
891 | |
892 | if (save_cnt) { |
893 | /* rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xa0); */ |
894 | pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow; |
895 | pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT); |
896 | pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow-pdbgpriv->dbg_rx_fifo_last_overflow; |
897 | } |
898 | } |
899 | |
900 | #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA |
901 | void rtw_dump_raw_rssi_info(struct adapter *padapter) |
902 | { |
903 | u8 isCCKrate, rf_path; |
904 | struct hal_com_data *pHalData = GET_HAL_DATA(padapter); |
905 | struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info; |
906 | |
907 | isCCKrate = psample_pkt_rssi->data_rate <= DESC_RATE11M; |
908 | |
909 | if (isCCKrate) |
910 | psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball; |
911 | |
912 | for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) { |
913 | if (!isCCKrate) { |
914 | printk(", rx_ofdm_pwr:%d(dBm), rx_ofdm_snr:%d(dB)\n" , |
915 | psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]); |
916 | } else { |
917 | printk("\n" ); |
918 | } |
919 | } |
920 | } |
921 | |
922 | void rtw_store_phy_info(struct adapter *padapter, union recv_frame *prframe) |
923 | { |
924 | u8 isCCKrate, rf_path; |
925 | struct hal_com_data *pHalData = GET_HAL_DATA(padapter); |
926 | struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; |
927 | |
928 | struct odm_phy_info *pPhyInfo = (PODM_PHY_INFO_T)(&pattrib->phy_info); |
929 | struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info; |
930 | |
931 | psample_pkt_rssi->data_rate = pattrib->data_rate; |
932 | isCCKrate = pattrib->data_rate <= DESC_RATE11M; |
933 | |
934 | psample_pkt_rssi->pwdball = pPhyInfo->rx_pwd_ba11; |
935 | psample_pkt_rssi->pwr_all = pPhyInfo->recv_signal_power; |
936 | |
937 | for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) { |
938 | psample_pkt_rssi->mimo_signal_strength[rf_path] = pPhyInfo->rx_mimo_signal_strength[rf_path]; |
939 | psample_pkt_rssi->mimo_signal_quality[rf_path] = pPhyInfo->rx_mimo_signal_quality[rf_path]; |
940 | if (!isCCKrate) { |
941 | psample_pkt_rssi->ofdm_pwr[rf_path] = pPhyInfo->RxPwr[rf_path]; |
942 | psample_pkt_rssi->ofdm_snr[rf_path] = pPhyInfo->RxSNR[rf_path]; |
943 | } |
944 | } |
945 | } |
946 | #endif |
947 | |
948 | static u32 Array_kfreemap[] = { |
949 | 0xf8, 0xe, |
950 | 0xf6, 0xc, |
951 | 0xf4, 0xa, |
952 | 0xf2, 0x8, |
953 | 0xf0, 0x6, |
954 | 0xf3, 0x4, |
955 | 0xf5, 0x2, |
956 | 0xf7, 0x0, |
957 | 0xf9, 0x0, |
958 | 0xfc, 0x0, |
959 | }; |
960 | |
961 | void rtw_bb_rf_gain_offset(struct adapter *padapter) |
962 | { |
963 | u8 value = padapter->eeprompriv.EEPROMRFGainOffset; |
964 | u32 res, i = 0; |
965 | u32 *Array = Array_kfreemap; |
966 | u32 v1 = 0, v2 = 0, target = 0; |
967 | |
968 | if (value & BIT4) { |
969 | if (padapter->eeprompriv.EEPROMRFGainVal != 0xff) { |
970 | res = rtw_hal_read_rfreg(padapter, eRFPath: RF_PATH_A, RegAddr: 0x7f, BitMask: 0xffffffff); |
971 | res &= 0xfff87fff; |
972 | /* res &= 0xfff87fff; */ |
973 | for (i = 0; i < ARRAY_SIZE(Array_kfreemap); i += 2) { |
974 | v1 = Array[i]; |
975 | v2 = Array[i+1]; |
976 | if (v1 == padapter->eeprompriv.EEPROMRFGainVal) { |
977 | target = v2; |
978 | break; |
979 | } |
980 | } |
981 | PHY_SetRFReg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18|BIT17|BIT16|BIT15, target); |
982 | |
983 | /* res |= (padapter->eeprompriv.EEPROMRFGainVal & 0x0f)<< 15; */ |
984 | /* rtw_hal_write_rfreg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, RF_GAIN_OFFSET_MASK, res); */ |
985 | res = rtw_hal_read_rfreg(padapter, eRFPath: RF_PATH_A, RegAddr: 0x7f, BitMask: 0xffffffff); |
986 | } |
987 | } |
988 | } |
989 | |