@@ -920,40 +920,22 @@ static int handle_remain_on_chan(struct wilc_vif *vif,
struct wid wid;
struct host_if_drv *hif_drv = vif->hif_drv;
- if (!hif_drv->remain_on_ch_pending) {
- hif_drv->remain_on_ch.arg = hif_remain_ch->arg;
- hif_drv->remain_on_ch.expired = hif_remain_ch->expired;
- hif_drv->remain_on_ch.ready = hif_remain_ch->ready;
- hif_drv->remain_on_ch.ch = hif_remain_ch->ch;
- hif_drv->remain_on_ch.id = hif_remain_ch->id;
- } else {
- hif_remain_ch->ch = hif_drv->remain_on_ch.ch;
- }
+ if (hif_drv->usr_scan_req.scan_result)
+ return -EBUSY;
- if (hif_drv->usr_scan_req.scan_result) {
- hif_drv->remain_on_ch_pending = 1;
- result = -EBUSY;
- goto error;
- }
- if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
- result = -EBUSY;
- goto error;
- }
+ if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP)
+ return -EBUSY;
- if (vif->obtaining_ip || vif->connecting) {
- result = -EBUSY;
- goto error;
- }
+ if (vif->obtaining_ip || vif->connecting)
+ return -EBUSY;
remain_on_chan_flag = true;
wid.id = WID_REMAIN_ON_CHAN;
wid.type = WID_STR;
wid.size = 2;
wid.val = kmalloc(wid.size, GFP_KERNEL);
- if (!wid.val) {
- result = -ENOMEM;
- goto error;
- }
+ if (!wid.val)
+ return -ENOMEM;
wid.val[0] = remain_on_chan_flag;
wid.val[1] = (s8)hif_remain_ch->ch;
@@ -961,21 +943,16 @@ static int handle_remain_on_chan(struct wilc_vif *vif,
result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
wilc_get_vif_idx(vif));
kfree(wid.val);
- if (result != 0)
- netdev_err(vif->ndev, "Failed to set remain on channel\n");
+ if (result)
+ return -EBUSY;
-error:
+ hif_drv->remain_on_ch.arg = hif_remain_ch->arg;
+ hif_drv->remain_on_ch.expired = hif_remain_ch->expired;
+ hif_drv->remain_on_ch.ch = hif_remain_ch->ch;
+ hif_drv->remain_on_ch.cookie = hif_remain_ch->cookie;
hif_drv->remain_on_ch_timer_vif = vif;
- mod_timer(&hif_drv->remain_on_ch_timer,
- jiffies + msecs_to_jiffies(hif_remain_ch->duration));
-
- if (hif_drv->remain_on_ch.ready)
- hif_drv->remain_on_ch.ready(hif_drv->remain_on_ch.arg);
- if (hif_drv->remain_on_ch_pending)
- hif_drv->remain_on_ch_pending = 0;
-
- return result;
+ return 0;
}
static void handle_listen_state_expired(struct work_struct *work)
@@ -1012,7 +989,7 @@ static void handle_listen_state_expired(struct work_struct *work)
if (hif_drv->remain_on_ch.expired) {
hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg,
- hif_remain_ch->id);
+ hif_remain_ch->cookie);
}
} else {
netdev_dbg(vif->ndev, "Not in listen state\n");
@@ -1036,7 +1013,7 @@ static void listen_timer_cb(struct timer_list *t)
if (IS_ERR(msg))
return;
- msg->body.remain_on_ch.id = vif->hif_drv->remain_on_ch.id;
+ msg->body.remain_on_ch.cookie = vif->hif_drv->remain_on_ch.cookie;
result = wilc_enqueue_work(msg);
if (result) {
@@ -1102,9 +1079,6 @@ static void handle_scan_complete(struct work_struct *work)
handle_scan_done(msg->vif, SCAN_EVENT_DONE);
- if (msg->vif->hif_drv->remain_on_ch_pending)
- handle_remain_on_chan(msg->vif,
- &msg->vif->hif_drv->remain_on_ch);
kfree(msg);
}
@@ -1842,10 +1816,9 @@ void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length)
}
}
-int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id,
+int wilc_remain_on_channel(struct wilc_vif *vif, u64 cookie,
u32 duration, u16 chan,
- void (*expired)(void *, u32),
- void (*ready)(void *),
+ void (*expired)(void *, u64),
void *user_arg)
{
struct remain_ch roc;
@@ -1853,10 +1826,9 @@ int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id,
roc.ch = chan;
roc.expired = expired;
- roc.ready = ready;
roc.arg = user_arg;
roc.duration = duration;
- roc.id = session_id;
+ roc.cookie = cookie;
result = handle_remain_on_chan(vif, &roc);
if (result)
netdev_err(vif->ndev, "%s: failed to set remain on channel\n",
@@ -1865,7 +1837,7 @@ int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id,
return result;
}
-int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id)
+int wilc_listen_state_expired(struct wilc_vif *vif, u64 cookie)
{
int result;
struct host_if_msg *msg;
@@ -1882,7 +1854,7 @@ int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id)
if (IS_ERR(msg))
return PTR_ERR(msg);
- msg->body.remain_on_ch.id = session_id;
+ msg->body.remain_on_ch.cookie = cookie;
result = wilc_enqueue_work(msg);
if (result) {
@@ -140,10 +140,9 @@ struct wilc_conn_info {
struct remain_ch {
u16 ch;
u32 duration;
- void (*expired)(void *priv, u32 session_id);
- void (*ready)(void *priv);
+ void (*expired)(void *priv, u64 cookie);
void *arg;
- u32 id;
+ u32 cookie;
};
struct wilc;
@@ -151,7 +150,6 @@ struct host_if_drv {
struct user_scan_req usr_scan_req;
struct wilc_conn_info conn_info;
struct remain_ch remain_on_ch;
- u8 remain_on_ch_pending;
u64 p2p_timeout;
enum host_if_state hif_state;
@@ -227,12 +225,11 @@ int wilc_edit_station(struct wilc_vif *vif, const u8 *mac,
int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout);
int wilc_setup_multicast_filter(struct wilc_vif *vif, u32 enabled, u32 count,
u8 *mc_list);
-int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id,
+int wilc_remain_on_channel(struct wilc_vif *vif, u64 cookie,
u32 duration, u16 chan,
- void (*expired)(void *, u32),
- void (*ready)(void *),
+ void (*expired)(void *, u64),
void *user_arg);
-int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id);
+int wilc_listen_state_expired(struct wilc_vif *vif, u64 cookie);
void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg);
int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode,
u8 ifc_id);
@@ -1119,27 +1119,12 @@ static void wilc_wfi_mgmt_tx_complete(void *priv, int status)
kfree(pv_data);
}
-static void wilc_wfi_remain_on_channel_ready(void *priv_data)
-{
- struct wilc_priv *priv;
-
- priv = priv_data;
-
- priv->p2p_listen_state = true;
-
- cfg80211_ready_on_channel(priv->wdev,
- priv->remain_on_ch_params.listen_cookie,
- priv->remain_on_ch_params.listen_ch,
- priv->remain_on_ch_params.listen_duration,
- GFP_KERNEL);
-}
-
-static void wilc_wfi_remain_on_channel_expired(void *data, u32 session_id)
+static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie)
{
struct wilc_priv *priv = data;
struct wilc_wfi_p2p_listen_params *params = &priv->remain_on_ch_params;
- if (session_id != params->listen_session_id)
+ if (cookie != params->listen_cookie)
return;
priv->p2p_listen_state = false;
@@ -1156,24 +1141,36 @@ static int remain_on_channel(struct wiphy *wiphy,
int ret = 0;
struct wilc_priv *priv = wiphy_priv(wiphy);
struct wilc_vif *vif = netdev_priv(priv->dev);
+ u64 id;
if (wdev->iftype == NL80211_IFTYPE_AP) {
netdev_dbg(vif->ndev, "Required while in AP mode\n");
return ret;
}
+ id = ++priv->inc_roc_cookie;
+ if (id == 0)
+ id = ++priv->inc_roc_cookie;
+
+ ret = wilc_remain_on_channel(vif, id, duration, chan->hw_value,
+ wilc_wfi_remain_on_channel_expired,
+ (void *)priv);
+ if (ret)
+ return ret;
+
curr_channel = chan->hw_value;
priv->remain_on_ch_params.listen_ch = chan;
- priv->remain_on_ch_params.listen_cookie = *cookie;
+ priv->remain_on_ch_params.listen_cookie = id;
+ *cookie = id;
+ priv->p2p_listen_state = true;
priv->remain_on_ch_params.listen_duration = duration;
- priv->remain_on_ch_params.listen_session_id++;
- return wilc_remain_on_channel(vif,
- priv->remain_on_ch_params.listen_session_id,
- duration, chan->hw_value,
- wilc_wfi_remain_on_channel_expired,
- wilc_wfi_remain_on_channel_ready, (void *)priv);
+ cfg80211_ready_on_channel(wdev, *cookie, chan, duration, GFP_KERNEL);
+ mod_timer(&vif->hif_drv->remain_on_ch_timer,
+ jiffies + msecs_to_jiffies(duration));
+
+ return ret;
}
static int cancel_remain_on_channel(struct wiphy *wiphy,
@@ -1183,8 +1180,10 @@ static int cancel_remain_on_channel(struct wiphy *wiphy,
struct wilc_priv *priv = wiphy_priv(wiphy);
struct wilc_vif *vif = netdev_priv(priv->dev);
- return wilc_listen_state_expired(vif,
- priv->remain_on_ch_params.listen_session_id);
+ if (cookie != priv->remain_on_ch_params.listen_cookie)
+ return -ENOENT;
+
+ return wilc_listen_state_expired(vif, cookie);
}
static void wilc_wfi_cfg_tx_vendor_spec(struct wilc_priv *priv,
@@ -65,7 +65,6 @@ struct wilc_wfi_p2p_listen_params {
struct ieee80211_channel *listen_ch;
u32 listen_duration;
u64 listen_cookie;
- u32 listen_session_id;
};
struct wilc_p2p_var {
@@ -161,6 +160,7 @@ struct wilc_priv {
struct ieee80211_rate bitrates[ARRAY_SIZE(wilc_bitrates)];
struct ieee80211_supported_band band;
u32 cipher_suites[ARRAY_SIZE(wilc_cipher_suites)];
+ u64 inc_roc_cookie;
};
struct frame_reg {