Commit e130632e authored by Shrirang Bagul's avatar Shrirang Bagul Committed by Thadeu Lima de Souza Cascardo

UBUNTU: SAUCE: Redpine driver to support Host AP mode

BugLink: http://bugs.launchpad.net/bugs/1665211

Dell Caracalla IoT gateways sport a Redpine RS9113 WLAN-BT combo card.
This patch adds Host AP mode support to the Redpine RS9113 driver.
Vendor release version: 0.9.8.3 (Beta)

Other fixes:
- Connection drop issue with multiple APs/mobile phone hotspots
Signed-off-by: default avatarShrirang Bagul <shrirang.bagul@canonical.com>
Acked-by: default avatarBrad Figg <brad.figg@canonical.com>
Acked-by: default avatarTim Gardner <tim.gardner@canonical.com>
Signed-off-by: default avatarThadeu Lima de Souza Cascardo <cascardo@canonical.com>
parent 28ba5876
EXTRA_CFLAGS += -DCONFIG_DELL_BOARD -DCONFIG_VEN_RSI_COEX -DLINUX -Wimplicit -Wstrict-prototypes -DCONFIG_VEN_RSI_DEBUGFS -DPLATFORM_X86 EXTRA_CFLAGS += -DCONFIG_CARACALLA_BOARD -DCONFIG_VEN_RSI_COEX -DLINUX -Wimplicit -Wstrict-prototypes -DCONFIG_VEN_RSI_DEBUGFS -DPLATFORM_X86 -DCONFIG_RSI_WOW
ven_rsi_91x-y += rsi_91x_main.o ven_rsi_91x-y += rsi_91x_main.o
ven_rsi_91x-y += rsi_91x_core.o ven_rsi_91x-y += rsi_91x_core.o
......
...@@ -270,15 +270,13 @@ void rsi_core_qos_processor(struct rsi_common *common) ...@@ -270,15 +270,13 @@ void rsi_core_qos_processor(struct rsi_common *common)
ven_rsi_dbg(DATA_TX_ZONE, ven_rsi_dbg(DATA_TX_ZONE,
"%s: Queue number = %d\n", __func__, q_num); "%s: Queue number = %d\n", __func__, q_num);
if (q_num == INVALID_QUEUE) { if (q_num == INVALID_QUEUE)
ven_rsi_dbg(DATA_TX_ZONE, "%s: No More Pkt\n", __func__);
break; break;
}
mutex_lock(&common->tx_lock); mutex_lock(&common->tx_lock);
status = adapter->check_hw_queue_status(adapter, q_num); status = adapter->check_hw_queue_status(adapter, q_num);
if ((status <= 0)) { if (status <= 0) {
mutex_unlock(&common->tx_lock); mutex_unlock(&common->tx_lock);
break; break;
} }
...@@ -286,6 +284,8 @@ void rsi_core_qos_processor(struct rsi_common *common) ...@@ -286,6 +284,8 @@ void rsi_core_qos_processor(struct rsi_common *common)
if ((q_num < MGMT_SOFT_Q) && if ((q_num < MGMT_SOFT_Q) &&
((skb_queue_len(&common->tx_queue[q_num])) <= ((skb_queue_len(&common->tx_queue[q_num])) <=
MIN_DATA_QUEUE_WATER_MARK)) { MIN_DATA_QUEUE_WATER_MARK)) {
if (!adapter->hw)
break;
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, ieee80211_wake_queue(adapter->hw,
WME_AC(q_num)); WME_AC(q_num));
...@@ -368,7 +368,9 @@ struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr) ...@@ -368,7 +368,9 @@ struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr)
{ {
int i; int i;
for (i = 0; i < common->num_stations; i++) { for (i = 0; i < RSI_MAX_ASSOC_STAS; i++) {
if (!common->stations[i].sta)
continue;
if (!(memcmp(common->stations[i].sta->addr, if (!(memcmp(common->stations[i].sta->addr,
mac_addr, ETH_ALEN))) mac_addr, ETH_ALEN)))
return &common->stations[i]; return &common->stations[i];
...@@ -397,7 +399,12 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb) ...@@ -397,7 +399,12 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
__func__); __func__);
goto xmit_fail; goto xmit_fail;
} }
#ifdef CONFIG_RSI_WOW
if(common->suspend_flag) {
ven_rsi_dbg(ERR_ZONE, "%s: Blocking Tx_packets when WOWLAN is enabled\n", __func__);
goto xmit_fail;
}
#endif
if (common->fsm_state != FSM_MAC_INIT_DONE) { if (common->fsm_state != FSM_MAC_INIT_DONE) {
ven_rsi_dbg(ERR_ZONE, "%s: FSM state not open\n", __func__); ven_rsi_dbg(ERR_ZONE, "%s: FSM state not open\n", __func__);
goto xmit_fail; goto xmit_fail;
...@@ -410,9 +417,24 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb) ...@@ -410,9 +417,24 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
if ((ieee80211_is_mgmt(wlh->frame_control)) || if ((ieee80211_is_mgmt(wlh->frame_control)) ||
(ieee80211_is_ctl(wlh->frame_control)) || (ieee80211_is_ctl(wlh->frame_control)) ||
(ieee80211_is_qos_nullfunc(wlh->frame_control))) { (ieee80211_is_qos_nullfunc(wlh->frame_control))) {
if ((ieee80211_is_assoc_req(wlh->frame_control)) ||
(ieee80211_is_reassoc_req(wlh->frame_control))) {
struct ieee80211_bss_conf *bss = NULL;
bss = &adapter->vifs[0]->bss_conf;
rsi_send_sta_notify_frame(common, STA_OPMODE,
STA_CONNECTED,
bss->bssid, bss->qos,
bss->aid, 0);
}
q_num = MGMT_SOFT_Q; q_num = MGMT_SOFT_Q;
skb->priority = q_num; skb->priority = q_num;
#ifdef CONFIG_RSI_WOW
if ((ieee80211_is_deauth(wlh->frame_control)) && (common->suspend_flag)) {
ven_rsi_dbg(ERR_ZONE, "%s: Discarding Deauth when WOWLAN is enabled\n", __func__);
goto xmit_fail;
}
#endif
ven_rsi_dbg(INFO_ZONE, "Core: TX Dot11 Mgmt Pkt Type: %s\n", ven_rsi_dbg(INFO_ZONE, "Core: TX Dot11 Mgmt Pkt Type: %s\n",
dot11_pkt_type(wlh->frame_control)); dot11_pkt_type(wlh->frame_control));
if (ieee80211_is_probe_req(wlh->frame_control)) { if (ieee80211_is_probe_req(wlh->frame_control)) {
...@@ -434,6 +456,16 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb) ...@@ -434,6 +456,16 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
rsi_hex_dump(DATA_TX_ZONE, "TX Data Packet", rsi_hex_dump(DATA_TX_ZONE, "TX Data Packet",
skb->data, skb->len); skb->data, skb->len);
/* Drop the null packets if bgscan is enabled
* as it is already handled in firmware */
if ((vif->type == NL80211_IFTYPE_STATION) && (common->bgscan_en)) {
if (ieee80211_is_qos_nullfunc(wlh->frame_control)) {
++common->tx_stats.total_tx_pkt_freed[skb->priority];
rsi_indicate_tx_status(adapter, skb, 0);
return;
}
}
if (ieee80211_is_data_qos(wlh->frame_control)) { if (ieee80211_is_data_qos(wlh->frame_control)) {
u8 *qos = ieee80211_get_qos_ctl(wlh); u8 *qos = ieee80211_get_qos_ctl(wlh);
......
...@@ -267,9 +267,19 @@ static ssize_t rsi_debug_zone_write(struct file *filp, ...@@ -267,9 +267,19 @@ static ssize_t rsi_debug_zone_write(struct file *filp,
static int rsi_bgscan_int_read(struct seq_file *file, void *data) static int rsi_bgscan_int_read(struct seq_file *file, void *data)
{ {
struct rsi_common *common = file->private; struct rsi_common *common = file->private;
struct bgscan_config_params *params = &common->bgscan_info; struct bgscan_config_params *params = NULL;
int cnt; int cnt;
if (!common) {
ven_rsi_dbg(ERR_ZONE, "No Interface\n");
return -ENODEV;
}
if (common->iface_down) {
ven_rsi_dbg(ERR_ZONE, "Interface Down\n");
return -ENODEV;
}
params = &common->bgscan_info;
seq_printf(file, "%d %d %d %d %d %d %d %d\n", seq_printf(file, "%d %d %d %d %d %d %d %d\n",
common->bgscan_en, common->bgscan_en,
params->bgscan_threshold, params->bgscan_threshold,
...@@ -314,14 +324,25 @@ static ssize_t rsi_bgscan_write(struct file *file, ...@@ -314,14 +324,25 @@ static ssize_t rsi_bgscan_write(struct file *file,
{ {
struct rsi_common *common = file->f_inode->i_private; struct rsi_common *common = file->f_inode->i_private;
struct rsi_hw *adapter = common->priv; struct rsi_hw *adapter = NULL;
struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf; struct ieee80211_bss_conf *bss = NULL;
char bgscan_buf[200]; char bgscan_buf[200];
int bgscan_vals[64] = { 0 }; int bgscan_vals[64] = { 0 };
int total_bytes, cnt = 0; int total_bytes, cnt = 0;
int bytes_read = 0, t_bytes; int bytes_read = 0, t_bytes;
int ret; int ret;
if (!common) {
ven_rsi_dbg(ERR_ZONE, "No Interface\n");
return -ENODEV;
}
if (common->iface_down) {
ven_rsi_dbg(ERR_ZONE, "Interface Down\n");
return -ENODEV;
}
adapter = common->priv;
bss = &adapter->vifs[0]->bss_conf;
total_bytes = simple_write_to_buffer(bgscan_buf, total_bytes = simple_write_to_buffer(bgscan_buf,
sizeof(bgscan_buf) - 1, sizeof(bgscan_buf) - 1,
ppos, user_buff, count); ppos, user_buff, count);
......
...@@ -160,11 +160,27 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb) ...@@ -160,11 +160,27 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
if (skb->protocol == cpu_to_be16(ETH_P_PAE)) { if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
ven_rsi_dbg(INFO_ZONE, "*** Tx EAPOL ***\n"); ven_rsi_dbg(INFO_ZONE, "*** Tx EAPOL ***\n");
frame_desc[3] = cpu_to_le16(RATE_INFO_ENABLE);
if (common->band == NL80211_BAND_5GHZ)
frame_desc[4] = cpu_to_le16(RSI_RATE_6);
else
frame_desc[4] = cpu_to_le16(RSI_RATE_1);
frame_desc[6] |= cpu_to_le16(BIT(13)); frame_desc[6] |= cpu_to_le16(BIT(13));
frame_desc[1] |= cpu_to_le16(BIT(12)); frame_desc[1] |= cpu_to_le16(BIT(12));
if (vif->type == NL80211_IFTYPE_STATION) {
frame_desc[0] = cpu_to_le16((skb->len - FRAME_DESC_SZ) |
(RSI_WIFI_MGMT_Q << 12));
if ((skb->len - header_size) == 133) {
ven_rsi_dbg(INFO_ZONE, "*** Tx EAPOL 4*****\n");
frame_desc[1] |=
cpu_to_le16(RSI_DESC_REQUIRE_CFM_TO_HOST);
xtend_desc->confirm_frame_type = EAPOL4_CONFIRM;
}
}
#define EAPOL_RETRY_CNT 15 #define EAPOL_RETRY_CNT 15
xtend_desc->retry_cnt = EAPOL_RETRY_CNT; xtend_desc->retry_cnt = EAPOL_RETRY_CNT;
#ifdef EAPOL_IN_MGMT_Q #if 0
skb->priority = VO_Q; skb->priority = VO_Q;
#endif #endif
} }
...@@ -178,14 +194,12 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb) ...@@ -178,14 +194,12 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
(is_multicast_ether_addr(wh->addr1))) { (is_multicast_ether_addr(wh->addr1))) {
frame_desc[3] = cpu_to_le16(RATE_INFO_ENABLE); frame_desc[3] = cpu_to_le16(RATE_INFO_ENABLE);
frame_desc[3] |= cpu_to_le16(RSI_BROADCAST_PKT); frame_desc[3] |= cpu_to_le16(RSI_BROADCAST_PKT);
#if 0 if (vif->type == NL80211_IFTYPE_AP) {
if (common->min_rate == 0xffff) {
if (common->band == NL80211_BAND_5GHZ) if (common->band == NL80211_BAND_5GHZ)
frame_desc[4] = cpu_to_le16(RSI_RATE_6); frame_desc[4] = cpu_to_le16(RSI_RATE_6);
else else
frame_desc[4] = cpu_to_le16(RSI_RATE_1); frame_desc[4] = cpu_to_le16(RSI_RATE_1);
} }
#endif
} }
if ((vif->type == NL80211_IFTYPE_AP) && if ((vif->type == NL80211_IFTYPE_AP) &&
...@@ -196,7 +210,7 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb) ...@@ -196,7 +210,7 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
err: err:
++common->tx_stats.total_tx_pkt_freed[skb->priority]; ++common->tx_stats.total_tx_pkt_freed[skb->priority];
rsi_indicate_tx_status(common->priv, skb, status); rsi_indicate_tx_status(adapter, skb, status);
return status; return status;
} }
...@@ -323,6 +337,8 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb) ...@@ -323,6 +337,8 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
u8 header_size = 0; u8 header_size = 0;
info = IEEE80211_SKB_CB(skb); info = IEEE80211_SKB_CB(skb);
if (!info->control.vif)
goto err;
bss = &info->control.vif->bss_conf; bss = &info->control.vif->bss_conf;
tx_params = (struct skb_info *)info->driver_data; tx_params = (struct skb_info *)info->driver_data;
...@@ -381,7 +397,6 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb) ...@@ -381,7 +397,6 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb)
skb->data, skb->len); skb->data, skb->len);
status = rsi_send_pkt(common, skb); status = rsi_send_pkt(common, skb);
if (status) { if (status) {
ven_rsi_dbg(ERR_ZONE, ven_rsi_dbg(ERR_ZONE,
"%s: Failed to write the packet\n", "%s: Failed to write the packet\n",
...@@ -391,6 +406,8 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb) ...@@ -391,6 +406,8 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb)
return status; return status;
} }
if (!info->control.vif)
goto out;
bss = &info->control.vif->bss_conf; bss = &info->control.vif->bss_conf;
wh = (struct ieee80211_hdr *)&skb->data[header_size]; wh = (struct ieee80211_hdr *)&skb->data[header_size];
...@@ -398,23 +415,24 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb) ...@@ -398,23 +415,24 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb)
xtend_desc = (struct xtended_desc *)&skb->data[FRAME_DESC_SZ]; xtend_desc = (struct xtended_desc *)&skb->data[FRAME_DESC_SZ];
/* Indicate to firmware to give cfm */ /* Indicate to firmware to give cfm */
if (ieee80211_is_probe_req(wh->frame_control)) { // && (!bss->assoc)) { if (ieee80211_is_probe_req(wh->frame_control)) {
if (!bss->assoc) { if (!bss->assoc) {
ven_rsi_dbg(INFO_ZONE, "%s: blocking mgmt queue\n", __func__); ven_rsi_dbg(INFO_ZONE,
"%s: blocking mgmt queue\n", __func__);
desc[1] |= cpu_to_le16(RSI_DESC_REQUIRE_CFM_TO_HOST); desc[1] |= cpu_to_le16(RSI_DESC_REQUIRE_CFM_TO_HOST);
xtend_desc->confirm_frame_type = PROBEREQ_CONFIRM; xtend_desc->confirm_frame_type = PROBEREQ_CONFIRM;
common->mgmt_q_block = true; common->mgmt_q_block = true;
ven_rsi_dbg(INFO_ZONE, "Mgmt queue blocked\n"); ven_rsi_dbg(INFO_ZONE, "Mgmt queue blocked\n");
} else if (common->bgscan_en) { } else if (common->bgscan_en) {
/* Drop off channel probe request */
if (common->mac80211_cur_channel != if (common->mac80211_cur_channel !=
rsi_get_connected_channel(adapter)) { rsi_get_connected_channel(adapter)) {
dev_kfree_skb(skb); /* Drop off channel probe request */
return 0; status = 0;
goto out;
} else if (wh->addr1[0] == 0xff) { } else if (wh->addr1[0] == 0xff) {
/* Drop broadcast probe in connected channel*/ /* Drop broadcast probe in connected channel*/
dev_kfree_skb(skb); status = 0;
return 0; goto out;
} }
} }
ven_rsi_dbg(MGMT_TX_ZONE, "Sending PROBE REQUEST =====>\n"); ven_rsi_dbg(MGMT_TX_ZONE, "Sending PROBE REQUEST =====>\n");
...@@ -433,6 +451,7 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb) ...@@ -433,6 +451,7 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb)
__func__); __func__);
} }
out:
rsi_indicate_tx_status(common->priv, skb, status); rsi_indicate_tx_status(common->priv, skb, status);
return status; return status;
} }
...@@ -472,7 +491,6 @@ int rsi_send_bt_pkt(struct rsi_common *common, struct sk_buff *skb) ...@@ -472,7 +491,6 @@ int rsi_send_bt_pkt(struct rsi_common *common, struct sk_buff *skb)
int rsi_send_beacon(struct rsi_common *common) int rsi_send_beacon(struct rsi_common *common)
{ {
struct rsi_hw *adapter = common->priv;
struct rsi_mac_frame *bcn_frm = NULL; struct rsi_mac_frame *bcn_frm = NULL;
u16 bcn_len = common->beacon_frame_len; u16 bcn_len = common->beacon_frame_len;
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
...@@ -481,16 +499,18 @@ int rsi_send_beacon(struct rsi_common *common) ...@@ -481,16 +499,18 @@ int rsi_send_beacon(struct rsi_common *common)
u8 vap_id = 0; u8 vap_id = 0;
u8 dword_align_bytes = 0; u8 dword_align_bytes = 0;
u8 header_size = 0; u8 header_size = 0;
int status = 0;
skb = dev_alloc_skb(FRAME_DESC_SZ + bcn_len + 64); skb = dev_alloc_skb(MAX_MGMT_PKT_SIZE);
if (!skb) if (!skb)
return -ENOMEM; return -ENOMEM;
dword_align_bytes = ((unsigned long)skb->data & 0x3f); dword_align_bytes = ((unsigned long)skb->data & 0x3f);
printk("%s: dword_bytes = %d\n", __func__, dword_align_bytes); if (dword_align_bytes) {
header_size = dword_align_bytes + FRAME_DESC_SZ; skb_pull(skb, (64 - dword_align_bytes));
printk("header_size = %d\n", header_size); }
memset(skb->data, 0, header_size + bcn_len + 64); header_size = FRAME_DESC_SZ;
memset(skb->data, 0, MAX_MGMT_PKT_SIZE);
common->beacon_cnt++; common->beacon_cnt++;
bcn_frm = (struct rsi_mac_frame *)skb->data; bcn_frm = (struct rsi_mac_frame *)skb->data;
...@@ -514,29 +534,31 @@ int rsi_send_beacon(struct rsi_common *common) ...@@ -514,29 +534,31 @@ int rsi_send_beacon(struct rsi_common *common)
} }
if (common->band == NL80211_BAND_2GHZ) if (common->band == NL80211_BAND_2GHZ)
bcn_frm->desc_word[4] |= cpu_to_le16(0xB | RSI_11G_MODE); bcn_frm->desc_word[4] |= cpu_to_le16(RSI_RATE_1);
else else
bcn_frm->desc_word[4] |= cpu_to_le16(RSI_11B_MODE); bcn_frm->desc_word[4] |= cpu_to_le16(RSI_RATE_6);
//if (!(common->beacon_cnt % common->dtim_cnt)) //if (!(common->beacon_cnt % common->dtim_cnt))
if (1) //FIXME check this if (1) //FIXME check this
bcn_frm->desc_word[3] |= cpu_to_le16(DTIM_BEACON); bcn_frm->desc_word[3] |= cpu_to_le16(DTIM_BEACON);
//mutex_lock(&common->mutex);
memcpy(&skb->data[header_size], common->beacon_frame, bcn_len); memcpy(&skb->data[header_size], common->beacon_frame, bcn_len);
//mutex_unlock(&common->mutex);
skb_put(skb, bcn_len + header_size); skb_put(skb, bcn_len + header_size);
rsi_hex_dump(MGMT_TX_ZONE, "Beacon Frame", skb->data, skb->len); rsi_hex_dump(MGMT_TX_ZONE, "Beacon Frame", skb->data, skb->len);
if (adapter->host_intf_ops->write_pkt(adapter, skb->data, skb->len) < 0) { mutex_lock(&common->tx_lock);
if (rsi_send_pkt(common, skb)) {
ven_rsi_dbg(ERR_ZONE, "Failed to send Beacon\n"); ven_rsi_dbg(ERR_ZONE, "Failed to send Beacon\n");
goto err; status = -EINVAL;
} }
return 0; mutex_unlock(&common->tx_lock);
err:
dev_kfree_skb(skb); dev_kfree_skb(skb);
return -1; return status;
} }
/** /**
......
...@@ -198,21 +198,6 @@ static int rsi_hci_send_pkt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -198,21 +198,6 @@ static int rsi_hci_send_pkt(struct hci_dev *hdev, struct sk_buff *skb)
return status; return status;
} }
void rsi_hci_scheduler_thread(struct rsi_common *common)
{
struct rsi_hw *adapter = common->priv;
int status = 0;
do {
status = adapter->check_intr_status_reg(adapter);
if (adapter->isr_pending)
adapter->isr_pending = 0;
msleep(20);
} while (atomic_read(&common->hci_thread.thread_done) == 0);
complete_and_exit(&common->hci_thread.completion, 0);
}
int rsi_hci_recv_pkt(struct rsi_common *common, u8 *pkt) int rsi_hci_recv_pkt(struct rsi_common *common, u8 *pkt)
{ {
struct rsi_hci_adapter *h_adapter = struct rsi_hci_adapter *h_adapter =
...@@ -234,31 +219,6 @@ int rsi_hci_recv_pkt(struct rsi_common *common, u8 *pkt) ...@@ -234,31 +219,6 @@ int rsi_hci_recv_pkt(struct rsi_common *common, u8 *pkt)
return 0; return 0;
} }
/* TODO: Work aroud for Dell; move this to module_param */
#if (defined(CONFIG_DELL_BOARD) && defined(CONFIG_VEN_RSI_HCI))
if (rsi_set_antenna(common, ANTENNA_SEL_UFL)) {
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to configure external antenna\n",
__func__);
} else
ven_rsi_dbg(INFO_ZONE, "***** UFL antenna is configured\n");
#endif
#if (defined(CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX))
#if defined(CONFIG_DELL_BOARD)
if (common->priv->rsi_host_intf == RSI_HOST_INTF_SDIO) {
rsi_init_event(&common->hci_thread.event);
if (rsi_create_kthread(common,
&common->hci_thread,
rsi_hci_scheduler_thread,
"hci-Thread")) {
ven_rsi_dbg(ERR_ZONE, "%s: Unable to init hci thrd\n",
__func__);
}
}
#endif
#endif
return 0; return 0;
} }
...@@ -504,6 +464,7 @@ int rsi_hci_attach(struct rsi_common *common) ...@@ -504,6 +464,7 @@ int rsi_hci_attach(struct rsi_common *common)
#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 12, 34) #if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 12, 34)
genl_unregister_ops(gcb->gc_family, gcb->gc_ops); genl_unregister_ops(gcb->gc_family, gcb->gc_ops);
#endif #endif
kfree(gcb);
} }
h_adapter->gcb = NULL; h_adapter->gcb = NULL;
kfree(h_adapter); kfree(h_adapter);
...@@ -547,6 +508,7 @@ void rsi_hci_detach(struct rsi_common *common) ...@@ -547,6 +508,7 @@ void rsi_hci_detach(struct rsi_common *common)
genl_unregister_ops(gcb->gc_family, gcb->gc_ops); genl_unregister_ops(gcb->gc_family, gcb->gc_ops);
#endif #endif
h_adapter->gcb = NULL; h_adapter->gcb = NULL;
kfree(gcb);
} }
kfree(h_adapter); kfree(h_adapter);
......
...@@ -442,9 +442,15 @@ static int rsi_mac80211_add_interface(struct ieee80211_hw *hw, ...@@ -442,9 +442,15 @@ static int rsi_mac80211_add_interface(struct ieee80211_hw *hw,
} }
if (vif->type == NL80211_IFTYPE_AP) { if (vif->type == NL80211_IFTYPE_AP) {
int i;
common->bc_mc_seqno = 1; common->bc_mc_seqno = 1;
rsi_send_rx_filter_frame(common, DISALLOW_BEACONS); rsi_send_rx_filter_frame(common, DISALLOW_BEACONS);
rsi_set_min_rate(hw, NULL, common); common->min_rate = 0xffff;
//common->bitrate_mask[NL80211_BAND_2GHZ] = 0xfff;
//common->bitrate_mask[NL80211_BAND_5GHZ] = 0xfff;
for (i = 0; i < RSI_MAX_ASSOC_STAS; i++)
common->stations[i].sta = NULL;
} }
mutex_unlock(&common->mutex); mutex_unlock(&common->mutex);
...@@ -762,7 +768,7 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw, ...@@ -762,7 +768,7 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
ALLOW_CTRL_ASSOC_PEER | ALLOW_CTRL_ASSOC_PEER |
ALLOW_MGMT_ASSOC_PEER | ALLOW_MGMT_ASSOC_PEER |
#ifdef RSI_HW_CONN_MONITOR #ifdef RSI_HW_CONN_MONITOR
DISALLOW_BEACONS | //DISALLOW_BEACONS |
#endif #endif
0); 0);
rsi_send_rx_filter_frame(common, rx_filter_word); rsi_send_rx_filter_frame(common, rx_filter_word);
...@@ -778,7 +784,7 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw, ...@@ -778,7 +784,7 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
/* Send peer notify to device */ /* Send peer notify to device */
ven_rsi_dbg(INFO_ZONE, "Indicate bss status to device\n"); ven_rsi_dbg(INFO_ZONE, "Indicate bss status to device\n");
rsi_inform_bss_status(common, STA_OPMODE, bss->assoc, rsi_inform_bss_status(common, STA_OPMODE, bss->assoc,
bss->bssid, bss->qos, bss->aid, 0); bss->bssid, bss->qos, bss->aid, NULL, 0);
adapter->ps_info.listen_interval = adapter->ps_info.listen_interval =
bss->beacon_int * adapter->ps_info.num_bcns_per_lis_int; bss->beacon_int * adapter->ps_info.num_bcns_per_lis_int;
...@@ -810,6 +816,7 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw, ...@@ -810,6 +816,7 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_BEACON_INT) { if (changed & BSS_CHANGED_BEACON_INT) {
ven_rsi_dbg(INFO_ZONE, "%s: Changed Beacon interval: %d\n", ven_rsi_dbg(INFO_ZONE, "%s: Changed Beacon interval: %d\n",
__func__, bss_conf->beacon_int); __func__, bss_conf->beacon_int);
common->beacon_interval = bss->beacon_int;
adapter->ps_info.listen_interval = adapter->ps_info.listen_interval =
bss->beacon_int * adapter->ps_info.num_bcns_per_lis_int; bss->beacon_int * adapter->ps_info.num_bcns_per_lis_int;
} }
...@@ -822,10 +829,19 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw, ...@@ -822,10 +829,19 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
if ((changed & BSS_CHANGED_BEACON_ENABLED) && if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
(vif->type == NL80211_IFTYPE_AP)) { (vif->type == NL80211_IFTYPE_AP)) {
if (bss->enable_beacon) if (bss->enable_beacon) {
ven_rsi_dbg(INFO_ZONE, "===> BEACON ENABLED <===\n"); ven_rsi_dbg(INFO_ZONE, "===> BEACON ENABLED <===\n");
else common->beacon_enabled = 1;
#ifdef CONFIG_CARACALLA_BOARD
rsi_init_bcn_timer(common);
#endif
} else {
ven_rsi_dbg(INFO_ZONE, "===> BEACON DISABLED <===\n"); ven_rsi_dbg(INFO_ZONE, "===> BEACON DISABLED <===\n");
common->beacon_enabled = 0;
#ifdef CONFIG_CARACALLA_BOARD
rsi_del_bcn_timer(common);
#endif
}
} }
mutex_unlock(&common->mutex); mutex_unlock(&common->mutex);
...@@ -1073,6 +1089,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw, ...@@ -1073,6 +1089,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
struct rsi_common *common = adapter->priv; struct rsi_common *common = adapter->priv;
u16 seq_no = 0; u16 seq_no = 0;
u8 ii = 0; u8 ii = 0;
u8 sta_id = 0;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0))
u16 tid = params->tid; u16 tid = params->tid;
...@@ -1094,6 +1111,15 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw, ...@@ -1094,6 +1111,15 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
#else #else
seq_no = params->ssn; seq_no = params->ssn;
#endif #endif
if (vif->type == NL80211_IFTYPE_AP) {
struct rsi_sta *rsta = rsi_find_sta(common, sta->addr);
if (!rsta) {
ven_rsi_dbg(ERR_ZONE, "No station mapped\n");
return 0;
}
sta_id = rsta->sta_id;
}
ven_rsi_dbg(INFO_ZONE, ven_rsi_dbg(INFO_ZONE,
"%s: AMPDU action tid=%d ssn=0x%x, buf_size=%d\n", "%s: AMPDU action tid=%d ssn=0x%x, buf_size=%d\n",
...@@ -1106,7 +1132,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw, ...@@ -1106,7 +1132,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
tid, tid,
seq_no, seq_no,
buf_size, buf_size,
STA_RX_ADDBA_DONE); STA_RX_ADDBA_DONE,
sta_id);
break; break;
case IEEE80211_AMPDU_RX_STOP: case IEEE80211_AMPDU_RX_STOP:
...@@ -1116,7 +1143,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw, ...@@ -1116,7 +1143,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
tid, tid,
0, 0,
buf_size, buf_size,
STA_RX_DELBA); STA_RX_DELBA,
sta_id);
break; break;
case IEEE80211_AMPDU_TX_START: case IEEE80211_AMPDU_TX_START:
...@@ -1137,7 +1165,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw, ...@@ -1137,7 +1165,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
tid, tid,
seq_no, seq_no,
buf_size, buf_size,
STA_TX_DELBA); STA_TX_DELBA,
sta_id);
if (!status) if (!status)
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
break; break;
...@@ -1150,7 +1179,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw, ...@@ -1150,7 +1179,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
tid, tid,
common->vif_info[ii].seq_start, common->vif_info[ii].seq_start,
buf_size, buf_size,
STA_TX_ADDBA_DONE); STA_TX_ADDBA_DONE,
sta_id);
break; break;
default: default:
...@@ -1332,6 +1362,8 @@ void rsi_indicate_pkt_to_os(struct rsi_common *common, ...@@ -1332,6 +1362,8 @@ void rsi_indicate_pkt_to_os(struct rsi_common *common,
/* filling in the ieee80211_rx_status flags */ /* filling in the ieee80211_rx_status flags */
rsi_fill_rx_status(hw, skb, common, rx_status); rsi_fill_rx_status(hw, skb, common, rx_status);
ven_rsi_dbg(INFO_ZONE, "RX Packet Type: %s\n",
dot11_pkt_type(skb->data[0]));
rsi_hex_dump(DATA_RX_ZONE, "802.11 RX packet", skb->data, skb->len); rsi_hex_dump(DATA_RX_ZONE, "802.11 RX packet", skb->data, skb->len);
ieee80211_rx_irqsafe(hw, skb); ieee80211_rx_irqsafe(hw, skb);
} }
...@@ -1359,10 +1391,22 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw, ...@@ -1359,10 +1391,22 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
if (vif->type == NL80211_IFTYPE_AP) { if (vif->type == NL80211_IFTYPE_AP) {
u8 i, j; u8 i, j;
int free_index = -1;
/* Check if max stations reached */
if (common->num_stations >= RSI_MAX_ASSOC_STAS) {
ven_rsi_dbg(ERR_ZONE, "Reject: Max Stations exists\n");
return -EINVAL;
}
/* Send peer notify to device */ /* Send peer notify to device */
ven_rsi_dbg(INFO_ZONE, "Indicate bss status to device\n"); ven_rsi_dbg(INFO_ZONE, "Indicate bss status to device\n");
for (i = 0; i < common->num_stations; i++) { for (i = 0; i < RSI_MAX_ASSOC_STAS; i++) {
if (!common->stations[i].sta) {
if (free_index < 0)
free_index = i;
continue;
}
if (!memcmp(common->stations[i].sta->addr, if (!memcmp(common->stations[i].sta->addr,
sta->addr, ETH_ALEN)) { sta->addr, ETH_ALEN)) {
ven_rsi_dbg(INFO_ZONE, "Station exists\n"); ven_rsi_dbg(INFO_ZONE, "Station exists\n");
...@@ -1372,15 +1416,18 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw, ...@@ -1372,15 +1416,18 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
} }
if (!sta_exist) { if (!sta_exist) {
ven_rsi_dbg(INFO_ZONE, "New Station\n"); ven_rsi_dbg(INFO_ZONE, "New Station\n");
rsi_inform_bss_status(common, AP_OPMODE, 1, sta->addr, if (free_index >= 0)
sta->wme, sta->aid, i); i = free_index;
common->stations[i].sta = sta; common->stations[i].sta = sta;
common->stations[i].sta_id = i; common->stations[i].sta_id = i;
rsi_inform_bss_status(common, AP_OPMODE, 1, sta->addr,
sta->wme, sta->aid, sta, i);
for (j = 0; j < IEEE80211_NUM_ACS; j++) for (j = 0; j < IEEE80211_NUM_ACS; j++)
common->stations[i].seq_no[j] = 1; common->stations[i].seq_no[j] = 1;
common->num_stations++; common->num_stations++;
} else { } else {
common->stations[i].sta = sta; common->stations[i].sta = sta;
common->stations[i].sta_id = i;
for (j = 0; j < IEEE80211_NUM_ACS; j++) for (j = 0; j < IEEE80211_NUM_ACS; j++)
common->stations[i].seq_no[j] = 1; common->stations[i].seq_no[j] = 1;
} }
...@@ -1403,8 +1450,11 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw, ...@@ -1403,8 +1450,11 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
} }
} }
#if 0
if ((vif->type == NL80211_IFTYPE_STATION) && if ((vif->type == NL80211_IFTYPE_STATION) &&
sta->ht_cap.ht_supported) sta->ht_cap.ht_supported)
#endif
if (sta->ht_cap.ht_supported)
ieee80211_start_tx_ba_session(sta, 0, 0); ieee80211_start_tx_ba_session(sta, 0, 0);
mutex_unlock(&common->mutex); mutex_unlock(&common->mutex);
...@@ -1431,22 +1481,27 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw, ...@@ -1431,22 +1481,27 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
rsi_hex_dump(INFO_ZONE, "Station Removed: ", sta->addr, ETH_ALEN); rsi_hex_dump(INFO_ZONE, "Station Removed: ", sta->addr, ETH_ALEN);
mutex_lock(&common->mutex);
if (vif->type == NL80211_IFTYPE_AP) { if (vif->type == NL80211_IFTYPE_AP) {
u8 i, j; u8 i, j;
/* Send peer notify to device */ /* Send peer notify to device */
ven_rsi_dbg(INFO_ZONE, "Indicate bss status to device\n"); ven_rsi_dbg(INFO_ZONE, "Indicate bss status to device\n");
for (i = 0; i < common->num_stations; i++) { for (i = 0; i < RSI_MAX_ASSOC_STAS; i++) {
if (!common->stations[i].sta)
continue;
if (!memcmp(common->stations[i].sta->addr, if (!memcmp(common->stations[i].sta->addr,
sta->addr, ETH_ALEN)) { sta->addr, ETH_ALEN)) {
rsi_inform_bss_status(common, AP_OPMODE, 0, rsi_inform_bss_status(common, AP_OPMODE, 0,
sta->addr, sta->wme, sta->addr, sta->wme,
sta->aid, i); sta->aid, sta, i);
common->stations[i].sta = NULL; common->stations[i].sta = NULL;
common->stations[i].sta_id = -1; common->stations[i].sta_id = -1;
for (j = 0; j < IEEE80211_NUM_ACS; j++) for (j = 0; j < IEEE80211_NUM_ACS; j++)
common->stations[i].seq_no[j] = 0; common->stations[i].seq_no[j] = 0;
common->num_stations--; common->num_stations--;
if (common->num_stations < 0)
common->num_stations = 0;
break; break;
} }
} }
...@@ -1456,7 +1511,6 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw, ...@@ -1456,7 +1511,6 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
if (vif->type == NL80211_IFTYPE_STATION) { if (vif->type == NL80211_IFTYPE_STATION) {
/* Resetting all the fields to default values */ /* Resetting all the fields to default values */
mutex_lock(&common->mutex);
memcpy((u8 *)bss->bssid, (u8 *)sta->addr, ETH_ALEN); memcpy((u8 *)bss->bssid, (u8 *)sta->addr, ETH_ALEN);
bss->qos = sta->wme; bss->qos = sta->wme;
common->bitrate_mask[NL80211_BAND_2GHZ] = 0; common->bitrate_mask[NL80211_BAND_2GHZ] = 0;
...@@ -1469,11 +1523,11 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw, ...@@ -1469,11 +1523,11 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
common->secinfo.gtk_cipher = 0; common->secinfo.gtk_cipher = 0;
if (common->bgscan_en) if (common->bgscan_en)
common->bgscan_en = 0; common->bgscan_en = 0;
mutex_unlock(&common->mutex);
if (!common->iface_down) if (!common->iface_down)
rsi_send_rx_filter_frame(common, 0); rsi_send_rx_filter_frame(common, 0);
} }
mutex_unlock(&common->mutex);
return 0; return 0;
} }
#if 0 #if 0
...@@ -1626,6 +1680,8 @@ static void rsi_reg_notify(struct wiphy *wiphy, ...@@ -1626,6 +1680,8 @@ static void rsi_reg_notify(struct wiphy *wiphy,
struct ieee80211_channel *ch; struct ieee80211_channel *ch;
int i; int i;
if (common->num_supp_bands == 1)
return;
mutex_lock(&common->mutex); mutex_lock(&common->mutex);
sband = wiphy->bands[NL80211_BAND_5GHZ]; sband = wiphy->bands[NL80211_BAND_5GHZ];
...@@ -1679,7 +1735,7 @@ void rsi_mac80211_rfkill_poll(struct ieee80211_hw *hw) ...@@ -1679,7 +1735,7 @@ void rsi_mac80211_rfkill_poll(struct ieee80211_hw *hw)
#ifdef CONFIG_RSI_WOW #ifdef CONFIG_RSI_WOW
static const struct wiphy_wowlan_support rsi_wowlan_support = { static const struct wiphy_wowlan_support rsi_wowlan_support = {
.flags =WIPHY_WOWLAN_ANY | .flags = WIPHY_WOWLAN_ANY |
WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_MAGIC_PKT |
WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_DISCONNECT |
WIPHY_WOWLAN_GTK_REKEY_FAILURE | WIPHY_WOWLAN_GTK_REKEY_FAILURE |
...@@ -1719,7 +1775,7 @@ int rsi_mac80211_suspend(struct ieee80211_hw *hw, ...@@ -1719,7 +1775,7 @@ int rsi_mac80211_suspend(struct ieee80211_hw *hw,
#ifdef CONFIG_RSI_WOW #ifdef CONFIG_RSI_WOW
struct rsi_hw *adapter = hw->priv; struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv; struct rsi_common *common = adapter->priv;
u16 triggers; u16 triggers, rx_filter_word = 0;
#endif #endif
int ret = 0; int ret = 0;
...@@ -1736,13 +1792,20 @@ int rsi_mac80211_suspend(struct ieee80211_hw *hw, ...@@ -1736,13 +1792,20 @@ int rsi_mac80211_suspend(struct ieee80211_hw *hw,
triggers = rsi_wow_map_triggers(common, wowlan); triggers = rsi_wow_map_triggers(common, wowlan);
if (!triggers) { if (!triggers) {
ven_rsi_dbg(ERR_ZONE, "%s:No valid WoW triggers\n",__func__); ven_rsi_dbg(ERR_ZONE, "%s:No valid WoW triggers\n",__func__);
ret = 1; ret = -EINVAL;
goto fail_wow; goto fail_wow;
} }
ven_rsi_dbg(INFO_ZONE, "TRIGGERS %x\n", triggers); ven_rsi_dbg(INFO_ZONE, "TRIGGERS %x\n", triggers);
rsi_send_wowlan_request(common, triggers, wowlan); rsi_send_wowlan_request(common, triggers, 1);
rx_filter_word = (ALLOW_DATA_ASSOC_PEER |
ALLOW_CTRL_ASSOC_PEER |
ALLOW_MGMT_ASSOC_PEER |
DISALLOW_BEACONS |
0);
rsi_send_rx_filter_frame(common, rx_filter_word);
common->suspend_flag = 1;
fail_wow: fail_wow:
#endif #endif
return ret; return ret;
...@@ -1750,8 +1813,24 @@ int rsi_mac80211_suspend(struct ieee80211_hw *hw, ...@@ -1750,8 +1813,24 @@ int rsi_mac80211_suspend(struct ieee80211_hw *hw,
static int rsi_mac80211_resume(struct ieee80211_hw *hw) static int rsi_mac80211_resume(struct ieee80211_hw *hw)
{ {
#ifdef CONFIG_RSI_WOW
struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv;
u16 rx_filter_word = 0;
#endif
ven_rsi_dbg(INFO_ZONE, "%s: mac80211 resume\n", __func__); ven_rsi_dbg(INFO_ZONE, "%s: mac80211 resume\n", __func__);
#ifdef CONFIG_RSI_WOW
rsi_send_wowlan_request(common, 0, 0);
//rx_filter_word = 0xE ;
rx_filter_word = (ALLOW_DATA_ASSOC_PEER |
ALLOW_CTRL_ASSOC_PEER |
ALLOW_MGMT_ASSOC_PEER |
0);
rsi_send_rx_filter_frame(common, rx_filter_word);
#endif
return 0; return 0;
} }
#endif #endif
...@@ -1842,10 +1921,17 @@ int rsi_mac80211_attach(struct rsi_common *common) ...@@ -1842,10 +1921,17 @@ int rsi_mac80211_attach(struct rsi_common *common)
hw->max_rate_tries = MAX_RETRIES; hw->max_rate_tries = MAX_RETRIES;
hw->uapsd_queues = IEEE80211_MARKALL_UAPSD_QUEUES; hw->uapsd_queues = IEEE80211_MARKALL_UAPSD_QUEUES;
hw->uapsd_max_sp_len = IEEE80211_STA_SP_ALL_PKTS; hw->uapsd_max_sp_len = IEEE80211_STA_SP_ALL_PKTS;
hw->max_tx_aggregation_subframes = 6; // hw->max_tx_aggregation_subframes = 6;
hw->max_tx_aggregation_subframes = 4;
rsi_register_rates_channels(adapter, NL80211_BAND_2GHZ); rsi_register_rates_channels(adapter, NL80211_BAND_2GHZ);
wiphy->bands[NL80211_BAND_2GHZ] =
&adapter->sbands[NL80211_BAND_2GHZ];
if (common->num_supp_bands == 2) {
rsi_register_rates_channels(adapter, NL80211_BAND_5GHZ); rsi_register_rates_channels(adapter, NL80211_BAND_5GHZ);
wiphy->bands[NL80211_BAND_5GHZ] =
&adapter->sbands[NL80211_BAND_5GHZ];
}
hw->rate_control_algorithm = "AARF"; hw->rate_control_algorithm = "AARF";
hw->sta_data_size = sizeof(struct rsi_sta); hw->sta_data_size = sizeof(struct rsi_sta);
...@@ -1861,10 +1947,6 @@ int rsi_mac80211_attach(struct rsi_common *common) ...@@ -1861,10 +1947,6 @@ int rsi_mac80211_attach(struct rsi_common *common)
wiphy->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; wiphy->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
wiphy->available_antennas_tx = 1; wiphy->available_antennas_tx = 1;
wiphy->available_antennas_rx = 1; wiphy->available_antennas_rx = 1;
wiphy->bands[NL80211_BAND_2GHZ] =
&adapter->sbands[NL80211_BAND_2GHZ];
wiphy->bands[NL80211_BAND_5GHZ] =
&adapter->sbands[NL80211_BAND_5GHZ];
wiphy->max_ap_assoc_sta = RSI_MAX_ASSOC_STAS; wiphy->max_ap_assoc_sta = RSI_MAX_ASSOC_STAS;
wiphy->flags = WIPHY_FLAG_REPORTS_OBSS; wiphy->flags = WIPHY_FLAG_REPORTS_OBSS;
......
...@@ -226,6 +226,54 @@ int ven_rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len) ...@@ -226,6 +226,54 @@ int ven_rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
} }
EXPORT_SYMBOL_GPL(ven_rsi_read_pkt); EXPORT_SYMBOL_GPL(ven_rsi_read_pkt);
#ifdef CONFIG_CARACALLA_BOARD
static void rsi_bcn_sched(unsigned long data)
{
struct rsi_common *common = (struct rsi_common *)data;
rsi_set_event(&common->bcn_thread.event);
common->bcn_timer.expires =
msecs_to_jiffies(common->beacon_interval - 5) + jiffies;
add_timer(&common->bcn_timer);
}
void rsi_init_bcn_timer(struct rsi_common *common)
{
init_timer(&common->bcn_timer);
common->bcn_timer.data = (unsigned long)common;
common->bcn_timer.expires =
msecs_to_jiffies(common->beacon_interval - 5) + jiffies;
common->bcn_timer.function = (void *)rsi_bcn_sched;
add_timer(&common->bcn_timer);
}
void rsi_del_bcn_timer(struct rsi_common *common)
{
del_timer(&common->bcn_timer);
}
void rsi_bcn_scheduler_thread(struct rsi_common *common)
{
do {
rsi_wait_event(&common->bcn_thread.event,
msecs_to_jiffies(common->beacon_interval));
rsi_reset_event(&common->bcn_thread.event);
if (!common->beacon_enabled)
continue;
if (!common->init_done)
continue;
if (common->iface_down)
continue;
rsi_send_beacon(common);
} while (atomic_read(&common->bcn_thread.thread_done) == 0);
complete_and_exit(&common->bcn_thread.completion, 0);
}
#endif
/** /**
* rsi_tx_scheduler_thread() - This function is a kernel thread to send the * rsi_tx_scheduler_thread() - This function is a kernel thread to send the
* packets to the device. * packets to the device.
...@@ -250,6 +298,36 @@ static void rsi_tx_scheduler_thread(struct rsi_common *common) ...@@ -250,6 +298,36 @@ static void rsi_tx_scheduler_thread(struct rsi_common *common)
complete_and_exit(&common->tx_thread.completion, 0); complete_and_exit(&common->tx_thread.completion, 0);
} }
#ifdef CONFIG_SDIO_INTR_POLL
void rsi_sdio_intr_poll_scheduler_thread(struct rsi_common *common)
{
struct rsi_hw *adapter = common->priv;
int status = 0;
do {
status = adapter->check_intr_status_reg(adapter);
if (adapter->isr_pending)
adapter->isr_pending = 0;
msleep(20);
} while (atomic_read(&common->sdio_intr_poll_thread.thread_done) == 0);
complete_and_exit(&common->sdio_intr_poll_thread.completion, 0);
}
void init_sdio_intr_status_poll_thread(struct rsi_common *common)
{
rsi_init_event(&common->sdio_intr_poll_thread.event);
if (rsi_create_kthread(common,
&common->sdio_intr_poll_thread,
rsi_sdio_intr_poll_scheduler_thread,
"Sdio Intr poll-Thread")) {
rsi_dbg(ERR_ZONE, "%s: Unable to init sdio intr poll thrd\n",
__func__);
}
}
EXPORT_SYMBOL_GPL(init_sdio_intr_status_poll_thread);
#endif
/** /**
* ven_rsi_91x_init() - This function initializes os interface operations. * ven_rsi_91x_init() - This function initializes os interface operations.
* @void: Void. * @void: Void.
...@@ -285,6 +363,7 @@ struct rsi_hw *ven_rsi_91x_init(void) ...@@ -285,6 +363,7 @@ struct rsi_hw *ven_rsi_91x_init(void)
skb_queue_head_init(&common->tx_queue[ii]); skb_queue_head_init(&common->tx_queue[ii]);
rsi_init_event(&common->tx_thread.event); rsi_init_event(&common->tx_thread.event);
rsi_init_event(&common->bcn_thread.event);
mutex_init(&common->mutex); mutex_init(&common->mutex);
mutex_init(&common->tx_lock); mutex_init(&common->tx_lock);
mutex_init(&common->rx_lock); mutex_init(&common->rx_lock);
...@@ -297,6 +376,16 @@ struct rsi_hw *ven_rsi_91x_init(void) ...@@ -297,6 +376,16 @@ struct rsi_hw *ven_rsi_91x_init(void)
goto err; goto err;
} }
#ifdef CONFIG_CARACALLA_BOARD
if (rsi_create_kthread(common,
&common->bcn_thread,
rsi_bcn_scheduler_thread,
"Beacon-Thread")) {
ven_rsi_dbg(ERR_ZONE, "%s: Unable to init bcn thrd\n", __func__);
goto err;
}
#endif
#ifdef CONFIG_VEN_RSI_COEX #ifdef CONFIG_VEN_RSI_COEX
if (rsi_coex_init(common)) { if (rsi_coex_init(common)) {
ven_rsi_dbg(ERR_ZONE, "Failed to init COEX module\n"); ven_rsi_dbg(ERR_ZONE, "Failed to init COEX module\n");
...@@ -332,6 +421,9 @@ void ven_rsi_91x_deinit(struct rsi_hw *adapter) ...@@ -332,6 +421,9 @@ void ven_rsi_91x_deinit(struct rsi_hw *adapter)
ven_rsi_dbg(INFO_ZONE, "%s: Deinit core module...\n", __func__); ven_rsi_dbg(INFO_ZONE, "%s: Deinit core module...\n", __func__);
rsi_kill_thread(&common->tx_thread); rsi_kill_thread(&common->tx_thread);
#ifdef CONFIG_CARACALLA_BOARD
rsi_kill_thread(&common->bcn_thread);
#endif
for (ii = 0; ii < NUM_SOFT_QUEUES; ii++) for (ii = 0; ii < NUM_SOFT_QUEUES; ii++)
skb_queue_purge(&common->tx_queue[ii]); skb_queue_purge(&common->tx_queue[ii]);
...@@ -341,6 +433,8 @@ void ven_rsi_91x_deinit(struct rsi_hw *adapter) ...@@ -341,6 +433,8 @@ void ven_rsi_91x_deinit(struct rsi_hw *adapter)
#endif #endif
common->init_done = false; common->init_done = false;
kfree(common->beacon_frame);
common->beacon_frame = NULL;
kfree(common); kfree(common);
kfree(adapter->rsi_dev); kfree(adapter->rsi_dev);
kfree(adapter); kfree(adapter);
......
...@@ -341,6 +341,7 @@ static void rsi_set_default_parameters(struct rsi_common *common) ...@@ -341,6 +341,7 @@ static void rsi_set_default_parameters(struct rsi_common *common)
common->antenna_diversity = 0; common->antenna_diversity = 0;
common->tx_power = RSI_TXPOWER_MAX; common->tx_power = RSI_TXPOWER_MAX;
common->dtim_cnt = 2; common->dtim_cnt = 2;
common->beacon_interval = 100;
} }
void init_bgscan_params(struct rsi_common *common) void init_bgscan_params(struct rsi_common *common)
...@@ -606,7 +607,7 @@ static int rsi_mgmt_pkt_to_core(struct rsi_common *common, ...@@ -606,7 +607,7 @@ static int rsi_mgmt_pkt_to_core(struct rsi_common *common,
* *
* Return: status: 0 on success, corresponding negative error code on failure. * Return: status: 0 on success, corresponding negative error code on failure.
*/ */
static int rsi_send_sta_notify_frame(struct rsi_common *common, int rsi_send_sta_notify_frame(struct rsi_common *common,
enum opmode opmode, enum opmode opmode,
u8 notify_event, u8 notify_event,
const unsigned char *bssid, const unsigned char *bssid,
...@@ -685,7 +686,8 @@ int rsi_send_aggr_params_frame(struct rsi_common *common, ...@@ -685,7 +686,8 @@ int rsi_send_aggr_params_frame(struct rsi_common *common,
u16 tid, u16 tid,
u16 ssn, u16 ssn,
u8 buf_size, u8 buf_size,
u8 event) u8 event,
u8 sta_id)
{ {
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
struct rsi_mac_frame *mgmt_frame; struct rsi_mac_frame *mgmt_frame;
...@@ -868,7 +870,7 @@ int rsi_set_vap_capabilities(struct rsi_common *common, ...@@ -868,7 +870,7 @@ int rsi_set_vap_capabilities(struct rsi_common *common,
#endif #endif
vap_caps->default_data_rate = 0; vap_caps->default_data_rate = 0;
vap_caps->beacon_interval = cpu_to_le16(200); vap_caps->beacon_interval = cpu_to_le16(common->beacon_interval);
vap_caps->dtim_period = cpu_to_le16(common->dtim_cnt); vap_caps->dtim_period = cpu_to_le16(common->dtim_cnt);
// vap_caps->beacon_miss_threshold = cpu_to_le16(10); // vap_caps->beacon_miss_threshold = cpu_to_le16(10);
if (mode == AP_OPMODE) if (mode == AP_OPMODE)
...@@ -972,17 +974,13 @@ int rsi_load_key(struct rsi_common *common, ...@@ -972,17 +974,13 @@ int rsi_load_key(struct rsi_common *common,
set_key->desc_word[4] = cpu_to_le16(key_descriptor); set_key->desc_word[4] = cpu_to_le16(key_descriptor);
set_key->desc_word[7] = cpu_to_le16(sta_id | (vap_id << 8)); set_key->desc_word[7] = cpu_to_le16(sta_id | (vap_id << 8));
#if 0 if (data) {
if ((cipher == WLAN_CIPHER_SUITE_WEP40) || if ((cipher == WLAN_CIPHER_SUITE_WEP40) ||
(cipher == WLAN_CIPHER_SUITE_WEP104)) { (cipher == WLAN_CIPHER_SUITE_WEP104)) {
memcpy(&set_key->key[key_id][1], data, key_len * 2); memcpy(&set_key->key[key_id][1], data, key_len * 2);
} else { } else {
memcpy(&set_key->key[0][0], data, key_len); memcpy(&set_key->key[0][0], data, key_len);
} }
#endif
if (data) {
memcpy(&set_key->key[0][0], data, key_len);
//memcpy(&set_key->key, data, 4 * 32);
memcpy(set_key->tx_mic_key, &data[16], 8); memcpy(set_key->tx_mic_key, &data[16], 8);
memcpy(set_key->rx_mic_key, &data[24], 8); memcpy(set_key->rx_mic_key, &data[24], 8);
} else { } else {
...@@ -1401,8 +1399,13 @@ int rsi_send_vap_dynamic_update(struct rsi_common *common) ...@@ -1401,8 +1399,13 @@ int rsi_send_vap_dynamic_update(struct rsi_common *common)
dynamic_frame->desc_word[5] = cpu_to_le16(common->frag_threshold); dynamic_frame->desc_word[5] = cpu_to_le16(common->frag_threshold);
dynamic_frame->desc_word[5] = cpu_to_le16(2352); dynamic_frame->desc_word[5] = cpu_to_le16(2352);
#endif #endif
// dynamic_frame->desc_word[6] = cpu_to_le16(10); /* bmiss_threshold */
#ifdef CONFIG_RSI_WOW
dynamic_frame->desc_word[6] = cpu_to_le16(24); /* bmiss_threshold */
dynamic_frame->frame_body.keep_alive_period = cpu_to_le16(10);
#else
dynamic_frame->frame_body.keep_alive_period = cpu_to_le16(90); dynamic_frame->frame_body.keep_alive_period = cpu_to_le16(90);
#endif
#if 0 #if 0
dynamic_frame->frame_body.mgmt_rate = cpu_to_le32(RSI_RATE_6); dynamic_frame->frame_body.mgmt_rate = cpu_to_le32(RSI_RATE_6);
...@@ -1526,8 +1529,10 @@ static bool rsi_map_rates(u16 rate, int *offset) ...@@ -1526,8 +1529,10 @@ static bool rsi_map_rates(u16 rate, int *offset)
* Return: 0 on success, corresponding error code on failure. * Return: 0 on success, corresponding error code on failure.
*/ */
static int rsi_send_auto_rate_request(struct rsi_common *common, static int rsi_send_auto_rate_request(struct rsi_common *common,
struct ieee80211_sta *sta,
u16 sta_id) u16 sta_id)
{ {
struct ieee80211_vif *vif = common->priv->vifs[0];
struct sk_buff *skb; struct sk_buff *skb;
struct rsi_auto_rate *auto_rate; struct rsi_auto_rate *auto_rate;
int ii = 0, jj = 0, kk = 0; int ii = 0, jj = 0, kk = 0;
...@@ -1535,8 +1540,9 @@ static int rsi_send_auto_rate_request(struct rsi_common *common, ...@@ -1535,8 +1540,9 @@ static int rsi_send_auto_rate_request(struct rsi_common *common,
u8 band = hw->conf.chandef.chan->band; u8 band = hw->conf.chandef.chan->band;
u8 num_supported_rates = 0; u8 num_supported_rates = 0;
u8 rate_table_offset, rate_offset = 0; u8 rate_table_offset, rate_offset = 0;
u32 rate_bitmap = common->bitrate_mask[band]; u32 rate_bitmap = 0;
u16 *selected_rates, min_rate; u16 *selected_rates, min_rate;
bool is_ht = false, is_sgi = false;
ven_rsi_dbg(MGMT_TX_ZONE, ven_rsi_dbg(MGMT_TX_ZONE,
"%s: Sending auto rate request frame\n", __func__); "%s: Sending auto rate request frame\n", __func__);
...@@ -1548,6 +1554,8 @@ static int rsi_send_auto_rate_request(struct rsi_common *common, ...@@ -1548,6 +1554,8 @@ static int rsi_send_auto_rate_request(struct rsi_common *common,
return -ENOMEM; return -ENOMEM;
} }
memset(skb->data, 0, MAX_MGMT_PKT_SIZE);
selected_rates = kzalloc(2 * RSI_TBL_SZ, GFP_KERNEL); selected_rates = kzalloc(2 * RSI_TBL_SZ, GFP_KERNEL);
if (!selected_rates) { if (!selected_rates) {
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of mem\n", ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of mem\n",
...@@ -1555,8 +1563,6 @@ static int rsi_send_auto_rate_request(struct rsi_common *common, ...@@ -1555,8 +1563,6 @@ static int rsi_send_auto_rate_request(struct rsi_common *common,
dev_kfree_skb(skb); dev_kfree_skb(skb);
return -ENOMEM; return -ENOMEM;
} }
memset(skb->data, 0, sizeof(struct rsi_auto_rate));
memset(selected_rates, 0, 2 * RSI_TBL_SZ); memset(selected_rates, 0, 2 * RSI_TBL_SZ);
auto_rate = (struct rsi_auto_rate *)skb->data; auto_rate = (struct rsi_auto_rate *)skb->data;
...@@ -1573,10 +1579,30 @@ static int rsi_send_auto_rate_request(struct rsi_common *common, ...@@ -1573,10 +1579,30 @@ static int rsi_send_auto_rate_request(struct rsi_common *common,
auto_rate->desc_word[7] = cpu_to_le16(1); auto_rate->desc_word[7] = cpu_to_le16(1);
auto_rate->desc_word[7] |= cpu_to_le16(sta_id << 8); auto_rate->desc_word[7] |= cpu_to_le16(sta_id << 8);
if (vif->type == NL80211_IFTYPE_STATION) {
rate_bitmap = common->bitrate_mask[band];
is_ht = common->vif_info[0].is_ht;
is_sgi = common->vif_info[0].sgi;
} else {
rate_bitmap = sta->supp_rates[band];
is_ht = sta->ht_cap.ht_supported;
if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ||
(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40))
is_sgi = true;
}
printk("rate_bitmap = %x\n", rate_bitmap);
printk("is_ht = %d\n", is_ht);
if (band == NL80211_BAND_2GHZ) { if (band == NL80211_BAND_2GHZ) {
if ((rate_bitmap == 0) && (is_ht))
min_rate = RSI_RATE_MCS0;
else
min_rate = RSI_RATE_1; min_rate = RSI_RATE_1;
rate_table_offset = 0; rate_table_offset = 0;
} else { } else {
if ((rate_bitmap == 0) && (is_ht))
min_rate = RSI_RATE_MCS0;
else
min_rate = RSI_RATE_6; min_rate = RSI_RATE_6;
rate_table_offset = 4; rate_table_offset = 4;
} }
...@@ -1591,7 +1617,7 @@ static int rsi_send_auto_rate_request(struct rsi_common *common, ...@@ -1591,7 +1617,7 @@ static int rsi_send_auto_rate_request(struct rsi_common *common,
} }
num_supported_rates = jj; num_supported_rates = jj;
if (common->vif_info[0].is_ht) { if (is_ht) {
for (ii = 0; ii < ARRAY_SIZE(mcs); ii++) for (ii = 0; ii < ARRAY_SIZE(mcs); ii++)
selected_rates[jj++] = mcs[ii]; selected_rates[jj++] = mcs[ii];
num_supported_rates += ARRAY_SIZE(mcs); num_supported_rates += ARRAY_SIZE(mcs);
...@@ -1612,13 +1638,16 @@ static int rsi_send_auto_rate_request(struct rsi_common *common, ...@@ -1612,13 +1638,16 @@ static int rsi_send_auto_rate_request(struct rsi_common *common,
} }
/* loading HT rates in the bottom half of the auto rate table */ /* loading HT rates in the bottom half of the auto rate table */
if (common->vif_info[0].is_ht) { if (is_ht) {
for (ii = rate_offset, kk = ARRAY_SIZE(rsi_mcsrates) - 1; for (ii = rate_offset, kk = ARRAY_SIZE(rsi_mcsrates) - 1;
ii < rate_offset + 2 * ARRAY_SIZE(rsi_mcsrates); ii++) { ii < rate_offset + 2 * ARRAY_SIZE(rsi_mcsrates); ii++) {
if (common->vif_info[0].sgi || if (is_sgi || conf_is_ht40(&common->priv->hw->conf)) {
conf_is_ht40(&common->priv->hw->conf))
auto_rate->supported_rates[ii++] = auto_rate->supported_rates[ii++] =
cpu_to_le16(rsi_mcsrates[kk] | BIT(9)); cpu_to_le16(rsi_mcsrates[kk] | BIT(9));
} else {
auto_rate->supported_rates[ii++] =
cpu_to_le16(rsi_mcsrates[kk]);
}
auto_rate->supported_rates[ii] = auto_rate->supported_rates[ii] =
cpu_to_le16(rsi_mcsrates[kk--]); cpu_to_le16(rsi_mcsrates[kk--]);
} }
...@@ -1849,6 +1878,7 @@ void rsi_inform_bss_status(struct rsi_common *common, ...@@ -1849,6 +1878,7 @@ void rsi_inform_bss_status(struct rsi_common *common,
u8 *bssid, u8 *bssid,
u8 qos_enable, u8 qos_enable,
u16 aid, u16 aid,
struct ieee80211_sta *sta,
u16 sta_id) u16 sta_id)
{ {
if (status) { if (status) {
...@@ -1863,15 +1893,21 @@ void rsi_inform_bss_status(struct rsi_common *common, ...@@ -1863,15 +1893,21 @@ void rsi_inform_bss_status(struct rsi_common *common,
sta_id); sta_id);
if (common->min_rate == 0xffff) { if (common->min_rate == 0xffff) {
ven_rsi_dbg(INFO_ZONE, "Send auto rate request\n"); ven_rsi_dbg(INFO_ZONE, "Send auto rate request\n");
rsi_send_auto_rate_request(common, sta_id); rsi_send_auto_rate_request(common, sta, sta_id);
} }
if (opmode == STA_OPMODE) { if (opmode == STA_OPMODE) {
if ((!common->secinfo.security_enable) ||
(rsi_is_cipher_wep(common))) {
if (!rsi_send_block_unblock_frame(common, false)) if (!rsi_send_block_unblock_frame(common, false))
common->hw_data_qs_blocked = false; common->hw_data_qs_blocked = false;
} }
}
} else { } else {
if (opmode == STA_OPMODE) if (opmode == STA_OPMODE)
common->hw_data_qs_blocked = true; common->hw_data_qs_blocked = true;
#ifdef CONFIG_RSI_WOW
if (!common->suspend_flag) {
#endif
rsi_send_sta_notify_frame(common, rsi_send_sta_notify_frame(common,
opmode, opmode,
STA_DISCONNECTED, STA_DISCONNECTED,
...@@ -1879,6 +1915,9 @@ void rsi_inform_bss_status(struct rsi_common *common, ...@@ -1879,6 +1915,9 @@ void rsi_inform_bss_status(struct rsi_common *common,
qos_enable, qos_enable,
aid, aid,
sta_id); sta_id);
#ifdef CONFIG_RSI_WOW
}
#endif
if (opmode == STA_OPMODE) if (opmode == STA_OPMODE)
rsi_send_block_unblock_frame(common, true); rsi_send_block_unblock_frame(common, true);
} }
...@@ -2004,6 +2043,7 @@ int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word) ...@@ -2004,6 +2043,7 @@ int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word)
return rsi_send_internal_mgmt_frame(common, skb); return rsi_send_internal_mgmt_frame(common, skb);
} }
EXPORT_SYMBOL_GPL(rsi_send_rx_filter_frame);
/** /**
* rsi_send_ps_request() - Sends power save request. * rsi_send_ps_request() - Sends power save request.
...@@ -2207,10 +2247,12 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg) ...@@ -2207,10 +2247,12 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg)
ven_rsi_dbg(INIT_ZONE, ven_rsi_dbg(INIT_ZONE,
"Dual band supported\n"); "Dual band supported\n");
common->band = NL80211_BAND_5GHZ; common->band = NL80211_BAND_5GHZ;
common->num_supp_bands = 2;
} else if ((msg[17] & 0x3) == 0x1) { } else if ((msg[17] & 0x3) == 0x1) {
ven_rsi_dbg(INIT_ZONE, ven_rsi_dbg(INIT_ZONE,
"Only 2.4Ghz band supported\n"); "Only 2.4Ghz band supported\n");
common->band = NL80211_BAND_2GHZ; common->band = NL80211_BAND_2GHZ;
common->num_supp_bands = 1;
} }
} else { } else {
common->fsm_state = FSM_CARD_NOT_READY; common->fsm_state = FSM_CARD_NOT_READY;
...@@ -2354,7 +2396,7 @@ int rsi_handle_card_ready(struct rsi_common *common) ...@@ -2354,7 +2396,7 @@ int rsi_handle_card_ready(struct rsi_common *common)
#ifdef CONFIG_RSI_WOW #ifdef CONFIG_RSI_WOW
int rsi_send_wowlan_request(struct rsi_common *common, u16 flags, int rsi_send_wowlan_request(struct rsi_common *common, u16 flags,
struct cfg80211_wowlan *wowlan) u16 sleep_status)
{ {
struct rsi_wowlan_req *cmd_frame; struct rsi_wowlan_req *cmd_frame;
struct sk_buff *skb; struct sk_buff *skb;
...@@ -2377,8 +2419,11 @@ int rsi_send_wowlan_request(struct rsi_common *common, u16 flags, ...@@ -2377,8 +2419,11 @@ int rsi_send_wowlan_request(struct rsi_common *common, u16 flags,
memcpy(cmd_frame->sourceid, &sourceid, IEEE80211_ADDR_LEN); memcpy(cmd_frame->sourceid, &sourceid, IEEE80211_ADDR_LEN);
cmd_frame->wow_flags = flags; /* TODO: check for the magic packet */ cmd_frame->host_sleep_status = sleep_status;
cmd_frame->host_sleep_status = 1; /* TODO: check for the host status */ if (sleep_status)
cmd_frame->wow_flags = flags; /* TODO: check for magic packet */
ven_rsi_dbg(INFO_ZONE, "Host_Sleep_Status : %d Flags : %d\n",
cmd_frame->host_sleep_status, cmd_frame->wow_flags );
length = FRAME_DESC_SZ + IEEE80211_ADDR_LEN + 2 + 2; length = FRAME_DESC_SZ + IEEE80211_ADDR_LEN + 2 + 2;
...@@ -2403,6 +2448,7 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg) ...@@ -2403,6 +2448,7 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg)
{ {
s32 msg_len = (le16_to_cpu(*(__le16 *)&msg[0]) & 0x0fff); s32 msg_len = (le16_to_cpu(*(__le16 *)&msg[0]) & 0x0fff);
u16 msg_type = msg[2]; u16 msg_type = msg[2];
struct ieee80211_vif *vif = common->priv->vifs[0];
switch (msg_type) { switch (msg_type) {
case TA_CONFIRM_TYPE: case TA_CONFIRM_TYPE:
...@@ -2417,6 +2463,18 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg) ...@@ -2417,6 +2463,18 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg)
common->mgmt_q_block = false; common->mgmt_q_block = false;
ven_rsi_dbg(INFO_ZONE, "Mgmt queue unblocked\n"); ven_rsi_dbg(INFO_ZONE, "Mgmt queue unblocked\n");
} }
if ((msg[15] & 0xff) == EAPOL4_CONFIRM) {
u8 status = msg[12];
if (status) {
if(vif->type == NL80211_IFTYPE_STATION) {
ven_rsi_dbg(ERR_ZONE, "EAPOL 4 confirm\n");
common->eapol4_confirm = 1;
if (!rsi_send_block_unblock_frame(common, false))
common->hw_data_qs_blocked = false;
}
}
}
break; break;
case PS_NOTIFY_IND: case PS_NOTIFY_IND:
...@@ -2447,13 +2505,15 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg) ...@@ -2447,13 +2505,15 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg)
case BEACON_EVENT_IND: case BEACON_EVENT_IND:
ven_rsi_dbg(INFO_ZONE, "Beacon event\n"); ven_rsi_dbg(INFO_ZONE, "Beacon event\n");
if (common->fsm_state != FSM_MAC_INIT_DONE) #ifndef CONFIG_CARACALLA_BOARD
if (!common->init_done)
return -1; return -1;
if (common->iface_down) if (common->iface_down)
return -1; return -1;
mutex_lock(&common->mutex); if (!common->beacon_enabled)
return -1;
rsi_send_beacon(common); rsi_send_beacon(common);
mutex_unlock(&common->mutex); #endif
break; break;
case RX_DOT11_MGMT: case RX_DOT11_MGMT:
......
...@@ -276,7 +276,7 @@ static void rsi_reset_card(struct sdio_func *pfunction) ...@@ -276,7 +276,7 @@ static void rsi_reset_card(struct sdio_func *pfunction)
u16 rca; u16 rca;
u32 cmd_delay = 0; u32 cmd_delay = 0;
#ifdef CONFIG_DELL_BOARD #ifdef CONFIG_CARACALLA_BOARD
/* Reset 9110 chip */ /* Reset 9110 chip */
err = rsi_cmd52writebyte(pfunction->card, err = rsi_cmd52writebyte(pfunction->card,
SDIO_CCCR_ABORT, SDIO_CCCR_ABORT,
...@@ -338,7 +338,7 @@ static void rsi_reset_card(struct sdio_func *pfunction) ...@@ -338,7 +338,7 @@ static void rsi_reset_card(struct sdio_func *pfunction)
if (err) if (err)
ven_rsi_dbg(ERR_ZONE, "%s: CMD0 failed : %d\n", __func__, err); ven_rsi_dbg(ERR_ZONE, "%s: CMD0 failed : %d\n", __func__, err);
#ifdef CONFIG_DELL_BOARD #ifdef CONFIG_CARACALLA_BOARD
if (!host->ocr_avail) { if (!host->ocr_avail) {
#else #else
if (1) { if (1) {
...@@ -352,7 +352,7 @@ static void rsi_reset_card(struct sdio_func *pfunction) ...@@ -352,7 +352,7 @@ static void rsi_reset_card(struct sdio_func *pfunction)
if (err) if (err)
ven_rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n", ven_rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n",
__func__, err); __func__, err);
#ifdef CONFIG_DELL_BOARD #ifdef CONFIG_CARACALLA_BOARD
host->ocr_avail = resp; host->ocr_avail = resp;
#else #else
card->ocr = resp; card->ocr = resp;
...@@ -363,7 +363,7 @@ static void rsi_reset_card(struct sdio_func *pfunction) ...@@ -363,7 +363,7 @@ static void rsi_reset_card(struct sdio_func *pfunction)
for (i = 0; i < 100; i++) { for (i = 0; i < 100; i++) {
err = rsi_issue_sdiocommand(pfunction, err = rsi_issue_sdiocommand(pfunction,
SD_IO_SEND_OP_COND, SD_IO_SEND_OP_COND,
#ifdef CONFIG_DELL_BOARD #ifdef CONFIG_CARACALLA_BOARD
host->ocr_avail, host->ocr_avail,
#else #else
card->ocr, card->ocr,
...@@ -1049,7 +1049,9 @@ static int rsi_probe(struct sdio_func *pfunction, ...@@ -1049,7 +1049,9 @@ static int rsi_probe(struct sdio_func *pfunction,
__func__); __func__);
goto fail; goto fail;
} }
#ifdef CONFIG_SDIO_INTR_POLL
init_sdio_intr_status_poll_thread(adapter->priv);
#endif
sdio_claim_host(pfunction); sdio_claim_host(pfunction);
// if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) { // if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) {
if (sdio_claim_irq(pfunction, rsi_dummy_isr)) { if (sdio_claim_irq(pfunction, rsi_dummy_isr)) {
...@@ -1089,6 +1091,9 @@ static int rsi_probe(struct sdio_func *pfunction, ...@@ -1089,6 +1091,9 @@ static int rsi_probe(struct sdio_func *pfunction,
return 0; return 0;
fail: fail:
#ifdef CONFIG_SDIO_INTR_POLL
rsi_kill_thread(&adapter->priv->sdio_intr_poll_thread);
#endif
ven_rsi_91x_deinit(adapter); ven_rsi_91x_deinit(adapter);
ven_rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__); ven_rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__);
return 1; return 1;
...@@ -1110,12 +1115,13 @@ static void rsi_disconnect(struct sdio_func *pfunction) ...@@ -1110,12 +1115,13 @@ static void rsi_disconnect(struct sdio_func *pfunction)
dev = (struct rsi_91x_sdiodev *)adapter->rsi_dev; dev = (struct rsi_91x_sdiodev *)adapter->rsi_dev;
#if defined(CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX) #ifdef CONFIG_SDIO_INTR_POLL
#if defined(CONFIG_DELL_BOARD) rsi_kill_thread(&adapter->priv->sdio_intr_poll_thread);
if (adapter->rsi_host_intf == RSI_HOST_INTF_SDIO)
rsi_kill_thread(&adapter->priv->hci_thread);
#endif
#endif #endif
sdio_claim_host(pfunction);
sdio_release_irq(pfunction);
sdio_release_host(pfunction);
mdelay(10);
ven_rsi_mac80211_detach(adapter); ven_rsi_mac80211_detach(adapter);
mdelay(10); mdelay(10);
...@@ -1124,10 +1130,6 @@ static void rsi_disconnect(struct sdio_func *pfunction) ...@@ -1124,10 +1130,6 @@ static void rsi_disconnect(struct sdio_func *pfunction)
rsi_hci_detach(adapter->priv); rsi_hci_detach(adapter->priv);
mdelay(10); mdelay(10);
#endif #endif
sdio_claim_host(pfunction);
sdio_release_irq(pfunction);
sdio_release_host(pfunction);
mdelay(10);
/* Reset Chip */ /* Reset Chip */
rsi_reset_chip(adapter); rsi_reset_chip(adapter);
...@@ -1148,16 +1150,8 @@ int rsi_set_sdio_pm_caps(struct rsi_hw *adapter) ...@@ -1148,16 +1150,8 @@ int rsi_set_sdio_pm_caps(struct rsi_hw *adapter)
struct rsi_91x_sdiodev *dev = struct rsi_91x_sdiodev *dev =
(struct rsi_91x_sdiodev *)adapter->rsi_dev; (struct rsi_91x_sdiodev *)adapter->rsi_dev;
struct sdio_func *func = dev->pfunction; struct sdio_func *func = dev->pfunction;
mmc_pm_flag_t flags;
int ret; int ret;
/*Getting the host power management capabilities*/
flags = sdio_get_host_pm_caps(func);
ven_rsi_dbg(INFO_ZONE, "sdio suspend pm_caps 0x%x\n", flags);
if ((!(flags & MMC_PM_WAKE_SDIO_IRQ)) ||
(!(flags & MMC_PM_KEEP_POWER)))
return -EINVAL;
/* Keep Power to the MMC while suspend*/ /* Keep Power to the MMC while suspend*/
ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
if (ret) { if (ret) {
...@@ -1165,53 +1159,45 @@ int rsi_set_sdio_pm_caps(struct rsi_hw *adapter) ...@@ -1165,53 +1159,45 @@ int rsi_set_sdio_pm_caps(struct rsi_hw *adapter)
return ret; return ret;
} }
/* sdio irq wakes up host */
ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
if (ret)
ven_rsi_dbg(ERR_ZONE,"set sdio wake irq flag failed: %d\n", ret);
return ret; return ret;
} }
int rsi_sdio_suspend(struct rsi_hw *adapter)
{
struct rsi_91x_sdiodev *dev =
(struct rsi_91x_sdiodev *)adapter->rsi_dev;
ven_rsi_dbg(INFO_ZONE,"Suspend SDIO\n");
sdio_claim_host(dev->pfunction);
sdio_release_irq(dev->pfunction);
sdio_release_host(dev->pfunction);
return 0;
}
static int rsi_suspend(struct device *dev) static int rsi_suspend(struct device *dev)
{ {
int ret = 0; int ret = 0;
struct sdio_func *pfunction = dev_to_sdio_func(dev); struct sdio_func *pfunction = dev_to_sdio_func(dev);
struct rsi_hw *adapter = sdio_get_drvdata(pfunction); struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
u8 isr_status = 0;
ven_rsi_dbg(INFO_ZONE,"***** SUSPEND CALLED ******\n"); ven_rsi_dbg(INFO_ZONE,"%s : ***** BUS SUSPEND ******\n",__func__);
ret = rsi_set_sdio_pm_caps(adapter);
if (ret){
ven_rsi_dbg(INFO_ZONE,"failed %s:%d\n",__func__,__LINE__);
}
ret = rsi_sdio_suspend(adapter);
if (ret && ret != -ENOTCONN) ven_rsi_dbg(INFO_ZONE, "Waiting for interrupts to be cleared..");
ven_rsi_dbg(ERR_ZONE,"wow suspend failed: %d\n", ret); do {
rsi_sdio_read_register(adapter,
RSI_FN1_INT_REGISTER,
&isr_status);
printk(".");
} while (isr_status);
printk("\n");
ret = rsi_set_sdio_pm_caps(adapter);
if (ret)
ven_rsi_dbg(INFO_ZONE, "Setting power management caps failed\n");
return 0; return 0;
} }
int rsi_resume(struct device *dev) int rsi_resume(struct device *dev)
{ {
ven_rsi_dbg(INFO_ZONE,"rsi_sdio_resume returning\n"); #ifdef CONFIG_RSI_WOW
return 0; struct sdio_func *pfunction = dev_to_sdio_func(dev);
struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
ven_rsi_dbg(INFO_ZONE,"%s: ***** BUS RESUME ******\n",__func__);
adapter->priv->suspend_flag = 0;
#endif
ven_rsi_dbg(INFO_ZONE, "RSI module resumed\n");
return 0;
} }
static const struct dev_pm_ops rsi_pm_ops = { static const struct dev_pm_ops rsi_pm_ops = {
......
...@@ -376,9 +376,9 @@ int rsi_sdio_read_buffer_status_register(struct rsi_hw *adapter, u8 q_num) ...@@ -376,9 +376,9 @@ int rsi_sdio_read_buffer_status_register(struct rsi_hw *adapter, u8 q_num)
(struct rsi_91x_sdiodev *)adapter->rsi_dev; (struct rsi_91x_sdiodev *)adapter->rsi_dev;
u8 buf_status = 0; u8 buf_status = 0;
int status = 0; int status = 0;
#if 0 // static int counter = 4;
static int counter = 4;
#if 0
if ((!dev->buff_status_updated) && counter) { if ((!dev->buff_status_updated) && counter) {
counter--; counter--;
goto out; goto out;
...@@ -389,7 +389,6 @@ int rsi_sdio_read_buffer_status_register(struct rsi_hw *adapter, u8 q_num) ...@@ -389,7 +389,6 @@ int rsi_sdio_read_buffer_status_register(struct rsi_hw *adapter, u8 q_num)
status = rsi_sdio_read_register(common->priv, status = rsi_sdio_read_register(common->priv,
RSI_DEVICE_BUFFER_STATUS_REGISTER, RSI_DEVICE_BUFFER_STATUS_REGISTER,
&buf_status); &buf_status);
if (status) { if (status) {
ven_rsi_dbg(ERR_ZONE, ven_rsi_dbg(ERR_ZONE,
"%s: Failed to read status register\n", __func__); "%s: Failed to read status register\n", __func__);
...@@ -421,11 +420,11 @@ int rsi_sdio_read_buffer_status_register(struct rsi_hw *adapter, u8 q_num) ...@@ -421,11 +420,11 @@ int rsi_sdio_read_buffer_status_register(struct rsi_hw *adapter, u8 q_num)
} }
// (dev->rx_info.semi_buffer_full ? (counter = 4) : (counter = 1)); // (dev->rx_info.semi_buffer_full ? (counter = 4) : (counter = 1));
out: //out:
if ((q_num == MGMT_SOFT_Q) && (dev->rx_info.mgmt_buffer_full)) if ((q_num == MGMT_SOFT_Q) && (dev->rx_info.mgmt_buffer_full))
return QUEUE_FULL; return QUEUE_FULL;
if (dev->rx_info.buffer_full) if ((q_num < MGMT_SOFT_Q) && (dev->rx_info.buffer_full))
return QUEUE_FULL; return QUEUE_FULL;
return QUEUE_NOT_FULL; return QUEUE_NOT_FULL;
......
...@@ -90,4 +90,10 @@ void rsi_resume_conn_channel(struct rsi_hw *adapter); ...@@ -90,4 +90,10 @@ void rsi_resume_conn_channel(struct rsi_hw *adapter);
void rsi_hci_detach(struct rsi_common *common); void rsi_hci_detach(struct rsi_common *common);
inline char *dot11_pkt_type(__le16 frame_control); inline char *dot11_pkt_type(__le16 frame_control);
struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr); struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr);
void rsi_init_bcn_timer(struct rsi_common *common);
void rsi_del_bcn_timer(struct rsi_common *common);
void rsi_bcn_scheduler_thread(struct rsi_common *common);
#ifdef CONFIG_SDIO_INTR_POLL
void init_sdio_intr_status_poll_thread(struct rsi_common *common);
#endif
#endif #endif
...@@ -210,7 +210,9 @@ struct rsi_common { ...@@ -210,7 +210,9 @@ struct rsi_common {
struct version_info fw_ver; struct version_info fw_ver;
struct rsi_thread tx_thread; struct rsi_thread tx_thread;
struct rsi_thread hci_thread; #ifdef CONFIG_SDIO_INTR_POLL
struct rsi_thread sdio_intr_poll_thread;
#endif
struct sk_buff_head tx_queue[NUM_EDCA_QUEUES + 1]; struct sk_buff_head tx_queue[NUM_EDCA_QUEUES + 1];
/* Mutex declaration */ /* Mutex declaration */
struct mutex mutex; struct mutex mutex;
...@@ -222,6 +224,7 @@ struct rsi_common { ...@@ -222,6 +224,7 @@ struct rsi_common {
/* Channel/band related */ /* Channel/band related */
u8 band; u8 band;
u8 num_supp_bands;
u8 channel_width; u8 channel_width;
u16 rts_threshold; u16 rts_threshold;
...@@ -287,6 +290,9 @@ struct rsi_common { ...@@ -287,6 +290,9 @@ struct rsi_common {
u8 host_wakeup_intr_active_high; u8 host_wakeup_intr_active_high;
int tx_power; int tx_power;
u8 ant_in_use; u8 ant_in_use;
#ifdef CONFIG_RSI_WOW
u8 suspend_flag;
#endif
#if defined (CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX) #if defined (CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX)
void *hci_adapter; void *hci_adapter;
...@@ -297,14 +303,20 @@ struct rsi_common { ...@@ -297,14 +303,20 @@ struct rsi_common {
#endif #endif
/* AP mode related */ /* AP mode related */
u8 beacon_enabled;
u16 beacon_interval;
u8 *beacon_frame; u8 *beacon_frame;
u16 beacon_frame_len; u16 beacon_frame_len;
u16 beacon_cnt; u16 beacon_cnt;
u8 dtim_cnt; u8 dtim_cnt;
u16 bc_mc_seqno; u16 bc_mc_seqno;
struct rsi_sta stations[RSI_MAX_ASSOC_STAS + 1]; struct rsi_sta stations[RSI_MAX_ASSOC_STAS + 1];
u8 num_stations; int num_stations;
struct ieee80211_channel *ap_channel; struct ieee80211_channel *ap_channel;
struct rsi_thread bcn_thread;
struct timer_list bcn_timer;
struct ieee80211_key_conf *key;
u8 eapol4_confirm;
}; };
enum host_intf { enum host_intf {
......
...@@ -66,7 +66,7 @@ enum rx_cmd_type { ...@@ -66,7 +66,7 @@ enum rx_cmd_type {
ANTENNA_SELECT = 0xf, ANTENNA_SELECT = 0xf,
}; };
#ifdef RSI_ENABLE_WOW #ifdef CONFIG_RSI_WOW
#define WOW_MAX_FILTERS_PER_LIST 16 #define WOW_MAX_FILTERS_PER_LIST 16
#define WOW_PATTERN_SIZE 256 #define WOW_PATTERN_SIZE 256
#endif #endif
...@@ -527,7 +527,7 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg); ...@@ -527,7 +527,7 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg);
int rsi_set_vap_capabilities(struct rsi_common *common, enum opmode mode, int rsi_set_vap_capabilities(struct rsi_common *common, enum opmode mode,
u8 vap_status); u8 vap_status);
int rsi_send_aggr_params_frame(struct rsi_common *common, u16 tid, int rsi_send_aggr_params_frame(struct rsi_common *common, u16 tid,
u16 ssn, u8 buf_size, u8 event); u16 ssn, u8 buf_size, u8 event, u8 sta_id);
int rsi_load_key(struct rsi_common *common, u8 *data, u16 key_len, int rsi_load_key(struct rsi_common *common, u8 *data, u16 key_len,
u8 key_type, u8 key_id, u32 cipher, s16 sta_id); u8 key_type, u8 key_id, u32 cipher, s16 sta_id);
int rsi_set_channel(struct rsi_common *common, int rsi_set_channel(struct rsi_common *common,
...@@ -536,7 +536,10 @@ int rsi_send_vap_dynamic_update(struct rsi_common *common); ...@@ -536,7 +536,10 @@ int rsi_send_vap_dynamic_update(struct rsi_common *common);
int rsi_send_block_unblock_frame(struct rsi_common *common, bool event); int rsi_send_block_unblock_frame(struct rsi_common *common, bool event);
void rsi_inform_bss_status(struct rsi_common *common, enum opmode opmode, void rsi_inform_bss_status(struct rsi_common *common, enum opmode opmode,
u8 status, u8 *bssid, u8 qos_enable, u16 aid, u8 status, u8 *bssid, u8 qos_enable, u16 aid,
u16 sta_id); struct ieee80211_sta *sta, u16 sta_id);
int rsi_send_sta_notify_frame(struct rsi_common *common, enum opmode opmode,
u8 notify_event, const unsigned char *bssid,
u8 qos_enable, u16 aid, u16 sta_id);
void rsi_indicate_pkt_to_os(struct rsi_common *common, struct sk_buff *skb); void rsi_indicate_pkt_to_os(struct rsi_common *common, struct sk_buff *skb);
int rsi_mac80211_attach(struct rsi_common *common); int rsi_mac80211_attach(struct rsi_common *common);
int rsi_send_bgscan_params(struct rsi_common *common, int enable); int rsi_send_bgscan_params(struct rsi_common *common, int enable);
...@@ -559,6 +562,6 @@ int rsi_hci_attach(struct rsi_common *common); ...@@ -559,6 +562,6 @@ int rsi_hci_attach(struct rsi_common *common);
int rsi_handle_card_ready(struct rsi_common *common); int rsi_handle_card_ready(struct rsi_common *common);
#ifdef CONFIG_RSI_WOW #ifdef CONFIG_RSI_WOW
int rsi_send_wowlan_request(struct rsi_common *common, u16 flags, int rsi_send_wowlan_request(struct rsi_common *common, u16 flags,
struct cfg80211_wowlan *wowlan); u16 sleep_status);
#endif #endif
#endif #endif
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