From 988cf07bb9a0f3c296e38124ab7e7f5d2f2d28a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Pouiller?= Date: Mon, 20 Apr 2020 18:02:59 +0200 Subject: [PATCH] staging: wfx: handle firmware events synchronously MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, events from firmware are handled in a work queue with a complex event queue mechanism. It is probably overkill since there is only two events to handle: bss_loss and CQM events. Handling these events synchronously is sufficient. Signed-off-by: Jérôme Pouiller Link: https://lore.kernel.org/r/20200420160311.57323-5-Jerome.Pouiller@silabs.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wfx/hif_rx.c | 39 +++++++++++--------- drivers/staging/wfx/sta.c | 70 +----------------------------------- drivers/staging/wfx/sta.h | 6 +--- drivers/staging/wfx/wfx.h | 4 --- 4 files changed, 24 insertions(+), 95 deletions(-) diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c index 33c22c5d629d..b8d570256498 100644 --- a/drivers/staging/wfx/hif_rx.c +++ b/drivers/staging/wfx/hif_rx.c @@ -158,26 +158,31 @@ static int hif_event_indication(struct wfx_dev *wdev, { struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); const struct hif_ind_event *body = buf; - struct wfx_hif_event *event; - int first; - WARN_ON(!wvif); - if (!wvif) + if (!wvif) { + dev_warn(wdev->dev, "received event for non-existent vif\n"); return 0; + } - event = kzalloc(sizeof(*event), GFP_KERNEL); - if (!event) - return -ENOMEM; - - memcpy(&event->evt, body, sizeof(struct hif_ind_event)); - spin_lock(&wvif->event_queue_lock); - first = list_empty(&wvif->event_queue); - list_add_tail(&event->link, &wvif->event_queue); - spin_unlock(&wvif->event_queue_lock); - - if (first) - schedule_work(&wvif->event_handler_work); - + switch (body->event_id) { + case HIF_EVENT_IND_RCPI_RSSI: + wfx_event_report_rssi(wvif, body->event_data.rcpi_rssi); + break; + case HIF_EVENT_IND_BSSLOST: + schedule_delayed_work(&wvif->beacon_loss_work, 0); + break; + case HIF_EVENT_IND_BSSREGAINED: + cancel_delayed_work(&wvif->beacon_loss_work); + dev_dbg(wdev->dev, "ignore BSSREGAINED indication\n"); + break; + case HIF_EVENT_IND_PS_MODE_ERROR: + dev_warn(wdev->dev, "error while processing power save request\n"); + break; + default: + dev_warn(wdev->dev, "unhandled event indication: %.2x\n", + body->event_id); + break; + } return 0; } diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 2253ec2bdbf3..a0c841658a0b 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -38,27 +38,6 @@ u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates) return ret; } -static void __wfx_free_event_queue(struct list_head *list) -{ - struct wfx_hif_event *event, *tmp; - - list_for_each_entry_safe(event, tmp, list, link) { - list_del(&event->link); - kfree(event); - } -} - -static void wfx_free_event_queue(struct wfx_vif *wvif) -{ - LIST_HEAD(list); - - spin_lock(&wvif->event_queue_lock); - list_splice_init(&wvif->event_queue, &list); - spin_unlock(&wvif->event_queue_lock); - - __wfx_free_event_queue(&list); -} - static void wfx_filter_beacon(struct wfx_vif *wvif, bool filter_beacon) { const struct hif_ie_table_entry filter_ies[] = { @@ -269,7 +248,7 @@ int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value) /* WSM callbacks */ -static void wfx_event_report_rssi(struct wfx_vif *wvif, u8 raw_rcpi_rssi) +void wfx_event_report_rssi(struct wfx_vif *wvif, u8 raw_rcpi_rssi) { /* RSSI: signed Q8.0, RCPI: unsigned Q7.1 * RSSI = RCPI / 2 - 110 @@ -296,44 +275,6 @@ static void wfx_beacon_loss_work(struct work_struct *work) msecs_to_jiffies(bss_conf->beacon_int)); } -static void wfx_event_handler_work(struct work_struct *work) -{ - struct wfx_vif *wvif = - container_of(work, struct wfx_vif, event_handler_work); - struct wfx_hif_event *event; - - LIST_HEAD(list); - - spin_lock(&wvif->event_queue_lock); - list_splice_init(&wvif->event_queue, &list); - spin_unlock(&wvif->event_queue_lock); - - list_for_each_entry(event, &list, link) { - switch (event->evt.event_id) { - case HIF_EVENT_IND_BSSLOST: - schedule_delayed_work(&wvif->beacon_loss_work, 0); - break; - case HIF_EVENT_IND_BSSREGAINED: - cancel_delayed_work(&wvif->beacon_loss_work); - break; - case HIF_EVENT_IND_RCPI_RSSI: - wfx_event_report_rssi(wvif, - event->evt.event_data.rcpi_rssi); - break; - case HIF_EVENT_IND_PS_MODE_ERROR: - dev_warn(wvif->wdev->dev, - "error while processing power save request\n"); - break; - default: - dev_warn(wvif->wdev->dev, - "unhandled event indication: %.2x\n", - event->evt.event_id); - break; - } - } - __wfx_free_event_queue(&list); -} - // Call it with wdev->conf_mutex locked static void wfx_do_unjoin(struct wfx_vif *wvif) { @@ -351,9 +292,6 @@ static void wfx_do_unjoin(struct wfx_vif *wvif) wfx_tx_policy_init(wvif); if (wvif_count(wvif->wdev) <= 1) hif_set_block_ack_policy(wvif, 0xFF, 0xFF); - wfx_free_event_queue(wvif); - cancel_work_sync(&wvif->event_handler_work); - wfx_tx_unlock(wvif->wdev); cancel_delayed_work_sync(&wvif->beacon_loss_work); } @@ -844,10 +782,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) wvif->wep_default_key_id = -1; INIT_WORK(&wvif->wep_key_work, wfx_wep_key_work); - spin_lock_init(&wvif->event_queue_lock); - INIT_LIST_HEAD(&wvif->event_queue); - INIT_WORK(&wvif->event_handler_work, wfx_event_handler_work); - init_completion(&wvif->set_pm_mode_complete); complete(&wvif->set_pm_mode_complete); INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work); @@ -904,9 +838,7 @@ void wfx_remove_interface(struct ieee80211_hw *hw, /* FIXME: In add to reset MAC address, try to reset interface */ hif_set_macaddr(wvif, NULL); - wfx_free_event_queue(wvif); cancel_delayed_work_sync(&wvif->beacon_loss_work); - wdev->vif[wvif->id] = NULL; wvif->vif = NULL; diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h index 6d7734c65902..767b794fa398 100644 --- a/drivers/staging/wfx/sta.h +++ b/drivers/staging/wfx/sta.h @@ -23,11 +23,6 @@ enum wfx_state { WFX_STATE_AP, }; -struct wfx_hif_event { - struct list_head link; - struct hif_ind_event evt; -}; - struct wfx_sta_priv { int link_id; int vif_id; @@ -79,6 +74,7 @@ void wfx_unassign_vif_chanctx(struct ieee80211_hw *hw, // WSM Callbacks void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd cmd); +void wfx_event_report_rssi(struct wfx_vif *wvif, u8 raw_rcpi_rssi); // Other Helpers u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates); diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index 5484e7c64c3c..913b80d024a3 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -98,10 +98,6 @@ struct wfx_vif { struct ieee80211_scan_request *scan_req; struct completion set_pm_mode_complete; - - struct list_head event_queue; - spinlock_t event_queue_lock; - struct work_struct event_handler_work; }; static inline struct wfx_vif *wdev_to_wvif(struct wfx_dev *wdev, int vif_id)