static int rtw_cfgvendor_get_feature_set_matrix(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) { int err = 0; struct sk_buff *skb; int *reply; int num, mem_needed, i; reply = rtw_dev_get_feature_set_matrix(wdev_to_ndev(wdev), &num); if (!reply) { DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" Could not get feature list matrix\n" , FUNC_NDEV_ARG(wdev_to_ndev(wdev))); err = -EINVAL; return err; } mem_needed = VENDOR_REPLY_OVERHEAD + (ATTRIBUTE_U32_LEN * num) + ATTRIBUTE_U32_LEN; /* Alloc the SKB for vendor_event */ skb = rtw_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed); if (unlikely(!skb)) { DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" skb alloc failed", FUNC_NDEV_ARG(wdev_to_ndev(wdev))); err = -ENOMEM; goto exit; } nla_put_u32(skb, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, num); for (i = 0; i < num; i++) { nla_put_u32(skb, ANDR_WIFI_ATTRIBUTE_FEATURE_SET, reply[i]); } err = rtw_cfg80211_vendor_cmd_reply(skb); if (unlikely(err)) DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" Vendor Command reply failed ret:%d \n" , FUNC_NDEV_ARG(wdev_to_ndev(wdev)), err); exit: rtw_mfree((u8*)reply, sizeof(int)*num); return err; }
int *rtw_dev_get_feature_set_matrix(struct net_device *dev, int *num) { int feature_set_full, mem_needed; int *ret; *num = 0; mem_needed = sizeof(int) * MAX_FEATURE_SET_CONCURRRENT_GROUPS; ret = (int *)rtw_malloc(mem_needed); if (!ret) { DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" failed to allocate %d bytes\n" , FUNC_NDEV_ARG(dev), mem_needed); return ret; } feature_set_full = rtw_dev_get_feature_set(dev); ret[0] = (feature_set_full & WIFI_FEATURE_INFRA) | (feature_set_full & WIFI_FEATURE_INFRA_5G) | (feature_set_full & WIFI_FEATURE_NAN) | (feature_set_full & WIFI_FEATURE_D2D_RTT) | (feature_set_full & WIFI_FEATURE_D2AP_RTT) | (feature_set_full & WIFI_FEATURE_PNO) | (feature_set_full & WIFI_FEATURE_BATCH_SCAN) | (feature_set_full & WIFI_FEATURE_GSCAN) | (feature_set_full & WIFI_FEATURE_HOTSPOT) | (feature_set_full & WIFI_FEATURE_ADDITIONAL_STA) | (feature_set_full & WIFI_FEATURE_EPR); ret[1] = (feature_set_full & WIFI_FEATURE_INFRA) | (feature_set_full & WIFI_FEATURE_INFRA_5G) | /* Not yet verified NAN with P2P */ /* (feature_set_full & WIFI_FEATURE_NAN) | */ (feature_set_full & WIFI_FEATURE_P2P) | (feature_set_full & WIFI_FEATURE_D2AP_RTT) | (feature_set_full & WIFI_FEATURE_D2D_RTT) | (feature_set_full & WIFI_FEATURE_EPR); ret[2] = (feature_set_full & WIFI_FEATURE_INFRA) | (feature_set_full & WIFI_FEATURE_INFRA_5G) | (feature_set_full & WIFI_FEATURE_NAN) | (feature_set_full & WIFI_FEATURE_D2D_RTT) | (feature_set_full & WIFI_FEATURE_D2AP_RTT) | (feature_set_full & WIFI_FEATURE_TDLS) | (feature_set_full & WIFI_FEATURE_TDLS_OFFCHANNEL) | (feature_set_full & WIFI_FEATURE_EPR); *num = MAX_FEATURE_SET_CONCURRRENT_GROUPS; return ret; }
static int rtw_cfgvendor_get_feature_set(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) { int err = 0; int reply; reply = rtw_dev_get_feature_set(wdev_to_ndev(wdev)); err = rtw_cfgvendor_send_cmd_reply(wiphy, wdev_to_ndev(wdev), &reply, sizeof(int)); if (unlikely(err)) DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" Vendor Command reply failed ret:%d \n" , FUNC_NDEV_ARG(wdev_to_ndev(wdev)), err); return err; }
static int rtw_cfgvendor_send_cmd_reply(struct wiphy *wiphy, struct net_device *dev, const void *data, int len) { struct sk_buff *skb; /* Alloc the SKB for vendor_event */ skb = rtw_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len); if (unlikely(!skb)) { DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" skb alloc failed", FUNC_NDEV_ARG(dev)); return -ENOMEM; } /* Push the data to the skb */ nla_put_nohdr(skb, len, data); return rtw_cfg80211_vendor_cmd_reply(skb); }
/* * This API is to be used for asynchronous vendor events. This * shouldn't be used in response to a vendor command from its * do_it handler context (instead rtw_cfgvendor_send_cmd_reply should * be used). */ int rtw_cfgvendor_send_async_event(struct wiphy *wiphy, struct net_device *dev, int event_id, const void *data, int len) { u16 kflags; struct sk_buff *skb; kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; /* Alloc the SKB for vendor_event */ skb = rtw_cfg80211_vendor_event_alloc(wiphy, len, event_id, kflags); if (!skb) { DBG_871X_LEVEL(_drv_err_, FUNC_NDEV_FMT" skb alloc failed", FUNC_NDEV_ARG(dev)); return -ENOMEM; } /* Push the data to the skb */ nla_put_nohdr(skb, len, data); rtw_cfg80211_vendor_event(skb, kflags); return 0; }
int rtw_sta_flush(struct adapter *padapter) { struct list_head *phead, *plist; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; DBG_88E(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev)); if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) return 0; spin_lock_bh(&pstapriv->asoc_list_lock); phead = &pstapriv->asoc_list; plist = phead->next; /* free sta asoc_queue */ while (phead != plist) { psta = container_of(plist, struct sta_info, asoc_list); plist = plist->next; list_del_init(&psta->asoc_list); pstapriv->asoc_list_cnt--; ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING); } spin_unlock_bh(&pstapriv->asoc_list_lock); issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING); associated_clients_update(padapter, true); return 0; }
void rtw_ndev_destructor(struct net_device *ndev) { DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); free_netdev(ndev); }