Quantcast

[PATCH] [Xenial][SRU] UBUNTU: SAUCE: Redpine driver to support Host AP mode

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH] [Xenial][SRU] UBUNTU: SAUCE: Redpine driver to support Host AP mode

Shrirang Bagul
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.2 (Beta)

Signed-off-by: Shrirang Bagul <[hidden email]>
---
 ubuntu/rsi/Makefile           |   2 +-
 ubuntu/rsi/rsi_91x_core.c     |  49 +++++++++--
 ubuntu/rsi/rsi_91x_debugfs.c  |  35 ++++++--
 ubuntu/rsi/rsi_91x_hal.c      |  78 +++++++++++-------
 ubuntu/rsi/rsi_91x_hci.c      |  44 +---------
 ubuntu/rsi/rsi_91x_mac80211.c | 146 ++++++++++++++++++++++++--------
 ubuntu/rsi/rsi_91x_main.c     |  96 +++++++++++++++++++++
 ubuntu/rsi/rsi_91x_mgmt.c     | 188 +++++++++++++++++++++++++++---------------
 ubuntu/rsi/rsi_91x_sdio.c     |  88 ++++++++------------
 ubuntu/rsi/rsi_91x_sdio_ops.c |  11 ++-
 ubuntu/rsi/rsi_coex.h         |   2 +-
 ubuntu/rsi/rsi_common.h       |   6 ++
 ubuntu/rsi/rsi_main.h         |  15 +++-
 ubuntu/rsi/rsi_mgmt.h         |  14 ++--
 14 files changed, 521 insertions(+), 253 deletions(-)

diff --git a/ubuntu/rsi/Makefile b/ubuntu/rsi/Makefile
index 941848c..a7db51c 100644
--- a/ubuntu/rsi/Makefile
+++ b/ubuntu/rsi/Makefile
@@ -1,4 +1,4 @@
-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
diff --git a/ubuntu/rsi/rsi_91x_core.c b/ubuntu/rsi/rsi_91x_core.c
index eaf0e29..ac55ce1 100644
--- a/ubuntu/rsi/rsi_91x_core.c
+++ b/ubuntu/rsi/rsi_91x_core.c
@@ -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,23 @@ 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_inform_bss_status(common, STA_OPMODE,1 ,
+      bss->bssid, bss->qos,
+      bss->aid, NULL, 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 +455,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 +481,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)) {
diff --git a/ubuntu/rsi/rsi_91x_debugfs.c b/ubuntu/rsi/rsi_91x_debugfs.c
index aeb0834..be4aec2 100644
--- a/ubuntu/rsi/rsi_91x_debugfs.c
+++ b/ubuntu/rsi/rsi_91x_debugfs.c
@@ -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");
diff --git a/ubuntu/rsi/rsi_91x_hal.c b/ubuntu/rsi/rsi_91x_hal.c
index 45f83e9..9181b54 100644
--- a/ubuntu/rsi/rsi_91x_hal.c
+++ b/ubuntu/rsi/rsi_91x_hal.c
@@ -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 @@ err:
 
 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;
 }
 
 /**
diff --git a/ubuntu/rsi/rsi_91x_hci.c b/ubuntu/rsi/rsi_91x_hci.c
index 773e216..4442651 100644
--- a/ubuntu/rsi/rsi_91x_hci.c
+++ b/ubuntu/rsi/rsi_91x_hci.c
@@ -198,21 +198,6 @@ fail:
  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 @@ err:
 #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);
 
diff --git a/ubuntu/rsi/rsi_91x_mac80211.c b/ubuntu/rsi/rsi_91x_mac80211.c
index 1d18b10..8cf3a47 100644
--- a/ubuntu/rsi/rsi_91x_mac80211.c
+++ b/ubuntu/rsi/rsi_91x_mac80211.c
@@ -419,10 +419,10 @@ static int rsi_mac80211_add_interface(struct ieee80211_hw *hw,
 
  mutex_lock(&common->mutex);
 
- /* Not supporting concurrent mode now */
+ /* Not supporting concurrent mode now */
  if (adapter->sc_nvifs > 0)
  return -1;
-
+
  adapter->vifs[adapter->sc_nvifs++] = vif;
 
  switch (vif->type) {
@@ -442,9 +442,15 @@ static int rsi_mac80211_add_interface(struct ieee80211_hw *hw,
  }
 
  if (vif->type == NL80211_IFTYPE_AP) {
+ int i;
+
  common->bc_mc_seqno = 1;
  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);
@@ -762,7 +768,7 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
   ALLOW_CTRL_ASSOC_PEER |
   ALLOW_MGMT_ASSOC_PEER |
 #ifdef RSI_HW_CONN_MONITOR
-  DISALLOW_BEACONS |
+  //DISALLOW_BEACONS |
 #endif
  0);
  rsi_send_rx_filter_frame(common, rx_filter_word);
@@ -778,7 +784,7 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
  /* Send peer notify to device */
  ven_rsi_dbg(INFO_ZONE, "Indicate bss status to device\n");
  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 =
  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,
  if (changed & BSS_CHANGED_BEACON_INT) {
  ven_rsi_dbg(INFO_ZONE, "%s: Changed Beacon interval: %d\n",
  __func__, bss_conf->beacon_int);
+ common->beacon_interval = bss->beacon_int;
  adapter->ps_info.listen_interval =
  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,
 
  if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
     (vif->type == NL80211_IFTYPE_AP)) {
- if (bss->enable_beacon)
+ if (bss->enable_beacon) {
  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");
+ common->beacon_enabled = 0;
+#ifdef CONFIG_CARACALLA_BOARD
+ rsi_del_bcn_timer(common);
+#endif
+ }
  }
 
  mutex_unlock(&common->mutex);
@@ -1073,6 +1089,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
  struct rsi_common *common = adapter->priv;
  u16 seq_no = 0;
  u8 ii = 0;
+ u8 sta_id = 0;
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0))
  u16 tid = params->tid;
@@ -1094,6 +1111,15 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
 #else
  seq_no = params->ssn;
 #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,
  "%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,
     tid,
     seq_no,
     buf_size,
-    STA_RX_ADDBA_DONE);
+    STA_RX_ADDBA_DONE,
+    sta_id);
  break;
 
  case IEEE80211_AMPDU_RX_STOP:
@@ -1116,7 +1143,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
     tid,
     0,
     buf_size,
-    STA_RX_DELBA);
+    STA_RX_DELBA,
+    sta_id);
  break;
 
  case IEEE80211_AMPDU_TX_START:
@@ -1137,7 +1165,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
     tid,
     seq_no,
     buf_size,
-    STA_TX_DELBA);
+    STA_TX_DELBA,
+    sta_id);
  if (!status)
  ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
  break;
@@ -1150,7 +1179,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
  tid,
  common->vif_info[ii].seq_start,
  buf_size,
- STA_TX_ADDBA_DONE);
+ STA_TX_ADDBA_DONE,
+ sta_id);
  break;
 
  default:
@@ -1332,6 +1362,8 @@ void rsi_indicate_pkt_to_os(struct rsi_common *common,
  /* filling in the ieee80211_rx_status flags */
  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);
  ieee80211_rx_irqsafe(hw, skb);
 }
@@ -1359,10 +1391,22 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
 
  if (vif->type == NL80211_IFTYPE_AP) {
  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 */
  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,
     sta->addr, ETH_ALEN)) {
  ven_rsi_dbg(INFO_ZONE, "Station exists\n");
@@ -1372,15 +1416,18 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
  }
  if (!sta_exist) {
  ven_rsi_dbg(INFO_ZONE, "New Station\n");
- rsi_inform_bss_status(common, AP_OPMODE, 1, sta->addr,
-      sta->wme, sta->aid, i);
+ if (free_index >= 0)
+ i = free_index;
  common->stations[i].sta = sta;
  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++)
  common->stations[i].seq_no[j] = 1;
  common->num_stations++;
  } else {
  common->stations[i].sta = sta;
+ common->stations[i].sta_id = i;
  for (j = 0; j < IEEE80211_NUM_ACS; j++)
  common->stations[i].seq_no[j] = 1;
  }
@@ -1403,8 +1450,11 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
  }
  }
 
+#if 0
  if ((vif->type == NL80211_IFTYPE_STATION) &&
     sta->ht_cap.ht_supported)
+#endif
+ if (sta->ht_cap.ht_supported)
  ieee80211_start_tx_ba_session(sta, 0, 0);
 
  mutex_unlock(&common->mutex);
@@ -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);
 
+ mutex_lock(&common->mutex);
  if (vif->type == NL80211_IFTYPE_AP) {
  u8 i, j;
 
  /* Send peer notify to device */
  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,
     sta->addr, ETH_ALEN)) {
  rsi_inform_bss_status(common, AP_OPMODE, 0,
       sta->addr, sta->wme,
-      sta->aid, i);
+      sta->aid, sta, i);
  common->stations[i].sta = NULL;
  common->stations[i].sta_id = -1;
  for (j = 0; j < IEEE80211_NUM_ACS; j++)
  common->stations[i].seq_no[j] = 0;
  common->num_stations--;
+ if (common->num_stations < 0)
+ common->num_stations = 0;
  break;
  }
  }
@@ -1456,7 +1511,6 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
 
  if (vif->type == NL80211_IFTYPE_STATION) {
  /* Resetting all the fields to default values */
- mutex_lock(&common->mutex);
  memcpy((u8 *)bss->bssid, (u8 *)sta->addr, ETH_ALEN);
  bss->qos = sta->wme;
  common->bitrate_mask[NL80211_BAND_2GHZ] = 0;
@@ -1469,11 +1523,11 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
  common->secinfo.gtk_cipher = 0;
  if (common->bgscan_en)
  common->bgscan_en = 0;
- mutex_unlock(&common->mutex);
 
  if (!common->iface_down)
  rsi_send_rx_filter_frame(common, 0);
  }
+ mutex_unlock(&common->mutex);
  return 0;
 }
 #if 0
@@ -1655,7 +1709,7 @@ static void rsi_reg_notify(struct wiphy *wiphy,
  common->bgscan_en = 1;
  }
  }
-
+
  adapter->dfs_region = request->dfs_region;
  adapter->country[0] = request->alpha2[0];
  adapter->country[1] = request->alpha2[1];
@@ -1679,13 +1733,13 @@ void rsi_mac80211_rfkill_poll(struct ieee80211_hw *hw)
 
 #ifdef CONFIG_RSI_WOW
 static const struct wiphy_wowlan_support rsi_wowlan_support = {
- .flags =WIPHY_WOWLAN_ANY |
- WIPHY_WOWLAN_MAGIC_PKT |
- WIPHY_WOWLAN_DISCONNECT |
- WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
- WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
- WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
- WIPHY_WOWLAN_4WAY_HANDSHAKE,
+ .flags = WIPHY_WOWLAN_ANY |
+ WIPHY_WOWLAN_MAGIC_PKT |
+ WIPHY_WOWLAN_DISCONNECT |
+ WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
+ WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
+ WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
+ WIPHY_WOWLAN_4WAY_HANDSHAKE,
  .n_patterns = 0,
  .pattern_min_len = 1,
  .pattern_max_len = 0,
@@ -1707,7 +1761,7 @@ static u16 rsi_wow_map_triggers(struct rsi_common *common,
  if (wowlan->gtk_rekey_failure || wowlan->eap_identity_req ||
     wowlan->four_way_handshake)
  wow_triggers |= RSI_WOW_SUPPORTS_GTK_REKEY;
-
+
  return wow_triggers;
 }
 #endif
@@ -1719,7 +1773,7 @@ int rsi_mac80211_suspend(struct ieee80211_hw *hw,
 #ifdef CONFIG_RSI_WOW
  struct rsi_hw *adapter = hw->priv;
  struct rsi_common *common = adapter->priv;
- u16 triggers;
+ u16 triggers, rx_filter_word = 0;
 #endif
  int ret = 0;
 
@@ -1736,22 +1790,45 @@ int rsi_mac80211_suspend(struct ieee80211_hw *hw,
  triggers = rsi_wow_map_triggers(common, wowlan);
  if (!triggers) {
  ven_rsi_dbg(ERR_ZONE, "%s:No valid WoW triggers\n",__func__);
- ret = 1;
+ ret = -EINVAL;
  goto fail_wow;
  }
  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:
 #endif
- return ret;
+        return ret;
 }
 
 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__);
 
+#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;
 }
 #endif
@@ -1774,8 +1851,8 @@ static struct ieee80211_ops mac80211_ops = {
  .sta_remove = rsi_mac80211_sta_remove,
  .set_antenna = rsi_mac80211_set_antenna,
  .get_antenna = rsi_mac80211_get_antenna,
- .rfkill_poll = rsi_mac80211_rfkill_poll,
-#ifdef CONFIG_PM
+        .rfkill_poll = rsi_mac80211_rfkill_poll,
+#ifdef CONFIG_PM
  .suspend = rsi_mac80211_suspend,
  .resume  = rsi_mac80211_resume,
 #endif
@@ -1842,7 +1919,8 @@ int rsi_mac80211_attach(struct rsi_common *common)
  hw->max_rate_tries = MAX_RETRIES;
  hw->uapsd_queues = IEEE80211_MARKALL_UAPSD_QUEUES;
  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_5GHZ);
diff --git a/ubuntu/rsi/rsi_91x_main.c b/ubuntu/rsi/rsi_91x_main.c
index 006dbd9..1c7a374 100644
--- a/ubuntu/rsi/rsi_91x_main.c
+++ b/ubuntu/rsi/rsi_91x_main.c
@@ -226,6 +226,54 @@ fail:
 }
 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) + 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 + 10) + 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,38 @@ 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)
+{
+ if (common->priv->rsi_host_intf == RSI_HOST_INTF_SDIO) {
+ 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")) {
+ ven_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 +365,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 +378,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 +423,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 +435,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);
diff --git a/ubuntu/rsi/rsi_91x_mgmt.c b/ubuntu/rsi/rsi_91x_mgmt.c
index 3329204..ca6151e 100644
--- a/ubuntu/rsi/rsi_91x_mgmt.c
+++ b/ubuntu/rsi/rsi_91x_mgmt.c
@@ -341,6 +341,7 @@ static void rsi_set_default_parameters(struct rsi_common *common)
  common->antenna_diversity = 0;
  common->tx_power = RSI_TXPOWER_MAX;
  common->dtim_cnt = 2;
+ common->beacon_interval = 100;
 }
 
 void init_bgscan_params(struct rsi_common *common)
@@ -685,7 +686,8 @@ int rsi_send_aggr_params_frame(struct rsi_common *common,
        u16 tid,
        u16 ssn,
        u8 buf_size,
-       u8 event)
+       u8 event,
+       u8 sta_id)
 {
  struct sk_buff *skb = NULL;
  struct rsi_mac_frame *mgmt_frame;
@@ -868,7 +870,7 @@ int rsi_set_vap_capabilities(struct rsi_common *common,
 #endif
 
  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->beacon_miss_threshold = cpu_to_le16(10);
  if (mode == AP_OPMODE)
@@ -972,22 +974,18 @@ int rsi_load_key(struct rsi_common *common,
  set_key->desc_word[4] = cpu_to_le16(key_descriptor);
  set_key->desc_word[7] = cpu_to_le16(sta_id | (vap_id << 8));
 
-#if 0
- if ((cipher == WLAN_CIPHER_SUITE_WEP40) ||
-    (cipher == WLAN_CIPHER_SUITE_WEP104)) {
- memcpy(&set_key->key[key_id][1], data, key_len * 2);
- } else {
- 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);
+ if ((cipher == WLAN_CIPHER_SUITE_WEP40) ||
+    (cipher == WLAN_CIPHER_SUITE_WEP104)) {
+ memcpy(&set_key->key[key_id][1], data, key_len * 2);
+ } else {
+ memcpy(&set_key->key[0][0], data, key_len);
+ }
  memcpy(set_key->tx_mic_key, &data[16], 8);
  memcpy(set_key->rx_mic_key, &data[24], 8);
  } else {
  memset(&set_key[FRAME_DESC_SZ], 0,
-       sizeof(struct rsi_set_key) - FRAME_DESC_SZ);
+       sizeof(struct rsi_set_key) - FRAME_DESC_SZ);
  }
 
  skb_put(skb, sizeof(struct rsi_set_key));
@@ -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(2352);
 #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);
+#endif
 
 #if 0
  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)
  * Return: 0 on success, corresponding error code on failure.
  */
 static int rsi_send_auto_rate_request(struct rsi_common *common,
+      struct ieee80211_sta *sta,
       u16 sta_id)
 {
+ struct ieee80211_vif *vif = common->priv->vifs[0];
  struct sk_buff *skb;
  struct rsi_auto_rate *auto_rate;
  int ii = 0, jj = 0, kk = 0;
@@ -1535,8 +1540,9 @@ static int rsi_send_auto_rate_request(struct rsi_common *common,
  u8 band = hw->conf.chandef.chan->band;
  u8 num_supported_rates = 0;
  u8 rate_table_offset, rate_offset = 0;
- u32 rate_bitmap = common->bitrate_mask[band];
+ u32 rate_bitmap = 0;
  u16 *selected_rates, min_rate;
+ bool is_ht = false, is_sgi = false;
 
  ven_rsi_dbg(MGMT_TX_ZONE,
  "%s: Sending auto rate request frame\n", __func__);
@@ -1548,6 +1554,8 @@ static int rsi_send_auto_rate_request(struct rsi_common *common,
  return -ENOMEM;
  }
 
+ memset(skb->data, 0, MAX_MGMT_PKT_SIZE);
+
  selected_rates = kzalloc(2 * RSI_TBL_SZ, GFP_KERNEL);
  if (!selected_rates) {
  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,
  dev_kfree_skb(skb);
  return -ENOMEM;
  }
-
- memset(skb->data, 0, sizeof(struct rsi_auto_rate));
  memset(selected_rates, 0, 2 * RSI_TBL_SZ);
 
  auto_rate = (struct rsi_auto_rate *)skb->data;
@@ -1573,11 +1579,31 @@ 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(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) {
- min_rate = RSI_RATE_1;
+ if ((rate_bitmap == 0) && (is_ht))
+ min_rate = RSI_RATE_MCS0;
+ else
+ min_rate = RSI_RATE_1;
  rate_table_offset = 0;
  } else {
- min_rate = RSI_RATE_6;
+ if ((rate_bitmap == 0) && (is_ht))
+ min_rate = RSI_RATE_MCS0;
+ else
+ min_rate = RSI_RATE_6;
  rate_table_offset = 4;
  }
 
@@ -1591,7 +1617,7 @@ static int rsi_send_auto_rate_request(struct rsi_common *common,
  }
  num_supported_rates = jj;
 
- if (common->vif_info[0].is_ht) {
+ if (is_ht) {
  for (ii = 0; ii < ARRAY_SIZE(mcs); ii++)
  selected_rates[jj++] = mcs[ii];
  num_supported_rates += ARRAY_SIZE(mcs);
@@ -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 */
- if (common->vif_info[0].is_ht) {
+ if (is_ht) {
  for (ii = rate_offset, kk = ARRAY_SIZE(rsi_mcsrates) - 1;
      ii < rate_offset + 2 * ARRAY_SIZE(rsi_mcsrates); ii++) {
- if (common->vif_info[0].sgi ||
-    conf_is_ht40(&common->priv->hw->conf))
+ if (is_sgi || conf_is_ht40(&common->priv->hw->conf)) {
  auto_rate->supported_rates[ii++] =
  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] =
  cpu_to_le16(rsi_mcsrates[kk--]);
  }
@@ -1637,8 +1666,8 @@ static int rsi_send_auto_rate_request(struct rsi_common *common,
  num_supported_rates *= 2;
 
  auto_rate->desc_word[0] = cpu_to_le16((sizeof(*auto_rate) -
-       FRAME_DESC_SZ) |
-       (RSI_WIFI_MGMT_Q << 12));
+      FRAME_DESC_SZ) |
+      (RSI_WIFI_MGMT_Q << 12));
 
  skb_put(skb, sizeof(struct rsi_auto_rate));
  kfree(selected_rates);
@@ -1659,7 +1688,7 @@ static void rsi_validate_bgscan_channels(struct rsi_hw *adapter,
 {
  struct ieee80211_supported_band *sband;
  struct ieee80211_channel *ch;
- struct wiphy *wiphy = adapter->hw->wiphy;
+ struct wiphy *wiphy = adapter->hw->wiphy;
  u16 bgscan_channels[MAX_BGSCAN_CHANNELS] = {1, 2, 3, 4, 5, 6, 7, 8, 9,
     10, 11, 12, 13, 14, 36, 40,
     44, 48, 52, 56, 60, 64, 100,
@@ -1745,7 +1774,7 @@ int rsi_send_bgscan_params(struct rsi_common *common, int enable)
  ven_rsi_dbg(ERR_ZONE, "##### No valid bgscan channels #####\n");
  return -1;
  }
-
+
  skb = dev_alloc_skb(frame_len);
  if (!skb)
  return -ENOMEM;
@@ -1849,6 +1878,7 @@ void rsi_inform_bss_status(struct rsi_common *common,
    u8 *bssid,
    u8 qos_enable,
    u16 aid,
+   struct ieee80211_sta *sta,
    u16 sta_id)
 {
  if (status) {
@@ -1863,15 +1893,21 @@ void rsi_inform_bss_status(struct rsi_common *common,
   sta_id);
  if (common->min_rate == 0xffff) {
  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 (!rsi_send_block_unblock_frame(common, false))
- common->hw_data_qs_blocked = false;
+ if ((!common->secinfo.security_enable) ||
+    (rsi_is_cipher_wep(common))) {
+ if (!rsi_send_block_unblock_frame(common, false))
+ common->hw_data_qs_blocked = false;
+ }
  }
  } else {
  if (opmode == STA_OPMODE)
  common->hw_data_qs_blocked = true;
+#ifdef CONFIG_RSI_WOW
+ if (!common->suspend_flag) {
+#endif
  rsi_send_sta_notify_frame(common,
   opmode,
   STA_DISCONNECTED,
@@ -1879,6 +1915,9 @@ void rsi_inform_bss_status(struct rsi_common *common,
   qos_enable,
   aid,
   sta_id);
+#ifdef CONFIG_RSI_WOW
+ }
+#endif
  if (opmode == STA_OPMODE)
  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)
 
  return rsi_send_internal_mgmt_frame(common, skb);
 }
+EXPORT_SYMBOL_GPL(rsi_send_rx_filter_frame);
 
 /**
  * rsi_send_ps_request() - Sends power save request.
@@ -2352,42 +2392,45 @@ int rsi_handle_card_ready(struct rsi_common *common)
  return 0;
 }
 
-#ifdef CONFIG_RSI_WOW
+#ifdef CONFIG_RSI_WOW
 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 sk_buff *skb;
- u8 length;
- u8 sourceid[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
- ven_rsi_dbg(ERR_ZONE, "%s: Sending wowlan request frame\n", __func__);
-
- skb = dev_alloc_skb(sizeof(*cmd_frame));
- if (!skb) {
- ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
- __func__);
- return -ENOMEM;
- }
- memset(skb->data, 0, sizeof(*cmd_frame));
- cmd_frame = (struct rsi_wowlan_req *)skb->data;
-
- cmd_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
- cmd_frame->desc_word[1] |= cpu_to_le16(WOWLAN_CONFIG_PARAMS);
-
- memcpy(cmd_frame->sourceid, &sourceid, IEEE80211_ADDR_LEN);
-
- cmd_frame->wow_flags = flags; /* TODO: check for the magic packet */
- cmd_frame->host_sleep_status = 1; /* TODO: check for the host status */
-
- length = FRAME_DESC_SZ + IEEE80211_ADDR_LEN + 2 + 2;
-
- cmd_frame->desc_word[0] |= cpu_to_le16(length - FRAME_DESC_SZ);
- cmd_frame->desc_word[2] |= cpu_to_le16(0);
+        struct rsi_wowlan_req *cmd_frame;
+        struct sk_buff *skb;
+        u8 length;
+        u8 sourceid[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+        ven_rsi_dbg(ERR_ZONE, "%s: Sending wowlan request frame\n", __func__);
+
+        skb = dev_alloc_skb(sizeof(*cmd_frame));
+        if (!skb) {
+                ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
+                                __func__);
+                return -ENOMEM;
+        }
+        memset(skb->data, 0, sizeof(*cmd_frame));
+        cmd_frame = (struct rsi_wowlan_req *)skb->data;
+
+        cmd_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
+        cmd_frame->desc_word[1] |= cpu_to_le16(WOWLAN_CONFIG_PARAMS);
+
+        memcpy(cmd_frame->sourceid, &sourceid, IEEE80211_ADDR_LEN);
+
+        cmd_frame->host_sleep_status = sleep_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;
 
- skb_put(skb, length);
+        cmd_frame->desc_word[0] |= cpu_to_le16(length - FRAME_DESC_SZ);
+        cmd_frame->desc_word[2] |= cpu_to_le16(0);
+  
+   skb_put(skb, length);
 
- return rsi_send_internal_mgmt_frame(common, skb);
+        return rsi_send_internal_mgmt_frame(common, skb);
 }
 #endif
 
@@ -2403,6 +2446,7 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg)
 {
  s32 msg_len = (le16_to_cpu(*(__le16 *)&msg[0]) & 0x0fff);
  u16 msg_type = msg[2];
+ struct ieee80211_vif *vif = common->priv->vifs[0];
 
  switch (msg_type) {
  case TA_CONFIRM_TYPE:
@@ -2417,6 +2461,18 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg)
  common->mgmt_q_block = false;
  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;
 
  case PS_NOTIFY_IND:
@@ -2447,13 +2503,15 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg)
 
  case BEACON_EVENT_IND:
  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;
  if (common->iface_down)
  return -1;
- mutex_lock(&common->mutex);
+ if (!common->beacon_enabled)
+ return -1;
  rsi_send_beacon(common);
- mutex_unlock(&common->mutex);
+#endif
  break;
 
  case RX_DOT11_MGMT:
diff --git a/ubuntu/rsi/rsi_91x_sdio.c b/ubuntu/rsi/rsi_91x_sdio.c
index 15083e5..9378b36 100644
--- a/ubuntu/rsi/rsi_91x_sdio.c
+++ b/ubuntu/rsi/rsi_91x_sdio.c
@@ -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)) {
@@ -1110,12 +1112,14 @@ 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)
+#ifdef CONFIG_SDIO_INTR_POLL
  if (adapter->rsi_host_intf == RSI_HOST_INTF_SDIO)
- rsi_kill_thread(&adapter->priv->hci_thread);
-#endif
+ 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 +1128,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 +1148,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 +1157,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 = {
diff --git a/ubuntu/rsi/rsi_91x_sdio_ops.c b/ubuntu/rsi/rsi_91x_sdio_ops.c
index be62d42..7d412f0 100644
--- a/ubuntu/rsi/rsi_91x_sdio_ops.c
+++ b/ubuntu/rsi/rsi_91x_sdio_ops.c
@@ -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;
diff --git a/ubuntu/rsi/rsi_coex.h b/ubuntu/rsi/rsi_coex.h
index 027bc77..24b8688 100644
--- a/ubuntu/rsi/rsi_coex.h
+++ b/ubuntu/rsi/rsi_coex.h
@@ -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;
 };
 
diff --git a/ubuntu/rsi/rsi_common.h b/ubuntu/rsi/rsi_common.h
index 5067af9..47951cf 100644
--- a/ubuntu/rsi/rsi_common.h
+++ b/ubuntu/rsi/rsi_common.h
@@ -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
diff --git a/ubuntu/rsi/rsi_main.h b/ubuntu/rsi/rsi_main.h
index 09b9c82..2edb661 100644
--- a/ubuntu/rsi/rsi_main.h
+++ b/ubuntu/rsi/rsi_main.h
@@ -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;
@@ -287,6 +289,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 +302,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 {
diff --git a/ubuntu/rsi/rsi_mgmt.h b/ubuntu/rsi/rsi_mgmt.h
index ece9b40..987f9dc 100644
--- a/ubuntu/rsi/rsi_mgmt.h
+++ b/ubuntu/rsi/rsi_mgmt.h
@@ -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,7 @@ 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);
 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 +559,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
--
2.9.3


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] [Xenial][SRU] UBUNTU: SAUCE: Redpine driver to support Host AP mode

Shrirang Bagul
Please ignore this patch as of now, we might have a newer version for the driver
from the vendor which will replace this patch.

Thanks,
Shrirang

On Thu, 2017-02-16 at 13:05 +0800, Shrirang Bagul wrote:

> 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.2 (Beta)
>
> Signed-off-by: Shrirang Bagul <[hidden email]>
> ---
>  ubuntu/rsi/Makefile           |   2 +-
>  ubuntu/rsi/rsi_91x_core.c     |  49 +++++++++--
>  ubuntu/rsi/rsi_91x_debugfs.c  |  35 ++++++--
>  ubuntu/rsi/rsi_91x_hal.c      |  78 +++++++++++-------
>  ubuntu/rsi/rsi_91x_hci.c      |  44 +---------
>  ubuntu/rsi/rsi_91x_mac80211.c | 146 ++++++++++++++++++++++++--------
>  ubuntu/rsi/rsi_91x_main.c     |  96 +++++++++++++++++++++
>  ubuntu/rsi/rsi_91x_mgmt.c     | 188 +++++++++++++++++++++++++++------------
> ---
>  ubuntu/rsi/rsi_91x_sdio.c     |  88 ++++++++------------
>  ubuntu/rsi/rsi_91x_sdio_ops.c |  11 ++-
>  ubuntu/rsi/rsi_coex.h         |   2 +-
>  ubuntu/rsi/rsi_common.h       |   6 ++
>  ubuntu/rsi/rsi_main.h         |  15 +++-
>  ubuntu/rsi/rsi_mgmt.h         |  14 ++--
>  14 files changed, 521 insertions(+), 253 deletions(-)
>
> diff --git a/ubuntu/rsi/Makefile b/ubuntu/rsi/Makefile
> index 941848c..a7db51c 100644
> --- a/ubuntu/rsi/Makefile
> +++ b/ubuntu/rsi/Makefile
> @@ -1,4 +1,4 @@
> -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
> diff --git a/ubuntu/rsi/rsi_91x_core.c b/ubuntu/rsi/rsi_91x_core.c
> index eaf0e29..ac55ce1 100644
> --- a/ubuntu/rsi/rsi_91x_core.c
> +++ b/ubuntu/rsi/rsi_91x_core.c
> @@ -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,23 @@ 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_inform_bss_status(common, STA_OPMODE,1 ,
> +       bss->bssid, bss->qos,
> +       bss->aid, NULL, 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 +455,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 +481,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)) {
> diff --git a/ubuntu/rsi/rsi_91x_debugfs.c b/ubuntu/rsi/rsi_91x_debugfs.c
> index aeb0834..be4aec2 100644
> --- a/ubuntu/rsi/rsi_91x_debugfs.c
> +++ b/ubuntu/rsi/rsi_91x_debugfs.c
> @@ -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");
> diff --git a/ubuntu/rsi/rsi_91x_hal.c b/ubuntu/rsi/rsi_91x_hal.c
> index 45f83e9..9181b54 100644
> --- a/ubuntu/rsi/rsi_91x_hal.c
> +++ b/ubuntu/rsi/rsi_91x_hal.c
> @@ -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_H
> OST);
> + 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 @@ err:
>  
>  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;
>  }
>  
>  /**
> diff --git a/ubuntu/rsi/rsi_91x_hci.c b/ubuntu/rsi/rsi_91x_hci.c
> index 773e216..4442651 100644
> --- a/ubuntu/rsi/rsi_91x_hci.c
> +++ b/ubuntu/rsi/rsi_91x_hci.c
> @@ -198,21 +198,6 @@ fail:
>   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 @@ err:
>  #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);
>  
> diff --git a/ubuntu/rsi/rsi_91x_mac80211.c b/ubuntu/rsi/rsi_91x_mac80211.c
> index 1d18b10..8cf3a47 100644
> --- a/ubuntu/rsi/rsi_91x_mac80211.c
> +++ b/ubuntu/rsi/rsi_91x_mac80211.c
> @@ -419,10 +419,10 @@ static int rsi_mac80211_add_interface(struct
> ieee80211_hw *hw,
>  
>   mutex_lock(&common->mutex);
>  
> - /* Not supporting concurrent mode now */
> + /* Not supporting concurrent mode now */
>   if (adapter->sc_nvifs > 0)
>   return -1;
> -
> +
>   adapter->vifs[adapter->sc_nvifs++] = vif;
>  
>   switch (vif->type) {
> @@ -442,9 +442,15 @@ static int rsi_mac80211_add_interface(struct ieee80211_hw
> *hw,
>   }
>  
>   if (vif->type == NL80211_IFTYPE_AP) {
> + int i;
> +
>   common->bc_mc_seqno = 1;
>   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);
> @@ -762,7 +768,7 @@ static void rsi_mac80211_bss_info_changed(struct
> ieee80211_hw *hw,
>     ALLOW_CTRL_ASSOC_PEER |
>     ALLOW_MGMT_ASSOC_PEER |
>  #ifdef RSI_HW_CONN_MONITOR
> -   DISALLOW_BEACONS |
> +   //DISALLOW_BEACONS |
>  #endif
>   0);
>   rsi_send_rx_filter_frame(common, rx_filter_word);
> @@ -778,7 +784,7 @@ static void rsi_mac80211_bss_info_changed(struct
> ieee80211_hw *hw,
>   /* Send peer notify to device */
>   ven_rsi_dbg(INFO_ZONE, "Indicate bss status to device\n");
>   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 =
>   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,
>   if (changed & BSS_CHANGED_BEACON_INT) {
>   ven_rsi_dbg(INFO_ZONE, "%s: Changed Beacon interval: %d\n",
>   __func__, bss_conf->beacon_int);
> + common->beacon_interval = bss->beacon_int; 
>   adapter->ps_info.listen_interval =
>   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,
>  
>   if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
>       (vif->type == NL80211_IFTYPE_AP)) {
> - if (bss->enable_beacon)
> + if (bss->enable_beacon) {
>   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");
> + common->beacon_enabled = 0;
> +#ifdef CONFIG_CARACALLA_BOARD
> + rsi_del_bcn_timer(common);
> +#endif
> + }
>   }
>  
>   mutex_unlock(&common->mutex);
> @@ -1073,6 +1089,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw
> *hw,
>   struct rsi_common *common = adapter->priv;
>   u16 seq_no = 0;
>   u8 ii = 0;
> + u8 sta_id = 0;
>  
>  #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0))
>   u16 tid = params->tid;
> @@ -1094,6 +1111,15 @@ static int rsi_mac80211_ampdu_action(struct
> ieee80211_hw *hw,
>  #else
>   seq_no = params->ssn;
>  #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,
>   "%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,
>       tid,
>       seq_no,
>       buf_size,
> -     STA_RX_ADDBA_DONE);
> +     STA_RX_ADDBA_DONE,
> +     sta_id);
>   break;
>  
>   case IEEE80211_AMPDU_RX_STOP:
> @@ -1116,7 +1143,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw
> *hw,
>       tid,
>       0,
>       buf_size,
> -     STA_RX_DELBA);
> +     STA_RX_DELBA,
> +     sta_id);
>   break;
>  
>   case IEEE80211_AMPDU_TX_START:
> @@ -1137,7 +1165,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw
> *hw,
>       tid,
>       seq_no,
>       buf_size,
> -     STA_TX_DELBA);
> +     STA_TX_DELBA,
> +     sta_id);
>   if (!status)
>   ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
>   break;
> @@ -1150,7 +1179,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw
> *hw,
>   tid,
>   common-
> >vif_info[ii].seq_start,
>   buf_size,
> - STA_TX_ADDBA_DONE);
> + STA_TX_ADDBA_DONE,
> + sta_id);
>   break;
>  
>   default:
> @@ -1332,6 +1362,8 @@ void rsi_indicate_pkt_to_os(struct rsi_common *common,
>   /* filling in the ieee80211_rx_status flags */
>   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);
>   ieee80211_rx_irqsafe(hw, skb);
>  }
> @@ -1359,10 +1391,22 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw
> *hw,
>  
>   if (vif->type == NL80211_IFTYPE_AP) {
>   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 */
>   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,
>       sta->addr, ETH_ALEN)) {
>   ven_rsi_dbg(INFO_ZONE, "Station exists\n");
> @@ -1372,15 +1416,18 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw
> *hw,
>   }
>   if (!sta_exist) {
>   ven_rsi_dbg(INFO_ZONE, "New Station\n");
> - rsi_inform_bss_status(common, AP_OPMODE, 1, sta-
> >addr,
> -       sta->wme, sta->aid, i);
> + if (free_index >= 0)
> + i = free_index;
>   common->stations[i].sta = sta;
>   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++)
>   common->stations[i].seq_no[j] = 1;
>   common->num_stations++;
>   } else {
>   common->stations[i].sta = sta;
> + common->stations[i].sta_id = i;
>   for (j = 0; j < IEEE80211_NUM_ACS; j++)
>   common->stations[i].seq_no[j] = 1;
>   }
> @@ -1403,8 +1450,11 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw
> *hw,
>   }
>   }
>  
> +#if 0
>   if ((vif->type == NL80211_IFTYPE_STATION) &&
>       sta->ht_cap.ht_supported)
> +#endif
> + if (sta->ht_cap.ht_supported)
>   ieee80211_start_tx_ba_session(sta, 0, 0);
>  
>   mutex_unlock(&common->mutex);
> @@ -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);
>  
> + mutex_lock(&common->mutex);
>   if (vif->type == NL80211_IFTYPE_AP) {
>   u8 i, j;
>  
>   /* Send peer notify to device */
>   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,
>       sta->addr, ETH_ALEN)) {
>   rsi_inform_bss_status(common, AP_OPMODE, 0,
>         sta->addr, sta->wme,
> -       sta->aid, i);
> +       sta->aid, sta, i);
>   common->stations[i].sta = NULL;
>   common->stations[i].sta_id = -1;
>   for (j = 0; j < IEEE80211_NUM_ACS; j++)
>   common->stations[i].seq_no[j] = 0;
>   common->num_stations--;
> + if (common->num_stations < 0)
> + common->num_stations = 0;
>   break;
>   }
>   }
> @@ -1456,7 +1511,6 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw
> *hw,
>  
>   if (vif->type == NL80211_IFTYPE_STATION) {
>   /* Resetting all the fields to default values */
> - mutex_lock(&common->mutex);
>   memcpy((u8 *)bss->bssid, (u8 *)sta->addr, ETH_ALEN);
>   bss->qos = sta->wme;
>   common->bitrate_mask[NL80211_BAND_2GHZ] = 0;
> @@ -1469,11 +1523,11 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw
> *hw,
>   common->secinfo.gtk_cipher = 0;
>   if (common->bgscan_en)
>   common->bgscan_en = 0;
> - mutex_unlock(&common->mutex);
>  
>   if (!common->iface_down)
>   rsi_send_rx_filter_frame(common, 0);
>   }
> + mutex_unlock(&common->mutex);
>   return 0;
>  }
>  #if 0
> @@ -1655,7 +1709,7 @@ static void rsi_reg_notify(struct wiphy *wiphy,
>   common->bgscan_en = 1;
>   }
>   }
> -
> +
>   adapter->dfs_region = request->dfs_region;
>   adapter->country[0] = request->alpha2[0];
>   adapter->country[1] = request->alpha2[1];
> @@ -1679,13 +1733,13 @@ void rsi_mac80211_rfkill_poll(struct ieee80211_hw *hw)
>  
>  #ifdef CONFIG_RSI_WOW
>  static const struct wiphy_wowlan_support rsi_wowlan_support = {
> - .flags =WIPHY_WOWLAN_ANY |
> - WIPHY_WOWLAN_MAGIC_PKT |
> - WIPHY_WOWLAN_DISCONNECT |
> - WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
> - WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
> - WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
> - WIPHY_WOWLAN_4WAY_HANDSHAKE,
> + .flags = WIPHY_WOWLAN_ANY |
> +  WIPHY_WOWLAN_MAGIC_PKT |
> +  WIPHY_WOWLAN_DISCONNECT |
> +  WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
> +  WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
> +  WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
> +  WIPHY_WOWLAN_4WAY_HANDSHAKE,
>   .n_patterns = 0,
>   .pattern_min_len = 1,
>   .pattern_max_len = 0,
> @@ -1707,7 +1761,7 @@ static u16 rsi_wow_map_triggers(struct rsi_common
> *common,
>   if (wowlan->gtk_rekey_failure || wowlan->eap_identity_req ||
>       wowlan->four_way_handshake)
>   wow_triggers |= RSI_WOW_SUPPORTS_GTK_REKEY;
> -
> +
>   return wow_triggers;
>  }
>  #endif
> @@ -1719,7 +1773,7 @@ int rsi_mac80211_suspend(struct ieee80211_hw *hw,
>  #ifdef CONFIG_RSI_WOW
>   struct rsi_hw *adapter = hw->priv;
>   struct rsi_common *common = adapter->priv;
> - u16 triggers;
> + u16 triggers, rx_filter_word = 0;
>  #endif
>   int ret = 0;
>  
> @@ -1736,22 +1790,45 @@ int rsi_mac80211_suspend(struct ieee80211_hw *hw,
>   triggers = rsi_wow_map_triggers(common, wowlan);
>   if (!triggers) {
>   ven_rsi_dbg(ERR_ZONE, "%s:No valid WoW triggers\n",__func__);
> - ret = 1;
> + ret = -EINVAL;
>   goto fail_wow;
>   }
>   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:
>  #endif
> - return ret;
> +        return ret;
>  }
>  
>  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__);
>  
> +#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;
>  }
>  #endif
> @@ -1774,8 +1851,8 @@ static struct ieee80211_ops mac80211_ops = {
>   .sta_remove = rsi_mac80211_sta_remove,
>   .set_antenna = rsi_mac80211_set_antenna,
>   .get_antenna = rsi_mac80211_get_antenna,
> - .rfkill_poll = rsi_mac80211_rfkill_poll,
> -#ifdef CONFIG_PM
> +        .rfkill_poll = rsi_mac80211_rfkill_poll,
> +#ifdef CONFIG_PM 
>   .suspend = rsi_mac80211_suspend,
>   .resume  = rsi_mac80211_resume,
>  #endif
> @@ -1842,7 +1919,8 @@ int rsi_mac80211_attach(struct rsi_common *common)
>   hw->max_rate_tries = MAX_RETRIES;
>   hw->uapsd_queues = IEEE80211_MARKALL_UAPSD_QUEUES;
>   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_5GHZ);
> diff --git a/ubuntu/rsi/rsi_91x_main.c b/ubuntu/rsi/rsi_91x_main.c
> index 006dbd9..1c7a374 100644
> --- a/ubuntu/rsi/rsi_91x_main.c
> +++ b/ubuntu/rsi/rsi_91x_main.c
> @@ -226,6 +226,54 @@ fail:
>  }
>  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) + 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 + 10) + 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,38 @@ 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)
> +{
> + if (common->priv->rsi_host_intf == RSI_HOST_INTF_SDIO) {
> + 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")) {
> + ven_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 +365,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 +378,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 +423,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 +435,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);
> diff --git a/ubuntu/rsi/rsi_91x_mgmt.c b/ubuntu/rsi/rsi_91x_mgmt.c
> index 3329204..ca6151e 100644
> --- a/ubuntu/rsi/rsi_91x_mgmt.c
> +++ b/ubuntu/rsi/rsi_91x_mgmt.c
> @@ -341,6 +341,7 @@ static void rsi_set_default_parameters(struct rsi_common
> *common)
>   common->antenna_diversity = 0;
>   common->tx_power = RSI_TXPOWER_MAX;
>   common->dtim_cnt = 2;
> + common->beacon_interval = 100;
>  }
>  
>  void init_bgscan_params(struct rsi_common *common)
> @@ -685,7 +686,8 @@ int rsi_send_aggr_params_frame(struct rsi_common *common,
>          u16 tid,
>          u16 ssn,
>          u8 buf_size,
> -        u8 event)
> +        u8 event,
> +        u8 sta_id)
>  {
>   struct sk_buff *skb = NULL;
>   struct rsi_mac_frame *mgmt_frame;
> @@ -868,7 +870,7 @@ int rsi_set_vap_capabilities(struct rsi_common *common,
>  #endif
>  
>   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->beacon_miss_threshold = cpu_to_le16(10);
>   if (mode == AP_OPMODE)
> @@ -972,22 +974,18 @@ int rsi_load_key(struct rsi_common *common,
>   set_key->desc_word[4] = cpu_to_le16(key_descriptor);
>   set_key->desc_word[7] = cpu_to_le16(sta_id | (vap_id << 8));
>  
> -#if 0
> - if ((cipher == WLAN_CIPHER_SUITE_WEP40) ||
> -     (cipher == WLAN_CIPHER_SUITE_WEP104)) {
> - memcpy(&set_key->key[key_id][1], data, key_len * 2);
> - } else {
> - 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);
> + if ((cipher == WLAN_CIPHER_SUITE_WEP40) ||
> +     (cipher == WLAN_CIPHER_SUITE_WEP104)) {
> + memcpy(&set_key->key[key_id][1], data, key_len * 2);
> + } else {
> + memcpy(&set_key->key[0][0], data, key_len);
> + }
>   memcpy(set_key->tx_mic_key, &data[16], 8);
>   memcpy(set_key->rx_mic_key, &data[24], 8);
>   } else {
>   memset(&set_key[FRAME_DESC_SZ], 0,
> -        sizeof(struct rsi_set_key) - FRAME_DESC_SZ);
> +        sizeof(struct rsi_set_key) - FRAME_DESC_SZ);
>
>   }
>  
>   skb_put(skb, sizeof(struct rsi_set_key));
> @@ -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(2352);
>  #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);
> +#endif
>  
>  #if 0
>   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)
>   * Return: 0 on success, corresponding error code on failure.
>   */
>  static int rsi_send_auto_rate_request(struct rsi_common *common,
> +       struct ieee80211_sta *sta,
>         u16 sta_id)
>  {
> + struct ieee80211_vif *vif = common->priv->vifs[0];
>   struct sk_buff *skb;
>   struct rsi_auto_rate *auto_rate;
>   int ii = 0, jj = 0, kk = 0;
> @@ -1535,8 +1540,9 @@ static int rsi_send_auto_rate_request(struct rsi_common
> *common,
>   u8 band = hw->conf.chandef.chan->band;
>   u8 num_supported_rates = 0;
>   u8 rate_table_offset, rate_offset = 0;
> - u32 rate_bitmap = common->bitrate_mask[band];
> + u32 rate_bitmap = 0;
>   u16 *selected_rates, min_rate;
> + bool is_ht = false, is_sgi = false;
>  
>   ven_rsi_dbg(MGMT_TX_ZONE,
>   "%s: Sending auto rate request frame\n", __func__);
> @@ -1548,6 +1554,8 @@ static int rsi_send_auto_rate_request(struct rsi_common
> *common,
>   return -ENOMEM;
>   }
>  
> + memset(skb->data, 0, MAX_MGMT_PKT_SIZE);
> +
>   selected_rates = kzalloc(2 * RSI_TBL_SZ, GFP_KERNEL);
>   if (!selected_rates) {
>   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,
>   dev_kfree_skb(skb);
>   return -ENOMEM;
>   }
> -
> - memset(skb->data, 0, sizeof(struct rsi_auto_rate));
>   memset(selected_rates, 0, 2 * RSI_TBL_SZ);
>  
>   auto_rate = (struct rsi_auto_rate *)skb->data;
> @@ -1573,11 +1579,31 @@ 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(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) {
> - min_rate = RSI_RATE_1;
> + if ((rate_bitmap == 0) && (is_ht))
> + min_rate = RSI_RATE_MCS0;
> + else
> + min_rate = RSI_RATE_1;
>   rate_table_offset = 0;
>   } else {
> - min_rate = RSI_RATE_6;
> + if ((rate_bitmap == 0) && (is_ht))
> + min_rate = RSI_RATE_MCS0;
> + else
> + min_rate = RSI_RATE_6;
>   rate_table_offset = 4;
>   }
>  
> @@ -1591,7 +1617,7 @@ static int rsi_send_auto_rate_request(struct rsi_common
> *common,
>   }
>   num_supported_rates = jj;
>  
> - if (common->vif_info[0].is_ht) {
> + if (is_ht) {
>   for (ii = 0; ii < ARRAY_SIZE(mcs); ii++)
>   selected_rates[jj++] = mcs[ii];
>   num_supported_rates += ARRAY_SIZE(mcs);
> @@ -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 */
> - if (common->vif_info[0].is_ht) {
> + if (is_ht) {
>   for (ii = rate_offset, kk = ARRAY_SIZE(rsi_mcsrates) - 1;
>        ii < rate_offset + 2 * ARRAY_SIZE(rsi_mcsrates); ii++) {
> - if (common->vif_info[0].sgi ||
> -     conf_is_ht40(&common->priv->hw->conf))
> + if (is_sgi || conf_is_ht40(&common->priv->hw->conf))
> {
>   auto_rate->supported_rates[ii++] =
>   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] =
>   cpu_to_le16(rsi_mcsrates[kk--]);
>   }
> @@ -1637,8 +1666,8 @@ static int rsi_send_auto_rate_request(struct rsi_common
> *common,
>   num_supported_rates *= 2;
>  
>   auto_rate->desc_word[0] = cpu_to_le16((sizeof(*auto_rate) -
> -        FRAME_DESC_SZ) |
> -        (RSI_WIFI_MGMT_Q << 12));
> +       FRAME_DESC_SZ) |
> +       (RSI_WIFI_MGMT_Q << 12));
>  
>   skb_put(skb, sizeof(struct rsi_auto_rate));
>   kfree(selected_rates);
> @@ -1659,7 +1688,7 @@ static void rsi_validate_bgscan_channels(struct rsi_hw
> *adapter,
>  {
>   struct ieee80211_supported_band *sband;
>   struct ieee80211_channel *ch;
> - struct wiphy *wiphy = adapter->hw->wiphy;
> + struct wiphy *wiphy = adapter->hw->wiphy; 
>   u16 bgscan_channels[MAX_BGSCAN_CHANNELS] = {1, 2, 3, 4, 5, 6, 7, 8,
> 9,
>       10, 11, 12, 13, 14, 36,
> 40,
>       44, 48, 52, 56, 60, 64,
> 100,
> @@ -1745,7 +1774,7 @@ int rsi_send_bgscan_params(struct rsi_common *common,
> int enable)
>   ven_rsi_dbg(ERR_ZONE, "##### No valid bgscan channels
> #####\n");
>   return -1;
>   }
> -
> +
>   skb = dev_alloc_skb(frame_len);
>   if (!skb)
>   return -ENOMEM;
> @@ -1849,6 +1878,7 @@ void rsi_inform_bss_status(struct rsi_common *common,
>      u8 *bssid,
>      u8 qos_enable,
>      u16 aid,
> +    struct ieee80211_sta *sta,
>      u16 sta_id)
>  {
>   if (status) {
> @@ -1863,15 +1893,21 @@ void rsi_inform_bss_status(struct rsi_common *common,
>     sta_id);
>   if (common->min_rate == 0xffff) {
>   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 (!rsi_send_block_unblock_frame(common, false))
> - common->hw_data_qs_blocked = false;
> + if ((!common->secinfo.security_enable) ||
> +     (rsi_is_cipher_wep(common))) {
> + if (!rsi_send_block_unblock_frame(common,
> false))
> + common->hw_data_qs_blocked = false;
> + }
>   }
>   } else {
>   if (opmode == STA_OPMODE)
>   common->hw_data_qs_blocked = true;
> +#ifdef CONFIG_RSI_WOW
> + if (!common->suspend_flag) {
> +#endif
>   rsi_send_sta_notify_frame(common,
>     opmode,
>     STA_DISCONNECTED,
> @@ -1879,6 +1915,9 @@ void rsi_inform_bss_status(struct rsi_common *common,
>     qos_enable,
>     aid,
>     sta_id);
> +#ifdef CONFIG_RSI_WOW
> + }
> +#endif
>   if (opmode == STA_OPMODE)
>   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)
>  
>   return rsi_send_internal_mgmt_frame(common, skb);
>  }
> +EXPORT_SYMBOL_GPL(rsi_send_rx_filter_frame); 
>  
>  /**
>   * rsi_send_ps_request() - Sends power save request.
> @@ -2352,42 +2392,45 @@ int rsi_handle_card_ready(struct rsi_common *common)
>   return 0;
>  }
>  
> -#ifdef CONFIG_RSI_WOW
> +#ifdef CONFIG_RSI_WOW 
>  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 sk_buff *skb;
> - u8 length;
> - u8 sourceid[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
> -
> - ven_rsi_dbg(ERR_ZONE, "%s: Sending wowlan request frame\n",
> __func__);
> -
> - skb = dev_alloc_skb(sizeof(*cmd_frame));
> - if (!skb) {
> - ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
> - __func__);
> - return -ENOMEM;
> - }
> - memset(skb->data, 0, sizeof(*cmd_frame));
> - cmd_frame = (struct rsi_wowlan_req *)skb->data;
> -
> - cmd_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
> - cmd_frame->desc_word[1] |= cpu_to_le16(WOWLAN_CONFIG_PARAMS);
> -
> - memcpy(cmd_frame->sourceid, &sourceid, IEEE80211_ADDR_LEN);
> -
> - cmd_frame->wow_flags = flags; /* TODO: check for the magic packet */
> - cmd_frame->host_sleep_status = 1; /* TODO: check for the host status
> */
> -
> - length = FRAME_DESC_SZ + IEEE80211_ADDR_LEN + 2 + 2;
> -
> - cmd_frame->desc_word[0] |= cpu_to_le16(length - FRAME_DESC_SZ);
> - cmd_frame->desc_word[2] |= cpu_to_le16(0);
> +        struct rsi_wowlan_req *cmd_frame;
> +        struct sk_buff *skb;
> +        u8 length;
> +        u8 sourceid[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
> +
> +        ven_rsi_dbg(ERR_ZONE, "%s: Sending wowlan request frame\n",
> __func__);
> +
> +        skb = dev_alloc_skb(sizeof(*cmd_frame));
> +        if (!skb) {
> +                ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
> +                                __func__);
> +                return -ENOMEM;
> +        }
> +        memset(skb->data, 0, sizeof(*cmd_frame));
> +        cmd_frame = (struct rsi_wowlan_req *)skb->data;
> +
> +        cmd_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
> +        cmd_frame->desc_word[1] |= cpu_to_le16(WOWLAN_CONFIG_PARAMS);
> + 
> +        memcpy(cmd_frame->sourceid, &sourceid, IEEE80211_ADDR_LEN);
> +
> +        cmd_frame->host_sleep_status = sleep_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;
>  
> - skb_put(skb, length);
> +        cmd_frame->desc_word[0] |= cpu_to_le16(length - FRAME_DESC_SZ);
> +        cmd_frame->desc_word[2] |= cpu_to_le16(0);
> +  
> +   skb_put(skb, length);
>  
> - return rsi_send_internal_mgmt_frame(common, skb);
> +        return rsi_send_internal_mgmt_frame(common, skb);
>  }
>  #endif
>  
> @@ -2403,6 +2446,7 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8
> *msg)
>  {
>   s32 msg_len = (le16_to_cpu(*(__le16 *)&msg[0]) & 0x0fff);
>   u16 msg_type = msg[2];
> + struct ieee80211_vif *vif = common->priv->vifs[0];
>  
>   switch (msg_type) {
>   case TA_CONFIRM_TYPE:
> @@ -2417,6 +2461,18 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8
> *msg)
>   common->mgmt_q_block = false;
>   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;
>  
>   case PS_NOTIFY_IND:
> @@ -2447,13 +2503,15 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8
> *msg)
>  
>   case BEACON_EVENT_IND:
>   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;
>   if (common->iface_down)
>   return -1;
> - mutex_lock(&common->mutex);
> + if (!common->beacon_enabled)
> + return -1;
>   rsi_send_beacon(common);
> - mutex_unlock(&common->mutex);
> +#endif
>   break;
>  
>   case RX_DOT11_MGMT:
> diff --git a/ubuntu/rsi/rsi_91x_sdio.c b/ubuntu/rsi/rsi_91x_sdio.c
> index 15083e5..9378b36 100644
> --- a/ubuntu/rsi/rsi_91x_sdio.c
> +++ b/ubuntu/rsi/rsi_91x_sdio.c
> @@ -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)) {
> @@ -1110,12 +1112,14 @@ 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)
> +#ifdef CONFIG_SDIO_INTR_POLL
>   if (adapter->rsi_host_intf == RSI_HOST_INTF_SDIO)
> - rsi_kill_thread(&adapter->priv->hci_thread);
> -#endif
> + 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 +1128,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 +1148,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 +1157,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 = {
> diff --git a/ubuntu/rsi/rsi_91x_sdio_ops.c b/ubuntu/rsi/rsi_91x_sdio_ops.c
> index be62d42..7d412f0 100644
> --- a/ubuntu/rsi/rsi_91x_sdio_ops.c
> +++ b/ubuntu/rsi/rsi_91x_sdio_ops.c
> @@ -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;
> diff --git a/ubuntu/rsi/rsi_coex.h b/ubuntu/rsi/rsi_coex.h
> index 027bc77..24b8688 100644
> --- a/ubuntu/rsi/rsi_coex.h
> +++ b/ubuntu/rsi/rsi_coex.h
> @@ -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;
>  };
>  
> diff --git a/ubuntu/rsi/rsi_common.h b/ubuntu/rsi/rsi_common.h
> index 5067af9..47951cf 100644
> --- a/ubuntu/rsi/rsi_common.h
> +++ b/ubuntu/rsi/rsi_common.h
> @@ -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
> diff --git a/ubuntu/rsi/rsi_main.h b/ubuntu/rsi/rsi_main.h
> index 09b9c82..2edb661 100644
> --- a/ubuntu/rsi/rsi_main.h
> +++ b/ubuntu/rsi/rsi_main.h
> @@ -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;
> @@ -287,6 +289,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 +302,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 {
> diff --git a/ubuntu/rsi/rsi_mgmt.h b/ubuntu/rsi/rsi_mgmt.h
> index ece9b40..987f9dc 100644
> --- a/ubuntu/rsi/rsi_mgmt.h
> +++ b/ubuntu/rsi/rsi_mgmt.h
> @@ -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,7 @@ 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);
>  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 +559,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
> -- 
> 2.9.3
>
>

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Loading...