linux/drivers/net/wireless/rsi/rsi_91x_mgmt.c
<<
>>
Prefs
   1/**
   2 * Copyright (c) 2014 Redpine Signals Inc.
   3 *
   4 * Permission to use, copy, modify, and/or distribute this software for any
   5 * purpose with or without fee is hereby granted, provided that the above
   6 * copyright notice and this permission notice appear in all copies.
   7 *
   8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15 */
  16
  17#include <linux/etherdevice.h>
  18#include "rsi_mgmt.h"
  19#include "rsi_common.h"
  20
  21static struct bootup_params boot_params_20 = {
  22        .magic_number = cpu_to_le16(0x5aa5),
  23        .crystal_good_time = 0x0,
  24        .valid = cpu_to_le32(VALID_20),
  25        .reserved_for_valids = 0x0,
  26        .bootup_mode_info = 0x0,
  27        .digital_loop_back_params = 0x0,
  28        .rtls_timestamp_en = 0x0,
  29        .host_spi_intr_cfg = 0x0,
  30        .device_clk_info = {{
  31                .pll_config_g = {
  32                        .tapll_info_g = {
  33                                .pll_reg_1 = cpu_to_le16((TA_PLL_N_VAL_20 << 8)|
  34                                              (TA_PLL_M_VAL_20)),
  35                                .pll_reg_2 = cpu_to_le16(TA_PLL_P_VAL_20),
  36                        },
  37                        .pll960_info_g = {
  38                                .pll_reg_1 = cpu_to_le16((PLL960_P_VAL_20 << 8)|
  39                                                         (PLL960_N_VAL_20)),
  40                                .pll_reg_2 = cpu_to_le16(PLL960_M_VAL_20),
  41                                .pll_reg_3 = 0x0,
  42                        },
  43                        .afepll_info_g = {
  44                                .pll_reg = cpu_to_le16(0x9f0),
  45                        }
  46                },
  47                .switch_clk_g = {
  48                        .switch_clk_info = cpu_to_le16(BIT(3)),
  49                        .bbp_lmac_clk_reg_val = cpu_to_le16(0x121),
  50                        .umac_clock_reg_config = 0x0,
  51                        .qspi_uart_clock_reg_config = 0x0
  52                }
  53        },
  54        {
  55                .pll_config_g = {
  56                        .tapll_info_g = {
  57                                .pll_reg_1 = cpu_to_le16((TA_PLL_N_VAL_20 << 8)|
  58                                                         (TA_PLL_M_VAL_20)),
  59                                .pll_reg_2 = cpu_to_le16(TA_PLL_P_VAL_20),
  60                        },
  61                        .pll960_info_g = {
  62                                .pll_reg_1 = cpu_to_le16((PLL960_P_VAL_20 << 8)|
  63                                                         (PLL960_N_VAL_20)),
  64                                .pll_reg_2 = cpu_to_le16(PLL960_M_VAL_20),
  65                                .pll_reg_3 = 0x0,
  66                        },
  67                        .afepll_info_g = {
  68                                .pll_reg = cpu_to_le16(0x9f0),
  69                        }
  70                },
  71                .switch_clk_g = {
  72                        .switch_clk_info = 0x0,
  73                        .bbp_lmac_clk_reg_val = 0x0,
  74                        .umac_clock_reg_config = 0x0,
  75                        .qspi_uart_clock_reg_config = 0x0
  76                }
  77        },
  78        {
  79                .pll_config_g = {
  80                        .tapll_info_g = {
  81                                .pll_reg_1 = cpu_to_le16((TA_PLL_N_VAL_20 << 8)|
  82                                                         (TA_PLL_M_VAL_20)),
  83                                .pll_reg_2 = cpu_to_le16(TA_PLL_P_VAL_20),
  84                        },
  85                        .pll960_info_g = {
  86                                .pll_reg_1 = cpu_to_le16((PLL960_P_VAL_20 << 8)|
  87                                                         (PLL960_N_VAL_20)),
  88                                .pll_reg_2 = cpu_to_le16(PLL960_M_VAL_20),
  89                                .pll_reg_3 = 0x0,
  90                        },
  91                        .afepll_info_g = {
  92                                .pll_reg = cpu_to_le16(0x9f0),
  93                        }
  94                },
  95                .switch_clk_g = {
  96                        .switch_clk_info = 0x0,
  97                        .bbp_lmac_clk_reg_val = 0x0,
  98                        .umac_clock_reg_config = 0x0,
  99                        .qspi_uart_clock_reg_config = 0x0
 100                }
 101        } },
 102        .buckboost_wakeup_cnt = 0x0,
 103        .pmu_wakeup_wait = 0x0,
 104        .shutdown_wait_time = 0x0,
 105        .pmu_slp_clkout_sel = 0x0,
 106        .wdt_prog_value = 0x0,
 107        .wdt_soc_rst_delay = 0x0,
 108        .dcdc_operation_mode = 0x0,
 109        .soc_reset_wait_cnt = 0x0
 110};
 111
 112static struct bootup_params boot_params_40 = {
 113        .magic_number = cpu_to_le16(0x5aa5),
 114        .crystal_good_time = 0x0,
 115        .valid = cpu_to_le32(VALID_40),
 116        .reserved_for_valids = 0x0,
 117        .bootup_mode_info = 0x0,
 118        .digital_loop_back_params = 0x0,
 119        .rtls_timestamp_en = 0x0,
 120        .host_spi_intr_cfg = 0x0,
 121        .device_clk_info = {{
 122                .pll_config_g = {
 123                        .tapll_info_g = {
 124                                .pll_reg_1 = cpu_to_le16((TA_PLL_N_VAL_40 << 8)|
 125                                                         (TA_PLL_M_VAL_40)),
 126                                .pll_reg_2 = cpu_to_le16(TA_PLL_P_VAL_40),
 127                        },
 128                        .pll960_info_g = {
 129                                .pll_reg_1 = cpu_to_le16((PLL960_P_VAL_40 << 8)|
 130                                                         (PLL960_N_VAL_40)),
 131                                .pll_reg_2 = cpu_to_le16(PLL960_M_VAL_40),
 132                                .pll_reg_3 = 0x0,
 133                        },
 134                        .afepll_info_g = {
 135                                .pll_reg = cpu_to_le16(0x9f0),
 136                        }
 137                },
 138                .switch_clk_g = {
 139                        .switch_clk_info = cpu_to_le16(0x09),
 140                        .bbp_lmac_clk_reg_val = cpu_to_le16(0x1121),
 141                        .umac_clock_reg_config = cpu_to_le16(0x48),
 142                        .qspi_uart_clock_reg_config = 0x0
 143                }
 144        },
 145        {
 146                .pll_config_g = {
 147                        .tapll_info_g = {
 148                                .pll_reg_1 = cpu_to_le16((TA_PLL_N_VAL_40 << 8)|
 149                                                         (TA_PLL_M_VAL_40)),
 150                                .pll_reg_2 = cpu_to_le16(TA_PLL_P_VAL_40),
 151                        },
 152                        .pll960_info_g = {
 153                                .pll_reg_1 = cpu_to_le16((PLL960_P_VAL_40 << 8)|
 154                                                         (PLL960_N_VAL_40)),
 155                                .pll_reg_2 = cpu_to_le16(PLL960_M_VAL_40),
 156                                .pll_reg_3 = 0x0,
 157                        },
 158                        .afepll_info_g = {
 159                                .pll_reg = cpu_to_le16(0x9f0),
 160                        }
 161                },
 162                .switch_clk_g = {
 163                        .switch_clk_info = 0x0,
 164                        .bbp_lmac_clk_reg_val = 0x0,
 165                        .umac_clock_reg_config = 0x0,
 166                        .qspi_uart_clock_reg_config = 0x0
 167                }
 168        },
 169        {
 170                .pll_config_g = {
 171                        .tapll_info_g = {
 172                                .pll_reg_1 = cpu_to_le16((TA_PLL_N_VAL_40 << 8)|
 173                                                         (TA_PLL_M_VAL_40)),
 174                                .pll_reg_2 = cpu_to_le16(TA_PLL_P_VAL_40),
 175                        },
 176                        .pll960_info_g = {
 177                                .pll_reg_1 = cpu_to_le16((PLL960_P_VAL_40 << 8)|
 178                                                         (PLL960_N_VAL_40)),
 179                                .pll_reg_2 = cpu_to_le16(PLL960_M_VAL_40),
 180                                .pll_reg_3 = 0x0,
 181                        },
 182                        .afepll_info_g = {
 183                                .pll_reg = cpu_to_le16(0x9f0),
 184                        }
 185                },
 186                .switch_clk_g = {
 187                        .switch_clk_info = 0x0,
 188                        .bbp_lmac_clk_reg_val = 0x0,
 189                        .umac_clock_reg_config = 0x0,
 190                        .qspi_uart_clock_reg_config = 0x0
 191                }
 192        } },
 193        .buckboost_wakeup_cnt = 0x0,
 194        .pmu_wakeup_wait = 0x0,
 195        .shutdown_wait_time = 0x0,
 196        .pmu_slp_clkout_sel = 0x0,
 197        .wdt_prog_value = 0x0,
 198        .wdt_soc_rst_delay = 0x0,
 199        .dcdc_operation_mode = 0x0,
 200        .soc_reset_wait_cnt = 0x0
 201};
 202
 203static u16 mcs[] = {13, 26, 39, 52, 78, 104, 117, 130};
 204
 205/**
 206 * rsi_set_default_parameters() - This function sets default parameters.
 207 * @common: Pointer to the driver private structure.
 208 *
 209 * Return: none
 210 */
 211static void rsi_set_default_parameters(struct rsi_common *common)
 212{
 213        common->band = IEEE80211_BAND_2GHZ;
 214        common->channel_width = BW_20MHZ;
 215        common->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
 216        common->channel = 1;
 217        common->min_rate = 0xffff;
 218        common->fsm_state = FSM_CARD_NOT_READY;
 219        common->iface_down = true;
 220        common->endpoint = EP_2GHZ_20MHZ;
 221}
 222
 223/**
 224 * rsi_set_contention_vals() - This function sets the contention values for the
 225 *                             backoff procedure.
 226 * @common: Pointer to the driver private structure.
 227 *
 228 * Return: None.
 229 */
 230static void rsi_set_contention_vals(struct rsi_common *common)
 231{
 232        u8 ii = 0;
 233
 234        for (; ii < NUM_EDCA_QUEUES; ii++) {
 235                common->tx_qinfo[ii].wme_params =
 236                        (((common->edca_params[ii].cw_min / 2) +
 237                          (common->edca_params[ii].aifs)) *
 238                          WMM_SHORT_SLOT_TIME + SIFS_DURATION);
 239                common->tx_qinfo[ii].weight = common->tx_qinfo[ii].wme_params;
 240                common->tx_qinfo[ii].pkt_contended = 0;
 241        }
 242}
 243
 244/**
 245 * rsi_send_internal_mgmt_frame() - This function sends management frames to
 246 *                                  firmware.Also schedules packet to queue
 247 *                                  for transmission.
 248 * @common: Pointer to the driver private structure.
 249 * @skb: Pointer to the socket buffer structure.
 250 *
 251 * Return: 0 on success, -1 on failure.
 252 */
 253static int rsi_send_internal_mgmt_frame(struct rsi_common *common,
 254                                        struct sk_buff *skb)
 255{
 256        struct skb_info *tx_params;
 257
 258        if (skb == NULL) {
 259                rsi_dbg(ERR_ZONE, "%s: Unable to allocate skb\n", __func__);
 260                return -ENOMEM;
 261        }
 262        tx_params = (struct skb_info *)&IEEE80211_SKB_CB(skb)->driver_data;
 263        tx_params->flags |= INTERNAL_MGMT_PKT;
 264        skb_queue_tail(&common->tx_queue[MGMT_SOFT_Q], skb);
 265        rsi_set_event(&common->tx_thread.event);
 266        return 0;
 267}
 268
 269/**
 270 * rsi_load_radio_caps() - This function is used to send radio capabilities
 271 *                         values to firmware.
 272 * @common: Pointer to the driver private structure.
 273 *
 274 * Return: 0 on success, corresponding negative error code on failure.
 275 */
 276static int rsi_load_radio_caps(struct rsi_common *common)
 277{
 278        struct rsi_radio_caps *radio_caps;
 279        struct rsi_hw *adapter = common->priv;
 280        u16 inx = 0;
 281        u8 ii;
 282        u8 radio_id = 0;
 283        u16 gc[20] = {0xf0, 0xf0, 0xf0, 0xf0,
 284                      0xf0, 0xf0, 0xf0, 0xf0,
 285                      0xf0, 0xf0, 0xf0, 0xf0,
 286                      0xf0, 0xf0, 0xf0, 0xf0,
 287                      0xf0, 0xf0, 0xf0, 0xf0};
 288        struct sk_buff *skb;
 289
 290        rsi_dbg(INFO_ZONE, "%s: Sending rate symbol req frame\n", __func__);
 291
 292        skb = dev_alloc_skb(sizeof(struct rsi_radio_caps));
 293
 294        if (!skb) {
 295                rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
 296                        __func__);
 297                return -ENOMEM;
 298        }
 299
 300        memset(skb->data, 0, sizeof(struct rsi_radio_caps));
 301        radio_caps = (struct rsi_radio_caps *)skb->data;
 302
 303        radio_caps->desc_word[1] = cpu_to_le16(RADIO_CAPABILITIES);
 304        radio_caps->desc_word[4] = cpu_to_le16(RSI_RF_TYPE << 8);
 305
 306        if (common->channel_width == BW_40MHZ) {
 307                radio_caps->desc_word[7] |= cpu_to_le16(RSI_LMAC_CLOCK_80MHZ);
 308                radio_caps->desc_word[7] |= cpu_to_le16(RSI_ENABLE_40MHZ);
 309
 310                if (common->fsm_state == FSM_MAC_INIT_DONE) {
 311                        struct ieee80211_hw *hw = adapter->hw;
 312                        struct ieee80211_conf *conf = &hw->conf;
 313                        if (conf_is_ht40_plus(conf)) {
 314                                radio_caps->desc_word[5] =
 315                                        cpu_to_le16(LOWER_20_ENABLE);
 316                                radio_caps->desc_word[5] |=
 317                                        cpu_to_le16(LOWER_20_ENABLE >> 12);
 318                        } else if (conf_is_ht40_minus(conf)) {
 319                                radio_caps->desc_word[5] =
 320                                        cpu_to_le16(UPPER_20_ENABLE);
 321                                radio_caps->desc_word[5] |=
 322                                        cpu_to_le16(UPPER_20_ENABLE >> 12);
 323                        } else {
 324                                radio_caps->desc_word[5] =
 325                                        cpu_to_le16(BW_40MHZ << 12);
 326                                radio_caps->desc_word[5] |=
 327                                        cpu_to_le16(FULL40M_ENABLE);
 328                        }
 329                }
 330        }
 331
 332        radio_caps->sifs_tx_11n = cpu_to_le16(SIFS_TX_11N_VALUE);
 333        radio_caps->sifs_tx_11b = cpu_to_le16(SIFS_TX_11B_VALUE);
 334        radio_caps->slot_rx_11n = cpu_to_le16(SHORT_SLOT_VALUE);
 335        radio_caps->ofdm_ack_tout = cpu_to_le16(OFDM_ACK_TOUT_VALUE);
 336        radio_caps->cck_ack_tout = cpu_to_le16(CCK_ACK_TOUT_VALUE);
 337        radio_caps->preamble_type = cpu_to_le16(LONG_PREAMBLE);
 338
 339        radio_caps->desc_word[7] |= cpu_to_le16(radio_id << 8);
 340
 341        for (ii = 0; ii < MAX_HW_QUEUES; ii++) {
 342                radio_caps->qos_params[ii].cont_win_min_q = cpu_to_le16(3);
 343                radio_caps->qos_params[ii].cont_win_max_q = cpu_to_le16(0x3f);
 344                radio_caps->qos_params[ii].aifsn_val_q = cpu_to_le16(2);
 345                radio_caps->qos_params[ii].txop_q = 0;
 346        }
 347
 348        for (ii = 0; ii < MAX_HW_QUEUES - 4; ii++) {
 349                radio_caps->qos_params[ii].cont_win_min_q =
 350                        cpu_to_le16(common->edca_params[ii].cw_min);
 351                radio_caps->qos_params[ii].cont_win_max_q =
 352                        cpu_to_le16(common->edca_params[ii].cw_max);
 353                radio_caps->qos_params[ii].aifsn_val_q =
 354                        cpu_to_le16((common->edca_params[ii].aifs) << 8);
 355                radio_caps->qos_params[ii].txop_q =
 356                        cpu_to_le16(common->edca_params[ii].txop);
 357        }
 358
 359        memcpy(&common->rate_pwr[0], &gc[0], 40);
 360        for (ii = 0; ii < 20; ii++)
 361                radio_caps->gcpd_per_rate[inx++] =
 362                        cpu_to_le16(common->rate_pwr[ii]  & 0x00FF);
 363
 364        radio_caps->desc_word[0] = cpu_to_le16((sizeof(struct rsi_radio_caps) -
 365                                                FRAME_DESC_SZ) |
 366                                               (RSI_WIFI_MGMT_Q << 12));
 367
 368
 369        skb_put(skb, (sizeof(struct rsi_radio_caps)));
 370
 371        return rsi_send_internal_mgmt_frame(common, skb);
 372}
 373
 374/**
 375 * rsi_mgmt_pkt_to_core() - This function is the entry point for Mgmt module.
 376 * @common: Pointer to the driver private structure.
 377 * @msg: Pointer to received packet.
 378 * @msg_len: Length of the recieved packet.
 379 * @type: Type of recieved packet.
 380 *
 381 * Return: 0 on success, -1 on failure.
 382 */
 383static int rsi_mgmt_pkt_to_core(struct rsi_common *common,
 384                                u8 *msg,
 385                                s32 msg_len,
 386                                u8 type)
 387{
 388        struct rsi_hw *adapter = common->priv;
 389        struct ieee80211_tx_info *info;
 390        struct skb_info *rx_params;
 391        u8 pad_bytes = msg[4];
 392        u8 pkt_recv;
 393        struct sk_buff *skb;
 394        char *buffer;
 395
 396        if (type == RX_DOT11_MGMT) {
 397                if (!adapter->sc_nvifs)
 398                        return -ENOLINK;
 399
 400                msg_len -= pad_bytes;
 401                if ((msg_len <= 0) || (!msg)) {
 402                        rsi_dbg(MGMT_RX_ZONE,
 403                                "%s: Invalid rx msg of len = %d\n",
 404                                __func__, msg_len);
 405                        return -EINVAL;
 406                }
 407
 408                skb = dev_alloc_skb(msg_len);
 409                if (!skb) {
 410                        rsi_dbg(ERR_ZONE, "%s: Failed to allocate skb\n",
 411                                __func__);
 412                        return -ENOMEM;
 413                }
 414
 415                buffer = skb_put(skb, msg_len);
 416
 417                memcpy(buffer,
 418                       (u8 *)(msg +  FRAME_DESC_SZ + pad_bytes),
 419                       msg_len);
 420
 421                pkt_recv = buffer[0];
 422
 423                info = IEEE80211_SKB_CB(skb);
 424                rx_params = (struct skb_info *)info->driver_data;
 425                rx_params->rssi = rsi_get_rssi(msg);
 426                rx_params->channel = rsi_get_channel(msg);
 427                rsi_indicate_pkt_to_os(common, skb);
 428        } else {
 429                rsi_dbg(MGMT_TX_ZONE, "%s: Internal Packet\n", __func__);
 430        }
 431
 432        return 0;
 433}
 434
 435/**
 436 * rsi_hal_send_sta_notify_frame() - This function sends the station notify
 437 *                                   frame to firmware.
 438 * @common: Pointer to the driver private structure.
 439 * @opmode: Operating mode of device.
 440 * @notify_event: Notification about station connection.
 441 * @bssid: bssid.
 442 * @qos_enable: Qos is enabled.
 443 * @aid: Aid (unique for all STA).
 444 *
 445 * Return: status: 0 on success, corresponding negative error code on failure.
 446 */
 447static int rsi_hal_send_sta_notify_frame(struct rsi_common *common,
 448                                         u8 opmode,
 449                                         u8 notify_event,
 450                                         const unsigned char *bssid,
 451                                         u8 qos_enable,
 452                                         u16 aid)
 453{
 454        struct sk_buff *skb = NULL;
 455        struct rsi_peer_notify *peer_notify;
 456        u16 vap_id = 0;
 457        int status;
 458
 459        rsi_dbg(MGMT_TX_ZONE, "%s: Sending sta notify frame\n", __func__);
 460
 461        skb = dev_alloc_skb(sizeof(struct rsi_peer_notify));
 462
 463        if (!skb) {
 464                rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
 465                        __func__);
 466                return -ENOMEM;
 467        }
 468
 469        memset(skb->data, 0, sizeof(struct rsi_peer_notify));
 470        peer_notify = (struct rsi_peer_notify *)skb->data;
 471
 472        peer_notify->command = cpu_to_le16(opmode << 1);
 473
 474        switch (notify_event) {
 475        case STA_CONNECTED:
 476                peer_notify->command |= cpu_to_le16(RSI_ADD_PEER);
 477                break;
 478        case STA_DISCONNECTED:
 479                peer_notify->command |= cpu_to_le16(RSI_DELETE_PEER);
 480                break;
 481        default:
 482                break;
 483        }
 484
 485        peer_notify->command |= cpu_to_le16((aid & 0xfff) << 4);
 486        ether_addr_copy(peer_notify->mac_addr, bssid);
 487
 488        peer_notify->sta_flags = cpu_to_le32((qos_enable) ? 1 : 0);
 489
 490        peer_notify->desc_word[0] =
 491                cpu_to_le16((sizeof(struct rsi_peer_notify) - FRAME_DESC_SZ) |
 492                            (RSI_WIFI_MGMT_Q << 12));
 493        peer_notify->desc_word[1] = cpu_to_le16(PEER_NOTIFY);
 494        peer_notify->desc_word[7] |= cpu_to_le16(vap_id << 8);
 495
 496        skb_put(skb, sizeof(struct rsi_peer_notify));
 497
 498        status = rsi_send_internal_mgmt_frame(common, skb);
 499
 500        if (!status && qos_enable) {
 501                rsi_set_contention_vals(common);
 502                status = rsi_load_radio_caps(common);
 503        }
 504        return status;
 505}
 506
 507/**
 508 * rsi_send_aggregation_params_frame() - This function sends the ampdu
 509 *                                       indication frame to firmware.
 510 * @common: Pointer to the driver private structure.
 511 * @tid: traffic identifier.
 512 * @ssn: ssn.
 513 * @buf_size: buffer size.
 514 * @event: notification about station connection.
 515 *
 516 * Return: 0 on success, corresponding negative error code on failure.
 517 */
 518int rsi_send_aggregation_params_frame(struct rsi_common *common,
 519                                      u16 tid,
 520                                      u16 ssn,
 521                                      u8 buf_size,
 522                                      u8 event)
 523{
 524        struct sk_buff *skb = NULL;
 525        struct rsi_mac_frame *mgmt_frame;
 526        u8 peer_id = 0;
 527
 528        skb = dev_alloc_skb(FRAME_DESC_SZ);
 529
 530        if (!skb) {
 531                rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
 532                        __func__);
 533                return -ENOMEM;
 534        }
 535
 536        memset(skb->data, 0, FRAME_DESC_SZ);
 537        mgmt_frame = (struct rsi_mac_frame *)skb->data;
 538
 539        rsi_dbg(MGMT_TX_ZONE, "%s: Sending AMPDU indication frame\n", __func__);
 540
 541        mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
 542        mgmt_frame->desc_word[1] = cpu_to_le16(AMPDU_IND);
 543
 544        if (event == STA_TX_ADDBA_DONE) {
 545                mgmt_frame->desc_word[4] = cpu_to_le16(ssn);
 546                mgmt_frame->desc_word[5] = cpu_to_le16(buf_size);
 547                mgmt_frame->desc_word[7] =
 548                cpu_to_le16((tid | (START_AMPDU_AGGR << 4) | (peer_id << 8)));
 549        } else if (event == STA_RX_ADDBA_DONE) {
 550                mgmt_frame->desc_word[4] = cpu_to_le16(ssn);
 551                mgmt_frame->desc_word[7] = cpu_to_le16(tid |
 552                                                       (START_AMPDU_AGGR << 4) |
 553                                                       (RX_BA_INDICATION << 5) |
 554                                                       (peer_id << 8));
 555        } else if (event == STA_TX_DELBA) {
 556                mgmt_frame->desc_word[7] = cpu_to_le16(tid |
 557                                                       (STOP_AMPDU_AGGR << 4) |
 558                                                       (peer_id << 8));
 559        } else if (event == STA_RX_DELBA) {
 560                mgmt_frame->desc_word[7] = cpu_to_le16(tid |
 561                                                       (STOP_AMPDU_AGGR << 4) |
 562                                                       (RX_BA_INDICATION << 5) |
 563                                                       (peer_id << 8));
 564        }
 565
 566        skb_put(skb, FRAME_DESC_SZ);
 567
 568        return rsi_send_internal_mgmt_frame(common, skb);
 569}
 570
 571/**
 572 * rsi_program_bb_rf() - This function starts base band and RF programming.
 573 *                       This is called after initial configurations are done.
 574 * @common: Pointer to the driver private structure.
 575 *
 576 * Return: 0 on success, corresponding negative error code on failure.
 577 */
 578static int rsi_program_bb_rf(struct rsi_common *common)
 579{
 580        struct sk_buff *skb;
 581        struct rsi_mac_frame *mgmt_frame;
 582
 583        rsi_dbg(MGMT_TX_ZONE, "%s: Sending program BB/RF frame\n", __func__);
 584
 585        skb = dev_alloc_skb(FRAME_DESC_SZ);
 586        if (!skb) {
 587                rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
 588                        __func__);
 589                return -ENOMEM;
 590        }
 591
 592        memset(skb->data, 0, FRAME_DESC_SZ);
 593        mgmt_frame = (struct rsi_mac_frame *)skb->data;
 594
 595        mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
 596        mgmt_frame->desc_word[1] = cpu_to_le16(BBP_PROG_IN_TA);
 597        mgmt_frame->desc_word[4] = cpu_to_le16(common->endpoint);
 598
 599        if (common->rf_reset) {
 600                mgmt_frame->desc_word[7] =  cpu_to_le16(RF_RESET_ENABLE);
 601                rsi_dbg(MGMT_TX_ZONE, "%s: ===> RF RESET REQUEST SENT <===\n",
 602                        __func__);
 603                common->rf_reset = 0;
 604        }
 605        common->bb_rf_prog_count = 1;
 606        mgmt_frame->desc_word[7] |= cpu_to_le16(PUT_BBP_RESET |
 607                                     BBP_REG_WRITE | (RSI_RF_TYPE << 4));
 608        skb_put(skb, FRAME_DESC_SZ);
 609
 610        return rsi_send_internal_mgmt_frame(common, skb);
 611}
 612
 613/**
 614 * rsi_set_vap_capabilities() - This function send vap capability to firmware.
 615 * @common: Pointer to the driver private structure.
 616 * @opmode: Operating mode of device.
 617 *
 618 * Return: 0 on success, corresponding negative error code on failure.
 619 */
 620int rsi_set_vap_capabilities(struct rsi_common *common, enum opmode mode)
 621{
 622        struct sk_buff *skb = NULL;
 623        struct rsi_vap_caps *vap_caps;
 624        struct rsi_hw *adapter = common->priv;
 625        struct ieee80211_hw *hw = adapter->hw;
 626        struct ieee80211_conf *conf = &hw->conf;
 627        u16 vap_id = 0;
 628
 629        rsi_dbg(MGMT_TX_ZONE, "%s: Sending VAP capabilities frame\n", __func__);
 630
 631        skb = dev_alloc_skb(sizeof(struct rsi_vap_caps));
 632        if (!skb) {
 633                rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
 634                        __func__);
 635                return -ENOMEM;
 636        }
 637
 638        memset(skb->data, 0, sizeof(struct rsi_vap_caps));
 639        vap_caps = (struct rsi_vap_caps *)skb->data;
 640
 641        vap_caps->desc_word[0] = cpu_to_le16((sizeof(struct rsi_vap_caps) -
 642                                             FRAME_DESC_SZ) |
 643                                             (RSI_WIFI_MGMT_Q << 12));
 644        vap_caps->desc_word[1] = cpu_to_le16(VAP_CAPABILITIES);
 645        vap_caps->desc_word[4] = cpu_to_le16(mode |
 646                                             (common->channel_width << 8));
 647        vap_caps->desc_word[7] = cpu_to_le16((vap_id << 8) |
 648                                             (common->mac_id << 4) |
 649                                             common->radio_id);
 650
 651        memcpy(vap_caps->mac_addr, common->mac_addr, IEEE80211_ADDR_LEN);
 652        vap_caps->keep_alive_period = cpu_to_le16(90);
 653        vap_caps->frag_threshold = cpu_to_le16(IEEE80211_MAX_FRAG_THRESHOLD);
 654
 655        vap_caps->rts_threshold = cpu_to_le16(common->rts_threshold);
 656        vap_caps->default_mgmt_rate = cpu_to_le32(RSI_RATE_6);
 657
 658        if (common->band == IEEE80211_BAND_5GHZ) {
 659                vap_caps->default_ctrl_rate = cpu_to_le32(RSI_RATE_6);
 660                if (conf_is_ht40(&common->priv->hw->conf)) {
 661                        vap_caps->default_ctrl_rate |=
 662                                cpu_to_le32(FULL40M_ENABLE << 16);
 663                }
 664        } else {
 665                vap_caps->default_ctrl_rate = cpu_to_le32(RSI_RATE_1);
 666                if (conf_is_ht40_minus(conf))
 667                        vap_caps->default_ctrl_rate |=
 668                                cpu_to_le32(UPPER_20_ENABLE << 16);
 669                else if (conf_is_ht40_plus(conf))
 670                        vap_caps->default_ctrl_rate |=
 671                                cpu_to_le32(LOWER_20_ENABLE << 16);
 672        }
 673
 674        vap_caps->default_data_rate = 0;
 675        vap_caps->beacon_interval = cpu_to_le16(200);
 676        vap_caps->dtim_period = cpu_to_le16(4);
 677
 678        skb_put(skb, sizeof(*vap_caps));
 679
 680        return rsi_send_internal_mgmt_frame(common, skb);
 681}
 682
 683/**
 684 * rsi_hal_load_key() - This function is used to load keys within the firmware.
 685 * @common: Pointer to the driver private structure.
 686 * @data: Pointer to the key data.
 687 * @key_len: Key length to be loaded.
 688 * @key_type: Type of key: GROUP/PAIRWISE.
 689 * @key_id: Key index.
 690 * @cipher: Type of cipher used.
 691 *
 692 * Return: 0 on success, -1 on failure.
 693 */
 694int rsi_hal_load_key(struct rsi_common *common,
 695                     u8 *data,
 696                     u16 key_len,
 697                     u8 key_type,
 698                     u8 key_id,
 699                     u32 cipher)
 700{
 701        struct sk_buff *skb = NULL;
 702        struct rsi_set_key *set_key;
 703        u16 key_descriptor = 0;
 704
 705        rsi_dbg(MGMT_TX_ZONE, "%s: Sending load key frame\n", __func__);
 706
 707        skb = dev_alloc_skb(sizeof(struct rsi_set_key));
 708        if (!skb) {
 709                rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
 710                        __func__);
 711                return -ENOMEM;
 712        }
 713
 714        memset(skb->data, 0, sizeof(struct rsi_set_key));
 715        set_key = (struct rsi_set_key *)skb->data;
 716
 717        if ((cipher == WLAN_CIPHER_SUITE_WEP40) ||
 718            (cipher == WLAN_CIPHER_SUITE_WEP104)) {
 719                key_len += 1;
 720                key_descriptor |= BIT(2);
 721                if (key_len >= 13)
 722                        key_descriptor |= BIT(3);
 723        } else if (cipher != KEY_TYPE_CLEAR) {
 724                key_descriptor |= BIT(4);
 725                if (key_type == RSI_PAIRWISE_KEY)
 726                        key_id = 0;
 727                if (cipher == WLAN_CIPHER_SUITE_TKIP)
 728                        key_descriptor |= BIT(5);
 729        }
 730        key_descriptor |= (key_type | BIT(13) | (key_id << 14));
 731
 732        set_key->desc_word[0] = cpu_to_le16((sizeof(struct rsi_set_key) -
 733                                            FRAME_DESC_SZ) |
 734                                            (RSI_WIFI_MGMT_Q << 12));
 735        set_key->desc_word[1] = cpu_to_le16(SET_KEY_REQ);
 736        set_key->desc_word[4] = cpu_to_le16(key_descriptor);
 737
 738        if ((cipher == WLAN_CIPHER_SUITE_WEP40) ||
 739            (cipher == WLAN_CIPHER_SUITE_WEP104)) {
 740                memcpy(&set_key->key[key_id][1],
 741                       data,
 742                       key_len * 2);
 743        } else {
 744                memcpy(&set_key->key[0][0], data, key_len);
 745        }
 746
 747        memcpy(set_key->tx_mic_key, &data[16], 8);
 748        memcpy(set_key->rx_mic_key, &data[24], 8);
 749
 750        skb_put(skb, sizeof(struct rsi_set_key));
 751
 752        return rsi_send_internal_mgmt_frame(common, skb);
 753}
 754
 755/*
 756 * rsi_load_bootup_params() - This function send bootup params to the firmware.
 757 * @common: Pointer to the driver private structure.
 758 *
 759 * Return: 0 on success, corresponding error code on failure.
 760 */
 761static int rsi_load_bootup_params(struct rsi_common *common)
 762{
 763        struct sk_buff *skb;
 764        struct rsi_boot_params *boot_params;
 765
 766        rsi_dbg(MGMT_TX_ZONE, "%s: Sending boot params frame\n", __func__);
 767        skb = dev_alloc_skb(sizeof(struct rsi_boot_params));
 768        if (!skb) {
 769                rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
 770                        __func__);
 771                return -ENOMEM;
 772        }
 773
 774        memset(skb->data, 0, sizeof(struct rsi_boot_params));
 775        boot_params = (struct rsi_boot_params *)skb->data;
 776
 777        rsi_dbg(MGMT_TX_ZONE, "%s:\n", __func__);
 778
 779        if (common->channel_width == BW_40MHZ) {
 780                memcpy(&boot_params->bootup_params,
 781                       &boot_params_40,
 782                       sizeof(struct bootup_params));
 783                rsi_dbg(MGMT_TX_ZONE, "%s: Packet 40MHZ <=== %d\n", __func__,
 784                        UMAC_CLK_40BW);
 785                boot_params->desc_word[7] = cpu_to_le16(UMAC_CLK_40BW);
 786        } else {
 787                memcpy(&boot_params->bootup_params,
 788                       &boot_params_20,
 789                       sizeof(struct bootup_params));
 790                if (boot_params_20.valid != cpu_to_le32(VALID_20)) {
 791                        boot_params->desc_word[7] = cpu_to_le16(UMAC_CLK_20BW);
 792                        rsi_dbg(MGMT_TX_ZONE,
 793                                "%s: Packet 20MHZ <=== %d\n", __func__,
 794                                UMAC_CLK_20BW);
 795                } else {
 796                        boot_params->desc_word[7] = cpu_to_le16(UMAC_CLK_40MHZ);
 797                        rsi_dbg(MGMT_TX_ZONE,
 798                                "%s: Packet 20MHZ <=== %d\n", __func__,
 799                                UMAC_CLK_40MHZ);
 800                }
 801        }
 802
 803        /**
 804         * Bit{0:11} indicates length of the Packet
 805         * Bit{12:15} indicates host queue number
 806         */
 807        boot_params->desc_word[0] = cpu_to_le16(sizeof(struct bootup_params) |
 808                                    (RSI_WIFI_MGMT_Q << 12));
 809        boot_params->desc_word[1] = cpu_to_le16(BOOTUP_PARAMS_REQUEST);
 810
 811        skb_put(skb, sizeof(struct rsi_boot_params));
 812
 813        return rsi_send_internal_mgmt_frame(common, skb);
 814}
 815
 816/**
 817 * rsi_send_reset_mac() - This function prepares reset MAC request and sends an
 818 *                        internal management frame to indicate it to firmware.
 819 * @common: Pointer to the driver private structure.
 820 *
 821 * Return: 0 on success, corresponding error code on failure.
 822 */
 823static int rsi_send_reset_mac(struct rsi_common *common)
 824{
 825        struct sk_buff *skb;
 826        struct rsi_mac_frame *mgmt_frame;
 827
 828        rsi_dbg(MGMT_TX_ZONE, "%s: Sending reset MAC frame\n", __func__);
 829
 830        skb = dev_alloc_skb(FRAME_DESC_SZ);
 831        if (!skb) {
 832                rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
 833                        __func__);
 834                return -ENOMEM;
 835        }
 836
 837        memset(skb->data, 0, FRAME_DESC_SZ);
 838        mgmt_frame = (struct rsi_mac_frame *)skb->data;
 839
 840        mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
 841        mgmt_frame->desc_word[1] = cpu_to_le16(RESET_MAC_REQ);
 842        mgmt_frame->desc_word[4] = cpu_to_le16(RETRY_COUNT << 8);
 843
 844        skb_put(skb, FRAME_DESC_SZ);
 845
 846        return rsi_send_internal_mgmt_frame(common, skb);
 847}
 848
 849/**
 850 * rsi_band_check() - This function programs the band
 851 * @common: Pointer to the driver private structure.
 852 *
 853 * Return: 0 on success, corresponding error code on failure.
 854 */
 855int rsi_band_check(struct rsi_common *common)
 856{
 857        struct rsi_hw *adapter = common->priv;
 858        struct ieee80211_hw *hw = adapter->hw;
 859        u8 prev_bw = common->channel_width;
 860        u8 prev_ep = common->endpoint;
 861        struct ieee80211_channel *curchan = hw->conf.chandef.chan;
 862        int status = 0;
 863
 864        if (common->band != curchan->band) {
 865                common->rf_reset = 1;
 866                common->band = curchan->band;
 867        }
 868
 869        if ((hw->conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) ||
 870            (hw->conf.chandef.width == NL80211_CHAN_WIDTH_20))
 871                common->channel_width = BW_20MHZ;
 872        else
 873                common->channel_width = BW_40MHZ;
 874
 875        if (common->band == IEEE80211_BAND_2GHZ) {
 876                if (common->channel_width)
 877                        common->endpoint = EP_2GHZ_40MHZ;
 878                else
 879                        common->endpoint = EP_2GHZ_20MHZ;
 880        } else {
 881                if (common->channel_width)
 882                        common->endpoint = EP_5GHZ_40MHZ;
 883                else
 884                        common->endpoint = EP_5GHZ_20MHZ;
 885        }
 886
 887        if (common->endpoint != prev_ep) {
 888                status = rsi_program_bb_rf(common);
 889                if (status)
 890                        return status;
 891        }
 892
 893        if (common->channel_width != prev_bw) {
 894                status = rsi_load_bootup_params(common);
 895                if (status)
 896                        return status;
 897
 898                status = rsi_load_radio_caps(common);
 899                if (status)
 900                        return status;
 901        }
 902
 903        return status;
 904}
 905
 906/**
 907 * rsi_set_channel() - This function programs the channel.
 908 * @common: Pointer to the driver private structure.
 909 * @channel: Channel value to be set.
 910 *
 911 * Return: 0 on success, corresponding error code on failure.
 912 */
 913int rsi_set_channel(struct rsi_common *common, u16 channel)
 914{
 915        struct sk_buff *skb = NULL;
 916        struct rsi_mac_frame *mgmt_frame;
 917
 918        rsi_dbg(MGMT_TX_ZONE,
 919                "%s: Sending scan req frame\n", __func__);
 920
 921        skb = dev_alloc_skb(FRAME_DESC_SZ);
 922        if (!skb) {
 923                rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
 924                        __func__);
 925                return -ENOMEM;
 926        }
 927
 928        memset(skb->data, 0, FRAME_DESC_SZ);
 929        mgmt_frame = (struct rsi_mac_frame *)skb->data;
 930
 931        mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
 932        mgmt_frame->desc_word[1] = cpu_to_le16(SCAN_REQUEST);
 933        mgmt_frame->desc_word[4] = cpu_to_le16(channel);
 934
 935        mgmt_frame->desc_word[7] = cpu_to_le16(PUT_BBP_RESET |
 936                                               BBP_REG_WRITE |
 937                                               (RSI_RF_TYPE << 4));
 938
 939        mgmt_frame->desc_word[5] = cpu_to_le16(0x01);
 940        mgmt_frame->desc_word[6] = cpu_to_le16(0x12);
 941
 942        if (common->channel_width == BW_40MHZ)
 943                mgmt_frame->desc_word[5] |= cpu_to_le16(0x1 << 8);
 944
 945        common->channel = channel;
 946
 947        skb_put(skb, FRAME_DESC_SZ);
 948
 949        return rsi_send_internal_mgmt_frame(common, skb);
 950}
 951
 952/**
 953 * rsi_compare() - This function is used to compare two integers
 954 * @a: pointer to the first integer
 955 * @b: pointer to the second integer
 956 *
 957 * Return: 0 if both are equal, -1 if the first is smaller, else 1
 958 */
 959static int rsi_compare(const void *a, const void *b)
 960{
 961        u16 _a = *(const u16 *)(a);
 962        u16 _b = *(const u16 *)(b);
 963
 964        if (_a > _b)
 965                return -1;
 966
 967        if (_a < _b)
 968                return 1;
 969
 970        return 0;
 971}
 972
 973/**
 974 * rsi_map_rates() - This function is used to map selected rates to hw rates.
 975 * @rate: The standard rate to be mapped.
 976 * @offset: Offset that will be returned.
 977 *
 978 * Return: 0 if it is a mcs rate, else 1
 979 */
 980static bool rsi_map_rates(u16 rate, int *offset)
 981{
 982        int kk;
 983        for (kk = 0; kk < ARRAY_SIZE(rsi_mcsrates); kk++) {
 984                if (rate == mcs[kk]) {
 985                        *offset = kk;
 986                        return false;
 987                }
 988        }
 989
 990        for (kk = 0; kk < ARRAY_SIZE(rsi_rates); kk++) {
 991                if (rate == rsi_rates[kk].bitrate / 5) {
 992                        *offset = kk;
 993                        break;
 994                }
 995        }
 996        return true;
 997}
 998
 999/**
1000 * rsi_send_auto_rate_request() - This function is to set rates for connection
1001 *                                and send autorate request to firmware.
1002 * @common: Pointer to the driver private structure.
1003 *
1004 * Return: 0 on success, corresponding error code on failure.
1005 */
1006static int rsi_send_auto_rate_request(struct rsi_common *common)
1007{
1008        struct sk_buff *skb;
1009        struct rsi_auto_rate *auto_rate;
1010        int ii = 0, jj = 0, kk = 0;
1011        struct ieee80211_hw *hw = common->priv->hw;
1012        u8 band = hw->conf.chandef.chan->band;
1013        u8 num_supported_rates = 0;
1014        u8 rate_table_offset, rate_offset = 0;
1015        u32 rate_bitmap = common->bitrate_mask[band];
1016
1017        u16 *selected_rates, min_rate;
1018
1019        skb = dev_alloc_skb(sizeof(struct rsi_auto_rate));
1020        if (!skb) {
1021                rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
1022                        __func__);
1023                return -ENOMEM;
1024        }
1025
1026        selected_rates = kzalloc(2 * RSI_TBL_SZ, GFP_KERNEL);
1027        if (!selected_rates) {
1028                rsi_dbg(ERR_ZONE, "%s: Failed in allocation of mem\n",
1029                        __func__);
1030                dev_kfree_skb(skb);
1031                return -ENOMEM;
1032        }
1033
1034        memset(skb->data, 0, sizeof(struct rsi_auto_rate));
1035
1036        auto_rate = (struct rsi_auto_rate *)skb->data;
1037
1038        auto_rate->aarf_rssi = cpu_to_le16(((u16)3 << 6) | (u16)(18 & 0x3f));
1039        auto_rate->collision_tolerance = cpu_to_le16(3);
1040        auto_rate->failure_limit = cpu_to_le16(3);
1041        auto_rate->initial_boundary = cpu_to_le16(3);
1042        auto_rate->max_threshold_limt = cpu_to_le16(27);
1043
1044        auto_rate->desc_word[1] = cpu_to_le16(AUTO_RATE_IND);
1045
1046        if (common->channel_width == BW_40MHZ)
1047                auto_rate->desc_word[7] |= cpu_to_le16(1);
1048
1049        if (band == IEEE80211_BAND_2GHZ) {
1050                min_rate = RSI_RATE_1;
1051                rate_table_offset = 0;
1052        } else {
1053                min_rate = RSI_RATE_6;
1054                rate_table_offset = 4;
1055        }
1056
1057        for (ii = 0, jj = 0;
1058             ii < (ARRAY_SIZE(rsi_rates) - rate_table_offset); ii++) {
1059                if (rate_bitmap & BIT(ii)) {
1060                        selected_rates[jj++] =
1061                        (rsi_rates[ii + rate_table_offset].bitrate / 5);
1062                        rate_offset++;
1063                }
1064        }
1065        num_supported_rates = jj;
1066
1067        if (common->vif_info[0].is_ht) {
1068                for (ii = 0; ii < ARRAY_SIZE(mcs); ii++)
1069                        selected_rates[jj++] = mcs[ii];
1070                num_supported_rates += ARRAY_SIZE(mcs);
1071                rate_offset += ARRAY_SIZE(mcs);
1072        }
1073
1074        sort(selected_rates, jj, sizeof(u16), &rsi_compare, NULL);
1075
1076        /* mapping the rates to RSI rates */
1077        for (ii = 0; ii < jj; ii++) {
1078                if (rsi_map_rates(selected_rates[ii], &kk)) {
1079                        auto_rate->supported_rates[ii] =
1080                                cpu_to_le16(rsi_rates[kk].hw_value);
1081                } else {
1082                        auto_rate->supported_rates[ii] =
1083                                cpu_to_le16(rsi_mcsrates[kk]);
1084                }
1085        }
1086
1087        /* loading HT rates in the bottom half of the auto rate table */
1088        if (common->vif_info[0].is_ht) {
1089                for (ii = rate_offset, kk = ARRAY_SIZE(rsi_mcsrates) - 1;
1090                     ii < rate_offset + 2 * ARRAY_SIZE(rsi_mcsrates); ii++) {
1091                        if (common->vif_info[0].sgi ||
1092                            conf_is_ht40(&common->priv->hw->conf))
1093                                auto_rate->supported_rates[ii++] =
1094                                        cpu_to_le16(rsi_mcsrates[kk] | BIT(9));
1095                        auto_rate->supported_rates[ii] =
1096                                cpu_to_le16(rsi_mcsrates[kk--]);
1097                }
1098
1099                for (; ii < (RSI_TBL_SZ - 1); ii++) {
1100                        auto_rate->supported_rates[ii] =
1101                                cpu_to_le16(rsi_mcsrates[0]);
1102                }
1103        }
1104
1105        for (; ii < RSI_TBL_SZ; ii++)
1106                auto_rate->supported_rates[ii] = cpu_to_le16(min_rate);
1107
1108        auto_rate->num_supported_rates = cpu_to_le16(num_supported_rates * 2);
1109        auto_rate->moderate_rate_inx = cpu_to_le16(num_supported_rates / 2);
1110        auto_rate->desc_word[7] |= cpu_to_le16(0 << 8);
1111        num_supported_rates *= 2;
1112
1113        auto_rate->desc_word[0] = cpu_to_le16((sizeof(*auto_rate) -
1114                                               FRAME_DESC_SZ) |
1115                                               (RSI_WIFI_MGMT_Q << 12));
1116
1117        skb_put(skb,
1118                sizeof(struct rsi_auto_rate));
1119        kfree(selected_rates);
1120
1121        return rsi_send_internal_mgmt_frame(common, skb);
1122}
1123
1124/**
1125 * rsi_inform_bss_status() - This function informs about bss status with the
1126 *                           help of sta notify params by sending an internal
1127 *                           management frame to firmware.
1128 * @common: Pointer to the driver private structure.
1129 * @status: Bss status type.
1130 * @bssid: Bssid.
1131 * @qos_enable: Qos is enabled.
1132 * @aid: Aid (unique for all STAs).
1133 *
1134 * Return: None.
1135 */
1136void rsi_inform_bss_status(struct rsi_common *common,
1137                           u8 status,
1138                           const unsigned char *bssid,
1139                           u8 qos_enable,
1140                           u16 aid)
1141{
1142        if (status) {
1143                rsi_hal_send_sta_notify_frame(common,
1144                                              RSI_IFTYPE_STATION,
1145                                              STA_CONNECTED,
1146                                              bssid,
1147                                              qos_enable,
1148                                              aid);
1149                if (common->min_rate == 0xffff)
1150                        rsi_send_auto_rate_request(common);
1151        } else {
1152                rsi_hal_send_sta_notify_frame(common,
1153                                              RSI_IFTYPE_STATION,
1154                                              STA_DISCONNECTED,
1155                                              bssid,
1156                                              qos_enable,
1157                                              aid);
1158        }
1159}
1160
1161/**
1162 * rsi_eeprom_read() - This function sends a frame to read the mac address
1163 *                     from the eeprom.
1164 * @common: Pointer to the driver private structure.
1165 *
1166 * Return: 0 on success, -1 on failure.
1167 */
1168static int rsi_eeprom_read(struct rsi_common *common)
1169{
1170        struct rsi_mac_frame *mgmt_frame;
1171        struct sk_buff *skb;
1172
1173        rsi_dbg(MGMT_TX_ZONE, "%s: Sending EEPROM read req frame\n", __func__);
1174
1175        skb = dev_alloc_skb(FRAME_DESC_SZ);
1176        if (!skb) {
1177                rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
1178                        __func__);
1179                return -ENOMEM;
1180        }
1181
1182        memset(skb->data, 0, FRAME_DESC_SZ);
1183        mgmt_frame = (struct rsi_mac_frame *)skb->data;
1184
1185        /* FrameType */
1186        mgmt_frame->desc_word[1] = cpu_to_le16(EEPROM_READ_TYPE);
1187        mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
1188        /* Number of bytes to read */
1189        mgmt_frame->desc_word[3] = cpu_to_le16(ETH_ALEN +
1190                                               WLAN_MAC_MAGIC_WORD_LEN +
1191                                               WLAN_HOST_MODE_LEN +
1192                                               WLAN_FW_VERSION_LEN);
1193        /* Address to read */
1194        mgmt_frame->desc_word[4] = cpu_to_le16(WLAN_MAC_EEPROM_ADDR);
1195
1196        skb_put(skb, FRAME_DESC_SZ);
1197
1198        return rsi_send_internal_mgmt_frame(common, skb);
1199}
1200
1201/**
1202 * This function sends a frame to block/unblock
1203 * data queues in the firmware
1204 *
1205 * @param common Pointer to the driver private structure.
1206 * @param block event - block if true, unblock if false
1207 * @return 0 on success, -1 on failure.
1208 */
1209int rsi_send_block_unblock_frame(struct rsi_common *common, bool block_event)
1210{
1211        struct rsi_mac_frame *mgmt_frame;
1212        struct sk_buff *skb;
1213
1214        rsi_dbg(MGMT_TX_ZONE, "%s: Sending block/unblock frame\n", __func__);
1215
1216        skb = dev_alloc_skb(FRAME_DESC_SZ);
1217        if (!skb) {
1218                rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
1219                        __func__);
1220                return -ENOMEM;
1221        }
1222
1223        memset(skb->data, 0, FRAME_DESC_SZ);
1224        mgmt_frame = (struct rsi_mac_frame *)skb->data;
1225
1226        mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
1227        mgmt_frame->desc_word[1] = cpu_to_le16(BLOCK_HW_QUEUE);
1228
1229        if (block_event) {
1230                rsi_dbg(INFO_ZONE, "blocking the data qs\n");
1231                mgmt_frame->desc_word[4] = cpu_to_le16(0xf);
1232        } else {
1233                rsi_dbg(INFO_ZONE, "unblocking the data qs\n");
1234                mgmt_frame->desc_word[5] = cpu_to_le16(0xf);
1235        }
1236
1237        skb_put(skb, FRAME_DESC_SZ);
1238
1239        return rsi_send_internal_mgmt_frame(common, skb);
1240
1241}
1242
1243
1244/**
1245 * rsi_handle_ta_confirm_type() - This function handles the confirm frames.
1246 * @common: Pointer to the driver private structure.
1247 * @msg: Pointer to received packet.
1248 *
1249 * Return: 0 on success, -1 on failure.
1250 */
1251static int rsi_handle_ta_confirm_type(struct rsi_common *common,
1252                                      u8 *msg)
1253{
1254        u8 sub_type = (msg[15] & 0xff);
1255
1256        switch (sub_type) {
1257        case BOOTUP_PARAMS_REQUEST:
1258                rsi_dbg(FSM_ZONE, "%s: Boot up params confirm received\n",
1259                        __func__);
1260                if (common->fsm_state == FSM_BOOT_PARAMS_SENT) {
1261                        if (rsi_eeprom_read(common)) {
1262                                common->fsm_state = FSM_CARD_NOT_READY;
1263                                goto out;
1264                        } else {
1265                                common->fsm_state = FSM_EEPROM_READ_MAC_ADDR;
1266                        }
1267                } else {
1268                        rsi_dbg(INFO_ZONE,
1269                                "%s: Received bootup params cfm in %d state\n",
1270                                 __func__, common->fsm_state);
1271                        return 0;
1272                }
1273                break;
1274
1275        case EEPROM_READ_TYPE:
1276                if (common->fsm_state == FSM_EEPROM_READ_MAC_ADDR) {
1277                        if (msg[16] == MAGIC_WORD) {
1278                                u8 offset = (FRAME_DESC_SZ + WLAN_HOST_MODE_LEN
1279                                             + WLAN_MAC_MAGIC_WORD_LEN);
1280                                memcpy(common->mac_addr,
1281                                       &msg[offset],
1282                                       ETH_ALEN);
1283                                memcpy(&common->fw_ver,
1284                                       &msg[offset + ETH_ALEN],
1285                                       sizeof(struct version_info));
1286
1287                        } else {
1288                                common->fsm_state = FSM_CARD_NOT_READY;
1289                                break;
1290                        }
1291                        if (rsi_send_reset_mac(common))
1292                                goto out;
1293                        else
1294                                common->fsm_state = FSM_RESET_MAC_SENT;
1295                } else {
1296                        rsi_dbg(ERR_ZONE,
1297                                "%s: Received eeprom mac addr in %d state\n",
1298                                __func__, common->fsm_state);
1299                        return 0;
1300                }
1301                break;
1302
1303        case RESET_MAC_REQ:
1304                if (common->fsm_state == FSM_RESET_MAC_SENT) {
1305                        rsi_dbg(FSM_ZONE, "%s: Reset MAC cfm received\n",
1306                                __func__);
1307
1308                        if (rsi_load_radio_caps(common))
1309                                goto out;
1310                        else
1311                                common->fsm_state = FSM_RADIO_CAPS_SENT;
1312                } else {
1313                        rsi_dbg(ERR_ZONE,
1314                                "%s: Received reset mac cfm in %d state\n",
1315                                 __func__, common->fsm_state);
1316                        return 0;
1317                }
1318                break;
1319
1320        case RADIO_CAPABILITIES:
1321                if (common->fsm_state == FSM_RADIO_CAPS_SENT) {
1322                        common->rf_reset = 1;
1323                        if (rsi_program_bb_rf(common)) {
1324                                goto out;
1325                        } else {
1326                                common->fsm_state = FSM_BB_RF_PROG_SENT;
1327                                rsi_dbg(FSM_ZONE, "%s: Radio cap cfm received\n",
1328                                        __func__);
1329                        }
1330                } else {
1331                        rsi_dbg(INFO_ZONE,
1332                                "%s: Received radio caps cfm in %d state\n",
1333                                 __func__, common->fsm_state);
1334                        return 0;
1335                }
1336                break;
1337
1338        case BB_PROG_VALUES_REQUEST:
1339        case RF_PROG_VALUES_REQUEST:
1340        case BBP_PROG_IN_TA:
1341                rsi_dbg(FSM_ZONE, "%s: BB/RF cfm received\n", __func__);
1342                if (common->fsm_state == FSM_BB_RF_PROG_SENT) {
1343                        common->bb_rf_prog_count--;
1344                        if (!common->bb_rf_prog_count) {
1345                                common->fsm_state = FSM_MAC_INIT_DONE;
1346                                return rsi_mac80211_attach(common);
1347                        }
1348                } else {
1349                        rsi_dbg(INFO_ZONE,
1350                                "%s: Received bbb_rf cfm in %d state\n",
1351                                 __func__, common->fsm_state);
1352                        return 0;
1353                }
1354                break;
1355
1356        default:
1357                rsi_dbg(INFO_ZONE, "%s: Invalid TA confirm pkt received\n",
1358                        __func__);
1359                break;
1360        }
1361        return 0;
1362out:
1363        rsi_dbg(ERR_ZONE, "%s: Unable to send pkt/Invalid frame received\n",
1364                __func__);
1365        return -EINVAL;
1366}
1367
1368/**
1369 * rsi_mgmt_pkt_recv() - This function processes the management packets
1370 *                       recieved from the hardware.
1371 * @common: Pointer to the driver private structure.
1372 * @msg: Pointer to the received packet.
1373 *
1374 * Return: 0 on success, -1 on failure.
1375 */
1376int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg)
1377{
1378        s32 msg_len = (le16_to_cpu(*(__le16 *)&msg[0]) & 0x0fff);
1379        u16 msg_type = (msg[2]);
1380        int ret;
1381
1382        rsi_dbg(FSM_ZONE, "%s: Msg Len: %d, Msg Type: %4x\n",
1383                __func__, msg_len, msg_type);
1384
1385        if (msg_type == TA_CONFIRM_TYPE) {
1386                return rsi_handle_ta_confirm_type(common, msg);
1387        } else if (msg_type == CARD_READY_IND) {
1388                rsi_dbg(FSM_ZONE, "%s: Card ready indication received\n",
1389                        __func__);
1390                if (common->fsm_state == FSM_CARD_NOT_READY) {
1391                        rsi_set_default_parameters(common);
1392
1393                        ret = rsi_load_bootup_params(common);
1394                        if (ret)
1395                                return ret;
1396                        else
1397                                common->fsm_state = FSM_BOOT_PARAMS_SENT;
1398                } else {
1399                        return -EINVAL;
1400                }
1401        } else if (msg_type == TX_STATUS_IND) {
1402                if (msg[15] == PROBEREQ_CONFIRM) {
1403                        common->mgmt_q_block = false;
1404                        rsi_dbg(FSM_ZONE, "%s: Probe confirm received\n",
1405                                __func__);
1406                }
1407        } else {
1408                return rsi_mgmt_pkt_to_core(common, msg, msg_len, msg_type);
1409        }
1410        return 0;
1411}
1412