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_core.o
......
......@@ -270,15 +270,13 @@ void rsi_core_qos_processor(struct rsi_common *common)
ven_rsi_dbg(DATA_TX_ZONE,
"%s: Queue number = %d\n", __func__, q_num);
if (q_num == INVALID_QUEUE) {
ven_rsi_dbg(DATA_TX_ZONE, "%s: No More Pkt\n", __func__);
if (q_num == INVALID_QUEUE)
break;
}
mutex_lock(&common->tx_lock);
status = adapter->check_hw_queue_status(adapter, q_num);
if ((status <= 0)) {
if (status <= 0) {
mutex_unlock(&common->tx_lock);
break;
}
......@@ -286,6 +284,8 @@ void rsi_core_qos_processor(struct rsi_common *common)
if ((q_num < MGMT_SOFT_Q) &&
((skb_queue_len(&common->tx_queue[q_num])) <=
MIN_DATA_QUEUE_WATER_MARK)) {
if (!adapter->hw)
break;
if (ieee80211_queue_stopped(adapter->hw, WME_AC(q_num)))
ieee80211_wake_queue(adapter->hw,
WME_AC(q_num));
......@@ -368,7 +368,9 @@ struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr)
{
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,
mac_addr, ETH_ALEN)))
return &common->stations[i];
......@@ -397,7 +399,12 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
__func__);
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) {
ven_rsi_dbg(ERR_ZONE, "%s: FSM state not open\n", __func__);
goto xmit_fail;
......@@ -410,9 +417,24 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
if ((ieee80211_is_mgmt(wlh->frame_control)) ||
(ieee80211_is_ctl(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;
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",
dot11_pkt_type(wlh->frame_control));
if (ieee80211_is_probe_req(wlh->frame_control)) {
......@@ -434,9 +456,19 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
rsi_hex_dump(DATA_TX_ZONE, "TX Data Packet",
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)) {
u8 *qos = ieee80211_get_qos_ctl(wlh);
tid = *qos & IEEE80211_QOS_CTL_TID_MASK;
skb->priority = TID_TO_WME_AC(tid);
......@@ -450,7 +482,7 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
} else {
tid = IEEE80211_NONQOS_TID;
skb->priority = BE_Q;
if ((!is_broadcast_ether_addr(wlh->addr1)) &&
(!is_multicast_ether_addr(wlh->addr1)) &&
(vif->type == NL80211_IFTYPE_AP)) {
......
......@@ -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)
{
struct rsi_common *common = file->private;
struct bgscan_config_params *params = &common->bgscan_info;
struct bgscan_config_params *params = NULL;
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",
common->bgscan_en,
params->bgscan_threshold,
......@@ -314,14 +324,25 @@ static ssize_t rsi_bgscan_write(struct file *file,
{
struct rsi_common *common = file->f_inode->i_private;
struct rsi_hw *adapter = common->priv;
struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf;
struct rsi_hw *adapter = NULL;
struct ieee80211_bss_conf *bss = NULL;
char bgscan_buf[200];
int bgscan_vals[64] = { 0 };
int total_bytes, cnt = 0;
int bytes_read = 0, t_bytes;
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,
sizeof(bgscan_buf) - 1,
ppos, user_buff, count);
......@@ -387,10 +408,10 @@ static ssize_t rsi_bgscan_write(struct file *file,
common->bgscan_info.num_user_channels = bgscan_vals[6];
memset(&common->bgscan_info.user_channels, 0,
(MAX_BGSCAN_CHANNELS * 2));
common->bgscan_info.num_user_channels =
common->bgscan_info.num_user_channels =
((bgscan_vals[6] > MAX_BGSCAN_CHANNELS) ?
MAX_BGSCAN_CHANNELS : bgscan_vals[6]);
MAX_BGSCAN_CHANNELS : bgscan_vals[6]);
for (cnt = 0; cnt < common->bgscan_info.num_user_channels; cnt++)
common->bgscan_info.user_channels[cnt] = bgscan_vals[7 + cnt];
......@@ -435,7 +456,7 @@ static ssize_t rsi_bgscan_write(struct file *file,
common->bgscan_en = 0;
g_bgscan_enable = 0;
}
} else {
#ifdef PLATFORM_X86
ven_rsi_dbg(ERR_ZONE, "Failed sending bgscan params req\n");
......
......@@ -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)) {
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[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
xtend_desc->retry_cnt = EAPOL_RETRY_CNT;
#ifdef EAPOL_IN_MGMT_Q
#if 0
skb->priority = VO_Q;
#endif
}
......@@ -178,14 +194,12 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
(is_multicast_ether_addr(wh->addr1))) {
frame_desc[3] = cpu_to_le16(RATE_INFO_ENABLE);
frame_desc[3] |= cpu_to_le16(RSI_BROADCAST_PKT);
#if 0
if (common->min_rate == 0xffff) {
if (vif->type == NL80211_IFTYPE_AP) {
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);
}
#endif
}
if ((vif->type == NL80211_IFTYPE_AP) &&
......@@ -196,7 +210,7 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
err:
++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;
}
......@@ -323,6 +337,8 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
u8 header_size = 0;
info = IEEE80211_SKB_CB(skb);
if (!info->control.vif)
goto err;
bss = &info->control.vif->bss_conf;
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)
skb->data, skb->len);
status = rsi_send_pkt(common, skb);
if (status) {
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to write the packet\n",
......@@ -391,6 +406,8 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb)
return status;
}
if (!info->control.vif)
goto out;
bss = &info->control.vif->bss_conf;
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)
xtend_desc = (struct xtended_desc *)&skb->data[FRAME_DESC_SZ];
/* 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) {
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);
xtend_desc->confirm_frame_type = PROBEREQ_CONFIRM;
common->mgmt_q_block = true;
ven_rsi_dbg(INFO_ZONE, "Mgmt queue blocked\n");
} else if (common->bgscan_en) {
/* Drop off channel probe request */
if (common->mac80211_cur_channel !=
rsi_get_connected_channel(adapter)) {
dev_kfree_skb(skb);
return 0;
/* Drop off channel probe request */
status = 0;
goto out;
} else if (wh->addr1[0] == 0xff) {
/* Drop broadcast probe in connected channel*/
dev_kfree_skb(skb);
return 0;
status = 0;
goto out;
}
}
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)
__func__);
}
out:
rsi_indicate_tx_status(common->priv, skb, status);
return status;
}
......@@ -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)
{
struct rsi_hw *adapter = common->priv;
struct rsi_mac_frame *bcn_frm = NULL;
u16 bcn_len = common->beacon_frame_len;
struct sk_buff *skb = NULL;
......@@ -481,16 +499,18 @@ int rsi_send_beacon(struct rsi_common *common)
u8 vap_id = 0;
u8 dword_align_bytes = 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)
return -ENOMEM;
dword_align_bytes = ((unsigned long)skb->data & 0x3f);
printk("%s: dword_bytes = %d\n", __func__, dword_align_bytes);
header_size = dword_align_bytes + FRAME_DESC_SZ;
printk("header_size = %d\n", header_size);
memset(skb->data, 0, header_size + bcn_len + 64);
if (dword_align_bytes) {
skb_pull(skb, (64 - dword_align_bytes));
}
header_size = FRAME_DESC_SZ;
memset(skb->data, 0, MAX_MGMT_PKT_SIZE);
common->beacon_cnt++;
bcn_frm = (struct rsi_mac_frame *)skb->data;
......@@ -504,7 +524,7 @@ int rsi_send_beacon(struct rsi_common *common)
bcn_frm->desc_word[3] |= cpu_to_le16(RATE_INFO_ENABLE);
bcn_frm->desc_word[4] = cpu_to_le16(vap_id << 14);
bcn_frm->desc_word[7] = cpu_to_le16(BEACON_HW_Q);
if (conf_is_ht40_plus(conf)) {
bcn_frm->desc_word[5] = cpu_to_le16(LOWER_20_ENABLE);
bcn_frm->desc_word[5] |= cpu_to_le16(LOWER_20_ENABLE >> 12);
......@@ -514,29 +534,31 @@ int rsi_send_beacon(struct rsi_common *common)
}
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
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 (1) //FIXME check this
bcn_frm->desc_word[3] |= cpu_to_le16(DTIM_BEACON);
//mutex_lock(&common->mutex);
memcpy(&skb->data[header_size], common->beacon_frame, bcn_len);
//mutex_unlock(&common->mutex);
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");
goto err;
status = -EINVAL;
}
return 0;
mutex_unlock(&common->tx_lock);
err:
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)
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)
{
struct rsi_hci_adapter *h_adapter =
......@@ -234,34 +219,9 @@ int rsi_hci_recv_pkt(struct rsi_common *common, u8 *pkt)
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;
}
if (common->bt_fsm_state != BT_DEVICE_READY) {
ven_rsi_dbg(INFO_ZONE, "BT Device not ready\n");
return 0;
......@@ -504,6 +464,7 @@ int rsi_hci_attach(struct rsi_common *common)
#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 12, 34)
genl_unregister_ops(gcb->gc_family, gcb->gc_ops);
#endif
kfree(gcb);
}
h_adapter->gcb = NULL;
kfree(h_adapter);
......@@ -547,6 +508,7 @@ void rsi_hci_detach(struct rsi_common *common)
genl_unregister_ops(gcb->gc_family, gcb->gc_ops);
#endif
h_adapter->gcb = NULL;
kfree(gcb);
}
kfree(h_adapter);
......
This diff is collapsed.
......@@ -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);
#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
* packets to the device.
......@@ -250,6 +298,36 @@ static void rsi_tx_scheduler_thread(struct rsi_common *common)
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.
* @void: Void.
......@@ -285,6 +363,7 @@ struct rsi_hw *ven_rsi_91x_init(void)
skb_queue_head_init(&common->tx_queue[ii]);
rsi_init_event(&common->tx_thread.event);
rsi_init_event(&common->bcn_thread.event);
mutex_init(&common->mutex);
mutex_init(&common->tx_lock);
mutex_init(&common->rx_lock);
......@@ -297,6 +376,16 @@ struct rsi_hw *ven_rsi_91x_init(void)
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
if (rsi_coex_init(common)) {
ven_rsi_dbg(ERR_ZONE, "Failed to init COEX module\n");
......@@ -332,6 +421,9 @@ void ven_rsi_91x_deinit(struct rsi_hw *adapter)
ven_rsi_dbg(INFO_ZONE, "%s: Deinit core module...\n", __func__);
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++)
skb_queue_purge(&common->tx_queue[ii]);
......@@ -341,6 +433,8 @@ void ven_rsi_91x_deinit(struct rsi_hw *adapter)
#endif
common->init_done = false;
kfree(common->beacon_frame);
common->beacon_frame = NULL;
kfree(common);
kfree(adapter->rsi_dev);
kfree(adapter);
......
This diff is collapsed.
......@@ -276,7 +276,7 @@ static void rsi_reset_card(struct sdio_func *pfunction)
u16 rca;
u32 cmd_delay = 0;
#ifdef CONFIG_DELL_BOARD
#ifdef CONFIG_CARACALLA_BOARD
/* Reset 9110 chip */
err = rsi_cmd52writebyte(pfunction->card,
SDIO_CCCR_ABORT,
......@@ -338,7 +338,7 @@ static void rsi_reset_card(struct sdio_func *pfunction)
if (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) {
#else
if (1) {
......@@ -352,7 +352,7 @@ static void rsi_reset_card(struct sdio_func *pfunction)
if (err)
ven_rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n",
__func__, err);
#ifdef CONFIG_DELL_BOARD
#ifdef CONFIG_CARACALLA_BOARD
host->ocr_avail = resp;
#else
card->ocr = resp;
......@@ -363,7 +363,7 @@ static void rsi_reset_card(struct sdio_func *pfunction)
for (i = 0; i < 100; i++) {
err = rsi_issue_sdiocommand(pfunction,
SD_IO_SEND_OP_COND,
#ifdef CONFIG_DELL_BOARD
#ifdef CONFIG_CARACALLA_BOARD
host->ocr_avail,
#else
card->ocr,
......@@ -997,7 +997,7 @@ static int rsi_init_sdio_interface(struct rsi_hw *adapter,
adapter->check_hw_queue_status = rsi_sdio_read_buffer_status_register;
adapter->process_isr_hci = rsi_interrupt_handler;
adapter->check_intr_status_reg = rsi_read_intr_status_reg;
#ifdef CONFIG_VEN_RSI_DEBUGFS
adapter->num_debugfs_entries = MAX_DEBUGFS_ENTRIES;
#endif
......@@ -1049,7 +1049,9 @@ static int rsi_probe(struct sdio_func *pfunction,
__func__);
goto fail;
}
#ifdef CONFIG_SDIO_INTR_POLL
init_sdio_intr_status_poll_thread(adapter->priv);
#endif
sdio_claim_host(pfunction);
// if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) {
if (sdio_claim_irq(pfunction, rsi_dummy_isr)) {
......@@ -1089,6 +1091,9 @@ static int rsi_probe(struct sdio_func *pfunction,
return 0;
fail:
#ifdef CONFIG_SDIO_INTR_POLL
rsi_kill_thread(&adapter->priv->sdio_intr_poll_thread);
#endif
ven_rsi_91x_deinit(adapter);
ven_rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__);
return 1;
......@@ -1110,12 +1115,13 @@ static void rsi_disconnect(struct sdio_func *pfunction)
dev = (struct rsi_91x_sdiodev *)adapter->rsi_dev;
#if defined(CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX)
#if defined(CONFIG_DELL_BOARD)
if (adapter->rsi_host_intf == RSI_HOST_INTF_SDIO)
rsi_kill_thread(&adapter->priv->hci_thread);
#endif
#ifdef CONFIG_SDIO_INTR_POLL
rsi_kill_thread(&adapter->priv->sdio_intr_poll_thread);
#endif
sdio_claim_host(pfunction);
sdio_release_irq(pfunction);
sdio_release_host(pfunction);
mdelay(10);
ven_rsi_mac80211_detach(adapter);
mdelay(10);
......@@ -1124,10 +1130,6 @@ static void rsi_disconnect(struct sdio_func *pfunction)
rsi_hci_detach(adapter->priv);
mdelay(10);
#endif
sdio_claim_host(pfunction);
sdio_release_irq(pfunction);
sdio_release_host(pfunction);
mdelay(10);
/* Reset Chip */
rsi_reset_chip(adapter);
......@@ -1148,16 +1150,8 @@ int rsi_set_sdio_pm_caps(struct rsi_hw *adapter)
struct rsi_91x_sdiodev *dev =
(struct rsi_91x_sdiodev *)adapter->rsi_dev;
struct sdio_func *func = dev->pfunction;
mmc_pm_flag_t flags;
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*/
ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
if (ret) {
......@@ -1165,53 +1159,45 @@ int rsi_set_sdio_pm_caps(struct rsi_hw *adapter)
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;
}
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)
{
int ret = 0;
struct sdio_func *pfunction = dev_to_sdio_func(dev);
struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
u8 isr_status = 0;
ven_rsi_dbg(INFO_ZONE,"***** SUSPEND CALLED ******\n");
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);
ven_rsi_dbg(INFO_ZONE,"%s : ***** BUS SUSPEND ******\n",__func__);
if (ret && ret != -ENOTCONN)
ven_rsi_dbg(ERR_ZONE,"wow suspend failed: %d\n", ret);
ven_rsi_dbg(INFO_ZONE, "Waiting for interrupts to be cleared..");
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;
}
int rsi_resume(struct device *dev)
{
ven_rsi_dbg(INFO_ZONE,"rsi_sdio_resume returning\n");
return 0;
#ifdef CONFIG_RSI_WOW
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 = {
......
......@@ -235,7 +235,7 @@ int rsi_read_intr_status_reg(struct rsi_hw *adapter)
RSI_FN1_INT_REGISTER,
&isr_status);
isr_status &= 0xE;
if(isr_status & BIT(MSDU_PKT_PENDING))
adapter->isr_pending = 1;
return 0;
......@@ -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;
u8 buf_status = 0;
int status = 0;
#if 0
static int counter = 4;
// static int counter = 4;
#if 0
if ((!dev->buff_status_updated) && counter) {
counter--;
goto out;
......@@ -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,
RSI_DEVICE_BUFFER_STATUS_REGISTER,
&buf_status);
if (status) {
ven_rsi_dbg(ERR_ZONE,
"%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)
}
// (dev->rx_info.semi_buffer_full ? (counter = 4) : (counter = 1));
out:
//out:
if ((q_num == MGMT_SOFT_Q) && (dev->rx_info.mgmt_buffer_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_NOT_FULL;
......
......@@ -40,7 +40,7 @@ enum rsi_proto {
struct rsi_coex_ctrl_block {
struct rsi_common *priv;
struct sk_buff_head coex_tx_qs[NUM_COEX_TX_QUEUES];
struct semaphore tx_bus_lock;
struct semaphore tx_bus_lock;
struct rsi_thread coex_tx_thread;
};
......
......@@ -90,4 +90,10 @@ void rsi_resume_conn_channel(struct rsi_hw *adapter);
void rsi_hci_detach(struct rsi_common *common);
inline char *dot11_pkt_type(__le16 frame_control);
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
......@@ -210,7 +210,9 @@ struct rsi_common {
struct version_info fw_ver;
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];
/* Mutex declaration */
struct mutex mutex;
......@@ -222,6 +224,7 @@ struct rsi_common {
/* Channel/band related */
u8 band;
u8 num_supp_bands;
u8 channel_width;
u16 rts_threshold;
......@@ -287,6 +290,9 @@ struct rsi_common {
u8 host_wakeup_intr_active_high;
int tx_power;
u8 ant_in_use;
#ifdef CONFIG_RSI_WOW
u8 suspend_flag;
#endif
#if defined (CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX)
void *hci_adapter;
......@@ -297,14 +303,20 @@ struct rsi_common {
#endif
/* AP mode related */
u8 beacon_enabled;
u16 beacon_interval;
u8 *beacon_frame;
u16 beacon_frame_len;
u16 beacon_cnt;
u8 dtim_cnt;
u16 bc_mc_seqno;
struct rsi_sta stations[RSI_MAX_ASSOC_STAS + 1];
u8 num_stations;
int num_stations;
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 {
......
......@@ -66,7 +66,7 @@ enum rx_cmd_type {
ANTENNA_SELECT = 0xf,
};
#ifdef RSI_ENABLE_WOW
#ifdef CONFIG_RSI_WOW
#define WOW_MAX_FILTERS_PER_LIST 16
#define WOW_PATTERN_SIZE 256
#endif
......@@ -210,12 +210,12 @@ enum rx_cmd_type {
#define IEEE80211_STA_SP_ALL_PKTS 0x00
/* Tx data frame format */
#define MAC_BBP_INFO BIT(0)
#define MAC_BBP_INFO BIT(0)
#define NO_ACK_IND BIT(9)
#define QOS_EN BIT(12)
/* frame type bit{11:10} */
#define NORMAL_FRAME 0x00
#define DTIM_BEACON_GATED_FRAME BIT(10)
#define DTIM_BEACON_GATED_FRAME BIT(10)
#define BEACON_FRAME BIT(11)
#define DTIM_BEACON BIT(10) | BIT(11)
#define INSERT_TSF BIT(15)
......@@ -490,7 +490,7 @@ struct rsi_request_ps {
u16 ps_num_dtim_intervals;
} __packed;
struct rsi_wowlan_req {
struct rsi_wowlan_req {
__le16 desc_word[8];
u8 sourceid[ETH_ALEN];
u16 wow_flags;
......@@ -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,
u8 vap_status);
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,
u8 key_type, u8 key_id, u32 cipher, s16 sta_id);
int rsi_set_channel(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);
void rsi_inform_bss_status(struct rsi_common *common, enum opmode opmode,
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);
int rsi_mac80211_attach(struct rsi_common *common);
int rsi_send_bgscan_params(struct rsi_common *common, int enable);
......@@ -559,6 +562,6 @@ int rsi_hci_attach(struct rsi_common *common);
int rsi_handle_card_ready(struct rsi_common *common);
#ifdef CONFIG_RSI_WOW
int rsi_send_wowlan_request(struct rsi_common *common, u16 flags,
struct cfg80211_wowlan *wowlan);
u16 sleep_status);
#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