Commit 4d55a0a1 authored by Vladimir Kondratiev's avatar Vladimir Kondratiev Committed by John W. Linville

wil6210: single station disconnect

implement del_station() method in the struct cfg80211_ops
It allows to disconnect single peer from the AP
Signed-off-by: default avatarVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 108d1eb6
...@@ -657,6 +657,14 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy, ...@@ -657,6 +657,14 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
return rc; return rc;
} }
static int wil_cfg80211_del_station(struct wiphy *wiphy,
struct net_device *dev, u8 *mac)
{
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
wil6210_disconnect(wil, mac);
return 0;
}
static struct cfg80211_ops wil_cfg80211_ops = { static struct cfg80211_ops wil_cfg80211_ops = {
.scan = wil_cfg80211_scan, .scan = wil_cfg80211_scan,
.connect = wil_cfg80211_connect, .connect = wil_cfg80211_connect,
...@@ -674,6 +682,7 @@ static struct cfg80211_ops wil_cfg80211_ops = { ...@@ -674,6 +682,7 @@ static struct cfg80211_ops wil_cfg80211_ops = {
/* AP mode */ /* AP mode */
.start_ap = wil_cfg80211_start_ap, .start_ap = wil_cfg80211_start_ap,
.stop_ap = wil_cfg80211_stop_ap, .stop_ap = wil_cfg80211_stop_ap,
.del_station = wil_cfg80211_del_station,
}; };
static void wil_wiphy_init(struct wiphy *wiphy) static void wil_wiphy_init(struct wiphy *wiphy)
......
...@@ -58,6 +58,12 @@ static void wil_disconnect_cid(struct wil6210_priv *wil, int cid) ...@@ -58,6 +58,12 @@ static void wil_disconnect_cid(struct wil6210_priv *wil, int cid)
{ {
uint i; uint i;
struct wil_sta_info *sta = &wil->sta[cid]; struct wil_sta_info *sta = &wil->sta[cid];
if (sta->status != wil_sta_unused) {
wmi_disconnect_sta(wil, sta->addr, WLAN_REASON_DEAUTH_LEAVING);
sta->status = wil_sta_unused;
}
for (i = 0; i < WIL_STA_TID_NUM; i++) { for (i = 0; i < WIL_STA_TID_NUM; i++) {
struct wil_tid_ampdu_rx *r = sta->tid_rx[i]; struct wil_tid_ampdu_rx *r = sta->tid_rx[i];
sta->tid_rx[i] = NULL; sta->tid_rx[i] = NULL;
......
...@@ -437,6 +437,7 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring); ...@@ -437,6 +437,7 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring);
int wmi_p2p_cfg(struct wil6210_priv *wil, int channel); int wmi_p2p_cfg(struct wil6210_priv *wil, int channel);
int wmi_rxon(struct wil6210_priv *wil, bool on); int wmi_rxon(struct wil6210_priv *wil, bool on);
int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r); int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r);
int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason);
int wil6210_init_irq(struct wil6210_priv *wil, int irq); int wil6210_init_irq(struct wil6210_priv *wil, int irq);
void wil6210_fini_irq(struct wil6210_priv *wil, int irq); void wil6210_fini_irq(struct wil6210_priv *wil, int irq);
......
...@@ -455,19 +455,14 @@ static void wmi_evt_disconnect(struct wil6210_priv *wil, int id, ...@@ -455,19 +455,14 @@ static void wmi_evt_disconnect(struct wil6210_priv *wil, int id,
void *d, int len) void *d, int len)
{ {
struct wmi_disconnect_event *evt = d; struct wmi_disconnect_event *evt = d;
int cid = wil_find_cid(wil, evt->bssid);
wil_dbg_wmi(wil, "Disconnect %pM CID %d reason %d proto %d wmi\n", wil_dbg_wmi(wil, "Disconnect %pM reason %d proto %d wmi\n",
evt->bssid, cid, evt->bssid,
evt->protocol_reason_status, evt->disconnect_reason); evt->protocol_reason_status, evt->disconnect_reason);
wil->sinfo_gen++; wil->sinfo_gen++;
/* TODO: fix for multiple connections */
wil6210_disconnect(wil, evt->bssid); wil6210_disconnect(wil, evt->bssid);
if (cid >= 0)
wil->sta[cid].status = wil_sta_unused;
} }
static void wmi_evt_notify(struct wil6210_priv *wil, int id, void *d, int len) static void wmi_evt_notify(struct wil6210_priv *wil, int id, void *d, int len)
...@@ -1062,6 +1057,18 @@ int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r) ...@@ -1062,6 +1057,18 @@ int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r)
return 0; return 0;
} }
int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason)
{
struct wmi_disconnect_sta_cmd cmd = {
.disconnect_reason = cpu_to_le16(reason),
};
memcpy(cmd.dst_mac, mac, ETH_ALEN);
wil_dbg_wmi(wil, "%s(%pM, reason %d)\n", __func__, mac, reason);
return wmi_send(wil, WMI_DISCONNECT_STA_CMDID, &cmd, sizeof(cmd));
}
void wmi_event_flush(struct wil6210_priv *wil) void wmi_event_flush(struct wil6210_priv *wil)
{ {
struct pending_wmi_event *evt, *t; struct pending_wmi_event *evt, *t;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment