.. | .. |
---|
1 | | -/** |
---|
| 1 | +/* |
---|
2 | 2 | * Copyright (c) 2014 Redpine Signals Inc. |
---|
3 | 3 | * |
---|
4 | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
---|
.. | .. |
---|
15 | 15 | */ |
---|
16 | 16 | |
---|
17 | 17 | #include <linux/etherdevice.h> |
---|
| 18 | +#include <linux/timer.h> |
---|
18 | 19 | #include "rsi_mgmt.h" |
---|
19 | 20 | #include "rsi_common.h" |
---|
20 | 21 | #include "rsi_ps.h" |
---|
.. | .. |
---|
208 | 209 | .beacon_resedue_alg_en = 0, |
---|
209 | 210 | }; |
---|
210 | 211 | |
---|
| 212 | +static struct bootup_params_9116 boot_params_9116_20 = { |
---|
| 213 | + .magic_number = cpu_to_le16(LOADED_TOKEN), |
---|
| 214 | + .valid = cpu_to_le32(VALID_20), |
---|
| 215 | + .device_clk_info_9116 = {{ |
---|
| 216 | + .pll_config_9116_g = { |
---|
| 217 | + .pll_ctrl_set_reg = cpu_to_le16(0xd518), |
---|
| 218 | + .pll_ctrl_clr_reg = cpu_to_le16(0x2ae7), |
---|
| 219 | + .pll_modem_conig_reg = cpu_to_le16(0x2000), |
---|
| 220 | + .soc_clk_config_reg = cpu_to_le16(0x0c18), |
---|
| 221 | + .adc_dac_strm1_config_reg = cpu_to_le16(0x1100), |
---|
| 222 | + .adc_dac_strm2_config_reg = cpu_to_le16(0x6600), |
---|
| 223 | + }, |
---|
| 224 | + .switch_clk_9116_g = { |
---|
| 225 | + .switch_clk_info = |
---|
| 226 | + cpu_to_le32((RSI_SWITCH_TASS_CLK | |
---|
| 227 | + RSI_SWITCH_WLAN_BBP_LMAC_CLK_REG | |
---|
| 228 | + RSI_SWITCH_BBP_LMAC_CLK_REG)), |
---|
| 229 | + .tass_clock_reg = cpu_to_le32(0x083C0503), |
---|
| 230 | + .wlan_bbp_lmac_clk_reg_val = cpu_to_le32(0x01042001), |
---|
| 231 | + .zbbt_bbp_lmac_clk_reg_val = cpu_to_le32(0x02010001), |
---|
| 232 | + .bbp_lmac_clk_en_val = cpu_to_le32(0x0000003b), |
---|
| 233 | + } |
---|
| 234 | + }, |
---|
| 235 | + }, |
---|
| 236 | +}; |
---|
| 237 | + |
---|
| 238 | +static struct bootup_params_9116 boot_params_9116_40 = { |
---|
| 239 | + .magic_number = cpu_to_le16(LOADED_TOKEN), |
---|
| 240 | + .valid = cpu_to_le32(VALID_40), |
---|
| 241 | + .device_clk_info_9116 = {{ |
---|
| 242 | + .pll_config_9116_g = { |
---|
| 243 | + .pll_ctrl_set_reg = cpu_to_le16(0xd518), |
---|
| 244 | + .pll_ctrl_clr_reg = cpu_to_le16(0x2ae7), |
---|
| 245 | + .pll_modem_conig_reg = cpu_to_le16(0x3000), |
---|
| 246 | + .soc_clk_config_reg = cpu_to_le16(0x0c18), |
---|
| 247 | + .adc_dac_strm1_config_reg = cpu_to_le16(0x0000), |
---|
| 248 | + .adc_dac_strm2_config_reg = cpu_to_le16(0x6600), |
---|
| 249 | + }, |
---|
| 250 | + .switch_clk_9116_g = { |
---|
| 251 | + .switch_clk_info = |
---|
| 252 | + cpu_to_le32((RSI_SWITCH_TASS_CLK | |
---|
| 253 | + RSI_SWITCH_WLAN_BBP_LMAC_CLK_REG | |
---|
| 254 | + RSI_SWITCH_BBP_LMAC_CLK_REG | |
---|
| 255 | + RSI_MODEM_CLK_160MHZ)), |
---|
| 256 | + .tass_clock_reg = cpu_to_le32(0x083C0503), |
---|
| 257 | + .wlan_bbp_lmac_clk_reg_val = cpu_to_le32(0x01042002), |
---|
| 258 | + .zbbt_bbp_lmac_clk_reg_val = cpu_to_le32(0x04010002), |
---|
| 259 | + .bbp_lmac_clk_en_val = cpu_to_le32(0x0000003b), |
---|
| 260 | + } |
---|
| 261 | + }, |
---|
| 262 | + }, |
---|
| 263 | +}; |
---|
| 264 | + |
---|
211 | 265 | static u16 mcs[] = {13, 26, 39, 52, 78, 104, 117, 130}; |
---|
212 | 266 | |
---|
213 | 267 | /** |
---|
.. | .. |
---|
234 | 288 | common->obm_ant_sel_val = 2; |
---|
235 | 289 | common->beacon_interval = RSI_BEACON_INTERVAL; |
---|
236 | 290 | common->dtim_cnt = RSI_DTIM_COUNT; |
---|
| 291 | + common->w9116_features.pll_mode = 0x0; |
---|
| 292 | + common->w9116_features.rf_type = 1; |
---|
| 293 | + common->w9116_features.wireless_mode = 0; |
---|
| 294 | + common->w9116_features.enable_ppe = 0; |
---|
| 295 | + common->w9116_features.afe_type = 1; |
---|
| 296 | + common->w9116_features.dpd = 0; |
---|
| 297 | + common->w9116_features.sifs_tx_enable = 0; |
---|
| 298 | + common->w9116_features.ps_options = 0; |
---|
| 299 | +} |
---|
| 300 | + |
---|
| 301 | +void init_bgscan_params(struct rsi_common *common) |
---|
| 302 | +{ |
---|
| 303 | + memset((u8 *)&common->bgscan, 0, sizeof(struct rsi_bgscan_params)); |
---|
| 304 | + common->bgscan.bgscan_threshold = RSI_DEF_BGSCAN_THRLD; |
---|
| 305 | + common->bgscan.roam_threshold = RSI_DEF_ROAM_THRLD; |
---|
| 306 | + common->bgscan.bgscan_periodicity = RSI_BGSCAN_PERIODICITY; |
---|
| 307 | + common->bgscan.num_bgscan_channels = 0; |
---|
| 308 | + common->bgscan.two_probe = 1; |
---|
| 309 | + common->bgscan.active_scan_duration = RSI_ACTIVE_SCAN_TIME; |
---|
| 310 | + common->bgscan.passive_scan_duration = RSI_PASSIVE_SCAN_TIME; |
---|
237 | 311 | } |
---|
238 | 312 | |
---|
239 | 313 | /** |
---|
.. | .. |
---|
350 | 424 | } |
---|
351 | 425 | radio_caps->radio_info |= radio_id; |
---|
352 | 426 | |
---|
| 427 | + if (adapter->device_model == RSI_DEV_9116 && |
---|
| 428 | + common->channel_width == BW_20MHZ) |
---|
| 429 | + radio_caps->radio_cfg_info &= ~0x3; |
---|
| 430 | + |
---|
353 | 431 | radio_caps->sifs_tx_11n = cpu_to_le16(SIFS_TX_11N_VALUE); |
---|
354 | 432 | radio_caps->sifs_tx_11b = cpu_to_le16(SIFS_TX_11B_VALUE); |
---|
355 | 433 | radio_caps->slot_rx_11n = cpu_to_le16(SHORT_SLOT_VALUE); |
---|
.. | .. |
---|
365 | 443 | } |
---|
366 | 444 | |
---|
367 | 445 | for (ii = 0; ii < NUM_EDCA_QUEUES; ii++) { |
---|
368 | | - radio_caps->qos_params[ii].cont_win_min_q = |
---|
369 | | - cpu_to_le16(common->edca_params[ii].cw_min); |
---|
370 | | - radio_caps->qos_params[ii].cont_win_max_q = |
---|
371 | | - cpu_to_le16(common->edca_params[ii].cw_max); |
---|
372 | | - radio_caps->qos_params[ii].aifsn_val_q = |
---|
373 | | - cpu_to_le16((common->edca_params[ii].aifs) << 8); |
---|
374 | | - radio_caps->qos_params[ii].txop_q = |
---|
375 | | - cpu_to_le16(common->edca_params[ii].txop); |
---|
| 446 | + if (common->edca_params[ii].cw_max > 0) { |
---|
| 447 | + radio_caps->qos_params[ii].cont_win_min_q = |
---|
| 448 | + cpu_to_le16(common->edca_params[ii].cw_min); |
---|
| 449 | + radio_caps->qos_params[ii].cont_win_max_q = |
---|
| 450 | + cpu_to_le16(common->edca_params[ii].cw_max); |
---|
| 451 | + radio_caps->qos_params[ii].aifsn_val_q = |
---|
| 452 | + cpu_to_le16(common->edca_params[ii].aifs << 8); |
---|
| 453 | + radio_caps->qos_params[ii].txop_q = |
---|
| 454 | + cpu_to_le16(common->edca_params[ii].txop); |
---|
| 455 | + } |
---|
376 | 456 | } |
---|
377 | 457 | |
---|
378 | 458 | radio_caps->qos_params[BROADCAST_HW_Q].txop_q = cpu_to_le16(0xffff); |
---|
.. | .. |
---|
396 | 476 | * rsi_mgmt_pkt_to_core() - This function is the entry point for Mgmt module. |
---|
397 | 477 | * @common: Pointer to the driver private structure. |
---|
398 | 478 | * @msg: Pointer to received packet. |
---|
399 | | - * @msg_len: Length of the recieved packet. |
---|
400 | | - * @type: Type of recieved packet. |
---|
| 479 | + * @msg_len: Length of the received packet. |
---|
401 | 480 | * |
---|
402 | 481 | * Return: 0 on success, -1 on failure. |
---|
403 | 482 | */ |
---|
.. | .. |
---|
448 | 527 | * @bssid: bssid. |
---|
449 | 528 | * @qos_enable: Qos is enabled. |
---|
450 | 529 | * @aid: Aid (unique for all STA). |
---|
| 530 | + * @sta_id: station id. |
---|
| 531 | + * @vif: Pointer to the ieee80211_vif structure. |
---|
451 | 532 | * |
---|
452 | 533 | * Return: status: 0 on success, corresponding negative error code on failure. |
---|
453 | 534 | */ |
---|
.. | .. |
---|
523 | 604 | * @ssn: ssn. |
---|
524 | 605 | * @buf_size: buffer size. |
---|
525 | 606 | * @event: notification about station connection. |
---|
| 607 | + * @sta_id: station id. |
---|
526 | 608 | * |
---|
527 | 609 | * Return: 0 on success, corresponding negative error code on failure. |
---|
528 | 610 | */ |
---|
.. | .. |
---|
619 | 701 | /** |
---|
620 | 702 | * rsi_set_vap_capabilities() - This function send vap capability to firmware. |
---|
621 | 703 | * @common: Pointer to the driver private structure. |
---|
622 | | - * @opmode: Operating mode of device. |
---|
| 704 | + * @mode: Operating mode of device. |
---|
| 705 | + * @mac_addr: MAC address |
---|
| 706 | + * @vap_id: Rate information - offset and mask |
---|
| 707 | + * @vap_status: VAP status - ADD, DELETE or UPDATE |
---|
623 | 708 | * |
---|
624 | 709 | * Return: 0 on success, corresponding negative error code on failure. |
---|
625 | 710 | */ |
---|
.. | .. |
---|
700 | 785 | * @key_type: Type of key: GROUP/PAIRWISE. |
---|
701 | 786 | * @key_id: Key index. |
---|
702 | 787 | * @cipher: Type of cipher used. |
---|
| 788 | + * @sta_id: Station id. |
---|
| 789 | + * @vif: Pointer to the ieee80211_vif structure. |
---|
703 | 790 | * |
---|
704 | 791 | * Return: 0 on success, -1 on failure. |
---|
705 | 792 | */ |
---|
.. | .. |
---|
880 | 967 | return rsi_send_internal_mgmt_frame(common, skb); |
---|
881 | 968 | } |
---|
882 | 969 | |
---|
| 970 | +static int rsi_load_9116_bootup_params(struct rsi_common *common) |
---|
| 971 | +{ |
---|
| 972 | + struct sk_buff *skb; |
---|
| 973 | + struct rsi_boot_params_9116 *boot_params; |
---|
| 974 | + |
---|
| 975 | + rsi_dbg(MGMT_TX_ZONE, "%s: Sending boot params frame\n", __func__); |
---|
| 976 | + |
---|
| 977 | + skb = dev_alloc_skb(sizeof(struct rsi_boot_params_9116)); |
---|
| 978 | + if (!skb) |
---|
| 979 | + return -ENOMEM; |
---|
| 980 | + memset(skb->data, 0, sizeof(struct rsi_boot_params)); |
---|
| 981 | + boot_params = (struct rsi_boot_params_9116 *)skb->data; |
---|
| 982 | + |
---|
| 983 | + if (common->channel_width == BW_40MHZ) { |
---|
| 984 | + memcpy(&boot_params->bootup_params, |
---|
| 985 | + &boot_params_9116_40, |
---|
| 986 | + sizeof(struct bootup_params_9116)); |
---|
| 987 | + rsi_dbg(MGMT_TX_ZONE, "%s: Packet 40MHZ <=== %d\n", __func__, |
---|
| 988 | + UMAC_CLK_40BW); |
---|
| 989 | + boot_params->umac_clk = cpu_to_le16(UMAC_CLK_40BW); |
---|
| 990 | + } else { |
---|
| 991 | + memcpy(&boot_params->bootup_params, |
---|
| 992 | + &boot_params_9116_20, |
---|
| 993 | + sizeof(struct bootup_params_9116)); |
---|
| 994 | + if (boot_params_20.valid != cpu_to_le32(VALID_20)) { |
---|
| 995 | + boot_params->umac_clk = cpu_to_le16(UMAC_CLK_20BW); |
---|
| 996 | + rsi_dbg(MGMT_TX_ZONE, |
---|
| 997 | + "%s: Packet 20MHZ <=== %d\n", __func__, |
---|
| 998 | + UMAC_CLK_20BW); |
---|
| 999 | + } else { |
---|
| 1000 | + boot_params->umac_clk = cpu_to_le16(UMAC_CLK_40MHZ); |
---|
| 1001 | + rsi_dbg(MGMT_TX_ZONE, |
---|
| 1002 | + "%s: Packet 20MHZ <=== %d\n", __func__, |
---|
| 1003 | + UMAC_CLK_40MHZ); |
---|
| 1004 | + } |
---|
| 1005 | + } |
---|
| 1006 | + rsi_set_len_qno(&boot_params->desc_dword0.len_qno, |
---|
| 1007 | + sizeof(struct bootup_params_9116), RSI_WIFI_MGMT_Q); |
---|
| 1008 | + boot_params->desc_dword0.frame_type = BOOTUP_PARAMS_REQUEST; |
---|
| 1009 | + skb_put(skb, sizeof(struct rsi_boot_params_9116)); |
---|
| 1010 | + |
---|
| 1011 | + return rsi_send_internal_mgmt_frame(common, skb); |
---|
| 1012 | +} |
---|
| 1013 | + |
---|
883 | 1014 | /** |
---|
884 | 1015 | * rsi_send_reset_mac() - This function prepares reset MAC request and sends an |
---|
885 | 1016 | * internal management frame to indicate it to firmware. |
---|
.. | .. |
---|
908 | 1039 | mgmt_frame->desc_word[1] = cpu_to_le16(RESET_MAC_REQ); |
---|
909 | 1040 | mgmt_frame->desc_word[4] = cpu_to_le16(RETRY_COUNT << 8); |
---|
910 | 1041 | |
---|
| 1042 | +#define RSI_9116_DEF_TA_AGGR 3 |
---|
| 1043 | + if (common->priv->device_model == RSI_DEV_9116) |
---|
| 1044 | + mgmt_frame->desc_word[3] |= |
---|
| 1045 | + cpu_to_le16(RSI_9116_DEF_TA_AGGR << 8); |
---|
| 1046 | + |
---|
911 | 1047 | skb_put(skb, FRAME_DESC_SZ); |
---|
912 | 1048 | |
---|
913 | 1049 | return rsi_send_internal_mgmt_frame(common, skb); |
---|
.. | .. |
---|
916 | 1052 | /** |
---|
917 | 1053 | * rsi_band_check() - This function programs the band |
---|
918 | 1054 | * @common: Pointer to the driver private structure. |
---|
| 1055 | + * @curchan: Pointer to the current channel structure. |
---|
919 | 1056 | * |
---|
920 | 1057 | * Return: 0 on success, corresponding error code on failure. |
---|
921 | 1058 | */ |
---|
.. | .. |
---|
958 | 1095 | } |
---|
959 | 1096 | |
---|
960 | 1097 | if (common->channel_width != prev_bw) { |
---|
961 | | - status = rsi_load_bootup_params(common); |
---|
| 1098 | + if (adapter->device_model == RSI_DEV_9116) |
---|
| 1099 | + status = rsi_load_9116_bootup_params(common); |
---|
| 1100 | + else |
---|
| 1101 | + status = rsi_load_bootup_params(common); |
---|
962 | 1102 | if (status) |
---|
963 | 1103 | return status; |
---|
964 | 1104 | |
---|
.. | .. |
---|
1033 | 1173 | * rsi_send_radio_params_update() - This function sends the radio |
---|
1034 | 1174 | * parameters update to device |
---|
1035 | 1175 | * @common: Pointer to the driver private structure. |
---|
1036 | | - * @channel: Channel value to be set. |
---|
1037 | 1176 | * |
---|
1038 | 1177 | * Return: 0 on success, corresponding error code on failure. |
---|
1039 | 1178 | */ |
---|
.. | .. |
---|
1157 | 1296 | * rsi_send_auto_rate_request() - This function is to set rates for connection |
---|
1158 | 1297 | * and send autorate request to firmware. |
---|
1159 | 1298 | * @common: Pointer to the driver private structure. |
---|
| 1299 | + * @sta: mac80211 station. |
---|
| 1300 | + * @sta_id: station id. |
---|
| 1301 | + * @vif: Pointer to the ieee80211_vif structure. |
---|
1160 | 1302 | * |
---|
1161 | 1303 | * Return: 0 on success, corresponding error code on failure. |
---|
1162 | 1304 | */ |
---|
.. | .. |
---|
1314 | 1456 | * help of sta notify params by sending an internal |
---|
1315 | 1457 | * management frame to firmware. |
---|
1316 | 1458 | * @common: Pointer to the driver private structure. |
---|
| 1459 | + * @opmode: Operating mode of device. |
---|
1317 | 1460 | * @status: Bss status type. |
---|
1318 | | - * @bssid: Bssid. |
---|
| 1461 | + * @addr: Address of the register. |
---|
1319 | 1462 | * @qos_enable: Qos is enabled. |
---|
1320 | 1463 | * @aid: Aid (unique for all STAs). |
---|
| 1464 | + * @sta: mac80211 station. |
---|
| 1465 | + * @sta_id: station id. |
---|
| 1466 | + * @assoc_cap: capabilities. |
---|
| 1467 | + * @vif: Pointer to the ieee80211_vif structure. |
---|
1321 | 1468 | * |
---|
1322 | 1469 | * Return: None. |
---|
1323 | 1470 | */ |
---|
.. | .. |
---|
1410 | 1557 | * This function sends a frame to block/unblock |
---|
1411 | 1558 | * data queues in the firmware |
---|
1412 | 1559 | * |
---|
1413 | | - * @param common Pointer to the driver private structure. |
---|
1414 | | - * @param block event - block if true, unblock if false |
---|
1415 | | - * @return 0 on success, -1 on failure. |
---|
| 1560 | + * @common: Pointer to the driver private structure. |
---|
| 1561 | + * @block_event: Event block if true, unblock if false |
---|
| 1562 | + * returns 0 on success, -1 on failure. |
---|
1416 | 1563 | */ |
---|
1417 | 1564 | int rsi_send_block_unblock_frame(struct rsi_common *common, bool block_event) |
---|
1418 | 1565 | { |
---|
.. | .. |
---|
1456 | 1603 | * @common: Pointer to the driver private structure. |
---|
1457 | 1604 | * @rx_filter_word: Flags of filter packets |
---|
1458 | 1605 | * |
---|
1459 | | - * @Return: 0 on success, -1 on failure. |
---|
| 1606 | + * Returns 0 on success, -1 on failure. |
---|
1460 | 1607 | */ |
---|
1461 | 1608 | int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word) |
---|
1462 | 1609 | { |
---|
.. | .. |
---|
1540 | 1687 | return rsi_send_internal_mgmt_frame(common, skb); |
---|
1541 | 1688 | } |
---|
1542 | 1689 | |
---|
| 1690 | +static int rsi_send_w9116_features(struct rsi_common *common) |
---|
| 1691 | +{ |
---|
| 1692 | + struct rsi_wlan_9116_features *w9116_features; |
---|
| 1693 | + u16 frame_len = sizeof(struct rsi_wlan_9116_features); |
---|
| 1694 | + struct sk_buff *skb; |
---|
| 1695 | + |
---|
| 1696 | + rsi_dbg(MGMT_TX_ZONE, |
---|
| 1697 | + "%s: Sending wlan 9116 features\n", __func__); |
---|
| 1698 | + |
---|
| 1699 | + skb = dev_alloc_skb(frame_len); |
---|
| 1700 | + if (!skb) |
---|
| 1701 | + return -ENOMEM; |
---|
| 1702 | + memset(skb->data, 0, frame_len); |
---|
| 1703 | + |
---|
| 1704 | + w9116_features = (struct rsi_wlan_9116_features *)skb->data; |
---|
| 1705 | + |
---|
| 1706 | + w9116_features->pll_mode = common->w9116_features.pll_mode; |
---|
| 1707 | + w9116_features->rf_type = common->w9116_features.rf_type; |
---|
| 1708 | + w9116_features->wireless_mode = common->w9116_features.wireless_mode; |
---|
| 1709 | + w9116_features->enable_ppe = common->w9116_features.enable_ppe; |
---|
| 1710 | + w9116_features->afe_type = common->w9116_features.afe_type; |
---|
| 1711 | + if (common->w9116_features.dpd) |
---|
| 1712 | + w9116_features->feature_enable |= cpu_to_le32(RSI_DPD); |
---|
| 1713 | + if (common->w9116_features.sifs_tx_enable) |
---|
| 1714 | + w9116_features->feature_enable |= |
---|
| 1715 | + cpu_to_le32(RSI_SIFS_TX_ENABLE); |
---|
| 1716 | + if (common->w9116_features.ps_options & RSI_DUTY_CYCLING) |
---|
| 1717 | + w9116_features->feature_enable |= cpu_to_le32(RSI_DUTY_CYCLING); |
---|
| 1718 | + if (common->w9116_features.ps_options & RSI_END_OF_FRAME) |
---|
| 1719 | + w9116_features->feature_enable |= cpu_to_le32(RSI_END_OF_FRAME); |
---|
| 1720 | + w9116_features->feature_enable |= |
---|
| 1721 | + cpu_to_le32((common->w9116_features.ps_options & ~0x3) << 2); |
---|
| 1722 | + |
---|
| 1723 | + rsi_set_len_qno(&w9116_features->desc.desc_dword0.len_qno, |
---|
| 1724 | + frame_len - FRAME_DESC_SZ, RSI_WIFI_MGMT_Q); |
---|
| 1725 | + w9116_features->desc.desc_dword0.frame_type = FEATURES_ENABLE; |
---|
| 1726 | + skb_put(skb, frame_len); |
---|
| 1727 | + |
---|
| 1728 | + return rsi_send_internal_mgmt_frame(common, skb); |
---|
| 1729 | +} |
---|
| 1730 | + |
---|
1543 | 1731 | /** |
---|
1544 | | - * rsi_set_antenna() - This fuction send antenna configuration request |
---|
| 1732 | + * rsi_set_antenna() - This function send antenna configuration request |
---|
1545 | 1733 | * to device |
---|
1546 | 1734 | * |
---|
1547 | 1735 | * @common: Pointer to the driver private structure. |
---|
.. | .. |
---|
1635 | 1823 | } |
---|
1636 | 1824 | #endif |
---|
1637 | 1825 | |
---|
| 1826 | +int rsi_send_bgscan_params(struct rsi_common *common, int enable) |
---|
| 1827 | +{ |
---|
| 1828 | + struct rsi_bgscan_params *params = &common->bgscan; |
---|
| 1829 | + struct cfg80211_scan_request *scan_req = common->hwscan; |
---|
| 1830 | + struct rsi_bgscan_config *bgscan; |
---|
| 1831 | + struct sk_buff *skb; |
---|
| 1832 | + u16 frame_len = sizeof(*bgscan); |
---|
| 1833 | + u8 i; |
---|
| 1834 | + |
---|
| 1835 | + rsi_dbg(MGMT_TX_ZONE, "%s: Sending bgscan params frame\n", __func__); |
---|
| 1836 | + |
---|
| 1837 | + skb = dev_alloc_skb(frame_len); |
---|
| 1838 | + if (!skb) |
---|
| 1839 | + return -ENOMEM; |
---|
| 1840 | + memset(skb->data, 0, frame_len); |
---|
| 1841 | + |
---|
| 1842 | + bgscan = (struct rsi_bgscan_config *)skb->data; |
---|
| 1843 | + rsi_set_len_qno(&bgscan->desc_dword0.len_qno, |
---|
| 1844 | + (frame_len - FRAME_DESC_SZ), RSI_WIFI_MGMT_Q); |
---|
| 1845 | + bgscan->desc_dword0.frame_type = BG_SCAN_PARAMS; |
---|
| 1846 | + bgscan->bgscan_threshold = cpu_to_le16(params->bgscan_threshold); |
---|
| 1847 | + bgscan->roam_threshold = cpu_to_le16(params->roam_threshold); |
---|
| 1848 | + if (enable) |
---|
| 1849 | + bgscan->bgscan_periodicity = |
---|
| 1850 | + cpu_to_le16(params->bgscan_periodicity); |
---|
| 1851 | + bgscan->active_scan_duration = |
---|
| 1852 | + cpu_to_le16(params->active_scan_duration); |
---|
| 1853 | + bgscan->passive_scan_duration = |
---|
| 1854 | + cpu_to_le16(params->passive_scan_duration); |
---|
| 1855 | + bgscan->two_probe = params->two_probe; |
---|
| 1856 | + |
---|
| 1857 | + bgscan->num_bgscan_channels = scan_req->n_channels; |
---|
| 1858 | + for (i = 0; i < bgscan->num_bgscan_channels; i++) |
---|
| 1859 | + bgscan->channels2scan[i] = |
---|
| 1860 | + cpu_to_le16(scan_req->channels[i]->hw_value); |
---|
| 1861 | + |
---|
| 1862 | + skb_put(skb, frame_len); |
---|
| 1863 | + |
---|
| 1864 | + return rsi_send_internal_mgmt_frame(common, skb); |
---|
| 1865 | +} |
---|
| 1866 | + |
---|
| 1867 | +/* This function sends the probe request to be used by firmware in |
---|
| 1868 | + * background scan |
---|
| 1869 | + */ |
---|
| 1870 | +int rsi_send_bgscan_probe_req(struct rsi_common *common, |
---|
| 1871 | + struct ieee80211_vif *vif) |
---|
| 1872 | +{ |
---|
| 1873 | + struct cfg80211_scan_request *scan_req = common->hwscan; |
---|
| 1874 | + struct rsi_bgscan_probe *bgscan; |
---|
| 1875 | + struct sk_buff *skb; |
---|
| 1876 | + struct sk_buff *probereq_skb; |
---|
| 1877 | + u16 frame_len = sizeof(*bgscan); |
---|
| 1878 | + size_t ssid_len = 0; |
---|
| 1879 | + u8 *ssid = NULL; |
---|
| 1880 | + |
---|
| 1881 | + rsi_dbg(MGMT_TX_ZONE, |
---|
| 1882 | + "%s: Sending bgscan probe req frame\n", __func__); |
---|
| 1883 | + |
---|
| 1884 | + if (common->priv->sc_nvifs <= 0) |
---|
| 1885 | + return -ENODEV; |
---|
| 1886 | + |
---|
| 1887 | + if (scan_req->n_ssids) { |
---|
| 1888 | + ssid = scan_req->ssids[0].ssid; |
---|
| 1889 | + ssid_len = scan_req->ssids[0].ssid_len; |
---|
| 1890 | + } |
---|
| 1891 | + |
---|
| 1892 | + skb = dev_alloc_skb(frame_len + MAX_BGSCAN_PROBE_REQ_LEN); |
---|
| 1893 | + if (!skb) |
---|
| 1894 | + return -ENOMEM; |
---|
| 1895 | + memset(skb->data, 0, frame_len + MAX_BGSCAN_PROBE_REQ_LEN); |
---|
| 1896 | + |
---|
| 1897 | + bgscan = (struct rsi_bgscan_probe *)skb->data; |
---|
| 1898 | + bgscan->desc_dword0.frame_type = BG_SCAN_PROBE_REQ; |
---|
| 1899 | + bgscan->flags = cpu_to_le16(HOST_BG_SCAN_TRIG); |
---|
| 1900 | + if (common->band == NL80211_BAND_5GHZ) { |
---|
| 1901 | + bgscan->mgmt_rate = cpu_to_le16(RSI_RATE_6); |
---|
| 1902 | + bgscan->def_chan = cpu_to_le16(40); |
---|
| 1903 | + } else { |
---|
| 1904 | + bgscan->mgmt_rate = cpu_to_le16(RSI_RATE_1); |
---|
| 1905 | + bgscan->def_chan = cpu_to_le16(11); |
---|
| 1906 | + } |
---|
| 1907 | + bgscan->channel_scan_time = cpu_to_le16(RSI_CHANNEL_SCAN_TIME); |
---|
| 1908 | + |
---|
| 1909 | + probereq_skb = ieee80211_probereq_get(common->priv->hw, vif->addr, ssid, |
---|
| 1910 | + ssid_len, scan_req->ie_len); |
---|
| 1911 | + if (!probereq_skb) { |
---|
| 1912 | + dev_kfree_skb(skb); |
---|
| 1913 | + return -ENOMEM; |
---|
| 1914 | + } |
---|
| 1915 | + |
---|
| 1916 | + memcpy(&skb->data[frame_len], probereq_skb->data, probereq_skb->len); |
---|
| 1917 | + |
---|
| 1918 | + bgscan->probe_req_length = cpu_to_le16(probereq_skb->len); |
---|
| 1919 | + |
---|
| 1920 | + rsi_set_len_qno(&bgscan->desc_dword0.len_qno, |
---|
| 1921 | + (frame_len - FRAME_DESC_SZ + probereq_skb->len), |
---|
| 1922 | + RSI_WIFI_MGMT_Q); |
---|
| 1923 | + |
---|
| 1924 | + skb_put(skb, frame_len + probereq_skb->len); |
---|
| 1925 | + |
---|
| 1926 | + dev_kfree_skb(probereq_skb); |
---|
| 1927 | + |
---|
| 1928 | + return rsi_send_internal_mgmt_frame(common, skb); |
---|
| 1929 | +} |
---|
| 1930 | + |
---|
1638 | 1931 | /** |
---|
1639 | 1932 | * rsi_handle_ta_confirm_type() - This function handles the confirm frames. |
---|
1640 | 1933 | * @common: Pointer to the driver private structure. |
---|
.. | .. |
---|
1655 | 1948 | rsi_dbg(FSM_ZONE, "%s: Boot up params confirm received\n", |
---|
1656 | 1949 | __func__); |
---|
1657 | 1950 | if (common->fsm_state == FSM_BOOT_PARAMS_SENT) { |
---|
1658 | | - adapter->eeprom.length = (IEEE80211_ADDR_LEN + |
---|
1659 | | - WLAN_MAC_MAGIC_WORD_LEN + |
---|
1660 | | - WLAN_HOST_MODE_LEN); |
---|
1661 | | - adapter->eeprom.offset = WLAN_MAC_EEPROM_ADDR; |
---|
1662 | | - if (rsi_eeprom_read(common)) { |
---|
1663 | | - common->fsm_state = FSM_CARD_NOT_READY; |
---|
1664 | | - goto out; |
---|
| 1951 | + if (adapter->device_model == RSI_DEV_9116) { |
---|
| 1952 | + common->band = NL80211_BAND_5GHZ; |
---|
| 1953 | + common->num_supp_bands = 2; |
---|
| 1954 | + |
---|
| 1955 | + if (rsi_send_reset_mac(common)) |
---|
| 1956 | + goto out; |
---|
| 1957 | + else |
---|
| 1958 | + common->fsm_state = FSM_RESET_MAC_SENT; |
---|
| 1959 | + } else { |
---|
| 1960 | + adapter->eeprom.length = |
---|
| 1961 | + (IEEE80211_ADDR_LEN + |
---|
| 1962 | + WLAN_MAC_MAGIC_WORD_LEN + |
---|
| 1963 | + WLAN_HOST_MODE_LEN); |
---|
| 1964 | + adapter->eeprom.offset = WLAN_MAC_EEPROM_ADDR; |
---|
| 1965 | + if (rsi_eeprom_read(common)) { |
---|
| 1966 | + common->fsm_state = FSM_CARD_NOT_READY; |
---|
| 1967 | + goto out; |
---|
| 1968 | + } |
---|
| 1969 | + common->fsm_state = FSM_EEPROM_READ_MAC_ADDR; |
---|
1665 | 1970 | } |
---|
1666 | | - common->fsm_state = FSM_EEPROM_READ_MAC_ADDR; |
---|
1667 | 1971 | } else { |
---|
1668 | 1972 | rsi_dbg(INFO_ZONE, |
---|
1669 | 1973 | "%s: Received bootup params cfm in %d state\n", |
---|
.. | .. |
---|
1742 | 2046 | case RADIO_CAPABILITIES: |
---|
1743 | 2047 | if (common->fsm_state == FSM_RADIO_CAPS_SENT) { |
---|
1744 | 2048 | common->rf_reset = 1; |
---|
| 2049 | + if (adapter->device_model == RSI_DEV_9116 && |
---|
| 2050 | + rsi_send_w9116_features(common)) { |
---|
| 2051 | + rsi_dbg(ERR_ZONE, |
---|
| 2052 | + "Failed to send 9116 features\n"); |
---|
| 2053 | + goto out; |
---|
| 2054 | + } |
---|
1745 | 2055 | if (rsi_program_bb_rf(common)) { |
---|
1746 | 2056 | goto out; |
---|
1747 | 2057 | } else { |
---|
.. | .. |
---|
1781 | 2091 | return 0; |
---|
1782 | 2092 | } |
---|
1783 | 2093 | break; |
---|
| 2094 | + |
---|
| 2095 | + case SCAN_REQUEST: |
---|
| 2096 | + rsi_dbg(INFO_ZONE, "Set channel confirm\n"); |
---|
| 2097 | + break; |
---|
| 2098 | + |
---|
1784 | 2099 | case WAKEUP_SLEEP_REQUEST: |
---|
1785 | 2100 | rsi_dbg(INFO_ZONE, "Wakeup/Sleep confirmation.\n"); |
---|
1786 | 2101 | return rsi_handle_ps_confirm(adapter, msg); |
---|
| 2102 | + |
---|
| 2103 | + case BG_SCAN_PROBE_REQ: |
---|
| 2104 | + rsi_dbg(INFO_ZONE, "BG scan complete event\n"); |
---|
| 2105 | + if (common->bgscan_en) { |
---|
| 2106 | + struct cfg80211_scan_info info; |
---|
| 2107 | + |
---|
| 2108 | + if (!rsi_send_bgscan_params(common, RSI_STOP_BGSCAN)) |
---|
| 2109 | + common->bgscan_en = 0; |
---|
| 2110 | + info.aborted = false; |
---|
| 2111 | + ieee80211_scan_completed(adapter->hw, &info); |
---|
| 2112 | + } |
---|
| 2113 | + rsi_dbg(INFO_ZONE, "Background scan completed\n"); |
---|
| 2114 | + break; |
---|
| 2115 | + |
---|
1787 | 2116 | default: |
---|
1788 | 2117 | rsi_dbg(INFO_ZONE, "%s: Invalid TA confirm pkt received\n", |
---|
1789 | 2118 | __func__); |
---|
.. | .. |
---|
1798 | 2127 | |
---|
1799 | 2128 | int rsi_handle_card_ready(struct rsi_common *common, u8 *msg) |
---|
1800 | 2129 | { |
---|
| 2130 | + int status; |
---|
| 2131 | + |
---|
1801 | 2132 | switch (common->fsm_state) { |
---|
1802 | 2133 | case FSM_CARD_NOT_READY: |
---|
1803 | 2134 | rsi_dbg(INIT_ZONE, "Card ready indication from Common HAL\n"); |
---|
.. | .. |
---|
1809 | 2140 | case FSM_COMMON_DEV_PARAMS_SENT: |
---|
1810 | 2141 | rsi_dbg(INIT_ZONE, "Card ready indication from WLAN HAL\n"); |
---|
1811 | 2142 | |
---|
| 2143 | + if (common->priv->device_model == RSI_DEV_9116) { |
---|
| 2144 | + if (msg[16] != MAGIC_WORD) { |
---|
| 2145 | + rsi_dbg(FSM_ZONE, |
---|
| 2146 | + "%s: [EEPROM_READ] Invalid token\n", |
---|
| 2147 | + __func__); |
---|
| 2148 | + common->fsm_state = FSM_CARD_NOT_READY; |
---|
| 2149 | + return -EINVAL; |
---|
| 2150 | + } |
---|
| 2151 | + memcpy(common->mac_addr, &msg[20], ETH_ALEN); |
---|
| 2152 | + rsi_dbg(INIT_ZONE, "MAC Addr %pM", common->mac_addr); |
---|
| 2153 | + } |
---|
1812 | 2154 | /* Get usb buffer status register address */ |
---|
1813 | 2155 | common->priv->usb_buffer_status_reg = *(u32 *)&msg[8]; |
---|
1814 | 2156 | rsi_dbg(INFO_ZONE, "USB buffer status register = %x\n", |
---|
1815 | 2157 | common->priv->usb_buffer_status_reg); |
---|
1816 | 2158 | |
---|
1817 | | - if (rsi_load_bootup_params(common)) { |
---|
| 2159 | + if (common->priv->device_model == RSI_DEV_9116) |
---|
| 2160 | + status = rsi_load_9116_bootup_params(common); |
---|
| 2161 | + else |
---|
| 2162 | + status = rsi_load_bootup_params(common); |
---|
| 2163 | + if (status < 0) { |
---|
1818 | 2164 | common->fsm_state = FSM_CARD_NOT_READY; |
---|
1819 | | - return -EINVAL; |
---|
| 2165 | + return status; |
---|
1820 | 2166 | } |
---|
1821 | 2167 | common->fsm_state = FSM_BOOT_PARAMS_SENT; |
---|
1822 | 2168 | break; |
---|
.. | .. |
---|
1832 | 2178 | |
---|
1833 | 2179 | /** |
---|
1834 | 2180 | * rsi_mgmt_pkt_recv() - This function processes the management packets |
---|
1835 | | - * recieved from the hardware. |
---|
| 2181 | + * received from the hardware. |
---|
1836 | 2182 | * @common: Pointer to the driver private structure. |
---|
1837 | 2183 | * @msg: Pointer to the received packet. |
---|
1838 | 2184 | * |
---|
.. | .. |
---|
1880 | 2226 | return -1; |
---|
1881 | 2227 | rsi_send_beacon(common); |
---|
1882 | 2228 | break; |
---|
| 2229 | + case WOWLAN_WAKEUP_REASON: |
---|
| 2230 | + rsi_dbg(ERR_ZONE, "\n\nWakeup Type: %x\n", msg[15]); |
---|
| 2231 | + switch (msg[15]) { |
---|
| 2232 | + case RSI_UNICAST_MAGIC_PKT: |
---|
| 2233 | + rsi_dbg(ERR_ZONE, |
---|
| 2234 | + "*** Wakeup for Unicast magic packet ***\n"); |
---|
| 2235 | + break; |
---|
| 2236 | + case RSI_BROADCAST_MAGICPKT: |
---|
| 2237 | + rsi_dbg(ERR_ZONE, |
---|
| 2238 | + "*** Wakeup for Broadcast magic packet ***\n"); |
---|
| 2239 | + break; |
---|
| 2240 | + case RSI_EAPOL_PKT: |
---|
| 2241 | + rsi_dbg(ERR_ZONE, |
---|
| 2242 | + "*** Wakeup for GTK renewal ***\n"); |
---|
| 2243 | + break; |
---|
| 2244 | + case RSI_DISCONNECT_PKT: |
---|
| 2245 | + rsi_dbg(ERR_ZONE, |
---|
| 2246 | + "*** Wakeup for Disconnect ***\n"); |
---|
| 2247 | + break; |
---|
| 2248 | + case RSI_HW_BMISS_PKT: |
---|
| 2249 | + rsi_dbg(ERR_ZONE, |
---|
| 2250 | + "*** Wakeup for HW Beacon miss ***\n"); |
---|
| 2251 | + break; |
---|
| 2252 | + default: |
---|
| 2253 | + rsi_dbg(ERR_ZONE, |
---|
| 2254 | + "##### Un-intentional Wakeup #####\n"); |
---|
| 2255 | + break; |
---|
| 2256 | + } |
---|
| 2257 | + break; |
---|
1883 | 2258 | case RX_DOT11_MGMT: |
---|
1884 | 2259 | return rsi_mgmt_pkt_to_core(common, msg, msg_len); |
---|
1885 | 2260 | default: |
---|