Commit d26a9559 authored by Prameela Rani Garnepudi's avatar Prameela Rani Garnepudi Committed by Kalle Valo
Browse files

rsi: add beacon changes for AP mode



Mac80211 config parameter BEACON_ENABLE is handled. When VAP
capabilities frame with AP mode is configured to firmware, beacon
events start coming to host at each PreTBTT. At this time, beacon
is taken from mac80211, descriptor is prepared and send to firmware.

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 75ca0049
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#include "rsi_mgmt.h"
#include "rsi_common.h"
#include "rsi_hal.h"

/**
 * rsi_determine_min_weight_queue() - This function determines the queue with
@@ -136,6 +137,10 @@ static u8 rsi_core_determine_hal_queue(struct rsi_common *common)
	u8 q_num = INVALID_QUEUE;
	u8 ii = 0;

	if (skb_queue_len(&common->tx_queue[MGMT_BEACON_Q])) {
		q_num = MGMT_BEACON_Q;
		return q_num;
	}
	if (skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])) {
		if (!common->mgmt_q_block)
			q_num = MGMT_SOFT_Q;
@@ -291,10 +296,14 @@ void rsi_core_qos_processor(struct rsi_common *common)
			break;
		}

		if (q_num == MGMT_SOFT_Q)
		if (q_num == MGMT_SOFT_Q) {
			status = rsi_send_mgmt_pkt(common, skb);
		else
		} else if (q_num == MGMT_BEACON_Q) {
			status = rsi_send_pkt_to_bus(common, skb);
			dev_kfree_skb(skb);
		} else {
			status = rsi_send_data_pkt(common, skb);
		}

		if (status) {
			mutex_unlock(&common->tx_lock);
@@ -358,7 +367,7 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
		tx_params->sta_id = 0;
	}

	if ((q_num != MGMT_SOFT_Q) &&
	if ((q_num < MGMT_SOFT_Q) &&
	    ((skb_queue_len(&common->tx_queue[q_num]) + 1) >=
	     DATA_QUEUE_WATER_MARK)) {
		rsi_dbg(ERR_ZONE, "%s: sw queue full\n", __func__);
+64 −1
Original line number Diff line number Diff line
@@ -25,7 +25,15 @@ static struct ta_metadata metadata_flash_content[] = {
	{"rsi/rs9113_wlan_qspi.rps", 0x00010000},
};

/*This function prepares descriptor for given management packet*/
int rsi_send_pkt_to_bus(struct rsi_common *common, struct sk_buff *skb)
{
	struct rsi_hw *adapter = common->priv;
	int status;

	status = adapter->host_intf_ops->write_pkt(common->priv,
						   skb->data, skb->len);
	return status;
}

static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
{
@@ -306,6 +314,61 @@ err:
	return status;
}

int rsi_prepare_beacon(struct rsi_common *common, struct sk_buff *skb)
{
	struct rsi_hw *adapter = (struct rsi_hw *)common->priv;
	struct rsi_data_desc *bcn_frm;
	struct ieee80211_hw *hw = common->priv->hw;
	struct ieee80211_conf *conf = &hw->conf;
	struct sk_buff *mac_bcn;
	u8 vap_id = 0;
	u16 tim_offset;

	mac_bcn = ieee80211_beacon_get_tim(adapter->hw,
					   adapter->vifs[adapter->sc_nvifs - 1],
					   &tim_offset, NULL);
	if (!mac_bcn) {
		rsi_dbg(ERR_ZONE, "Failed to get beacon from mac80211\n");
		return -EINVAL;
	}

	common->beacon_cnt++;
	bcn_frm = (struct rsi_data_desc *)skb->data;
	rsi_set_len_qno(&bcn_frm->len_qno, mac_bcn->len, RSI_WIFI_DATA_Q);
	bcn_frm->header_len = MIN_802_11_HDR_LEN;
	bcn_frm->frame_info = cpu_to_le16(RSI_DATA_DESC_MAC_BBP_INFO |
					  RSI_DATA_DESC_NO_ACK_IND |
					  RSI_DATA_DESC_BEACON_FRAME |
					  RSI_DATA_DESC_INSERT_TSF |
					  RSI_DATA_DESC_INSERT_SEQ_NO |
					  RATE_INFO_ENABLE);
	bcn_frm->rate_info = cpu_to_le16(vap_id << 14);
	bcn_frm->qid_tid = BEACON_HW_Q;

	if (conf_is_ht40_plus(conf)) {
		bcn_frm->bbp_info = cpu_to_le16(LOWER_20_ENABLE);
		bcn_frm->bbp_info |= cpu_to_le16(LOWER_20_ENABLE >> 12);
	} else if (conf_is_ht40_minus(conf)) {
		bcn_frm->bbp_info = cpu_to_le16(UPPER_20_ENABLE);
		bcn_frm->bbp_info |= cpu_to_le16(UPPER_20_ENABLE >> 12);
	}

	if (common->band == NL80211_BAND_2GHZ)
		bcn_frm->bbp_info |= cpu_to_le16(RSI_RATE_1);
	else
		bcn_frm->bbp_info |= cpu_to_le16(RSI_RATE_6);

	if (mac_bcn->data[tim_offset + 2] == 0)
		bcn_frm->frame_info |= cpu_to_le16(RSI_DATA_DESC_DTIM_BEACON);

	memcpy(&skb->data[FRAME_DESC_SZ], mac_bcn->data, mac_bcn->len);
	skb_put(skb, mac_bcn->len + FRAME_DESC_SZ);

	dev_kfree_skb(mac_bcn);

	return 0;
}

