提交 09db47b0 编写于 作者: J John W. Linville
上级 a0019bca 72c2d9e5
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
......@@ -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,13 +983,45 @@ int wl1271_acx_mem_cfg(struct wl1271 *wl)
return ret;
}
int wl1271_acx_init_mem_config(struct wl1271 *wl)
int wl1271_acx_sta_mem_cfg(struct wl1271 *wl)
{
struct wl1271_acx_sta_config_memory *mem_conf;
int ret;
ret = wl1271_acx_mem_cfg(wl);
if (ret < 0)
return 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;
wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map),
GFP_KERNEL);
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部