Commit 40115bbc authored by Jérôme Pouiller's avatar Jérôme Pouiller Committed by Greg Kroah-Hartman
Browse files

staging: wfx: implement the rest of mac80211 API



Finish to fill struct ieee80211_ops with necessary callbacks. Driver is
now ready to be registered to mac80211.

Signed-off-by: default avatarJérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20190919142527.31797-21-Jerome.Pouiller@silabs.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent fb2490f6
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ static int wfx_handle_pspoll(struct wfx_vif *wvif, struct sk_buff *skb)
	u32 pspoll_mask = 0;
	int i;

	if (wvif->state != WFX_STATE_AP)
		return 1;
	if (!ether_addr_equal(wvif->vif->addr, pspoll->bssid))
		return 1;

@@ -162,6 +164,30 @@ void wfx_rx_cb(struct wfx_vif *wvif, struct hif_ind_rx *arg, struct sk_buff *skb
	    && arg->rx_flags.match_uc_addr
	    && mgmt->u.action.category == WLAN_CATEGORY_BACK)
		goto drop;
	if (ieee80211_is_beacon(frame->frame_control)
	    && !arg->status && wvif->vif
	    && ether_addr_equal(ieee80211_get_SA(frame), wvif->vif->bss_conf.bssid)) {
		const u8 *tim_ie;
		u8 *ies = mgmt->u.beacon.variable;
		size_t ies_len = skb->len - (ies - skb->data);

		tim_ie = cfg80211_find_ie(WLAN_EID_TIM, ies, ies_len);
		if (tim_ie) {
			struct ieee80211_tim_ie *tim = (struct ieee80211_tim_ie *) &tim_ie[2];

			if (wvif->dtim_period != tim->dtim_period) {
				wvif->dtim_period = tim->dtim_period;
				schedule_work(&wvif->set_beacon_wakeup_period_work);
			}
		}

		/* Disable beacon filter once we're associated... */
		if (wvif->disable_beacon_filter &&
		    (wvif->vif->bss_conf.assoc || wvif->vif->bss_conf.ibss_joined)) {
			wvif->disable_beacon_filter = false;
			schedule_work(&wvif->update_filtering_work);
		}
	}

	if (early_data) {
		spin_lock_bh(&wvif->ps_state_lock);
+16 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#include "data_tx.h"
#include "wfx.h"
#include "bh.h"
#include "sta.h"
#include "queue.h"
#include "debug.h"
#include "traces.h"
@@ -359,6 +360,9 @@ void wfx_link_id_gc_work(struct work_struct *work)
	u32 mask;
	int i;

	if (wvif->state != WFX_STATE_AP)
		return;

	wfx_tx_lock_flush(wvif->wdev);
	spin_lock_bh(&wvif->ps_state_lock);
	for (i = 0; i < WFX_MAX_STA_IN_AP_MODE; ++i) {
@@ -729,14 +733,26 @@ void wfx_tx_confirm_cb(struct wfx_vif *wvif, struct hif_cnf_tx *arg)
	memset(tx_info->pad, 0, sizeof(tx_info->pad));

	if (!arg->status) {
		if (wvif->bss_loss_state && arg->packet_id == wvif->bss_loss_confirm_id)
			wfx_cqm_bssloss_sm(wvif, 0, 1, 0);
		tx_info->status.tx_time = arg->media_delay - arg->tx_queue_delay;
		if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
			tx_info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
		else
			tx_info->flags |= IEEE80211_TX_STAT_ACK;
	} else if (arg->status == HIF_REQUEUE) {
		/* "REQUEUE" means "implicit suspend" */
		struct hif_ind_suspend_resume_tx suspend = {
			.suspend_resume_flags.resume = 0,
			.suspend_resume_flags.bc_mc_only = 1,
		};

		WARN(!arg->tx_result_flags.requeue, "incoherent status and result_flags");
		wfx_suspend_resume(wvif, &suspend);
		tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
	} else {
		if (wvif->bss_loss_state && arg->packet_id == wvif->bss_loss_confirm_id)
			wfx_cqm_bssloss_sm(wvif, 0, 0, 1);
	}
	wfx_pending_remove(wvif->wdev, skb);
}
+2 −0
Original line number Diff line number Diff line
@@ -11,7 +11,9 @@

#include "debug.h"
#include "wfx.h"
#include "sta.h"
#include "main.h"
#include "hif_tx.h"
#include "hif_tx_mib.h"

#define CREATE_TRACE_POINTS
+53 −0
Original line number Diff line number Diff line
@@ -12,6 +12,8 @@
#include "hif_rx.h"
#include "wfx.h"
#include "scan.h"
#include "bh.h"
#include "sta.h"
#include "data_rx.h"
#include "secure_link.h"
#include "hif_api_cmd.h"
@@ -144,6 +146,43 @@ static int hif_receive_indication(struct wfx_dev *wdev, struct hif_msg *hif, voi
	return 0;
}

static int hif_event_indication(struct wfx_dev *wdev, struct hif_msg *hif, void *buf)
{
	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
	struct hif_ind_event *body = buf;
	struct wfx_hif_event *event;
	int first;

	WARN_ON(!wvif);
	if (!wvif)
		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);

	return 0;
}

static int hif_pm_mode_complete_indication(struct wfx_dev *wdev, struct hif_msg *hif, void *buf)
{
	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);

	WARN_ON(!wvif);
	complete(&wvif->set_pm_mode_complete);

	return 0;
}

static int hif_scan_complete_indication(struct wfx_dev *wdev, struct hif_msg *hif, void *buf)
{
	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
@@ -165,6 +204,17 @@ static int hif_join_complete_indication(struct wfx_dev *wdev, struct hif_msg *hi
	return 0;
}

static int hif_suspend_resume_indication(struct wfx_dev *wdev, struct hif_msg *hif, void *buf)
{
	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
	struct hif_ind_suspend_resume_tx *body = buf;

	WARN_ON(!wvif);
	wfx_suspend_resume(wvif, body);

	return 0;
}

static int hif_error_indication(struct wfx_dev *wdev, struct hif_msg *hif, void *buf)
{
	struct hif_ind_error *body = buf;
@@ -242,8 +292,11 @@ static const struct {
	{ HIF_IND_ID_STARTUP,              hif_startup_indication },
	{ HIF_IND_ID_WAKEUP,               hif_wakeup_indication },
	{ HIF_IND_ID_JOIN_COMPLETE,        hif_join_complete_indication },
	{ HIF_IND_ID_SET_PM_MODE_CMPL,     hif_pm_mode_complete_indication },
	{ HIF_IND_ID_SCAN_CMPL,            hif_scan_complete_indication },
	{ HIF_IND_ID_SUSPEND_RESUME_TX,    hif_suspend_resume_indication },
	{ HIF_IND_ID_SL_EXCHANGE_PUB_KEYS, hif_keys_indication },
	{ HIF_IND_ID_EVENT,                hif_event_indication },
	{ HIF_IND_ID_GENERIC,              hif_generic_indication },
	{ HIF_IND_ID_ERROR,                hif_error_indication },
	{ HIF_IND_ID_EXCEPTION,            hif_exception_indication },
+1 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include "bh.h"
#include "hwio.h"
#include "debug.h"
#include "sta.h"

void wfx_init_hif_cmd(struct wfx_hif_cmd *hif_cmd)
{
Loading