1 /******************************************************************************
2 *
3 * Copyright(c) 2015 - 2016 Realtek Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 *
19 ******************************************************************************/
20 #define _HAL_HALMAC_C_
21
22 #include <drv_types.h> /* PADAPTER, struct dvobj_priv, SDIO_ERR_VAL8 and etc. */
23 #include <hal_data.h> /* efuse, PHAL_DATA_TYPE and etc. */
24 #include "halmac/halmac_api.h" /* HALMAC_FW_SIZE_MAX_88XX and etc. */
25 #include "hal_halmac.h" /* dvobj_to_halmac() and ect. */
26
27 #define DEFAULT_INDICATOR_TIMELMT 1000 /* ms */
28 #define FIRMWARE_MAX_SIZE HALMAC_FW_SIZE_MAX_88XX
29
30 /*
31 * Driver API for HALMAC operations
32 */
33
34 #ifdef CONFIG_SDIO_HCI
35 #include <rtw_sdio.h>
_halmac_sdio_cmd52_read(void * p,u32 offset)36 static u8 _halmac_sdio_cmd52_read(void *p, u32 offset)
37 {
38 struct dvobj_priv *d;
39 u8 val;
40 u8 ret;
41
42
43 d = (struct dvobj_priv *)p;
44 ret = rtw_sdio_read_cmd52(d, offset, &val, 1);
45 if (_FAIL == ret) {
46 RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
47 return SDIO_ERR_VAL8;
48 }
49
50 return val;
51 }
52
_halmac_sdio_cmd52_write(void * p,u32 offset,u8 val)53 static void _halmac_sdio_cmd52_write(void *p, u32 offset, u8 val)
54 {
55 struct dvobj_priv *d;
56 u8 ret;
57
58
59 d = (struct dvobj_priv *)p;
60 ret = rtw_sdio_write_cmd52(d, offset, &val, 1);
61 if (_FAIL == ret)
62 RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
63 }
64
_halmac_sdio_reg_read_8(void * p,u32 offset)65 static u8 _halmac_sdio_reg_read_8(void *p, u32 offset)
66 {
67 struct dvobj_priv *d;
68 u8 *pbuf;
69 u8 val;
70 int err;
71
72
73 d = (struct dvobj_priv *)p;
74 val = SDIO_ERR_VAL8;
75 pbuf = rtw_zmalloc(1);
76 if (!pbuf)
77 return val;
78
79 err = d->intf_ops->read(d, offset, pbuf, 1, 0);
80 if (err) {
81 RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
82 goto exit;
83 }
84
85 val = *pbuf;
86
87 exit:
88 rtw_mfree(pbuf, 1);
89
90 return val;
91 }
92
_halmac_sdio_reg_read_16(void * p,u32 offset)93 static u16 _halmac_sdio_reg_read_16(void *p, u32 offset)
94 {
95 struct dvobj_priv *d;
96 u8 *pbuf;
97 u16 val;
98 int err;
99
100
101 d = (struct dvobj_priv *)p;
102 val = SDIO_ERR_VAL16;
103 pbuf = rtw_zmalloc(2);
104 if (!pbuf)
105 return val;
106
107 err = d->intf_ops->read(d, offset, pbuf, 2, 0);
108 if (err) {
109 RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
110 goto exit;
111 }
112
113 val = le16_to_cpu(*(u16 *)pbuf);
114
115 exit:
116 rtw_mfree(pbuf, 2);
117
118 return val;
119 }
120
_halmac_sdio_reg_read_32(void * p,u32 offset)121 static u32 _halmac_sdio_reg_read_32(void *p, u32 offset)
122 {
123 struct dvobj_priv *d;
124 u8 *pbuf;
125 u32 val;
126 int err;
127
128
129 d = (struct dvobj_priv *)p;
130 val = SDIO_ERR_VAL32;
131 pbuf = rtw_zmalloc(4);
132 if (!pbuf)
133 return val;
134
135 err = d->intf_ops->read(d, offset, pbuf, 4, 0);
136 if (err) {
137 RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
138 goto exit;
139 }
140
141 val = le32_to_cpu(*(u32 *)pbuf);
142
143 exit:
144 rtw_mfree(pbuf, 4);
145
146 return val;
147 }
148
_halmac_sdio_reg_write_8(void * p,u32 offset,u8 val)149 static void _halmac_sdio_reg_write_8(void *p, u32 offset, u8 val)
150 {
151 struct dvobj_priv *d;
152 u8 *pbuf;
153 int err;
154
155
156 d = (struct dvobj_priv *)p;
157 pbuf = rtw_zmalloc(1);
158 if (!pbuf)
159 return;
160 _rtw_memcpy(pbuf, &val, 1);
161
162 err = d->intf_ops->write(d, offset, pbuf, 1, 0);
163 if (err)
164 RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
165
166 rtw_mfree(pbuf, 1);
167 }
168
_halmac_sdio_reg_write_16(void * p,u32 offset,u16 val)169 static void _halmac_sdio_reg_write_16(void *p, u32 offset, u16 val)
170 {
171 struct dvobj_priv *d;
172 u8 *pbuf;
173 int err;
174
175
176 d = (struct dvobj_priv *)p;
177 val = cpu_to_le16(val);
178 pbuf = rtw_zmalloc(2);
179 if (!pbuf)
180 return;
181 _rtw_memcpy(pbuf, &val, 2);
182
183 err = d->intf_ops->write(d, offset, pbuf, 2, 0);
184 if (err)
185 RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
186
187 rtw_mfree(pbuf, 2);
188 }
189
_halmac_sdio_reg_write_32(void * p,u32 offset,u32 val)190 static void _halmac_sdio_reg_write_32(void *p, u32 offset, u32 val)
191 {
192 struct dvobj_priv *d;
193 u8 *pbuf;
194 int err;
195
196
197 d = (struct dvobj_priv *)p;
198 val = cpu_to_le32(val);
199 pbuf = rtw_zmalloc(4);
200 if (!pbuf)
201 return;
202 _rtw_memcpy(pbuf, &val, 4);
203
204 err = d->intf_ops->write(d, offset, pbuf, 4, 0);
205 if (err)
206 RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
207
208 rtw_mfree(pbuf, 4);
209 }
210
211 #else /* !CONFIG_SDIO_HCI */
212
_halmac_reg_read_8(void * p,u32 offset)213 static u8 _halmac_reg_read_8(void *p, u32 offset)
214 {
215 struct dvobj_priv *d;
216 PADAPTER adapter;
217
218
219 d = (struct dvobj_priv *)p;
220 adapter = d->padapters[IFACE_ID0];
221
222 return rtw_read8(adapter, offset);
223 }
224
_halmac_reg_read_16(void * p,u32 offset)225 static u16 _halmac_reg_read_16(void *p, u32 offset)
226 {
227 struct dvobj_priv *d;
228 PADAPTER adapter;
229
230
231 d = (struct dvobj_priv *)p;
232 adapter = d->padapters[IFACE_ID0];
233
234 return rtw_read16(adapter, offset);
235 }
236
_halmac_reg_read_32(void * p,u32 offset)237 static u32 _halmac_reg_read_32(void *p, u32 offset)
238 {
239 struct dvobj_priv *d;
240 PADAPTER adapter;
241
242
243 d = (struct dvobj_priv *)p;
244 adapter = d->padapters[IFACE_ID0];
245
246 return rtw_read32(adapter, offset);
247 }
248
_halmac_reg_write_8(void * p,u32 offset,u8 val)249 static void _halmac_reg_write_8(void *p, u32 offset, u8 val)
250 {
251 struct dvobj_priv *d;
252 PADAPTER adapter;
253 int err;
254
255
256 d = (struct dvobj_priv *)p;
257 adapter = d->padapters[IFACE_ID0];
258
259 err = rtw_write8(adapter, offset, val);
260 if (err == _FAIL)
261 RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
262 }
263
_halmac_reg_write_16(void * p,u32 offset,u16 val)264 static void _halmac_reg_write_16(void *p, u32 offset, u16 val)
265 {
266 struct dvobj_priv *d;
267 PADAPTER adapter;
268 int err;
269
270
271 d = (struct dvobj_priv *)p;
272 adapter = d->padapters[IFACE_ID0];
273
274 err = rtw_write16(adapter, offset, val);
275 if (err == _FAIL)
276 RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
277 }
278
_halmac_reg_write_32(void * p,u32 offset,u32 val)279 static void _halmac_reg_write_32(void *p, u32 offset, u32 val)
280 {
281 struct dvobj_priv *d;
282 PADAPTER adapter;
283 int err;
284
285
286 d = (struct dvobj_priv *)p;
287 adapter = d->padapters[IFACE_ID0];
288
289 err = rtw_write32(adapter, offset, val);
290 if (err == _FAIL)
291 RTW_INFO("%s: [ERROR] I/O FAIL!\n", __FUNCTION__);
292 }
293 #endif /* !CONFIG_SDIO_HCI */
294
_halmac_mfree(void * p,void * buffer,u32 size)295 static u8 _halmac_mfree(void *p, void *buffer, u32 size)
296 {
297 rtw_mfree(buffer, size);
298 return _TRUE;
299 }
300
_halmac_malloc(void * p,u32 size)301 static void *_halmac_malloc(void *p, u32 size)
302 {
303 return rtw_zmalloc(size);
304 }
305
_halmac_memcpy(void * p,void * dest,void * src,u32 size)306 static u8 _halmac_memcpy(void *p, void *dest, void *src, u32 size)
307 {
308 _rtw_memcpy(dest, src, size);
309 return _TRUE;
310 }
311
_halmac_memset(void * p,void * addr,u8 value,u32 size)312 static u8 _halmac_memset(void *p, void *addr, u8 value, u32 size)
313 {
314 _rtw_memset(addr, value, size);
315 return _TRUE;
316 }
317
_halmac_udelay(void * p,u32 us)318 static void _halmac_udelay(void *p, u32 us)
319 {
320 rtw_udelay_os(us);
321 }
322
_halmac_mutex_init(void * p,HALMAC_MUTEX * pMutex)323 static u8 _halmac_mutex_init(void *p, HALMAC_MUTEX *pMutex)
324 {
325 _rtw_mutex_init(pMutex);
326 return _TRUE;
327 }
328
_halmac_mutex_deinit(void * p,HALMAC_MUTEX * pMutex)329 static u8 _halmac_mutex_deinit(void *p, HALMAC_MUTEX *pMutex)
330 {
331 _rtw_mutex_free(pMutex);
332 return _TRUE;
333 }
334
_halmac_mutex_lock(void * p,HALMAC_MUTEX * pMutex)335 static u8 _halmac_mutex_lock(void *p, HALMAC_MUTEX *pMutex)
336 {
337 int err;
338
339 err = _enter_critical_mutex(pMutex, NULL);
340 if (err)
341 return _FALSE;
342
343 return _TRUE;
344 }
345
_halmac_mutex_unlock(void * p,HALMAC_MUTEX * pMutex)346 static u8 _halmac_mutex_unlock(void *p, HALMAC_MUTEX *pMutex)
347 {
348 _exit_critical_mutex(pMutex, NULL);
349 return _TRUE;
350 }
351
_halmac_msg_print(void * p,u32 msg_type,u8 msg_level,s8 * fmt,...)352 static u8 _halmac_msg_print(void *p, u32 msg_type, u8 msg_level, s8 *fmt, ...)
353 {
354 #define MSG_LEN 100
355 #define MSG_PREFIX "[HALMAC]"
356 va_list args;
357 u8 str[MSG_LEN] = {0};
358 u32 type;
359 u8 level;
360
361
362 str[0] = '\n';
363 type = 0xFFFFFFFF;
364 if (rtw_drv_log_level <= _DRV_ERR_)
365 level = HALMAC_DBG_ERR;
366 else if (rtw_drv_log_level <= _DRV_INFO_)
367 level = HALMAC_DBG_WARN;
368 else
369 level = HALMAC_DBG_TRACE;
370
371 if (!(type & BIT(msg_type)))
372 return _TRUE;
373 if (level < msg_level)
374 return _TRUE;
375
376 va_start(args, fmt);
377 vsnprintf(str, MSG_LEN, fmt, args);
378 va_end(args);
379
380 if (msg_level <= HALMAC_DBG_ERR)
381 RTW_ERR(MSG_PREFIX "%s", str);
382 else if (msg_level <= HALMAC_DBG_WARN)
383 RTW_WARN(MSG_PREFIX "%s", str);
384 else
385 RTW_DBG(MSG_PREFIX "%s", str);
386
387 return _TRUE;
388 }
389
390 const char *const RTW_HALMAC_FEATURE_NAME[] = {
391 "HALMAC_FEATURE_CFG_PARA",
392 "HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE",
393 "HALMAC_FEATURE_DUMP_LOGICAL_EFUSE",
394 "HALMAC_FEATURE_UPDATE_PACKET",
395 "HALMAC_FEATURE_UPDATE_DATAPACK",
396 "HALMAC_FEATURE_RUN_DATAPACK",
397 "HALMAC_FEATURE_CHANNEL_SWITCH",
398 "HALMAC_FEATURE_IQK",
399 "HALMAC_FEATURE_POWER_TRACKING",
400 "HALMAC_FEATURE_PSD",
401 "HALMAC_FEATURE_ALL"
402 };
403
is_valid_id_status(HALMAC_FEATURE_ID id,HALMAC_CMD_PROCESS_STATUS status)404 static inline u8 is_valid_id_status(HALMAC_FEATURE_ID id, HALMAC_CMD_PROCESS_STATUS status)
405 {
406 switch (id) {
407 case HALMAC_FEATURE_CFG_PARA:
408 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
409 break;
410 case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
411 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
412 if (HALMAC_CMD_PROCESS_DONE != status) {
413 RTW_INFO("%s: <WARN> id(%d) unspecified status(%d)!\n",
414 __FUNCTION__, id, status);
415 }
416 break;
417 case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
418 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
419 if (HALMAC_CMD_PROCESS_DONE != status) {
420 RTW_INFO("%s: <WARN> id(%d) unspecified status(%d)!\n",
421 __FUNCTION__, id, status);
422 }
423 break;
424 case HALMAC_FEATURE_UPDATE_PACKET:
425 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
426 break;
427 case HALMAC_FEATURE_UPDATE_DATAPACK:
428 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
429 break;
430 case HALMAC_FEATURE_RUN_DATAPACK:
431 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
432 break;
433 case HALMAC_FEATURE_CHANNEL_SWITCH:
434 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
435 break;
436 case HALMAC_FEATURE_IQK:
437 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
438 break;
439 case HALMAC_FEATURE_POWER_TRACKING:
440 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
441 break;
442 case HALMAC_FEATURE_PSD:
443 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
444 break;
445 case HALMAC_FEATURE_ALL:
446 RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
447 break;
448 default:
449 RTW_INFO("%s: unknown feature id(%d)\n", __FUNCTION__, id);
450 return _FALSE;
451 }
452
453 return _TRUE;
454 }
455
init_halmac_event_with_waittime(struct dvobj_priv * d,HALMAC_FEATURE_ID id,u8 * buf,u32 size,u32 time)456 static int init_halmac_event_with_waittime(struct dvobj_priv *d, HALMAC_FEATURE_ID id, u8 *buf, u32 size, u32 time)
457 {
458 struct submit_ctx *sctx;
459
460
461 if (!d->hmpriv.indicator[id].sctx) {
462 sctx = (struct submit_ctx *)rtw_zmalloc(sizeof(*sctx));
463 if (!sctx)
464 return -1;
465 } else {
466 RTW_INFO("%s: <WARN> id(%d) sctx is not NULL!!\n", __FUNCTION__, id);
467 sctx = d->hmpriv.indicator[id].sctx;
468 d->hmpriv.indicator[id].sctx = NULL;
469 }
470
471 rtw_sctx_init(sctx, time);
472 d->hmpriv.indicator[id].buffer = buf;
473 d->hmpriv.indicator[id].buf_size = size;
474 d->hmpriv.indicator[id].ret_size = 0;
475 d->hmpriv.indicator[id].status = 0;
476 /* fill sctx at least to sure other variables are all ready! */
477 d->hmpriv.indicator[id].sctx = sctx;
478
479 return 0;
480 }
481
init_halmac_event(struct dvobj_priv * d,HALMAC_FEATURE_ID id,u8 * buf,u32 size)482 static inline int init_halmac_event(struct dvobj_priv *d, HALMAC_FEATURE_ID id, u8 *buf, u32 size)
483 {
484 return init_halmac_event_with_waittime(d, id, buf, size, DEFAULT_INDICATOR_TIMELMT);
485 }
486
free_halmac_event(struct dvobj_priv * d,HALMAC_FEATURE_ID id)487 static void free_halmac_event(struct dvobj_priv *d, HALMAC_FEATURE_ID id)
488 {
489 struct submit_ctx *sctx;
490
491
492 if (!d->hmpriv.indicator[id].sctx)
493 return;
494
495 sctx = d->hmpriv.indicator[id].sctx;
496 d->hmpriv.indicator[id].sctx = NULL;
497 rtw_mfree((u8 *)sctx, sizeof(*sctx));
498 }
499
wait_halmac_event(struct dvobj_priv * d,HALMAC_FEATURE_ID id)500 static int wait_halmac_event(struct dvobj_priv *d, HALMAC_FEATURE_ID id)
501 {
502 struct submit_ctx *sctx;
503 int ret;
504
505
506 sctx = d->hmpriv.indicator[id].sctx;
507 if (!sctx)
508 return -1;
509
510 ret = rtw_sctx_wait(sctx, RTW_HALMAC_FEATURE_NAME[id]);
511 free_halmac_event(d, id);
512 if (_SUCCESS == ret)
513 return 0;
514
515 return -1;
516 }
517
518 /*
519 * Return:
520 * Always return _TRUE, HALMAC don't care the return value.
521 */
_halmac_event_indication(void * p,HALMAC_FEATURE_ID feature_id,HALMAC_CMD_PROCESS_STATUS process_status,u8 * buf,u32 size)522 static u8 _halmac_event_indication(void *p, HALMAC_FEATURE_ID feature_id, HALMAC_CMD_PROCESS_STATUS process_status, u8 *buf, u32 size)
523 {
524 struct dvobj_priv *d;
525 PADAPTER adapter;
526 PHAL_DATA_TYPE hal;
527 struct halmac_indicator *tbl, *indicator;
528 struct submit_ctx *sctx;
529 u32 cpsz;
530 u8 ret;
531
532
533 d = (struct dvobj_priv *)p;
534 adapter = d->padapters[IFACE_ID0];
535 hal = GET_HAL_DATA(adapter);
536 tbl = d->hmpriv.indicator;
537
538 ret = is_valid_id_status(feature_id, process_status);
539 if (_FALSE == ret)
540 goto exit;
541
542 indicator = &tbl[feature_id];
543 indicator->status = process_status;
544 indicator->ret_size = size;
545 if (!indicator->sctx) {
546 RTW_INFO("%s: No feature id(%d) waiting!!\n", __FUNCTION__, feature_id);
547 goto exit;
548 }
549 sctx = indicator->sctx;
550
551 if (HALMAC_CMD_PROCESS_ERROR == process_status) {
552 RTW_INFO("%s: Something wrong id(%d)!!\n", __FUNCTION__, feature_id);
553 rtw_sctx_done_err(&sctx, RTW_SCTX_DONE_UNKNOWN);
554 goto exit;
555 }
556
557 if (size > indicator->buf_size) {
558 RTW_INFO("%s: <WARN> id(%d) buffer is not enough(%d<%d), data will be truncated!\n",
559 __FUNCTION__, feature_id, indicator->buf_size, size);
560 cpsz = indicator->buf_size;
561 } else
562 cpsz = size;
563 if (cpsz && indicator->buffer)
564 _rtw_memcpy(indicator->buffer, buf, cpsz);
565
566 rtw_sctx_done(&sctx);
567
568 exit:
569 return _TRUE;
570 }
571
572 HALMAC_PLATFORM_API rtw_halmac_platform_api = {
573 /* R/W register */
574 #ifdef CONFIG_SDIO_HCI
575 .SDIO_CMD52_READ = _halmac_sdio_cmd52_read,
576 .SDIO_CMD53_READ_8 = _halmac_sdio_reg_read_8,
577 .SDIO_CMD53_READ_16 = _halmac_sdio_reg_read_16,
578 .SDIO_CMD53_READ_32 = _halmac_sdio_reg_read_32,
579 .SDIO_CMD52_WRITE = _halmac_sdio_cmd52_write,
580 .SDIO_CMD53_WRITE_8 = _halmac_sdio_reg_write_8,
581 .SDIO_CMD53_WRITE_16 = _halmac_sdio_reg_write_16,
582 .SDIO_CMD53_WRITE_32 = _halmac_sdio_reg_write_32,
583 #endif /* CONFIG_SDIO_HCI */
584 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCIE_HCI)
585 .REG_READ_8 = _halmac_reg_read_8,
586 .REG_READ_16 = _halmac_reg_read_16,
587 .REG_READ_32 = _halmac_reg_read_32,
588 .REG_WRITE_8 = _halmac_reg_write_8,
589 .REG_WRITE_16 = _halmac_reg_write_16,
590 .REG_WRITE_32 = _halmac_reg_write_32,
591 #endif /* CONFIG_USB_HCI || CONFIG_PCIE_HCI */
592
593 /* Write data */
594 #if 0
595 /* impletement in HAL-IC level */
596 .SEND_RSVD_PAGE = sdio_write_data_rsvd_page,
597 .SEND_H2C_PKT = sdio_write_data_h2c,
598 #endif
599 /* Memory allocate */
600 .RTL_FREE = _halmac_mfree,
601 .RTL_MALLOC = _halmac_malloc,
602 .RTL_MEMCPY = _halmac_memcpy,
603 .RTL_MEMSET = _halmac_memset,
604
605 /* Sleep */
606 .RTL_DELAY_US = _halmac_udelay,
607
608 /* Process Synchronization */
609 .MUTEX_INIT = _halmac_mutex_init,
610 .MUTEX_DEINIT = _halmac_mutex_deinit,
611 .MUTEX_LOCK = _halmac_mutex_lock,
612 .MUTEX_UNLOCK = _halmac_mutex_unlock,
613
614 .MSG_PRINT = _halmac_msg_print,
615 .EVENT_INDICATION = _halmac_event_indication,
616 };
617
rtw_halmac_read8(struct intf_hdl * pintfhdl,u32 addr)618 u8 rtw_halmac_read8(struct intf_hdl *pintfhdl, u32 addr)
619 {
620 PHALMAC_ADAPTER mac;
621 PHALMAC_API api;
622
623
624 /* WARNING: pintf_dev should not be null! */
625 mac = dvobj_to_halmac(pintfhdl->pintf_dev);
626 api = HALMAC_GET_API(mac);
627
628 return api->halmac_reg_read_8(mac, addr);
629 }
630
rtw_halmac_read16(struct intf_hdl * pintfhdl,u32 addr)631 u16 rtw_halmac_read16(struct intf_hdl *pintfhdl, u32 addr)
632 {
633 PHALMAC_ADAPTER mac;
634 PHALMAC_API api;
635
636
637 /* WARNING: pintf_dev should not be null! */
638 mac = dvobj_to_halmac(pintfhdl->pintf_dev);
639 api = HALMAC_GET_API(mac);
640
641 return api->halmac_reg_read_16(mac, addr);
642 }
643
rtw_halmac_read32(struct intf_hdl * pintfhdl,u32 addr)644 u32 rtw_halmac_read32(struct intf_hdl *pintfhdl, u32 addr)
645 {
646 PHALMAC_ADAPTER mac;
647 PHALMAC_API api;
648
649
650 /* WARNING: pintf_dev should not be null! */
651 mac = dvobj_to_halmac(pintfhdl->pintf_dev);
652 api = HALMAC_GET_API(mac);
653
654 return api->halmac_reg_read_32(mac, addr);
655 }
656
rtw_halmac_write8(struct intf_hdl * pintfhdl,u32 addr,u8 value)657 int rtw_halmac_write8(struct intf_hdl *pintfhdl, u32 addr, u8 value)
658 {
659 PHALMAC_ADAPTER mac;
660 PHALMAC_API api;
661 HALMAC_RET_STATUS status;
662
663
664 /* WARNING: pintf_dev should not be null! */
665 mac = dvobj_to_halmac(pintfhdl->pintf_dev);
666 api = HALMAC_GET_API(mac);
667
668 status = api->halmac_reg_write_8(mac, addr, value);
669
670 if (status == HALMAC_RET_SUCCESS)
671 return 0;
672
673 return -1;
674 }
675
rtw_halmac_write16(struct intf_hdl * pintfhdl,u32 addr,u16 value)676 int rtw_halmac_write16(struct intf_hdl *pintfhdl, u32 addr, u16 value)
677 {
678 PHALMAC_ADAPTER mac;
679 PHALMAC_API api;
680 HALMAC_RET_STATUS status;
681
682
683 /* WARNING: pintf_dev should not be null! */
684 mac = dvobj_to_halmac(pintfhdl->pintf_dev);
685 api = HALMAC_GET_API(mac);
686
687 status = api->halmac_reg_write_16(mac, addr, value);
688
689 if (status == HALMAC_RET_SUCCESS)
690 return 0;
691
692 return -1;
693 }
694
rtw_halmac_write32(struct intf_hdl * pintfhdl,u32 addr,u32 value)695 int rtw_halmac_write32(struct intf_hdl *pintfhdl, u32 addr, u32 value)
696 {
697 PHALMAC_ADAPTER mac;
698 PHALMAC_API api;
699 HALMAC_RET_STATUS status;
700
701
702 /* WARNING: pintf_dev should not be null! */
703 mac = dvobj_to_halmac(pintfhdl->pintf_dev);
704 api = HALMAC_GET_API(mac);
705
706 status = api->halmac_reg_write_32(mac, addr, value);
707
708 if (status == HALMAC_RET_SUCCESS)
709 return 0;
710
711 return -1;
712 }
713
init_priv(struct halmacpriv * priv)714 static int init_priv(struct halmacpriv *priv)
715 {
716 struct halmac_indicator *indicator;
717 u32 count, size;
718
719
720 size = sizeof(*priv);
721 _rtw_memset(priv, 0, size);
722
723 count = HALMAC_FEATURE_ALL + 1;
724 size = sizeof(*indicator) * count;
725 indicator = (struct halmac_indicator *)rtw_zmalloc(size);
726 if (!indicator)
727 return -1;
728 priv->indicator = indicator;
729
730 return 0;
731 }
732
deinit_priv(struct halmacpriv * priv)733 static void deinit_priv(struct halmacpriv *priv)
734 {
735 struct halmac_indicator *indicator;
736
737
738 indicator = priv->indicator;
739 priv->indicator = NULL;
740 if (indicator) {
741 u32 count, size;
742
743 count = HALMAC_FEATURE_ALL + 1;
744 #ifdef CONFIG_RTW_DEBUG
745 {
746 struct submit_ctx *sctx;
747 u32 i;
748
749 for (i = 0; i < count; i++) {
750 if (!indicator[i].sctx)
751 continue;
752
753 RTW_INFO("%s: <WARN> %s id(%d) sctx still exist!!\n",
754 __FUNCTION__, RTW_HALMAC_FEATURE_NAME[i], i);
755 sctx = indicator[i].sctx;
756 indicator[i].sctx = NULL;
757 rtw_mfree((u8 *)sctx, sizeof(*sctx));
758 }
759 }
760 #endif /* !CONFIG_RTW_DEBUG */
761 size = sizeof(*indicator) * count;
762 rtw_mfree((u8 *)indicator, size);
763 }
764 }
765
rtw_halmac_init_adapter(struct dvobj_priv * d,PHALMAC_PLATFORM_API pf_api)766 int rtw_halmac_init_adapter(struct dvobj_priv *d, PHALMAC_PLATFORM_API pf_api)
767 {
768 PHALMAC_ADAPTER halmac;
769 PHALMAC_API api;
770 HALMAC_INTERFACE intf;
771 HALMAC_RET_STATUS status;
772 int err = 0;
773
774
775 halmac = dvobj_to_halmac(d);
776 if (halmac) {
777 err = 0;
778 goto out;
779 }
780
781 err = init_priv(&d->hmpriv);
782 if (err)
783 goto out;
784
785 #ifdef CONFIG_SDIO_HCI
786 intf = HALMAC_INTERFACE_SDIO;
787 #elif defined(CONFIG_USB_HCI)
788 intf = HALMAC_INTERFACE_USB;
789 #elif defined(CONFIG_PCIE_HCI)
790 intf = HALMAC_INTERFACE_PCIE;
791 #else
792 #warning "INTERFACE(CONFIG_XXX_HCI) not be defined!!"
793 intf = HALMAC_INTERFACE_UNDEFINE;
794 #endif
795 status = halmac_init_adapter(d, pf_api, intf, &halmac, &api);
796 if (HALMAC_RET_SUCCESS != status) {
797 RTW_INFO("%s: halmac_init_adapter fail!(status=%d)\n", __FUNCTION__, status);
798 err = -1;
799 goto out;
800 }
801
802 dvobj_set_halmac(d, halmac);
803
804 out:
805 if (err)
806 rtw_halmac_deinit_adapter(d);
807
808 return err;
809 }
810
rtw_halmac_deinit_adapter(struct dvobj_priv * d)811 int rtw_halmac_deinit_adapter(struct dvobj_priv *d)
812 {
813 PHALMAC_ADAPTER halmac;
814 HALMAC_RET_STATUS status;
815 int err = 0;
816
817
818 halmac = dvobj_to_halmac(d);
819 if (!halmac) {
820 err = 0;
821 goto out;
822 }
823
824 deinit_priv(&d->hmpriv);
825
826 status = halmac_deinit_adapter(halmac);
827 dvobj_set_halmac(d, NULL);
828 if (status != HALMAC_RET_SUCCESS) {
829 err = -1;
830 goto out;
831 }
832
833 out:
834 return err;
835 }
836
rtw_halmac_poweron(struct dvobj_priv * d)837 int rtw_halmac_poweron(struct dvobj_priv *d)
838 {
839 PHALMAC_ADAPTER halmac;
840 PHALMAC_API api;
841 HALMAC_RET_STATUS status;
842 int err = -1;
843
844
845 halmac = dvobj_to_halmac(d);
846 if (!halmac)
847 goto out;
848
849 api = HALMAC_GET_API(halmac);
850
851 status = api->halmac_pre_init_system_cfg(halmac);
852 if (status != HALMAC_RET_SUCCESS)
853 goto out;
854
855 status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_ON);
856 if (status != HALMAC_RET_SUCCESS)
857 goto out;
858
859 status = api->halmac_init_system_cfg(halmac);
860 if (status != HALMAC_RET_SUCCESS)
861 goto out;
862
863 err = 0;
864 out:
865 return err;
866 }
867
rtw_halmac_poweroff(struct dvobj_priv * d)868 int rtw_halmac_poweroff(struct dvobj_priv *d)
869 {
870 PHALMAC_ADAPTER halmac;
871 PHALMAC_API api;
872 HALMAC_RET_STATUS status;
873 int err = -1;
874
875
876 halmac = dvobj_to_halmac(d);
877 if (!halmac)
878 goto out;
879
880 api = HALMAC_GET_API(halmac);
881
882 status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_OFF);
883 if (status != HALMAC_RET_SUCCESS)
884 goto out;
885
886 err = 0;
887 out:
888 return err;
889 }
890
891 /*
892 * Note:
893 * When this function return, the register REG_RCR may be changed.
894 */
rtw_halmac_config_rx_info(struct dvobj_priv * d,HALMAC_DRV_INFO info)895 int rtw_halmac_config_rx_info(struct dvobj_priv *d, HALMAC_DRV_INFO info)
896 {
897 PHALMAC_ADAPTER halmac;
898 PHALMAC_API api;
899 HALMAC_RET_STATUS status;
900 int err = -1;
901
902
903 halmac = dvobj_to_halmac(d);
904 api = HALMAC_GET_API(halmac);
905
906 status = api->halmac_cfg_drv_info(halmac, info);
907 if (status != HALMAC_RET_SUCCESS)
908 goto out;
909
910 err = 0;
911 out:
912 return err;
913 }
914
init_mac_flow(struct dvobj_priv * d)915 static HALMAC_RET_STATUS init_mac_flow(struct dvobj_priv *d)
916 {
917 PADAPTER p;
918 PHALMAC_ADAPTER halmac;
919 PHALMAC_API api;
920 HALMAC_WLAN_ADDR hwa;
921 HALMAC_RET_STATUS status;
922 u8 wifi_test = 0;
923 u8 nettype;
924 int err;
925
926
927 p = d->padapters[IFACE_ID0];
928 halmac = dvobj_to_halmac(d);
929 api = HALMAC_GET_API(halmac);
930 if (p->registrypriv.wifi_spec)
931 wifi_test = 1;
932
933 #ifdef CONFIG_USB_HCI
934 status = api->halmac_set_bulkout_num(halmac, d->RtNumOutPipes);
935 if (status != HALMAC_RET_SUCCESS)
936 goto out;
937 #endif /* CONFIG_USB_HCI */
938
939 if (wifi_test)
940 status = api->halmac_init_mac_cfg(halmac, HALMAC_TRX_MODE_WMM);
941 else
942 status = api->halmac_init_mac_cfg(halmac, HALMAC_TRX_MODE_NORMAL);
943 if (status != HALMAC_RET_SUCCESS)
944 goto out;
945
946 err = rtw_halmac_rx_agg_switch(d, _TRUE);
947 if (err)
948 goto out;
949
950 nettype = dvobj_to_regsty(d)->wireless_mode;
951 if (IsSupportedVHT(nettype) == _TRUE)
952 status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_AC);
953 else if (IsSupportedHT(nettype) == _TRUE)
954 status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_N);
955 else if (IsSupportedTxOFDM(nettype) == _TRUE)
956 status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_G);
957 else
958 status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_B);
959 if (status != HALMAC_RET_SUCCESS)
960 goto out;
961
962 out:
963 return status;
964 }
965
_rf_type_drv2halmac(RT_RF_TYPE_DEF_E rf_drv)966 static inline HALMAC_RF_TYPE _rf_type_drv2halmac(RT_RF_TYPE_DEF_E rf_drv)
967 {
968 HALMAC_RF_TYPE rf_mac;
969
970
971 switch (rf_drv) {
972 case RF_1T2R:
973 rf_mac = HALMAC_RF_1T2R;
974 break;
975 case RF_2T4R:
976 rf_mac = HALMAC_RF_2T4R;
977 break;
978 case RF_2T2R:
979 rf_mac = HALMAC_RF_2T2R;
980 break;
981 case RF_1T1R:
982 rf_mac = HALMAC_RF_1T1R;
983 break;
984 case RF_2T2R_GREEN:
985 rf_mac = HALMAC_RF_2T2R_GREEN;
986 break;
987 case RF_2T3R:
988 rf_mac = HALMAC_RF_2T3R;
989 break;
990 case RF_3T3R:
991 rf_mac = HALMAC_RF_3T3R;
992 break;
993 case RF_3T4R:
994 rf_mac = HALMAC_RF_3T4R;
995 break;
996 case RF_4T4R:
997 rf_mac = HALMAC_RF_4T4R;
998 break;
999 default:
1000 rf_mac = (HALMAC_RF_TYPE)rf_drv;
1001 break;
1002 }
1003
1004 return rf_mac;
1005 }
1006
_send_general_info(struct dvobj_priv * d)1007 static int _send_general_info(struct dvobj_priv *d)
1008 {
1009 PADAPTER adapter;
1010 PHAL_DATA_TYPE hal;
1011 PHALMAC_ADAPTER halmac;
1012 PHALMAC_API api;
1013 HALMAC_GENERAL_INFO info;
1014 HALMAC_RET_STATUS status;
1015 u8 val8;
1016
1017
1018 adapter = d->padapters[IFACE_ID0];
1019 hal = GET_HAL_DATA(adapter);
1020 halmac = dvobj_to_halmac(d);
1021 if (!halmac)
1022 return -1;
1023 api = HALMAC_GET_API(halmac);
1024
1025 _rtw_memset(&info, 0, sizeof(info));
1026 info.rfe_type = (u8)hal->RFEType;
1027 rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, &val8);
1028 info.rf_type = _rf_type_drv2halmac(val8);
1029
1030 status = api->halmac_send_general_info(halmac, &info);
1031 switch (status) {
1032 case HALMAC_RET_SUCCESS:
1033 break;
1034 case HALMAC_RET_NO_DLFW:
1035 RTW_WARN("%s: halmac_send_general_info() fail because fw not dl!\n",
1036 __FUNCTION__);
1037 /* go through */
1038 default:
1039 return -1;
1040 }
1041
1042 return 0;
1043 }
1044
1045 /*
1046 * Notices:
1047 * Make sure
1048 * 1. rtw_hal_get_hwreg(HW_VAR_RF_TYPE)
1049 * 2. HAL_DATA_TYPE.rfe_type
1050 * already ready for use before calling this function.
1051 */
_halmac_init_hal(struct dvobj_priv * d,u8 * fw,u32 fwsize)1052 static int _halmac_init_hal(struct dvobj_priv *d, u8 *fw, u32 fwsize)
1053 {
1054 PADAPTER adapter;
1055 PHALMAC_ADAPTER halmac;
1056 PHALMAC_API api;
1057 HALMAC_RET_STATUS status;
1058 u32 ok = _TRUE;
1059 u8 fw_ok = _FALSE;
1060 int err, err_ret = -1;
1061
1062
1063 adapter = d->padapters[IFACE_ID0];
1064 halmac = dvobj_to_halmac(d);
1065 if (!halmac)
1066 goto out;
1067 api = HALMAC_GET_API(halmac);
1068
1069 /* StatePowerOff */
1070
1071 /* SKIP: halmac_init_adapter (Already done before) */
1072
1073 /* halmac_pre_Init_system_cfg */
1074 /* halmac_mac_power_switch(on) */
1075 /* halmac_Init_system_cfg */
1076 ok = rtw_hal_power_on(adapter);
1077 if (_FALSE == ok)
1078 goto out;
1079
1080 /* StatePowerOn */
1081
1082 /* DownloadFW */
1083 d->hmpriv.send_general_info = 0;
1084 if (fw && fwsize) {
1085 err = rtw_halmac_dlfw(d, fw, fwsize);
1086 if (err)
1087 goto out;
1088 fw_ok = _TRUE;
1089 }
1090
1091 /* InitMACFlow */
1092 status = init_mac_flow(d);
1093 if (status != HALMAC_RET_SUCCESS)
1094 goto out;
1095
1096 /* halmac_send_general_info */
1097 if (_TRUE == fw_ok) {
1098 d->hmpriv.send_general_info = 0;
1099 err = _send_general_info(d);
1100 if (err)
1101 goto out;
1102 } else
1103 d->hmpriv.send_general_info = 1;
1104
1105 /* Init Phy parameter-MAC */
1106 ok = rtw_hal_init_mac_register(adapter);
1107 if (_FALSE == ok)
1108 goto out;
1109
1110 /* StateMacInitialized */
1111
1112 /* halmac_cfg_drv_info */
1113 err = rtw_halmac_config_rx_info(d, HALMAC_DRV_INFO_PHY_STATUS);
1114 if (err)
1115 goto out;
1116
1117 /* halmac_set_hw_value(HALMAC_HW_EN_BB_RF) */
1118 /* Init BB, RF */
1119 ok = rtw_hal_init_phy(adapter);
1120 if (_FALSE == ok)
1121 goto out;
1122
1123 status = api->halmac_init_interface_cfg(halmac);
1124 if (status != HALMAC_RET_SUCCESS)
1125 goto out;
1126
1127 /* SKIP: halmac_verify_platform_api */
1128 /* SKIP: halmac_h2c_lb */
1129
1130 /* StateRxIdle */
1131
1132 err_ret = 0;
1133 out:
1134 return err_ret;
1135 }
1136
rtw_halmac_init_hal(struct dvobj_priv * d)1137 int rtw_halmac_init_hal(struct dvobj_priv *d)
1138 {
1139 return _halmac_init_hal(d, NULL, 0);
1140 }
1141
1142 /*
1143 * Notices:
1144 * Make sure
1145 * 1. rtw_hal_get_hwreg(HW_VAR_RF_TYPE)
1146 * 2. HAL_DATA_TYPE.rfe_type
1147 * already ready for use before calling this function.
1148 */
rtw_halmac_init_hal_fw(struct dvobj_priv * d,u8 * fw,u32 fwsize)1149 int rtw_halmac_init_hal_fw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
1150 {
1151 return _halmac_init_hal(d, fw, fwsize);
1152 }
1153
1154 /*
1155 * Notices:
1156 * Make sure
1157 * 1. rtw_hal_get_hwreg(HW_VAR_RF_TYPE)
1158 * 2. HAL_DATA_TYPE.rfe_type
1159 * already ready for use before calling this function.
1160 */
rtw_halmac_init_hal_fw_file(struct dvobj_priv * d,u8 * fwpath)1161 int rtw_halmac_init_hal_fw_file(struct dvobj_priv *d, u8 *fwpath)
1162 {
1163 u8 *fw = NULL;
1164 u32 fwmaxsize, size = 0;
1165 int err = 0;
1166
1167
1168 fwmaxsize = FIRMWARE_MAX_SIZE;
1169 fw = rtw_zmalloc(fwmaxsize);
1170 if (!fw)
1171 return -1;
1172
1173 size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
1174 if (!size) {
1175 err = -1;
1176 goto exit;
1177 }
1178
1179 err = _halmac_init_hal(d, fw, size);
1180
1181 exit:
1182 rtw_mfree(fw, fwmaxsize);
1183 fw = NULL;
1184
1185 return err;
1186 }
1187
rtw_halmac_deinit_hal(struct dvobj_priv * d)1188 int rtw_halmac_deinit_hal(struct dvobj_priv *d)
1189 {
1190 PADAPTER adapter;
1191 PHALMAC_ADAPTER halmac;
1192 PHALMAC_API api;
1193 HALMAC_RET_STATUS status;
1194 int err = -1;
1195
1196
1197 adapter = d->padapters[IFACE_ID0];
1198 halmac = dvobj_to_halmac(d);
1199 if (!halmac)
1200 goto out;
1201 api = HALMAC_GET_API(halmac);
1202
1203 status = api->halmac_deinit_interface_cfg(halmac);
1204 if (status != HALMAC_RET_SUCCESS)
1205 goto out;
1206
1207 rtw_hal_power_off(adapter);
1208
1209 err = 0;
1210 out:
1211 return err;
1212 }
1213
rtw_halmac_self_verify(struct dvobj_priv * d)1214 int rtw_halmac_self_verify(struct dvobj_priv *d)
1215 {
1216 PHALMAC_ADAPTER mac;
1217 PHALMAC_API api;
1218 HALMAC_RET_STATUS status;
1219 int err = -1;
1220
1221
1222 mac = dvobj_to_halmac(d);
1223 api = HALMAC_GET_API(mac);
1224
1225 status = api->halmac_verify_platform_api(mac);
1226 if (status != HALMAC_RET_SUCCESS)
1227 goto out;
1228
1229 status = api->halmac_h2c_lb(mac);
1230 if (status != HALMAC_RET_SUCCESS)
1231 goto out;
1232
1233 err = 0;
1234 out:
1235 return err;
1236 }
1237
rtw_halmac_dlfw(struct dvobj_priv * d,u8 * fw,u32 fwsize)1238 int rtw_halmac_dlfw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
1239 {
1240 PHALMAC_ADAPTER mac;
1241 PHALMAC_API api;
1242 HALMAC_RET_STATUS status;
1243 int err = 0;
1244 PHAL_DATA_TYPE hal;
1245 HALMAC_FW_VERSION fw_vesion;
1246
1247
1248 mac = dvobj_to_halmac(d);
1249 api = HALMAC_GET_API(mac);
1250 hal = GET_HAL_DATA(d->padapters[IFACE_ID0]);
1251
1252 if ((!fw) || (!fwsize))
1253 return -1;
1254
1255 /* 1. Driver Stop Tx */
1256 /* ToDo */
1257
1258 /* 2. Driver Check Tx FIFO is empty */
1259 /* ToDo */
1260
1261 /* 3. Config MAX download size */
1262 #ifdef CONFIG_USB_HCI
1263 /* for USB do not exceed MAX_CMDBUF_SZ */
1264 api->halmac_cfg_max_dl_size(mac, 0x1000);
1265 #elif defined CONFIG_PCIE_HCI
1266 /* required a even length from u32 */
1267 api->halmac_cfg_max_dl_size(mac, (MAX_CMDBUF_SZ - TXDESC_OFFSET) & 0xFFFFFFFE);
1268 #endif
1269
1270 /* 4. Download Firmware */
1271 status = api->halmac_download_firmware(mac, fw, fwsize);
1272 if (HALMAC_RET_SUCCESS != status)
1273 return -1;
1274
1275 if (d->hmpriv.send_general_info) {
1276 d->hmpriv.send_general_info = 0;
1277 err = _send_general_info(d);
1278 }
1279
1280 /* 5. Driver resume TX if needed */
1281 /* ToDo */
1282
1283 /* 6. Reset driver variables if needed */
1284 hal->LastHMEBoxNum = 0;
1285
1286
1287 /* 7. Get FW version */
1288 status = api->halmac_get_fw_version(mac, &fw_vesion);
1289 if (status == HALMAC_RET_SUCCESS) {
1290 hal->FirmwareVersion = fw_vesion.version;
1291 hal->FirmwareSubVersion = fw_vesion.sub_version;
1292 }
1293
1294 return err;
1295 }
1296
rtw_halmac_dlfw_from_file(struct dvobj_priv * d,u8 * fwpath)1297 int rtw_halmac_dlfw_from_file(struct dvobj_priv *d, u8 *fwpath)
1298 {
1299 u8 *fw = NULL;
1300 u32 fwmaxsize, size = 0;
1301 int err = 0;
1302
1303
1304 fwmaxsize = FIRMWARE_MAX_SIZE;
1305 fw = rtw_zmalloc(fwmaxsize);
1306 if (!fw)
1307 return -1;
1308
1309 size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
1310 if (size)
1311 err = rtw_halmac_dlfw(d, fw, size);
1312 else
1313 err = -1;
1314
1315 rtw_mfree(fw, fwmaxsize);
1316 fw = NULL;
1317
1318 return err;
1319 }
1320
1321 /*
1322 * Description:
1323 * Power on/off BB/RF domain.
1324 *
1325 * Parameters:
1326 * enable _TRUE/_FALSE for power on/off
1327 *
1328 * Return:
1329 * 0 Success
1330 * others Fail
1331 */
rtw_halmac_phy_power_switch(struct dvobj_priv * d,u8 enable)1332 int rtw_halmac_phy_power_switch(struct dvobj_priv *d, u8 enable)
1333 {
1334 PADAPTER adapter;
1335 PHALMAC_ADAPTER halmac;
1336 PHALMAC_API api;
1337 HALMAC_RET_STATUS status;
1338
1339
1340 adapter = d->padapters[IFACE_ID0];
1341 halmac = dvobj_to_halmac(d);
1342 if (!halmac)
1343 return -1;
1344 api = HALMAC_GET_API(halmac);
1345
1346 status = api->halmac_set_hw_value(halmac, HALMAC_HW_EN_BB_RF, &enable);
1347 if (status != HALMAC_RET_SUCCESS)
1348 return -1;
1349
1350 return 0;
1351 }
1352
_is_fw_read_cmd_down(PADAPTER adapter,u8 msgbox_num)1353 static u8 _is_fw_read_cmd_down(PADAPTER adapter, u8 msgbox_num)
1354 {
1355 u8 read_down = _FALSE;
1356 int retry_cnts = 100;
1357 u8 valid;
1358
1359 /* RTW_INFO("_is_fw_read_cmd_down, reg_1cc(%x), msg_box(%d)...\n", rtw_read8(adapter, REG_HMETFR), msgbox_num); */
1360
1361 do {
1362 valid = rtw_read8(adapter, REG_HMETFR) & BIT(msgbox_num);
1363 if (0 == valid)
1364 read_down = _TRUE;
1365 else
1366 rtw_msleep_os(1);
1367 } while ((!read_down) && (retry_cnts--));
1368
1369 return read_down;
1370 }
1371
rtw_halmac_send_h2c(struct dvobj_priv * d,u8 * h2c)1372 int rtw_halmac_send_h2c(struct dvobj_priv *d, u8 *h2c)
1373 {
1374 PADAPTER adapter = d->padapters[IFACE_ID0];
1375 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
1376 u8 h2c_box_num = 0;
1377 u32 msgbox_addr = 0;
1378 u32 msgbox_ex_addr = 0;
1379 u32 h2c_cmd = 0;
1380 u32 h2c_cmd_ex = 0;
1381 s32 ret = _FAIL;
1382
1383 if (adapter->bFWReady == _FALSE) {
1384 RTW_INFO("%s: return H2C cmd because fw is not ready\n", __FUNCTION__);
1385 return ret;
1386 }
1387
1388 if (!h2c) {
1389 RTW_INFO("%s: pbuf is NULL\n", __FUNCTION__);
1390 return ret;
1391 }
1392
1393 if (rtw_is_surprise_removed(adapter)) {
1394 RTW_INFO("%s: surprise removed\n", __FUNCTION__);
1395 return ret;
1396 }
1397
1398 _enter_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
1399
1400 /* pay attention to if race condition happened in H2C cmd setting */
1401 h2c_box_num = hal->LastHMEBoxNum;
1402
1403 if (!_is_fw_read_cmd_down(adapter, h2c_box_num)) {
1404 RTW_INFO(" fw read cmd failed...\n");
1405 goto exit;
1406 }
1407
1408 /* Write Ext command(byte 4 -7) */
1409 msgbox_ex_addr = REG_HMEBOX_E0 + (h2c_box_num * EX_MESSAGE_BOX_SIZE);
1410 _rtw_memcpy((u8 *)(&h2c_cmd_ex), h2c + 4, EX_MESSAGE_BOX_SIZE);
1411 h2c_cmd_ex = le32_to_cpu(h2c_cmd_ex);
1412 rtw_write32(adapter, msgbox_ex_addr, h2c_cmd_ex);
1413
1414 /* Write command (byte 0 -3 ) */
1415 msgbox_addr = REG_HMEBOX0 + (h2c_box_num * MESSAGE_BOX_SIZE);
1416 _rtw_memcpy((u8 *)(&h2c_cmd), h2c, 4);
1417 h2c_cmd = le32_to_cpu(h2c_cmd);
1418 rtw_write32(adapter, msgbox_addr, h2c_cmd);
1419
1420 /* update last msg box number */
1421 hal->LastHMEBoxNum = (h2c_box_num + 1) % MAX_H2C_BOX_NUMS;
1422 ret = _SUCCESS;
1423
1424 exit:
1425 _exit_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
1426 return ret;
1427 }
1428
rtw_halmac_c2h_handle(struct dvobj_priv * d,u8 * c2h,u32 size)1429 int rtw_halmac_c2h_handle(struct dvobj_priv *d, u8 *c2h, u32 size)
1430 {
1431 PHALMAC_ADAPTER mac;
1432 PHALMAC_API api;
1433 HALMAC_RET_STATUS status;
1434
1435
1436 mac = dvobj_to_halmac(d);
1437 api = HALMAC_GET_API(mac);
1438
1439 status = api->halmac_get_c2h_info(mac, c2h, size);
1440 if (HALMAC_RET_SUCCESS != status)
1441 return -1;
1442
1443 return 0;
1444 }
1445
rtw_halmac_get_available_efuse_size(struct dvobj_priv * d,u32 * size)1446 int rtw_halmac_get_available_efuse_size(struct dvobj_priv *d, u32 *size)
1447 {
1448 PHALMAC_ADAPTER mac;
1449 PHALMAC_API api;
1450 HALMAC_RET_STATUS status;
1451 u32 val;
1452
1453
1454 mac = dvobj_to_halmac(d);
1455 api = HALMAC_GET_API(mac);
1456
1457 status = api->halmac_get_efuse_available_size(mac, &val);
1458 if (HALMAC_RET_SUCCESS != status)
1459 return -1;
1460
1461 *size = val;
1462 return 0;
1463 }
1464
rtw_halmac_get_physical_efuse_size(struct dvobj_priv * d,u32 * size)1465 int rtw_halmac_get_physical_efuse_size(struct dvobj_priv *d, u32 *size)
1466 {
1467 PHALMAC_ADAPTER mac;
1468 PHALMAC_API api;
1469 HALMAC_RET_STATUS status;
1470 u32 val;
1471
1472
1473 mac = dvobj_to_halmac(d);
1474 api = HALMAC_GET_API(mac);
1475
1476 status = api->halmac_get_efuse_size(mac, &val);
1477 if (HALMAC_RET_SUCCESS != status)
1478 return -1;
1479
1480 *size = val;
1481 return 0;
1482 }
1483
rtw_halmac_read_physical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size)1484 int rtw_halmac_read_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
1485 {
1486 PHALMAC_ADAPTER mac;
1487 PHALMAC_API api;
1488 HALMAC_RET_STATUS status;
1489 HALMAC_FEATURE_ID id;
1490 int ret;
1491
1492
1493 mac = dvobj_to_halmac(d);
1494 api = HALMAC_GET_API(mac);
1495 id = HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE;
1496
1497 ret = init_halmac_event(d, id, map, size);
1498 if (ret)
1499 return -1;
1500
1501 status = api->halmac_dump_efuse_map(mac, HALMAC_EFUSE_R_AUTO);
1502 if (HALMAC_RET_SUCCESS != status) {
1503 free_halmac_event(d, id);
1504 return -1;
1505 }
1506
1507 ret = wait_halmac_event(d, id);
1508 if (ret)
1509 return -1;
1510
1511 return 0;
1512 }
1513
rtw_halmac_read_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)1514 int rtw_halmac_read_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
1515 {
1516 PHALMAC_ADAPTER mac;
1517 PHALMAC_API api;
1518 HALMAC_RET_STATUS status;
1519 u8 v;
1520 u32 i;
1521
1522
1523 mac = dvobj_to_halmac(d);
1524 api = HALMAC_GET_API(mac);
1525
1526 for (i = 0; i < cnt; i++) {
1527 status = api->halmac_read_efuse(mac, offset + i, &v);
1528 if (HALMAC_RET_SUCCESS != status)
1529 return -1;
1530 data[i] = v;
1531 }
1532
1533 return 0;
1534 }
1535
rtw_halmac_write_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)1536 int rtw_halmac_write_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
1537 {
1538 PHALMAC_ADAPTER mac;
1539 PHALMAC_API api;
1540 HALMAC_RET_STATUS status;
1541 u32 i;
1542
1543
1544 mac = dvobj_to_halmac(d);
1545 api = HALMAC_GET_API(mac);
1546
1547 for (i = 0; i < cnt; i++) {
1548 status = api->halmac_write_efuse(mac, offset + i, data[i]);
1549 if (HALMAC_RET_SUCCESS != status)
1550 return -1;
1551 }
1552
1553 return 0;
1554 }
1555
rtw_halmac_get_logical_efuse_size(struct dvobj_priv * d,u32 * size)1556 int rtw_halmac_get_logical_efuse_size(struct dvobj_priv *d, u32 *size)
1557 {
1558 PHALMAC_ADAPTER mac;
1559 PHALMAC_API api;
1560 HALMAC_RET_STATUS status;
1561 u32 val;
1562
1563
1564 mac = dvobj_to_halmac(d);
1565 api = HALMAC_GET_API(mac);
1566
1567 status = api->halmac_get_logical_efuse_size(mac, &val);
1568 if (HALMAC_RET_SUCCESS != status)
1569 return -1;
1570
1571 *size = val;
1572 return 0;
1573 }
1574
rtw_halmac_read_logical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size)1575 int rtw_halmac_read_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
1576 {
1577 PHALMAC_ADAPTER mac;
1578 PHALMAC_API api;
1579 HALMAC_RET_STATUS status;
1580 HALMAC_FEATURE_ID id;
1581 int ret;
1582
1583
1584 mac = dvobj_to_halmac(d);
1585 api = HALMAC_GET_API(mac);
1586 id = HALMAC_FEATURE_DUMP_LOGICAL_EFUSE;
1587
1588 ret = init_halmac_event(d, id, map, size);
1589 if (ret)
1590 return -1;
1591
1592 status = api->halmac_dump_logical_efuse_map(mac, HALMAC_EFUSE_R_AUTO);
1593 if (HALMAC_RET_SUCCESS != status) {
1594 free_halmac_event(d, id);
1595 return -1;
1596 }
1597
1598 ret = wait_halmac_event(d, id);
1599 if (ret)
1600 return -1;
1601
1602 return 0;
1603 }
1604
rtw_halmac_write_logical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size,u8 * maskmap,u32 masksize)1605 int rtw_halmac_write_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size, u8 *maskmap, u32 masksize)
1606 {
1607 PHALMAC_ADAPTER mac;
1608 PHALMAC_API api;
1609 HALMAC_PG_EFUSE_INFO pginfo;
1610 HALMAC_RET_STATUS status;
1611
1612
1613 mac = dvobj_to_halmac(d);
1614 api = HALMAC_GET_API(mac);
1615
1616 pginfo.pEfuse_map = map;
1617 pginfo.efuse_map_size = size;
1618 pginfo.pEfuse_mask = maskmap;
1619 pginfo.efuse_mask_size = masksize;
1620
1621 status = api->halmac_pg_efuse_by_map(mac, &pginfo, HALMAC_EFUSE_R_AUTO);
1622 if (HALMAC_RET_SUCCESS != status)
1623 return -1;
1624
1625 return 0;
1626 }
1627
rtw_halmac_read_logical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)1628 int rtw_halmac_read_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
1629 {
1630 PHALMAC_ADAPTER mac;
1631 PHALMAC_API api;
1632 HALMAC_RET_STATUS status;
1633 u8 v;
1634 u32 i;
1635
1636
1637 mac = dvobj_to_halmac(d);
1638 api = HALMAC_GET_API(mac);
1639
1640 for (i = 0; i < cnt; i++) {
1641 status = api->halmac_read_logical_efuse(mac, offset + i, &v);
1642 if (HALMAC_RET_SUCCESS != status)
1643 return -1;
1644 data[i] = v;
1645 }
1646
1647 return 0;
1648 }
1649
rtw_halmac_write_logical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)1650 int rtw_halmac_write_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
1651 {
1652 PHALMAC_ADAPTER mac;
1653 PHALMAC_API api;
1654 HALMAC_RET_STATUS status;
1655 u32 i;
1656
1657
1658 mac = dvobj_to_halmac(d);
1659 api = HALMAC_GET_API(mac);
1660
1661 for (i = 0; i < cnt; i++) {
1662 status = api->halmac_write_logical_efuse(mac, offset + i, data[i]);
1663 if (HALMAC_RET_SUCCESS != status)
1664 return -1;
1665 }
1666
1667 return 0;
1668 }
1669
rtw_halmac_write_bt_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)1670 int rtw_halmac_write_bt_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
1671 {
1672 PHALMAC_ADAPTER mac;
1673 PHALMAC_API api;
1674 HALMAC_RET_STATUS status;
1675 u32 i;
1676 u8 bank = 1;
1677
1678 mac = dvobj_to_halmac(d);
1679 api = HALMAC_GET_API(mac);
1680
1681 for (i = 0; i < cnt; i++) {
1682 status = api->halmac_write_efuse_bt(mac, offset + i, data[i], bank);
1683 if (HALMAC_RET_SUCCESS != status) {
1684 printk("%s: halmac_write_efuse_bt status = %d\n", __FUNCTION__, status);
1685 return -1;
1686 }
1687 }
1688 printk("%s: halmac_write_efuse_bt status = HALMAC_RET_SUCCESS %d\n", __FUNCTION__, status);
1689 return 0;
1690 }
1691
1692
rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size)1693 int rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
1694 {
1695 PHALMAC_ADAPTER mac;
1696 PHALMAC_API api;
1697 HALMAC_RET_STATUS status;
1698 HALMAC_FEATURE_ID id;
1699 int ret;
1700 int bank = 1;
1701
1702 mac = dvobj_to_halmac(d);
1703 api = HALMAC_GET_API(mac);
1704
1705 status = api->halmac_dump_efuse_map_bt(mac, bank, size, map);
1706 if (HALMAC_RET_SUCCESS != status) {
1707 printk("%s: halmac_dump_efuse_map_bt fail!\n", __FUNCTION__);
1708 return -1;
1709 }
1710
1711 printk("%s: OK!\n", __FUNCTION__);
1712
1713 return 0;
1714 }
1715
_hw_port_drv2halmac(enum _hw_port hwport)1716 static inline u8 _hw_port_drv2halmac(enum _hw_port hwport)
1717 {
1718 u8 port = 0;
1719
1720
1721 switch (hwport) {
1722 case HW_PORT0:
1723 port = 0;
1724 break;
1725 case HW_PORT1:
1726 port = 1;
1727 break;
1728 case HW_PORT2:
1729 port = 2;
1730 break;
1731 case HW_PORT3:
1732 port = 3;
1733 break;
1734 case HW_PORT4:
1735 port = 4;
1736 break;
1737 default:
1738 port = hwport;
1739 break;
1740 }
1741
1742 return port;
1743 }
1744
rtw_halmac_set_mac_address(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)1745 int rtw_halmac_set_mac_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
1746 {
1747 PHALMAC_ADAPTER halmac;
1748 PHALMAC_API api;
1749 u8 port;
1750 HALMAC_WLAN_ADDR hwa;
1751 HALMAC_RET_STATUS status;
1752 int err = -1;
1753
1754
1755 halmac = dvobj_to_halmac(d);
1756 api = HALMAC_GET_API(halmac);
1757
1758 port = _hw_port_drv2halmac(hwport);
1759 _rtw_memset(&hwa, 0, sizeof(hwa));
1760 _rtw_memcpy(hwa.Address, addr, 6);
1761
1762 status = api->halmac_cfg_mac_addr(halmac, port, &hwa);
1763 if (status != HALMAC_RET_SUCCESS)
1764 goto out;
1765
1766 err = 0;
1767 out:
1768 return err;
1769 }
1770
rtw_halmac_set_bssid(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)1771 int rtw_halmac_set_bssid(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
1772 {
1773 PHALMAC_ADAPTER halmac;
1774 PHALMAC_API api;
1775 u8 port;
1776 HALMAC_WLAN_ADDR hwa;
1777 HALMAC_RET_STATUS status;
1778 int err = -1;
1779
1780 halmac = dvobj_to_halmac(d);
1781 api = HALMAC_GET_API(halmac);
1782 port = _hw_port_drv2halmac(hwport);
1783
1784 _rtw_memset(&hwa, 0, sizeof(HALMAC_WLAN_ADDR));
1785 _rtw_memcpy(hwa.Address, addr, 6);
1786 status = api->halmac_cfg_bssid(halmac, port, &hwa);
1787 if (status != HALMAC_RET_SUCCESS)
1788 goto out;
1789
1790 err = 0;
1791 out:
1792 return err;
1793 }
1794
rtw_halmac_set_bandwidth(struct dvobj_priv * d,u8 channel,u8 pri_ch_idx,u8 bw)1795 int rtw_halmac_set_bandwidth(struct dvobj_priv *d, u8 channel, u8 pri_ch_idx, u8 bw)
1796 {
1797 PHALMAC_ADAPTER mac;
1798 PHALMAC_API api;
1799 HALMAC_RET_STATUS status;
1800
1801
1802 mac = dvobj_to_halmac(d);
1803 api = HALMAC_GET_API(mac);
1804
1805 status = api->halmac_cfg_ch_bw(mac, channel, pri_ch_idx, bw);
1806 if (HALMAC_RET_SUCCESS != status)
1807 return -1;
1808
1809 return 0;
1810 }
1811
rtw_halmac_get_hw_value(struct dvobj_priv * d,HALMAC_HW_ID hw_id,VOID * pvalue)1812 int rtw_halmac_get_hw_value(struct dvobj_priv *d, HALMAC_HW_ID hw_id, VOID *pvalue)
1813 {
1814 PHALMAC_ADAPTER mac;
1815 PHALMAC_API api;
1816 HALMAC_RET_STATUS status;
1817
1818
1819 mac = dvobj_to_halmac(d);
1820 api = HALMAC_GET_API(mac);
1821
1822 status = api->halmac_get_hw_value(mac, hw_id, pvalue);
1823 if (HALMAC_RET_SUCCESS != status)
1824 return -1;
1825
1826 return 0;
1827 }
1828
rtw_halmac_dump_fifo(struct dvobj_priv * d,HAL_FIFO_SEL halmac_fifo_sel)1829 int rtw_halmac_dump_fifo(struct dvobj_priv *d, HAL_FIFO_SEL halmac_fifo_sel)
1830 {
1831 PHALMAC_ADAPTER mac;
1832 PHALMAC_API api;
1833 HALMAC_RET_STATUS status;
1834 u8 *pfifo_map = NULL;
1835 u32 fifo_size = 0;
1836 s8 ret = 0;
1837
1838 mac = dvobj_to_halmac(d);
1839 api = HALMAC_GET_API(mac);
1840
1841 fifo_size = api->halmac_get_fifo_size(mac, halmac_fifo_sel);
1842 if (fifo_size)
1843 pfifo_map = rtw_vmalloc(fifo_size);
1844 if (pfifo_map == NULL)
1845 return -1;
1846
1847 status = api->halmac_dump_fifo(mac, halmac_fifo_sel, pfifo_map, fifo_size);
1848 if (HALMAC_RET_SUCCESS != status) {
1849 ret = -1;
1850 goto _exit;
1851 }
1852
1853 _exit:
1854 if (pfifo_map)
1855 rtw_vmfree(pfifo_map, fifo_size);
1856 return ret;
1857
1858 }
1859
rtw_halmac_rx_agg_switch(struct dvobj_priv * d,u8 enable)1860 int rtw_halmac_rx_agg_switch(struct dvobj_priv *d, u8 enable)
1861 {
1862 PADAPTER adapter;
1863 PHAL_DATA_TYPE hal;
1864 PHALMAC_ADAPTER halmac;
1865 PHALMAC_API api;
1866 HALMAC_RXAGG_CFG rxaggcfg;
1867 HALMAC_RET_STATUS status;
1868 int err = -1;
1869
1870
1871 adapter = d->padapters[IFACE_ID0];
1872 hal = GET_HAL_DATA(adapter);
1873 halmac = dvobj_to_halmac(d);
1874 api = HALMAC_GET_API(halmac);
1875 _rtw_memset((void *)&rxaggcfg, 0, sizeof(rxaggcfg));
1876
1877 if (_TRUE == enable) {
1878 #ifdef CONFIG_SDIO_HCI
1879 rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
1880 rxaggcfg.threshold.drv_define = 0;
1881 #elif defined(CONFIG_USB_HCI) && defined(CONFIG_USB_RX_AGGREGATION)
1882 switch (hal->rxagg_mode) {
1883 case RX_AGG_DISABLE:
1884 rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
1885 break;
1886
1887 case RX_AGG_DMA:
1888 rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
1889 if (hal->rxagg_dma_size || hal->rxagg_dma_timeout) {
1890 rxaggcfg.threshold.drv_define = 1;
1891 rxaggcfg.threshold.timeout = hal->rxagg_dma_timeout;
1892 rxaggcfg.threshold.size = hal->rxagg_dma_size;
1893 }
1894 break;
1895
1896 case RX_AGG_USB:
1897 case RX_AGG_MIX:
1898 rxaggcfg.mode = HALMAC_RX_AGG_MODE_USB;
1899 if (hal->rxagg_usb_size || hal->rxagg_usb_timeout) {
1900 rxaggcfg.threshold.drv_define = 1;
1901 rxaggcfg.threshold.timeout = hal->rxagg_usb_timeout;
1902 rxaggcfg.threshold.size = hal->rxagg_usb_size;
1903 }
1904 break;
1905 }
1906 #endif /* CONFIG_USB_HCI */
1907 } else
1908 rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
1909
1910 status = api->halmac_cfg_rx_aggregation(halmac, &rxaggcfg);
1911 if (status != HALMAC_RET_SUCCESS)
1912 goto out;
1913
1914 err = 0;
1915 out:
1916 return err;
1917 }
1918
rtw_halmac_get_wow_reason(struct dvobj_priv * d,u8 * reason)1919 int rtw_halmac_get_wow_reason(struct dvobj_priv *d, u8 *reason)
1920 {
1921 PADAPTER adapter;
1922 u8 val8;
1923 int err = -1;
1924
1925
1926 adapter = d->padapters[IFACE_ID0];
1927
1928 val8 = rtw_read8(adapter, 0x1C7);
1929 if (val8 == 0xEA)
1930 goto out;
1931
1932 *reason = val8;
1933 err = 0;
1934 out:
1935 return err;
1936 }
1937
1938 /*
1939 * Description:
1940 * Get RX driver info size. RX driver info is a small memory space between
1941 * scriptor and RX payload.
1942 *
1943 * +-------------------------+
1944 * | RX descriptor |
1945 * | usually 24 bytes |
1946 * +-------------------------+
1947 * | RX driver info |
1948 * | depends on driver cfg |
1949 * +-------------------------+
1950 * | RX paylad |
1951 * | |
1952 * +-------------------------+
1953 *
1954 * Parameter:
1955 * d pointer to struct dvobj_priv of driver
1956 * sz rx driver info size in bytes.
1957 *
1958 * Rteurn:
1959 * 0 Success
1960 * other Fail
1961 */
rtw_halmac_get_drv_info_sz(struct dvobj_priv * d,u8 * sz)1962 int rtw_halmac_get_drv_info_sz(struct dvobj_priv *d, u8 *sz)
1963 {
1964 HALMAC_RET_STATUS status;
1965 u8 dw = 6; /* max number */
1966
1967 #if 0 /* TODO wait for halmac ready */
1968 status = api->halmac_get_hw_value(halmac, HALMAC_HW_RX_, &dw);
1969 if (status != HALMAC_RET_SUCCESS)
1970 return -1;
1971 #endif
1972
1973 *sz = dw * 8;
1974 return 0;
1975 }
rtw_halmac_get_rsvd_drv_pg_bndy(struct dvobj_priv * dvobj,u16 * drv_pg)1976 int rtw_halmac_get_rsvd_drv_pg_bndy(struct dvobj_priv *dvobj, u16 *drv_pg)
1977 {
1978 HALMAC_RET_STATUS status;
1979 PHALMAC_ADAPTER halmac = dvobj_to_halmac(dvobj);
1980 PHALMAC_API api = HALMAC_GET_API(halmac);
1981
1982 status = api->halmac_get_hw_value(halmac, HALMAC_HW_RSVD_PG_BNDY, drv_pg);
1983 if (status != HALMAC_RET_SUCCESS)
1984 return -1;
1985
1986 return 0;
1987 }
1988
rtw_halmac_download_rsvd_page(struct dvobj_priv * dvobj,u16 page_idx,u8 * pbuf,u8 length)1989 int rtw_halmac_download_rsvd_page(struct dvobj_priv *dvobj, u16 page_idx, u8 *pbuf, u8 length)
1990 {
1991 HALMAC_RET_STATUS status = HALMAC_RET_SUCCESS;
1992 PHALMAC_ADAPTER halmac = dvobj_to_halmac(dvobj);
1993 PHALMAC_API api = HALMAC_GET_API(halmac);
1994
1995 /*status = api->halmac_get_hw_value(halmac, HALMAC_HW_RSVD_PG_BNDY, drv_pg);*/
1996 if (status != HALMAC_RET_SUCCESS)
1997 return -1;
1998
1999 return 0;
2000
2001 }
2002
2003 #ifdef CONFIG_SDIO_HCI
2004
2005 /*
2006 * Description:
2007 * Update queue allocated page number to driver
2008 *
2009 * Parameter:
2010 * d pointer to struct dvobj_priv of driver
2011 *
2012 * Rteurn:
2013 * 0 Success, "page" is valid.
2014 * others Fail, "page" is invalid.
2015 */
rtw_halmac_query_tx_page_num(struct dvobj_priv * d)2016 int rtw_halmac_query_tx_page_num(struct dvobj_priv *d)
2017 {
2018 PADAPTER adapter;
2019 struct halmacpriv *hmpriv;
2020 PHALMAC_ADAPTER halmac;
2021 PHALMAC_API api;
2022 HALMAC_RQPN_MAP rqpn;
2023 HALMAC_DMA_MAPPING dmaqueue;
2024 HALMAC_TXFF_ALLOCATION fifosize;
2025 HALMAC_RET_STATUS status;
2026 u8 i;
2027
2028
2029 adapter = d->padapters[IFACE_ID0];
2030 hmpriv = &d->hmpriv;
2031 halmac = dvobj_to_halmac(d);
2032 api = HALMAC_GET_API(halmac);
2033 _rtw_memset((void *)&rqpn, 0, sizeof(rqpn));
2034 _rtw_memset((void *)&fifosize, 0, sizeof(fifosize));
2035
2036 status = api->halmac_get_hw_value(halmac, HALMAC_HW_RQPN_MAPPING, &rqpn);
2037 if (status != HALMAC_RET_SUCCESS)
2038 return -1;
2039 status = api->halmac_get_hw_value(halmac, HALMAC_HW_TXFF_ALLOCATION, &fifosize);
2040 if (status != HALMAC_RET_SUCCESS)
2041 return -1;
2042
2043 for (i = 0; i < HW_QUEUE_ENTRY; i++) {
2044 hmpriv->txpage[i] = 0;
2045
2046 /* Driver index mapping to HALMAC DMA queue */
2047 dmaqueue = HALMAC_DMA_MAPPING_UNDEFINE;
2048 switch (i) {
2049 case VO_QUEUE_INX:
2050 dmaqueue = rqpn.dma_map_vo;
2051 break;
2052 case VI_QUEUE_INX:
2053 dmaqueue = rqpn.dma_map_vi;
2054 break;
2055 case BE_QUEUE_INX:
2056 dmaqueue = rqpn.dma_map_be;
2057 break;
2058 case BK_QUEUE_INX:
2059 dmaqueue = rqpn.dma_map_bk;
2060 break;
2061 case MGT_QUEUE_INX:
2062 dmaqueue = rqpn.dma_map_mg;
2063 break;
2064 case HIGH_QUEUE_INX:
2065 dmaqueue = rqpn.dma_map_hi;
2066 break;
2067 case BCN_QUEUE_INX:
2068 case TXCMD_QUEUE_INX:
2069 /* Unlimited */
2070 hmpriv->txpage[i] = 0xFFFF;
2071 continue;
2072 }
2073
2074 switch (dmaqueue) {
2075 case HALMAC_DMA_MAPPING_EXTRA:
2076 hmpriv->txpage[i] = fifosize.extra_queue_pg_num;
2077 break;
2078 case HALMAC_DMA_MAPPING_LOW:
2079 hmpriv->txpage[i] = fifosize.low_queue_pg_num;
2080 break;
2081 case HALMAC_DMA_MAPPING_NORMAL:
2082 hmpriv->txpage[i] = fifosize.normal_queue_pg_num;
2083 break;
2084 case HALMAC_DMA_MAPPING_HIGH:
2085 hmpriv->txpage[i] = fifosize.high_queue_pg_num;
2086 break;
2087 case HALMAC_DMA_MAPPING_UNDEFINE:
2088 break;
2089 }
2090 hmpriv->txpage[i] += fifosize.pub_queue_pg_num;
2091 }
2092
2093 return 0;
2094 }
2095
2096 /*
2097 * Description:
2098 * Get specific queue allocated page number
2099 *
2100 * Parameter:
2101 * d pointer to struct dvobj_priv of driver
2102 * queue target queue to query, VO/VI/BE/BK/.../TXCMD_QUEUE_INX
2103 * page return allocated page number
2104 *
2105 * Rteurn:
2106 * 0 Success, "page" is valid.
2107 * others Fail, "page" is invalid.
2108 */
rtw_halmac_get_tx_queue_page_num(struct dvobj_priv * d,u8 queue,u32 * page)2109 int rtw_halmac_get_tx_queue_page_num(struct dvobj_priv *d, u8 queue, u32 *page)
2110 {
2111 *page = 0;
2112 if (queue < HW_QUEUE_ENTRY)
2113 *page = d->hmpriv.txpage[queue];
2114
2115 return 0;
2116 }
2117
2118 /*
2119 * Return:
2120 * address for SDIO command
2121 */
rtw_halmac_sdio_get_tx_addr(struct dvobj_priv * d,u8 * desc,u32 size)2122 u32 rtw_halmac_sdio_get_tx_addr(struct dvobj_priv *d, u8 *desc, u32 size)
2123 {
2124 PHALMAC_ADAPTER mac;
2125 PHALMAC_API api;
2126 HALMAC_RET_STATUS status;
2127 u32 addr;
2128
2129
2130 mac = dvobj_to_halmac(d);
2131 api = HALMAC_GET_API(mac);
2132
2133 status = api->halmac_get_sdio_tx_addr(mac, desc, size, &addr);
2134 if (HALMAC_RET_SUCCESS != status)
2135 return 0;
2136
2137 return addr;
2138 }
2139
rtw_halmac_sdio_tx_allowed(struct dvobj_priv * d,u8 * buf,u32 size)2140 int rtw_halmac_sdio_tx_allowed(struct dvobj_priv *d, u8 *buf, u32 size)
2141 {
2142 PHALMAC_ADAPTER mac;
2143 PHALMAC_API api;
2144 HALMAC_RET_STATUS status;
2145
2146
2147 mac = dvobj_to_halmac(d);
2148 api = HALMAC_GET_API(mac);
2149
2150 status = api->halmac_tx_allowed_sdio(mac, buf, size);
2151 if (HALMAC_RET_SUCCESS != status)
2152 return -1;
2153
2154 return 0;
2155 }
2156
rtw_halmac_sdio_get_rx_addr(struct dvobj_priv * d,u8 * seq)2157 u32 rtw_halmac_sdio_get_rx_addr(struct dvobj_priv *d, u8 *seq)
2158 {
2159 u8 id;
2160
2161 #define RTW_SDIO_ADDR_RX_RX0FF_PRFIX 0x0E000
2162 #define RTW_SDIO_ADDR_RX_RX0FF_GEN(a) (RTW_SDIO_ADDR_RX_RX0FF_PRFIX|(a&0x3))
2163
2164 id = *seq;
2165 (*seq)++;
2166 return RTW_SDIO_ADDR_RX_RX0FF_GEN(id);
2167 }
2168 #endif /* CONFIG_SDIO_HCI */
2169
2170 #ifdef CONFIG_USB_HCI
rtw_halmac_usb_get_bulkout_id(struct dvobj_priv * d,u8 * buf,u32 size)2171 u8 rtw_halmac_usb_get_bulkout_id(struct dvobj_priv *d, u8 *buf, u32 size)
2172 {
2173 PHALMAC_ADAPTER mac;
2174 PHALMAC_API api;
2175 HALMAC_RET_STATUS status;
2176 u8 bulkout_id;
2177
2178
2179 mac = dvobj_to_halmac(d);
2180 api = HALMAC_GET_API(mac);
2181
2182 status = api->halmac_get_usb_bulkout_id(mac, buf, size, &bulkout_id);
2183 if (HALMAC_RET_SUCCESS != status)
2184 return 0;
2185
2186 return bulkout_id;
2187 }
2188
_usb_mode_drv2halmac(enum RTW_USB_SPEED usb_mode)2189 static inline HALMAC_USB_MODE _usb_mode_drv2halmac(enum RTW_USB_SPEED usb_mode)
2190 {
2191 HALMAC_USB_MODE halmac_usb_mode = HALMAC_USB_MODE_U2;
2192
2193 switch (usb_mode) {
2194 case RTW_USB_SPEED_2:
2195 halmac_usb_mode = HALMAC_USB_MODE_U2;
2196 break;
2197 case RTW_USB_SPEED_3:
2198 halmac_usb_mode = HALMAC_USB_MODE_U3;
2199 break;
2200 default:
2201 halmac_usb_mode = HALMAC_USB_MODE_U2;
2202 break;
2203 }
2204
2205 return halmac_usb_mode;
2206 }
2207
rtw_halmac_switch_usb_mode(struct dvobj_priv * d,enum RTW_USB_SPEED usb_mode)2208 u8 rtw_halmac_switch_usb_mode(struct dvobj_priv *d, enum RTW_USB_SPEED usb_mode)
2209 {
2210 PHALMAC_ADAPTER mac;
2211 PHALMAC_API api;
2212 HALMAC_RET_STATUS status;
2213 PADAPTER adapter;
2214 HALMAC_USB_MODE halmac_usb_mode;
2215
2216 adapter = d->padapters[IFACE_ID0];
2217 mac = dvobj_to_halmac(d);
2218 api = HALMAC_GET_API(mac);
2219 halmac_usb_mode = _usb_mode_drv2halmac(usb_mode);
2220 status = api->halmac_set_hw_value(mac, HALMAC_HW_USB_MODE, (void *)&halmac_usb_mode);
2221
2222 if (HALMAC_RET_SUCCESS != status)
2223 return _FAIL;
2224
2225 return _SUCCESS;
2226 }
2227 #endif /* CONFIG_USB_HCI */
2228