GNU Linux-libre 4.19.245-gnu1
[releases.git] / drivers / staging / rtlwifi / halmac / rtl_halmac.c
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2016  Realtek Corporation.
5  *
6  * Contact Information:
7  * wlanfae <wlanfae@realtek.com>
8  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
9  * Hsinchu 300, Taiwan.
10  *
11  * Larry Finger <Larry.Finger@lwfinger.net>
12  *
13  *****************************************************************************/
14
15 #include "halmac_api.h"
16 #include "rtl_halmac.h"
17 #include <linux/module.h>
18 #include <linux/vmalloc.h>
19
20 #define DEFAULT_INDICATOR_TIMELMT msecs_to_jiffies(1000) /* ms */
21 #define FIRMWARE_MAX_SIZE HALMAC_FW_SIZE_MAX_88XX
22
23 static struct rtl_halmac_ops rtl_halmac_operation = {
24         .halmac_init_adapter = rtl_halmac_init_adapter,
25         .halmac_deinit_adapter = rtl_halmac_deinit_adapter,
26         .halmac_init_hal = rtl_halmac_init_hal,
27         .halmac_deinit_hal = rtl_halmac_deinit_hal,
28         .halmac_poweron = rtl_halmac_poweron,
29         .halmac_poweroff = rtl_halmac_poweroff,
30
31         .halmac_phy_power_switch = rtl_halmac_phy_power_switch,
32         .halmac_set_mac_address = rtl_halmac_set_mac_address,
33         .halmac_set_bssid = rtl_halmac_set_bssid,
34
35         .halmac_get_physical_efuse_size = rtl_halmac_get_physical_efuse_size,
36         .halmac_read_physical_efuse_map = rtl_halmac_read_physical_efuse_map,
37         .halmac_get_logical_efuse_size = rtl_halmac_get_logical_efuse_size,
38         .halmac_read_logical_efuse_map = rtl_halmac_read_logical_efuse_map,
39
40         .halmac_set_bandwidth = rtl_halmac_set_bandwidth,
41
42         .halmac_c2h_handle = rtl_halmac_c2h_handle,
43
44         .halmac_chk_txdesc = rtl_halmac_chk_txdesc,
45 };
46
47 struct rtl_halmac_ops *rtl_halmac_get_ops_pointer(void)
48 {
49         return &rtl_halmac_operation;
50 }
51 EXPORT_SYMBOL(rtl_halmac_get_ops_pointer);
52
53 /*
54  * Driver API for HALMAC operations
55  */
56
57 static u8 _halmac_reg_read_8(void *p, u32 offset)
58 {
59         struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
60
61         return rtl_read_byte(rtlpriv, offset);
62 }
63
64 static u16 _halmac_reg_read_16(void *p, u32 offset)
65 {
66         struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
67
68         return rtl_read_word(rtlpriv, offset);
69 }
70
71 static u32 _halmac_reg_read_32(void *p, u32 offset)
72 {
73         struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
74
75         return rtl_read_dword(rtlpriv, offset);
76 }
77
78 static void _halmac_reg_write_8(void *p, u32 offset, u8 val)
79 {
80         struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
81
82         rtl_write_byte(rtlpriv, offset, val);
83 }
84
85 static void _halmac_reg_write_16(void *p, u32 offset, u16 val)
86 {
87         struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
88
89         rtl_write_word(rtlpriv, offset, val);
90 }
91
92 static void _halmac_reg_write_32(void *p, u32 offset, u32 val)
93 {
94         struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
95
96         rtl_write_dword(rtlpriv, offset, val);
97 }
98
99 static bool _halmac_write_data_rsvd_page(void *p, u8 *buf, u32 size)
100 {
101         struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
102
103         if (rtlpriv->cfg->ops->halmac_cb_write_data_rsvd_page &&
104             rtlpriv->cfg->ops->halmac_cb_write_data_rsvd_page(rtlpriv, buf,
105                                                               size))
106                 return true;
107
108         return false;
109 }
110
111 static bool _halmac_write_data_h2c(void *p, u8 *buf, u32 size)
112 {
113         struct rtl_priv *rtlpriv = (struct rtl_priv *)p;
114
115         if (rtlpriv->cfg->ops->halmac_cb_write_data_h2c &&
116             rtlpriv->cfg->ops->halmac_cb_write_data_h2c(rtlpriv, buf, size))
117                 return true;
118
119         return false;
120 }
121
122 static const char *const RTL_HALMAC_FEATURE_NAME[] = {
123         "HALMAC_FEATURE_CFG_PARA",
124         "HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE",
125         "HALMAC_FEATURE_DUMP_LOGICAL_EFUSE",
126         "HALMAC_FEATURE_UPDATE_PACKET",
127         "HALMAC_FEATURE_UPDATE_DATAPACK",
128         "HALMAC_FEATURE_RUN_DATAPACK",
129         "HALMAC_FEATURE_CHANNEL_SWITCH",
130         "HALMAC_FEATURE_IQK",
131         "HALMAC_FEATURE_POWER_TRACKING",
132         "HALMAC_FEATURE_PSD",
133         "HALMAC_FEATURE_ALL"};
134
135 static inline bool is_valid_id_status(struct rtl_priv *rtlpriv,
136                                       enum halmac_feature_id id,
137                                       enum halmac_cmd_process_status status)
138 {
139         switch (id) {
140         case HALMAC_FEATURE_CFG_PARA:
141                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
142                          RTL_HALMAC_FEATURE_NAME[id]);
143                 break;
144         case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
145                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
146                          RTL_HALMAC_FEATURE_NAME[id]);
147                 if (status != HALMAC_CMD_PROCESS_DONE) {
148                         RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
149                                  "%s: <WARN> id(%d) unspecified status(%d)!\n",
150                                  __func__, id, status);
151                 }
152                 break;
153         case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
154                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
155                          RTL_HALMAC_FEATURE_NAME[id]);
156                 if (status != HALMAC_CMD_PROCESS_DONE) {
157                         RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
158                                  "%s: <WARN> id(%d) unspecified status(%d)!\n",
159                                  __func__, id, status);
160                 }
161                 break;
162         case HALMAC_FEATURE_UPDATE_PACKET:
163                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
164                          RTL_HALMAC_FEATURE_NAME[id]);
165                 break;
166         case HALMAC_FEATURE_UPDATE_DATAPACK:
167                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
168                          RTL_HALMAC_FEATURE_NAME[id]);
169                 break;
170         case HALMAC_FEATURE_RUN_DATAPACK:
171                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
172                          RTL_HALMAC_FEATURE_NAME[id]);
173                 break;
174         case HALMAC_FEATURE_CHANNEL_SWITCH:
175                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
176                          RTL_HALMAC_FEATURE_NAME[id]);
177                 break;
178         case HALMAC_FEATURE_IQK:
179                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
180                          RTL_HALMAC_FEATURE_NAME[id]);
181                 break;
182         case HALMAC_FEATURE_POWER_TRACKING:
183                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
184                          RTL_HALMAC_FEATURE_NAME[id]);
185                 break;
186         case HALMAC_FEATURE_PSD:
187                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
188                          RTL_HALMAC_FEATURE_NAME[id]);
189                 break;
190         case HALMAC_FEATURE_ALL:
191                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: %s\n", __func__,
192                          RTL_HALMAC_FEATURE_NAME[id]);
193                 break;
194         default:
195                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
196                          "%s: unknown feature id(%d)\n", __func__, id);
197                 return false;
198         }
199
200         return true;
201 }
202
203 static int init_halmac_event_with_waittime(struct rtl_priv *rtlpriv,
204                                            enum halmac_feature_id id, u8 *buf,
205                                            u32 size, u32 time)
206 {
207         struct completion *comp;
208
209         if (!rtlpriv->halmac.indicator[id].comp) {
210                 comp = kzalloc(sizeof(*comp), GFP_KERNEL);
211                 if (!comp)
212                         return -1;
213         } else {
214                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
215                          "%s: <WARN> id(%d) sctx is not NULL!!\n", __func__,
216                          id);
217                 comp = rtlpriv->halmac.indicator[id].comp;
218                 rtlpriv->halmac.indicator[id].comp = NULL;
219         }
220
221         init_completion(comp);
222         rtlpriv->halmac.indicator[id].wait_ms = time;
223
224         rtlpriv->halmac.indicator[id].buffer = buf;
225         rtlpriv->halmac.indicator[id].buf_size = size;
226         rtlpriv->halmac.indicator[id].ret_size = 0;
227         rtlpriv->halmac.indicator[id].status = 0;
228         /* fill sctx at least to sure other variables are all ready! */
229         rtlpriv->halmac.indicator[id].comp = comp;
230
231         return 0;
232 }
233
234 static inline int init_halmac_event(struct rtl_priv *rtlpriv,
235                                     enum halmac_feature_id id, u8 *buf,
236                                     u32 size)
237 {
238         return init_halmac_event_with_waittime(rtlpriv, id, buf, size,
239                                                DEFAULT_INDICATOR_TIMELMT);
240 }
241
242 static void free_halmac_event(struct rtl_priv *rtlpriv,
243                               enum halmac_feature_id id)
244 {
245         struct completion *comp;
246
247         if (!rtlpriv->halmac.indicator[id].comp)
248                 return;
249
250         comp = rtlpriv->halmac.indicator[id].comp;
251         rtlpriv->halmac.indicator[id].comp = NULL;
252         kfree(comp);
253 }
254
255 static int wait_halmac_event(struct rtl_priv *rtlpriv,
256                              enum halmac_feature_id id)
257 {
258         struct completion *comp;
259         int ret;
260
261         comp = rtlpriv->halmac.indicator[id].comp;
262         if (!comp)
263                 return -1;
264
265         ret = wait_for_completion_timeout(
266                 comp, rtlpriv->halmac.indicator[id].wait_ms);
267         free_halmac_event(rtlpriv, id);
268         if (ret > 0)
269                 return 0;
270
271         return -1;
272 }
273
274 /*
275  * Return:
276  *      Always return true, HALMAC don't care the return value.
277  */
278 static bool
279 _halmac_event_indication(void *p, enum halmac_feature_id feature_id,
280                          enum halmac_cmd_process_status process_status, u8 *buf,
281                          u32 size)
282 {
283         struct rtl_priv *rtlpriv;
284         struct rtl_halmac_indicator *tbl, *indicator;
285         struct completion *comp;
286         u32 cpsz;
287         bool ret;
288
289         rtlpriv = (struct rtl_priv *)p;
290         tbl = rtlpriv->halmac.indicator;
291
292         ret = is_valid_id_status(rtlpriv, feature_id, process_status);
293         if (!ret)
294                 goto exit;
295
296         indicator = &tbl[feature_id];
297         indicator->status = process_status;
298         indicator->ret_size = size;
299         if (!indicator->comp) {
300                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
301                          "%s: No feature id(%d) waiting!!\n", __func__,
302                          feature_id);
303                 goto exit;
304         }
305         comp = indicator->comp;
306
307         if (process_status == HALMAC_CMD_PROCESS_ERROR) {
308                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
309                          "%s: Something wrong id(%d)!!\n", __func__,
310                          feature_id);
311                 complete(comp); /* may provide error code */
312                 goto exit;
313         }
314
315         if (size > indicator->buf_size) {
316                 RT_TRACE(
317                         rtlpriv, COMP_HALMAC, DBG_LOUD,
318                         "%s: <WARN> id(%d) buffer is not enough(%d<%d), data will be truncated!\n",
319                         __func__, feature_id, indicator->buf_size, size);
320                 cpsz = indicator->buf_size;
321         } else {
322                 cpsz = size;
323         }
324
325         if (cpsz && indicator->buffer)
326                 memcpy(indicator->buffer, buf, cpsz);
327
328         complete(comp);
329
330 exit:
331         return true;
332 }
333
334 static struct halmac_platform_api rtl_halmac_platform_api = {
335         /* R/W register */
336         .REG_READ_8 = _halmac_reg_read_8,
337         .REG_READ_16 = _halmac_reg_read_16,
338         .REG_READ_32 = _halmac_reg_read_32,
339         .REG_WRITE_8 = _halmac_reg_write_8,
340         .REG_WRITE_16 = _halmac_reg_write_16,
341         .REG_WRITE_32 = _halmac_reg_write_32,
342
343         /* Write data */
344         /* impletement in HAL-IC level */
345         .SEND_RSVD_PAGE = _halmac_write_data_rsvd_page,
346         .SEND_H2C_PKT = _halmac_write_data_h2c,
347
348         .EVENT_INDICATION = _halmac_event_indication,
349 };
350
351 static int init_priv(struct rtl_halmac *halmac)
352 {
353         struct rtl_halmac_indicator *indicator;
354         u32 count, size;
355
356         halmac->send_general_info = 0;
357
358         count = HALMAC_FEATURE_ALL + 1;
359         size = sizeof(*indicator) * count;
360         indicator = kzalloc(size, GFP_KERNEL);
361         if (!indicator)
362                 return -1;
363         halmac->indicator = indicator;
364
365         return 0;
366 }
367
368 static void deinit_priv(struct rtl_halmac *halmac)
369 {
370         struct rtl_halmac_indicator *indicator;
371
372         indicator = halmac->indicator;
373         halmac->indicator = NULL;
374         kfree(indicator);
375 }
376
377 int rtl_halmac_init_adapter(struct rtl_priv *rtlpriv)
378 {
379         struct halmac_adapter *halmac;
380         struct halmac_api *api;
381         enum halmac_interface intf;
382         enum halmac_ret_status status;
383         int err = 0;
384         struct halmac_platform_api *pf_api = &rtl_halmac_platform_api;
385
386         halmac = rtlpriv_to_halmac(rtlpriv);
387         if (halmac) {
388                 err = 0;
389                 goto out;
390         }
391
392         err = init_priv(&rtlpriv->halmac);
393         if (err)
394                 goto out;
395
396         intf = HALMAC_INTERFACE_PCIE;
397         status = halmac_init_adapter(rtlpriv, pf_api, intf, &halmac, &api);
398         if (status != HALMAC_RET_SUCCESS) {
399                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
400                          "%s: halmac_init_adapter fail!(status=%d)\n", __func__,
401                          status);
402                 err = -1;
403                 goto out;
404         }
405
406         rtlpriv->halmac.internal = halmac;
407
408 out:
409         if (err)
410                 rtl_halmac_deinit_adapter(rtlpriv);
411
412         return err;
413 }
414
415 int rtl_halmac_deinit_adapter(struct rtl_priv *rtlpriv)
416 {
417         struct halmac_adapter *halmac;
418         enum halmac_ret_status status;
419         int err = 0;
420
421         halmac = rtlpriv_to_halmac(rtlpriv);
422         if (!halmac) {
423                 err = 0;
424                 goto out;
425         }
426
427         deinit_priv(&rtlpriv->halmac);
428
429         halmac_halt_api(halmac);
430
431         status = halmac_deinit_adapter(halmac);
432         rtlpriv->halmac.internal = NULL;
433         if (status != HALMAC_RET_SUCCESS) {
434                 err = -1;
435                 goto out;
436         }
437
438 out:
439         return err;
440 }
441
442 int rtl_halmac_poweron(struct rtl_priv *rtlpriv)
443 {
444         struct halmac_adapter *halmac;
445         struct halmac_api *api;
446         enum halmac_ret_status status;
447         int err = -1;
448
449         halmac = rtlpriv_to_halmac(rtlpriv);
450         if (!halmac)
451                 goto out;
452
453         api = HALMAC_GET_API(halmac);
454
455         status = api->halmac_pre_init_system_cfg(halmac);
456         if (status != HALMAC_RET_SUCCESS)
457                 goto out;
458
459         status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_ON);
460         if (status != HALMAC_RET_SUCCESS)
461                 goto out;
462
463         status = api->halmac_init_system_cfg(halmac);
464         if (status != HALMAC_RET_SUCCESS)
465                 goto out;
466
467         err = 0;
468 out:
469         return err;
470 }
471
472 int rtl_halmac_poweroff(struct rtl_priv *rtlpriv)
473 {
474         struct halmac_adapter *halmac;
475         struct halmac_api *api;
476         enum halmac_ret_status status;
477         int err = -1;
478
479         halmac = rtlpriv_to_halmac(rtlpriv);
480         if (!halmac)
481                 goto out;
482
483         api = HALMAC_GET_API(halmac);
484
485         status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_OFF);
486         if (status != HALMAC_RET_SUCCESS)
487                 goto out;
488
489         err = 0;
490 out:
491         return err;
492 }
493
494 /*
495  * Note:
496  *      When this function return, the register REG_RCR may be changed.
497  */
498 int rtl_halmac_config_rx_info(struct rtl_priv *rtlpriv,
499                               enum halmac_drv_info info)
500 {
501         struct halmac_adapter *halmac;
502         struct halmac_api *api;
503         enum halmac_ret_status status;
504         int err = -1;
505
506         halmac = rtlpriv_to_halmac(rtlpriv);
507         api = HALMAC_GET_API(halmac);
508
509         status = api->halmac_cfg_drv_info(halmac, info);
510         if (status != HALMAC_RET_SUCCESS)
511                 goto out;
512
513         err = 0;
514 out:
515         return err;
516 }
517
518 static enum halmac_ret_status init_mac_flow(struct rtl_priv *rtlpriv)
519 {
520         struct halmac_adapter *halmac;
521         struct halmac_api *api;
522         enum halmac_ret_status status;
523         u8 wifi_test = 0;
524         int err;
525
526         halmac = rtlpriv_to_halmac(rtlpriv);
527         api = HALMAC_GET_API(halmac);
528
529         if (wifi_test)
530                 status = api->halmac_init_mac_cfg(halmac, HALMAC_TRX_MODE_WMM);
531         else
532                 status = api->halmac_init_mac_cfg(halmac,
533                                                   HALMAC_TRX_MODE_NORMAL);
534         if (status != HALMAC_RET_SUCCESS)
535                 goto out;
536
537         err = rtl_halmac_rx_agg_switch(rtlpriv, true);
538         if (err)
539                 goto out;
540
541         if (rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS7])
542                 status = api->halmac_cfg_operation_mode(
543                         halmac, HALMAC_WIRELESS_MODE_AC);
544         else if (rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS7])
545                 status = api->halmac_cfg_operation_mode(halmac,
546                                                         HALMAC_WIRELESS_MODE_N);
547         else if (rtlpriv->cfg->maps[RTL_RC_OFDM_RATE6M])
548                 status = api->halmac_cfg_operation_mode(halmac,
549                                                         HALMAC_WIRELESS_MODE_G);
550         else
551                 status = api->halmac_cfg_operation_mode(halmac,
552                                                         HALMAC_WIRELESS_MODE_B);
553         if (status != HALMAC_RET_SUCCESS)
554                 goto out;
555
556 out:
557         return status;
558 }
559
560 static inline enum halmac_rf_type _rf_type_drv2halmac(enum rf_type rf_drv)
561 {
562         enum halmac_rf_type rf_mac;
563
564         switch (rf_drv) {
565         case RF_1T2R:
566                 rf_mac = HALMAC_RF_1T2R;
567                 break;
568         case RF_2T2R:
569                 rf_mac = HALMAC_RF_2T2R;
570                 break;
571         case RF_1T1R:
572                 rf_mac = HALMAC_RF_1T1R;
573                 break;
574         case RF_2T2R_GREEN:
575                 rf_mac = HALMAC_RF_2T2R_GREEN;
576                 break;
577         default:
578                 rf_mac = (enum halmac_rf_type)rf_drv;
579                 break;
580         }
581
582         return rf_mac;
583 }
584
585 static int _send_general_info(struct rtl_priv *rtlpriv)
586 {
587         struct halmac_adapter *halmac;
588         struct halmac_api *api;
589         struct halmac_general_info info;
590         enum halmac_ret_status status;
591
592         halmac = rtlpriv_to_halmac(rtlpriv);
593         if (!halmac)
594                 return -1;
595         api = HALMAC_GET_API(halmac);
596
597         memset(&info, 0, sizeof(info));
598         info.rfe_type = rtlpriv->rtlhal.rfe_type;
599         info.rf_type = _rf_type_drv2halmac(rtlpriv->phy.rf_type);
600
601         status = api->halmac_send_general_info(halmac, &info);
602         switch (status) {
603         case HALMAC_RET_SUCCESS:
604                 break;
605         case HALMAC_RET_NO_DLFW:
606                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_WARNING,
607                          "%s: halmac_send_general_info() fail because fw not dl!\n",
608                          __func__);
609         /* fall through */
610         default:
611                 return -1;
612         }
613
614         return 0;
615 }
616
617 /*
618  * Notices:
619  *      Make sure
620  *      1. rtl_hal_get_hwreg(HW_VAR_RF_TYPE)
621  *      2. HAL_DATA_TYPE.rfe_type
622  *      already ready for use before calling this function.
623  */
624 static int _halmac_init_hal(struct rtl_priv *rtlpriv, u8 *fw, u32 fwsize)
625 {
626         struct halmac_adapter *halmac;
627         struct halmac_api *api;
628         enum halmac_ret_status status;
629         bool ok;
630         bool fw_ok = false;
631         int err, err_ret = -1;
632
633         halmac = rtlpriv_to_halmac(rtlpriv);
634         if (!halmac)
635                 goto out;
636         api = HALMAC_GET_API(halmac);
637
638         /* StatePowerOff */
639
640         /* SKIP: halmac_init_adapter (Already done before) */
641
642         /* halmac_pre_Init_system_cfg */
643         /* halmac_mac_power_switch(on) */
644         /* halmac_Init_system_cfg */
645         err = rtl_halmac_poweron(rtlpriv);
646         if (err)
647                 goto out;
648
649         /* StatePowerOn */
650
651         /* DownloadFW */
652         rtlpriv->halmac.send_general_info = 0;
653         if (fw && fwsize) {
654                 err = rtl_halmac_dlfw(rtlpriv, fw, fwsize);
655                 if (err)
656                         goto out;
657                 fw_ok = true;
658         }
659
660         /* InitMACFlow */
661         status = init_mac_flow(rtlpriv);
662         if (status != HALMAC_RET_SUCCESS)
663                 goto out;
664
665         /* halmac_send_general_info */
666         if (fw_ok) {
667                 rtlpriv->halmac.send_general_info = 0;
668                 err = _send_general_info(rtlpriv);
669                 if (err)
670                         goto out;
671         } else {
672                 rtlpriv->halmac.send_general_info = 1;
673         }
674
675         /* Init Phy parameter-MAC */
676         if (rtlpriv->cfg->ops->halmac_cb_init_mac_register)
677                 ok = rtlpriv->cfg->ops->halmac_cb_init_mac_register(rtlpriv);
678         else
679                 ok = false;
680
681         if (!ok)
682                 goto out;
683
684         /* StateMacInitialized */
685
686         /* halmac_cfg_drv_info */
687         err = rtl_halmac_config_rx_info(rtlpriv, HALMAC_DRV_INFO_PHY_STATUS);
688         if (err)
689                 goto out;
690
691         /* halmac_set_hw_value(HALMAC_HW_EN_BB_RF) */
692         /* Init BB, RF */
693         if (rtlpriv->cfg->ops->halmac_cb_init_bb_rf_register)
694                 ok = rtlpriv->cfg->ops->halmac_cb_init_bb_rf_register(rtlpriv);
695         else
696                 ok = false;
697
698         if (!ok)
699                 goto out;
700
701         status = api->halmac_init_interface_cfg(halmac);
702         if (status != HALMAC_RET_SUCCESS)
703                 goto out;
704
705         /* SKIP: halmac_verify_platform_api */
706         /* SKIP: halmac_h2c_lb */
707
708         /* StateRxIdle */
709
710         err_ret = 0;
711 out:
712         return err_ret;
713 }
714
715 int rtl_halmac_init_hal(struct rtl_priv *rtlpriv)
716 {
717         if (!rtlpriv->rtlhal.pfirmware || rtlpriv->rtlhal.fwsize == 0)
718                 return -1;
719
720         return _halmac_init_hal(rtlpriv, rtlpriv->rtlhal.pfirmware,
721                                 rtlpriv->rtlhal.fwsize);
722 }
723
724 int rtl_halmac_deinit_hal(struct rtl_priv *rtlpriv)
725 {
726         struct halmac_adapter *halmac;
727         struct halmac_api *api;
728         enum halmac_ret_status status;
729         int err = -1;
730
731         halmac = rtlpriv_to_halmac(rtlpriv);
732         if (!halmac)
733                 goto out;
734         api = HALMAC_GET_API(halmac);
735
736         status = api->halmac_deinit_interface_cfg(halmac);
737         if (status != HALMAC_RET_SUCCESS)
738                 goto out;
739
740         /* rtw_hal_power_off(adapter); */
741         status = api->halmac_mac_power_switch(halmac, HALMAC_MAC_POWER_OFF);
742         if (status != HALMAC_RET_SUCCESS)
743                 goto out;
744
745         err = 0;
746 out:
747         return err;
748 }
749
750 int rtl_halmac_self_verify(struct rtl_priv *rtlpriv)
751 {
752         struct halmac_adapter *mac;
753         struct halmac_api *api;
754         enum halmac_ret_status status;
755         int err = -1;
756
757         mac = rtlpriv_to_halmac(rtlpriv);
758         api = HALMAC_GET_API(mac);
759
760         status = api->halmac_verify_platform_api(mac);
761         if (status != HALMAC_RET_SUCCESS)
762                 goto out;
763
764         status = api->halmac_h2c_lb(mac);
765         if (status != HALMAC_RET_SUCCESS)
766                 goto out;
767
768         err = 0;
769 out:
770         return err;
771 }
772
773 int rtl_halmac_dlfw(struct rtl_priv *rtlpriv, u8 *fw, u32 fwsize)
774 {
775         struct halmac_adapter *mac;
776         struct halmac_api *api;
777         enum halmac_ret_status status;
778         struct halmac_fw_version fw_version;
779         int err = 0;
780
781         mac = rtlpriv_to_halmac(rtlpriv);
782         api = HALMAC_GET_API(mac);
783
784         if ((!fw) || (!fwsize))
785                 return -1;
786
787         /* 1. Driver Stop Tx */
788         /* ToDo */
789
790         /* 2. Driver Check Tx FIFO is empty */
791         /* ToDo */
792
793         /* 3. Config MAX download size */
794         api->halmac_cfg_max_dl_size(mac, 0x1000);
795
796         /* 4. Download Firmware */
797         mac->h2c_packet_seq = 0;
798         status = api->halmac_download_firmware(mac, fw, fwsize);
799         if (status != HALMAC_RET_SUCCESS)
800                 return -1;
801
802         status = api->halmac_get_fw_version(mac, &fw_version);
803         if (status == HALMAC_RET_SUCCESS) {
804                 rtlpriv->rtlhal.fw_version = fw_version.version;
805                 rtlpriv->rtlhal.fw_subversion =
806                         (fw_version.sub_version << 8) | (fw_version.sub_index);
807
808                 RT_TRACE(
809                         rtlpriv, COMP_HALMAC, DBG_DMESG,
810                         "halmac report firmware version %04X.%04X\n",
811                         rtlpriv->rtlhal.fw_version,
812                         rtlpriv->rtlhal.fw_subversion);
813         }
814
815         if (rtlpriv->halmac.send_general_info) {
816                 rtlpriv->halmac.send_general_info = 0;
817                 err = _send_general_info(rtlpriv);
818         }
819
820         /* 5. Driver resume TX if needed */
821         /* ToDo */
822
823         /* 6. Reset driver variables if needed */
824         /*hal->LastHMEBoxNum = 0;*/
825
826         return err;
827 }
828
829 /*
830  * Description:
831  *      Power on/off BB/RF domain.
832  *
833  * Parameters:
834  *      enable  true/false for power on/off
835  *
836  * Return:
837  *      0       Success
838  *      others  Fail
839  */
840 int rtl_halmac_phy_power_switch(struct rtl_priv *rtlpriv, u8 enable)
841 {
842         struct halmac_adapter *halmac;
843         struct halmac_api *api;
844         enum halmac_ret_status status;
845
846         halmac = rtlpriv_to_halmac(rtlpriv);
847         if (!halmac)
848                 return -1;
849         api = HALMAC_GET_API(halmac);
850
851         status = api->halmac_set_hw_value(halmac, HALMAC_HW_EN_BB_RF, &enable);
852         if (status != HALMAC_RET_SUCCESS)
853                 return -1;
854
855         return 0;
856 }
857
858 static bool _is_fw_read_cmd_down(struct rtl_priv *rtlpriv, u8 msgbox_num)
859 {
860         bool read_down = false;
861         int retry_cnts = 100;
862         u8 valid;
863
864         RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
865                  "%s, reg_1cc(%x), msg_box(%d)...\n", __func__,
866                  rtl_read_byte(rtlpriv, REG_HMETFR), msgbox_num);
867
868         do {
869                 valid = rtl_read_byte(rtlpriv, REG_HMETFR) & BIT(msgbox_num);
870                 if (valid == 0)
871                         read_down = true;
872                 else
873                         mdelay(1);
874         } while ((!read_down) && (retry_cnts--));
875
876         return read_down;
877 }
878
879 int rtl_halmac_send_h2c(struct rtl_priv *rtlpriv, u8 *h2c)
880 {
881         u8 h2c_box_num = 0;
882         u32 msgbox_addr = 0;
883         u32 msgbox_ex_addr = 0;
884         __le32 h2c_cmd = 0;
885         __le32 h2c_cmd_ex = 0;
886         s32 ret = -1;
887         unsigned long flag = 0;
888         struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
889
890         if (!h2c) {
891                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD, "%s: pbuf is NULL\n",
892                          __func__);
893                 return ret;
894         }
895
896         spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
897
898         /* pay attention to if race condition happened in  H2C cmd setting */
899         h2c_box_num = rtlhal->last_hmeboxnum;
900
901         if (!_is_fw_read_cmd_down(rtlpriv, h2c_box_num)) {
902                 RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
903                          " fw read cmd failed...\n");
904                 goto exit;
905         }
906
907         /* Write Ext command(byte 4 -7) */
908         msgbox_ex_addr = REG_HMEBOX_E0 + (h2c_box_num * EX_MESSAGE_BOX_SIZE);
909         memcpy((u8 *)(&h2c_cmd_ex), h2c + 4, EX_MESSAGE_BOX_SIZE);
910         rtl_write_dword(rtlpriv, msgbox_ex_addr, le32_to_cpu(h2c_cmd_ex));
911
912         /* Write command (byte 0 -3 ) */
913         msgbox_addr = REG_HMEBOX0 + (h2c_box_num * MESSAGE_BOX_SIZE);
914         memcpy((u8 *)(&h2c_cmd), h2c, 4);
915         rtl_write_dword(rtlpriv, msgbox_addr, le32_to_cpu(h2c_cmd));
916
917         /* update last msg box number */
918         rtlhal->last_hmeboxnum = (h2c_box_num + 1) % MAX_H2C_BOX_NUMS;
919         ret = 0;
920
921 exit:
922         spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
923         return ret;
924 }
925
926 int rtl_halmac_c2h_handle(struct rtl_priv *rtlpriv, u8 *c2h, u32 size)
927 {
928         struct halmac_adapter *mac;
929         struct halmac_api *api;
930         enum halmac_ret_status status;
931
932         mac = rtlpriv_to_halmac(rtlpriv);
933         api = HALMAC_GET_API(mac);
934
935         status = api->halmac_get_c2h_info(mac, c2h, size);
936         if (status != HALMAC_RET_SUCCESS)
937                 return -1;
938
939         return 0;
940 }
941
942 int rtl_halmac_get_physical_efuse_size(struct rtl_priv *rtlpriv, u32 *size)
943 {
944         struct halmac_adapter *mac;
945         struct halmac_api *api;
946         enum halmac_ret_status status;
947         u32 val;
948
949         mac = rtlpriv_to_halmac(rtlpriv);
950         api = HALMAC_GET_API(mac);
951
952         status = api->halmac_get_efuse_size(mac, &val);
953         if (status != HALMAC_RET_SUCCESS)
954                 return -1;
955
956         *size = val;
957         return 0;
958 }
959
960 int rtl_halmac_read_physical_efuse_map(struct rtl_priv *rtlpriv, u8 *map,
961                                        u32 size)
962 {
963         struct halmac_adapter *mac;
964         struct halmac_api *api;
965         enum halmac_ret_status status;
966         enum halmac_feature_id id;
967         int ret;
968
969         mac = rtlpriv_to_halmac(rtlpriv);
970         api = HALMAC_GET_API(mac);
971         id = HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE;
972
973         ret = init_halmac_event(rtlpriv, id, map, size);
974         if (ret)
975                 return -1;
976
977         status = api->halmac_dump_efuse_map(mac, HALMAC_EFUSE_R_DRV);
978         if (status != HALMAC_RET_SUCCESS) {
979                 free_halmac_event(rtlpriv, id);
980                 return -1;
981         }
982
983         ret = wait_halmac_event(rtlpriv, id);
984         if (ret)
985                 return -1;
986
987         return 0;
988 }
989
990 int rtl_halmac_read_physical_efuse(struct rtl_priv *rtlpriv, u32 offset,
991                                    u32 cnt, u8 *data)
992 {
993         struct halmac_adapter *mac;
994         struct halmac_api *api;
995         enum halmac_ret_status status;
996         u8 v;
997         u32 i;
998
999         mac = rtlpriv_to_halmac(rtlpriv);
1000         api = HALMAC_GET_API(mac);
1001
1002         for (i = 0; i < cnt; i++) {
1003                 status = api->halmac_read_efuse(mac, offset + i, &v);
1004                 if (status != HALMAC_RET_SUCCESS)
1005                         return -1;
1006                 data[i] = v;
1007         }
1008
1009         return 0;
1010 }
1011
1012 int rtl_halmac_write_physical_efuse(struct rtl_priv *rtlpriv, u32 offset,
1013                                     u32 cnt, u8 *data)
1014 {
1015         struct halmac_adapter *mac;
1016         struct halmac_api *api;
1017         enum halmac_ret_status status;
1018         u32 i;
1019
1020         mac = rtlpriv_to_halmac(rtlpriv);
1021         api = HALMAC_GET_API(mac);
1022
1023         for (i = 0; i < cnt; i++) {
1024                 status = api->halmac_write_efuse(mac, offset + i, data[i]);
1025                 if (status != HALMAC_RET_SUCCESS)
1026                         return -1;
1027         }
1028
1029         return 0;
1030 }
1031
1032 int rtl_halmac_get_logical_efuse_size(struct rtl_priv *rtlpriv, u32 *size)
1033 {
1034         struct halmac_adapter *mac;
1035         struct halmac_api *api;
1036         enum halmac_ret_status status;
1037         u32 val;
1038
1039         mac = rtlpriv_to_halmac(rtlpriv);
1040         api = HALMAC_GET_API(mac);
1041
1042         status = api->halmac_get_logical_efuse_size(mac, &val);
1043         if (status != HALMAC_RET_SUCCESS)
1044                 return -1;
1045
1046         *size = val;
1047         return 0;
1048 }
1049
1050 int rtl_halmac_read_logical_efuse_map(struct rtl_priv *rtlpriv, u8 *map,
1051                                       u32 size)
1052 {
1053         struct halmac_adapter *mac;
1054         struct halmac_api *api;
1055         enum halmac_ret_status status;
1056         enum halmac_feature_id id;
1057         int ret;
1058
1059         mac = rtlpriv_to_halmac(rtlpriv);
1060         api = HALMAC_GET_API(mac);
1061         id = HALMAC_FEATURE_DUMP_LOGICAL_EFUSE;
1062
1063         ret = init_halmac_event(rtlpriv, id, map, size);
1064         if (ret)
1065                 return -1;
1066
1067         status = api->halmac_dump_logical_efuse_map(mac, HALMAC_EFUSE_R_AUTO);
1068         if (status != HALMAC_RET_SUCCESS) {
1069                 free_halmac_event(rtlpriv, id);
1070                 return -1;
1071         }
1072
1073         ret = wait_halmac_event(rtlpriv, id);
1074         if (ret)
1075                 return -1;
1076
1077         return 0;
1078 }
1079
1080 int rtl_halmac_write_logical_efuse_map(struct rtl_priv *rtlpriv, u8 *map,
1081                                        u32 size, u8 *maskmap, u32 masksize)
1082 {
1083         struct halmac_adapter *mac;
1084         struct halmac_api *api;
1085         struct halmac_pg_efuse_info pginfo;
1086         enum halmac_ret_status status;
1087
1088         mac = rtlpriv_to_halmac(rtlpriv);
1089         api = HALMAC_GET_API(mac);
1090
1091         pginfo.efuse_map = map;
1092         pginfo.efuse_map_size = size;
1093         pginfo.efuse_mask = maskmap;
1094         pginfo.efuse_mask_size = masksize;
1095
1096         status = api->halmac_pg_efuse_by_map(mac, &pginfo, HALMAC_EFUSE_R_AUTO);
1097         if (status != HALMAC_RET_SUCCESS)
1098                 return -1;
1099
1100         return 0;
1101 }
1102
1103 int rtl_halmac_read_logical_efuse(struct rtl_priv *rtlpriv, u32 offset, u32 cnt,
1104                                   u8 *data)
1105 {
1106         struct halmac_adapter *mac;
1107         struct halmac_api *api;
1108         enum halmac_ret_status status;
1109         u8 v;
1110         u32 i;
1111
1112         mac = rtlpriv_to_halmac(rtlpriv);
1113         api = HALMAC_GET_API(mac);
1114
1115         for (i = 0; i < cnt; i++) {
1116                 status = api->halmac_read_logical_efuse(mac, offset + i, &v);
1117                 if (status != HALMAC_RET_SUCCESS)
1118                         return -1;
1119                 data[i] = v;
1120         }
1121
1122         return 0;
1123 }
1124
1125 int rtl_halmac_write_logical_efuse(struct rtl_priv *rtlpriv, u32 offset,
1126                                    u32 cnt, u8 *data)
1127 {
1128         struct halmac_adapter *mac;
1129         struct halmac_api *api;
1130         enum halmac_ret_status status;
1131         u32 i;
1132
1133         mac = rtlpriv_to_halmac(rtlpriv);
1134         api = HALMAC_GET_API(mac);
1135
1136         for (i = 0; i < cnt; i++) {
1137                 status = api->halmac_write_logical_efuse(mac, offset + i,
1138                                                          data[i]);
1139                 if (status != HALMAC_RET_SUCCESS)
1140                         return -1;
1141         }
1142
1143         return 0;
1144 }
1145
1146 int rtl_halmac_set_mac_address(struct rtl_priv *rtlpriv, u8 hwport, u8 *addr)
1147 {
1148         struct halmac_adapter *halmac;
1149         struct halmac_api *api;
1150         u8 port;
1151         union halmac_wlan_addr hwa;
1152         enum halmac_ret_status status;
1153         int err = -1;
1154
1155         halmac = rtlpriv_to_halmac(rtlpriv);
1156         api = HALMAC_GET_API(halmac);
1157
1158         port = hwport;
1159         memset(&hwa, 0, sizeof(hwa));
1160         memcpy(hwa.address, addr, 6);
1161
1162         status = api->halmac_cfg_mac_addr(halmac, port, &hwa);
1163         if (status != HALMAC_RET_SUCCESS)
1164                 goto out;
1165
1166         err = 0;
1167 out:
1168         return err;
1169 }
1170
1171 int rtl_halmac_set_bssid(struct rtl_priv *rtlpriv, u8 hwport, u8 *addr)
1172 {
1173         struct halmac_adapter *halmac;
1174         struct halmac_api *api;
1175         u8 port;
1176         union halmac_wlan_addr hwa;
1177         enum halmac_ret_status status;
1178         int err = -1;
1179
1180         halmac = rtlpriv_to_halmac(rtlpriv);
1181         api = HALMAC_GET_API(halmac);
1182         port = hwport;
1183
1184         memset(&hwa, 0, sizeof(union halmac_wlan_addr));
1185         memcpy(hwa.address, addr, 6);
1186         status = api->halmac_cfg_bssid(halmac, port, &hwa);
1187         if (status != HALMAC_RET_SUCCESS)
1188                 goto out;
1189
1190         err = 0;
1191 out:
1192         return err;
1193 }
1194
1195 int rtl_halmac_set_bandwidth(struct rtl_priv *rtlpriv, u8 channel,
1196                              u8 pri_ch_idx, u8 bw)
1197 {
1198         struct halmac_adapter *mac;
1199         struct halmac_api *api;
1200         enum halmac_ret_status status;
1201
1202         mac = rtlpriv_to_halmac(rtlpriv);
1203         api = HALMAC_GET_API(mac);
1204
1205         status = api->halmac_cfg_ch_bw(mac, channel, pri_ch_idx, bw);
1206         if (status != HALMAC_RET_SUCCESS)
1207                 return -1;
1208
1209         return 0;
1210 }
1211
1212 int rtl_halmac_get_hw_value(struct rtl_priv *rtlpriv, enum halmac_hw_id hw_id,
1213                             void *pvalue)
1214 {
1215         struct halmac_adapter *mac;
1216         struct halmac_api *api;
1217         enum halmac_ret_status status;
1218
1219         mac = rtlpriv_to_halmac(rtlpriv);
1220         api = HALMAC_GET_API(mac);
1221
1222         status = api->halmac_get_hw_value(mac, hw_id, pvalue);
1223         if (status != HALMAC_RET_SUCCESS)
1224                 return -1;
1225
1226         return 0;
1227 }
1228
1229 int rtl_halmac_dump_fifo(struct rtl_priv *rtlpriv,
1230                          enum hal_fifo_sel halmac_fifo_sel)
1231 {
1232         struct halmac_adapter *mac;
1233         struct halmac_api *api;
1234         enum halmac_ret_status status;
1235         u8 *pfifo_map = NULL;
1236         u32 fifo_size = 0;
1237         s8 ret = 0;
1238
1239         mac = rtlpriv_to_halmac(rtlpriv);
1240         api = HALMAC_GET_API(mac);
1241
1242         fifo_size = api->halmac_get_fifo_size(mac, halmac_fifo_sel);
1243         if (fifo_size)
1244                 pfifo_map = vmalloc(fifo_size);
1245         if (!pfifo_map)
1246                 return -1;
1247
1248         status = api->halmac_dump_fifo(mac, halmac_fifo_sel, 0, fifo_size,
1249                                        pfifo_map);
1250
1251         if (status != HALMAC_RET_SUCCESS) {
1252                 ret = -1;
1253                 goto _exit;
1254         }
1255
1256 _exit:
1257         if (pfifo_map)
1258                 vfree(pfifo_map);
1259         return ret;
1260 }
1261
1262 int rtl_halmac_rx_agg_switch(struct rtl_priv *rtlpriv, bool enable)
1263 {
1264         struct halmac_adapter *halmac;
1265         struct halmac_api *api;
1266         struct halmac_rxagg_cfg rxaggcfg;
1267         enum halmac_ret_status status;
1268         int err = -1;
1269
1270         halmac = rtlpriv_to_halmac(rtlpriv);
1271         api = HALMAC_GET_API(halmac);
1272         memset((void *)&rxaggcfg, 0, sizeof(rxaggcfg));
1273
1274         if (enable) {
1275                 /* enable RX agg. */
1276                 /* PCIE do nothing */
1277         } else {
1278                 /* disable RX agg. */
1279                 rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
1280         }
1281
1282         status = api->halmac_cfg_rx_aggregation(halmac, &rxaggcfg);
1283         if (status != HALMAC_RET_SUCCESS)
1284                 goto out;
1285
1286         err = 0;
1287 out:
1288         return err;
1289 }
1290
1291 int rtl_halmac_get_wow_reason(struct rtl_priv *rtlpriv, u8 *reason)
1292 {
1293         u8 val8;
1294         int err = -1;
1295
1296         val8 = rtl_read_byte(rtlpriv, 0x1C7);
1297         if (val8 == 0xEA)
1298                 goto out;
1299
1300         *reason = val8;
1301         err = 0;
1302 out:
1303         return err;
1304 }
1305
1306 /*
1307  * Description:
1308  *      Get RX driver info size. RX driver info is a small memory space between
1309  *      scriptor and RX payload.
1310  *
1311  *      +-------------------------+
1312  *      | RX descriptor           |
1313  *      | usually 24 bytes        |
1314  *      +-------------------------+
1315  *      | RX driver info          |
1316  *      | depends on driver cfg   |
1317  *      +-------------------------+
1318  *      | RX paylad               |
1319  *      |                         |
1320  *      +-------------------------+
1321  *
1322  * Parameter:
1323  *      d       pointer to struct dvobj_priv of driver
1324  *      sz      rx driver info size in bytes.
1325  *
1326  * Rteurn:
1327  *      0       Success
1328  *      other   Fail
1329  */
1330 int rtl_halmac_get_drv_info_sz(struct rtl_priv *rtlpriv, u8 *sz)
1331 {
1332         /*      enum halmac_ret_status status; */
1333         u8 dw = 6; /* max number */
1334
1335         *sz = dw * 8;
1336         return 0;
1337 }
1338
1339 int rtl_halmac_get_rsvd_drv_pg_bndy(struct rtl_priv *rtlpriv, u16 *drv_pg)
1340 {
1341         enum halmac_ret_status status;
1342         struct halmac_adapter *halmac = rtlpriv_to_halmac(rtlpriv);
1343         struct halmac_api *api = HALMAC_GET_API(halmac);
1344
1345         status = api->halmac_get_hw_value(halmac, HALMAC_HW_RSVD_PG_BNDY,
1346                                           drv_pg);
1347         if (status != HALMAC_RET_SUCCESS)
1348                 return -1;
1349
1350         return 0;
1351 }
1352
1353 int rtl_halmac_chk_txdesc(struct rtl_priv *rtlpriv, u8 *txdesc, u32 size)
1354 {
1355         struct halmac_adapter *mac;
1356         struct halmac_api *api;
1357         enum halmac_ret_status status;
1358
1359         mac = rtlpriv_to_halmac(rtlpriv);
1360         api = HALMAC_GET_API(mac);
1361
1362         status = api->halmac_chk_txdesc(mac, txdesc, size);
1363
1364         if (status != HALMAC_RET_SUCCESS)
1365                 return -1;
1366
1367         return 0;
1368 }
1369
1370 MODULE_AUTHOR("Realtek WlanFAE  <wlanfae@realtek.com>");
1371 MODULE_AUTHOR("Larry Finger     <Larry.FInger@lwfinger.net>");
1372 MODULE_LICENSE("GPL");
1373 MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");