From 6abf032885a507a2439a7049798577cee624168c Mon Sep 17 00:00:00 2001
From: Divya Madhyan <Divya.Madhyan@infineon.com>
Date: Mon, 5 Apr 2021 05:49:50 -0500
Subject: [PATCH] brcmfmac: Frameburst vendor command addition

These set of changes are added to enable frameburst
vendor command support in IW tool.
The vendor send command has to be in the format :
./iw dev wlan0 vendor send 0x001018 0x02 0x0/0x1
The vendor get/query command will be in the format :
./iw dev wlan0 vendor recv 0x001018 0x02 0xff

Signed-off-by: Divya Madhyan <Divya.Madhyan@infineon.com>
Signed-off-by: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
 .../broadcom/brcm80211/brcmfmac/cfg80211.c    |  5 +-
 .../broadcom/brcm80211/brcmfmac/fwil.h        |  1 +
 .../broadcom/brcm80211/brcmfmac/vendor.c      | 64 +++++++++++++++++++
 .../broadcom/brcm80211/brcmfmac/vendor.h      |  1 +
 4 files changed, 67 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index bff790dae..e49c11ef6 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -3349,10 +3349,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
 		pm = PM_OFF;
 	}
 
-	if (cfg->pwr_save)
-		brcmf_set_mpc(ifp, ifp->drvr->req_mpc);
-	else
-		brcmf_set_mpc(ifp, 0);
+	brcmf_set_mpc(ifp, ifp->drvr->req_mpc);
 
 	brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
index 2b205efdc..5547bb6b2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
@@ -71,6 +71,7 @@
 #define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON	201
 #define BRCMF_C_SET_ASSOC_PREFER		205
 #define BRCMF_C_GET_VALID_CHANNELS		217
+#define BRCMF_C_GET_FAKEFRAG                    218
 #define BRCMF_C_SET_FAKEFRAG			219
 #define BRCMF_C_GET_KEY_PRIMARY			235
 #define BRCMF_C_SET_KEY_PRIMARY			236
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
index bf425d2c2..dec1307a0 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
@@ -114,6 +114,60 @@ static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy,
 	return ret;
 }
 
+static int brcmf_cfg80211_vndr_cmds_int_get(struct brcmf_if *ifp,
+					    u32 cmd, struct wiphy *wiphy)
+{
+	struct sk_buff *reply;
+	int get_value = 0;
+	int ret;
+
+	ret = brcmf_fil_cmd_int_get(ifp, cmd, &get_value);
+	if (ret)
+		brcmf_err("Command %u get failure. Error :  %d\n", cmd, ret);
+
+	reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(int));
+	nla_put_nohdr(reply, sizeof(int), &get_value);
+	ret = cfg80211_vendor_cmd_reply(reply);
+	if (ret)
+		brcmf_err("Command %u failure. Error : %d\n", cmd, ret);
+	return ret;
+}
+
+static int brcmf_cfg80211_vndr_cmds_int_set(struct brcmf_if *ifp, int val, u32 cmd)
+{
+	int ret;
+
+	ret = brcmf_fil_cmd_int_set(ifp, cmd, val);
+	if (ret < 0)
+		brcmf_err("Command %u set failure. Error : %d\n", cmd, ret);
+	return ret;
+}
+
+static int brcmf_cfg80211_vndr_cmds_frameburst(struct wiphy *wiphy,
+					       struct wireless_dev *wdev,
+					       const void *data, int len)
+{
+	int ret;
+	int val = *(int *)data;
+	struct brcmf_cfg80211_vif *vif;
+	struct brcmf_if *ifp;
+
+	vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
+	ifp = vif->ifp;
+
+	if (val == 0x0 || val == 0x1)
+		ret = brcmf_cfg80211_vndr_cmds_int_set(ifp, val,
+						       BRCMF_C_SET_FAKEFRAG);
+	else if (val == 0xff)
+		ret = brcmf_cfg80211_vndr_cmds_int_get(ifp,
+						       BRCMF_C_GET_FAKEFRAG,
+						       wiphy);
+	else
+		brcmf_err("Invalid Input\n");
+
+	return ret;
+}
+
 s32
 brcmf_wiphy_phy_temp_evt_handler(struct brcmf_if *ifp,
 				 const struct brcmf_event_msg *e, void *data)
@@ -175,6 +229,16 @@ const struct wiphy_vendor_command brcmf_vendor_cmds[] = {
 		.policy = VENDOR_CMD_RAW_DATA,
 		.doit = brcmf_cfg80211_vndr_cmds_dcmd_handler
 	},
+	{
+		{
+			.vendor_id = BROADCOM_OUI,
+			.subcmd = BRCMF_VNDR_CMDS_FRAMEBURST
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.policy = VENDOR_CMD_RAW_DATA,
+		.doit = brcmf_cfg80211_vndr_cmds_frameburst
+	},
 };
 
 const struct nl80211_vendor_cmd_info brcmf_vendor_events[] = {
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.h
index 3bdf47369..3c691bbe0 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.h
@@ -11,6 +11,7 @@
 enum brcmf_vndr_cmds {
 	BRCMF_VNDR_CMDS_UNSPEC,
 	BRCMF_VNDR_CMDS_DCMD,
+	BRCMF_VNDR_CMDS_FRAMEBURST,
 	BRCMF_VNDR_CMDS_LAST
 };
 
-- 
2.39.5 (Apple Git-154)

