int dhd_cfg80211_testmode_cmd(struct wiphy *wiphy, void *data, int len) { struct sk_buff *reply; struct wl_priv *wl; dhd_pub_t *dhd; dhd_ioctl_t *ioc = data; int err = 0; WL_TRACE(("entry: cmd = %d\n", ioc->cmd)); wl = wiphy_priv(wiphy); dhd = wl->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); } /* currently there is only one wiphy for ifidx 0 */ err = dhd_ioctl_process(dhd, 0, ioc); if (err) goto done; /* response data is in ioc->buf so return ioc here */ reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*ioc)); nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*ioc), ioc); err = cfg80211_testmode_reply(reply); done: DHD_OS_WAKE_UNLOCK(dhd); return err; }
int dhd_cfg80211_testmode_cmd(struct wiphy *wiphy, void *data, int len) { struct sk_buff *reply; struct wl_priv *wl; dhd_pub_t *dhd; dhd_ioctl_t *ioc = data; int err = 0; WL_TRACE(("entry: cmd = %d\n", ioc->cmd)); wl = wiphy_priv(wiphy); dhd = wl->pub; DHD_OS_WAKE_LOCK(dhd); /* currently there is only one wiphy for ifidx 0 */ err = dhd_ioctl_process(dhd, 0, ioc); if (err) goto done; /* response data is in ioc->buf so return ioc here */ reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*ioc)); nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*ioc), ioc); err = cfg80211_testmode_reply(reply); done: DHD_OS_WAKE_UNLOCK(dhd); return err; }
int dhd_cfg80211_testmode_cmd(struct wiphy *wiphy, void *data, int len) { struct sk_buff *reply; struct wl_priv *wl; dhd_pub_t *dhd; dhd_ioctl_t *ioc = data; int err = 0; WL_TRACE(("entry: cmd = %d\n", ioc->cmd)); wl = wiphy_priv(wiphy); dhd = wl->pub; DHD_OS_WAKE_LOCK(dhd); if (dhd->hang_was_sent) { WL_ERR(("%s: HANG was sent up earlier\n", __FUNCTION__)); DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(dhd, DHD_EVENT_TIMEOUT_MS); DHD_OS_WAKE_UNLOCK(dhd); return OSL_ERROR(BCME_DONGLE_DOWN); } err = dhd_ioctl_process(dhd, 0, ioc); if (err) goto done; reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*ioc)); nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*ioc), ioc); err = cfg80211_testmode_reply(reply); done: DHD_OS_WAKE_UNLOCK(dhd); return err; }
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; }
int dhd_cfg80211_testmode_cmd(struct wiphy *wiphy, void *data, int len) #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */ { struct sk_buff *reply; struct bcm_cfg80211 *cfg; dhd_pub_t *dhd; struct bcm_nlmsg_hdr *nlioc = data; dhd_ioctl_t ioc = { 0 }; int err = 0; void *buf = NULL, *cur; u16 buflen; u16 maxmsglen = PAGE_SIZE - 0x100; bool newbuf = false; int8 index = 0; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) struct net_device *ndev = NULL; #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */ 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); if (nlioc->len > 0) { if (nlioc->len <= len) { buf = (void *)nlioc + nlioc->offset; *(char *)(buf + nlioc->len) = '\0'; } else { if (nlioc->len > DHD_IOCTL_MAXLEN) nlioc->len = DHD_IOCTL_MAXLEN; buf = vzalloc(nlioc->len); if (!buf) return -ENOMEM; newbuf = true; memcpy(buf, (void *)nlioc + nlioc->offset, len); *(char *)(buf + len) = '\0'; } } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 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)); return BCME_ERROR; } #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */ ioc.cmd = nlioc->cmd; ioc.len = nlioc->len; ioc.set = nlioc->set; ioc.driver = nlioc->magic; err = dhd_ioctl_process(dhd, index, &ioc, buf); if (err) { WL_TRACE(("dhd_ioctl_process return err %d\n", err)); err = OSL_ERROR(err); goto done; } cur = buf; while (nlioc->len > 0) { buflen = nlioc->len > maxmsglen ? maxmsglen : nlioc->len; nlioc->len -= buflen; reply = cfg80211_testmode_alloc_reply_skb(wiphy, buflen+4); if (!reply) { WL_ERR(("Failed to allocate reply msg\n")); err = -ENOMEM; break; } if (nla_put(reply, BCM_NLATTR_DATA, buflen, cur) || nla_put_u16(reply, BCM_NLATTR_LEN, buflen)) { kfree_skb(reply); err = -ENOBUFS; break; } do { err = cfg80211_testmode_reply(reply); } while (err == -EAGAIN); if (err) { WL_ERR(("testmode reply failed:%d\n", err)); break; } cur += buflen; } done: if (newbuf) vfree(buf); DHD_OS_WAKE_UNLOCK(dhd); return err; }