MLK-11065-3 wireless: bcmdhd: make work driver on 3.14 kernel
authorDong Aisheng <b29396@freescale.com>
Mon, 9 Feb 2015 09:40:43 +0000 (17:40 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 19:49:00 +0000 (14:49 -0500)
Add missing file delivered by Broadcom to make driver work on L3.14.y kernel.

Signed-off-by: Dong Aisheng <b29396@freescale.com>
(cherry picked from commit b795547e37c3b68ed019e5d0b9daa3fc6474f623)

drivers/net/wireless/bcmdhd/Makefile
drivers/net/wireless/bcmdhd/wl_cfg80211.c
drivers/net/wireless/bcmdhd/wl_cfgvendor.c [new file with mode: 0644]
drivers/net/wireless/bcmdhd/wl_cfgvendor.h [new file with mode: 0644]

index add38d0..08e805a 100644 (file)
@@ -167,7 +167,7 @@ DHDOFILES := dhd_pno.o dhd_common.o dhd_ip.o dhd_custom_gpio.o \
        dhd_linux.o dhd_linux_sched.o dhd_cfg80211.o dhd_linux_wq.o aiutils.o bcmevent.o \
        bcmutils.o bcmwifi_channels.o hndpmu.o linux_osl.o sbutils.o siutils.o \
        wl_android.o wl_cfg80211.o wl_cfgp2p.o wl_cfg_btcoex.o wldev_common.o wl_linux_mon.o  \
-       dhd_linux_platdev.o dhd_pno.o dhd_linux_wq.o wl_cfg_btcoex.o
+       dhd_linux_platdev.o dhd_pno.o dhd_linux_wq.o wl_cfg_btcoex.o wl_cfgvendor.o
 
 ifneq ($(CONFIG_BCMDHD_SDIO),)
   DHDOFILES += bcmsdh.o bcmsdh_linux.o bcmsdh_sdmmc.o bcmsdh_sdmmc_linux.o
index f92dca6..3fec4c8 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux cfg80211 driver
  *
- * Copyright (C) 1999-2014, Broadcom Corporation
+ * Copyright (C) 1999-2015, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -7715,23 +7715,29 @@ wl_notify_connect_status_ap(struct bcm_cfg80211 *cfg, struct net_device *ndev,
        isfree = true;
 
        if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
+                cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, 0, GFP_ATOMIC);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
                cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC);
 #else
                cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
-#endif 
+#endif /* KERNEL VERSION 3, 12 */ 
        } else if (event == WLC_E_DISASSOC_IND) {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
+                cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, 0, GFP_ATOMIC);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
                cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC);
 #else
                cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
-#endif 
+#endif /* version 3.12*/ 
        } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
+                cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, 0, GFP_ATOMIC);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
                cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC);
 #else
                cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
-#endif 
+#endif /* version 3.12 */
        }
 
 exit:
@@ -8777,14 +8783,14 @@ wl_notify_rx_mgmt_frame(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
        WL_DBG((" device name is ndev %s \n", ndev->name));
 #endif
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
        retval = cfg80211_rx_mgmt(cfgdev, freq, 0,  mgmt_frame, mgmt_frame_len, 0, GFP_ATOMIC);
 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) || \
        defined(WL_COMPAT_WIRELESS)
        retval = cfg80211_rx_mgmt(cfgdev, freq, 0, mgmt_frame, mgmt_frame_len, GFP_ATOMIC);
 #else
        retval = cfg80211_rx_mgmt(cfgdev, freq, mgmt_frame, mgmt_frame_len, GFP_ATOMIC);
-#endif /* LINUX_VERSION >= VERSION(3, 14, 0) */
+#endif /* LINUX_VERSION >= VERSION(3, 12, 0) */
 
        WL_DBG(("mgmt_frame_len (%d) , e->datalen (%d), channel (%d), freq (%d) retval (%d)\n",
                mgmt_frame_len, ntoh32(e->datalen), channel, freq, retval));
@@ -11349,7 +11355,11 @@ wl_tdls_event_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                break;
        case WLC_E_TDLS_PEER_CONNECTED :
                if (cfg->tdls_mgmt_frame) {
-                       #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) || defined(WL_COMPAT_WIRELESS)
+                       #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
+                                cfg80211_rx_mgmt(cfgdev, cfg->tdls_mgmt_freq, 0,
+                                       cfg->tdls_mgmt_frame, cfg->tdls_mgmt_frame_len,
+                                        0, GFP_ATOMIC);
+                       #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) || defined(WL_COMPAT_WIRELESS)
                                cfg80211_rx_mgmt(cfgdev, cfg->tdls_mgmt_freq, 0,
                                        cfg->tdls_mgmt_frame, cfg->tdls_mgmt_frame_len,
                                        GFP_ATOMIC);
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgvendor.c b/drivers/net/wireless/bcmdhd/wl_cfgvendor.c
new file mode 100644 (file)
index 0000000..16b9388
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Linux cfg80211 Vendor Extension Code
+ *
+ * Copyright (C) 1999-2015, 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.
+ *
+ * $Id: wl_cfgvendor.c 455257 2014-02-13 08:10:24Z $
+*/
+
+/*
+ * New vendor interface additon to nl80211/cfg80211 to allow vendors
+ * to implement proprietary features over the cfg80211 stack.
+*/
+
+#include <typedefs.h>
+#include <linuxver.h>
+#include <osl.h>
+#include <linux/kernel.h>
+
+#include <bcmutils.h>
+#include <bcmwifi_channels.h>
+#include <bcmendian.h>
+#include <proto/ethernet.h>
+#include <proto/802.11.h>
+#include <linux/if_arp.h>
+#include <asm/uaccess.h>
+
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhdioctl.h>
+#include <wlioctl.h>
+#include <dhd_cfg80211.h>
+#ifdef PNO_SUPPORT
+#include <dhd_pno.h>
+#endif /* PNO_SUPPORT */
+
+#include <proto/ethernet.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/netdevice.h>
+#include <linux/sched.h>
+#include <linux/etherdevice.h>
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <linux/wait.h>
+#include <net/cfg80211.h>
+#include <net/rtnetlink.h>
+
+#include <wlioctl.h>
+#include <wldev_common.h>
+#include <wl_cfg80211.h>
+#include <wl_cfgp2p.h>
+#include <wl_android.h>
+#include <wl_cfgvendor.h>
+#ifdef PROP_TXSTATUS
+#include <dhd_wlfc.h>
+#endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT)
+/*
+ * 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 wl_cfgvendor_send_cmd_reply should
+ * be used).
+ */
+int wl_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 = cfg80211_vendor_event_alloc(wiphy, len, event_id, kflags);
+       if (!skb) {
+               WL_ERR(("skb alloc failed"));
+               return -ENOMEM;
+       }
+
+       /* Push the data to the skb */
+       nla_put_nohdr(skb, len, data);
+
+       cfg80211_vendor_event(skb, kflags);
+
+       return 0;
+}
+
+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);
+}
+
+static int wl_cfgvendor_priv_string_handler(struct wiphy *wiphy,
+       struct wireless_dev *wdev, const void  *data, int len)
+{
+       struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+       int err = 0;
+       int data_len = 0;
+
+       WL_INFO(("%s: Enter \n", __func__));
+
+       bzero(cfg->ioctl_buf, WLC_IOCTL_MAXLEN);
+
+       if (strncmp((char *)data, BRCM_VENDOR_SCMD_CAPA, strlen(BRCM_VENDOR_SCMD_CAPA)) == 0) {
+               err = wldev_iovar_getbuf(bcmcfg_to_prmry_ndev(cfg), "cap", NULL, 0,
+                       cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
+               if (unlikely(err)) {
+                       WL_ERR(("error (%d)\n", err));
+                       return err;
+               }
+               data_len = strlen(cfg->ioctl_buf);
+               cfg->ioctl_buf[data_len] = '\0';
+       }
+
+       err =  wl_cfgvendor_send_cmd_reply(wiphy, bcmcfg_to_prmry_ndev(cfg),
+               cfg->ioctl_buf, data_len+1);
+       if (unlikely(err))
+               WL_ERR(("Vendor Command reply failed ret:%d \n", err));
+       else
+               WL_INFO(("Vendor Command reply sent successfully!\n"));
+
+       return err;
+}
+
+static const struct wiphy_vendor_command wl_vendor_cmds [] = {
+       {
+               {
+                       .vendor_id = OUI_BRCM,
+                       .subcmd = BRCM_VENDOR_SCMD_PRIV_STR
+               },
+               .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+               .doit = wl_cfgvendor_priv_string_handler
+       },
+};
+
+static const struct  nl80211_vendor_cmd_info wl_vendor_events [] = {
+               { OUI_BRCM, BRCM_VENDOR_EVENT_UNSPEC },
+               { OUI_BRCM, BRCM_VENDOR_EVENT_PRIV_STR },
+};
+
+int wl_cfgvendor_attach(struct wiphy *wiphy)
+{
+
+       WL_INFO(("Vendor: Register BRCM cfg80211 vendor cmd(0x%x) interface \n",
+               NL80211_CMD_VENDOR));
+
+       wiphy->vendor_commands  = wl_vendor_cmds;
+       wiphy->n_vendor_commands = ARRAY_SIZE(wl_vendor_cmds);
+       wiphy->vendor_events    = wl_vendor_events;
+       wiphy->n_vendor_events  = ARRAY_SIZE(wl_vendor_events);
+
+       return 0;
+}
+
+int wl_cfgvendor_detach(struct wiphy *wiphy)
+{
+       WL_INFO(("Vendor: Unregister BRCM cfg80211 vendor interface \n"));
+
+       wiphy->vendor_commands  = NULL;
+       wiphy->vendor_events    = NULL;
+       wiphy->n_vendor_commands = 0;
+       wiphy->n_vendor_events  = 0;
+
+       return 0;
+}
+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT) */
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgvendor.h b/drivers/net/wireless/bcmdhd/wl_cfgvendor.h
new file mode 100644 (file)
index 0000000..4ac8bb0
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Linux cfg80211 Vendor Extension Code
+ *
+ * Copyright (C) 1999-2015, 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.
+ *
+ * $Id: wl_cfgvendor.h 455257 2014-02-13 08:10:24Z $
+ */
+
+/*
+ * New vendor interface additon to nl80211/cfg80211 to allow vendors
+ * to implement proprietary features over the cfg80211 stack.
+ */
+
+#ifndef _wl_cfgvendor_h_
+#define _wl_cfgvendor_h_
+
+#define OUI_BRCM  0x001018
+#define BRCM_VENDOR_SUBCMD_PRIV_STR    1
+
+enum wl_vendor_subcmd {
+       BRCM_VENDOR_SCMD_UNSPEC,
+       BRCM_VENDOR_SCMD_PRIV_STR
+};
+
+enum wl_vendor_event {
+       BRCM_VENDOR_EVENT_UNSPEC,
+       BRCM_VENDOR_EVENT_PRIV_STR
+};
+
+/* Capture the BRCM_VENDOR_SUBCMD_PRIV_STRINGS* here */
+#define BRCM_VENDOR_SCMD_CAPA  "cap"
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT)
+extern int wl_cfgvendor_attach(struct wiphy *wiphy);
+extern int wl_cfgvendor_detach(struct wiphy *wiphy);
+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT) */
+
+#endif /* _wl_cfgvendor_h_ */