2014-06-02 14:57:34

by Jahnavi Meher

[permalink] [raw]
Subject: [PATCH 1/1] rsi: Adding support for bgscan, 5GHz support and clean up of code


From: Jahnavi Meher <[email protected]>

This patch adds code for support of bgscan and 5GHz. It also contains
changes to the piece of code that determines the number of packets to
be de-queued from soft queues - it is changed from a fixed number to
a count based on txop. There are also a number of small clean ups.

Signed-off-by: Jahnavi Meher <[email protected]>
---
rsi_91x_core.c | 81 ++++++++++++++++++++---------
rsi_91x_debugfs.c | 10 +--
rsi_91x_mac80211.c | 110 +++++++++++++++++++++++++++++++++------
rsi_91x_main.c | 2
rsi_91x_mgmt.c | 148 +++++++++++++++++++++++++++++++++++++++++++----------
rsi_91x_sdio_ops.c | 4 -
rsi_main.h | 14 +++++
rsi_mgmt.h | 2
rsi_sdio.h | 4 -
9 files changed, 299 insertions(+), 76 deletions(-)

diff -uprN b/drivers/net/wireless/rsi/rsi_91x_core.c a/drivers/net/wireless/rsi/rsi_91x_core.c
--- b/drivers/net/wireless/rsi/rsi_91x_core.c 2014-06-02 19:45:25.337377135 +0530
+++ a/drivers/net/wireless/rsi/rsi_91x_core.c 2014-06-02 19:46:06.962374674 +0530
@@ -77,6 +77,50 @@ static bool rsi_recalculate_weights(stru
}

/**
+ * rsi_get_num_pkts_dequeue() - This function determines the number of
+ * packets to be dequeued based on the number
+ * of bytes calculated using txop.
+ *
+ * @common: Pointer to the driver private structure.
+ * @q_num: the queue from which pkts have to be dequeued
+ *
+ * Return: pkt_num: Number of pkts to be dequeued.
+ */
+static u32 rsi_get_num_pkts_dequeue(struct rsi_common *common, u8 q_num)
+{
+ struct rsi_hw *adapter = common->priv;
+ struct sk_buff *skb;
+ u32 pkt_cnt = 0;
+ s16 txop = common->tx_qinfo[q_num].txop * 32;
+ struct ieee80211_rate rate;
+ rate.bitrate = RSI_RATE_MCS0 * 5 * 10;
+
+ if (q_num == VI_Q)
+ txop = ((txop << 5) / 80);
+
+ if (skb_queue_len(&common->tx_queue[q_num]))
+ skb = skb_peek(&common->tx_queue[q_num]);
+ else
+ return 0;
+
+ do {
+ txop -= ieee80211_generic_frame_duration(adapter->hw,
+ adapter->vifs[0],
+ common->band,
+ skb->len, &rate);
+ pkt_cnt += 1;
+ /*checking if pkts are still there*/
+ if (skb_queue_len(&common->tx_queue[q_num]) - pkt_cnt)
+ skb = skb->next;
+ else
+ break;
+
+ } while (txop > 0);
+
+ return pkt_cnt;
+}
+
+/**
* rsi_core_determine_hal_queue() - This function determines the queue from
* which packet has to be dequeued.
* @common: Pointer to the driver private structure.
@@ -88,7 +132,7 @@ static u8 rsi_core_determine_hal_queue(s
bool recontend_queue = false;
u32 q_len = 0;
u8 q_num = INVALID_QUEUE;
- u8 ii = 0, min = 0;
+ u8 ii = 0;

if (skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])) {
if (!common->mgmt_q_block)
@@ -106,14 +150,15 @@ get_queue_num:

q_num = rsi_determine_min_weight_queue(common);

- q_len = skb_queue_len(&common->tx_queue[ii]);
ii = q_num;

/* Selecting the queue with least back off */
for (; ii < NUM_EDCA_QUEUES; ii++) {
+ q_len = skb_queue_len(&common->tx_queue[ii]);
if (((common->tx_qinfo[ii].pkt_contended) &&
- (common->tx_qinfo[ii].weight < min)) && q_len) {
- min = common->tx_qinfo[ii].weight;
+ (common->tx_qinfo[ii].weight < common->min_weight)) &&
+ q_len) {
+ common->min_weight = common->tx_qinfo[ii].weight;
q_num = ii;
}
}
@@ -140,25 +185,11 @@ get_queue_num:
common->selected_qnum = q_num;
q_len = skb_queue_len(&common->tx_queue[q_num]);

