[PATCH 04/16] staging: wfx: handle firmware events synchronously

Jerome Pouiller Jerome.Pouiller at silabs.com
Mon Apr 20 16:02:59 UTC 2020


From: Jérôme Pouiller <jerome.pouiller at silabs.com>

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 <jerome.pouiller at silabs.com>
---
 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)
-- 
2.26.1



More information about the devel mailing list