linux/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2016  Realtek Corporation.
   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 * The full GNU General Public License is included in this distribution in the
  15 * file called LICENSE.
  16 *
  17 * Contact Information:
  18 * wlanfae <wlanfae@realtek.com>
  19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  20 * Hsinchu 300, Taiwan.
  21 *
  22 * Larry Finger <Larry.Finger@lwfinger.net>
  23 *
  24 *****************************************************************************/
  25#include "halmac_88xx_cfg.h"
  26
  27static enum halmac_ret_status
  28halmac_dump_efuse_fw_88xx(struct halmac_adapter *halmac_adapter);
  29
  30static enum halmac_ret_status
  31halmac_dump_efuse_drv_88xx(struct halmac_adapter *halmac_adapter);
  32
  33static enum halmac_ret_status
  34halmac_update_eeprom_mask_88xx(struct halmac_adapter *halmac_adapter,
  35                               struct halmac_pg_efuse_info *pg_efuse_info,
  36                               u8 *eeprom_mask_updated);
  37
  38static enum halmac_ret_status
  39halmac_check_efuse_enough_88xx(struct halmac_adapter *halmac_adapter,
  40                               struct halmac_pg_efuse_info *pg_efuse_info,
  41                               u8 *eeprom_mask_updated);
  42
  43static enum halmac_ret_status
  44halmac_program_efuse_88xx(struct halmac_adapter *halmac_adapter,
  45                          struct halmac_pg_efuse_info *pg_efuse_info,
  46                          u8 *eeprom_mask_updated);
  47
  48static enum halmac_ret_status
  49halmac_pwr_sub_seq_parer_88xx(struct halmac_adapter *halmac_adapter, u8 cut,
  50                              u8 fab, u8 intf,
  51                              struct halmac_wl_pwr_cfg_ *pwr_sub_seq_cfg);
  52
  53static enum halmac_ret_status
  54halmac_parse_c2h_debug_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
  55                            u32 c2h_size);
  56
  57static enum halmac_ret_status
  58halmac_parse_scan_status_rpt_88xx(struct halmac_adapter *halmac_adapter,
  59                                  u8 *c2h_buf, u32 c2h_size);
  60
  61static enum halmac_ret_status
  62halmac_parse_psd_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
  63                           u32 c2h_size);
  64
  65static enum halmac_ret_status
  66halmac_parse_efuse_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
  67                             u32 c2h_size);
  68
  69static enum halmac_ret_status
  70halmac_parse_h2c_ack_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
  71                          u32 c2h_size);
  72
  73static enum halmac_ret_status
  74halmac_enqueue_para_buff_88xx(struct halmac_adapter *halmac_adapter,
  75                              struct halmac_phy_parameter_info *para_info,
  76                              u8 *curr_buff_wptr, bool *end_cmd);
  77
  78static enum halmac_ret_status
  79halmac_parse_h2c_ack_phy_efuse_88xx(struct halmac_adapter *halmac_adapter,
  80                                    u8 *c2h_buf, u32 c2h_size);
  81
  82static enum halmac_ret_status
  83halmac_parse_h2c_ack_cfg_para_88xx(struct halmac_adapter *halmac_adapter,
  84                                   u8 *c2h_buf, u32 c2h_size);
  85
  86static enum halmac_ret_status
  87halmac_gen_cfg_para_h2c_88xx(struct halmac_adapter *halmac_adapter,
  88                             u8 *h2c_buff);
  89
  90static enum halmac_ret_status
  91halmac_parse_h2c_ack_update_packet_88xx(struct halmac_adapter *halmac_adapter,
  92                                        u8 *c2h_buf, u32 c2h_size);
  93
  94static enum halmac_ret_status
  95halmac_parse_h2c_ack_update_datapack_88xx(struct halmac_adapter *halmac_adapter,
  96                                          u8 *c2h_buf, u32 c2h_size);
  97
  98static enum halmac_ret_status
  99halmac_parse_h2c_ack_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
 100                                       u8 *c2h_buf, u32 c2h_size);
 101
 102static enum halmac_ret_status
 103halmac_parse_h2c_ack_channel_switch_88xx(struct halmac_adapter *halmac_adapter,
 104                                         u8 *c2h_buf, u32 c2h_size);
 105
 106static enum halmac_ret_status
 107halmac_parse_h2c_ack_iqk_88xx(struct halmac_adapter *halmac_adapter,
 108                              u8 *c2h_buf, u32 c2h_size);
 109
 110static enum halmac_ret_status
 111halmac_parse_h2c_ack_power_tracking_88xx(struct halmac_adapter *halmac_adapter,
 112                                         u8 *c2h_buf, u32 c2h_size);
 113
 114void halmac_init_offload_feature_state_machine_88xx(
 115        struct halmac_adapter *halmac_adapter)
 116{
 117        struct halmac_state *state = &halmac_adapter->halmac_state;
 118
 119        state->efuse_state_set.efuse_cmd_construct_state =
 120                HALMAC_EFUSE_CMD_CONSTRUCT_IDLE;
 121        state->efuse_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
 122        state->efuse_state_set.seq_num = halmac_adapter->h2c_packet_seq;
 123
 124        state->cfg_para_state_set.cfg_para_cmd_construct_state =
 125                HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE;
 126        state->cfg_para_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
 127        state->cfg_para_state_set.seq_num = halmac_adapter->h2c_packet_seq;
 128
 129        state->scan_state_set.scan_cmd_construct_state =
 130                HALMAC_SCAN_CMD_CONSTRUCT_IDLE;
 131        state->scan_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
 132        state->scan_state_set.seq_num = halmac_adapter->h2c_packet_seq;
 133
 134        state->update_packet_set.process_status = HALMAC_CMD_PROCESS_IDLE;
 135        state->update_packet_set.seq_num = halmac_adapter->h2c_packet_seq;
 136
 137        state->iqk_set.process_status = HALMAC_CMD_PROCESS_IDLE;
 138        state->iqk_set.seq_num = halmac_adapter->h2c_packet_seq;
 139
 140        state->power_tracking_set.process_status = HALMAC_CMD_PROCESS_IDLE;
 141        state->power_tracking_set.seq_num = halmac_adapter->h2c_packet_seq;
 142
 143        state->psd_set.process_status = HALMAC_CMD_PROCESS_IDLE;
 144        state->psd_set.seq_num = halmac_adapter->h2c_packet_seq;
 145        state->psd_set.data_size = 0;
 146        state->psd_set.segment_size = 0;
 147        state->psd_set.data = NULL;
 148}
 149
 150enum halmac_ret_status
 151halmac_dump_efuse_88xx(struct halmac_adapter *halmac_adapter,
 152                       enum halmac_efuse_read_cfg cfg)
 153{
 154        u32 chk_h2c_init;
 155        void *driver_adapter = NULL;
 156        struct halmac_api *halmac_api =
 157                (struct halmac_api *)halmac_adapter->halmac_api;
 158        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
 159        enum halmac_cmd_process_status *process_status =
 160                &halmac_adapter->halmac_state.efuse_state_set.process_status;
 161
 162        driver_adapter = halmac_adapter->driver_adapter;
 163
 164        *process_status = HALMAC_CMD_PROCESS_SENDING;
 165
 166        if (halmac_transition_efuse_state_88xx(
 167                    halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT) !=
 168            HALMAC_RET_SUCCESS)
 169                return HALMAC_RET_ERROR_STATE;
 170
 171        if (cfg == HALMAC_EFUSE_R_AUTO) {
 172                chk_h2c_init = HALMAC_REG_READ_32(halmac_adapter,
 173                                                  REG_H2C_PKT_READADDR);
 174                if (halmac_adapter->halmac_state.dlfw_state ==
 175                            HALMAC_DLFW_NONE ||
 176                    chk_h2c_init == 0)
 177                        status = halmac_dump_efuse_drv_88xx(halmac_adapter);
 178                else
 179                        status = halmac_dump_efuse_fw_88xx(halmac_adapter);
 180        } else if (cfg == HALMAC_EFUSE_R_FW) {
 181                status = halmac_dump_efuse_fw_88xx(halmac_adapter);
 182        } else {
 183                status = halmac_dump_efuse_drv_88xx(halmac_adapter);
 184        }
 185
 186        if (status != HALMAC_RET_SUCCESS) {
 187                pr_err("halmac_read_efuse error = %x\n", status);
 188                return status;
 189        }
 190
 191        return status;
 192}
 193
 194enum halmac_ret_status
 195halmac_func_read_efuse_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
 196                            u32 size, u8 *efuse_map)
 197{
 198        void *driver_adapter = NULL;
 199
 200        driver_adapter = halmac_adapter->driver_adapter;
 201
 202        if (!efuse_map) {
 203                pr_err("Malloc for dump efuse map error\n");
 204                return HALMAC_RET_NULL_POINTER;
 205        }
 206
 207        if (halmac_adapter->hal_efuse_map_valid)
 208                memcpy(efuse_map, halmac_adapter->hal_efuse_map + offset, size);
 209        else if (halmac_read_hw_efuse_88xx(halmac_adapter, offset, size,
 210                                           efuse_map) != HALMAC_RET_SUCCESS)
 211                return HALMAC_RET_EFUSE_R_FAIL;
 212
 213        return HALMAC_RET_SUCCESS;
 214}
 215
 216enum halmac_ret_status
 217halmac_read_hw_efuse_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
 218                          u32 size, u8 *efuse_map)
 219{
 220        u8 value8;
 221        u32 value32;
 222        u32 address;
 223        u32 tmp32, counter;
 224        void *driver_adapter = NULL;
 225        struct halmac_api *halmac_api;
 226
 227        driver_adapter = halmac_adapter->driver_adapter;
 228        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
 229
 230        /* Read efuse no need 2.5V LDO */
 231        value8 = HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 3);
 232        if (value8 & BIT(7))
 233                HALMAC_REG_WRITE_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 3,
 234                                   (u8)(value8 & ~(BIT(7))));
 235
 236        value32 = HALMAC_REG_READ_32(halmac_adapter, REG_EFUSE_CTRL);
 237
 238        for (address = offset; address < offset + size; address++) {
 239                value32 = value32 &
 240                          ~((BIT_MASK_EF_DATA) |
 241                            (BIT_MASK_EF_ADDR << BIT_SHIFT_EF_ADDR));
 242                value32 = value32 |
 243                          ((address & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR);
 244                HALMAC_REG_WRITE_32(halmac_adapter, REG_EFUSE_CTRL,
 245                                    value32 & (~BIT_EF_FLAG));
 246
 247                counter = 1000000;
 248                do {
 249                        udelay(1);
 250                        tmp32 = HALMAC_REG_READ_32(halmac_adapter,
 251                                                   REG_EFUSE_CTRL);
 252                        counter--;
 253                        if (counter == 0) {
 254                                pr_err("HALMAC_RET_EFUSE_R_FAIL\n");
 255                                return HALMAC_RET_EFUSE_R_FAIL;
 256                        }
 257                } while ((tmp32 & BIT_EF_FLAG) == 0);
 258
 259                *(efuse_map + address - offset) =
 260                        (u8)(tmp32 & BIT_MASK_EF_DATA);
 261        }
 262
 263        return HALMAC_RET_SUCCESS;
 264}
 265
 266static enum halmac_ret_status
 267halmac_dump_efuse_drv_88xx(struct halmac_adapter *halmac_adapter)
 268{
 269        u8 *efuse_map = NULL;
 270        u32 efuse_size;
 271        void *driver_adapter = NULL;
 272
 273        driver_adapter = halmac_adapter->driver_adapter;
 274
 275        efuse_size = halmac_adapter->hw_config_info.efuse_size;
 276
 277        if (!halmac_adapter->hal_efuse_map) {
 278                halmac_adapter->hal_efuse_map = kzalloc(efuse_size, GFP_KERNEL);
 279                if (!halmac_adapter->hal_efuse_map) {
 280                        pr_err("[ERR]halmac allocate efuse map Fail!!\n");
 281                        return HALMAC_RET_MALLOC_FAIL;
 282                }
 283        }
 284
 285        efuse_map = kzalloc(efuse_size, GFP_KERNEL);
 286        if (!efuse_map) {
 287                /* out of memory */
 288                return HALMAC_RET_MALLOC_FAIL;
 289        }
 290
 291        if (halmac_read_hw_efuse_88xx(halmac_adapter, 0, efuse_size,
 292                                      efuse_map) != HALMAC_RET_SUCCESS) {
 293                kfree(efuse_map);
 294                return HALMAC_RET_EFUSE_R_FAIL;
 295        }
 296
 297        spin_lock(&halmac_adapter->efuse_lock);
 298        memcpy(halmac_adapter->hal_efuse_map, efuse_map, efuse_size);
 299        halmac_adapter->hal_efuse_map_valid = true;
 300        spin_unlock(&halmac_adapter->efuse_lock);
 301
 302        kfree(efuse_map);
 303
 304        return HALMAC_RET_SUCCESS;
 305}
 306
 307static enum halmac_ret_status
 308halmac_dump_efuse_fw_88xx(struct halmac_adapter *halmac_adapter)
 309{
 310        u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
 311        u16 h2c_seq_mum = 0;
 312        void *driver_adapter = NULL;
 313        struct halmac_h2c_header_info h2c_header_info;
 314        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
 315
 316        driver_adapter = halmac_adapter->driver_adapter;
 317
 318        h2c_header_info.sub_cmd_id = SUB_CMD_ID_DUMP_PHYSICAL_EFUSE;
 319        h2c_header_info.content_size = 0;
 320        h2c_header_info.ack = true;
 321        halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
 322                                              &h2c_header_info, &h2c_seq_mum);
 323        halmac_adapter->halmac_state.efuse_state_set.seq_num = h2c_seq_mum;
 324
 325        if (!halmac_adapter->hal_efuse_map) {
 326                halmac_adapter->hal_efuse_map = kzalloc(
 327                        halmac_adapter->hw_config_info.efuse_size, GFP_KERNEL);
 328                if (!halmac_adapter->hal_efuse_map) {
 329                        /* out of memory */
 330                        return HALMAC_RET_MALLOC_FAIL;
 331                }
 332        }
 333
 334        if (!halmac_adapter->hal_efuse_map_valid) {
 335                status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
 336                                                  HALMAC_H2C_CMD_SIZE_88XX,
 337                                                  true);
 338                if (status != HALMAC_RET_SUCCESS) {
 339                        pr_err("halmac_read_efuse_fw Fail = %x!!\n", status);
 340                        return status;
 341                }
 342        }
 343
 344        return HALMAC_RET_SUCCESS;
 345}
 346
 347enum halmac_ret_status
 348halmac_func_write_efuse_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
 349                             u8 value)
 350{
 351        const u8 wite_protect_code = 0x69;
 352        u32 value32, tmp32, counter;
 353        void *driver_adapter = NULL;
 354        struct halmac_api *halmac_api;
 355
 356        driver_adapter = halmac_adapter->driver_adapter;
 357        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
 358
 359        spin_lock(&halmac_adapter->efuse_lock);
 360        halmac_adapter->hal_efuse_map_valid = false;
 361        spin_unlock(&halmac_adapter->efuse_lock);
 362
 363        HALMAC_REG_WRITE_8(halmac_adapter, REG_PMC_DBG_CTRL2 + 3,
 364                           wite_protect_code);
 365
 366        /* Enable 2.5V LDO */
 367        HALMAC_REG_WRITE_8(
 368                halmac_adapter, REG_LDO_EFUSE_CTRL + 3,
 369                (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 3) |
 370                     BIT(7)));
 371
 372        value32 = HALMAC_REG_READ_32(halmac_adapter, REG_EFUSE_CTRL);
 373        value32 =
 374                value32 &
 375                ~((BIT_MASK_EF_DATA) | (BIT_MASK_EF_ADDR << BIT_SHIFT_EF_ADDR));
 376        value32 = value32 | ((offset & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR) |
 377                  (value & BIT_MASK_EF_DATA);
 378        HALMAC_REG_WRITE_32(halmac_adapter, REG_EFUSE_CTRL,
 379                            value32 | BIT_EF_FLAG);
 380
 381        counter = 1000000;
 382        do {
 383                udelay(1);
 384                tmp32 = HALMAC_REG_READ_32(halmac_adapter, REG_EFUSE_CTRL);
 385                counter--;
 386                if (counter == 0) {
 387                        pr_err("halmac_write_efuse Fail !!\n");
 388                        return HALMAC_RET_EFUSE_W_FAIL;
 389                }
 390        } while ((tmp32 & BIT_EF_FLAG) == BIT_EF_FLAG);
 391
 392        HALMAC_REG_WRITE_8(halmac_adapter, REG_PMC_DBG_CTRL2 + 3, 0x00);
 393
 394        /* Disable 2.5V LDO */
 395        HALMAC_REG_WRITE_8(
 396                halmac_adapter, REG_LDO_EFUSE_CTRL + 3,
 397                (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 3) &
 398                     ~(BIT(7))));
 399
 400        return HALMAC_RET_SUCCESS;
 401}
 402
 403enum halmac_ret_status
 404halmac_func_switch_efuse_bank_88xx(struct halmac_adapter *halmac_adapter,
 405                                   enum halmac_efuse_bank efuse_bank)
 406{
 407        u8 reg_value;
 408        struct halmac_api *halmac_api;
 409
 410        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
 411
 412        if (halmac_transition_efuse_state_88xx(
 413                    halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_BUSY) !=
 414            HALMAC_RET_SUCCESS)
 415                return HALMAC_RET_ERROR_STATE;
 416
 417        reg_value = HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 1);
 418
 419        if (efuse_bank == (reg_value & (BIT(0) | BIT(1))))
 420                return HALMAC_RET_SUCCESS;
 421
 422        reg_value &= ~(BIT(0) | BIT(1));
 423        reg_value |= efuse_bank;
 424        HALMAC_REG_WRITE_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 1, reg_value);
 425
 426        if ((HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 1) &
 427             (BIT(0) | BIT(1))) != efuse_bank)
 428                return HALMAC_RET_SWITCH_EFUSE_BANK_FAIL;
 429
 430        return HALMAC_RET_SUCCESS;
 431}
 432
 433enum halmac_ret_status
 434halmac_eeprom_parser_88xx(struct halmac_adapter *halmac_adapter,
 435                          u8 *physical_efuse_map, u8 *logical_efuse_map)
 436{
 437        u8 j;
 438        u8 value8;
 439        u8 block_index;
 440        u8 valid_word_enable, word_enable;
 441        u8 efuse_read_header, efuse_read_header2 = 0;
 442        u32 eeprom_index;
 443        u32 efuse_index = 0;
 444        u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
 445        void *driver_adapter = NULL;
 446
 447        driver_adapter = halmac_adapter->driver_adapter;
 448
 449        memset(logical_efuse_map, 0xFF, eeprom_size);
 450
 451        do {
 452                value8 = *(physical_efuse_map + efuse_index);
 453                efuse_read_header = value8;
 454
 455                if ((efuse_read_header & 0x1f) == 0x0f) {
 456                        efuse_index++;
 457                        value8 = *(physical_efuse_map + efuse_index);
 458                        efuse_read_header2 = value8;
 459                        block_index = ((efuse_read_header2 & 0xF0) >> 1) |
 460                                      ((efuse_read_header >> 5) & 0x07);
 461                        word_enable = efuse_read_header2 & 0x0F;
 462                } else {
 463                        block_index = (efuse_read_header & 0xF0) >> 4;
 464                        word_enable = efuse_read_header & 0x0F;
 465                }
 466
 467                if (efuse_read_header == 0xff)
 468                        break;
 469
 470                efuse_index++;
 471
 472                if (efuse_index >= halmac_adapter->hw_config_info.efuse_size -
 473                                           HALMAC_PROTECTED_EFUSE_SIZE_88XX - 1)
 474                        return HALMAC_RET_EEPROM_PARSING_FAIL;
 475
 476                for (j = 0; j < 4; j++) {
 477                        valid_word_enable =
 478                                (u8)((~(word_enable >> j)) & BIT(0));
 479                        if (valid_word_enable != 1)
 480                                continue;
 481
 482                        eeprom_index = (block_index << 3) + (j << 1);
 483
 484                        if ((eeprom_index + 1) > eeprom_size) {
 485                                pr_err("Error: EEPROM addr exceeds eeprom_size:0x%X, at eFuse 0x%X\n",
 486                                       eeprom_size, efuse_index - 1);
 487                                if ((efuse_read_header & 0x1f) == 0x0f)
 488                                        pr_err("Error: EEPROM header: 0x%X, 0x%X,\n",
 489                                               efuse_read_header,
 490                                               efuse_read_header2);
 491                                else
 492                                        pr_err("Error: EEPROM header: 0x%X,\n",
 493                                               efuse_read_header);
 494
 495                                return HALMAC_RET_EEPROM_PARSING_FAIL;
 496                        }
 497
 498                        value8 = *(physical_efuse_map + efuse_index);
 499                        *(logical_efuse_map + eeprom_index) = value8;
 500
 501                        eeprom_index++;
 502                        efuse_index++;
 503
 504                        if (efuse_index >
 505                            halmac_adapter->hw_config_info.efuse_size -
 506                                    HALMAC_PROTECTED_EFUSE_SIZE_88XX - 1)
 507                                return HALMAC_RET_EEPROM_PARSING_FAIL;
 508
 509                        value8 = *(physical_efuse_map + efuse_index);
 510                        *(logical_efuse_map + eeprom_index) = value8;
 511
 512                        efuse_index++;
 513
 514                        if (efuse_index >
 515                            halmac_adapter->hw_config_info.efuse_size -
 516                                    HALMAC_PROTECTED_EFUSE_SIZE_88XX)
 517                                return HALMAC_RET_EEPROM_PARSING_FAIL;
 518                }
 519        } while (1);
 520
 521        halmac_adapter->efuse_end = efuse_index;
 522
 523        return HALMAC_RET_SUCCESS;
 524}
 525
 526enum halmac_ret_status
 527halmac_read_logical_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
 528                                   u8 *map)
 529{
 530        u8 *efuse_map = NULL;
 531        u32 efuse_size;
 532        void *driver_adapter = NULL;
 533        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
 534
 535        driver_adapter = halmac_adapter->driver_adapter;
 536        efuse_size = halmac_adapter->hw_config_info.efuse_size;
 537
 538        if (!halmac_adapter->hal_efuse_map_valid) {
 539                efuse_map = kzalloc(efuse_size, GFP_KERNEL);
 540                if (!efuse_map) {
 541                        pr_err("[ERR]halmac allocate local efuse map Fail!!\n");
 542                        return HALMAC_RET_MALLOC_FAIL;
 543                }
 544
 545                status = halmac_func_read_efuse_88xx(halmac_adapter, 0,
 546                                                     efuse_size, efuse_map);
 547                if (status != HALMAC_RET_SUCCESS) {
 548                        pr_err("[ERR]halmac_read_efuse error = %x\n", status);
 549                        kfree(efuse_map);
 550                        return status;
 551                }
 552
 553                if (!halmac_adapter->hal_efuse_map) {
 554                        halmac_adapter->hal_efuse_map =
 555                                kzalloc(efuse_size, GFP_KERNEL);
 556                        if (!halmac_adapter->hal_efuse_map) {
 557                                pr_err("[ERR]halmac allocate efuse map Fail!!\n");
 558                                kfree(efuse_map);
 559                                return HALMAC_RET_MALLOC_FAIL;
 560                        }
 561                }
 562
 563                spin_lock(&halmac_adapter->efuse_lock);
 564                memcpy(halmac_adapter->hal_efuse_map, efuse_map, efuse_size);
 565                halmac_adapter->hal_efuse_map_valid = true;
 566                spin_unlock(&halmac_adapter->efuse_lock);
 567
 568                kfree(efuse_map);
 569        }
 570
 571        if (halmac_eeprom_parser_88xx(halmac_adapter,
 572                                      halmac_adapter->hal_efuse_map,
 573                                      map) != HALMAC_RET_SUCCESS)
 574                return HALMAC_RET_EEPROM_PARSING_FAIL;
 575
 576        return status;
 577}
 578
 579enum halmac_ret_status
 580halmac_func_write_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
 581                                     u32 offset, u8 value)
 582{
 583        u8 pg_efuse_byte1, pg_efuse_byte2;
 584        u8 pg_block, pg_block_index;
 585        u8 pg_efuse_header, pg_efuse_header2;
 586        u8 *eeprom_map = NULL;
 587        u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
 588        u32 efuse_end, pg_efuse_num;
 589        void *driver_adapter = NULL;
 590        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
 591
 592        driver_adapter = halmac_adapter->driver_adapter;
 593
 594        eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
 595        if (!eeprom_map) {
 596                /* out of memory */
 597                return HALMAC_RET_MALLOC_FAIL;
 598        }
 599        memset(eeprom_map, 0xFF, eeprom_size);
 600
 601        status = halmac_read_logical_efuse_map_88xx(halmac_adapter, eeprom_map);
 602        if (status != HALMAC_RET_SUCCESS) {
 603                pr_err("[ERR]halmac_read_logical_efuse_map_88xx error = %x\n",
 604                       status);
 605                kfree(eeprom_map);
 606                return status;
 607        }
 608
 609        if (*(eeprom_map + offset) != value) {
 610                efuse_end = halmac_adapter->efuse_end;
 611                pg_block = (u8)(offset >> 3);
 612                pg_block_index = (u8)((offset & (8 - 1)) >> 1);
 613
 614                if (offset > 0x7f) {
 615                        pg_efuse_header =
 616                                (((pg_block & 0x07) << 5) & 0xE0) | 0x0F;
 617                        pg_efuse_header2 =
 618                                (u8)(((pg_block & 0x78) << 1) +
 619                                     ((0x1 << pg_block_index) ^ 0x0F));
 620                } else {
 621                        pg_efuse_header =
 622                                (u8)((pg_block << 4) +
 623                                     ((0x01 << pg_block_index) ^ 0x0F));
 624                }
 625
 626                if ((offset & 1) == 0) {
 627                        pg_efuse_byte1 = value;
 628                        pg_efuse_byte2 = *(eeprom_map + offset + 1);
 629                } else {
 630                        pg_efuse_byte1 = *(eeprom_map + offset - 1);
 631                        pg_efuse_byte2 = value;
 632                }
 633
 634                if (offset > 0x7f) {
 635                        pg_efuse_num = 4;
 636                        if (halmac_adapter->hw_config_info.efuse_size <=
 637                            (pg_efuse_num + HALMAC_PROTECTED_EFUSE_SIZE_88XX +
 638                             halmac_adapter->efuse_end)) {
 639                                kfree(eeprom_map);
 640                                return HALMAC_RET_EFUSE_NOT_ENOUGH;
 641                        }
 642                        halmac_func_write_efuse_88xx(halmac_adapter, efuse_end,
 643                                                     pg_efuse_header);
 644                        halmac_func_write_efuse_88xx(halmac_adapter,
 645                                                     efuse_end + 1,
 646                                                     pg_efuse_header2);
 647                        halmac_func_write_efuse_88xx(
 648                                halmac_adapter, efuse_end + 2, pg_efuse_byte1);
 649                        status = halmac_func_write_efuse_88xx(
 650                                halmac_adapter, efuse_end + 3, pg_efuse_byte2);
 651                } else {
 652                        pg_efuse_num = 3;
 653                        if (halmac_adapter->hw_config_info.efuse_size <=
 654                            (pg_efuse_num + HALMAC_PROTECTED_EFUSE_SIZE_88XX +
 655                             halmac_adapter->efuse_end)) {
 656                                kfree(eeprom_map);
 657                                return HALMAC_RET_EFUSE_NOT_ENOUGH;
 658                        }
 659                        halmac_func_write_efuse_88xx(halmac_adapter, efuse_end,
 660                                                     pg_efuse_header);
 661                        halmac_func_write_efuse_88xx(
 662                                halmac_adapter, efuse_end + 1, pg_efuse_byte1);
 663                        status = halmac_func_write_efuse_88xx(
 664                                halmac_adapter, efuse_end + 2, pg_efuse_byte2);
 665                }
 666
 667                if (status != HALMAC_RET_SUCCESS) {
 668                        pr_err("[ERR]halmac_write_logical_efuse error = %x\n",
 669                               status);
 670                        kfree(eeprom_map);
 671                        return status;
 672                }
 673        }
 674
 675        kfree(eeprom_map);
 676
 677        return HALMAC_RET_SUCCESS;
 678}
 679
 680enum halmac_ret_status
 681halmac_func_pg_efuse_by_map_88xx(struct halmac_adapter *halmac_adapter,
 682                                 struct halmac_pg_efuse_info *pg_efuse_info,
 683                                 enum halmac_efuse_read_cfg cfg)
 684{
 685        u8 *eeprom_mask_updated = NULL;
 686        u32 eeprom_mask_size = halmac_adapter->hw_config_info.eeprom_size >> 4;
 687        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
 688
 689        eeprom_mask_updated = kzalloc(eeprom_mask_size, GFP_KERNEL);
 690        if (!eeprom_mask_updated) {
 691                /* out of memory */
 692                return HALMAC_RET_MALLOC_FAIL;
 693        }
 694
 695        status = halmac_update_eeprom_mask_88xx(halmac_adapter, pg_efuse_info,
 696                                                eeprom_mask_updated);
 697
 698        if (status != HALMAC_RET_SUCCESS) {
 699                pr_err("[ERR]halmac_update_eeprom_mask_88xx error = %x\n",
 700                       status);
 701                kfree(eeprom_mask_updated);
 702                return status;
 703        }
 704
 705        status = halmac_check_efuse_enough_88xx(halmac_adapter, pg_efuse_info,
 706                                                eeprom_mask_updated);
 707
 708        if (status != HALMAC_RET_SUCCESS) {
 709                pr_err("[ERR]halmac_check_efuse_enough_88xx error = %x\n",
 710                       status);
 711                kfree(eeprom_mask_updated);
 712                return status;
 713        }
 714
 715        status = halmac_program_efuse_88xx(halmac_adapter, pg_efuse_info,
 716                                           eeprom_mask_updated);
 717
 718        if (status != HALMAC_RET_SUCCESS) {
 719                pr_err("[ERR]halmac_program_efuse_88xx error = %x\n", status);
 720                kfree(eeprom_mask_updated);
 721                return status;
 722        }
 723
 724        kfree(eeprom_mask_updated);
 725
 726        return HALMAC_RET_SUCCESS;
 727}
 728
 729static enum halmac_ret_status
 730halmac_update_eeprom_mask_88xx(struct halmac_adapter *halmac_adapter,
 731                               struct halmac_pg_efuse_info *pg_efuse_info,
 732                               u8 *eeprom_mask_updated)
 733{
 734        u8 *eeprom_map = NULL;
 735        u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
 736        u8 *eeprom_map_pg, *eeprom_mask;
 737        u16 i, j;
 738        u16 map_byte_offset, mask_byte_offset;
 739        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
 740
 741        void *driver_adapter = NULL;
 742
 743        driver_adapter = halmac_adapter->driver_adapter;
 744
 745        eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
 746        if (!eeprom_map) {
 747                /* out of memory */
 748                return HALMAC_RET_MALLOC_FAIL;
 749        }
 750        memset(eeprom_map, 0xFF, eeprom_size);
 751
 752        memset(eeprom_mask_updated, 0x00, pg_efuse_info->efuse_mask_size);
 753
 754        status = halmac_read_logical_efuse_map_88xx(halmac_adapter, eeprom_map);
 755
 756        if (status != HALMAC_RET_SUCCESS) {
 757                kfree(eeprom_map);
 758                return status;
 759        }
 760
 761        eeprom_map_pg = pg_efuse_info->efuse_map;
 762        eeprom_mask = pg_efuse_info->efuse_mask;
 763
 764        for (i = 0; i < pg_efuse_info->efuse_mask_size; i++)
 765                *(eeprom_mask_updated + i) = *(eeprom_mask + i);
 766
 767        for (i = 0; i < pg_efuse_info->efuse_map_size; i = i + 16) {
 768                for (j = 0; j < 16; j = j + 2) {
 769                        map_byte_offset = i + j;
 770                        mask_byte_offset = i >> 4;
 771                        if (*(eeprom_map_pg + map_byte_offset) ==
 772                            *(eeprom_map + map_byte_offset)) {
 773                                if (*(eeprom_map_pg + map_byte_offset + 1) ==
 774                                    *(eeprom_map + map_byte_offset + 1)) {
 775                                        switch (j) {
 776                                        case 0:
 777                                                *(eeprom_mask_updated +
 778                                                  mask_byte_offset) =
 779                                                        *(eeprom_mask_updated +
 780                                                          mask_byte_offset) &
 781                                                        (BIT(4) ^ 0xFF);
 782                                                break;
 783                                        case 2:
 784                                                *(eeprom_mask_updated +
 785                                                  mask_byte_offset) =
 786                                                        *(eeprom_mask_updated +
 787                                                          mask_byte_offset) &
 788                                                        (BIT(5) ^ 0xFF);
 789                                                break;
 790                                        case 4:
 791                                                *(eeprom_mask_updated +
 792                                                  mask_byte_offset) =
 793                                                        *(eeprom_mask_updated +
 794                                                          mask_byte_offset) &
 795                                                        (BIT(6) ^ 0xFF);
 796                                                break;
 797                                        case 6:
 798                                                *(eeprom_mask_updated +
 799                                                  mask_byte_offset) =
 800                                                        *(eeprom_mask_updated +
 801                                                          mask_byte_offset) &
 802                                                        (BIT(7) ^ 0xFF);
 803                                                break;
 804                                        case 8:
 805                                                *(eeprom_mask_updated +
 806                                                  mask_byte_offset) =
 807                                                        *(eeprom_mask_updated +
 808                                                          mask_byte_offset) &
 809                                                        (BIT(0) ^ 0xFF);
 810                                                break;
 811                                        case 10:
 812                                                *(eeprom_mask_updated +
 813                                                  mask_byte_offset) =
 814                                                        *(eeprom_mask_updated +
 815                                                          mask_byte_offset) &
 816                                                        (BIT(1) ^ 0xFF);
 817                                                break;
 818                                        case 12:
 819                                                *(eeprom_mask_updated +
 820                                                  mask_byte_offset) =
 821                                                        *(eeprom_mask_updated +
 822                                                          mask_byte_offset) &
 823                                                        (BIT(2) ^ 0xFF);
 824                                                break;
 825                                        case 14:
 826                                                *(eeprom_mask_updated +
 827                                                  mask_byte_offset) =
 828                                                        *(eeprom_mask_updated +
 829                                                          mask_byte_offset) &
 830                                                        (BIT(3) ^ 0xFF);
 831                                                break;
 832                                        default:
 833                                                break;
 834                                        }
 835                                }
 836                        }
 837                }
 838        }
 839
 840        kfree(eeprom_map);
 841
 842        return status;
 843}
 844
 845static enum halmac_ret_status
 846halmac_check_efuse_enough_88xx(struct halmac_adapter *halmac_adapter,
 847                               struct halmac_pg_efuse_info *pg_efuse_info,
 848                               u8 *eeprom_mask_updated)
 849{
 850        u8 pre_word_enb, word_enb;
 851        u8 pg_efuse_header, pg_efuse_header2;
 852        u8 pg_block;
 853        u16 i, j;
 854        u32 efuse_end;
 855        u32 tmp_eeprom_offset, pg_efuse_num = 0;
 856
 857        efuse_end = halmac_adapter->efuse_end;
 858
 859        for (i = 0; i < pg_efuse_info->efuse_map_size; i = i + 8) {
 860                tmp_eeprom_offset = i;
 861
 862                if ((tmp_eeprom_offset & 7) > 0) {
 863                        pre_word_enb =
 864                                (*(eeprom_mask_updated + (i >> 4)) & 0x0F);
 865                        word_enb = pre_word_enb ^ 0x0F;
 866                } else {
 867                        pre_word_enb = (*(eeprom_mask_updated + (i >> 4)) >> 4);
 868                        word_enb = pre_word_enb ^ 0x0F;
 869                }
 870
 871                pg_block = (u8)(tmp_eeprom_offset >> 3);
 872
 873                if (pre_word_enb > 0) {
 874                        if (tmp_eeprom_offset > 0x7f) {
 875                                pg_efuse_header =
 876                                        (((pg_block & 0x07) << 5) & 0xE0) |
 877                                        0x0F;
 878                                pg_efuse_header2 = (u8)(
 879                                        ((pg_block & 0x78) << 1) + word_enb);
 880                        } else {
 881                                pg_efuse_header =
 882                                        (u8)((pg_block << 4) + word_enb);
 883                        }
 884
 885                        if (tmp_eeprom_offset > 0x7f) {
 886                                pg_efuse_num++;
 887                                pg_efuse_num++;
 888                                efuse_end = efuse_end + 2;
 889                                for (j = 0; j < 4; j++) {
 890                                        if (((pre_word_enb >> j) & 0x1) > 0) {
 891                                                pg_efuse_num++;
 892                                                pg_efuse_num++;
 893                                                efuse_end = efuse_end + 2;
 894                                        }
 895                                }
 896                        } else {
 897                                pg_efuse_num++;
 898                                efuse_end = efuse_end + 1;
 899                                for (j = 0; j < 4; j++) {
 900                                        if (((pre_word_enb >> j) & 0x1) > 0) {
 901                                                pg_efuse_num++;
 902                                                pg_efuse_num++;
 903                                                efuse_end = efuse_end + 2;
 904                                        }
 905                                }
 906                        }
 907                }
 908        }
 909
 910        if (halmac_adapter->hw_config_info.efuse_size <=
 911            (pg_efuse_num + HALMAC_PROTECTED_EFUSE_SIZE_88XX +
 912             halmac_adapter->efuse_end))
 913                return HALMAC_RET_EFUSE_NOT_ENOUGH;
 914
 915        return HALMAC_RET_SUCCESS;
 916}
 917
 918static enum halmac_ret_status
 919halmac_program_efuse_88xx(struct halmac_adapter *halmac_adapter,
 920                          struct halmac_pg_efuse_info *pg_efuse_info,
 921                          u8 *eeprom_mask_updated)
 922{
 923        u8 pre_word_enb, word_enb;
 924        u8 pg_efuse_header, pg_efuse_header2;
 925        u8 pg_block;
 926        u16 i, j;
 927        u32 efuse_end;
 928        u32 tmp_eeprom_offset;
 929        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
 930
 931        efuse_end = halmac_adapter->efuse_end;
 932
 933        for (i = 0; i < pg_efuse_info->efuse_map_size; i = i + 8) {
 934                tmp_eeprom_offset = i;
 935
 936                if (((tmp_eeprom_offset >> 3) & 1) > 0) {
 937                        pre_word_enb =
 938                                (*(eeprom_mask_updated + (i >> 4)) & 0x0F);
 939                        word_enb = pre_word_enb ^ 0x0F;
 940                } else {
 941                        pre_word_enb = (*(eeprom_mask_updated + (i >> 4)) >> 4);
 942                        word_enb = pre_word_enb ^ 0x0F;
 943                }
 944
 945                pg_block = (u8)(tmp_eeprom_offset >> 3);
 946
 947                if (pre_word_enb <= 0)
 948                        continue;
 949
 950                if (tmp_eeprom_offset > 0x7f) {
 951                        pg_efuse_header =
 952                                (((pg_block & 0x07) << 5) & 0xE0) | 0x0F;
 953                        pg_efuse_header2 =
 954                                (u8)(((pg_block & 0x78) << 1) + word_enb);
 955                } else {
 956                        pg_efuse_header = (u8)((pg_block << 4) + word_enb);
 957                }
 958
 959                if (tmp_eeprom_offset > 0x7f) {
 960                        halmac_func_write_efuse_88xx(halmac_adapter, efuse_end,
 961                                                     pg_efuse_header);
 962                        status = halmac_func_write_efuse_88xx(halmac_adapter,
 963                                                              efuse_end + 1,
 964                                                              pg_efuse_header2);
 965                        efuse_end = efuse_end + 2;
 966                        for (j = 0; j < 4; j++) {
 967                                if (((pre_word_enb >> j) & 0x1) > 0) {
 968                                        halmac_func_write_efuse_88xx(
 969                                                halmac_adapter, efuse_end,
 970                                                *(pg_efuse_info->efuse_map +
 971                                                  tmp_eeprom_offset +
 972                                                  (j << 1)));
 973                                        status = halmac_func_write_efuse_88xx(
 974                                                halmac_adapter, efuse_end + 1,
 975                                                *(pg_efuse_info->efuse_map +
 976                                                  tmp_eeprom_offset + (j << 1) +
 977                                                  1));
 978                                        efuse_end = efuse_end + 2;
 979                                }
 980                        }
 981                } else {
 982                        status = halmac_func_write_efuse_88xx(
 983                                halmac_adapter, efuse_end, pg_efuse_header);
 984                        efuse_end = efuse_end + 1;
 985                        for (j = 0; j < 4; j++) {
 986                                if (((pre_word_enb >> j) & 0x1) > 0) {
 987                                        halmac_func_write_efuse_88xx(
 988                                                halmac_adapter, efuse_end,
 989                                                *(pg_efuse_info->efuse_map +
 990                                                  tmp_eeprom_offset +
 991                                                  (j << 1)));
 992                                        status = halmac_func_write_efuse_88xx(
 993                                                halmac_adapter, efuse_end + 1,
 994                                                *(pg_efuse_info->efuse_map +
 995                                                  tmp_eeprom_offset + (j << 1) +
 996                                                  1));
 997                                        efuse_end = efuse_end + 2;
 998                                }
 999                        }
1000                }
1001        }
1002
1003        return status;
1004}
1005
1006enum halmac_ret_status
1007halmac_dlfw_to_mem_88xx(struct halmac_adapter *halmac_adapter, u8 *ram_code,
1008                        u32 dest, u32 code_size)
1009{
1010        u8 *code_ptr;
1011        u8 first_part;
1012        u32 mem_offset;
1013        u32 pkt_size_tmp, send_pkt_size;
1014        void *driver_adapter = NULL;
1015        struct halmac_api *halmac_api;
1016
1017        driver_adapter = halmac_adapter->driver_adapter;
1018        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1019
1020        code_ptr = ram_code;
1021        mem_offset = 0;
1022        first_part = 1;
1023        pkt_size_tmp = code_size;
1024
1025        HALMAC_REG_WRITE_32(
1026                halmac_adapter, REG_DDMA_CH0CTRL,
1027                HALMAC_REG_READ_32(halmac_adapter, REG_DDMA_CH0CTRL) |
1028                        BIT_DDMACH0_RESET_CHKSUM_STS);
1029
1030        while (pkt_size_tmp != 0) {
1031                if (pkt_size_tmp >= halmac_adapter->max_download_size)
1032                        send_pkt_size = halmac_adapter->max_download_size;
1033                else
1034                        send_pkt_size = pkt_size_tmp;
1035
1036                if (halmac_send_fwpkt_88xx(
1037                            halmac_adapter, code_ptr + mem_offset,
1038                            send_pkt_size) != HALMAC_RET_SUCCESS) {
1039                        pr_err("halmac_send_fwpkt_88xx fail!!");
1040                        return HALMAC_RET_DLFW_FAIL;
1041                }
1042
1043                if (halmac_iddma_dlfw_88xx(
1044                            halmac_adapter,
1045                            HALMAC_OCPBASE_TXBUF_88XX +
1046                                    halmac_adapter->hw_config_info.txdesc_size,
1047                            dest + mem_offset, send_pkt_size,
1048                            first_part) != HALMAC_RET_SUCCESS) {
1049                        pr_err("halmac_iddma_dlfw_88xx fail!!");
1050                        return HALMAC_RET_DLFW_FAIL;
1051                }
1052
1053                first_part = 0;
1054                mem_offset += send_pkt_size;
1055                pkt_size_tmp -= send_pkt_size;
1056        }
1057
1058        if (halmac_check_fw_chksum_88xx(halmac_adapter, dest) !=
1059            HALMAC_RET_SUCCESS) {
1060                pr_err("halmac_check_fw_chksum_88xx fail!!");
1061                return HALMAC_RET_DLFW_FAIL;
1062        }
1063
1064        return HALMAC_RET_SUCCESS;
1065}
1066
1067enum halmac_ret_status
1068halmac_send_fwpkt_88xx(struct halmac_adapter *halmac_adapter, u8 *ram_code,
1069                       u32 code_size)
1070{
1071        if (halmac_download_rsvd_page_88xx(halmac_adapter, ram_code,
1072                                           code_size) != HALMAC_RET_SUCCESS) {
1073                pr_err("PLATFORM_SEND_RSVD_PAGE 0 error!!\n");
1074                return HALMAC_RET_DL_RSVD_PAGE_FAIL;
1075        }
1076
1077        return HALMAC_RET_SUCCESS;
1078}
1079
1080enum halmac_ret_status
1081halmac_iddma_dlfw_88xx(struct halmac_adapter *halmac_adapter, u32 source,
1082                       u32 dest, u32 length, u8 first)
1083{
1084        u32 counter;
1085        u32 ch0_control = (u32)(BIT_DDMACH0_CHKSUM_EN | BIT_DDMACH0_OWN);
1086        void *driver_adapter = NULL;
1087        struct halmac_api *halmac_api;
1088
1089        driver_adapter = halmac_adapter->driver_adapter;
1090        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1091
1092        counter = HALMC_DDMA_POLLING_COUNT;
1093        while (HALMAC_REG_READ_32(halmac_adapter, REG_DDMA_CH0CTRL) &
1094               BIT_DDMACH0_OWN) {
1095                counter--;
1096                if (counter == 0) {
1097                        pr_err("%s error-1!!\n", __func__);
1098                        return HALMAC_RET_DDMA_FAIL;
1099                }
1100        }
1101
1102        ch0_control |= (length & BIT_MASK_DDMACH0_DLEN);
1103        if (first == 0)
1104                ch0_control |= BIT_DDMACH0_CHKSUM_CONT;
1105
1106        HALMAC_REG_WRITE_32(halmac_adapter, REG_DDMA_CH0SA, source);
1107        HALMAC_REG_WRITE_32(halmac_adapter, REG_DDMA_CH0DA, dest);
1108        HALMAC_REG_WRITE_32(halmac_adapter, REG_DDMA_CH0CTRL, ch0_control);
1109
1110        counter = HALMC_DDMA_POLLING_COUNT;
1111        while (HALMAC_REG_READ_32(halmac_adapter, REG_DDMA_CH0CTRL) &
1112               BIT_DDMACH0_OWN) {
1113                counter--;
1114                if (counter == 0) {
1115                        pr_err("%s error-2!!\n", __func__);
1116                        return HALMAC_RET_DDMA_FAIL;
1117                }
1118        }
1119
1120        return HALMAC_RET_SUCCESS;
1121}
1122
1123enum halmac_ret_status
1124halmac_check_fw_chksum_88xx(struct halmac_adapter *halmac_adapter,
1125                            u32 memory_address)
1126{
1127        u8 mcu_fw_ctrl;
1128        void *driver_adapter = NULL;
1129        struct halmac_api *halmac_api;
1130        enum halmac_ret_status status;
1131
1132        driver_adapter = halmac_adapter->driver_adapter;
1133        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1134
1135        mcu_fw_ctrl = HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL);
1136
1137        if (HALMAC_REG_READ_32(halmac_adapter, REG_DDMA_CH0CTRL) &
1138            BIT_DDMACH0_CHKSUM_STS) {
1139                if (memory_address < HALMAC_OCPBASE_DMEM_88XX) {
1140                        mcu_fw_ctrl |= BIT_IMEM_DW_OK;
1141                        HALMAC_REG_WRITE_8(
1142                                halmac_adapter, REG_MCUFW_CTRL,
1143                                (u8)(mcu_fw_ctrl & ~(BIT_IMEM_CHKSUM_OK)));
1144                } else {
1145                        mcu_fw_ctrl |= BIT_DMEM_DW_OK;
1146                        HALMAC_REG_WRITE_8(
1147                                halmac_adapter, REG_MCUFW_CTRL,
1148                                (u8)(mcu_fw_ctrl & ~(BIT_DMEM_CHKSUM_OK)));
1149                }
1150
1151                pr_err("%s error!!\n", __func__);
1152
1153                status = HALMAC_RET_FW_CHECKSUM_FAIL;
1154        } else {
1155                if (memory_address < HALMAC_OCPBASE_DMEM_88XX) {
1156                        mcu_fw_ctrl |= BIT_IMEM_DW_OK;
1157                        HALMAC_REG_WRITE_8(
1158                                halmac_adapter, REG_MCUFW_CTRL,
1159                                (u8)(mcu_fw_ctrl | BIT_IMEM_CHKSUM_OK));
1160                } else {
1161                        mcu_fw_ctrl |= BIT_DMEM_DW_OK;
1162                        HALMAC_REG_WRITE_8(
1163                                halmac_adapter, REG_MCUFW_CTRL,
1164                                (u8)(mcu_fw_ctrl | BIT_DMEM_CHKSUM_OK));
1165                }
1166
1167                status = HALMAC_RET_SUCCESS;
1168        }
1169
1170        return status;
1171}
1172
1173enum halmac_ret_status
1174halmac_dlfw_end_flow_88xx(struct halmac_adapter *halmac_adapter)
1175{
1176        u8 value8;
1177        u32 counter;
1178        void *driver_adapter = halmac_adapter->driver_adapter;
1179        struct halmac_api *halmac_api =
1180                (struct halmac_api *)halmac_adapter->halmac_api;
1181
1182        HALMAC_REG_WRITE_32(halmac_adapter, REG_TXDMA_STATUS, BIT(2));
1183
1184        /* Check IMEM & DMEM checksum is OK or not */
1185        if ((HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL) & 0x50) == 0x50)
1186                HALMAC_REG_WRITE_16(halmac_adapter, REG_MCUFW_CTRL,
1187                                    (u16)(HALMAC_REG_READ_16(halmac_adapter,
1188                                                             REG_MCUFW_CTRL) |
1189                                          BIT_FW_DW_RDY));
1190        else
1191                return HALMAC_RET_DLFW_FAIL;
1192
1193        HALMAC_REG_WRITE_8(
1194                halmac_adapter, REG_MCUFW_CTRL,
1195                (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL) &
1196                     ~(BIT(0))));
1197
1198        value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RSV_CTRL + 1);
1199        value8 = (u8)(value8 | BIT(0));
1200        HALMAC_REG_WRITE_8(halmac_adapter, REG_RSV_CTRL + 1, value8);
1201
1202        value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN + 1);
1203        value8 = (u8)(value8 | BIT(2));
1204        HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN + 1,
1205                           value8); /* Release MCU reset */
1206        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1207                        "Download Finish, Reset CPU\n");
1208
1209        counter = 10000;
1210        while (HALMAC_REG_READ_16(halmac_adapter, REG_MCUFW_CTRL) != 0xC078) {
1211                if (counter == 0) {
1212                        pr_err("Check 0x80 = 0xC078 fail\n");
1213                        if ((HALMAC_REG_READ_32(halmac_adapter, REG_FW_DBG7) &
1214                             0xFFFFFF00) == 0xFAAAAA00)
1215                                pr_err("Key fail\n");
1216                        return HALMAC_RET_DLFW_FAIL;
1217                }
1218                counter--;
1219                usleep_range(50, 60);
1220        }
1221
1222        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1223                        "Check 0x80 = 0xC078 counter = %d\n", counter);
1224
1225        return HALMAC_RET_SUCCESS;
1226}
1227
1228enum halmac_ret_status
1229halmac_free_dl_fw_end_flow_88xx(struct halmac_adapter *halmac_adapter)
1230{
1231        u32 counter;
1232        struct halmac_api *halmac_api =
1233                (struct halmac_api *)halmac_adapter->halmac_api;
1234
1235        counter = 100;
1236        while (HALMAC_REG_READ_8(halmac_adapter, REG_HMETFR + 3) != 0) {
1237                counter--;
1238                if (counter == 0) {
1239                        pr_err("[ERR]0x1CF != 0\n");
1240                        return HALMAC_RET_DLFW_FAIL;
1241                }
1242                usleep_range(50, 60);
1243        }
1244
1245        HALMAC_REG_WRITE_8(halmac_adapter, REG_HMETFR + 3,
1246                           ID_INFORM_DLEMEM_RDY);
1247
1248        counter = 10000;
1249        while (HALMAC_REG_READ_8(halmac_adapter, REG_C2HEVT_3 + 3) !=
1250               ID_INFORM_DLEMEM_RDY) {
1251                counter--;
1252                if (counter == 0) {
1253                        pr_err("[ERR]0x1AF != 0x80\n");
1254                        return HALMAC_RET_DLFW_FAIL;
1255                }
1256                usleep_range(50, 60);
1257        }
1258
1259        HALMAC_REG_WRITE_8(halmac_adapter, REG_C2HEVT_3 + 3, 0);
1260
1261        return HALMAC_RET_SUCCESS;
1262}
1263
1264enum halmac_ret_status
1265halmac_pwr_seq_parser_88xx(struct halmac_adapter *halmac_adapter, u8 cut,
1266                           u8 fab, u8 intf,
1267                           struct halmac_wl_pwr_cfg_ **pp_pwr_seq_cfg)
1268{
1269        u32 seq_idx = 0;
1270        void *driver_adapter = NULL;
1271        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1272        struct halmac_wl_pwr_cfg_ *seq_cmd;
1273
1274        driver_adapter = halmac_adapter->driver_adapter;
1275
1276        do {
1277                seq_cmd = pp_pwr_seq_cfg[seq_idx];
1278
1279                if (!seq_cmd)
1280                        break;
1281
1282                status = halmac_pwr_sub_seq_parer_88xx(halmac_adapter, cut, fab,
1283                                                       intf, seq_cmd);
1284                if (status != HALMAC_RET_SUCCESS) {
1285                        pr_err("[Err]pwr sub seq parser fail, status = 0x%X!\n",
1286                               status);
1287                        return status;
1288                }
1289
1290                seq_idx++;
1291        } while (1);
1292
1293        return status;
1294}
1295
1296static enum halmac_ret_status
1297halmac_pwr_sub_seq_parer_do_cmd_88xx(struct halmac_adapter *halmac_adapter,
1298                                     struct halmac_wl_pwr_cfg_ *sub_seq_cmd,
1299                                     bool *reti)
1300{
1301        void *driver_adapter = NULL;
1302        struct halmac_api *halmac_api;
1303        u8 value, flag;
1304        u8 polling_bit;
1305        u32 polling_count;
1306        static u32 poll_to_static;
1307        u32 offset;
1308
1309        driver_adapter = halmac_adapter->driver_adapter;
1310        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1311        *reti = true;
1312
1313        switch (sub_seq_cmd->cmd) {
1314        case HALMAC_PWR_CMD_WRITE:
1315                if (sub_seq_cmd->base == HALMAC_PWR_BASEADDR_SDIO)
1316                        offset = sub_seq_cmd->offset | SDIO_LOCAL_OFFSET;
1317                else
1318                        offset = sub_seq_cmd->offset;
1319
1320                value = HALMAC_REG_READ_8(halmac_adapter, offset);
1321                value = (u8)(value & (u8)(~(sub_seq_cmd->msk)));
1322                value = (u8)(value |
1323                             (u8)(sub_seq_cmd->value & sub_seq_cmd->msk));
1324
1325                HALMAC_REG_WRITE_8(halmac_adapter, offset, value);
1326                break;
1327        case HALMAC_PWR_CMD_POLLING:
1328                polling_bit = 0;
1329                polling_count = HALMAC_POLLING_READY_TIMEOUT_COUNT;
1330                flag = 0;
1331
1332                if (sub_seq_cmd->base == HALMAC_PWR_BASEADDR_SDIO)
1333                        offset = sub_seq_cmd->offset | SDIO_LOCAL_OFFSET;
1334                else
1335                        offset = sub_seq_cmd->offset;
1336
1337                do {
1338                        polling_count--;
1339                        value = HALMAC_REG_READ_8(halmac_adapter, offset);
1340                        value = (u8)(value & sub_seq_cmd->msk);
1341
1342                        if (value == (sub_seq_cmd->value & sub_seq_cmd->msk)) {
1343                                polling_bit = 1;
1344                                continue;
1345                        }
1346
1347                        if (polling_count != 0) {
1348                                usleep_range(50, 60);
1349                                continue;
1350                        }
1351
1352                        if (halmac_adapter->halmac_interface ==
1353                                    HALMAC_INTERFACE_PCIE &&
1354                            flag == 0) {
1355                                /* For PCIE + USB package poll power bit
1356                                 * timeout issue
1357                                 */
1358                                poll_to_static++;
1359                                HALMAC_RT_TRACE(
1360                                        driver_adapter, HALMAC_MSG_PWR,
1361                                        DBG_WARNING,
1362                                        "[WARN]PCIE polling timeout : %d!!\n",
1363                                        poll_to_static);
1364                                HALMAC_REG_WRITE_8(
1365                                        halmac_adapter, REG_SYS_PW_CTRL,
1366                                        HALMAC_REG_READ_8(halmac_adapter,
1367                                                          REG_SYS_PW_CTRL) |
1368                                                BIT(3));
1369                                HALMAC_REG_WRITE_8(
1370                                        halmac_adapter, REG_SYS_PW_CTRL,
1371                                        HALMAC_REG_READ_8(halmac_adapter,
1372                                                          REG_SYS_PW_CTRL) &
1373                                                ~BIT(3));
1374                                polling_bit = 0;
1375                                polling_count =
1376                                        HALMAC_POLLING_READY_TIMEOUT_COUNT;
1377                                flag = 1;
1378                        } else {
1379                                pr_err("[ERR]Pwr cmd polling timeout!!\n");
1380                                pr_err("[ERR]Pwr cmd offset : %X!!\n",
1381                                       sub_seq_cmd->offset);
1382                                pr_err("[ERR]Pwr cmd value : %X!!\n",
1383                                       sub_seq_cmd->value);
1384                                pr_err("[ERR]Pwr cmd msk : %X!!\n",
1385                                       sub_seq_cmd->msk);
1386                                pr_err("[ERR]Read offset = %X value = %X!!\n",
1387                                       offset, value);
1388                                return HALMAC_RET_PWRSEQ_POLLING_FAIL;
1389                        }
1390                } while (!polling_bit);
1391                break;
1392        case HALMAC_PWR_CMD_DELAY:
1393                if (sub_seq_cmd->value == HALMAC_PWRSEQ_DELAY_US)
1394                        udelay(sub_seq_cmd->offset);
1395                else
1396                        usleep_range(1000 * sub_seq_cmd->offset,
1397                                     1000 * sub_seq_cmd->offset + 100);
1398
1399                break;
1400        case HALMAC_PWR_CMD_READ:
1401                break;
1402        case HALMAC_PWR_CMD_END:
1403                return HALMAC_RET_SUCCESS;
1404        default:
1405                return HALMAC_RET_PWRSEQ_CMD_INCORRECT;
1406        }
1407
1408        *reti = false;
1409
1410        return HALMAC_RET_SUCCESS;
1411}
1412
1413static enum halmac_ret_status
1414halmac_pwr_sub_seq_parer_88xx(struct halmac_adapter *halmac_adapter, u8 cut,
1415                              u8 fab, u8 intf,
1416                              struct halmac_wl_pwr_cfg_ *pwr_sub_seq_cfg)
1417{
1418        struct halmac_wl_pwr_cfg_ *sub_seq_cmd;
1419        bool reti;
1420        enum halmac_ret_status status;
1421
1422        for (sub_seq_cmd = pwr_sub_seq_cfg;; sub_seq_cmd++) {
1423                if ((sub_seq_cmd->interface_msk & intf) &&
1424                    (sub_seq_cmd->fab_msk & fab) &&
1425                    (sub_seq_cmd->cut_msk & cut)) {
1426                        status = halmac_pwr_sub_seq_parer_do_cmd_88xx(
1427                                halmac_adapter, sub_seq_cmd, &reti);
1428
1429                        if (reti)
1430                                return status;
1431                }
1432        }
1433
1434        return HALMAC_RET_SUCCESS;
1435}
1436
1437enum halmac_ret_status
1438halmac_get_h2c_buff_free_space_88xx(struct halmac_adapter *halmac_adapter)
1439{
1440        u32 hw_wptr, fw_rptr;
1441        struct halmac_api *halmac_api =
1442                (struct halmac_api *)halmac_adapter->halmac_api;
1443
1444        hw_wptr = HALMAC_REG_READ_32(halmac_adapter, REG_H2C_PKT_WRITEADDR) &
1445                  BIT_MASK_H2C_WR_ADDR;
1446        fw_rptr = HALMAC_REG_READ_32(halmac_adapter, REG_H2C_PKT_READADDR) &
1447                  BIT_MASK_H2C_READ_ADDR;
1448
1449        if (hw_wptr >= fw_rptr)
1450                halmac_adapter->h2c_buf_free_space =
1451                        halmac_adapter->h2c_buff_size - (hw_wptr - fw_rptr);
1452        else
1453                halmac_adapter->h2c_buf_free_space = fw_rptr - hw_wptr;
1454
1455        return HALMAC_RET_SUCCESS;
1456}
1457
1458enum halmac_ret_status
1459halmac_send_h2c_pkt_88xx(struct halmac_adapter *halmac_adapter, u8 *hal_h2c_cmd,
1460                         u32 size, bool ack)
1461{
1462        u32 counter = 100;
1463        void *driver_adapter = halmac_adapter->driver_adapter;
1464        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1465
1466        while (halmac_adapter->h2c_buf_free_space <=
1467               HALMAC_H2C_CMD_SIZE_UNIT_88XX) {
1468                halmac_get_h2c_buff_free_space_88xx(halmac_adapter);
1469                counter--;
1470                if (counter == 0) {
1471                        pr_err("h2c free space is not enough!!\n");
1472                        return HALMAC_RET_H2C_SPACE_FULL;
1473                }
1474        }
1475
1476        /* Send TxDesc + H2C_CMD */
1477        if (!PLATFORM_SEND_H2C_PKT(driver_adapter, hal_h2c_cmd, size)) {
1478                pr_err("Send H2C_CMD pkt error!!\n");
1479                return HALMAC_RET_SEND_H2C_FAIL;
1480        }
1481
1482        halmac_adapter->h2c_buf_free_space -= HALMAC_H2C_CMD_SIZE_UNIT_88XX;
1483
1484        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1485                        "H2C free space : %d\n",
1486                        halmac_adapter->h2c_buf_free_space);
1487
1488        return status;
1489}
1490
1491enum halmac_ret_status
1492halmac_download_rsvd_page_88xx(struct halmac_adapter *halmac_adapter,
1493                               u8 *hal_buf, u32 size)
1494{
1495        u8 restore[3];
1496        u8 value8;
1497        u32 counter;
1498        void *driver_adapter = NULL;
1499        struct halmac_api *halmac_api;
1500        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1501
1502        driver_adapter = halmac_adapter->driver_adapter;
1503        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1504
1505        if (size == 0) {
1506                HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1507                                "Rsvd page packet size is zero!!\n");
1508                return HALMAC_RET_ZERO_LEN_RSVD_PACKET;
1509        }
1510
1511        value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1);
1512        value8 = (u8)(value8 | BIT(7));
1513        HALMAC_REG_WRITE_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1, value8);
1514
1515        value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CR + 1);
1516        restore[0] = value8;
1517        value8 = (u8)(value8 | BIT(0));
1518        HALMAC_REG_WRITE_8(halmac_adapter, REG_CR + 1, value8);
1519
1520        value8 = HALMAC_REG_READ_8(halmac_adapter, REG_BCN_CTRL);
1521        restore[1] = value8;
1522        value8 = (u8)((value8 & ~(BIT(3))) | BIT(4));
1523        HALMAC_REG_WRITE_8(halmac_adapter, REG_BCN_CTRL, value8);
1524
1525        value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2);
1526        restore[2] = value8;
1527        value8 = (u8)(value8 & ~(BIT(6)));
1528        HALMAC_REG_WRITE_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2, value8);
1529
1530        if (!PLATFORM_SEND_RSVD_PAGE(driver_adapter, hal_buf, size)) {
1531                pr_err("PLATFORM_SEND_RSVD_PAGE 1 error!!\n");
1532                status = HALMAC_RET_DL_RSVD_PAGE_FAIL;
1533        }
1534
1535        /* Check Bcn_Valid_Bit */
1536        counter = 1000;
1537        while (!(HALMAC_REG_READ_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1) &
1538                 BIT(7))) {
1539                udelay(10);
1540                counter--;
1541                if (counter == 0) {
1542                        pr_err("Polling Bcn_Valid_Fail error!!\n");
1543                        status = HALMAC_RET_POLLING_BCN_VALID_FAIL;
1544                        break;
1545                }
1546        }
1547
1548        value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1);
1549        HALMAC_REG_WRITE_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1,
1550                           (value8 | BIT(7)));
1551
1552        HALMAC_REG_WRITE_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2, restore[2]);
1553        HALMAC_REG_WRITE_8(halmac_adapter, REG_BCN_CTRL, restore[1]);
1554        HALMAC_REG_WRITE_8(halmac_adapter, REG_CR + 1, restore[0]);
1555
1556        return status;
1557}
1558
1559enum halmac_ret_status
1560halmac_set_h2c_header_88xx(struct halmac_adapter *halmac_adapter,
1561                           u8 *hal_h2c_hdr, u16 *seq, bool ack)
1562{
1563        void *driver_adapter = halmac_adapter->driver_adapter;
1564
1565        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1566                        "%s!!\n", __func__);
1567
1568        H2C_CMD_HEADER_SET_CATEGORY(hal_h2c_hdr, 0x00);
1569        H2C_CMD_HEADER_SET_TOTAL_LEN(hal_h2c_hdr, 16);
1570
1571        spin_lock(&halmac_adapter->h2c_seq_lock);
1572        H2C_CMD_HEADER_SET_SEQ_NUM(hal_h2c_hdr, halmac_adapter->h2c_packet_seq);
1573        *seq = halmac_adapter->h2c_packet_seq;
1574        halmac_adapter->h2c_packet_seq++;
1575        spin_unlock(&halmac_adapter->h2c_seq_lock);
1576
1577        if (ack)
1578                H2C_CMD_HEADER_SET_ACK(hal_h2c_hdr, 1);
1579
1580        return HALMAC_RET_SUCCESS;
1581}
1582
1583enum halmac_ret_status halmac_set_fw_offload_h2c_header_88xx(
1584        struct halmac_adapter *halmac_adapter, u8 *hal_h2c_hdr,
1585        struct halmac_h2c_header_info *h2c_header_info, u16 *seq_num)
1586{
1587        void *driver_adapter = halmac_adapter->driver_adapter;
1588
1589        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1590                        "%s!!\n", __func__);
1591
1592        FW_OFFLOAD_H2C_SET_TOTAL_LEN(hal_h2c_hdr,
1593                                     8 + h2c_header_info->content_size);
1594        FW_OFFLOAD_H2C_SET_SUB_CMD_ID(hal_h2c_hdr, h2c_header_info->sub_cmd_id);
1595
1596        FW_OFFLOAD_H2C_SET_CATEGORY(hal_h2c_hdr, 0x01);
1597        FW_OFFLOAD_H2C_SET_CMD_ID(hal_h2c_hdr, 0xFF);
1598
1599        spin_lock(&halmac_adapter->h2c_seq_lock);
1600        FW_OFFLOAD_H2C_SET_SEQ_NUM(hal_h2c_hdr, halmac_adapter->h2c_packet_seq);
1601        *seq_num = halmac_adapter->h2c_packet_seq;
1602        halmac_adapter->h2c_packet_seq++;
1603        spin_unlock(&halmac_adapter->h2c_seq_lock);
1604
1605        if (h2c_header_info->ack)
1606                FW_OFFLOAD_H2C_SET_ACK(hal_h2c_hdr, 1);
1607
1608        return HALMAC_RET_SUCCESS;
1609}
1610
1611enum halmac_ret_status
1612halmac_send_h2c_set_pwr_mode_88xx(struct halmac_adapter *halmac_adapter,
1613                                  struct halmac_fwlps_option *hal_fw_lps_opt)
1614{
1615        u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX];
1616        u8 *h2c_header, *h2c_cmd;
1617        u16 seq = 0;
1618        void *driver_adapter = NULL;
1619        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1620
1621        driver_adapter = halmac_adapter->driver_adapter;
1622
1623        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1624                        "%s!!\n", __func__);
1625
1626        h2c_header = h2c_buff;
1627        h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
1628
1629        memset(h2c_buff, 0x00, HALMAC_H2C_CMD_SIZE_88XX);
1630
1631        SET_PWR_MODE_SET_CMD_ID(h2c_cmd, CMD_ID_SET_PWR_MODE);
1632        SET_PWR_MODE_SET_CLASS(h2c_cmd, CLASS_SET_PWR_MODE);
1633        SET_PWR_MODE_SET_MODE(h2c_cmd, hal_fw_lps_opt->mode);
1634        SET_PWR_MODE_SET_CLK_REQUEST(h2c_cmd, hal_fw_lps_opt->clk_request);
1635        SET_PWR_MODE_SET_RLBM(h2c_cmd, hal_fw_lps_opt->rlbm);
1636        SET_PWR_MODE_SET_SMART_PS(h2c_cmd, hal_fw_lps_opt->smart_ps);
1637        SET_PWR_MODE_SET_AWAKE_INTERVAL(h2c_cmd,
1638                                        hal_fw_lps_opt->awake_interval);
1639        SET_PWR_MODE_SET_B_ALL_QUEUE_UAPSD(h2c_cmd,
1640                                           hal_fw_lps_opt->all_queue_uapsd);
1641        SET_PWR_MODE_SET_PWR_STATE(h2c_cmd, hal_fw_lps_opt->pwr_state);
1642        SET_PWR_MODE_SET_ANT_AUTO_SWITCH(h2c_cmd,
1643                                         hal_fw_lps_opt->ant_auto_switch);
1644        SET_PWR_MODE_SET_PS_ALLOW_BT_HIGH_PRIORITY(
1645                h2c_cmd, hal_fw_lps_opt->ps_allow_bt_high_priority);
1646        SET_PWR_MODE_SET_PROTECT_BCN(h2c_cmd, hal_fw_lps_opt->protect_bcn);
1647        SET_PWR_MODE_SET_SILENCE_PERIOD(h2c_cmd,
1648                                        hal_fw_lps_opt->silence_period);
1649        SET_PWR_MODE_SET_FAST_BT_CONNECT(h2c_cmd,
1650                                         hal_fw_lps_opt->fast_bt_connect);
1651        SET_PWR_MODE_SET_TWO_ANTENNA_EN(h2c_cmd,
1652                                        hal_fw_lps_opt->two_antenna_en);
1653        SET_PWR_MODE_SET_ADOPT_USER_SETTING(h2c_cmd,
1654                                            hal_fw_lps_opt->adopt_user_setting);
1655        SET_PWR_MODE_SET_DRV_BCN_EARLY_SHIFT(
1656                h2c_cmd, hal_fw_lps_opt->drv_bcn_early_shift);
1657
1658        halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, &seq, true);
1659
1660        status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
1661                                          HALMAC_H2C_CMD_SIZE_88XX, true);
1662
1663        if (status != HALMAC_RET_SUCCESS) {
1664                pr_err("%s Fail = %x!!\n", __func__, status);
1665                return status;
1666        }
1667
1668        return HALMAC_RET_SUCCESS;
1669}
1670
1671enum halmac_ret_status
1672halmac_func_send_original_h2c_88xx(struct halmac_adapter *halmac_adapter,
1673                                   u8 *original_h2c, u16 *seq, u8 ack)
1674{
1675        u8 H2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
1676        u8 *h2c_header, *h2c_cmd;
1677        void *driver_adapter = NULL;
1678        struct halmac_api *halmac_api;
1679        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1680
1681        driver_adapter = halmac_adapter->driver_adapter;
1682        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1683
1684        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1685                        "halmac_send_original_h2c ==========>\n");
1686
1687        h2c_header = H2c_buff;
1688        h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
1689        memcpy(h2c_cmd, original_h2c, 8); /* Original H2C 8 byte */
1690
1691        halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, seq, ack);
1692
1693        status = halmac_send_h2c_pkt_88xx(halmac_adapter, H2c_buff,
1694                                          HALMAC_H2C_CMD_SIZE_88XX, ack);
1695
1696        if (status != HALMAC_RET_SUCCESS) {
1697                pr_err("halmac_send_original_h2c Fail = %x!!\n", status);
1698                return status;
1699        }
1700
1701        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1702                        "halmac_send_original_h2c <==========\n");
1703
1704        return HALMAC_RET_SUCCESS;
1705}
1706
1707enum halmac_ret_status
1708halmac_media_status_rpt_88xx(struct halmac_adapter *halmac_adapter, u8 op_mode,
1709                             u8 mac_id_ind, u8 mac_id, u8 mac_id_end)
1710{
1711        u8 H2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
1712        u8 *h2c_header, *h2c_cmd;
1713        u16 seq = 0;
1714        void *driver_adapter = NULL;
1715        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1716
1717        driver_adapter = halmac_adapter->driver_adapter;
1718
1719        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1720                        "halmac_send_h2c_set_pwr_mode_88xx!!\n");
1721
1722        h2c_header = H2c_buff;
1723        h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
1724
1725        memset(H2c_buff, 0x00, HALMAC_H2C_CMD_SIZE_88XX);
1726
1727        MEDIA_STATUS_RPT_SET_CMD_ID(h2c_cmd, CMD_ID_MEDIA_STATUS_RPT);
1728        MEDIA_STATUS_RPT_SET_CLASS(h2c_cmd, CLASS_MEDIA_STATUS_RPT);
1729        MEDIA_STATUS_RPT_SET_OP_MODE(h2c_cmd, op_mode);
1730        MEDIA_STATUS_RPT_SET_MACID_IN(h2c_cmd, mac_id_ind);
1731        MEDIA_STATUS_RPT_SET_MACID(h2c_cmd, mac_id);
1732        MEDIA_STATUS_RPT_SET_MACID_END(h2c_cmd, mac_id_end);
1733
1734        halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, &seq, true);
1735
1736        status = halmac_send_h2c_pkt_88xx(halmac_adapter, H2c_buff,
1737                                          HALMAC_H2C_CMD_SIZE_88XX, true);
1738
1739        if (status != HALMAC_RET_SUCCESS) {
1740                pr_err("%s Fail = %x!!\n", __func__, status);
1741                return status;
1742        }
1743
1744        return HALMAC_RET_SUCCESS;
1745}
1746
1747enum halmac_ret_status
1748halmac_send_h2c_update_packet_88xx(struct halmac_adapter *halmac_adapter,
1749                                   enum halmac_packet_id pkt_id, u8 *pkt,
1750                                   u32 pkt_size)
1751{
1752        u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
1753        u16 h2c_seq_mum = 0;
1754        void *driver_adapter = NULL;
1755        struct halmac_api *halmac_api;
1756        struct halmac_h2c_header_info h2c_header_info;
1757        enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
1758
1759        driver_adapter = halmac_adapter->driver_adapter;
1760        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1761
1762        HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
1763                            (u16)(halmac_adapter->txff_allocation
1764                                          .rsvd_h2c_extra_info_pg_bndy &
1765                                  BIT_MASK_BCN_HEAD_1_V1));
1766
1767        ret_status =
1768                halmac_download_rsvd_page_88xx(halmac_adapter, pkt, pkt_size);
1769
1770        if (ret_status != HALMAC_RET_SUCCESS) {
1771                pr_err("halmac_download_rsvd_page_88xx Fail = %x!!\n",
1772                       ret_status);
1773                HALMAC_REG_WRITE_16(
1774                        halmac_adapter, REG_FIFOPAGE_CTRL_2,
1775                        (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
1776                              BIT_MASK_BCN_HEAD_1_V1));
1777                return ret_status;
1778        }
1779
1780        HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
1781                            (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
1782                                  BIT_MASK_BCN_HEAD_1_V1));
1783
1784        UPDATE_PACKET_SET_SIZE(
1785                h2c_buff,
1786                pkt_size + halmac_adapter->hw_config_info.txdesc_size);
1787        UPDATE_PACKET_SET_PACKET_ID(h2c_buff, pkt_id);
1788        UPDATE_PACKET_SET_PACKET_LOC(
1789                h2c_buff,
1790                halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy -
1791                        halmac_adapter->txff_allocation.rsvd_pg_bndy);
1792
1793        h2c_header_info.sub_cmd_id = SUB_CMD_ID_UPDATE_PACKET;
1794        h2c_header_info.content_size = 8;
1795        h2c_header_info.ack = true;
1796        halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
1797                                              &h2c_header_info, &h2c_seq_mum);
1798        halmac_adapter->halmac_state.update_packet_set.seq_num = h2c_seq_mum;
1799
1800        ret_status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
1801                                              HALMAC_H2C_CMD_SIZE_88XX, true);
1802
1803        if (ret_status != HALMAC_RET_SUCCESS) {
1804                pr_err("%s Fail = %x!!\n", __func__, ret_status);
1805                return ret_status;
1806        }
1807
1808        return ret_status;
1809}
1810
1811enum halmac_ret_status
1812halmac_send_h2c_phy_parameter_88xx(struct halmac_adapter *halmac_adapter,
1813                                   struct halmac_phy_parameter_info *para_info,
1814                                   bool full_fifo)
1815{
1816        bool drv_trigger_send = false;
1817        u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
1818        u16 h2c_seq_mum = 0;
1819        u32 info_size = 0;
1820        void *driver_adapter = NULL;
1821        struct halmac_api *halmac_api;
1822        struct halmac_h2c_header_info h2c_header_info;
1823        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1824        struct halmac_config_para_info *config_para_info;
1825
1826        driver_adapter = halmac_adapter->driver_adapter;
1827        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1828        config_para_info = &halmac_adapter->config_para_info;
1829
1830        if (!config_para_info->cfg_para_buf) {
1831                if (full_fifo)
1832                        config_para_info->para_buf_size =
1833                                HALMAC_EXTRA_INFO_BUFF_SIZE_FULL_FIFO_88XX;
1834                else
1835                        config_para_info->para_buf_size =
1836                                HALMAC_EXTRA_INFO_BUFF_SIZE_88XX;
1837
1838                config_para_info->cfg_para_buf =
1839                        kzalloc(config_para_info->para_buf_size, GFP_KERNEL);
1840
1841                if (config_para_info->cfg_para_buf) {
1842                        memset(config_para_info->cfg_para_buf, 0x00,
1843                               config_para_info->para_buf_size);
1844                        config_para_info->full_fifo_mode = full_fifo;
1845                        config_para_info->para_buf_w =
1846                                config_para_info->cfg_para_buf;
1847                        config_para_info->para_num = 0;
1848                        config_para_info->avai_para_buf_size =
1849                                config_para_info->para_buf_size;
1850                        config_para_info->value_accumulation = 0;
1851                        config_para_info->offset_accumulation = 0;
1852                } else {
1853                        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C,
1854                                        DBG_DMESG,
1855                                        "Allocate cfg_para_buf fail!!\n");
1856                        return HALMAC_RET_MALLOC_FAIL;
1857                }
1858        }
1859
1860        if (halmac_transition_cfg_para_state_88xx(
1861                    halmac_adapter,
1862                    HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING) !=
1863            HALMAC_RET_SUCCESS)
1864                return HALMAC_RET_ERROR_STATE;
1865
1866        halmac_enqueue_para_buff_88xx(halmac_adapter, para_info,
1867                                      config_para_info->para_buf_w,
1868                                      &drv_trigger_send);
1869
1870        if (para_info->cmd_id != HALMAC_PARAMETER_CMD_END) {
1871                config_para_info->para_num++;
1872                config_para_info->para_buf_w += HALMAC_FW_OFFLOAD_CMD_SIZE_88XX;
1873                config_para_info->avai_para_buf_size =
1874                        config_para_info->avai_para_buf_size -
1875                        HALMAC_FW_OFFLOAD_CMD_SIZE_88XX;
1876        }
1877
1878        if ((config_para_info->avai_para_buf_size -
1879             halmac_adapter->hw_config_info.txdesc_size) >
1880                    HALMAC_FW_OFFLOAD_CMD_SIZE_88XX &&
1881            !drv_trigger_send)
1882                return HALMAC_RET_SUCCESS;
1883
1884        if (config_para_info->para_num == 0) {
1885                kfree(config_para_info->cfg_para_buf);
1886                config_para_info->cfg_para_buf = NULL;
1887                config_para_info->para_buf_w = NULL;
1888                HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_WARNING,
1889                                "no cfg parameter element!!\n");
1890
1891                if (halmac_transition_cfg_para_state_88xx(
1892                            halmac_adapter,
1893                            HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE) !=
1894                    HALMAC_RET_SUCCESS)
1895                        return HALMAC_RET_ERROR_STATE;
1896
1897                return HALMAC_RET_SUCCESS;
1898        }
1899
1900        if (halmac_transition_cfg_para_state_88xx(
1901                    halmac_adapter, HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT) !=
1902            HALMAC_RET_SUCCESS)
1903                return HALMAC_RET_ERROR_STATE;
1904
1905        halmac_adapter->halmac_state.cfg_para_state_set.process_status =
1906                HALMAC_CMD_PROCESS_SENDING;
1907
1908        if (config_para_info->full_fifo_mode)
1909                HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2, 0);
1910        else
1911                HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
1912                                    (u16)(halmac_adapter->txff_allocation
1913                                                  .rsvd_h2c_extra_info_pg_bndy &
1914                                          BIT_MASK_BCN_HEAD_1_V1));
1915
1916        info_size =
1917                config_para_info->para_num * HALMAC_FW_OFFLOAD_CMD_SIZE_88XX;
1918
1919        status = halmac_download_rsvd_page_88xx(
1920                halmac_adapter, (u8 *)config_para_info->cfg_para_buf,
1921                info_size);
1922
1923        if (status != HALMAC_RET_SUCCESS) {
1924                pr_err("halmac_download_rsvd_page_88xx Fail!!\n");
1925        } else {
1926                halmac_gen_cfg_para_h2c_88xx(halmac_adapter, h2c_buff);
1927
1928                h2c_header_info.sub_cmd_id = SUB_CMD_ID_CFG_PARAMETER;
1929                h2c_header_info.content_size = 4;
1930                h2c_header_info.ack = true;
1931                halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
1932                                                      &h2c_header_info,
1933                                                      &h2c_seq_mum);
1934
1935                halmac_adapter->halmac_state.cfg_para_state_set.seq_num =
1936                        h2c_seq_mum;
1937
1938                status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
1939                                                  HALMAC_H2C_CMD_SIZE_88XX,
1940                                                  true);
1941
1942                if (status != HALMAC_RET_SUCCESS)
1943                        pr_err("halmac_send_h2c_pkt_88xx Fail!!\n");
1944
1945                HALMAC_RT_TRACE(
1946                        driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1947                        "config parameter time = %d\n",
1948                        HALMAC_REG_READ_32(halmac_adapter, REG_FW_DBG6));
1949        }
1950
1951        kfree(config_para_info->cfg_para_buf);
1952        config_para_info->cfg_para_buf = NULL;
1953        config_para_info->para_buf_w = NULL;
1954
1955        /* Restore bcn head */
1956        HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
1957                            (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
1958                                  BIT_MASK_BCN_HEAD_1_V1));
1959
1960        if (halmac_transition_cfg_para_state_88xx(
1961                    halmac_adapter, HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE) !=
1962            HALMAC_RET_SUCCESS)
1963                return HALMAC_RET_ERROR_STATE;
1964
1965        if (!drv_trigger_send) {
1966                HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1967                                "Buffer full trigger sending H2C!!\n");
1968                return HALMAC_RET_PARA_SENDING;
1969        }
1970
1971        return status;
1972}
1973
1974static enum halmac_ret_status
1975halmac_enqueue_para_buff_88xx(struct halmac_adapter *halmac_adapter,
1976                              struct halmac_phy_parameter_info *para_info,
1977                              u8 *curr_buff_wptr, bool *end_cmd)
1978{
1979        struct halmac_config_para_info *config_para_info =
1980                &halmac_adapter->config_para_info;
1981
1982        *end_cmd = false;
1983
1984        PHY_PARAMETER_INFO_SET_LENGTH(curr_buff_wptr,
1985                                      HALMAC_FW_OFFLOAD_CMD_SIZE_88XX);
1986        PHY_PARAMETER_INFO_SET_IO_CMD(curr_buff_wptr, para_info->cmd_id);
1987
1988        switch (para_info->cmd_id) {
1989        case HALMAC_PARAMETER_CMD_BB_W8:
1990        case HALMAC_PARAMETER_CMD_BB_W16:
1991        case HALMAC_PARAMETER_CMD_BB_W32:
1992        case HALMAC_PARAMETER_CMD_MAC_W8:
1993        case HALMAC_PARAMETER_CMD_MAC_W16:
1994        case HALMAC_PARAMETER_CMD_MAC_W32:
1995                PHY_PARAMETER_INFO_SET_IO_ADDR(
1996                        curr_buff_wptr, para_info->content.MAC_REG_W.offset);
1997                PHY_PARAMETER_INFO_SET_DATA(curr_buff_wptr,
1998                                            para_info->content.MAC_REG_W.value);
1999                PHY_PARAMETER_INFO_SET_MASK(curr_buff_wptr,
2000                                            para_info->content.MAC_REG_W.msk);
2001                PHY_PARAMETER_INFO_SET_MSK_EN(
2002                        curr_buff_wptr, para_info->content.MAC_REG_W.msk_en);
2003                config_para_info->value_accumulation +=
2004                        para_info->content.MAC_REG_W.value;
2005                config_para_info->offset_accumulation +=
2006                        para_info->content.MAC_REG_W.offset;
2007                break;
2008        case HALMAC_PARAMETER_CMD_RF_W:
2009                /*In rf register, the address is only 1 byte*/
2010                PHY_PARAMETER_INFO_SET_RF_ADDR(
2011                        curr_buff_wptr, para_info->content.RF_REG_W.offset);
2012                PHY_PARAMETER_INFO_SET_RF_PATH(
2013                        curr_buff_wptr, para_info->content.RF_REG_W.rf_path);
2014                PHY_PARAMETER_INFO_SET_DATA(curr_buff_wptr,
2015                                            para_info->content.RF_REG_W.value);
2016                PHY_PARAMETER_INFO_SET_MASK(curr_buff_wptr,
2017                                            para_info->content.RF_REG_W.msk);
2018                PHY_PARAMETER_INFO_SET_MSK_EN(
2019                        curr_buff_wptr, para_info->content.RF_REG_W.msk_en);
2020                config_para_info->value_accumulation +=
2021                        para_info->content.RF_REG_W.value;
2022                config_para_info->offset_accumulation +=
2023                        (para_info->content.RF_REG_W.offset +
2024                         (para_info->content.RF_REG_W.rf_path << 8));
2025                break;
2026        case HALMAC_PARAMETER_CMD_DELAY_US:
2027        case HALMAC_PARAMETER_CMD_DELAY_MS:
2028                PHY_PARAMETER_INFO_SET_DELAY_VALUE(
2029                        curr_buff_wptr,
2030                        para_info->content.DELAY_TIME.delay_time);
2031                break;
2032        case HALMAC_PARAMETER_CMD_END:
2033                *end_cmd = true;
2034                break;
2035        default:
2036                pr_err(" halmac_send_h2c_phy_parameter_88xx illegal cmd_id!!\n");
2037                break;
2038        }
2039
2040        return HALMAC_RET_SUCCESS;
2041}
2042
2043static enum halmac_ret_status
2044halmac_gen_cfg_para_h2c_88xx(struct halmac_adapter *halmac_adapter,
2045                             u8 *h2c_buff)
2046{
2047        struct halmac_config_para_info *config_para_info =
2048                &halmac_adapter->config_para_info;
2049
2050        CFG_PARAMETER_SET_NUM(h2c_buff, config_para_info->para_num);
2051
2052        if (config_para_info->full_fifo_mode) {
2053                CFG_PARAMETER_SET_INIT_CASE(h2c_buff, 0x1);
2054                CFG_PARAMETER_SET_PHY_PARAMETER_LOC(h2c_buff, 0);
2055        } else {
2056                CFG_PARAMETER_SET_INIT_CASE(h2c_buff, 0x0);
2057                CFG_PARAMETER_SET_PHY_PARAMETER_LOC(
2058                        h2c_buff,
2059                        halmac_adapter->txff_allocation
2060                                        .rsvd_h2c_extra_info_pg_bndy -
2061                                halmac_adapter->txff_allocation.rsvd_pg_bndy);
2062        }
2063
2064        return HALMAC_RET_SUCCESS;
2065}
2066
2067enum halmac_ret_status
2068halmac_send_h2c_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
2069                                  enum halmac_data_type halmac_data_type)
2070{
2071        u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2072        u16 h2c_seq_mum = 0;
2073        void *driver_adapter = NULL;
2074        struct halmac_h2c_header_info h2c_header_info;
2075        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2076
2077        driver_adapter = halmac_adapter->driver_adapter;
2078
2079        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2080                        "%s!!\n", __func__);
2081
2082        RUN_DATAPACK_SET_DATAPACK_ID(h2c_buff, halmac_data_type);
2083
2084        h2c_header_info.sub_cmd_id = SUB_CMD_ID_RUN_DATAPACK;
2085        h2c_header_info.content_size = 4;
2086        h2c_header_info.ack = true;
2087        halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2088                                              &h2c_header_info, &h2c_seq_mum);
2089
2090        status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2091                                          HALMAC_H2C_CMD_SIZE_88XX, true);
2092
2093        if (status != HALMAC_RET_SUCCESS) {
2094                pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2095                return status;
2096        }
2097
2098        return HALMAC_RET_SUCCESS;
2099}
2100
2101enum halmac_ret_status
2102halmac_send_bt_coex_cmd_88xx(struct halmac_adapter *halmac_adapter, u8 *bt_buf,
2103                             u32 bt_size, u8 ack)
2104{
2105        u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2106        u16 h2c_seq_mum = 0;
2107        void *driver_adapter = NULL;
2108        struct halmac_h2c_header_info h2c_header_info;
2109        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2110
2111        driver_adapter = halmac_adapter->driver_adapter;
2112
2113        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2114                        "%s!!\n", __func__);
2115
2116        memcpy(h2c_buff + 8, bt_buf, bt_size);
2117
2118        h2c_header_info.sub_cmd_id = SUB_CMD_ID_BT_COEX;
2119        h2c_header_info.content_size = (u16)bt_size;
2120        h2c_header_info.ack = ack;
2121        halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2122                                              &h2c_header_info, &h2c_seq_mum);
2123
2124        status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2125                                          HALMAC_H2C_CMD_SIZE_88XX, ack);
2126
2127        if (status != HALMAC_RET_SUCCESS) {
2128                pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2129                return status;
2130        }
2131
2132        return HALMAC_RET_SUCCESS;
2133}
2134
2135enum halmac_ret_status
2136halmac_func_ctrl_ch_switch_88xx(struct halmac_adapter *halmac_adapter,
2137                                struct halmac_ch_switch_option *cs_option)
2138{
2139        u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2140        u16 h2c_seq_mum = 0;
2141        void *driver_adapter = NULL;
2142        struct halmac_api *halmac_api;
2143        struct halmac_h2c_header_info h2c_header_info;
2144        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2145        enum halmac_cmd_process_status *process_status =
2146                &halmac_adapter->halmac_state.scan_state_set.process_status;
2147
2148        driver_adapter = halmac_adapter->driver_adapter;
2149
2150        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2151                        "halmac_ctrl_ch_switch!!\n");
2152
2153        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2154
2155        if (halmac_transition_scan_state_88xx(
2156                    halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT) !=
2157            HALMAC_RET_SUCCESS)
2158                return HALMAC_RET_ERROR_STATE;
2159
2160        *process_status = HALMAC_CMD_PROCESS_SENDING;
2161
2162        if (cs_option->switch_en != 0) {
2163                HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
2164                                    (u16)(halmac_adapter->txff_allocation
2165                                                  .rsvd_h2c_extra_info_pg_bndy &
2166                                          BIT_MASK_BCN_HEAD_1_V1));
2167
2168                status = halmac_download_rsvd_page_88xx(
2169                        halmac_adapter, halmac_adapter->ch_sw_info.ch_info_buf,
2170                        halmac_adapter->ch_sw_info.total_size);
2171
2172                if (status != HALMAC_RET_SUCCESS) {
2173                        pr_err("halmac_download_rsvd_page_88xx Fail = %x!!\n",
2174                               status);
2175                        HALMAC_REG_WRITE_16(
2176                                halmac_adapter, REG_FIFOPAGE_CTRL_2,
2177                                (u16)(halmac_adapter->txff_allocation
2178                                              .rsvd_pg_bndy &
2179                                      BIT_MASK_BCN_HEAD_1_V1));
2180                        return status;
2181                }
2182
2183                HALMAC_REG_WRITE_16(
2184                        halmac_adapter, REG_FIFOPAGE_CTRL_2,
2185                        (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
2186                              BIT_MASK_BCN_HEAD_1_V1));
2187        }
2188
2189        CHANNEL_SWITCH_SET_SWITCH_START(h2c_buff, cs_option->switch_en);
2190        CHANNEL_SWITCH_SET_CHANNEL_NUM(h2c_buff,
2191                                       halmac_adapter->ch_sw_info.ch_num);
2192        CHANNEL_SWITCH_SET_CHANNEL_INFO_LOC(
2193                h2c_buff,
2194                halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy -
2195                        halmac_adapter->txff_allocation.rsvd_pg_bndy);
2196        CHANNEL_SWITCH_SET_DEST_CH_EN(h2c_buff, cs_option->dest_ch_en);
2197        CHANNEL_SWITCH_SET_DEST_CH(h2c_buff, cs_option->dest_ch);
2198        CHANNEL_SWITCH_SET_PRI_CH_IDX(h2c_buff, cs_option->dest_pri_ch_idx);
2199        CHANNEL_SWITCH_SET_ABSOLUTE_TIME(h2c_buff, cs_option->absolute_time_en);
2200        CHANNEL_SWITCH_SET_TSF_LOW(h2c_buff, cs_option->tsf_low);
2201        CHANNEL_SWITCH_SET_PERIODIC_OPTION(h2c_buff,
2202                                           cs_option->periodic_option);
2203        CHANNEL_SWITCH_SET_NORMAL_CYCLE(h2c_buff, cs_option->normal_cycle);
2204        CHANNEL_SWITCH_SET_NORMAL_PERIOD(h2c_buff, cs_option->normal_period);
2205        CHANNEL_SWITCH_SET_SLOW_PERIOD(h2c_buff, cs_option->phase_2_period);
2206        CHANNEL_SWITCH_SET_CHANNEL_INFO_SIZE(
2207                h2c_buff, halmac_adapter->ch_sw_info.total_size);
2208
2209        h2c_header_info.sub_cmd_id = SUB_CMD_ID_CHANNEL_SWITCH;
2210        h2c_header_info.content_size = 20;
2211        h2c_header_info.ack = true;
2212        halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2213                                              &h2c_header_info, &h2c_seq_mum);
2214        halmac_adapter->halmac_state.scan_state_set.seq_num = h2c_seq_mum;
2215
2216        status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2217                                          HALMAC_H2C_CMD_SIZE_88XX, true);
2218
2219        if (status != HALMAC_RET_SUCCESS)
2220                pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2221
2222        kfree(halmac_adapter->ch_sw_info.ch_info_buf);
2223        halmac_adapter->ch_sw_info.ch_info_buf = NULL;
2224        halmac_adapter->ch_sw_info.ch_info_buf_w = NULL;
2225        halmac_adapter->ch_sw_info.extra_info_en = 0;
2226        halmac_adapter->ch_sw_info.buf_size = 0;
2227        halmac_adapter->ch_sw_info.avai_buf_size = 0;
2228        halmac_adapter->ch_sw_info.total_size = 0;
2229        halmac_adapter->ch_sw_info.ch_num = 0;
2230
2231        if (halmac_transition_scan_state_88xx(halmac_adapter,
2232                                              HALMAC_SCAN_CMD_CONSTRUCT_IDLE) !=
2233            HALMAC_RET_SUCCESS)
2234                return HALMAC_RET_ERROR_STATE;
2235
2236        return status;
2237}
2238
2239enum halmac_ret_status
2240halmac_func_send_general_info_88xx(struct halmac_adapter *halmac_adapter,
2241                                   struct halmac_general_info *general_info)
2242{
2243        u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2244        u16 h2c_seq_mum = 0;
2245        void *driver_adapter = NULL;
2246        struct halmac_h2c_header_info h2c_header_info;
2247        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2248
2249        driver_adapter = halmac_adapter->driver_adapter;
2250
2251        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2252                        "halmac_send_general_info!!\n");
2253
2254        GENERAL_INFO_SET_REF_TYPE(h2c_buff, general_info->rfe_type);
2255        GENERAL_INFO_SET_RF_TYPE(h2c_buff, general_info->rf_type);
2256        GENERAL_INFO_SET_FW_TX_BOUNDARY(
2257                h2c_buff,
2258                halmac_adapter->txff_allocation.rsvd_fw_txbuff_pg_bndy -
2259                        halmac_adapter->txff_allocation.rsvd_pg_bndy);
2260
2261        h2c_header_info.sub_cmd_id = SUB_CMD_ID_GENERAL_INFO;
2262        h2c_header_info.content_size = 4;
2263        h2c_header_info.ack = false;
2264        halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2265                                              &h2c_header_info, &h2c_seq_mum);
2266
2267        status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2268                                          HALMAC_H2C_CMD_SIZE_88XX, true);
2269
2270        if (status != HALMAC_RET_SUCCESS)
2271                pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2272
2273        return status;
2274}
2275
2276enum halmac_ret_status halmac_send_h2c_update_bcn_parse_info_88xx(
2277        struct halmac_adapter *halmac_adapter,
2278        struct halmac_bcn_ie_info *bcn_ie_info)
2279{
2280        u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2281        u16 h2c_seq_mum = 0;
2282        void *driver_adapter = halmac_adapter->driver_adapter;
2283        struct halmac_h2c_header_info h2c_header_info;
2284        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2285
2286        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2287                        "%s!!\n", __func__);
2288
2289        UPDATE_BEACON_PARSING_INFO_SET_FUNC_EN(h2c_buff, bcn_ie_info->func_en);
2290        UPDATE_BEACON_PARSING_INFO_SET_SIZE_TH(h2c_buff, bcn_ie_info->size_th);
2291        UPDATE_BEACON_PARSING_INFO_SET_TIMEOUT(h2c_buff, bcn_ie_info->timeout);
2292
2293        UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_0(
2294                h2c_buff, (u32)(bcn_ie_info->ie_bmp[0]));
2295        UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_1(
2296                h2c_buff, (u32)(bcn_ie_info->ie_bmp[1]));
2297        UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_2(
2298                h2c_buff, (u32)(bcn_ie_info->ie_bmp[2]));
2299        UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_3(
2300                h2c_buff, (u32)(bcn_ie_info->ie_bmp[3]));
2301        UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_4(
2302                h2c_buff, (u32)(bcn_ie_info->ie_bmp[4]));
2303
2304        h2c_header_info.sub_cmd_id = SUB_CMD_ID_UPDATE_BEACON_PARSING_INFO;
2305        h2c_header_info.content_size = 24;
2306        h2c_header_info.ack = true;
2307        halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2308                                              &h2c_header_info, &h2c_seq_mum);
2309
2310        status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2311                                          HALMAC_H2C_CMD_SIZE_88XX, true);
2312
2313        if (status != HALMAC_RET_SUCCESS) {
2314                pr_err("halmac_send_h2c_pkt_88xx Fail =%x !!\n", status);
2315                return status;
2316        }
2317
2318        return status;
2319}
2320
2321enum halmac_ret_status
2322halmac_send_h2c_ps_tuning_para_88xx(struct halmac_adapter *halmac_adapter)
2323{
2324        u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2325        u8 *h2c_header, *h2c_cmd;
2326        u16 seq = 0;
2327        void *driver_adapter = NULL;
2328        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2329
2330        driver_adapter = halmac_adapter->driver_adapter;
2331
2332        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2333                        "%s!!\n", __func__);
2334
2335        h2c_header = h2c_buff;
2336        h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
2337
2338        halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, &seq, false);
2339
2340        status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2341                                          HALMAC_H2C_CMD_SIZE_88XX, false);
2342
2343        if (status != HALMAC_RET_SUCCESS) {
2344                pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2345                return status;
2346        }
2347
2348        return status;
2349}
2350
2351enum halmac_ret_status
2352halmac_parse_c2h_packet_88xx(struct halmac_adapter *halmac_adapter,
2353                             u8 *halmac_buf, u32 halmac_size)
2354{
2355        u8 c2h_cmd, c2h_sub_cmd_id;
2356        u8 *c2h_buf = halmac_buf + halmac_adapter->hw_config_info.rxdesc_size;
2357        u32 c2h_size = halmac_size - halmac_adapter->hw_config_info.rxdesc_size;
2358        void *driver_adapter = halmac_adapter->driver_adapter;
2359        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2360
2361        c2h_cmd = (u8)C2H_HDR_GET_CMD_ID(c2h_buf);
2362
2363        /* FW offload C2H cmd is 0xFF */
2364        if (c2h_cmd != 0xFF) {
2365                HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2366                                "C2H_PKT not for FwOffloadC2HFormat!!\n");
2367                return HALMAC_RET_C2H_NOT_HANDLED;
2368        }
2369
2370        /* Get C2H sub cmd ID */
2371        c2h_sub_cmd_id = (u8)C2H_HDR_GET_C2H_SUB_CMD_ID(c2h_buf);
2372
2373        switch (c2h_sub_cmd_id) {
2374        case C2H_SUB_CMD_ID_C2H_DBG:
2375                status = halmac_parse_c2h_debug_88xx(halmac_adapter, c2h_buf,
2376                                                     c2h_size);
2377                break;
2378        case C2H_SUB_CMD_ID_H2C_ACK_HDR:
2379                status = halmac_parse_h2c_ack_88xx(halmac_adapter, c2h_buf,
2380                                                   c2h_size);
2381                break;
2382        case C2H_SUB_CMD_ID_BT_COEX_INFO:
2383                status = HALMAC_RET_C2H_NOT_HANDLED;
2384                break;
2385        case C2H_SUB_CMD_ID_SCAN_STATUS_RPT:
2386                status = halmac_parse_scan_status_rpt_88xx(halmac_adapter,
2387                                                           c2h_buf, c2h_size);
2388                break;
2389        case C2H_SUB_CMD_ID_PSD_DATA:
2390                status = halmac_parse_psd_data_88xx(halmac_adapter, c2h_buf,
2391                                                    c2h_size);
2392                break;
2393
2394        case C2H_SUB_CMD_ID_EFUSE_DATA:
2395                status = halmac_parse_efuse_data_88xx(halmac_adapter, c2h_buf,
2396                                                      c2h_size);
2397                break;
2398        default:
2399                pr_err("c2h_sub_cmd_id switch case out of boundary!!\n");
2400                pr_err("[ERR]c2h pkt : %.8X %.8X!!\n", *(u32 *)c2h_buf,
2401                       *(u32 *)(c2h_buf + 4));
2402                status = HALMAC_RET_C2H_NOT_HANDLED;
2403                break;
2404        }
2405
2406        return status;
2407}
2408
2409static enum halmac_ret_status
2410halmac_parse_c2h_debug_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
2411                            u32 c2h_size)
2412{
2413        void *driver_adapter = NULL;
2414        u8 *c2h_buf_local = (u8 *)NULL;
2415        u32 c2h_size_local = 0;
2416        u8 dbg_content_length = 0;
2417        u8 dbg_seq_num = 0;
2418
2419        driver_adapter = halmac_adapter->driver_adapter;
2420        c2h_buf_local = c2h_buf;
2421        c2h_size_local = c2h_size;
2422
2423        dbg_content_length = (u8)C2H_HDR_GET_LEN((u8 *)c2h_buf_local);
2424
2425        if (dbg_content_length > C2H_DBG_CONTENT_MAX_LENGTH)
2426                return HALMAC_RET_SUCCESS;
2427
2428        *(c2h_buf_local + C2H_DBG_HEADER_LENGTH + dbg_content_length - 2) =
2429                '\n';
2430        dbg_seq_num = (u8)(*(c2h_buf_local + C2H_DBG_HEADER_LENGTH));
2431        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2432                        "[RTKFW, SEQ=%d]: %s", dbg_seq_num,
2433                        (char *)(c2h_buf_local + C2H_DBG_HEADER_LENGTH + 1));
2434
2435        return HALMAC_RET_SUCCESS;
2436}
2437
2438static enum halmac_ret_status
2439halmac_parse_scan_status_rpt_88xx(struct halmac_adapter *halmac_adapter,
2440                                  u8 *c2h_buf, u32 c2h_size)
2441{
2442        u8 h2c_return_code;
2443        void *driver_adapter = halmac_adapter->driver_adapter;
2444        enum halmac_cmd_process_status process_status;
2445
2446        h2c_return_code = (u8)SCAN_STATUS_RPT_GET_H2C_RETURN_CODE(c2h_buf);
2447        process_status = (enum halmac_h2c_return_code)h2c_return_code ==
2448                                         HALMAC_H2C_RETURN_SUCCESS ?
2449                                 HALMAC_CMD_PROCESS_DONE :
2450                                 HALMAC_CMD_PROCESS_ERROR;
2451
2452        PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_CHANNEL_SWITCH,
2453                                  process_status, NULL, 0);
2454
2455        halmac_adapter->halmac_state.scan_state_set.process_status =
2456                process_status;
2457
2458        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2459                        "[TRACE]scan status : %X\n", process_status);
2460
2461        return HALMAC_RET_SUCCESS;
2462}
2463
2464static enum halmac_ret_status
2465halmac_parse_psd_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
2466                           u32 c2h_size)
2467{
2468        u8 segment_id = 0, segment_size = 0, h2c_seq = 0;
2469        u16 total_size;
2470        void *driver_adapter = halmac_adapter->driver_adapter;
2471        enum halmac_cmd_process_status process_status;
2472        struct halmac_psd_state_set *psd_set =
2473                &halmac_adapter->halmac_state.psd_set;
2474
2475        h2c_seq = (u8)PSD_DATA_GET_H2C_SEQ(c2h_buf);
2476        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2477                        "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2478                        psd_set->seq_num, h2c_seq);
2479        if (h2c_seq != psd_set->seq_num) {
2480                pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2481                       psd_set->seq_num, h2c_seq);
2482                return HALMAC_RET_SUCCESS;
2483        }
2484
2485        if (psd_set->process_status != HALMAC_CMD_PROCESS_SENDING) {
2486                pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2487                return HALMAC_RET_SUCCESS;
2488        }
2489
2490        total_size = (u16)PSD_DATA_GET_TOTAL_SIZE(c2h_buf);
2491        segment_id = (u8)PSD_DATA_GET_SEGMENT_ID(c2h_buf);
2492        segment_size = (u8)PSD_DATA_GET_SEGMENT_SIZE(c2h_buf);
2493        psd_set->data_size = total_size;
2494
2495        if (!psd_set->data)
2496                psd_set->data = kzalloc(psd_set->data_size, GFP_KERNEL);
2497
2498        if (segment_id == 0)
2499                psd_set->segment_size = segment_size;
2500
2501        memcpy(psd_set->data + segment_id * psd_set->segment_size,
2502               c2h_buf + HALMAC_C2H_DATA_OFFSET_88XX, segment_size);
2503
2504        if (!PSD_DATA_GET_END_SEGMENT(c2h_buf))
2505                return HALMAC_RET_SUCCESS;
2506
2507        process_status = HALMAC_CMD_PROCESS_DONE;
2508        psd_set->process_status = process_status;
2509
2510        PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_PSD,
2511                                  process_status, psd_set->data,
2512                                  psd_set->data_size);
2513
2514        return HALMAC_RET_SUCCESS;
2515}
2516
2517static enum halmac_ret_status
2518halmac_parse_efuse_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
2519                             u32 c2h_size)
2520{
2521        u8 segment_id = 0, segment_size = 0, h2c_seq = 0;
2522        u8 *eeprom_map = NULL;
2523        u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
2524        u8 h2c_return_code = 0;
2525        void *driver_adapter = halmac_adapter->driver_adapter;
2526        enum halmac_cmd_process_status process_status;
2527
2528        h2c_seq = (u8)EFUSE_DATA_GET_H2C_SEQ(c2h_buf);
2529        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2530                        "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2531                        halmac_adapter->halmac_state.efuse_state_set.seq_num,
2532                        h2c_seq);
2533        if (h2c_seq != halmac_adapter->halmac_state.efuse_state_set.seq_num) {
2534                pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2535                       halmac_adapter->halmac_state.efuse_state_set.seq_num,
2536                       h2c_seq);
2537                return HALMAC_RET_SUCCESS;
2538        }
2539
2540        if (halmac_adapter->halmac_state.efuse_state_set.process_status !=
2541            HALMAC_CMD_PROCESS_SENDING) {
2542                pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2543                return HALMAC_RET_SUCCESS;
2544        }
2545
2546        segment_id = (u8)EFUSE_DATA_GET_SEGMENT_ID(c2h_buf);
2547        segment_size = (u8)EFUSE_DATA_GET_SEGMENT_SIZE(c2h_buf);
2548        if (segment_id == 0)
2549                halmac_adapter->efuse_segment_size = segment_size;
2550
2551        eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
2552        if (!eeprom_map) {
2553                /* out of memory */
2554                return HALMAC_RET_MALLOC_FAIL;
2555        }
2556        memset(eeprom_map, 0xFF, eeprom_size);
2557
2558        spin_lock(&halmac_adapter->efuse_lock);
2559        memcpy(halmac_adapter->hal_efuse_map +
2560                       segment_id * halmac_adapter->efuse_segment_size,
2561               c2h_buf + HALMAC_C2H_DATA_OFFSET_88XX, segment_size);
2562        spin_unlock(&halmac_adapter->efuse_lock);
2563
2564        if (!EFUSE_DATA_GET_END_SEGMENT(c2h_buf)) {
2565                kfree(eeprom_map);
2566                return HALMAC_RET_SUCCESS;
2567        }
2568
2569        h2c_return_code =
2570                halmac_adapter->halmac_state.efuse_state_set.fw_return_code;
2571
2572        if ((enum halmac_h2c_return_code)h2c_return_code ==
2573            HALMAC_H2C_RETURN_SUCCESS) {
2574                process_status = HALMAC_CMD_PROCESS_DONE;
2575                halmac_adapter->halmac_state.efuse_state_set.process_status =
2576                        process_status;
2577
2578                spin_lock(&halmac_adapter->efuse_lock);
2579                halmac_adapter->hal_efuse_map_valid = true;
2580                spin_unlock(&halmac_adapter->efuse_lock);
2581
2582                if (halmac_adapter->event_trigger.physical_efuse_map == 1) {
2583                        PLATFORM_EVENT_INDICATION(
2584                                driver_adapter,
2585                                HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
2586                                process_status, halmac_adapter->hal_efuse_map,
2587                                halmac_adapter->hw_config_info.efuse_size);
2588                        halmac_adapter->event_trigger.physical_efuse_map = 0;
2589                }
2590
2591                if (halmac_adapter->event_trigger.logical_efuse_map == 1) {
2592                        if (halmac_eeprom_parser_88xx(
2593                                    halmac_adapter,
2594                                    halmac_adapter->hal_efuse_map,
2595                                    eeprom_map) != HALMAC_RET_SUCCESS) {
2596                                kfree(eeprom_map);
2597                                return HALMAC_RET_EEPROM_PARSING_FAIL;
2598                        }
2599                        PLATFORM_EVENT_INDICATION(
2600                                driver_adapter,
2601                                HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
2602                                process_status, eeprom_map, eeprom_size);
2603                        halmac_adapter->event_trigger.logical_efuse_map = 0;
2604                }
2605        } else {
2606                process_status = HALMAC_CMD_PROCESS_ERROR;
2607                halmac_adapter->halmac_state.efuse_state_set.process_status =
2608                        process_status;
2609
2610                if (halmac_adapter->event_trigger.physical_efuse_map == 1) {
2611                        PLATFORM_EVENT_INDICATION(
2612                                driver_adapter,
2613                                HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
2614                                process_status,
2615                                &halmac_adapter->halmac_state.efuse_state_set
2616                                         .fw_return_code,
2617                                1);
2618                        halmac_adapter->event_trigger.physical_efuse_map = 0;
2619                }
2620
2621                if (halmac_adapter->event_trigger.logical_efuse_map == 1) {
2622                        if (halmac_eeprom_parser_88xx(
2623                                    halmac_adapter,
2624                                    halmac_adapter->hal_efuse_map,
2625                                    eeprom_map) != HALMAC_RET_SUCCESS) {
2626                                kfree(eeprom_map);
2627                                return HALMAC_RET_EEPROM_PARSING_FAIL;
2628                        }
2629                        PLATFORM_EVENT_INDICATION(
2630                                driver_adapter,
2631                                HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
2632                                process_status,
2633                                &halmac_adapter->halmac_state.efuse_state_set
2634                                         .fw_return_code,
2635                                1);
2636                        halmac_adapter->event_trigger.logical_efuse_map = 0;
2637                }
2638        }
2639
2640        kfree(eeprom_map);
2641
2642        return HALMAC_RET_SUCCESS;
2643}
2644
2645static enum halmac_ret_status
2646halmac_parse_h2c_ack_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
2647                          u32 c2h_size)
2648{
2649        u8 h2c_cmd_id, h2c_sub_cmd_id;
2650        u8 h2c_return_code;
2651        void *driver_adapter = halmac_adapter->driver_adapter;
2652        enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2653
2654        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2655                        "Ack for C2H!!\n");
2656
2657        h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2658        if ((enum halmac_h2c_return_code)h2c_return_code !=
2659            HALMAC_H2C_RETURN_SUCCESS)
2660                HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2661                                "C2H_PKT Status Error!! Status = %d\n",
2662                                h2c_return_code);
2663
2664        h2c_cmd_id = (u8)H2C_ACK_HDR_GET_H2C_CMD_ID(c2h_buf);
2665
2666        if (h2c_cmd_id != 0xFF) {
2667                pr_err("original h2c ack is not handled!!\n");
2668                status = HALMAC_RET_C2H_NOT_HANDLED;
2669        } else {
2670                h2c_sub_cmd_id = (u8)H2C_ACK_HDR_GET_H2C_SUB_CMD_ID(c2h_buf);
2671
2672                switch (h2c_sub_cmd_id) {
2673                case H2C_SUB_CMD_ID_DUMP_PHYSICAL_EFUSE_ACK:
2674                        status = halmac_parse_h2c_ack_phy_efuse_88xx(
2675                                halmac_adapter, c2h_buf, c2h_size);
2676                        break;
2677                case H2C_SUB_CMD_ID_CFG_PARAMETER_ACK:
2678                        status = halmac_parse_h2c_ack_cfg_para_88xx(
2679                                halmac_adapter, c2h_buf, c2h_size);
2680                        break;
2681                case H2C_SUB_CMD_ID_UPDATE_PACKET_ACK:
2682                        status = halmac_parse_h2c_ack_update_packet_88xx(
2683                                halmac_adapter, c2h_buf, c2h_size);
2684                        break;
2685                case H2C_SUB_CMD_ID_UPDATE_DATAPACK_ACK:
2686                        status = halmac_parse_h2c_ack_update_datapack_88xx(
2687                                halmac_adapter, c2h_buf, c2h_size);
2688                        break;
2689                case H2C_SUB_CMD_ID_RUN_DATAPACK_ACK:
2690                        status = halmac_parse_h2c_ack_run_datapack_88xx(
2691                                halmac_adapter, c2h_buf, c2h_size);
2692                        break;
2693                case H2C_SUB_CMD_ID_CHANNEL_SWITCH_ACK:
2694                        status = halmac_parse_h2c_ack_channel_switch_88xx(
2695                                halmac_adapter, c2h_buf, c2h_size);
2696                        break;
2697                case H2C_SUB_CMD_ID_IQK_ACK:
2698                        status = halmac_parse_h2c_ack_iqk_88xx(
2699                                halmac_adapter, c2h_buf, c2h_size);
2700                        break;
2701                case H2C_SUB_CMD_ID_POWER_TRACKING_ACK:
2702                        status = halmac_parse_h2c_ack_power_tracking_88xx(
2703                                halmac_adapter, c2h_buf, c2h_size);
2704                        break;
2705                case H2C_SUB_CMD_ID_PSD_ACK:
2706                        break;
2707                default:
2708                        pr_err("h2c_sub_cmd_id switch case out of boundary!!\n");
2709                        status = HALMAC_RET_C2H_NOT_HANDLED;
2710                        break;
2711                }
2712        }
2713
2714        return status;
2715}
2716
2717static enum halmac_ret_status
2718halmac_parse_h2c_ack_phy_efuse_88xx(struct halmac_adapter *halmac_adapter,
2719                                    u8 *c2h_buf, u32 c2h_size)
2720{
2721        u8 h2c_seq = 0;
2722        u8 h2c_return_code;
2723        void *driver_adapter = halmac_adapter->driver_adapter;
2724
2725        h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2726        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2727                        "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2728                        halmac_adapter->halmac_state.efuse_state_set.seq_num,
2729                        h2c_seq);
2730        if (h2c_seq != halmac_adapter->halmac_state.efuse_state_set.seq_num) {
2731                pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2732                       halmac_adapter->halmac_state.efuse_state_set.seq_num,
2733                       h2c_seq);
2734                return HALMAC_RET_SUCCESS;
2735        }
2736
2737        if (halmac_adapter->halmac_state.efuse_state_set.process_status !=
2738            HALMAC_CMD_PROCESS_SENDING) {
2739                pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2740                return HALMAC_RET_SUCCESS;
2741        }
2742
2743        h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2744        halmac_adapter->halmac_state.efuse_state_set.fw_return_code =
2745                h2c_return_code;
2746
2747        return HALMAC_RET_SUCCESS;
2748}
2749
2750static enum halmac_ret_status
2751halmac_parse_h2c_ack_cfg_para_88xx(struct halmac_adapter *halmac_adapter,
2752                                   u8 *c2h_buf, u32 c2h_size)
2753{
2754        u8 h2c_seq = 0;
2755        u8 h2c_return_code;
2756        u32 offset_accu = 0, value_accu = 0;
2757        void *driver_adapter = halmac_adapter->driver_adapter;
2758        enum halmac_cmd_process_status process_status =
2759                HALMAC_CMD_PROCESS_UNDEFINE;
2760
2761        h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2762        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2763                        "Seq num : h2c -> %d c2h -> %d\n",
2764                        halmac_adapter->halmac_state.cfg_para_state_set.seq_num,
2765                        h2c_seq);
2766        if (h2c_seq !=
2767            halmac_adapter->halmac_state.cfg_para_state_set.seq_num) {
2768                pr_err("Seq num mismatch : h2c -> %d c2h -> %d\n",
2769                       halmac_adapter->halmac_state.cfg_para_state_set.seq_num,
2770                       h2c_seq);
2771                return HALMAC_RET_SUCCESS;
2772        }
2773
2774        if (halmac_adapter->halmac_state.cfg_para_state_set.process_status !=
2775            HALMAC_CMD_PROCESS_SENDING) {
2776                pr_err("Not in HALMAC_CMD_PROCESS_SENDING\n");
2777                return HALMAC_RET_SUCCESS;
2778        }
2779
2780        h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2781        halmac_adapter->halmac_state.cfg_para_state_set.fw_return_code =
2782                h2c_return_code;
2783        offset_accu = CFG_PARAMETER_ACK_GET_OFFSET_ACCUMULATION(c2h_buf);
2784        value_accu = CFG_PARAMETER_ACK_GET_VALUE_ACCUMULATION(c2h_buf);
2785
2786        if ((offset_accu !=
2787             halmac_adapter->config_para_info.offset_accumulation) ||
2788            (value_accu !=
2789             halmac_adapter->config_para_info.value_accumulation)) {
2790                pr_err("[C2H]offset_accu : %x, value_accu : %x!!\n",
2791                       offset_accu, value_accu);
2792                pr_err("[Adapter]offset_accu : %x, value_accu : %x!!\n",
2793                       halmac_adapter->config_para_info.offset_accumulation,
2794                       halmac_adapter->config_para_info.value_accumulation);
2795                process_status = HALMAC_CMD_PROCESS_ERROR;
2796        }
2797
2798        if ((enum halmac_h2c_return_code)h2c_return_code ==
2799                    HALMAC_H2C_RETURN_SUCCESS &&
2800            process_status != HALMAC_CMD_PROCESS_ERROR) {
2801                process_status = HALMAC_CMD_PROCESS_DONE;
2802                halmac_adapter->halmac_state.cfg_para_state_set.process_status =
2803                        process_status;
2804                PLATFORM_EVENT_INDICATION(driver_adapter,
2805                                          HALMAC_FEATURE_CFG_PARA,
2806                                          process_status, NULL, 0);
2807        } else {
2808                process_status = HALMAC_CMD_PROCESS_ERROR;
2809                halmac_adapter->halmac_state.cfg_para_state_set.process_status =
2810                        process_status;
2811                PLATFORM_EVENT_INDICATION(
2812                        driver_adapter, HALMAC_FEATURE_CFG_PARA, process_status,
2813                        &halmac_adapter->halmac_state.cfg_para_state_set
2814                                 .fw_return_code,
2815                        1);
2816        }
2817
2818        return HALMAC_RET_SUCCESS;
2819}
2820
2821static enum halmac_ret_status
2822halmac_parse_h2c_ack_update_packet_88xx(struct halmac_adapter *halmac_adapter,
2823                                        u8 *c2h_buf, u32 c2h_size)
2824{
2825        u8 h2c_seq = 0;
2826        u8 h2c_return_code;
2827        void *driver_adapter = halmac_adapter->driver_adapter;
2828        enum halmac_cmd_process_status process_status;
2829
2830        h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2831        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2832                        "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2833                        halmac_adapter->halmac_state.update_packet_set.seq_num,
2834                        h2c_seq);
2835        if (h2c_seq != halmac_adapter->halmac_state.update_packet_set.seq_num) {
2836                pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2837                       halmac_adapter->halmac_state.update_packet_set.seq_num,
2838                       h2c_seq);
2839                return HALMAC_RET_SUCCESS;
2840        }
2841
2842        if (halmac_adapter->halmac_state.update_packet_set.process_status !=
2843            HALMAC_CMD_PROCESS_SENDING) {
2844                pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2845                return HALMAC_RET_SUCCESS;
2846        }
2847
2848        h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2849        halmac_adapter->halmac_state.update_packet_set.fw_return_code =
2850                h2c_return_code;
2851
2852        if ((enum halmac_h2c_return_code)h2c_return_code ==
2853            HALMAC_H2C_RETURN_SUCCESS) {
2854                process_status = HALMAC_CMD_PROCESS_DONE;
2855                halmac_adapter->halmac_state.update_packet_set.process_status =
2856                        process_status;
2857                PLATFORM_EVENT_INDICATION(driver_adapter,
2858                                          HALMAC_FEATURE_UPDATE_PACKET,
2859                                          process_status, NULL, 0);
2860        } else {
2861                process_status = HALMAC_CMD_PROCESS_ERROR;
2862                halmac_adapter->halmac_state.update_packet_set.process_status =
2863                        process_status;
2864                PLATFORM_EVENT_INDICATION(
2865                        driver_adapter, HALMAC_FEATURE_UPDATE_PACKET,
2866                        process_status,
2867                        &halmac_adapter->halmac_state.update_packet_set
2868                                 .fw_return_code,
2869                        1);
2870        }
2871
2872        return HALMAC_RET_SUCCESS;
2873}
2874
2875static enum halmac_ret_status
2876halmac_parse_h2c_ack_update_datapack_88xx(struct halmac_adapter *halmac_adapter,
2877                                          u8 *c2h_buf, u32 c2h_size)
2878{
2879        void *driver_adapter = halmac_adapter->driver_adapter;
2880        enum halmac_cmd_process_status process_status =
2881                HALMAC_CMD_PROCESS_UNDEFINE;
2882
2883        PLATFORM_EVENT_INDICATION(driver_adapter,
2884                                  HALMAC_FEATURE_UPDATE_DATAPACK,
2885                                  process_status, NULL, 0);
2886
2887        return HALMAC_RET_SUCCESS;
2888}
2889
2890static enum halmac_ret_status
2891halmac_parse_h2c_ack_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
2892                                       u8 *c2h_buf, u32 c2h_size)
2893{
2894        void *driver_adapter = halmac_adapter->driver_adapter;
2895        enum halmac_cmd_process_status process_status =
2896                HALMAC_CMD_PROCESS_UNDEFINE;
2897
2898        PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_RUN_DATAPACK,
2899                                  process_status, NULL, 0);
2900
2901        return HALMAC_RET_SUCCESS;
2902}
2903
2904static enum halmac_ret_status
2905halmac_parse_h2c_ack_channel_switch_88xx(struct halmac_adapter *halmac_adapter,
2906                                         u8 *c2h_buf, u32 c2h_size)
2907{
2908        u8 h2c_seq = 0;
2909        u8 h2c_return_code;
2910        void *driver_adapter = halmac_adapter->driver_adapter;
2911        enum halmac_cmd_process_status process_status;
2912
2913        h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2914        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2915                        "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2916                        halmac_adapter->halmac_state.scan_state_set.seq_num,
2917                        h2c_seq);
2918        if (h2c_seq != halmac_adapter->halmac_state.scan_state_set.seq_num) {
2919                pr_err("[ERR]Seq num misactch : h2c -> %d c2h -> %d\n",
2920                       halmac_adapter->halmac_state.scan_state_set.seq_num,
2921                       h2c_seq);
2922                return HALMAC_RET_SUCCESS;
2923        }
2924
2925        if (halmac_adapter->halmac_state.scan_state_set.process_status !=
2926            HALMAC_CMD_PROCESS_SENDING) {
2927                pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2928                return HALMAC_RET_SUCCESS;
2929        }
2930
2931        h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2932        halmac_adapter->halmac_state.scan_state_set.fw_return_code =
2933                h2c_return_code;
2934
2935        if ((enum halmac_h2c_return_code)h2c_return_code ==
2936            HALMAC_H2C_RETURN_SUCCESS) {
2937                process_status = HALMAC_CMD_PROCESS_RCVD;
2938                halmac_adapter->halmac_state.scan_state_set.process_status =
2939                        process_status;
2940                PLATFORM_EVENT_INDICATION(driver_adapter,
2941                                          HALMAC_FEATURE_CHANNEL_SWITCH,
2942                                          process_status, NULL, 0);
2943        } else {
2944                process_status = HALMAC_CMD_PROCESS_ERROR;
2945                halmac_adapter->halmac_state.scan_state_set.process_status =
2946                        process_status;
2947                PLATFORM_EVENT_INDICATION(
2948                        driver_adapter, HALMAC_FEATURE_CHANNEL_SWITCH,
2949                        process_status, &halmac_adapter->halmac_state
2950                                                 .scan_state_set.fw_return_code,
2951                        1);
2952        }
2953
2954        return HALMAC_RET_SUCCESS;
2955}
2956
2957static enum halmac_ret_status
2958halmac_parse_h2c_ack_iqk_88xx(struct halmac_adapter *halmac_adapter,
2959                              u8 *c2h_buf, u32 c2h_size)
2960{
2961        u8 h2c_seq = 0;
2962        u8 h2c_return_code;
2963        void *driver_adapter = halmac_adapter->driver_adapter;
2964        enum halmac_cmd_process_status process_status;
2965
2966        h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2967        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2968                        "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2969                        halmac_adapter->halmac_state.iqk_set.seq_num, h2c_seq);
2970        if (h2c_seq != halmac_adapter->halmac_state.iqk_set.seq_num) {
2971                pr_err("[ERR]Seq num misactch : h2c -> %d c2h -> %d\n",
2972                       halmac_adapter->halmac_state.iqk_set.seq_num, h2c_seq);
2973                return HALMAC_RET_SUCCESS;
2974        }
2975
2976        if (halmac_adapter->halmac_state.iqk_set.process_status !=
2977            HALMAC_CMD_PROCESS_SENDING) {
2978                pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2979                return HALMAC_RET_SUCCESS;
2980        }
2981
2982        h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2983        halmac_adapter->halmac_state.iqk_set.fw_return_code = h2c_return_code;
2984
2985        if ((enum halmac_h2c_return_code)h2c_return_code ==
2986            HALMAC_H2C_RETURN_SUCCESS) {
2987                process_status = HALMAC_CMD_PROCESS_DONE;
2988                halmac_adapter->halmac_state.iqk_set.process_status =
2989                        process_status;
2990                PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_IQK,
2991                                          process_status, NULL, 0);
2992        } else {
2993                process_status = HALMAC_CMD_PROCESS_ERROR;
2994                halmac_adapter->halmac_state.iqk_set.process_status =
2995                        process_status;
2996                PLATFORM_EVENT_INDICATION(
2997                        driver_adapter, HALMAC_FEATURE_IQK, process_status,
2998                        &halmac_adapter->halmac_state.iqk_set.fw_return_code,
2999                        1);
3000        }
3001
3002        return HALMAC_RET_SUCCESS;
3003}
3004
3005static enum halmac_ret_status
3006halmac_parse_h2c_ack_power_tracking_88xx(struct halmac_adapter *halmac_adapter,
3007                                         u8 *c2h_buf, u32 c2h_size)
3008{
3009        u8 h2c_seq = 0;
3010        u8 h2c_return_code;
3011        void *driver_adapter = halmac_adapter->driver_adapter;
3012        enum halmac_cmd_process_status process_status;
3013
3014        h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
3015        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3016                        "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
3017                        halmac_adapter->halmac_state.power_tracking_set.seq_num,
3018                        h2c_seq);
3019        if (h2c_seq !=
3020            halmac_adapter->halmac_state.power_tracking_set.seq_num) {
3021                pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
3022                       halmac_adapter->halmac_state.power_tracking_set.seq_num,
3023                       h2c_seq);
3024                return HALMAC_RET_SUCCESS;
3025        }
3026
3027        if (halmac_adapter->halmac_state.power_tracking_set.process_status !=
3028            HALMAC_CMD_PROCESS_SENDING) {
3029                pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
3030                return HALMAC_RET_SUCCESS;
3031        }
3032
3033        h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
3034        halmac_adapter->halmac_state.power_tracking_set.fw_return_code =
3035                h2c_return_code;
3036
3037        if ((enum halmac_h2c_return_code)h2c_return_code ==
3038            HALMAC_H2C_RETURN_SUCCESS) {
3039                process_status = HALMAC_CMD_PROCESS_DONE;
3040                halmac_adapter->halmac_state.power_tracking_set.process_status =
3041                        process_status;
3042                PLATFORM_EVENT_INDICATION(driver_adapter,
3043                                          HALMAC_FEATURE_POWER_TRACKING,
3044                                          process_status, NULL, 0);
3045        } else {
3046                process_status = HALMAC_CMD_PROCESS_ERROR;
3047                halmac_adapter->halmac_state.power_tracking_set.process_status =
3048                        process_status;
3049                PLATFORM_EVENT_INDICATION(
3050                        driver_adapter, HALMAC_FEATURE_POWER_TRACKING,
3051                        process_status,
3052                        &halmac_adapter->halmac_state.power_tracking_set
3053                                 .fw_return_code,
3054                        1);
3055        }
3056
3057        return HALMAC_RET_SUCCESS;
3058}
3059
3060enum halmac_ret_status
3061halmac_convert_to_sdio_bus_offset_88xx(struct halmac_adapter *halmac_adapter,
3062                                       u32 *halmac_offset)
3063{
3064        void *driver_adapter = NULL;
3065
3066        driver_adapter = halmac_adapter->driver_adapter;
3067
3068        switch ((*halmac_offset) & 0xFFFF0000) {
3069        case WLAN_IOREG_OFFSET:
3070                *halmac_offset = (HALMAC_SDIO_CMD_ADDR_MAC_REG << 13) |
3071                                 (*halmac_offset & HALMAC_WLAN_MAC_REG_MSK);
3072                break;
3073        case SDIO_LOCAL_OFFSET:
3074                *halmac_offset = (HALMAC_SDIO_CMD_ADDR_SDIO_REG << 13) |
3075                                 (*halmac_offset & HALMAC_SDIO_LOCAL_MSK);
3076                break;
3077        default:
3078                *halmac_offset = 0xFFFFFFFF;
3079                pr_err("Unknown base address!!\n");
3080                return HALMAC_RET_CONVERT_SDIO_OFFSET_FAIL;
3081        }
3082
3083        return HALMAC_RET_SUCCESS;
3084}
3085
3086enum halmac_ret_status
3087halmac_update_sdio_free_page_88xx(struct halmac_adapter *halmac_adapter)
3088{
3089        u32 free_page = 0, free_page2 = 0, free_page3 = 0;
3090        void *driver_adapter = NULL;
3091        struct halmac_api *halmac_api;
3092        struct halmac_sdio_free_space *sdio_free_space;
3093        u8 data[12] = {0};
3094
3095        driver_adapter = halmac_adapter->driver_adapter;
3096        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3097
3098        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3099                        "%s ==========>\n", __func__);
3100
3101        sdio_free_space = &halmac_adapter->sdio_free_space;
3102        /*need to use HALMAC_REG_READ_N, 20160316, Soar*/
3103        HALMAC_REG_SDIO_CMD53_READ_N(halmac_adapter, REG_SDIO_FREE_TXPG, 12,
3104                                     data);
3105        free_page =
3106                data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
3107        free_page2 =
3108                data[4] | (data[5] << 8) | (data[6] << 16) | (data[7] << 24);
3109        free_page3 =
3110                data[8] | (data[9] << 8) | (data[10] << 16) | (data[11] << 24);
3111
3112        sdio_free_space->high_queue_number =
3113                (u16)BIT_GET_HIQ_FREEPG_V1(free_page);
3114        sdio_free_space->normal_queue_number =
3115                (u16)BIT_GET_MID_FREEPG_V1(free_page);
3116        sdio_free_space->low_queue_number =
3117                (u16)BIT_GET_LOW_FREEPG_V1(free_page2);
3118        sdio_free_space->public_queue_number =
3119                (u16)BIT_GET_PUB_FREEPG_V1(free_page2);
3120        sdio_free_space->extra_queue_number =
3121                (u16)BIT_GET_EXQ_FREEPG_V1(free_page3);
3122        sdio_free_space->ac_oqt_number = (u8)((free_page3 >> 16) & 0xFF);
3123        sdio_free_space->non_ac_oqt_number = (u8)((free_page3 >> 24) & 0xFF);
3124
3125        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3126                        "%s <==========\n", __func__);
3127
3128        return HALMAC_RET_SUCCESS;
3129}
3130
3131enum halmac_ret_status
3132halmac_update_oqt_free_space_88xx(struct halmac_adapter *halmac_adapter)
3133{
3134        void *driver_adapter = NULL;
3135        struct halmac_api *halmac_api;
3136        struct halmac_sdio_free_space *sdio_free_space;
3137
3138        driver_adapter = halmac_adapter->driver_adapter;
3139        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3140
3141        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3142                        "%s ==========>\n", __func__);
3143
3144        sdio_free_space = &halmac_adapter->sdio_free_space;
3145
3146        sdio_free_space->ac_oqt_number = HALMAC_REG_READ_8(
3147                halmac_adapter, REG_SDIO_OQT_FREE_TXPG_V1 + 2);
3148        sdio_free_space->ac_empty =
3149                HALMAC_REG_READ_8(halmac_adapter, REG_TXPKT_EMPTY);
3150
3151        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3152                        "%s <==========\n", __func__);
3153
3154        return HALMAC_RET_SUCCESS;
3155}
3156
3157enum halmac_efuse_cmd_construct_state
3158halmac_query_efuse_curr_state_88xx(struct halmac_adapter *halmac_adapter)
3159{
3160        return halmac_adapter->halmac_state.efuse_state_set
3161                .efuse_cmd_construct_state;
3162}
3163
3164enum halmac_ret_status halmac_transition_efuse_state_88xx(
3165        struct halmac_adapter *halmac_adapter,
3166        enum halmac_efuse_cmd_construct_state dest_state)
3167{
3168        struct halmac_efuse_state_set *efuse_state =
3169                &halmac_adapter->halmac_state.efuse_state_set;
3170
3171        if (efuse_state->efuse_cmd_construct_state !=
3172                    HALMAC_EFUSE_CMD_CONSTRUCT_IDLE &&
3173            efuse_state->efuse_cmd_construct_state !=
3174                    HALMAC_EFUSE_CMD_CONSTRUCT_BUSY &&
3175            efuse_state->efuse_cmd_construct_state !=
3176                    HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT)
3177                return HALMAC_RET_ERROR_STATE;
3178
3179        if (efuse_state->efuse_cmd_construct_state == dest_state)
3180                return HALMAC_RET_ERROR_STATE;
3181
3182        if (dest_state == HALMAC_EFUSE_CMD_CONSTRUCT_BUSY) {
3183                if (efuse_state->efuse_cmd_construct_state ==
3184                    HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT)
3185                        return HALMAC_RET_ERROR_STATE;
3186        } else if (dest_state == HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT) {
3187                if (efuse_state->efuse_cmd_construct_state ==
3188                    HALMAC_EFUSE_CMD_CONSTRUCT_IDLE)
3189                        return HALMAC_RET_ERROR_STATE;
3190        }
3191
3192        efuse_state->efuse_cmd_construct_state = dest_state;
3193
3194        return HALMAC_RET_SUCCESS;
3195}
3196
3197enum halmac_cfg_para_cmd_construct_state
3198halmac_query_cfg_para_curr_state_88xx(struct halmac_adapter *halmac_adapter)
3199{
3200        return halmac_adapter->halmac_state.cfg_para_state_set
3201                .cfg_para_cmd_construct_state;
3202}
3203
3204enum halmac_ret_status halmac_transition_cfg_para_state_88xx(
3205        struct halmac_adapter *halmac_adapter,
3206        enum halmac_cfg_para_cmd_construct_state dest_state)
3207{
3208        struct halmac_cfg_para_state_set *cfg_para =
3209                &halmac_adapter->halmac_state.cfg_para_state_set;
3210
3211        if (cfg_para->cfg_para_cmd_construct_state !=
3212                    HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE &&
3213            cfg_para->cfg_para_cmd_construct_state !=
3214                    HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING &&
3215            cfg_para->cfg_para_cmd_construct_state !=
3216                    HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT)
3217                return HALMAC_RET_ERROR_STATE;
3218
3219        if (dest_state == HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE) {
3220                if (cfg_para->cfg_para_cmd_construct_state ==
3221                    HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING)
3222                        return HALMAC_RET_ERROR_STATE;
3223        } else if (dest_state == HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING) {
3224                if (cfg_para->cfg_para_cmd_construct_state ==
3225                    HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT)
3226                        return HALMAC_RET_ERROR_STATE;
3227        } else if (dest_state == HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT) {
3228                if (cfg_para->cfg_para_cmd_construct_state ==
3229                            HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE ||
3230                    cfg_para->cfg_para_cmd_construct_state ==
3231                            HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT)
3232                        return HALMAC_RET_ERROR_STATE;
3233        }
3234
3235        cfg_para->cfg_para_cmd_construct_state = dest_state;
3236
3237        return HALMAC_RET_SUCCESS;
3238}
3239
3240enum halmac_scan_cmd_construct_state
3241halmac_query_scan_curr_state_88xx(struct halmac_adapter *halmac_adapter)
3242{
3243        return halmac_adapter->halmac_state.scan_state_set
3244                .scan_cmd_construct_state;
3245}
3246
3247enum halmac_ret_status halmac_transition_scan_state_88xx(
3248        struct halmac_adapter *halmac_adapter,
3249        enum halmac_scan_cmd_construct_state dest_state)
3250{
3251        struct halmac_scan_state_set *scan =
3252                &halmac_adapter->halmac_state.scan_state_set;
3253
3254        if (scan->scan_cmd_construct_state > HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT)
3255                return HALMAC_RET_ERROR_STATE;
3256
3257        if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_IDLE) {
3258                if (scan->scan_cmd_construct_state ==
3259                            HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED ||
3260                    scan->scan_cmd_construct_state ==
3261                            HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING)
3262                        return HALMAC_RET_ERROR_STATE;
3263        } else if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED) {
3264                if (scan->scan_cmd_construct_state ==
3265                    HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT)
3266                        return HALMAC_RET_ERROR_STATE;
3267        } else if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
3268                if (scan->scan_cmd_construct_state ==
3269                            HALMAC_SCAN_CMD_CONSTRUCT_IDLE ||
3270                    scan->scan_cmd_construct_state ==
3271                            HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT)
3272                        return HALMAC_RET_ERROR_STATE;
3273        } else if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT) {
3274                if (scan->scan_cmd_construct_state !=
3275                            HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING &&
3276                    scan->scan_cmd_construct_state !=
3277                            HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED)
3278                        return HALMAC_RET_ERROR_STATE;
3279        }
3280
3281        scan->scan_cmd_construct_state = dest_state;
3282
3283        return HALMAC_RET_SUCCESS;
3284}
3285
3286enum halmac_ret_status halmac_query_cfg_para_status_88xx(
3287        struct halmac_adapter *halmac_adapter,
3288        enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3289{
3290        struct halmac_cfg_para_state_set *cfg_para_state_set =
3291                &halmac_adapter->halmac_state.cfg_para_state_set;
3292
3293        *process_status = cfg_para_state_set->process_status;
3294
3295        return HALMAC_RET_SUCCESS;
3296}
3297
3298enum halmac_ret_status halmac_query_dump_physical_efuse_status_88xx(
3299        struct halmac_adapter *halmac_adapter,
3300        enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3301{
3302        void *driver_adapter = NULL;
3303        struct halmac_efuse_state_set *efuse_state_set =
3304                &halmac_adapter->halmac_state.efuse_state_set;
3305
3306        driver_adapter = halmac_adapter->driver_adapter;
3307
3308        *process_status = efuse_state_set->process_status;
3309
3310        if (!data)
3311                return HALMAC_RET_NULL_POINTER;
3312
3313        if (!size)
3314                return HALMAC_RET_NULL_POINTER;
3315
3316        if (*process_status == HALMAC_CMD_PROCESS_DONE) {
3317                if (*size < halmac_adapter->hw_config_info.efuse_size) {
3318                        *size = halmac_adapter->hw_config_info.efuse_size;
3319                        return HALMAC_RET_BUFFER_TOO_SMALL;
3320                }
3321
3322                *size = halmac_adapter->hw_config_info.efuse_size;
3323                memcpy(data, halmac_adapter->hal_efuse_map, *size);
3324        }
3325
3326        return HALMAC_RET_SUCCESS;
3327}
3328
3329enum halmac_ret_status halmac_query_dump_logical_efuse_status_88xx(
3330        struct halmac_adapter *halmac_adapter,
3331        enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3332{
3333        u8 *eeprom_map = NULL;
3334        u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
3335        void *driver_adapter = NULL;
3336        struct halmac_efuse_state_set *efuse_state_set =
3337                &halmac_adapter->halmac_state.efuse_state_set;
3338
3339        driver_adapter = halmac_adapter->driver_adapter;
3340
3341        *process_status = efuse_state_set->process_status;
3342
3343        if (!data)
3344                return HALMAC_RET_NULL_POINTER;
3345
3346        if (!size)
3347                return HALMAC_RET_NULL_POINTER;
3348
3349        if (*process_status == HALMAC_CMD_PROCESS_DONE) {
3350                if (*size < eeprom_size) {
3351                        *size = eeprom_size;
3352                        return HALMAC_RET_BUFFER_TOO_SMALL;
3353                }
3354
3355                *size = eeprom_size;
3356
3357                eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
3358                if (!eeprom_map) {
3359                        /* out of memory */
3360                        return HALMAC_RET_MALLOC_FAIL;
3361                }
3362                memset(eeprom_map, 0xFF, eeprom_size);
3363
3364                if (halmac_eeprom_parser_88xx(
3365                            halmac_adapter, halmac_adapter->hal_efuse_map,
3366                            eeprom_map) != HALMAC_RET_SUCCESS) {
3367                        kfree(eeprom_map);
3368                        return HALMAC_RET_EEPROM_PARSING_FAIL;
3369                }
3370
3371                memcpy(data, eeprom_map, *size);
3372
3373                kfree(eeprom_map);
3374        }
3375
3376        return HALMAC_RET_SUCCESS;
3377}
3378
3379enum halmac_ret_status halmac_query_channel_switch_status_88xx(
3380        struct halmac_adapter *halmac_adapter,
3381        enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3382{
3383        struct halmac_scan_state_set *scan_state_set =
3384                &halmac_adapter->halmac_state.scan_state_set;
3385
3386        *process_status = scan_state_set->process_status;
3387
3388        return HALMAC_RET_SUCCESS;
3389}
3390
3391enum halmac_ret_status halmac_query_update_packet_status_88xx(
3392        struct halmac_adapter *halmac_adapter,
3393        enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3394{
3395        struct halmac_update_packet_state_set *update_packet_set =
3396                &halmac_adapter->halmac_state.update_packet_set;
3397
3398        *process_status = update_packet_set->process_status;
3399
3400        return HALMAC_RET_SUCCESS;
3401}
3402
3403enum halmac_ret_status
3404halmac_query_iqk_status_88xx(struct halmac_adapter *halmac_adapter,
3405                             enum halmac_cmd_process_status *process_status,
3406                             u8 *data, u32 *size)
3407{
3408        struct halmac_iqk_state_set *iqk_set =
3409                &halmac_adapter->halmac_state.iqk_set;
3410
3411        *process_status = iqk_set->process_status;
3412
3413        return HALMAC_RET_SUCCESS;
3414}
3415
3416enum halmac_ret_status halmac_query_power_tracking_status_88xx(
3417        struct halmac_adapter *halmac_adapter,
3418        enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3419{
3420        struct halmac_power_tracking_state_set *power_tracking_state_set =
3421                &halmac_adapter->halmac_state.power_tracking_set;
3422        ;
3423
3424        *process_status = power_tracking_state_set->process_status;
3425
3426        return HALMAC_RET_SUCCESS;
3427}
3428
3429enum halmac_ret_status
3430halmac_query_psd_status_88xx(struct halmac_adapter *halmac_adapter,
3431                             enum halmac_cmd_process_status *process_status,
3432                             u8 *data, u32 *size)
3433{
3434        void *driver_adapter = NULL;
3435        struct halmac_psd_state_set *psd_set =
3436                &halmac_adapter->halmac_state.psd_set;
3437
3438        driver_adapter = halmac_adapter->driver_adapter;
3439
3440        *process_status = psd_set->process_status;
3441
3442        if (!data)
3443                return HALMAC_RET_NULL_POINTER;
3444
3445        if (!size)
3446                return HALMAC_RET_NULL_POINTER;
3447
3448        if (*process_status == HALMAC_CMD_PROCESS_DONE) {
3449                if (*size < psd_set->data_size) {
3450                        *size = psd_set->data_size;
3451                        return HALMAC_RET_BUFFER_TOO_SMALL;
3452                }
3453
3454                *size = psd_set->data_size;
3455                memcpy(data, psd_set->data, *size);
3456        }
3457
3458        return HALMAC_RET_SUCCESS;
3459}
3460
3461enum halmac_ret_status
3462halmac_verify_io_88xx(struct halmac_adapter *halmac_adapter)
3463{
3464        u8 value8, wvalue8;
3465        u32 value32, value32_2, wvalue32;
3466        u32 halmac_offset;
3467        void *driver_adapter = NULL;
3468        enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
3469
3470        driver_adapter = halmac_adapter->driver_adapter;
3471
3472        if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
3473                halmac_offset = REG_PAGE5_DUMMY;
3474                if ((halmac_offset & 0xFFFF0000) == 0)
3475                        halmac_offset |= WLAN_IOREG_OFFSET;
3476
3477                ret_status = halmac_convert_to_sdio_bus_offset_88xx(
3478                        halmac_adapter, &halmac_offset);
3479
3480                /* Verify CMD52 R/W */
3481                wvalue8 = 0xab;
3482                PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset,
3483                                          wvalue8);
3484
3485                value8 =
3486                        PLATFORM_SDIO_CMD52_READ(driver_adapter, halmac_offset);
3487
3488                if (value8 != wvalue8) {
3489                        pr_err("cmd52 r/w fail write = %X read = %X\n", wvalue8,
3490                               value8);
3491                        ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3492                } else {
3493                        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3494                                        DBG_DMESG, "cmd52 r/w ok\n");
3495                }
3496
3497                /* Verify CMD53 R/W */
3498                PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset, 0xaa);
3499                PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 1,
3500                                          0xbb);
3501                PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 2,
3502                                          0xcc);
3503                PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 3,
3504                                          0xdd);
3505
3506                value32 = PLATFORM_SDIO_CMD53_READ_32(driver_adapter,
3507                                                      halmac_offset);
3508
3509                if (value32 != 0xddccbbaa) {
3510                        pr_err("cmd53 r fail : read = %X\n", value32);
3511                        ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3512                } else {
3513                        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3514                                        DBG_DMESG, "cmd53 r ok\n");
3515                }
3516
3517                wvalue32 = 0x11223344;
3518                PLATFORM_SDIO_CMD53_WRITE_32(driver_adapter, halmac_offset,
3519                                             wvalue32);
3520
3521                value32 = PLATFORM_SDIO_CMD53_READ_32(driver_adapter,
3522                                                      halmac_offset);
3523
3524                if (value32 != wvalue32) {
3525                        pr_err("cmd53 w fail\n");
3526                        ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3527                } else {
3528                        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3529                                        DBG_DMESG, "cmd53 w ok\n");
3530                }
3531
3532                value32 = PLATFORM_SDIO_CMD53_READ_32(
3533                        driver_adapter,
3534                        halmac_offset + 2); /* value32 should be 0x33441122 */
3535
3536                wvalue32 = 0x11225566;
3537                PLATFORM_SDIO_CMD53_WRITE_32(driver_adapter, halmac_offset,
3538                                             wvalue32);
3539
3540                value32_2 = PLATFORM_SDIO_CMD53_READ_32(
3541                        driver_adapter,
3542                        halmac_offset + 2); /* value32 should be 0x55661122 */
3543                if (value32_2 == value32) {
3544                        pr_err("cmd52 is used for HAL_SDIO_CMD53_READ_32\n");
3545                        ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3546                } else {
3547                        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3548                                        DBG_DMESG, "cmd53 is correctly used\n");
3549                }
3550        } else {
3551                wvalue32 = 0x77665511;
3552                PLATFORM_REG_WRITE_32(driver_adapter, REG_PAGE5_DUMMY,
3553                                      wvalue32);
3554
3555                value32 = PLATFORM_REG_READ_32(driver_adapter, REG_PAGE5_DUMMY);
3556                if (value32 != wvalue32) {
3557                        pr_err("reg rw\n");
3558                        ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3559                } else {
3560                        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3561                                        DBG_DMESG, "reg rw ok\n");
3562                }
3563        }
3564
3565        return ret_status;
3566}
3567
3568enum halmac_ret_status
3569halmac_verify_send_rsvd_page_88xx(struct halmac_adapter *halmac_adapter)
3570{
3571        u8 *rsvd_buf = NULL;
3572        u8 *rsvd_page = NULL;
3573        u32 i;
3574        u32 h2c_pkt_verify_size = 64, h2c_pkt_verify_payload = 0xab;
3575        void *driver_adapter = NULL;
3576        enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
3577
3578        driver_adapter = halmac_adapter->driver_adapter;
3579
3580        rsvd_buf = kzalloc(h2c_pkt_verify_size, GFP_KERNEL);
3581
3582        if (!rsvd_buf) {
3583                /*pr_err("[ERR]rsvd buffer malloc fail!!\n");*/
3584                return HALMAC_RET_MALLOC_FAIL;
3585        }
3586
3587        memset(rsvd_buf, (u8)h2c_pkt_verify_payload, h2c_pkt_verify_size);
3588
3589        ret_status = halmac_download_rsvd_page_88xx(halmac_adapter, rsvd_buf,
3590                                                    h2c_pkt_verify_size);
3591
3592        if (ret_status != HALMAC_RET_SUCCESS) {
3593                kfree(rsvd_buf);
3594                return ret_status;
3595        }
3596
3597        rsvd_page = kzalloc(h2c_pkt_verify_size +
3598                                    halmac_adapter->hw_config_info.txdesc_size,
3599                            GFP_KERNEL);
3600
3601        if (!rsvd_page) {
3602                pr_err("[ERR]rsvd page malloc fail!!\n");
3603                kfree(rsvd_buf);
3604                return HALMAC_RET_MALLOC_FAIL;
3605        }
3606
3607        ret_status = halmac_dump_fifo_88xx(
3608                halmac_adapter, HAL_FIFO_SEL_RSVD_PAGE, 0,
3609                h2c_pkt_verify_size +
3610                        halmac_adapter->hw_config_info.txdesc_size,
3611                rsvd_page);
3612
3613        if (ret_status != HALMAC_RET_SUCCESS) {
3614                kfree(rsvd_buf);
3615                kfree(rsvd_page);
3616                return ret_status;
3617        }
3618
3619        for (i = 0; i < h2c_pkt_verify_size; i++) {
3620                if (*(rsvd_buf + i) !=
3621                    *(rsvd_page +
3622                      (i + halmac_adapter->hw_config_info.txdesc_size))) {
3623                        pr_err("[ERR]Compare RSVD page Fail\n");
3624                        ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3625                }
3626        }
3627
3628        kfree(rsvd_buf);
3629        kfree(rsvd_page);
3630
3631        return ret_status;
3632}
3633
3634void halmac_power_save_cb_88xx(void *cb_data)
3635{
3636        void *driver_adapter = NULL;
3637        struct halmac_adapter *halmac_adapter = (struct halmac_adapter *)NULL;
3638
3639        halmac_adapter = (struct halmac_adapter *)cb_data;
3640        driver_adapter = halmac_adapter->driver_adapter;
3641
3642        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
3643                        "%s\n", __func__);
3644}
3645
3646enum halmac_ret_status
3647halmac_buffer_read_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
3648                        u32 size, enum hal_fifo_sel halmac_fifo_sel,
3649                        u8 *fifo_map)
3650{
3651        u32 start_page, value_read;
3652        u32 i, counter = 0, residue;
3653        struct halmac_api *halmac_api;
3654
3655        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3656
3657        if (halmac_fifo_sel == HAL_FIFO_SEL_RSVD_PAGE)
3658                offset = offset +
3659                         (halmac_adapter->txff_allocation.rsvd_pg_bndy << 7);
3660
3661        start_page = offset >> 12;
3662        residue = offset & (4096 - 1);
3663
3664        if (halmac_fifo_sel == HAL_FIFO_SEL_TX ||
3665            halmac_fifo_sel == HAL_FIFO_SEL_RSVD_PAGE)
3666                start_page += 0x780;
3667        else if (halmac_fifo_sel == HAL_FIFO_SEL_RX)
3668                start_page += 0x700;
3669        else if (halmac_fifo_sel == HAL_FIFO_SEL_REPORT)
3670                start_page += 0x660;
3671        else if (halmac_fifo_sel == HAL_FIFO_SEL_LLT)
3672                start_page += 0x650;
3673        else
3674                return HALMAC_RET_NOT_SUPPORT;
3675
3676        value_read = HALMAC_REG_READ_16(halmac_adapter, REG_PKTBUF_DBG_CTRL);
3677
3678        do {
3679                HALMAC_REG_WRITE_16(halmac_adapter, REG_PKTBUF_DBG_CTRL,
3680                                    (u16)(start_page | (value_read & 0xF000)));
3681
3682                for (i = 0x8000 + residue; i <= 0x8FFF; i += 4) {
3683                        *(u32 *)(fifo_map + counter) =
3684                                HALMAC_REG_READ_32(halmac_adapter, i);
3685                        *(u32 *)(fifo_map + counter) =
3686                                le32_to_cpu(*(__le32 *)(fifo_map + counter));
3687                        counter += 4;
3688                        if (size == counter)
3689                                goto HALMAC_BUF_READ_OK;
3690                }
3691
3692                residue = 0;
3693                start_page++;
3694        } while (1);
3695
3696HALMAC_BUF_READ_OK:
3697        HALMAC_REG_WRITE_16(halmac_adapter, REG_PKTBUF_DBG_CTRL,
3698                            (u16)value_read);
3699
3700        return HALMAC_RET_SUCCESS;
3701}
3702
3703void halmac_restore_mac_register_88xx(struct halmac_adapter *halmac_adapter,
3704                                      struct halmac_restore_info *restore_info,
3705                                      u32 restore_num)
3706{
3707        u8 value_length;
3708        u32 i;
3709        u32 mac_register;
3710        u32 mac_value;
3711        struct halmac_api *halmac_api;
3712        struct halmac_restore_info *curr_restore_info = restore_info;
3713
3714        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3715
3716        for (i = 0; i < restore_num; i++) {
3717                mac_register = curr_restore_info->mac_register;
3718                mac_value = curr_restore_info->value;
3719                value_length = curr_restore_info->length;
3720
3721                if (value_length == 1)
3722                        HALMAC_REG_WRITE_8(halmac_adapter, mac_register,
3723                                           (u8)mac_value);
3724                else if (value_length == 2)
3725                        HALMAC_REG_WRITE_16(halmac_adapter, mac_register,
3726                                            (u16)mac_value);
3727                else if (value_length == 4)
3728                        HALMAC_REG_WRITE_32(halmac_adapter, mac_register,
3729                                            mac_value);
3730
3731                curr_restore_info++;
3732        }
3733}
3734
3735void halmac_api_record_id_88xx(struct halmac_adapter *halmac_adapter,
3736                               enum halmac_api_id api_id)
3737{
3738}
3739
3740enum halmac_ret_status
3741halmac_set_usb_mode_88xx(struct halmac_adapter *halmac_adapter,
3742                         enum halmac_usb_mode usb_mode)
3743{
3744        u32 usb_temp;
3745        void *driver_adapter = NULL;
3746        struct halmac_api *halmac_api;
3747        enum halmac_usb_mode current_usb_mode;
3748
3749        driver_adapter = halmac_adapter->driver_adapter;
3750        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3751
3752        current_usb_mode =
3753                HALMAC_REG_READ_8(halmac_adapter, REG_SYS_CFG2 + 3) == 0x20 ?
3754                        HALMAC_USB_MODE_U3 :
3755                        HALMAC_USB_MODE_U2;
3756
3757        /*check if HW supports usb2_usb3 swtich*/
3758        usb_temp = HALMAC_REG_READ_32(halmac_adapter, REG_PAD_CTRL2);
3759        if (!BIT_GET_USB23_SW_MODE_V1(usb_temp) &&
3760            !(usb_temp & BIT_USB3_USB2_TRANSITION)) {
3761                pr_err("HALMAC_HW_USB_MODE usb mode HW unsupport\n");
3762                return HALMAC_RET_USB2_3_SWITCH_UNSUPPORT;
3763        }
3764
3765        if (usb_mode == current_usb_mode) {
3766                pr_err("HALMAC_HW_USB_MODE usb mode unchange\n");
3767                return HALMAC_RET_USB_MODE_UNCHANGE;
3768        }
3769
3770        usb_temp &= ~(BIT_USB23_SW_MODE_V1(0x3));
3771
3772        if (usb_mode == HALMAC_USB_MODE_U2) {
3773                /* usb3 to usb2 */
3774                HALMAC_REG_WRITE_32(
3775                        halmac_adapter, REG_PAD_CTRL2,
3776                        usb_temp | BIT_USB23_SW_MODE_V1(HALMAC_USB_MODE_U2) |
3777                                BIT_RSM_EN_V1);
3778        } else {
3779                /* usb2 to usb3 */
3780                HALMAC_REG_WRITE_32(
3781                        halmac_adapter, REG_PAD_CTRL2,
3782                        usb_temp | BIT_USB23_SW_MODE_V1(HALMAC_USB_MODE_U3) |
3783                                BIT_RSM_EN_V1);
3784        }
3785
3786        HALMAC_REG_WRITE_8(halmac_adapter, REG_PAD_CTRL2 + 1,
3787                           4); /* set counter down timer 4x64 ms */
3788        HALMAC_REG_WRITE_16(
3789                halmac_adapter, REG_SYS_PW_CTRL,
3790                HALMAC_REG_READ_16(halmac_adapter, REG_SYS_PW_CTRL) |
3791                        BIT_APFM_OFFMAC);
3792        usleep_range(1000, 1100);
3793        HALMAC_REG_WRITE_32(halmac_adapter, REG_PAD_CTRL2,
3794                            HALMAC_REG_READ_32(halmac_adapter, REG_PAD_CTRL2) |
3795                                    BIT_NO_PDN_CHIPOFF_V1);
3796
3797        return HALMAC_RET_SUCCESS;
3798}
3799
3800void halmac_enable_bb_rf_88xx(struct halmac_adapter *halmac_adapter, u8 enable)
3801{
3802        u8 value8;
3803        u32 value32;
3804        struct halmac_api *halmac_api;
3805
3806        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3807
3808        if (enable == 1) {
3809                value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN);
3810                value8 = value8 | BIT(0) | BIT(1);
3811                HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN, value8);
3812
3813                value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RF_CTRL);
3814                value8 = value8 | BIT(0) | BIT(1) | BIT(2);
3815                HALMAC_REG_WRITE_8(halmac_adapter, REG_RF_CTRL, value8);
3816
3817                value32 = HALMAC_REG_READ_32(halmac_adapter, REG_WLRF1);
3818                value32 = value32 | BIT(24) | BIT(25) | BIT(26);
3819                HALMAC_REG_WRITE_32(halmac_adapter, REG_WLRF1, value32);
3820        } else {
3821                value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN);
3822                value8 = value8 & (~(BIT(0) | BIT(1)));
3823                HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN, value8);
3824
3825                value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RF_CTRL);
3826                value8 = value8 & (~(BIT(0) | BIT(1) | BIT(2)));
3827                HALMAC_REG_WRITE_8(halmac_adapter, REG_RF_CTRL, value8);
3828
3829                value32 = HALMAC_REG_READ_32(halmac_adapter, REG_WLRF1);
3830                value32 = value32 & (~(BIT(24) | BIT(25) | BIT(26)));
3831                HALMAC_REG_WRITE_32(halmac_adapter, REG_WLRF1, value32);
3832        }
3833}
3834
3835void halmac_config_sdio_tx_page_threshold_88xx(
3836        struct halmac_adapter *halmac_adapter,
3837        struct halmac_tx_page_threshold_info *threshold_info)
3838{
3839        struct halmac_api *halmac_api;
3840
3841        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3842
3843        switch (threshold_info->dma_queue_sel) {
3844        case HALMAC_MAP2_HQ:
3845                HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT1,
3846                                    threshold_info->threshold);
3847                break;
3848        case HALMAC_MAP2_NQ:
3849                HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT2,
3850                                    threshold_info->threshold);
3851                break;
3852        case HALMAC_MAP2_LQ:
3853                HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT3,
3854                                    threshold_info->threshold);
3855                break;
3856        case HALMAC_MAP2_EXQ:
3857                HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT4,
3858                                    threshold_info->threshold);
3859                break;
3860        default:
3861                break;
3862        }
3863}
3864
3865void halmac_config_ampdu_88xx(struct halmac_adapter *halmac_adapter,
3866                              struct halmac_ampdu_config *ampdu_config)
3867{
3868        struct halmac_api *halmac_api;
3869
3870        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3871
3872        HALMAC_REG_WRITE_8(halmac_adapter, REG_PROT_MODE_CTRL + 2,
3873                           ampdu_config->max_agg_num);
3874        HALMAC_REG_WRITE_8(halmac_adapter, REG_PROT_MODE_CTRL + 3,
3875                           ampdu_config->max_agg_num);
3876};
3877
3878enum halmac_ret_status
3879halmac_check_oqt_88xx(struct halmac_adapter *halmac_adapter, u32 tx_agg_num,
3880                      u8 *halmac_buf)
3881{
3882        u32 counter = 10;
3883
3884        /*S0, S1 are not allowed to use, 0x4E4[0] should be 0. Soar 20160323*/
3885        /*no need to check non_ac_oqt_number. HI and MGQ blocked will cause
3886         *protocal issue before H_OQT being full
3887         */
3888        switch ((enum halmac_queue_select)GET_TX_DESC_QSEL(halmac_buf)) {
3889        case HALMAC_QUEUE_SELECT_VO:
3890        case HALMAC_QUEUE_SELECT_VO_V2:
3891        case HALMAC_QUEUE_SELECT_VI:
3892        case HALMAC_QUEUE_SELECT_VI_V2:
3893        case HALMAC_QUEUE_SELECT_BE:
3894        case HALMAC_QUEUE_SELECT_BE_V2:
3895        case HALMAC_QUEUE_SELECT_BK:
3896        case HALMAC_QUEUE_SELECT_BK_V2:
3897                counter = 10;
3898                do {
3899                        if (halmac_adapter->sdio_free_space.ac_empty > 0) {
3900                                halmac_adapter->sdio_free_space.ac_empty -= 1;
3901                                break;
3902                        }
3903
3904                        if (halmac_adapter->sdio_free_space.ac_oqt_number >=
3905                            tx_agg_num) {
3906                                halmac_adapter->sdio_free_space.ac_oqt_number -=
3907                                        (u8)tx_agg_num;
3908                                break;
3909                        }
3910
3911                        halmac_update_oqt_free_space_88xx(halmac_adapter);
3912
3913                        counter--;
3914                        if (counter == 0)
3915                                return HALMAC_RET_OQT_NOT_ENOUGH;
3916                } while (1);
3917                break;
3918        default:
3919                break;
3920        }
3921
3922        return HALMAC_RET_SUCCESS;
3923}
3924
3925enum halmac_ret_status
3926halmac_rqpn_parser_88xx(struct halmac_adapter *halmac_adapter,
3927                        enum halmac_trx_mode halmac_trx_mode,
3928                        struct halmac_rqpn_ *rqpn_table)
3929{
3930        u8 search_flag;
3931        u32 i;
3932        void *driver_adapter = NULL;
3933        struct halmac_api *halmac_api;
3934
3935        driver_adapter = halmac_adapter->driver_adapter;
3936        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3937
3938        search_flag = 0;
3939        for (i = 0; i < HALMAC_TRX_MODE_MAX; i++) {
3940                if (halmac_trx_mode == rqpn_table[i].mode) {
3941                        halmac_adapter
3942                                ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO] =
3943                                rqpn_table[i].dma_map_vo;
3944                        halmac_adapter
3945                                ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI] =
3946                                rqpn_table[i].dma_map_vi;
3947                        halmac_adapter
3948                                ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE] =
3949                                rqpn_table[i].dma_map_be;
3950                        halmac_adapter
3951                                ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK] =
3952                                rqpn_table[i].dma_map_bk;
3953                        halmac_adapter
3954                                ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG] =
3955                                rqpn_table[i].dma_map_mg;
3956                        halmac_adapter
3957                                ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI] =
3958                                rqpn_table[i].dma_map_hi;
3959                        search_flag = 1;
3960                        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3961                                        DBG_DMESG, "%s done\n", __func__);
3962                        break;
3963                }
3964        }
3965
3966        if (search_flag == 0) {
3967                pr_err("HALMAC_RET_TRX_MODE_NOT_SUPPORT 1 switch case not support\n");
3968                return HALMAC_RET_TRX_MODE_NOT_SUPPORT;
3969        }
3970
3971        return HALMAC_RET_SUCCESS;
3972}
3973
3974enum halmac_ret_status
3975halmac_pg_num_parser_88xx(struct halmac_adapter *halmac_adapter,
3976                          enum halmac_trx_mode halmac_trx_mode,
3977                          struct halmac_pg_num_ *pg_num_table)
3978{
3979        u8 search_flag;
3980        u16 HPQ_num = 0, lpq_nnum = 0, NPQ_num = 0, GAPQ_num = 0;
3981        u16 EXPQ_num = 0, PUBQ_num = 0;
3982        u32 i = 0;
3983        void *driver_adapter = NULL;
3984        struct halmac_api *halmac_api;
3985
3986        driver_adapter = halmac_adapter->driver_adapter;
3987        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3988
3989        search_flag = 0;
3990        for (i = 0; i < HALMAC_TRX_MODE_MAX; i++) {
3991                if (halmac_trx_mode == pg_num_table[i].mode) {
3992                        HPQ_num = pg_num_table[i].hq_num;
3993                        lpq_nnum = pg_num_table[i].lq_num;
3994                        NPQ_num = pg_num_table[i].nq_num;
3995                        EXPQ_num = pg_num_table[i].exq_num;
3996                        GAPQ_num = pg_num_table[i].gap_num;
3997                        PUBQ_num = halmac_adapter->txff_allocation.ac_q_pg_num -
3998                                   HPQ_num - lpq_nnum - NPQ_num - EXPQ_num -
3999                                   GAPQ_num;
4000                        search_flag = 1;
4001                        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
4002                                        DBG_DMESG, "%s done\n", __func__);
4003                        break;
4004                }
4005        }
4006
4007        if (search_flag == 0) {
4008                pr_err("HALMAC_RET_TRX_MODE_NOT_SUPPORT 1 switch case not support\n");
4009                return HALMAC_RET_TRX_MODE_NOT_SUPPORT;
4010        }
4011
4012        if (halmac_adapter->txff_allocation.ac_q_pg_num <
4013            HPQ_num + lpq_nnum + NPQ_num + EXPQ_num + GAPQ_num)
4014                return HALMAC_RET_CFG_TXFIFO_PAGE_FAIL;
4015
4016        halmac_adapter->txff_allocation.high_queue_pg_num = HPQ_num;
4017        halmac_adapter->txff_allocation.low_queue_pg_num = lpq_nnum;
4018        halmac_adapter->txff_allocation.normal_queue_pg_num = NPQ_num;
4019        halmac_adapter->txff_allocation.extra_queue_pg_num = EXPQ_num;
4020        halmac_adapter->txff_allocation.pub_queue_pg_num = PUBQ_num;
4021
4022        return HALMAC_RET_SUCCESS;
4023}
4024
4025enum halmac_ret_status
4026halmac_parse_intf_phy_88xx(struct halmac_adapter *halmac_adapter,
4027                           struct halmac_intf_phy_para_ *intf_phy_para,
4028                           enum halmac_intf_phy_platform platform,
4029                           enum hal_intf_phy intf_phy)
4030{
4031        u16 value;
4032        u16 curr_cut;
4033        u16 offset;
4034        u16 ip_sel;
4035        struct halmac_intf_phy_para_ *curr_phy_para;
4036        struct halmac_api *halmac_api;
4037        void *driver_adapter = NULL;
4038        u8 result = HALMAC_RET_SUCCESS;
4039
4040        driver_adapter = halmac_adapter->driver_adapter;
4041        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4042
4043        switch (halmac_adapter->chip_version) {
4044        case HALMAC_CHIP_VER_A_CUT:
4045                curr_cut = (u16)HALMAC_INTF_PHY_CUT_A;
4046                break;
4047        case HALMAC_CHIP_VER_B_CUT:
4048                curr_cut = (u16)HALMAC_INTF_PHY_CUT_B;
4049                break;
4050        case HALMAC_CHIP_VER_C_CUT:
4051                curr_cut = (u16)HALMAC_INTF_PHY_CUT_C;
4052                break;
4053        case HALMAC_CHIP_VER_D_CUT:
4054                curr_cut = (u16)HALMAC_INTF_PHY_CUT_D;
4055                break;
4056        case HALMAC_CHIP_VER_E_CUT:
4057                curr_cut = (u16)HALMAC_INTF_PHY_CUT_E;
4058                break;
4059        case HALMAC_CHIP_VER_F_CUT:
4060                curr_cut = (u16)HALMAC_INTF_PHY_CUT_F;
4061                break;
4062        case HALMAC_CHIP_VER_TEST:
4063                curr_cut = (u16)HALMAC_INTF_PHY_CUT_TESTCHIP;
4064                break;
4065        default:
4066                return HALMAC_RET_FAIL;
4067        }
4068
4069        for (curr_phy_para = intf_phy_para;; curr_phy_para++) {
4070                if (!(curr_phy_para->cut & curr_cut) ||
4071                    !(curr_phy_para->plaform & (u16)platform))
4072                        continue;
4073
4074                offset = curr_phy_para->offset;
4075                value = curr_phy_para->value;
4076                ip_sel = curr_phy_para->ip_sel;
4077
4078                if (offset == 0xFFFF)
4079                        break;
4080
4081                if (ip_sel == HALMAC_IP_SEL_MAC) {
4082                        HALMAC_REG_WRITE_8(halmac_adapter, (u32)offset,
4083                                           (u8)value);
4084                } else if (intf_phy == HAL_INTF_PHY_USB2) {
4085                        result = halmac_usbphy_write_88xx(halmac_adapter,
4086                                                          (u8)offset, value,
4087                                                          HAL_INTF_PHY_USB2);
4088
4089                        if (result != HALMAC_RET_SUCCESS)
4090                                pr_err("[ERR]Write USB2PHY fail!\n");
4091
4092                } else if (intf_phy == HAL_INTF_PHY_USB3) {
4093                        result = halmac_usbphy_write_88xx(halmac_adapter,
4094                                                          (u8)offset, value,
4095                                                          HAL_INTF_PHY_USB3);
4096
4097                        if (result != HALMAC_RET_SUCCESS)
4098                                pr_err("[ERR]Write USB3PHY fail!\n");
4099
4100                } else if (intf_phy == HAL_INTF_PHY_PCIE_GEN1) {
4101                        if (ip_sel == HALMAC_IP_SEL_INTF_PHY)
4102                                result = halmac_mdio_write_88xx(
4103                                        halmac_adapter, (u8)offset, value,
4104                                        HAL_INTF_PHY_PCIE_GEN1);
4105                        else
4106                                result = halmac_dbi_write8_88xx(
4107                                        halmac_adapter, offset, (u8)value);
4108
4109                        if (result != HALMAC_RET_SUCCESS)
4110                                pr_err("[ERR]MDIO write GEN1 fail!\n");
4111
4112                } else if (intf_phy == HAL_INTF_PHY_PCIE_GEN2) {
4113                        if (ip_sel == HALMAC_IP_SEL_INTF_PHY)
4114                                result = halmac_mdio_write_88xx(
4115                                        halmac_adapter, (u8)offset, value,
4116                                        HAL_INTF_PHY_PCIE_GEN2);
4117                        else
4118                                result = halmac_dbi_write8_88xx(
4119                                        halmac_adapter, offset, (u8)value);
4120
4121                        if (result != HALMAC_RET_SUCCESS)
4122                                pr_err("[ERR]MDIO write GEN2 fail!\n");
4123                } else {
4124                        pr_err("[ERR]Parse intf phy cfg error!\n");
4125                }
4126        }
4127
4128        return HALMAC_RET_SUCCESS;
4129}
4130
4131enum halmac_ret_status
4132halmac_dbi_write32_88xx(struct halmac_adapter *halmac_adapter, u16 addr,
4133                        u32 data)
4134{
4135        u8 tmp_u1b = 0;
4136        u32 count = 0;
4137        u16 write_addr = 0;
4138        void *driver_adapter = NULL;
4139        struct halmac_api *halmac_api;
4140
4141        driver_adapter = halmac_adapter->driver_adapter;
4142        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4143
4144        HALMAC_REG_WRITE_32(halmac_adapter, REG_DBI_WDATA_V1, data);
4145
4146        write_addr = ((addr & 0x0ffc) | (0x000F << 12));
4147        HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, write_addr);
4148
4149        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
4150                        "WriteAddr = %x\n", write_addr);
4151
4152        HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x01);
4153        tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4154
4155        count = 20;
4156        while (tmp_u1b && count != 0) {
4157                udelay(10);
4158                tmp_u1b =
4159                        HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4160                count--;
4161        }
4162
4163        if (tmp_u1b) {
4164                pr_err("DBI write fail!\n");
4165                return HALMAC_RET_FAIL;
4166        } else {
4167                return HALMAC_RET_SUCCESS;
4168        }
4169}
4170
4171u32 halmac_dbi_read32_88xx(struct halmac_adapter *halmac_adapter, u16 addr)
4172{
4173        u16 read_addr = addr & 0x0ffc;
4174        u8 tmp_u1b = 0;
4175        u32 count = 0;
4176        u32 ret = 0;
4177        void *driver_adapter = NULL;
4178        struct halmac_api *halmac_api;
4179
4180        driver_adapter = halmac_adapter->driver_adapter;
4181        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4182
4183        HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, read_addr);
4184
4185        HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x2);
4186        tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4187
4188        count = 20;
4189        while (tmp_u1b && count != 0) {
4190                udelay(10);
4191                tmp_u1b =
4192                        HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4193                count--;
4194        }
4195
4196        if (tmp_u1b) {
4197                ret = 0xFFFF;
4198                pr_err("DBI read fail!\n");
4199        } else {
4200                ret = HALMAC_REG_READ_32(halmac_adapter, REG_DBI_RDATA_V1);
4201                HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
4202                                "Read Value = %x\n", ret);
4203        }
4204
4205        return ret;
4206}
4207
4208enum halmac_ret_status
4209halmac_dbi_write8_88xx(struct halmac_adapter *halmac_adapter, u16 addr, u8 data)
4210{
4211        u8 tmp_u1b = 0;
4212        u32 count = 0;
4213        u16 write_addr = 0;
4214        u16 remainder = addr & (4 - 1);
4215        void *driver_adapter = NULL;
4216        struct halmac_api *halmac_api;
4217
4218        driver_adapter = halmac_adapter->driver_adapter;
4219        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4220
4221        HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_WDATA_V1 + remainder, data);
4222
4223        write_addr = ((addr & 0x0ffc) | (BIT(0) << (remainder + 12)));
4224
4225        HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, write_addr);
4226
4227        HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
4228                        "WriteAddr = %x\n", write_addr);
4229
4230        HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x01);
4231
4232        tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4233
4234        count = 20;
4235        while (tmp_u1b && count != 0) {
4236                udelay(10);
4237                tmp_u1b =
4238                        HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4239                count--;
4240        }
4241
4242        if (tmp_u1b) {
4243                pr_err("DBI write fail!\n");
4244                return HALMAC_RET_FAIL;
4245        } else {
4246                return HALMAC_RET_SUCCESS;
4247        }
4248}
4249
4250u8 halmac_dbi_read8_88xx(struct halmac_adapter *halmac_adapter, u16 addr)
4251{
4252        u16 read_addr = addr & 0x0ffc;
4253        u8 tmp_u1b = 0;
4254        u32 count = 0;
4255        u8 ret = 0;
4256        void *driver_adapter = NULL;
4257        struct halmac_api *halmac_api;
4258
4259        driver_adapter = halmac_adapter->driver_adapter;
4260        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4261
4262        HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, read_addr);
4263        HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x2);
4264
4265        tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4266
4267        count = 20;
4268        while (tmp_u1b && count != 0) {
4269                udelay(10);
4270                tmp_u1b =
4271                        HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4272                count--;
4273        }
4274
4275        if (tmp_u1b) {
4276                ret = 0xFF;
4277                pr_err("DBI read fail!\n");
4278        } else {
4279                ret = HALMAC_REG_READ_8(halmac_adapter,
4280                                        REG_DBI_RDATA_V1 + (addr & (4 - 1)));
4281                HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
4282                                "Read Value = %x\n", ret);
4283        }
4284
4285        return ret;
4286}
4287
4288enum halmac_ret_status
4289halmac_mdio_write_88xx(struct halmac_adapter *halmac_adapter, u8 addr, u16 data,
4290                       u8 speed)
4291{
4292        u8 tmp_u1b = 0;
4293        u32 count = 0;
4294        void *driver_adapter = NULL;
4295        struct halmac_api *halmac_api;
4296        u8 real_addr = 0;
4297
4298        driver_adapter = halmac_adapter->driver_adapter;
4299        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4300
4301        HALMAC_REG_WRITE_16(halmac_adapter, REG_MDIO_V1, data);
4302
4303        /* address : 5bit */
4304        real_addr = (addr & 0x1F);
4305        HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG, real_addr);
4306
4307        if (speed == HAL_INTF_PHY_PCIE_GEN1) {
4308                /* GEN1 page 0 */
4309                if (addr < 0x20) {
4310                        /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b00 */
4311                        HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4312                                           0x00);
4313
4314                        /* GEN1 page 1 */
4315                } else {
4316                        /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b01 */
4317                        HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4318                                           0x01);
4319                }
4320
4321        } else if (speed == HAL_INTF_PHY_PCIE_GEN2) {
4322                /* GEN2 page 0 */
4323                if (addr < 0x20) {
4324                        /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b10 */
4325                        HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4326                                           0x02);
4327
4328                        /* GEN2 page 1 */
4329                } else {
4330                        /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b11 */
4331                        HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4332                                           0x03);
4333                }
4334        } else {
4335                pr_err("Error Speed !\n");
4336        }
4337
4338        HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG,
4339                           HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) |
4340                                   BIT_MDIO_WFLAG_V1);
4341
4342        tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
4343                  BIT_MDIO_WFLAG_V1;
4344        count = 20;
4345
4346        while (tmp_u1b && count != 0) {
4347                udelay(10);
4348                tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
4349                          BIT_MDIO_WFLAG_V1;
4350                count--;
4351        }
4352
4353        if (tmp_u1b) {
4354                pr_err("MDIO write fail!\n");
4355                return HALMAC_RET_FAIL;
4356        } else {
4357                return HALMAC_RET_SUCCESS;
4358        }
4359}
4360
4361u16 halmac_mdio_read_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
4362                          u8 speed
4363
4364                          )
4365{
4366        u16 ret = 0;
4367        u8 tmp_u1b = 0;
4368        u32 count = 0;
4369        void *driver_adapter = NULL;
4370        struct halmac_api *halmac_api;
4371        u8 real_addr = 0;
4372
4373        driver_adapter = halmac_adapter->driver_adapter;
4374        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4375
4376        /* address : 5bit */
4377        real_addr = (addr & 0x1F);
4378        HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG, real_addr);
4379
4380        if (speed == HAL_INTF_PHY_PCIE_GEN1) {
4381                /* GEN1 page 0 */
4382                if (addr < 0x20) {
4383                        /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b00 */
4384                        HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4385                                           0x00);
4386
4387                        /* GEN1 page 1 */
4388                } else {
4389                        /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b01 */
4390                        HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4391                                           0x01);
4392                }
4393
4394        } else if (speed == HAL_INTF_PHY_PCIE_GEN2) {
4395                /* GEN2 page 0 */
4396                if (addr < 0x20) {
4397                        /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b10 */
4398                        HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4399                                           0x02);
4400
4401                        /* GEN2 page 1 */
4402                } else {
4403                        /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b11 */
4404                        HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4405                                           0x03);
4406                }
4407        } else {
4408                pr_err("Error Speed !\n");
4409        }
4410
4411        HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG,
4412                           HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) |
4413                                   BIT_MDIO_RFLAG_V1);
4414
4415        tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
4416                  BIT_MDIO_RFLAG_V1;
4417        count = 20;
4418
4419        while (tmp_u1b && count != 0) {
4420                udelay(10);
4421                tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
4422                          BIT_MDIO_RFLAG_V1;
4423                count--;
4424        }
4425
4426        if (tmp_u1b) {
4427                ret = 0xFFFF;
4428                pr_err("MDIO read fail!\n");
4429
4430        } else {
4431                ret = HALMAC_REG_READ_16(halmac_adapter, REG_MDIO_V1 + 2);
4432                HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_MDIO, DBG_DMESG,
4433                                "Read Value = %x\n", ret);
4434        }
4435
4436        return ret;
4437}
4438
4439enum halmac_ret_status
4440halmac_usbphy_write_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
4441                         u16 data, u8 speed)
4442{
4443        void *driver_adapter = NULL;
4444        struct halmac_api *halmac_api;
4445
4446        driver_adapter = halmac_adapter->driver_adapter;
4447        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4448
4449        if (speed == HAL_INTF_PHY_USB3) {
4450                HALMAC_REG_WRITE_8(halmac_adapter, 0xff0d, (u8)data);
4451                HALMAC_REG_WRITE_8(halmac_adapter, 0xff0e, (u8)(data >> 8));
4452                HALMAC_REG_WRITE_8(halmac_adapter, 0xff0c, addr | BIT(7));
4453        } else if (speed == HAL_INTF_PHY_USB2) {
4454                HALMAC_REG_WRITE_8(halmac_adapter, 0xfe41, (u8)data);
4455                HALMAC_REG_WRITE_8(halmac_adapter, 0xfe40, addr);
4456                HALMAC_REG_WRITE_8(halmac_adapter, 0xfe42, 0x81);
4457        } else {
4458                pr_err("[ERR]Error USB Speed !\n");
4459                return HALMAC_RET_NOT_SUPPORT;
4460        }
4461
4462        return HALMAC_RET_SUCCESS;
4463}
4464
4465u16 halmac_usbphy_read_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
4466                            u8 speed)
4467{
4468        void *driver_adapter = NULL;
4469        struct halmac_api *halmac_api;
4470        u16 value = 0;
4471
4472        driver_adapter = halmac_adapter->driver_adapter;
4473        halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4474
4475        if (speed == HAL_INTF_PHY_USB3) {
4476                HALMAC_REG_WRITE_8(halmac_adapter, 0xff0c, addr | BIT(6));
4477                value = (u16)(HALMAC_REG_READ_32(halmac_adapter, 0xff0c) >> 8);
4478        } else if (speed == HAL_INTF_PHY_USB2) {
4479                if ((addr >= 0xE0) /*&& (addr <= 0xFF)*/)
4480                        addr -= 0x20;
4481                if ((addr >= 0xC0) && (addr <= 0xDF)) {
4482                        HALMAC_REG_WRITE_8(halmac_adapter, 0xfe40, addr);
4483                        HALMAC_REG_WRITE_8(halmac_adapter, 0xfe42, 0x81);
4484                        value = HALMAC_REG_READ_8(halmac_adapter, 0xfe43);
4485                } else {
4486                        pr_err("[ERR]Error USB2PHY offset!\n");
4487                        return HALMAC_RET_NOT_SUPPORT;
4488                }
4489        } else {
4490                pr_err("[ERR]Error USB Speed !\n");
4491                return HALMAC_RET_NOT_SUPPORT;
4492        }
4493
4494        return value;
4495}
4496