linux/drivers/staging/rtlwifi/halmac/rtl_halmac.c
<<
>>
Prefs
   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
  23static 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
  47struct rtl_halmac_ops *rtl_halmac_get_ops_pointer(void)
  48{
  49        return &rtl_halmac_operation;
  50}
  51EXPORT_SYMBOL(rtl_halmac_get_ops_pointer);
  52
  53/*
  54 * Driver API for HALMAC operations
  55 */
  56
  57static 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
  64static 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
  71static 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
  78static 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
  85static 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
  92static 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
  99static 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
 111static 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
 122static 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
 135static 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
 203static 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
 234static 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
 242static 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
 255static 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 */
 278static 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
 330exit:
 331        return true;
 332}
 333
 334static 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
 351static 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
 368static 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
 377int 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
 408out:
 409        if (err)
 410                rtl_halmac_deinit_adapter(rtlpriv);
 411
 412        return err;
 413}
 414
 415int 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
 438out:
 439        return err;
 440}
 441
 442int 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;
 468out:
 469        return err;
 470}
 471
 472int 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;
 490out:
 491        return err;
 492}
 493
 494/*
 495 * Note:
 496 *      When this function return, the register REG_RCR may be changed.
 497 */
 498int 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;
 514out:
 515        return err;
 516}
 517
 518static 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
 556out:
 557        return status;
 558}
 559
 560static 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
 585static 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 */
 624static 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;
 711out:
 712        return err_ret;
 713}
 714
 715int 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
 724int 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;
 746out:
 747        return err;
 748}
 749
 750int 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;
 769out:
 770        return err;
 771}
 772
 773int 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 */
 840int 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
 858static 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                        schedule();
 874        } while ((!read_down) && (retry_cnts--));
 875
 876        return read_down;
 877}
 878
 879int 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
 921exit:
 922        spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
 923        return ret;
 924}
 925
 926int 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
 942int 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
 960int 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
 990int 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
1012int 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
1032int 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
1050int 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
1080int 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
1103int 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
1125int 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
1146int 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;
1167out:
1168        return err;
1169}
1170
1171int 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;
1191out:
1192        return err;
1193}
1194
1195int 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
1212int 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
1229int 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
1262int 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;
1287out:
1288        return err;
1289}
1290
1291int 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;
1302out:
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 */
1330int 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
1339int 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
1353int 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
1370MODULE_AUTHOR("Realtek WlanFAE  <wlanfae@realtek.com>");
1371MODULE_AUTHOR("Larry Finger     <Larry.FInger@lwfinger.net>");
1372MODULE_LICENSE("GPL");
1373MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
1374