static void bl_cmd_timeout(unsigned long priv)
{
	struct rsi_hw *adapter = (struct rsi_hw *)priv;
+12 −0
Original line number Diff line number Diff line
@@ -652,6 +652,18 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
			common->cqm_info.rssi_thold,
			common->cqm_info.rssi_hyst);
	}

	if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
	    (vif->type == NL80211_IFTYPE_AP)) {
		if (bss->enable_beacon) {
			rsi_dbg(INFO_ZONE, "===> BEACON ENABLED <===\n");
			common->beacon_enabled = 1;
		} else {
			rsi_dbg(INFO_ZONE, "===> BEACON DISABLED <===\n");
			common->beacon_enabled = 0;
		}
	}

	mutex_unlock(&common->mutex);
}

+43 −5
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include "rsi_mgmt.h"
#include "rsi_common.h"
#include "rsi_ps.h"
#include "rsi_hal.h"

static struct bootup_params boot_params_20 = {
	.magic_number = cpu_to_le16(0x5aa5),
@@ -1518,6 +1519,31 @@ int rsi_set_antenna(struct rsi_common *common, u8 antenna)
	return rsi_send_internal_mgmt_frame(common, skb);
}

static int rsi_send_beacon(struct rsi_common *common)
{
	struct sk_buff *skb = NULL;
	u8 dword_align_bytes = 0;

	skb = dev_alloc_skb(MAX_MGMT_PKT_SIZE);
	if (!skb)
		return -ENOMEM;

	memset(skb->data, 0, MAX_MGMT_PKT_SIZE);

	dword_align_bytes = ((unsigned long)skb->data & 0x3f);
	if (dword_align_bytes)
		skb_pull(skb, (64 - dword_align_bytes));
	if (rsi_prepare_beacon(common, skb)) {
		rsi_dbg(ERR_ZONE, "Failed to prepare beacon\n");
		return -EINVAL;
	}
	skb_queue_tail(&common->tx_queue[MGMT_BEACON_Q], skb);
	rsi_set_event(&common->tx_thread.event);
	rsi_dbg(DATA_TX_ZONE, "%s: Added to beacon queue\n", __func__);

	return 0;
}

/**
 * rsi_handle_ta_confirm_type() - This function handles the confirm frames.
 * @common: Pointer to the driver private structure.
@@ -1722,21 +1748,33 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg)
	rsi_dbg(FSM_ZONE, "%s: Msg Len: %d, Msg Type: %4x\n",
		__func__, msg_len, msg_type);

	if (msg_type == TA_CONFIRM_TYPE) {
	switch (msg_type) {
	case TA_CONFIRM_TYPE:
		return rsi_handle_ta_confirm_type(common, msg);
	} else if (msg_type == CARD_READY_IND) {
	case CARD_READY_IND:
		rsi_dbg(FSM_ZONE, "%s: Card ready indication received\n",
			__func__);
		return rsi_handle_card_ready(common, msg);
	} else if (msg_type == TX_STATUS_IND) {
	case TX_STATUS_IND:
		if (msg[15] == PROBEREQ_CONFIRM) {
			common->mgmt_q_block = false;
			rsi_dbg(FSM_ZONE, "%s: Probe confirm received\n",
				__func__);
		}
	} else if (msg_type == RX_DOT11_MGMT) {
		break;
	case BEACON_EVENT_IND:
		rsi_dbg(INFO_ZONE, "Beacon event\n");
		if (common->fsm_state != FSM_MAC_INIT_DONE)
			return -1;
		if (common->iface_down)
			return -1;
		if (!common->beacon_enabled)
			return -1;
		rsi_send_beacon(common);
		break;
	case RX_DOT11_MGMT:
		return rsi_mgmt_pkt_to_core(common, msg, msg_len);
	} else {
	default:
		rsi_dbg(INFO_ZONE, "Received packet type: 0x%x\n", msg_type);
	}
	return 0;
+2 −0
Original line number Diff line number Diff line
@@ -144,5 +144,7 @@ struct rsi_data_desc {
} __packed;

int rsi_hal_device_init(struct rsi_hw *adapter);
int rsi_prepare_beacon(struct rsi_common *common, struct sk_buff *skb);
int rsi_send_pkt_to_bus(struct rsi_common *common, struct sk_buff *skb);

#endif
Loading