mirror of https://gitee.com/openkylin/linux.git
Merge branch 'for-linville' of git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx
This commit is contained in:
commit
09db47b08a
|
@ -783,6 +783,10 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl)
|
|||
|
||||
acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT);
|
||||
|
||||
wl1271_debug(DEBUG_ACX, "basic_rate: 0x%x, full_rate: 0x%x",
|
||||
acx->rate_class[ACX_TX_BASIC_RATE].enabled_rates,
|
||||
acx->rate_class[ACX_TX_AP_FULL_RATE].enabled_rates);
|
||||
|
||||
ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
|
||||
if (ret < 0) {
|
||||
wl1271_warning("Setting of rate policies failed: %d", ret);
|
||||
|
@ -947,9 +951,9 @@ int wl1271_acx_tx_config_options(struct wl1271 *wl)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_acx_mem_cfg(struct wl1271 *wl)
|
||||
int wl1271_acx_ap_mem_cfg(struct wl1271 *wl)
|
||||
{
|
||||
struct wl1271_acx_config_memory *mem_conf;
|
||||
struct wl1271_acx_ap_config_memory *mem_conf;
|
||||
int ret;
|
||||
|
||||
wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
|
||||
|
@ -961,10 +965,10 @@ int wl1271_acx_mem_cfg(struct wl1271 *wl)
|
|||
}
|
||||
|
||||
/* memory config */
|
||||
mem_conf->num_stations = DEFAULT_NUM_STATIONS;
|
||||
mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS;
|
||||
mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS;
|
||||
mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES;
|
||||
mem_conf->num_stations = wl->conf.mem.num_stations;
|
||||
mem_conf->rx_mem_block_num = wl->conf.mem.rx_block_num;
|
||||
mem_conf->tx_min_mem_block_num = wl->conf.mem.tx_min_block_num;
|
||||
mem_conf->num_ssid_profiles = wl->conf.mem.ssid_profiles;
|
||||
mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS);
|
||||
|
||||
ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
|
||||
|
@ -979,14 +983,46 @@ int wl1271_acx_mem_cfg(struct wl1271 *wl)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_acx_sta_mem_cfg(struct wl1271 *wl)
|
||||
{
|
||||
struct wl1271_acx_sta_config_memory *mem_conf;
|
||||
int ret;
|
||||
|
||||
wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
|
||||
|
||||
mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
|
||||
if (!mem_conf) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* memory config */
|
||||
mem_conf->num_stations = wl->conf.mem.num_stations;
|
||||
mem_conf->rx_mem_block_num = wl->conf.mem.rx_block_num;
|
||||
mem_conf->tx_min_mem_block_num = wl->conf.mem.tx_min_block_num;
|
||||
mem_conf->num_ssid_profiles = wl->conf.mem.ssid_profiles;
|
||||
mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS);
|
||||
mem_conf->dyn_mem_enable = wl->conf.mem.dynamic_memory;
|
||||
mem_conf->tx_free_req = wl->conf.mem.min_req_tx_blocks;
|
||||
mem_conf->rx_free_req = wl->conf.mem.min_req_rx_blocks;
|
||||
mem_conf->tx_min = wl->conf.mem.tx_min;
|
||||
|
||||
ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
|
||||
sizeof(*mem_conf));
|
||||
if (ret < 0) {
|
||||
wl1271_warning("wl1271 mem config failed: %d", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(mem_conf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_acx_init_mem_config(struct wl1271 *wl)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = wl1271_acx_mem_cfg(wl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map),
|
||||
GFP_KERNEL);
|
||||
if (!wl->target_mem_map) {
|
||||
|
@ -1476,3 +1512,33 @@ int wl1271_acx_max_tx_retry(struct wl1271 *wl)
|
|||
kfree(acx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_acx_config_ps(struct wl1271 *wl)
|
||||
{
|
||||
struct wl1271_acx_config_ps *config_ps;
|
||||
int ret;
|
||||
|
||||
wl1271_debug(DEBUG_ACX, "acx config ps");
|
||||
|
||||
config_ps = kzalloc(sizeof(*config_ps), GFP_KERNEL);
|
||||
if (!config_ps) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
config_ps->exit_retries = wl->conf.conn.psm_exit_retries;
|
||||
config_ps->enter_retries = wl->conf.conn.psm_entry_retries;
|
||||
config_ps->null_data_rate = cpu_to_le32(wl->basic_rate);
|
||||
|
||||
ret = wl1271_cmd_configure(wl, ACX_CONFIG_PS, config_ps,
|
||||
sizeof(*config_ps));
|
||||
|
||||
if (ret < 0) {
|
||||
wl1271_warning("acx config ps failed: %d", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(config_ps);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -133,7 +133,6 @@ enum {
|
|||
|
||||
#define DEFAULT_UCAST_PRIORITY 0
|
||||
#define DEFAULT_RX_Q_PRIORITY 0
|
||||
#define DEFAULT_NUM_STATIONS 1
|
||||
#define DEFAULT_RXQ_PRIORITY 0 /* low 0 .. 15 high */
|
||||
#define DEFAULT_RXQ_TYPE 0x07 /* All frames, Data/Ctrl/Mgmt */
|
||||
#define TRACE_BUFFER_MAX_SIZE 256
|
||||
|
@ -797,12 +796,9 @@ struct acx_tx_config_options {
|
|||
__le16 tx_compl_threshold; /* number of packets */
|
||||
} __packed;
|
||||
|
||||
#define ACX_RX_MEM_BLOCKS 70
|
||||
#define ACX_TX_MIN_MEM_BLOCKS 40
|
||||
#define ACX_TX_DESCRIPTORS 32
|
||||
#define ACX_NUM_SSID_PROFILES 1
|
||||
|
||||
struct wl1271_acx_config_memory {
|
||||
struct wl1271_acx_ap_config_memory {
|
||||
struct acx_header header;
|
||||
|
||||
u8 rx_mem_block_num;
|
||||
|
@ -812,6 +808,20 @@ struct wl1271_acx_config_memory {
|
|||
__le32 total_tx_descriptors;
|
||||
} __packed;
|
||||
|
||||
struct wl1271_acx_sta_config_memory {
|
||||
struct acx_header header;
|
||||
|
||||
u8 rx_mem_block_num;
|
||||
u8 tx_min_mem_block_num;
|
||||
u8 num_stations;
|
||||
u8 num_ssid_profiles;
|
||||
__le32 total_tx_descriptors;
|
||||
u8 dyn_mem_enable;
|
||||
u8 tx_free_req;
|
||||
u8 rx_free_req;
|
||||
u8 tx_min;
|
||||
} __packed;
|
||||
|
||||
struct wl1271_acx_mem_map {
|
||||
struct acx_header header;
|
||||
|
||||
|
@ -1136,6 +1146,15 @@ struct wl1271_acx_max_tx_retry {
|
|||
u8 padding_1[2];
|
||||
} __packed;
|
||||
|
||||
struct wl1271_acx_config_ps {
|
||||
struct acx_header header;
|
||||
|
||||
u8 exit_retries;
|
||||
u8 enter_retries;
|
||||
u8 padding[2];
|
||||
__le32 null_data_rate;
|
||||
} __packed;
|
||||
|
||||
enum {
|
||||
ACX_WAKE_UP_CONDITIONS = 0x0002,
|
||||
ACX_MEM_CFG = 0x0003,
|
||||
|
@ -1193,6 +1212,8 @@ enum {
|
|||
ACX_HT_BSS_OPERATION = 0x0058,
|
||||
ACX_COEX_ACTIVITY = 0x0059,
|
||||
ACX_SET_DCO_ITRIM_PARAMS = 0x0061,
|
||||
ACX_GEN_FW_CMD = 0x0070,
|
||||
ACX_HOST_IF_CFG_BITMAP = 0x0071,
|
||||
ACX_MAX_TX_FAILURE = 0x0072,
|
||||
DOT11_RX_MSDU_LIFE_TIME = 0x1004,
|
||||
DOT11_CUR_TX_PWR = 0x100D,
|
||||
|
@ -1200,10 +1221,8 @@ enum {
|
|||
DOT11_RTS_THRESHOLD = 0x1013,
|
||||
DOT11_GROUP_ADDRESS_TBL = 0x1014,
|
||||
ACX_PM_CONFIG = 0x1016,
|
||||
|
||||
MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL,
|
||||
|
||||
MAX_IE = 0xFFFF
|
||||
ACX_CONFIG_PS = 0x1017,
|
||||
ACX_CONFIG_HANGOVER = 0x1018,
|
||||
};
|
||||
|
||||
|
||||
|
@ -1245,7 +1264,8 @@ int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
|
|||
u32 apsd_conf0, u32 apsd_conf1);
|
||||
int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold);
|
||||
int wl1271_acx_tx_config_options(struct wl1271 *wl);
|
||||
int wl1271_acx_mem_cfg(struct wl1271 *wl);
|
||||
int wl1271_acx_ap_mem_cfg(struct wl1271 *wl);
|
||||
int wl1271_acx_sta_mem_cfg(struct wl1271 *wl);
|
||||
int wl1271_acx_init_mem_config(struct wl1271 *wl);
|
||||
int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
|
||||
int wl1271_acx_smart_reflex(struct wl1271 *wl);
|
||||
|
@ -1269,5 +1289,6 @@ int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn,
|
|||
bool enable);
|
||||
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
|
||||
int wl1271_acx_max_tx_retry(struct wl1271 *wl);
|
||||
int wl1271_acx_config_ps(struct wl1271 *wl);
|
||||
|
||||
#endif /* __WL1271_ACX_H__ */
|
||||
|
|
|
@ -286,6 +286,7 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
|
|||
join->rx_filter_options = cpu_to_le32(wl->rx_filter);
|
||||
join->bss_type = bss_type;
|
||||
join->basic_rate_set = cpu_to_le32(wl->basic_rate_set);
|
||||
join->supported_rate_set = cpu_to_le32(wl->rate_set);
|
||||
|
||||
if (wl->band == IEEE80211_BAND_5GHZ)
|
||||
join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ;
|
||||
|
@ -303,6 +304,9 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
|
|||
wl->tx_security_last_seq = 0;
|
||||
wl->tx_security_seq = 0;
|
||||
|
||||
wl1271_debug(DEBUG_CMD, "cmd join: basic_rate_set=0x%x, rate_set=0x%x",
|
||||
join->basic_rate_set, join->supported_rate_set);
|
||||
|
||||
ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0);
|
||||
if (ret < 0) {
|
||||
wl1271_error("failed to initiate cmd join");
|
||||
|
@ -454,7 +458,7 @@ int wl1271_cmd_data_path(struct wl1271 *wl, bool enable)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send)
|
||||
int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode)
|
||||
{
|
||||
struct wl1271_cmd_ps_params *ps_params = NULL;
|
||||
int ret = 0;
|
||||
|
@ -468,10 +472,6 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send)
|
|||
}
|
||||
|
||||
ps_params->ps_mode = ps_mode;
|
||||
ps_params->send_null_data = send;
|
||||
ps_params->retries = wl->conf.conn.psm_entry_nullfunc_retries;
|
||||
ps_params->hang_over_period = wl->conf.conn.psm_entry_hangover_period;
|
||||
ps_params->null_data_rate = cpu_to_le32(rates);
|
||||
|
||||
ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
|
||||
sizeof(*ps_params), 0);
|
||||
|
|
|
@ -39,7 +39,7 @@ int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
|
|||
int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
|
||||
int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
|
||||
int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
|
||||
int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send);
|
||||
int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode);
|
||||
int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
|
||||
size_t len);
|
||||
int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
|
||||
|
@ -140,6 +140,7 @@ enum cmd_templ {
|
|||
* For CTS-to-self (FastCTS) mechanism
|
||||
* for BT/WLAN coexistence (SoftGemini). */
|
||||
CMD_TEMPL_ARP_RSP,
|
||||
CMD_TEMPL_LINK_MEASUREMENT_REPORT,
|
||||
|
||||
/* AP-mode specific */
|
||||
CMD_TEMPL_AP_BEACON = 13,
|
||||
|
@ -216,6 +217,7 @@ struct wl1271_cmd_join {
|
|||
* ACK or CTS frames).
|
||||
*/
|
||||
__le32 basic_rate_set;
|
||||
__le32 supported_rate_set;
|
||||
u8 dtim_interval;
|
||||
/*
|
||||
* bits 0-2: This bitwise field specifies the type
|
||||
|
@ -278,15 +280,7 @@ struct wl1271_cmd_ps_params {
|
|||
struct wl1271_cmd_header header;
|
||||
|
||||
u8 ps_mode; /* STATION_* */
|
||||
u8 send_null_data; /* Do we have to send NULL data packet ? */
|
||||
u8 retries; /* Number of retires for the initial NULL data packet */
|
||||
|
||||
/*
|
||||
* TUs during which the target stays awake after switching
|
||||
* to power save mode.
|
||||
*/
|
||||
u8 hang_over_period;
|
||||
__le32 null_data_rate;
|
||||
u8 padding[3];
|
||||
} __packed;
|
||||
|
||||
/* HW encryption keys */
|
||||
|
|
|
@ -959,6 +959,14 @@ struct conf_conn_settings {
|
|||
*/
|
||||
u8 psm_entry_retries;
|
||||
|
||||
/*
|
||||
* Specifies the maximum number of times to try PSM exit if it fails
|
||||
* (if sending the appropriate null-func message fails.)
|
||||
*
|
||||
* Range 0 - 255
|
||||
*/
|
||||
u8 psm_exit_retries;
|
||||
|
||||
/*
|
||||
* Specifies the maximum number of times to try transmit the PSM entry
|
||||
* null-func frame for each PSM entry attempt
|
||||
|
@ -1143,6 +1151,46 @@ struct conf_ht_setting {
|
|||
u16 inactivity_timeout;
|
||||
};
|
||||
|
||||
struct conf_memory_settings {
|
||||
/* Number of stations supported in IBSS mode */
|
||||
u8 num_stations;
|
||||
|
||||
/* Number of ssid profiles used in IBSS mode */
|
||||
u8 ssid_profiles;
|
||||
|
||||
/* Number of memory buffers allocated to rx pool */
|
||||
u8 rx_block_num;
|
||||
|
||||
/* Minimum number of blocks allocated to tx pool */
|
||||
u8 tx_min_block_num;
|
||||
|
||||
/* Disable/Enable dynamic memory */
|
||||
u8 dynamic_memory;
|
||||
|
||||
/*
|
||||
* Minimum required free tx memory blocks in order to assure optimum
|
||||
* performence
|
||||
*
|
||||
* Range: 0-120
|
||||
*/
|
||||
u8 min_req_tx_blocks;
|
||||
|
||||
/*
|
||||
* Minimum required free rx memory blocks in order to assure optimum
|
||||
* performence
|
||||
*
|
||||
* Range: 0-120
|
||||
*/
|
||||
u8 min_req_rx_blocks;
|
||||
|
||||
/*
|
||||
* Minimum number of mem blocks (free+used) guaranteed for TX
|
||||
*
|
||||
* Range: 0-120
|
||||
*/
|
||||
u8 tx_min;
|
||||
};
|
||||
|
||||
struct conf_drv_settings {
|
||||
struct conf_sg_settings sg;
|
||||
struct conf_rx_settings rx;
|
||||
|
@ -1154,6 +1202,7 @@ struct conf_drv_settings {
|
|||
struct conf_scan_settings scan;
|
||||
struct conf_rf_settings rf;
|
||||
struct conf_ht_setting ht;
|
||||
struct conf_memory_settings mem;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -135,20 +135,6 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
|
|||
/* go to extremely low power mode */
|
||||
wl1271_ps_elp_sleep(wl);
|
||||
break;
|
||||
case EVENT_EXIT_POWER_SAVE_FAIL:
|
||||
wl1271_debug(DEBUG_PSM, "PSM exit failed");
|
||||
|
||||
if (test_bit(WL1271_FLAG_PSM, &wl->flags)) {
|
||||
wl->psm_entry_retry = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* make sure the firmware goes to active mode - the frame to
|
||||
be sent next will indicate to the AP, that we are active. */
|
||||
ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
|
||||
wl->basic_rate, false);
|
||||
break;
|
||||
case EVENT_EXIT_POWER_SAVE_SUCCESS:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -75,8 +75,6 @@ enum {
|
|||
enum {
|
||||
EVENT_ENTER_POWER_SAVE_FAIL = 0,
|
||||
EVENT_ENTER_POWER_SAVE_SUCCESS,
|
||||
EVENT_EXIT_POWER_SAVE_FAIL,
|
||||
EVENT_EXIT_POWER_SAVE_SUCCESS,
|
||||
};
|
||||
|
||||
struct event_debug_report {
|
||||
|
|
|
@ -325,6 +325,11 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* PS config */
|
||||
ret = wl1271_acx_config_ps(wl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = wl1271_sta_init_templates_config(wl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -367,6 +372,10 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = wl1271_acx_sta_mem_cfg(wl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -433,6 +442,10 @@ static int wl1271_ap_hw_init(struct wl1271 *wl)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = wl1271_acx_ap_mem_cfg(wl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -256,6 +256,7 @@ static struct conf_drv_settings default_conf = {
|
|||
.bet_enable = CONF_BET_MODE_ENABLE,
|
||||
.bet_max_consecutive = 10,
|
||||
.psm_entry_retries = 5,
|
||||
.psm_exit_retries = 255,
|
||||
.psm_entry_nullfunc_retries = 3,
|
||||
.psm_entry_hangover_period = 1,
|
||||
.keep_alive_interval = 55000,
|
||||
|
@ -297,6 +298,16 @@ static struct conf_drv_settings default_conf = {
|
|||
.tx_ba_win_size = 64,
|
||||
.inactivity_timeout = 10000,
|
||||
},
|
||||
.mem = {
|
||||
.num_stations = 1,
|
||||
.ssid_profiles = 1,
|
||||
.rx_block_num = 70,
|
||||
.tx_min_block_num = 40,
|
||||
.dynamic_memory = 0,
|
||||
.min_req_tx_blocks = 104,
|
||||
.min_req_rx_blocks = 22,
|
||||
.tx_min = 27,
|
||||
}
|
||||
};
|
||||
|
||||
static void __wl1271_op_remove_interface(struct wl1271 *wl);
|
||||
|
@ -523,13 +534,19 @@ static int wl1271_plt_init(struct wl1271 *wl)
|
|||
}
|
||||
|
||||
static void wl1271_fw_status(struct wl1271 *wl,
|
||||
struct wl1271_fw_status *status)
|
||||
struct wl1271_fw_full_status *full_status)
|
||||
{
|
||||
struct wl1271_fw_common_status *status = &full_status->common;
|
||||
struct timespec ts;
|
||||
u32 total = 0;
|
||||
int i;
|
||||
|
||||
wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false);
|
||||
if (wl->bss_type == BSS_TYPE_AP_BSS)
|
||||
wl1271_raw_read(wl, FW_STATUS_ADDR, status,
|
||||
sizeof(struct wl1271_fw_ap_status), false);
|
||||
else
|
||||
wl1271_raw_read(wl, FW_STATUS_ADDR, status,
|
||||
sizeof(struct wl1271_fw_sta_status), false);
|
||||
|
||||
wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
|
||||
"drv_rx_counter = %d, tx_results_counter = %d)",
|
||||
|
@ -588,7 +605,7 @@ static void wl1271_irq_work(struct work_struct *work)
|
|||
loopcount--;
|
||||
|
||||
wl1271_fw_status(wl, wl->fw_status);
|
||||
intr = le32_to_cpu(wl->fw_status->intr);
|
||||
intr = le32_to_cpu(wl->fw_status->common.intr);
|
||||
if (!intr) {
|
||||
wl1271_debug(DEBUG_IRQ, "Zero interrupt received.");
|
||||
spin_lock_irqsave(&wl->wl_lock, flags);
|
||||
|
@ -610,7 +627,7 @@ static void wl1271_irq_work(struct work_struct *work)
|
|||
wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
|
||||
|
||||
/* check for tx results */
|
||||
if (wl->fw_status->tx_results_counter !=
|
||||
if (wl->fw_status->common.tx_results_counter !=
|
||||
(wl->tx_results_count & 0xff))
|
||||
wl1271_tx_complete(wl);
|
||||
|
||||
|
@ -624,7 +641,7 @@ static void wl1271_irq_work(struct work_struct *work)
|
|||
wl1271_tx_work_locked(wl);
|
||||
}
|
||||
|
||||
wl1271_rx(wl, wl->fw_status);
|
||||
wl1271_rx(wl, &wl->fw_status->common);
|
||||
}
|
||||
|
||||
if (intr & WL1271_ACX_INTR_EVENT_A) {
|
||||
|
@ -961,39 +978,10 @@ int wl1271_plt_stop(struct wl1271 *wl)
|
|||
static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
{
|
||||
struct wl1271 *wl = hw->priv;
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_sta *sta = txinfo->control.sta;
|
||||
unsigned long flags;
|
||||
int q;
|
||||
|
||||
/*
|
||||
* peek into the rates configured in the STA entry.
|
||||
* The rates set after connection stage, The first block only BG sets:
|
||||
* the compare is for bit 0-16 of sta_rate_set. The second block add
|
||||
* HT rates in case of HT supported.
|
||||
*/
|
||||
spin_lock_irqsave(&wl->wl_lock, flags);
|
||||
if (sta &&
|
||||
(sta->supp_rates[conf->channel->band] !=
|
||||
(wl->sta_rate_set & HW_BG_RATES_MASK)) &&
|
||||
wl->bss_type != BSS_TYPE_AP_BSS) {
|
||||
wl->sta_rate_set = sta->supp_rates[conf->channel->band];
|
||||
set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_WL12XX_HT
|
||||
if (sta &&
|
||||
sta->ht_cap.ht_supported &&
|
||||
((wl->sta_rate_set >> HW_HT_RATES_OFFSET) !=
|
||||
sta->ht_cap.mcs.rx_mask[0])) {
|
||||
/* Clean MCS bits before setting them */
|
||||
wl->sta_rate_set &= HW_BG_RATES_MASK;
|
||||
wl->sta_rate_set |=
|
||||
(sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
|
||||
set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
|
||||
}
|
||||
#endif
|
||||
wl->tx_queue_count++;
|
||||
spin_unlock_irqrestore(&wl->wl_lock, flags);
|
||||
|
||||
|
@ -1228,7 +1216,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
|
|||
wl->time_offset = 0;
|
||||
wl->session_counter = 0;
|
||||
wl->rate_set = CONF_TX_RATE_MASK_BASIC;
|
||||
wl->sta_rate_set = 0;
|
||||
wl->flags = 0;
|
||||
wl->vif = NULL;
|
||||
wl->filters = 0;
|
||||
|
@ -1415,7 +1402,6 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle)
|
|||
goto out;
|
||||
}
|
||||
wl->rate_set = wl1271_tx_min_rate_get(wl);
|
||||
wl->sta_rate_set = 0;
|
||||
ret = wl1271_acx_sta_rate_policies(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
@ -2229,6 +2215,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
|
|||
{
|
||||
bool do_join = false, set_assoc = false;
|
||||
bool is_ibss = (wl->bss_type == BSS_TYPE_IBSS);
|
||||
u32 sta_rate_set = 0;
|
||||
int ret;
|
||||
struct ieee80211_sta *sta;
|
||||
|
||||
|
@ -2294,6 +2281,49 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
|
|||
}
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
sta = ieee80211_find_sta(vif, bss_conf->bssid);
|
||||
if (sta) {
|
||||
/* save the supp_rates of the ap */
|
||||
sta_rate_set = sta->supp_rates[wl->hw->conf.channel->band];
|
||||
if (sta->ht_cap.ht_supported)
|
||||
sta_rate_set |=
|
||||
(sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
|
||||
|
||||
/* handle new association with HT and HT information change */
|
||||
if ((changed & BSS_CHANGED_HT) &&
|
||||
(bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
|
||||
ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
|
||||
true);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("Set ht cap true failed %d",
|
||||
ret);
|
||||
rcu_read_unlock();
|
||||
goto out;
|
||||
}
|
||||
ret = wl1271_acx_set_ht_information(wl,
|
||||
bss_conf->ht_operation_mode);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("Set ht information failed %d",
|
||||
ret);
|
||||
rcu_read_unlock();
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* handle new association without HT and disassociation */
|
||||
else if (changed & BSS_CHANGED_ASSOC) {
|
||||
ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
|
||||
false);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("Set ht cap false failed %d",
|
||||
ret);
|
||||
rcu_read_unlock();
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
if ((changed & BSS_CHANGED_ASSOC)) {
|
||||
if (bss_conf->assoc) {
|
||||
u32 rates;
|
||||
|
@ -2311,6 +2341,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
|
|||
wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl,
|
||||
rates);
|
||||
wl->basic_rate = wl1271_tx_min_rate_get(wl);
|
||||
if (sta_rate_set)
|
||||
wl->rate_set = wl1271_tx_enabled_rates_get(wl,
|
||||
sta_rate_set);
|
||||
ret = wl1271_acx_sta_rate_policies(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
@ -2389,43 +2422,6 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
|
|||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
rcu_read_lock();
|
||||
sta = ieee80211_find_sta(vif, bss_conf->bssid);
|
||||
if (sta) {
|
||||
/* handle new association with HT and HT information change */
|
||||
if ((changed & BSS_CHANGED_HT) &&
|
||||
(bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
|
||||
ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
|
||||
true);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("Set ht cap true failed %d",
|
||||
ret);
|
||||
rcu_read_unlock();
|
||||
goto out;
|
||||
}
|
||||
ret = wl1271_acx_set_ht_information(wl,
|
||||
bss_conf->ht_operation_mode);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("Set ht information failed %d",
|
||||
ret);
|
||||
rcu_read_unlock();
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* handle new association without HT and disassociation */
|
||||
else if (changed & BSS_CHANGED_ASSOC) {
|
||||
ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
|
||||
false);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("Set ht cap false failed %d",
|
||||
ret);
|
||||
rcu_read_unlock();
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
if (changed & BSS_CHANGED_ARP_FILTER) {
|
||||
__be32 addr = bss_conf->arp_addr_list[0];
|
||||
WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
|
||||
|
@ -3313,7 +3309,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
|
|||
wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
|
||||
wl->basic_rate = CONF_TX_RATE_MASK_BASIC;
|
||||
wl->rate_set = CONF_TX_RATE_MASK_BASIC;
|
||||
wl->sta_rate_set = 0;
|
||||
wl->band = IEEE80211_BAND_2GHZ;
|
||||
wl->vif = NULL;
|
||||
wl->flags = 0;
|
||||
|
|
|
@ -139,8 +139,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE,
|
||||
rates, send);
|
||||
ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -163,8 +162,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE,
|
||||
rates, send);
|
||||
ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -29,14 +29,14 @@
|
|||
#include "rx.h"
|
||||
#include "io.h"
|
||||
|
||||
static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status,
|
||||
static u8 wl1271_rx_get_mem_block(struct wl1271_fw_common_status *status,
|
||||
u32 drv_rx_counter)
|
||||
{
|
||||
return le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) &
|
||||
RX_MEM_BLOCK_MASK;
|
||||
}
|
||||
|
||||
static u32 wl1271_rx_get_buf_size(struct wl1271_fw_status *status,
|
||||
static u32 wl1271_rx_get_buf_size(struct wl1271_fw_common_status *status,
|
||||
u32 drv_rx_counter)
|
||||
{
|
||||
return (le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) &
|
||||
|
@ -134,7 +134,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
|
||||
void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
|
||||
{
|
||||
struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
|
||||
u32 buf_size;
|
||||
|
|
|
@ -119,7 +119,7 @@ struct wl1271_rx_descriptor {
|
|||
u8 reserved;
|
||||
} __packed;
|
||||
|
||||
void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status);
|
||||
void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status);
|
||||
u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
|
||||
void wl1271_set_default_filters(struct wl1271 *wl);
|
||||
|
||||
|
|
|
@ -334,35 +334,13 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
|
|||
{
|
||||
struct sk_buff *skb;
|
||||
bool woken_up = false;
|
||||
u32 sta_rates = 0;
|
||||
u32 buf_offset = 0;
|
||||
bool sent_packets = false;
|
||||
int ret;
|
||||
|
||||
/* check if the rates supported by the AP have changed */
|
||||
if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED,
|
||||
&wl->flags))) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&wl->wl_lock, flags);
|
||||
sta_rates = wl->sta_rate_set;
|
||||
spin_unlock_irqrestore(&wl->wl_lock, flags);
|
||||
}
|
||||
|
||||
if (unlikely(wl->state == WL1271_STATE_OFF))
|
||||
goto out;
|
||||
|
||||
/* if rates have changed, re-configure the rate policy */
|
||||
if (unlikely(sta_rates)) {
|
||||
ret = wl1271_ps_elp_wakeup(wl, false);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
woken_up = true;
|
||||
|
||||
wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates);
|
||||
wl1271_acx_sta_rate_policies(wl);
|
||||
}
|
||||
|
||||
while ((skb = wl1271_skb_dequeue(wl))) {
|
||||
if (!woken_up) {
|
||||
ret = wl1271_ps_elp_wakeup(wl, false);
|
||||
|
|
|
@ -130,7 +130,7 @@ extern u32 wl12xx_debug_level;
|
|||
|
||||
|
||||
|
||||
#define WL1271_FW_NAME "wl1271-fw.bin"
|
||||
#define WL1271_FW_NAME "wl1271-fw-2.bin"
|
||||
#define WL1271_AP_FW_NAME "wl1271-fw-ap.bin"
|
||||
|
||||
#define WL1271_NVS_NAME "wl1271-nvs.bin"
|
||||
|
@ -214,8 +214,8 @@ struct wl1271_stats {
|
|||
/* Broadcast and Global links + links to stations */
|
||||
#define AP_MAX_LINKS (AP_MAX_STATIONS + 2)
|
||||
|
||||
/* FW status registers */
|
||||
struct wl1271_fw_status {
|
||||
/* FW status registers common for AP/STA */
|
||||
struct wl1271_fw_common_status {
|
||||
__le32 intr;
|
||||
u8 fw_rx_counter;
|
||||
u8 drv_rx_counter;
|
||||
|
@ -224,6 +224,11 @@ struct wl1271_fw_status {
|
|||
__le32 rx_pkt_descs[NUM_RX_PKT_DESC];
|
||||
__le32 tx_released_blks[NUM_TX_QUEUES];
|
||||
__le32 fw_localtime;
|
||||
} __packed;
|
||||
|
||||
/* FW status registers for AP */
|
||||
struct wl1271_fw_ap_status {
|
||||
struct wl1271_fw_common_status common;
|
||||
|
||||
/* Next fields valid only in AP FW */
|
||||
|
||||
|
@ -238,6 +243,24 @@ struct wl1271_fw_status {
|
|||
u8 padding_1[1];
|
||||
} __packed;
|
||||
|
||||
/* FW status registers for STA */
|
||||
struct wl1271_fw_sta_status {
|
||||
struct wl1271_fw_common_status common;
|
||||
|
||||
u8 tx_total;
|
||||
u8 reserved1;
|
||||
__le16 reserved2;
|
||||
} __packed;
|
||||
|
||||
struct wl1271_fw_full_status {
|
||||
union {
|
||||
struct wl1271_fw_common_status common;
|
||||
struct wl1271_fw_sta_status sta;
|
||||
struct wl1271_fw_ap_status ap;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
|
||||
struct wl1271_rx_mem_pool_addr {
|
||||
u32 addr;
|
||||
u32 addr_extra;
|
||||
|
@ -278,6 +301,24 @@ struct wl1271_ap_key {
|
|||
u16 tx_seq_16;
|
||||
};
|
||||
|
||||
enum wl12xx_flags {
|
||||
WL1271_FLAG_STA_ASSOCIATED,
|
||||
WL1271_FLAG_JOINED,
|
||||
WL1271_FLAG_GPIO_POWER,
|
||||
WL1271_FLAG_TX_QUEUE_STOPPED,
|
||||
WL1271_FLAG_IN_ELP,
|
||||
WL1271_FLAG_PSM,
|
||||
WL1271_FLAG_PSM_REQUESTED,
|
||||
WL1271_FLAG_IRQ_PENDING,
|
||||
WL1271_FLAG_IRQ_RUNNING,
|
||||
WL1271_FLAG_IDLE,
|
||||
WL1271_FLAG_IDLE_REQUESTED,
|
||||
WL1271_FLAG_PSPOLL_FAILURE,
|
||||
WL1271_FLAG_STA_STATE_SENT,
|
||||
WL1271_FLAG_FW_TX_BUSY,
|
||||
WL1271_FLAG_AP_STARTED
|
||||
};
|
||||
|
||||
struct wl1271 {
|
||||
struct platform_device *plat_dev;
|
||||
struct ieee80211_hw *hw;
|
||||
|
@ -296,22 +337,6 @@ struct wl1271 {
|
|||
enum wl1271_state state;
|
||||
struct mutex mutex;
|
||||
|
||||
#define WL1271_FLAG_STA_RATES_CHANGED (0)
|
||||
#define WL1271_FLAG_STA_ASSOCIATED (1)
|
||||
#define WL1271_FLAG_JOINED (2)
|
||||
#define WL1271_FLAG_GPIO_POWER (3)
|
||||
#define WL1271_FLAG_TX_QUEUE_STOPPED (4)
|
||||
#define WL1271_FLAG_IN_ELP (5)
|
||||
#define WL1271_FLAG_PSM (6)
|
||||
#define WL1271_FLAG_PSM_REQUESTED (7)
|
||||
#define WL1271_FLAG_IRQ_PENDING (8)
|
||||
#define WL1271_FLAG_IRQ_RUNNING (9)
|
||||
#define WL1271_FLAG_IDLE (10)
|
||||
#define WL1271_FLAG_IDLE_REQUESTED (11)
|
||||
#define WL1271_FLAG_PSPOLL_FAILURE (12)
|
||||
#define WL1271_FLAG_STA_STATE_SENT (13)
|
||||
#define WL1271_FLAG_FW_TX_BUSY (14)
|
||||
#define WL1271_FLAG_AP_STARTED (15)
|
||||
unsigned long flags;
|
||||
|
||||
struct wl1271_partition_set part;
|
||||
|
@ -405,7 +430,6 @@ struct wl1271 {
|
|||
* bits 16-23 - 802.11n MCS index mask
|
||||
* support only 1 stream, thus only 8 bits for the MCS rates (0-7).
|
||||
*/
|
||||
u32 sta_rate_set;
|
||||
u32 basic_rate_set;
|
||||
u32 basic_rate;
|
||||
u32 rate_set;
|
||||
|
@ -445,7 +469,7 @@ struct wl1271 {
|
|||
u32 buffer_cmd;
|
||||
u32 buffer_busyword[WL1271_BUSY_WORD_CNT];
|
||||
|
||||
struct wl1271_fw_status *fw_status;
|
||||
struct wl1271_fw_full_status *fw_status;
|
||||
struct wl1271_tx_hw_res_if *tx_res_if;
|
||||
|
||||
struct ieee80211_vif *vif;
|
||||
|
|
Loading…
Reference in New Issue