Commit fc008b9a authored by Franky Lin's avatar Franky Lin Committed by Greg Kroah-Hartman

staging: brcm80211: stop using kthread for iscan status check in fullmac

Use work queue instead.
Reported-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Reviewed-by: default avatarArend van Spriel <arend@broadcom.com>
Reviewed-by: default avatarHoward Harte <hharte@broadcom.com>
Signed-off-by: default avatarRoland Vossen <rvossen@broadcom.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 7c1387e0
...@@ -271,7 +271,6 @@ static s32 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, ...@@ -271,7 +271,6 @@ static s32 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar,
static void brcmf_iscan_timer(unsigned long data); static void brcmf_iscan_timer(unsigned long data);
static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv); static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv);
static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv); static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv);
static s32 brcmf_iscan_thread(void *data);
static s32 brcmf_dev_iovar_setbuf(struct net_device *dev, s8 *iovar, static s32 brcmf_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
void *param, s32 paramlen, void *bufptr, void *param, s32 paramlen, void *bufptr,
s32 buflen); s32 buflen);
...@@ -3151,18 +3150,15 @@ static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv) ...@@ -3151,18 +3150,15 @@ static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
struct brcmf_ssid ssid; struct brcmf_ssid ssid;
if (cfg_priv->iscan_on && iscan->tsk) { if (cfg_priv->iscan_on) {
iscan->state = WL_ISCAN_STATE_IDLE; iscan->state = WL_ISCAN_STATE_IDLE;
send_sig(SIGTERM, iscan->tsk, 1);
/* if (iscan->timer_on) {
* The iscan task may want to acquire the rtnl_lock del_timer_sync(&iscan->timer);
* so release it here upon stopping the task. iscan->timer_on = 0;
*/ }
rtnl_unlock();
kthread_stop(iscan->tsk); cancel_work_sync(&iscan->work);
rtnl_lock();
iscan->tsk = NULL;
/* Abort iscan running in FW */ /* Abort iscan running in FW */
memset(&ssid, 0, sizeof(ssid)); memset(&ssid, 0, sizeof(ssid));
...@@ -3195,7 +3191,7 @@ static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan) ...@@ -3195,7 +3191,7 @@ static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
{ {
if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) { if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
WL_SCAN("wake up iscan\n"); WL_SCAN("wake up iscan\n");
wake_up(&iscan->waitq); schedule_work(&iscan->work);
return 0; return 0;
} }
...@@ -3294,50 +3290,28 @@ static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv) ...@@ -3294,50 +3290,28 @@ static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
return err; return err;
} }
static s32 brcmf_iscan_thread(void *data) static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
{ {
struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
struct brcmf_cfg80211_iscan_ctrl *iscan = struct brcmf_cfg80211_iscan_ctrl *iscan =
(struct brcmf_cfg80211_iscan_ctrl *)data; container_of(work, struct brcmf_cfg80211_iscan_ctrl,
work);
struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan); struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
struct brcmf_cfg80211_iscan_eloop *el = &iscan->el; struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
DECLARE_WAITQUEUE(wait, current); u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
u32 status;
int err = 0;
sched_setscheduler(current, SCHED_FIFO, &param);
allow_signal(SIGTERM);
status = BRCMF_SCAN_RESULTS_PARTIAL;
add_wait_queue(&iscan->waitq, &wait);
while (1) {
prepare_to_wait(&iscan->waitq, &wait, TASK_INTERRUPTIBLE);
schedule();
if (kthread_should_stop())
break;
if (iscan->timer_on) { if (iscan->timer_on) {
del_timer_sync(&iscan->timer); del_timer_sync(&iscan->timer);
iscan->timer_on = 0; iscan->timer_on = 0;
} }
rtnl_lock(); rtnl_lock();
err = brcmf_get_iscan_results(iscan, &status, if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
&cfg_priv->bss_list);
if (unlikely(err)) {
status = BRCMF_SCAN_RESULTS_ABORTED; status = BRCMF_SCAN_RESULTS_ABORTED;
WL_ERR("Abort iscan\n"); WL_ERR("Abort iscan\n");
} }
rtnl_unlock(); rtnl_unlock();
el->handler[status](cfg_priv);
}
finish_wait(&iscan->waitq, &wait);
if (iscan->timer_on) {
del_timer_sync(&iscan->timer);
iscan->timer_on = 0;
}
WL_SCAN("ISCAN thread terminated\n");
return 0; el->handler[status](cfg_priv);
} }
static void brcmf_iscan_timer(unsigned long data) static void brcmf_iscan_timer(unsigned long data)
...@@ -3356,15 +3330,9 @@ static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv) ...@@ -3356,15 +3330,9 @@ static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
{ {
struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
if (cfg_priv->iscan_on && !iscan->tsk) { if (cfg_priv->iscan_on) {
iscan->state = WL_ISCAN_STATE_IDLE; iscan->state = WL_ISCAN_STATE_IDLE;
init_waitqueue_head(&iscan->waitq); INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
iscan->tsk = kthread_run(brcmf_iscan_thread, iscan, "wl_iscan");
if (IS_ERR(iscan->tsk)) {
WL_ERR("Could not create iscan thread\n");
iscan->tsk = NULL;
return -ENOMEM;
}
} }
return 0; return 0;
......
...@@ -248,8 +248,7 @@ struct brcmf_cfg80211_iscan_ctrl { ...@@ -248,8 +248,7 @@ struct brcmf_cfg80211_iscan_ctrl {
u32 timer_ms; u32 timer_ms;
u32 timer_on; u32 timer_on;
s32 state; s32 state;
struct task_struct *tsk; struct work_struct work;
wait_queue_head_t waitq;
struct brcmf_cfg80211_iscan_eloop el; struct brcmf_cfg80211_iscan_eloop el;
void *data; void *data;
s8 ioctl_buf[BRCMF_C_IOCTL_SMLEN]; s8 ioctl_buf[BRCMF_C_IOCTL_SMLEN];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment