From ac7850295c248eb8209e5687218dce127ddc6091 Mon Sep 17 00:00:00 2001
From: "Angus Ainslie (Purism)" <angus@akkea.ca>
Date: Tue, 10 Sep 2019 09:40:10 -0700
Subject: [PATCH] net: wireless: redpine: Add the antenna diversity patch

To enable the diversity set the module parameter antenna_diversity=1

insmod rsi_91x.ko rsi_zone_enabled=1 dev_oper_mode=13 antenna_diversity=1

Signed-off-by: Angus Ainslie (Purism) <angus@akkea.ca>
---
 .../net/wireless/redpine/rsi_91x_mac80211.c   | 33 ++++++++++++++++++-
 drivers/net/wireless/redpine/rsi_91x_main.c   | 13 ++++++++
 drivers/net/wireless/redpine/rsi_main.h       |  4 +++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/redpine/rsi_91x_mac80211.c b/drivers/net/wireless/redpine/rsi_91x_mac80211.c
index 182b574d95f00..3945772510d4b 100644
--- a/drivers/net/wireless/redpine/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/redpine/rsi_91x_mac80211.c
@@ -399,6 +399,26 @@ static void rsi_set_min_rate(struct ieee80211_hw *hw,
 	rsi_dbg(INFO_ZONE, "Min Rate = %d\n", common->min_rate);
 }
 
+static void rsi_trigger_antenna_change(struct rsi_common *common)
+{
+	common->rsi_scan_count++;
+	if (common->rsi_scan_count > MAX_SCAN_PER_ANTENNA) {
+		common->rsi_scan_count = 0;
+		if (common->ant_in_use == ANTENNA_SEL_INT)
+			common->obm_ant_sel_val = ANTENNA_SEL_UFL;
+		else
+			common->obm_ant_sel_val = ANTENNA_SEL_INT;
+		if (rsi_set_antenna(common, common->obm_ant_sel_val)) {
+			rsi_dbg(ERR_ZONE, "Failed to change antenna to %d\n",
+				common->obm_ant_sel_val);
+		} else {
+			rsi_dbg(ERR_ZONE, "Antenna is changed to %d\n",
+				common->obm_ant_sel_val);
+			common->ant_in_use = common->obm_ant_sel_val;
+		}
+	}
+	return;
+}
 
 #ifdef CONFIG_REDPINE_HW_SCAN_OFFLOAD
 #define MAX_HW_SCAN_SSID 1
