mirror of
https://github.com/torvalds/linux.git
synced 2024-11-01 09:41:44 +00:00
Merge branch 'for-linville' of git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx
This commit is contained in:
commit
03877332ae
@ -1835,6 +1835,9 @@ int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif)
|
||||
wlvif->bss_type == BSS_TYPE_IBSS)))
|
||||
return -EINVAL;
|
||||
|
||||
/* flush all pending packets */
|
||||
wl1271_tx_work_locked(wl);
|
||||
|
||||
if (test_bit(wlvif->dev_role_id, wl->roc_map)) {
|
||||
ret = wl12xx_croc(wl, wlvif->dev_role_id);
|
||||
if (ret < 0)
|
||||
|
@ -267,8 +267,8 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
|
||||
wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_COMPLETE_EVENT "
|
||||
"(status 0x%0x)", mbox->scheduled_scan_status);
|
||||
if (wl->sched_scanning) {
|
||||
wl1271_scan_sched_scan_stop(wl);
|
||||
ieee80211_sched_scan_stopped(wl->hw);
|
||||
wl->sched_scanning = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -450,7 +450,16 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
|
||||
if (wl->state == WL1271_STATE_OFF)
|
||||
goto out;
|
||||
|
||||
if (dev->operstate != IF_OPER_UP)
|
||||
goto out;
|
||||
/*
|
||||
* The correct behavior should be just getting the appropriate wlvif
|
||||
* from the given dev, but currently we don't have a mac80211
|
||||
* interface for it.
|
||||
*/
|
||||
wl12xx_for_each_wlvif_sta(wl, wlvif) {
|
||||
struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
|
||||
|
||||
if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
|
||||
continue;
|
||||
|
||||
@ -458,7 +467,8 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wl1271_check_operstate(wl, wlvif, dev->operstate);
|
||||
wl1271_check_operstate(wl, wlvif,
|
||||
ieee80211_get_operstate(vif));
|
||||
|
||||
wl1271_ps_elp_sleep(wl);
|
||||
}
|
||||
@ -2036,6 +2046,11 @@ out:
|
||||
return booted;
|
||||
}
|
||||
|
||||
static bool wl12xx_dev_role_started(struct wl12xx_vif *wlvif)
|
||||
{
|
||||
return wlvif->dev_hlid != WL12XX_INVALID_LINK_ID;
|
||||
}
|
||||
|
||||
static int wl1271_op_add_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
@ -2184,7 +2199,11 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
|
||||
if (ret < 0)
|
||||
goto deinit;
|
||||
|
||||
if (wlvif->bss_type == BSS_TYPE_STA_BSS) {
|
||||
if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
|
||||
wlvif->bss_type == BSS_TYPE_IBSS) {
|
||||
if (wl12xx_dev_role_started(wlvif))
|
||||
wl12xx_stop_dev(wl, wlvif);
|
||||
|
||||
ret = wl12xx_cmd_role_disable(wl, &wlvif->dev_role_id);
|
||||
if (ret < 0)
|
||||
goto deinit;
|
||||
@ -2269,6 +2288,17 @@ out:
|
||||
cancel_work_sync(&wl->recovery_work);
|
||||
}
|
||||
|
||||
static int wl12xx_op_change_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum nl80211_iftype new_type, bool p2p)
|
||||
{
|
||||
wl1271_op_remove_interface(hw, vif);
|
||||
|
||||
vif->type = ieee80211_iftype_p2p(new_type, p2p);
|
||||
vif->p2p = p2p;
|
||||
return wl1271_op_add_interface(hw, vif);
|
||||
}
|
||||
|
||||
static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
bool set_assoc)
|
||||
{
|
||||
@ -2358,25 +2388,18 @@ static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif)
|
||||
wlvif->rate_set = wlvif->basic_rate_set;
|
||||
}
|
||||
|
||||
static bool wl12xx_is_roc(struct wl1271 *wl)
|
||||
{
|
||||
u8 role_id;
|
||||
|
||||
role_id = find_first_bit(wl->roc_map, WL12XX_MAX_ROLES);
|
||||
if (role_id >= WL12XX_MAX_ROLES)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
bool idle)
|
||||
{
|
||||
int ret;
|
||||
bool cur_idle = !test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
|
||||
|
||||
if (idle == cur_idle)
|
||||
return 0;
|
||||
|
||||
if (idle) {
|
||||
/* no need to croc if we weren't busy (e.g. during boot) */
|
||||
if (wl12xx_is_roc(wl)) {
|
||||
if (wl12xx_dev_role_started(wlvif)) {
|
||||
ret = wl12xx_stop_dev(wl, wlvif);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
@ -2391,7 +2414,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
ACX_KEEP_ALIVE_TPL_INVALID);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
set_bit(WL1271_FLAG_IDLE, &wl->flags);
|
||||
clear_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
|
||||
} else {
|
||||
/* The current firmware only supports sched_scan in idle */
|
||||
if (wl->sched_scanning) {
|
||||
@ -2402,7 +2425,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
ret = wl12xx_start_dev(wl, wlvif);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
clear_bit(WL1271_FLAG_IDLE, &wl->flags);
|
||||
set_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
|
||||
}
|
||||
|
||||
out:
|
||||
@ -2446,7 +2469,7 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
|
||||
if (test_bit(WLVIF_FLAG_STA_ASSOCIATED,
|
||||
&wlvif->flags)) {
|
||||
if (wl12xx_is_roc(wl)) {
|
||||
if (wl12xx_dev_role_started(wlvif)) {
|
||||
/* roaming */
|
||||
ret = wl12xx_croc(wl,
|
||||
wlvif->dev_role_id);
|
||||
@ -2463,7 +2486,7 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
* not idle. otherwise, CROC will be called
|
||||
* anyway.
|
||||
*/
|
||||
if (wl12xx_is_roc(wl) &&
|
||||
if (wl12xx_dev_role_started(wlvif) &&
|
||||
!(conf->flags & IEEE80211_CONF_IDLE)) {
|
||||
ret = wl12xx_stop_dev(wl, wlvif);
|
||||
if (ret < 0)
|
||||
@ -3010,16 +3033,17 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* cancel ROC before scanning */
|
||||
if (wl12xx_is_roc(wl)) {
|
||||
if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {
|
||||
/* don't allow scanning right now */
|
||||
ret = -EBUSY;
|
||||
goto out_sleep;
|
||||
}
|
||||
wl12xx_stop_dev(wl, wlvif);
|
||||
if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
|
||||
test_bit(wlvif->role_id, wl->roc_map)) {
|
||||
/* don't allow scanning right now */
|
||||
ret = -EBUSY;
|
||||
goto out_sleep;
|
||||
}
|
||||
|
||||
/* cancel ROC before scanning */
|
||||
if (wl12xx_dev_role_started(wlvif))
|
||||
wl12xx_stop_dev(wl, wlvif);
|
||||
|
||||
ret = wl1271_scan(hw->priv, vif, ssid, len, req);
|
||||
out_sleep:
|
||||
wl1271_ps_elp_sleep(wl);
|
||||
@ -3829,9 +3853,9 @@ sta_not_found:
|
||||
}
|
||||
/*
|
||||
* stop device role if started (we might already be in
|
||||
* STA role). TODO: make it better.
|
||||
* STA/IBSS role).
|
||||
*/
|
||||
if (wlvif->dev_role_id != WL12XX_INVALID_ROLE_ID) {
|
||||
if (wl12xx_dev_role_started(wlvif)) {
|
||||
ret = wl12xx_stop_dev(wl, wlvif);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
@ -3948,31 +3972,8 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw,
|
||||
else
|
||||
ps_scheme = CONF_PS_SCHEME_LEGACY;
|
||||
|
||||
if (wl->state == WL1271_STATE_OFF) {
|
||||
/*
|
||||
* If the state is off, the parameters will be recorded and
|
||||
* configured on init. This happens in AP-mode.
|
||||
*/
|
||||
struct conf_tx_ac_category *conf_ac =
|
||||
&wl->conf.tx.ac_conf[wl1271_tx_get_queue(queue)];
|
||||
struct conf_tx_tid *conf_tid =
|
||||
&wl->conf.tx.tid_conf[wl1271_tx_get_queue(queue)];
|
||||
|
||||
conf_ac->ac = wl1271_tx_get_queue(queue);
|
||||
conf_ac->cw_min = (u8)params->cw_min;
|
||||
conf_ac->cw_max = params->cw_max;
|
||||
conf_ac->aifsn = params->aifs;
|
||||
conf_ac->tx_op_limit = params->txop << 5;
|
||||
|
||||
conf_tid->queue_id = wl1271_tx_get_queue(queue);
|
||||
conf_tid->channel_type = CONF_CHANNEL_TYPE_EDCF;
|
||||
conf_tid->tsid = wl1271_tx_get_queue(queue);
|
||||
conf_tid->ps_scheme = ps_scheme;
|
||||
conf_tid->ack_policy = CONF_ACK_POLICY_LEGACY;
|
||||
conf_tid->apsd_conf[0] = 0;
|
||||
conf_tid->apsd_conf[1] = 0;
|
||||
if (!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = wl1271_ps_elp_wakeup(wl);
|
||||
if (ret < 0)
|
||||
@ -4629,6 +4630,7 @@ static const struct ieee80211_ops wl1271_ops = {
|
||||
.stop = wl1271_op_stop,
|
||||
.add_interface = wl1271_op_add_interface,
|
||||
.remove_interface = wl1271_op_remove_interface,
|
||||
.change_interface = wl12xx_op_change_interface,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = wl1271_op_suspend,
|
||||
.resume = wl1271_op_resume,
|
||||
|
@ -53,8 +53,11 @@ void wl1271_elp_work(struct work_struct *work)
|
||||
goto out;
|
||||
|
||||
wl12xx_for_each_wlvif(wl, wlvif) {
|
||||
if (wlvif->bss_type == BSS_TYPE_AP_BSS)
|
||||
goto out;
|
||||
|
||||
if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags) &&
|
||||
!test_bit(WL1271_FLAG_IDLE, &wl->flags))
|
||||
test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -78,8 +81,11 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
|
||||
return;
|
||||
|
||||
wl12xx_for_each_wlvif(wl, wlvif) {
|
||||
if (wlvif->bss_type == BSS_TYPE_AP_BSS)
|
||||
return;
|
||||
|
||||
if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags) &&
|
||||
!test_bit(WL1271_FLAG_IDLE, &wl->flags))
|
||||
test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -437,18 +437,19 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
|
||||
|
||||
if (flags & IEEE80211_CHAN_RADAR) {
|
||||
channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS;
|
||||
|
||||
channels[j].passive_duration =
|
||||
cpu_to_le16(c->dwell_time_dfs);
|
||||
}
|
||||
else if (flags & IEEE80211_CHAN_PASSIVE_SCAN) {
|
||||
} else {
|
||||
channels[j].passive_duration =
|
||||
cpu_to_le16(c->dwell_time_passive);
|
||||
} else {
|
||||
channels[j].min_duration =
|
||||
cpu_to_le16(c->min_dwell_time_active);
|
||||
channels[j].max_duration =
|
||||
cpu_to_le16(c->max_dwell_time_active);
|
||||
}
|
||||
|
||||
channels[j].min_duration =
|
||||
cpu_to_le16(c->min_dwell_time_active);
|
||||
channels[j].max_duration =
|
||||
cpu_to_le16(c->max_dwell_time_active);
|
||||
|
||||
channels[j].tx_power_att = req->channels[i]->max_power;
|
||||
channels[j].channel = req->channels[i]->hw_value;
|
||||
|
||||
@ -703,7 +704,7 @@ int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif)
|
||||
if (wlvif->bss_type != BSS_TYPE_STA_BSS)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!test_bit(WL1271_FLAG_IDLE, &wl->flags))
|
||||
if (test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
|
||||
return -EBUSY;
|
||||
|
||||
start = kzalloc(sizeof(*start), GFP_KERNEL);
|
||||
@ -753,7 +754,6 @@ void wl1271_scan_sched_scan_stop(struct wl1271 *wl)
|
||||
wl1271_error("failed to send sched scan stop command");
|
||||
goto out_free;
|
||||
}
|
||||
wl->sched_scanning = false;
|
||||
|
||||
out_free:
|
||||
kfree(stop);
|
||||
|
@ -241,7 +241,6 @@ enum wl12xx_flags {
|
||||
WL1271_FLAG_IN_ELP,
|
||||
WL1271_FLAG_ELP_REQUESTED,
|
||||
WL1271_FLAG_IRQ_RUNNING,
|
||||
WL1271_FLAG_IDLE,
|
||||
WL1271_FLAG_FW_TX_BUSY,
|
||||
WL1271_FLAG_DUMMY_PACKET_PENDING,
|
||||
WL1271_FLAG_SUSPENDED,
|
||||
@ -262,6 +261,7 @@ enum wl12xx_vif_flags {
|
||||
WLVIF_FLAG_PSPOLL_FAILURE,
|
||||
WLVIF_FLAG_CS_PROGRESS,
|
||||
WLVIF_FLAG_AP_PROBE_RESP_SET,
|
||||
WLVIF_FLAG_IN_USE,
|
||||
};
|
||||
|
||||
struct wl1271_link {
|
||||
|
@ -1,3 +1,24 @@
|
||||
/*
|
||||
* This file is part of wl12xx
|
||||
*
|
||||
* Copyright (C) 2010-2011 Texas Instruments, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/wl12xx.h>
|
||||
|
Loading…
Reference in New Issue
Block a user