cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

main.c (62763B)


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