Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 716b840c authored by Siva Rebbagondla's avatar Siva Rebbagondla Committed by Kalle Valo
Browse files

rsi: handle BT traffic in driver



BT frames are passed through coex and hal modules to BUS.
After firmware is loaded, based on the operating mode CARD
READY frame comes for each protocol. When BT card ready is
received, BT attach is called.
Protocol operations are exchanged between the modules
at initialization time.
Build flag CONFIG_RSI_COEX is introduced to enable coex support
if CONFIG_BT_RSIHCI is enabled. Coex operations are valid if
coex mode is greater than 1 only.

Signed-off-by: default avatarSiva Rebbagondla <siva.rebbagondla@redpinesignals.com>
Signed-off-by: default avatarPrameela Rani Garnepudi <prameela.j04cs@gmail.com>
Signed-off-by: default avatarAmitkumar Karwar <amit.karwar@redpinesignals.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 38aa4da5
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -43,8 +43,10 @@ static void rsi_coex_sched_tx_pkts(struct rsi_coex_ctrl_block *coex_cb)
		coex_q = rsi_coex_determine_coex_q(coex_cb);
		rsi_dbg(INFO_ZONE, "queue = %d\n", coex_q);

		if (coex_q == RSI_COEX_Q_BT)
		if (coex_q == RSI_COEX_Q_BT) {
			skb = skb_dequeue(&coex_cb->coex_tx_qs[RSI_COEX_Q_BT]);
			rsi_send_bt_pkt(coex_cb->priv, skb);
		}
	} while (coex_q != RSI_COEX_Q_INVALID);
}

+15 −5
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "rsi_mgmt.h"
#include "rsi_common.h"
#include "rsi_hal.h"
#include "rsi_coex.h"

