net: wireless: rsi: fix for kernel hang

parent 336a968b
......@@ -390,8 +390,8 @@ static ssize_t rsi_bgscan_write(struct file *file,
common->debugfs_bgscan = true;
/* Return if bgscan is already in progress */
if (common->bgscan_en)
return total_bytes;
if (common->bgscan_en && bss->assoc)
common->bgscan_en = 0;
bytes_read += t_bytes;
while (1) {
......@@ -447,29 +447,6 @@ static ssize_t rsi_bgscan_write(struct file *file,
return total_bytes;
}
/* Send bgscan params to device */
mutex_lock(&common->mutex);
if (!rsi_send_bgscan_params(common, 1)) {
if (!rsi_send_bgscan_probe_req(common)) {
#ifdef PLATFORM_X86
rsi_dbg(INFO_ZONE, "Background scan started ===>\n");
#endif
common->bgscan_en = 1;
} else {
#ifdef PLATFORM_X86
rsi_dbg(ERR_ZONE, "Failed sending bgscan probe req\n");
#endif
common->bgscan_en = 0;
g_bgscan_enable = 0;
}
} else {
#ifdef PLATFORM_X86
rsi_dbg(ERR_ZONE, "Failed sending bgscan params req\n");
#endif
}
mutex_unlock(&common->mutex);
return total_bytes;
}
......
......@@ -142,6 +142,10 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
wh = (struct ieee80211_hdr *)&skb->data[header_size];
seq_num = le16_to_cpu(IEEE80211_SEQ_TO_SN(wh->seq_ctrl));
vif = rsi_get_vif(adapter, wh->addr2);
if (!vif) {
status = -ENOSPC;
goto err;
}
vap_id = ((struct vif_priv *)vif->drv_priv)->vap_id;
frame_desc[2] = cpu_to_le16(header_size - FRAME_DESC_SZ);
......
......@@ -215,6 +215,20 @@ static struct reg_map rsi_caracalla_reg_db[MAX_REG_COUNTRIES] = {
{"MA", NL80211_DFS_WORLD}, {"NL", NL80211_DFS_ETSI},
};
#endif
static int rsi_validate_mac_addr(struct rsi_common *common, u8 *addr_t)
{
u8 addr[ETH_ALEN] = {0};
if (!memcmp(addr, addr_t, ETH_ALEN)) {
rsi_dbg(ERR_ZONE, "%s: MAC addr is NULL\n", __func__);
return -1;
} else if (memcmp(common->mac_addr, addr_t, ETH_ALEN)) {
memcpy(common->mac_addr, addr_t, ETH_ALEN);
}
return 0;
}
static int rsi_mac80211_get_chan_survey(struct ieee80211_hw *hw,
int idx, struct survey_info *survey)
{
......@@ -412,6 +426,8 @@ static int rsi_mac80211_hw_scan_start(struct ieee80211_hw *hw,
/* Scan already in progress. So return */
if (common->bgscan_en || common->scan_in_prog)
return -EBUSY;
if (rsi_validate_mac_addr(common, vif->addr))
return -ENODEV;
cancel_work_sync(&common->scan_work);
mutex_lock(&common->mutex);
......@@ -429,6 +445,10 @@ static int rsi_mac80211_hw_scan_start(struct ieee80211_hw *hw,
return -EBUSY;
}
}
if (common->bgscan_en) {
mutex_unlock(&common->mutex);
return 0;
}
if (!common->debugfs_bgscan) {
common->bgscan_info.num_user_channels = scan_req->n_channels;
for (ii = 0; ii < scan_req->n_channels; ii++) {
......@@ -606,9 +626,7 @@ static void rsi_mac80211_tx(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf;
#ifndef CONFIG_RSI_P2P
if ((memcmp(common->mac_addr, wlh->addr2, ETH_ALEN))) {
rsi_dbg(ERR_ZONE,
"%s: MAC ID is not found and dropping this packets\n", __func__);
if (rsi_validate_mac_addr(common, wlh->addr2)) {
ieee80211_free_txskb(common->priv->hw, skb);
return;
}
......@@ -2004,10 +2022,7 @@ static int rsi_fill_rx_status(struct ieee80211_hw *hw,
rxs->signal = -(rssi);
if (channel >=1 && channel <= 14)
rxs->band = NL80211_BAND_2GHZ;
else if (channel >= 32 && channel <= 173)
rxs->band = NL80211_BAND_5GHZ;
rxs->band = common->band;
freq = ieee80211_channel_to_frequency(channel, rxs->band);
......@@ -2181,15 +2196,7 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
for (i = 0; i < IEEE80211_NUM_ACS; i++)
rsta->seq_start[i] = 0;
rsi_set_min_rate(hw, sta, common);
if (g_bgscan_enable) {
if (!rsi_send_bgscan_params(common, 1)) {
if (!rsi_send_bgscan_probe_req(common)) {
rsi_dbg(INFO_ZONE,
"Bgscan started ===>\n");
common->bgscan_en = 1;
}
}
}
}
if (((vif->type == NL80211_IFTYPE_STATION) ||
......@@ -3095,9 +3102,6 @@ int rsi_mac80211_attach(struct rsi_common *common)
// NL80211_FEATURE_P2P_GO_OPPPS);
#endif
if (common->coex_mode > 1)
wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
status = ieee80211_register_hw(hw);
if (status) {
rsi_dbg(ERR_ZONE, "Failed to register to mac80211\n");
......
......@@ -651,7 +651,7 @@ static void rsi_set_default_parameters(struct rsi_common *common)
void init_bgscan_params(struct rsi_common *common)
{
common->bgscan_info.bgscan_threshold = 0;
common->bgscan_info.bgscan_threshold = 10;
common->bgscan_info.roam_threshold = 10;
common->bgscan_info.bgscan_periodicity = 30;
common->bgscan_info.num_bg_channels = 0;
......@@ -2147,6 +2147,7 @@ void rsi_validate_bgscan_channels(struct rsi_hw *adapter,
int ch_num, i;
int num_valid_chs = 0, cnt;
struct rsi_common *common = adapter->priv;
/* If user passes 0 for num of bgscan channels, take all channels */
if (params->num_user_channels == 0) {
......@@ -2190,16 +2191,23 @@ void rsi_validate_bgscan_channels(struct rsi_hw *adapter,
if (ch->flags & IEEE80211_CHAN_DISABLED)
continue;
params->channels2scan[num_valid_chs] = ch_num;
rsi_dbg(INFO_ZONE, "%d ", ch_num);
if ((ch->flags & IEEE80211_CHAN_NO_IR) ||
(ch->flags & IEEE80211_CHAN_RADAR)) {
if((ch->flags & IEEE80211_CHAN_RADAR))
rsi_dbg(INFO_ZONE, "[DFS]");
params->channels2scan[num_valid_chs] |=
(cpu_to_le16(BIT(15))); /* DFS indication */
if (common->band == NL80211_BAND_2GHZ && ch_num <= 14) {
params->channels2scan[num_valid_chs] = ch_num;
rsi_dbg(INFO_ZONE, "%d ", ch_num);
num_valid_chs++;
} else if (common->band == NL80211_BAND_5GHZ && ch_num > 14) {
params->channels2scan[num_valid_chs] = ch_num;
rsi_dbg(ERR_ZONE, "%d ", ch_num);
if ((ch->flags & IEEE80211_CHAN_NO_IR) ||
(ch->flags & IEEE80211_CHAN_RADAR)) {
if ((ch->flags & IEEE80211_CHAN_RADAR)) {
rsi_dbg(INFO_ZONE, "[DFS]");
}
params->channels2scan[num_valid_chs] |=
(cpu_to_le16(BIT(15)));
}
num_valid_chs++;
}
num_valid_chs++;
}
params->num_bg_channels = num_valid_chs;
......@@ -3546,17 +3554,16 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg)
case BG_SCAN_PROBE_REQ:
rsi_dbg(INFO_ZONE, "BG scan complete event\n");
if (common->bgscan_en) {
if (!rsi_send_bgscan_params(common, 0))
common->bgscan_en = 0;
}
#ifdef CONFIG_HW_SCAN_OFFLOAD
if (common->hwscan_en) {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
info.aborted = false;
ieee80211_scan_completed(adapter->hw, &info);
info.aborted = false;
ieee80211_scan_completed(adapter->hw, &info);
#else
ieee80211_scan_completed(adapter->hw, false);
ieee80211_scan_completed(adapter->hw, false);
#endif
common->hwscan_en = false;
}
if (common->hw_scan_cancel)
rsi_set_event(&common->cancel_hw_scan_event);
#endif
......@@ -3765,6 +3772,18 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg)
case RX_DOT11_MGMT:
return rsi_mgmt_pkt_to_core(common, msg, msg_len);
case FW_ERROR_STATE_IND:
if (msg[15] == RSI_MAX_BGSCAN_CHANNEL_SUPPORTED) {
rsi_dbg(ERR_ZONE,
"*** Bgscan Channel's greater than 24 Not Supported ***\n");
return -1;
} else if (msg[15] == RSI_MAX_BGSCAN_PROBE_REQ_LEN) {
rsi_dbg(ERR_ZONE,
"*** Bgscan Probe Request Length is greater than Max Size ***\n");
return -1;
}
break;
default:
rsi_dbg(INFO_ZONE, "Cmd Frame Type: %d\n", msg_type);
break;
......
......@@ -431,6 +431,7 @@ struct rsi_common {
bool reinit_hw;
struct completion wlan_init_completion;
bool debugfs_bgscan;
bool hwscan_en;
#ifdef CONFIG_RSI_WOW
u8 wow_flags;
#endif
......
......@@ -94,6 +94,7 @@ enum rx_cmd_type {
TSF_SYNC_CONFIRM = 0xc0,
ANTENNA_SELECT = 0xf,
RADIO_MEAS_RPT = 0x10,
FW_ERROR_STATE_IND = 0x1C,
};
......@@ -105,6 +106,9 @@ enum rx_cmd_type {
#define PROBEREQ_CONFIRM 2
#define NULLDATA_CONFIRM 3
#define RSI_MAX_BGSCAN_CHANNEL_SUPPORTED 0x6F
#define RSI_MAX_BGSCAN_PROBE_REQ_LEN 0x71
#define RSI_DELETE_PEER 0x0
#define RSI_ADD_PEER 0x1
#define START_AMPDU_AGGR 0x1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment