int mtk_cfg80211_vendor_get_gscan_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) { P_GLUE_INFO_T prGlueInfo = NULL; INT_32 i4Status = -EINVAL; PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T rGscanCapabilities; struct sk_buff *skb; /* UINT_32 u4BufLen; */ DBGLOG(REQ, TRACE, "%s for vendor command \r\n", __func__); ASSERT(wiphy); ASSERT(wdev); prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(rGscanCapabilities)); if (!skb) { DBGLOG(REQ, ERROR, "%s allocate skb failed:%x\n", __func__, i4Status); return -ENOMEM; } kalMemZero(&rGscanCapabilities, sizeof(rGscanCapabilities)); /*rStatus = kalIoctl(prGlueInfo, wlanoidQueryStatistics, &rGscanCapabilities, sizeof(rGscanCapabilities), TRUE, TRUE, TRUE, FALSE, &u4BufLen); */ rGscanCapabilities.max_scan_cache_size = PSCAN_MAX_SCAN_CACHE_SIZE; rGscanCapabilities.max_scan_buckets = GSCAN_MAX_BUCKETS; rGscanCapabilities.max_ap_cache_per_scan = PSCAN_MAX_AP_CACHE_PER_SCAN; rGscanCapabilities.max_rssi_sample_size = 10; rGscanCapabilities.max_scan_reporting_threshold = GSCAN_MAX_REPORT_THRESHOLD; rGscanCapabilities.max_hotlist_aps = MAX_HOTLIST_APS; rGscanCapabilities.max_significant_wifi_change_aps = MAX_SIGNIFICANT_CHANGE_APS; rGscanCapabilities.max_bssid_history_entries = PSCAN_MAX_AP_CACHE_PER_SCAN * PSCAN_MAX_SCAN_CACHE_SIZE; /* NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0); */ /* NLA_PUT_U32(skb, NL80211_ATTR_VENDOR_ID, GOOGLE_OUI); */ /* NLA_PUT_U32(skb, NL80211_ATTR_VENDOR_SUBCMD, GSCAN_SUBCMD_GET_CAPABILITIES); */ /*NLA_PUT(skb, NL80211_ATTR_VENDOR_CAPABILITIES, sizeof(rGscanCapabilities), &rGscanCapabilities);*/ if (unlikely(nla_put(skb, NL80211_ATTR_VENDOR_CAPABILITIES, sizeof(rGscanCapabilities), &rGscanCapabilities) < 0)) goto nla_put_failure; i4Status = cfg80211_vendor_cmd_reply(skb); return i4Status; nla_put_failure: kfree_skb(skb); return i4Status; }
int mtk_cfg80211_vendor_llstats_get_info(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) { INT_32 i4Status = -EINVAL; WIFI_RADIO_STAT *pRadioStat; struct sk_buff *skb; UINT_32 u4BufLen; ASSERT(wiphy); ASSERT(wdev); u4BufLen = sizeof(WIFI_RADIO_STAT) + sizeof(WIFI_IFACE_STAT); pRadioStat = kalMemAlloc(u4BufLen, VIR_MEM_TYPE); if (!pRadioStat) { DBGLOG(REQ, ERROR, "%s kalMemAlloc pRadioStat failed\n", __func__); return -ENOMEM; } kalMemZero(pRadioStat, u4BufLen); skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, u4BufLen); if (!skb) { DBGLOG(REQ, TRACE, "%s allocate skb failed:%x\n", __func__, i4Status); return -ENOMEM; } /*rStatus = kalIoctl(prGlueInfo, wlanoidQueryStatistics, &rRadioStat, sizeof(rRadioStat), TRUE, TRUE, TRUE, FALSE, &u4BufLen); */ /* only for test */ pRadioStat->radio = 10; pRadioStat->on_time = 11; pRadioStat->tx_time = 12; pRadioStat->num_channels = 4; /*NLA_PUT(skb, NL80211_ATTR_VENDOR_LLSTAT, u4BufLen, pRadioStat);*/ if (unlikely(nla_put(skb, NL80211_ATTR_VENDOR_LLSTAT, u4BufLen, pRadioStat) < 0)) goto nla_put_failure; i4Status = cfg80211_vendor_cmd_reply(skb); kalMemFree(pRadioStat, VIR_MEM_TYPE, u4BufLen); return -1; /* not support LLS now*/ /* return i4Status; */ nla_put_failure: kfree_skb(skb); return i4Status; }
int mtk_cfg80211_vendor_get_rtt_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) { P_GLUE_INFO_T prGlueInfo = NULL; INT_32 i4Status = -EINVAL; PARAM_WIFI_RTT_CAPABILITIES rRttCapabilities; struct sk_buff *skb; DBGLOG(REQ, TRACE, "%s for vendor command \r\n", __func__); ASSERT(wiphy); ASSERT(wdev); prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(rRttCapabilities)); if (!skb) { DBGLOG(REQ, ERROR, "%s allocate skb failed:%x\n", __func__, i4Status); return -ENOMEM; } kalMemZero(&rRttCapabilities, sizeof(rRttCapabilities)); /*rStatus = kalIoctl(prGlueInfo, wlanoidQueryStatistics, &rRttCapabilities, sizeof(rRttCapabilities), TRUE, TRUE, TRUE, FALSE, &u4BufLen); */ rRttCapabilities.rtt_one_sided_supported = 0; rRttCapabilities.rtt_ftm_supported = 1; rRttCapabilities.lci_support = 1; rRttCapabilities.lcr_support = 1; rRttCapabilities.preamble_support = 0x07; rRttCapabilities.bw_support = 0x1c; if (unlikely(nla_put(skb, RTT_ATTRIBUTE_CAPABILITIES, sizeof(rRttCapabilities), &rRttCapabilities) < 0)) goto nla_put_failure; i4Status = cfg80211_vendor_cmd_reply(skb); return i4Status; nla_put_failure: kfree_skb(skb); return i4Status; }
static int wl_cfgvendor_gscan_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) { int err = 0, type, band; struct wl_priv *cfg = wiphy_priv(wiphy); uint16 *reply = NULL; uint32 reply_len = 0, num_channels, mem_needed; struct sk_buff *skb; type = nla_type(data); if (type == GSCAN_ATTRIBUTE_BAND) { band = nla_get_u32(data); } else { return -1; } reply = dhd_dev_pno_get_gscan(wl_to_prmry_ndev(cfg), DHD_PNO_GET_CHANNEL_LIST, &band, &reply_len); if (!reply) { WL_ERR(("Could not get channel list\n")); err = -EINVAL; return err; } num_channels = reply_len/ sizeof(uint32); mem_needed = reply_len + VENDOR_REPLY_OVERHEAD + (ATTRIBUTE_U32_LEN * 2); /* Alloc the SKB for vendor_event */ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed); if (unlikely(!skb)) { WL_ERR(("skb alloc failed")); err = -ENOMEM; goto exit; } nla_put_u32(skb, GSCAN_ATTRIBUTE_NUM_CHANNELS, num_channels); nla_put(skb, GSCAN_ATTRIBUTE_CHANNEL_LIST, reply_len, reply); err = cfg80211_vendor_cmd_reply(skb); if (unlikely(err)) WL_ERR(("Vendor Command reply failed ret:%d \n", err)); exit: kfree(reply); return err; }
static int wl_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 = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len); if (unlikely(!skb)) { WL_ERR(("skb alloc failed")); return -ENOMEM; } /* Push the data to the skb */ nla_put_nohdr(skb, len, data); return cfg80211_vendor_cmd_reply(skb); }
int dbg_rtw_cfg80211_vendor_cmd_reply(struct sk_buff *skb , const enum mstat_f flags, const char *func, const int line) { unsigned int truesize = skb->truesize; int ret; if(match_mstat_sniff_rules(flags, truesize)) DBG_871X("DBG_MEM_ALLOC %s:%d %s, truesize=%u\n", func, line, __FUNCTION__, truesize); ret = cfg80211_vendor_cmd_reply(skb); rtw_mstat_update( flags , MSTAT_FREE , truesize ); return ret; }
static int wl_cfgvendor_get_feature_set_matrix(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) { int err = 0; struct wl_priv *cfg = wiphy_priv(wiphy); struct sk_buff *skb; int *reply; int num, mem_needed, i; reply = dhd_dev_get_feature_set_matrix(wl_to_prmry_ndev(cfg), &num); if (!reply) { WL_ERR(("Could not get feature list matrix\n")); err = -EINVAL; return err; } mem_needed = VENDOR_REPLY_OVERHEAD + (ATTRIBUTE_U32_LEN * num) + ATTRIBUTE_U32_LEN; /* Alloc the SKB for vendor_event */ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed); if (unlikely(!skb)) { WL_ERR(("skb alloc failed")); 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 = cfg80211_vendor_cmd_reply(skb); if (unlikely(err)) WL_ERR(("Vendor Command reply failed ret:%d \n", err)); exit: kfree(reply); return err; }
/** * @brief vendor command to set drvdbg * * @param wiphy A pointer to wiphy struct * @param wdev A pointer to wireless_dev struct * @param data a pointer to data * @param len data length * * @return 0: success 1: fail */ static int woal_cfg80211_subcmd_set_drvdbg(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) { struct net_device *dev = wdev->netdev; moal_private *priv = (moal_private *)woal_get_netdev_priv(dev); struct sk_buff *skb = NULL; t_u8 *pos = NULL; int ret = 0; ENTER(); /**handle this sub command*/ DBG_HEXDUMP(MCMD_D, "Vendor drvdbg", (t_u8 *)data, data_len); if (data_len) { /* Get the driver debug bit masks from user */ drvdbg = *((t_u32 *)data); PRINTM(MIOCTL, "new drvdbg %x\n", drvdbg); /* Set the driver debug bit masks into mlan */ if (woal_set_drvdbg(priv, drvdbg)) { PRINTM(MERROR, "Set drvdbg failed!\n"); ret = 1; } } /** Allocate skb for cmd reply*/ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(drvdbg)); if (!skb) { PRINTM(MERROR, "allocate memory fail for vendor cmd\n"); ret = 1; LEAVE(); return ret; } pos = skb_put(skb, sizeof(drvdbg)); memcpy(pos, &drvdbg, sizeof(drvdbg)); ret = cfg80211_vendor_cmd_reply(skb); LEAVE(); return ret; }
static int dhd_cfgvendor_priv_string_handler(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) { const struct bcm_nlmsg_hdr *nlioc = data; struct net_device *ndev = NULL; struct bcm_cfg80211 *cfg; struct sk_buff *reply; void *buf = NULL, *cur; dhd_pub_t *dhd; dhd_ioctl_t ioc = { 0 }; int ret = 0, ret_len, payload, msglen; int maxmsglen = PAGE_SIZE - 0x100; int8 index; WL_TRACE(("entry: cmd = %d\n", nlioc->cmd)); cfg = wiphy_priv(wiphy); dhd = cfg->pub; DHD_OS_WAKE_LOCK(dhd); /* send to dongle only if we are not waiting for reload already */ if (dhd->hang_was_sent) { WL_ERR(("HANG was sent up earlier\n")); DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(dhd, DHD_EVENT_TIMEOUT_MS); DHD_OS_WAKE_UNLOCK(dhd); return OSL_ERROR(BCME_DONGLE_DOWN); } len -= sizeof(struct bcm_nlmsg_hdr); ret_len = nlioc->len; if (ret_len > 0 || len > 0) { if (len > DHD_IOCTL_MAXLEN) { WL_ERR(("oversize input buffer %d\n", len)); len = DHD_IOCTL_MAXLEN; } if (ret_len > DHD_IOCTL_MAXLEN) { WL_ERR(("oversize return buffer %d\n", ret_len)); ret_len = DHD_IOCTL_MAXLEN; } payload = max(ret_len, len) + 1; buf = vzalloc(payload); if (!buf) { DHD_OS_WAKE_UNLOCK(dhd); return -ENOMEM; } memcpy(buf, (void *)nlioc + nlioc->offset, len); *(char *)(buf + len) = '\0'; } ndev = wdev_to_wlc_ndev(wdev, cfg); index = dhd_net2idx(dhd->info, ndev); if (index == DHD_BAD_IF) { WL_ERR(("Bad ifidx from wdev:%p\n", wdev)); ret = BCME_ERROR; goto done; } ioc.cmd = nlioc->cmd; ioc.len = nlioc->len; ioc.set = nlioc->set; ioc.driver = nlioc->magic; ret = dhd_ioctl_process(dhd, index, &ioc, buf); if (ret) { WL_TRACE(("dhd_ioctl_process return err %d\n", ret)); ret = OSL_ERROR(ret); goto done; } cur = buf; while (ret_len > 0) { msglen = nlioc->len > maxmsglen ? maxmsglen : ret_len; ret_len -= msglen; payload = msglen + sizeof(msglen); reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload); if (!reply) { WL_ERR(("Failed to allocate reply msg\n")); ret = -ENOMEM; break; } if (nla_put(reply, BCM_NLATTR_DATA, msglen, cur) || nla_put_u16(reply, BCM_NLATTR_LEN, msglen)) { kfree_skb(reply); ret = -ENOBUFS; break; } ret = cfg80211_vendor_cmd_reply(reply); if (ret) { WL_ERR(("testmode reply failed:%d\n", ret)); break; } cur += msglen; } done: vfree(buf); DHD_OS_WAKE_UNLOCK(dhd); return ret; }
static int wl_cfgvendor_gscan_get_batch_results(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) { int err = 0; struct wl_priv *cfg = wiphy_priv(wiphy); gscan_results_cache_t *results, *iter; uint32 reply_len, complete = 1; int32 mem_needed, num_results_iter; wifi_gscan_result_t *ptr; uint16 num_scan_ids, num_results; struct sk_buff *skb; struct nlattr *scan_hdr, *complete_flag; err = dhd_dev_wait_batch_results_complete(wl_to_prmry_ndev(cfg)); if (err != BCME_OK) return -EBUSY; err = dhd_dev_pno_lock_access_batch_results(wl_to_prmry_ndev(cfg)); if (err != BCME_OK) { WL_ERR(("Can't obtain lock to access batch results %d\n", err)); return -EBUSY; } results = dhd_dev_pno_get_gscan(wl_to_prmry_ndev(cfg), DHD_PNO_GET_BATCH_RESULTS, NULL, &reply_len); if (!results) { WL_ERR(("No results to send %d\n", err)); err = wl_cfgvendor_send_cmd_reply(wiphy, wl_to_prmry_ndev(cfg), results, 0); if (unlikely(err)) WL_ERR(("Vendor Command reply failed ret:%d \n", err)); dhd_dev_pno_unlock_access_batch_results(wl_to_prmry_ndev(cfg)); return err; } num_scan_ids = reply_len & 0xFFFF; num_results = (reply_len & 0xFFFF0000) >> 16; mem_needed = (num_results * sizeof(wifi_gscan_result_t)) + (num_scan_ids * GSCAN_BATCH_RESULT_HDR_LEN) + VENDOR_REPLY_OVERHEAD + SCAN_RESULTS_COMPLETE_FLAG_LEN; if (mem_needed > (int32)NLMSG_DEFAULT_SIZE) { mem_needed = (int32)NLMSG_DEFAULT_SIZE; complete = 0; } WL_TRACE(("complete %d mem_needed %d max_mem %d\n", complete, mem_needed, (int)NLMSG_DEFAULT_SIZE)); /* Alloc the SKB for vendor_event */ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed); if (unlikely(!skb)) { WL_ERR(("skb alloc failed")); dhd_dev_pno_unlock_access_batch_results(wl_to_prmry_ndev(cfg)); return -ENOMEM; } iter = results; complete_flag = nla_reserve(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, sizeof(complete)); mem_needed = mem_needed - (SCAN_RESULTS_COMPLETE_FLAG_LEN + VENDOR_REPLY_OVERHEAD); while (iter) { num_results_iter = (mem_needed - GSCAN_BATCH_RESULT_HDR_LEN)/sizeof(wifi_gscan_result_t); if (num_results_iter <= 0 || ((iter->tot_count - iter->tot_consumed) > num_results_iter)) break; scan_hdr = nla_nest_start(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS); /* no more room? we are done then (for now) */ if (scan_hdr == NULL) { complete = 0; break; } nla_put_u32(skb, GSCAN_ATTRIBUTE_SCAN_ID, iter->scan_id); nla_put_u8(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, iter->flag); num_results_iter = iter->tot_count - iter->tot_consumed; nla_put_u32(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS, num_results_iter); if (num_results_iter) { ptr = &iter->results[iter->tot_consumed]; iter->tot_consumed += num_results_iter; nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS, num_results_iter * sizeof(wifi_gscan_result_t), ptr); } nla_nest_end(skb, scan_hdr); mem_needed -= GSCAN_BATCH_RESULT_HDR_LEN + (num_results_iter * sizeof(wifi_gscan_result_t)); iter = iter->next; } memcpy(nla_data(complete_flag), &complete, sizeof(complete)); dhd_dev_gscan_batch_cache_cleanup(wl_to_prmry_ndev(cfg)); dhd_dev_pno_unlock_access_batch_results(wl_to_prmry_ndev(cfg)); return cfg80211_vendor_cmd_reply(skb); }
static int wl_cfgvendor_gscan_get_batch_results(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) { int err = 0; struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); gscan_results_cache_t *results, *iter; uint32 reply_len, complete = 0, num_results_iter; int32 mem_needed; wifi_gscan_result_t *ptr; uint16 num_scan_ids, num_results; struct sk_buff *skb; struct nlattr *scan_hdr; dhd_dev_wait_batch_results_complete(bcmcfg_to_prmry_ndev(cfg)); dhd_dev_pno_lock_access_batch_results(bcmcfg_to_prmry_ndev(cfg)); results = dhd_dev_pno_get_gscan(bcmcfg_to_prmry_ndev(cfg), DHD_PNO_GET_BATCH_RESULTS, NULL, &reply_len); if (!results) { WL_ERR(("No results to send %d\n", err)); err = wl_cfgvendor_send_cmd_reply(wiphy, bcmcfg_to_prmry_ndev(cfg), results, 0); if (unlikely(err)) WL_ERR(("Vendor Command reply failed ret:%d \n", err)); dhd_dev_pno_unlock_access_batch_results(bcmcfg_to_prmry_ndev(cfg)); return err; } num_scan_ids = reply_len & 0xFFFF; num_results = (reply_len & 0xFFFF0000) >> 16; mem_needed = (num_results * sizeof(wifi_gscan_result_t)) + (num_scan_ids * GSCAN_BATCH_RESULT_HDR_LEN) + VENDOR_REPLY_OVERHEAD + SCAN_RESULTS_COMPLETE_FLAG_LEN; if (mem_needed > (int32)NLMSG_DEFAULT_SIZE) { mem_needed = (int32)NLMSG_DEFAULT_SIZE; complete = 0; } else { complete = 1; } WL_TRACE(("complete %d mem_needed %d max_mem %d\n", complete, mem_needed, (int)NLMSG_DEFAULT_SIZE)); /* Alloc the SKB for vendor_event */ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed); if (unlikely(!skb)) { WL_ERR(("skb alloc failed")); dhd_dev_pno_unlock_access_batch_results(bcmcfg_to_prmry_ndev(cfg)); return -ENOMEM; } iter = results; nla_put_u32(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, complete); mem_needed = mem_needed - (SCAN_RESULTS_COMPLETE_FLAG_LEN + VENDOR_REPLY_OVERHEAD); while (iter && ((mem_needed - GSCAN_BATCH_RESULT_HDR_LEN) > 0)) { scan_hdr = nla_nest_start(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS); nla_put_u32(skb, GSCAN_ATTRIBUTE_SCAN_ID, iter->scan_id); nla_put_u8(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, iter->flag); num_results_iter = (mem_needed - GSCAN_BATCH_RESULT_HDR_LEN)/sizeof(wifi_gscan_result_t); if ((iter->tot_count - iter->tot_consumed) < num_results_iter) num_results_iter = iter->tot_count - iter->tot_consumed; nla_put_u32(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS, num_results_iter); if (num_results_iter) { ptr = &iter->results[iter->tot_consumed]; iter->tot_consumed += num_results_iter; nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS, num_results_iter * sizeof(wifi_gscan_result_t), ptr); } nla_nest_end(skb, scan_hdr); mem_needed -= GSCAN_BATCH_RESULT_HDR_LEN + (num_results_iter * sizeof(wifi_gscan_result_t)); iter = iter->next; } dhd_dev_gscan_batch_cache_cleanup(bcmcfg_to_prmry_ndev(cfg)); dhd_dev_pno_unlock_access_batch_results(bcmcfg_to_prmry_ndev(cfg)); return cfg80211_vendor_cmd_reply(skb); }
int mtk_cfg80211_vendor_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) { INT_32 i4Status = -EINVAL; struct nlattr *attr; UINT_32 band = 0; UINT_32 num_channel; wifi_channel channels[4]; struct sk_buff *skb; ASSERT(wiphy); ASSERT(wdev); if ((data == NULL) || !data_len) return i4Status; DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); attr = (struct nlattr *)data; if (attr->nla_type == GSCAN_ATTRIBUTE_BAND) band = nla_get_u32(attr); DBGLOG(REQ, INFO, "get channel list: band=%d \r\n", band); skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(wifi_channel) * 4); if (!skb) { DBGLOG(REQ, TRACE, "%s allocate skb failed:%x\n", __func__, i4Status); return -ENOMEM; } kalMemZero(channels, sizeof(wifi_channel) * 4); /*rStatus = kalIoctl(prGlueInfo, wlanoidQueryStatistics, &channel, sizeof(channel), TRUE, TRUE, TRUE, FALSE, &u4BufLen); */ /* only for test */ num_channel = 3; channels[0] = 2412; channels[1] = 2413; channels[2] = 2414; /*NLA_PUT_U32(skb, GSCAN_ATTRIBUTE_NUM_CHANNELS, num_channel);*/ { unsigned int __tmp = num_channel; if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_NUM_CHANNELS, sizeof(unsigned int), &__tmp) < 0)) goto nla_put_failure; } /*NLA_PUT(skb, GSCAN_ATTRIBUTE_CHANNEL_LIST, (sizeof(wifi_channel) * num_channel), channels);*/ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_CHANNEL_LIST, (sizeof(wifi_channel) * num_channel), channels) < 0)) goto nla_put_failure; i4Status = cfg80211_vendor_cmd_reply(skb); return i4Status; nla_put_failure: kfree_skb(skb); return i4Status; }