diff options
Diffstat (limited to 'drivers/net')
49 files changed, 9059 insertions, 1186 deletions
diff --git a/drivers/net/wireless/sd8797/Makefile b/drivers/net/wireless/sd8797/Makefile index d5eb7872a232..3ef70380dd82 100644 --- a/drivers/net/wireless/sd8797/Makefile +++ b/drivers/net/wireless/sd8797/Makefile @@ -52,6 +52,7 @@ EXTRA_CFLAGS += -DPROC_DEBUG EXTRA_CFLAGS += -DSDIO_MULTI_PORT_TX_AGGR EXTRA_CFLAGS += -DSDIO_MULTI_PORT_RX_AGGR EXTRA_CFLAGS += -DSDIO_SUSPEND_RESUME +EXTRA_CFLAGS += -DMMC_PM_KEEP_POWER EXTRA_CFLAGS += -DDFS_TESTING_SUPPORT EXTRA_CFLAGS += -DMFG_CMD_SUPPORT diff --git a/drivers/net/wireless/sd8797/mlan/mlan_11d.c b/drivers/net/wireless/sd8797/mlan/mlan_11d.c index 1727c5890fc8..fdc0d993e381 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_11d.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_11d.c @@ -2,7 +2,7 @@ * * @brief This file contains functions for 802.11D. * - * Copyright (C) 2008-2011, Marvell International Ltd. + * Copyright (C) 2008-2012, Marvell International Ltd. * * This software file (the "File") is distributed by Marvell International * Ltd. under the terms of the GNU General Public License Version 2, June 1991 @@ -55,6 +55,7 @@ static region_code_mapping_t region_code_mapping[] = { {"JP ", 0x40}, /* Japan */ {"JP ", 0x41}, /* Japan */ {"CN ", 0x50}, /* China */ + {"JP ", 0xFE}, /* Japan */ {"JP ", 0xFF}, /* Japan special */ }; diff --git a/drivers/net/wireless/sd8797/mlan/mlan_11h.c b/drivers/net/wireless/sd8797/mlan/mlan_11h.c index 7e08f4cd5d8a..3a38979a8dd2 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_11h.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_11h.c @@ -2,7 +2,7 @@ * * @brief This file contains functions for 802.11H. * - * Copyright (C) 2008-2011, Marvell International Ltd. + * Copyright (C) 2008-2012, Marvell International Ltd. * * This software file (the "File") is distributed by Marvell International * Ltd. under the terms of the GNU General Public License Version 2, June 1991 @@ -298,6 +298,11 @@ wlan_11h_set_supp_channels_ie(mlan_private * priv, sizeof(IEEEtypes_SupportedChannels_t)); cfp_bg = cfp_a = priv->adapter->region_code; + if (!priv->adapter->region_code) { + /* Invalid region code, use CFP code */ + cfp_bg = priv->adapter->cfp_code_bg; + cfp_a = priv->adapter->cfp_code_a; + } if ((band & BAND_B) || (band & BAND_G)) { /* @@ -355,6 +360,23 @@ wlan_11h_set_supp_channels_ie(mlan_private * priv, psup_chan->subband[num_subbands++] = wlan_11h_unii_middle_band; psup_chan->subband[num_subbands++] = wlan_11h_unii_mid_upper_band; break; + case 0x1: /* Low band (5150-5250 MHz) channels */ + psup_chan->subband[num_subbands++] = wlan_11h_unii_lower_band; + break; + case 0x2: /* Lower middle band (5250-5350 MHz) channels */ + psup_chan->subband[num_subbands++] = wlan_11h_unii_middle_band; + break; + case 0x3: /* Upper middle band (5470-5725 MHz) channels */ + psup_chan->subband[num_subbands++] = wlan_11h_unii_mid_upper_band; + break; + case 0x4: /* High band (5725-5850 MHz) channels */ + psup_chan->subband[num_subbands++] = wlan_11h_unii_upper_band; + break; + case 0x5: /* Low band (5150-5250 MHz) and High band + (5725-5850 MHz) channels */ + psup_chan->subband[num_subbands++] = wlan_11h_unii_lower_band; + psup_chan->subband[num_subbands++] = wlan_11h_unii_upper_band; + break; } } @@ -1799,9 +1821,15 @@ wlan_11h_radar_detect_required(mlan_private * priv, t_u8 channel) required = wlan_get_cfp_radar_detect(priv, channel); - PRINTM(MINFO, "11h: Radar detection in region %#02x " - "is %srequired for channel %d\n", - priv->adapter->region_code, (required ? "" : "not "), channel); + if (!priv->adapter->region_code) + PRINTM(MINFO, "11h: Radar detection in CFP code[BG:%#x, A:%#x] " + "is %srequired for channel %d\n", + priv->adapter->cfp_code_bg, priv->adapter->cfp_code_a, + (required ? "" : "not "), channel); + else + PRINTM(MINFO, "11h: Radar detection in region %#02x " + "is %srequired for channel %d\n", + priv->adapter->region_code, (required ? "" : "not "), channel); if (required == MTRUE && priv->media_connected == MTRUE && priv->curr_bss_params.bss_descriptor.channel == channel) { @@ -3153,13 +3181,13 @@ wlan_11h_switch_non_dfs_chan(mlan_private * priv, t_u8 * chan) def_chan = (t_u8) chn_tbl->pcfp[rand_entry].channel; rand_tries++; } while ((wlan_11h_is_channel_under_nop(pmadapter, def_chan) || - chn_tbl->pcfp[rand_entry].radar_detect == MTRUE) && - (rand_tries < MAX_SWITCH_CHANNEL_RETRIES)); + chn_tbl->pcfp[rand_entry].passive_scan_or_radar_detect == MTRUE) + && (rand_tries < MAX_SWITCH_CHANNEL_RETRIES)); /* meet max retries, use the lowest non-dfs channel */ if (rand_tries == MAX_SWITCH_CHANNEL_RETRIES) { for (i = 0; i < chn_tbl->num_cfp; i++) { - if (chn_tbl->pcfp[i].radar_detect == MFALSE && + if (chn_tbl->pcfp[i].passive_scan_or_radar_detect == MFALSE && !wlan_11h_is_channel_under_nop(pmadapter, (t_u8) chn_tbl->pcfp[i]. channel)) { diff --git a/drivers/net/wireless/sd8797/mlan/mlan_11n.c b/drivers/net/wireless/sd8797/mlan/mlan_11n.c index 48b51a5bf7e0..5e78748e4a3b 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_11n.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_11n.c @@ -1335,6 +1335,7 @@ wlan_ret_tx_bf_cfg(IN pmlan_private pmpriv, } #ifdef STA_SUPPORT + /** * @brief This function append the 802_11N tlv * @@ -1426,12 +1427,12 @@ wlan_cmd_append_11n_tlv(IN mlan_private * pmpriv, pbss_desc->pht_info->ht_info.pri_chan; pchan_list->chan_scan_param[0].radio_type = wlan_band_to_radio_type((t_u8) pbss_desc->bss_band); - if (ISSUPP_CHANWIDTH40(usr_dot_11n_dev_cap) && - ISALLOWED_CHANWIDTH40(pbss_desc->pht_info->ht_info.field2)) + ISALLOWED_CHANWIDTH40(pbss_desc->pht_info->ht_info.field2)) { SET_SECONDARYCHAN(pchan_list->chan_scan_param[0].radio_type, GET_SECONDARYCHAN(pbss_desc->pht_info->ht_info. field2)); + } HEXDUMP("ChanList", (t_u8 *) pchan_list, sizeof(MrvlIEtypes_ChanListParamSet_t)); @@ -1467,15 +1468,13 @@ wlan_cmd_append_11n_tlv(IN mlan_private * pmpriv, memcpy(pmadapter, (t_u8 *) pext_cap + sizeof(MrvlIEtypesHeader_t), (t_u8 *) pbss_desc->pext_cap + sizeof(IEEEtypes_Header_t), - pext_cap->header.len); - + pbss_desc->pext_cap->ieee_hdr.len); HEXDUMP("Extended Capabilities IE", (t_u8 *) pext_cap, sizeof(MrvlIETypes_ExtCap_t)); *ppbuffer += sizeof(MrvlIETypes_ExtCap_t); ret_len += sizeof(MrvlIETypes_ExtCap_t); pext_cap->header.len = wlan_cpu_to_le16(pext_cap->header.len); } - LEAVE(); return ret_len; } diff --git a/drivers/net/wireless/sd8797/mlan/mlan_11n_aggr.c b/drivers/net/wireless/sd8797/mlan/mlan_11n_aggr.c index 6af4b6a698e8..6125262d5b7a 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_11n_aggr.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_11n_aggr.c @@ -333,7 +333,9 @@ wlan_11n_aggregate_pkt(mlan_private * priv, raListTbl * pra_list, t_u8 *data; int pad = 0; mlan_status ret = MLAN_STATUS_SUCCESS; +#ifdef DEBUG_LEVEL1 t_u32 sec, usec; +#endif mlan_tx_param tx_param; #ifdef STA_SUPPORT TxPD *ptx_pd = MNULL; @@ -497,8 +499,7 @@ wlan_11n_aggregate_pkt(mlan_private * priv, raListTbl * pra_list, pmadapter->callbacks.moal_spin_unlock(pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock); } - pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle, &sec, - &usec); + PRINTM_GET_SYS_TIME(MDATA, &sec, &usec); PRINTM_NETINTF(MDATA, priv); PRINTM(MDATA, "%lu.%06lu : Data => FW\n", sec, usec); diff --git a/drivers/net/wireless/sd8797/mlan/mlan_11n_rxreorder.c b/drivers/net/wireless/sd8797/mlan/mlan_11n_rxreorder.c index 870081799c07..af689b7bab49 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_11n_rxreorder.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_11n_rxreorder.c @@ -4,7 +4,7 @@ * driver. * * Copyright (C) 2008-2011, Marvell International Ltd. - * + * * This software file (the "File") is distributed by Marvell International * Ltd. under the terms of the GNU General Public License Version 2, June 1991 * (the "License"). You may use, redistribute and/or modify this File in @@ -639,6 +639,9 @@ wlan_cmd_11n_addba_rspgen(mlan_private * priv, BLOCKACKPARAM_WINSIZE_POS); win_size = (padd_ba_rsp->block_ack_param_set & BLOCKACKPARAM_WINSIZE_MASK) >> BLOCKACKPARAM_WINSIZE_POS; + if (win_size == 0) + padd_ba_rsp->status_code = wlan_cpu_to_le16(ADDBA_RSP_STATUS_DECLINED); + padd_ba_rsp->block_ack_param_set = wlan_cpu_to_le16(padd_ba_rsp->block_ack_param_set); diff --git a/drivers/net/wireless/sd8797/mlan/mlan_cfp.c b/drivers/net/wireless/sd8797/mlan/mlan_cfp.c index 23e849f04b63..ccbb5aa1f666 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_cfp.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_cfp.c @@ -4,7 +4,7 @@ * @brief This file contains WLAN client mode channel, frequency and power * related code * - * Copyright (C) 2009-2011, Marvell International Ltd. + * Copyright (C) 2009-2012, Marvell International Ltd. * * This software file (the "File") is distributed by Marvell International * Ltd. under the terms of the GNU General Public License Version 2, June 1991 @@ -52,6 +52,30 @@ Change Log: /** 2000mW */ #define WLAN_TX_PWR_CN_2000MW 33 +/** Region code mapping */ +typedef struct _country_code_mapping +{ + /** Region */ + t_u8 country_code[COUNTRY_CODE_LEN]; + /** Code for B/G CFP table */ + t_u8 cfp_code_bg; + /** Code for A CFP table */ + t_u8 cfp_code_a; +} country_code_mapping_t; + +/** Region code mapping table */ +static country_code_mapping_t country_code_mapping[] = { + {"US", 0x10, 0x10}, /* US FCC */ + {"CA", 0x10, 0x20}, /* IC Canada */ + {"SG", 0x10, 0x10}, /* Singapore */ + {"EU", 0x30, 0x30}, /* ETSI */ + {"AU", 0x30, 0x30}, /* Australia */ + {"KR", 0x30, 0x30}, /* Republic Of Korea */ + {"FR", 0x32, 0x32}, /* France */ + {"JP", 0xFF, 0x40}, /* Japan */ + {"CN", 0x30, 0x50}, /* China */ +}; + /** * The structure for Channel-Frequency-Power table */ @@ -68,91 +92,108 @@ typedef struct _cfp_table /* Format { Channel, Frequency (MHz), MaxTxPower } */ /** Band: 'B/G', Region: USA FCC/Canada IC */ static chan_freq_power_t channel_freq_power_US_BG[] = { - {1, 2412, WLAN_TX_PWR_US_DEFAULT}, - {2, 2417, WLAN_TX_PWR_US_DEFAULT}, - {3, 2422, WLAN_TX_PWR_US_DEFAULT}, - {4, 2427, WLAN_TX_PWR_US_DEFAULT}, - {5, 2432, WLAN_TX_PWR_US_DEFAULT}, - {6, 2437, WLAN_TX_PWR_US_DEFAULT}, - {7, 2442, WLAN_TX_PWR_US_DEFAULT}, - {8, 2447, WLAN_TX_PWR_US_DEFAULT}, - {9, 2452, WLAN_TX_PWR_US_DEFAULT}, - {10, 2457, WLAN_TX_PWR_US_DEFAULT}, - {11, 2462, WLAN_TX_PWR_US_DEFAULT} + {1, 2412, WLAN_TX_PWR_US_DEFAULT, MFALSE}, + {2, 2417, WLAN_TX_PWR_US_DEFAULT, MFALSE}, + {3, 2422, WLAN_TX_PWR_US_DEFAULT, MFALSE}, + {4, 2427, WLAN_TX_PWR_US_DEFAULT, MFALSE}, + {5, 2432, WLAN_TX_PWR_US_DEFAULT, MFALSE}, + {6, 2437, WLAN_TX_PWR_US_DEFAULT, MFALSE}, + {7, 2442, WLAN_TX_PWR_US_DEFAULT, MFALSE}, + {8, 2447, WLAN_TX_PWR_US_DEFAULT, MFALSE}, + {9, 2452, WLAN_TX_PWR_US_DEFAULT, MFALSE}, + {10, 2457, WLAN_TX_PWR_US_DEFAULT, MFALSE}, + {11, 2462, WLAN_TX_PWR_US_DEFAULT, MFALSE} }; /** Band: 'B/G', Region: Europe ETSI/China */ static chan_freq_power_t channel_freq_power_EU_BG[] = { - {1, 2412, WLAN_TX_PWR_EMEA_DEFAULT}, - {2, 2417, WLAN_TX_PWR_EMEA_DEFAULT}, - {3, 2422, WLAN_TX_PWR_EMEA_DEFAULT}, - {4, 2427, WLAN_TX_PWR_EMEA_DEFAULT}, - {5, 2432, WLAN_TX_PWR_EMEA_DEFAULT}, - {6, 2437, WLAN_TX_PWR_EMEA_DEFAULT}, - {7, 2442, WLAN_TX_PWR_EMEA_DEFAULT}, - {8, 2447, WLAN_TX_PWR_EMEA_DEFAULT}, - {9, 2452, WLAN_TX_PWR_EMEA_DEFAULT}, - {10, 2457, WLAN_TX_PWR_EMEA_DEFAULT}, - {11, 2462, WLAN_TX_PWR_EMEA_DEFAULT}, - {12, 2467, WLAN_TX_PWR_EMEA_DEFAULT}, - {13, 2472, WLAN_TX_PWR_EMEA_DEFAULT} + {1, 2412, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {2, 2417, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {3, 2422, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {4, 2427, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {5, 2432, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {6, 2437, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {7, 2442, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {8, 2447, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {9, 2452, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {10, 2457, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {11, 2462, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {12, 2467, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE}, + {13, 2472, WLAN_TX_PWR_EMEA_DEFAULT, MFALSE} }; /** Band: 'B/G', Region: France */ static chan_freq_power_t channel_freq_power_FR_BG[] = { - {1, 2412, WLAN_TX_PWR_FR_100MW}, - {2, 2417, WLAN_TX_PWR_FR_100MW}, - {3, 2422, WLAN_TX_PWR_FR_100MW}, - {4, 2427, WLAN_TX_PWR_FR_100MW}, - {5, 2432, WLAN_TX_PWR_FR_100MW}, - {6, 2437, WLAN_TX_PWR_FR_100MW}, - {7, 2442, WLAN_TX_PWR_FR_100MW}, - {8, 2447, WLAN_TX_PWR_FR_100MW}, - {9, 2452, WLAN_TX_PWR_FR_100MW}, - {10, 2457, WLAN_TX_PWR_FR_10MW}, - {11, 2462, WLAN_TX_PWR_FR_10MW}, - {12, 2467, WLAN_TX_PWR_FR_10MW}, - {13, 2472, WLAN_TX_PWR_FR_10MW} + {1, 2412, WLAN_TX_PWR_FR_100MW, MFALSE}, + {2, 2417, WLAN_TX_PWR_FR_100MW, MFALSE}, + {3, 2422, WLAN_TX_PWR_FR_100MW, MFALSE}, + {4, 2427, WLAN_TX_PWR_FR_100MW, MFALSE}, + {5, 2432, WLAN_TX_PWR_FR_100MW, MFALSE}, + {6, 2437, WLAN_TX_PWR_FR_100MW, MFALSE}, + {7, 2442, WLAN_TX_PWR_FR_100MW, MFALSE}, + {8, 2447, WLAN_TX_PWR_FR_100MW, MFALSE}, + {9, 2452, WLAN_TX_PWR_FR_100MW, MFALSE}, + {10, 2457, WLAN_TX_PWR_FR_10MW, MFALSE}, + {11, 2462, WLAN_TX_PWR_FR_10MW, MFALSE}, + {12, 2467, WLAN_TX_PWR_FR_10MW, MFALSE}, + {13, 2472, WLAN_TX_PWR_FR_10MW, MFALSE} }; /** Band: 'B/G', Region: Japan */ static chan_freq_power_t channel_freq_power_JPN41_BG[] = { - {1, 2412, WLAN_TX_PWR_JP_BG_DEFAULT}, - {2, 2417, WLAN_TX_PWR_JP_BG_DEFAULT}, - {3, 2422, WLAN_TX_PWR_JP_BG_DEFAULT}, - {4, 2427, WLAN_TX_PWR_JP_BG_DEFAULT}, - {5, 2432, WLAN_TX_PWR_JP_BG_DEFAULT}, - {6, 2437, WLAN_TX_PWR_JP_BG_DEFAULT}, - {7, 2442, WLAN_TX_PWR_JP_BG_DEFAULT}, - {8, 2447, WLAN_TX_PWR_JP_BG_DEFAULT}, - {9, 2452, WLAN_TX_PWR_JP_BG_DEFAULT}, - {10, 2457, WLAN_TX_PWR_JP_BG_DEFAULT}, - {11, 2462, WLAN_TX_PWR_JP_BG_DEFAULT}, - {12, 2467, WLAN_TX_PWR_JP_BG_DEFAULT}, - {13, 2472, WLAN_TX_PWR_JP_BG_DEFAULT} + {1, 2412, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {2, 2417, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {3, 2422, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {4, 2427, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {5, 2432, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {6, 2437, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {7, 2442, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {8, 2447, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {9, 2452, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {10, 2457, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {11, 2462, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {12, 2467, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {13, 2472, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE} }; /** Band: 'B/G', Region: Japan */ static chan_freq_power_t channel_freq_power_JPN40_BG[] = { - {14, 2484, WLAN_TX_PWR_JP_BG_DEFAULT} + {14, 2484, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE} +}; + +/** Band: 'B/G', Region: Japan */ +static chan_freq_power_t channel_freq_power_JPNFE_BG[] = { + {1, 2412, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {2, 2417, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {3, 2422, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {4, 2427, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {5, 2432, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {6, 2437, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {7, 2442, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {8, 2447, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {9, 2452, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {10, 2457, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {11, 2462, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {12, 2467, WLAN_TX_PWR_JP_BG_DEFAULT, MTRUE}, + {13, 2472, WLAN_TX_PWR_JP_BG_DEFAULT, MTRUE} }; /** Band : 'B/G', Region: Special */ static chan_freq_power_t channel_freq_power_SPECIAL_BG[] = { - {1, 2412, WLAN_TX_PWR_JP_BG_DEFAULT}, - {2, 2417, WLAN_TX_PWR_JP_BG_DEFAULT}, - {3, 2422, WLAN_TX_PWR_JP_BG_DEFAULT}, - {4, 2427, WLAN_TX_PWR_JP_BG_DEFAULT}, - {5, 2432, WLAN_TX_PWR_JP_BG_DEFAULT}, - {6, 2437, WLAN_TX_PWR_JP_BG_DEFAULT}, - {7, 2442, WLAN_TX_PWR_JP_BG_DEFAULT}, - {8, 2447, WLAN_TX_PWR_JP_BG_DEFAULT}, - {9, 2452, WLAN_TX_PWR_JP_BG_DEFAULT}, - {10, 2457, WLAN_TX_PWR_JP_BG_DEFAULT}, - {11, 2462, WLAN_TX_PWR_JP_BG_DEFAULT}, - {12, 2467, WLAN_TX_PWR_JP_BG_DEFAULT}, - {13, 2472, WLAN_TX_PWR_JP_BG_DEFAULT}, - {14, 2484, WLAN_TX_PWR_JP_BG_DEFAULT} + {1, 2412, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {2, 2417, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {3, 2422, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {4, 2427, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {5, 2432, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {6, 2437, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {7, 2442, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {8, 2447, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {9, 2452, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {10, 2457, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {11, 2462, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {12, 2467, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {13, 2472, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE}, + {14, 2484, WLAN_TX_PWR_JP_BG_DEFAULT, MFALSE} }; /** @@ -194,6 +235,12 @@ static cfp_table_t cfp_table_BG[] = { sizeof(channel_freq_power_EU_BG) / sizeof(chan_freq_power_t), } , + { + 0xfe, /* JAPAN */ + channel_freq_power_JPNFE_BG, + sizeof(channel_freq_power_JPNFE_BG) / sizeof(chan_freq_power_t), + } + , {0xff, /* Special */ channel_freq_power_SPECIAL_BG, sizeof(channel_freq_power_SPECIAL_BG) / sizeof(chan_freq_power_t), @@ -317,6 +364,64 @@ static chan_freq_power_t channel_freq_power_CN_A[] = { {165, 5825, WLAN_TX_PWR_CN_2000MW, MFALSE} }; +/** Band: 'A', NULL */ +static chan_freq_power_t channel_freq_power_NULL_A[] = { +}; + +/** Band: 'A', Code: 1, Low band (5150-5250 MHz) channels */ +static chan_freq_power_t channel_freq_power_low_band[] = { + {36, 5180, WLAN_TX_PWR_DEFAULT, MFALSE}, + {40, 5200, WLAN_TX_PWR_DEFAULT, MFALSE}, + {44, 5220, WLAN_TX_PWR_DEFAULT, MFALSE}, + {48, 5240, WLAN_TX_PWR_DEFAULT, MFALSE}, +}; + +/** Band: 'A', Code: 2, Lower middle band (5250-5350 MHz) channels */ +static chan_freq_power_t channel_freq_power_lower_middle_band[] = { + {52, 5260, WLAN_TX_PWR_DEFAULT, MTRUE}, + {56, 5280, WLAN_TX_PWR_DEFAULT, MTRUE}, + {60, 5300, WLAN_TX_PWR_DEFAULT, MTRUE}, + {64, 5320, WLAN_TX_PWR_DEFAULT, MTRUE}, +}; + +/** Band: 'A', Code: 3, Upper middle band (5470-5725 MHz) channels */ +static chan_freq_power_t channel_freq_power_upper_middle_band[] = { + {100, 5500, WLAN_TX_PWR_DEFAULT, MTRUE}, + {104, 5520, WLAN_TX_PWR_DEFAULT, MTRUE}, + {108, 5540, WLAN_TX_PWR_DEFAULT, MTRUE}, + {112, 5560, WLAN_TX_PWR_DEFAULT, MTRUE}, + {116, 5580, WLAN_TX_PWR_DEFAULT, MTRUE}, + {120, 5600, WLAN_TX_PWR_DEFAULT, MTRUE}, + {124, 5620, WLAN_TX_PWR_DEFAULT, MTRUE}, + {128, 5640, WLAN_TX_PWR_DEFAULT, MTRUE}, + {132, 5660, WLAN_TX_PWR_DEFAULT, MTRUE}, + {136, 5680, WLAN_TX_PWR_DEFAULT, MTRUE}, + {140, 5700, WLAN_TX_PWR_DEFAULT, MTRUE}, +}; + +/** Band: 'A', Code: 4, High band (5725-5850 MHz) channels */ +static chan_freq_power_t channel_freq_power_high_band[] = { + {149, 5745, WLAN_TX_PWR_DEFAULT, MFALSE}, + {153, 5765, WLAN_TX_PWR_DEFAULT, MFALSE}, + {157, 5785, WLAN_TX_PWR_DEFAULT, MFALSE}, + {161, 5805, WLAN_TX_PWR_DEFAULT, MFALSE}, + {165, 5825, WLAN_TX_PWR_DEFAULT, MFALSE} +}; + +/** Band: 'A', Code: 5, Low band (5150-5250 MHz) and + * High band (5725-5850 MHz) channels */ +static chan_freq_power_t channel_freq_power_low_high_band[] = { + {36, 5180, WLAN_TX_PWR_DEFAULT, MFALSE}, + {40, 5200, WLAN_TX_PWR_DEFAULT, MFALSE}, + {44, 5220, WLAN_TX_PWR_DEFAULT, MFALSE}, + {48, 5240, WLAN_TX_PWR_DEFAULT, MFALSE}, + {149, 5745, WLAN_TX_PWR_DEFAULT, MFALSE}, + {153, 5765, WLAN_TX_PWR_DEFAULT, MFALSE}, + {157, 5785, WLAN_TX_PWR_DEFAULT, MFALSE}, + {161, 5805, WLAN_TX_PWR_DEFAULT, MFALSE}, + {165, 5825, WLAN_TX_PWR_DEFAULT, MFALSE} +}; + /** * The 5GHz CFP tables */ @@ -356,11 +461,42 @@ static cfp_table_t cfp_table_A[] = { sizeof(channel_freq_power_CN_A) / sizeof(chan_freq_power_t), } , + {0xfe, /* JAPAN */ + channel_freq_power_NULL_A, + sizeof(channel_freq_power_NULL_A) / sizeof(chan_freq_power_t), + } + , {0xff, /* Special */ channel_freq_power_JPN_A, sizeof(channel_freq_power_JPN_A) / sizeof(chan_freq_power_t), } , + {0x1, /* Low band (5150-5250 MHz) channels */ + channel_freq_power_low_band, + sizeof(channel_freq_power_low_band) / sizeof(chan_freq_power_t) + } + , + {0x2, /* Lower middle band (5250-5350 MHz) channels */ + channel_freq_power_lower_middle_band, + sizeof(channel_freq_power_lower_middle_band) / sizeof(chan_freq_power_t) + } + , + {0x3, /* Upper middle band (5470-5725 MHz) channels */ + channel_freq_power_upper_middle_band, + sizeof(channel_freq_power_upper_middle_band) / sizeof(chan_freq_power_t) + } + , + {0x4, /* High band (5725-5850 MHz) channels */ + channel_freq_power_high_band, + sizeof(channel_freq_power_high_band) / sizeof(chan_freq_power_t) + } + , + {0x5, /* Low band (5150-5250 MHz) and High band + (5725-5850 MHz) channels */ + channel_freq_power_low_high_band, + sizeof(channel_freq_power_low_high_band) / sizeof(chan_freq_power_t) + } + , /* Add new region here */ }; @@ -374,7 +510,13 @@ static cfp_table_t cfp_table_A[] = { * The table to keep region code */ t_u16 region_code_index[MRVDRV_MAX_REGION_CODE] = - { 0x10, 0x20, 0x30, 0x32, 0x40, 0x41, 0x50, 0xff }; + { 0x10, 0x20, 0x30, 0x32, 0x40, 0x41, 0x50, 0xfe, 0xff }; + +/** The table to keep CFP code for BG */ +t_u16 cfp_code_index_bg[MRVDRV_MAX_CFP_CODE_BG] = { }; + +/** The table to keep CFP code for A */ +t_u16 cfp_code_index_a[MRVDRV_MAX_CFP_CODE_A] = { 0x1, 0x2, 0x3, 0x4, 0x5 }; /** * The rates supported for ad-hoc B mode @@ -494,6 +636,11 @@ wlan_get_region_cfp_table(pmlan_adapter pmadapter, t_u8 region, t_u8 band, ENTER(); cfp_bg = cfp_a = region; + if (!region) { + /* Invalid region code, use CFP code */ + cfp_bg = pmadapter->cfp_code_bg; + cfp_a = pmadapter->cfp_code_a; + } if (band & (BAND_B | BAND_G | BAND_GN)) { for (i = 0; i < MLAN_CFP_TABLE_SIZE_BG; i++) { @@ -521,7 +668,11 @@ wlan_get_region_cfp_table(pmlan_adapter pmadapter, t_u8 region, t_u8 band, } } - PRINTM(MERROR, "Error Band[0x%x] or region[%#x]\n", band, region); + if (!region) + PRINTM(MERROR, "Error Band[0x%x] or code[BG:%#x, A:%#x]\n", + band, cfp_bg, cfp_a); + else + PRINTM(MERROR, "Error Band[0x%x] or region[%#x]\n", band, region); LEAVE(); return MNULL; @@ -530,6 +681,38 @@ wlan_get_region_cfp_table(pmlan_adapter pmadapter, t_u8 region, t_u8 band, /******************************************************** Global Functions ********************************************************/ +/** + * @brief This function converts region string to integer code + * + * @param pmadapter A pointer to mlan_adapter structure + * @param country_code Country string + * @param cfp_bg Pointer to buffer + * @param cfp_a Pointer to buffer + * + * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE + */ +mlan_status +wlan_misc_country_2_cfp_table_code(pmlan_adapter pmadapter, t_u8 * country_code, + t_u8 * cfp_bg, t_u8 * cfp_a) +{ + t_u8 i; + + ENTER(); + + /* Look for code in mapping table */ + for (i = 0; i < NELEMENTS(country_code_mapping); i++) { + if (!memcmp(pmadapter, country_code_mapping[i].country_code, + country_code, COUNTRY_CODE_LEN - 1)) { + *cfp_bg = country_code_mapping[i].cfp_code_bg; + *cfp_a = country_code_mapping[i].cfp_code_a; + LEAVE(); + return MLAN_STATUS_SUCCESS; + } + } + + LEAVE(); + return MLAN_STATUS_FAILURE; +} #ifdef STA_SUPPORT #endif /* STA_SUPPORT */ @@ -1137,7 +1320,7 @@ wlan_get_cfp_radar_detect(mlan_private * priv, t_u8 chnl) /* get the radar detection requirements according to chan num */ for (j = 0; j < priv->adapter->region_channel[i].num_cfp; j++) { if (pcfp[j].channel == chnl) { - required = pcfp[j].radar_detect; + required = pcfp[j].passive_scan_or_radar_detect; break; } } @@ -1146,3 +1329,50 @@ wlan_get_cfp_radar_detect(mlan_private * priv, t_u8 chnl) LEAVE(); return required; } + +/** + * @brief Get if scan type is passive or not on a certain channel for b/g band + * + * @param priv Private driver information structure + * @param chnl Channel to determine scan type + * + * @return + * - MTRUE if scan type is passive + * - MFALSE otherwise + */ + +t_bool +wlan_bg_scan_type_is_passive(mlan_private * priv, t_u8 chnl) +{ + int i, j; + t_bool passive = MFALSE; + chan_freq_power_t *pcfp = MNULL; + + ENTER(); + + /* get the cfp table first */ + for (i = 0; i < MAX_REGION_CHANNEL_NUM; i++) { + if (priv->adapter->region_channel[i].band & (BAND_B | BAND_G)) { + pcfp = priv->adapter->region_channel[i].pcfp; + break; + } + } + + if (!pcfp) { + /* This means operation in BAND-B or BAND_G is not support, we can + just return false here */ + goto done; + } + + /* get the bg scan type according to chan num */ + for (j = 0; j < priv->adapter->region_channel[i].num_cfp; j++) { + if (pcfp[j].channel == chnl) { + passive = pcfp[j].passive_scan_or_radar_detect; + break; + } + } + + done: + LEAVE(); + return passive; +} diff --git a/drivers/net/wireless/sd8797/mlan/mlan_cmdevt.c b/drivers/net/wireless/sd8797/mlan/mlan_cmdevt.c index f3db9e662565..a3e5ef0517f0 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_cmdevt.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_cmdevt.c @@ -344,7 +344,9 @@ wlan_dnld_cmd_to_fw(IN mlan_private * pmpriv, IN cmd_ctrl_node * pcmd_node) mlan_ioctl_req *pioctl_buf = MNULL; t_u16 cmd_code; t_u16 cmd_size; +#ifdef DEBUG_LEVEL1 t_u32 sec, usec; +#endif ENTER(); @@ -389,8 +391,7 @@ wlan_dnld_cmd_to_fw(IN mlan_private * pmpriv, IN cmd_ctrl_node * pcmd_node) pcmd_node->cmdbuf->data_len = cmd_size; - pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle, &sec, - &usec); + PRINTM_GET_SYS_TIME(MCMND, &sec, &usec); PRINTM_NETINTF(MCMND, pmpriv); PRINTM(MCMND, "DNLD_CMD (%lu.%06lu): 0x%x, act 0x%x, len %d, seqno 0x%x\n", sec, usec, cmd_code, @@ -690,8 +691,9 @@ wlan_process_event(pmlan_adapter pmadapter) pmlan_private priv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY); pmlan_buffer pmbuf = pmadapter->pmlan_buffer_event; t_u32 eventcause = pmadapter->event_cause; - t_u32 in_ts_sec; - t_u32 in_ts_usec; +#ifdef DEBUG_LEVEL1 + t_u32 in_ts_sec, in_ts_usec; +#endif ENTER(); /* Save the last event to debug log */ @@ -726,8 +728,7 @@ wlan_process_event(pmlan_adapter pmadapter) if (MTRUE && (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) ) { - pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle, - &in_ts_sec, &in_ts_usec); + PRINTM_GET_SYS_TIME(MEVENT, &in_ts_sec, &in_ts_usec); PRINTM_NETINTF(MEVENT, priv); PRINTM(MEVENT, "%lu.%06lu : Event: 0x%x\n", in_ts_sec, in_ts_usec, eventcause); @@ -1109,7 +1110,10 @@ wlan_process_cmdresp(mlan_adapter * pmadapter) t_u16 cmdresp_result; mlan_ioctl_req *pioctl_buf = MNULL; mlan_callbacks *pcb = (mlan_callbacks *) & pmadapter->callbacks; - t_u32 sec, usec, i; +#ifdef DEBUG_LEVEL1 + t_u32 sec, usec; +#endif + t_u32 i; ENTER(); @@ -1189,8 +1193,7 @@ wlan_process_cmdresp(mlan_adapter * pmadapter) pmadapter->dbg.last_cmd_resp_id[pmadapter->dbg.last_cmd_resp_index] = orig_cmdresp_no; - pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle, &sec, - &usec); + PRINTM_GET_SYS_TIME(MCMND, &sec, &usec); PRINTM_NETINTF(MCMND, pmadapter->curr_cmd->priv); PRINTM(MCMND, "CMD_RESP (%lu.%06lu): 0x%x, result %d, len %d, seqno 0x%x\n", sec, usec, orig_cmdresp_no, cmdresp_result, resp->size, @@ -1301,7 +1304,9 @@ wlan_cmd_timeout_func(t_void * function_context) mlan_adapter *pmadapter = (mlan_adapter *) function_context; cmd_ctrl_node *pcmd_node = MNULL; mlan_ioctl_req *pioctl_buf = MNULL; +#ifdef DEBUG_LEVEL1 t_u32 sec, usec; +#endif t_u8 i; mlan_private *pmpriv = MNULL; @@ -1325,8 +1330,7 @@ wlan_cmd_timeout_func(t_void * function_context) pmadapter->dbg.last_cmd_id[pmadapter->dbg.last_cmd_index]; pmadapter->dbg.timeout_cmd_act = pmadapter->dbg.last_cmd_act[pmadapter->dbg.last_cmd_index]; - pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle, &sec, - &usec); + PRINTM_GET_SYS_TIME(MERROR, &sec, &usec); PRINTM(MERROR, "Timeout cmd id (%lu.%06lu) = 0x%x, act = 0x%x \n", sec, usec, pmadapter->dbg.timeout_cmd_id, pmadapter->dbg.timeout_cmd_act); @@ -2719,6 +2723,9 @@ wlan_ret_get_hw_spec(IN pmlan_private pmpriv, PRINTM(MWARN, "unidentified region code, use the default (0x%02x)\n", MRVDRV_DEFAULT_REGION_CODE); } + /* Synchronize CFP code with region code */ + pmadapter->cfp_code_bg = pmadapter->region_code; + pmadapter->cfp_code_a = pmadapter->region_code; if (wlan_set_regiontable(pmpriv, (t_u8) pmadapter->region_code, pmadapter->fw_bands)) { diff --git a/drivers/net/wireless/sd8797/mlan/mlan_decl.h b/drivers/net/wireless/sd8797/mlan/mlan_decl.h index d0ca7acae937..41cf2bf5f2f1 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_decl.h +++ b/drivers/net/wireless/sd8797/mlan/mlan_decl.h @@ -27,7 +27,7 @@ Change log: #define _MLAN_DECL_H_ /** MLAN release version */ -#define MLAN_RELEASE_VERSION "303" +#define MLAN_RELEASE_VERSION "311" /** Re-define generic data types for MLAN/MOAL */ /** Signed char (1-byte) */ @@ -136,10 +136,18 @@ typedef t_s32 t_sval; /** This is current limit on Maximum Rx AMPDU allowed */ #define MLAN_MAX_RX_BASTREAM_SUPPORTED 16 +#ifdef STA_SUPPORT /** Default Win size attached during ADDBA request */ -#define MLAN_AMPDU_DEF_TXWINSIZE 32 +#define MLAN_STA_AMPDU_DEF_TXWINSIZE 16 /** Default Win size attached during ADDBA response */ -#define MLAN_AMPDU_DEF_RXWINSIZE 16 +#define MLAN_STA_AMPDU_DEF_RXWINSIZE 32 +#endif /* STA_SUPPORT */ +#ifdef UAP_SUPPORT +/** Default Win size attached during ADDBA request */ +#define MLAN_UAP_AMPDU_DEF_TXWINSIZE 32 +/** Default Win size attached during ADDBA response */ +#define MLAN_UAP_AMPDU_DEF_RXWINSIZE 16 +#endif /* UAP_SUPPORT */ /** Block ack timeout value */ #define MLAN_DEFAULT_BLOCK_ACK_TIMEOUT 0xffff /** Maximum Tx Win size configured for ADDBA request [10 bits] */ @@ -626,6 +634,8 @@ typedef MLAN_PACK_START struct _custom_ie t_u8 ie_buffer[MAX_IE_SIZE]; } MLAN_PACK_END custom_ie; +/** Max IE index to FW */ +#define MAX_MGMT_IE_INDEX_TO_FW 4 /** Max IE index per BSS */ #define MAX_MGMT_IE_INDEX 16 @@ -659,7 +669,7 @@ typedef MLAN_PACK_START struct _tlvbuf_custom_ie /** Length */ t_u16 len; /** IE data */ - custom_ie ie_data_list[MAX_MGMT_IE_INDEX]; + custom_ie ie_data_list[MAX_MGMT_IE_INDEX_TO_FW]; /** Max mgmt IE TLV */ tlvbuf_max_mgmt_ie max_mgmt_ie; } MLAN_PACK_END mlan_ds_misc_custom_ie; diff --git a/drivers/net/wireless/sd8797/mlan/mlan_fw.h b/drivers/net/wireless/sd8797/mlan/mlan_fw.h index 1b0af8d8c0ea..fda2e7285dfd 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_fw.h +++ b/drivers/net/wireless/sd8797/mlan/mlan_fw.h @@ -148,6 +148,11 @@ typedef enum _KEY_TYPE_ID KEY_TYPE_ID_WAPI, } KEY_TYPE_ID; +/** Key Info flag for multicast key */ +#define KEY_INFO_MCAST_KEY 0x01 +/** Key Info flag for unicast key */ +#define KEY_INFO_UCAST_KEY 0x02 + /** KEY_INFO_WEP*/ typedef enum _KEY_INFO_WEP { @@ -311,9 +316,10 @@ typedef enum _WLAN_802_11_WEP_STATUS #define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 0x16) // 0x0116 /** TLV type : Beacon SNR high */ #define TLV_TYPE_SNR_HIGH (PROPRIETARY_TLV_BASE_ID + 0x17) // 0x0117 - /** TLV type : Start BG scan later */ #define TLV_TYPE_STARTBGSCANLATER (PROPRIETARY_TLV_BASE_ID + 0x1e) // 0x011e +/** TLV type: BG scan repeat count */ +#define TLV_TYPE_REPEAT_COUNT (PROPRIETARY_TLV_BASE_ID + 0xb0) // 0x01b0 /** TLV type : Authentication type */ #define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 0x1f) // 0x011f /** TLV type : BSSID */ @@ -397,7 +403,7 @@ typedef enum _WLAN_802_11_WEP_STATUS #define BA_STREAM_NOT_ALLOWED 0xff /** Test if 11n is enabled by checking the HTCap IE */ -#define IS_11N_ENABLED(priv) ((priv->adapter->config_bands & BAND_GN ||priv->adapter->config_bands & BAND_AN) \ +#define IS_11N_ENABLED(priv) ((priv->config_bands & BAND_GN ||priv->config_bands & BAND_AN) \ && priv->curr_bss_params.bss_descriptor.pht_cap) /** Find out if we are the initiator or not */ #define INITIATOR_BIT(DelBAParamSet) (((DelBAParamSet) & \ @@ -848,6 +854,9 @@ typedef enum _WLAN_802_11_WEP_STATUS #define HostCmd_CMD_802_11_REMAIN_ON_CHANNEL 0x010d #endif +/** Host Command ID : OTP user data */ +#define HostCmd_CMD_OTP_READ_USER_DATA 0x0114 + /** Enhanced PS modes */ typedef enum _ENH_PS_MODES { @@ -2806,6 +2815,25 @@ typedef MLAN_PACK_START struct _HostCmd_DS_802_11_BG_SCAN_QUERY_RSP HostCmd_DS_802_11_SCAN_RSP scan_resp; } MLAN_PACK_END HostCmd_DS_802_11_BG_SCAN_QUERY_RSP; +/** MrvlIEtypes_StartLater_t */ +typedef MLAN_PACK_START struct _MrvlIEtypes_StartLater_t +{ + /** Header */ + MrvlIEtypesHeader_t header; + /* 0 - BGScan start immediately, 1 - BGScan will start later after "Scan + Interval" */ + t_u16 value; +} MLAN_PACK_END MrvlIEtypes_StartLater_t; + +/** MrvlIEtypes_RepeatCount_t */ +typedef MLAN_PACK_START struct _MrvlIEtypes_RepeatCount_t +{ + /** Header */ + MrvlIEtypesHeader_t header; + /* Repeat count */ + t_u16 repeat_count; +} MLAN_PACK_END MrvlIEtypes_RepeatCount_t; + /** MrvlIEtypes_DomainParamSet_t */ typedef MLAN_PACK_START struct _MrvlIEtypes_DomainParamSet { @@ -3540,6 +3568,19 @@ typedef MLAN_PACK_START struct _HostCmd_DS_SUBSCRIBE_EVENT t_u16 event_bitmap; } MLAN_PACK_END HostCmd_DS_SUBSCRIBE_EVENT; +/** HostCmd_DS_OTP_USER_DATA */ +typedef MLAN_PACK_START struct _HostCmd_DS_OTP_USER_DATA +{ + /** Action */ + t_u16 action; + /** Reserved field */ + t_u16 reserved; + /** User data length */ + t_u16 user_data_length; + /** User data */ + t_u8 user_data[1]; +} MLAN_PACK_END HostCmd_DS_OTP_USER_DATA; + /** HostCmd_DS_INACTIVITY_TIMEOUT_EXT */ typedef MLAN_PACK_START struct _HostCmd_DS_INACTIVITY_TIMEOUT_EXT { @@ -4495,6 +4536,7 @@ typedef struct MLAN_PACK_START _HostCmd_DS_COMMAND HostCmd_DS_802_11_BG_SCAN_QUERY bg_scan_query; HostCmd_DS_802_11_BG_SCAN_QUERY_RSP bg_scan_query_resp; HostCmd_DS_SUBSCRIBE_EVENT subscribe_event; + HostCmd_DS_OTP_USER_DATA otp_user_data; /** Associate */ HostCmd_DS_802_11_ASSOCIATE associate; diff --git a/drivers/net/wireless/sd8797/mlan/mlan_ieee.h b/drivers/net/wireless/sd8797/mlan/mlan_ieee.h index 9473c498b973..2431e06f48fa 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_ieee.h +++ b/drivers/net/wireless/sd8797/mlan/mlan_ieee.h @@ -27,6 +27,8 @@ Change log: #ifndef _MLAN_IEEE_H_ #define _MLAN_IEEE_H_ +/** FIX IES size in beacon buffer */ +#define WLAN_802_11_FIXED_IE_SIZE 12 /** WLAN supported rates */ #define WLAN_SUPPORTED_RATES 14 @@ -1179,6 +1181,8 @@ typedef MLAN_PACK_START struct t_u8 rssi_threshold; /** SNR threshold */ t_u8 snr_threshold; + /** repeat count */ + t_u16 repeat_count; /** SSID filter list used in the to limit the scan results */ wlan_user_scan_ssid ssid_list[MRVDRV_MAX_SSID_LIST_LENGTH]; /** Variable number (fixed maximum) of channels to scan up */ diff --git a/drivers/net/wireless/sd8797/mlan/mlan_init.c b/drivers/net/wireless/sd8797/mlan/mlan_init.c index 563f74cd3980..48681b3e3ed9 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_init.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_init.c @@ -312,10 +312,17 @@ wlan_init_priv(pmlan_private priv) priv->bcn_rssi_avg = 0; priv->bcn_nf_avg = 0; priv->bcn_nf_last = 0; + + priv->sec_info.ewpa_enabled = MFALSE; + priv->sec_info.wpa_enabled = MFALSE; + priv->sec_info.wpa2_enabled = MFALSE; memset(pmadapter, &priv->wpa_ie, 0, sizeof(priv->wpa_ie)); memset(pmadapter, &priv->aes_key, 0, sizeof(priv->aes_key)); priv->wpa_ie_len = 0; priv->wpa_is_gtk_set = MFALSE; + priv->sec_info.wapi_enabled = MFALSE; + priv->wapi_ie_len = 0; + priv->sec_info.wapi_key_on = MFALSE; memset(pmadapter, &priv->wps, 0, sizeof(priv->wps)); memset(pmadapter, &priv->gen_ie_buf, 0, sizeof(priv->gen_ie_buf)); @@ -362,7 +369,6 @@ wlan_init_priv(pmlan_private priv) t_void wlan_init_adapter(pmlan_adapter pmadapter) { - int i; opt_sleep_confirm_buffer *sleep_cfm_buf = MNULL; ENTER(); @@ -391,9 +397,6 @@ wlan_init_adapter(pmlan_adapter pmadapter) pmadapter->mp_wr_bitmap = 0; pmadapter->curr_rd_port = 1; pmadapter->curr_wr_port = 1; - for (i = 0; i < MAX_NUM_TID; i++) { - pmadapter->tx_eligibility[i] = 1; - } pmadapter->mp_data_port_mask = DATA_PORT_MASK; #ifdef SDIO_MULTI_PORT_TX_AGGR @@ -559,6 +562,8 @@ wlan_init_adapter(pmlan_adapter pmadapter) memset(pmadapter, &pmadapter->region_channel, 0, sizeof(pmadapter->region_channel)); pmadapter->region_code = 0; + memcpy(pmadapter, pmadapter->country_code, MRVDRV_DEFAULT_COUNTRY_CODE, + COUNTRY_CODE_LEN); pmadapter->bcn_miss_time_out = DEFAULT_BCN_MISS_TIMEOUT; pmadapter->adhoc_awake_period = 0; #ifdef STA_SUPPORT diff --git a/drivers/net/wireless/sd8797/mlan/mlan_ioctl.h b/drivers/net/wireless/sd8797/mlan/mlan_ioctl.h index 15e88e631067..964de9197ffe 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_ioctl.h +++ b/drivers/net/wireless/sd8797/mlan/mlan_ioctl.h @@ -82,6 +82,7 @@ enum _mlan_ioctl_req_id MLAN_OID_SNMP_MIB_DOT11D, MLAN_OID_SNMP_MIB_DOT11H, #endif + MLAN_OID_SNMP_MIB_DTIM_PERIOD, /* Status Information Group */ MLAN_IOCTL_GET_INFO = 0x00050000, @@ -204,12 +205,15 @@ enum _mlan_ioctl_req_id MLAN_OID_MISC_IP_ADDR, MLAN_OID_MISC_MAC_CONTROL, MLAN_OID_MISC_MEF_CFG, + MLAN_OID_MISC_CFP_CODE, + MLAN_OID_MISC_COUNTRY_CODE, MLAN_OID_MISC_THERMAL, MLAN_OID_MISC_RX_MGMT_IND, MLAN_OID_MISC_SUBSCRIBE_EVENT, #ifdef DEBUG_LEVEL1 MLAN_OID_MISC_DRVDBG, #endif + MLAN_OID_MISC_OTP_USER_DATA, }; /** Sub command size */ @@ -1041,6 +1045,8 @@ typedef struct _mlan_ds_snmp_mib /** OID value for MLAN_OID_SNMP_MIB_DOT11D/H */ t_u32 oid_value; #endif + /** DTIM period for MLAN_OID_SNMP_MIB_DTIM_PERIOD */ + t_u32 dtim_period; } param; } mlan_ds_snmp_mib, *pmlan_ds_snmp_mib; @@ -1266,6 +1272,8 @@ typedef struct _mlan_bss_info #ifdef STA_SUPPORT /** Capability Info */ t_u16 capability_info; + /** Beacon Interval */ + t_u16 beacon_interval; /** Listen Interval */ t_u16 listen_interval; /** Association Id */ @@ -1442,7 +1450,7 @@ typedef struct _mlan_debug_info #ifdef UAP_SUPPORT /** Maximum number of clients supported by AP */ -#define MAX_NUM_CLIENTS 16 +#define MAX_NUM_CLIENTS MAX_STA_COUNT /** station info */ typedef struct _sta_info @@ -1553,7 +1561,7 @@ enum _mlan_psk_type /** key flag for rx_seq */ #define KEY_FLAG_RX_SEQ_VALID 0x00000002 /** key flag for group key */ -#define KEY_FLAG_GROUP_KEY 0x00000004 +#define KEY_FLAG_GROUP_KEY 0x00000004 /** key flag for tx and rx */ #define KEY_FLAG_SET_TX_KEY 0x00000008 /** key flag for remove key */ @@ -1600,6 +1608,24 @@ typedef struct _mlan_pmk_t t_u8 pmk[MLAN_MAX_KEY_LENGTH]; } mlan_pmk_t; +/** Embedded supplicant RSN type: No RSN */ +#define RSN_TYPE_NO_RSN MBIT(0) +/** Embedded supplicant RSN type: WPA */ +#define RSN_TYPE_WPA MBIT(3) +/** Embedded supplicant RSN type: WPA-NONE */ +#define RSN_TYPE_WPANONE MBIT(4) +/** Embedded supplicant RSN type: WPA2 */ +#define RSN_TYPE_WPA2 MBIT(5) +/** Embedded supplicant RSN type: RFU */ +#define RSN_TYPE_VALID_BITS (RSN_TYPE_NO_RSN | RSN_TYPE_WPA | RSN_TYPE_WPANONE | RSN_TYPE_WPA2) + +/** Embedded supplicant cipher type: TKIP */ +#define EMBED_CIPHER_TKIP MBIT(2) +/** Embedded supplicant cipher type: AES */ +#define EMBED_CIPHER_AES MBIT(3) +/** Embedded supplicant cipher type: RFU */ +#define EMBED_CIPHER_VALID_BITS (EMBED_CIPHER_TKIP | EMBED_CIPHER_AES) + /** Type definition of mlan_ds_passphrase for MLAN_OID_SEC_CFG_PASSPHRASE */ typedef struct _mlan_ds_passphrase { @@ -2545,7 +2571,7 @@ enum _mlan_reg_type MLAN_REG_MAC = 1, MLAN_REG_BBP, MLAN_REG_RF, - MLAN_REG_CAU, + MLAN_REG_CAU = 5, }; /** Type definition of mlan_ds_reg_rw for MLAN_OID_REG_RW */ @@ -2782,6 +2808,22 @@ typedef struct _mlan_ds_misc_mef_cfg } param; } mlan_ds_misc_mef_cfg; +/** Type definition of mlan_ds_misc_cfp_code for MLAN_OID_MISC_CFP_CODE */ +typedef struct _mlan_ds_misc_cfp_code +{ + /** CFP table code for 2.4GHz */ + t_u32 cfp_code_bg; + /** CFP table code for 5GHz */ + t_u32 cfp_code_a; +} mlan_ds_misc_cfp_code; + +/** Type definition of mlan_ds_misc_country_code for MLAN_OID_MISC_COUNTRY_CODE */ +typedef struct _mlan_ds_misc_country_code +{ + /** Country Code */ + t_u8 country_code[COUNTRY_CODE_LEN]; +} mlan_ds_misc_country_code; + /** BITMAP for subscribe event rssi low */ #define SUBSCRIBE_EVT_RSSI_LOW MBIT(0) /** BITMAP for subscribe event snr low */ @@ -2806,6 +2848,8 @@ typedef struct _mlan_ds_misc_mef_cfg #define SUBSCRIBE_EVT_LINK_QUALITY MBIT(10) /** BITMAP for subscribe event pre_beacon_lost */ #define SUBSCRIBE_EVT_PRE_BEACON_LOST MBIT(11) +/** default PRE_BEACON_MISS_COUNT */ +#define DEFAULT_PRE_BEACON_MISS 30 /** Type definition of mlan_ds_subscribe_evt for MLAN_OID_MISC_CFP_CODE */ typedef struct _mlan_ds_subscribe_evt @@ -2868,6 +2912,20 @@ typedef struct _mlan_ds_subscribe_evt t_u8 pre_beacon_miss; } mlan_ds_subscribe_evt; +/** Max OTP user data length */ +#define MAX_OTP_USER_DATA_LEN 252 + +/** Type definition of mlan_ds_misc_otp_user_data for MLAN_OID_MISC_OTP_USER_DATA */ +typedef struct _mlan_ds_misc_otp_user_data +{ + /** Reserved */ + t_u16 reserved; + /** OTP user data length */ + t_u16 user_data_length; + /** User data buffer */ + t_u8 user_data[MAX_OTP_USER_DATA_LEN]; +} mlan_ds_misc_otp_user_data; + /** Type definition of mlan_ds_misc_cfg for MLAN_IOCTL_MISC_CFG */ typedef struct _mlan_ds_misc_cfg { @@ -2902,6 +2960,10 @@ typedef struct _mlan_ds_misc_cfg t_u32 mac_ctrl; /** MEF configuration for MLAN_OID_MISC_MEF_CFG */ mlan_ds_misc_mef_cfg mef_cfg; + /** CFP code for MLAN_OID_MISC_CFP_CODE */ + mlan_ds_misc_cfp_code cfp_code; + /** Country code for MLAN_OID_MISC_COUNTRY_CODE */ + mlan_ds_misc_country_code country_code; /** Thermal reading for MLAN_OID_MISC_THERMAL */ t_u32 thermal; /** Mgmt subtype mask for MLAN_OID_MISC_RX_MGMT_IND */ @@ -2912,6 +2974,7 @@ typedef struct _mlan_ds_misc_cfg /** Driver debug bit masks */ t_u32 drvdbg; #endif + mlan_ds_misc_otp_user_data otp_user_data; } param; } mlan_ds_misc_cfg, *pmlan_ds_misc_cfg; diff --git a/drivers/net/wireless/sd8797/mlan/mlan_main.h b/drivers/net/wireless/sd8797/mlan/mlan_main.h index fb15c7226c38..44e4f8001201 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_main.h +++ b/drivers/net/wireless/sd8797/mlan/mlan_main.h @@ -4,7 +4,7 @@ * structures and declares global function prototypes used * in MLAN module. * - * Copyright (C) 2008-2011, Marvell International Ltd. + * Copyright (C) 2008-2012, Marvell International Ltd. * * This software file (the "File") is distributed by Marvell International * Ltd. under the terms of the GNU General Public License Version 2, June 1991 @@ -31,6 +31,11 @@ Change log: #ifdef DEBUG_LEVEL1 extern t_void(*print_callback) (IN t_void * pmoal_handle, IN t_u32 level, IN t_s8 * pformat, IN ...); + +extern mlan_status(*get_sys_time_callback) (IN t_void * pmoal_handle, + OUT t_u32 * psec, + OUT t_u32 * pusec); + extern t_u32 drvdbg; #ifdef DEBUG_LEVEL2 @@ -40,10 +45,35 @@ extern t_u32 drvdbg; print_callback(MNULL, MWARN, msg);} while(0) #define PRINTM_MENTRY(msg...) do {if ((drvdbg & MENTRY) && (print_callback)) \ print_callback(MNULL, MENTRY, msg);} while(0) +#define PRINTM_GET_SYS_TIME(level, psec, pusec) \ +do { \ + if ((level & drvdbg) && (get_sys_time_callback)) \ + get_sys_time_callback(MNULL, psec, pusec); \ +} while (0) + +/** Hexdump for level-2 debugging */ +#define HEXDUMP(x,y,z) \ +do { \ + if ((drvdbg & (MHEX_DUMP | MINFO)) && (print_callback)) \ + print_callback(MNULL, MHEX_DUMP | MINFO, x, y, z); \ +} while (0) + #else + #define PRINTM_MINFO(msg...) do {} while (0) #define PRINTM_MWARN(msg...) do {} while (0) #define PRINTM_MENTRY(msg...) do {} while (0) + +#define PRINTM_GET_SYS_TIME(level, psec, pusec) \ +do { \ + if ((level & drvdbg) && (get_sys_time_callback) \ + && (level != MINFO) && (level != MWARN)) \ + get_sys_time_callback(MNULL, psec, pusec); \ +} while (0) + +/** Hexdump for debugging */ +#define HEXDUMP(x,y,z) do {} while (0) + #endif /* DEBUG_LEVEL2 */ #define PRINTM_MFW_D(msg...) do {if ((drvdbg & MFW_D) && (print_callback)) \ @@ -74,20 +104,6 @@ extern t_u32 drvdbg; #define PRINTM(level,msg...) PRINTM_##level(msg) -#ifdef DEBUG_LEVEL2 - -/** Hexdump for level-2 debugging */ -#define HEXDUMP(x,y,z) \ -do { \ - if ((drvdbg & (MHEX_DUMP | MINFO)) && (print_callback)) \ - print_callback(MNULL, MHEX_DUMP | MINFO, x, y, z); \ -} while (0) -#else - -/** Hexdump for debugging */ -#define HEXDUMP(x,y,z) do {} while (0) -#endif /* DEBUG_LEVEL2 */ - /** Log debug message */ #ifdef __GNUC__ #define PRINTM_NETINTF(level, pmpriv) \ @@ -122,6 +138,8 @@ do { \ /** Hexdump for debugging */ #define HEXDUMP(x,y,z) do {} while (0) +#define PRINTM_GET_SYS_TIME(level, psec, pusec) do { } while(0) + #endif /* DEBUG_LEVEL1 */ /** Log entry point for debugging */ @@ -330,11 +348,19 @@ do { \ #define MLAN_DEFAULT_LISTEN_INTERVAL 10 /** Maximum number of region codes */ -#define MRVDRV_MAX_REGION_CODE 8 +#define MRVDRV_MAX_REGION_CODE 9 + +/** Maximum number of CFP codes for BG */ +#define MRVDRV_MAX_CFP_CODE_BG 0 +/** Maximum number of CFP codes for A */ +#define MRVDRV_MAX_CFP_CODE_A 5 /** Default region code */ #define MRVDRV_DEFAULT_REGION_CODE 0x10 +/** Default country code */ +#define MRVDRV_DEFAULT_COUNTRY_CODE "US" + /** Default factor for calculating beacon average */ #define DEFAULT_BCN_AVG_FACTOR 8 /** Default factor for calculating data average */ @@ -722,8 +748,9 @@ typedef struct _chan_freq_power_t t_u32 freq; /** Max allowed Tx power level */ t_u16 max_tx_power; - /** TRUE:radar detect required; FALSE:radar detect not required*/ - t_bool radar_detect; + /** TRUE:radar detect required for BAND A or passive scan for BAND B/G; + * FALSE:radar detect not required for BAND A or active scan for BAND B/G*/ + t_bool passive_scan_or_radar_detect; /** TRUE:channel unsupported; FALSE:supported */ t_u8 unsupported; } chan_freq_power_t; @@ -1368,7 +1395,7 @@ typedef struct _sdio_mpa_tx /** multiport tx aggregation packet count */ t_u32 pkt_cnt; /** multiport tx aggregation ports */ - t_u16 ports; + t_u32 ports; /** multiport tx aggregation starting port */ t_u16 start_port; /** multiport tx aggregation enable/disable flag */ @@ -1393,7 +1420,7 @@ typedef struct _sdio_mpa_rx /** multiport rx aggregation packet count */ t_u32 pkt_cnt; /** multiport rx aggregation ports */ - t_u16 ports; + t_u32 ports; /** multiport rx aggregation starting port */ t_u16 start_port; @@ -1511,8 +1538,6 @@ typedef struct _mlan_adapter t_u8 *mp_regs; /** allocated buf to read SDIO multiple port group registers */ t_u8 *mp_regs_buf; - /** Array to store data transfer eligibility based on tid (QoS-over-SDIO) */ - t_u8 tx_eligibility[MAX_NUM_TID]; #ifdef SDIO_MULTI_PORT_TX_AGGR /** data structure for SDIO MPA TX */ @@ -1596,6 +1621,10 @@ typedef struct _mlan_adapter t_u16 region_code; /** Region Channel data */ region_chan_t region_channel[MAX_REGION_CHANNEL_NUM]; + /** CFP table code for 2.4GHz */ + t_u8 cfp_code_bg; + /** CFP table code for 5GHz */ + t_u8 cfp_code_a; #ifdef STA_SUPPORT /** Universal Channel data */ region_chan_t universal_channel[MAX_REGION_CHANNEL_NUM]; @@ -1604,6 +1633,8 @@ typedef struct _mlan_adapter #endif /* STA_SUPPORT */ /** 11D and Domain Regulatory Data */ wlan_802_11d_domain_reg_t domain_reg; + /** Country Code */ + t_u8 country_code[COUNTRY_CODE_LEN]; /** FSM variable for 11h support */ wlan_11h_device_state_t state_11h; /** FSM variable for DFS support */ @@ -1620,6 +1651,7 @@ typedef struct _mlan_adapter BSSDescriptor_t *pscan_table; /** scan age in secs */ t_u32 age_in_secs; + t_u8 bgscan_reported; /** Number of records in the scan table */ t_u32 num_in_scan_table; @@ -2177,6 +2209,9 @@ mlan_status wlan_cmd_bgscan_config(IN mlan_private * pmpriv, mlan_status wlan_ret_bgscan_config(IN mlan_private * pmpriv, IN HostCmd_DS_COMMAND * resp, IN mlan_ioctl_req * pioctl_buf); +mlan_status wlan_ret_802_11_bgscan_query(IN mlan_private * pmpriv, + IN HostCmd_DS_COMMAND * resp, + IN mlan_ioctl_req * pioctl_buf); /** Get Channel-Frequency-Power by band and channel */ chan_freq_power_t *wlan_get_cfp_by_band_and_channel(pmlan_adapter pmadapter, @@ -2221,10 +2256,16 @@ int wlan_get_rate_index(pmlan_adapter pmadapter, t_u16 * rateBitmap, int size); /* CFP related functions */ /** Region code index table */ extern t_u16 region_code_index[MRVDRV_MAX_REGION_CODE]; +/** The table to keep CFP code for BG */ +extern t_u16 cfp_code_index_bg[MRVDRV_MAX_CFP_CODE_BG]; +/** The table to keep CFP code for A */ +extern t_u16 cfp_code_index_a[MRVDRV_MAX_CFP_CODE_A]; /** Set region table */ mlan_status wlan_set_regiontable(mlan_private * pmpriv, t_u8 region, t_u8 band); /** Get radar detection requirements*/ t_bool wlan_get_cfp_radar_detect(mlan_private * priv, t_u8 chnl); +/** check if scan type is passive for b/g band*/ +t_bool wlan_bg_scan_type_is_passive(mlan_private * priv, t_u8 chnl); /* 802.11D related functions */ /** Initialize 11D */ @@ -2280,6 +2321,12 @@ mlan_status wlan_11d_handle_uap_domain_info(mlan_private * pmpriv, t_void * pioctl_buf); #endif +/** This function converts region string to CFP table code */ +mlan_status wlan_misc_country_2_cfp_table_code(IN pmlan_adapter pmadapter, + IN t_u8 * country_code, + OUT t_u8 * cfp_bg, + OUT t_u8 * cfp_a); + /** check if station list is empty */ t_u8 wlan_is_station_list_empty(mlan_private * priv); /** get station node */ @@ -2316,7 +2363,6 @@ wlan_is_tx_pause(mlan_private * priv, t_u8 * ra) t_void wlan_updata_ralist_tx_pause(pmlan_private priv, t_u8 * mac, t_u8 tx_pause); -sta_node *wlan_get_tx_pause_station_entry(mlan_private * priv); #ifdef UAP_SUPPORT mlan_status wlan_process_uap_rx_packet(IN mlan_private * priv, @@ -2366,6 +2412,9 @@ mlan_status wlan_set_drvdbg(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req); #endif +mlan_status wlan_misc_otp_user_data(IN pmlan_adapter pmadapter, + IN pmlan_ioctl_req pioctl_req); + /** * @brief RA based queueing * diff --git a/drivers/net/wireless/sd8797/mlan/mlan_misc.c b/drivers/net/wireless/sd8797/mlan/mlan_misc.c index 929a38ab33f6..f41dcea3d206 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_misc.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_misc.c @@ -970,7 +970,7 @@ wlan_misc_ioctl_custom_ie_list(IN pmlan_adapter pmadapter, goto done; } memset(pmadapter, ie_data, 0, - sizeof(custom_ie) * MAX_MGMT_IE_INDEX); + sizeof(custom_ie) * MAX_MGMT_IE_INDEX_TO_FW); len = 0; for (i = 0; i < pmadapter->max_mgmt_ie_index; i++) { memcpy(pmadapter, (t_u8 *) ie_data + len, &i, @@ -1042,7 +1042,7 @@ wlan_misc_ioctl_custom_ie_list(IN pmlan_adapter pmadapter, goto done; } memset(pmadapter, ie_data, 0, - sizeof(custom_ie) * MAX_MGMT_IE_INDEX); + sizeof(custom_ie) * MAX_MGMT_IE_INDEX_TO_FW); memcpy(pmadapter, (t_u8 *) ie_data, &pmpriv->mgmt_ie[index], pmpriv->mgmt_ie[index].ie_length + MLAN_CUSTOM_IE_HDR_SIZE); @@ -1281,41 +1281,6 @@ wlan_delete_station_list(pmlan_private priv) } /** - * @brief This function will return the pointer to station entry in station list - * table which in tx_pause state - * - * @param priv A pointer to mlan_private - * - * @return A pointer to structure sta_node - */ -sta_node * -wlan_get_tx_pause_station_entry(mlan_private * priv) -{ - sta_node *sta_ptr; - - ENTER(); - - if (!(sta_ptr = (sta_node *) util_peek_list(priv->adapter->pmoal_handle, - &priv->sta_list, - priv->adapter->callbacks. - moal_spin_lock, - priv->adapter->callbacks. - moal_spin_unlock))) { - LEAVE(); - return MNULL; - } - while (sta_ptr != (sta_node *) & priv->sta_list) { - if (sta_ptr->tx_pause) { - LEAVE(); - return sta_ptr; - } - sta_ptr = sta_ptr->pnext; - } - LEAVE(); - return MNULL; -} - -/** * @brief Get extended version information * * @param pmadapter A pointer to mlan_adapter structure @@ -1496,6 +1461,44 @@ wlan_process_802dot11_mgmt_pkt(IN mlan_private * priv, } /** + * @brief Get OTP user data + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req A pointer to ioctl request buffer + * + * @return MLAN_STATUS_PENDING --success, otherwise fail + */ +mlan_status +wlan_misc_otp_user_data(IN pmlan_adapter pmadapter, + IN pmlan_ioctl_req pioctl_req) +{ + pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index]; + mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf; + mlan_status ret = MLAN_STATUS_FAILURE; + + ENTER(); + + if (misc->param.otp_user_data.user_data_length > MAX_OTP_USER_DATA_LEN) { + PRINTM(MERROR, "Invalid OTP user data length\n"); + pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER; + LEAVE(); + return ret; + } + + ret = wlan_prepare_cmd(pmpriv, + HostCmd_CMD_OTP_READ_USER_DATA, + HostCmd_ACT_GEN_GET, + 0, + (t_void *) pioctl_req, &misc->param.otp_user_data); + + if (ret == MLAN_STATUS_SUCCESS) + ret = MLAN_STATUS_PENDING; + + LEAVE(); + return ret; +} + +/** * @brief This function will search for the specific ie * * @@ -1718,26 +1721,26 @@ wlan_rate_ioctl_get_rate_value(IN pmlan_adapter pmadapter, /* If not connected, set rate to the lowest in each band */ if (pmpriv->media_connected != MTRUE) { - if (pmadapter->config_bands & (BAND_B | BAND_G)) { + if (pmpriv->config_bands & (BAND_B | BAND_G)) { /* Return the lowest supported rate for BG band */ rate->param.rate_cfg.rate = SupportedRates_BG[0] & 0x7f; - } else if (pmadapter->config_bands & (BAND_A | BAND_B)) { + } else if (pmpriv->config_bands & (BAND_A | BAND_B)) { /* Return the lowest supported rate for A band */ rate->param.rate_cfg.rate = SupportedRates_BG[0] & 0x7f; - } else if (pmadapter->config_bands & BAND_A) { + } else if (pmpriv->config_bands & BAND_A) { /* Return the lowest supported rate for A band */ rate->param.rate_cfg.rate = SupportedRates_A[0] & 0x7f; - } else if (pmadapter->config_bands & BAND_G) { + } else if (pmpriv->config_bands & BAND_G) { /* Return the lowest supported rate for G band */ rate->param.rate_cfg.rate = SupportedRates_G[0] & 0x7f; - } else if (pmadapter->config_bands & BAND_B) { + } else if (pmpriv->config_bands & BAND_B) { /* Return the lowest supported rate for B band */ rate->param.rate_cfg.rate = SupportedRates_B[0] & 0x7f; - } else if (pmadapter->config_bands & BAND_GN) { + } else if (pmpriv->config_bands & BAND_GN) { /* Return the lowest supported rate for N band */ rate->param.rate_cfg.rate = SupportedRates_N[0] & 0x7f; } else { - PRINTM(MMSG, "Invalid Band 0x%x\n", pmadapter->config_bands); + PRINTM(MMSG, "Invalid Band 0x%x\n", pmpriv->config_bands); } } else { @@ -1793,7 +1796,7 @@ wlan_rate_ioctl_set_rate_value(IN pmlan_adapter pmadapter, memset(pmadapter, rates, 0, sizeof(rates)); wlan_get_active_data_rates(pmpriv, pmpriv->bss_mode, (pmpriv->bss_mode == MLAN_BSS_MODE_INFRA) ? - pmadapter->config_bands : pmadapter-> + pmpriv->config_bands : pmadapter-> adhoc_start_band, rates); rate = rates; for (i = 0; (rate[i] && i < WLAN_SUPPORTED_RATES); i++) { diff --git a/drivers/net/wireless/sd8797/mlan/mlan_scan.c b/drivers/net/wireless/sd8797/mlan/mlan_scan.c index 2c4eadf04a2e..895fb38a5786 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_scan.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_scan.c @@ -5,7 +5,7 @@ * IOCTL handlers as well as command preparation and response routines * for sending scan commands to the firmware. * - * Copyright (C) 2008-2011, Marvell International Ltd. + * Copyright (C) 2008-2012, Marvell International Ltd. * * This software file (the "File") is distributed by Marvell International * Ltd. under the terms of the GNU General Public License Version 2, June 1991 @@ -378,6 +378,9 @@ wlan_scan_create_channel_list(IN mlan_private * pmpriv, break; case BAND_B: case BAND_G: + if (wlan_bg_scan_type_is_passive(pmpriv, (t_u8) cfp->channel)) { + scan_type = MLAN_SCAN_TYPE_PASSIVE; + } default: pscan_chan_list[chan_idx].radio_type = HostCmd_SCAN_RADIO_TYPE_BG; @@ -825,7 +828,7 @@ wlan_scan_setup_scan_config(IN mlan_private * pmpriv, rates_size = wlan_get_supported_rates(pmpriv, pmpriv->bss_mode, (pmpriv->bss_mode == - MLAN_BSS_MODE_INFRA) ? pmadapter-> + MLAN_BSS_MODE_INFRA) ? pmpriv-> config_bands : pmadapter-> adhoc_start_band, rates); @@ -838,13 +841,12 @@ wlan_scan_setup_scan_config(IN mlan_private * pmpriv, PRINTM(MINFO, "SCAN_CMD: Rates size = %d\n", rates_size); if (ISSUPP_11NENABLED(pmpriv->adapter->fw_cap_info) - && (pmpriv->adapter->config_bands & BAND_GN - || pmpriv->adapter->config_bands & BAND_AN)) { + && (pmpriv->config_bands & BAND_GN || pmpriv->config_bands & BAND_AN)) { pht_cap = (MrvlIETypes_HTCap_t *) ptlv_pos; memset(pmadapter, pht_cap, 0, sizeof(MrvlIETypes_HTCap_t)); pht_cap->header.type = wlan_cpu_to_le16(HT_CAPABILITY); pht_cap->header.len = sizeof(HTCap_t); - wlan_fill_ht_cap_tlv(pmpriv, pht_cap, pmpriv->adapter->config_bands); + wlan_fill_ht_cap_tlv(pmpriv, pht_cap, pmpriv->config_bands); HEXDUMP("SCAN: HT_CAPABILITIES IE", (t_u8 *) pht_cap, sizeof(MrvlIETypes_HTCap_t)); ptlv_pos += sizeof(MrvlIETypes_HTCap_t); @@ -898,6 +900,11 @@ wlan_scan_setup_scan_config(IN mlan_private * pmpriv, scan_type = MLAN_SCAN_TYPE_PASSIVE; } } + if (radio_type == HostCmd_SCAN_RADIO_TYPE_BG) { + if (wlan_bg_scan_type_is_passive(pmpriv, channel)) { + scan_type = MLAN_SCAN_TYPE_PASSIVE; + } + } if (scan_type == MLAN_SCAN_TYPE_PASSIVE) { (pscan_chan_list + chan_idx)->chan_scan_mode.passive_scan = MTRUE; @@ -2938,7 +2945,8 @@ wlan_ret_802_11_scan(IN mlan_private * pmpriv, pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle, &pmadapter->age_in_secs, &age_ts_usec); - + if (is_bgscan_resp) + goto done; if (!util_peek_list (pmadapter->pmoal_handle, &pmadapter->scan_pending_q, pcb->moal_spin_lock, pcb->moal_spin_unlock)) { @@ -2961,6 +2969,7 @@ wlan_ret_802_11_scan(IN mlan_private * pmpriv, (pmlan_ioctl_req) pioctl_buf, MLAN_STATUS_SUCCESS); } + pmadapter->bgscan_reported = MFALSE; wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_SCAN_REPORT, MNULL); } else { /* If firmware not ready, do not issue any more scan commands */ @@ -3360,6 +3369,7 @@ wlan_handle_event_ext_scan_report(IN mlan_private * pmpriv, (pmlan_ioctl_req) pioctl_req, MLAN_STATUS_SUCCESS); } + pmadapter->bgscan_reported = MFALSE; wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_SCAN_REPORT, MNULL); } else { /* If firmware not ready, do not issue any more scan commands */ @@ -3508,6 +3518,8 @@ wlan_bgscan_create_channel_list(IN mlan_private * pmpriv, break; case BAND_B: case BAND_G: + if (wlan_bg_scan_type_is_passive(pmpriv, (t_u8) cfp->channel)) + scan_type = MLAN_SCAN_TYPE_PASSIVE; default: tlv_chan_list->chan_scan_param[chan_idx].radio_type = HostCmd_SCAN_RADIO_TYPE_BG; @@ -3575,6 +3587,8 @@ wlan_cmd_bgscan_config(IN mlan_private * pmpriv, MrvlIEtypes_BeaconLowSnrThreshold_t *snr_tlv = MNULL; MrvlIEtypes_WildCardSsIdParamSet_t *pwildcard_ssid_tlv = MNULL; MrvlIEtypes_ChanListParamSet_t *tlv_chan_list = MNULL; + MrvlIEtypes_StartLater_t *tlv_start_later = MNULL; + MrvlIEtypes_RepeatCount_t *tlv_repeat = MNULL; t_u8 *tlv = MNULL; t_u16 num_probes = 0; t_u32 ssid_idx; @@ -3640,6 +3654,16 @@ wlan_cmd_bgscan_config(IN mlan_private * pmpriv, tlv += sizeof(MrvlIEtypes_BeaconLowRssiThreshold_t); cmd_size += sizeof(MrvlIEtypes_BeaconLowRssiThreshold_t); } + if (bg_scan_in->repeat_count) { + tlv_repeat = (MrvlIEtypes_RepeatCount_t *) tlv; + tlv_repeat->header.type = wlan_cpu_to_le16(TLV_TYPE_REPEAT_COUNT); + tlv_repeat->header.len = + wlan_cpu_to_le16(sizeof(MrvlIEtypes_RepeatCount_t) - + sizeof(MrvlIEtypesHeader_t)); + tlv_repeat->repeat_count = wlan_cpu_to_le16(bg_scan_in->repeat_count); + tlv += sizeof(MrvlIEtypes_RepeatCount_t); + cmd_size += sizeof(MrvlIEtypes_RepeatCount_t); + } for (ssid_idx = 0; ((ssid_idx < NELEMENTS(bg_scan_in->ssid_list)) && (*bg_scan_in->ssid_list[ssid_idx].ssid || bg_scan_in->ssid_list[ssid_idx].max_len)); @@ -3683,6 +3707,12 @@ wlan_cmd_bgscan_config(IN mlan_private * pmpriv, scan_type = MLAN_SCAN_TYPE_PASSIVE; } } + if (radio_type == HostCmd_SCAN_RADIO_TYPE_BG) { + if (wlan_bg_scan_type_is_passive + (pmpriv, bg_scan_in->chan_list[chan_idx].chan_number)) { + scan_type = MLAN_SCAN_TYPE_PASSIVE; + } + } tlv_chan_list->chan_scan_param[chan_num].chan_number = bg_scan_in->chan_list[chan_idx].chan_number; tlv_chan_list->chan_scan_param[chan_num].radio_type = @@ -3729,6 +3759,14 @@ wlan_cmd_bgscan_config(IN mlan_private * pmpriv, cmd_size += sizeof(MrvlIEtypesHeader_t) + sizeof(ChanScanParamSet_t) * chan_num; } + tlv_start_later = (MrvlIEtypes_StartLater_t *) tlv; + tlv_start_later->header.type = wlan_cpu_to_le16(TLV_TYPE_STARTBGSCANLATER); + tlv_start_later->header.len = + wlan_cpu_to_le16(sizeof(MrvlIEtypes_StartLater_t) - + sizeof(MrvlIEtypesHeader_t)); + tlv_start_later->value = 0; + tlv += sizeof(MrvlIEtypes_StartLater_t); + cmd_size += sizeof(MrvlIEtypes_StartLater_t); done: pcmd->size = wlan_cpu_to_le16(cmd_size); LEAVE(); @@ -3776,6 +3814,36 @@ wlan_ret_bgscan_config(IN mlan_private * pmpriv, } /** + * @brief This function handles the command response of bgscan_query + * @param pmpriv A pointer to mlan_private structure + * @param resp A pointer to HostCmd_DS_COMMAND + * @param pioctl_buf A pointer to mlan_ioctl_req structure + * + * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE + */ +mlan_status +wlan_ret_802_11_bgscan_query(IN mlan_private * pmpriv, + IN HostCmd_DS_COMMAND * resp, + IN mlan_ioctl_req * pioctl_buf) +{ + mlan_ds_scan *pscan = MNULL; + mlan_adapter *pmadapter = pmpriv->adapter; + ENTER(); + wlan_ret_802_11_scan(pmpriv, resp, MNULL); + if (pioctl_buf) { + pscan = (mlan_ds_scan *) pioctl_buf->pbuf; + pscan->param.scan_resp.pscan_table = (t_u8 *) pmadapter->pscan_table; + pscan->param.scan_resp.num_in_scan_table = pmadapter->num_in_scan_table; + pscan->param.scan_resp.age_in_secs = pmadapter->age_in_secs; + pioctl_buf->data_read_written = sizeof(mlan_scan_resp) + + MLAN_SUB_COMMAND_SIZE; + + } + LEAVE(); + return MLAN_STATUS_SUCCESS; +} + +/** * @brief This function finds ssid in ssid list. * * @param pmpriv A pointer to mlan_private structure @@ -3812,7 +3880,7 @@ wlan_find_ssid_in_list(IN mlan_private * pmpriv, MLAN_MAC_ADDR_LENGTH))) { if (((mode == MLAN_BSS_MODE_INFRA) && - !wlan_is_band_compatible(pmadapter->config_bands, + !wlan_is_band_compatible(pmpriv->config_bands, pmadapter->pscan_table[i].bss_band)) || (wlan_find_cfp_by_band_and_channel @@ -3896,7 +3964,7 @@ wlan_find_bssid_in_list(IN mlan_private * pmpriv, (pmadapter, pmadapter->pscan_table[i].mac_address, bssid, MLAN_MAC_ADDR_LENGTH)) { if (((mode == MLAN_BSS_MODE_INFRA) && - !wlan_is_band_compatible(pmadapter->config_bands, + !wlan_is_band_compatible(pmpriv->config_bands, pmadapter->pscan_table[i].bss_band)) || (wlan_find_cfp_by_band_and_channel diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sdio.c b/drivers/net/wireless/sd8797/mlan/mlan_sdio.c index 0718cec12ee2..02e73477b619 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_sdio.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_sdio.c @@ -218,8 +218,9 @@ wlan_get_wr_port_data(mlan_adapter * pmadapter, t_u8 * pport) PRINTM(MIF_D, "wlan_get_wr_port_data: mp_wr_bitmap=0x%08x\n", wr_bitmap); if (!(wr_bitmap & pmadapter->mp_data_port_mask)) { + pmadapter->data_sent = MTRUE; LEAVE(); - return MLAN_STATUS_FAILURE; + return MLAN_STATUS_RESOURCE; } if (pmadapter->mp_wr_bitmap & (1 << pmadapter->curr_wr_port)) { @@ -1431,7 +1432,6 @@ wlan_sdio_host_to_card(mlan_adapter * pmadapter, t_u8 type, mlan_buffer * pmbuf, ret = wlan_get_wr_port_data(pmadapter, &port); if (ret != MLAN_STATUS_SUCCESS) { PRINTM(MERROR, "no wr_port available: %d\n", ret); - pmbuf->status_code = MLAN_ERROR_PKT_INVALID; goto exit; } /* Transfer data to card */ diff --git a/drivers/net/wireless/sd8797/mlan/mlan_shim.c b/drivers/net/wireless/sd8797/mlan/mlan_shim.c index 1e06a52b87cb..07f7db5c7227 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_shim.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_shim.c @@ -108,6 +108,12 @@ t_void(*assert_callback) (IN t_void * pmoal_handle, IN t_u32 cond) = MNULL; /** Global moal_print callback */ t_void(*print_callback) (IN t_void * pmoal_handle, IN t_u32 level, IN t_s8 * pformat, IN ...) = MNULL; + +/** Global moal_get_system_time callback */ +mlan_status(*get_sys_time_callback) (IN t_void * pmoal_handle, + OUT t_u32 * psec, + OUT t_u32 * pusec) = MNULL; + /** Global driver debug mit masks */ t_u32 drvdbg = DEFAULT_DEBUG_MASK; #endif @@ -161,6 +167,7 @@ mlan_register(IN pmlan_device pmdevice, OUT t_void ** ppmlan_adapter) MASSERT(pmdevice->callbacks.moal_print); #ifdef DEBUG_LEVEL1 print_callback = pmdevice->callbacks.moal_print; + get_sys_time_callback = pmdevice->callbacks.moal_get_system_time; #endif assert_callback = pmdevice->callbacks.moal_assert; diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sta_cmd.c b/drivers/net/wireless/sd8797/mlan/mlan_sta_cmd.c index c91fcc9f6e12..7c426595117e 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_sta_cmd.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_sta_cmd.c @@ -151,6 +151,16 @@ wlan_cmd_802_11_snmp_mib(IN pmlan_private pmpriv, } switch (cmd_oid) { + case DtimPeriod_i: + psnmp_mib->oid = wlan_cpu_to_le16((t_u16) DtimPeriod_i); + if (cmd_action == HostCmd_ACT_GEN_SET) { + psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET); + psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u8)); + ul_temp = *((t_u32 *) pdata_buf); + psnmp_mib->value[0] = (t_u8) ul_temp; + cmd->size += sizeof(t_u8); + } + break; case FragThresh_i: psnmp_mib->oid = wlan_cpu_to_le16((t_u16) FragThresh_i); if (cmd_action == HostCmd_ACT_GEN_SET) { @@ -712,7 +722,22 @@ wlan_cmd_802_11_key_material(IN pmlan_private pmpriv, pkey_material->action = wlan_cpu_to_le16(cmd_action); if (cmd_action == HostCmd_ACT_GEN_GET) { - cmd->size = wlan_cpu_to_le16(sizeof(pkey_material->action) + S_DS_GEN); + cmd->size = + wlan_cpu_to_le16(sizeof(pkey_material->action) + S_DS_GEN + + KEYPARAMSET_FIXED_LEN + + sizeof(MrvlIEtypesHeader_t)); + memset(pmpriv->adapter, &pkey_material->key_param_set, 0, + sizeof(MrvlIEtype_KeyParamSet_t)); + pkey_material->key_param_set.type = + wlan_cpu_to_le16(TLV_TYPE_KEY_MATERIAL); + pkey_material->key_param_set.length = + wlan_cpu_to_le16(KEYPARAMSET_FIXED_LEN); + if (pkey->key_flags & KEY_FLAG_GROUP_KEY) + pkey_material->key_param_set.key_info |= KEY_INFO_MCAST_KEY; + else + pkey_material->key_param_set.key_info |= KEY_INFO_UCAST_KEY; + pkey_material->key_param_set.key_info = + wlan_cpu_to_le16(pkey_material->key_param_set.key_info); goto done; } @@ -963,10 +988,14 @@ wlan_cmd_802_11_supplicant_pmk(IN pmlan_private pmpriv, static mlan_status wlan_cmd_802_11_supplicant_profile(IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND * cmd, - IN t_u16 cmd_action) + IN t_u16 cmd_action, IN t_void * pdata_buf) { HostCmd_DS_802_11_SUPPLICANT_PROFILE *sup_profile = &cmd->params.esupplicant_profile; + MrvlIEtypes_EncrProto_t *encr_proto_tlv = MNULL; + MrvlIEtypes_Cipher_t *pcipher_tlv = MNULL; + t_u8 *ptlv_buffer = (t_u8 *) sup_profile->tlv_buf; + mlan_ds_esupp_mode *esupp = MNULL; ENTER(); @@ -975,6 +1004,44 @@ wlan_cmd_802_11_supplicant_profile(IN pmlan_private pmpriv, S_DS_GEN - 1); cmd->command = wlan_cpu_to_le16(HostCmd_CMD_SUPPLICANT_PROFILE); sup_profile->action = wlan_cpu_to_le16(cmd_action); + if ((cmd_action == HostCmd_ACT_GEN_SET) && pdata_buf) { + esupp = (mlan_ds_esupp_mode *) pdata_buf; + if (esupp->rsn_mode) { + encr_proto_tlv = (MrvlIEtypes_EncrProto_t *) ptlv_buffer; + encr_proto_tlv->header.type = + wlan_cpu_to_le16(TLV_TYPE_ENCRYPTION_PROTO); + encr_proto_tlv->header.len = + (t_u16) sizeof(encr_proto_tlv->rsn_mode); + encr_proto_tlv->rsn_mode = wlan_cpu_to_le16(esupp->rsn_mode); + ptlv_buffer += + (encr_proto_tlv->header.len + sizeof(MrvlIEtypesHeader_t)); + cmd->size += + (encr_proto_tlv->header.len + sizeof(MrvlIEtypesHeader_t)); + encr_proto_tlv->header.len = + wlan_cpu_to_le16(encr_proto_tlv->header.len); + } + if (esupp->act_paircipher || esupp->act_groupcipher) { + pcipher_tlv = (MrvlIEtypes_Cipher_t *) ptlv_buffer; + pcipher_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_CIPHER); + pcipher_tlv->header.len = + (t_u16) (sizeof(pcipher_tlv->pair_cipher) + + sizeof(pcipher_tlv->group_cipher)); + if (esupp->act_paircipher) { + pcipher_tlv->pair_cipher = + wlan_cpu_to_le16(esupp->act_paircipher); + } + if (esupp->act_groupcipher) { + pcipher_tlv->group_cipher = + wlan_cpu_to_le16(esupp->act_groupcipher); + } + ptlv_buffer += + (pcipher_tlv->header.len + sizeof(MrvlIEtypesHeader_t)); + cmd->size += + (pcipher_tlv->header.len + sizeof(MrvlIEtypesHeader_t)); + pcipher_tlv->header.len = wlan_cpu_to_le16(pcipher_tlv->header.len); + } + } + cmd->size = wlan_cpu_to_le16(cmd->size); LEAVE(); return MLAN_STATUS_SUCCESS; } @@ -1113,7 +1180,8 @@ wlan_cmd_mgmt_ie_list(IN pmlan_private pmpriv, } cmd->size -= - (MAX_MGMT_IE_INDEX * sizeof(custom_ie)) + sizeof(tlvbuf_max_mgmt_ie); + (MAX_MGMT_IE_INDEX_TO_FW * sizeof(custom_ie)) + + sizeof(tlvbuf_max_mgmt_ie); cmd->size += cust_ie->len; cmd->size = wlan_cpu_to_le16(cmd->size); @@ -1460,6 +1528,42 @@ wlan_cmd_subscribe_event(IN pmlan_private pmpriv, } /** + * @brief This function prepares command of OTP user data. + * + * @param pmpriv A pointer to mlan_private structure + * @param cmd A pointer to HostCmd_DS_COMMAND structure + * @param cmd_action the action: GET or SET + * @param pdata_buf A pointer to data buffer + * @return MLAN_STATUS_SUCCESS + */ +static mlan_status +wlan_cmd_otp_user_data(IN pmlan_private pmpriv, + IN HostCmd_DS_COMMAND * cmd, + IN t_u16 cmd_action, IN t_void * pdata_buf) +{ + mlan_ds_misc_otp_user_data *user_data = + (mlan_ds_misc_otp_user_data *) pdata_buf; + HostCmd_DS_OTP_USER_DATA *cmd_user_data = + (HostCmd_DS_OTP_USER_DATA *) & cmd->params.otp_user_data; + t_u16 cmd_size = 0; + + ENTER(); + + cmd->command = wlan_cpu_to_le16(HostCmd_CMD_OTP_READ_USER_DATA); + cmd_size = sizeof(HostCmd_DS_OTP_USER_DATA) + S_DS_GEN - 1; + + cmd_user_data->action = wlan_cpu_to_le16(cmd_action); + cmd_user_data->reserved = 0; + cmd_user_data->user_data_length = + wlan_cpu_to_le16(user_data->user_data_length); + cmd_size += user_data->user_data_length; + cmd->size = wlan_cpu_to_le16(cmd_size); + + LEAVE(); + return MLAN_STATUS_SUCCESS; +} + +/** * @brief This function prepares inactivity timeout command * * @param cmd A pointer to HostCmd_DS_COMMAND structure @@ -1679,7 +1783,8 @@ wlan_ops_sta_prepare_cmd(IN t_void * priv, pdata_buf); break; case HostCmd_CMD_SUPPLICANT_PROFILE: - ret = wlan_cmd_802_11_supplicant_profile(pmpriv, cmd_ptr, cmd_action); + ret = wlan_cmd_802_11_supplicant_profile(pmpriv, cmd_ptr, cmd_action, + pdata_buf); break; case HostCmd_CMD_802_11D_DOMAIN_INFO: @@ -1786,6 +1891,9 @@ wlan_ops_sta_prepare_cmd(IN t_void * priv, case HostCmd_CMD_802_11_SUBSCRIBE_EVENT: ret = wlan_cmd_subscribe_event(pmpriv, cmd_ptr, cmd_action, pdata_buf); break; + case HostCmd_CMD_OTP_READ_USER_DATA: + ret = wlan_cmd_otp_user_data(pmpriv, cmd_ptr, cmd_action, pdata_buf); + break; default: PRINTM(MERROR, "PREP_CMD: unknown command- %#x\n", cmd_no); ret = MLAN_STATUS_FAILURE; diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sta_cmdresp.c b/drivers/net/wireless/sd8797/mlan/mlan_sta_cmdresp.c index be56a16615b9..086d16ae5a62 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_sta_cmdresp.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_sta_cmdresp.c @@ -3,7 +3,7 @@ * @brief This file contains the handling of command * responses generated by firmware. * - * Copyright (C) 2008-2011, Marvell International Ltd. + * Copyright (C) 2008-2012, Marvell International Ltd. * * This software file (the "File") is distributed by Marvell International * Ltd. under the terms of the GNU General Public License Version 2, June 1991 @@ -231,6 +231,12 @@ wlan_ret_802_11_snmp_mib(IN pmlan_private pmpriv, wlan_le16_to_cpu(psmib->buf_size)); if (query_type == HostCmd_ACT_GEN_GET) { switch (oid) { + case DtimPeriod_i: + ul_temp = psmib->value[0]; + PRINTM(MINFO, "SNMP_RESP: DTIM Period =%u\n", ul_temp); + if (mib) + mib->param.dtim_period = ul_temp; + break; case FragThresh_i: ul_temp = wlan_le16_to_cpu(*((t_u16 *) (psmib->value))); PRINTM(MINFO, "SNMP_RESP: FragThsd =%u\n", ul_temp); @@ -765,6 +771,7 @@ wlan_ret_802_11_key_material(IN pmlan_private pmpriv, IN mlan_ioctl_req * pioctl_buf) { HostCmd_DS_802_11_KEY_MATERIAL *pkey = &resp->params.key_material; + mlan_ds_sec_cfg *sec = MNULL; ENTER(); @@ -780,8 +787,50 @@ wlan_ret_802_11_key_material(IN pmlan_private pmpriv, } pmpriv->scan_block = MFALSE; } + } else { + if (pioctl_buf && + (wlan_le16_to_cpu(pkey->key_param_set.type) == + TLV_TYPE_KEY_MATERIAL)) { + PRINTM(MIOCTL, "key_type_id=%d, key_len=%d, key_info=0x%x\n", + wlan_le16_to_cpu(pkey->key_param_set.key_type_id), + wlan_le16_to_cpu(pkey->key_param_set.key_len), + wlan_le16_to_cpu(pkey->key_param_set.key_info)); + sec = (mlan_ds_sec_cfg *) pioctl_buf->pbuf; +#define WAPI_KEY_SIZE 32 + switch (wlan_le16_to_cpu(pkey->key_param_set.key_type_id)) { + case KEY_TYPE_ID_WEP: + sec->param.encrypt_key.key_index = pkey->key_param_set.key[0]; + sec->param.encrypt_key.key_len = + wlan_le16_to_cpu(pkey->key_param_set.key_len); + memcpy(pmpriv->adapter, sec->param.encrypt_key.key_material, + &pkey->key_param_set.key[2], + sec->param.encrypt_key.key_len); + break; + case KEY_TYPE_ID_TKIP: + sec->param.encrypt_key.key_len = + wlan_le16_to_cpu(pkey->key_param_set.key_len); + memcpy(pmpriv->adapter, sec->param.encrypt_key.key_material, + pkey->key_param_set.key, sec->param.encrypt_key.key_len); + break; + case KEY_TYPE_ID_AES: + sec->param.encrypt_key.key_len = + wlan_le16_to_cpu(pkey->key_param_set.key_len); + memcpy(pmpriv->adapter, sec->param.encrypt_key.key_material, + pkey->key_param_set.key, sec->param.encrypt_key.key_len); + break; + case KEY_TYPE_ID_WAPI: + sec->param.encrypt_key.is_wapi_key = MTRUE; + sec->param.encrypt_key.key_index = pkey->key_param_set.key[0]; + sec->param.encrypt_key.key_len = WAPI_KEY_SIZE; + memcpy(pmpriv->adapter, sec->param.encrypt_key.key_material, + &pkey->key_param_set.key[2], + sec->param.encrypt_key.key_len); + memcpy(pmpriv->adapter, sec->param.encrypt_key.pn, + &pkey->key_param_set.key[2 + WAPI_KEY_SIZE], PN_SIZE); + break; + } + } } - LEAVE(); return MLAN_STATUS_SUCCESS; } @@ -1374,6 +1423,41 @@ wlan_ret_subscribe_event(IN pmlan_private pmpriv, return MLAN_STATUS_SUCCESS; } +/** + * @brief This function handles the command response of + * OTP user data + * + * @param pmpriv A pointer to mlan_private structure + * @param resp A pointer to HostCmd_DS_COMMAND + * @param pioctl_buf A pointer to command buffer + * + * @return MLAN_STATUS_SUCCESS + */ +static mlan_status +wlan_ret_otp_user_data(IN pmlan_private pmpriv, + IN HostCmd_DS_COMMAND * resp, + IN mlan_ioctl_req * pioctl_buf) +{ + + HostCmd_DS_OTP_USER_DATA *cmd_user_data = + (HostCmd_DS_OTP_USER_DATA *) & resp->params.otp_user_data; + mlan_ds_misc_otp_user_data *user_data = MNULL; + + ENTER(); + if (pioctl_buf && (pioctl_buf->action == MLAN_ACT_GET)) { + user_data = (mlan_ds_misc_otp_user_data *) pioctl_buf->pbuf; + user_data->user_data_length = MIN(MAX_OTP_USER_DATA_LEN, + wlan_le16_to_cpu(cmd_user_data-> + user_data_length)); + memcpy(pmpriv->adapter, user_data->user_data, cmd_user_data->user_data, + user_data->user_data_length); + pioctl_buf->data_read_written = + sizeof(mlan_ds_misc_otp_user_data) + user_data->user_data_length; + } + LEAVE(); + return MLAN_STATUS_SUCCESS; +} + /******************************************************** Global Functions ********************************************************/ @@ -1442,8 +1526,7 @@ wlan_ops_sta_process_cmdresp(IN t_void * priv, ret = wlan_ret_bgscan_config(pmpriv, resp, pioctl_buf); break; case HostCmd_CMD_802_11_BG_SCAN_QUERY: - ret = wlan_ret_802_11_scan(pmpriv, resp, pioctl_buf); - wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BG_SCAN, MNULL); + ret = wlan_ret_802_11_bgscan_query(pmpriv, resp, pioctl_buf); PRINTM(MINFO, "CMD_RESP: BG_SCAN result is ready!\n"); break; case HostCmd_CMD_TXPWR_CFG: @@ -1629,6 +1712,9 @@ wlan_ops_sta_process_cmdresp(IN t_void * priv, case HostCmd_CMD_802_11_SUBSCRIBE_EVENT: ret = wlan_ret_subscribe_event(pmpriv, resp, pioctl_buf); break; + case HostCmd_CMD_OTP_READ_USER_DATA: + ret = wlan_ret_otp_user_data(pmpriv, resp, pioctl_buf); + break; default: PRINTM(MERROR, "CMD_RESP: Unknown command response %#x\n", resp->command); diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sta_event.c b/drivers/net/wireless/sd8797/mlan/mlan_sta_event.c index f638241f9632..1ad77818995f 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_sta_event.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_sta_event.c @@ -341,14 +341,8 @@ wlan_ops_sta_process_event(IN t_void * priv) case EVENT_BG_SCAN_REPORT: PRINTM(MEVENT, "EVENT: BGS_REPORT\n"); - /* Clear the previous scan result */ - memset(pmadapter, pmadapter->pscan_table, 0x00, - sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST); - pmadapter->num_in_scan_table = 0; - pmadapter->pbcn_buf_end = pmadapter->bcn_buf; - ret = wlan_prepare_cmd(pmpriv, - HostCmd_CMD_802_11_BG_SCAN_QUERY, - HostCmd_ACT_GEN_GET, 0, MNULL, MNULL); + pmadapter->bgscan_reported = MTRUE; + wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BG_SCAN, MNULL); break; case EVENT_PORT_RELEASE: diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sta_ioctl.c b/drivers/net/wireless/sd8797/mlan/mlan_sta_ioctl.c index 72dd525ca4af..eb715cb804c8 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_sta_ioctl.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_sta_ioctl.c @@ -222,6 +222,9 @@ wlan_get_info_bss_info(IN pmlan_adapter pmadapter, /* Channel */ info->param.bss_info.bss_chan = pbss_desc->channel; + /* Beacon interval */ + info->param.bss_info.beacon_interval = pbss_desc->beacon_period; + /* Band */ info->param.bss_info.bss_band = (t_u8) pbss_desc->bss_band; @@ -396,6 +399,10 @@ wlan_snmp_mib_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req) value = mib->param.retry_count; cmd_oid = ShortRetryLim_i; break; + case MLAN_OID_SNMP_MIB_DTIM_PERIOD: + value = mib->param.dtim_period; + cmd_oid = DtimPeriod_i; + break; } /* Send request to firmware */ @@ -509,6 +516,7 @@ wlan_radio_ioctl_band_cfg(IN pmlan_adapter pmadapter, } pmpriv->adhoc_channel = (t_u8) adhoc_channel; } + if ((adhoc_band & BAND_GN) || (adhoc_band & BAND_AN) ) { @@ -993,6 +1001,7 @@ wlan_bss_ioctl_start(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req) CLOSED state */ if (pmpriv->port_ctrl_mode == MTRUE) { PRINTM(MINFO, "bss_ioctl_start(): port_state=CLOSED\n"); + pmpriv->prior_port_status = pmpriv->port_open; pmpriv->port_open = MFALSE; } pmpriv->scan_block = MFALSE; @@ -1437,7 +1446,7 @@ wlan_rate_ioctl_get_supported_rate(IN pmlan_adapter pmadapter, else wlan_get_active_data_rates(pmpriv, pmpriv->bss_mode, (pmpriv->bss_mode == MLAN_BSS_MODE_INFRA) ? - pmadapter->config_bands : pmadapter-> + pmpriv->config_bands : pmadapter-> adhoc_start_band, rate->param.rates); pioctl_req->data_read_written = MLAN_SUPPORTED_RATES + MLAN_SUB_COMMAND_SIZE; @@ -3306,20 +3315,61 @@ wlan_sec_ioctl_esupp_mode(IN pmlan_adapter pmadapter, { mlan_status ret = MLAN_STATUS_SUCCESS; mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; + t_u16 cmd_action = 0; + mlan_ds_sec_cfg *sec = MNULL; ENTER(); - if (pmpriv->media_connected != MTRUE) { - pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID; - ret = MLAN_STATUS_FAILURE; - goto exit; + sec = (mlan_ds_sec_cfg *) pioctl_req->pbuf; + if (pioctl_req->action == MLAN_ACT_SET) { + cmd_action = HostCmd_ACT_GEN_SET; + if (pmpriv->media_connected == MTRUE) { + PRINTM(MERROR, + "Cannot set esupplicant mode configuration while connected.\n"); + pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID; + ret = MLAN_STATUS_FAILURE; + goto exit; + } + if (!sec->param.esupp_mode.rsn_mode || + (sec->param.esupp_mode.rsn_mode & RSN_TYPE_VALID_BITS) + != sec->param.esupp_mode.rsn_mode) { + PRINTM(MERROR, "Invalid RSN mode\n"); + pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID; + ret = MLAN_STATUS_FAILURE; + goto exit; + } + if (!sec->param.esupp_mode.act_paircipher || + (sec->param.esupp_mode.act_paircipher & EMBED_CIPHER_VALID_BITS) + != sec->param.esupp_mode.act_paircipher) { + PRINTM(MERROR, "Invalid pairwise cipher\n"); + pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID; + ret = MLAN_STATUS_FAILURE; + goto exit; + } + if (!sec->param.esupp_mode.act_groupcipher || + (sec->param.esupp_mode.act_groupcipher & EMBED_CIPHER_VALID_BITS) + != sec->param.esupp_mode.act_groupcipher) { + PRINTM(MERROR, "Invalid group cipher\n"); + pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID; + ret = MLAN_STATUS_FAILURE; + goto exit; + } + } else { + cmd_action = HostCmd_ACT_GEN_GET_CURRENT; } /* Send request to firmware */ - ret = wlan_prepare_cmd(pmpriv, - HostCmd_CMD_SUPPLICANT_PROFILE, - HostCmd_ACT_GEN_GET_CURRENT, - 0, (t_void *) pioctl_req, MNULL); + if (sec) { + ret = wlan_prepare_cmd(pmpriv, + HostCmd_CMD_SUPPLICANT_PROFILE, + cmd_action, + 0, + (t_void *) pioctl_req, &sec->param.esupp_mode); + } else { + ret = wlan_prepare_cmd(pmpriv, + HostCmd_CMD_SUPPLICANT_PROFILE, + cmd_action, 0, (t_void *) pioctl_req, MNULL); + } if (ret == MLAN_STATUS_SUCCESS) ret = MLAN_STATUS_PENDING; @@ -4137,6 +4187,8 @@ wlan_misc_ioctl_region(IN pmlan_adapter pmadapter, LEAVE(); return MLAN_STATUS_FAILURE; } + pmadapter->cfp_code_bg = misc->param.region_code; + pmadapter->cfp_code_a = misc->param.region_code; if (wlan_set_regiontable(pmpriv, (t_u8) pmadapter->region_code, pmadapter->config_bands | pmadapter-> adhoc_start_band)) { @@ -4827,6 +4879,158 @@ wlan_misc_ioctl_ipaddr_cfg(IN pmlan_adapter pmadapter, } /** + * @brief CFP code configuration + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req A pointer to ioctl request buffer + * + * @return MLAN_STATUS_PENDING --success, otherwise fail + */ +mlan_status +wlan_misc_ioctl_cfp_code_cfg(IN pmlan_adapter pmadapter, + IN pmlan_ioctl_req pioctl_req) +{ + mlan_status ret = MLAN_STATUS_SUCCESS; + mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; + mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf; + mlan_ds_misc_cfp_code *cfp_code = MNULL; + t_u32 region_bg = 0; + t_u32 region_a = 0; + int i; + + ENTER(); + + cfp_code = &misc->param.cfp_code; + if (pioctl_req->action == MLAN_ACT_SET) { + /* Save the values in MLAN */ + if (!cfp_code->cfp_code_bg) + cfp_code->cfp_code_bg = pmadapter->cfp_code_bg; + for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { + /* Use the region code to search for the index */ + if (cfp_code->cfp_code_bg == region_code_index[i]) { + region_bg = cfp_code->cfp_code_bg; + break; + } + } + if (!region_bg) { + for (i = 0; i < MRVDRV_MAX_CFP_CODE_BG; i++) { + /* Use the CFP code to search for the index */ + if (cfp_code->cfp_code_bg == cfp_code_index_bg[i]) + break; + } + if (i >= MRVDRV_MAX_CFP_CODE_BG) { + PRINTM(MERROR, "CFP Code not identified for BG\n"); + pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER; + ret = MLAN_STATUS_FAILURE; + goto done; + } + } + if (!cfp_code->cfp_code_a) + cfp_code->cfp_code_a = pmadapter->cfp_code_a; + for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { + /* Use the region code to search for the index */ + if (cfp_code->cfp_code_a == region_code_index[i]) { + region_a = cfp_code->cfp_code_a; + break; + } + } + if (!region_a) { + for (i = 0; i < MRVDRV_MAX_CFP_CODE_A; i++) { + /* Use the CFP code to search for the index */ + if (cfp_code->cfp_code_a == cfp_code_index_a[i]) + break; + } + if (i >= MRVDRV_MAX_CFP_CODE_A) { + PRINTM(MERROR, "CFP Code not identified for A\n"); + pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER; + ret = MLAN_STATUS_FAILURE; + goto done; + } + } + pmadapter->cfp_code_bg = (t_u8) cfp_code->cfp_code_bg; + pmadapter->cfp_code_a = (t_u8) cfp_code->cfp_code_a; + if (region_bg && region_a && (region_bg == region_a)) + pmadapter->region_code = pmadapter->cfp_code_a; + else + pmadapter->region_code = 0; + if (wlan_set_regiontable(pmpriv, (t_u8) pmadapter->region_code, + pmadapter->config_bands | pmadapter-> + adhoc_start_band)) { + pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER; + ret = MLAN_STATUS_FAILURE; + goto done; + } + } else { + /* GET operation */ + cfp_code->cfp_code_bg = pmadapter->cfp_code_bg; + cfp_code->cfp_code_a = pmadapter->cfp_code_a; + } + + done: + LEAVE(); + return ret; +} + +/** + * @brief This function sets up country code and downloads CMD to FW + * + * @param pmadapter A pointer to mlan_adapter structure + * @param pioctl_req Pointer to the IOCTL request buffer + * + * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE + */ +mlan_status +wlan_misc_ioctl_country_code(IN pmlan_adapter pmadapter, + IN mlan_ioctl_req * pioctl_req) +{ + mlan_status ret = MLAN_STATUS_SUCCESS; + mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; + mlan_ds_misc_country_code *country_code = MNULL; + mlan_ds_misc_cfg *cfg_misc = MNULL; + t_u8 cfp_bg = 0, cfp_a = 0; + + ENTER(); + + cfg_misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf; + country_code = &cfg_misc->param.country_code; + + if (pioctl_req->action == MLAN_ACT_SET) { + /* Update region code and table based on country code */ + if (wlan_misc_country_2_cfp_table_code(pmadapter, + country_code->country_code, + &cfp_bg, &cfp_a)) { + PRINTM(MERROR, "Country code not found!\n"); + pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER; + ret = MLAN_STATUS_FAILURE; + goto done; + } + pmadapter->cfp_code_bg = cfp_bg; + pmadapter->cfp_code_a = cfp_a; + if (cfp_bg && cfp_a && (cfp_bg == cfp_a)) + pmadapter->region_code = cfp_a; + else + pmadapter->region_code = 0; + if (wlan_set_regiontable(pmpriv, pmadapter->region_code, + pmadapter->config_bands | pmadapter-> + adhoc_start_band)) { + pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER; + ret = MLAN_STATUS_FAILURE; + goto done; + } + memcpy(pmadapter, pmadapter->country_code, + country_code->country_code, COUNTRY_CODE_LEN); + } else { + /* GET operation */ + memcpy(pmadapter, country_code->country_code, + pmadapter->country_code, COUNTRY_CODE_LEN); + } + + done: + LEAVE(); + return ret; +} + +/** * @brief Miscellaneous configuration handler * * @param pmadapter A pointer to mlan_adapter structure @@ -4906,12 +5110,21 @@ wlan_misc_cfg_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req) case MLAN_OID_MISC_IP_ADDR: status = wlan_misc_ioctl_ipaddr_cfg(pmadapter, pioctl_req); break; + case MLAN_OID_MISC_CFP_CODE: + status = wlan_misc_ioctl_cfp_code_cfg(pmadapter, pioctl_req); + break; + case MLAN_OID_MISC_COUNTRY_CODE: + status = wlan_misc_ioctl_country_code(pmadapter, pioctl_req); + break; case MLAN_OID_MISC_THERMAL: status = wlan_misc_ioctl_thermal(pmadapter, pioctl_req); break; case MLAN_OID_MISC_SUBSCRIBE_EVENT: status = wlan_misc_ioctl_subscribe_evt(pmadapter, pioctl_req); break; + case MLAN_OID_MISC_OTP_USER_DATA: + status = wlan_misc_otp_user_data(pmadapter, pioctl_req); + break; default: if (pioctl_req) pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID; @@ -5070,13 +5283,31 @@ wlan_scan_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req) pioctl_req->data_read_written = sizeof(mlan_scan_resp) + MLAN_SUB_COMMAND_SIZE; } else { - pscan->param.scan_resp.pscan_table = - (t_u8 *) pmadapter->pscan_table; - pscan->param.scan_resp.num_in_scan_table = - pmadapter->num_in_scan_table; - pscan->param.scan_resp.age_in_secs = pmadapter->age_in_secs; - pioctl_req->data_read_written = sizeof(mlan_scan_resp) + - MLAN_SUB_COMMAND_SIZE; + if (pmadapter->bgscan_reported) { + pmadapter->bgscan_reported = MFALSE; + /* Clear the previous scan result */ + memset(pmadapter, pmadapter->pscan_table, 0x00, + sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST); + pmadapter->num_in_scan_table = 0; + pmadapter->pbcn_buf_end = pmadapter->bcn_buf; + status = wlan_prepare_cmd(pmpriv, + HostCmd_CMD_802_11_BG_SCAN_QUERY, + HostCmd_ACT_GEN_GET, + 0, (t_void *) pioctl_req, MNULL); + if (status == MLAN_STATUS_SUCCESS) { + PRINTM(MINFO, + "wlan_scan_ioctl: return MLAN_STATUS_PENDING\n"); + status = MLAN_STATUS_PENDING; + } + } else { + pscan->param.scan_resp.pscan_table = + (t_u8 *) pmadapter->pscan_table; + pscan->param.scan_resp.num_in_scan_table = + pmadapter->num_in_scan_table; + pscan->param.scan_resp.age_in_secs = pmadapter->age_in_secs; + pioctl_req->data_read_written = sizeof(mlan_scan_resp) + + MLAN_SUB_COMMAND_SIZE; + } } } @@ -5198,6 +5429,7 @@ wlan_ops_sta_ioctl(t_void * adapter, pmlan_ioctl_req pioctl_req) mlan_status status = MLAN_STATUS_SUCCESS; ENTER(); + switch (pioctl_req->req_id) { case MLAN_IOCTL_SCAN: status = wlan_scan_ioctl(pmadapter, pioctl_req); diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sta_rx.c b/drivers/net/wireless/sd8797/mlan/mlan_sta_rx.c index 2ad9a810afcf..5e5c68e2a108 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_sta_rx.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_sta_rx.c @@ -2,7 +2,7 @@ * * @brief This file contains the handling of RX in MLAN * module. - * + * * Copyright (C) 2008-2011, Marvell International Ltd. * * This software file (the "File") is distributed by Marvell International @@ -59,6 +59,7 @@ typedef struct /******************************************************** Global functions ********************************************************/ + /** * @brief This function processes received packet and forwards it * to kernel/upper layer @@ -174,6 +175,7 @@ wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf) PRINTM(MDATA, "%lu.%06lu : Data => kernel seq_num=%d tid=%d\n", pmbuf->out_ts_sec, pmbuf->out_ts_usec, prx_pd->seq_num, prx_pd->priority); + ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle, pmbuf); if (ret == MLAN_STATUS_FAILURE) { pmbuf->status_code = MLAN_ERROR_PKT_INVALID; diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sta_tx.c b/drivers/net/wireless/sd8797/mlan/mlan_sta_tx.c index 06c1a4de064e..2258853a4089 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_sta_tx.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_sta_tx.c @@ -166,7 +166,9 @@ wlan_send_null_packet(pmlan_private priv, t_u8 flags) pmlan_buffer pmbuf = MNULL; t_u8 *ptr; mlan_status ret = MLAN_STATUS_SUCCESS; +#ifdef DEBUG_LEVEL1 t_u32 sec, usec; +#endif ENTER(); @@ -228,8 +230,7 @@ wlan_send_null_packet(pmlan_private priv, t_u8 flags) break; } - pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle, &sec, - &usec); + PRINTM_GET_SYS_TIME(MDATA, &sec, &usec); PRINTM(MDATA, "%lu.%06lu : Null data => FW\n", sec, usec); DBG_HEXDUMP(MDAT_D, "Null data", ptr, sizeof(TxPD) + INTF_HEADER_LEN); done: diff --git a/drivers/net/wireless/sd8797/mlan/mlan_txrx.c b/drivers/net/wireless/sd8797/mlan/mlan_txrx.c index e15dd14f0443..93dea9e284f8 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_txrx.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_txrx.c @@ -63,7 +63,9 @@ wlan_handle_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf) mlan_status ret = MLAN_STATUS_SUCCESS; pmlan_private priv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY); RxPD *prx_pd; +#ifdef DEBUG_LEVEL1 t_u32 sec, usec; +#endif ENTER(); @@ -75,8 +77,7 @@ wlan_handle_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf) if (!priv) priv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY); pmbuf->bss_index = priv->bss_index; - pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle, &sec, - &usec); + PRINTM_GET_SYS_TIME(MDATA, &sec, &usec); PRINTM_NETINTF(MDATA, priv); PRINTM(MDATA, "%lu.%06lu : Data <= FW\n", sec, usec); ret = priv->ops.process_rx_packet(pmadapter, pmbuf); @@ -101,7 +102,9 @@ wlan_process_tx(pmlan_private priv, pmlan_buffer pmbuf, mlan_status ret = MLAN_STATUS_SUCCESS; pmlan_adapter pmadapter = priv->adapter; t_u8 *head_ptr = MNULL; +#ifdef DEBUG_LEVEL1 t_u32 sec, usec; +#endif #ifdef STA_SUPPORT TxPD *plocal_tx_pd = MNULL; #endif @@ -153,8 +156,7 @@ wlan_process_tx(pmlan_private priv, pmlan_buffer pmbuf, } if ((ret == MLAN_STATUS_SUCCESS) || (ret == MLAN_STATUS_PENDING)) { - pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle, &sec, - &usec); + PRINTM_GET_SYS_TIME(MDATA, &sec, &usec); PRINTM_NETINTF(MDATA, priv); PRINTM(MDATA, "%lu.%06lu : Data => FW\n", sec, usec); } diff --git a/drivers/net/wireless/sd8797/mlan/mlan_uap_cmdevent.c b/drivers/net/wireless/sd8797/mlan/mlan_uap_cmdevent.c index ed79dcfaaf68..7d7d5510433c 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_uap_cmdevent.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_uap_cmdevent.c @@ -3,7 +3,7 @@ * @brief This file contains the handling of AP mode command and event * * Copyright (C) 2009-2011, Marvell International Ltd. - * + * * This software file (the "File") is distributed by Marvell International * Ltd. under the terms of the GNU General Public License Version 2, June 1991 * (the "License"). You may use, redistribute and/or modify this File in diff --git a/drivers/net/wireless/sd8797/mlan/mlan_uap_ioctl.c b/drivers/net/wireless/sd8797/mlan/mlan_uap_ioctl.c index 5081d9e4aabc..f71a222f4f48 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_uap_ioctl.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_uap_ioctl.c @@ -3,7 +3,7 @@ * @brief This file contains the handling of AP mode ioctls * * Copyright (C) 2009-2011, Marvell International Ltd. - * + * * This software file (the "File") is distributed by Marvell International * Ltd. under the terms of the GNU General Public License Version 2, June 1991 * (the "License"). You may use, redistribute and/or modify this File in @@ -230,8 +230,8 @@ wlan_uap_bss_ioctl_reset(IN pmlan_adapter pmadapter, memset(pmadapter, &pmpriv->mgmt_ie[i], 0, sizeof(custom_ie)); } pmpriv->add_ba_param.timeout = MLAN_DEFAULT_BLOCK_ACK_TIMEOUT; - pmpriv->add_ba_param.tx_win_size = MLAN_AMPDU_DEF_TXWINSIZE; - pmpriv->add_ba_param.rx_win_size = MLAN_AMPDU_DEF_RXWINSIZE; + pmpriv->add_ba_param.tx_win_size = MLAN_UAP_AMPDU_DEF_TXWINSIZE; + pmpriv->add_ba_param.rx_win_size = MLAN_UAP_AMPDU_DEF_RXWINSIZE; for (i = 0; i < MAX_NUM_TID; i++) { pmpriv->aggr_prio_tbl[i].ampdu_user = tos_to_tid_inv[i]; pmpriv->aggr_prio_tbl[i].amsdu = BA_STREAM_NOT_ALLOWED; diff --git a/drivers/net/wireless/sd8797/mlan/mlan_uap_txrx.c b/drivers/net/wireless/sd8797/mlan/mlan_uap_txrx.c index 0abd1ecd1c2a..590def325f27 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_uap_txrx.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_uap_txrx.c @@ -3,7 +3,7 @@ * @brief This file contains AP mode transmit and receive functions * * Copyright (C) 2009-2011, Marvell International Ltd. - * + * * This software file (the "File") is distributed by Marvell International * Ltd. under the terms of the GNU General Public License Version 2, June 1991 * (the "License"). You may use, redistribute and/or modify this File in diff --git a/drivers/net/wireless/sd8797/mlan/mlan_wmm.c b/drivers/net/wireless/sd8797/mlan/mlan_wmm.c index d2c3227aca87..4b72c9193e27 100644 --- a/drivers/net/wireless/sd8797/mlan/mlan_wmm.c +++ b/drivers/net/wireless/sd8797/mlan/mlan_wmm.c @@ -946,8 +946,6 @@ wlan_dequeue_tx_packet(pmlan_adapter pmadapter) t_u8 ra[MLAN_MAC_ADDR_LENGTH]; int tid_del = 0; int tid = 0; - t_u8 avail_ports = 0; - int i; ENTER(); @@ -975,24 +973,6 @@ wlan_dequeue_tx_packet(pmlan_adapter pmadapter) if (tid >= MAX_NUM_TID) tid = wlan_wmm_downgrade_tid(priv, tid); - for (i = 1; i < pmadapter->mp_end_port; i++) { - if ((pmadapter->mp_wr_bitmap >> i) & 1) - avail_ports++; - } - - PRINTM(MINFO, - "mp_wr_bitmap=0x%08x avail_ports=%d tid=%d tx_eligibility[%d]=%d\n", - pmadapter->mp_wr_bitmap, avail_ports, - tid, tid, pmadapter->tx_eligibility[tid]); - - if (avail_ports < pmadapter->tx_eligibility[tid]) { - pmadapter->callbacks.moal_spin_unlock(pmadapter->pmoal_handle, - priv->wmm.ra_list_spinlock); - pmadapter->data_sent = MTRUE; - LEAVE(); - return MLAN_STATUS_FAILURE; - } - if (wlan_is_ptr_processed(priv, ptr)) { wlan_send_processed_packet(priv, ptr, ptrindex); LEAVE(); @@ -1407,8 +1387,22 @@ wlan_wmm_init(pmlan_adapter pmadapter) = priv->aggr_prio_tbl[7].ampdu_user = BA_STREAM_NOT_ALLOWED; priv->add_ba_param.timeout = MLAN_DEFAULT_BLOCK_ACK_TIMEOUT; - priv->add_ba_param.tx_win_size = MLAN_AMPDU_DEF_TXWINSIZE; - priv->add_ba_param.rx_win_size = MLAN_AMPDU_DEF_RXWINSIZE; +#ifdef STA_SUPPORT + if (priv->bss_type == MLAN_BSS_TYPE_STA) { + priv->add_ba_param.tx_win_size = MLAN_STA_AMPDU_DEF_TXWINSIZE; + priv->add_ba_param.rx_win_size = MLAN_STA_AMPDU_DEF_RXWINSIZE; + } +#endif +#ifdef UAP_SUPPORT + if (priv->bss_type == MLAN_BSS_TYPE_UAP +#ifdef WIFI_DIRECT_SUPPORT + || priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT +#endif + ) { + priv->add_ba_param.tx_win_size = MLAN_UAP_AMPDU_DEF_TXWINSIZE; + priv->add_ba_param.rx_win_size = MLAN_UAP_AMPDU_DEF_RXWINSIZE; + } +#endif priv->add_ba_param.tx_amsdu = MTRUE; priv->add_ba_param.rx_amsdu = MTRUE; memset(priv->adapter, priv->rx_seq, 0xff, sizeof(priv->rx_seq)); @@ -1885,8 +1879,7 @@ wlan_wmm_process_association_req(pmlan_private priv, if ((priv->wmm_required || (pHTCap && (pHTCap->ieee_hdr.element_id == HT_CAPABILITY) - && (priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN)) + && (priv->config_bands & BAND_GN || priv->config_bands & BAND_AN)) ) && pWmmIE->vend_hdr.element_id == WMM_IE) { pwmm_tlv = (MrvlIEtypes_WmmParamSet_t *) * ppAssocBuf; @@ -2015,14 +2008,12 @@ wlan_wmm_select_queue(mlan_private * pmpriv, t_u8 tid) * @param priv Pointer to the mlan_private driver data struct * @param ra_list_head ra list header * @param tid tid - * @param tx_pause tx_pause flag * * @return N/A */ static INLINE t_u8 wlan_del_tx_pkts_in_ralist(pmlan_private priv, - mlan_list_head * ra_list_head, - int tid, t_u8 tx_pause) + mlan_list_head * ra_list_head, int tid) { raListTbl *ra_list = MNULL; pmlan_adapter pmadapter = priv->adapter; @@ -2034,15 +2025,14 @@ wlan_del_tx_pkts_in_ralist(pmlan_private priv, MNULL, MNULL); while (ra_list && ra_list != (raListTbl *) ra_list_head) { if (ra_list->total_pkts && (ra_list->tx_pause || - (!tx_pause && - ra_list->total_pkts > RX_LOW_THRESHOLD))) { + (ra_list->total_pkts > RX_LOW_THRESHOLD))) { if ((pmbuf = (pmlan_buffer) util_dequeue_list(pmadapter->pmoal_handle, &ra_list->buf_head, MNULL, MNULL))) { PRINTM(MDATA, "Drop pkts: tid=%d tx_pause=%d pkts=%d brd_pkts=%d %02x:%02x:%02x:%02x:%02x:%02x\n", - tid, tx_pause, ra_list->total_pkts, + tid, ra_list->tx_pause, ra_list->total_pkts, pmadapter->pending_bridge_pkts, ra_list->ra[0], ra_list->ra[1], ra_list->ra[2], ra_list->ra[3], ra_list->ra[4], ra_list->ra[5]); @@ -2077,17 +2067,14 @@ wlan_drop_tx_pkts(pmlan_private priv) { int j; static int i = 0; - t_u8 tx_pause = 0; pmlan_adapter pmadapter = priv->adapter; pmadapter->callbacks.moal_spin_lock(pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock); - if (wlan_get_tx_pause_station_entry(priv)) - tx_pause = 1; for (j = 0; j < MAX_NUM_TID; j++, i++) { if (i == MAX_NUM_TID) i = 0; if (wlan_del_tx_pkts_in_ralist - (priv, &priv->wmm.tid_tbl_ptr[i].ra_list, i, tx_pause)) { + (priv, &priv->wmm.tid_tbl_ptr[i].ra_list, i)) { i++; break; } diff --git a/drivers/net/wireless/sd8797/mlinux/mlan.h b/drivers/net/wireless/sd8797/mlinux/mlan.h new file mode 100644 index 000000000000..a341e1547099 --- /dev/null +++ b/drivers/net/wireless/sd8797/mlinux/mlan.h @@ -0,0 +1,35 @@ +/** @file mlan.h + * + * @brief This file declares all APIs that will be called from MOAL module. + * It also defines the data structures used for APIs between MLAN and MOAL. + * + * Copyright (C) 2008-2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +/****************************************************** +Change log: + 10/13/2008: initial version + 11/07/2008: split mlan.h into mlan_decl.h & mlan_ioctl.h +******************************************************/ + +#ifndef _MLAN_H_ +#define _MLAN_H_ + +#include "mlan_decl.h" +#include "mlan_ioctl.h" +#include "mlan_ieee.h" + +#endif /* !_MLAN_H_ */ diff --git a/drivers/net/wireless/sd8797/mlinux/mlan_decl.h b/drivers/net/wireless/sd8797/mlinux/mlan_decl.h new file mode 100644 index 000000000000..41cf2bf5f2f1 --- /dev/null +++ b/drivers/net/wireless/sd8797/mlinux/mlan_decl.h @@ -0,0 +1,893 @@ +/** @file mlan_decl.h + * + * @brief This file declares the generic data structures and APIs. + * + * Copyright (C) 2008-2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +/****************************************************** +Change log: + 11/07/2008: initial version +******************************************************/ + +#ifndef _MLAN_DECL_H_ +#define _MLAN_DECL_H_ + +/** MLAN release version */ +#define MLAN_RELEASE_VERSION "311" + +/** Re-define generic data types for MLAN/MOAL */ +/** Signed char (1-byte) */ +typedef char t_s8; +/** Unsigned char (1-byte) */ +typedef unsigned char t_u8; +/** Signed short (2-bytes) */ +typedef short t_s16; +/** Unsigned short (2-bytes) */ +typedef unsigned short t_u16; +/** Signed long (4-bytes) */ +typedef int t_s32; +/** Unsigned long (4-bytes) */ +typedef unsigned int t_u32; +/** Signed long long 8-bytes) */ +typedef long long t_s64; +/** Unsigned long long 8-bytes) */ +typedef unsigned long long t_u64; +/** Void pointer (4-bytes) */ +typedef void t_void; +/** Size type */ +typedef t_u32 t_size; +/** Boolean type */ +typedef t_u8 t_bool; + +#ifdef MLAN_64BIT +/** Pointer type (64-bit) */ +typedef t_u64 t_ptr; +/** Signed value (64-bit) */ +typedef t_s64 t_sval; +#else +/** Pointer type (32-bit) */ +typedef t_u32 t_ptr; +/** Signed value (32-bit) */ +typedef t_s32 t_sval; +#endif + +/** Constants below */ + +#ifdef __GNUC__ +/** Structure packing begins */ +#define MLAN_PACK_START +/** Structure packeing end */ +#define MLAN_PACK_END __attribute__ ((packed)) +#else /* !__GNUC__ */ +#ifdef PRAGMA_PACK +/** Structure packing begins */ +#define MLAN_PACK_START +/** Structure packeing end */ +#define MLAN_PACK_END +#else /* !PRAGMA_PACK */ +/** Structure packing begins */ +#define MLAN_PACK_START __packed +/** Structure packing end */ +#define MLAN_PACK_END +#endif /* PRAGMA_PACK */ +#endif /* __GNUC__ */ + +#ifndef INLINE +#ifdef __GNUC__ +/** inline directive */ +#define INLINE inline +#else +/** inline directive */ +#define INLINE __inline +#endif +#endif + +/** MLAN TRUE */ +#define MTRUE (1) +/** MLAN FALSE */ +#define MFALSE (0) + +/** Macros for Data Alignment : size */ +#define ALIGN_SZ(p, a) \ + (((p) + ((a) - 1)) & ~((a) - 1)) + +/** Macros for Data Alignment : address */ +#define ALIGN_ADDR(p, a) \ + ((((t_ptr)(p)) + (((t_ptr)(a)) - 1)) & ~(((t_ptr)(a)) - 1)) + +/** Return the byte offset of a field in the given structure */ +#define MLAN_FIELD_OFFSET(type, field) ((t_u32)(t_ptr)&(((type *)0)->field)) +/** Return aligned offset */ +#define OFFSET_ALIGN_ADDR(p, a) (t_u32)(ALIGN_ADDR(p, a) - (t_ptr)p) + +/** Maximum BSS numbers */ +#define MLAN_MAX_BSS_NUM (16) + +/** NET IP alignment */ +#define MLAN_NET_IP_ALIGN 0 + +/** DMA alignment */ +#define DMA_ALIGNMENT 64 +/** max size of TxPD */ +#define MAX_TXPD_SIZE 32 + +/** Minimum data header length */ +#define MLAN_MIN_DATA_HEADER_LEN (DMA_ALIGNMENT+MAX_TXPD_SIZE) + +/** rx data header length */ +#define MLAN_RX_HEADER_LEN MLAN_MIN_DATA_HEADER_LEN + +/** This is current limit on Maximum Tx AMPDU allowed */ +#define MLAN_MAX_TX_BASTREAM_SUPPORTED 2 +/** This is current limit on Maximum Rx AMPDU allowed */ +#define MLAN_MAX_RX_BASTREAM_SUPPORTED 16 + +#ifdef STA_SUPPORT +/** Default Win size attached during ADDBA request */ +#define MLAN_STA_AMPDU_DEF_TXWINSIZE 16 +/** Default Win size attached during ADDBA response */ +#define MLAN_STA_AMPDU_DEF_RXWINSIZE 32 +#endif /* STA_SUPPORT */ +#ifdef UAP_SUPPORT +/** Default Win size attached during ADDBA request */ +#define MLAN_UAP_AMPDU_DEF_TXWINSIZE 32 +/** Default Win size attached during ADDBA response */ +#define MLAN_UAP_AMPDU_DEF_RXWINSIZE 16 +#endif /* UAP_SUPPORT */ +/** Block ack timeout value */ +#define MLAN_DEFAULT_BLOCK_ACK_TIMEOUT 0xffff +/** Maximum Tx Win size configured for ADDBA request [10 bits] */ +#define MLAN_AMPDU_MAX_TXWINSIZE 0x3ff +/** Maximum Rx Win size configured for ADDBA request [10 bits] */ +#define MLAN_AMPDU_MAX_RXWINSIZE 0x3ff + +/** Rate index for HR/DSSS 0 */ +#define MLAN_RATE_INDEX_HRDSSS0 0 +/** Rate index for HR/DSSS 3 */ +#define MLAN_RATE_INDEX_HRDSSS3 3 +/** Rate index for OFDM 0 */ +#define MLAN_RATE_INDEX_OFDM0 4 +/** Rate index for OFDM 7 */ +#define MLAN_RATE_INDEX_OFDM7 11 +/** Rate index for MCS 0 */ +#define MLAN_RATE_INDEX_MCS0 12 +/** Rate index for MCS 7 */ +#define MLAN_RATE_INDEX_MCS7 19 +/** Rate index for MCS 9 */ +#define MLAN_RATE_INDEX_MCS9 21 +/** Rate index for MCS15 */ +#define MLAN_RATE_INDEX_MCS15 27 +/** Rate index for MCS 32 */ +#define MLAN_RATE_INDEX_MCS32 44 +/** Rate index for MCS 127 */ +#define MLAN_RATE_INDEX_MCS127 139 + +/** Rate bitmap for OFDM 0 */ +#define MLAN_RATE_BITMAP_OFDM0 16 +/** Rate bitmap for OFDM 7 */ +#define MLAN_RATE_BITMAP_OFDM7 23 +/** Rate bitmap for MCS 0 */ +#define MLAN_RATE_BITMAP_MCS0 32 +/** Rate bitmap for MCS 127 */ +#define MLAN_RATE_BITMAP_MCS127 159 + +/** Size of rx data buffer */ +#define MLAN_RX_DATA_BUF_SIZE (4 * 1024) +/** Size of rx command buffer */ +#define MLAN_RX_CMD_BUF_SIZE (2 * 1024) + +/** MLAN MAC Address Length */ +#define MLAN_MAC_ADDR_LENGTH (6) +/** MLAN 802.11 MAC Address */ +typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH]; + +/** MLAN Maximum SSID Length */ +#define MLAN_MAX_SSID_LENGTH (32) + +/** RTS/FRAG related defines */ +/** Minimum RTS value */ +#define MLAN_RTS_MIN_VALUE (0) +/** Maximum RTS value */ +#define MLAN_RTS_MAX_VALUE (2347) +/** Minimum FRAG value */ +#define MLAN_FRAG_MIN_VALUE (256) +/** Maximum FRAG value */ +#define MLAN_FRAG_MAX_VALUE (2346) + +/** Minimum tx retry count */ +#define MLAN_TX_RETRY_MIN (0) +/** Maximum tx retry count */ +#define MLAN_TX_RETRY_MAX (14) + +/** define SDIO block size for data Tx/Rx */ +/* We support up to 480-byte block size due to FW buffer limitation. */ +#define MLAN_SDIO_BLOCK_SIZE 256 + +/** define SDIO block size for firmware download */ +#define MLAN_SDIO_BLOCK_SIZE_FW_DNLD MLAN_SDIO_BLOCK_SIZE + +/** define allocated buffer size */ +#define ALLOC_BUF_SIZE (4 * 1024) + +/** SDIO IO Port mask */ +#define MLAN_SDIO_IO_PORT_MASK 0xfffff +/** SDIO Block/Byte mode mask */ +#define MLAN_SDIO_BYTE_MODE_MASK 0x80000000 + +/** Max retry number of IO write */ +#define MAX_WRITE_IOMEM_RETRY 2 + +/** IN parameter */ +#define IN +/** OUT parameter */ +#define OUT + +/** BIT value */ +#define MBIT(x) (((t_u32)1) << (x)) + +/** Buffer flag for requeued packet */ +#define MLAN_BUF_FLAG_REQUEUED_PKT MBIT(0) +/** Buffer flag for transmit buf from moal */ +#define MLAN_BUF_FLAG_MOAL_TX_BUF MBIT(1) +/** Buffer flag for malloc mlan_buffer */ +#define MLAN_BUF_FLAG_MALLOC_BUF MBIT(2) + +/** Buffer flag for bridge packet */ +#define MLAN_BUF_FLAG_BRIDGE_BUF MBIT(3) + +#ifdef DEBUG_LEVEL1 +/** Debug level bit definition */ +#define MMSG MBIT(0) +#define MFATAL MBIT(1) +#define MERROR MBIT(2) +#define MDATA MBIT(3) +#define MCMND MBIT(4) +#define MEVENT MBIT(5) +#define MINTR MBIT(6) +#define MIOCTL MBIT(7) + +#define MDAT_D MBIT(16) +#define MCMD_D MBIT(17) +#define MEVT_D MBIT(18) +#define MFW_D MBIT(19) +#define MIF_D MBIT(20) + +#define MENTRY MBIT(28) +#define MWARN MBIT(29) +#define MINFO MBIT(30) +#define MHEX_DUMP MBIT(31) +#endif /* DEBUG_LEVEL1 */ + +/** Memory allocation type: DMA */ +#define MLAN_MEM_DMA MBIT(0) + +/** Default memory allocation flag */ +#define MLAN_MEM_DEF 0 + +/** mlan_status */ +typedef enum _mlan_status +{ + MLAN_STATUS_FAILURE = 0xffffffff, + MLAN_STATUS_SUCCESS = 0, + MLAN_STATUS_PENDING, + MLAN_STATUS_RESOURCE, +} mlan_status; + +/** mlan_error_code */ +typedef enum _mlan_error_code +{ + /** No error */ + MLAN_ERROR_NO_ERROR = 0, + /** Firmware/device errors below (MSB=0) */ + MLAN_ERROR_FW_NOT_READY = 0x00000001, + MLAN_ERROR_FW_BUSY, + MLAN_ERROR_FW_CMDRESP, + MLAN_ERROR_DATA_TX_FAIL, + MLAN_ERROR_DATA_RX_FAIL, + /** Driver errors below (MSB=1) */ + MLAN_ERROR_PKT_SIZE_INVALID = 0x80000001, + MLAN_ERROR_PKT_TIMEOUT, + MLAN_ERROR_PKT_INVALID, + MLAN_ERROR_CMD_INVALID, + MLAN_ERROR_CMD_TIMEOUT, + MLAN_ERROR_CMD_DNLD_FAIL, + MLAN_ERROR_CMD_CANCEL, + MLAN_ERROR_CMD_RESP_FAIL, + MLAN_ERROR_CMD_ASSOC_FAIL, + MLAN_ERROR_CMD_SCAN_FAIL, + MLAN_ERROR_IOCTL_INVALID, + MLAN_ERROR_IOCTL_FAIL, + MLAN_ERROR_EVENT_UNKNOWN, + MLAN_ERROR_INVALID_PARAMETER, + MLAN_ERROR_NO_MEM, + /** More to add */ +} mlan_error_code; + +/** mlan_buf_type */ +typedef enum _mlan_buf_type +{ + MLAN_BUF_TYPE_CMD = 1, + MLAN_BUF_TYPE_DATA, + MLAN_BUF_TYPE_EVENT, + MLAN_BUF_TYPE_RAW_DATA, +} mlan_buf_type; + +/** MLAN BSS type */ +typedef enum _mlan_bss_type +{ + MLAN_BSS_TYPE_STA = 0, + MLAN_BSS_TYPE_UAP = 1, +#ifdef WIFI_DIRECT_SUPPORT + MLAN_BSS_TYPE_WIFIDIRECT = 2, +#endif + MLAN_BSS_TYPE_ANY = 0xff, +} mlan_bss_type; + +/** MLAN BSS role */ +typedef enum _mlan_bss_role +{ + MLAN_BSS_ROLE_STA = 0, + MLAN_BSS_ROLE_UAP = 1, + MLAN_BSS_ROLE_ANY = 0xff, +} mlan_bss_role; + +/** BSS role bit mask */ +#define BSS_ROLE_BIT_MASK MBIT(0) + +/** Get BSS role */ +#define GET_BSS_ROLE(priv) ((priv)->bss_role & BSS_ROLE_BIT_MASK) + +/** mlan_data_frame_type */ +typedef enum _mlan_data_frame_type +{ + MLAN_DATA_FRAME_TYPE_ETH_II = 0, + MLAN_DATA_FRAME_TYPE_802_11, +} mlan_data_frame_type; + +/** mlan_event_id */ +typedef enum _mlan_event_id +{ + /* Event generated by firmware (MSB=0) */ + MLAN_EVENT_ID_FW_UNKNOWN = 0x00000001, + MLAN_EVENT_ID_FW_ADHOC_LINK_SENSED, + MLAN_EVENT_ID_FW_ADHOC_LINK_LOST, + MLAN_EVENT_ID_FW_DISCONNECTED, + MLAN_EVENT_ID_FW_MIC_ERR_UNI, + MLAN_EVENT_ID_FW_MIC_ERR_MUL, + MLAN_EVENT_ID_FW_BCN_RSSI_LOW, + MLAN_EVENT_ID_FW_BCN_RSSI_HIGH, + MLAN_EVENT_ID_FW_BCN_SNR_LOW, + MLAN_EVENT_ID_FW_BCN_SNR_HIGH, + MLAN_EVENT_ID_FW_MAX_FAIL, + MLAN_EVENT_ID_FW_DATA_RSSI_LOW, + MLAN_EVENT_ID_FW_DATA_RSSI_HIGH, + MLAN_EVENT_ID_FW_DATA_SNR_LOW, + MLAN_EVENT_ID_FW_DATA_SNR_HIGH, + MLAN_EVENT_ID_FW_LINK_QUALITY, + MLAN_EVENT_ID_FW_PORT_RELEASE, + MLAN_EVENT_ID_FW_PRE_BCN_LOST, + MLAN_EVENT_ID_FW_WMM_CONFIG_CHANGE, + MLAN_EVENT_ID_FW_HS_WAKEUP, + MLAN_EVENT_ID_FW_BG_SCAN, + MLAN_EVENT_ID_FW_WEP_ICV_ERR, + MLAN_EVENT_ID_FW_STOP_TX, + MLAN_EVENT_ID_FW_START_TX, + MLAN_EVENT_ID_FW_CHANNEL_SWITCH_ANN, + MLAN_EVENT_ID_FW_RADAR_DETECTED, + MLAN_EVENT_ID_FW_CHANNEL_REPORT_RDY, + MLAN_EVENT_ID_FW_BW_CHANGED, +#ifdef WIFI_DIRECT_SUPPORT + MLAN_EVENT_ID_FW_REMAIN_ON_CHAN_EXPIRED, +#endif +#ifdef UAP_SUPPORT + MLAN_EVENT_ID_UAP_FW_BSS_START, + MLAN_EVENT_ID_UAP_FW_BSS_ACTIVE, + MLAN_EVENT_ID_UAP_FW_BSS_IDLE, + MLAN_EVENT_ID_UAP_FW_STA_CONNECT, + MLAN_EVENT_ID_UAP_FW_STA_DISCONNECT, +#endif + + /* Event generated by MLAN driver (MSB=1) */ + MLAN_EVENT_ID_DRV_CONNECTED = 0x80000001, + MLAN_EVENT_ID_DRV_DEFER_HANDLING, + MLAN_EVENT_ID_DRV_HS_ACTIVATED, + MLAN_EVENT_ID_DRV_HS_DEACTIVATED, + MLAN_EVENT_ID_DRV_MGMT_FRAME, + MLAN_EVENT_ID_DRV_OBSS_SCAN_PARAM, + MLAN_EVENT_ID_DRV_PASSTHRU, + MLAN_EVENT_ID_DRV_SCAN_REPORT, + MLAN_EVENT_ID_DRV_MEAS_REPORT, + MLAN_EVENT_ID_DRV_REPORT_STRING, + MLAN_EVENT_ID_DRV_DBG_DUMP, +} mlan_event_id; + +/** Data Structures */ +/** mlan_image data structure */ +typedef struct _mlan_fw_image +{ + /** Helper image buffer pointer */ + t_u8 *phelper_buf; + /** Helper image length */ + t_u32 helper_len; + /** Firmware image buffer pointer */ + t_u8 *pfw_buf; + /** Firmware image length */ + t_u32 fw_len; +} mlan_fw_image, *pmlan_fw_image; + +/** Custom data structure */ +typedef struct _mlan_init_param +{ + /** Cal data buffer pointer */ + t_u8 *pcal_data_buf; + /** Cal data length */ + t_u32 cal_data_len; + /** Other custom data */ +} mlan_init_param, *pmlan_init_param; + +/** mlan_event data structure */ +typedef struct _mlan_event +{ + /** BSS index number for multiple BSS support */ + t_u32 bss_index; + /** Event ID */ + mlan_event_id event_id; + /** Event length */ + t_u32 event_len; + /** Event buffer */ + t_u8 event_buf[1]; +} mlan_event, *pmlan_event; + +/** mlan_event_scan_result data structure */ +typedef MLAN_PACK_START struct _mlan_event_scan_result +{ + /** Event ID */ + t_u16 event_id; + /** BSS index number for multiple BSS support */ + t_u8 bss_index; + /** BSS type */ + t_u8 bss_type; + /** More event available or not */ + t_u8 more_event; + /** Reserved */ + t_u8 reserved[3]; + /** Size of the response buffer */ + t_u16 buf_size; + /** Number of BSS in scan response */ + t_u8 num_of_set; +} MLAN_PACK_END mlan_event_scan_result, *pmlan_event_scan_result; + +/** mlan_ioctl_req data structure */ +typedef struct _mlan_ioctl_req +{ + /** Status code from firmware/driver */ + t_u32 status_code; + /** BSS index number for multiple BSS support */ + t_u32 bss_index; + /** Request id */ + t_u32 req_id; + /** Action: set or get */ + t_u32 action; + /** Pointer to buffer */ + t_u8 *pbuf; + /** Length of buffer */ + t_u32 buf_len; + /** Length of the data read/written in buffer */ + t_u32 data_read_written; + /** Length of buffer needed */ + t_u32 buf_len_needed; + /** Reserved for MOAL module */ + t_ptr reserved_1; +} mlan_ioctl_req, *pmlan_ioctl_req; + +/** mlan_buffer data structure */ +typedef struct _mlan_buffer +{ + /** Pointer to previous mlan_buffer */ + struct _mlan_buffer *pprev; + /** Pointer to next mlan_buffer */ + struct _mlan_buffer *pnext; + /** Status code from firmware/driver */ + t_u32 status_code; + /** Flags for this buffer */ + t_u32 flags; + /** BSS index number for multiple BSS support */ + t_u32 bss_index; + /** Buffer descriptor, e.g. skb in Linux */ + t_void *pdesc; + /** Pointer to buffer */ + t_u8 *pbuf; + /** Offset to data */ + t_u32 data_offset; + /** Data length */ + t_u32 data_len; + /** Buffer type: data, cmd, event etc. */ + mlan_buf_type buf_type; + + /** Fields below are valid for data packet only */ + /** QoS priority */ + t_u32 priority; + /** Time stamp when packet is received (seconds) */ + t_u32 in_ts_sec; + /** Time stamp when packet is received (micro seconds) */ + t_u32 in_ts_usec; + /** Time stamp when packet is processed (seconds) */ + t_u32 out_ts_sec; + /** Time stamp when packet is processed (micro seconds) */ + t_u32 out_ts_usec; + + /** Fields below are valid for MLAN module only */ + /** Pointer to parent mlan_buffer */ + struct _mlan_buffer *pparent; + /** Use count for this buffer */ + t_u32 use_count; +} mlan_buffer, *pmlan_buffer; + +/** mlan_bss_attr data structure */ +typedef struct _mlan_bss_attr +{ + /** BSS type */ + t_u32 bss_type; + /** Data frame type: Ethernet II, 802.11, etc. */ + t_u32 frame_type; + /** The BSS is active (non-0) or not (0). */ + t_u32 active; + /** BSS Priority */ + t_u32 bss_priority; + /** BSS number */ + t_u32 bss_num; +} mlan_bss_attr, *pmlan_bss_attr; + +#ifdef PRAGMA_PACK +#pragma pack(push, 1) +#endif + +/** Type enumeration for the command result */ +typedef MLAN_PACK_START enum _mlan_cmd_result_e +{ + MLAN_CMD_RESULT_SUCCESS = 0, + MLAN_CMD_RESULT_FAILURE = 1, + MLAN_CMD_RESULT_TIMEOUT = 2, + MLAN_CMD_RESULT_INVALID_DATA = 3 +} MLAN_PACK_END mlan_cmd_result_e; + +/** Type enumeration of WMM AC_QUEUES */ +typedef MLAN_PACK_START enum _mlan_wmm_ac_e +{ + WMM_AC_BK, + WMM_AC_BE, + WMM_AC_VI, + WMM_AC_VO +} MLAN_PACK_END mlan_wmm_ac_e; + +/** Type enumeration for the action field in the Queue Config command */ +typedef MLAN_PACK_START enum _mlan_wmm_queue_config_action_e +{ + MLAN_WMM_QUEUE_CONFIG_ACTION_GET = 0, + MLAN_WMM_QUEUE_CONFIG_ACTION_SET = 1, + MLAN_WMM_QUEUE_CONFIG_ACTION_DEFAULT = 2, + MLAN_WMM_QUEUE_CONFIG_ACTION_MAX +} MLAN_PACK_END mlan_wmm_queue_config_action_e; + +/** Type enumeration for the action field in the queue stats command */ +typedef MLAN_PACK_START enum _mlan_wmm_queue_stats_action_e +{ + MLAN_WMM_STATS_ACTION_START = 0, + MLAN_WMM_STATS_ACTION_STOP = 1, + MLAN_WMM_STATS_ACTION_GET_CLR = 2, + MLAN_WMM_STATS_ACTION_SET_CFG = 3, /* Not currently used */ + MLAN_WMM_STATS_ACTION_GET_CFG = 4, /* Not currently used */ + MLAN_WMM_STATS_ACTION_MAX +} MLAN_PACK_END mlan_wmm_queue_stats_action_e; + +/** + * @brief IOCTL structure for a Traffic stream status. + * + */ +typedef MLAN_PACK_START struct +{ + /** TSID: Range: 0->7 */ + t_u8 tid; + /** TSID specified is valid */ + t_u8 valid; + /** AC TSID is active on */ + t_u8 access_category; + /** UP specified for the TSID */ + t_u8 user_priority; + /** Power save mode for TSID: 0 (legacy), 1 (UAPSD) */ + t_u8 psb; + /** Upstream(0), Downlink(1), Bidirectional(3) */ + t_u8 flow_dir; + /** Medium time granted for the TSID */ + t_u16 medium_time; +} MLAN_PACK_END wlan_ioctl_wmm_ts_status_t, +/** Type definition of mlan_ds_wmm_ts_status for MLAN_OID_WMM_CFG_TS_STATUS */ + mlan_ds_wmm_ts_status, *pmlan_ds_wmm_ts_status; + +/** Max Ie length */ +#define MAX_IE_SIZE 256 + +/** custom IE */ +typedef MLAN_PACK_START struct _custom_ie +{ + /** IE Index */ + t_u16 ie_index; + /** Mgmt Subtype Mask */ + t_u16 mgmt_subtype_mask; + /** IE Length */ + t_u16 ie_length; + /** IE buffer */ + t_u8 ie_buffer[MAX_IE_SIZE]; +} MLAN_PACK_END custom_ie; + +/** Max IE index to FW */ +#define MAX_MGMT_IE_INDEX_TO_FW 4 +/** Max IE index per BSS */ +#define MAX_MGMT_IE_INDEX 16 + +/** custom IE info */ +typedef MLAN_PACK_START struct _custom_ie_info +{ + /** size of buffer */ + t_u16 buf_size; + /** no of buffers of buf_size */ + t_u16 buf_count; +} MLAN_PACK_END custom_ie_info; + +/** TLV buffer : Max Mgmt IE */ +typedef MLAN_PACK_START struct _tlvbuf_max_mgmt_ie +{ + /** Type */ + t_u16 type; + /** Length */ + t_u16 len; + /** No of tuples */ + t_u16 count; + /** custom IE info tuples */ + custom_ie_info info[MAX_MGMT_IE_INDEX]; +} MLAN_PACK_END tlvbuf_max_mgmt_ie; + +/** TLV buffer : custom IE */ +typedef MLAN_PACK_START struct _tlvbuf_custom_ie +{ + /** Type */ + t_u16 type; + /** Length */ + t_u16 len; + /** IE data */ + custom_ie ie_data_list[MAX_MGMT_IE_INDEX_TO_FW]; + /** Max mgmt IE TLV */ + tlvbuf_max_mgmt_ie max_mgmt_ie; +} MLAN_PACK_END mlan_ds_misc_custom_ie; + +#ifdef PRAGMA_PACK +#pragma pack(pop) +#endif + +/** mlan_callbacks data structure */ +typedef struct _mlan_callbacks +{ + /** moal_get_fw_data */ + mlan_status(*moal_get_fw_data) (IN t_void * pmoal_handle, + IN t_u32 offset, + IN t_u32 len, OUT t_u8 * pbuf); + /** moal_init_fw_complete */ + mlan_status(*moal_init_fw_complete) (IN t_void * pmoal_handle, + IN mlan_status status); + /** moal_shutdown_fw_complete */ + mlan_status(*moal_shutdown_fw_complete) (IN t_void * pmoal_handle, + IN mlan_status status); + /** moal_send_packet_complete */ + mlan_status(*moal_send_packet_complete) (IN t_void * pmoal_handle, + IN pmlan_buffer pmbuf, + IN mlan_status status); + /** moal_recv_complete */ + mlan_status(*moal_recv_complete) (IN t_void * pmoal_handle, + IN pmlan_buffer pmbuf, + IN t_u32 port, IN mlan_status status); + /** moal_recv_packet */ + mlan_status(*moal_recv_packet) (IN t_void * pmoal_handle, + IN pmlan_buffer pmbuf); + /** moal_recv_event */ + mlan_status(*moal_recv_event) (IN t_void * pmoal_handle, + IN pmlan_event pmevent); + /** moal_ioctl_complete */ + mlan_status(*moal_ioctl_complete) (IN t_void * pmoal_handle, + IN pmlan_ioctl_req pioctl_req, + IN mlan_status status); + /** moal_alloc_mlan_buffer */ + mlan_status(*moal_alloc_mlan_buffer) (IN t_void * pmoal_handle, + IN t_u32 size, + OUT pmlan_buffer * pmbuf); + /** moal_free_mlan_buffer */ + mlan_status(*moal_free_mlan_buffer) (IN t_void * pmoal_handle, + IN pmlan_buffer pmbuf); + /** moal_write_reg */ + mlan_status(*moal_write_reg) (IN t_void * pmoal_handle, + IN t_u32 reg, IN t_u32 data); + /** moal_read_reg */ + mlan_status(*moal_read_reg) (IN t_void * pmoal_handle, + IN t_u32 reg, OUT t_u32 * data); + /** moal_write_data_sync */ + mlan_status(*moal_write_data_sync) (IN t_void * pmoal_handle, + IN pmlan_buffer pmbuf, + IN t_u32 port, IN t_u32 timeout); + /** moal_read_data_sync */ + mlan_status(*moal_read_data_sync) (IN t_void * pmoal_handle, + IN OUT pmlan_buffer pmbuf, + IN t_u32 port, IN t_u32 timeout); + /** moal_malloc */ + mlan_status(*moal_malloc) (IN t_void * pmoal_handle, + IN t_u32 size, IN t_u32 flag, OUT t_u8 ** ppbuf); + /** moal_mfree */ + mlan_status(*moal_mfree) (IN t_void * pmoal_handle, IN t_u8 * pbuf); + /** moal_memset */ + t_void *(*moal_memset) (IN t_void * pmoal_handle, + IN t_void * pmem, IN t_u8 byte, IN t_u32 num); + /** moal_memcpy */ + t_void *(*moal_memcpy) (IN t_void * pmoal_handle, + IN t_void * pdest, + IN const t_void * psrc, IN t_u32 num); + /** moal_memmove */ + t_void *(*moal_memmove) (IN t_void * pmoal_handle, + IN t_void * pdest, + IN const t_void * psrc, IN t_u32 num); + /** moal_memcmp */ + t_s32(*moal_memcmp) (IN t_void * pmoal_handle, + IN const t_void * pmem1, + IN const t_void * pmem2, IN t_u32 num); + /** moal_udelay */ + t_void(*moal_udelay) (IN t_void * pmoal_handle, IN t_u32 udelay); + /** moal_get_system_time */ + mlan_status(*moal_get_system_time) (IN t_void * pmoal_handle, + OUT t_u32 * psec, OUT t_u32 * pusec); + /** moal_init_timer*/ + mlan_status(*moal_init_timer) (IN t_void * pmoal_handle, + OUT t_void ** pptimer, + IN t_void(*callback) (t_void * pcontext), + IN t_void * pcontext); + /** moal_free_timer */ + mlan_status(*moal_free_timer) (IN t_void * pmoal_handle, + IN t_void * ptimer); + /** moal_start_timer*/ + mlan_status(*moal_start_timer) (IN t_void * pmoal_handle, + IN t_void * ptimer, + IN t_u8 periodic, IN t_u32 msec); + /** moal_stop_timer*/ + mlan_status(*moal_stop_timer) (IN t_void * pmoal_handle, + IN t_void * ptimer); + /** moal_init_lock */ + mlan_status(*moal_init_lock) (IN t_void * pmoal_handle, + OUT t_void ** pplock); + /** moal_free_lock */ + mlan_status(*moal_free_lock) (IN t_void * pmoal_handle, + IN t_void * plock); + /** moal_spin_lock */ + mlan_status(*moal_spin_lock) (IN t_void * pmoal_handle, + IN t_void * plock); + /** moal_spin_unlock */ + mlan_status(*moal_spin_unlock) (IN t_void * pmoal_handle, + IN t_void * plock); + /** moal_print */ + t_void(*moal_print) (IN t_void * pmoal_handle, + IN t_u32 level, IN t_s8 * pformat, IN ...); + /** moal_print_netintf */ + t_void(*moal_print_netintf) (IN t_void * pmoal_handle, + IN t_u32 bss_index, IN t_u32 level); + /** moal_assert */ + t_void(*moal_assert) (IN t_void * pmoal_handle, IN t_u32 cond); +} mlan_callbacks, *pmlan_callbacks; + +/** Interrupt Mode SDIO */ +#define INT_MODE_SDIO 0 +/** Interrupt Mode GPIO */ +#define INT_MODE_GPIO 1 + +/** Parameter unchanged, use MLAN default setting */ +#define MLAN_INIT_PARA_UNCHANGED 0 +/** Parameter enabled, override MLAN default setting */ +#define MLAN_INIT_PARA_ENABLED 1 +/** Parameter disabled, override MLAN default setting */ +#define MLAN_INIT_PARA_DISABLED 2 + +/** mlan_device data structure */ +typedef struct _mlan_device +{ + /** MOAL Handle */ + t_void *pmoal_handle; + /** BSS Attributes */ + mlan_bss_attr bss_attr[MLAN_MAX_BSS_NUM]; + /** Callbacks */ + mlan_callbacks callbacks; +#ifdef MFG_CMD_SUPPORT + /** MFG mode */ + t_u32 mfg_mode; +#endif + /** SDIO interrupt mode (0: INT_MODE_SDIO, 1: INT_MODE_GPIO) */ + t_u32 int_mode; + /** GPIO interrupt pin number */ + t_u32 gpio_pin; +#ifdef DEBUG_LEVEL1 + /** Driver debug bit masks */ + t_u32 drvdbg; +#endif +#ifdef SDIO_MULTI_PORT_TX_AGGR + /** SDIO MPA Tx */ + t_u32 mpa_tx_cfg; +#endif +#ifdef SDIO_MULTI_PORT_RX_AGGR + /** SDIO MPA Rx */ + t_u32 mpa_rx_cfg; +#endif + /** Auto deep sleep */ + t_u32 auto_ds; + /** IEEE PS mode */ + t_u32 ps_mode; + /** Max Tx buffer size */ + t_u32 max_tx_buf; +#if defined(STA_SUPPORT) + /** 802.11d configuration */ + t_u32 cfg_11d; +#endif +} mlan_device, *pmlan_device; + +/** MLAN API function prototype */ +#define MLAN_API + +/** Registration */ +MLAN_API mlan_status mlan_register(IN pmlan_device pmdevice, + OUT t_void ** ppmlan_adapter); + +/** Un-registration */ +MLAN_API mlan_status mlan_unregister(IN t_void * pmlan_adapter); + +/** Firmware Downloading */ +MLAN_API mlan_status mlan_dnld_fw(IN t_void * pmlan_adapter, + IN pmlan_fw_image pmfw); + +/** Custom data pass API */ +MLAN_API mlan_status mlan_set_init_param(IN t_void * pmlan_adapter, + IN pmlan_init_param pparam); + +/** Firmware Initialization */ +MLAN_API mlan_status mlan_init_fw(IN t_void * pmlan_adapter); + +/** Firmware Shutdown */ +MLAN_API mlan_status mlan_shutdown_fw(IN t_void * pmlan_adapter); + +/** Main Process */ +MLAN_API mlan_status mlan_main_process(IN t_void * pmlan_adapter); + +/** Packet Transmission */ +MLAN_API mlan_status mlan_send_packet(IN t_void * pmlan_adapter, + IN pmlan_buffer pmbuf); + +/** Packet Reception complete callback */ +MLAN_API mlan_status mlan_recv_packet_complete(IN t_void * pmlan_adapter, + IN pmlan_buffer pmbuf, + IN mlan_status status); + +/** interrupt handler */ +MLAN_API t_void mlan_interrupt(IN t_void * pmlan_adapter); + +/** mlan ioctl */ +MLAN_API mlan_status mlan_ioctl(IN t_void * pmlan_adapter, + IN pmlan_ioctl_req pioctl_req); +/** mlan select wmm queue */ +MLAN_API t_u8 mlan_select_wmm_queue(IN t_void * pmlan_adapter, + IN t_u8 bss_num, IN t_u8 tid); +#endif /* !_MLAN_DECL_H_ */ diff --git a/drivers/net/wireless/sd8797/mlinux/mlan_ieee.h b/drivers/net/wireless/sd8797/mlinux/mlan_ieee.h new file mode 100644 index 000000000000..2431e06f48fa --- /dev/null +++ b/drivers/net/wireless/sd8797/mlinux/mlan_ieee.h @@ -0,0 +1,1322 @@ +/** @file mlan_ieee.h + * + * @brief This file contains IEEE information element related + * definitions used in MLAN and MOAL module. + * + * Copyright (C) 2008-2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +/****************************************************** +Change log: + 11/03/2008: initial version +******************************************************/ + +#ifndef _MLAN_IEEE_H_ +#define _MLAN_IEEE_H_ + +/** FIX IES size in beacon buffer */ +#define WLAN_802_11_FIXED_IE_SIZE 12 +/** WLAN supported rates */ +#define WLAN_SUPPORTED_RATES 14 + +/** WLAN supported rates extension*/ +#define WLAN_SUPPORTED_RATES_EXT 32 + +/** Enumeration definition*/ +/** WLAN_802_11_NETWORK_TYPE */ +typedef enum _WLAN_802_11_NETWORK_TYPE +{ + Wlan802_11FH, + Wlan802_11DS, + /* Defined as upper bound */ + Wlan802_11NetworkTypeMax +} WLAN_802_11_NETWORK_TYPE; + +/** Maximum size of IEEE Information Elements */ +#define IEEE_MAX_IE_SIZE 256 + +#ifdef BIG_ENDIAN_SUPPORT +/** Frame control: Type Mgmt frame */ +#define IEEE80211_FC_MGMT_FRAME_TYPE_MASK 0x3000 +/** Frame control: SubType Mgmt frame */ +#define IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE(fc) (((fc) & 0xF000) >> 12) +#else +/** Frame control: Type Mgmt frame */ +#define IEEE80211_FC_MGMT_FRAME_TYPE_MASK 0x000C +/** Frame control: SubType Mgmt frame */ +#define IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE(fc) (((fc) & 0x00F0) >> 4) +#endif + +#ifdef PRAGMA_PACK +#pragma pack(push, 1) +#endif + +/** IEEE Type definitions */ +typedef MLAN_PACK_START enum _IEEEtypes_ElementId_e +{ + SSID = 0, + SUPPORTED_RATES = 1, + + FH_PARAM_SET = 2, + DS_PARAM_SET = 3, + CF_PARAM_SET = 4, + + IBSS_PARAM_SET = 6, + +#ifdef STA_SUPPORT + COUNTRY_INFO = 7, +#endif /* STA_SUPPORT */ + + POWER_CONSTRAINT = 32, + POWER_CAPABILITY = 33, + TPC_REQUEST = 34, + TPC_REPORT = 35, + SUPPORTED_CHANNELS = 36, + CHANNEL_SWITCH_ANN = 37, + QUIET = 40, + IBSS_DFS = 41, + HT_CAPABILITY = 45, + HT_OPERATION = 61, + BSSCO_2040 = 72, + OVERLAPBSSSCANPARAM = 74, + EXT_CAPABILITY = 127, + + ERP_INFO = 42, + + EXTENDED_SUPPORTED_RATES = 50, + + VENDOR_SPECIFIC_221 = 221, + WMM_IE = VENDOR_SPECIFIC_221, + + WPS_IE = VENDOR_SPECIFIC_221, + + WPA_IE = VENDOR_SPECIFIC_221, + RSN_IE = 48, + VS_IE = VENDOR_SPECIFIC_221, + WAPI_IE = 68, +} MLAN_PACK_END IEEEtypes_ElementId_e; + +/** IEEE IE header */ +typedef MLAN_PACK_START struct _IEEEtypes_Header_t +{ + /** Element ID */ + t_u8 element_id; + /** Length */ + t_u8 len; +} MLAN_PACK_END IEEEtypes_Header_t, *pIEEEtypes_Header_t; + +/** Vendor specific IE header */ +typedef MLAN_PACK_START struct _IEEEtypes_VendorHeader_t +{ + /** Element ID */ + t_u8 element_id; + /** Length */ + t_u8 len; + /** OUI */ + t_u8 oui[3]; + /** OUI type */ + t_u8 oui_type; + /** OUI subtype */ + t_u8 oui_subtype; + /** Version */ + t_u8 version; +} MLAN_PACK_END IEEEtypes_VendorHeader_t, *pIEEEtypes_VendorHeader_t; + +/** Vendor specific IE */ +typedef MLAN_PACK_START struct _IEEEtypes_VendorSpecific_t +{ + /** Vendor specific IE header */ + IEEEtypes_VendorHeader_t vend_hdr; + /** IE Max - size of previous fields */ + t_u8 data[IEEE_MAX_IE_SIZE - sizeof(IEEEtypes_VendorHeader_t)]; +} +MLAN_PACK_END IEEEtypes_VendorSpecific_t, *pIEEEtypes_VendorSpecific_t; + +/** IEEE IE */ +typedef MLAN_PACK_START struct _IEEEtypes_Generic_t +{ + /** Generic IE header */ + IEEEtypes_Header_t ieee_hdr; + /** IE Max - size of previous fields */ + t_u8 data[IEEE_MAX_IE_SIZE - sizeof(IEEEtypes_Header_t)]; +} +MLAN_PACK_END IEEEtypes_Generic_t, *pIEEEtypes_Generic_t; + +/** Capability information mask */ +#define CAPINFO_MASK (~(MBIT(15) | MBIT(14) | \ + MBIT(12) | MBIT(11) | MBIT(9))) + +/** Capability Bit Map*/ +#ifdef BIG_ENDIAN_SUPPORT +typedef MLAN_PACK_START struct _IEEEtypes_CapInfo_t +{ + t_u8 rsrvd1:2; + t_u8 dsss_ofdm:1; + t_u8 rsvrd2:2; + t_u8 short_slot_time:1; + t_u8 rsrvd3:1; + t_u8 spectrum_mgmt:1; + t_u8 chan_agility:1; + t_u8 pbcc:1; + t_u8 short_preamble:1; + t_u8 privacy:1; + t_u8 cf_poll_rqst:1; + t_u8 cf_pollable:1; + t_u8 ibss:1; + t_u8 ess:1; +} MLAN_PACK_END IEEEtypes_CapInfo_t, *pIEEEtypes_CapInfo_t; +#else +typedef MLAN_PACK_START struct _IEEEtypes_CapInfo_t +{ + /** Capability Bit Map : ESS */ + t_u8 ess:1; + /** Capability Bit Map : IBSS */ + t_u8 ibss:1; + /** Capability Bit Map : CF pollable */ + t_u8 cf_pollable:1; + /** Capability Bit Map : CF poll request */ + t_u8 cf_poll_rqst:1; + /** Capability Bit Map : privacy */ + t_u8 privacy:1; + /** Capability Bit Map : Short preamble */ + t_u8 short_preamble:1; + /** Capability Bit Map : PBCC */ + t_u8 pbcc:1; + /** Capability Bit Map : Channel agility */ + t_u8 chan_agility:1; + /** Capability Bit Map : Spectrum management */ + t_u8 spectrum_mgmt:1; + /** Capability Bit Map : Reserved */ + t_u8 rsrvd3:1; + /** Capability Bit Map : Short slot time */ + t_u8 short_slot_time:1; + /** Capability Bit Map : APSD */ + t_u8 Apsd:1; + /** Capability Bit Map : Reserved */ + t_u8 rsvrd2:1; + /** Capability Bit Map : DSS OFDM */ + t_u8 dsss_ofdm:1; + /** Capability Bit Map : Reserved */ + t_u8 rsrvd1:2; +} MLAN_PACK_END IEEEtypes_CapInfo_t, *pIEEEtypes_CapInfo_t; +#endif /* BIG_ENDIAN_SUPPORT */ + +/** IEEEtypes_CfParamSet_t */ +typedef MLAN_PACK_START struct _IEEEtypes_CfParamSet_t +{ + /** CF peremeter : Element ID */ + t_u8 element_id; + /** CF peremeter : Length */ + t_u8 len; + /** CF peremeter : Count */ + t_u8 cfp_cnt; + /** CF peremeter : Period */ + t_u8 cfp_period; + /** CF peremeter : Maximum duration */ + t_u16 cfp_max_duration; + /** CF peremeter : Remaining duration */ + t_u16 cfp_duration_remaining; +} MLAN_PACK_END IEEEtypes_CfParamSet_t, *pIEEEtypes_CfParamSet_t; + +/** IEEEtypes_IbssParamSet_t */ +typedef MLAN_PACK_START struct _IEEEtypes_IbssParamSet_t +{ + /** Element ID */ + t_u8 element_id; + /** Length */ + t_u8 len; + /** ATIM window value in milliseconds */ + t_u16 atim_window; +} MLAN_PACK_END IEEEtypes_IbssParamSet_t, *pIEEEtypes_IbssParamSet_t; + +/** IEEEtypes_SsParamSet_t */ +typedef MLAN_PACK_START union _IEEEtypes_SsParamSet_t +{ + /** SS parameter : CF parameter set */ + IEEEtypes_CfParamSet_t cf_param_set; + /** SS parameter : IBSS parameter set */ + IEEEtypes_IbssParamSet_t ibss_param_set; +} MLAN_PACK_END IEEEtypes_SsParamSet_t, *pIEEEtypes_SsParamSet_t; + +/** IEEEtypes_FhParamSet_t */ +typedef MLAN_PACK_START struct _IEEEtypes_FhParamSet_t +{ + /** FH parameter : Element ID */ + t_u8 element_id; + /** FH parameter : Length */ + t_u8 len; + /** FH parameter : Dwell time in milliseconds */ + t_u16 dwell_time; + /** FH parameter : Hop set */ + t_u8 hop_set; + /** FH parameter : Hop pattern */ + t_u8 hop_pattern; + /** FH parameter : Hop index */ + t_u8 hop_index; +} MLAN_PACK_END IEEEtypes_FhParamSet_t, *pIEEEtypes_FhParamSet_t; + +/** IEEEtypes_DsParamSet_t */ +typedef MLAN_PACK_START struct _IEEEtypes_DsParamSet_t +{ + /** DS parameter : Element ID */ + t_u8 element_id; + /** DS parameter : Length */ + t_u8 len; + /** DS parameter : Current channel */ + t_u8 current_chan; +} MLAN_PACK_END IEEEtypes_DsParamSet_t, *pIEEEtypes_DsParamSet_t; + +/** IEEEtypes_PhyParamSet_t */ +typedef MLAN_PACK_START union _IEEEtypes_PhyParamSet_t +{ + /** FH parameter set */ + IEEEtypes_FhParamSet_t fh_param_set; + /** DS parameter set */ + IEEEtypes_DsParamSet_t ds_param_set; +} MLAN_PACK_END IEEEtypes_PhyParamSet_t, *pIEEEtypes_PhyParamSet_t; + +/** IEEEtypes_ERPInfo_t */ +typedef MLAN_PACK_START struct _IEEEtypes_ERPInfo_t +{ + /** Element ID */ + t_u8 element_id; + /** Length */ + t_u8 len; + /** ERP flags */ + t_u8 erp_flags; +} MLAN_PACK_END IEEEtypes_ERPInfo_t, *pIEEEtypes_ERPInfo_t; + +/** IEEEtypes_AId_t */ +typedef t_u16 IEEEtypes_AId_t; + +/** IEEEtypes_StatusCode_t */ +typedef t_u16 IEEEtypes_StatusCode_t; + +/** IEEEtypes_AssocRsp_t */ +typedef MLAN_PACK_START struct _IEEEtypes_AssocRsp_t +{ + /** Capability information */ + IEEEtypes_CapInfo_t capability; + /** Association response status code */ + IEEEtypes_StatusCode_t status_code; + /** Association ID */ + IEEEtypes_AId_t a_id; + /** IE data buffer */ + t_u8 ie_buffer[1]; +} MLAN_PACK_END IEEEtypes_AssocRsp_t, *pIEEEtypes_AssocRsp_t; + +/** 802.11 supported rates */ +typedef t_u8 WLAN_802_11_RATES[WLAN_SUPPORTED_RATES]; + +/** cipher TKIP */ +#define WPA_CIPHER_TKIP 2 +/** cipher AES */ +#define WPA_CIPHER_AES_CCM 4 +/** AKM: 8021x */ +#define RSN_AKM_8021X 1 +/** AKM: PSK */ +#define RSN_AKM_PSK 2 + +/** wpa_suite_t */ +typedef MLAN_PACK_START struct _wpa_suite_t +{ + /** OUI */ + t_u8 oui[3]; + /** tyep */ + t_u8 type; +} MLAN_PACK_END wpa_suite, wpa_suite_mcast_t; + +/** wpa_suite_ucast_t */ +typedef MLAN_PACK_START struct +{ + /* count */ + t_u16 count; + /** wpa_suite list */ + wpa_suite list[1]; +} MLAN_PACK_END wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t; + +/** IEEEtypes_Rsn_t */ +typedef MLAN_PACK_START struct _IEEEtypes_Rsn_t +{ + /** Rsn : Element ID */ + t_u8 element_id; + /** Rsn : Length */ + t_u8 len; + /** Rsn : version */ + t_u16 version; + /** Rsn : group cipher */ + wpa_suite_mcast_t group_cipher; + /** Rsn : pairwise cipher */ + wpa_suite_ucast_t pairwise_cipher; +} MLAN_PACK_END IEEEtypes_Rsn_t, *pIEEEtypes_Rsn_t; + +/** IEEEtypes_Wpa_t */ +typedef MLAN_PACK_START struct _IEEEtypes_Wpa_t +{ + /** Wpa : Element ID */ + t_u8 element_id; + /** Wpa : Length */ + t_u8 len; + /** Wpa : oui */ + t_u8 oui[4]; + /** version */ + t_u16 version; + /** Wpa : group cipher */ + wpa_suite_mcast_t group_cipher; + /** Wpa : pairwise cipher */ + wpa_suite_ucast_t pairwise_cipher; +} MLAN_PACK_END IEEEtypes_Wpa_t, *pIEEEtypes_Wpa_t; + +/** Maximum number of AC QOS queues available in the driver/firmware */ +#define MAX_AC_QUEUES 4 + +/** Data structure of WMM QoS information */ +typedef MLAN_PACK_START struct _IEEEtypes_WmmQosInfo_t +{ +#ifdef BIG_ENDIAN_SUPPORT + /** QoS UAPSD */ + t_u8 qos_uapsd:1; + /** Reserved */ + t_u8 reserved:3; + /** Parameter set count */ + t_u8 para_set_count:4; +#else + /** Parameter set count */ + t_u8 para_set_count:4; + /** Reserved */ + t_u8 reserved:3; + /** QoS UAPSD */ + t_u8 qos_uapsd:1; +#endif /* BIG_ENDIAN_SUPPORT */ +} MLAN_PACK_END IEEEtypes_WmmQosInfo_t, *pIEEEtypes_WmmQosInfo_t; + +/** Data structure of WMM Aci/Aifsn */ +typedef MLAN_PACK_START struct _IEEEtypes_WmmAciAifsn_t +{ +#ifdef BIG_ENDIAN_SUPPORT + /** Reserved */ + t_u8 reserved:1; + /** Aci */ + t_u8 aci:2; + /** Acm */ + t_u8 acm:1; + /** Aifsn */ + t_u8 aifsn:4; +#else + /** Aifsn */ + t_u8 aifsn:4; + /** Acm */ + t_u8 acm:1; + /** Aci */ + t_u8 aci:2; + /** Reserved */ + t_u8 reserved:1; +#endif /* BIG_ENDIAN_SUPPORT */ +} MLAN_PACK_END IEEEtypes_WmmAciAifsn_t, *pIEEEtypes_WmmAciAifsn_t; + +/** Data structure of WMM ECW */ +typedef MLAN_PACK_START struct _IEEEtypes_WmmEcw_t +{ +#ifdef BIG_ENDIAN_SUPPORT + /** Maximum Ecw */ + t_u8 ecw_max:4; + /** Minimum Ecw */ + t_u8 ecw_min:4; +#else + /** Minimum Ecw */ + t_u8 ecw_min:4; + /** Maximum Ecw */ + t_u8 ecw_max:4; +#endif /* BIG_ENDIAN_SUPPORT */ +} MLAN_PACK_END IEEEtypes_WmmEcw_t, *pIEEEtypes_WmmEcw_t; + +/** Data structure of WMM AC parameters */ +typedef MLAN_PACK_START struct _IEEEtypes_WmmAcParameters_t +{ + IEEEtypes_WmmAciAifsn_t aci_aifsn; /**< AciAifSn */ + IEEEtypes_WmmEcw_t ecw; /**< Ecw */ + t_u16 tx_op_limit; /**< Tx op limit */ +} MLAN_PACK_END IEEEtypes_WmmAcParameters_t, *pIEEEtypes_WmmAcParameters_t; + +/** Data structure of WMM Info IE */ +typedef MLAN_PACK_START struct _IEEEtypes_WmmInfo_t +{ + + /** + * WMM Info IE - Vendor Specific Header: + * element_id [221/0xdd] + * Len [7] + * Oui [00:50:f2] + * OuiType [2] + * OuiSubType [0] + * Version [1] + */ + IEEEtypes_VendorHeader_t vend_hdr; + + /** QoS information */ + IEEEtypes_WmmQosInfo_t qos_info; + +} MLAN_PACK_END IEEEtypes_WmmInfo_t, *pIEEEtypes_WmmInfo_t; + +/** Data structure of WMM parameter IE */ +typedef MLAN_PACK_START struct _IEEEtypes_WmmParameter_t +{ + /** + * WMM Parameter IE - Vendor Specific Header: + * element_id [221/0xdd] + * Len [24] + * Oui [00:50:f2] + * OuiType [2] + * OuiSubType [1] + * Version [1] + */ + IEEEtypes_VendorHeader_t vend_hdr; + + /** QoS information */ + IEEEtypes_WmmQosInfo_t qos_info; + /** Reserved */ + t_u8 reserved; + + /** AC Parameters Record WMM_AC_BE, WMM_AC_BK, WMM_AC_VI, WMM_AC_VO */ + IEEEtypes_WmmAcParameters_t ac_params[MAX_AC_QUEUES]; +} MLAN_PACK_END IEEEtypes_WmmParameter_t, *pIEEEtypes_WmmParameter_t; + +/** Enumerator for TSPEC direction */ +typedef MLAN_PACK_START enum _IEEEtypes_WMM_TSPEC_TS_Info_Direction_e +{ + + TSPEC_DIR_UPLINK = 0, + TSPEC_DIR_DOWNLINK = 1, + /* 2 is a reserved value */ + TSPEC_DIR_BIDIRECT = 3, + +} MLAN_PACK_END IEEEtypes_WMM_TSPEC_TS_Info_Direction_e; + +/** Enumerator for TSPEC PSB */ +typedef MLAN_PACK_START enum _IEEEtypes_WMM_TSPEC_TS_Info_PSB_e +{ + + TSPEC_PSB_LEGACY = 0, + TSPEC_PSB_TRIG = 1, + +} MLAN_PACK_END IEEEtypes_WMM_TSPEC_TS_Info_PSB_e; + +/** Enumerator for TSPEC Ack Policy */ +typedef MLAN_PACK_START enum _IEEEtypes_WMM_TSPEC_TS_Info_AckPolicy_e +{ + + TSPEC_ACKPOLICY_NORMAL = 0, + TSPEC_ACKPOLICY_NOACK = 1, + /* 2 is reserved */ + TSPEC_ACKPOLICY_BLOCKACK = 3, + +} MLAN_PACK_END IEEEtypes_WMM_TSPEC_TS_Info_AckPolicy_e; + +/** Enumerator for TSPEC Trafffice type */ +typedef MLAN_PACK_START enum _IEEEtypes_WMM_TSPEC_TS_TRAFFIC_TYPE_e +{ + + TSPEC_TRAFFIC_APERIODIC = 0, + TSPEC_TRAFFIC_PERIODIC = 1, + +} MLAN_PACK_END IEEEtypes_WMM_TSPEC_TS_TRAFFIC_TYPE_e; + +/** Data structure of WMM TSPEC information */ +typedef MLAN_PACK_START struct +{ +#ifdef BIG_ENDIAN_SUPPORT + t_u8 Reserved17_23:7; // ! Reserved + t_u8 Schedule:1; + IEEEtypes_WMM_TSPEC_TS_Info_AckPolicy_e AckPolicy:2; + t_u8 UserPri:3; // ! 802.1d User Priority + IEEEtypes_WMM_TSPEC_TS_Info_PSB_e PowerSaveBehavior:1; // ! + // Legacy/Trigg + t_u8 Aggregation:1; // ! Reserved + t_u8 AccessPolicy2:1; // ! + t_u8 AccessPolicy1:1; // ! + IEEEtypes_WMM_TSPEC_TS_Info_Direction_e Direction:2; + t_u8 TID:4; // ! Unique identifier + IEEEtypes_WMM_TSPEC_TS_TRAFFIC_TYPE_e TrafficType:1; +#else + IEEEtypes_WMM_TSPEC_TS_TRAFFIC_TYPE_e TrafficType:1; + t_u8 TID:4; // ! Unique identifier + IEEEtypes_WMM_TSPEC_TS_Info_Direction_e Direction:2; + t_u8 AccessPolicy1:1; // ! + t_u8 AccessPolicy2:1; // ! + t_u8 Aggregation:1; // ! Reserved + IEEEtypes_WMM_TSPEC_TS_Info_PSB_e PowerSaveBehavior:1; // ! + // Legacy/Trigg + t_u8 UserPri:3; // ! 802.1d User Priority + IEEEtypes_WMM_TSPEC_TS_Info_AckPolicy_e AckPolicy:2; + t_u8 Schedule:1; + t_u8 Reserved17_23:7; // ! Reserved +#endif +} MLAN_PACK_END IEEEtypes_WMM_TSPEC_TS_Info_t; + +/** Data structure of WMM TSPEC Nominal Size */ +typedef MLAN_PACK_START struct +{ +#ifdef BIG_ENDIAN_SUPPORT + t_u16 Fixed:1; // ! 1: Fixed size given in Size, 0: Var, size + // is nominal + t_u16 Size:15; // ! Nominal size in octets +#else + t_u16 Size:15; // ! Nominal size in octets + t_u16 Fixed:1; // ! 1: Fixed size given in Size, 0: Var, size + // is nominal +#endif +} MLAN_PACK_END IEEEtypes_WMM_TSPEC_NomMSDUSize_t; + +/** Data structure of WMM TSPEC SBWA */ +typedef MLAN_PACK_START struct +{ +#ifdef BIG_ENDIAN_SUPPORT + t_u16 Whole:3; // ! Whole portion + t_u16 Fractional:13; // ! Fractional portion +#else + t_u16 Fractional:13; // ! Fractional portion + t_u16 Whole:3; // ! Whole portion +#endif +} MLAN_PACK_END IEEEtypes_WMM_TSPEC_SBWA; + +/** Data structure of WMM TSPEC Body */ +typedef MLAN_PACK_START struct +{ + + IEEEtypes_WMM_TSPEC_TS_Info_t TSInfo; + IEEEtypes_WMM_TSPEC_NomMSDUSize_t NomMSDUSize; + t_u16 MaximumMSDUSize; + t_u32 MinServiceInterval; + t_u32 MaxServiceInterval; + t_u32 InactivityInterval; + t_u32 SuspensionInterval; + t_u32 ServiceStartTime; + t_u32 MinimumDataRate; + t_u32 MeanDataRate; + t_u32 PeakDataRate; + t_u32 MaxBurstSize; + t_u32 DelayBound; + t_u32 MinPHYRate; + IEEEtypes_WMM_TSPEC_SBWA SurplusBWAllowance; + t_u16 MediumTime; +} MLAN_PACK_END IEEEtypes_WMM_TSPEC_Body_t; + +/** Data structure of WMM TSPEC all elements */ +typedef MLAN_PACK_START struct +{ + t_u8 ElementId; + t_u8 Len; + t_u8 OuiType[4]; /* 00:50:f2:02 */ + t_u8 OuiSubType; /* 01 */ + t_u8 Version; + + IEEEtypes_WMM_TSPEC_Body_t TspecBody; + +} MLAN_PACK_END IEEEtypes_WMM_TSPEC_t; + +/** WMM Action Category values */ +typedef MLAN_PACK_START enum _IEEEtypes_ActionCategory_e +{ + + IEEE_MGMT_ACTION_CATEGORY_SPECTRUM_MGMT = 0, + IEEE_MGMT_ACTION_CATEGORY_QOS = 1, + IEEE_MGMT_ACTION_CATEGORY_DLS = 2, + IEEE_MGMT_ACTION_CATEGORY_BLOCK_ACK = 3, + IEEE_MGMT_ACTION_CATEGORY_PUBLIC = 4, + IEEE_MGMT_ACTION_CATEGORY_RADIO_RSRC = 5, + IEEE_MGMT_ACTION_CATEGORY_FAST_BSS_TRANS = 6, + IEEE_MGMT_ACTION_CATEGORY_HT = 7, + + IEEE_MGMT_ACTION_CATEGORY_WNM = 10, + IEEE_MGMT_ACTION_CATEGORY_UNPROTECT_WNM = 11, + + IEEE_MGMT_ACTION_CATEGORY_WMM_TSPEC = 17 +} MLAN_PACK_END IEEEtypes_ActionCategory_e; + +/** WMM TSPEC operations */ +typedef MLAN_PACK_START enum _IEEEtypes_WMM_Tspec_Action_e +{ + + TSPEC_ACTION_CODE_ADDTS_REQ = 0, + TSPEC_ACTION_CODE_ADDTS_RSP = 1, + TSPEC_ACTION_CODE_DELTS = 2, + +} MLAN_PACK_END IEEEtypes_WMM_Tspec_Action_e; + +/** WMM TSPEC Category Action Base */ +typedef MLAN_PACK_START struct +{ + + IEEEtypes_ActionCategory_e category; + IEEEtypes_WMM_Tspec_Action_e action; + t_u8 dialogToken; + +} MLAN_PACK_END IEEEtypes_WMM_Tspec_Action_Base_Tspec_t; + +/** WMM TSPEC AddTS request structure */ +typedef MLAN_PACK_START struct +{ + + IEEEtypes_WMM_Tspec_Action_Base_Tspec_t tspecAct; + t_u8 statusCode; + IEEEtypes_WMM_TSPEC_t tspecIE; + + /* Place holder for additional elements after the TSPEC */ + t_u8 subElem[256]; + +} MLAN_PACK_END IEEEtypes_Action_WMM_AddTsReq_t; + +/** WMM TSPEC AddTS response structure */ +typedef MLAN_PACK_START struct +{ + IEEEtypes_WMM_Tspec_Action_Base_Tspec_t tspecAct; + t_u8 statusCode; + IEEEtypes_WMM_TSPEC_t tspecIE; + + /* Place holder for additional elements after the TSPEC */ + t_u8 subElem[256]; + +} MLAN_PACK_END IEEEtypes_Action_WMM_AddTsRsp_t; + +/** WMM TSPEC DelTS structure */ +typedef MLAN_PACK_START struct +{ + IEEEtypes_WMM_Tspec_Action_Base_Tspec_t tspecAct; + t_u8 reasonCode; + IEEEtypes_WMM_TSPEC_t tspecIE; + +} MLAN_PACK_END IEEEtypes_Action_WMM_DelTs_t; + +/** union of WMM TSPEC structures */ +typedef MLAN_PACK_START union +{ + IEEEtypes_WMM_Tspec_Action_Base_Tspec_t tspecAct; + + IEEEtypes_Action_WMM_AddTsReq_t addTsReq; + IEEEtypes_Action_WMM_AddTsRsp_t addTsRsp; + IEEEtypes_Action_WMM_DelTs_t delTs; + +} MLAN_PACK_END IEEEtypes_Action_WMMAC_t; + +/** union of WMM TSPEC & Action category */ +typedef MLAN_PACK_START union +{ + IEEEtypes_ActionCategory_e category; + + IEEEtypes_Action_WMMAC_t wmmAc; + +} MLAN_PACK_END IEEEtypes_ActionFrame_t; + +/** Data structure for subband set */ +typedef MLAN_PACK_START struct _IEEEtypes_SubbandSet_t +{ + /** First channel */ + t_u8 first_chan; + /** Number of channels */ + t_u8 no_of_chan; + /** Maximum Tx power in dBm */ + t_u8 max_tx_pwr; +} MLAN_PACK_END IEEEtypes_SubbandSet_t, *pIEEEtypes_SubbandSet_t; + +#ifdef STA_SUPPORT +/** Data structure for Country IE */ +typedef MLAN_PACK_START struct _IEEEtypes_CountryInfoSet_t +{ + /** Element ID */ + t_u8 element_id; + /** Length */ + t_u8 len; + /** Country code */ + t_u8 country_code[COUNTRY_CODE_LEN]; + /** Set of subbands */ + IEEEtypes_SubbandSet_t sub_band[1]; +} MLAN_PACK_END IEEEtypes_CountryInfoSet_t, *pIEEEtypes_CountryInfoSet_t; + +/** Data structure for Country IE full set */ +typedef MLAN_PACK_START struct _IEEEtypes_CountryInfoFullSet_t +{ + /** Element ID */ + t_u8 element_id; + /** Length */ + t_u8 len; + /** Country code */ + t_u8 country_code[COUNTRY_CODE_LEN]; + /** Set of subbands */ + IEEEtypes_SubbandSet_t sub_band[MRVDRV_MAX_SUBBAND_802_11D]; +} MLAN_PACK_END IEEEtypes_CountryInfoFullSet_t, + *pIEEEtypes_CountryInfoFullSet_t; + +#endif /* STA_SUPPORT */ + +/** HT Capabilities Data */ +typedef struct MLAN_PACK_START _HTCap_t +{ + /** HT Capabilities Info field */ + t_u16 ht_cap_info; + /** A-MPDU Parameters field */ + t_u8 ampdu_param; + /** Supported MCS Set field */ + t_u8 supported_mcs_set[16]; + /** HT Extended Capabilities field */ + t_u16 ht_ext_cap; + /** Transmit Beamforming Capabilities field */ + t_u32 tx_bf_cap; + /** Antenna Selection Capability field */ + t_u8 asel; +} MLAN_PACK_END HTCap_t, *pHTCap_t; + +/** HT Information Data */ +typedef struct MLAN_PACK_START _HTInfo_t +{ + /** Primary channel */ + t_u8 pri_chan; + /** Field 2 */ + t_u8 field2; + /** Field 3 */ + t_u16 field3; + /** Field 4 */ + t_u16 field4; + /** Bitmap indicating MCSs supported by all HT STAs in the BSS */ + t_u8 basic_mcs_set[16]; +} MLAN_PACK_END HTInfo_t, *pHTInfo_t; + +/** 20/40 BSS Coexistence Data */ +typedef struct MLAN_PACK_START _BSSCo2040_t +{ + /** 20/40 BSS Coexistence value */ + t_u8 bss_co_2040_value; +} MLAN_PACK_END BSSCo2040_t, *pBSSCo2040_t; + +/** Extended Capabilities Data */ +typedef struct MLAN_PACK_START _ExtCap_t +{ + /** Extended Capabilities value */ + t_u8 ext_cap_value; +} MLAN_PACK_END ExtCap_t, *pExtCap_t; + +/** Overlapping BSS Scan Parameters Data */ +typedef struct MLAN_PACK_START _OverlapBSSScanParam_t +{ + /** OBSS Scan Passive Dwell in milliseconds */ + t_u16 obss_scan_passive_dwell; + /** OBSS Scan Active Dwell in milliseconds */ + t_u16 obss_scan_active_dwell; + /** BSS Channel Width Trigger Scan Interval in seconds */ + t_u16 bss_chan_width_trigger_scan_int; + /** OBSS Scan Passive Total Per Channel */ + t_u16 obss_scan_passive_total; + /** OBSS Scan Active Total Per Channel */ + t_u16 obss_scan_active_total; + /** BSS Width Channel Transition Delay Factor */ + t_u16 bss_width_chan_trans_delay; + /** OBSS Scan Activity Threshold */ + t_u16 obss_scan_active_threshold; +} MLAN_PACK_END OBSSScanParam_t, *pOBSSScanParam_t; + +/** HT Capabilities IE */ +typedef MLAN_PACK_START struct _IEEEtypes_HTCap_t +{ + /** Generic IE header */ + IEEEtypes_Header_t ieee_hdr; + /** HTCap struct */ + HTCap_t ht_cap; +} MLAN_PACK_END IEEEtypes_HTCap_t, *pIEEEtypes_HTCap_t; + +/** HT Information IE */ +typedef MLAN_PACK_START struct _IEEEtypes_HTInfo_t +{ + /** Generic IE header */ + IEEEtypes_Header_t ieee_hdr; + /** HTInfo struct */ + HTInfo_t ht_info; +} MLAN_PACK_END IEEEtypes_HTInfo_t, *pIEEEtypes_HTInfo_t; + +/** 20/40 BSS Coexistence IE */ +typedef MLAN_PACK_START struct _IEEEtypes_2040BSSCo_t +{ + /** Generic IE header */ + IEEEtypes_Header_t ieee_hdr; + /** BSSCo2040_t struct */ + BSSCo2040_t bss_co_2040; +} MLAN_PACK_END IEEEtypes_2040BSSCo_t, *pIEEEtypes_2040BSSCo_t; + +/** Extended Capabilities IE */ +typedef MLAN_PACK_START struct _IEEEtypes_ExtCap_t +{ + /** Generic IE header */ + IEEEtypes_Header_t ieee_hdr; + /** ExtCap_t struct */ + ExtCap_t ext_cap; +} MLAN_PACK_END IEEEtypes_ExtCap_t, *pIEEEtypes_ExtCap_t; + +/** Overlapping BSS Scan Parameters IE */ +typedef MLAN_PACK_START struct _IEEEtypes_OverlapBSSScanParam_t +{ + /** Generic IE header */ + IEEEtypes_Header_t ieee_hdr; + /** OBSSScanParam_t struct */ + OBSSScanParam_t obss_scan_param; +} MLAN_PACK_END IEEEtypes_OverlapBSSScanParam_t, + *pIEEEtypes_OverlapBSSScanParam_t; + +/** Maximum number of subbands in the IEEEtypes_SupportedChannels_t structure */ +#define WLAN_11H_MAX_SUBBANDS 5 + +/** Maximum number of DFS channels configured in IEEEtypes_IBSS_DFS_t */ +#define WLAN_11H_MAX_IBSS_DFS_CHANNELS 25 + +/** IEEE Power Constraint element (7.3.2.15) */ +typedef MLAN_PACK_START struct +{ + t_u8 element_id; /**< IEEE Element ID = 32 */ + t_u8 len; /**< Element length after id and len */ + t_u8 local_constraint; /**< Local power constraint applied to 11d chan info */ +} MLAN_PACK_END IEEEtypes_PowerConstraint_t; + +/** IEEE Power Capability element (7.3.2.16) */ +typedef MLAN_PACK_START struct +{ + t_u8 element_id; /**< IEEE Element ID = 33 */ + t_u8 len; /**< Element length after id and len */ + t_s8 min_tx_power_capability; /**< Minimum Transmit power (dBm) */ + t_s8 max_tx_power_capability; /**< Maximum Transmit power (dBm) */ +} MLAN_PACK_END IEEEtypes_PowerCapability_t; + +/** IEEE TPC Report element (7.3.2.18) */ +typedef MLAN_PACK_START struct +{ + t_u8 element_id; /**< IEEE Element ID = 35 */ + t_u8 len; /**< Element length after id and len */ + t_s8 tx_power; /**< Max power used to transmit the TPC Report frame (dBm) */ + t_s8 link_margin; /**< Link margin when TPC Request received (dB) */ +} MLAN_PACK_END IEEEtypes_TPCReport_t; + +/* IEEE Supported Channel sub-band description (7.3.2.19) */ +/** + * Sub-band description used in the supported channels element. + */ +typedef MLAN_PACK_START struct +{ + t_u8 start_chan; /**< Starting channel in the subband */ + t_u8 num_chans; /**< Number of channels in the subband */ + +} MLAN_PACK_END IEEEtypes_SupportChan_Subband_t; + +/* IEEE Supported Channel element (7.3.2.19) */ +/** + * Sent in association requests. Details the sub-bands and number + * of channels supported in each subband + */ +typedef MLAN_PACK_START struct +{ + t_u8 element_id; /**< IEEE Element ID = 36 */ + t_u8 len; /**< Element length after id and len */ + + /** Configured sub-bands information in the element */ + IEEEtypes_SupportChan_Subband_t subband[WLAN_11H_MAX_SUBBANDS]; + +} MLAN_PACK_END IEEEtypes_SupportedChannels_t; + +/* IEEE Channel Switch Announcement Element (7.3.2.20) */ +/** + * Provided in beacons and probe responses. Used to advertise when + * and to which channel it is changing to. Only starting STAs in + * an IBSS and APs are allowed to originate a chan switch element. + */ +typedef MLAN_PACK_START struct +{ + t_u8 element_id; /**< IEEE Element ID = 37 */ + t_u8 len; /**< Element length after id and len */ + t_u8 chan_switch_mode; /**< STA should not transmit any frames if 1 */ + t_u8 new_channel_num; /**< Channel # that AP/IBSS is moving to */ + t_u8 chan_switch_count; /**< # of TBTTs before channel switch */ + +} MLAN_PACK_END IEEEtypes_ChanSwitchAnn_t; + +/* IEEE Quiet Period Element (7.3.2.23) */ +/** + * Provided in beacons and probe responses. Indicates times during + * which the STA should not be transmitting data. Only starting STAs in + * an IBSS and APs are allowed to originate a quiet element. + */ +typedef MLAN_PACK_START struct +{ + t_u8 element_id; /**< IEEE Element ID = 40 */ + t_u8 len; /**< Element length after id and len */ + t_u8 quiet_count; /**< Number of TBTTs until beacon with the quiet period */ + t_u8 quiet_period; /**< Regular quiet period, # of TBTTS between periods */ + t_u16 quiet_duration; /**< Duration of the quiet period in TUs */ + t_u16 quiet_offset; /**< Offset in TUs from the TBTT for the quiet period */ + +} MLAN_PACK_END IEEEtypes_Quiet_t; + +/** +*** @brief Map octet of the basic measurement report (7.3.2.22.1) +**/ +typedef MLAN_PACK_START struct +{ +#ifdef BIG_ENDIAN_SUPPORT + t_u8 rsvd5_7:3; /**< Reserved */ + t_u8 unmeasured:1; /**< Channel is unmeasured */ + t_u8 radar:1; /**< Radar detected on channel */ + t_u8 unidentified_sig:1; /**< Unidentified signal found on channel */ + t_u8 ofdm_preamble:1; /**< OFDM preamble detected on channel */ + t_u8 bss:1; /**< At least one valid MPDU received on channel */ +#else + t_u8 bss:1; /**< At least one valid MPDU received on channel */ + t_u8 ofdm_preamble:1; /**< OFDM preamble detected on channel */ + t_u8 unidentified_sig:1; /**< Unidentified signal found on channel */ + t_u8 radar:1; /**< Radar detected on channel */ + t_u8 unmeasured:1; /**< Channel is unmeasured */ + t_u8 rsvd5_7:3; /**< Reserved */ +#endif /* BIG_ENDIAN_SUPPORT */ + +} MLAN_PACK_END MeasRptBasicMap_t; + +/* IEEE DFS Channel Map field (7.3.2.24) */ +/** + * Used to list supported channels and provide a octet "map" field which + * contains a basic measurement report for that channel in the + * IEEEtypes_IBSS_DFS_t element + */ +typedef MLAN_PACK_START struct +{ + t_u8 channel_number; /**< Channel number */ + MeasRptBasicMap_t rpt_map; /**< Basic measurement report for the channel */ + +} MLAN_PACK_END IEEEtypes_ChannelMap_t; + +/* IEEE IBSS DFS Element (7.3.2.24) */ +/** + * IBSS DFS element included in ad hoc beacons and probe responses. + * Provides information regarding the IBSS DFS Owner as well as the + * originating STAs supported channels and basic measurement results. + */ +typedef MLAN_PACK_START struct +{ + t_u8 element_id; /**< IEEE Element ID = 41 */ + t_u8 len; /**< Element length after id and len */ + t_u8 dfs_owner[MLAN_MAC_ADDR_LENGTH]; /**< DFS Owner STA Address */ + t_u8 dfs_recovery_interval; /**< DFS Recovery time in TBTTs */ + + /** Variable length map field, one Map entry for each supported channel */ + IEEEtypes_ChannelMap_t channel_map[WLAN_11H_MAX_IBSS_DFS_CHANNELS]; + +} MLAN_PACK_END IEEEtypes_IBSS_DFS_t; + +/* 802.11h BSS information kept for each BSSID received in scan results */ +/** + * IEEE BSS information needed from scan results for later processing in + * join commands + */ +typedef struct +{ + t_u8 sensed_11h; /**< Capability bit set or 11h IE found in this BSS */ + + IEEEtypes_PowerConstraint_t power_constraint; /**< Power Constraint IE */ + IEEEtypes_PowerCapability_t power_capability; /**< Power Capability IE */ + IEEEtypes_TPCReport_t tpc_report; /**< TPC Report IE */ + IEEEtypes_ChanSwitchAnn_t chan_switch_ann; /**< Channel Switch Announcement IE */ + IEEEtypes_Quiet_t quiet; /**< Quiet IE */ + IEEEtypes_IBSS_DFS_t ibss_dfs; /**< IBSS DFS Element IE */ + +} wlan_11h_bss_info_t; + +#ifdef STA_SUPPORT +/** Macro for maximum size of scan response buffer */ +#define MAX_SCAN_RSP_BUF (16 * 1024) + +/** Maximum number of channels that can be sent in user scan config */ +#define WLAN_USER_SCAN_CHAN_MAX 50 + +/** Maximum length of SSID list */ +#define MRVDRV_MAX_SSID_LIST_LENGTH 10 + +/** Scan all the channels in specified band */ +#define BAND_SPECIFIED 0x80 + +/** + * IOCTL SSID List sub-structure sent in wlan_ioctl_user_scan_cfg + * + * Used to specify SSID specific filters as well as SSID pattern matching + * filters for scan result processing in firmware. + */ +typedef MLAN_PACK_START struct _wlan_user_scan_ssid +{ + /** SSID */ + t_u8 ssid[MLAN_MAX_SSID_LENGTH + 1]; + /** Maximum length of SSID */ + t_u8 max_len; +} MLAN_PACK_END wlan_user_scan_ssid; + +/** + * @brief IOCTL channel sub-structure sent in wlan_ioctl_user_scan_cfg + * + * Multiple instances of this structure are included in the IOCTL command + * to configure a instance of a scan on the specific channel. + */ +typedef MLAN_PACK_START struct _wlan_user_scan_chan +{ + /** Channel Number to scan */ + t_u8 chan_number; + /** Radio type: 'B/G' Band = 0, 'A' Band = 1 */ + t_u8 radio_type; + /** Scan type: Active = 1, Passive = 2 */ + t_u8 scan_type; + /** Reserved */ + t_u8 reserved; + /** Scan duration in milliseconds; if 0 default used */ + t_u32 scan_time; +} MLAN_PACK_END wlan_user_scan_chan; + +/** + * Input structure to configure an immediate scan cmd to firmware + * + * Specifies a number of parameters to be used in general for the scan + * as well as a channel list (wlan_user_scan_chan) for each scan period + * desired. + */ +typedef MLAN_PACK_START struct +{ + /** + * Flag set to keep the previous scan table intact + * + * If set, the scan results will accumulate, replacing any previous + * matched entries for a BSS with the new scan data + */ + t_u8 keep_previous_scan; + /** + * BSS mode to be sent in the firmware command + * + * Field can be used to restrict the types of networks returned in the + * scan. Valid settings are: + * + * - MLAN_SCAN_MODE_BSS (infrastructure) + * - MLAN_SCAN_MODE_IBSS (adhoc) + * - MLAN_SCAN_MODE_ANY (unrestricted, adhoc and infrastructure) + */ + t_u8 bss_mode; + /** + * Configure the number of probe requests for active chan scans + */ + t_u8 num_probes; + /** + * @brief Reserved + */ + t_u8 reserved; + /** + * @brief BSSID filter sent in the firmware command to limit the results + */ + t_u8 specific_bssid[MLAN_MAC_ADDR_LENGTH]; + /** + * SSID filter list used in the to limit the scan results + */ + wlan_user_scan_ssid ssid_list[MRVDRV_MAX_SSID_LIST_LENGTH]; + /** + * Variable number (fixed maximum) of channels to scan up + */ + wlan_user_scan_chan chan_list[WLAN_USER_SCAN_CHAN_MAX]; +} MLAN_PACK_END wlan_user_scan_cfg; + +/** Default scan interval in millisecond*/ +#define DEFAULT_BGSCAN_INTERVAL 30000 + +/** action get all, except pps/uapsd config */ +#define BG_SCAN_ACT_GET 0x0000 +/** action set all, except pps/uapsd config */ +#define BG_SCAN_ACT_SET 0x0001 +/** action get pps/uapsd config */ +#define BG_SCAN_ACT_GET_PPS_UAPSD 0x0100 +/** action set pps/uapsd config */ +#define BG_SCAN_ACT_SET_PPS_UAPSD 0x0101 +/** action set all */ +#define BG_SCAN_ACT_SET_ALL 0xff01 +/** ssid match */ +#define BG_SCAN_SSID_MATCH 0x0001 +/** ssid match and RSSI exceeded */ +#define BG_SCAN_SSID_RSSI_MATCH 0x0004 +/** Maximum number of channels that can be sent in bg scan config */ +#define WLAN_BG_SCAN_CHAN_MAX 32 + +/** + * Input structure to configure bs scan cmd to firmware + */ +typedef MLAN_PACK_START struct +{ + /** action */ + t_u16 action; + /** enable/disable */ + t_u8 enable; + /** BSS type: + * MLAN_SCAN_MODE_BSS (infrastructure) + * MLAN_SCAN_MODE_IBSS (adhoc) + * MLAN_SCAN_MODE_ANY (unrestricted, adhoc and infrastructure) + */ + t_u8 bss_type; + /** number of channel scanned during each scan */ + t_u8 chan_per_scan; + /** interval between consecutive scan */ + t_u32 scan_interval; + /** bit 0: ssid match bit 1: ssid match and SNR exceeded + * bit 2: ssid match and RSSI exceeded + * bit 31: wait for all channel scan to complete to report scan result + */ + t_u32 report_condition; + /* Configure the number of probe requests for active chan scans */ + t_u8 num_probes; + /** RSSI threshold */ + t_u8 rssi_threshold; + /** SNR threshold */ + t_u8 snr_threshold; + /** repeat count */ + t_u16 repeat_count; + /** SSID filter list used in the to limit the scan results */ + wlan_user_scan_ssid ssid_list[MRVDRV_MAX_SSID_LIST_LENGTH]; + /** Variable number (fixed maximum) of channels to scan up */ + wlan_user_scan_chan chan_list[WLAN_BG_SCAN_CHAN_MAX]; +} MLAN_PACK_END wlan_bgscan_cfg; +#endif /* STA_SUPPORT */ + +#ifdef PRAGMA_PACK +#pragma pack(pop) +#endif + +/** BSSDescriptor_t + * Structure used to store information for beacon/probe response + */ +typedef struct _BSSDescriptor_t +{ + /** MAC address */ + mlan_802_11_mac_addr mac_address; + + /** SSID */ + mlan_802_11_ssid ssid; + + /** WEP encryption requirement */ + t_u32 privacy; + + /** Receive signal strength in dBm */ + t_s32 rssi; + + /** Channel */ + t_u32 channel; + + /** Freq */ + t_u32 freq; + + /** Beacon period */ + t_u16 beacon_period; + + /** ATIM window */ + t_u32 atim_window; + + /** ERP flags */ + t_u8 erp_flags; + + /** Type of network in use */ + WLAN_802_11_NETWORK_TYPE network_type_use; + + /** Network infrastructure mode */ + t_u32 bss_mode; + + /** Network supported rates */ + WLAN_802_11_RATES supported_rates; + + /** Supported data rates */ + t_u8 data_rates[WLAN_SUPPORTED_RATES]; + + /** Network band. + * BAND_B(0x01): 'b' band + * BAND_G(0x02): 'g' band + * BAND_A(0X04): 'a' band + */ + t_u16 bss_band; + + /** TSF timestamp from the current firmware TSF */ + t_u64 network_tsf; + + /** TSF value included in the beacon/probe response */ + t_u8 time_stamp[8]; + + /** PHY parameter set */ + IEEEtypes_PhyParamSet_t phy_param_set; + + /** SS parameter set */ + IEEEtypes_SsParamSet_t ss_param_set; + + /** Capability information */ + IEEEtypes_CapInfo_t cap_info; + + /** WMM IE */ + IEEEtypes_WmmParameter_t wmm_ie; + + /** 802.11h BSS information */ + wlan_11h_bss_info_t wlan_11h_bss_info; + + /** Indicate disabling 11n when associate with AP */ + t_u8 disable_11n; + /** 802.11n BSS information */ + /** HT Capabilities IE */ + IEEEtypes_HTCap_t *pht_cap; + /** HT Capabilities Offset */ + t_u16 ht_cap_offset; + /** HT Information IE */ + IEEEtypes_HTInfo_t *pht_info; + /** HT Information Offset */ + t_u16 ht_info_offset; + /** 20/40 BSS Coexistence IE */ + IEEEtypes_2040BSSCo_t *pbss_co_2040; + /** 20/40 BSS Coexistence Offset */ + t_u16 bss_co_2040_offset; + /** Extended Capabilities IE */ + IEEEtypes_ExtCap_t *pext_cap; + /** Extended Capabilities Offset */ + t_u16 ext_cap_offset; + /** Overlapping BSS Scan Parameters IE */ + IEEEtypes_OverlapBSSScanParam_t *poverlap_bss_scan_param; + /** Overlapping BSS Scan Parameters Offset */ + t_u16 overlap_bss_offset; + +#ifdef STA_SUPPORT + /** Country information set */ + IEEEtypes_CountryInfoFullSet_t country_info; +#endif /* STA_SUPPORT */ + + /** WPA IE */ + IEEEtypes_VendorSpecific_t *pwpa_ie; + /** WPA IE offset in the beacon buffer */ + t_u16 wpa_offset; + /** RSN IE */ + IEEEtypes_Generic_t *prsn_ie; + /** RSN IE offset in the beacon buffer */ + t_u16 rsn_offset; +#ifdef STA_SUPPORT + /** WAPI IE */ + IEEEtypes_Generic_t *pwapi_ie; + /** WAPI IE offset in the beacon buffer */ + t_u16 wapi_offset; +#endif + + /** Pointer to the returned scan response */ + t_u8 *pbeacon_buf; + /** Length of the stored scan response */ + t_u32 beacon_buf_size; + /** Max allocated size for updated scan response */ + t_u32 beacon_buf_size_max; + +} BSSDescriptor_t, *pBSSDescriptor_t; + +#endif /* !_MLAN_IEEE_H_ */ diff --git a/drivers/net/wireless/sd8797/mlinux/mlan_ioctl.h b/drivers/net/wireless/sd8797/mlinux/mlan_ioctl.h new file mode 100644 index 000000000000..964de9197ffe --- /dev/null +++ b/drivers/net/wireless/sd8797/mlinux/mlan_ioctl.h @@ -0,0 +1,2981 @@ +/** @file mlan_ioctl.h + * + * @brief This file declares the IOCTL data structures and APIs. + * + * Copyright (C) 2008-2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +/****************************************************** +Change log: + 11/07/2008: initial version +******************************************************/ + +#ifndef _MLAN_IOCTL_H_ +#define _MLAN_IOCTL_H_ + +/** Enumeration for IOCTL request ID */ +enum _mlan_ioctl_req_id +{ + /* Scan Group */ + MLAN_IOCTL_SCAN = 0x00010000, + MLAN_OID_SCAN_NORMAL, + MLAN_OID_SCAN_SPECIFIC_SSID, + MLAN_OID_SCAN_USER_CONFIG, + MLAN_OID_SCAN_CONFIG, + MLAN_OID_SCAN_GET_CURRENT_BSS, + MLAN_OID_SCAN_CANCEL, + MLAN_OID_SCAN_TABLE_FLUSH, + MLAN_OID_SCAN_BGSCAN_CONFIG, + /* BSS Configuration Group */ + MLAN_IOCTL_BSS = 0x00020000, + MLAN_OID_BSS_START, + MLAN_OID_BSS_STOP, + MLAN_OID_BSS_MODE, + MLAN_OID_BSS_CHANNEL, + MLAN_OID_BSS_CHANNEL_LIST, + MLAN_OID_BSS_MAC_ADDR, + MLAN_OID_BSS_MULTICAST_LIST, + MLAN_OID_BSS_FIND_BSS, + MLAN_OID_IBSS_BCN_INTERVAL, + MLAN_OID_IBSS_ATIM_WINDOW, + MLAN_OID_IBSS_CHANNEL, +#ifdef UAP_SUPPORT + MLAN_OID_UAP_BSS_CONFIG, + MLAN_OID_UAP_DEAUTH_STA, + MLAN_OID_UAP_BSS_RESET, +#endif +#if defined(STA_SUPPORT) && defined(UAP_SUPPORT) + MLAN_OID_BSS_ROLE, +#endif +#ifdef WIFI_DIRECT_SUPPORT + MLAN_OID_WIFI_DIRECT_MODE, +#endif + + /* Radio Configuration Group */ + MLAN_IOCTL_RADIO_CFG = 0x00030000, + MLAN_OID_RADIO_CTRL, + MLAN_OID_BAND_CFG, + MLAN_OID_ANT_CFG, +#ifdef WIFI_DIRECT_SUPPORT + MLAN_OID_REMAIN_CHAN_CFG, +#endif + + /* SNMP MIB Group */ + MLAN_IOCTL_SNMP_MIB = 0x00040000, + MLAN_OID_SNMP_MIB_RTS_THRESHOLD, + MLAN_OID_SNMP_MIB_FRAG_THRESHOLD, + MLAN_OID_SNMP_MIB_RETRY_COUNT, +#if defined(UAP_SUPPORT) + MLAN_OID_SNMP_MIB_DOT11D, + MLAN_OID_SNMP_MIB_DOT11H, +#endif + MLAN_OID_SNMP_MIB_DTIM_PERIOD, + + /* Status Information Group */ + MLAN_IOCTL_GET_INFO = 0x00050000, + MLAN_OID_GET_STATS, + MLAN_OID_GET_SIGNAL, + MLAN_OID_GET_FW_INFO, + MLAN_OID_GET_VER_EXT, + MLAN_OID_GET_BSS_INFO, + MLAN_OID_GET_DEBUG_INFO, +#ifdef UAP_SUPPORT + MLAN_OID_UAP_STA_LIST, +#endif + + /* Security Configuration Group */ + MLAN_IOCTL_SEC_CFG = 0x00060000, + MLAN_OID_SEC_CFG_AUTH_MODE, + MLAN_OID_SEC_CFG_ENCRYPT_MODE, + MLAN_OID_SEC_CFG_WPA_ENABLED, + MLAN_OID_SEC_CFG_ENCRYPT_KEY, + MLAN_OID_SEC_CFG_PASSPHRASE, + MLAN_OID_SEC_CFG_EWPA_ENABLED, + MLAN_OID_SEC_CFG_ESUPP_MODE, + MLAN_OID_SEC_CFG_WAPI_ENABLED, + MLAN_OID_SEC_CFG_PORT_CTRL_ENABLED, + + /* Rate Group */ + MLAN_IOCTL_RATE = 0x00070000, + MLAN_OID_RATE_CFG, + MLAN_OID_GET_DATA_RATE, + MLAN_OID_SUPPORTED_RATES, + + /* Power Configuration Group */ + MLAN_IOCTL_POWER_CFG = 0x00080000, + MLAN_OID_POWER_CFG, + MLAN_OID_POWER_CFG_EXT, + + /* Power Management Configuration Group */ + MLAN_IOCTL_PM_CFG = 0x00090000, + MLAN_OID_PM_CFG_IEEE_PS, + MLAN_OID_PM_CFG_HS_CFG, + MLAN_OID_PM_CFG_INACTIVITY_TO, + MLAN_OID_PM_CFG_DEEP_SLEEP, + MLAN_OID_PM_CFG_SLEEP_PD, + MLAN_OID_PM_CFG_PS_CFG, + MLAN_OID_PM_CFG_SLEEP_PARAMS, +#ifdef UAP_SUPPORT + MLAN_OID_PM_CFG_PS_MODE, +#endif /* UAP_SUPPORT */ + MLAN_OID_PM_INFO, + + /* WMM Configuration Group */ + MLAN_IOCTL_WMM_CFG = 0x000A0000, + MLAN_OID_WMM_CFG_ENABLE, + MLAN_OID_WMM_CFG_QOS, + MLAN_OID_WMM_CFG_ADDTS, + MLAN_OID_WMM_CFG_DELTS, + MLAN_OID_WMM_CFG_QUEUE_CONFIG, + MLAN_OID_WMM_CFG_QUEUE_STATS, + MLAN_OID_WMM_CFG_QUEUE_STATUS, + MLAN_OID_WMM_CFG_TS_STATUS, + + /* WPS Configuration Group */ + MLAN_IOCTL_WPS_CFG = 0x000B0000, + MLAN_OID_WPS_CFG_SESSION, + + /* 802.11n Configuration Group */ + MLAN_IOCTL_11N_CFG = 0x000C0000, + MLAN_OID_11N_CFG_TX, + MLAN_OID_11N_HTCAP_CFG, + MLAN_OID_11N_CFG_ADDBA_REJECT, + MLAN_OID_11N_CFG_AGGR_PRIO_TBL, + MLAN_OID_11N_CFG_ADDBA_PARAM, + MLAN_OID_11N_CFG_MAX_TX_BUF_SIZE, + MLAN_OID_11N_CFG_AMSDU_AGGR_CTRL, + MLAN_OID_11N_CFG_SUPPORTED_MCS_SET, + MLAN_OID_11N_CFG_TX_BF_CAP, + MLAN_OID_11N_CFG_TX_BF_CFG, + MLAN_OID_11N_CFG_STREAM_CFG, + + /* 802.11d Configuration Group */ + MLAN_IOCTL_11D_CFG = 0x000D0000, +#ifdef STA_SUPPORT + MLAN_OID_11D_CFG_ENABLE, + MLAN_OID_11D_CLR_CHAN_TABLE, +#endif /* STA_SUPPORT */ + MLAN_OID_11D_DOMAIN_INFO, + + /* Register Memory Access Group */ + MLAN_IOCTL_REG_MEM = 0x000E0000, + MLAN_OID_REG_RW, + MLAN_OID_EEPROM_RD, + MLAN_OID_MEM_RW, + + /* Multi-Radio Configuration Group */ + MLAN_IOCTL_MFR_CFG = 0x00100000, + + /* 802.11h Configuration Group */ + MLAN_IOCTL_11H_CFG = 0x00110000, + MLAN_OID_11H_CHANNEL_CHECK, + MLAN_OID_11H_LOCAL_POWER_CONSTRAINT, +#if defined(DFS_TESTING_SUPPORT) + MLAN_OID_11H_DFS_TESTING, +#endif + + /* Miscellaneous Configuration Group */ + MLAN_IOCTL_MISC_CFG = 0x00200000, + MLAN_OID_MISC_GEN_IE, + MLAN_OID_MISC_REGION, + MLAN_OID_MISC_WARM_RESET, +#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR) + MLAN_OID_MISC_SDIO_MPA_CTRL, +#endif + MLAN_OID_MISC_HOST_CMD, + MLAN_OID_MISC_SYS_CLOCK, + MLAN_OID_MISC_SOFT_RESET, + MLAN_OID_MISC_WWS, + MLAN_OID_MISC_INIT_SHUTDOWN, + MLAN_OID_MISC_CUSTOM_IE, + MLAN_OID_MISC_TX_DATAPAUSE, + MLAN_OID_MISC_IP_ADDR, + MLAN_OID_MISC_MAC_CONTROL, + MLAN_OID_MISC_MEF_CFG, + MLAN_OID_MISC_CFP_CODE, + MLAN_OID_MISC_COUNTRY_CODE, + MLAN_OID_MISC_THERMAL, + MLAN_OID_MISC_RX_MGMT_IND, + MLAN_OID_MISC_SUBSCRIBE_EVENT, +#ifdef DEBUG_LEVEL1 + MLAN_OID_MISC_DRVDBG, +#endif + MLAN_OID_MISC_OTP_USER_DATA, +}; + +/** Sub command size */ +#define MLAN_SUB_COMMAND_SIZE 4 + +/** Enumeration for the action of IOCTL request */ +enum _mlan_act_ioctl +{ + MLAN_ACT_SET = 1, + MLAN_ACT_GET, + MLAN_ACT_CANCEL +}; + +/** Enumeration for generic enable/disable */ +enum _mlan_act_generic +{ + MLAN_ACT_DISABLE = 0, + MLAN_ACT_ENABLE = 1 +}; + +/** Enumeration for scan mode */ +enum _mlan_scan_mode +{ + MLAN_SCAN_MODE_UNCHANGED = 0, + MLAN_SCAN_MODE_BSS, + MLAN_SCAN_MODE_IBSS, + MLAN_SCAN_MODE_ANY +}; + +/** Enumeration for scan type */ +enum _mlan_scan_type +{ + MLAN_SCAN_TYPE_UNCHANGED = 0, + MLAN_SCAN_TYPE_ACTIVE, + MLAN_SCAN_TYPE_PASSIVE +}; + +/** Max number of supported rates */ +#define MLAN_SUPPORTED_RATES 32 + +/** RSSI scan */ +#define SCAN_RSSI(RSSI) (0x100 - ((t_u8)(RSSI))) + +/** Max passive scan time for each channel in milliseconds */ +#define MRVDRV_MAX_PASSIVE_SCAN_CHAN_TIME 2000 + +/** Max active scan time for each channel in milliseconds */ +#define MRVDRV_MAX_ACTIVE_SCAN_CHAN_TIME 500 + +/** Maximum number of probes to send on each channel */ +#define MAX_PROBES 4 + +/** Default number of probes to send on each channel */ +#define DEFAULT_PROBES 4 + +/** + * @brief Sub-structure passed in wlan_ioctl_get_scan_table_entry for each BSS + * + * Fixed field information returned for the scan response in the IOCTL + * response. + */ +typedef struct _wlan_get_scan_table_fixed +{ + /** BSSID of this network */ + t_u8 bssid[MLAN_MAC_ADDR_LENGTH]; + /** Channel this beacon/probe response was detected */ + t_u8 channel; + /** RSSI for the received packet */ + t_u8 rssi; + /** TSF value in microseconds from the firmware at packet reception */ + t_u64 network_tsf; +} wlan_get_scan_table_fixed; + +/** mlan_802_11_ssid data structure */ +typedef struct _mlan_802_11_ssid +{ + /** SSID Length */ + t_u32 ssid_len; + /** SSID information field */ + t_u8 ssid[MLAN_MAX_SSID_LENGTH]; +} mlan_802_11_ssid, *pmlan_802_11_ssid; + +/** + * Sructure to retrieve the scan table + */ +typedef struct +{ + /** + * - Zero based scan entry to start retrieval in command request + * - Number of scans entries returned in command response + */ + t_u32 scan_number; + /** + * Buffer marker for multiple wlan_ioctl_get_scan_table_entry structures. + * Each struct is padded to the nearest 32 bit boundary. + */ + t_u8 scan_table_entry_buf[1]; +} wlan_ioctl_get_scan_table_info; + +/** + * Structure passed in the wlan_ioctl_get_scan_table_info for each + * BSS returned in the WLAN_GET_SCAN_RESP IOCTL + */ +typedef struct _wlan_ioctl_get_scan_table_entry +{ + /** + * Fixed field length included in the response. + * + * Length value is included so future fixed fields can be added to the + * response without breaking backwards compatibility. Use the length + * to find the offset for the bssInfoLength field, not a sizeof() calc. + */ + t_u32 fixed_field_length; + + /** + * Length of the BSS Information (probe resp or beacon) that + * follows after the fixed_field_length + */ + t_u32 bss_info_length; + + /** + * Always present, fixed length data fields for the BSS + */ + wlan_get_scan_table_fixed fixed_fields; + + /* + * Probe response or beacon scanned for the BSS. + * + * Field layout: + * - TSF 8 octets + * - Beacon Interval 2 octets + * - Capability Info 2 octets + * + * - IEEE Infomation Elements; variable number & length per 802.11 spec + */ + /* t_u8 bss_info_buffer[0]; */ +} wlan_ioctl_get_scan_table_entry; + +/** Type definition of mlan_scan_time_params */ +typedef struct _mlan_scan_time_params +{ + /** Scan channel time for specific scan in milliseconds */ + t_u32 specific_scan_time; + /** Scan channel time for active scan in milliseconds */ + t_u32 active_scan_time; + /** Scan channel time for passive scan in milliseconds */ + t_u32 passive_scan_time; +} mlan_scan_time_params, *pmlan_scan_time_params; + +/** Type definition of mlan_user_scan */ +typedef struct _mlan_user_scan +{ + /** Length of scan_cfg_buf */ + t_u32 scan_cfg_len; + /** Buffer of scan config */ + t_u8 scan_cfg_buf[1]; +} mlan_user_scan, *pmlan_user_scan; + +/** Type definition of mlan_scan_req */ +typedef struct _mlan_scan_req +{ + /** BSS mode for scanning */ + t_u32 scan_mode; + /** Scan type */ + t_u32 scan_type; + /** SSID */ + mlan_802_11_ssid scan_ssid; + /** Scan time parameters */ + mlan_scan_time_params scan_time; + /** Scan config parameters in user scan */ + mlan_user_scan user_scan; +} mlan_scan_req, *pmlan_scan_req; + +/** Type defnition of mlan_scan_resp */ +typedef struct _mlan_scan_resp +{ + /** Number of scan result */ + t_u32 num_in_scan_table; + /** Scan table */ + t_u8 *pscan_table; + /* Age in seconds */ + t_u32 age_in_secs; +} mlan_scan_resp, *pmlan_scan_resp; + +/** Type definition of mlan_scan_cfg */ +typedef struct _mlan_scan_cfg +{ + /** Scan type */ + t_u32 scan_type; + /** BSS mode for scanning */ + t_u32 scan_mode; + /** Scan probe */ + t_u32 scan_probe; + /** Scan time parameters */ + mlan_scan_time_params scan_time; + /** Extended Scan */ + t_u32 ext_scan; +} mlan_scan_cfg, *pmlan_scan_cfg; + +/** Type defnition of mlan_ds_scan for MLAN_IOCTL_SCAN */ +typedef struct _mlan_ds_scan +{ + /** Sub-command */ + t_u32 sub_command; + /** Scan request/response */ + union + { + /** Scan request */ + mlan_scan_req scan_req; + /** Scan response */ + mlan_scan_resp scan_resp; + /** Scan config parameters in user scan */ + mlan_user_scan user_scan; + /** Scan config parameters */ + mlan_scan_cfg scan_cfg; + } param; +} mlan_ds_scan, *pmlan_ds_scan; + +/*-----------------------------------------------------------------*/ +/** BSS Configuration Group */ +/*-----------------------------------------------------------------*/ +/** Enumeration for BSS mode */ +enum _mlan_bss_mode +{ + MLAN_BSS_MODE_INFRA = 1, + MLAN_BSS_MODE_IBSS, + MLAN_BSS_MODE_AUTO +}; + +/** Maximum key length */ +#define MLAN_MAX_KEY_LENGTH 32 + +/** max Wmm AC queues */ +#define MAX_AC_QUEUES 4 + +/** Maximum atim window in milliseconds */ +#define MLAN_MAX_ATIM_WINDOW 50 + +/** Minimum beacon interval */ +#define MLAN_MIN_BEACON_INTERVAL 20 +/** Maximum beacon interval */ +#define MLAN_MAX_BEACON_INTERVAL 1000 +/** Default beacon interval */ +#define MLAN_BEACON_INTERVAL 100 + +/** Receive all packets */ +#define MLAN_PROMISC_MODE 1 +/** Receive multicast packets in multicast list */ +#define MLAN_MULTICAST_MODE 2 +/** Receive all multicast packets */ +#define MLAN_ALL_MULTI_MODE 4 + +/** Maximum size of multicast list */ +#define MLAN_MAX_MULTICAST_LIST_SIZE 32 + +/** mlan_multicast_list data structure for MLAN_OID_BSS_MULTICAST_LIST */ +typedef struct _mlan_multicast_list +{ + /** Multicast mode */ + t_u32 mode; + /** Number of multicast addresses in the list */ + t_u32 num_multicast_addr; + /** Multicast address list */ + mlan_802_11_mac_addr mac_list[MLAN_MAX_MULTICAST_LIST_SIZE]; +} mlan_multicast_list, *pmlan_multicast_list; + +/** Max channel */ +#define MLAN_MAX_CHANNEL 165 + +/** Maximum number of channels in table */ +#define MLAN_MAX_CHANNEL_NUM 128 + +/** Channel/frequence for MLAN_OID_BSS_CHANNEL */ +typedef struct _chan_freq +{ + /** Channel Number */ + t_u32 channel; + /** Frequency of this Channel */ + t_u32 freq; +} chan_freq; + +/** mlan_chan_list data structure for MLAN_OID_BSS_CHANNEL_LIST */ +typedef struct _mlan_chan_list +{ + /** Number of channel */ + t_u32 num_of_chan; + /** Channel-Frequency table */ + chan_freq cf[MLAN_MAX_CHANNEL_NUM]; +} mlan_chan_list; + +/** mlan_ssid_bssid data structure for MLAN_OID_BSS_START and MLAN_OID_BSS_FIND_BSS */ +typedef struct _mlan_ssid_bssid +{ + /** SSID */ + mlan_802_11_ssid ssid; + /** BSSID */ + mlan_802_11_mac_addr bssid; + /** index in BSSID list, start from 1 */ + t_u32 idx; +} mlan_ssid_bssid; + +#ifdef UAP_SUPPORT +/** Maximum packet forward control value */ +#define MAX_PKT_FWD_CTRL 15 +/** Maximum BEACON period */ +#define MAX_BEACON_PERIOD 4000 +/** Minimum BEACON period */ +#define MIN_BEACON_PERIOD 50 +/** Maximum DTIM period */ +#define MAX_DTIM_PERIOD 100 +/** Minimum DTIM period */ +#define MIN_DTIM_PERIOD 1 +/** Maximum TX Power Limit */ +#define MAX_TX_POWER 20 +/** Minimum TX Power Limit */ +#define MIN_TX_POWER 0 +/** MAX station count */ +#define MAX_STA_COUNT 10 +/** Maximum RTS threshold */ +#define MAX_RTS_THRESHOLD 2347 +/** Maximum fragmentation threshold */ +#define MAX_FRAG_THRESHOLD 2346 +/** Minimum fragmentation threshold */ +#define MIN_FRAG_THRESHOLD 256 +/** data rate 54 M */ +#define DATA_RATE_54M 108 +/** antenna A */ +#define ANTENNA_MODE_A 0 +/** antenna B */ +#define ANTENNA_MODE_B 1 +/** transmit antenna */ +#define TX_ANTENNA 1 +/** receive antenna */ +#define RX_ANTENNA 0 +/** Maximum stage out time */ +#define MAX_STAGE_OUT_TIME 864000 +/** Minimum stage out time */ +#define MIN_STAGE_OUT_TIME 300 +/** Maximum Retry Limit */ +#define MAX_RETRY_LIMIT 14 + +/** Maximum group key timer in seconds */ +#define MAX_GRP_TIMER 86400 + +/** Maximum value of 4 byte configuration */ +#define MAX_VALID_DWORD 0x7FFFFFFF /* (1 << 31) - 1 */ + +/** Band config ACS mode */ +#define BAND_CONFIG_ACS_MODE 0x40 +/** Band config manual */ +#define BAND_CONFIG_MANUAL 0x00 + +/** Maximum data rates */ +#define MAX_DATA_RATES 14 + +/** auto data rate */ +#define DATA_RATE_AUTO 0 + +/**filter mode: disable */ +#define MAC_FILTER_MODE_DISABLE 0 +/**filter mode: block mac address */ +#define MAC_FILTER_MODE_ALLOW_MAC 1 +/**filter mode: block mac address */ +#define MAC_FILTER_MODE_BLOCK_MAC 2 +/** Maximum mac filter num */ +#define MAX_MAC_FILTER_NUM 16 + +/* Bitmap for protocol to use */ +/** No security */ +#define PROTOCOL_NO_SECURITY 0x01 +/** Static WEP */ +#define PROTOCOL_STATIC_WEP 0x02 +/** WPA */ +#define PROTOCOL_WPA 0x08 +/** WPA2 */ +#define PROTOCOL_WPA2 0x20 +/** WP2 Mixed */ +#define PROTOCOL_WPA2_MIXED 0x28 +/** EAP */ +#define PROTOCOL_EAP 0x40 +/** WAPI */ +#define PROTOCOL_WAPI 0x80 + +/** Key_mgmt_psk */ +#define KEY_MGMT_NONE 0x04 +/** Key_mgmt_none */ +#define KEY_MGMT_PSK 0x02 +/** Key_mgmt_eap */ +#define KEY_MGMT_EAP 0x01 + +/** TKIP */ +#define CIPHER_TKIP 0x04 +/** AES CCMP */ +#define CIPHER_AES_CCMP 0x08 + +/** Valid cipher bitmap */ +#define VALID_CIPHER_BITMAP 0x0c + +/** Channel List Entry */ +typedef struct _channel_list +{ + /** Channel Number */ + t_u8 chan_number; + /** Band Config */ + t_u8 band_config_type; +} scan_chan_list; + +/** mac_filter data structure */ +typedef struct _mac_filter +{ + /** mac filter mode */ + t_u16 filter_mode; + /** mac adress count */ + t_u16 mac_count; + /** mac address list */ + mlan_802_11_mac_addr mac_list[MAX_MAC_FILTER_NUM]; +} mac_filter; + +/** wpa parameter */ +typedef struct _wpa_param +{ + /** Pairwise cipher WPA */ + t_u8 pairwise_cipher_wpa; + /** Pairwise cipher WPA2 */ + t_u8 pairwise_cipher_wpa2; + /** group cipher */ + t_u8 group_cipher; + /** RSN replay protection */ + t_u8 rsn_protection; + /** passphrase length */ + t_u32 length; + /** passphrase */ + t_u8 passphrase[64]; + /**group key rekey time in seconds */ + t_u32 gk_rekey_time; +} wpa_param; + +/** wep key */ +typedef struct _wep_key +{ + /** key index 0-3 */ + t_u8 key_index; + /** is default */ + t_u8 is_default; + /** length */ + t_u16 length; + /** key data */ + t_u8 key[26]; +} wep_key; + +/** wep param */ +typedef struct _wep_param +{ + /** key 0 */ + wep_key key0; + /** key 1 */ + wep_key key1; + /** key 2 */ + wep_key key2; + /** key 3 */ + wep_key key3; +} wep_param; + +/** Data structure of WMM QoS information */ +typedef struct _wmm_qos_info_t +{ +#ifdef BIG_ENDIAN_SUPPORT + /** QoS UAPSD */ + t_u8 qos_uapsd:1; + /** Reserved */ + t_u8 reserved:3; + /** Parameter set count */ + t_u8 para_set_count:4; +#else + /** Parameter set count */ + t_u8 para_set_count:4; + /** Reserved */ + t_u8 reserved:3; + /** QoS UAPSD */ + t_u8 qos_uapsd:1; +#endif /* BIG_ENDIAN_SUPPORT */ +} wmm_qos_info_t, *pwmm_qos_info_t; + +/** Data structure of WMM ECW */ +typedef struct _wmm_ecw_t +{ +#ifdef BIG_ENDIAN_SUPPORT + /** Maximum Ecw */ + t_u8 ecw_max:4; + /** Minimum Ecw */ + t_u8 ecw_min:4; +#else + /** Minimum Ecw */ + t_u8 ecw_min:4; + /** Maximum Ecw */ + t_u8 ecw_max:4; +#endif /* BIG_ENDIAN_SUPPORT */ +} wmm_ecw_t, *pwmm_ecw_t; + +/** Data structure of WMM Aci/Aifsn */ +typedef struct _wmm_aci_aifsn_t +{ +#ifdef BIG_ENDIAN_SUPPORT + /** Reserved */ + t_u8 reserved:1; + /** Aci */ + t_u8 aci:2; + /** Acm */ + t_u8 acm:1; + /** Aifsn */ + t_u8 aifsn:4; +#else + /** Aifsn */ + t_u8 aifsn:4; + /** Acm */ + t_u8 acm:1; + /** Aci */ + t_u8 aci:2; + /** Reserved */ + t_u8 reserved:1; +#endif /* BIG_ENDIAN_SUPPORT */ +} wmm_aci_aifsn_t, *pwmm_aci_aifsn_t; + +/** Data structure of WMM AC parameters */ +typedef struct _wmm_ac_parameters_t +{ + wmm_aci_aifsn_t aci_aifsn; /**< AciAifSn */ + wmm_ecw_t ecw; /**< Ecw */ + t_u16 tx_op_limit; /**< Tx op limit */ +} wmm_ac_parameters_t, *pwmm_ac_parameters_t; + +/** Data structure of WMM parameter IE */ +typedef struct _wmm_parameter_t +{ + /** OuiType: 00:50:f2:02 */ + t_u8 ouitype[4]; + /** Oui subtype: 01 */ + t_u8 ouisubtype; + /** version: 01 */ + t_u8 version; + /** QoS information */ + t_u8 qos_info; + /** Reserved */ + t_u8 reserved; + /** AC Parameters Record WMM_AC_BE, WMM_AC_BK, WMM_AC_VI, WMM_AC_VO */ + wmm_ac_parameters_t ac_params[MAX_AC_QUEUES]; +} wmm_parameter_t, *pwmm_parameter_t; + +/** mlan_bss_param + * Note: For each entry you must enter an invalid value + * in the MOAL function woal_set_sys_config_invalid_data(). + * Otherwise for a valid data an unwanted TLV will be + * added to that command. + */ +typedef struct _mlan_uap_bss_param +{ + /** AP mac addr */ + mlan_802_11_mac_addr mac_addr; + /** SSID */ + mlan_802_11_ssid ssid; + /** Broadcast ssid control */ + t_u8 bcast_ssid_ctl; + /** Radio control: on/off */ + t_u8 radio_ctl; + /** dtim period */ + t_u8 dtim_period; + /** beacon period */ + t_u16 beacon_period; + /** rates */ + t_u8 rates[MAX_DATA_RATES]; + /** Tx data rate */ + t_u16 tx_data_rate; + /** multicast/broadcast data rate */ + t_u16 mcbc_data_rate; + /** Tx power level in dBm */ + t_u8 tx_power_level; + /** Tx antenna */ + t_u8 tx_antenna; + /** Rx antenna */ + t_u8 rx_antenna; + /** packet forward control */ + t_u8 pkt_forward_ctl; + /** max station count */ + t_u16 max_sta_count; + /** mac filter */ + mac_filter filter; + /** station ageout timer in unit of 100ms */ + t_u32 sta_ageout_timer; + /** PS station ageout timer in unit of 100ms */ + t_u32 ps_sta_ageout_timer; + /** RTS threshold */ + t_u16 rts_threshold; + /** fragmentation threshold */ + t_u16 frag_threshold; + /** retry_limit */ + t_u16 retry_limit; + /** pairwise update timeout in milliseconds */ + t_u32 pairwise_update_timeout; + /** pairwise handshake retries */ + t_u32 pwk_retries; + /** groupwise update timeout in milliseconds */ + t_u32 groupwise_update_timeout; + /** groupwise handshake retries */ + t_u32 gwk_retries; + /** preamble type */ + t_u8 preamble_type; + /** band cfg */ + t_u8 band_cfg; + /** channel */ + t_u8 channel; + /** auth mode */ + t_u16 auth_mode; + /** encryption protocol */ + t_u16 protocol; + /** key managment type */ + t_u16 key_mgmt; + /** wep param */ + wep_param wep_cfg; + /** wpa param */ + wpa_param wpa_cfg; + /** Mgmt IE passthru mask */ + t_u32 mgmt_ie_passthru_mask; + /* + * 11n HT Cap HTCap_t ht_cap + */ + /** HT Capabilities Info field */ + t_u16 ht_cap_info; + /** A-MPDU Parameters field */ + t_u8 ampdu_param; + /** Supported MCS Set field */ + t_u8 supported_mcs_set[16]; + /** HT Extended Capabilities field */ + t_u16 ht_ext_cap; + /** Transmit Beamforming Capabilities field */ + t_u32 tx_bf_cap; + /** Antenna Selection Capability field */ + t_u8 asel; + /** Enable 2040 Coex */ + t_u8 enable_2040coex; + /** key management operation */ + t_u16 key_mgmt_operation; + /** BSS status */ + t_u16 bss_status; +#ifdef WIFI_DIRECT_SUPPORT + /* pre shared key */ + t_u8 psk[MLAN_MAX_KEY_LENGTH]; +#endif /* WIFI_DIRECT_SUPPORT */ + /** Number of channels in scan_channel_list */ + t_u32 num_of_chan; + /** scan channel list in ACS mode */ + scan_chan_list chan_list[MLAN_MAX_CHANNEL]; + /** Wmm parameters */ + wmm_parameter_t wmm_para; +} mlan_uap_bss_param; + +/** mlan_deauth_param */ +typedef struct _mlan_deauth_param +{ + /** STA mac addr */ + t_u8 mac_addr[MLAN_MAC_ADDR_LENGTH]; + /** deauth reason */ + t_u16 reason_code; +} mlan_deauth_param; +#endif + +#ifdef WIFI_DIRECT_SUPPORT +/** mode: disable wifi direct */ +#define WIFI_DIRECT_MODE_DISABLE 0 +/** mode: listen */ +#define WIFI_DIRECT_MODE_LISTEN 1 +/** mode: GO */ +#define WIFI_DIRECT_MODE_GO 2 +/** mode: client */ +#define WIFI_DIRECT_MODE_CLIENT 3 +/** mode: find */ +#define WIFI_DIRECT_MODE_FIND 4 +/** mode: stop find */ +#define WIFI_DIRECT_MODE_STOP_FIND 5 +#endif + +/** Type definition of mlan_ds_bss for MLAN_IOCTL_BSS */ +typedef struct _mlan_ds_bss +{ + /** Sub-command */ + t_u32 sub_command; + /** BSS parameter */ + union + { + /** SSID-BSSID for MLAN_OID_BSS_START */ + mlan_ssid_bssid ssid_bssid; + /** BSSID for MLAN_OID_BSS_STOP */ + mlan_802_11_mac_addr bssid; + /** BSS mode for MLAN_OID_BSS_MODE */ + t_u32 bss_mode; + /** BSS channel/frequency for MLAN_OID_BSS_CHANNEL */ + chan_freq bss_chan; + /** BSS channel list for MLAN_OID_BSS_CHANNEL_LIST */ + mlan_chan_list chanlist; + /** MAC address for MLAN_OID_BSS_MAC_ADDR */ + mlan_802_11_mac_addr mac_addr; + /** Multicast list for MLAN_OID_BSS_MULTICAST_LIST */ + mlan_multicast_list multicast_list; + /** Beacon interval for MLAN_OID_IBSS_BCN_INTERVAL */ + t_u32 bcn_interval; + /** ATIM window for MLAN_OID_IBSS_ATIM_WINDOW */ + t_u32 atim_window; +#ifdef UAP_SUPPORT + /** BSS param for AP mode */ + mlan_uap_bss_param bss_config; + /** deauth param for MLAN_OID_UAP_DEAUTH_STA */ + mlan_deauth_param deauth_param; +#endif +#if defined(STA_SUPPORT) && defined(UAP_SUPPORT) + /** BSS role */ + t_u8 bss_role; +#endif +#ifdef WIFI_DIRECT_SUPPORT + t_u16 wfd_mode; +#endif + } param; +} mlan_ds_bss, *pmlan_ds_bss; + +/*-----------------------------------------------------------------*/ +/** Radio Control Group */ +/*-----------------------------------------------------------------*/ +/** Enumeration for band */ +enum _mlan_band_def +{ + BAND_B = 1, + BAND_G = 2, + BAND_A = 4, + BAND_GN = 8, + BAND_AN = 16, +}; + +/** NO secondary channel */ +#define NO_SEC_CHANNEL 0 +/** secondary channel is above primary channel */ +#define SEC_CHANNEL_ABOVE 1 +/** secondary channel is below primary channel */ +#define SEC_CHANNEL_BELOW 3 +/** Channel bandwidth */ +#define CHANNEL_BW_20MHZ 0 +#define CHANNEL_BW_40MHZ_ABOVE 1 +#define CHANNEL_BW_40MHZ_BELOW 3 + +/** Type definition of mlan_ds_band_cfg for MLAN_OID_BAND_CFG */ +typedef struct _mlan_ds_band_cfg +{ + /** Infra band */ + t_u32 config_bands; + /** Ad-hoc start band */ + t_u32 adhoc_start_band; + /** Ad-hoc start channel */ + t_u32 adhoc_channel; + /** Ad-hoc channel bandwidth */ + t_u32 sec_chan_offset; + /** fw supported band */ + t_u32 fw_bands; +} mlan_ds_band_cfg; + +/** Type definition of mlan_ds_ant_cfg for MLAN_OID_ANT_CFG */ +typedef struct _mlan_ds_ant_cfg +{ + /** Tx antenna mode */ + t_u32 tx_antenna; + /** Rx antenna mode */ + t_u32 rx_antenna; +} mlan_ds_ant_cfg, *pmlan_ds_ant_cfg; + +#ifdef WIFI_DIRECT_SUPPORT +/** Type definition of mlan_ds_remain_chan for MLAN_OID_REMAIN_CHAN_CFG */ +typedef struct _mlan_ds_remain_chan +{ + /** remove flag */ + t_u16 remove; + /** status */ + t_u8 status; + /** Band cfg */ + t_u8 bandcfg; + /** channel */ + t_u8 channel; + /** remain time: Unit ms*/ + t_u32 remain_period; +} mlan_ds_remain_chan, *pmlan_ds_remain_chan; +#endif + +/** Type definition of mlan_ds_radio_cfg for MLAN_IOCTL_RADIO_CFG */ +typedef struct _mlan_ds_radio_cfg +{ + /** Sub-command */ + t_u32 sub_command; + /** Radio control parameter */ + union + { + /** Radio on/off for MLAN_OID_RADIO_CTRL */ + t_u32 radio_on_off; + /** Band info for MLAN_OID_BAND_CFG */ + mlan_ds_band_cfg band_cfg; + /** Antenna info for MLAN_OID_ANT_CFG */ + mlan_ds_ant_cfg ant_cfg; + /** Antenna info for MLAN_OID_ANT_CFG */ + t_u32 antenna; +#ifdef WIFI_DIRECT_SUPPORT + /** remain on channel for MLAN_OID_REMAIN_CHAN_CFG */ + mlan_ds_remain_chan remain_chan; +#endif + } param; +} mlan_ds_radio_cfg, *pmlan_ds_radio_cfg; + +/*-----------------------------------------------------------------*/ +/** SNMP MIB Group */ +/*-----------------------------------------------------------------*/ +/** Type definition of mlan_ds_snmp_mib for MLAN_IOCTL_SNMP_MIB */ +typedef struct _mlan_ds_snmp_mib +{ + /** Sub-command */ + t_u32 sub_command; + /** SNMP MIB parameter */ + union + { + /** RTS threshold for MLAN_OID_SNMP_MIB_RTS_THRESHOLD */ + t_u32 rts_threshold; + /** Fragment threshold for MLAN_OID_SNMP_MIB_FRAG_THRESHOLD */ + t_u32 frag_threshold; + /** Retry count for MLAN_OID_SNMP_MIB_RETRY_COUNT */ + t_u32 retry_count; +#if defined(UAP_SUPPORT) + /** OID value for MLAN_OID_SNMP_MIB_DOT11D/H */ + t_u32 oid_value; +#endif + /** DTIM period for MLAN_OID_SNMP_MIB_DTIM_PERIOD */ + t_u32 dtim_period; + } param; +} mlan_ds_snmp_mib, *pmlan_ds_snmp_mib; + +/*-----------------------------------------------------------------*/ +/** Status Information Group */ +/*-----------------------------------------------------------------*/ +/** Enumeration for ad-hoc status */ +enum _mlan_adhoc_status +{ + ADHOC_IDLE, + ADHOC_STARTED, + ADHOC_JOINED, + ADHOC_COALESCED, ADHOC_STARTING +}; + +/** Type definition of mlan_ds_get_stats for MLAN_OID_GET_STATS */ +typedef struct _mlan_ds_get_stats +{ + /** Statistics counter */ + /** Multicast transmitted frame count */ + t_u32 mcast_tx_frame; + /** Failure count */ + t_u32 failed; + /** Retry count */ + t_u32 retry; + /** Multi entry count */ + t_u32 multi_retry; + /** Duplicate frame count */ + t_u32 frame_dup; + /** RTS success count */ + t_u32 rts_success; + /** RTS failure count */ + t_u32 rts_failure; + /** Ack failure count */ + t_u32 ack_failure; + /** Rx fragmentation count */ + t_u32 rx_frag; + /** Multicast Tx frame count */ + t_u32 mcast_rx_frame; + /** FCS error count */ + t_u32 fcs_error; + /** Tx frame count */ + t_u32 tx_frame; + /** WEP ICV error count */ + t_u32 wep_icv_error[4]; +} mlan_ds_get_stats, *pmlan_ds_get_stats; + +/** Type definition of mlan_ds_uap_stats for MLAN_OID_GET_STATS */ +typedef struct _mlan_ds_uap_stats +{ + /** tkip mic failures */ + t_u32 tkip_mic_failures; + /** ccmp decrypt errors */ + t_u32 ccmp_decrypt_errors; + /** wep undecryptable count */ + t_u32 wep_undecryptable_count; + /** wep icv error count */ + t_u32 wep_icv_error_count; + /** decrypt failure count */ + t_u32 decrypt_failure_count; + /** dot11 multicast tx count */ + t_u32 mcast_tx_count; + /** dot11 failed count */ + t_u32 failed_count; + /** dot11 retry count */ + t_u32 retry_count; + /** dot11 multi retry count */ + t_u32 multi_retry_count; + /** dot11 frame duplicate count */ + t_u32 frame_dup_count; + /** dot11 rts success count */ + t_u32 rts_success_count; + /** dot11 rts failure count */ + t_u32 rts_failure_count; + /** dot11 ack failure count */ + t_u32 ack_failure_count; + /** dot11 rx ragment count */ + t_u32 rx_fragment_count; + /** dot11 mcast rx frame count */ + t_u32 mcast_rx_frame_count; + /** dot11 fcs error count */ + t_u32 fcs_error_count; + /** dot11 tx frame count */ + t_u32 tx_frame_count; + /** dot11 rsna tkip cm invoked */ + t_u32 rsna_tkip_cm_invoked; + /** dot11 rsna 4way handshake failures */ + t_u32 rsna_4way_hshk_failures; +} mlan_ds_uap_stats, *pmlan_ds_uap_stats; + +/** Mask of last beacon RSSI */ +#define BCN_RSSI_LAST_MASK 0x00000001 +/** Mask of average beacon RSSI */ +#define BCN_RSSI_AVG_MASK 0x00000002 +/** Mask of last data RSSI */ +#define DATA_RSSI_LAST_MASK 0x00000004 +/** Mask of average data RSSI */ +#define DATA_RSSI_AVG_MASK 0x00000008 +/** Mask of last beacon SNR */ +#define BCN_SNR_LAST_MASK 0x00000010 +/** Mask of average beacon SNR */ +#define BCN_SNR_AVG_MASK 0x00000020 +/** Mask of last data SNR */ +#define DATA_SNR_LAST_MASK 0x00000040 +/** Mask of average data SNR */ +#define DATA_SNR_AVG_MASK 0x00000080 +/** Mask of last beacon NF */ +#define BCN_NF_LAST_MASK 0x00000100 +/** Mask of average beacon NF */ +#define BCN_NF_AVG_MASK 0x00000200 +/** Mask of last data NF */ +#define DATA_NF_LAST_MASK 0x00000400 +/** Mask of average data NF */ +#define DATA_NF_AVG_MASK 0x00000800 +/** Mask of all RSSI_INFO */ +#define ALL_RSSI_INFO_MASK 0x00000fff + +/** Type definition of mlan_ds_get_signal for MLAN_OID_GET_SIGNAL */ +typedef struct _mlan_ds_get_signal +{ + /** Selector of get operation */ + /* + * Bit0: Last Beacon RSSI, Bit1: Average Beacon RSSI, + * Bit2: Last Data RSSI, Bit3: Average Data RSSI, + * Bit4: Last Beacon SNR, Bit5: Average Beacon SNR, + * Bit6: Last Data SNR, Bit7: Average Data SNR, + * Bit8: Last Beacon NF, Bit9: Average Beacon NF, + * Bit10: Last Data NF, Bit11: Average Data NF + */ + t_u16 selector; + + /** RSSI */ + /** RSSI of last beacon */ + t_s16 bcn_rssi_last; + /** RSSI of beacon average */ + t_s16 bcn_rssi_avg; + /** RSSI of last data packet */ + t_s16 data_rssi_last; + /** RSSI of data packet average */ + t_s16 data_rssi_avg; + + /** SNR */ + /** SNR of last beacon */ + t_s16 bcn_snr_last; + /** SNR of beacon average */ + t_s16 bcn_snr_avg; + /** SNR of last data packet */ + t_s16 data_snr_last; + /** SNR of data packet average */ + t_s16 data_snr_avg; + + /** NF */ + /** NF of last beacon */ + t_s16 bcn_nf_last; + /** NF of beacon average */ + t_s16 bcn_nf_avg; + /** NF of last data packet */ + t_s16 data_nf_last; + /** NF of data packet average */ + t_s16 data_nf_avg; +} mlan_ds_get_signal, *pmlan_ds_get_signal; + +/** mlan_fw_info data structure for MLAN_OID_GET_FW_INFO */ +typedef struct _mlan_fw_info +{ + /** Firmware version */ + t_u32 fw_ver; + /** MAC address */ + mlan_802_11_mac_addr mac_addr; + /** Device support for MIMO abstraction of MCSs */ + t_u8 hw_dev_mcs_support; + /** fw supported band */ + t_u8 fw_bands; +} mlan_fw_info, *pmlan_fw_info; + +/** Version string buffer length */ +#define MLAN_MAX_VER_STR_LEN 128 + +/** mlan_ver_ext data structure for MLAN_OID_GET_VER_EXT */ +typedef struct _mlan_ver_ext +{ + /** Selected version string */ + t_u32 version_str_sel; + /** Version string */ + char version_str[MLAN_MAX_VER_STR_LEN]; +} mlan_ver_ext, *pmlan_ver_ext; + +/** mlan_bss_info data structure for MLAN_OID_GET_BSS_INFO */ +typedef struct _mlan_bss_info +{ + /** BSS mode */ + t_u32 bss_mode; + /** SSID */ + mlan_802_11_ssid ssid; + /** Table index */ + t_u32 scan_table_idx; + /** Channel */ + t_u32 bss_chan; + /** Band */ + t_u8 bss_band; + /** Region code */ + t_u32 region_code; + /** Connection status */ + t_u32 media_connected; + /** Radio on */ + t_u32 radio_on; + /** Max power level in dBm */ + t_u32 max_power_level; + /** Min power level in dBm */ + t_u32 min_power_level; + /** Adhoc state */ + t_u32 adhoc_state; + /** NF of last beacon */ + t_s32 bcn_nf_last; + /** wep status */ + t_u32 wep_status; + /** Host Sleep configured flag */ + t_u32 is_hs_configured; + /** Deep Sleep flag */ + t_u32 is_deep_sleep; + /** BSSID */ + mlan_802_11_mac_addr bssid; +#ifdef STA_SUPPORT + /** Capability Info */ + t_u16 capability_info; + /** Beacon Interval */ + t_u16 beacon_interval; + /** Listen Interval */ + t_u16 listen_interval; + /** Association Id */ + t_u16 assoc_id; + /** AP/Peer supported rates */ + t_u8 peer_supp_rates[MLAN_SUPPORTED_RATES]; +#endif /* STA_SUPPORT */ +} mlan_bss_info, *pmlan_bss_info; + +/** MAXIMUM number of TID */ +#define MAX_NUM_TID 8 + +/** Max RX Win size */ +#define MAX_RX_WINSIZE 64 + +/** rx_reorder_tbl */ +typedef struct +{ + /** TID */ + t_u16 tid; + /** TA */ + t_u8 ta[MLAN_MAC_ADDR_LENGTH]; + /** Start window */ + t_u32 start_win; + /** Window size */ + t_u32 win_size; + /** amsdu flag */ + t_u8 amsdu; + /** buffer status */ + t_u32 buffer[MAX_RX_WINSIZE]; +} rx_reorder_tbl; + +/** tx_ba_stream_tbl */ +typedef struct +{ + /** TID */ + t_u16 tid; + /** RA */ + t_u8 ra[MLAN_MAC_ADDR_LENGTH]; + /** amsdu flag */ + t_u8 amsdu; +} tx_ba_stream_tbl; + +/** Debug command number */ +#define DBG_CMD_NUM 5 + +/** mlan_debug_info data structure for MLAN_OID_GET_DEBUG_INFO */ +typedef struct _mlan_debug_info +{ + /* WMM AC_BK count */ + t_u32 wmm_ac_bk; + /* WMM AC_BE count */ + t_u32 wmm_ac_be; + /* WMM AC_VI count */ + t_u32 wmm_ac_vi; + /* WMM AC_VO count */ + t_u32 wmm_ac_vo; + /** Corresponds to max_tx_buf_size member of mlan_adapter*/ + t_u32 max_tx_buf_size; + /** Corresponds to tx_buf_size member of mlan_adapter*/ + t_u32 tx_buf_size; + /** Corresponds to curr_tx_buf_size member of mlan_adapter*/ + t_u32 curr_tx_buf_size; + /** Tx table num */ + t_u32 tx_tbl_num; + /** Tx ba stream table */ + tx_ba_stream_tbl tx_tbl[MLAN_MAX_TX_BASTREAM_SUPPORTED]; + /** Rx table num */ + t_u32 rx_tbl_num; + /** Rx reorder table*/ + rx_reorder_tbl rx_tbl[MLAN_MAX_RX_BASTREAM_SUPPORTED]; + /** Corresponds to ps_mode member of mlan_adapter */ + t_u16 ps_mode; + /** Corresponds to ps_state member of mlan_adapter */ + t_u32 ps_state; +#ifdef STA_SUPPORT + /** Corresponds to is_deep_sleep member of mlan_adapter */ + t_u8 is_deep_sleep; +#endif /** STA_SUPPORT */ + /** Corresponds to pm_wakeup_card_req member of mlan_adapter */ + t_u8 pm_wakeup_card_req; + /** Corresponds to pm_wakeup_fw_try member of mlan_adapter */ + t_u32 pm_wakeup_fw_try; + /** Corresponds to is_hs_configured member of mlan_adapter */ + t_u8 is_hs_configured; + /** Corresponds to hs_activated member of mlan_adapter */ + t_u8 hs_activated; + /** Corresponds to pps_uapsd_mode member of mlan_adapter */ + t_u16 pps_uapsd_mode; + /** Corresponds to sleep_period.period member of mlan_adapter */ + t_u16 sleep_pd; + /** Corresponds to wmm_qosinfo member of mlan_private */ + t_u8 qos_cfg; + /** Corresponds to tx_lock_flag member of mlan_adapter */ + t_u8 tx_lock_flag; + /** Corresponds to port_open member of mlan_private */ + t_u8 port_open; + /** Corresponds to scan_processing member of mlan_adapter */ + t_u32 scan_processing; + /** Number of host to card command failures */ + t_u32 num_cmd_host_to_card_failure; + /** Number of host to card sleep confirm failures */ + t_u32 num_cmd_sleep_cfm_host_to_card_failure; + /** Number of host to card Tx failures */ + t_u32 num_tx_host_to_card_failure; + /** Number of card to host command/event failures */ + t_u32 num_cmdevt_card_to_host_failure; + /** Number of card to host Rx failures */ + t_u32 num_rx_card_to_host_failure; + /** Number of interrupt read failures */ + t_u32 num_int_read_failure; + /** Last interrupt status */ + t_u32 last_int_status; + /** Number of deauthentication events */ + t_u32 num_event_deauth; + /** Number of disassosiation events */ + t_u32 num_event_disassoc; + /** Number of link lost events */ + t_u32 num_event_link_lost; + /** Number of deauthentication commands */ + t_u32 num_cmd_deauth; + /** Number of association comamnd successes */ + t_u32 num_cmd_assoc_success; + /** Number of association command failures */ + t_u32 num_cmd_assoc_failure; + /** Number of Tx timeouts */ + t_u32 num_tx_timeout; + /** Number of command timeouts */ + t_u32 num_cmd_timeout; + /** Timeout command ID */ + t_u16 timeout_cmd_id; + /** Timeout command action */ + t_u16 timeout_cmd_act; + /** List of last command IDs */ + t_u16 last_cmd_id[DBG_CMD_NUM]; + /** List of last command actions */ + t_u16 last_cmd_act[DBG_CMD_NUM]; + /** Last command index */ + t_u16 last_cmd_index; + /** List of last command response IDs */ + t_u16 last_cmd_resp_id[DBG_CMD_NUM]; + /** Last command response index */ + t_u16 last_cmd_resp_index; + /** List of last events */ + t_u16 last_event[DBG_CMD_NUM]; + /** Last event index */ + t_u16 last_event_index; + + /** Corresponds to data_sent member of mlan_adapter */ + t_u8 data_sent; + /** Corresponds to cmd_sent member of mlan_adapter */ + t_u8 cmd_sent; + /** SDIO multiple port read bitmap */ + t_u32 mp_rd_bitmap; + /** SDIO multiple port write bitmap */ + t_u32 mp_wr_bitmap; + /** Current available port for read */ + t_u8 curr_rd_port; + /** Current available port for write */ + t_u8 curr_wr_port; + /** Corresponds to cmdresp_received member of mlan_adapter */ + t_u8 cmd_resp_received; + /** Corresponds to event_received member of mlan_adapter */ + t_u8 event_received; + /** pendig tx pkts */ + t_u32 tx_pkts_queued; +#ifdef UAP_SUPPORT + /** pending bridge pkts */ + t_u16 num_bridge_pkts; + /** dropped pkts */ + t_u32 num_drop_pkts; +#endif +} mlan_debug_info, *pmlan_debug_info; + +#ifdef UAP_SUPPORT +/** Maximum number of clients supported by AP */ +#define MAX_NUM_CLIENTS MAX_STA_COUNT + +/** station info */ +typedef struct _sta_info +{ + /** STA MAC address */ + t_u8 mac_address[MLAN_MAC_ADDR_LENGTH]; + /** Power mfg status */ + t_u8 power_mfg_status; + /** RSSI */ + t_s8 rssi; +} sta_info; + +/** mlan_ds_sta_list structure for MLAN_OID_UAP_STA_LIST */ +typedef struct _mlan_ds_sta_list +{ + /** station count */ + t_u16 sta_count; + /** station list */ + sta_info info[MAX_NUM_CLIENTS]; +} mlan_ds_sta_list, *pmlan_ds_sta_list; +#endif + +/** Type definition of mlan_ds_get_info for MLAN_IOCTL_GET_INFO */ +typedef struct _mlan_ds_get_info +{ + /** Sub-command */ + t_u32 sub_command; + + /** Status information parameter */ + union + { + /** Signal information for MLAN_OID_GET_SIGNAL */ + mlan_ds_get_signal signal; + /** Statistics information for MLAN_OID_GET_STATS */ + mlan_ds_get_stats stats; + /** Firmware information for MLAN_OID_GET_FW_INFO */ + mlan_fw_info fw_info; + /** Extended version information for MLAN_OID_GET_VER_EXT */ + mlan_ver_ext ver_ext; + /** BSS information for MLAN_OID_GET_BSS_INFO */ + mlan_bss_info bss_info; + /** Debug information for MLAN_OID_GET_DEBUG_INFO */ + mlan_debug_info debug_info; +#ifdef UAP_SUPPORT + /** UAP Statistics information for MLAN_OID_GET_STATS */ + mlan_ds_uap_stats ustats; + /** UAP station list for MLAN_OID_UAP_STA_LIST */ + mlan_ds_sta_list sta_list; +#endif + } param; +} mlan_ds_get_info, *pmlan_ds_get_info; + +/*-----------------------------------------------------------------*/ +/** Security Configuration Group */ +/*-----------------------------------------------------------------*/ +/** Enumeration for authentication mode */ +enum _mlan_auth_mode +{ + MLAN_AUTH_MODE_OPEN = 0x00, + MLAN_AUTH_MODE_SHARED = 0x01, + MLAN_AUTH_MODE_NETWORKEAP = 0x80, + MLAN_AUTH_MODE_AUTO = 0xFF, +}; + +/** Enumeration for encryption mode */ +enum _mlan_encryption_mode +{ + MLAN_ENCRYPTION_MODE_NONE = 0, + MLAN_ENCRYPTION_MODE_WEP40 = 1, + MLAN_ENCRYPTION_MODE_TKIP = 2, + MLAN_ENCRYPTION_MODE_CCMP = 3, + MLAN_ENCRYPTION_MODE_WEP104 = 4, +}; + +/** Enumeration for PSK */ +enum _mlan_psk_type +{ + MLAN_PSK_PASSPHRASE = 1, + MLAN_PSK_PMK, + MLAN_PSK_CLEAR, + MLAN_PSK_QUERY, +}; + +/** The bit to indicate the key is for unicast */ +#define MLAN_KEY_INDEX_UNICAST 0x40000000 +/** The key index to indicate default key */ +#define MLAN_KEY_INDEX_DEFAULT 0x000000ff +/** Maximum key length */ +// #define MLAN_MAX_KEY_LENGTH 32 +/** Minimum passphrase length */ +#define MLAN_MIN_PASSPHRASE_LENGTH 8 +/** Maximum passphrase length */ +#define MLAN_MAX_PASSPHRASE_LENGTH 63 +/** PMK length */ +#define MLAN_PMK_HEXSTR_LENGTH 64 +/* A few details needed for WEP (Wireless Equivalent Privacy) */ +/** 104 bits */ +#define MAX_WEP_KEY_SIZE 13 +/** 40 bits RC4 - WEP */ +#define MIN_WEP_KEY_SIZE 5 +/** packet number size */ +#define PN_SIZE 16 +/** max seq size of wpa/wpa2 key */ +#define SEQ_MAX_SIZE 8 + +/** key flag for tx_seq */ +#define KEY_FLAG_TX_SEQ_VALID 0x00000001 +/** key flag for rx_seq */ +#define KEY_FLAG_RX_SEQ_VALID 0x00000002 +/** key flag for group key */ +#define KEY_FLAG_GROUP_KEY 0x00000004 +/** key flag for tx and rx */ +#define KEY_FLAG_SET_TX_KEY 0x00000008 +/** key flag for remove key */ +#define KEY_FLAG_REMOVE_KEY 0x80000000 + +/** Type definition of mlan_ds_encrypt_key for MLAN_OID_SEC_CFG_ENCRYPT_KEY */ +typedef struct _mlan_ds_encrypt_key +{ + /** Key disabled, all other fields will be ignore when this flag set to MTRUE */ + t_u32 key_disable; + /** key removed flag, when this flag is set to MTRUE, only key_index will be check */ + t_u32 key_remove; + /** Key index, used as current tx key index when is_current_wep_key is set to MTRUE */ + t_u32 key_index; + /** Current Tx key flag */ + t_u32 is_current_wep_key; + /** Key length */ + t_u32 key_len; + /** Key */ + t_u8 key_material[MLAN_MAX_KEY_LENGTH]; + /** mac address */ + t_u8 mac_addr[MLAN_MAC_ADDR_LENGTH]; + /** wapi key flag */ + t_u32 is_wapi_key; + /** Initial packet number */ + t_u8 pn[PN_SIZE]; + /** key flags */ + t_u32 key_flags; +} mlan_ds_encrypt_key, *pmlan_ds_encrypt_key; + +/** Type definition of mlan_passphrase_t */ +typedef struct _mlan_passphrase_t +{ + /** Length of passphrase */ + t_u32 passphrase_len; + /** Passphrase */ + t_u8 passphrase[MLAN_MAX_PASSPHRASE_LENGTH]; +} mlan_passphrase_t; + +/** Type defnition of mlan_pmk_t */ +typedef struct _mlan_pmk_t +{ + /** PMK */ + t_u8 pmk[MLAN_MAX_KEY_LENGTH]; +} mlan_pmk_t; + +/** Embedded supplicant RSN type: No RSN */ +#define RSN_TYPE_NO_RSN MBIT(0) +/** Embedded supplicant RSN type: WPA */ +#define RSN_TYPE_WPA MBIT(3) +/** Embedded supplicant RSN type: WPA-NONE */ +#define RSN_TYPE_WPANONE MBIT(4) +/** Embedded supplicant RSN type: WPA2 */ +#define RSN_TYPE_WPA2 MBIT(5) +/** Embedded supplicant RSN type: RFU */ +#define RSN_TYPE_VALID_BITS (RSN_TYPE_NO_RSN | RSN_TYPE_WPA | RSN_TYPE_WPANONE | RSN_TYPE_WPA2) + +/** Embedded supplicant cipher type: TKIP */ +#define EMBED_CIPHER_TKIP MBIT(2) +/** Embedded supplicant cipher type: AES */ +#define EMBED_CIPHER_AES MBIT(3) +/** Embedded supplicant cipher type: RFU */ +#define EMBED_CIPHER_VALID_BITS (EMBED_CIPHER_TKIP | EMBED_CIPHER_AES) + +/** Type definition of mlan_ds_passphrase for MLAN_OID_SEC_CFG_PASSPHRASE */ +typedef struct _mlan_ds_passphrase +{ + /** SSID may be used */ + mlan_802_11_ssid ssid; + /** BSSID may be used */ + mlan_802_11_mac_addr bssid; + /** Flag for passphrase or pmk used */ + t_u16 psk_type; + /** Passphrase or PMK */ + union + { + /** Passphrase */ + mlan_passphrase_t passphrase; + /** PMK */ + mlan_pmk_t pmk; + } psk; +} mlan_ds_passphrase, *pmlan_ds_passphrase; + +/** Type definition of mlan_ds_esupp_mode for MLAN_OID_SEC_CFG_ESUPP_MODE */ +typedef struct _mlan_ds_ewpa_mode +{ + /** RSN mode */ + t_u32 rsn_mode; + /** Active pairwise cipher */ + t_u32 act_paircipher; + /** Active pairwise cipher */ + t_u32 act_groupcipher; +} mlan_ds_esupp_mode, *pmlan_ds_esupp_mode; + +/** Type definition of mlan_ds_sec_cfg for MLAN_IOCTL_SEC_CFG */ +typedef struct _mlan_ds_sec_cfg +{ + /** Sub-command */ + t_u32 sub_command; + /** Security configuration parameter */ + union + { + /** Authentication mode for MLAN_OID_SEC_CFG_AUTH_MODE */ + t_u32 auth_mode; + /** Encryption mode for MLAN_OID_SEC_CFG_ENCRYPT_MODE */ + t_u32 encrypt_mode; + /** WPA enabled flag for MLAN_OID_SEC_CFG_WPA_ENABLED */ + t_u32 wpa_enabled; + /** WAPI enabled flag for MLAN_OID_SEC_CFG_WAPI_ENABLED */ + t_u32 wapi_enabled; + /** Port Control enabled flag for MLAN_OID_SEC_CFG_PORT_CTRL */ + t_u32 port_ctrl_enabled; + /** Encryption key for MLAN_OID_SEC_CFG_ENCRYPT_KEY */ + mlan_ds_encrypt_key encrypt_key; + /** Passphrase for MLAN_OID_SEC_CFG_PASSPHRASE */ + mlan_ds_passphrase passphrase; + /** Embedded supplicant WPA enabled flag for MLAN_OID_SEC_CFG_EWPA_ENABLED */ + t_u32 ewpa_enabled; + /** Embedded supplicant mode for MLAN_OID_SEC_CFG_ESUPP_MODE */ + mlan_ds_esupp_mode esupp_mode; + } param; +} mlan_ds_sec_cfg, *pmlan_ds_sec_cfg; + +/*-----------------------------------------------------------------*/ +/** Rate Configuration Group */ +/*-----------------------------------------------------------------*/ +/** Enumeration for rate type */ +enum _mlan_rate_type +{ + MLAN_RATE_INDEX, + MLAN_RATE_VALUE +}; + +/** Enumeration for rate format */ +enum _mlan_rate_format +{ + MLAN_RATE_FORMAT_LG = 0, + MLAN_RATE_FORMAT_HT, + MLAN_RATE_FORMAT_AUTO = 0xFF, +}; +/** Max bitmap rates size */ +#define MAX_BITMAP_RATES_SIZE 10 + +/** Type definition of mlan_rate_cfg_t for MLAN_OID_RATE_CFG */ +typedef struct _mlan_rate_cfg_t +{ + /** Fixed rate: 0, auto rate: 1 */ + t_u32 is_rate_auto; + /** Rate type. 0: index; 1: valude */ + t_u32 rate_type; + /** Rate/MCS index or rate value if fixed rate */ + t_u32 rate; + /** Rate Bitmap */ + t_u16 bitmap_rates[MAX_BITMAP_RATES_SIZE]; +} mlan_rate_cfg_t; + +/** HT channel bandwidth */ +typedef enum _mlan_ht_bw +{ + MLAN_HT_BW20, + MLAN_HT_BW40, +} mlan_ht_bw; + +/** HT guard interval */ +typedef enum _mlan_ht_gi +{ + MLAN_HT_LGI, + MLAN_HT_SGI, +} mlan_ht_gi; + +/** Band and BSS mode */ +typedef struct _mlan_band_data_rate +{ + /** Band configuration */ + t_u8 config_bands; + /** BSS mode (Infra or IBSS) */ + t_u8 bss_mode; +} mlan_band_data_rate; + +/** Type definition of mlan_data_rate for MLAN_OID_GET_DATA_RATE */ +typedef struct _mlan_data_rate +{ + /** Tx data rate */ + t_u32 tx_data_rate; + /** Rx data rate */ + t_u32 rx_data_rate; + + /** Tx channel bandwidth */ + t_u32 tx_ht_bw; + /** Tx guard interval */ + t_u32 tx_ht_gi; + /** Rx channel bandwidth */ + t_u32 rx_ht_bw; + /** Rx guard interval */ + t_u32 rx_ht_gi; +} mlan_data_rate; + +/** Type definition of mlan_ds_rate for MLAN_IOCTL_RATE */ +typedef struct _mlan_ds_rate +{ + /** Sub-command */ + t_u32 sub_command; + /** Rate configuration parameter */ + union + { + /** Rate configuration for MLAN_OID_RATE_CFG */ + mlan_rate_cfg_t rate_cfg; + /** Data rate for MLAN_OID_GET_DATA_RATE */ + mlan_data_rate data_rate; + /** Supported rates for MLAN_OID_SUPPORTED_RATES */ + t_u8 rates[MLAN_SUPPORTED_RATES]; + /** Band/BSS mode for getting supported rates */ + mlan_band_data_rate rate_band_cfg; + } param; +} mlan_ds_rate, *pmlan_ds_rate; + +/*-----------------------------------------------------------------*/ +/** Power Configuration Group */ +/*-----------------------------------------------------------------*/ + +/** Type definition of mlan_power_cfg_t for MLAN_OID_POWER_CFG */ +typedef struct _mlan_power_cfg_t +{ + /** Is power auto */ + t_u32 is_power_auto; + /** Power level in dBm */ + t_u32 power_level; +} mlan_power_cfg_t; + +/** max power table size */ +#define MAX_POWER_TABLE_SIZE 128 + +/** The HT BW40 bit in Tx rate index */ +#define TX_RATE_HT_BW40_BIT MBIT(7) + +/** Type definition of mlan_power_cfg_ext for MLAN_OID_POWER_CFG_EXT */ +typedef struct _mlan_power_cfg_ext +{ + /** Length of power_data */ + t_u32 len; + /** Buffer of power configuration data */ + t_u32 power_data[MAX_POWER_TABLE_SIZE]; +} mlan_power_cfg_ext; + +/** Type definition of mlan_ds_power_cfg for MLAN_IOCTL_POWER_CFG */ +typedef struct _mlan_ds_power_cfg +{ + /** Sub-command */ + t_u32 sub_command; + /** Power configuration parameter */ + union + { + /** Power configuration for MLAN_OID_POWER_CFG */ + mlan_power_cfg_t power_cfg; + /** Extended power configuration for MLAN_OID_POWER_CFG_EXT */ + mlan_power_cfg_ext power_ext; + } param; +} mlan_ds_power_cfg, *pmlan_ds_power_cfg; + +/*-----------------------------------------------------------------*/ +/** Power Management Configuration Group */ +/*-----------------------------------------------------------------*/ +/** Host sleep config conditions : Cancel */ +#define HOST_SLEEP_CFG_CANCEL 0xffffffff + +/** Host sleep config condition: broadcast data */ +#define HOST_SLEEP_COND_BROADCAST_DATA MBIT(0) +/** Host sleep config condition: unicast data */ +#define HOST_SLEEP_COND_UNICAST_DATA MBIT(1) +/** Host sleep config condition: mac event */ +#define HOST_SLEEP_COND_MAC_EVENT MBIT(2) +/** Host sleep config condition: multicast data */ +#define HOST_SLEEP_COND_MULTICAST_DATA MBIT(3) + +/** Host sleep config conditions: Default */ +#define HOST_SLEEP_DEF_COND (HOST_SLEEP_COND_BROADCAST_DATA | HOST_SLEEP_COND_UNICAST_DATA | HOST_SLEEP_COND_MAC_EVENT) +/** Host sleep config GPIO : Default */ +#define HOST_SLEEP_DEF_GPIO 0xff +/** Host sleep config gap : Default */ +#define HOST_SLEEP_DEF_GAP 200 + +/** Type definition of mlan_ds_hs_cfg for MLAN_OID_PM_CFG_HS_CFG */ +typedef struct _mlan_ds_hs_cfg +{ + /** MTRUE to invoke the HostCmd, MFALSE otherwise */ + t_u32 is_invoke_hostcmd; + /** Host sleep config condition */ + /** Bit0: broadcast data + * Bit1: unicast data + * Bit2: mac event + * Bit3: multicast data + */ + t_u32 conditions; + /** GPIO pin or 0xff for interface */ + t_u32 gpio; + /** Gap in milliseconds or or 0xff for special setting when GPIO is used to wakeup host */ + t_u32 gap; +} mlan_ds_hs_cfg, *pmlan_ds_hs_cfg; + +/** Enable deep sleep mode */ +#define DEEP_SLEEP_ON 1 +/** Disable deep sleep mode */ +#define DEEP_SLEEP_OFF 0 + +/** Default idle time in milliseconds for auto deep sleep */ +#define DEEP_SLEEP_IDLE_TIME 100 + +typedef struct _mlan_ds_auto_ds +{ + /** auto ds mode, 0 - disable, 1 - enable */ + t_u16 auto_ds; + /** auto ds idle time in milliseconds */ + t_u16 idletime; +} mlan_ds_auto_ds; + +/** Type definition of mlan_ds_inactivity_to for MLAN_OID_PM_CFG_INACTIVITY_TO */ +typedef struct _mlan_ds_inactivity_to +{ + /** Timeout unit in microsecond, 0 means 1000us (1ms) */ + t_u32 timeout_unit; + /** Inactivity timeout for unicast data */ + t_u32 unicast_timeout; + /** Inactivity timeout for multicast data */ + t_u32 mcast_timeout; + /** Timeout for additional Rx traffic after Null PM1 packet exchange */ + t_u32 ps_entry_timeout; +} mlan_ds_inactivity_to, *pmlan_ds_inactivity_to; + +/** Minimum sleep period in milliseconds */ +#define MIN_SLEEP_PERIOD 10 +/** Maximum sleep period in milliseconds */ +#define MAX_SLEEP_PERIOD 60 +/** Special setting for UPSD certification tests */ +#define SLEEP_PERIOD_RESERVED_FF 0xFF + +/** PS null interval disable */ +#define PS_NULL_DISABLE (-1) + +/** Local listen interval disable */ +#define MRVDRV_LISTEN_INTERVAL_DISABLE (-1) +/** Minimum listen interval */ +#define MRVDRV_MIN_LISTEN_INTERVAL 0 + +/** Minimum multiple DTIM */ +#define MRVDRV_MIN_MULTIPLE_DTIM 0 +/** Maximum multiple DTIM */ +#define MRVDRV_MAX_MULTIPLE_DTIM 5 +/** Ignore multiple DTIM */ +#define MRVDRV_IGNORE_MULTIPLE_DTIM 0xfffe +/** Match listen interval to closest DTIM */ +#define MRVDRV_MATCH_CLOSEST_DTIM 0xfffd + +/** Minimum adhoc awake period */ +#define MIN_ADHOC_AWAKE_PD 0 +/** Maximum adhoc awake period */ +#define MAX_ADHOC_AWAKE_PD 31 +/** Special adhoc awake period */ +#define SPECIAL_ADHOC_AWAKE_PD 255 + +/** Minimum beacon miss timeout in milliseconds */ +#define MIN_BCN_MISS_TO 0 +/** Maximum beacon miss timeout in milliseconds */ +#define MAX_BCN_MISS_TO 50 +/** Disable beacon miss timeout */ +#define DISABLE_BCN_MISS_TO 65535 + +/** Minimum delay to PS in milliseconds */ +#define MIN_DELAY_TO_PS 0 +/** Maximum delay to PS in milliseconds */ +#define MAX_DELAY_TO_PS 65535 +/** Delay to PS unchanged */ +#define DELAY_TO_PS_UNCHANGED (-1) +/** Default delay to PS in milliseconds */ +#define DELAY_TO_PS_DEFAULT 1000 + +/** PS mode: Unchanged */ +#define PS_MODE_UNCHANGED 0 +/** PS mode: Auto */ +#define PS_MODE_AUTO 1 +/** PS mode: Poll */ +#define PS_MODE_POLL 2 +/** PS mode: Null */ +#define PS_MODE_NULL 3 + +/** Type definition of mlan_ds_ps_cfg for MLAN_OID_PM_CFG_PS_CFG */ +typedef struct _mlan_ds_ps_cfg +{ + /** PS null interval in seconds */ + t_u32 ps_null_interval; + /** Multiple DTIM interval */ + t_u32 multiple_dtim_interval; + /** Listen interval */ + t_u32 listen_interval; + /** Adhoc awake period */ + t_u32 adhoc_awake_period; + /** Beacon miss timeout in milliseconds */ + t_u32 bcn_miss_timeout; + /** Delay to PS in milliseconds */ + t_s32 delay_to_ps; + /** PS mode */ + t_u32 ps_mode; +} mlan_ds_ps_cfg, *pmlan_ds_ps_cfg; + +/** Type definition of mlan_ds_sleep_params for MLAN_OID_PM_CFG_SLEEP_PARAMS */ +typedef struct _mlan_ds_sleep_params +{ + /** Error */ + t_u32 error; + /** Offset in microseconds */ + t_u32 offset; + /** Stable time in microseconds */ + t_u32 stable_time; + /** Calibration control */ + t_u32 cal_control; + /** External sleep clock */ + t_u32 ext_sleep_clk; + /** Reserved */ + t_u32 reserved; +} mlan_ds_sleep_params, *pmlan_ds_sleep_params; + +/** sleep_param */ +typedef struct _ps_sleep_param +{ + /** control bitmap */ + t_u32 ctrl_bitmap; + /** minimum sleep period (micro second) */ + t_u32 min_sleep; + /** maximum sleep period (micro second) */ + t_u32 max_sleep; +} ps_sleep_param; + +/** inactivity sleep_param */ +typedef struct _inact_sleep_param +{ + /** inactivity timeout (micro second) */ + t_u32 inactivity_to; + /** miniumu awake period (micro second) */ + t_u32 min_awake; + /** maximum awake period (micro second) */ + t_u32 max_awake; +} inact_sleep_param; + +/** flag for ps mode */ +#define PS_FLAG_PS_MODE 1 +/** flag for sleep param */ +#define PS_FLAG_SLEEP_PARAM 2 +/** flag for inactivity sleep param */ +#define PS_FLAG_INACT_SLEEP_PARAM 4 + +/** Disable power mode */ +#define PS_MODE_DISABLE 0 +/** Enable periodic dtim ps */ +#define PS_MODE_PERIODIC_DTIM 1 +/** Enable inactivity ps */ +#define PS_MODE_INACTIVITY 2 + +/** mlan_ds_ps_mgmt */ +typedef struct _mlan_ds_ps_mgmt +{ + /** flags for valid field */ + t_u16 flags; + /** power mode */ + t_u16 ps_mode; + /** sleep param */ + ps_sleep_param sleep_param; + /** inactivity sleep param */ + inact_sleep_param inact_param; +} mlan_ds_ps_mgmt; + +/** mlan_ds_ps_info */ +typedef struct _mlan_ds_ps_info +{ + /** suspend allowed flag */ + t_u32 is_suspend_allowed; +} mlan_ds_ps_info; + +/** Type definition of mlan_ds_pm_cfg for MLAN_IOCTL_PM_CFG */ +typedef struct _mlan_ds_pm_cfg +{ + /** Sub-command */ + t_u32 sub_command; + /** Power management parameter */ + union + { + /** Power saving mode for MLAN_OID_PM_CFG_IEEE_PS */ + t_u32 ps_mode; + /** Host Sleep configuration for MLAN_OID_PM_CFG_HS_CFG */ + mlan_ds_hs_cfg hs_cfg; + /** Deep sleep mode for MLAN_OID_PM_CFG_DEEP_SLEEP */ + mlan_ds_auto_ds auto_deep_sleep; + /** Inactivity timeout for MLAN_OID_PM_CFG_INACTIVITY_TO */ + mlan_ds_inactivity_to inactivity_to; + /** Sleep period for MLAN_OID_PM_CFG_SLEEP_PD */ + t_u32 sleep_period; + /** PS configuration parameters for MLAN_OID_PM_CFG_PS_CFG */ + mlan_ds_ps_cfg ps_cfg; + /** PS configuration parameters for MLAN_OID_PM_CFG_SLEEP_PARAMS */ + mlan_ds_sleep_params sleep_params; + /** PS configuration parameters for MLAN_OID_PM_CFG_PS_MODE */ + mlan_ds_ps_mgmt ps_mgmt; + /** power info for MLAN_OID_PM_INFO */ + mlan_ds_ps_info ps_info; + } param; +} mlan_ds_pm_cfg, *pmlan_ds_pm_cfg; + +/*-----------------------------------------------------------------*/ +/** WMM Configuration Group */ +/*-----------------------------------------------------------------*/ + +/** WMM TSpec size */ +#define MLAN_WMM_TSPEC_SIZE 63 +/** WMM Add TS extra IE bytes */ +#define MLAN_WMM_ADDTS_EXTRA_IE_BYTES 256 +/** WMM statistics for packets hist bins */ +#define MLAN_WMM_STATS_PKTS_HIST_BINS 7 +/** Maximum number of AC QOS queues available */ +#define MLAN_WMM_MAX_AC_QUEUES 4 + +/** + * @brief IOCTL structure to send an ADDTS request and retrieve the response. + * + * IOCTL structure from the application layer relayed to firmware to + * instigate an ADDTS management frame with an appropriate TSPEC IE as well + * as any additional IEs appended in the ADDTS Action frame. + * + * @sa woal_wmm_addts_req_ioctl + */ +typedef struct +{ + mlan_cmd_result_e cmd_result; /**< Firmware execution result */ + + t_u32 timeout_ms; /**< Timeout value in milliseconds */ + t_u8 ieee_status_code; /**< IEEE status code */ + + t_u32 ie_data_len; /**< Length of ie block in ie_data */ + t_u8 ie_data[MLAN_WMM_TSPEC_SIZE /**< TSPEC to send in the ADDTS */ + + MLAN_WMM_ADDTS_EXTRA_IE_BYTES]; /**< Extra IE buf*/ +} wlan_ioctl_wmm_addts_req_t; + +/** + * @brief IOCTL structure to send a DELTS request. + * + * IOCTL structure from the application layer relayed to firmware to + * instigate an DELTS management frame with an appropriate TSPEC IE. + * + * @sa woal_wmm_delts_req_ioctl + */ +typedef struct +{ + mlan_cmd_result_e cmd_result; /**< Firmware execution result */ + t_u8 ieee_reason_code; /**< IEEE reason code sent, unused for WMM */ + t_u32 ie_data_len; /**< Length of ie block in ie_data */ + t_u8 ie_data[MLAN_WMM_TSPEC_SIZE]; /**< TSPEC to send in the DELTS */ +} wlan_ioctl_wmm_delts_req_t; + +/** + * @brief IOCTL structure to configure a specific AC Queue's parameters + * + * IOCTL structure from the application layer relayed to firmware to + * get, set, or default the WMM AC queue parameters. + * + * - msdu_lifetime_expiry is ignored if set to 0 on a set command + * + * @sa woal_wmm_queue_config_ioctl + */ +typedef struct +{ + mlan_wmm_queue_config_action_e action; /**< Set, Get, or Default */ + mlan_wmm_ac_e access_category; /**< WMM_AC_BK(0) to WMM_AC_VO(3) */ + t_u16 msdu_lifetime_expiry; /**< lifetime expiry in TUs */ + t_u8 supported_rates[10]; /**< Not supported yet */ +} wlan_ioctl_wmm_queue_config_t; + +/** + * @brief IOCTL structure to start, stop, and get statistics for a WMM AC + * + * IOCTL structure from the application layer relayed to firmware to + * start or stop statistical collection for a given AC. Also used to + * retrieve and clear the collected stats on a given AC. + * + * @sa woal_wmm_queue_stats_ioctl + */ +typedef struct +{ + /** Action of Queue Config : Start, Stop, or Get */ + mlan_wmm_queue_stats_action_e action; + /** User Priority */ + t_u8 user_priority; + /** Number of successful packets transmitted */ + t_u16 pkt_count; + /** Packets lost; not included in pkt_count */ + t_u16 pkt_loss; + /** Average Queue delay in microseconds */ + t_u32 avg_queue_delay; + /** Average Transmission delay in microseconds */ + t_u32 avg_tx_delay; + /** Calculated used time in units of 32 microseconds */ + t_u16 used_time; + /** Calculated policed time in units of 32 microseconds */ + t_u16 policed_time; + /** Queue Delay Histogram; number of packets per queue delay range + * + * [0] - 0ms <= delay < 5ms + * [1] - 5ms <= delay < 10ms + * [2] - 10ms <= delay < 20ms + * [3] - 20ms <= delay < 30ms + * [4] - 30ms <= delay < 40ms + * [5] - 40ms <= delay < 50ms + * [6] - 50ms <= delay < msduLifetime (TUs) + */ + t_u16 delay_histogram[MLAN_WMM_STATS_PKTS_HIST_BINS]; +} wlan_ioctl_wmm_queue_stats_t, +/** Type definition of mlan_ds_wmm_queue_stats for MLAN_OID_WMM_CFG_QUEUE_STATS */ + mlan_ds_wmm_queue_stats, *pmlan_ds_wmm_queue_stats; + +/** + * @brief IOCTL sub structure for a specific WMM AC Status + */ +typedef struct +{ + /** WMM Acm */ + t_u8 wmm_acm; + /** Flow required flag */ + t_u8 flow_required; + /** Flow created flag */ + t_u8 flow_created; + /** Disabled flag */ + t_u8 disabled; +} wlan_ioctl_wmm_queue_status_ac_t; + +/** + * @brief IOCTL structure to retrieve the WMM AC Queue status + * + * IOCTL structure from the application layer to retrieve: + * - ACM bit setting for the AC + * - Firmware status (flow required, flow created, flow disabled) + * + * @sa woal_wmm_queue_status_ioctl + */ +typedef struct +{ + /** WMM AC queue status */ + wlan_ioctl_wmm_queue_status_ac_t ac_status[MLAN_WMM_MAX_AC_QUEUES]; +} wlan_ioctl_wmm_queue_status_t, +/** Type definition of mlan_ds_wmm_queue_status for MLAN_OID_WMM_CFG_QUEUE_STATUS */ + mlan_ds_wmm_queue_status, *pmlan_ds_wmm_queue_status; + +/** Type definition of mlan_ds_wmm_addts for MLAN_OID_WMM_CFG_ADDTS */ +typedef struct _mlan_ds_wmm_addts +{ + /** Result of ADDTS request */ + mlan_cmd_result_e result; + /** Timeout value in milliseconds */ + t_u32 timeout; + /** IEEE status code */ + t_u32 status_code; + /** Dialog token */ + t_u8 dialog_tok; + /** TSPEC data length */ + t_u8 ie_data_len; + /** TSPEC to send in the ADDTS + buffering for any extra IEs */ + t_u8 ie_data[MLAN_WMM_TSPEC_SIZE + MLAN_WMM_ADDTS_EXTRA_IE_BYTES]; +} mlan_ds_wmm_addts, *pmlan_ds_wmm_addts; + +/** Type definition of mlan_ds_wmm_delts for MLAN_OID_WMM_CFG_DELTS */ +typedef struct _mlan_ds_wmm_delts +{ + /** Result of DELTS request */ + mlan_cmd_result_e result; + /** IEEE status code */ + t_u32 status_code; + /** TSPEC data length */ + t_u8 ie_data_len; + /** TSPEC to send in the DELTS */ + t_u8 ie_data[MLAN_WMM_TSPEC_SIZE]; +} mlan_ds_wmm_delts, *pmlan_ds_wmm_delts; + +/** Type definition of mlan_ds_wmm_queue_config for MLAN_OID_WMM_CFG_QUEUE_CONFIG */ +typedef struct _mlan_ds_wmm_queue_config +{ + /** Action of Queue Config : Set, Get, or Default */ + mlan_wmm_queue_config_action_e action; + /** WMM Access Category: WMM_AC_BK(0) to WMM_AC_VO(3) */ + mlan_wmm_ac_e access_category; + /** Lifetime expiry in TUs */ + t_u16 msdu_lifetime_expiry; + /** Reserve for future use */ + t_u8 reserved[10]; +} mlan_ds_wmm_queue_config, *pmlan_ds_wmm_queue_config; + +/** Type definition of mlan_ds_wmm_cfg for MLAN_IOCTL_WMM_CFG */ +typedef struct _mlan_ds_wmm_cfg +{ + /** Sub-command */ + t_u32 sub_command; + /** WMM configuration parameter */ + union + { + /** WMM enable for MLAN_OID_WMM_CFG_ENABLE */ + t_u32 wmm_enable; + /** QoS configuration for MLAN_OID_WMM_CFG_QOS */ + t_u8 qos_cfg; + /** WMM add TS for MLAN_OID_WMM_CFG_ADDTS */ + mlan_ds_wmm_addts addts; + /** WMM delete TS for MLAN_OID_WMM_CFG_DELTS */ + mlan_ds_wmm_delts delts; + /** WMM queue configuration for MLAN_OID_WMM_CFG_QUEUE_CONFIG */ + mlan_ds_wmm_queue_config q_cfg; + /** WMM queue status for MLAN_OID_WMM_CFG_QUEUE_STATS */ + mlan_ds_wmm_queue_stats q_stats; + /** WMM queue status for MLAN_OID_WMM_CFG_QUEUE_STATUS */ + mlan_ds_wmm_queue_status q_status; + /** WMM TS status for MLAN_OID_WMM_CFG_TS_STATUS */ + mlan_ds_wmm_ts_status ts_status; + } param; +} mlan_ds_wmm_cfg, *pmlan_ds_wmm_cfg; + +/*-----------------------------------------------------------------*/ +/** WPS Configuration Group */ +/*-----------------------------------------------------------------*/ +/** Enumeration for WPS session */ +enum _mlan_wps_status +{ + MLAN_WPS_CFG_SESSION_START = 1, + MLAN_WPS_CFG_SESSION_END = 0 +}; + +/** Type definition of mlan_ds_wps_cfg for MLAN_IOCTL_WPS_CFG */ +typedef struct _mlan_ds_wps_cfg +{ + /** Sub-command */ + t_u32 sub_command; + /** WPS configuration parameter */ + union + { + /** WPS session for MLAN_OID_WPS_CFG_SESSION */ + t_u32 wps_session; + } param; +} mlan_ds_wps_cfg, *pmlan_ds_wps_cfg; + +/*-----------------------------------------------------------------*/ +/** 802.11n Configuration Group */ +/*-----------------------------------------------------------------*/ +/** Maximum MCS */ +#define NUM_MCS_FIELD 16 + +/** Supported stream modes */ +#define HT_STREAM_MODE_1X1 0x11 +#define HT_STREAM_MODE_2X2 0x22 + +/* Both 2.4G and 5G band selected */ +#define BAND_SELECT_BOTH 0 +/* Band 2.4G selected */ +#define BAND_SELECT_BG 1 +/* Band 5G selected */ +#define BAND_SELECT_A 2 + +/** Type definition of mlan_ds_11n_htcap_cfg for MLAN_OID_11N_HTCAP_CFG */ +typedef struct _mlan_ds_11n_htcap_cfg +{ + /** HT Capability information */ + t_u32 htcap; + /** Band selection */ + t_u32 misc_cfg; + /** Hardware HT cap information required */ + t_u32 hw_cap_req; +} mlan_ds_11n_htcap_cfg, *pmlan_ds_11n_htcap_cfg; + +/** Type definition of mlan_ds_11n_addba_param for MLAN_OID_11N_CFG_ADDBA_PARAM */ +typedef struct _mlan_ds_11n_addba_param +{ + /** Timeout */ + t_u32 timeout; + /** Buffer size for ADDBA request */ + t_u32 txwinsize; + /** Buffer size for ADDBA response */ + t_u32 rxwinsize; + /** amsdu for ADDBA request */ + t_u8 txamsdu; + /** amsdu for ADDBA response */ + t_u8 rxamsdu; +} mlan_ds_11n_addba_param, *pmlan_ds_11n_addba_param; + +/** Type definition of mlan_ds_11n_tx_cfg for MLAN_OID_11N_CFG_TX */ +typedef struct _mlan_ds_11n_tx_cfg +{ + /** HTTxCap */ + t_u16 httxcap; + /** HTTxInfo */ + t_u16 httxinfo; + /** Band selection */ + t_u32 misc_cfg; +} mlan_ds_11n_tx_cfg, *pmlan_ds_11n_tx_cfg; + +/** BF Global Configuration */ +#define BF_GLOBAL_CONFIGURATION 0x00 +/** Performs NDP sounding for PEER specified */ +#define TRIGGER_SOUNDING_FOR_PEER 0x01 +/** TX BF interval for channel sounding */ +#define SET_GET_BF_PERIODICITY 0x02 +/** Tell FW not to perform any sounding for peer */ +#define TX_BF_FOR_PEER_ENBL 0x03 +/** TX BF SNR threshold for peer */ +#define SET_SNR_THR_PEER 0x04 + +/* Maximum number of peer MAC and status/SNR tuples */ +#define MAX_PEER_MAC_TUPLES 10 + +/** Any new subcommand structure should be declare here */ + +/** bf global cfg args */ +typedef struct _mlan_bf_global_cfg_args +{ + /** Global enable/disable bf */ + t_u8 bf_enbl; + /** Global enable/disable sounding */ + t_u8 sounding_enbl; + /** FB Type */ + t_u8 fb_type; + /** SNR Threshold */ + t_u8 snr_threshold; + /** Sounding interval in milliseconds */ + t_u16 sounding_interval; + /** BF mode */ + t_u8 bf_mode; + /** Reserved */ + t_u8 reserved; +} mlan_bf_global_cfg_args; + +/** trigger sounding args */ +typedef struct _mlan_trigger_sound_args +{ + /** Peer MAC address */ + t_u8 peer_mac[MLAN_MAC_ADDR_LENGTH]; + /** Status */ + t_u8 status; +} mlan_trigger_sound_args; + +/** bf periodicity args */ +typedef struct _mlan_bf_periodicity_args +{ + /** Peer MAC address */ + t_u8 peer_mac[MLAN_MAC_ADDR_LENGTH]; + /** Current Tx BF Interval in milliseconds */ + t_u16 interval; + /** Status */ + t_u8 status; +} mlan_bf_periodicity_args; + +/** tx bf peer args */ +typedef struct _mlan_tx_bf_peer_args +{ + /** Peer MAC address */ + t_u8 peer_mac[MLAN_MAC_ADDR_LENGTH]; + /** Reserved */ + t_u16 reserved; + /** Enable/Disable Beamforming */ + t_u8 bf_enbl; + /** Enable/Disable sounding */ + t_u8 sounding_enbl; + /** FB Type */ + t_u8 fb_type; +} mlan_tx_bf_peer_args; + +/** SNR threshold args */ +typedef struct _mlan_snr_thr_args +{ + /** Peer MAC address */ + t_u8 peer_mac[MLAN_MAC_ADDR_LENGTH]; + /** SNR for peer */ + t_u8 snr; +} mlan_snr_thr_args; + +/** Type definition of mlan_ds_11n_tx_bf_cfg for MLAN_OID_11N_CFG_TX_BF_CFG */ +typedef struct _mlan_ds_11n_tx_bf_cfg +{ + /** BF Action */ + t_u16 bf_action; + /** Action */ + t_u16 action; + /** Number of peers */ + t_u32 no_of_peers; + union + { + mlan_bf_global_cfg_args bf_global_cfg; + mlan_trigger_sound_args bf_sound[MAX_PEER_MAC_TUPLES]; + mlan_bf_periodicity_args bf_periodicity[MAX_PEER_MAC_TUPLES]; + mlan_tx_bf_peer_args tx_bf_peer[MAX_PEER_MAC_TUPLES]; + mlan_snr_thr_args bf_snr[MAX_PEER_MAC_TUPLES]; + } body; +} mlan_ds_11n_tx_bf_cfg, *pmlan_ds_11n_tx_bf_cfg; + +/** Type definition of mlan_ds_11n_amsdu_aggr_ctrl for + * MLAN_OID_11N_AMSDU_AGGR_CTRL*/ +typedef struct _mlan_ds_11n_amsdu_aggr_ctrl +{ + /** Enable/Disable */ + t_u16 enable; + /** Current AMSDU size valid */ + t_u16 curr_buf_size; +} mlan_ds_11n_amsdu_aggr_ctrl, *pmlan_ds_11n_amsdu_aggr_ctrl; + +/** Type definition of mlan_ds_11n_aggr_prio_tbl for MLAN_OID_11N_CFG_AGGR_PRIO_TBL */ +typedef struct _mlan_ds_11n_aggr_prio_tbl +{ + /** ampdu priority table */ + t_u8 ampdu[MAX_NUM_TID]; + /** amsdu priority table */ + t_u8 amsdu[MAX_NUM_TID]; +} mlan_ds_11n_aggr_prio_tbl, *pmlan_ds_11n_aggr_prio_tbl; + +/** Type definition of mlan_ds_11n_cfg for MLAN_IOCTL_11N_CFG */ +typedef struct _mlan_ds_11n_cfg +{ + /** Sub-command */ + t_u32 sub_command; + /** 802.11n configuration parameter */ + union + { + /** Tx param for 11n for MLAN_OID_11N_CFG_TX */ + mlan_ds_11n_tx_cfg tx_cfg; + /** Aggr priority table for MLAN_OID_11N_CFG_AGGR_PRIO_TBL */ + mlan_ds_11n_aggr_prio_tbl aggr_prio_tbl; + /** Add BA param for MLAN_OID_11N_CFG_ADDBA_PARAM */ + mlan_ds_11n_addba_param addba_param; + /** Add BA Reject paramters for MLAN_OID_11N_CFG_ADDBA_REJECT */ + t_u8 addba_reject[MAX_NUM_TID]; + /** Tx buf size for MLAN_OID_11N_CFG_MAX_TX_BUF_SIZE */ + t_u32 tx_buf_size; + /** HT cap info configuration for MLAN_OID_11N_HTCAP_CFG */ + mlan_ds_11n_htcap_cfg htcap_cfg; + /** Tx param for 11n for MLAN_OID_11N_AMSDU_AGGR_CTRL */ + mlan_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl; + /** Supported MCS Set field */ + t_u8 supported_mcs_set[NUM_MCS_FIELD]; + /** Transmit Beamforming Capabilities field */ + t_u32 tx_bf_cap; + /** Transmit Beamforming configuration */ + mlan_ds_11n_tx_bf_cfg tx_bf; + /** HT stream configuration */ + t_u32 stream_cfg; + } param; +} mlan_ds_11n_cfg, *pmlan_ds_11n_cfg; + +/** Country code length */ +#define COUNTRY_CODE_LEN 3 + +/*-----------------------------------------------------------------*/ +/** 802.11d Configuration Group */ +/*-----------------------------------------------------------------*/ +/** Maximum subbands for 11d */ +#define MRVDRV_MAX_SUBBAND_802_11D 83 + +#ifdef STA_SUPPORT +/** Data structure for subband set */ +typedef struct _mlan_ds_subband_set_t +{ + /** First channel */ + t_u8 first_chan; + /** Number of channels */ + t_u8 no_of_chan; + /** Maximum Tx power in dBm */ + t_u8 max_tx_pwr; +} mlan_ds_subband_set_t; + +/** Domain regulatory information */ +typedef struct _mlan_ds_11d_domain_info +{ + /** Country Code */ + t_u8 country_code[COUNTRY_CODE_LEN]; + /** Band that channels in sub_band belong to */ + t_u8 band; + /** No. of subband in below */ + t_u8 no_of_sub_band; + /** Subband data to send/last sent */ + mlan_ds_subband_set_t sub_band[MRVDRV_MAX_SUBBAND_802_11D]; +} mlan_ds_11d_domain_info; +#endif + +/** Type definition of mlan_ds_11d_cfg for MLAN_IOCTL_11D_CFG */ +typedef struct _mlan_ds_11d_cfg +{ + /** Sub-command */ + t_u32 sub_command; + /** 802.11d configuration parameter */ + union + { +#ifdef STA_SUPPORT + /** Enable for MLAN_OID_11D_CFG_ENABLE */ + t_u32 enable_11d; + /** Domain info for MLAN_OID_11D_DOMAIN_INFO */ + mlan_ds_11d_domain_info domain_info; +#endif /* STA_SUPPORT */ +#ifdef UAP_SUPPORT + /** tlv data for MLAN_OID_11D_DOMAIN_INFO */ + t_u8 domain_tlv[MAX_IE_SIZE]; +#endif /* UAP_SUPPORT */ + } param; +} mlan_ds_11d_cfg, *pmlan_ds_11d_cfg; + +/*-----------------------------------------------------------------*/ +/** Register Memory Access Group */ +/*-----------------------------------------------------------------*/ +/** Enumeration for register type */ +enum _mlan_reg_type +{ + MLAN_REG_MAC = 1, + MLAN_REG_BBP, + MLAN_REG_RF, + MLAN_REG_CAU = 5, +}; + +/** Type definition of mlan_ds_reg_rw for MLAN_OID_REG_RW */ +typedef struct _mlan_ds_reg_rw +{ + /** Register type */ + t_u32 type; + /** Offset */ + t_u32 offset; + /** Value */ + t_u32 value; +} mlan_ds_reg_rw; + +/** Maximum EEPROM data */ +#define MAX_EEPROM_DATA 256 + +/** Type definition of mlan_ds_read_eeprom for MLAN_OID_EEPROM_RD */ +typedef struct _mlan_ds_read_eeprom +{ + /** Multiples of 4 */ + t_u16 offset; + /** Number of bytes */ + t_u16 byte_count; + /** Value */ + t_u8 value[MAX_EEPROM_DATA]; +} mlan_ds_read_eeprom; + +/** Type definition of mlan_ds_mem_rw for MLAN_OID_MEM_RW */ +typedef struct _mlan_ds_mem_rw +{ + /** Address */ + t_u32 addr; + /** Value */ + t_u32 value; +} mlan_ds_mem_rw; + +/** Type definition of mlan_ds_reg_mem for MLAN_IOCTL_REG_MEM */ +typedef struct _mlan_ds_reg_mem +{ + /** Sub-command */ + t_u32 sub_command; + /** Register memory access parameter */ + union + { + /** Register access for MLAN_OID_REG_RW */ + mlan_ds_reg_rw reg_rw; + /** EEPROM access for MLAN_OID_EEPROM_RD */ + mlan_ds_read_eeprom rd_eeprom; + /** Memory access for MLAN_OID_MEM_RW */ + mlan_ds_mem_rw mem_rw; + } param; +} mlan_ds_reg_mem, *pmlan_ds_reg_mem; + +/*-----------------------------------------------------------------*/ +/** Multi-Radio Configuration Group */ +/*-----------------------------------------------------------------*/ + +/*-----------------------------------------------------------------*/ +/** 802.11h Configuration Group */ +/*-----------------------------------------------------------------*/ +#if defined(DFS_TESTING_SUPPORT) +/** Type definition of mlan_ds_11h_dfs_testing for MLAN_OID_11H_DFS_TESTING */ +typedef struct _mlan_ds_11h_dfs_testing +{ + /** User-configured CAC period in milliseconds, 0 to use default */ + t_u16 usr_cac_period_msec; + /** User-configured NOP period in seconds, 0 to use default */ + t_u16 usr_nop_period_sec; + /** User-configured skip channel change, 0 to disable */ + t_u8 usr_no_chan_change; + /** User-configured fixed channel to change to, 0 to use random channel */ + t_u8 usr_fixed_new_chan; +} mlan_ds_11h_dfs_testing, *pmlan_ds_11h_dfs_testing; +#endif + +/** Type definition of mlan_ds_11h_cfg for MLAN_IOCTL_11H_CFG */ +typedef struct _mlan_ds_11h_cfg +{ + /** Sub-command */ + t_u32 sub_command; + union + { + /** Local power constraint for MLAN_OID_11H_LOCAL_POWER_CONSTRAINT */ + t_s8 usr_local_power_constraint; +#if defined(DFS_TESTING_SUPPORT) + /** User-configuation for MLAN_OID_11H_DFS_TESTING */ + mlan_ds_11h_dfs_testing dfs_testing; +#endif + } param; +} mlan_ds_11h_cfg, *pmlan_ds_11h_cfg; + +/*-----------------------------------------------------------------*/ +/** Miscellaneous Configuration Group */ +/*-----------------------------------------------------------------*/ + +/** CMD buffer size */ +#define MLAN_SIZE_OF_CMD_BUFFER 2048 + +/** LDO Internal */ +#define LDO_INTERNAL 0 +/** LDO External */ +#define LDO_EXTERNAL 1 + +/** Enumeration for IE type */ +enum _mlan_ie_type +{ + MLAN_IE_TYPE_GEN_IE = 0, +#ifdef STA_SUPPORT + MLAN_IE_TYPE_ARP_FILTER, +#endif /* STA_SUPPORT */ +}; + +/** Type definition of mlan_ds_misc_gen_ie for MLAN_OID_MISC_GEN_IE */ +typedef struct _mlan_ds_misc_gen_ie +{ + /** IE type */ + t_u32 type; + /** IE length */ + t_u32 len; + /** IE buffer */ + t_u8 ie_data[MAX_IE_SIZE]; +} mlan_ds_misc_gen_ie; + +#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR) +/** Type definition of mlan_ds_misc_sdio_mpa_ctrl for MLAN_OID_MISC_SDIO_MPA_CTRL */ +typedef struct _mlan_ds_misc_sdio_mpa_ctrl +{ + /** SDIO MP-A TX enable/disable */ + t_u16 tx_enable; + /** SDIO MP-A RX enable/disable */ + t_u16 rx_enable; + /** SDIO MP-A TX buf size */ + t_u16 tx_buf_size; + /** SDIO MP-A RX buf size */ + t_u16 rx_buf_size; + /** SDIO MP-A TX Max Ports */ + t_u16 tx_max_ports; + /** SDIO MP-A RX Max Ports */ + t_u16 rx_max_ports; +} mlan_ds_misc_sdio_mpa_ctrl; +#endif + +/** Type definition of mlan_ds_misc_cmd for MLAN_OID_MISC_HOST_CMD */ +typedef struct _mlan_ds_misc_cmd +{ + /** Command length */ + t_u32 len; + /** Command buffer */ + t_u8 cmd[MLAN_SIZE_OF_CMD_BUFFER]; +} mlan_ds_misc_cmd; + +/** Maximum number of system clocks */ +#define MLAN_MAX_CLK_NUM 16 + +/** Clock type : Configurable */ +#define MLAN_CLK_CONFIGURABLE 0 +/** Clock type : Supported */ +#define MLAN_CLK_SUPPORTED 1 + +/** Type definition of mlan_ds_misc_sys_clock for MLAN_OID_MISC_SYS_CLOCK */ +typedef struct _mlan_ds_misc_sys_clock +{ + /** Current system clock */ + t_u16 cur_sys_clk; + /** Clock type */ + t_u16 sys_clk_type; + /** Number of clocks */ + t_u16 sys_clk_num; + /** System clocks */ + t_u16 sys_clk[MLAN_MAX_CLK_NUM]; +} mlan_ds_misc_sys_clock; + +/** Enumeration for function init/shutdown */ +enum _mlan_func_cmd +{ + MLAN_FUNC_INIT = 1, + MLAN_FUNC_SHUTDOWN, +}; + +/** Type definition of mlan_ds_misc_tx_datapause for MLAN_OID_MISC_TX_DATAPAUSE */ +typedef struct _mlan_ds_misc_tx_datapause +{ + /** Tx data pause flag */ + t_u16 tx_pause; + /** Max number of Tx buffers for all PS clients */ + t_u16 tx_buf_cnt; +} mlan_ds_misc_tx_datapause; + +/** IP address length */ +#define IPADDR_LEN (16) +/** Max number of ip */ +#define MAX_IPADDR (4) +/** IP address type - IPv4*/ +#define IPADDR_TYPE_IPV4 (1) +/** IP operation remove */ +#define MLAN_IPADDR_OP_IP_REMOVE (0) +/** IP operation ARP filter */ +#define MLAN_IPADDR_OP_ARP_FILTER MBIT(0) +/** IP operation ARP response */ +#define MLAN_IPADDR_OP_AUTO_ARP_RESP MBIT(1) + +/** Type definition of mlan_ds_misc_ipaddr_cfg for MLAN_OID_MISC_IP_ADDR */ +typedef struct _mlan_ds_misc_ipaddr_cfg +{ + /** Operation code */ + t_u32 op_code; + /** IP address type */ + t_u32 ip_addr_type; + /** Number of IP */ + t_u32 ip_addr_num; + /** IP address */ + t_u8 ip_addr[MAX_IPADDR][IPADDR_LEN]; +} mlan_ds_misc_ipaddr_cfg; + +/* MEF configuration disable */ +#define MEF_CFG_DISABLE 0 +/* MEF configuration Rx filter enable */ +#define MEF_CFG_RX_FILTER_ENABLE 1 +/* MEF configuration auto ARP response */ +#define MEF_CFG_AUTO_ARP_RESP 2 +/* MEF configuration host command */ +#define MEF_CFG_HOSTCMD 0xFFFF + +/** Type definition of mlan_ds_misc_mef_cfg for MLAN_OID_MISC_MEF_CFG */ +typedef struct _mlan_ds_misc_mef_cfg +{ + /** Sub-ID for operation */ + t_u32 sub_id; + /** Parameter according to sub-ID */ + union + { + /** MEF command buffer for MEF_CFG_HOSTCMD */ + mlan_ds_misc_cmd cmd_buf; + } param; +} mlan_ds_misc_mef_cfg; + +/** Type definition of mlan_ds_misc_cfp_code for MLAN_OID_MISC_CFP_CODE */ +typedef struct _mlan_ds_misc_cfp_code +{ + /** CFP table code for 2.4GHz */ + t_u32 cfp_code_bg; + /** CFP table code for 5GHz */ + t_u32 cfp_code_a; +} mlan_ds_misc_cfp_code; + +/** Type definition of mlan_ds_misc_country_code for MLAN_OID_MISC_COUNTRY_CODE */ +typedef struct _mlan_ds_misc_country_code +{ + /** Country Code */ + t_u8 country_code[COUNTRY_CODE_LEN]; +} mlan_ds_misc_country_code; + +/** BITMAP for subscribe event rssi low */ +#define SUBSCRIBE_EVT_RSSI_LOW MBIT(0) +/** BITMAP for subscribe event snr low */ +#define SUBSCRIBE_EVT_SNR_LOW MBIT(1) +/** BITMAP for subscribe event max fail */ +#define SUBSCRIBE_EVT_MAX_FAIL MBIT(2) +/** BITMAP for subscribe event beacon missed */ +#define SUBSCRIBE_EVT_BEACON_MISSED MBIT(3) +/** BITMAP for subscribe event rssi high */ +#define SUBSCRIBE_EVT_RSSI_HIGH MBIT(4) +/** BITMAP for subscribe event snr high */ +#define SUBSCRIBE_EVT_SNR_HIGH MBIT(5) +/** BITMAP for subscribe event data rssi low */ +#define SUBSCRIBE_EVT_DATA_RSSI_LOW MBIT(6) +/** BITMAP for subscribe event data snr low */ +#define SUBSCRIBE_EVT_DATA_SNR_LOW MBIT(7) +/** BITMAP for subscribe event data rssi high */ +#define SUBSCRIBE_EVT_DATA_RSSI_HIGH MBIT(8) +/** BITMAP for subscribe event data snr high */ +#define SUBSCRIBE_EVT_DATA_SNR_HIGH MBIT(9) +/** BITMAP for subscribe event link quality */ +#define SUBSCRIBE_EVT_LINK_QUALITY MBIT(10) +/** BITMAP for subscribe event pre_beacon_lost */ +#define SUBSCRIBE_EVT_PRE_BEACON_LOST MBIT(11) +/** default PRE_BEACON_MISS_COUNT */ +#define DEFAULT_PRE_BEACON_MISS 30 + +/** Type definition of mlan_ds_subscribe_evt for MLAN_OID_MISC_CFP_CODE */ +typedef struct _mlan_ds_subscribe_evt +{ + /** bitmap for subscribe event */ + t_u16 evt_bitmap; + /** Absolute value of RSSI threshold value (dBm) */ + t_u8 low_rssi; + /** 0--report once, 1--report everytime happen, N -- report only happend > N consecutive times */ + t_u8 low_rssi_freq; + /** SNR threshold value (dB) */ + t_u8 low_snr; + /** 0--report once, 1--report everytime happen, N -- report only happend > N consecutive times */ + t_u8 low_snr_freq; + /** Failure count threshold */ + t_u8 failure_count; + /** 0--report once, 1--report everytime happen, N -- report only happend > N consecutive times */ + t_u8 failure_count_freq; + /** num of missed beacons */ + t_u8 beacon_miss; + /** 0--report once, 1--report everytime happen, N -- report only happend > N consecutive times */ + t_u8 beacon_miss_freq; + /** Absolute value of RSSI threshold value (dBm) */ + t_u8 high_rssi; + /** 0--report once, 1--report everytime happen, N -- report only happend > N consecutive times */ + t_u8 high_rssi_freq; + /** SNR threshold value (dB) */ + t_u8 high_snr; + /** 0--report once, 1--report everytime happen, N -- report only happend > N consecutive times */ + t_u8 high_snr_freq; + /** Absolute value of data RSSI threshold value (dBm) */ + t_u8 data_low_rssi; + /** 0--report once, 1--report everytime happen, N -- report only happend > N consecutive times */ + t_u8 data_low_rssi_freq; + /** Absolute value of data SNR threshold value (dBm) */ + t_u8 data_low_snr; + /** 0--report once, 1--report everytime happen, N -- report only happend > N consecutive times */ + t_u8 data_low_snr_freq; + /** Absolute value of data RSSI threshold value (dBm) */ + t_u8 data_high_rssi; + /** 0--report once, 1--report everytime happen, N -- report only happend > N consecutive times */ + t_u8 data_high_rssi_freq; + /** Absolute value of data SNR threshold value (dBm) */ + t_u8 data_high_snr; + /** 0--report once, 1--report everytime happen, N -- report only happend > N consecutive times */ + t_u8 data_high_snr_freq; + /* Link SNR threshold (dB) */ + t_u16 link_snr; + /* Link SNR frequency */ + t_u16 link_snr_freq; + /* Second minimum rate value as per the rate table below */ + t_u16 link_rate; + /* Second minimum rate frequency */ + t_u16 link_rate_freq; + /* Tx latency value (us) */ + t_u16 link_tx_latency; + /* Tx latency frequency */ + t_u16 link_tx_lantency_freq; + /* Number of pre missed beacons */ + t_u8 pre_beacon_miss; +} mlan_ds_subscribe_evt; + +/** Max OTP user data length */ +#define MAX_OTP_USER_DATA_LEN 252 + +/** Type definition of mlan_ds_misc_otp_user_data for MLAN_OID_MISC_OTP_USER_DATA */ +typedef struct _mlan_ds_misc_otp_user_data +{ + /** Reserved */ + t_u16 reserved; + /** OTP user data length */ + t_u16 user_data_length; + /** User data buffer */ + t_u8 user_data[MAX_OTP_USER_DATA_LEN]; +} mlan_ds_misc_otp_user_data; + +/** Type definition of mlan_ds_misc_cfg for MLAN_IOCTL_MISC_CFG */ +typedef struct _mlan_ds_misc_cfg +{ + /** Sub-command */ + t_u32 sub_command; + /** Miscellaneous configuration parameter */ + union + { + /** Generic IE for MLAN_OID_MISC_GEN_IE */ + mlan_ds_misc_gen_ie gen_ie; + /** Region code for MLAN_OID_MISC_REGION */ + t_u32 region_code; +#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR) + /** SDIO MP-A Ctrl command for MLAN_OID_MISC_SDIO_MPA_CTRL */ + mlan_ds_misc_sdio_mpa_ctrl mpa_ctrl; +#endif + /** Hostcmd for MLAN_OID_MISC_HOST_CMD */ + mlan_ds_misc_cmd hostcmd; + /** System clock for MLAN_OID_MISC_SYS_CLOCK */ + mlan_ds_misc_sys_clock sys_clock; + /** WWS set/get for MLAN_OID_MISC_WWS */ + t_u32 wws_cfg; + /** Function init/shutdown for MLAN_OID_MISC_INIT_SHUTDOWN */ + t_u32 func_init_shutdown; + /** Custom IE for MLAN_OID_MISC_CUSTOM_IE */ + mlan_ds_misc_custom_ie cust_ie; + /** Tx data pause for MLAN_OID_MISC_TX_DATAPAUSE */ + mlan_ds_misc_tx_datapause tx_datapause; + /** IP address configuration */ + mlan_ds_misc_ipaddr_cfg ipaddr_cfg; + /** MAC control for MLAN_OID_MISC_MAC_CONTROL */ + t_u32 mac_ctrl; + /** MEF configuration for MLAN_OID_MISC_MEF_CFG */ + mlan_ds_misc_mef_cfg mef_cfg; + /** CFP code for MLAN_OID_MISC_CFP_CODE */ + mlan_ds_misc_cfp_code cfp_code; + /** Country code for MLAN_OID_MISC_COUNTRY_CODE */ + mlan_ds_misc_country_code country_code; + /** Thermal reading for MLAN_OID_MISC_THERMAL */ + t_u32 thermal; + /** Mgmt subtype mask for MLAN_OID_MISC_RX_MGMT_IND */ + t_u32 mgmt_subtype_mask; + /** subscribe event for MLAN_OID_MISC_SUBSCRIBE_EVENT */ + mlan_ds_subscribe_evt subscribe_event; +#ifdef DEBUG_LEVEL1 + /** Driver debug bit masks */ + t_u32 drvdbg; +#endif + mlan_ds_misc_otp_user_data otp_user_data; + } param; +} mlan_ds_misc_cfg, *pmlan_ds_misc_cfg; + +#endif /* !_MLAN_IOCTL_H_ */ diff --git a/drivers/net/wireless/sd8797/mlinux/moal_cfg80211.c b/drivers/net/wireless/sd8797/mlinux/moal_cfg80211.c index 1b04db6b4da0..6b2a01f5c218 100644 --- a/drivers/net/wireless/sd8797/mlinux/moal_cfg80211.c +++ b/drivers/net/wireless/sd8797/mlinux/moal_cfg80211.c @@ -164,6 +164,19 @@ woal_get_wiphy_priv(struct wiphy *wiphy) } /** + * @brief Get the private structure from net device + * + * @param wiphy A pointer to net_device structure + * + * @return Pointer to moal_private + */ +void * +woal_get_netdev_priv(struct net_device *dev) +{ + return (void *) netdev_priv(dev); +} + +/** * @brief Set/Enable encryption key * * @param priv A pointer to moal_private structure @@ -270,8 +283,12 @@ woal_cfg80211_set_key(moal_private * priv, t_u8 is_enable_wep, } } } else { - sec->param.encrypt_key.key_remove = MTRUE; - sec->param.encrypt_key.key_index = key_index; + if (key_index == KEY_INDEX_CLEAR_ALL) + sec->param.encrypt_key.key_disable = MTRUE; + else { + sec->param.encrypt_key.key_remove = MTRUE; + sec->param.encrypt_key.key_index = key_index; + } sec->param.encrypt_key.key_flags = KEY_FLAG_REMOVE_KEY; if (addr) memcpy(sec->param.encrypt_key.mac_addr, addr, ETH_ALEN); @@ -343,96 +360,30 @@ static int woal_cfg80211_bss_role_cfg(moal_private * priv, t_u16 action, t_u8 * bss_role) { int ret = 0; - mlan_ds_bss *bss = NULL; - mlan_ioctl_req *req = NULL; - struct net_device *dev = priv->netdev; ENTER(); - req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss)); - if (req == NULL) { - ret = -ENOMEM; - goto done; - } - bss = (mlan_ds_bss *) req->pbuf; - bss->sub_command = MLAN_OID_BSS_ROLE; - req->req_id = MLAN_IOCTL_BSS; - req->action = action; - bss->param.bss_role = *bss_role; - - if (req->action == MLAN_ACT_SET) { + if (action == MLAN_ACT_SET) { /* Reset interface */ woal_reset_intf(priv, MOAL_IOCTL_WAIT, MFALSE); } - if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) { + + if (MLAN_STATUS_SUCCESS != + woal_bss_role_cfg(priv, action, MOAL_IOCTL_WAIT, bss_role)) { ret = -EFAULT; goto done; } - if (req->action == MLAN_ACT_GET) { - *bss_role = bss->param.bss_role; - } else { - /* Update moal_private */ - priv->bss_role = *bss_role; - if (priv->bss_type == MLAN_BSS_TYPE_UAP) - priv->bss_type = MLAN_BSS_TYPE_STA; - else if (priv->bss_type == MLAN_BSS_TYPE_STA) - priv->bss_type = MLAN_BSS_TYPE_UAP; - + if (action == MLAN_ACT_SET) { /* Initialize private structures */ woal_init_priv(priv, MOAL_IOCTL_WAIT); - if (*bss_role == MLAN_BSS_ROLE_UAP) { - /* Switch: STA -> uAP */ - /* Setup the OS Interface to our functions */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) - dev->do_ioctl = woal_uap_do_ioctl; - dev->set_multicast_list = woal_uap_set_multicast_list; -#else - dev->netdev_ops = &woal_uap_netdev_ops; -#endif -#ifdef WIRELESS_EXT -#ifdef UAP_WEXT - if (IS_UAP_WEXT(cfg80211_wext)) { -#if WIRELESS_EXT < 21 - dev->get_wireless_stats = woal_get_uap_wireless_stats; -#endif - dev->wireless_handlers = - (struct iw_handler_def *) &woal_uap_handler_def; - init_waitqueue_head(&priv->w_stats_wait_q); - } -#endif /* UAP_WEXT */ -#endif /* WIRELESS_EXT */ - } else if (*bss_role == MLAN_BSS_ROLE_STA) { - /* Switch: uAP -> STA */ - /* Setup the OS Interface to our functions */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) - dev->do_ioctl = woal_do_ioctl; - dev->set_multicast_list = woal_set_multicast_list; -#else - dev->netdev_ops = &woal_netdev_ops; -#endif -#ifdef WIRELESS_EXT -#ifdef STA_WEXT - if (IS_STA_WEXT(cfg80211_wext)) { -#if WIRELESS_EXT < 21 - dev->get_wireless_stats = woal_get_wireless_stats; -#endif - dev->wireless_handlers = - (struct iw_handler_def *) &woal_handler_def; - init_waitqueue_head(&priv->w_stats_wait_q); - } -#endif /* STA_WEXT */ -#endif - } /* Enable interfaces */ - netif_device_attach(dev); - woal_start_queue(dev); + netif_device_attach(priv->netdev); + woal_start_queue(priv->netdev); } done: - if (req) - kfree(req); LEAVE(); return ret; } @@ -478,8 +429,7 @@ woal_cfg80211_init_p2p_client(moal_private * priv) wifi_direct_mode = WIFI_DIRECT_MODE_DISABLE; if (MLAN_STATUS_SUCCESS != - woal_cfg80211_wifi_direct_mode_cfg(priv, - MLAN_ACT_SET, &wifi_direct_mode)) { + woal_wifi_direct_mode_cfg(priv, MLAN_ACT_SET, &wifi_direct_mode)) { ret = -EFAULT; goto done; } @@ -487,8 +437,7 @@ woal_cfg80211_init_p2p_client(moal_private * priv) /* first, init wifi direct to listen mode */ wifi_direct_mode = WIFI_DIRECT_MODE_LISTEN; if (MLAN_STATUS_SUCCESS != - woal_cfg80211_wifi_direct_mode_cfg(priv, MLAN_ACT_SET, - &wifi_direct_mode)) { + woal_wifi_direct_mode_cfg(priv, MLAN_ACT_SET, &wifi_direct_mode)) { ret = -EFAULT; goto done; } @@ -496,8 +445,7 @@ woal_cfg80211_init_p2p_client(moal_private * priv) /* second, init wifi direct client */ wifi_direct_mode = WIFI_DIRECT_MODE_CLIENT; if (MLAN_STATUS_SUCCESS != - woal_cfg80211_wifi_direct_mode_cfg(priv, - MLAN_ACT_SET, &wifi_direct_mode)) { + woal_wifi_direct_mode_cfg(priv, MLAN_ACT_SET, &wifi_direct_mode)) { ret = -EFAULT; goto done; } @@ -531,8 +479,7 @@ woal_cfg80211_init_p2p_go(moal_private * priv) wifi_direct_mode = WIFI_DIRECT_MODE_DISABLE; if (MLAN_STATUS_SUCCESS != - woal_cfg80211_wifi_direct_mode_cfg(priv, - MLAN_ACT_SET, &wifi_direct_mode)) { + woal_wifi_direct_mode_cfg(priv, MLAN_ACT_SET, &wifi_direct_mode)) { ret = -EFAULT; goto done; } @@ -540,8 +487,7 @@ woal_cfg80211_init_p2p_go(moal_private * priv) /* first, init wifi direct to listen mode */ wifi_direct_mode = WIFI_DIRECT_MODE_LISTEN; if (MLAN_STATUS_SUCCESS != - woal_cfg80211_wifi_direct_mode_cfg(priv, MLAN_ACT_SET, - &wifi_direct_mode)) { + woal_wifi_direct_mode_cfg(priv, MLAN_ACT_SET, &wifi_direct_mode)) { ret = -EFAULT; goto done; } @@ -549,8 +495,7 @@ woal_cfg80211_init_p2p_go(moal_private * priv) /* second, init wifi direct to GO mode */ wifi_direct_mode = WIFI_DIRECT_MODE_GO; if (MLAN_STATUS_SUCCESS != - woal_cfg80211_wifi_direct_mode_cfg(priv, - MLAN_ACT_SET, &wifi_direct_mode)) { + woal_wifi_direct_mode_cfg(priv, MLAN_ACT_SET, &wifi_direct_mode)) { ret = -EFAULT; goto done; } @@ -603,8 +548,7 @@ woal_cfg80211_deinit_p2p(moal_private * priv) /* cancel previous remain on channel */ if (priv->phandle->remain_on_channel) { if (woal_cfg80211_remain_on_channel_cfg - (priv->wdev->wiphy, MOAL_IOCTL_WAIT, MTRUE, &channel_status, NULL, - 0, 0)) { + (priv, MOAL_IOCTL_WAIT, MTRUE, &channel_status, NULL, 0, 0)) { PRINTM(MERROR, "Fail to cancel remain on channel\n"); ret = -EFAULT; goto done; @@ -640,8 +584,7 @@ woal_cfg80211_deinit_p2p(moal_private * priv) wifi_direct_mode = WIFI_DIRECT_MODE_DISABLE; if (MLAN_STATUS_SUCCESS != - woal_cfg80211_wifi_direct_mode_cfg(priv, - MLAN_ACT_SET, &wifi_direct_mode)) { + woal_wifi_direct_mode_cfg(priv, MLAN_ACT_SET, &wifi_direct_mode)) { ret = -EFAULT; goto done; } @@ -670,7 +613,7 @@ woal_cfg80211_change_virtual_intf(struct wiphy *wiphy, struct vif_params *params) { int ret = 0; - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); mlan_ds_bss *bss = NULL; mlan_ioctl_req *req = NULL; @@ -687,7 +630,7 @@ woal_cfg80211_change_virtual_intf(struct wiphy *wiphy, if (priv->phandle->remain_on_channel) { t_u8 channel_status; if (woal_cfg80211_remain_on_channel_cfg - (wiphy, MOAL_IOCTL_WAIT, MTRUE, &channel_status, NULL, 0, 0)) { + (priv, MOAL_IOCTL_WAIT, MTRUE, &channel_status, NULL, 0, 0)) { PRINTM(MERROR, "Fail to cancel remain on channel\n"); ret = -EFAULT; goto done; @@ -908,7 +851,7 @@ woal_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, #endif const t_u8 * mac_addr, struct key_params *params) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(netdev); ENTER(); @@ -945,7 +888,7 @@ woal_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, #endif const t_u8 * mac_addr) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(netdev); ENTER(); @@ -981,7 +924,7 @@ woal_cfg80211_set_default_key(struct wiphy *wiphy, ) { int ret = 0; - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(netdev); mlan_bss_info bss_info; ENTER(); @@ -1019,9 +962,15 @@ woal_cfg80211_set_channel(struct wiphy *wiphy, enum nl80211_channel_type channel_type) { int ret = 0; - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = NULL; ENTER(); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,34) || defined(COMPAT_WIRELESS) + if (dev) + priv = woal_get_netdev_priv(dev); + else +#endif + priv = (moal_private *) woal_get_wiphy_priv(wiphy); #ifdef STA_CFG80211 #ifdef STA_SUPPORT if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) { @@ -1031,7 +980,7 @@ woal_cfg80211_set_channel(struct wiphy *wiphy, LEAVE(); return -EINVAL; } - ret = woal_set_rf_channel(wiphy, chan, channel_type); + ret = woal_set_rf_channel(priv, chan, channel_type); } #endif #endif @@ -1055,7 +1004,7 @@ woal_cfg80211_mgmt_frame_register(struct wiphy *wiphy, struct net_device *dev, u16 frame_type, bool reg) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); mlan_status status = MLAN_STATUS_SUCCESS; t_u32 mgmt_subtype_mask = 0x0; static t_u32 last_mgmt_subtype_mask = 0x0; @@ -1112,7 +1061,7 @@ woal_cfg80211_mgmt_tx(struct wiphy *wiphy, #endif u64 * cookie) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); int ret = 0; pmlan_buffer pmbuf = NULL; mlan_status status = MLAN_STATUS_SUCCESS; @@ -1151,7 +1100,7 @@ woal_cfg80211_mgmt_tx(struct wiphy *wiphy, /** cancel previous remain on channel */ if (priv->phandle->remain_on_channel) { if (woal_cfg80211_remain_on_channel_cfg - (wiphy, MOAL_IOCTL_WAIT, MTRUE, &channel_status, NULL, 0, 0)) { + (priv, MOAL_IOCTL_WAIT, MTRUE, &channel_status, NULL, 0, 0)) { PRINTM(MERROR, "Fail to cancel remain on channel\n"); ret = -EFAULT; goto done; @@ -1171,13 +1120,13 @@ woal_cfg80211_mgmt_tx(struct wiphy *wiphy, duration = MGMT_TX_DEFAULT_WAIT_TIME; if (channel_type_valid) ret = - woal_cfg80211_remain_on_channel_cfg(wiphy, MOAL_IOCTL_WAIT, + woal_cfg80211_remain_on_channel_cfg(priv, MOAL_IOCTL_WAIT, MFALSE, &channel_status, chan, channel_type, duration); else ret = - woal_cfg80211_remain_on_channel_cfg(wiphy, MOAL_IOCTL_WAIT, + woal_cfg80211_remain_on_channel_cfg(priv, MOAL_IOCTL_WAIT, MFALSE, &channel_status, chan, 0, duration); if (ret) { @@ -1261,3 +1210,478 @@ woal_cfg80211_mgmt_tx(struct wiphy *wiphy, LEAVE(); return ret; } + +/** + * @brief Look up specific IE in a buf + * + * @param ie Pointer to IEs + * @param len Total length of ie + * @param id Element id to lookup + * + * @return Pointer of the specific IE -- success, NULL -- fail + */ +const t_u8 * +woal_parse_ie_tlv(const t_u8 * ie, int len, t_u8 id) +{ + int left_len = len; + const t_u8 *pos = ie; + int length; + + /* IE format: | u8 | id | | u8 | len | | var | data | */ + while (left_len >= 2) { + length = *(pos + 1); + if ((*pos == id) && (length + 2) <= left_len) + return pos; + pos += (length + 2); + left_len -= (length + 2); + } + + return NULL; +} + +/** + * @brief This function returns priv + * based on mgmt ie index + * + * @param handle A pointer to moal_handle + * @param index mgmt ie index + * + * @return Pointer to moal_private + */ +static moal_private * +woal_get_priv_by_mgmt_index(moal_handle * handle, t_u16 index) +{ + int i; + + for (i = 0; i < MIN(handle->priv_num, MLAN_MAX_BSS_NUM); i++) { + if (handle->priv[i]) { + if (handle->priv[i]->probereq_index == index) + return (handle->priv[i]); + } + } + return NULL; +} + +/** + * @brief Add custom ie to mgmt frames. + * + * @param priv A pointer to moal private structure + * @param beacon_ies_data Beacon ie + * @param beacon_index The index for beacon when auto index + * @param proberesp_ies_data Probe resp ie + * @param proberesp_index The index for probe resp when auto index + * @param assocresp_ies_data Assoc resp ie + * @param assocresp_index The index for assoc resp when auto index + * @param probereq_ies_data Probe req ie + * @param probereq_index The index for probe req when auto index * + * + * @return 0 -- success, otherwise fail + */ +static int +woal_cfg80211_custom_ie(moal_private * priv, + custom_ie * beacon_ies_data, t_u16 * beacon_index, + custom_ie * proberesp_ies_data, t_u16 * proberesp_index, + custom_ie * assocresp_ies_data, t_u16 * assocresp_index, + custom_ie * probereq_ies_data, t_u16 * probereq_index) +{ + mlan_ioctl_req *ioctl_req = NULL; + mlan_ds_misc_cfg *misc = NULL; + mlan_ds_misc_custom_ie *custom_ie = NULL; + t_u8 *pos = NULL; + t_u16 len = 0; + int ret = 0; + + ENTER(); + + if (!(custom_ie = kmalloc(sizeof(mlan_ds_misc_custom_ie), GFP_KERNEL))) { + ret = -ENOMEM; + goto done; + } + + memset(custom_ie, 0x00, sizeof(mlan_ds_misc_custom_ie)); + custom_ie->type = TLV_TYPE_MGMT_IE; + + pos = (t_u8 *) custom_ie->ie_data_list; + if (beacon_ies_data) { + len = sizeof(*beacon_ies_data) - MAX_IE_SIZE + + beacon_ies_data->ie_length; + memcpy(pos, beacon_ies_data, len); + pos += len; + custom_ie->len += len; + } + + if (proberesp_ies_data) { + len = sizeof(*proberesp_ies_data) - MAX_IE_SIZE + + proberesp_ies_data->ie_length; + memcpy(pos, proberesp_ies_data, len); + pos += len; + custom_ie->len += len; + } + + if (assocresp_ies_data) { + len = sizeof(*assocresp_ies_data) - MAX_IE_SIZE + + assocresp_ies_data->ie_length; + memcpy(pos, assocresp_ies_data, len); + custom_ie->len += len; + } + + if (probereq_ies_data) { + len = sizeof(*probereq_ies_data) - MAX_IE_SIZE + + probereq_ies_data->ie_length; + memcpy(pos, probereq_ies_data, len); + pos += len; + custom_ie->len += len; + } + + ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (ioctl_req == NULL) { + ret = -ENOMEM; + goto done; + } + + misc = (mlan_ds_misc_cfg *) ioctl_req->pbuf; + misc->sub_command = MLAN_OID_MISC_CUSTOM_IE; + ioctl_req->req_id = MLAN_IOCTL_MISC_CFG; + ioctl_req->action = MLAN_ACT_SET; + + memcpy(&misc->param.cust_ie, custom_ie, sizeof(mlan_ds_misc_custom_ie)); + + if (MLAN_STATUS_SUCCESS != + woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) { + ret = -EFAULT; + goto done; + } + + /* get the assigned index */ + pos = (t_u8 *) (&misc->param.cust_ie.ie_data_list[0].ie_index); + if (beacon_ies_data && beacon_ies_data->ie_length + && beacon_ies_data->ie_index == MLAN_CUSTOM_IE_AUTO_IDX_MASK) { + /* save beacon ie index after auto-indexing */ + *beacon_index = misc->param.cust_ie.ie_data_list[0].ie_index; + len = sizeof(*beacon_ies_data) - MAX_IE_SIZE + + beacon_ies_data->ie_length; + pos += len; + } + + if (proberesp_ies_data && proberesp_ies_data->ie_length + && proberesp_ies_data->ie_index == MLAN_CUSTOM_IE_AUTO_IDX_MASK) { + /* save probe resp ie index after auto-indexing */ + *proberesp_index = *((t_u16 *) pos); + len = sizeof(*proberesp_ies_data) - MAX_IE_SIZE + + proberesp_ies_data->ie_length; + pos += len; + } + + if (assocresp_ies_data && assocresp_ies_data->ie_length + && assocresp_ies_data->ie_index == MLAN_CUSTOM_IE_AUTO_IDX_MASK) { + /* save assoc resp ie index after auto-indexing */ + *assocresp_index = *((t_u16 *) pos); + len = sizeof(*assocresp_ies_data) - MAX_IE_SIZE + + assocresp_ies_data->ie_length; + pos += len; + } + if (probereq_ies_data && probereq_ies_data->ie_length + && probereq_ies_data->ie_index == MLAN_CUSTOM_IE_AUTO_IDX_MASK) { + /* save probe resp ie index after auto-indexing */ + *probereq_index = *((t_u16 *) pos); + len = sizeof(*probereq_ies_data) - MAX_IE_SIZE + + probereq_ies_data->ie_length; + pos += len; + } + + if (ioctl_req->status_code == MLAN_ERROR_IOCTL_FAIL) + ret = -EFAULT; + + done: + if (ioctl_req) + kfree(ioctl_req); + if (custom_ie) + kfree(custom_ie); + LEAVE(); + return ret; +} + +/** + * @brief Filter specific IE in ie buf + * + * @param ie Pointer to IEs + * @param len Total length of ie + * @param ie_out Pointer to out IE buf + * + * @return out IE length + */ +static t_u16 +woal_filter_beacon_ies(const t_u8 * ie, int len, t_u8 * ie_out) +{ + int left_len = len; + const t_u8 *pos = ie; + int length; + t_u8 id = 0; + t_u16 out_len = 0; + + /* ERP_INFO and RSN IE will be fileter out */ + while (left_len >= 2) { + length = *(pos + 1); + id = *pos; + if ((length + 2) > left_len) + break; + switch (id) { + case WLAN_EID_ERP_INFO: + case RSN_IE: + break; + default: + memcpy(ie_out + out_len, pos, length + 2); + out_len += length + 2; + break; + } + pos += (length + 2); + left_len -= (length + 2); + } + return out_len; +} + +/** + * @brief config AP or GO for mgmt frame ies. + * + * @param priv A pointer to moal private structure + * @param beacon_ies A pointer to beacon ies + * @param beacon_ies_len Beacon ies length + * @param proberesp_ies A pointer to probe resp ies + * @param proberesp_ies_len Probe resp ies length + * @param assocresp_ies A pointer to probe resp ies + * @param assocresp_ies_len Assoc resp ies length + * @param probereq_ies A pointer to probe req ies + * @param probereq_ies_len Probe req ies length * + * @param mask Mgmt frame mask + * + * @return 0 -- success, otherwise fail + */ +int +woal_cfg80211_mgmt_frame_ie(moal_private * priv, + const t_u8 * beacon_ies, size_t beacon_ies_len, + const t_u8 * proberesp_ies, + size_t proberesp_ies_len, + const t_u8 * assocresp_ies, + size_t assocresp_ies_len, const t_u8 * probereq_ies, + size_t probereq_ies_len, t_u16 mask) +{ + int ret = 0; + t_u8 *pos = NULL; + custom_ie *beacon_ies_data = NULL; + custom_ie *proberesp_ies_data = NULL; + custom_ie *assocresp_ies_data = NULL; + custom_ie *probereq_ies_data = NULL; + + /* static variables for mgmt frame ie auto-indexing */ + static t_u16 beacon_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; + static t_u16 proberesp_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; + static t_u16 assocresp_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; + static t_u16 probereq_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; + moal_private *pmpriv = NULL; + static t_u16 rsn_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; + const t_u8 *rsn_ie; + + ENTER(); + + if (mask & MGMT_MASK_BEACON) { + if (!(beacon_ies_data = kmalloc(sizeof(custom_ie), GFP_KERNEL))) { + ret = -ENOMEM; + goto done; + } + if (beacon_ies && beacon_ies_len) { + rsn_ie = + woal_parse_ie_tlv((t_u8 *) beacon_ies, (int) beacon_ies_len, + RSN_IE); + if (rsn_ie) { + beacon_ies_data->ie_index = rsn_index; + beacon_ies_data->mgmt_subtype_mask = + MGMT_MASK_BEACON | MGMT_MASK_PROBE_RESP | + MGMT_MASK_ASSOC_RESP; + beacon_ies_data->ie_length = rsn_ie[1] + 2; + memcpy(beacon_ies_data->ie_buffer, rsn_ie, rsn_ie[1] + 2); + if (MLAN_STATUS_SUCCESS != + woal_cfg80211_custom_ie(priv, beacon_ies_data, &rsn_index, + NULL, &proberesp_index, NULL, + &assocresp_index, NULL, + &probereq_index)) { + ret = -EFAULT; + goto done; + } + } + } else { + /* clear rsn_ie */ + if (rsn_index <= MAX_MGMT_IE_INDEX) { + beacon_ies_data->ie_index = rsn_index; + beacon_ies_data->mgmt_subtype_mask = MLAN_CUSTOM_IE_DELETE_MASK; + beacon_ies_data->ie_length = 0; + rsn_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; + if (MLAN_STATUS_SUCCESS != + woal_cfg80211_custom_ie(priv, beacon_ies_data, &rsn_index, + NULL, &proberesp_index, NULL, + &assocresp_index, NULL, + &probereq_index)) { + ret = -EFAULT; + goto done; + } + } + } + } + + if (mask & MGMT_MASK_PROBE_RESP) { + if (!(proberesp_ies_data = kmalloc(sizeof(custom_ie), GFP_KERNEL))) { + ret = -ENOMEM; + goto done; + } + } + + if (mask & MGMT_MASK_ASSOC_RESP) { + if (!(assocresp_ies_data = kmalloc(sizeof(custom_ie), GFP_KERNEL))) { + ret = -ENOMEM; + goto done; + } + } + if (mask & MGMT_MASK_PROBE_REQ) { + if (!(probereq_ies_data = kmalloc(sizeof(custom_ie), GFP_KERNEL))) { + ret = -ENOMEM; + goto done; + } + } + + if (beacon_ies_data) { + memset(beacon_ies_data, 0x00, sizeof(custom_ie)); + if (beacon_ies && beacon_ies_len) { + /* set the beacon ies */ + beacon_ies_data->ie_index = beacon_index; + beacon_ies_data->mgmt_subtype_mask = MGMT_MASK_BEACON; + beacon_ies_data->mgmt_subtype_mask |= MGMT_MASK_ASSOC_RESP; + beacon_ies_data->ie_length = woal_filter_beacon_ies(beacon_ies, + beacon_ies_len, + beacon_ies_data-> + ie_buffer); + } else { + /* clear the beacon ies */ + if (beacon_index > MAX_MGMT_IE_INDEX) { + PRINTM(MERROR, "Invalid beacon index for mgmt frame ie.\n"); + goto done; + } + + beacon_ies_data->ie_index = beacon_index; + beacon_ies_data->mgmt_subtype_mask = MLAN_CUSTOM_IE_DELETE_MASK; + beacon_ies_data->ie_length = 0; + beacon_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; + } + } + + if (proberesp_ies_data) { + memset(proberesp_ies_data, 0x00, sizeof(custom_ie)); + if (proberesp_ies && proberesp_ies_len) { + /* set the probe response ies */ + // proberesp_ies_data->ie_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; + proberesp_ies_data->ie_index = proberesp_index; + proberesp_ies_data->mgmt_subtype_mask = MGMT_MASK_PROBE_RESP; + proberesp_ies_data->ie_length = proberesp_ies_len; + pos = proberesp_ies_data->ie_buffer; + memcpy(pos, proberesp_ies, proberesp_ies_len); + } else { + /* clear the probe response ies */ + if (proberesp_index > MAX_MGMT_IE_INDEX) { + PRINTM(MERROR, "Invalid probe resp index for mgmt frame ie.\n"); + goto done; + } + + proberesp_ies_data->ie_index = proberesp_index; + proberesp_ies_data->mgmt_subtype_mask = MLAN_CUSTOM_IE_DELETE_MASK; + proberesp_ies_data->ie_length = 0; + proberesp_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; + } + } + if (assocresp_ies_data) { + memset(assocresp_ies_data, 0x00, sizeof(custom_ie)); + if (assocresp_ies && assocresp_ies_len) { + /* set the assoc response ies */ + assocresp_ies_data->ie_index = assocresp_index; + assocresp_ies_data->mgmt_subtype_mask = MGMT_MASK_ASSOC_RESP; + assocresp_ies_data->ie_length = assocresp_ies_len; + pos = assocresp_ies_data->ie_buffer; + memcpy(pos, assocresp_ies, assocresp_ies_len); + } else { + /* clear the assoc response ies */ + if (assocresp_index > MAX_MGMT_IE_INDEX) { + PRINTM(MERROR, "Invalid assoc resp index for mgmt frame ie.\n"); + goto done; + } + + assocresp_ies_data->ie_index = assocresp_index; + assocresp_ies_data->mgmt_subtype_mask = MLAN_CUSTOM_IE_DELETE_MASK; + assocresp_ies_data->ie_length = 0; + assocresp_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; + } + } + + if (probereq_ies_data) { + memset(probereq_ies_data, 0x00, sizeof(custom_ie)); + if ((probereq_index != MLAN_CUSTOM_IE_AUTO_IDX_MASK) && + (priv->probereq_index != probereq_index)) { + pmpriv = woal_get_priv_by_mgmt_index(priv->phandle, probereq_index); + if (pmpriv) { + probereq_ies_data->ie_index = probereq_index; + probereq_ies_data->mgmt_subtype_mask = + MLAN_CUSTOM_IE_DELETE_MASK; + probereq_ies_data->ie_length = 0; + probereq_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; + pmpriv->probereq_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; + if (MLAN_STATUS_SUCCESS != + woal_cfg80211_custom_ie(pmpriv, NULL, &beacon_index, + NULL, &proberesp_index, + NULL, &assocresp_index, + probereq_ies_data, + &probereq_index)) { + ret = -EFAULT; + goto done; + } + memset(probereq_ies_data, 0x00, sizeof(custom_ie)); + } + } + if (probereq_ies && probereq_ies_len) { + /* set the probe req ies */ + probereq_ies_data->ie_index = probereq_index; + probereq_ies_data->mgmt_subtype_mask = MGMT_MASK_PROBE_REQ; + probereq_ies_data->ie_length = probereq_ies_len; + pos = probereq_ies_data->ie_buffer; + memcpy(pos, probereq_ies, probereq_ies_len); + } else { + /* clear the probe req ies */ + if (probereq_index > MAX_MGMT_IE_INDEX) { + PRINTM(MERROR, "Invalid probe resp index for mgmt frame ie.\n"); + goto done; + } + probereq_ies_data->ie_index = probereq_index; + probereq_ies_data->mgmt_subtype_mask = MLAN_CUSTOM_IE_DELETE_MASK; + probereq_ies_data->ie_length = 0; + probereq_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; + } + } + + if (MLAN_STATUS_SUCCESS != + woal_cfg80211_custom_ie(priv, beacon_ies_data, &beacon_index, + proberesp_ies_data, &proberesp_index, + assocresp_ies_data, &assocresp_index, + probereq_ies_data, &probereq_index)) { + ret = -EFAULT; + goto done; + } + if (probereq_ies_data) + priv->probereq_index = probereq_index; + + done: + if (beacon_ies_data) + kfree(beacon_ies_data); + if (proberesp_ies_data) + kfree(proberesp_ies_data); + if (assocresp_ies_data) + kfree(assocresp_ies_data); + + LEAVE(); + + return ret; +} diff --git a/drivers/net/wireless/sd8797/mlinux/moal_cfg80211.h b/drivers/net/wireless/sd8797/mlinux/moal_cfg80211.h index e1683ed08a89..f58fc18829fa 100644 --- a/drivers/net/wireless/sd8797/mlinux/moal_cfg80211.h +++ b/drivers/net/wireless/sd8797/mlinux/moal_cfg80211.h @@ -24,8 +24,11 @@ #include "moal_main.h" +/* Clear all key indexes */ +#define KEY_INDEX_CLEAR_ALL (0x0000000F) + /** RTS/FRAG disabled value */ -#define MLAN_FRAG_RTS_DISABLED (0xFFFFFFFF) +#define MLAN_FRAG_RTS_DISABLED (0xFFFFFFFF) #ifndef WLAN_CIPHER_SUITE_WAPI #define WLAN_CIPHER_SUITE_WAPI 0x00000020 @@ -55,6 +58,9 @@ static const void *const mrvl_wiphy_privid = &mrvl_wiphy_privid; /* Get the private structure from wiphy */ void *woal_get_wiphy_priv(struct wiphy *wiphy); +/* Get the private structure from net device */ +void *woal_get_netdev_priv(struct net_device *dev); + int woal_cfg80211_change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, enum nl80211_iftype type, @@ -78,7 +84,7 @@ int woal_cfg80211_del_key(struct wiphy *wiphy, #ifdef STA_CFG80211 #ifdef STA_SUPPORT -int woal_set_rf_channel(struct wiphy *wiphy, +int woal_set_rf_channel(moal_private * priv, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type); mlan_status woal_inform_bss_from_scan_result(moal_private * priv, @@ -149,7 +155,7 @@ int woal_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev); #if defined(WIFI_DIRECT_SUPPORT) /** Define kernel version for wifi direct */ #if !defined(COMPAT_WIRELESS) -#define WIFI_DIRECT_KERNEL_VERSION KERNEL_VERSION(3,0,0) +#define WIFI_DIRECT_KERNEL_VERSION KERNEL_VERSION(2,6,39) #else #define WIFI_DIRECT_KERNEL_VERSION KERNEL_VERSION(2,6,33) #endif /* COMPAT_WIRELESS */ @@ -173,7 +179,7 @@ int woal_cfg80211_init_p2p_go(moal_private * priv); int woal_cfg80211_deinit_p2p(moal_private * priv); -int woal_cfg80211_remain_on_channel_cfg(struct wiphy *wiphy, +int woal_cfg80211_remain_on_channel_cfg(moal_private * priv, t_u8 wait_option, t_u8 remove, t_u8 * status, struct ieee80211_channel *chan, @@ -184,6 +190,8 @@ int woal_uap_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, #endif /* KERNEL_VERSION */ #endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */ +const t_u8 *woal_parse_ie_tlv(const t_u8 * ie, int len, t_u8 id); + int woal_cfg80211_mgmt_frame_ie(moal_private * priv, const t_u8 * beacon_ies, size_t beacon_ies_len, const t_u8 * proberesp_ies, diff --git a/drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.c b/drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.c index 2282216f7d55..31040a29ceec 100644 --- a/drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.c +++ b/drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.c @@ -50,10 +50,29 @@ Change log: #define PRIV_CMD_BANDCFG "bandcfg" /** Private command: Host cmd */ #define PRIV_CMD_HOSTCMD "hostcmd" +/** Private command: Custom IE config*/ +#define PRIV_CMD_CUSTOMIE "customie" /** Private command: HT Tx Cfg */ #define PRIV_CMD_HTTXCFG "httxcfg" #define PRIV_CMD_DATARATE "getdatarate" #define PRIV_CMD_TXRATECFG "txratecfg" +#define PRIV_CMD_ESUPPMODE "esuppmode" +#define PRIV_CMD_PASSPHRASE "passphrase" +#define PRIV_CMD_DEAUTH "deauth" +#if defined(WIFI_DIRECT_SUPPORT) +#if defined(STA_SUPPORT) && defined(UAP_SUPPORT) +#define PRIV_CMD_BSSROLE "bssrole" +#endif +#endif +#ifdef STA_SUPPORT +#define PRIV_CMD_SETUSERSCAN "setuserscan" +#endif +#define PRIV_CMD_DEEPSLEEP "deepsleep" +#define PRIV_CMD_IPADDR "ipaddr" +#define PRIV_CMD_WPSSESSION "wpssession" +#define PRIV_CMD_OTPUSERDATA "otpuserdata" +#define PRIV_CMD_COUNTRYCODE "countrycode" +#define PRIV_CMD_TCPACKENH "tcpackenh" /** Bands supported in Infra mode */ static t_u8 SupportedInfraBand[] = { @@ -76,6 +95,17 @@ static t_u8 SupportedAdhocBand[] = { /******************************************************** Global Variables ********************************************************/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) +#ifdef UAP_SUPPORT +/** Network device handlers for uAP */ +extern const struct net_device_ops woal_uap_netdev_ops; +#endif +#ifdef STA_SUPPORT +/** Network device handlers for STA */ +extern const struct net_device_ops woal_netdev_ops; +#endif +#endif +extern int cfg80211_wext; /******************************************************** Local Functions @@ -85,7 +115,7 @@ static t_u8 SupportedAdhocBand[] = { * * @param pos Pointer to the arguments string * @param data Pointer to the arguments buffer - * @param len Pointer to the number of arguments extracted + * @param user_data_len Pointer to the number of arguments extracted * * @return MLAN_STATUS_SUCCESS * @@ -246,7 +276,6 @@ woal_get_priv_driver_version(moal_private * priv, t_u8 * respbuf, return ret; } -#ifdef WIFI_DIRECT_SUPPORT /** * @brief Hostcmd interface from application * @@ -296,8 +325,12 @@ woal_priv_hostcmd(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen) ret = -EFAULT; goto error; } - sprintf(respbuf, "OK"); - ret = 3; + memcpy(data_ptr + sizeof(buf_len), misc_cfg->param.hostcmd.cmd, + misc_cfg->param.hostcmd.len); + ret = + misc_cfg->param.hostcmd.len + sizeof(buf_len) + strlen(CMD_MARVELL) + + strlen(PRIV_CMD_HOSTCMD); + memcpy(data_ptr, (t_u8 *) & ret, sizeof(t_u32)); error: if (req) @@ -306,7 +339,65 @@ woal_priv_hostcmd(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen) LEAVE(); return ret; } -#endif + +/** + * @brief Custom IE setting + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written, negative for failure. + */ +int +woal_priv_customie(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen) +{ + int ret = 0; + t_u8 *data_ptr; + mlan_ioctl_req *ioctl_req = NULL; + mlan_ds_misc_cfg *misc = NULL; + mlan_ds_misc_custom_ie *custom_ie = NULL; + + ENTER(); + data_ptr = respbuf + (strlen(CMD_MARVELL) + strlen(PRIV_CMD_CUSTOMIE)); + + custom_ie = (mlan_ds_misc_custom_ie *) data_ptr; + ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (ioctl_req == NULL) { + ret = -ENOMEM; + goto done; + } + + misc = (mlan_ds_misc_cfg *) ioctl_req->pbuf; + misc->sub_command = MLAN_OID_MISC_CUSTOM_IE; + ioctl_req->req_id = MLAN_IOCTL_MISC_CFG; + if ((custom_ie->len == 0) || + (custom_ie->len == sizeof(custom_ie->ie_data_list[0].ie_index))) + ioctl_req->action = MLAN_ACT_GET; + else + ioctl_req->action = MLAN_ACT_SET; + + memcpy(&misc->param.cust_ie, custom_ie, sizeof(mlan_ds_misc_custom_ie)); + + if (MLAN_STATUS_SUCCESS != + woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) { + ret = -EFAULT; + goto done; + } + custom_ie = (mlan_ds_misc_custom_ie *) data_ptr; + memcpy(custom_ie, &misc->param.cust_ie, sizeof(mlan_ds_misc_custom_ie)); + ret = sizeof(mlan_ds_misc_custom_ie); + if (ioctl_req->status_code == MLAN_ERROR_IOCTL_FAIL) { + /* send a separate error code to indicate error from driver */ + ret = EFAULT; + } + done: + if (ioctl_req) { + kfree(ioctl_req); + } + LEAVE(); + return ret; +} /** * @brief Set/Get Band and Adhoc-band setting @@ -728,6 +819,824 @@ woal_setget_priv_txratecfg(moal_private * priv, t_u8 * respbuf, } /** + * @brief Set/Get esupplicant mode configurations + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written, negative for failure. + */ +int +woal_setget_priv_esuppmode(moal_private * priv, t_u8 * respbuf, + t_u32 respbuflen) +{ + t_u32 data[3]; + mlan_ioctl_req *req = NULL; + mlan_ds_sec_cfg *sec = NULL; + woal_esuppmode_cfg *esupp_mode = NULL; + int ret = 0; + int user_data_len = 0; + + ENTER(); + + if (strlen(respbuf) == (strlen(CMD_MARVELL) + strlen(PRIV_CMD_ESUPPMODE))) { + /* GET operation */ + user_data_len = 0; + } else { + /* SET operation */ + memset((char *) data, 0, sizeof(data)); + parse_arguments(respbuf + strlen(CMD_MARVELL) + + strlen(PRIV_CMD_ESUPPMODE), data, &user_data_len); + } + + if (user_data_len >= 4 || user_data_len == 1 || user_data_len == 2) { + PRINTM(MERROR, "Invalid number of arguments\n"); + ret = -EINVAL; + goto done; + } + + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg)); + if (req == NULL) { + ret = -ENOMEM; + goto done; + } + + req->req_id = MLAN_IOCTL_SEC_CFG; + sec = (mlan_ds_sec_cfg *) req->pbuf; + sec->sub_command = MLAN_OID_SEC_CFG_ESUPP_MODE; + + if (user_data_len == 0) { + /* Get operation */ + req->action = MLAN_ACT_GET; + } else { + /* Set operation */ + req->action = MLAN_ACT_SET; + /* RSN mode */ + sec->param.esupp_mode.rsn_mode = data[0]; + /* Pairwise cipher */ + sec->param.esupp_mode.act_paircipher = (data[1] & 0xFF); + /* Group cipher */ + sec->param.esupp_mode.act_groupcipher = (data[2] & 0xFF); + } + + if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) { + ret = -EFAULT; + goto done; + } + + esupp_mode = (woal_esuppmode_cfg *) respbuf; + esupp_mode->rsn_mode = (t_u16) ((sec->param.esupp_mode.rsn_mode) & 0xFFFF); + esupp_mode->pairwise_cipher = + (t_u8) ((sec->param.esupp_mode.act_paircipher) & 0xFF); + esupp_mode->group_cipher = + (t_u8) ((sec->param.esupp_mode.act_groupcipher) & 0xFF); + + ret = sizeof(woal_esuppmode_cfg); + done: + if (req) + kfree(req); + LEAVE(); + return ret; + +} + +/** + * @brief Set/Get esupplicant passphrase configurations + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written, negative for failure. + */ +int +woal_setget_priv_passphrase(moal_private * priv, t_u8 * respbuf, + t_u32 respbuflen) +{ + mlan_ioctl_req *req = NULL; + mlan_ds_sec_cfg *sec = NULL; + int ret = 0, action = -1, i = 0; + char *begin, *end, *opt; + t_u16 len = 0; + t_u8 zero_mac[] = { 0, 0, 0, 0, 0, 0 }; + t_u8 *mac = NULL; + + ENTER(); + + if (strlen(respbuf) == (strlen(CMD_MARVELL) + strlen(PRIV_CMD_PASSPHRASE))) { + PRINTM(MERROR, "No arguments provided\n"); + ret = -EINVAL; + goto done; + } + + /* Parse the buf to get the cmd_action */ + begin = respbuf + strlen(CMD_MARVELL) + strlen(PRIV_CMD_PASSPHRASE); + end = woal_strsep(&begin, ';', '/'); + if (end) + action = woal_atox(end); + if (action < 0 || action > 2 || end[1] != '\0') { + PRINTM(MERROR, "Invalid action argument %s\n", end); + ret = -EINVAL; + goto done; + } + + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg)); + if (req == NULL) { + ret = -ENOMEM; + goto done; + } + + req->req_id = MLAN_IOCTL_SEC_CFG; + sec = (mlan_ds_sec_cfg *) req->pbuf; + sec->sub_command = MLAN_OID_SEC_CFG_PASSPHRASE; + if (action == 0) + req->action = MLAN_ACT_GET; + else + req->action = MLAN_ACT_SET; + + while (begin) { + end = woal_strsep(&begin, ';', '/'); + opt = woal_strsep(&end, '=', '/'); + if (!opt || !end || !end[0]) { + PRINTM(MERROR, "Invalid option\n"); + ret = -EINVAL; + break; + } else if (!strnicmp(opt, "ssid", strlen(opt))) { + if (strlen(end) > MLAN_MAX_SSID_LENGTH) { + PRINTM(MERROR, "SSID length exceeds max length\n"); + ret = -EFAULT; + break; + } + sec->param.passphrase.ssid.ssid_len = strlen(end); + strncpy((char *) sec->param.passphrase.ssid.ssid, end, strlen(end)); + PRINTM(MINFO, "ssid=%s, len=%d\n", sec->param.passphrase.ssid.ssid, + (int) sec->param.passphrase.ssid.ssid_len); + } else if (!strnicmp(opt, "bssid", strlen(opt))) { + woal_mac2u8((t_u8 *) & sec->param.passphrase.bssid, end); + } else if (!strnicmp(opt, "psk", strlen(opt)) && + req->action == MLAN_ACT_SET) { + if (strlen(end) != MLAN_PMK_HEXSTR_LENGTH) { + PRINTM(MERROR, "Invalid PMK length\n"); + ret = -EINVAL; + break; + } + woal_ascii2hex((t_u8 *) (sec->param.passphrase.psk.pmk.pmk), end, + MLAN_PMK_HEXSTR_LENGTH / 2); + sec->param.passphrase.psk_type = MLAN_PSK_PMK; + } else if (!strnicmp(opt, "passphrase", strlen(opt)) && + req->action == MLAN_ACT_SET) { + if (strlen(end) < MLAN_MIN_PASSPHRASE_LENGTH || + strlen(end) > MLAN_MAX_PASSPHRASE_LENGTH) { + PRINTM(MERROR, "Invalid length for passphrase\n"); + ret = -EINVAL; + break; + } + sec->param.passphrase.psk_type = MLAN_PSK_PASSPHRASE; + strncpy(sec->param.passphrase.psk.passphrase.passphrase, end, + sizeof(sec->param.passphrase.psk.passphrase.passphrase)); + sec->param.passphrase.psk.passphrase.passphrase_len = strlen(end); + PRINTM(MINFO, "passphrase=%s, len=%d\n", + sec->param.passphrase.psk.passphrase.passphrase, + (int) sec->param.passphrase.psk.passphrase.passphrase_len); + } else { + PRINTM(MERROR, "Invalid option %s\n", opt); + ret = -EINVAL; + break; + } + } + if (ret) + goto done; + + if (action == 2) + sec->param.passphrase.psk_type = MLAN_PSK_CLEAR; + + if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) { + ret = -EFAULT; + goto done; + } + + memset(respbuf, 0, respbuflen); + if (sec->param.passphrase.ssid.ssid_len) { + len += sprintf(respbuf + len, "ssid:"); + memcpy(respbuf + len, sec->param.passphrase.ssid.ssid, + sec->param.passphrase.ssid.ssid_len); + len += sec->param.passphrase.ssid.ssid_len; + len += sprintf(respbuf + len, " "); + } + if (memcmp(&sec->param.passphrase.bssid, zero_mac, sizeof(zero_mac))) { + mac = (t_u8 *) & sec->param.passphrase.bssid; + len += sprintf(respbuf + len, "bssid:"); + for (i = 0; i < ETH_ALEN - 1; ++i) + len += sprintf(respbuf + len, "%02x:", mac[i]); + len += sprintf(respbuf + len, "%02x ", mac[i]); + } + if (sec->param.passphrase.psk_type == MLAN_PSK_PMK) { + len += sprintf(respbuf + len, "psk:"); + for (i = 0; i < MLAN_MAX_KEY_LENGTH; ++i) + len += + sprintf(respbuf + len, "%02x", + sec->param.passphrase.psk.pmk.pmk[i]); + len += sprintf(respbuf + len, "\n"); + } + if (sec->param.passphrase.psk_type == MLAN_PSK_PASSPHRASE) { + len += + sprintf(respbuf + len, "passphrase:%s \n", + sec->param.passphrase.psk.passphrase.passphrase); + } + + ret = len; + done: + if (req) + kfree(req); + LEAVE(); + return ret; + +} + +/** + * @brief Deauthenticate + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written, negative for failure. + */ +int +woal_priv_deauth(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen) +{ + mlan_ioctl_req *req = NULL; + int ret = 0; + t_u8 mac[ETH_ALEN]; + + ENTER(); + + if (strlen(respbuf) > (strlen(CMD_MARVELL) + strlen(PRIV_CMD_DEAUTH))) { + /* Deauth mentioned BSSID */ + woal_mac2u8(mac, + respbuf + strlen(CMD_MARVELL) + strlen(PRIV_CMD_DEAUTH)); + if (MLAN_STATUS_SUCCESS != woal_disconnect(priv, MOAL_IOCTL_WAIT, mac)) { + ret = -EFAULT; + goto done; + } + } else { + if (MLAN_STATUS_SUCCESS != woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL)) + ret = -EFAULT; + } + + done: + if (req) + kfree(req); + LEAVE(); + return ret; +} + +#if defined(WIFI_DIRECT_SUPPORT) +#if defined(STA_SUPPORT) && defined(UAP_SUPPORT) +/** + * @brief Set/Get BSS role + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written, negative for failure. + */ +int +woal_priv_bssrole(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen) +{ + t_u32 data[1]; + int ret = 0; + int user_data_len = 0; + t_u8 action = MLAN_ACT_GET; + + ENTER(); + + if (strlen(respbuf) == (strlen(CMD_MARVELL) + strlen(PRIV_CMD_BSSROLE))) { + /* GET operation */ + user_data_len = 0; + } else { + /* SET operation */ + memset((char *) data, 0, sizeof(data)); + parse_arguments(respbuf + strlen(CMD_MARVELL) + + strlen(PRIV_CMD_BSSROLE), data, &user_data_len); + } + + if (user_data_len >= 2) { + PRINTM(MERROR, "Invalid number of arguments\n"); + ret = -EINVAL; + goto error; + } + + if (user_data_len == 0) { + action = MLAN_ACT_GET; + } else { + if ((data[0] != MLAN_BSS_ROLE_STA && + data[0] != MLAN_BSS_ROLE_UAP) || + priv->bss_type != MLAN_BSS_TYPE_WIFIDIRECT) { + PRINTM(MWARN, "Invalid BSS role\n"); + ret = -EINVAL; + goto error; + } + if (data[0] == GET_BSS_ROLE(priv)) { + PRINTM(MWARN, "Already BSS is in desired role\n"); + goto done; + } + action = MLAN_ACT_SET; + /* Reset interface */ + woal_reset_intf(priv, MOAL_IOCTL_WAIT, MFALSE); + } + + if (MLAN_STATUS_SUCCESS != woal_bss_role_cfg(priv, + action, MOAL_IOCTL_WAIT, + (t_u8 *) data)) { + ret = -EFAULT; + goto error; + } + + if (user_data_len) { + /* Initialize private structures */ + woal_init_priv(priv, MOAL_IOCTL_WAIT); + /* Enable interfaces */ + netif_device_attach(priv->netdev); + woal_start_queue(priv->netdev); + } + + done: + memset(respbuf, 0, respbuflen); + respbuf[0] = (t_u8) data[0]; + ret = 1; + + error: + LEAVE(); + return ret; +} +#endif /* STA_SUPPORT && UAP_SUPPORT */ +#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */ + +#ifdef STA_SUPPORT +/** + * @brief Set user scan + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written, negative for failure. + */ +int +woal_priv_setuserscan(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen) +{ + wlan_user_scan_cfg scan_cfg; + int ret = 0; + + ENTER(); + + /* Create the scan_cfg structure */ + memset(&scan_cfg, 0, sizeof(scan_cfg)); + + /* We expect the scan_cfg structure to be passed in respbuf */ + memcpy((char *) &scan_cfg, + respbuf + strlen(CMD_MARVELL) + strlen(PRIV_CMD_SETUSERSCAN), + sizeof(wlan_user_scan_cfg)); + + /* Call for scan */ + if (MLAN_STATUS_FAILURE == woal_do_scan(priv, &scan_cfg)) + ret = -EFAULT; + + LEAVE(); + return ret; +} +#endif + +/** + * @brief Set/Get deep sleep mode configurations + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written, negative for failure. + */ +int +woal_priv_setgetdeepsleep(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen) +{ + t_u32 data[2]; + int ret = 0; + int user_data_len = 0; + + ENTER(); + + if (strlen(respbuf) == (strlen(CMD_MARVELL) + strlen(PRIV_CMD_DEEPSLEEP))) { + /* GET operation */ + user_data_len = 0; + } else { + /* SET operation */ + memset((char *) data, 0, sizeof(data)); + parse_arguments(respbuf + strlen(CMD_MARVELL) + + strlen(PRIV_CMD_DEEPSLEEP), data, &user_data_len); + } + + if (user_data_len >= 3) { + PRINTM(MERROR, "Invalid number of arguments\n"); + ret = -EINVAL; + goto done; + } + + if (user_data_len == 0) { + if (MLAN_STATUS_SUCCESS != woal_get_deep_sleep(priv, data)) { + ret = -EFAULT; + goto done; + } + sprintf(respbuf, "%d %d", data[0], data[1]); + ret = strlen(respbuf) + 1; + } else { + if (data[0] == DEEP_SLEEP_OFF) { + PRINTM(MINFO, "Exit Deep Sleep Mode\n"); + ret = woal_set_deep_sleep(priv, MOAL_IOCTL_WAIT, MFALSE, 0); + if (ret != MLAN_STATUS_SUCCESS) { + ret = -EINVAL; + goto done; + } + } else if (data[0] == DEEP_SLEEP_ON) { + PRINTM(MINFO, "Enter Deep Sleep Mode\n"); + if (user_data_len != 2) + data[1] = 0; + ret = woal_set_deep_sleep(priv, MOAL_IOCTL_WAIT, MTRUE, data[1]); + if (ret != MLAN_STATUS_SUCCESS) { + ret = -EINVAL; + goto done; + } + } else { + PRINTM(MERROR, "Unknown option = %u\n", data[0]); + ret = -EINVAL; + goto done; + } + ret = sprintf(respbuf, "OK\n") + 1; + } + + done: + LEAVE(); + return ret; + +} + +/** + * @brief Set/Get IP address configurations + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written, negative for failure. + */ +int +woal_priv_setgetipaddr(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen) +{ + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *misc = NULL; + int ret = 0, op_code = 0, data_length = 0, header = 0; + + ENTER(); + + header = strlen(CMD_MARVELL) + strlen(PRIV_CMD_IPADDR); + data_length = strlen(respbuf) - header; + + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (req == NULL) { + ret = -ENOMEM; + goto done; + } + misc = (mlan_ds_misc_cfg *) req->pbuf; + + if (data_length < 1) { /* GET */ + req->action = MLAN_ACT_GET; + } else { + /* Make sure we have the operation argument */ + if (data_length > 2 && respbuf[header + 1] != ';') { + PRINTM(MERROR, "No operation argument. Separate with ';'\n"); + ret = -EINVAL; + goto done; + } else { + respbuf[header + 1] = '\0'; + } + req->action = MLAN_ACT_SET; + + /* Only one IP is supported in current firmware */ + memset(misc->param.ipaddr_cfg.ip_addr[0], 0, IPADDR_LEN); + in4_pton(&respbuf[header + 2], + MIN((IPADDR_MAX_BUF - 3), (data_length - 2)), + misc->param.ipaddr_cfg.ip_addr[0], ' ', NULL); + misc->param.ipaddr_cfg.ip_addr_num = 1; + misc->param.ipaddr_cfg.ip_addr_type = IPADDR_TYPE_IPV4; + + if (woal_atoi(&op_code, &respbuf[header]) != MLAN_STATUS_SUCCESS) { + ret = -EINVAL; + goto done; + } + misc->param.ipaddr_cfg.op_code = (t_u32) op_code; + } + + req->req_id = MLAN_IOCTL_MISC_CFG; + misc->sub_command = MLAN_OID_MISC_IP_ADDR; + + if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) { + ret = -EFAULT; + goto done; + } + + if (req->action == MLAN_ACT_GET) { + snprintf(respbuf, IPADDR_MAX_BUF, "%d;%d.%d.%d.%d", + misc->param.ipaddr_cfg.op_code, + misc->param.ipaddr_cfg.ip_addr[0][0], + misc->param.ipaddr_cfg.ip_addr[0][1], + misc->param.ipaddr_cfg.ip_addr[0][2], + misc->param.ipaddr_cfg.ip_addr[0][3]); + ret = IPADDR_MAX_BUF + 1; + } else { + ret = sprintf(respbuf, "OK\n") + 1; + } + + done: + if (req) + kfree(req); + LEAVE(); + return ret; +} + +/** + * @brief Set/Get WPS session configurations + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written, negative for failure. + */ +int +woal_priv_setwpssession(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen) +{ + mlan_ioctl_req *req = NULL; + mlan_ds_wps_cfg *pwps = NULL; + t_u32 data[1]; + int ret = 0; + int user_data_len = 0; + + ENTER(); + + if (strlen(respbuf) == (strlen(CMD_MARVELL) + strlen(PRIV_CMD_WPSSESSION))) { + /* GET operation */ + user_data_len = 0; + } else { + /* SET operation */ + memset((char *) data, 0, sizeof(data)); + parse_arguments(respbuf + strlen(CMD_MARVELL) + + strlen(PRIV_CMD_WPSSESSION), data, &user_data_len); + } + + if (user_data_len != 1) { + PRINTM(MERROR, "Invalid number of arguments\n"); + ret = -EINVAL; + goto done; + } + + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wps_cfg)); + if (req == NULL) { + ret = -ENOMEM; + goto done; + } + pwps = (mlan_ds_wps_cfg *) req->pbuf; + + req->req_id = MLAN_IOCTL_WPS_CFG; + req->action = MLAN_ACT_SET; + pwps->sub_command = MLAN_OID_WPS_CFG_SESSION; + + if (data[0] == 1) + pwps->param.wps_session = MLAN_WPS_CFG_SESSION_START; + else + pwps->param.wps_session = MLAN_WPS_CFG_SESSION_END; + + if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) { + ret = -EFAULT; + goto done; + } + + ret = sprintf(respbuf, "OK\n") + 1; + done: + if (req) + kfree(req); + LEAVE(); + return ret; +} + +/** + * @brief Get OTP user data + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written, negative for failure. + */ +int +woal_priv_otpuserdata(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen) +{ + int data[1]; + int user_data_len = 0; + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *misc = NULL; + mlan_ds_misc_otp_user_data *otp = NULL; + int ret = 0; + + ENTER(); + + memset((char *) data, 0, sizeof(data)); + parse_arguments(respbuf + strlen(CMD_MARVELL) + + strlen(PRIV_CMD_OTPUSERDATA), data, &user_data_len); + + if (user_data_len > 1) { + PRINTM(MERROR, "Too many arguments\n"); + LEAVE(); + return -EINVAL; + } + + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (req == NULL) { + ret = -ENOMEM; + goto done; + } + req->action = MLAN_ACT_GET; + req->req_id = MLAN_IOCTL_MISC_CFG; + + misc = (mlan_ds_misc_cfg *) req->pbuf; + misc->sub_command = MLAN_OID_MISC_OTP_USER_DATA; + misc->param.otp_user_data.user_data_length = data[0]; + + if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) { + ret = -EFAULT; + goto done; + } + otp = (mlan_ds_misc_otp_user_data *) req->pbuf; + + if (req->action == MLAN_ACT_GET) { + ret = MIN(otp->user_data_length, data[0]); + memcpy(respbuf, otp->user_data, ret); + } + + done: + if (req) + kfree(req); + LEAVE(); + return ret; +} + +/** + * @brief Set / Get country code + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written, negative for failure. + */ +int +woal_priv_set_get_countrycode(moal_private * priv, t_u8 * respbuf, + t_u32 respbuflen) +{ + int ret = 0; + // char data[COUNTRY_CODE_LEN] = {0, 0, 0}; + int header = 0, data_length = 0; // wrq->u.data.length; + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *pcfg_misc = NULL; + mlan_ds_misc_country_code *country_code = NULL; + + ENTER(); + + header = strlen(CMD_MARVELL) + strlen(PRIV_CMD_COUNTRYCODE); + data_length = strlen(respbuf) - header; + + if (data_length > COUNTRY_CODE_LEN) { + PRINTM(MERROR, "Invalid argument!\n"); + ret = -EINVAL; + goto done; + } + + /* Allocate an IOCTL request buffer */ + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (req == NULL) { + ret = -ENOMEM; + goto done; + } + + /* Fill request buffer */ + pcfg_misc = (mlan_ds_misc_cfg *) req->pbuf; + country_code = &pcfg_misc->param.country_code; + pcfg_misc->sub_command = MLAN_OID_MISC_COUNTRY_CODE; + req->req_id = MLAN_IOCTL_MISC_CFG; + + if (data_length <= 1) { + req->action = MLAN_ACT_GET; + } else { + memset(country_code->country_code, 0, COUNTRY_CODE_LEN); + memcpy(country_code->country_code, respbuf + header, COUNTRY_CODE_LEN); + req->action = MLAN_ACT_SET; + } + + /* Send IOCTL request to MLAN */ + if (woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT) != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } + + if (req->action == MLAN_ACT_GET) { + ret = data_length = COUNTRY_CODE_LEN; + memset(respbuf + header, 0, COUNTRY_CODE_LEN); + memcpy(respbuf, country_code->country_code, COUNTRY_CODE_LEN); + } + + done: + if (req) + kfree(req); + + LEAVE(); + return ret; +} + +/** + * @brief Set/Get TCP Ack enhancement configurations + * + * @param priv A pointer to moal_private structure + * @param respbuf A pointer to response buffer + * @param respbuflen Available length of response buffer + * + * @return Number of bytes written, negative for failure. + */ +int +woal_priv_setgettcpackenh(moal_private * priv, t_u8 * respbuf, t_u32 respbuflen) +{ + t_u32 data[1]; + int ret = 0; + int user_data_len = 0; + struct list_head *link = NULL; + struct tcp_sess *tcp_sess = NULL; + + ENTER(); + + if (strlen(respbuf) == (strlen(CMD_MARVELL) + strlen(PRIV_CMD_TCPACKENH))) { + /* GET operation */ + user_data_len = 0; + } else { + /* SET operation */ + memset((char *) data, 0, sizeof(data)); + parse_arguments(respbuf + strlen(CMD_MARVELL) + + strlen(PRIV_CMD_TCPACKENH), data, &user_data_len); + } + + if (user_data_len >= 2) { + PRINTM(MERROR, "Invalid number of arguments\n"); + ret = -EINVAL; + goto done; + } + + if (user_data_len == 0) { + /* get operation */ + respbuf[0] = priv->enable_tcp_ack_enh; + } else { + /* set operation */ + if (data[0] == MTRUE) { + PRINTM(MINFO, "Enabling TCP Ack enhancement\n"); + priv->enable_tcp_ack_enh = MTRUE; + } else if (data[0] == MFALSE) { + PRINTM(MINFO, "Disabling TCP Ack enhancement\n"); + priv->enable_tcp_ack_enh = MFALSE; + /* release the tcp sessions if any */ + while (!list_empty(&priv->tcp_sess_queue)) { + link = priv->tcp_sess_queue.next; + tcp_sess = list_entry(link, struct tcp_sess, link); + PRINTM(MINFO, + "Disable TCP ACK Enh: release a tcp session in dl. (src: ipaddr 0x%08x, port: %d. dst: ipaddr 0x%08x, port: %d\n", + tcp_sess->src_ip_addr, tcp_sess->src_tcp_port, + tcp_sess->dst_ip_addr, tcp_sess->dst_tcp_port); + list_del(link); + kfree(tcp_sess); + } + } else { + PRINTM(MERROR, "Unknown option = %u\n", data[0]); + ret = -EINVAL; + goto done; + } + respbuf[0] = priv->enable_tcp_ack_enh; + } + ret = 1; + + done: + LEAVE(); + return ret; + +} + +/** * @brief Set priv command for Android * @param dev A pointer to net_device structure * @param req A pointer to ifreq structure @@ -788,7 +1697,6 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) /* Set/Get band configuration */ len = woal_setget_priv_bandcfg(priv, buf, priv_cmd.total_len); goto handled; -#ifdef WIFI_DIRECT_SUPPORT } else if (strnicmp (buf + strlen(CMD_MARVELL), PRIV_CMD_HOSTCMD, @@ -796,7 +1704,6 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) /* hostcmd configuration */ len = woal_priv_hostcmd(priv, buf, priv_cmd.total_len); goto handled; -#endif } else if (strnicmp (buf + strlen(CMD_MARVELL), PRIV_CMD_HTTXCFG, @@ -818,13 +1725,110 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) /* Set/Get tx rate cfg */ len = woal_setget_priv_txratecfg(priv, buf, priv_cmd.total_len); goto handled; + } else + if (strnicmp + (buf + strlen(CMD_MARVELL), PRIV_CMD_CUSTOMIE, + strlen(PRIV_CMD_CUSTOMIE)) == 0) { + /* Custom IE configuration */ + len = woal_priv_customie(priv, buf, priv_cmd.total_len); + goto handled; + } else + if (strnicmp + (buf + strlen(CMD_MARVELL), PRIV_CMD_ESUPPMODE, + strlen(PRIV_CMD_ESUPPMODE)) == 0) { + /* Esupplicant mode configuration */ + len = woal_setget_priv_esuppmode(priv, buf, priv_cmd.total_len); + goto handled; + } else + if (strnicmp + (buf + strlen(CMD_MARVELL), PRIV_CMD_PASSPHRASE, + strlen(PRIV_CMD_PASSPHRASE)) == 0) { + /* Esupplicant passphrase configuration */ + len = woal_setget_priv_passphrase(priv, buf, priv_cmd.total_len); + goto handled; + } else + if (strnicmp + (buf + strlen(CMD_MARVELL), PRIV_CMD_DEAUTH, + strlen(PRIV_CMD_DEAUTH)) == 0) { + /* Deauth */ + len = woal_priv_deauth(priv, buf, priv_cmd.total_len); + goto handled; +#if defined(WIFI_DIRECT_SUPPORT) +#if defined(STA_SUPPORT) && defined(UAP_SUPPORT) + } else + if (strnicmp + (buf + strlen(CMD_MARVELL), PRIV_CMD_BSSROLE, + strlen(PRIV_CMD_BSSROLE)) == 0) { + /* BSS Role */ + len = woal_priv_bssrole(priv, buf, priv_cmd.total_len); + goto handled; +#endif +#endif +#ifdef STA_SUPPORT + } else + if (strnicmp + (buf + strlen(CMD_MARVELL), PRIV_CMD_SETUSERSCAN, + strlen(PRIV_CMD_SETUSERSCAN)) == 0) { + /* Set user scan */ + len = woal_priv_setuserscan(priv, buf, priv_cmd.total_len); + goto handled; +#endif + } else + if (strnicmp + (buf + strlen(CMD_MARVELL), PRIV_CMD_DEEPSLEEP, + strlen(PRIV_CMD_DEEPSLEEP)) == 0) { + /* Deep sleep */ + len = woal_priv_setgetdeepsleep(priv, buf, priv_cmd.total_len); + goto handled; + } else + if (strnicmp + (buf + strlen(CMD_MARVELL), PRIV_CMD_IPADDR, + strlen(PRIV_CMD_IPADDR)) == 0) { + /* IP address */ + len = woal_priv_setgetipaddr(priv, buf, priv_cmd.total_len); + goto handled; + } else + if (strnicmp + (buf + strlen(CMD_MARVELL), PRIV_CMD_WPSSESSION, + strlen(PRIV_CMD_WPSSESSION)) == 0) { + /* WPS Session */ + len = woal_priv_setwpssession(priv, buf, priv_cmd.total_len); + goto handled; + } else + if (strnicmp + (buf + strlen(CMD_MARVELL), PRIV_CMD_OTPUSERDATA, + strlen(PRIV_CMD_OTPUSERDATA)) == 0) { + /* OTP user data */ + len = woal_priv_otpuserdata(priv, buf, priv_cmd.total_len); + goto handled; + } else + if (strnicmp + (buf + strlen(CMD_MARVELL), PRIV_CMD_COUNTRYCODE, + strlen(PRIV_CMD_COUNTRYCODE)) == 0) { + /* OTP user data */ + len = woal_priv_set_get_countrycode(priv, buf, priv_cmd.total_len); + goto handled; + } else + if (strnicmp + (buf + strlen(CMD_MARVELL), PRIV_CMD_TCPACKENH, + strlen(PRIV_CMD_TCPACKENH)) == 0) { + /* OTP user data */ + len = woal_priv_setgettcpackenh(priv, buf, priv_cmd.total_len); + goto handled; } else { /* Fall through, after stripping off the custom header */ buf += strlen(CMD_MARVELL); } } #ifdef STA_SUPPORT - if (strncmp(buf, "RSSI", strlen("RSSI")) == 0) { + if (strncmp(buf, "RSSILOW-THRESHOLD", strlen("RSSILOW-THRESHOLD")) == 0) { + pdata = buf + strlen("RSSILOW-THRESHOLD") + 1; + if (MLAN_STATUS_SUCCESS != woal_set_rssi_low_threshold(priv, pdata)) { + ret = -EFAULT; + goto done; + } + len = sprintf(buf, "OK\n") + 1; + } else if (strncmp(buf, "RSSI", strlen("RSSI")) == 0) { if (MLAN_STATUS_SUCCESS != woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info)) { @@ -983,12 +1987,14 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) priv->bg_scan_reported = MFALSE; len = sprintf(buf, "OK\n") + 1; } else if (strncmp(buf, "BGSCAN-STOP", strlen("BGSCAN-STOP")) == 0) { - if (MLAN_STATUS_SUCCESS != woal_stop_bg_scan(priv)) { - ret = -EFAULT; - goto done; + if (priv->bg_scan_start && !priv->scan_cfg.rssi_threshold) { + if (MLAN_STATUS_SUCCESS != woal_stop_bg_scan(priv)) { + ret = -EFAULT; + goto done; + } + priv->bg_scan_start = MFALSE; + priv->bg_scan_reported = MFALSE; } - priv->bg_scan_start = MFALSE; - priv->bg_scan_reported = MFALSE; len = sprintf(buf, "OK\n") + 1; } else if (strncmp(buf, "RXFILTER-START", strlen("RXFILTER-START")) == 0) { #ifdef MEF_CFG_RX_FILTER @@ -1004,7 +2010,19 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) } #endif len = sprintf(buf, "OK\n") + 1; - } else if (strncmp(buf, "RXFILTER-ADD", strlen("RXFILTER-ADD")) == 0) { + } +#ifdef STA_CFG80211 + else if (strncmp(buf, "GET_RSSI_STATUS", strlen("GET_RSSI_STATUS")) == 0) { + if (priv->rssi_status == MLAN_EVENT_ID_FW_BCN_RSSI_LOW) + len = sprintf(buf, "EVENT=BEACON_RSSI_LOW\n"); + else if (priv->rssi_status == MLAN_EVENT_ID_FW_PRE_BCN_LOST) + len = sprintf(buf, "EVENT=PRE_BEACON_LOST\n"); + else + len = sprintf(buf, "OK\n") + 1; + priv->rssi_status = 0; + } +#endif + else if (strncmp(buf, "RXFILTER-ADD", strlen("RXFILTER-ADD")) == 0) { pdata = buf + strlen("RXFILTER-ADD") + 1; if (MLAN_STATUS_SUCCESS != woal_add_rxfilter(priv, pdata)) { ret = -EFAULT; @@ -1071,10 +2089,20 @@ woal_android_priv_cmd(struct net_device *dev, struct ifreq *req) if (len > 0) { priv_cmd.used_len = len; - if (copy_to_user(priv_cmd.buf, buf, len)) { + if (priv_cmd.used_len < priv_cmd.total_len) + memset(priv_cmd.buf + priv_cmd.used_len, 0, + priv_cmd.total_len - priv_cmd.used_len); + if (copy_to_user(priv_cmd.buf, buf, priv_cmd.used_len)) { PRINTM(MERROR, "%s: failed to copy data to user buffer\n", __FUNCTION__); ret = -EFAULT; + goto done; + } + if (copy_to_user + (req->ifr_data, &priv_cmd, sizeof(android_wifi_priv_cmd))) { + PRINTM(MERROR, "%s: failed to copy command header to user buffer\n", + __FUNCTION__); + ret = -EFAULT; } } else { ret = len; diff --git a/drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.h b/drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.h index a1481e88ff21..a68991694a9d 100644 --- a/drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.h +++ b/drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.h @@ -44,12 +44,23 @@ Change log: /** Private command ID to get BSS type */ #define WOAL_GET_BSS_TYPE (SIOCDEVPRIVATE + 15) -int woal_do_ioctl(struct net_device *dev, struct ifreq *req, int i); +int woal_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd); +/* + * For android private commands, fixed value of ioctl is used. + * Internally commands are differentiated using strings. + * + * application needs to specify "total_len" of data for copy_from_user + * kernel updates "used_len" during copy_to_user + */ +/** Private command structure from app */ typedef struct _android_wifi_priv_cmd { + /** Buffer pointer */ char *buf; + /** buffer updated by driver */ int used_len; + /** buffer sent by application */ int total_len; } android_wifi_priv_cmd; @@ -62,6 +73,16 @@ typedef struct woal_priv_tx_rate_cfg t_u32 rate_index; } woal_tx_rate_cfg; +typedef struct woal_priv_esuppmode_cfg +{ + /* RSN mode */ + t_u16 rsn_mode; + /* Pairwise cipher */ + t_u8 pairwise_cipher; + /* Group cipher */ + t_u8 group_cipher; +} woal_esuppmode_cfg; + mlan_status woal_set_ap_wps_p2p_ie(moal_private * priv, t_u8 * ie, size_t len); int woal_android_priv_cmd(struct net_device *dev, struct ifreq *req); diff --git a/drivers/net/wireless/sd8797/mlinux/moal_ioctl.c b/drivers/net/wireless/sd8797/mlinux/moal_ioctl.c index efe6e7ddcea1..94fe7e11669e 100644 --- a/drivers/net/wireless/sd8797/mlinux/moal_ioctl.c +++ b/drivers/net/wireless/sd8797/mlinux/moal_ioctl.c @@ -2,7 +2,7 @@ * * @brief This file contains ioctl function to MLAN * - * Copyright (C) 2008-2011, Marvell International Ltd. + * Copyright (C) 2008-2012, Marvell International Ltd. * * This software file (the "File") is distributed by Marvell International * Ltd. under the terms of the GNU General Public License Version 2, June 1991 @@ -792,7 +792,7 @@ woal_set_get_retry(moal_private * priv, t_u32 action, #ifdef STA_CFG80211 /* If set is invoked from other than iw i.e iwconfig, wiphy retry count should be updated as well */ - if (IS_STA_CFG80211(cfg80211_wext) && + if (IS_STA_CFG80211(cfg80211_wext) && priv->wdev && priv->wdev->wiphy && (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) && (action == MLAN_ACT_SET)) { priv->wdev->wiphy->retry_long = (t_u8) * value; priv->wdev->wiphy->retry_short = (t_u8) * value; @@ -854,7 +854,7 @@ woal_set_get_rts(moal_private * priv, t_u32 action, #ifdef STA_CFG80211 /* If set is invoked from other than iw i.e iwconfig, wiphy RTS threshold should be updated as well */ - if (IS_STA_CFG80211(cfg80211_wext) && + if (IS_STA_CFG80211(cfg80211_wext) && priv->wdev && priv->wdev->wiphy && (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) && (action == MLAN_ACT_SET)) priv->wdev->wiphy->rts_threshold = *value; #endif @@ -914,7 +914,7 @@ woal_set_get_frag(moal_private * priv, t_u32 action, #ifdef STA_CFG80211 /* If set is invoked from other than iw i.e iwconfig, wiphy fragment threshold should be updated as well */ - if (IS_STA_CFG80211(cfg80211_wext) && + if (IS_STA_CFG80211(cfg80211_wext) && priv->wdev && priv->wdev->wiphy && (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) && (action == MLAN_ACT_SET)) priv->wdev->wiphy->frag_threshold = *value; #endif @@ -1096,7 +1096,7 @@ woal_set_get_power_mgmt(moal_private * priv, #ifdef STA_CFG80211 /* If set is invoked from other than iw i.e iwconfig, wiphy IEEE power save mode should be updated */ - if (IS_STA_CFG80211(cfg80211_wext) && + if (IS_STA_CFG80211(cfg80211_wext) && priv->wdev && (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) && (action == MLAN_ACT_SET)) { if (*disabled) priv->wdev->ps = MFALSE; @@ -1780,20 +1780,22 @@ woal_get_bss_type(struct net_device *dev, struct ifreq *req) #if defined(STA_SUPPORT) && defined(UAP_SUPPORT) #if defined(STA_WEXT) || defined(UAP_WEXT) /** - * @brief Set/Get BSS role + * @brief Swithces BSS role of WFD interface * - * @param priv A pointer to moal_private structure - * @param wrq A pointer to iwreq structure + * @param priv A pointer to moal_private structure + * @param action Action: set or get + * @param wait_option Wait option (MOAL_WAIT or MOAL_NO_WAIT) + * @param bss_role A pointer to bss role * * @return 0 --success, otherwise fail */ -int -woal_set_get_bss_role(moal_private * priv, struct iwreq *wrq) +mlan_status +woal_bss_role_cfg(moal_private * priv, t_u8 action, + t_u8 wait_option, t_u8 * bss_role) { int ret = 0; mlan_ds_bss *bss = NULL; mlan_ioctl_req *req = NULL; - int bss_role = 0; struct net_device *dev = priv->netdev; ENTER(); @@ -1812,55 +1814,26 @@ woal_set_get_bss_role(moal_private * priv, struct iwreq *wrq) bss = (mlan_ds_bss *) req->pbuf; bss->sub_command = MLAN_OID_BSS_ROLE; req->req_id = MLAN_IOCTL_BSS; - if (wrq->u.data.length) { - if (copy_from_user(&bss_role, wrq->u.data.pointer, sizeof(int))) { - PRINTM(MERROR, "Copy from user failed\n"); - ret = -EFAULT; - goto done; - } - if (bss_role != MLAN_BSS_ROLE_STA && bss_role != MLAN_BSS_ROLE_UAP) { - PRINTM(MWARN, "Invalid BSS role\n"); - ret = -EINVAL; - goto done; - } - if (bss_role == GET_BSS_ROLE(priv)) { - PRINTM(MWARN, "Already BSS is in desired role\n"); - ret = -EINVAL; - goto done; - } - req->action = MLAN_ACT_SET; - bss->param.bss_role = (t_u8) bss_role; - } else { - req->action = MLAN_ACT_GET; - } - - if (req->action == MLAN_ACT_SET) { - /* Reset interface */ - woal_reset_intf(priv, MOAL_IOCTL_WAIT, MFALSE); + req->action = action; + if (action == MLAN_ACT_SET) { + bss->param.bss_role = *bss_role; } - if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) { + if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, wait_option)) { ret = -EFAULT; goto done; } - if (!wrq->u.data.length) { - bss_role = (int) bss->param.bss_role; - if (copy_to_user(wrq->u.data.pointer, &bss_role, sizeof(int))) { - ret = -EFAULT; - goto done; - } - wrq->u.data.length = 1; + + if (action == MLAN_ACT_GET) { + *bss_role = bss->param.bss_role; } else { /* Update moal_private */ - priv->bss_role = bss_role; + priv->bss_role = *bss_role; if (priv->bss_type == MLAN_BSS_TYPE_UAP) priv->bss_type = MLAN_BSS_TYPE_STA; else if (priv->bss_type == MLAN_BSS_TYPE_STA) priv->bss_type = MLAN_BSS_TYPE_UAP; - /* Initialize private structures */ - woal_init_priv(priv, MOAL_IOCTL_WAIT); - - if (bss_role == MLAN_BSS_ROLE_UAP) { + if (*bss_role == MLAN_BSS_ROLE_UAP) { /* Switch: STA -> uAP */ /* Setup the OS Interface to our functions */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) @@ -1881,7 +1854,7 @@ woal_set_get_bss_role(moal_private * priv, struct iwreq *wrq) init_waitqueue_head(&priv->w_stats_wait_q); } #endif /* UAP_WEXT */ - } else if (bss_role == MLAN_BSS_ROLE_STA) { + } else if (*bss_role == MLAN_BSS_ROLE_STA) { /* Switch: uAP -> STA */ /* Setup the OS Interface to our functions */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) @@ -1903,9 +1876,6 @@ woal_set_get_bss_role(moal_private * priv, struct iwreq *wrq) } #endif /* STA_WEXT */ } - /* Enable interfaces */ - netif_device_attach(dev); - woal_start_queue(dev); } done: @@ -1914,8 +1884,75 @@ woal_set_get_bss_role(moal_private * priv, struct iwreq *wrq) LEAVE(); return ret; } -#endif -#endif + +/** + * @brief Set/Get BSS role + * + * @param priv A pointer to moal_private structure + * @param wrq A pointer to iwreq structure + * + * @return 0 --success, otherwise fail + */ +int +woal_set_get_bss_role(moal_private * priv, struct iwreq *wrq) +{ + int ret = 0; + int bss_role = 0; + t_u8 action = MLAN_ACT_GET; + + ENTER(); + + if (wrq->u.data.length) { + if (copy_from_user(&bss_role, wrq->u.data.pointer, sizeof(int))) { + PRINTM(MERROR, "Copy from user failed\n"); + ret = -EFAULT; + goto done; + } + if ((bss_role != MLAN_BSS_ROLE_STA && + bss_role != MLAN_BSS_ROLE_UAP) || + (priv->bss_type != MLAN_BSS_TYPE_WIFIDIRECT)) { + PRINTM(MWARN, "Invalid BSS role\n"); + ret = -EINVAL; + goto done; + } + if (bss_role == GET_BSS_ROLE(priv)) { + PRINTM(MWARN, "Already BSS is in desired role\n"); + ret = -EINVAL; + goto done; + } + action = MLAN_ACT_SET; + /* Reset interface */ + woal_reset_intf(priv, MOAL_IOCTL_WAIT, MFALSE); + } + + if (MLAN_STATUS_SUCCESS != woal_bss_role_cfg(priv, + action, MOAL_IOCTL_WAIT, + (t_u8 *) & bss_role)) { + ret = -EFAULT; + goto done; + } + + if (!wrq->u.data.length) { + if (copy_to_user(wrq->u.data.pointer, &bss_role, sizeof(int))) { + ret = -EFAULT; + goto done; + } + wrq->u.data.length = 1; + } else { + /* Initialize private structures */ + woal_init_priv(priv, MOAL_IOCTL_WAIT); + + /* Enable interfaces */ + netif_device_attach(priv->netdev); + woal_start_queue(priv->netdev); + } + + done: + LEAVE(); + return ret; +} +#endif /* STA_WEXT || UAP_WEXT */ +#endif /* STA_SUPPORT && UAP_SUPPORT */ #endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */ /** @@ -1993,6 +2030,7 @@ woal_cancel_hs(moal_private * priv, t_u8 wait_option) return ret; } +#if defined(SDIO_SUSPEND_RESUME) /** @brief This function enables the host sleep * * @param priv A Pointer to the moal_private structure @@ -2074,6 +2112,7 @@ woal_enable_hs(moal_private * priv) LEAVE(); return hs_actived; } +#endif /** * @brief This function send soft_reset command to firmware @@ -2525,6 +2564,48 @@ woal_get_pm_info(moal_private * priv, mlan_ds_ps_info * pm_info) } /** + * @brief Get Deep Sleep + * + * @param priv Pointer to the moal_private driver data struct + * @param data Pointer to return deep_sleep setting + * + * @return 0 --success, otherwise fail + */ +int +woal_get_deep_sleep(moal_private * priv, t_u32 * data) +{ + int ret = 0; + mlan_ioctl_req *req = NULL; + mlan_ds_pm_cfg *pm = NULL; + + ENTER(); + + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg)); + if (req == NULL) { + LEAVE(); + return -ENOMEM; + } + pm = (mlan_ds_pm_cfg *) req->pbuf; + pm->sub_command = MLAN_OID_PM_CFG_DEEP_SLEEP; + req->req_id = MLAN_IOCTL_PM_CFG; + + req->action = MLAN_ACT_GET; + if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) { + ret = -EFAULT; + goto done; + } + *data = pm->param.auto_deep_sleep.auto_ds; + *(data + 1) = pm->param.auto_deep_sleep.idletime; + + done: + if (req) + kfree(req); + + LEAVE(); + return ret; +} + +/** * @brief Set Deep Sleep * * @param priv Pointer to the moal_private driver data struct @@ -2665,8 +2746,7 @@ woal_11h_channel_check_ioctl(moal_private * priv) * @return MLAN_STATUS_SUCCESS -- success, otherwise fail */ mlan_status -woal_cfg80211_wifi_direct_mode_cfg(moal_private * priv, t_u16 action, - t_u16 * mode) +woal_wifi_direct_mode_cfg(moal_private * priv, t_u16 action, t_u16 * mode) { mlan_status ret = MLAN_STATUS_SUCCESS; mlan_ioctl_req *req = NULL; @@ -3640,6 +3720,13 @@ woal_set_bg_scan(moal_private * priv, char *buf, int length) ptr += 2; buf_left -= 2; break; + case WEXT_BGSCAN_REPEAT_SECTION: + priv->scan_cfg.repeat_count = (t_u16) ptr[1]; + PRINTM(MIOCTL, "BG scan: repeat_count=%d\n", + (int) priv->scan_cfg.repeat_count); + ptr += 2; + buf_left -= 2; + break; case WEXT_BGSCAN_INTERVAL_SECTION: priv->scan_cfg.scan_interval = (ptr[2] << 8 | ptr[1]) * 1000; PRINTM(MIOCTL, "BG scan: scan_interval=%d\n", @@ -3728,7 +3815,7 @@ woal_reconfig_bgscan(moal_handle * handle) * @brief set rssi low threshold * * @param priv A pointer to moal_private structure - * @param scan_type MLAN_SCAN_TYPE_ACTIVE/MLAN_SCAN_TYPE_PASSIVE + * @param rssi A pointer to low rssi * * @return MLAN_STATUS_SUCCESS -- success, otherwise fail */ @@ -3754,10 +3841,16 @@ woal_set_rssi_low_threshold(moal_private * priv, char *rssi) misc->sub_command = MLAN_OID_MISC_SUBSCRIBE_EVENT; req->action = MLAN_ACT_SET; misc->param.subscribe_event.evt_bitmap = SUBSCRIBE_EVT_RSSI_LOW; + misc->param.subscribe_event.evt_bitmap |= SUBSCRIBE_EVT_PRE_BEACON_LOST; + misc->param.subscribe_event.pre_beacon_miss = DEFAULT_PRE_BEACON_MISS; + if (MLAN_STATUS_SUCCESS != woal_atoi(&low_rssi, rssi)) { ret = -EFAULT; goto done; } +#ifdef STA_CFG80211 + priv->mrvl_rssi_low = low_rssi; +#endif misc->param.subscribe_event.low_rssi = low_rssi; misc->param.subscribe_event.low_rssi_freq = 0; if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) { @@ -3771,6 +3864,69 @@ woal_set_rssi_low_threshold(moal_private * priv, char *rssi) return ret; } +#ifdef STA_CFG80211 +/** + * @brief set rssi low threshold + * + * @param priv A pointer to moal_private structure + * @param event_id event id. + * + * @return MLAN_STATUS_SUCCESS -- success, otherwise fail + */ +mlan_status +woal_set_rssi_threshold(moal_private * priv, t_u32 event_id) +{ + mlan_status ret = MLAN_STATUS_SUCCESS; + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *misc = NULL; + + ENTER(); + if (priv->media_connected == MFALSE) + goto done; + if (priv->mrvl_rssi_low) + goto done; + if (event_id == MLAN_EVENT_ID_FW_BCN_RSSI_LOW) { + if (priv->last_rssi_low < 100) + priv->last_rssi_low += priv->cqm_rssi_hyst; + priv->last_rssi_high = abs(priv->cqm_rssi_thold); + } else if (event_id == MLAN_EVENT_ID_FW_BCN_RSSI_HIGH) { + priv->last_rssi_low = abs(priv->cqm_rssi_thold); + if (priv->last_rssi_high > priv->cqm_rssi_hyst) + priv->last_rssi_high -= priv->cqm_rssi_hyst; + } else { + priv->last_rssi_low = abs(priv->cqm_rssi_thold); + priv->last_rssi_high = abs(priv->cqm_rssi_thold); + } + + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (req == NULL) { + ret = -ENOMEM; + goto done; + } + misc = (mlan_ds_misc_cfg *) req->pbuf; + req->req_id = MLAN_IOCTL_MISC_CFG; + misc->sub_command = MLAN_OID_MISC_SUBSCRIBE_EVENT; + req->action = MLAN_ACT_SET; + misc->param.subscribe_event.evt_bitmap = + SUBSCRIBE_EVT_RSSI_LOW | SUBSCRIBE_EVT_RSSI_HIGH; + misc->param.subscribe_event.low_rssi_freq = 0; + misc->param.subscribe_event.low_rssi = priv->last_rssi_low; + misc->param.subscribe_event.high_rssi_freq = 0; + misc->param.subscribe_event.high_rssi = priv->last_rssi_high; + PRINTM(MIOCTL, "rssi_low=%d, rssi_high=%d\n", (int) priv->last_rssi_low, + (int) priv->last_rssi_high); + if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) { + ret = -EFAULT; + goto done; + } + done: + if (req) + kfree(req); + LEAVE(); + return ret; +} +#endif + /** * @brief Get power mode * diff --git a/drivers/net/wireless/sd8797/mlinux/moal_main.c b/drivers/net/wireless/sd8797/mlinux/moal_main.c index eac248b70129..d5bed42fa73d 100644 --- a/drivers/net/wireless/sd8797/mlinux/moal_main.c +++ b/drivers/net/wireless/sd8797/mlinux/moal_main.c @@ -47,6 +47,11 @@ Change log: #include <linux/wlan_plat.h> #include "moal_eth_ioctl.h" +#include <linux/if_ether.h> +#include <linux/in.h> +#include <linux/tcp.h> +#include <net/tcp.h> + /******************************************************** Local Variables ********************************************************/ @@ -205,7 +210,7 @@ int woal_close(struct net_device *dev); int woal_set_mac_address(struct net_device *dev, void *addr); void woal_tx_timeout(struct net_device *dev); struct net_device_stats *woal_get_stats(struct net_device *dev); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) u16 woal_select_queue(struct net_device *dev, struct sk_buff *skb); #endif @@ -404,7 +409,7 @@ woal_init_sw(moal_handle * handle) /* PnP and power profile */ handle->surprise_removed = MFALSE; init_waitqueue_head(&handle->init_wait_q); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) spin_lock_init(&handle->queue_lock); #endif @@ -1215,9 +1220,7 @@ const struct net_device_ops woal_netdev_ops = { #else .ndo_set_multicast_list = woal_set_multicast_list, #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) .ndo_select_queue = woal_select_queue, -#endif }; #endif @@ -1292,9 +1295,7 @@ const struct net_device_ops woal_uap_netdev_ops = { #else .ndo_set_multicast_list = woal_uap_set_multicast_list, #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) .ndo_select_queue = woal_select_queue, -#endif }; #endif @@ -1373,7 +1374,7 @@ woal_add_interface(moal_handle * handle, t_u8 bss_index, t_u8 bss_type) moal_private *priv = NULL; ENTER(); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) #define MAX_WMM_QUEUE 4 /* Allocate an Ethernet device */ if (!(dev = alloc_etherdev_mq(sizeof(moal_private), MAX_WMM_QUEUE))) { @@ -1420,11 +1421,8 @@ woal_add_interface(moal_handle * handle, t_u8 bss_index, t_u8 bss_type) else if (bss_type == MLAN_BSS_TYPE_WIFIDIRECT) priv->bss_role = MLAN_BSS_ROLE_STA; #endif -#if defined(STA_CFG80211) || defined(UAP_CFG80211) - priv->probereq_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; -#endif -#ifdef STA_SUPPORT -#endif + + INIT_LIST_HEAD(&priv->tcp_sess_queue); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) SET_MODULE_OWNER(dev); @@ -1448,7 +1446,7 @@ woal_add_interface(moal_handle * handle, t_u8 bss_index, t_u8 bss_type) if ((priv->bss_role == MLAN_BSS_ROLE_STA) && IS_STA_CFG80211(cfg80211_wext)) { if (bss_type == MLAN_BSS_TYPE_STA #if defined(WIFI_DIRECT_SUPPORT) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) || defined(COMPAT_WIRELESS) +#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION || bss_type == MLAN_BSS_TYPE_WIFIDIRECT #endif #endif @@ -1883,7 +1881,14 @@ woal_close(struct net_device *dev) moal_private *priv = (moal_private *) netdev_priv(dev); ENTER(); - +#ifdef STA_SUPPORT +#ifdef STA_CFG80211 + if (IS_STA_CFG80211(cfg80211_wext) && priv->scan_request) { + cfg80211_scan_done(priv->scan_request, MTRUE); + priv->scan_request = NULL; + } +#endif +#endif woal_stop_queue(priv->netdev); MODULE_PUT; @@ -2066,7 +2071,7 @@ woal_get_stats(struct net_device *dev) return &priv->stats; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) /** * @brief This function handles wmm queue select * @@ -2109,6 +2114,233 @@ woal_select_queue(struct net_device * dev, struct sk_buff * skb) #endif /** + * @brief This function gets tcp session from the tcp session queue + * + * @param priv A pointer to moal_private structure + * @param src_ip IP address of the device + * @param src_port TCP port of the device + * @param dst_ip IP address of the client + * @param src_port TCP port of the client + * + * @return A pointer to the tcp session data structure, if found. + * Otherwise, null + */ +struct tcp_sess * +woal_get_tcp_sess(moal_private * priv, + t_u32 src_ip, t_u16 src_port, t_u32 dst_ip, t_u16 dst_port) +{ + struct tcp_sess *tcp_sess = NULL; + ENTER(); + + list_for_each_entry(tcp_sess, &priv->tcp_sess_queue, link) { + if ((tcp_sess->src_ip_addr == src_ip) && + (tcp_sess->src_tcp_port == src_port) && + (tcp_sess->dst_ip_addr == dst_ip) && + (tcp_sess->dst_tcp_port == dst_port)) { + LEAVE(); + return tcp_sess; + } + } + LEAVE(); + return NULL; +} + +/** + * @brief This function checks received tcp packet for FIN + * and release the tcp session if received + * + * @param priv A pointer to moal_private structure + * @param skb A pointer to sk_buff structure + * + * @return None + */ +void +woal_check_tcp_fin(moal_private * priv, struct sk_buff *skb) +{ + struct ethhdr *ethh = NULL; + struct iphdr *iph = NULL; + struct tcphdr *tcph = NULL; + struct tcp_sess *tcp_sess = NULL; + + ENTER(); + + ethh = eth_hdr(skb); + if (ntohs(ethh->h_proto) == ETH_P_IP) { + iph = (struct iphdr *) ((t_u8 *) ethh + sizeof(struct ethhdr)); + if (iph->protocol == IPPROTO_TCP) { + tcph = (struct tcphdr *) ((t_u8 *) iph + iph->ihl * 4); + if (tcph->fin) { + tcp_sess = woal_get_tcp_sess(priv, iph->daddr, + tcph->dest, iph->saddr, + tcph->source); + if (tcp_sess != NULL) { + PRINTM(MINFO, + "TX: release a tcp session in dl. (src: ipaddr 0x%08x, port: %d. dst: ipaddr 0x%08x, port: %d\n", + iph->daddr, tcph->dest, iph->saddr, tcph->source); + /* remove the tcp session from the queue */ + list_del(&tcp_sess->link); + kfree(tcp_sess); + } else { + PRINTM(MINFO, "Tx: released TCP session is not found.\n "); + } + } + } + } + LEAVE(); +} + +/** + * @brief This function process tcp ack packets + * + * @param priv A pointer to moal_private structure + * @param pmbuf A pointer to the mlan buffer associated with the skb + * + * @return 1, if a tcp ack packet has been dropped. Otherwise, 0. + */ +int +woal_process_tcp_ack(moal_private * priv, mlan_buffer * pmbuf) +{ + int ret = 0; + struct ethhdr *ethh = NULL; + struct iphdr *iph = NULL; + struct tcphdr *tcph = NULL; + struct tcp_sess *tcp_sess = NULL; + struct sk_buff *skb = NULL; + t_u32 ack_seq = 0; + t_u32 len = 0; + t_u8 opt = 0; + t_u8 opt_len = 0; + t_u8 *pos = NULL; + t_u32 win_size = 0; + +#define TCP_ACK_DELAY 3 +#define TCP_ACK_INIT_WARMING_UP 1000 /* initial */ +#define TCP_ACK_RECV_WARMING_UP 1000 /* recovery */ + + ENTER(); + + /** check the tcp packet */ + ethh = (struct ethhdr *) (pmbuf->pbuf + pmbuf->data_offset); + if (ntohs(ethh->h_proto) != ETH_P_IP) { + return 0; + } + iph = (struct iphdr *) ((t_u8 *) ethh + sizeof(struct ethhdr)); + if (iph->protocol != IPPROTO_TCP) { + return 0; + } + tcph = (struct tcphdr *) ((t_u8 *) iph + iph->ihl * 4); + + if (tcph->syn & tcph->ack) { + /* respond to a TCP request. create a tcp session */ + if (!(tcp_sess = kmalloc(sizeof(struct tcp_sess), GFP_ATOMIC))) { + PRINTM(MERROR, "Fail to allocate tcp_sess.\n"); + return 0; + } + memset(tcp_sess, 0, sizeof(struct tcp_sess)); + tcp_sess->src_ip_addr = iph->saddr; /* my ip addr */ + tcp_sess->dst_ip_addr = iph->daddr; + tcp_sess->src_tcp_port = tcph->source; + tcp_sess->dst_tcp_port = tcph->dest; + tcp_sess->start_cnt = TCP_ACK_INIT_WARMING_UP; + + INIT_LIST_HEAD(&tcp_sess->link); + list_add_tail(&tcp_sess->link, &priv->tcp_sess_queue); + PRINTM(MINFO, + "create a tcp session. (src: ipaddr 0x%08x, port: %d. dst: ipaddr 0x%08x, port: %d\n", + iph->saddr, tcph->source, iph->daddr, tcph->dest); + + /* parse tcp options for the window scale */ + len = (tcph->doff * 4) - sizeof(struct tcphdr); + pos = (t_u8 *) (tcph + 1); + while (len > 0) { + opt = *pos++; + switch (opt) { + case TCPOPT_EOL: + len = 0; + continue; + case TCPOPT_NOP: + len--; + continue; + case TCPOPT_WINDOW: + opt_len = *pos++; + if (opt_len == TCPOLEN_WINDOW) { + tcp_sess->rx_win_scale = *pos; + tcp_sess->rx_win_opt = 1; + if (tcp_sess->rx_win_scale > 14) + tcp_sess->rx_win_scale = 14; + PRINTM(MINFO, "TCP Window Scale: %d \n", + tcp_sess->rx_win_scale); + } + break; + default: + opt_len = *pos++; + } + len -= opt_len; + pos += opt_len - 2; + } + } else if (tcph->ack && !(tcph->syn) && + (ntohs(iph->tot_len) == (iph->ihl * 4 + tcph->doff * 4))) { + /** it is an ack packet, not a piggyback ack */ + tcp_sess = woal_get_tcp_sess(priv, iph->saddr, tcph->source, + iph->daddr, tcph->dest); + if (tcp_sess == NULL) { + return 0; + } + /** do not drop the ack packets initially */ + if (tcp_sess->start_cnt) { + tcp_sess->start_cnt--; + return 0; + } + + /* check the window size. */ + win_size = ntohs(tcph->window); + if (tcp_sess->rx_win_opt) { + win_size <<= tcp_sess->rx_win_scale; + /* Note: it may depend on the rtd */ + if ((win_size > 1500 * (TCP_ACK_DELAY + 5)) && + (tcp_sess->ack_cnt < TCP_ACK_DELAY)) { + /* if windiow is big enough, drop the ack packet */ + if (tcp_sess->ack_seq != ntohl(tcph->ack_seq)) { + ack_seq = tcp_sess->ack_seq; + tcp_sess->ack_seq = ntohl(tcph->ack_seq); + tcp_sess->ack_cnt++; + skb = (struct sk_buff *) pmbuf->pdesc; + if (skb) + dev_kfree_skb_any(skb); + ret = 1; + } else { + /* the ack packet is retransmitted. thus, stop dropping + the ack packets */ + tcp_sess->start_cnt = TCP_ACK_RECV_WARMING_UP; + PRINTM(MINFO, "Recover the TCP session.\n "); + } + } else { + /* send the current ack pacekt */ + ack_seq = tcp_sess->ack_seq; + tcp_sess->ack_seq = ntohl(tcph->ack_seq); + tcp_sess->ack_cnt = 0; + ret = 0; + } + } + } else if (tcph->fin) { + tcp_sess = woal_get_tcp_sess(priv, iph->saddr, tcph->source, + iph->daddr, tcph->dest); + if (tcp_sess != NULL) { + /* remove the tcp session from the queue */ + PRINTM(MINFO, + "Rx: release a tcp session in ul. (src: ipaddr 0x%08x, port: %d. dst: ipaddr 0x%08x, port: %d\n", + iph->saddr, tcph->source, iph->daddr, tcph->dest); + list_del(&tcp_sess->link); + kfree(tcp_sess); + } else { + PRINTM(MINFO, "released TCP session is not found.\n "); + } + } + LEAVE(); + return ret; +} + +/** * @brief This function handles packet transmission * * @param skb A pointer to sk_buff structure @@ -2165,6 +2397,13 @@ woal_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) memset((t_u8 *) pmbuf, 0, sizeof(mlan_buffer)); pmbuf->bss_index = priv->bss_index; woal_fill_mlan_buffer(priv, pmbuf, skb); + if (priv->enable_tcp_ack_enh == MTRUE) { + if (woal_process_tcp_ack(priv, pmbuf)) { + /* the ack packet has been dropped */ + goto done; + } + } + status = mlan_send_packet(priv->phandle->pmlan_adapter, pmbuf); switch (status) { case MLAN_STATUS_PENDING: @@ -2394,6 +2633,8 @@ woal_set_multicast_list(struct net_device *dev) void woal_init_priv(moal_private * priv, t_u8 wait_option) { + struct list_head *link = NULL; + struct tcp_sess *tcp_sess = NULL; ENTER(); #ifdef STA_SUPPORT if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) { @@ -2414,7 +2655,7 @@ woal_init_priv(moal_private * priv, t_u8 wait_option) if (IS_STA_CFG80211(cfg80211_wext)) { if (priv->bss_type == MLAN_BSS_TYPE_STA #if defined(WIFI_DIRECT_SUPPORT) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) || defined(COMPAT_WIRELESS) +#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION || priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT #endif #endif @@ -2434,6 +2675,25 @@ woal_init_priv(moal_private * priv, t_u8 wait_option) } #endif priv->media_connected = MFALSE; + +#if defined(STA_CFG80211) || defined(UAP_CFG80211) + priv->probereq_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; +#endif +#ifdef STA_SUPPORT +#endif + + priv->enable_tcp_ack_enh = MTRUE; + while (!list_empty(&priv->tcp_sess_queue)) { + link = priv->tcp_sess_queue.next; + tcp_sess = list_entry(link, struct tcp_sess, link); + PRINTM(MINFO, + "warm reset: release a tcp session in dl. (src: ipaddr 0x%08x, port: %d. dst: ipaddr 0x%08x, port: %d\n", + tcp_sess->src_ip_addr, tcp_sess->src_tcp_port, + tcp_sess->dst_ip_addr, tcp_sess->dst_tcp_port); + list_del(link); + kfree(tcp_sess); + } + woal_request_get_fw_info(priv, wait_option, NULL); LEAVE(); @@ -2805,8 +3065,9 @@ woal_reassociation_thread(void *data) for (i = 0; i < handle->priv_num && (priv = handle->priv[i]); i++) { - if (priv->reassoc_required == MFALSE) + if (priv->reassoc_required == MFALSE) { continue; + } memset(&bss_info, 0x00, sizeof(bss_info)); @@ -2892,7 +3153,6 @@ woal_reassociation_thread(void *data) mlan_ioctl_req *req = NULL; reassoc_timer_req = MFALSE; - if (priv->rate_index != AUTO_RATE) { req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_rate)); @@ -2928,11 +3188,13 @@ woal_reassociation_thread(void *data) break; if (reassoc_timer_req == MTRUE) { - PRINTM(MEVENT, - "Reassoc: No AP found or assoc failed. " - "Restarting re-assoc Timer: %d\n", (int) timer_val); handle->is_reassoc_timer_set = MTRUE; - woal_mod_timer(&handle->reassoc_timer, timer_val); + { + PRINTM(MEVENT, + "Reassoc: No AP found or assoc failed. " + "Restarting re-assoc Timer: %d\n", (int) timer_val); + woal_mod_timer(&handle->reassoc_timer, timer_val); + } } } woal_deactivate_thread(pmoal_thread); @@ -3083,7 +3345,7 @@ woal_moal_debug_info(moal_private * priv, moal_handle * handle, u8 flag) { moal_handle *phandle = NULL; char buf[MLAN_MAX_VER_STR_LEN]; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) int i = 0; #endif @@ -3122,7 +3384,7 @@ woal_moal_debug_info(moal_private * priv, moal_handle * handle, u8 flag) MFALSE) ? "Disconnected" : "Connected")); PRINTM(MERROR, "carrier %s\n", ((netif_carrier_ok(priv->netdev)) ? "on" : "off")); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) for (i = 0; i < (priv->netdev->num_tx_queues); i++) { PRINTM(MERROR, "tx queue %d: %s\n", i, ((netif_tx_queue_stopped @@ -3599,11 +3861,11 @@ woal_init_module(void) /* Init mutex */ MOAL_INIT_SEMAPHORE(&AddRemoveCardSem); + wifi_add_dev(); + /* Register with bus */ ret = woal_bus_register(); - wifi_add_dev(); - LEAVE(); return ret; } @@ -3645,7 +3907,8 @@ woal_cleanup_module(void) if (handle->priv[i]->media_connected == MTRUE) woal_disconnect(handle->priv[i], MOAL_CMD_WAIT, NULL); #ifdef STA_CFG80211 - if (handle->priv[i]->scan_request) { + if (IS_STA_CFG80211(cfg80211_wext) && + handle->priv[i]->scan_request) { cfg80211_scan_done(handle->priv[i]->scan_request, MTRUE); handle->priv[i]->scan_request = NULL; } @@ -3681,13 +3944,13 @@ woal_cleanup_module(void) MOAL_CMD_WAIT); } - wifi_del_dev(); - exit: MOAL_REL_SEMAPHORE(&AddRemoveCardSem); exit_sem_err: /* Unregister from bus */ woal_bus_unregister(); + wifi_del_dev(); + LEAVE(); } @@ -3749,7 +4012,7 @@ module_param(init_cfg, charp, 0); MODULE_PARM_DESC(init_cfg, "Init config file name"); module_param(cal_data_cfg, charp, 0); MODULE_PARM_DESC(cal_data_cfg, "Calibration data file name"); -module_param(minicard_pwrup, int, 0); +module_param(minicard_pwrup, int, 1); MODULE_PARM_DESC(minicard_pwrup, "1: Driver load clears PDn/Rst, unload sets (default); 0: Don't do this."); module_param(cfg80211_wext, int, 0); diff --git a/drivers/net/wireless/sd8797/mlinux/moal_main.h b/drivers/net/wireless/sd8797/mlinux/moal_main.h index cd1fdd8244c1..32426a149779 100644 --- a/drivers/net/wireless/sd8797/mlinux/moal_main.h +++ b/drivers/net/wireless/sd8797/mlinux/moal_main.h @@ -2,7 +2,7 @@ * * @brief This file contains wlan driver specific defines etc. * - * Copyright (C) 2008-2011, Marvell International Ltd. + * Copyright (C) 2008-2012, Marvell International Ltd. * * This software file (the "File") is distributed by Marvell International * Ltd. under the terms of the GNU General Public License Version 2, June 1991 @@ -49,8 +49,9 @@ Change log: #include <linux/ctype.h> #include <linux/proc_fs.h> #include <linux/vmalloc.h> -#include <linux/ptrace.h> -#include <linux/string.h> +#include <linux/ptrace.h> +#include <linux/string.h> +#include <linux/list.h> #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) #include <linux/config.h> @@ -654,6 +655,24 @@ struct debug_data_priv /** IP address operation: Remove */ #define IPADDR_OP_REMOVE 0 +struct tcp_sess +{ + struct list_head link; + /** tcp session info */ + t_u32 src_ip_addr; + t_u32 dst_ip_addr; + t_u16 src_tcp_port; + t_u16 dst_tcp_port; + /** tcp window info */ + t_u8 rx_win_opt; + t_u32 rx_win_scale; + /** warming up counter */ + t_u32 start_cnt; + /** tx ack packet info */ + t_u32 ack_seq; + t_u32 ack_cnt; +}; + /** Private structure for MOAL */ struct _moal_private { @@ -715,6 +734,18 @@ struct _moal_private t_u8 cfg_bssid[ETH_ALEN]; /** Disconnect request from CFG80211 */ bool cfg_disconnect; + /** rssi_threshold */ + s32 cqm_rssi_thold; + /** rssi hysteresis */ + u32 cqm_rssi_hyst; + /** last rssi_low */ + u8 last_rssi_low; + /** last rssi_high */ + u8 last_rssi_high; + /** mrvl rssi threshold */ + u8 mrvl_rssi_low; + /** rssi status */ + u32 rssi_status; #endif /* STA_SUPPORT */ #endif /* STA_CFG80211 */ /** IOCTL wait queue */ @@ -779,6 +810,11 @@ struct _moal_private /** MLAN debug info */ struct debug_data_priv items_priv; #endif + + /** tcp session queue */ + struct list_head tcp_sess_queue; + /** TCP Ack enhance flag */ + t_u8 enable_tcp_ack_enh; }; /** Handle data structure for MOAL */ @@ -818,6 +854,7 @@ struct _moal_handle t_u16 init_wait_q_woken; /** Init wait queue */ wait_queue_head_t init_wait_q __ATTRIB_ALIGN__; +#if defined(SDIO_SUSPEND_RESUME) /** Device suspend flag */ BOOLEAN is_suspended; #ifdef SDIO_SUSPEND_RESUME @@ -830,6 +867,7 @@ struct _moal_handle t_u16 hs_activate_wait_q_woken; /** Host Sleep activated event wait queue */ wait_queue_head_t hs_activate_wait_q __ATTRIB_ALIGN__; +#endif /** Card pointer */ t_void *card; /** Rx pending in MLAN */ @@ -844,12 +882,14 @@ struct _moal_handle t_u32 lock_count; /** mlan buffer alloc count */ t_u32 mbufalloc_count; +#if defined(SDIO_SUSPEND_RESUME) /** hs skip count */ t_u32 hs_skip_count; /** hs force count */ t_u32 hs_force_count; /** suspend_fail flag */ BOOLEAN suspend_fail; +#endif #ifdef REASSOCIATION /** Re-association thread */ moal_thread reassoc_thread; @@ -923,7 +963,7 @@ struct _moal_handle t_u8 cmd52_reg; /** cmd52 value */ t_u8 cmd52_val; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) /** spinlock to stop_queue/wake_queue*/ spinlock_t queue_lock; #endif @@ -939,7 +979,7 @@ struct _moal_handle static inline void woal_set_trans_start(struct net_device *dev) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) unsigned int i; for (i = 0; i < dev->num_tx_queues; i++) { netdev_get_tx_queue(dev, i)->trans_start = jiffies; @@ -958,7 +998,7 @@ woal_set_trans_start(struct net_device *dev) static inline void woal_start_queue(struct net_device *dev) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) netif_start_queue(dev); #else netif_tx_start_all_queues(dev); @@ -975,7 +1015,7 @@ woal_start_queue(struct net_device *dev) static inline void woal_stop_queue(struct net_device *dev) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) unsigned long flags; moal_private *priv = (moal_private *) netdev_priv(dev); spin_lock_irqsave(&priv->phandle->queue_lock, flags); @@ -1000,7 +1040,7 @@ woal_stop_queue(struct net_device *dev) static inline void woal_wake_queue(struct net_device *dev) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) unsigned long flags; moal_private *priv = (moal_private *) netdev_priv(dev); spin_lock_irqsave(&priv->phandle->queue_lock, flags); @@ -1217,6 +1257,8 @@ typedef struct _HostCmd_DS_802_11_CFG_DATA #define WEXT_BGSCAN_RSSI_SECTION 'R' /** BGSCAN SCAN INTERVAL SECTION */ #define WEXT_BGSCAN_INTERVAL_SECTION 'T' +/** BGSCAN REPEAT SECTION */ +#define WEXT_BGSCAN_REPEAT_SECTION 'E' /** band AUTO */ #define WIFI_FREQUENCY_BAND_AUTO 0 @@ -1316,11 +1358,15 @@ mlan_status woal_set_get_hs_params(moal_private * priv, t_u16 action, t_u8 wait_option, mlan_ds_hs_cfg * hscfg); /** Cancel Host Sleep configuration */ mlan_status woal_cancel_hs(moal_private * priv, t_u8 wait_option); +#if defined(SDIO_SUSPEND_RESUME) /** Enable Host Sleep configuration */ int woal_enable_hs(moal_private * priv); /** hs active timeout 2 second */ #define HS_ACTIVE_TIMEOUT (2 * HZ) +#endif +/** get deep sleep */ +int woal_get_deep_sleep(moal_private * priv, t_u32 * data); /** set deep sleep */ int woal_set_deep_sleep(moal_private * priv, t_u8 wait_option, BOOLEAN bdeep_sleep, t_u16 idletime); @@ -1431,6 +1477,8 @@ int woal_host_command(moal_private * priv, struct iwreq *wrq); #if defined(WIFI_DIRECT_SUPPORT) #if defined(STA_SUPPORT) && defined(UAP_SUPPORT) #if defined(STA_WEXT) || defined(UAP_WEXT) +mlan_status woal_bss_role_cfg(moal_private * priv, t_u8 action, + t_u8 wait_option, t_u8 * bss_role); int woal_set_get_bss_role(moal_private * priv, struct iwreq *wrq); #endif #endif @@ -1443,8 +1491,8 @@ int woal_hostcmd_ioctl(struct net_device *dev, struct ifreq *req); #if defined(WIFI_DIRECT_SUPPORT) mlan_status woal_set_remain_channel_ioctl(moal_private * priv, t_u8 wait_option, mlan_ds_remain_chan * pchan); -mlan_status woal_cfg80211_wifi_direct_mode_cfg(moal_private * priv, - t_u16 action, t_u16 * mode); +mlan_status woal_wifi_direct_mode_cfg(moal_private * priv, t_u16 action, + t_u16 * mode); #endif /* WIFI_DIRECT_SUPPORT */ #ifdef CONFIG_PROC_FS @@ -1502,9 +1550,15 @@ mlan_status woal_remove_rxfilter(moal_private * priv, char *rxfilter); mlan_status woal_set_qos_cfg(moal_private * priv, char *qos_cfg); int woal_set_sleeppd(moal_private * priv, char *psleeppd); mlan_status woal_set_rssi_low_threshold(moal_private * priv, char *rssi); +mlan_status woal_set_rssi_threshold(moal_private * priv, t_u32 event_id); mlan_status woal_set_bg_scan(moal_private * priv, char *buf, int length); mlan_status woal_stop_bg_scan(moal_private * priv); void woal_reconfig_bgscan(moal_handle * handle); #endif +struct tcp_sess *woal_get_tcp_sess(moal_private * priv, + t_u32 src_ip, t_u16 src_port, + t_u32 dst_ip, t_u16 dst_port); +void woal_check_tcp_fin(moal_private * priv, struct sk_buff *skb); + #endif /* _MOAL_MAIN_H */ diff --git a/drivers/net/wireless/sd8797/mlinux/moal_priv.c b/drivers/net/wireless/sd8797/mlinux/moal_priv.c index e3e4b844e11b..9a5173ddfb3f 100644 --- a/drivers/net/wireless/sd8797/mlinux/moal_priv.c +++ b/drivers/net/wireless/sd8797/mlinux/moal_priv.c @@ -101,6 +101,13 @@ woal_warm_reset(moal_private * priv) moal_handle *handle = priv->phandle; mlan_ioctl_req *req = NULL; mlan_ds_misc_cfg *misc = NULL; +#if defined(WIFI_DIRECT_SUPPORT) +#if defined(STA_SUPPORT) && defined(UAP_SUPPORT) +#if defined(STA_WEXT) || defined(UAP_WEXT) + t_u8 bss_role = MLAN_BSS_ROLE_STA; +#endif +#endif +#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */ ENTER(); @@ -110,8 +117,24 @@ woal_warm_reset(moal_private * priv) ret = woal_reset_intf(priv, MOAL_IOCTL_WAIT, MTRUE); /* Initialize private structures */ - for (intf_num = 0; intf_num < handle->priv_num; intf_num++) + for (intf_num = 0; intf_num < handle->priv_num; intf_num++) { woal_init_priv(handle->priv[intf_num], MOAL_IOCTL_WAIT); +#if defined(WIFI_DIRECT_SUPPORT) +#if defined(STA_SUPPORT) && defined(UAP_SUPPORT) +#if defined(STA_WEXT) || defined(UAP_WEXT) + if (handle->priv[intf_num]->bss_type == MLAN_BSS_TYPE_WIFIDIRECT) { + if (MLAN_STATUS_SUCCESS != woal_bss_role_cfg(handle->priv[intf_num], + MLAN_ACT_SET, + MOAL_IOCTL_WAIT, + &bss_role)) { + ret = -EFAULT; + goto done; + } + } +#endif /* STA_WEXT || UAP_WEXT */ +#endif /* STA_SUPPORT && UAP_SUPPORT */ +#endif /* WIFI_DIRECT_SUPPORT && V14_FEATURE */ + } /* Restart the firmware */ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); @@ -334,48 +357,6 @@ woal_get_signal(moal_private * priv, struct iwreq *wrq) } /** - * @brief Get Deep Sleep - * - * @param priv Pointer to the moal_private driver data struct - * @param deep_sleep Pointer to return deep_sleep setting - * - * @return 0 --success, otherwise fail - */ -static int -woal_get_deep_sleep(moal_private * priv, t_u32 * data) -{ - int ret = 0; - mlan_ioctl_req *req = NULL; - mlan_ds_pm_cfg *pm = NULL; - - ENTER(); - - req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg)); - if (req == NULL) { - LEAVE(); - return -ENOMEM; - } - pm = (mlan_ds_pm_cfg *) req->pbuf; - pm->sub_command = MLAN_OID_PM_CFG_DEEP_SLEEP; - req->req_id = MLAN_IOCTL_PM_CFG; - - req->action = MLAN_ACT_GET; - if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) { - ret = -EFAULT; - goto done; - } - *data = pm->param.auto_deep_sleep.auto_ds; - *(data + 1) = pm->param.auto_deep_sleep.idletime; - - done: - if (req) - kfree(req); - - LEAVE(); - return ret; -} - -/** * @brief Get/Set DeepSleep mode * * @param priv Pointer to the moal_private driver data struct @@ -3692,7 +3673,6 @@ static int woal_set_get_ip_addr(moal_private * priv, struct iwreq *wrq) { char buf[IPADDR_MAX_BUF]; - struct iwreq *wreq = (struct iwreq *) wrq; mlan_ioctl_req *ioctl_req = NULL; mlan_ds_misc_cfg *misc = NULL; int ret = 0, op_code = 0, data_length = wrq->u.data.length; @@ -3710,8 +3690,8 @@ woal_set_get_ip_addr(moal_private * priv, struct iwreq *wrq) if (data_length <= 1) { /* GET */ ioctl_req->action = MLAN_ACT_GET; } else { - if (copy_from_user(buf, wreq->u.data.pointer, - MIN(IPADDR_MAX_BUF - 1, wreq->u.data.length))) { + if (copy_from_user(buf, wrq->u.data.pointer, + MIN(IPADDR_MAX_BUF - 1, wrq->u.data.length))) { PRINTM(MERROR, "Copy from user failed\n"); ret = -EFAULT; goto done; @@ -3727,7 +3707,7 @@ woal_set_get_ip_addr(moal_private * priv, struct iwreq *wrq) ioctl_req->action = MLAN_ACT_SET; /* only one IP is supported in current firmware */ memset(misc->param.ipaddr_cfg.ip_addr[0], 0, IPADDR_LEN); - in4_pton(&buf[2], MIN((IPADDR_MAX_BUF - 3), (wreq->u.data.length - 2)), + in4_pton(&buf[2], MIN((IPADDR_MAX_BUF - 3), (wrq->u.data.length - 2)), misc->param.ipaddr_cfg.ip_addr[0], ' ', NULL); /* only one IP is supported in current firmware */ misc->param.ipaddr_cfg.ip_addr_num = 1; @@ -4525,6 +4505,34 @@ woal_get_scan_table_ioctl(moal_private * priv, struct iwreq *wrq) } /** + * @brief Set user scan ext -- Async mode, without wait + * + * @param priv A pointer to moal_private structure + * @param wrq A pointer to iwreq structure + * + * @return 0 -- success, otherwise fail + */ +static int +woal_set_user_scan_ext_ioctl(moal_private * priv, struct iwreq *wrq) +{ + int ret = 0; + wlan_user_scan_cfg scan_req; + ENTER(); + memset(&scan_req, 0x00, sizeof(scan_req)); + if (copy_from_user + (&scan_req, wrq->u.data.pointer, + MIN(wrq->u.data.length, sizeof(scan_req)))) { + PRINTM(MINFO, "Copy from user failed\n"); + LEAVE(); + return -EFAULT; + } + if (MLAN_STATUS_FAILURE == woal_do_scan(priv, &scan_req)) + ret = -EFAULT; + LEAVE(); + return ret; +} + +/** * @brief Set user scan * * @param priv A pointer to moal_private structure @@ -5912,6 +5920,86 @@ woal_mgmt_frame_passthru_ctrl(moal_private * priv, struct iwreq *wrq) } /** + * @brief Set/Get CFP table codes + * + * @param priv Pointer to the moal_private driver data struct + * @param wrq A pointer to iwreq structure + * + * @return 0 --success, otherwise fail + */ +static int +woal_cfp_code(moal_private * priv, struct iwreq *wrq) +{ + int ret = 0; + int data[2]; + int data_length = wrq->u.data.length; + mlan_ioctl_req *req = NULL; + mlan_ds_misc_cfg *misc_cfg = NULL; + mlan_ds_misc_cfp_code *cfp_code = NULL; + + ENTER(); + + if (data_length > 2) { + PRINTM(MERROR, "Invalid number of argument!\n"); + ret = -EINVAL; + goto done; + } + + /* Allocate an IOCTL request buffer */ + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); + if (req == NULL) { + ret = -ENOMEM; + goto done; + } + + /* Fill request buffer */ + misc_cfg = (mlan_ds_misc_cfg *) req->pbuf; + cfp_code = &misc_cfg->param.cfp_code; + misc_cfg->sub_command = MLAN_OID_MISC_CFP_CODE; + req->req_id = MLAN_IOCTL_MISC_CFG; + + if (!data_length) { + req->action = MLAN_ACT_GET; + } else { + if (copy_from_user + (data, wrq->u.data.pointer, sizeof(int) * data_length)) { + PRINTM(MERROR, "Copy from user failed\n"); + ret = -EFAULT; + goto done; + } + cfp_code->cfp_code_bg = data[0]; + if (data_length == 2) + cfp_code->cfp_code_a = data[1]; + req->action = MLAN_ACT_SET; + } + + /* Send IOCTL request to MLAN */ + if (woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT) != MLAN_STATUS_SUCCESS) { + ret = -EFAULT; + goto done; + } + + if (!data_length) { + data[0] = cfp_code->cfp_code_bg; + data[1] = cfp_code->cfp_code_a; + data_length = 2; + if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int) * data_length)) { + PRINTM(MERROR, "Copy to user failed\n"); + ret = -EFAULT; + goto done; + } + wrq->u.data.length = data_length; + } + + done: + if (req) + kfree(req); + + LEAVE(); + return ret; +} + +/** * @brief Set/Get Tx/Rx antenna * * @param priv A pointer to moal_private structure @@ -6183,6 +6271,9 @@ woal_wext_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) case WOAL_MGMT_FRAME_CTRL: ret = woal_mgmt_frame_passthru_ctrl(priv, wrq); break; + case WOAL_CFP_CODE: + ret = woal_cfp_code(priv, wrq); + break; case WOAL_SET_GET_TX_RX_ANT: ret = woal_set_get_tx_rx_ant(priv, wrq); break; @@ -6296,6 +6387,9 @@ woal_wext_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) case WOAL_GET_SCAN_TABLE: ret = woal_get_scan_table_ioctl(priv, wrq); break; + case WOAL_SET_USER_SCAN_EXT: + ret = woal_set_user_scan_ext_ioctl(priv, wrq); + break; case WOAL_WMM_ADDTS: ret = woal_wmm_addts_req_ioctl(priv, wrq); break; diff --git a/drivers/net/wireless/sd8797/mlinux/moal_priv.h b/drivers/net/wireless/sd8797/mlinux/moal_priv.h index de491f6d6a29..1c24f30502f6 100644 --- a/drivers/net/wireless/sd8797/mlinux/moal_priv.h +++ b/drivers/net/wireless/sd8797/mlinux/moal_priv.h @@ -115,6 +115,8 @@ Change log: /** Private command ID to set/get dfs testing settings */ #define WOAL_DFS_TESTING 33 #endif +/** Private command ID to set/get CFP table codes */ +#define WOAL_CFP_CODE 34 /** Private command ID to set/get tx/rx antenna */ #define WOAL_SET_GET_TX_RX_ANT 35 /** Private command ID to set/get management frame passthru mask */ @@ -226,6 +228,8 @@ Change log: #define WOAL_SET_USER_SCAN 3 /** Private command ID for getscantable */ #define WOAL_GET_SCAN_TABLE 4 +/** Private command ID for setuserscanext: async without wait */ +#define WOAL_SET_USER_SCAN_EXT 5 /** Private command ID to request ADDTS */ #define WOAL_WMM_ADDTS 7 @@ -526,6 +530,11 @@ static const struct iw_priv_args woal_private_args[] = { IW_PRIV_TYPE_INT | 16, "mgmtframectrl"}, { + WOAL_CFP_CODE, + IW_PRIV_TYPE_INT | 16, + IW_PRIV_TYPE_INT | 16, + "cfpcode"}, + { WOAL_SET_GET_TX_RX_ANT, IW_PRIV_TYPE_INT | 16, IW_PRIV_TYPE_INT | 16, @@ -656,6 +665,11 @@ static const struct iw_priv_args woal_private_args[] = { IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES, "getscantable"}, { + WOAL_SET_USER_SCAN_EXT, + IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES, + IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES, + "setuserscanext"}, + { WOAL_WMM_ADDTS, IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES, IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES, diff --git a/drivers/net/wireless/sd8797/mlinux/moal_proc.c b/drivers/net/wireless/sd8797/mlinux/moal_proc.c index e98803c2e3fb..fb7c63a29cab 100644 --- a/drivers/net/wireless/sd8797/mlinux/moal_proc.c +++ b/drivers/net/wireless/sd8797/mlinux/moal_proc.c @@ -95,9 +95,9 @@ woal_info_proc_read(char *page, char **start, off_t offset, int mc_count = netdev_mc_count(netdev); #endif /* < 2.6.35 */ #else -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) int i = 0; -#endif /* >= 2.6.34 */ +#endif /* >= 2.6.29 */ #endif #ifdef UAP_SUPPORT mlan_ds_uap_stats ustats; @@ -199,7 +199,7 @@ woal_info_proc_read(char *page, char **start, off_t offset, p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors); p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev)) ? "on" : "off")); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) for (i = 0; i < netdev->num_tx_queues; i++) { p += sprintf(p, "tx queue %d: %s\n", i, ((netif_tx_queue_stopped(netdev_get_tx_queue(netdev, 0))) ? diff --git a/drivers/net/wireless/sd8797/mlinux/moal_sdio_mmc.c b/drivers/net/wireless/sd8797/mlinux/moal_sdio_mmc.c index 96e3e971936f..f09f33e6435d 100644 --- a/drivers/net/wireless/sd8797/mlinux/moal_sdio_mmc.c +++ b/drivers/net/wireless/sd8797/mlinux/moal_sdio_mmc.c @@ -315,6 +315,12 @@ woal_sdio_suspend(struct device *dev) } handle = cardp->handle; + if (handle->is_suspended == MTRUE) { + PRINTM(MWARN, "Device already suspended\n"); + LEAVE(); + return MLAN_STATUS_SUCCESS; + } + handle->suspend_fail = MFALSE; memset(&pm_info, 0, sizeof(pm_info)); if (MLAN_STATUS_SUCCESS == diff --git a/drivers/net/wireless/sd8797/mlinux/moal_shim.c b/drivers/net/wireless/sd8797/mlinux/moal_shim.c index e33a6e38067a..25cfdc549f3d 100644 --- a/drivers/net/wireless/sd8797/mlinux/moal_shim.c +++ b/drivers/net/wireless/sd8797/mlinux/moal_shim.c @@ -745,6 +745,11 @@ moal_recv_packet(IN t_void * pmoal_handle, IN pmlan_buffer pmbuf) skb->dev = priv->netdev; skb->protocol = eth_type_trans(skb, priv->netdev); skb->ip_summed = CHECKSUM_NONE; + + if (priv->enable_tcp_ack_enh == MTRUE) { + woal_check_tcp_fin(priv, skb); + } + priv->stats.rx_bytes += skb->len; priv->stats.rx_packets++; if (in_interrupt()) @@ -950,6 +955,13 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent) #endif } #endif /* STA_WEXT */ +#ifdef STA_CFG80211 + if (IS_STA_CFG80211(cfg80211_wext)) { + cfg80211_michael_mic_failure(priv->netdev, priv->cfg_bssid, + NL80211_KEYTYPE_PAIRWISE, -1, NULL, + GFP_KERNEL); + } +#endif break; case MLAN_EVENT_ID_FW_MIC_ERR_MUL: #ifdef STA_WEXT @@ -961,18 +973,48 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent) #endif } #endif /* STA_WEXT */ +#ifdef STA_CFG80211 + if (IS_STA_CFG80211(cfg80211_wext)) { + cfg80211_michael_mic_failure(priv->netdev, priv->cfg_bssid, + NL80211_KEYTYPE_GROUP, -1, NULL, + GFP_KERNEL); + } +#endif break; case MLAN_EVENT_ID_FW_BCN_RSSI_LOW: #ifdef STA_WEXT if (IS_STA_WEXT(cfg80211_wext)) woal_send_iwevcustom_event(priv, CUS_EVT_BEACON_RSSI_LOW); #endif +#ifdef STA_CFG80211 + if (IS_STA_CFG80211(cfg80211_wext)) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) || defined(COMPAT_WIRELESS) + cfg80211_cqm_rssi_notify(priv->netdev, + NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, + GFP_KERNEL); + priv->rssi_status = MLAN_EVENT_ID_FW_BCN_RSSI_LOW; +#endif + woal_set_rssi_threshold(priv, MLAN_EVENT_ID_FW_BCN_RSSI_LOW); + } +#endif break; case MLAN_EVENT_ID_FW_BCN_RSSI_HIGH: #ifdef STA_WEXT if (IS_STA_WEXT(cfg80211_wext)) woal_send_iwevcustom_event(priv, CUS_EVT_BEACON_RSSI_HIGH); #endif +#ifdef STA_CFG80211 + if (IS_STA_CFG80211(cfg80211_wext)) { + if (!priv->mrvl_rssi_low) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) || defined(COMPAT_WIRELESS) + cfg80211_cqm_rssi_notify(priv->netdev, + NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, + GFP_KERNEL); +#endif + woal_set_rssi_threshold(priv, MLAN_EVENT_ID_FW_BCN_RSSI_HIGH); + } + } +#endif break; case MLAN_EVENT_ID_FW_BCN_SNR_LOW: #ifdef STA_WEXT @@ -1033,6 +1075,22 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent) if (IS_STA_WEXT(cfg80211_wext)) woal_send_iwevcustom_event(priv, CUS_EVT_PRE_BEACON_LOST); #endif +#ifdef STA_CFG80211 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) || defined(COMPAT_WIRELESS) + if (IS_STA_CFG80211(cfg80211_wext)) { + struct cfg80211_bss *bss = NULL; + bss = + cfg80211_get_bss(priv->wdev->wiphy, NULL, priv->cfg_bssid, NULL, + 0, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); + if (bss) + cfg80211_unlink_bss(priv->wdev->wiphy, bss); + cfg80211_cqm_rssi_notify(priv->netdev, + NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, + GFP_KERNEL); + priv->rssi_status = MLAN_EVENT_ID_FW_PRE_BCN_LOST; + } +#endif +#endif break; case MLAN_EVENT_ID_FW_WMM_CONFIG_CHANGE: #ifdef STA_WEXT @@ -1069,11 +1127,22 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent) priv->bg_scan_reported = MTRUE; #ifdef STA_WEXT if (IS_STA_WEXT(cfg80211_wext)) { - woal_send_iwevcustom_event(priv, CUS_EVT_BG_SCAN); memset(&wrqu, 0, sizeof(union iwreq_data)); wireless_send_event(priv->netdev, SIOCGIWSCAN, &wrqu, NULL); } #endif +#ifdef STA_CFG80211 + if (IS_STA_CFG80211(cfg80211_wext)) { + woal_inform_bss_from_scan_result(priv, NULL); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) || defined(COMPAT_WIRELESS) + if (priv->mrvl_rssi_low) { + cfg80211_cqm_rssi_notify(priv->netdev, + NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, + GFP_KERNEL); + } +#endif + } +#endif break; case MLAN_EVENT_ID_FW_CHANNEL_SWITCH_ANN: #ifdef STA_WEXT @@ -1285,10 +1354,15 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent) #endif /* UAP_WEXT */ break; case MLAN_EVENT_ID_DRV_MGMT_FRAME: +#ifdef UAP_WEXT + if (IS_UAP_WEXT(cfg80211_wext)) { + woal_broadcast_event(priv, pmevent->event_buf, pmevent->event_len); + } +#endif /* UAP_WEXT */ #ifdef WIFI_DIRECT_SUPPORT #if defined(STA_CFG80211) || defined(UAP_CFG80211) if (IS_STA_OR_UAP_CFG80211(cfg80211_wext)) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) || defined(COMPAT_WIRELESS) +#if LINUX_VERSION_CODE >= WIFI_DIRECT_KERNEL_VERSION if (priv->netdev && priv->netdev->ieee80211_ptr->wiphy->mgmt_stypes) { /* frmctl + durationid + addr1 + addr2 + addr3 + seqctl */ #define PACKET_ADDR4_POS (2 + 2 + 6 + 6 + 6 + 2) @@ -1310,11 +1384,6 @@ moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent) } #endif /* STA_CFG80211 || UAP_CFG80211 */ #endif /* WIFI_DIRECT_SUPPORT */ -#ifdef UAP_WEXT - if (IS_UAP_WEXT(cfg80211_wext)) { - woal_broadcast_event(priv, pmevent->event_buf, pmevent->event_len); - } -#endif /* UAP_WEXT */ break; #endif /* UAP_SUPPORT */ case MLAN_EVENT_ID_DRV_PASSTHRU: diff --git a/drivers/net/wireless/sd8797/mlinux/moal_sta_cfg80211.c b/drivers/net/wireless/sd8797/mlinux/moal_sta_cfg80211.c index d6768a3bd647..ed44cdefe43b 100644 --- a/drivers/net/wireless/sd8797/mlinux/moal_sta_cfg80211.c +++ b/drivers/net/wireless/sd8797/mlinux/moal_sta_cfg80211.c @@ -44,6 +44,11 @@ static int woal_cfg80211_dump_station(struct wiphy *wiphy, static int woal_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) || defined(COMPAT_WIRELESS) +static int woal_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy, + struct net_device *dev, + s32 rssi_thold, u32 rssi_hyst); +#endif static int woal_cfg80211_set_tx_power(struct wiphy *wiphy, #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) && !defined(COMPAT_WIRELESS) @@ -98,6 +103,9 @@ static struct cfg80211_ops woal_cfg80211_sta_ops = { .set_default_key = woal_cfg80211_set_default_key, .set_power_mgmt = woal_cfg80211_set_power_mgmt, .set_tx_power = woal_cfg80211_set_tx_power, +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) || defined(COMPAT_WIRELESS) + .set_cqm_rssi_config = woal_cfg80211_set_cqm_rssi_config, +#endif }; #if defined(WIFI_DIRECT_SUPPORT) @@ -518,14 +526,13 @@ woal_cfg80211_assoc_ies_cfg(moal_private * priv, t_u8 * ie, int ie_len) /** * @brief Send domain info command to FW * - * @param wiphy A pointer to wiphy structure + * @param priv A pointer to moal_private structure * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ static mlan_status -woal_send_domain_info_cmd_fw(struct wiphy *wiphy) +woal_send_domain_info_cmd_fw(moal_private * priv) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); mlan_status ret = MLAN_STATUS_SUCCESS; enum ieee80211_band band; struct ieee80211_supported_band *sband = NULL; @@ -540,6 +547,12 @@ woal_send_domain_info_cmd_fw(struct wiphy *wiphy) ENTER(); + if (!priv->wdev || !priv->wdev->wiphy) { + PRINTM(MERROR, "No wdev or wiphy in priv\n"); + ret = MLAN_STATUS_FAILURE; + goto done; + } + /* Allocate an IOCTL request buffer */ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_radio_cfg)); if (req == NULL) { @@ -556,7 +569,7 @@ woal_send_domain_info_cmd_fw(struct wiphy *wiphy) goto done; } band = woal_band_cfg_to_ieee_band(radio_cfg->param.band_cfg.config_bands); - if (!wiphy->bands[band]) { + if (!priv->wdev->wiphy->bands[band]) { PRINTM(MERROR, "11D: setting domain info in FW failed"); ret = MLAN_STATUS_FAILURE; goto done; @@ -580,7 +593,7 @@ woal_send_domain_info_cmd_fw(struct wiphy *wiphy) cfg_11d->param.domain_info.country_code[2] = ' '; cfg_11d->param.domain_info.band = band; - sband = wiphy->bands[band]; + sband = priv->wdev->wiphy->bands[band]; for (i = 0; (i < sband->n_channels) && (no_of_sub_band < MRVDRV_MAX_SUBBAND_802_11D); i++) { channel = &sband->channels[i]; @@ -641,18 +654,17 @@ woal_send_domain_info_cmd_fw(struct wiphy *wiphy) * @brief Request the driver to change the channel and * change domain info according to that channel * - * @param wiphy A pointer to wiphy structure + * @param priv A pointer to moal_private structure * @param chan A pointer to ieee80211_channel structure * @param channel_type Channel type of nl80211_channel_type * * @return 0 -- success, otherwise fail */ int -woal_set_rf_channel(struct wiphy *wiphy, +woal_set_rf_channel(moal_private * priv, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); int ret = 0; t_u32 mode, config_bands = 0; mlan_ioctl_req *req1 = NULL, *req2 = NULL; @@ -692,7 +704,7 @@ woal_set_rf_channel(struct wiphy *wiphy, ret = -EFAULT; goto done; } - woal_send_domain_info_cmd_fw(wiphy); + woal_send_domain_info_cmd_fw(priv); } PRINTM(MINFO, "Setting band %d, channel bandwidth %d and mode = %d\n", @@ -864,17 +876,15 @@ woal_inform_bss_from_scan_result(moal_private * priv, mlan_802_11_ssid * ssid) struct ieee80211_channel *chan; mlan_scan_resp scan_resp; BSSDescriptor_t *scan_table; - t_u8 *ie, *tmp, *ie_buf; - __le32 ie_len; t_u64 ts = 0; - t_u8 *cap; - t_u8 *beacon; - int beacon_size, i, j; - IEEEtypes_ElementId_e element_id; - t_u8 element_len; + u16 cap_info = 0; + int i = 0; struct cfg80211_bss *pub = NULL; - ENTER(); + if (!priv->wdev || !priv->wdev->wiphy) { + LEAVE(); + return MLAN_STATUS_FAILURE; + } memset(&scan_resp, 0, sizeof(scan_resp)); if (MLAN_STATUS_SUCCESS != woal_get_scan_table(priv, @@ -885,14 +895,6 @@ woal_inform_bss_from_scan_result(moal_private * priv, mlan_802_11_ssid * ssid) } if (scan_resp.num_in_scan_table) { -#define MAX_IE_BUF 2048 - ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL); - if (ie_buf == NULL) { - PRINTM(MERROR, "%s: failed to allocate ie_buf\n", __func__); - ret = MLAN_STATUS_FAILURE; - goto done; - } - scan_table = (BSSDescriptor_t *) scan_resp.pscan_table; for (i = 0; i < scan_resp.num_in_scan_table; i++) { if (ssid) { @@ -905,105 +907,31 @@ woal_inform_bss_from_scan_result(moal_private * priv, mlan_802_11_ssid * ssid) (int) scan_table[i].channel); continue; } - memset(ie_buf, 0, MAX_IE_BUF); - ie_buf[0] = WLAN_EID_SSID; - ie_buf[1] = scan_table[i].ssid.ssid_len; - memcpy(&ie_buf[sizeof(IEEEtypes_Header_t)], - scan_table[i].ssid.ssid, ie_buf[1]); - - ie = ie_buf + ie_buf[1] + sizeof(IEEEtypes_Header_t); - ie_len = ie_buf[1] + sizeof(IEEEtypes_Header_t); - - ie[0] = WLAN_EID_SUPP_RATES; - - for (j = 0; j < sizeof(scan_table[i].supported_rates); j++) { - if (!scan_table[i].supported_rates[j]) - break; - else { - ie[j + sizeof(IEEEtypes_Header_t)] = - scan_table[i].supported_rates[j]; - } - } - - ie[1] = j; - ie_len += ie[1] + sizeof(IEEEtypes_Header_t); - - beacon = scan_table[i].pbeacon_buf; - beacon_size = scan_table[i].beacon_buf_size; - - /* Skip time stamp, beacon interval and capability */ - - if (beacon) { - beacon += sizeof(scan_table[i].beacon_period) - + sizeof(scan_table[i].time_stamp) + - +sizeof(scan_table[i].cap_info); - - beacon_size -= sizeof(scan_table[i].beacon_period) - + sizeof(scan_table[i].time_stamp) - + sizeof(scan_table[i].cap_info); - } - - while (beacon_size >= sizeof(IEEEtypes_Header_t)) { - ie = ie_buf + ie_len; - element_id = *beacon; - element_len = *(beacon + 1); - if (beacon_size < (int) element_len + - sizeof(IEEEtypes_Header_t)) { - PRINTM(MERROR, - "Get scan: Error in processing IE, " - "bytes left < IE length\n"); - break; - } - switch (element_id) { - case WLAN_EID_FH_PARAMS: - case WLAN_EID_DS_PARAMS: - case WLAN_EID_CF_PARAMS: - case WLAN_EID_IBSS_PARAMS: - case WLAN_EID_COUNTRY: - case WLAN_EID_PWR_CONSTRAINT: - case WLAN_EID_PWR_CAPABILITY: - case WLAN_EID_TPC_REQUEST: - case WLAN_EID_TPC_REPORT: - case WLAN_EID_CHANNEL_SWITCH: - case WLAN_EID_QUIET: - case WLAN_EID_IBSS_DFS: - case WLAN_EID_SUPPORTED_CHANNELS: - case WLAN_EID_ERP_INFO: - case WLAN_EID_EXT_SUPP_RATES: - case WLAN_EID_HT_CAPABILITY: - case WLAN_EID_HT_INFORMATION: - case EXT_CAPABILITY: // TODO: Replace when kernel macro - // available - case WLAN_EID_RSN: - case WAPI_IE: // TODO: Replace when kernel macro available - case WLAN_EID_VENDOR_SPECIFIC: - ie[0] = element_id; - ie[1] = element_len; - tmp = (t_u8 *) beacon; - memcpy(&ie[sizeof(IEEEtypes_Header_t)], - tmp + sizeof(IEEEtypes_Header_t), element_len); - ie_len += ie[1] + sizeof(IEEEtypes_Header_t); - break; - default: - break; - } - beacon += element_len + sizeof(IEEEtypes_Header_t); - beacon_size -= (element_len + sizeof(IEEEtypes_Header_t)); - } chan = ieee80211_get_channel(priv->wdev->wiphy, scan_table[i].freq); - cap = (t_u8 *) & scan_table[i].cap_info; + if (!chan) { + PRINTM(MERROR, + "Fail to get chan with freq: channel=%d freq=%d\n", + (int) scan_table[i].channel, (int) scan_table[i].freq); + continue; + } + memcpy(&ts, scan_table[i].time_stamp, sizeof(ts)); + memcpy(&cap_info, &scan_table[i].cap_info, sizeof(cap_info)); pub = cfg80211_inform_bss(priv->wdev->wiphy, chan, scan_table[i].mac_address, - ts, (__le16) (*cap), - scan_table[i].beacon_period, ie_buf, - ie_len, + ts, cap_info, + scan_table[i].beacon_period, + scan_table[i].pbeacon_buf + + WLAN_802_11_FIXED_IE_SIZE, + scan_table[i].beacon_buf_size - + WLAN_802_11_FIXED_IE_SIZE, -RSSI_DBM_TO_MDM(scan_table[i].rssi), GFP_KERNEL); - pub->len_information_elements = pub->len_beacon_ies; + if (pub) { + pub->len_information_elements = pub->len_beacon_ies; + cfg80211_put_bss(pub); + } } - kfree(ie_buf); } - done: LEAVE(); return ret; @@ -1044,6 +972,7 @@ woal_cfg80211_inform_ibss_bss(moal_private * priv, mlan_ds_get_signal signal; t_u8 ie_buf[MLAN_MAX_SSID_LENGTH + sizeof(IEEEtypes_Header_t)]; int ie_len = 0; + struct cfg80211_bss *bss = NULL; ENTER(); @@ -1068,11 +997,12 @@ woal_cfg80211_inform_ibss_bss(moal_private * priv, goto done; } - cfg80211_inform_bss(priv->wdev->wiphy, chan, - bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, - beacon_interval, ie_buf, ie_len, signal.bcn_rssi_avg, - GFP_KERNEL); - + bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, + bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, + beacon_interval, ie_buf, ie_len, + signal.bcn_rssi_avg, GFP_KERNEL); + if (bss) + cfg80211_put_bss(bss); done: LEAVE(); return ret; @@ -1081,15 +1011,14 @@ woal_cfg80211_inform_ibss_bss(moal_private * priv, /** * @brief Request the driver for (re)association * - * @param wiphy A pointer to wiphy structure + * @param priv A pointer to moal_private structure * @param sme A pointer to connect parameters * * @return 0 -- success, otherwise fail */ static int -woal_cfg80211_assoc(struct wiphy *wiphy, void *sme) +woal_cfg80211_assoc(moal_private * priv, void *sme) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); struct cfg80211_ibss_params *ibss_param = NULL; struct cfg80211_connect_params *conn_param = NULL; mlan_802_11_ssid req_ssid; @@ -1170,7 +1099,7 @@ woal_cfg80211_assoc(struct wiphy *wiphy, void *sme) ret = -EFAULT; goto done; } - if (MLAN_STATUS_SUCCESS != woal_set_rf_channel(wiphy, + if (MLAN_STATUS_SUCCESS != woal_set_rf_channel(priv, channel, woal_channel_to_nl80211_channel_type (radio_cfg->param. @@ -1188,8 +1117,9 @@ woal_cfg80211_assoc(struct wiphy *wiphy, void *sme) } if (MLAN_STATUS_SUCCESS != - woal_cfg80211_set_key(priv, 0, 0, NULL, 0, NULL, 0, 0, NULL, 1)) { - /* Disable keys */ + woal_cfg80211_set_key(priv, 0, 0, NULL, 0, NULL, 0, + KEY_INDEX_CLEAR_ALL, NULL, 1)) { + /* Disable keys and clear all previous security settings */ ret = -EFAULT; goto done; } @@ -1386,6 +1316,58 @@ woal_cfg80211_assoc(struct wiphy *wiphy, void *sme) return ret; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) || defined(COMPAT_WIRELESS) +/** + * @brief Set/Get DTIM period + * + * @param priv A pointer to moal_private structure + * @param action Action set or get + * @param wait_option Wait option + * @param value DTIM period + * + * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING -- success, otherwise fail + */ +static mlan_status +woal_set_get_dtim_period(moal_private * priv, + t_u32 action, t_u8 wait_option, t_u8 * value) +{ + mlan_ioctl_req *req = NULL; + mlan_ds_snmp_mib *mib = NULL; + mlan_status ret = MLAN_STATUS_SUCCESS; + + ENTER(); + + /* Allocate an IOCTL request buffer */ + req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_snmp_mib)); + if (req == NULL) { + ret = MLAN_STATUS_FAILURE; + goto done; + } + + /* Fill request buffer */ + mib = (mlan_ds_snmp_mib *) req->pbuf; + mib->sub_command = MLAN_OID_SNMP_MIB_DTIM_PERIOD; + req->req_id = MLAN_IOCTL_SNMP_MIB; + req->action = action; + + if (action == MLAN_ACT_SET) { + mib->param.dtim_period = *value; + } + + /* Send IOCTL request to MLAN */ + ret = woal_request_ioctl(priv, req, wait_option); + if (ret == MLAN_STATUS_SUCCESS && action == MLAN_ACT_GET) { + *value = (t_u8) mib->param.dtim_period; + } + + done: + if (req && (ret != MLAN_STATUS_PENDING)) + kfree(req); + LEAVE(); + return ret; +} +#endif + /** * @brief Request the driver to dump the station information * @@ -1397,10 +1379,14 @@ woal_cfg80211_assoc(struct wiphy *wiphy, void *sme) static mlan_status woal_cfg80211_dump_station_info(moal_private * priv, struct station_info *sinfo) { + mlan_status ret = MLAN_STATUS_SUCCESS; mlan_ds_get_signal signal; mlan_ioctl_req *req = NULL; mlan_ds_rate *rate = NULL; - mlan_status ret = MLAN_STATUS_SUCCESS; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) || defined(COMPAT_WIRELESS) + mlan_bss_info bss_info; + t_u8 dtim_period = 0; +#endif ENTER(); sinfo->filled = STATION_INFO_RX_BYTES | STATION_INFO_TX_BYTES | @@ -1443,6 +1429,28 @@ woal_cfg80211_dump_station_info(moal_private * priv, struct station_info *sinfo) sinfo->tx_packets = priv->stats.tx_packets; sinfo->signal = signal.bcn_rssi_avg; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) || defined(COMPAT_WIRELESS) + /* Update BSS information */ + sinfo->filled |= STATION_INFO_BSS_PARAM; + sinfo->bss_param.flags = 0; + ret = woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info); + if (ret) + goto done; + if (bss_info.capability_info & WLAN_CAPABILITY_SHORT_PREAMBLE) + sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; + if (bss_info.capability_info & WLAN_CAPABILITY_SHORT_SLOT_TIME) + sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; + sinfo->bss_param.beacon_interval = bss_info.beacon_interval; + /* Get DTIM period */ + ret = woal_set_get_dtim_period(priv, MLAN_ACT_GET, + MOAL_IOCTL_WAIT, &dtim_period); + if (ret) { + PRINTM(MERROR, "Get DTIM period failed\n"); + goto done; + } + sinfo->bss_param.dtim_period = dtim_period; +#endif + done: if (req) kfree(req); @@ -1472,6 +1480,12 @@ woal_cfg80211_reg_notifier(struct wiphy *wiphy, ENTER(); + if (!priv) { + PRINTM(MFATAL, "Unable to get priv in %s()\n", __FUNCTION__); + LEAVE(); + return -EINVAL; + } + PRINTM(MINFO, "cfg80211 regulatory domain callback " "%c%c\n", request->alpha2[0], request->alpha2[1]); @@ -1496,7 +1510,7 @@ woal_cfg80211_reg_notifier(struct wiphy *wiphy, break; } - if (MLAN_STATUS_SUCCESS != woal_send_domain_info_cmd_fw(wiphy)) + if (MLAN_STATUS_SUCCESS != woal_send_domain_info_cmd_fw(priv)) ret = -EFAULT; LEAVE(); @@ -1519,7 +1533,7 @@ static int woal_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_scan_request *request) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); wlan_user_scan_cfg scan_req; struct ieee80211_channel *chan; int ret = 0, i; @@ -1604,10 +1618,11 @@ static int woal_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); int ret = 0; ENTER(); + PRINTM(MINFO, "Received association request on %s\n", dev->name); if (priv->wdev->iftype != NL80211_IFTYPE_STATION @@ -1645,7 +1660,7 @@ woal_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, if (priv->scan_type == MLAN_SCAN_TYPE_PASSIVE) woal_set_scan_type(priv, MLAN_SCAN_TYPE_ACTIVE); - ret = woal_cfg80211_assoc(wiphy, (void *) sme); + ret = woal_cfg80211_assoc(priv, (void *) sme); if (priv->scan_type == MLAN_SCAN_TYPE_PASSIVE) woal_set_scan_type(priv, MLAN_SCAN_TYPE_PASSIVE); @@ -1680,7 +1695,7 @@ static int woal_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, t_u16 reason_code) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); ENTER(); PRINTM(MINFO, "Received disassociation request on %s\n", dev->name); @@ -1729,7 +1744,7 @@ woal_cfg80211_get_station(struct wiphy *wiphy, t_u8 * mac, struct station_info *sinfo) { mlan_status ret = MLAN_STATUS_SUCCESS; - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); ENTER(); @@ -1778,7 +1793,7 @@ woal_cfg80211_dump_station(struct wiphy *wiphy, t_u8 * mac, struct station_info *sinfo) { mlan_status ret = MLAN_STATUS_SUCCESS; - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); ENTER(); @@ -1814,7 +1829,7 @@ static int woal_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); int ret = 0; ENTER(); @@ -1826,7 +1841,7 @@ woal_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, return -EINVAL; } - ret = woal_cfg80211_assoc(wiphy, (void *) params); + ret = woal_cfg80211_assoc(priv, (void *) params); if (!ret) { cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL); @@ -1852,7 +1867,7 @@ woal_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, static int woal_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); ENTER(); @@ -1898,7 +1913,7 @@ woal_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout) { int ret = 0, disabled; - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); ENTER(); @@ -1940,6 +1955,12 @@ woal_cfg80211_set_tx_power(struct wiphy *wiphy, ENTER(); + if (!priv) { + PRINTM(MFATAL, "Unable to get priv in %s()\n", __FUNCTION__); + LEAVE(); + return -EFAULT; + } + if (type) { power_cfg.is_power_auto = 0; power_cfg.power_level = dbm; @@ -1954,6 +1975,33 @@ woal_cfg80211_set_tx_power(struct wiphy *wiphy, return ret; } +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) || defined(COMPAT_WIRELESS) +/** + * CFG802.11 operation handler for connection quality monitoring. + * + * @param wiphy A pointer to wiphy structure + * @param dev A pointer to net_device structure + * @param rssi_thold rssi threshold + * @param rssi_hyst rssi hysteresis + */ +static int +woal_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy, + struct net_device *dev, + s32 rssi_thold, u32 rssi_hyst) +{ + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); + ENTER(); + priv->cqm_rssi_thold = rssi_thold; + priv->cqm_rssi_hyst = rssi_hyst; + + PRINTM(MIOCTL, "rssi_thold=%d rssi_hyst=%d\n", + (int) rssi_thold, (int) rssi_hyst); + woal_set_rssi_threshold(priv, 0); + LEAVE(); + return 0; +} +#endif + /** * @brief Sets up the CFG802.11 specific HT capability fields * with default values @@ -2010,7 +2058,7 @@ woal_cfg80211_setup_sta_ht_cap(struct ieee80211_sta_ht_cap *ht_info, /** * @brief remain on channel config * - * @param wiphy A pointer to wiphy structure + * @param priv A pointer to moal_private structure * @param wait_option Wait option * @param cancel cancel remain on channel flag * @param status A pointer to status, success, in process or reject @@ -2021,7 +2069,7 @@ woal_cfg80211_setup_sta_ht_cap(struct ieee80211_sta_ht_cap *ht_info, * @return 0 -- success, otherwise fail */ int -woal_cfg80211_remain_on_channel_cfg(struct wiphy *wiphy, +woal_cfg80211_remain_on_channel_cfg(moal_private * priv, t_u8 wait_option, t_u8 remove, t_u8 * status, struct ieee80211_channel *chan, @@ -2029,8 +2077,6 @@ woal_cfg80211_remain_on_channel_cfg(struct wiphy *wiphy, t_u32 duration) { mlan_ds_remain_chan chan_cfg; - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); - int ret = 0; ENTER(); @@ -2042,10 +2088,6 @@ woal_cfg80211_remain_on_channel_cfg(struct wiphy *wiphy, chan_cfg.bandcfg = 0; else if (chan->band == IEEE80211_BAND_5GHZ) chan_cfg.bandcfg = 1; -/** secondary channel is below */ -#define SEC_CHAN_BELOW 0x30 -/** secondary channel is above */ -#define SEC_CHAN_ABOVE 0x10 switch (channel_type) { case NL80211_CHAN_HT40MINUS: chan_cfg.bandcfg |= SEC_CHANNEL_BELOW; @@ -2084,14 +2126,14 @@ static int woal_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, struct net_device *dev, u64 cookie) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); int ret = 0; t_u8 status = 1; ENTER(); if (priv->phandle->remain_on_channel) { - if (woal_cfg80211_remain_on_channel_cfg(priv->wdev->wiphy, + if (woal_cfg80211_remain_on_channel_cfg(priv, MOAL_IOCTL_WAIT, MTRUE, &status, NULL, 0, 0)) { PRINTM(MERROR, "Fail to cancel remain on channel\n"); @@ -2133,7 +2175,7 @@ woal_cfg80211_remain_on_channel(struct wiphy *wiphy, enum nl80211_channel_type channel_type, unsigned int duration, u64 * cookie) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); int ret = 0; t_u8 status = 1; @@ -2146,8 +2188,9 @@ woal_cfg80211_remain_on_channel(struct wiphy *wiphy, } /** cancel previous remain on channel */ if (priv->phandle->remain_on_channel) { - if (woal_cfg80211_remain_on_channel_cfg - (wiphy, MOAL_IOCTL_WAIT, MTRUE, &status, NULL, 0, 0)) { + if (woal_cfg80211_remain_on_channel_cfg(priv, + MOAL_IOCTL_WAIT, MTRUE, &status, + NULL, 0, 0)) { PRINTM(MERROR, "Fail to cancel remain on channel\n"); ret = -EFAULT; goto done; @@ -2156,7 +2199,7 @@ woal_cfg80211_remain_on_channel(struct wiphy *wiphy, priv->phandle->remain_on_channel = MFALSE; } if (MLAN_STATUS_SUCCESS != - woal_cfg80211_remain_on_channel_cfg(wiphy, MOAL_IOCTL_WAIT, + woal_cfg80211_remain_on_channel_cfg(priv, MOAL_IOCTL_WAIT, MFALSE, &status, chan, channel_type, (t_u32) duration)) { ret = -EFAULT; @@ -2195,14 +2238,15 @@ static int woal_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct net_device *dev, u64 cookie) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); int ret = 0; t_u8 status = 1; ENTER(); PRINTM(MIOCTL, "Cancel remain on Channel: cookie = %#llx\n", cookie); - if (woal_cfg80211_remain_on_channel_cfg - (wiphy, MOAL_IOCTL_WAIT, MTRUE, &status, NULL, 0, 0)) { + if (woal_cfg80211_remain_on_channel_cfg(priv, + MOAL_IOCTL_WAIT, MTRUE, &status, + NULL, 0, 0)) { PRINTM(MERROR, "Fail to cancel remain on channel\n"); ret = -EFAULT; goto done; diff --git a/drivers/net/wireless/sd8797/mlinux/moal_uap_cfg80211.c b/drivers/net/wireless/sd8797/mlinux/moal_uap_cfg80211.c index 7f7528216282..18d18328d0ed 100644 --- a/drivers/net/wireless/sd8797/mlinux/moal_uap_cfg80211.c +++ b/drivers/net/wireless/sd8797/mlinux/moal_uap_cfg80211.c @@ -124,44 +124,6 @@ static struct cfg80211_ops woal_cfg80211_uap_ops = { /******************************************************** Global Functions ********************************************************/ -/** - * @brief Filter specific IE in ie buf - * - * @param ie Pointer to IEs - * @param len Total length of ie - * @param ie_out Pointer to out IE buf - * - * @return out IE length - */ -static t_u16 -woal_filter_beacon_ies(const t_u8 * ie, int len, t_u8 * ie_out) -{ - int left_len = len; - const t_u8 *pos = ie; - int length; - t_u8 id = 0; - t_u16 out_len = 0; - - /* ERP_INFO and RSN IE will be fileter out */ - while (left_len >= 2) { - length = *(pos + 1); - id = *pos; - if ((length + 2) > left_len) - break; - switch (id) { - case ERP_INFO: - case RSN_IE: - break; - default: - memcpy(ie_out + out_len, pos, length + 2); - out_len += length + 2; - break; - } - pos += (length + 2); - left_len -= (length + 2); - } - return out_len; -} #if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) && !defined(COMPAT_WIRELESS) /** @@ -364,442 +326,6 @@ woal_find_wpa_ies(t_u8 * ie, int len, mlan_uap_bss_param * sys_config) #endif /** - * @brief Look up specific IE in a buf - * - * @param ie Pointer to IEs - * @param len Total length of ie - * @param id Element id to lookup - * - * @return Pointer of the specific IE -- success, NULL -- fail - */ -static const t_u8 * -woal_parse_ie_tlv(const t_u8 * ie, int len, t_u8 id) -{ - int left_len = len; - const t_u8 *pos = ie; - int length; - - /* IE format: | u8 | id | | u8 | len | | var | data | */ - while (left_len >= 2) { - length = *(pos + 1); - if ((*pos == id) && (length + 2) <= left_len) - return pos; - pos += (length + 2); - left_len -= (length + 2); - } - - return NULL; -} - -/** - * @brief Add custom ie to mgmt frames. - * - * @param priv A pointer to moal private structure - * @param beacon_ies_data Beacon ie - * @param beacon_index The index for beacon when auto index - * @param proberesp_ies_data Probe resp ie - * @param proberesp_index The index for probe resp when auto index - * @param assocresp_ies_data Assoc resp ie - * @param assocresp_index The index for assoc resp when auto index - * @param probereq_ies_data Probe req ie - * @param probereq_index The index for probe req when auto index * - * - * @return 0 -- success, otherwise fail - */ -static int -woal_cfg80211_custom_ie(moal_private * priv, - custom_ie * beacon_ies_data, t_u16 * beacon_index, - custom_ie * proberesp_ies_data, t_u16 * proberesp_index, - custom_ie * assocresp_ies_data, t_u16 * assocresp_index, - custom_ie * probereq_ies_data, t_u16 * probereq_index) -{ - mlan_ioctl_req *ioctl_req = NULL; - mlan_ds_misc_cfg *misc = NULL; - mlan_ds_misc_custom_ie *custom_ie = NULL; - t_u8 *pos = NULL; - t_u16 len = 0; - int ret = 0; - - ENTER(); - - if (!(custom_ie = kmalloc(sizeof(mlan_ds_misc_custom_ie), GFP_KERNEL))) { - ret = -ENOMEM; - goto done; - } - - memset(custom_ie, 0x00, sizeof(mlan_ds_misc_custom_ie)); - custom_ie->type = TLV_TYPE_MGMT_IE; - - pos = (t_u8 *) custom_ie->ie_data_list; - if (beacon_ies_data) { - len = sizeof(*beacon_ies_data) - MAX_IE_SIZE - + beacon_ies_data->ie_length; - memcpy(pos, beacon_ies_data, len); - pos += len; - custom_ie->len += len; - } - - if (proberesp_ies_data) { - len = sizeof(*proberesp_ies_data) - MAX_IE_SIZE - + proberesp_ies_data->ie_length; - memcpy(pos, proberesp_ies_data, len); - pos += len; - custom_ie->len += len; - } - - if (assocresp_ies_data) { - len = sizeof(*assocresp_ies_data) - MAX_IE_SIZE - + assocresp_ies_data->ie_length; - memcpy(pos, assocresp_ies_data, len); - custom_ie->len += len; - } - - if (probereq_ies_data) { - len = sizeof(*probereq_ies_data) - MAX_IE_SIZE - + probereq_ies_data->ie_length; - memcpy(pos, probereq_ies_data, len); - pos += len; - custom_ie->len += len; - } - - ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); - if (ioctl_req == NULL) { - ret = -ENOMEM; - goto done; - } - - misc = (mlan_ds_misc_cfg *) ioctl_req->pbuf; - misc->sub_command = MLAN_OID_MISC_CUSTOM_IE; - ioctl_req->req_id = MLAN_IOCTL_MISC_CFG; - ioctl_req->action = MLAN_ACT_SET; - - memcpy(&misc->param.cust_ie, custom_ie, sizeof(mlan_ds_misc_custom_ie)); - - if (MLAN_STATUS_SUCCESS != - woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) { - ret = -EFAULT; - goto done; - } - - /* get the assigned index */ - pos = (t_u8 *) (&misc->param.cust_ie.ie_data_list[0].ie_index); - if (beacon_ies_data && beacon_ies_data->ie_length - && beacon_ies_data->ie_index == MLAN_CUSTOM_IE_AUTO_IDX_MASK) { - /* save beacon ie index after auto-indexing */ - *beacon_index = misc->param.cust_ie.ie_data_list[0].ie_index; - len = sizeof(*beacon_ies_data) - MAX_IE_SIZE - + beacon_ies_data->ie_length; - pos += len; - } - - if (proberesp_ies_data && proberesp_ies_data->ie_length - && proberesp_ies_data->ie_index == MLAN_CUSTOM_IE_AUTO_IDX_MASK) { - /* save probe resp ie index after auto-indexing */ - *proberesp_index = *((t_u16 *) pos); - len = sizeof(*proberesp_ies_data) - MAX_IE_SIZE - + proberesp_ies_data->ie_length; - pos += len; - } - - if (assocresp_ies_data && assocresp_ies_data->ie_length - && assocresp_ies_data->ie_index == MLAN_CUSTOM_IE_AUTO_IDX_MASK) { - /* save assoc resp ie index after auto-indexing */ - *assocresp_index = *((t_u16 *) pos); - len = sizeof(*assocresp_ies_data) - MAX_IE_SIZE - + assocresp_ies_data->ie_length; - pos += len; - } - if (probereq_ies_data && probereq_ies_data->ie_length - && probereq_ies_data->ie_index == MLAN_CUSTOM_IE_AUTO_IDX_MASK) { - /* save probe resp ie index after auto-indexing */ - *probereq_index = *((t_u16 *) pos); - len = sizeof(*probereq_ies_data) - MAX_IE_SIZE - + probereq_ies_data->ie_length; - pos += len; - } - - if (ioctl_req->status_code == MLAN_ERROR_IOCTL_FAIL) - ret = -EFAULT; - - done: - if (ioctl_req) - kfree(ioctl_req); - if (custom_ie) - kfree(custom_ie); - LEAVE(); - return ret; -} - -/** - * @brief This function returns priv - * based on mgmt ie index - * - * @param handle A pointer to moal_handle - * @param index mgmt ie index - * - * @return Pointer to moal_private - */ -static moal_private * -woal_get_priv_by_mgmt_index(moal_handle * handle, t_u16 index) -{ - int i; - - for (i = 0; i < MIN(handle->priv_num, MLAN_MAX_BSS_NUM); i++) { - if (handle->priv[i]) { - if (handle->priv[i]->probereq_index == index) - return (handle->priv[i]); - } - } - return NULL; -} - -/** - * @brief config AP or GO for mgmt frame ies. - * - * @param priv A pointer to moal private structure - * @param beacon_ies A pointer to beacon ies - * @param beacon_ies_len Beacon ies length - * @param proberesp_ies A pointer to probe resp ies - * @param proberesp_ies_len Probe resp ies length - * @param assocresp_ies A pointer to probe resp ies - * @param assocresp_ies_len Assoc resp ies length - * @param probereq_ies A pointer to probe req ies - * @param probereq_ies_len Probe req ies length * - * @param mask Mgmt frame mask - * - * @return 0 -- success, otherwise fail - */ -int -woal_cfg80211_mgmt_frame_ie(moal_private * priv, - const t_u8 * beacon_ies, size_t beacon_ies_len, - const t_u8 * proberesp_ies, - size_t proberesp_ies_len, - const t_u8 * assocresp_ies, - size_t assocresp_ies_len, const t_u8 * probereq_ies, - size_t probereq_ies_len, t_u16 mask) -{ - int ret = 0; - t_u8 *pos = NULL; - custom_ie *beacon_ies_data = NULL; - custom_ie *proberesp_ies_data = NULL; - custom_ie *assocresp_ies_data = NULL; - custom_ie *probereq_ies_data = NULL; - - /* static variables for mgmt frame ie auto-indexing */ - static t_u16 beacon_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; - static t_u16 proberesp_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; - static t_u16 assocresp_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; - static t_u16 probereq_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; - moal_private *pmpriv = NULL; - static t_u16 rsn_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; - const t_u8 *rsn_ie; - - ENTER(); - - if (mask & MGMT_MASK_BEACON) { - if (!(beacon_ies_data = kmalloc(sizeof(custom_ie), GFP_KERNEL))) { - ret = -ENOMEM; - goto done; - } - if (beacon_ies && beacon_ies_len) { - rsn_ie = - woal_parse_ie_tlv((t_u8 *) beacon_ies, (int) beacon_ies_len, - RSN_IE); - if (rsn_ie) { - beacon_ies_data->ie_index = rsn_index; - beacon_ies_data->mgmt_subtype_mask = - MGMT_MASK_BEACON | MGMT_MASK_PROBE_RESP | - MGMT_MASK_ASSOC_RESP; - beacon_ies_data->ie_length = rsn_ie[1] + 2; - memcpy(beacon_ies_data->ie_buffer, rsn_ie, rsn_ie[1] + 2); - if (MLAN_STATUS_SUCCESS != - woal_cfg80211_custom_ie(priv, beacon_ies_data, &rsn_index, - NULL, &proberesp_index, NULL, - &assocresp_index, NULL, - &probereq_index)) { - ret = -EFAULT; - goto done; - } - } - } else { - /* clear rsn_ie */ - if (rsn_index <= MAX_MGMT_IE_INDEX) { - beacon_ies_data->ie_index = rsn_index; - beacon_ies_data->mgmt_subtype_mask = MLAN_CUSTOM_IE_DELETE_MASK; - beacon_ies_data->ie_length = 0; - rsn_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; - if (MLAN_STATUS_SUCCESS != - woal_cfg80211_custom_ie(priv, beacon_ies_data, &rsn_index, - NULL, &proberesp_index, NULL, - &assocresp_index, NULL, - &probereq_index)) { - ret = -EFAULT; - goto done; - } - } - } - } - - if (mask & MGMT_MASK_PROBE_RESP) { - if (!(proberesp_ies_data = kmalloc(sizeof(custom_ie), GFP_KERNEL))) { - ret = -ENOMEM; - goto done; - } - } - - if (mask & MGMT_MASK_ASSOC_RESP) { - if (!(assocresp_ies_data = kmalloc(sizeof(custom_ie), GFP_KERNEL))) { - ret = -ENOMEM; - goto done; - } - } - if (mask & MGMT_MASK_PROBE_REQ) { - if (!(probereq_ies_data = kmalloc(sizeof(custom_ie), GFP_KERNEL))) { - ret = -ENOMEM; - goto done; - } - } - - if (beacon_ies_data) { - memset(beacon_ies_data, 0x00, sizeof(custom_ie)); - if (beacon_ies && beacon_ies_len) { - /* set the beacon ies */ - beacon_ies_data->ie_index = beacon_index; - beacon_ies_data->mgmt_subtype_mask = MGMT_MASK_BEACON; - beacon_ies_data->mgmt_subtype_mask |= MGMT_MASK_ASSOC_RESP; - beacon_ies_data->ie_length = woal_filter_beacon_ies(beacon_ies, - beacon_ies_len, - beacon_ies_data-> - ie_buffer); - } else { - /* clear the beacon ies */ - if (beacon_index > MAX_MGMT_IE_INDEX) { - PRINTM(MERROR, "Invalid beacon index for mgmt frame ie.\n"); - goto done; - } - - beacon_ies_data->ie_index = beacon_index; - beacon_ies_data->mgmt_subtype_mask = MLAN_CUSTOM_IE_DELETE_MASK; - beacon_ies_data->ie_length = 0; - beacon_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; - } - } - - if (proberesp_ies_data) { - memset(proberesp_ies_data, 0x00, sizeof(custom_ie)); - if (proberesp_ies && proberesp_ies_len) { - /* set the probe response ies */ - // proberesp_ies_data->ie_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; - proberesp_ies_data->ie_index = proberesp_index; - proberesp_ies_data->mgmt_subtype_mask = MGMT_MASK_PROBE_RESP; - proberesp_ies_data->ie_length = proberesp_ies_len; - pos = proberesp_ies_data->ie_buffer; - memcpy(pos, proberesp_ies, proberesp_ies_len); - } else { - /* clear the probe response ies */ - if (proberesp_index > MAX_MGMT_IE_INDEX) { - PRINTM(MERROR, "Invalid probe resp index for mgmt frame ie.\n"); - goto done; - } - - proberesp_ies_data->ie_index = proberesp_index; - proberesp_ies_data->mgmt_subtype_mask = MLAN_CUSTOM_IE_DELETE_MASK; - proberesp_ies_data->ie_length = 0; - proberesp_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; - } - } - if (assocresp_ies_data) { - memset(assocresp_ies_data, 0x00, sizeof(custom_ie)); - if (assocresp_ies && assocresp_ies_len) { - /* set the assoc response ies */ - assocresp_ies_data->ie_index = assocresp_index; - assocresp_ies_data->mgmt_subtype_mask = MGMT_MASK_ASSOC_RESP; - assocresp_ies_data->ie_length = assocresp_ies_len; - pos = assocresp_ies_data->ie_buffer; - memcpy(pos, assocresp_ies, assocresp_ies_len); - } else { - /* clear the assoc response ies */ - if (assocresp_index > MAX_MGMT_IE_INDEX) { - PRINTM(MERROR, "Invalid assoc resp index for mgmt frame ie.\n"); - goto done; - } - - assocresp_ies_data->ie_index = assocresp_index; - assocresp_ies_data->mgmt_subtype_mask = MLAN_CUSTOM_IE_DELETE_MASK; - assocresp_ies_data->ie_length = 0; - assocresp_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; - } - } - - if (probereq_ies_data) { - memset(probereq_ies_data, 0x00, sizeof(custom_ie)); - if ((probereq_index != MLAN_CUSTOM_IE_AUTO_IDX_MASK) && - (priv->probereq_index != probereq_index)) { - pmpriv = woal_get_priv_by_mgmt_index(priv->phandle, probereq_index); - if (pmpriv) { - probereq_ies_data->ie_index = probereq_index; - probereq_ies_data->mgmt_subtype_mask = - MLAN_CUSTOM_IE_DELETE_MASK; - probereq_ies_data->ie_length = 0; - probereq_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; - pmpriv->probereq_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; - if (MLAN_STATUS_SUCCESS != - woal_cfg80211_custom_ie(pmpriv, NULL, &beacon_index, - NULL, &proberesp_index, - NULL, &assocresp_index, - probereq_ies_data, - &probereq_index)) { - ret = -EFAULT; - goto done; - } - memset(probereq_ies_data, 0x00, sizeof(custom_ie)); - } - } - if (probereq_ies && probereq_ies_len) { - /* set the probe req ies */ - probereq_ies_data->ie_index = probereq_index; - probereq_ies_data->mgmt_subtype_mask = MGMT_MASK_PROBE_REQ; - probereq_ies_data->ie_length = probereq_ies_len; - pos = probereq_ies_data->ie_buffer; - memcpy(pos, probereq_ies, probereq_ies_len); - } else { - /* clear the probe req ies */ - if (probereq_index > MAX_MGMT_IE_INDEX) { - PRINTM(MERROR, "Invalid probe resp index for mgmt frame ie.\n"); - goto done; - } - probereq_ies_data->ie_index = probereq_index; - probereq_ies_data->mgmt_subtype_mask = MLAN_CUSTOM_IE_DELETE_MASK; - probereq_ies_data->ie_length = 0; - probereq_index = MLAN_CUSTOM_IE_AUTO_IDX_MASK; - } - } - - if (MLAN_STATUS_SUCCESS != - woal_cfg80211_custom_ie(priv, beacon_ies_data, &beacon_index, - proberesp_ies_data, &proberesp_index, - assocresp_ies_data, &assocresp_index, - probereq_ies_data, &probereq_index)) { - ret = -EFAULT; - goto done; - } - if (probereq_ies_data) - priv->probereq_index = probereq_index; - - done: - if (beacon_ies_data) - kfree(beacon_ies_data); - if (proberesp_ies_data) - kfree(proberesp_ies_data); - if (assocresp_ies_data) - kfree(assocresp_ies_data); - - LEAVE(); - - return ret; -} - -/** * @brief initialize AP or GO bss config * * @param priv A pointer to moal private structure @@ -1330,7 +856,7 @@ woal_cfg80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, struct beacon_parameters *params) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); int ret = 0; ENTER(); @@ -1402,7 +928,7 @@ woal_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, struct beacon_parameters *params) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); int ret = 0; ENTER(); @@ -1471,7 +997,7 @@ woal_cfg80211_set_beacon(struct wiphy *wiphy, int woal_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); int ret = 0; ENTER(); @@ -1521,7 +1047,7 @@ int woal_uap_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, u8 * mac, struct station_info *stainfo) { - moal_private *priv = (moal_private *) woal_get_wiphy_priv(wiphy); + moal_private *priv = (moal_private *) woal_get_netdev_priv(dev); int ret = -EFAULT; int i = 0; mlan_ds_get_info *info = NULL; diff --git a/drivers/net/wireless/sd8797/mlinux/moal_wext.c b/drivers/net/wireless/sd8797/mlinux/moal_wext.c index 8595892090fb..a967c939f009 100644 --- a/drivers/net/wireless/sd8797/mlinux/moal_wext.c +++ b/drivers/net/wireless/sd8797/mlinux/moal_wext.c @@ -2124,12 +2124,14 @@ woal_set_priv(struct net_device *dev, struct iw_request_info *info, priv->bg_scan_reported = MFALSE; len = sprintf(buf, "OK\n") + 1; } else if (strncmp(buf, "BGSCAN-STOP", strlen("BGSCAN-STOP")) == 0) { - if (MLAN_STATUS_SUCCESS != woal_stop_bg_scan(priv)) { - ret = -EFAULT; - goto done; + if (priv->bg_scan_start && !priv->scan_cfg.rssi_threshold) { + if (MLAN_STATUS_SUCCESS != woal_stop_bg_scan(priv)) { + ret = -EFAULT; + goto done; + } + priv->bg_scan_start = MFALSE; + priv->bg_scan_reported = MFALSE; } - priv->bg_scan_start = MFALSE; - priv->bg_scan_reported = MFALSE; len = sprintf(buf, "OK\n") + 1; } else if (strncmp(buf, "RXFILTER-START", strlen("RXFILTER-START")) == 0) { #ifdef MEF_CFG_RX_FILTER @@ -2326,13 +2328,13 @@ woal_set_essid(struct net_device *dev, struct iw_request_info *info, * Check if we asked for `any' or 'particular' */ if (!dwrq->flags) { - +#ifdef REASSOCIATION if (!req_ssid.ssid_len) { memset(&priv->prev_ssid_bssid.ssid, 0x00, sizeof(mlan_802_11_ssid)); memset(&priv->prev_ssid_bssid.bssid, 0x00, MLAN_MAC_ADDR_LENGTH); goto setessid_ret; } - +#endif /* Do normal SSID scanning */ if (MLAN_STATUS_SUCCESS != woal_request_scan(priv, MOAL_IOCTL_WAIT, NULL)) { @@ -2351,6 +2353,7 @@ woal_set_essid(struct net_device *dev, struct iw_request_info *info, PRINTM(MINFO, "Requested new SSID = %s\n", (char *) req_ssid.ssid); memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(mlan_802_11_ssid)); + if (dwrq->flags != 0xFFFF) { if (MLAN_STATUS_SUCCESS != woal_find_essid(priv, &ssid_bssid)) { /* Do specific SSID scanning */ diff --git a/drivers/net/wireless/sd8797/mlinux/moal_wext.h b/drivers/net/wireless/sd8797/mlinux/moal_wext.h index 91f918e1b130..dfafff866b96 100644 --- a/drivers/net/wireless/sd8797/mlinux/moal_wext.h +++ b/drivers/net/wireless/sd8797/mlinux/moal_wext.h @@ -45,7 +45,6 @@ Change log: #define CUS_EVT_BEACON_SNR_HIGH "EVENT=BEACON_SNR_HIGH" /** Custom event : Max fail */ #define CUS_EVT_MAX_FAIL "EVENT=MAX_FAIL" -#define CUS_EVT_BG_SCAN "EVENT=BG_SCAN_REPORT" /** Custom event : Data RSSI low */ #define CUS_EVT_DATA_RSSI_LOW "EVENT=DATA_RSSI_LOW" /** Custom event : Data SNR low */ |