- switch (common->selected_qnum) {
- case VO_Q:
- if (q_len > MAX_CONTINUOUS_VO_PKTS)
- common->pkt_cnt = (MAX_CONTINUOUS_VO_PKTS - 1);
- else
- common->pkt_cnt = --q_len;
- break;
-
- case VI_Q:
- if (q_len > MAX_CONTINUOUS_VI_PKTS)
- common->pkt_cnt = (MAX_CONTINUOUS_VI_PKTS - 1);
- else
- common->pkt_cnt = --q_len;
-
- break;
-
- default:
+ if (q_num == VO_Q || q_num == VI_Q) {
+ common->pkt_cnt = rsi_get_num_pkts_dequeue(common, q_num);
+ common->pkt_cnt -= 1;
+ } else {
common->pkt_cnt = 0;
- break;
}

return q_num;
@@ -245,13 +276,16 @@ void rsi_core_qos_processor(struct rsi_c
if ((q_num < MGMT_SOFT_Q) &&
((skb_queue_len(&common->tx_queue[q_num])) <=
MIN_DATA_QUEUE_WATER_MARK)) {
- if (ieee80211_queue_stopped(adapter->hw, WME_AC(q_num)))
+ if (ieee80211_queue_stopped(adapter->hw,
+ WME_AC(q_num))) {
ieee80211_wake_queue(adapter->hw,
WME_AC(q_num));
+ }
}

skb = rsi_core_dequeue_pkt(common, q_num);
if (skb == NULL) {
+ rsi_dbg(ERR_ZONE, "skb null\n");
mutex_unlock(&common->tx_rxlock);
break;
}
@@ -325,6 +359,7 @@ void rsi_core_xmit(struct rsi_common *co
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__);
if (!ieee80211_queue_stopped(adapter->hw, WME_AC(q_num)))
ieee80211_stop_queue(adapter->hw, WME_AC(q_num));
rsi_set_event(&common->tx_thread.event);
diff -uprN b/drivers/net/wireless/rsi/rsi_91x_debugfs.c a/drivers/net/wireless/rsi/rsi_91x_debugfs.c
--- b/drivers/net/wireless/rsi/rsi_91x_debugfs.c 2014-06-02 19:45:25.343377134 +0530
+++ a/drivers/net/wireless/rsi/rsi_91x_debugfs.c 2014-06-02 19:46:06.962374674 +0530
@@ -145,7 +145,7 @@ static int rsi_stats_read(struct seq_fil
seq_printf(seq, "total_mgmt_pkt_send : %d\n",
common->tx_stats.total_tx_pkt_send[MGMT_SOFT_Q]);
seq_printf(seq, "total_mgmt_pkt_queued : %d\n",
- skb_queue_len(&common->tx_queue[4]));
+ skb_queue_len(&common->tx_queue[MGMT_SOFT_Q]));
seq_printf(seq, "total_mgmt_pkt_freed : %d\n",
common->tx_stats.total_tx_pkt_freed[MGMT_SOFT_Q]);

@@ -153,25 +153,25 @@ static int rsi_stats_read(struct seq_fil
seq_printf(seq, "total_data_vo_pkt_send: %8d\t",
common->tx_stats.total_tx_pkt_send[VO_Q]);
seq_printf(seq, "total_data_vo_pkt_queued: %8d\t",
- skb_queue_len(&common->tx_queue[0]));
+ skb_queue_len(&common->tx_queue[VO_Q]));
seq_printf(seq, "total_vo_pkt_freed: %8d\n",
common->tx_stats.total_tx_pkt_freed[VO_Q]);
seq_printf(seq, "total_data_vi_pkt_send: %8d\t",
common->tx_stats.total_tx_pkt_send[VI_Q]);
seq_printf(seq, "total_data_vi_pkt_queued: %8d\t",
- skb_queue_len(&common->tx_queue[1]));
+ skb_queue_len(&common->tx_queue[VI_Q]));
seq_printf(seq, "total_vi_pkt_freed: %8d\n",
common->tx_stats.total_tx_pkt_freed[VI_Q]);
seq_printf(seq, "total_data_be_pkt_send: %8d\t",
common->tx_stats.total_tx_pkt_send[BE_Q]);
seq_printf(seq, "total_data_be_pkt_queued: %8d\t",
- skb_queue_len(&common->tx_queue[2]));
+ skb_queue_len(&common->tx_queue[BE_Q]));
seq_printf(seq, "total_be_pkt_freed: %8d\n",
common->tx_stats.total_tx_pkt_freed[BE_Q]);
seq_printf(seq, "total_data_bk_pkt_send: %8d\t",
common->tx_stats.total_tx_pkt_send[BK_Q]);
seq_printf(seq, "total_data_bk_pkt_queued: %8d\t",
- skb_queue_len(&common->tx_queue[3]));
+ skb_queue_len(&common->tx_queue[BK_Q]));
seq_printf(seq, "total_bk_pkt_freed: %8d\n",
common->tx_stats.total_tx_pkt_freed[BK_Q]);

