1 /* 2 * This file is part of wl18xx 3 * 4 * Copyright (C) 2011 Texas Instruments 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * version 2 as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 18 * 02110-1301 USA 19 * 20 */ 21 22 #include <linux/module.h> 23 #include <linux/mod_devicetable.h> 24 #include <linux/platform_device.h> 25 #include <linux/ip.h> 26 #include <linux/firmware.h> 27 #include <linux/etherdevice.h> 28 #include <linux/irq.h> 29 30 #include "../wlcore/wlcore.h" 31 #include "../wlcore/debug.h" 32 #include "../wlcore/io.h" 33 #include "../wlcore/acx.h" 34 #include "../wlcore/tx.h" 35 #include "../wlcore/rx.h" 36 #include "../wlcore/boot.h" 37 38 #include "reg.h" 39 #include "conf.h" 40 #include "cmd.h" 41 #include "acx.h" 42 #include "tx.h" 43 #include "wl18xx.h" 44 #include "io.h" 45 #include "scan.h" 46 #include "event.h" 47 #include "debugfs.h" 48 49 #define WL18XX_RX_CHECKSUM_MASK 0x40 50 51 static char *ht_mode_param = NULL; 52 static char *board_type_param = NULL; 53 static bool checksum_param = false; 54 static int num_rx_desc_param = -1; 55 56 /* phy paramters */ 57 static int dc2dc_param = -1; 58 static int n_antennas_2_param = -1; 59 static int n_antennas_5_param = -1; 60 static int low_band_component_param = -1; 61 static int low_band_component_type_param = -1; 62 static int high_band_component_param = -1; 63 static int high_band_component_type_param = -1; 64 static int pwr_limit_reference_11_abg_param = -1; 65 66 static const u8 wl18xx_rate_to_idx_2ghz[] = { 67 /* MCS rates are used only with 11n */ 68 15, /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */ 69 14, /* WL18XX_CONF_HW_RXTX_RATE_MCS14 */ 70 13, /* WL18XX_CONF_HW_RXTX_RATE_MCS13 */ 71 12, /* WL18XX_CONF_HW_RXTX_RATE_MCS12 */ 72 11, /* WL18XX_CONF_HW_RXTX_RATE_MCS11 */ 73 10, /* WL18XX_CONF_HW_RXTX_RATE_MCS10 */ 74 9, /* WL18XX_CONF_HW_RXTX_RATE_MCS9 */ 75 8, /* WL18XX_CONF_HW_RXTX_RATE_MCS8 */ 76 7, /* WL18XX_CONF_HW_RXTX_RATE_MCS7 */ 77 6, /* WL18XX_CONF_HW_RXTX_RATE_MCS6 */ 78 5, /* WL18XX_CONF_HW_RXTX_RATE_MCS5 */ 79 4, /* WL18XX_CONF_HW_RXTX_RATE_MCS4 */ 80 3, /* WL18XX_CONF_HW_RXTX_RATE_MCS3 */ 81 2, /* WL18XX_CONF_HW_RXTX_RATE_MCS2 */ 82 1, /* WL18XX_CONF_HW_RXTX_RATE_MCS1 */ 83 0, /* WL18XX_CONF_HW_RXTX_RATE_MCS0 */ 84 85 11, /* WL18XX_CONF_HW_RXTX_RATE_54 */ 86 10, /* WL18XX_CONF_HW_RXTX_RATE_48 */ 87 9, /* WL18XX_CONF_HW_RXTX_RATE_36 */ 88 8, /* WL18XX_CONF_HW_RXTX_RATE_24 */ 89 90 /* TI-specific rate */ 91 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_22 */ 92 93 7, /* WL18XX_CONF_HW_RXTX_RATE_18 */ 94 6, /* WL18XX_CONF_HW_RXTX_RATE_12 */ 95 3, /* WL18XX_CONF_HW_RXTX_RATE_11 */ 96 5, /* WL18XX_CONF_HW_RXTX_RATE_9 */ 97 4, /* WL18XX_CONF_HW_RXTX_RATE_6 */ 98 2, /* WL18XX_CONF_HW_RXTX_RATE_5_5 */ 99 1, /* WL18XX_CONF_HW_RXTX_RATE_2 */ 100 0 /* WL18XX_CONF_HW_RXTX_RATE_1 */ 101 }; 102 103 static const u8 wl18xx_rate_to_idx_5ghz[] = { 104 /* MCS rates are used only with 11n */ 105 15, /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */ 106 14, /* WL18XX_CONF_HW_RXTX_RATE_MCS14 */ 107 13, /* WL18XX_CONF_HW_RXTX_RATE_MCS13 */ 108 12, /* WL18XX_CONF_HW_RXTX_RATE_MCS12 */ 109 11, /* WL18XX_CONF_HW_RXTX_RATE_MCS11 */ 110 10, /* WL18XX_CONF_HW_RXTX_RATE_MCS10 */ 111 9, /* WL18XX_CONF_HW_RXTX_RATE_MCS9 */ 112 8, /* WL18XX_CONF_HW_RXTX_RATE_MCS8 */ 113 7, /* WL18XX_CONF_HW_RXTX_RATE_MCS7 */ 114 6, /* WL18XX_CONF_HW_RXTX_RATE_MCS6 */ 115 5, /* WL18XX_CONF_HW_RXTX_RATE_MCS5 */ 116 4, /* WL18XX_CONF_HW_RXTX_RATE_MCS4 */ 117 3, /* WL18XX_CONF_HW_RXTX_RATE_MCS3 */ 118 2, /* WL18XX_CONF_HW_RXTX_RATE_MCS2 */ 119 1, /* WL18XX_CONF_HW_RXTX_RATE_MCS1 */ 120 0, /* WL18XX_CONF_HW_RXTX_RATE_MCS0 */ 121 122 7, /* WL18XX_CONF_HW_RXTX_RATE_54 */ 123 6, /* WL18XX_CONF_HW_RXTX_RATE_48 */ 124 5, /* WL18XX_CONF_HW_RXTX_RATE_36 */ 125 4, /* WL18XX_CONF_HW_RXTX_RATE_24 */ 126 127 /* TI-specific rate */ 128 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_22 */ 129 130 3, /* WL18XX_CONF_HW_RXTX_RATE_18 */ 131 2, /* WL18XX_CONF_HW_RXTX_RATE_12 */ 132 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_11 */ 133 1, /* WL18XX_CONF_HW_RXTX_RATE_9 */ 134 0, /* WL18XX_CONF_HW_RXTX_RATE_6 */ 135 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_5_5 */ 136 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_2 */ 137 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_1 */ 138 }; 139 140 static const u8 *wl18xx_band_rate_to_idx[] = { 141 [NL80211_BAND_2GHZ] = wl18xx_rate_to_idx_2ghz, 142 [NL80211_BAND_5GHZ] = wl18xx_rate_to_idx_5ghz 143 }; 144 145 enum wl18xx_hw_rates { 146 WL18XX_CONF_HW_RXTX_RATE_MCS15 = 0, 147 WL18XX_CONF_HW_RXTX_RATE_MCS14, 148 WL18XX_CONF_HW_RXTX_RATE_MCS13, 149 WL18XX_CONF_HW_RXTX_RATE_MCS12, 150 WL18XX_CONF_HW_RXTX_RATE_MCS11, 151 WL18XX_CONF_HW_RXTX_RATE_MCS10, 152 WL18XX_CONF_HW_RXTX_RATE_MCS9, 153 WL18XX_CONF_HW_RXTX_RATE_MCS8, 154 WL18XX_CONF_HW_RXTX_RATE_MCS7, 155 WL18XX_CONF_HW_RXTX_RATE_MCS6, 156 WL18XX_CONF_HW_RXTX_RATE_MCS5, 157 WL18XX_CONF_HW_RXTX_RATE_MCS4, 158 WL18XX_CONF_HW_RXTX_RATE_MCS3, 159 WL18XX_CONF_HW_RXTX_RATE_MCS2, 160 WL18XX_CONF_HW_RXTX_RATE_MCS1, 161 WL18XX_CONF_HW_RXTX_RATE_MCS0, 162 WL18XX_CONF_HW_RXTX_RATE_54, 163 WL18XX_CONF_HW_RXTX_RATE_48, 164 WL18XX_CONF_HW_RXTX_RATE_36, 165 WL18XX_CONF_HW_RXTX_RATE_24, 166 WL18XX_CONF_HW_RXTX_RATE_22, 167 WL18XX_CONF_HW_RXTX_RATE_18, 168 WL18XX_CONF_HW_RXTX_RATE_12, 169 WL18XX_CONF_HW_RXTX_RATE_11, 170 WL18XX_CONF_HW_RXTX_RATE_9, 171 WL18XX_CONF_HW_RXTX_RATE_6, 172 WL18XX_CONF_HW_RXTX_RATE_5_5, 173 WL18XX_CONF_HW_RXTX_RATE_2, 174 WL18XX_CONF_HW_RXTX_RATE_1, 175 WL18XX_CONF_HW_RXTX_RATE_MAX, 176 }; 177 178 static struct wlcore_conf wl18xx_conf = { 179 .sg = { 180 .params = { 181 [WL18XX_CONF_SG_PARAM_0] = 0, 182 /* Configuration Parameters */ 183 [WL18XX_CONF_SG_ANTENNA_CONFIGURATION] = 0, 184 [WL18XX_CONF_SG_ZIGBEE_COEX] = 0, 185 [WL18XX_CONF_SG_TIME_SYNC] = 0, 186 [WL18XX_CONF_SG_PARAM_4] = 0, 187 [WL18XX_CONF_SG_PARAM_5] = 0, 188 [WL18XX_CONF_SG_PARAM_6] = 0, 189 [WL18XX_CONF_SG_PARAM_7] = 0, 190 [WL18XX_CONF_SG_PARAM_8] = 0, 191 [WL18XX_CONF_SG_PARAM_9] = 0, 192 [WL18XX_CONF_SG_PARAM_10] = 0, 193 [WL18XX_CONF_SG_PARAM_11] = 0, 194 [WL18XX_CONF_SG_PARAM_12] = 0, 195 [WL18XX_CONF_SG_PARAM_13] = 0, 196 [WL18XX_CONF_SG_PARAM_14] = 0, 197 [WL18XX_CONF_SG_PARAM_15] = 0, 198 [WL18XX_CONF_SG_PARAM_16] = 0, 199 [WL18XX_CONF_SG_PARAM_17] = 0, 200 [WL18XX_CONF_SG_PARAM_18] = 0, 201 [WL18XX_CONF_SG_PARAM_19] = 0, 202 [WL18XX_CONF_SG_PARAM_20] = 0, 203 [WL18XX_CONF_SG_PARAM_21] = 0, 204 [WL18XX_CONF_SG_PARAM_22] = 0, 205 [WL18XX_CONF_SG_PARAM_23] = 0, 206 [WL18XX_CONF_SG_PARAM_24] = 0, 207 [WL18XX_CONF_SG_PARAM_25] = 0, 208 /* Active Scan Parameters */ 209 [WL18XX_CONF_SG_AUTO_SCAN_PROBE_REQ] = 170, 210 [WL18XX_CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50, 211 [WL18XX_CONF_SG_PARAM_28] = 0, 212 /* Passive Scan Parameters */ 213 [WL18XX_CONF_SG_PARAM_29] = 0, 214 [WL18XX_CONF_SG_PARAM_30] = 0, 215 [WL18XX_CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200, 216 /* Passive Scan in Dual Antenna Parameters */ 217 [WL18XX_CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0, 218 [WL18XX_CONF_SG_BEACON_HV3_COLL_TH_IN_PASSIVE_SCAN] = 0, 219 [WL18XX_CONF_SG_TX_RX_PROTECT_BW_IN_PASSIVE_SCAN] = 0, 220 /* General Parameters */ 221 [WL18XX_CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1, 222 [WL18XX_CONF_SG_PARAM_36] = 0, 223 [WL18XX_CONF_SG_BEACON_MISS_PERCENT] = 60, 224 [WL18XX_CONF_SG_PARAM_38] = 0, 225 [WL18XX_CONF_SG_RXT] = 1200, 226 [WL18XX_CONF_SG_UNUSED] = 0, 227 [WL18XX_CONF_SG_ADAPTIVE_RXT_TXT] = 1, 228 [WL18XX_CONF_SG_GENERAL_USAGE_BIT_MAP] = 3, 229 [WL18XX_CONF_SG_HV3_MAX_SERVED] = 6, 230 [WL18XX_CONF_SG_PARAM_44] = 0, 231 [WL18XX_CONF_SG_PARAM_45] = 0, 232 [WL18XX_CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2, 233 [WL18XX_CONF_SG_GEMINI_PARAM_47] = 0, 234 [WL18XX_CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 0, 235 /* AP Parameters */ 236 [WL18XX_CONF_SG_AP_BEACON_MISS_TX] = 3, 237 [WL18XX_CONF_SG_PARAM_50] = 0, 238 [WL18XX_CONF_SG_AP_BEACON_WINDOW_INTERVAL] = 2, 239 [WL18XX_CONF_SG_AP_CONNECTION_PROTECTION_TIME] = 30, 240 [WL18XX_CONF_SG_PARAM_53] = 0, 241 [WL18XX_CONF_SG_PARAM_54] = 0, 242 /* CTS Diluting Parameters */ 243 [WL18XX_CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0, 244 [WL18XX_CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0, 245 [WL18XX_CONF_SG_TEMP_PARAM_1] = 0, 246 [WL18XX_CONF_SG_TEMP_PARAM_2] = 0, 247 [WL18XX_CONF_SG_TEMP_PARAM_3] = 0, 248 [WL18XX_CONF_SG_TEMP_PARAM_4] = 0, 249 [WL18XX_CONF_SG_TEMP_PARAM_5] = 0, 250 [WL18XX_CONF_SG_TEMP_PARAM_6] = 0, 251 [WL18XX_CONF_SG_TEMP_PARAM_7] = 0, 252 [WL18XX_CONF_SG_TEMP_PARAM_8] = 0, 253 [WL18XX_CONF_SG_TEMP_PARAM_9] = 0, 254 [WL18XX_CONF_SG_TEMP_PARAM_10] = 0, 255 }, 256 .state = CONF_SG_PROTECTIVE, 257 }, 258 .rx = { 259 .rx_msdu_life_time = 512000, 260 .packet_detection_threshold = 0, 261 .ps_poll_timeout = 15, 262 .upsd_timeout = 15, 263 .rts_threshold = IEEE80211_MAX_RTS_THRESHOLD, 264 .rx_cca_threshold = 0, 265 .irq_blk_threshold = 0xFFFF, 266 .irq_pkt_threshold = 0, 267 .irq_timeout = 600, 268 .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY, 269 }, 270 .tx = { 271 .tx_energy_detection = 0, 272 .sta_rc_conf = { 273 .enabled_rates = 0, 274 .short_retry_limit = 10, 275 .long_retry_limit = 10, 276 .aflags = 0, 277 }, 278 .ac_conf_count = 4, 279 .ac_conf = { 280 [CONF_TX_AC_BE] = { 281 .ac = CONF_TX_AC_BE, 282 .cw_min = 15, 283 .cw_max = 63, 284 .aifsn = 3, 285 .tx_op_limit = 0, 286 }, 287 [CONF_TX_AC_BK] = { 288 .ac = CONF_TX_AC_BK, 289 .cw_min = 15, 290 .cw_max = 63, 291 .aifsn = 7, 292 .tx_op_limit = 0, 293 }, 294 [CONF_TX_AC_VI] = { 295 .ac = CONF_TX_AC_VI, 296 .cw_min = 15, 297 .cw_max = 63, 298 .aifsn = CONF_TX_AIFS_PIFS, 299 .tx_op_limit = 3008, 300 }, 301 [CONF_TX_AC_VO] = { 302 .ac = CONF_TX_AC_VO, 303 .cw_min = 15, 304 .cw_max = 63, 305 .aifsn = CONF_TX_AIFS_PIFS, 306 .tx_op_limit = 1504, 307 }, 308 }, 309 .max_tx_retries = 100, 310 .ap_aging_period = 300, 311 .tid_conf_count = 4, 312 .tid_conf = { 313 [CONF_TX_AC_BE] = { 314 .queue_id = CONF_TX_AC_BE, 315 .channel_type = CONF_CHANNEL_TYPE_EDCF, 316 .tsid = CONF_TX_AC_BE, 317 .ps_scheme = CONF_PS_SCHEME_LEGACY, 318 .ack_policy = CONF_ACK_POLICY_LEGACY, 319 .apsd_conf = {0, 0}, 320 }, 321 [CONF_TX_AC_BK] = { 322 .queue_id = CONF_TX_AC_BK, 323 .channel_type = CONF_CHANNEL_TYPE_EDCF, 324 .tsid = CONF_TX_AC_BK, 325 .ps_scheme = CONF_PS_SCHEME_LEGACY, 326 .ack_policy = CONF_ACK_POLICY_LEGACY, 327 .apsd_conf = {0, 0}, 328 }, 329 [CONF_TX_AC_VI] = { 330 .queue_id = CONF_TX_AC_VI, 331 .channel_type = CONF_CHANNEL_TYPE_EDCF, 332 .tsid = CONF_TX_AC_VI, 333 .ps_scheme = CONF_PS_SCHEME_LEGACY, 334 .ack_policy = CONF_ACK_POLICY_LEGACY, 335 .apsd_conf = {0, 0}, 336 }, 337 [CONF_TX_AC_VO] = { 338 .queue_id = CONF_TX_AC_VO, 339 .channel_type = CONF_CHANNEL_TYPE_EDCF, 340 .tsid = CONF_TX_AC_VO, 341 .ps_scheme = CONF_PS_SCHEME_LEGACY, 342 .ack_policy = CONF_ACK_POLICY_LEGACY, 343 .apsd_conf = {0, 0}, 344 }, 345 }, 346 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD, 347 .tx_compl_timeout = 350, 348 .tx_compl_threshold = 10, 349 .basic_rate = CONF_HW_BIT_RATE_1MBPS, 350 .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS, 351 .tmpl_short_retry_limit = 10, 352 .tmpl_long_retry_limit = 10, 353 .tx_watchdog_timeout = 5000, 354 .slow_link_thold = 3, 355 .fast_link_thold = 30, 356 }, 357 .conn = { 358 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, 359 .listen_interval = 1, 360 .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM, 361 .suspend_listen_interval = 3, 362 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED, 363 .bcn_filt_ie_count = 3, 364 .bcn_filt_ie = { 365 [0] = { 366 .ie = WLAN_EID_CHANNEL_SWITCH, 367 .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE, 368 }, 369 [1] = { 370 .ie = WLAN_EID_HT_OPERATION, 371 .rule = CONF_BCN_RULE_PASS_ON_CHANGE, 372 }, 373 [2] = { 374 .ie = WLAN_EID_ERP_INFO, 375 .rule = CONF_BCN_RULE_PASS_ON_CHANGE, 376 }, 377 }, 378 .synch_fail_thold = 12, 379 .bss_lose_timeout = 400, 380 .beacon_rx_timeout = 10000, 381 .broadcast_timeout = 20000, 382 .rx_broadcast_in_ps = 1, 383 .ps_poll_threshold = 10, 384 .bet_enable = CONF_BET_MODE_ENABLE, 385 .bet_max_consecutive = 50, 386 .psm_entry_retries = 8, 387 .psm_exit_retries = 16, 388 .psm_entry_nullfunc_retries = 3, 389 .dynamic_ps_timeout = 1500, 390 .forced_ps = false, 391 .keep_alive_interval = 55000, 392 .max_listen_interval = 20, 393 .sta_sleep_auth = WL1271_PSM_ILLEGAL, 394 .suspend_rx_ba_activity = 0, 395 }, 396 .itrim = { 397 .enable = false, 398 .timeout = 50000, 399 }, 400 .pm_config = { 401 .host_clk_settling_time = 5000, 402 .host_fast_wakeup_support = CONF_FAST_WAKEUP_DISABLE, 403 }, 404 .roam_trigger = { 405 .trigger_pacing = 1, 406 .avg_weight_rssi_beacon = 20, 407 .avg_weight_rssi_data = 10, 408 .avg_weight_snr_beacon = 20, 409 .avg_weight_snr_data = 10, 410 }, 411 .scan = { 412 .min_dwell_time_active = 7500, 413 .max_dwell_time_active = 30000, 414 .min_dwell_time_active_long = 25000, 415 .max_dwell_time_active_long = 50000, 416 .dwell_time_passive = 100000, 417 .dwell_time_dfs = 150000, 418 .num_probe_reqs = 2, 419 .split_scan_timeout = 50000, 420 }, 421 .sched_scan = { 422 /* 423 * Values are in TU/1000 but since sched scan FW command 424 * params are in TUs rounding up may occur. 425 */ 426 .base_dwell_time = 7500, 427 .max_dwell_time_delta = 22500, 428 /* based on 250bits per probe @1Mbps */ 429 .dwell_time_delta_per_probe = 2000, 430 /* based on 250bits per probe @6Mbps (plus a bit more) */ 431 .dwell_time_delta_per_probe_5 = 350, 432 .dwell_time_passive = 100000, 433 .dwell_time_dfs = 150000, 434 .num_probe_reqs = 2, 435 .rssi_threshold = -90, 436 .snr_threshold = 0, 437 .num_short_intervals = SCAN_MAX_SHORT_INTERVALS, 438 .long_interval = 30000, 439 }, 440 .ht = { 441 .rx_ba_win_size = 32, 442 .tx_ba_win_size = 64, 443 .inactivity_timeout = 10000, 444 .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP, 445 }, 446 .mem = { 447 .num_stations = 1, 448 .ssid_profiles = 1, 449 .rx_block_num = 40, 450 .tx_min_block_num = 40, 451 .dynamic_memory = 1, 452 .min_req_tx_blocks = 45, 453 .min_req_rx_blocks = 22, 454 .tx_min = 27, 455 }, 456 .fm_coex = { 457 .enable = true, 458 .swallow_period = 5, 459 .n_divider_fref_set_1 = 0xff, /* default */ 460 .n_divider_fref_set_2 = 12, 461 .m_divider_fref_set_1 = 0xffff, 462 .m_divider_fref_set_2 = 148, /* default */ 463 .coex_pll_stabilization_time = 0xffffffff, /* default */ 464 .ldo_stabilization_time = 0xffff, /* default */ 465 .fm_disturbed_band_margin = 0xff, /* default */ 466 .swallow_clk_diff = 0xff, /* default */ 467 }, 468 .rx_streaming = { 469 .duration = 150, 470 .queues = 0x1, 471 .interval = 20, 472 .always = 0, 473 }, 474 .fwlog = { 475 .mode = WL12XX_FWLOG_CONTINUOUS, 476 .mem_blocks = 0, 477 .severity = 0, 478 .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED, 479 .output = WL12XX_FWLOG_OUTPUT_DBG_PINS, 480 .threshold = 0, 481 }, 482 .rate = { 483 .rate_retry_score = 32000, 484 .per_add = 8192, 485 .per_th1 = 2048, 486 .per_th2 = 4096, 487 .max_per = 8100, 488 .inverse_curiosity_factor = 5, 489 .tx_fail_low_th = 4, 490 .tx_fail_high_th = 10, 491 .per_alpha_shift = 4, 492 .per_add_shift = 13, 493 .per_beta1_shift = 10, 494 .per_beta2_shift = 8, 495 .rate_check_up = 2, 496 .rate_check_down = 12, 497 .rate_retry_policy = { 498 0x00, 0x00, 0x00, 0x00, 0x00, 499 0x00, 0x00, 0x00, 0x00, 0x00, 500 0x00, 0x00, 0x00, 501 }, 502 }, 503 .hangover = { 504 .recover_time = 0, 505 .hangover_period = 20, 506 .dynamic_mode = 1, 507 .early_termination_mode = 1, 508 .max_period = 20, 509 .min_period = 1, 510 .increase_delta = 1, 511 .decrease_delta = 2, 512 .quiet_time = 4, 513 .increase_time = 1, 514 .window_size = 16, 515 }, 516 .recovery = { 517 .bug_on_recovery = 0, 518 .no_recovery = 0, 519 }, 520 }; 521 522 static struct wl18xx_priv_conf wl18xx_default_priv_conf = { 523 .ht = { 524 .mode = HT_MODE_WIDE, 525 }, 526 .phy = { 527 .phy_standalone = 0x00, 528 .primary_clock_setting_time = 0x05, 529 .clock_valid_on_wake_up = 0x00, 530 .secondary_clock_setting_time = 0x05, 531 .board_type = BOARD_TYPE_HDK_18XX, 532 .auto_detect = 0x00, 533 .dedicated_fem = FEM_NONE, 534 .low_band_component = COMPONENT_3_WAY_SWITCH, 535 .low_band_component_type = 0x05, 536 .high_band_component = COMPONENT_2_WAY_SWITCH, 537 .high_band_component_type = 0x09, 538 .tcxo_ldo_voltage = 0x00, 539 .xtal_itrim_val = 0x04, 540 .srf_state = 0x00, 541 .io_configuration = 0x01, 542 .sdio_configuration = 0x00, 543 .settings = 0x00, 544 .enable_clpc = 0x00, 545 .enable_tx_low_pwr_on_siso_rdl = 0x00, 546 .rx_profile = 0x00, 547 .pwr_limit_reference_11_abg = 0x64, 548 .per_chan_pwr_limit_arr_11abg = { 549 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 550 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 551 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 552 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 553 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 554 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 555 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 556 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 557 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 558 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 559 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 560 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 561 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 562 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 563 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 564 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 565 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 566 .pwr_limit_reference_11p = 0x64, 567 .per_chan_bo_mode_11_abg = { 0x00, 0x00, 0x00, 0x00, 568 0x00, 0x00, 0x00, 0x00, 569 0x00, 0x00, 0x00, 0x00, 570 0x00 }, 571 .per_chan_bo_mode_11_p = { 0x00, 0x00, 0x00, 0x00 }, 572 .per_chan_pwr_limit_arr_11p = { 0xff, 0xff, 0xff, 0xff, 573 0xff, 0xff, 0xff }, 574 .psat = 0, 575 .external_pa_dc2dc = 0, 576 .number_of_assembled_ant2_4 = 2, 577 .number_of_assembled_ant5 = 1, 578 .low_power_val = 0xff, 579 .med_power_val = 0xff, 580 .high_power_val = 0xff, 581 .low_power_val_2nd = 0xff, 582 .med_power_val_2nd = 0xff, 583 .high_power_val_2nd = 0xff, 584 .tx_rf_margin = 1, 585 }, 586 .ap_sleep = { /* disabled by default */ 587 .idle_duty_cycle = 0, 588 .connected_duty_cycle = 0, 589 .max_stations_thresh = 0, 590 .idle_conn_thresh = 0, 591 }, 592 }; 593 594 static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = { 595 [PART_TOP_PRCM_ELP_SOC] = { 596 .mem = { .start = 0x00A00000, .size = 0x00012000 }, 597 .reg = { .start = 0x00807000, .size = 0x00005000 }, 598 .mem2 = { .start = 0x00800000, .size = 0x0000B000 }, 599 .mem3 = { .start = 0x00401594, .size = 0x00001020 }, 600 }, 601 [PART_DOWN] = { 602 .mem = { .start = 0x00000000, .size = 0x00014000 }, 603 .reg = { .start = 0x00810000, .size = 0x0000BFFF }, 604 .mem2 = { .start = 0x00000000, .size = 0x00000000 }, 605 .mem3 = { .start = 0x00000000, .size = 0x00000000 }, 606 }, 607 [PART_BOOT] = { 608 .mem = { .start = 0x00700000, .size = 0x0000030c }, 609 .reg = { .start = 0x00802000, .size = 0x00014578 }, 610 .mem2 = { .start = 0x00B00404, .size = 0x00001000 }, 611 .mem3 = { .start = 0x00C00000, .size = 0x00000400 }, 612 }, 613 [PART_WORK] = { 614 .mem = { .start = 0x00800000, .size = 0x000050FC }, 615 .reg = { .start = 0x00B00404, .size = 0x00001000 }, 616 .mem2 = { .start = 0x00C00000, .size = 0x00000400 }, 617 .mem3 = { .start = 0x00401594, .size = 0x00001020 }, 618 }, 619 [PART_PHY_INIT] = { 620 .mem = { .start = WL18XX_PHY_INIT_MEM_ADDR, 621 .size = WL18XX_PHY_INIT_MEM_SIZE }, 622 .reg = { .start = 0x00000000, .size = 0x00000000 }, 623 .mem2 = { .start = 0x00000000, .size = 0x00000000 }, 624 .mem3 = { .start = 0x00000000, .size = 0x00000000 }, 625 }, 626 }; 627 628 static const int wl18xx_rtable[REG_TABLE_LEN] = { 629 [REG_ECPU_CONTROL] = WL18XX_REG_ECPU_CONTROL, 630 [REG_INTERRUPT_NO_CLEAR] = WL18XX_REG_INTERRUPT_NO_CLEAR, 631 [REG_INTERRUPT_ACK] = WL18XX_REG_INTERRUPT_ACK, 632 [REG_COMMAND_MAILBOX_PTR] = WL18XX_REG_COMMAND_MAILBOX_PTR, 633 [REG_EVENT_MAILBOX_PTR] = WL18XX_REG_EVENT_MAILBOX_PTR, 634 [REG_INTERRUPT_TRIG] = WL18XX_REG_INTERRUPT_TRIG_H, 635 [REG_INTERRUPT_MASK] = WL18XX_REG_INTERRUPT_MASK, 636 [REG_PC_ON_RECOVERY] = WL18XX_SCR_PAD4, 637 [REG_CHIP_ID_B] = WL18XX_REG_CHIP_ID_B, 638 [REG_CMD_MBOX_ADDRESS] = WL18XX_CMD_MBOX_ADDRESS, 639 640 /* data access memory addresses, used with partition translation */ 641 [REG_SLV_MEM_DATA] = WL18XX_SLV_MEM_DATA, 642 [REG_SLV_REG_DATA] = WL18XX_SLV_REG_DATA, 643 644 /* raw data access memory addresses */ 645 [REG_RAW_FW_STATUS_ADDR] = WL18XX_FW_STATUS_ADDR, 646 }; 647 648 static const struct wl18xx_clk_cfg wl18xx_clk_table_coex[NUM_CLOCK_CONFIGS] = { 649 [CLOCK_CONFIG_16_2_M] = { 8, 121, 0, 0, false }, 650 [CLOCK_CONFIG_16_368_M] = { 8, 120, 0, 0, false }, 651 [CLOCK_CONFIG_16_8_M] = { 8, 117, 0, 0, false }, 652 [CLOCK_CONFIG_19_2_M] = { 10, 128, 0, 0, false }, 653 [CLOCK_CONFIG_26_M] = { 11, 104, 0, 0, false }, 654 [CLOCK_CONFIG_32_736_M] = { 8, 120, 0, 0, false }, 655 [CLOCK_CONFIG_33_6_M] = { 8, 117, 0, 0, false }, 656 [CLOCK_CONFIG_38_468_M] = { 10, 128, 0, 0, false }, 657 [CLOCK_CONFIG_52_M] = { 11, 104, 0, 0, false }, 658 }; 659 660 static const struct wl18xx_clk_cfg wl18xx_clk_table[NUM_CLOCK_CONFIGS] = { 661 [CLOCK_CONFIG_16_2_M] = { 7, 104, 801, 4, true }, 662 [CLOCK_CONFIG_16_368_M] = { 9, 132, 3751, 4, true }, 663 [CLOCK_CONFIG_16_8_M] = { 7, 100, 0, 0, false }, 664 [CLOCK_CONFIG_19_2_M] = { 8, 100, 0, 0, false }, 665 [CLOCK_CONFIG_26_M] = { 13, 120, 0, 0, false }, 666 [CLOCK_CONFIG_32_736_M] = { 9, 132, 3751, 4, true }, 667 [CLOCK_CONFIG_33_6_M] = { 7, 100, 0, 0, false }, 668 [CLOCK_CONFIG_38_468_M] = { 8, 100, 0, 0, false }, 669 [CLOCK_CONFIG_52_M] = { 13, 120, 0, 0, false }, 670 }; 671 672 /* TODO: maybe move to a new header file? */ 673 #define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw-4.bin" 674 675 static int wl18xx_identify_chip(struct wl1271 *wl) 676 { 677 int ret = 0; 678 679 switch (wl->chip.id) { 680 case CHIP_ID_185x_PG20: 681 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG20)", 682 wl->chip.id); 683 wl->sr_fw_name = WL18XX_FW_NAME; 684 /* wl18xx uses the same firmware for PLT */ 685 wl->plt_fw_name = WL18XX_FW_NAME; 686 wl->quirks |= WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN | 687 WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN | 688 WLCORE_QUIRK_NO_SCHED_SCAN_WHILE_CONN | 689 WLCORE_QUIRK_TX_PAD_LAST_FRAME | 690 WLCORE_QUIRK_REGDOMAIN_CONF | 691 WLCORE_QUIRK_DUAL_PROBE_TMPL; 692 693 wlcore_set_min_fw_ver(wl, WL18XX_CHIP_VER, 694 WL18XX_IFTYPE_VER, WL18XX_MAJOR_VER, 695 WL18XX_SUBTYPE_VER, WL18XX_MINOR_VER, 696 /* there's no separate multi-role FW */ 697 0, 0, 0, 0); 698 break; 699 case CHIP_ID_185x_PG10: 700 wl1271_warning("chip id 0x%x (185x PG10) is deprecated", 701 wl->chip.id); 702 ret = -ENODEV; 703 goto out; 704 705 default: 706 wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); 707 ret = -ENODEV; 708 goto out; 709 } 710 711 wl->fw_mem_block_size = 272; 712 wl->fwlog_end = 0x40000000; 713 714 wl->scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4; 715 wl->scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5; 716 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC; 717 wl->sched_scan_templ_id_5 = CMD_TEMPL_PROBE_REQ_5_PERIODIC; 718 wl->max_channels_5 = WL18XX_MAX_CHANNELS_5GHZ; 719 wl->ba_rx_session_count_max = WL18XX_RX_BA_MAX_SESSIONS; 720 out: 721 return ret; 722 } 723 724 static int wl18xx_set_clk(struct wl1271 *wl) 725 { 726 u16 clk_freq; 727 int ret; 728 729 ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); 730 if (ret < 0) 731 goto out; 732 733 /* TODO: PG2: apparently we need to read the clk type */ 734 735 ret = wl18xx_top_reg_read(wl, PRIMARY_CLK_DETECT, &clk_freq); 736 if (ret < 0) 737 goto out; 738 739 wl1271_debug(DEBUG_BOOT, "clock freq %d (%d, %d, %d, %d, %s)", clk_freq, 740 wl18xx_clk_table[clk_freq].n, wl18xx_clk_table[clk_freq].m, 741 wl18xx_clk_table[clk_freq].p, wl18xx_clk_table[clk_freq].q, 742 wl18xx_clk_table[clk_freq].swallow ? "swallow" : "spit"); 743 744 /* coex PLL configuration */ 745 ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_N, 746 wl18xx_clk_table_coex[clk_freq].n); 747 if (ret < 0) 748 goto out; 749 750 ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_M, 751 wl18xx_clk_table_coex[clk_freq].m); 752 if (ret < 0) 753 goto out; 754 755 /* bypass the swallowing logic */ 756 ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_SWALLOW_EN, 757 PLLSH_COEX_PLL_SWALLOW_EN_VAL1); 758 if (ret < 0) 759 goto out; 760 761 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_N, 762 wl18xx_clk_table[clk_freq].n); 763 if (ret < 0) 764 goto out; 765 766 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_M, 767 wl18xx_clk_table[clk_freq].m); 768 if (ret < 0) 769 goto out; 770 771 if (wl18xx_clk_table[clk_freq].swallow) { 772 /* first the 16 lower bits */ 773 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_1, 774 wl18xx_clk_table[clk_freq].q & 775 PLLSH_WCS_PLL_Q_FACTOR_CFG_1_MASK); 776 if (ret < 0) 777 goto out; 778 779 /* then the 16 higher bits, masked out */ 780 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_2, 781 (wl18xx_clk_table[clk_freq].q >> 16) & 782 PLLSH_WCS_PLL_Q_FACTOR_CFG_2_MASK); 783 if (ret < 0) 784 goto out; 785 786 /* first the 16 lower bits */ 787 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_1, 788 wl18xx_clk_table[clk_freq].p & 789 PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK); 790 if (ret < 0) 791 goto out; 792 793 /* then the 16 higher bits, masked out */ 794 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_2, 795 (wl18xx_clk_table[clk_freq].p >> 16) & 796 PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK); 797 if (ret < 0) 798 goto out; 799 } else { 800 ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_SWALLOW_EN, 801 PLLSH_WCS_PLL_SWALLOW_EN_VAL2); 802 if (ret < 0) 803 goto out; 804 } 805 806 /* choose WCS PLL */ 807 ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_SEL, 808 PLLSH_WL_PLL_SEL_WCS_PLL); 809 if (ret < 0) 810 goto out; 811 812 /* enable both PLLs */ 813 ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_EN, PLLSH_WL_PLL_EN_VAL1); 814 if (ret < 0) 815 goto out; 816 817 udelay(1000); 818 819 /* disable coex PLL */ 820 ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_EN, PLLSH_WL_PLL_EN_VAL2); 821 if (ret < 0) 822 goto out; 823 824 /* reset the swallowing logic */ 825 ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_SWALLOW_EN, 826 PLLSH_COEX_PLL_SWALLOW_EN_VAL2); 827 828 out: 829 return ret; 830 } 831 832 static int wl18xx_boot_soft_reset(struct wl1271 *wl) 833 { 834 int ret; 835 836 /* disable Rx/Tx */ 837 ret = wlcore_write32(wl, WL18XX_ENABLE, 0x0); 838 if (ret < 0) 839 goto out; 840 841 /* disable auto calibration on start*/ 842 ret = wlcore_write32(wl, WL18XX_SPARE_A2, 0xffff); 843 844 out: 845 return ret; 846 } 847 848 static int wl18xx_pre_boot(struct wl1271 *wl) 849 { 850 int ret; 851 852 ret = wl18xx_set_clk(wl); 853 if (ret < 0) 854 goto out; 855 856 /* Continue the ELP wake up sequence */ 857 ret = wlcore_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); 858 if (ret < 0) 859 goto out; 860 861 udelay(500); 862 863 ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); 864 if (ret < 0) 865 goto out; 866 867 /* Disable interrupts */ 868 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); 869 if (ret < 0) 870 goto out; 871 872 ret = wl18xx_boot_soft_reset(wl); 873 874 out: 875 return ret; 876 } 877 878 static int wl18xx_pre_upload(struct wl1271 *wl) 879 { 880 u32 tmp; 881 int ret; 882 u16 irq_invert; 883 884 BUILD_BUG_ON(sizeof(struct wl18xx_mac_and_phy_params) > 885 WL18XX_PHY_INIT_MEM_SIZE); 886 887 ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); 888 if (ret < 0) 889 goto out; 890 891 /* TODO: check if this is all needed */ 892 ret = wlcore_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND); 893 if (ret < 0) 894 goto out; 895 896 ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp); 897 if (ret < 0) 898 goto out; 899 900 wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp); 901 902 ret = wlcore_read32(wl, WL18XX_SCR_PAD2, &tmp); 903 if (ret < 0) 904 goto out; 905 906 /* 907 * Workaround for FDSP code RAM corruption (needed for PG2.1 908 * and newer; for older chips it's a NOP). Change FDSP clock 909 * settings so that it's muxed to the ATGP clock instead of 910 * its own clock. 911 */ 912 913 ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); 914 if (ret < 0) 915 goto out; 916 917 /* disable FDSP clock */ 918 ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1, 919 MEM_FDSP_CLK_120_DISABLE); 920 if (ret < 0) 921 goto out; 922 923 /* set ATPG clock toward FDSP Code RAM rather than its own clock */ 924 ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1, 925 MEM_FDSP_CODERAM_FUNC_CLK_SEL); 926 if (ret < 0) 927 goto out; 928 929 /* re-enable FDSP clock */ 930 ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1, 931 MEM_FDSP_CLK_120_ENABLE); 932 if (ret < 0) 933 goto out; 934 935 ret = irq_get_trigger_type(wl->irq); 936 if ((ret == IRQ_TYPE_LEVEL_LOW) || (ret == IRQ_TYPE_EDGE_FALLING)) { 937 wl1271_info("using inverted interrupt logic: %d", ret); 938 ret = wlcore_set_partition(wl, 939 &wl->ptable[PART_TOP_PRCM_ELP_SOC]); 940 if (ret < 0) 941 goto out; 942 943 ret = wl18xx_top_reg_read(wl, TOP_FN0_CCCR_REG_32, &irq_invert); 944 if (ret < 0) 945 goto out; 946 947 irq_invert |= BIT(1); 948 ret = wl18xx_top_reg_write(wl, TOP_FN0_CCCR_REG_32, irq_invert); 949 if (ret < 0) 950 goto out; 951 952 ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); 953 } 954 955 out: 956 return ret; 957 } 958 959 static int wl18xx_set_mac_and_phy(struct wl1271 *wl) 960 { 961 struct wl18xx_priv *priv = wl->priv; 962 struct wl18xx_mac_and_phy_params *params; 963 int ret; 964 965 params = kmemdup(&priv->conf.phy, sizeof(*params), GFP_KERNEL); 966 if (!params) { 967 ret = -ENOMEM; 968 goto out; 969 } 970 971 ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); 972 if (ret < 0) 973 goto out; 974 975 ret = wlcore_write(wl, WL18XX_PHY_INIT_MEM_ADDR, params, 976 sizeof(*params), false); 977 978 out: 979 kfree(params); 980 return ret; 981 } 982 983 static int wl18xx_enable_interrupts(struct wl1271 *wl) 984 { 985 u32 event_mask, intr_mask; 986 int ret; 987 988 event_mask = WL18XX_ACX_EVENTS_VECTOR; 989 intr_mask = WL18XX_INTR_MASK; 990 991 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask); 992 if (ret < 0) 993 goto out; 994 995 wlcore_enable_interrupts(wl); 996 997 ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, 998 WL1271_ACX_INTR_ALL & ~intr_mask); 999 if (ret < 0) 1000 goto disable_interrupts; 1001 1002 return ret; 1003 1004 disable_interrupts: 1005 wlcore_disable_interrupts(wl); 1006 1007 out: 1008 return ret; 1009 } 1010 1011 static int wl18xx_boot(struct wl1271 *wl) 1012 { 1013 int ret; 1014 1015 ret = wl18xx_pre_boot(wl); 1016 if (ret < 0) 1017 goto out; 1018 1019 ret = wl18xx_pre_upload(wl); 1020 if (ret < 0) 1021 goto out; 1022 1023 ret = wlcore_boot_upload_firmware(wl); 1024 if (ret < 0) 1025 goto out; 1026 1027 ret = wl18xx_set_mac_and_phy(wl); 1028 if (ret < 0) 1029 goto out; 1030 1031 wl->event_mask = BSS_LOSS_EVENT_ID | 1032 SCAN_COMPLETE_EVENT_ID | 1033 RADAR_DETECTED_EVENT_ID | 1034 RSSI_SNR_TRIGGER_0_EVENT_ID | 1035 PERIODIC_SCAN_COMPLETE_EVENT_ID | 1036 PERIODIC_SCAN_REPORT_EVENT_ID | 1037 DUMMY_PACKET_EVENT_ID | 1038 PEER_REMOVE_COMPLETE_EVENT_ID | 1039 BA_SESSION_RX_CONSTRAINT_EVENT_ID | 1040 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID | 1041 INACTIVE_STA_EVENT_ID | 1042 CHANNEL_SWITCH_COMPLETE_EVENT_ID | 1043 DFS_CHANNELS_CONFIG_COMPLETE_EVENT | 1044 SMART_CONFIG_SYNC_EVENT_ID | 1045 SMART_CONFIG_DECODE_EVENT_ID | 1046 TIME_SYNC_EVENT_ID | 1047 FW_LOGGER_INDICATION | 1048 RX_BA_WIN_SIZE_CHANGE_EVENT_ID; 1049 1050 wl->ap_event_mask = MAX_TX_FAILURE_EVENT_ID; 1051 1052 ret = wlcore_boot_run_firmware(wl); 1053 if (ret < 0) 1054 goto out; 1055 1056 ret = wl18xx_enable_interrupts(wl); 1057 1058 out: 1059 return ret; 1060 } 1061 1062 static int wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr, 1063 void *buf, size_t len) 1064 { 1065 struct wl18xx_priv *priv = wl->priv; 1066 1067 memcpy(priv->cmd_buf, buf, len); 1068 memset(priv->cmd_buf + len, 0, WL18XX_CMD_MAX_SIZE - len); 1069 1070 return wlcore_write(wl, cmd_box_addr, priv->cmd_buf, 1071 WL18XX_CMD_MAX_SIZE, false); 1072 } 1073 1074 static int wl18xx_ack_event(struct wl1271 *wl) 1075 { 1076 return wlcore_write_reg(wl, REG_INTERRUPT_TRIG, 1077 WL18XX_INTR_TRIG_EVENT_ACK); 1078 } 1079 1080 static u32 wl18xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks) 1081 { 1082 u32 blk_size = WL18XX_TX_HW_BLOCK_SIZE; 1083 return (len + blk_size - 1) / blk_size + spare_blks; 1084 } 1085 1086 static void 1087 wl18xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, 1088 u32 blks, u32 spare_blks) 1089 { 1090 desc->wl18xx_mem.total_mem_blocks = blks; 1091 } 1092 1093 static void 1094 wl18xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, 1095 struct sk_buff *skb) 1096 { 1097 desc->length = cpu_to_le16(skb->len); 1098 1099 /* if only the last frame is to be padded, we unset this bit on Tx */ 1100 if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME) 1101 desc->wl18xx_mem.ctrl = WL18XX_TX_CTRL_NOT_PADDED; 1102 else 1103 desc->wl18xx_mem.ctrl = 0; 1104 1105 wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d " 1106 "len: %d life: %d mem: %d", desc->hlid, 1107 le16_to_cpu(desc->length), 1108 le16_to_cpu(desc->life_time), 1109 desc->wl18xx_mem.total_mem_blocks); 1110 } 1111 1112 static enum wl_rx_buf_align 1113 wl18xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc) 1114 { 1115 if (rx_desc & RX_BUF_PADDED_PAYLOAD) 1116 return WLCORE_RX_BUF_PADDED; 1117 1118 return WLCORE_RX_BUF_ALIGNED; 1119 } 1120 1121 static u32 wl18xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data, 1122 u32 data_len) 1123 { 1124 struct wl1271_rx_descriptor *desc = rx_data; 1125 1126 /* invalid packet */ 1127 if (data_len < sizeof(*desc)) 1128 return 0; 1129 1130 return data_len - sizeof(*desc); 1131 } 1132 1133 static void wl18xx_tx_immediate_completion(struct wl1271 *wl) 1134 { 1135 wl18xx_tx_immediate_complete(wl); 1136 } 1137 1138 static int wl18xx_set_host_cfg_bitmap(struct wl1271 *wl, u32 extra_mem_blk) 1139 { 1140 int ret; 1141 u32 sdio_align_size = 0; 1142 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE | 1143 HOST_IF_CFG_ADD_RX_ALIGNMENT; 1144 1145 /* Enable Tx SDIO padding */ 1146 if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN) { 1147 host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK; 1148 sdio_align_size = WL12XX_BUS_BLOCK_SIZE; 1149 } 1150 1151 /* Enable Rx SDIO padding */ 1152 if (wl->quirks & WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN) { 1153 host_cfg_bitmap |= HOST_IF_CFG_RX_PAD_TO_SDIO_BLK; 1154 sdio_align_size = WL12XX_BUS_BLOCK_SIZE; 1155 } 1156 1157 ret = wl18xx_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap, 1158 sdio_align_size, extra_mem_blk, 1159 WL18XX_HOST_IF_LEN_SIZE_FIELD); 1160 if (ret < 0) 1161 return ret; 1162 1163 return 0; 1164 } 1165 1166 static int wl18xx_hw_init(struct wl1271 *wl) 1167 { 1168 int ret; 1169 struct wl18xx_priv *priv = wl->priv; 1170 1171 /* (re)init private structures. Relevant on recovery as well. */ 1172 priv->last_fw_rls_idx = 0; 1173 priv->extra_spare_key_count = 0; 1174 1175 /* set the default amount of spare blocks in the bitmap */ 1176 ret = wl18xx_set_host_cfg_bitmap(wl, WL18XX_TX_HW_BLOCK_SPARE); 1177 if (ret < 0) 1178 return ret; 1179 1180 /* set the dynamic fw traces bitmap */ 1181 ret = wl18xx_acx_dynamic_fw_traces(wl); 1182 if (ret < 0) 1183 return ret; 1184 1185 if (checksum_param) { 1186 ret = wl18xx_acx_set_checksum_state(wl); 1187 if (ret != 0) 1188 return ret; 1189 } 1190 1191 return ret; 1192 } 1193 1194 static void wl18xx_convert_fw_status(struct wl1271 *wl, void *raw_fw_status, 1195 struct wl_fw_status *fw_status) 1196 { 1197 struct wl18xx_fw_status *int_fw_status = raw_fw_status; 1198 1199 fw_status->intr = le32_to_cpu(int_fw_status->intr); 1200 fw_status->fw_rx_counter = int_fw_status->fw_rx_counter; 1201 fw_status->drv_rx_counter = int_fw_status->drv_rx_counter; 1202 fw_status->tx_results_counter = int_fw_status->tx_results_counter; 1203 fw_status->rx_pkt_descs = int_fw_status->rx_pkt_descs; 1204 1205 fw_status->fw_localtime = le32_to_cpu(int_fw_status->fw_localtime); 1206 fw_status->link_ps_bitmap = le32_to_cpu(int_fw_status->link_ps_bitmap); 1207 fw_status->link_fast_bitmap = 1208 le32_to_cpu(int_fw_status->link_fast_bitmap); 1209 fw_status->total_released_blks = 1210 le32_to_cpu(int_fw_status->total_released_blks); 1211 fw_status->tx_total = le32_to_cpu(int_fw_status->tx_total); 1212 1213 fw_status->counters.tx_released_pkts = 1214 int_fw_status->counters.tx_released_pkts; 1215 fw_status->counters.tx_lnk_free_pkts = 1216 int_fw_status->counters.tx_lnk_free_pkts; 1217 fw_status->counters.tx_voice_released_blks = 1218 int_fw_status->counters.tx_voice_released_blks; 1219 fw_status->counters.tx_last_rate = 1220 int_fw_status->counters.tx_last_rate; 1221 fw_status->counters.tx_last_rate_mbps = 1222 int_fw_status->counters.tx_last_rate_mbps; 1223 fw_status->counters.hlid = 1224 int_fw_status->counters.hlid; 1225 1226 fw_status->log_start_addr = le32_to_cpu(int_fw_status->log_start_addr); 1227 1228 fw_status->priv = &int_fw_status->priv; 1229 } 1230 1231 static void wl18xx_set_tx_desc_csum(struct wl1271 *wl, 1232 struct wl1271_tx_hw_descr *desc, 1233 struct sk_buff *skb) 1234 { 1235 u32 ip_hdr_offset; 1236 struct iphdr *ip_hdr; 1237 1238 if (!checksum_param) { 1239 desc->wl18xx_checksum_data = 0; 1240 return; 1241 } 1242 1243 if (skb->ip_summed != CHECKSUM_PARTIAL) { 1244 desc->wl18xx_checksum_data = 0; 1245 return; 1246 } 1247 1248 ip_hdr_offset = skb_network_header(skb) - skb_mac_header(skb); 1249 if (WARN_ON(ip_hdr_offset >= (1<<7))) { 1250 desc->wl18xx_checksum_data = 0; 1251 return; 1252 } 1253 1254 desc->wl18xx_checksum_data = ip_hdr_offset << 1; 1255 1256 /* FW is interested only in the LSB of the protocol TCP=0 UDP=1 */ 1257 ip_hdr = (void *)skb_network_header(skb); 1258 desc->wl18xx_checksum_data |= (ip_hdr->protocol & 0x01); 1259 } 1260 1261 static void wl18xx_set_rx_csum(struct wl1271 *wl, 1262 struct wl1271_rx_descriptor *desc, 1263 struct sk_buff *skb) 1264 { 1265 if (desc->status & WL18XX_RX_CHECKSUM_MASK) 1266 skb->ip_summed = CHECKSUM_UNNECESSARY; 1267 } 1268 1269 static bool wl18xx_is_mimo_supported(struct wl1271 *wl) 1270 { 1271 struct wl18xx_priv *priv = wl->priv; 1272 1273 /* only support MIMO with multiple antennas, and when SISO 1274 * is not forced through config 1275 */ 1276 return (priv->conf.phy.number_of_assembled_ant2_4 >= 2) && 1277 (priv->conf.ht.mode != HT_MODE_WIDE) && 1278 (priv->conf.ht.mode != HT_MODE_SISO20); 1279 } 1280 1281 /* 1282 * TODO: instead of having these two functions to get the rate mask, 1283 * we should modify the wlvif->rate_set instead 1284 */ 1285 static u32 wl18xx_sta_get_ap_rate_mask(struct wl1271 *wl, 1286 struct wl12xx_vif *wlvif) 1287 { 1288 u32 hw_rate_set = wlvif->rate_set; 1289 1290 if (wlvif->channel_type == NL80211_CHAN_HT40MINUS || 1291 wlvif->channel_type == NL80211_CHAN_HT40PLUS) { 1292 wl1271_debug(DEBUG_ACX, "using wide channel rate mask"); 1293 hw_rate_set |= CONF_TX_RATE_USE_WIDE_CHAN; 1294 1295 /* we don't support MIMO in wide-channel mode */ 1296 hw_rate_set &= ~CONF_TX_MIMO_RATES; 1297 } else if (wl18xx_is_mimo_supported(wl)) { 1298 wl1271_debug(DEBUG_ACX, "using MIMO channel rate mask"); 1299 hw_rate_set |= CONF_TX_MIMO_RATES; 1300 } 1301 1302 return hw_rate_set; 1303 } 1304 1305 static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, 1306 struct wl12xx_vif *wlvif) 1307 { 1308 if (wlvif->channel_type == NL80211_CHAN_HT40MINUS || 1309 wlvif->channel_type == NL80211_CHAN_HT40PLUS) { 1310 wl1271_debug(DEBUG_ACX, "using wide channel rate mask"); 1311 1312 /* sanity check - we don't support this */ 1313 if (WARN_ON(wlvif->band != NL80211_BAND_5GHZ)) 1314 return 0; 1315 1316 return CONF_TX_RATE_USE_WIDE_CHAN; 1317 } else if (wl18xx_is_mimo_supported(wl) && 1318 wlvif->band == NL80211_BAND_2GHZ) { 1319 wl1271_debug(DEBUG_ACX, "using MIMO rate mask"); 1320 /* 1321 * we don't care about HT channel here - if a peer doesn't 1322 * support MIMO, we won't enable it in its rates 1323 */ 1324 return CONF_TX_MIMO_RATES; 1325 } else { 1326 return 0; 1327 } 1328 } 1329 1330 static const char *wl18xx_rdl_name(enum wl18xx_rdl_num rdl_num) 1331 { 1332 switch (rdl_num) { 1333 case RDL_1_HP: 1334 return "183xH"; 1335 case RDL_2_SP: 1336 return "183x or 180x"; 1337 case RDL_3_HP: 1338 return "187xH"; 1339 case RDL_4_SP: 1340 return "187x"; 1341 case RDL_5_SP: 1342 return "RDL11 - Not Supported"; 1343 case RDL_6_SP: 1344 return "180xD"; 1345 case RDL_7_SP: 1346 return "RDL13 - Not Supported (1893Q)"; 1347 case RDL_8_SP: 1348 return "18xxQ"; 1349 case RDL_NONE: 1350 return "UNTRIMMED"; 1351 default: 1352 return "UNKNOWN"; 1353 } 1354 } 1355 1356 static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver) 1357 { 1358 u32 fuse; 1359 s8 rom = 0, metal = 0, pg_ver = 0, rdl_ver = 0, package_type = 0; 1360 int ret; 1361 1362 ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); 1363 if (ret < 0) 1364 goto out; 1365 1366 ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_2_3, &fuse); 1367 if (ret < 0) 1368 goto out; 1369 1370 package_type = (fuse >> WL18XX_PACKAGE_TYPE_OFFSET) & 1; 1371 1372 ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_1_3, &fuse); 1373 if (ret < 0) 1374 goto out; 1375 1376 pg_ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET; 1377 rom = (fuse & WL18XX_ROM_VER_MASK) >> WL18XX_ROM_VER_OFFSET; 1378 1379 if ((rom <= 0xE) && (package_type == WL18XX_PACKAGE_TYPE_WSP)) 1380 metal = (fuse & WL18XX_METAL_VER_MASK) >> 1381 WL18XX_METAL_VER_OFFSET; 1382 else 1383 metal = (fuse & WL18XX_NEW_METAL_VER_MASK) >> 1384 WL18XX_NEW_METAL_VER_OFFSET; 1385 1386 ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_2_3, &fuse); 1387 if (ret < 0) 1388 goto out; 1389 1390 rdl_ver = (fuse & WL18XX_RDL_VER_MASK) >> WL18XX_RDL_VER_OFFSET; 1391 1392 wl1271_info("wl18xx HW: %s, PG %d.%d (ROM 0x%x)", 1393 wl18xx_rdl_name(rdl_ver), pg_ver, metal, rom); 1394 1395 if (ver) 1396 *ver = pg_ver; 1397 1398 ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); 1399 1400 out: 1401 return ret; 1402 } 1403 1404 static int wl18xx_load_conf_file(struct device *dev, struct wlcore_conf *conf, 1405 struct wl18xx_priv_conf *priv_conf, 1406 const char *file) 1407 { 1408 struct wlcore_conf_file *conf_file; 1409 const struct firmware *fw; 1410 int ret; 1411 1412 ret = request_firmware(&fw, file, dev); 1413 if (ret < 0) { 1414 wl1271_error("could not get configuration binary %s: %d", 1415 file, ret); 1416 return ret; 1417 } 1418 1419 if (fw->size != WL18XX_CONF_SIZE) { 1420 wl1271_error("%s configuration binary size is wrong, expected %zu got %zu", 1421 file, WL18XX_CONF_SIZE, fw->size); 1422 ret = -EINVAL; 1423 goto out_release; 1424 } 1425 1426 conf_file = (struct wlcore_conf_file *) fw->data; 1427 1428 if (conf_file->header.magic != cpu_to_le32(WL18XX_CONF_MAGIC)) { 1429 wl1271_error("configuration binary file magic number mismatch, " 1430 "expected 0x%0x got 0x%0x", WL18XX_CONF_MAGIC, 1431 conf_file->header.magic); 1432 ret = -EINVAL; 1433 goto out_release; 1434 } 1435 1436 if (conf_file->header.version != cpu_to_le32(WL18XX_CONF_VERSION)) { 1437 wl1271_error("configuration binary file version not supported, " 1438 "expected 0x%08x got 0x%08x", 1439 WL18XX_CONF_VERSION, conf_file->header.version); 1440 ret = -EINVAL; 1441 goto out_release; 1442 } 1443 1444 memcpy(conf, &conf_file->core, sizeof(*conf)); 1445 memcpy(priv_conf, &conf_file->priv, sizeof(*priv_conf)); 1446 1447 out_release: 1448 release_firmware(fw); 1449 return ret; 1450 } 1451 1452 static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev) 1453 { 1454 struct platform_device *pdev = wl->pdev; 1455 struct wlcore_platdev_data *pdata = dev_get_platdata(&pdev->dev); 1456 struct wl18xx_priv *priv = wl->priv; 1457 1458 if (wl18xx_load_conf_file(dev, &wl->conf, &priv->conf, 1459 pdata->family->cfg_name) < 0) { 1460 wl1271_warning("falling back to default config"); 1461 1462 /* apply driver default configuration */ 1463 memcpy(&wl->conf, &wl18xx_conf, sizeof(wl->conf)); 1464 /* apply default private configuration */ 1465 memcpy(&priv->conf, &wl18xx_default_priv_conf, 1466 sizeof(priv->conf)); 1467 } 1468 1469 return 0; 1470 } 1471 1472 static int wl18xx_plt_init(struct wl1271 *wl) 1473 { 1474 int ret; 1475 1476 /* calibrator based auto/fem detect not supported for 18xx */ 1477 if (wl->plt_mode == PLT_FEM_DETECT) { 1478 wl1271_error("wl18xx_plt_init: PLT FEM_DETECT not supported"); 1479 return -EINVAL; 1480 } 1481 1482 ret = wlcore_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT); 1483 if (ret < 0) 1484 return ret; 1485 1486 return wl->ops->boot(wl); 1487 } 1488 1489 static int wl18xx_get_mac(struct wl1271 *wl) 1490 { 1491 u32 mac1, mac2; 1492 int ret; 1493 1494 ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); 1495 if (ret < 0) 1496 goto out; 1497 1498 ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1, &mac1); 1499 if (ret < 0) 1500 goto out; 1501 1502 ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_2, &mac2); 1503 if (ret < 0) 1504 goto out; 1505 1506 /* these are the two parts of the BD_ADDR */ 1507 wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) + 1508 ((mac1 & 0xff000000) >> 24); 1509 wl->fuse_nic_addr = (mac1 & 0xffffff); 1510 1511 if (!wl->fuse_oui_addr && !wl->fuse_nic_addr) { 1512 u8 mac[ETH_ALEN]; 1513 1514 eth_random_addr(mac); 1515 1516 wl->fuse_oui_addr = (mac[0] << 16) + (mac[1] << 8) + mac[2]; 1517 wl->fuse_nic_addr = (mac[3] << 16) + (mac[4] << 8) + mac[5]; 1518 wl1271_warning("MAC address from fuse not available, using random locally administered addresses."); 1519 } 1520 1521 ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]); 1522 1523 out: 1524 return ret; 1525 } 1526 1527 static int wl18xx_handle_static_data(struct wl1271 *wl, 1528 struct wl1271_static_data *static_data) 1529 { 1530 struct wl18xx_static_data_priv *static_data_priv = 1531 (struct wl18xx_static_data_priv *) static_data->priv; 1532 1533 strncpy(wl->chip.phy_fw_ver_str, static_data_priv->phy_version, 1534 sizeof(wl->chip.phy_fw_ver_str)); 1535 1536 /* make sure the string is NULL-terminated */ 1537 wl->chip.phy_fw_ver_str[sizeof(wl->chip.phy_fw_ver_str) - 1] = '\0'; 1538 1539 wl1271_info("PHY firmware version: %s", static_data_priv->phy_version); 1540 1541 return 0; 1542 } 1543 1544 static int wl18xx_get_spare_blocks(struct wl1271 *wl, bool is_gem) 1545 { 1546 struct wl18xx_priv *priv = wl->priv; 1547 1548 /* If we have keys requiring extra spare, indulge them */ 1549 if (priv->extra_spare_key_count) 1550 return WL18XX_TX_HW_EXTRA_BLOCK_SPARE; 1551 1552 return WL18XX_TX_HW_BLOCK_SPARE; 1553 } 1554 1555 static int wl18xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd, 1556 struct ieee80211_vif *vif, 1557 struct ieee80211_sta *sta, 1558 struct ieee80211_key_conf *key_conf) 1559 { 1560 struct wl18xx_priv *priv = wl->priv; 1561 bool change_spare = false, special_enc; 1562 int ret; 1563 1564 wl1271_debug(DEBUG_CRYPT, "extra spare keys before: %d", 1565 priv->extra_spare_key_count); 1566 1567 special_enc = key_conf->cipher == WL1271_CIPHER_SUITE_GEM || 1568 key_conf->cipher == WLAN_CIPHER_SUITE_TKIP; 1569 1570 ret = wlcore_set_key(wl, cmd, vif, sta, key_conf); 1571 if (ret < 0) 1572 goto out; 1573 1574 /* 1575 * when adding the first or removing the last GEM/TKIP key, 1576 * we have to adjust the number of spare blocks. 1577 */ 1578 if (special_enc) { 1579 if (cmd == SET_KEY) { 1580 /* first key */ 1581 change_spare = (priv->extra_spare_key_count == 0); 1582 priv->extra_spare_key_count++; 1583 } else if (cmd == DISABLE_KEY) { 1584 /* last key */ 1585 change_spare = (priv->extra_spare_key_count == 1); 1586 priv->extra_spare_key_count--; 1587 } 1588 } 1589 1590 wl1271_debug(DEBUG_CRYPT, "extra spare keys after: %d", 1591 priv->extra_spare_key_count); 1592 1593 if (!change_spare) 1594 goto out; 1595 1596 /* key is now set, change the spare blocks */ 1597 if (priv->extra_spare_key_count) 1598 ret = wl18xx_set_host_cfg_bitmap(wl, 1599 WL18XX_TX_HW_EXTRA_BLOCK_SPARE); 1600 else 1601 ret = wl18xx_set_host_cfg_bitmap(wl, 1602 WL18XX_TX_HW_BLOCK_SPARE); 1603 1604 out: 1605 return ret; 1606 } 1607 1608 static u32 wl18xx_pre_pkt_send(struct wl1271 *wl, 1609 u32 buf_offset, u32 last_len) 1610 { 1611 if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME) { 1612 struct wl1271_tx_hw_descr *last_desc; 1613 1614 /* get the last TX HW descriptor written to the aggr buf */ 1615 last_desc = (struct wl1271_tx_hw_descr *)(wl->aggr_buf + 1616 buf_offset - last_len); 1617 1618 /* the last frame is padded up to an SDIO block */ 1619 last_desc->wl18xx_mem.ctrl &= ~WL18XX_TX_CTRL_NOT_PADDED; 1620 return ALIGN(buf_offset, WL12XX_BUS_BLOCK_SIZE); 1621 } 1622 1623 /* no modifications */ 1624 return buf_offset; 1625 } 1626 1627 static void wl18xx_sta_rc_update(struct wl1271 *wl, 1628 struct wl12xx_vif *wlvif) 1629 { 1630 bool wide = wlvif->rc_update_bw >= IEEE80211_STA_RX_BW_40; 1631 1632 wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update wide %d", wide); 1633 1634 /* sanity */ 1635 if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS)) 1636 return; 1637 1638 /* ignore the change before association */ 1639 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) 1640 return; 1641 1642 /* 1643 * If we started out as wide, we can change the operation mode. If we 1644 * thought this was a 20mhz AP, we have to reconnect 1645 */ 1646 if (wlvif->sta.role_chan_type == NL80211_CHAN_HT40MINUS || 1647 wlvif->sta.role_chan_type == NL80211_CHAN_HT40PLUS) 1648 wl18xx_acx_peer_ht_operation_mode(wl, wlvif->sta.hlid, wide); 1649 else 1650 ieee80211_connection_loss(wl12xx_wlvif_to_vif(wlvif)); 1651 } 1652 1653 static int wl18xx_set_peer_cap(struct wl1271 *wl, 1654 struct ieee80211_sta_ht_cap *ht_cap, 1655 bool allow_ht_operation, 1656 u32 rate_set, u8 hlid) 1657 { 1658 return wl18xx_acx_set_peer_cap(wl, ht_cap, allow_ht_operation, 1659 rate_set, hlid); 1660 } 1661 1662 static bool wl18xx_lnk_high_prio(struct wl1271 *wl, u8 hlid, 1663 struct wl1271_link *lnk) 1664 { 1665 u8 thold; 1666 struct wl18xx_fw_status_priv *status_priv = 1667 (struct wl18xx_fw_status_priv *)wl->fw_status->priv; 1668 unsigned long suspend_bitmap; 1669 1670 /* if we don't have the link map yet, assume they all low prio */ 1671 if (!status_priv) 1672 return false; 1673 1674 /* suspended links are never high priority */ 1675 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap); 1676 if (test_bit(hlid, &suspend_bitmap)) 1677 return false; 1678 1679 /* the priority thresholds are taken from FW */ 1680 if (test_bit(hlid, &wl->fw_fast_lnk_map) && 1681 !test_bit(hlid, &wl->ap_fw_ps_map)) 1682 thold = status_priv->tx_fast_link_prio_threshold; 1683 else 1684 thold = status_priv->tx_slow_link_prio_threshold; 1685 1686 return lnk->allocated_pkts < thold; 1687 } 1688 1689 static bool wl18xx_lnk_low_prio(struct wl1271 *wl, u8 hlid, 1690 struct wl1271_link *lnk) 1691 { 1692 u8 thold; 1693 struct wl18xx_fw_status_priv *status_priv = 1694 (struct wl18xx_fw_status_priv *)wl->fw_status->priv; 1695 unsigned long suspend_bitmap; 1696 1697 /* if we don't have the link map yet, assume they all low prio */ 1698 if (!status_priv) 1699 return true; 1700 1701 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap); 1702 if (test_bit(hlid, &suspend_bitmap)) 1703 thold = status_priv->tx_suspend_threshold; 1704 else if (test_bit(hlid, &wl->fw_fast_lnk_map) && 1705 !test_bit(hlid, &wl->ap_fw_ps_map)) 1706 thold = status_priv->tx_fast_stop_threshold; 1707 else 1708 thold = status_priv->tx_slow_stop_threshold; 1709 1710 return lnk->allocated_pkts < thold; 1711 } 1712 1713 static u32 wl18xx_convert_hwaddr(struct wl1271 *wl, u32 hwaddr) 1714 { 1715 return hwaddr & ~0x80000000; 1716 } 1717 1718 static int wl18xx_setup(struct wl1271 *wl); 1719 1720 static struct wlcore_ops wl18xx_ops = { 1721 .setup = wl18xx_setup, 1722 .identify_chip = wl18xx_identify_chip, 1723 .boot = wl18xx_boot, 1724 .plt_init = wl18xx_plt_init, 1725 .trigger_cmd = wl18xx_trigger_cmd, 1726 .ack_event = wl18xx_ack_event, 1727 .wait_for_event = wl18xx_wait_for_event, 1728 .process_mailbox_events = wl18xx_process_mailbox_events, 1729 .calc_tx_blocks = wl18xx_calc_tx_blocks, 1730 .set_tx_desc_blocks = wl18xx_set_tx_desc_blocks, 1731 .set_tx_desc_data_len = wl18xx_set_tx_desc_data_len, 1732 .get_rx_buf_align = wl18xx_get_rx_buf_align, 1733 .get_rx_packet_len = wl18xx_get_rx_packet_len, 1734 .tx_immediate_compl = wl18xx_tx_immediate_completion, 1735 .tx_delayed_compl = NULL, 1736 .hw_init = wl18xx_hw_init, 1737 .convert_fw_status = wl18xx_convert_fw_status, 1738 .set_tx_desc_csum = wl18xx_set_tx_desc_csum, 1739 .get_pg_ver = wl18xx_get_pg_ver, 1740 .set_rx_csum = wl18xx_set_rx_csum, 1741 .sta_get_ap_rate_mask = wl18xx_sta_get_ap_rate_mask, 1742 .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask, 1743 .get_mac = wl18xx_get_mac, 1744 .debugfs_init = wl18xx_debugfs_add_files, 1745 .scan_start = wl18xx_scan_start, 1746 .scan_stop = wl18xx_scan_stop, 1747 .sched_scan_start = wl18xx_sched_scan_start, 1748 .sched_scan_stop = wl18xx_scan_sched_scan_stop, 1749 .handle_static_data = wl18xx_handle_static_data, 1750 .get_spare_blocks = wl18xx_get_spare_blocks, 1751 .set_key = wl18xx_set_key, 1752 .channel_switch = wl18xx_cmd_channel_switch, 1753 .pre_pkt_send = wl18xx_pre_pkt_send, 1754 .sta_rc_update = wl18xx_sta_rc_update, 1755 .set_peer_cap = wl18xx_set_peer_cap, 1756 .convert_hwaddr = wl18xx_convert_hwaddr, 1757 .lnk_high_prio = wl18xx_lnk_high_prio, 1758 .lnk_low_prio = wl18xx_lnk_low_prio, 1759 .smart_config_start = wl18xx_cmd_smart_config_start, 1760 .smart_config_stop = wl18xx_cmd_smart_config_stop, 1761 .smart_config_set_group_key = wl18xx_cmd_smart_config_set_group_key, 1762 .interrupt_notify = wl18xx_acx_interrupt_notify_config, 1763 .rx_ba_filter = wl18xx_acx_rx_ba_filter, 1764 .ap_sleep = wl18xx_acx_ap_sleep, 1765 .set_cac = wl18xx_cmd_set_cac, 1766 .dfs_master_restart = wl18xx_cmd_dfs_master_restart, 1767 }; 1768 1769 /* HT cap appropriate for wide channels in 2Ghz */ 1770 static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = { 1771 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | 1772 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40 | 1773 IEEE80211_HT_CAP_GRN_FLD, 1774 .ht_supported = true, 1775 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, 1776 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1777 .mcs = { 1778 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 1779 .rx_highest = cpu_to_le16(150), 1780 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, 1781 }, 1782 }; 1783 1784 /* HT cap appropriate for wide channels in 5Ghz */ 1785 static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = { 1786 .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | 1787 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 1788 IEEE80211_HT_CAP_GRN_FLD, 1789 .ht_supported = true, 1790 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, 1791 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1792 .mcs = { 1793 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 1794 .rx_highest = cpu_to_le16(150), 1795 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, 1796 }, 1797 }; 1798 1799 /* HT cap appropriate for SISO 20 */ 1800 static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = { 1801 .cap = IEEE80211_HT_CAP_SGI_20 | 1802 IEEE80211_HT_CAP_GRN_FLD, 1803 .ht_supported = true, 1804 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, 1805 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1806 .mcs = { 1807 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 1808 .rx_highest = cpu_to_le16(72), 1809 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, 1810 }, 1811 }; 1812 1813 /* HT cap appropriate for MIMO rates in 20mhz channel */ 1814 static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = { 1815 .cap = IEEE80211_HT_CAP_SGI_20 | 1816 IEEE80211_HT_CAP_GRN_FLD, 1817 .ht_supported = true, 1818 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, 1819 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1820 .mcs = { 1821 .rx_mask = { 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, }, 1822 .rx_highest = cpu_to_le16(144), 1823 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, 1824 }, 1825 }; 1826 1827 static const struct ieee80211_iface_limit wl18xx_iface_limits[] = { 1828 { 1829 .max = 2, 1830 .types = BIT(NL80211_IFTYPE_STATION), 1831 }, 1832 { 1833 .max = 1, 1834 .types = BIT(NL80211_IFTYPE_AP) 1835 | BIT(NL80211_IFTYPE_P2P_GO) 1836 | BIT(NL80211_IFTYPE_P2P_CLIENT) 1837 #ifdef CONFIG_MAC80211_MESH 1838 | BIT(NL80211_IFTYPE_MESH_POINT) 1839 #endif 1840 }, 1841 { 1842 .max = 1, 1843 .types = BIT(NL80211_IFTYPE_P2P_DEVICE), 1844 }, 1845 }; 1846 1847 static const struct ieee80211_iface_limit wl18xx_iface_ap_limits[] = { 1848 { 1849 .max = 2, 1850 .types = BIT(NL80211_IFTYPE_AP), 1851 }, 1852 #ifdef CONFIG_MAC80211_MESH 1853 { 1854 .max = 1, 1855 .types = BIT(NL80211_IFTYPE_MESH_POINT), 1856 }, 1857 #endif 1858 { 1859 .max = 1, 1860 .types = BIT(NL80211_IFTYPE_P2P_DEVICE), 1861 }, 1862 }; 1863 1864 static const struct ieee80211_iface_limit wl18xx_iface_ap_cl_limits[] = { 1865 { 1866 .max = 1, 1867 .types = BIT(NL80211_IFTYPE_STATION), 1868 }, 1869 { 1870 .max = 1, 1871 .types = BIT(NL80211_IFTYPE_AP), 1872 }, 1873 { 1874 .max = 1, 1875 .types = BIT(NL80211_IFTYPE_P2P_CLIENT), 1876 }, 1877 { 1878 .max = 1, 1879 .types = BIT(NL80211_IFTYPE_P2P_DEVICE), 1880 }, 1881 }; 1882 1883 static const struct ieee80211_iface_limit wl18xx_iface_ap_go_limits[] = { 1884 { 1885 .max = 1, 1886 .types = BIT(NL80211_IFTYPE_STATION), 1887 }, 1888 { 1889 .max = 1, 1890 .types = BIT(NL80211_IFTYPE_AP), 1891 }, 1892 { 1893 .max = 1, 1894 .types = BIT(NL80211_IFTYPE_P2P_GO), 1895 }, 1896 { 1897 .max = 1, 1898 .types = BIT(NL80211_IFTYPE_P2P_DEVICE), 1899 }, 1900 }; 1901 1902 static const struct ieee80211_iface_combination 1903 wl18xx_iface_combinations[] = { 1904 { 1905 .max_interfaces = 3, 1906 .limits = wl18xx_iface_limits, 1907 .n_limits = ARRAY_SIZE(wl18xx_iface_limits), 1908 .num_different_channels = 2, 1909 }, 1910 { 1911 .max_interfaces = 2, 1912 .limits = wl18xx_iface_ap_limits, 1913 .n_limits = ARRAY_SIZE(wl18xx_iface_ap_limits), 1914 .num_different_channels = 1, 1915 .radar_detect_widths = BIT(NL80211_CHAN_NO_HT) | 1916 BIT(NL80211_CHAN_HT20) | 1917 BIT(NL80211_CHAN_HT40MINUS) | 1918 BIT(NL80211_CHAN_HT40PLUS), 1919 } 1920 }; 1921 1922 static int wl18xx_setup(struct wl1271 *wl) 1923 { 1924 struct wl18xx_priv *priv = wl->priv; 1925 int ret; 1926 1927 BUILD_BUG_ON(WL18XX_MAX_LINKS > WLCORE_MAX_LINKS); 1928 BUILD_BUG_ON(WL18XX_MAX_AP_STATIONS > WL18XX_MAX_LINKS); 1929 BUILD_BUG_ON(WL18XX_CONF_SG_PARAMS_MAX > WLCORE_CONF_SG_PARAMS_MAX); 1930 1931 wl->rtable = wl18xx_rtable; 1932 wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS; 1933 wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS; 1934 wl->num_links = WL18XX_MAX_LINKS; 1935 wl->max_ap_stations = WL18XX_MAX_AP_STATIONS; 1936 wl->iface_combinations = wl18xx_iface_combinations; 1937 wl->n_iface_combinations = ARRAY_SIZE(wl18xx_iface_combinations); 1938 wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES; 1939 wl->band_rate_to_idx = wl18xx_band_rate_to_idx; 1940 wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; 1941 wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; 1942 wl->fw_status_len = sizeof(struct wl18xx_fw_status); 1943 wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv); 1944 wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics); 1945 wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv); 1946 1947 if (num_rx_desc_param != -1) 1948 wl->num_rx_desc = num_rx_desc_param; 1949 1950 ret = wl18xx_conf_init(wl, wl->dev); 1951 if (ret < 0) 1952 return ret; 1953 1954 /* If the module param is set, update it in conf */ 1955 if (board_type_param) { 1956 if (!strcmp(board_type_param, "fpga")) { 1957 priv->conf.phy.board_type = BOARD_TYPE_FPGA_18XX; 1958 } else if (!strcmp(board_type_param, "hdk")) { 1959 priv->conf.phy.board_type = BOARD_TYPE_HDK_18XX; 1960 } else if (!strcmp(board_type_param, "dvp")) { 1961 priv->conf.phy.board_type = BOARD_TYPE_DVP_18XX; 1962 } else if (!strcmp(board_type_param, "evb")) { 1963 priv->conf.phy.board_type = BOARD_TYPE_EVB_18XX; 1964 } else if (!strcmp(board_type_param, "com8")) { 1965 priv->conf.phy.board_type = BOARD_TYPE_COM8_18XX; 1966 } else { 1967 wl1271_error("invalid board type '%s'", 1968 board_type_param); 1969 return -EINVAL; 1970 } 1971 } 1972 1973 if (priv->conf.phy.board_type >= NUM_BOARD_TYPES) { 1974 wl1271_error("invalid board type '%d'", 1975 priv->conf.phy.board_type); 1976 return -EINVAL; 1977 } 1978 1979 if (low_band_component_param != -1) 1980 priv->conf.phy.low_band_component = low_band_component_param; 1981 if (low_band_component_type_param != -1) 1982 priv->conf.phy.low_band_component_type = 1983 low_band_component_type_param; 1984 if (high_band_component_param != -1) 1985 priv->conf.phy.high_band_component = high_band_component_param; 1986 if (high_band_component_type_param != -1) 1987 priv->conf.phy.high_band_component_type = 1988 high_band_component_type_param; 1989 if (pwr_limit_reference_11_abg_param != -1) 1990 priv->conf.phy.pwr_limit_reference_11_abg = 1991 pwr_limit_reference_11_abg_param; 1992 if (n_antennas_2_param != -1) 1993 priv->conf.phy.number_of_assembled_ant2_4 = n_antennas_2_param; 1994 if (n_antennas_5_param != -1) 1995 priv->conf.phy.number_of_assembled_ant5 = n_antennas_5_param; 1996 if (dc2dc_param != -1) 1997 priv->conf.phy.external_pa_dc2dc = dc2dc_param; 1998 1999 if (ht_mode_param) { 2000 if (!strcmp(ht_mode_param, "default")) 2001 priv->conf.ht.mode = HT_MODE_DEFAULT; 2002 else if (!strcmp(ht_mode_param, "wide")) 2003 priv->conf.ht.mode = HT_MODE_WIDE; 2004 else if (!strcmp(ht_mode_param, "siso20")) 2005 priv->conf.ht.mode = HT_MODE_SISO20; 2006 else { 2007 wl1271_error("invalid ht_mode '%s'", ht_mode_param); 2008 return -EINVAL; 2009 } 2010 } 2011 2012 if (priv->conf.ht.mode == HT_MODE_DEFAULT) { 2013 /* 2014 * Only support mimo with multiple antennas. Fall back to 2015 * siso40. 2016 */ 2017 if (wl18xx_is_mimo_supported(wl)) 2018 wlcore_set_ht_cap(wl, NL80211_BAND_2GHZ, 2019 &wl18xx_mimo_ht_cap_2ghz); 2020 else 2021 wlcore_set_ht_cap(wl, NL80211_BAND_2GHZ, 2022 &wl18xx_siso40_ht_cap_2ghz); 2023 2024 /* 5Ghz is always wide */ 2025 wlcore_set_ht_cap(wl, NL80211_BAND_5GHZ, 2026 &wl18xx_siso40_ht_cap_5ghz); 2027 } else if (priv->conf.ht.mode == HT_MODE_WIDE) { 2028 wlcore_set_ht_cap(wl, NL80211_BAND_2GHZ, 2029 &wl18xx_siso40_ht_cap_2ghz); 2030 wlcore_set_ht_cap(wl, NL80211_BAND_5GHZ, 2031 &wl18xx_siso40_ht_cap_5ghz); 2032 } else if (priv->conf.ht.mode == HT_MODE_SISO20) { 2033 wlcore_set_ht_cap(wl, NL80211_BAND_2GHZ, 2034 &wl18xx_siso20_ht_cap); 2035 wlcore_set_ht_cap(wl, NL80211_BAND_5GHZ, 2036 &wl18xx_siso20_ht_cap); 2037 } 2038 2039 if (!checksum_param) { 2040 wl18xx_ops.set_rx_csum = NULL; 2041 wl18xx_ops.init_vif = NULL; 2042 } 2043 2044 /* Enable 11a Band only if we have 5G antennas */ 2045 wl->enable_11a = (priv->conf.phy.number_of_assembled_ant5 != 0); 2046 2047 return 0; 2048 } 2049 2050 static int wl18xx_probe(struct platform_device *pdev) 2051 { 2052 struct wl1271 *wl; 2053 struct ieee80211_hw *hw; 2054 int ret; 2055 2056 hw = wlcore_alloc_hw(sizeof(struct wl18xx_priv), 2057 WL18XX_AGGR_BUFFER_SIZE, 2058 sizeof(struct wl18xx_event_mailbox)); 2059 if (IS_ERR(hw)) { 2060 wl1271_error("can't allocate hw"); 2061 ret = PTR_ERR(hw); 2062 goto out; 2063 } 2064 2065 wl = hw->priv; 2066 wl->ops = &wl18xx_ops; 2067 wl->ptable = wl18xx_ptable; 2068 ret = wlcore_probe(wl, pdev); 2069 if (ret) 2070 goto out_free; 2071 2072 return ret; 2073 2074 out_free: 2075 wlcore_free_hw(wl); 2076 out: 2077 return ret; 2078 } 2079 2080 static const struct platform_device_id wl18xx_id_table[] = { 2081 { "wl18xx", 0 }, 2082 { } /* Terminating Entry */ 2083 }; 2084 MODULE_DEVICE_TABLE(platform, wl18xx_id_table); 2085 2086 static struct platform_driver wl18xx_driver = { 2087 .probe = wl18xx_probe, 2088 .remove = wlcore_remove, 2089 .id_table = wl18xx_id_table, 2090 .driver = { 2091 .name = "wl18xx_driver", 2092 } 2093 }; 2094 2095 module_platform_driver(wl18xx_driver); 2096 module_param_named(ht_mode, ht_mode_param, charp, 0400); 2097 MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or siso20"); 2098 2099 module_param_named(board_type, board_type_param, charp, 0400); 2100 MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or " 2101 "dvp"); 2102 2103 module_param_named(checksum, checksum_param, bool, 0400); 2104 MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to false)"); 2105 2106 module_param_named(dc2dc, dc2dc_param, int, 0400); 2107 MODULE_PARM_DESC(dc2dc, "External DC2DC: u8 (defaults to 0)"); 2108 2109 module_param_named(n_antennas_2, n_antennas_2_param, int, 0400); 2110 MODULE_PARM_DESC(n_antennas_2, 2111 "Number of installed 2.4GHz antennas: 1 (default) or 2"); 2112 2113 module_param_named(n_antennas_5, n_antennas_5_param, int, 0400); 2114 MODULE_PARM_DESC(n_antennas_5, 2115 "Number of installed 5GHz antennas: 1 (default) or 2"); 2116 2117 module_param_named(low_band_component, low_band_component_param, int, 0400); 2118 MODULE_PARM_DESC(low_band_component, "Low band component: u8 " 2119 "(default is 0x01)"); 2120 2121 module_param_named(low_band_component_type, low_band_component_type_param, 2122 int, 0400); 2123 MODULE_PARM_DESC(low_band_component_type, "Low band component type: u8 " 2124 "(default is 0x05 or 0x06 depending on the board_type)"); 2125 2126 module_param_named(high_band_component, high_band_component_param, int, 0400); 2127 MODULE_PARM_DESC(high_band_component, "High band component: u8, " 2128 "(default is 0x01)"); 2129 2130 module_param_named(high_band_component_type, high_band_component_type_param, 2131 int, 0400); 2132 MODULE_PARM_DESC(high_band_component_type, "High band component type: u8 " 2133 "(default is 0x09)"); 2134 2135 module_param_named(pwr_limit_reference_11_abg, 2136 pwr_limit_reference_11_abg_param, int, 0400); 2137 MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 " 2138 "(default is 0xc8)"); 2139 2140 module_param_named(num_rx_desc, num_rx_desc_param, int, 0400); 2141 MODULE_PARM_DESC(num_rx_desc_param, 2142 "Number of Rx descriptors: u8 (default is 32)"); 2143 2144 MODULE_LICENSE("GPL v2"); 2145 MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); 2146 MODULE_FIRMWARE(WL18XX_FW_NAME); 2147