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