diff -uprN b/drivers/net/wireless/rsi/rsi_91x_mac80211.c a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
--- b/drivers/net/wireless/rsi/rsi_91x_mac80211.c 2014-06-02 19:45:25.337377135 +0530
+++ a/drivers/net/wireless/rsi/rsi_91x_mac80211.c 2014-06-02 19:46:06.962374674 +0530
@@ -243,8 +243,8 @@ static void rsi_mac80211_tx(struct ieee8
{
struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv;
-
rsi_core_xmit(common, skb);
+ return;
}

/**
@@ -357,16 +357,36 @@ static int rsi_mac80211_config(struct ie
int status = -EOPNOTSUPP;

mutex_lock(&common->mutex);
+
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
struct ieee80211_channel *curchan = hw->conf.chandef.chan;
u16 channel = curchan->hw_value;
+ struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf;

rsi_dbg(INFO_ZONE,
"%s: Set channel: %d MHz type: %d channel_no %d\n",
__func__, curchan->center_freq,
curchan->flags, channel);
- common->band = curchan->band;
- status = rsi_set_channel(adapter->priv, channel);
+
+ if (bss->assoc && !common->block_state &&
+ (rsi_get_connected_channel(adapter) != channel)) {
+ rsi_dbg(INFO_ZONE, "blk data q %d\n", channel);
+ if (!rsi_send_block_unblock_frame(common, true))
+ common->block_state = true;
+ }
+
+ status = rsi_band_check(common);
+ if (!status)
+ status = rsi_set_channel(adapter->priv, channel);
+
+ if ((bss->assoc && common->block_state &&
+ (rsi_get_connected_channel(adapter) == channel)) ||
+ (!bss->assoc && common->block_state)) {
+ rsi_dbg(INFO_ZONE, "unblk data q %d\n", channel);
+ if (!rsi_send_block_unblock_frame(common, false))
+ common->block_state = false;
+ }
+
}
mutex_unlock(&common->mutex);

@@ -388,8 +408,7 @@ u16 rsi_get_connected_channel(struct rsi
struct ieee80211_channel *channel = bss->chandef.chan;
return channel->hw_value;
}
-
- return 0;
+ return -EOPNOTSUPP;
}

/**
@@ -421,6 +440,15 @@ static void rsi_mac80211_bss_info_change
bss_conf->qos,
bss_conf->aid);
}
+
+ if (changed & BSS_CHANGED_CQM) {
+ common->cqm_info.last_cqm_event = 0;
+ common->cqm_info.rssi_thold = bss_conf->cqm_rssi_thold;
+ common->cqm_info.rssi_hyst = bss_conf->cqm_rssi_hyst;
+ rsi_dbg(INFO_ZONE, "RSSI throld & hysteresis are: %d %d\n",
+ common->cqm_info.rssi_thold,
+ common->cqm_info.rssi_hyst);
+ }
mutex_unlock(&common->mutex);
}

@@ -723,23 +751,62 @@ static int rsi_mac80211_set_rate_mask(st
struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv;

- mutex_lock(&common->mutex);
+ u8 band = hw->conf.chandef.chan->band;

- common->fixedrate_mask[IEEE80211_BAND_2GHZ] = 0;
+ mutex_lock(&common->mutex);
+ common->fixedrate_mask[band] = 0;

- if (mask->control[IEEE80211_BAND_2GHZ].legacy == 0xfff) {
- common->fixedrate_mask[IEEE80211_BAND_2GHZ] =
- (mask->control[IEEE80211_BAND_2GHZ].ht_mcs[0] << 12);
+ if (mask->control[band].legacy == 0xfff) {
+ common->fixedrate_mask[band] =
+ (mask->control[band].ht_mcs[0] << 12);
} else {
- common->fixedrate_mask[IEEE80211_BAND_2GHZ] =
- mask->control[IEEE80211_BAND_2GHZ].legacy;
+ common->fixedrate_mask[band] =
+ mask->control[band].legacy;
}
- mutex_unlock(&common->mutex);

+ mutex_unlock(&common->mutex);
return 0;
}

/**
+ * rsi_perform_cqm() - This function performs cqm.
+ * @common: Pointer to the driver private structure.
+ * @bss: Pointer to the ieee80211_bss_conf structure.
+ * @bssid: pointer to the bssid.
+ * @rssi: RSSI value.
+ */
+static void rsi_perform_cqm(struct rsi_common *common,
+ struct ieee80211_bss_conf *bss,
+ unsigned char *bssid,
+ char rssi)
+{
+ struct rsi_hw *adapter = common->priv;
+ char last_event = common->cqm_info.last_cqm_event;
+ int thold = common->cqm_info.rssi_thold;
+ u32 hyst = common->cqm_info.rssi_hyst;
+ enum nl80211_cqm_rssi_threshold_event event;
+
+ if (!bss->assoc)
+ return;
+
+ if (memcmp(bss->bssid, bssid, ETH_ALEN))
+ return;
+
+ if (rssi < thold && (last_event == 0 || rssi < last_event - hyst))
+ event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
+ else if (rssi > thold && (last_event == 0 || rssi > last_event + hyst))
+ event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
+ else
+ return;
+
+ common->cqm_info.last_cqm_event = rssi;
+ rsi_dbg(INFO_ZONE, "CQM: Notifying event: %d\n", event);
+ ieee80211_cqm_rssi_notify(adapter->vifs[0], event, GFP_KERNEL);
+
+ return;
+}
+
+/**
* rsi_fill_rx_status() - This function fills rx status in
* ieee80211_rx_status structure.
* @hw: Pointer to the ieee80211_hw structure.
@@ -754,6 +821,8 @@ static void rsi_fill_rx_status(struct ie
struct rsi_common *common,
struct ieee80211_rx_status *rxs)
{
+ struct rsi_hw *adapter = common->priv;
+ struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct skb_info *rx_params = (struct skb_info *)info->driver_data;
struct ieee80211_hdr *hdr;
@@ -769,10 +838,7 @@ static void rsi_fill_rx_status(struct ie

rxs->signal = -(rssi);

- if (channel <= 14)
- rxs->band = IEEE80211_BAND_2GHZ;
- else
- rxs->band = IEEE80211_BAND_5GHZ;
+ rxs->band = common->band;

freq = ieee80211_channel_to_frequency(channel, rxs->band);

@@ -791,6 +857,13 @@ static void rsi_fill_rx_status(struct ie
rxs->flag |= RX_FLAG_DECRYPTED;
rxs->flag |= RX_FLAG_IV_STRIPPED;
}
+
+
+ /* CQM only for beacons as RSSI is weighted avg RSSI in beacons */
+ if (ieee80211_is_beacon(hdr->frame_control))
+ rsi_perform_cqm(common, bss, hdr->addr2, rxs->signal);
+
+ return;
}

