Commit 726e478c authored by Martin Kaistra's avatar Martin Kaistra Committed by Kalle Valo
Browse files

wifi: rtl8xxxu: Add sta_add() and sta_remove() callbacks



In AP mode, sta_add() gets called when a new STA gets associated to
us. Call rtl8xxxu_refresh_rate_mask() to set a rate mask for the newly
connected STA (referenced by the macid) and then send a media connnect
report. Ignore the call to sta_add() in station mode.

Reserve one macid for broadcast/multicast packets in init.

Signed-off-by: default avatarMartin Kaistra <martin.kaistra@linutronix.de>
Reviewed-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230428150833.218605-11-martin.kaistra@linutronix.de
parent 40d02ff2
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1730,6 +1730,7 @@ struct rtl8xxxu_cfo_tracking {
};

#define RTL8XXXU_HW_LED_CONTROL	2
#define RTL8XXXU_MAX_MAC_ID_NUM	128
#define RTL8XXXU_BC_MC_MACID	0

struct rtl8xxxu_priv {
@@ -1863,6 +1864,14 @@ struct rtl8xxxu_priv {
	bool led_registered;
	char led_name[32];
	struct led_classdev led_cdev;
	DECLARE_BITMAP(mac_id_map, RTL8XXXU_MAX_MAC_ID_NUM);
};

struct rtl8xxxu_sta_info {
	struct ieee80211_sta *sta;
	struct ieee80211_vif *vif;

	u8 macid;
};

struct rtl8xxxu_rx_urb {
+52 −0
Original line number Diff line number Diff line
@@ -3977,6 +3977,22 @@ void rtl8xxxu_init_burst(struct rtl8xxxu_priv *priv)
	rtl8xxxu_write8(priv, REG_RSV_CTRL, val8);
}

static u8 rtl8xxxu_acquire_macid(struct rtl8xxxu_priv *priv)
{
	u8 macid;

	macid = find_first_zero_bit(priv->mac_id_map, RTL8XXXU_MAX_MAC_ID_NUM);
	if (macid < RTL8XXXU_MAX_MAC_ID_NUM)
		set_bit(macid, priv->mac_id_map);

	return macid;
}

static void rtl8xxxu_release_macid(struct rtl8xxxu_priv *priv, u8 macid)
{
	clear_bit(macid, priv->mac_id_map);
}

static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
{
	struct rtl8xxxu_priv *priv = hw->priv;
@@ -4446,6 +4462,8 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
	if (priv->rtl_chip == RTL8188E)
		rtl8188e_ra_info_init_all(&priv->ra_info);

	set_bit(RTL8XXXU_BC_MC_MACID, priv->mac_id_map);

exit:
	return ret;
}
@@ -7212,6 +7230,38 @@ static void rtl8xxxu_stop(struct ieee80211_hw *hw)
	rtl8xxxu_free_tx_resources(priv);
}

static int rtl8xxxu_sta_add(struct ieee80211_hw *hw,
			    struct ieee80211_vif *vif,
			    struct ieee80211_sta *sta)
{
	struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv;
	struct rtl8xxxu_priv *priv = hw->priv;

	if (vif->type == NL80211_IFTYPE_AP) {
		sta_info->macid = rtl8xxxu_acquire_macid(priv);
		if (sta_info->macid >= RTL8XXXU_MAX_MAC_ID_NUM)
			return -ENOSPC;

		rtl8xxxu_refresh_rate_mask(priv, 0, sta, true);
		priv->fops->report_connect(priv, sta_info->macid, H2C_MACID_ROLE_STA, true);
	}

	return 0;
}

static int rtl8xxxu_sta_remove(struct ieee80211_hw *hw,
			       struct ieee80211_vif *vif,
			       struct ieee80211_sta *sta)
{
	struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv;
	struct rtl8xxxu_priv *priv = hw->priv;

	if (vif->type == NL80211_IFTYPE_AP)
		rtl8xxxu_release_macid(priv, sta_info->macid);

	return 0;
}

static const struct ieee80211_ops rtl8xxxu_ops = {
	.tx = rtl8xxxu_tx,
	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
@@ -7232,6 +7282,8 @@ static const struct ieee80211_ops rtl8xxxu_ops = {
	.sta_statistics = rtl8xxxu_sta_statistics,
	.get_antenna = rtl8xxxu_get_antenna,
	.set_tim = rtl8xxxu_set_tim,
	.sta_add = rtl8xxxu_sta_add,
	.sta_remove = rtl8xxxu_sta_remove,
};

static int rtl8xxxu_parse_usb(struct rtl8xxxu_priv *priv,