@@ -433,11 +453,17 @@ static int rsi_mac80211_hw_scan_start(struct ieee80211_hw *hw,
 	mutex_lock(&common->mutex);
 
 	if (!bss->assoc) {
+		if (common->antenna_diversity)
+			rsi_trigger_antenna_change(common);
+
 		common->scan_request = scan_req;
 		common->scan_vif = vif;
 		common->scan_in_prog = false;
 		queue_work(common->scan_workqueue, &common->scan_work);
 	} else {
+		/* Upon connection, make scan count to 0 */
+		common->rsi_scan_count = 0;
+
 		/* Wait for EAPOL4 completion before starting bg scan */
 		if ((bss->assoc_capability & BIT(4))) {	
 			if (!common->start_bgscan) {
@@ -2318,9 +2344,14 @@ static void rsi_mac80211_sw_scan_start(struct ieee80211_hw *hw,
 
 	if (common->p2p_enabled)
 		return;
-	if (!bss->assoc)
+	if (!bss->assoc) {
+		if (common->antenna_diversity)
+			rsi_trigger_antenna_change(common);
 		return;
+	}
 
+	/* Upon connection, make scan count to 0 */
+	common->rsi_scan_count = 0;
 	mutex_lock(&common->mutex);
 
 	if (!rsi_send_bgscan_params(common, 1)) {
diff --git a/drivers/net/wireless/redpine/rsi_91x_main.c b/drivers/net/wireless/redpine/rsi_91x_main.c
index bb259f6b79950..3233568221b2f 100644
--- a/drivers/net/wireless/redpine/rsi_91x_main.c
+++ b/drivers/net/wireless/redpine/rsi_91x_main.c
@@ -75,12 +75,14 @@ bool host_intf_on_demand;
  * Default sleep clock derivation source is RC clock.
  */
 bool crystal_as_sleep_clk;
+bool antenna_diversity;
 u16 feature_bitmap_9116;
 u8 bt_rf_type = 0x01;
 u8 ble_tx_pwr_inx =  0x1E;
 u8 ble_pwr_save_options = 0x02;
 u8 bt_rf_tx_power_mode;
 u8 bt_rf_rx_power_mode;
+u8 antenna_sel = ANTENNA_SEL_UFL;
 
 module_param(bt_rf_type, byte, 0);
 module_param(ble_tx_pwr_inx, byte, 0);
@@ -125,6 +127,14 @@ module_param(crystal_as_sleep_clk, bool, 0);
 MODULE_PARM_DESC(crystal_as_sleep_clk, "\nSleep clock selection (0) RC clock \
 as sleep clock (1) 32KHz crystal as sleep clock\n");
 
+module_param(antenna_diversity, bool, 0);
+MODULE_PARM_DESC(antenna_diversity, "\n Anetanna diversity selection(Only for \
+STA mode).\n '0' for disable and '1' for enable\n");
+
+module_param(antenna_sel, byte, 0);
+MODULE_PARM_DESC(antenna_sel, "\n Antenna selection. '2' for  intenal antenna \
+and '3' for External antenna\n");
+
 module_param(feature_bitmap_9116, ushort, 0);
 MODULE_PARM_DESC(feature_bitmap_9116, "\n9116 Feature Bitmap BIT(0) 0: AGC_PD \
 Enable, 1: AGC_PD Disable BIT(7:1) Reserved\n");
@@ -599,6 +609,8 @@ struct rsi_hw *rsi_91x_init(void)
 	common->feature_bitmap_9116 = feature_bitmap_9116;
 	common->host_intf_on_demand = host_intf_on_demand;
 	common->bt_rf_type = bt_rf_type;
+	common->obm_ant_sel_val = antenna_sel;
+	common->antenna_diversity = antenna_diversity;
 	common->ble_tx_pwr_inx = ble_tx_pwr_inx;
 	common->ble_pwr_save_options = ble_pwr_save_options;
 	common->bt_rf_tx_power_mode = bt_rf_tx_power_mode;
@@ -622,6 +634,7 @@ struct rsi_hw *rsi_91x_init(void)
 	rsi_default_ps_params(adapter);
 	spin_lock_init(&adapter->ps_lock);
 	common->uapsd_bitmap = 0;
+	common->rsi_scan_count = 0;
 
 	/* BGScan related */
 	init_bgscan_params(common);
diff --git a/drivers/net/wireless/redpine/rsi_main.h b/drivers/net/wireless/redpine/rsi_main.h
index db9c7df8dacbd..c70e6c33b7590 100644
--- a/drivers/net/wireless/redpine/rsi_main.h
+++ b/drivers/net/wireless/redpine/rsi_main.h
@@ -72,6 +72,9 @@ struct rsi_hw;
 #define ACS_TIMEOUT_TYPE	15
 #define ACS_TIMEOUT_TIME	150
 
+/* Antenna Diversity */
+#define MAX_SCAN_PER_ANTENNA		2
+
 extern u16 rsi_zone_enabled;
 extern __printf(2, 3) void rsi_dbg(u32 zone, const char *fmt, ...);
 void rsi_hex_dump(u32 zone, char *msg_str, const u8 *msg, u32 len);
@@ -521,6 +524,7 @@ struct rsi_common {
 	u8 bt_rf_tx_power_mode;
 	u8 bt_rf_rx_power_mode;
 	u8 load_image_no;
+	u8 rsi_scan_count;
 };
 
 enum host_intf {
-- 
GitLab