| /* |
| * Linux cfg80211 vendor command/event handlers of DHD |
| * |
| * Copyright (C) 1999-2016, Broadcom Corporation |
| * |
| * Unless you and Broadcom execute a separate written software license |
| * agreement governing use of this software, this software is licensed to you |
| * under the terms of the GNU General Public License version 2 (the "GPL"), |
| * available at http://www.broadcom.com/licenses/GPLv2.php, with the |
| * following added to such license: |
| * |
| * As a special exception, the copyright holders of this software give you |
| * permission to link this software with independent modules, and to copy and |
| * distribute the resulting executable under terms of your choice, provided that |
| * you also meet, for each linked independent module, the terms and conditions of |
| * the license of that module. An independent module is a module which is not |
| * derived from this software. The special exception does not apply to any |
| * modifications of the software. |
| * |
| * Notwithstanding the above, under no circumstances may you combine this |
| * software in any way with any other Broadcom software provided under a license |
| * other than the GPL, without Broadcom's express prior written consent. |
| * |
| * |
| * <<Broadcom-WL-IPTag/Open:>> |
| * |
| * $Id: dhd_cfg_vendor.c 525516 2015-01-09 23:12:53Z $ |
| */ |
| |
| #include <linux/vmalloc.h> |
| #include <linuxver.h> |
| #include <net/cfg80211.h> |
| #include <net/netlink.h> |
| |
| #include <bcmutils.h> |
| #ifdef WL_CFG80211_V1 |
| #include <wl_cfg80211_v1.h> |
| #else |
| #include <wl_cfg80211.h> |
| #endif /* WL_CFG80211_V1 */ |
| #include <wl_cfgvendor.h> |
| #include <dngl_stats.h> |
| #include <dhd.h> |
| #include <dhd_dbg.h> |
| #include <dhdioctl.h> |
| #include <brcm_nl80211.h> |
| |
| #ifdef VENDOR_EXT_SUPPORT |
| int dhd_cfgvendor_priv_string_handler(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev, |
| const struct bcm_nlmsg_hdr *nlioc, void *buf) |
| { |
| struct net_device *ndev = NULL; |
| dhd_pub_t *dhd; |
| dhd_ioctl_t ioc = { 0, NULL, 0, 0, 0, 0, 0}; |
| int ret = 0, err = 0; |
| int8 index; |
| |
| WL_TRACE(("entry: cmd = %d\n", nlioc->cmd)); |
| |
| 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); |
| } |
| |
| index = dhd_ifindex2idx(dhd->info, nlioc->ifindex); |
| if (index == DHD_BAD_IF) { |
| ndev = wdev_to_wlc_ndev(wdev, cfg); |
| index = dhd_net2idx(dhd->info, ndev); |
| if (index == DHD_BAD_IF) { |
| WL_ERR(("Bad ifidx %d, wdev:%p\n", nlioc->ifindex, wdev)); |
| ret = BCME_ERROR; |
| goto done; |
| } |
| } |
| |
| 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) { |
| ret = OSL_ERROR(err); |
| ndev = dhd_idx2net(dhd, index); |
| if(ndev && (ndev->flags & IFF_UP)) { |
| if ((err == BCME_NOTFOUND) || (err == BCME_NOTREADY)) { |
| WL_TRACE(("cmd %d return err %d on %s, ret %d\n", |
| nlioc->cmd, err, ndev->name, ret)); |
| } else { |
| WL_ERR(("cmd %d return err %d on %s, ret %d\n", |
| nlioc->cmd, err, ndev->name, ret)); |
| } |
| } |
| goto done; |
| } |
| |
| done: |
| DHD_OS_WAKE_UNLOCK(dhd); |
| return ret; |
| } |
| const struct wiphy_vendor_command dhd_cfgvendor_cmds [] = { |
| { |
| { |
| .vendor_id = OUI_BRCM, |
| .subcmd = BRCM_VENDOR_SCMD_PRIV_STR |
| }, |
| .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, |
| .doit = dhd_cfgvendor_priv_string_handler |
| }, |
| }; |
| |
| int cfgvendor_attach(struct wiphy *wiphy) |
| { |
| wiphy->vendor_commands = dhd_cfgvendor_cmds; |
| wiphy->n_vendor_commands = ARRAY_SIZE(dhd_cfgvendor_cmds); |
| |
| return 0; |
| } |
| |
| int cfgvendor_detach(struct wiphy *wiphy) |
| { |
| wiphy->vendor_commands = NULL; |
| wiphy->n_vendor_commands = 0; |
| |
| return 0; |
| } |
| #endif /* VENDOR_EXT_SUPPORT */ |