From 1389fc3ce6787af145d0851ba5a4931bd8d72b23 Mon Sep 17 00:00:00 2001
From: Arend van Spriel <arend@broadcom.com>
Date: Sat, 29 Nov 2014 16:31:44 +0100
Subject: [PATCH] brcmsmac: obtain more btcoex related details

Added initial btcoex module for supporting bcm4313 combo chips. For
now it just detects the btcoex support and flavours.

Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmsmac/Makefile   |   1 +
 drivers/net/wireless/brcm80211/brcmsmac/btcoex.c   | 114 +++++++++++++++++++++
 drivers/net/wireless/brcm80211/brcmsmac/btcoex.h   |  25 +++++
 drivers/net/wireless/brcm80211/brcmsmac/d11.h      |   2 +-
 drivers/net/wireless/brcm80211/brcmsmac/main.c     |   5 +
 drivers/net/wireless/brcm80211/brcmsmac/main.h     |   1 +
 drivers/net/wireless/brcm80211/brcmsmac/types.h    |   3 +-
 .../net/wireless/brcm80211/include/chipcommon.h    |   2 +
 8 files changed, 151 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/btcoex.c
 create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/btcoex.h

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
index 32464ac..aa341bb 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
@@ -26,6 +26,7 @@ brcmsmac-y := \
 	ucode_loader.o \
 	ampdu.o \
 	antsel.o \
+	btcoex.o \
 	channel.o \
 	main.o \
 	phy_shim.o \
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/btcoex.c b/drivers/net/wireless/brcm80211/brcmsmac/btcoex.c
new file mode 100644
index 0000000..01cd10d
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/btcoex.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2014 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/types.h>
+#include <net/mac80211.h>
+
+#include <chipcommon.h>
+#include "types.h"
+#include "debug.h"
+#include "btcoex.h"
+#include "main.h"
+
+struct brcms_btcoex {
+	struct brcms_hardware *hw;
+};
+
+static bool brcms_btc_ecicoex_enab(struct brcms_hardware *wlc_hw)
+{
+	struct bcma_bus *bus;
+	bool enab;
+
+	enab = brcms_btc_ecicoex_enab(wlc_hw);
+	if (!enab)
+		return false;
+
+	bus = wlc_hw->d11core->bus;
+	enab = D11REV_GE(wlc_hw->corerev, 15) &&
+	       (bus->drv_cc.capabilities & CC_CAP_ECI) &&
+	       (wlc_hw->machwcap & MCAP_BTCX) &&
+	       (wlc_hw->boardflags & BFL_BTCOEX) &&
+	       (wlc_hw->boardflags2 & BFL2_LEGACY) &&
+	       !(bus->drv_cc.capabilities_ext & CC_CAP2_SECI);
+
+	return enab;
+}
+
+static bool brcms_btc_secicoex_enab(struct brcms_hardware *wlc_hw)
+{
+	struct bcma_bus *bus;
+	bool enab;
+
+	bus = wlc_hw->d11core->bus;
+	enab = (wlc_hw->boardflags & BFL_BTCOEX) &&
+	       (wlc_hw->boardflags2 & BFL2_LEGACY) &&
+	       (bus->drv_cc.capabilities_ext & CC_CAP2_SECI) &&
+	       (wlc_hw->machwcap & MCAP_BTCX);
+
+	return enab;
+}
+
+static bool brcms_btc_gcicoex_enab(struct brcms_hardware *wlc_hw)
+{
+	struct bcma_bus *bus;
+	bool enab;
+
+	bus = wlc_hw->d11core->bus;
+	enab = (wlc_hw->boardflags & BFL_BTCOEX) &&
+	       (wlc_hw->boardflags2 & BFL2_LEGACY) &&
+	       (bus->drv_cc.capabilities_ext & CC_CAP_EXT_GCI_PRESENT) &&
+	       (wlc_hw->machwcap & MCAP_BTCX);
+
+	return enab;
+}
+
+static bool brcms_btc_coex_enab(struct brcms_hardware *wlc_hw)
+{
+	bool enab;
+
+	enab = brcms_btc_ecicoex_enab(wlc_hw) ||
+	       brcms_btc_secicoex_enab(wlc_hw) ||
+	       brcms_btc_gcicoex_enab(wlc_hw);
+
+	return enab;
+}
+
+struct brcms_btcoex *brcms_btcoex_attach(struct brcms_hardware *wlc_hw)
+{
+	struct brcms_btcoex *btc;
+
+	if (!brcms_btc_coex_enab(wlc_hw)) {
+		brcms_err(wlc_hw->d11core, "no btcoex supported\n");
+		return NULL;
+	}
+	btc = kzalloc(sizeof(*btc), GFP_KERNEL);
+	if (!btc)
+		return NULL;
+
+	btc->hw = wlc_hw;
+
+	brcms_err(wlc_hw->d11core, "hardware:%s%s%s\n",
+		  brcms_btc_ecicoex_enab(wlc_hw) ? " ECI" : "",
+		  brcms_btc_secicoex_enab(wlc_hw) ? " SECI" : "",
+		  brcms_btc_gcicoex_enab(wlc_hw) ? " GCI" : "");
+
+	return btc;
+}
+
+void brcms_btcoex_detach(struct brcms_btcoex *btc)
+{
+	kfree(btc);
+}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/btcoex.h b/drivers/net/wireless/brcm80211/brcmsmac/btcoex.h
new file mode 100644
index 0000000..92032d8
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/btcoex.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef _BRCMS_BTCOEX_H_
+#define _BRCMS_BTCOEX_H_
+
+struct brcms_btcoex;
+
+struct brcms_btcoex *brcms_btcoex_attach(struct brcms_hardware *wlc_hw);
+void brcms_btcoex_detach(struct brcms_btcoex *btc);
+
+#endif /* _BRCMS_BTCOEX_H_ */
+
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/d11.h b/drivers/net/wireless/brcm80211/brcmsmac/d11.h
index 9035cc4..a4754f8 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/d11.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/d11.h
@@ -548,7 +548,7 @@ struct d11regs {
 /* Mac capabilities registers */
 /*== machwcap ==*/
 #define	MCAP_TKIPMIC		0x80000000	/* TKIP MIC hardware present */
-
+#define MCAP_BTCX               0x20000000      /* BT coex hardware present */
 /*== pmqhost data ==*/
 /* data entry of head pmq entry */
 #define	PMQH_DATA_MASK		0xffff0000
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index bc9be78..fbb8b83 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -33,6 +33,7 @@
 #include "ampdu.h"
 #include "mac80211_if.h"
 #include "ucode_loader.h"
+#include "btcoex.h"
 #include "main.h"
 #include "soc.h"
 #include "dma.h"
@@ -4665,6 +4666,8 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
 		}
 	}
 
+	wlc_hw->btc = brcms_btcoex_attach(wlc_hw);
+
 	/* disable core to match driver "down" state */
 	brcms_c_coredisable(wlc_hw);
 
@@ -4856,6 +4859,8 @@ static void brcms_b_detach(struct brcms_c_info *wlc)
 
 	wlc_phy_shim_detach(wlc_hw->physhim);
 
+	brcms_btcoex_detach(wlc_hw->btc);
+
 	if (wlc_hw->sih) {
 		ai_detach(wlc_hw->sih);
 		wlc_hw->sih = NULL;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h
index c4d135c..1089264 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
@@ -376,6 +376,7 @@ struct brcms_hardware {
 				 * put struct antsel_info here if more info is
 				 * needed
 				 */
+	struct brcms_btcoex *btc;
 };
 
 /*
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/types.h b/drivers/net/wireless/brcm80211/brcmsmac/types.h
index ae1f3ad..ac8e3df 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/types.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h
@@ -26,7 +26,8 @@
 #define WL_CHAN_FREQ_RANGE_5GH     3
 
 /* boardflags */
-
+/* Board supports BTCOEX */
+#define BFL_BTCOEX		0x00000001
 /* Board has gpio 9 controlling the PA */
 #define	BFL_PACTRL		0x00000002
 /* Not ok to power down the chip pll and oscillator */
diff --git a/drivers/net/wireless/brcm80211/include/chipcommon.h b/drivers/net/wireless/brcm80211/include/chipcommon.h
index d242333..d2d424c 100644
--- a/drivers/net/wireless/brcm80211/include/chipcommon.h
+++ b/drivers/net/wireless/brcm80211/include/chipcommon.h
@@ -254,6 +254,7 @@ struct chipcregs {
 #define CC_CAP_ROM		0x00800000	/* Internal boot rom active */
 #define CC_CAP_BKPLN64		0x08000000	/* 64-bit backplane */
 #define	CC_CAP_PMU		0x10000000	/* PMU Present, rev >= 20 */
+#define CC_CAP_ECI              0x20000000      /* ECI Present, rev >= 21 */
 #define	CC_CAP_SROM		0x40000000	/* Srom Present, rev >= 32 */
 /* Nand flash present, rev >= 35 */
 #define	CC_CAP_NFLASH		0x80000000
@@ -261,6 +262,7 @@ struct chipcregs {
 #define	CC_CAP2_SECI		0x00000001	/* SECI Present, rev >= 36 */
 /* GSIO (spi/i2c) present, rev >= 37 */
 #define	CC_CAP2_GSIO		0x00000002
+#define CC_CAP_EXT_GCI_PRESENT  0x00000004    /* GCI present */
 
 /* pmucapabilities */
 #define PCAP_REV_MASK	0x000000ff
-- 
1.9.1