/**
@@ -982,6 +1055,7 @@ int rsi_mac80211_attach(struct rsi_commo

hw->max_tx_aggregation_subframes = 6;
rsi_register_rates_channels(adapter, IEEE80211_BAND_2GHZ);
+ rsi_register_rates_channels(adapter, IEEE80211_BAND_5GHZ);
hw->rate_control_algorithm = "AARF";

SET_IEEE80211_PERM_ADDR(hw, common->mac_addr);
@@ -999,6 +1073,8 @@ int rsi_mac80211_attach(struct rsi_commo
wiphy->available_antennas_tx = 1;
wiphy->bands[IEEE80211_BAND_2GHZ] =
&adapter->sbands[IEEE80211_BAND_2GHZ];
+ wiphy->bands[IEEE80211_BAND_5GHZ] =
+ &adapter->sbands[IEEE80211_BAND_5GHZ];

status = ieee80211_register_hw(hw);
if (status)
diff -uprN b/drivers/net/wireless/rsi/rsi_91x_main.c a/drivers/net/wireless/rsi/rsi_91x_main.c
--- b/drivers/net/wireless/rsi/rsi_91x_main.c 2014-06-02 19:45:25.337377135 +0530
+++ a/drivers/net/wireless/rsi/rsi_91x_main.c 2014-06-02 19:46:06.962374674 +0530
@@ -21,7 +21,7 @@
#include "rsi_mgmt.h"
#include "rsi_common.h"

-u32 rsi_zone_enabled = /* INFO_ZONE |
+u32 rsi_zone_enabled = /*INFO_ZONE |
INIT_ZONE |
MGMT_TX_ZONE |
MGMT_RX_ZONE |
diff -uprN b/drivers/net/wireless/rsi/rsi_91x_mgmt.c a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
--- b/drivers/net/wireless/rsi/rsi_91x_mgmt.c 2014-06-02 19:45:25.337377135 +0530
+++ a/drivers/net/wireless/rsi/rsi_91x_mgmt.c 2014-06-02 19:46:06.962374674 +0530
@@ -217,6 +217,7 @@ static void rsi_set_default_parameters(s
common->min_rate = 0xffff;
common->fsm_state = FSM_CARD_NOT_READY;
common->iface_down = true;
+ common->endpoint = 0;
}

/**
@@ -306,11 +307,15 @@ static int rsi_load_radio_caps(struct rs

if (common->channel_width == BW_40MHZ) {
radio_caps->desc_word[7] |= cpu_to_le16(RSI_LMAC_CLOCK_80MHZ);
+
radio_caps->desc_word[7] |= cpu_to_le16(RSI_ENABLE_40MHZ);
if (common->channel_width) {
+
radio_caps->desc_word[5] =
cpu_to_le16(common->channel_width << 12);
+
radio_caps->desc_word[5] |= cpu_to_le16(FULL40M_ENABLE);
+
}

if (conf_is_ht40_minus(conf)) {
@@ -330,8 +335,8 @@ static int rsi_load_radio_caps(struct rs
}
}

- radio_caps->desc_word[7] |= cpu_to_le16(radio_id << 8);

+ radio_caps->desc_word[7] |= cpu_to_le16(radio_id << 8);
for (ii = 0; ii < MAX_HW_QUEUES; ii++) {
radio_caps->qos_params[ii].cont_win_min_q = cpu_to_le16(3);
radio_caps->qos_params[ii].cont_win_max_q = cpu_to_le16(0x3f);
@@ -588,7 +593,13 @@ static int rsi_program_bb_rf(struct rsi_

mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
mgmt_frame->desc_word[1] = cpu_to_le16(BBP_PROG_IN_TA);
- mgmt_frame->desc_word[4] = cpu_to_le16(common->endpoint << 8);
+
+ if (common->band == IEEE80211_BAND_2GHZ)
+ common->endpoint = 0;
+ else
+ common->endpoint = 2;
+
+ mgmt_frame->desc_word[4] = cpu_to_le16(common->endpoint);

if (common->rf_reset) {
mgmt_frame->desc_word[7] = cpu_to_le16(RF_RESET_ENABLE);
@@ -827,6 +838,49 @@ static int rsi_send_reset_mac(struct rsi
}

/**
+ * rsi_band_check() - This function programs the band
+ * @common: Pointer to the driver private structure.
+ *
+ * Return: 0 on success, corresponding error code on failure.
+ */
+int rsi_band_check(struct rsi_common *common)
+{
+ struct rsi_hw *adapter = common->priv;
+ struct ieee80211_hw *hw = adapter->hw;
+ u8 band_width = common->channel_width;
+ struct ieee80211_channel *curchan = hw->conf.chandef.chan;
+
+ if (common->band != curchan->band) {
+ common->rf_reset = 1;
+ common->band = curchan->band;
+
+ if (common->band == IEEE80211_BAND_2GHZ)
+ common->endpoint = 0;
+ else
+ common->endpoint = 1;
+
+ if (rsi_program_bb_rf(common))
+ return -1;
+ }
+
+ if ((hw->conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) ||
+ (hw->conf.chandef.width == NL80211_CHAN_WIDTH_20))
+ common->channel_width = BW_20MHZ;
+ else
+ common->channel_width = BW_40MHZ;
+
+ if (band_width != common->channel_width) {
+ common->rf_reset = 1;
+ if (rsi_load_bootup_params(common))
+ return -1;
+ if (rsi_load_radio_caps(common))
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
* rsi_set_channel() - This function programs the channel.
* @common: Pointer to the driver private structure.
* @channel: Channel value to be set.
@@ -842,14 +896,12 @@ int rsi_set_channel(struct rsi_common *c
"%s: Sending scan req frame\n", __func__);

if (common->band == IEEE80211_BAND_5GHZ) {
- if ((channel >= 36) && (channel <= 64))
- channel = ((channel - 32) / 4);
- else if ((channel > 64) && (channel <= 140))
- channel = ((channel - 102) / 4) + 8;
- else if (channel >= 149)
- channel = ((channel - 151) / 4) + 18;
- else
+ if (channel > 165) {
+ rsi_dbg(ERR_ZONE, "%s: Invalid chno %d, band = %d\n",
+ __func__, channel, common->band);
return -EINVAL;
+ }
+
} else {
if (channel > 14) {
rsi_dbg(ERR_ZONE, "%s: Invalid chno %d, band = %d\n",
@@ -987,14 +1039,23 @@ static int rsi_send_auto_rate_request(st
auto_rate->desc_word[7] |= cpu_to_le16(1);

if (band == IEEE80211_BAND_2GHZ)
- min_rate = STD_RATE_01;
+ min_rate = RSI_RATE_1;
else
- min_rate = STD_RATE_06;
+ min_rate = RSI_RATE_6;

for (ii = 0, jj = 0; ii < ARRAY_SIZE(rsi_rates); ii++) {
- if (rate_bitmap & BIT(ii)) {
- selected_rates[jj++] = (rsi_rates[ii].bitrate / 5);
- rate_offset++;
+ if (band == IEEE80211_BAND_2GHZ) {
+ if (rate_bitmap & BIT(ii)) {
+ selected_rates[jj++] =
+ (rsi_rates[ii].bitrate / 5);
+ rate_offset++;
+ }
+ } else {
+ if (rate_bitmap & BIT(ii)) {
+ selected_rates[jj++] =
+ (rsi_rates[ii + 4].bitrate / 5);
+ rate_offset++;
+ }
}
}
num_supported_rates = jj;
@@ -1006,13 +1067,6 @@ static int rsi_send_auto_rate_request(st
rate_offset += ARRAY_SIZE(mcs);
}

- if (rate_offset < (RSI_TBL_SZ / 2) - 1) {
- for (ii = jj; ii < (RSI_TBL_SZ / 2); ii++) {
- selected_rates[jj++] = min_rate;
- rate_offset++;
- }
- }
-
sort(selected_rates, jj, sizeof(u16), &rsi_compare, NULL);

/* mapping the rates to RSI rates */
@@ -1028,10 +1082,6 @@ static int rsi_send_auto_rate_request(st

/* loading HT rates in the bottom half of the auto rate table */
if (common->vif_info[0].is_ht) {
- if (common->vif_info[0].sgi)
- auto_rate->supported_rates[rate_offset++] =
- cpu_to_le16(RSI_RATE_MCS7_SG);
-
for (ii = rate_offset, kk = ARRAY_SIZE(rsi_mcsrates) - 1;
ii < rate_offset + 2 * ARRAY_SIZE(rsi_mcsrates); ii++) {
if (common->vif_info[0].sgi)
@@ -1041,12 +1091,15 @@ static int rsi_send_auto_rate_request(st
cpu_to_le16(rsi_mcsrates[kk--]);
}

- for (; ii < RSI_TBL_SZ; ii++) {
+ for (; ii < (RSI_TBL_SZ - 1); ii++) {
auto_rate->supported_rates[ii] =
cpu_to_le16(rsi_mcsrates[0]);
}
}

+ for (; ii < RSI_TBL_SZ; ii++)
+ auto_rate->supported_rates[ii] = min_rate;
+
auto_rate->num_supported_rates = cpu_to_le16(num_supported_rates * 2);
auto_rate->moderate_rate_inx = cpu_to_le16(num_supported_rates / 2);
auto_rate->desc_word[7] |= cpu_to_le16(0 << 8);
@@ -1141,6 +1194,49 @@ static int rsi_eeprom_read(struct rsi_co
}

/**
+ * This function sends a frame to block/unblock
+ * data queues in the firmware
+ *
+ * @param common Pointer to the driver private structure.
+ * @param block/unblock event
+ * @return 0 on success, -1 on failure.
+ */
+int rsi_send_block_unblock_frame(struct rsi_common *common, bool event)
+{
+ struct rsi_mac_frame *mgmt_frame;
+ struct sk_buff *skb;
+
+ rsi_dbg(MGMT_TX_ZONE, "%s: Sending block/unblock frame\n", __func__);
+
+ skb = dev_alloc_skb(FRAME_DESC_SZ);
+ if (!skb) {
+ rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
+ __func__);
+ return -1;
+ }
+
+ memset(skb->data, 0, FRAME_DESC_SZ);
+ mgmt_frame = (struct rsi_mac_frame *)skb->data;
+
+ mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
+ mgmt_frame->desc_word[1] = cpu_to_le16(BLOCK_UNBLOCK);
+
+ if (event) {
+ rsi_dbg(ERR_ZONE, "blocking the data qs\n");
+ mgmt_frame->desc_word[4] = cpu_to_le16(0xf);
+ } else {
+ rsi_dbg(ERR_ZONE, "unblocking the data qs\n");
+ mgmt_frame->desc_word[5] = cpu_to_le16(0xf);
+ }
+
+ skb_put(skb, FRAME_DESC_SZ);
+
+ return rsi_send_internal_mgmt_frame(common, skb);
+
+}
+
+
+/**
* rsi_handle_ta_confirm_type() - This function handles the confirm frames.
* @common: Pointer to the driver private structure.
* @msg: Pointer to received packet.
diff -uprN b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
--- b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c 2014-06-02 19:45:25.343377134 +0530
+++ a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c 2014-06-02 19:46:06.963374674 +0530
@@ -404,9 +404,9 @@ void rsi_interrupt_handler(struct rsi_hw
dev->rx_info.mgmt_buffer_full = false;
rsi_sdio_ack_intr(common->priv,
(1 << PKT_BUFF_AVAILABLE));
- rsi_set_event((&common->tx_thread.event));
+ rsi_set_event(&common->tx_thread.event);
rsi_dbg(ISR_ZONE,
- "%s: ==> BUFFER_AVILABLE <==\n",
+ "%s: ==> BUFFER_AVAILABLE <==\n",
__func__);
dev->rx_info.buf_avilable_counter++;
break;
diff -uprN b/drivers/net/wireless/rsi/rsi_main.h a/drivers/net/wireless/rsi/rsi_main.h
--- b/drivers/net/wireless/rsi/rsi_main.h 2014-06-02 19:45:25.337377135 +0530
+++ a/drivers/net/wireless/rsi/rsi_main.h 2014-06-02 19:46:06.963374674 +0530
@@ -19,6 +19,9 @@

#include <linux/string.h>
#include <linux/skbuff.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
#include <net/mac80211.h>

#define ERR_ZONE BIT(0) /* For Error Msgs */
@@ -115,6 +118,7 @@ struct wmm_qinfo {
s32 weight;
s32 wme_params;
s32 pkt_contended;
+ s32 txop;
};

struct transmit_q_stats {
@@ -141,6 +145,12 @@ struct rsi_thread {
atomic_t thread_done;
};

+struct cqm_info {
+ char last_cqm_event;
+ int rssi_thold;
+ unsigned int rssi_hyst;
+};
+
struct rsi_hw;

struct rsi_common {
@@ -192,6 +202,10 @@ struct rsi_common {
u8 selected_qnum;
u32 pkt_cnt;
u8 min_weight;
+
+ /* bgscan related */
+ struct cqm_info cqm_info;
+ bool block_state;
};

struct rsi_hw {
diff -uprN b/drivers/net/wireless/rsi/rsi_mgmt.h a/drivers/net/wireless/rsi/rsi_mgmt.h
--- b/drivers/net/wireless/rsi/rsi_mgmt.h 2014-06-02 19:45:25.337377135 +0530
+++ a/drivers/net/wireless/rsi/rsi_mgmt.h 2014-06-02 19:46:06.963374674 +0530
@@ -271,6 +271,7 @@ int rsi_send_aggregation_params_frame(st
int rsi_hal_load_key(struct rsi_common *common, u8 *data, u16 key_len,
u8 key_type, u8 key_id, u32 cipher);
int rsi_set_channel(struct rsi_common *common, u16 chno);
+int rsi_send_block_unblock_frame(struct rsi_common *common, bool event);
void rsi_inform_bss_status(struct rsi_common *common, u8 status,
const u8 *bssid, u8 qos_enable, u16 aid);
void rsi_indicate_pkt_to_os(struct rsi_common *common, struct sk_buff *skb);
@@ -282,4 +283,5 @@ void rsi_core_qos_processor(struct rsi_c
void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb);
int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb);
int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb);
+int rsi_band_check(struct rsi_common *common);
#endif
diff -uprN b/drivers/net/wireless/rsi/rsi_sdio.h a/drivers/net/wireless/rsi/rsi_sdio.h
--- b/drivers/net/wireless/rsi/rsi_sdio.h 2014-06-02 19:45:25.337377135 +0530
+++ a/drivers/net/wireless/rsi/rsi_sdio.h 2014-06-02 19:46:06.963374674 +0530
@@ -30,7 +30,7 @@

enum sdio_interrupt_type {
BUFFER_FULL = 0x0,
- BUFFER_AVAILABLE = 0x1,
+ BUFFER_AVAILABLE = 0x2,
FIRMWARE_ASSERT_IND = 0x3,
MSDU_PACKET_PENDING = 0x4,
UNKNOWN_INT = 0XE
@@ -42,7 +42,7 @@ enum sdio_interrupt_type {
#define PKT_MGMT_BUFF_FULL 2
#define MSDU_PKT_PENDING 3
/* Interrupt Bit Related Macros */
-#define PKT_BUFF_AVAILABLE 0
+#define PKT_BUFF_AVAILABLE 1
#define FW_ASSERT_IND 2

#define RSI_DEVICE_BUFFER_STATUS_REGISTER 0xf3







2014-06-03 10:52:06

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 1/1] rsi: Adding support for bgscan, 5GHz support and clean up of code

Jahnavi Meher <[email protected]> writes:

> From: Jahnavi Meher <[email protected]>
>
> This patch adds code for support of bgscan and 5GHz. It also contains
> changes to the piece of code that determines the number of packets to
> be de-queued from soft queues - it is changed from a fixed number to
> a count based on txop. There are also a number of small clean ups.
>
> Signed-off-by: Jahnavi Meher <[email protected]>

Patches should always contain one logical change per patch. This patch
adds three new features plus small clean ups, that's too much. For
example, you could split the patches like this:

1. add 5 GHz
2. add bgscan
3. queue change
4. small cleanups (one or more patches depending on the changes)

--
Kalle Valo

2014-06-02 16:28:37

by Joe Perches

[permalink] [raw]
Subject: Re: [PATCH 1/1] rsi: Adding support for bgscan, 5GHz support and clean up of code

On Mon, 2014-06-02 at 20:28 +0530, Jahnavi Meher wrote:
> This patch adds code for support of bgscan and 5GHz.
[]
> There are also a number of small clean ups.

[]

> diff -uprN b/drivers/net/wireless/rsi/rsi_91x_mac80211.c a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
[]
> @@ -243,8 +243,8 @@ static void rsi_mac80211_tx(struct ieee8
> {
> struct rsi_hw *adapter = hw->priv;
> struct rsi_common *common = adapter->priv;
> -
> rsi_core_xmit(common, skb);
> + return;
> }

Adding unnecessary returns at the end of a void function
is not an improvement.