static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid) { int cid = -ENOENT; struct net_device *ndev = wil_to_ndev(wil); struct wireless_dev *wdev = wil->wdev; might_sleep(); if (bssid) { cid = wil_find_cid(wil, bssid); wil_dbg_misc(wil, "%s(%pM, CID %d)\n", __func__, bssid, cid); } else { wil_dbg_misc(wil, "%s(all)\n", __func__); } if (cid >= 0) /* disconnect 1 peer */ wil_disconnect_cid(wil, cid); else /* disconnect all */ for (cid = 0; cid < WIL6210_MAX_CID; cid++) wil_disconnect_cid(wil, cid); /* link state */ switch (wdev->iftype) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: wil_link_off(wil); if (test_bit(wil_status_fwconnected, &wil->status)) { clear_bit(wil_status_fwconnected, &wil->status); cfg80211_disconnected(ndev, WLAN_STATUS_UNSPECIFIED_FAILURE, NULL, 0, GFP_KERNEL); } else if (test_bit(wil_status_fwconnecting, &wil->status)) { cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0, WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL); } clear_bit(wil_status_fwconnecting, &wil->status); break; default: break; } }
static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid) { int cid = -ENOENT; struct net_device *ndev = wil_to_ndev(wil); struct wireless_dev *wdev = wil->wdev; might_sleep(); if (bssid) { cid = wil_find_cid(wil, bssid); wil_dbg_misc(wil, "%s(%pM, CID %d)\n", __func__, bssid, cid); } else { wil_dbg_misc(wil, "%s(all)\n", __func__); } if (cid >= 0) /* disconnect 1 peer */ wil_disconnect_cid(wil, cid); else {/* disconnect all */ /* * BUG FIX: Disconnect single sta only * We may get to here few times * with BSSID address */ if(ndev->dev_addr && bssid) { if(ether_addr_equal(ndev->dev_addr, bssid) ) { for (cid = 0; cid < WIL6210_MAX_CID; cid++) wil_disconnect_cid(wil, cid); } } } /* link state */ switch (wdev->iftype) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: wil_link_off(wil); clear_bit(wil_status_fwconnected, &wil->status); switch (wdev->sme_state) { case CFG80211_SME_CONNECTED: cfg80211_disconnected(ndev, WLAN_STATUS_UNSPECIFIED_FAILURE, NULL, 0, GFP_KERNEL); break; case CFG80211_SME_CONNECTING: cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0, WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL); break; default: break; } wil_dbg_misc(wil, "clear_bit(wil_status_dontscan)\n"); clear_bit(wil_status_dontscan, &wil->status); break; default: /* AP-like interface and monitor: * never scan, always connected */ if (bssid) cfg80211_del_sta(ndev, bssid, GFP_KERNEL); break; } }