/**
 * rsi_determine_min_weight_queue() - This function determines the queue with
@@ -301,14 +302,23 @@ void rsi_core_qos_processor(struct rsi_common *common)
			mutex_unlock(&common->tx_lock);
			break;
		}

		if (q_num == MGMT_SOFT_Q) {
			status = rsi_send_mgmt_pkt(common, skb);
		} else if (q_num == MGMT_BEACON_Q) {
		if (q_num == MGMT_BEACON_Q) {
			status = rsi_send_pkt_to_bus(common, skb);
			dev_kfree_skb(skb);
		} else {
#ifdef CONFIG_RSI_COEX
			if (common->coex_mode > 1) {
				status = rsi_coex_send_pkt(common, skb,
							   RSI_WLAN_Q);
			} else {
#endif
				if (q_num == MGMT_SOFT_Q)
					status = rsi_send_mgmt_pkt(common, skb);
				else
					status = rsi_send_data_pkt(common, skb);
#ifdef CONFIG_RSI_COEX
			}
#endif
		}

		if (status) {
+39 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

#include <linux/firmware.h>
#include <net/bluetooth/bluetooth.h>
#include "rsi_mgmt.h"
#include "rsi_hal.h"
#include "rsi_sdio.h"
@@ -24,6 +25,7 @@
static struct ta_metadata metadata_flash_content[] = {
	{"flash_content", 0x00010000},
	{"rsi/rs9113_wlan_qspi.rps", 0x00010000},
	{"rsi/rs9113_wlan_bt_dual_mode.rps", 0x00010000},
};

int rsi_send_pkt_to_bus(struct rsi_common *common, struct sk_buff *skb)
@@ -357,6 +359,43 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
	return status;
}

int rsi_send_bt_pkt(struct rsi_common *common, struct sk_buff *skb)
{
	int status = -EINVAL;
	u8 header_size = 0;
	struct rsi_bt_desc *bt_desc;
	u8 queueno = ((skb->data[1] >> 4) & 0xf);

	if (queueno == RSI_BT_MGMT_Q) {
		status = rsi_send_pkt_to_bus(common, skb);
		if (status)
			rsi_dbg(ERR_ZONE, "%s: Failed to write bt mgmt pkt\n",
				__func__);
		goto out;
	}
	header_size = FRAME_DESC_SZ;
	if (header_size > skb_headroom(skb)) {
		rsi_dbg(ERR_ZONE, "%s: Not enough headroom\n", __func__);
		status = -ENOSPC;
		goto out;
	}
	skb_push(skb, header_size);
	memset(skb->data, 0, header_size);
	bt_desc = (struct rsi_bt_desc *)skb->data;

	rsi_set_len_qno(&bt_desc->len_qno, (skb->len - FRAME_DESC_SZ),
			RSI_BT_DATA_Q);
	bt_desc->bt_pkt_type = cpu_to_le16(bt_cb(skb)->pkt_type);

	status = rsi_send_pkt_to_bus(common, skb);
	if (status)
		rsi_dbg(ERR_ZONE, "%s: Failed to write bt pkt\n", __func__);

out:
	dev_kfree_skb(skb);
	return status;
}

int rsi_prepare_beacon(struct rsi_common *common, struct sk_buff *skb)
{
	struct rsi_hw *adapter = (struct rsi_hw *)common->priv;
+46 −3
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <linux/module.h>
#include <linux/firmware.h>
#include <net/rsi_91x.h>
#include "rsi_mgmt.h"
#include "rsi_common.h"
#include "rsi_coex.h"
@@ -35,6 +36,14 @@ u32 rsi_zone_enabled = /* INFO_ZONE |
			0;
EXPORT_SYMBOL_GPL(rsi_zone_enabled);

#ifdef CONFIG_RSI_COEX
static struct rsi_proto_ops g_proto_ops = {
	.coex_send_pkt = rsi_coex_send_pkt,
	.get_host_intf = rsi_get_host_intf,
	.set_bt_context = rsi_set_bt_context,
};
#endif

/**
 * rsi_dbg() - This function outputs informational messages.
 * @zone: Zone of interest for output message.
@@ -144,6 +153,9 @@ int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
	u32 index, length = 0, queueno = 0;
	u16 actual_length = 0, offset;
	struct sk_buff *skb = NULL;
#ifdef CONFIG_RSI_COEX
	u8 bt_pkt_type;
#endif

	index = 0;
	do {
@@ -185,6 +197,25 @@ int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
			rsi_mgmt_pkt_recv(common, (frame_desc + offset));
			break;

#ifdef CONFIG_RSI_COEX
		case RSI_BT_MGMT_Q:
		case RSI_BT_DATA_Q:
#define BT_RX_PKT_TYPE_OFST	14
#define BT_CARD_READY_IND	0x89
			bt_pkt_type = frame_desc[offset + BT_RX_PKT_TYPE_OFST];
			if (bt_pkt_type == BT_CARD_READY_IND) {
				rsi_dbg(INFO_ZONE, "BT Card ready recvd\n");
				if (rsi_bt_ops.attach(common, &g_proto_ops))
					rsi_dbg(ERR_ZONE,
						"Failed to attach BT module\n");
			} else {
				if (common->bt_adapter)
					rsi_bt_ops.recv_pkt(common->bt_adapter,
							frame_desc + offset);
			}
			break;
#endif

		default:
			rsi_dbg(ERR_ZONE, "%s: pkt from invalid queue: %d\n",
				__func__,   queueno);
@@ -232,6 +263,13 @@ enum rsi_host_intf rsi_get_host_intf(void *priv)

	return common->priv->rsi_host_intf;
}

void rsi_set_bt_context(void *priv, void *bt_context)
{
	struct rsi_common *common = (struct rsi_common *)priv;

	common->bt_adapter = bt_context;
}
#endif

/**
@@ -323,13 +361,18 @@ void rsi_91x_deinit(struct rsi_hw *adapter)
	for (ii = 0; ii < NUM_SOFT_QUEUES; ii++)
		skb_queue_purge(&common->tx_queue[ii]);

	common->init_done = false;

#ifdef CONFIG_RSI_COEX
	if (common->coex_mode > 1)
	if (common->coex_mode > 1) {
		if (common->bt_adapter) {
			rsi_bt_ops.detach(common->bt_adapter);
			common->bt_adapter = NULL;
		}
		rsi_coex_detach(common);
	}
#endif

	common->init_done = false;

	kfree(common);
	kfree(adapter->rsi_dev);
	kfree(adapter);
+1 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
 */

#include <linux/firmware.h>
#include <net/rsi_91x.h>
#include "rsi_sdio.h"
#include "rsi_common.h"

Loading