Commit b3a5d2d3 authored by Darren Wu's avatar Darren Wu Committed by Luis Henriques

UBUNTU: SAUCE: Redpine RS9113 WLAN/BT driver ver. 0.9.7

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

This is the beta2 release for RS9113 driver from Redpine
Signed-off-by: default avatarDarren Wu <darren.wu@canonical.com>
Signed-off-by: default avatarShrirang Bagul <shrirang.bagul@canonical.com>
Acked-by: default avatarTim Gardner <tim.gardner@canonical.com>
Acked-by: default avatarBrad Figg <brad.figg@canonical.com>
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
parent 5867572a
EXTRA_CFLAGS += -DCONFIG_DELL_BOARD -DCONFIG_VEN_RSI_COEX -DLINUX -Wimplicit -Wstrict-prototypes -DCONFIG_VEN_RSI_DEBUGFS -DPLATFORM_X86
ven_rsi_91x-y += rsi_91x_main.o
ven_rsi_91x-y += rsi_91x_core.o
ven_rsi_91x-y += rsi_91x_mac80211.o
ven_rsi_91x-y += rsi_91x_mgmt.o
ven_rsi_91x-y += rsi_91x_hal.o
ven_rsi_91x-y += rsi_91x_ps.o
ven_rsi_91x-$(CONFIG_VEN_RSI_DEBUGFS) += rsi_91x_debugfs.o
ven_rsi_91x-y += rsi_91x_debugfs.o
ven_rsi_91x-$(CONFIG_VEN_RSI_HCI) += rsi_91x_hci.o
ven_rsi_91x-$(CONFIG_RSI_COEX) += rsi_91x_coex.o
ven_rsi_91x-y += rsi_91x_hci.o rsi_91x_coex.o
ven_rsi_usb-y += rsi_91x_usb.o rsi_91x_usb_ops.o
ven_rsi_sdio-y += rsi_91x_sdio.o rsi_91x_sdio_ops.o
......
......@@ -16,13 +16,10 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//#include "rsi_common.h"
#include "rsi_main.h"
#include "rsi_coex.h"
#include"rsi_hal.h"
#include "rsi_hal.h"
#include "rsi_mgmt.h"
static u8 rsi_coex_determine_coex_q(struct rsi_coex_ctrl_block *coex_cb)
{
......@@ -49,21 +46,21 @@ static void rsi_coex_sched_tx_pkts(struct rsi_coex_ctrl_block *coex_cb)
while (1) {
coex_q = rsi_coex_determine_coex_q(coex_cb);
rsi_dbg(INFO_ZONE, "queue = %d\n", coex_q);
ven_rsi_dbg(INFO_ZONE, "queue = %d\n", coex_q);
if (coex_q == INVALID_QUEUE) {
rsi_dbg(DATA_TX_ZONE, "No more pkt\n");
ven_rsi_dbg(DATA_TX_ZONE, "No more pkt\n");
break;
}
mutex_lock(&coex_cb->coex_tx_lock);
down(&coex_cb->tx_bus_lock);
if (coex_q == BT_Q) {
skb = skb_dequeue(&coex_cb->coex_tx_qs[BT_Q]);
rsi_send_bt_pkt(coex_cb->priv, skb);
}
mutex_unlock(&coex_cb->coex_tx_lock);
up(&coex_cb->tx_bus_lock);
}
}
......@@ -74,9 +71,11 @@ static void rsi_coex_sched_tx_pkts(struct rsi_coex_ctrl_block *coex_cb)
*
* Return: None.
*/
static void rsi_coex_scheduler_thread(struct rsi_coex_ctrl_block *coex_cb)
static void rsi_coex_scheduler_thread(struct rsi_common *common)
{
struct rsi_common *common = (struct rsi_common *)coex_cb->priv;
struct rsi_coex_ctrl_block *coex_cb =
(struct rsi_coex_ctrl_block *)common->coex_cb;
u32 timeout = EVENT_WAIT_FOREVER;
do {
......@@ -89,8 +88,18 @@ static void rsi_coex_scheduler_thread(struct rsi_coex_ctrl_block *coex_cb)
complete_and_exit(&coex_cb->coex_tx_thread.completion, 0);
}
int rsi_coex_recv_pkt(struct rsi_common *common, struct sk_buff *skb)
int rsi_coex_recv_pkt(struct rsi_common *common, u8 *msg)
{
u16 msg_type = msg[2];
if (msg_type == COMMON_CARD_READY_IND) {
ven_rsi_dbg(INFO_ZONE, "COMMON CARD READY RECEIVED\n");
rsi_handle_card_ready(common);
} else if (msg_type == SLEEP_NOTIFY_IND) {
ven_rsi_dbg(INFO_ZONE, "\n\n sleep notify RECEIVED\n");
rsi_mgmt_pkt_recv(common, msg);
}
return 0;
}
......@@ -98,7 +107,8 @@ int rsi_coex_send_pkt(struct rsi_common *common,
struct sk_buff *skb,
u8 hal_queue)
{
struct rsi_coex_ctrl_block *coex_cb = common->coex_cb;
struct rsi_coex_ctrl_block *coex_cb =
(struct rsi_coex_ctrl_block *)common->coex_cb;
int status = 0;
/* Add pkt to queue if not WLAN packet */
......@@ -108,13 +118,12 @@ int rsi_coex_send_pkt(struct rsi_common *common,
return status;
}
mutex_lock(&coex_cb->coex_tx_lock);
/* Send packet to hal */
if (skb->priority == MGMT_SOFT_Q)
status = rsi_send_mgmt_pkt(common, skb);
else
status = rsi_send_data_pkt(common, skb);
mutex_unlock(&coex_cb->coex_tx_lock);
return 0;
}
......@@ -124,32 +133,30 @@ int rsi_coex_init(struct rsi_common *common)
int cnt;
coex_cb = kzalloc(sizeof(*coex_cb), GFP_KERNEL);
if (!coex_cb) {
rsi_dbg(ERR_ZONE,
"%s: Failed allocate coex control block\n",
__func__);
if (!coex_cb)
return -ENOMEM;
}
common->coex_cb = (void *)coex_cb;
coex_cb->priv = common;
sema_init(&coex_cb->tx_bus_lock, 1);
/* Initialize co-ex queues */
for (cnt = 0; cnt < NUM_COEX_TX_QUEUES; cnt++)
skb_queue_head_init(&coex_cb->coex_tx_qs[cnt]);
mutex_init(&coex_cb->coex_tx_lock);
rsi_init_event(&coex_cb->coex_tx_thread.event);
/* Initialize co-ex thread */
if (rsi_create_kthread(common,
&coex_cb->coex_tx_thread,
rsi_coex_scheduler_thread,
"Coex-Tx-Thread")) {
rsi_dbg(ERR_ZONE, "%s: Unable to init tx thrd\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Unable to init tx thrd\n", __func__);
goto err;
}
return 0;
err:
return -1;
return -EINVAL;
}
void rsi_coex_deinit(struct rsi_common *common)
......@@ -168,6 +175,4 @@ void rsi_coex_deinit(struct rsi_common *common)
/* Free the coex control block */
kfree(coex_cb);
return;
}
......@@ -16,6 +16,10 @@
#include "rsi_mgmt.h"
#include "rsi_common.h"
#include "rsi_hal.h"
#ifdef CONFIG_VEN_RSI_COEX
#include "rsi_coex.h"
#endif
/**
* rsi_determine_min_weight_queue() - This function determines the queue with
......@@ -143,7 +147,7 @@ static u8 rsi_core_determine_hal_queue(struct rsi_common *common)
}
if (common->hw_data_qs_blocked) {
rsi_dbg(INFO_ZONE, "%s: data queue blocked\n", __func__);
ven_rsi_dbg(INFO_ZONE, "%s: data queue blocked\n", __func__);
return q_num;
}
......@@ -214,7 +218,7 @@ static void rsi_core_queue_pkt(struct rsi_common *common,
u8 q_num = skb->priority;
if (q_num >= NUM_SOFT_QUEUES) {
rsi_dbg(ERR_ZONE, "%s: Invalid Queue Number: q_num = %d\n",
ven_rsi_dbg(ERR_ZONE, "%s: Invalid Queue Number: q_num = %d\n",
__func__, q_num);
dev_kfree_skb(skb);
return;
......@@ -235,7 +239,7 @@ static struct sk_buff *rsi_core_dequeue_pkt(struct rsi_common *common,
u8 q_num)
{
if (q_num >= NUM_SOFT_QUEUES) {
rsi_dbg(ERR_ZONE, "%s: Invalid Queue Number: q_num = %d\n",
ven_rsi_dbg(ERR_ZONE, "%s: Invalid Queue Number: q_num = %d\n",
__func__, q_num);
return NULL;
}
......@@ -263,11 +267,11 @@ void rsi_core_qos_processor(struct rsi_common *common)
tstamp_1 = jiffies;
while (1) {
q_num = rsi_core_determine_hal_queue(common);
rsi_dbg(DATA_TX_ZONE,
ven_rsi_dbg(DATA_TX_ZONE,
"%s: Queue number = %d\n", __func__, q_num);
if (q_num == INVALID_QUEUE) {
rsi_dbg(DATA_TX_ZONE, "%s: No More Pkt\n", __func__);
ven_rsi_dbg(DATA_TX_ZONE, "%s: No More Pkt\n", __func__);
break;
}
......@@ -289,15 +293,18 @@ void rsi_core_qos_processor(struct rsi_common *common)
skb = rsi_core_dequeue_pkt(common, q_num);
if (!skb) {
rsi_dbg(ERR_ZONE, "skb null\n");
ven_rsi_dbg(ERR_ZONE, "skb null\n");
mutex_unlock(&common->tx_lock);
break;
}
#ifdef CONFIG_VEN_RSI_COEX
status = rsi_coex_send_pkt(common, skb, RSI_WLAN_Q);
#else
if (q_num == MGMT_SOFT_Q)
status = rsi_send_mgmt_pkt(common, skb);
else
status = rsi_send_data_pkt(common, skb);
#endif
if (status) {
mutex_unlock(&common->tx_lock);
......@@ -314,6 +321,61 @@ void rsi_core_qos_processor(struct rsi_common *common)
}
}
inline char *dot11_pkt_type(__le16 frame_control)
{
if (ieee80211_is_beacon(frame_control))
return "BEACON";
if (ieee80211_is_assoc_req(frame_control))
return "ASSOC_REQ";
if (ieee80211_is_assoc_resp(frame_control))
return "ASSOC_RESP";
if (ieee80211_is_reassoc_req(frame_control))
return "REASSOC_REQ";
if (ieee80211_is_reassoc_resp(frame_control))
return "REASSOC_RESP";
if (ieee80211_is_auth(frame_control))
return "AUTH";
if (ieee80211_is_probe_req(frame_control))
return "PROBE_REQ";
if (ieee80211_is_probe_resp(frame_control))
return "PROBE_RESP";
if (ieee80211_is_disassoc(frame_control))
return "DISASSOC";
if (ieee80211_is_deauth(frame_control))
return "DEAUTH";
if (ieee80211_is_action(frame_control))
return "ACTION";
if (ieee80211_is_data_qos(frame_control))
return "QOS DATA";
if (ieee80211_is_pspoll(frame_control))
return "PS_POLL";
if (ieee80211_is_nullfunc(frame_control))
return "NULL_DATA";
if (ieee80211_is_qos_nullfunc(frame_control))
return "QOS_NULL_DATA";
if (ieee80211_is_mgmt(frame_control))
return "DOT11_MGMT";
if (ieee80211_is_data(frame_control))
return "DOT11_DATA";
if (ieee80211_is_ctl(frame_control))
return "DOT11_CTRL";
return "UNKNOWN";
}
struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr)
{
int i;
for (i = 0; i < common->num_stations; i++) {
if (!(memcmp(common->stations[i].sta->addr,
mac_addr, ETH_ALEN)))
return &common->stations[i];
}
return NULL;
}
/**
* rsi_core_xmit() - This function transmits the packets received from mac80211
* @common: Pointer to the driver private structure.
......@@ -326,62 +388,114 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
struct rsi_hw *adapter = common->priv;
struct ieee80211_tx_info *info;
struct skb_info *tx_params;
struct ieee80211_hdr *tmp_hdr = NULL;
struct ieee80211_hdr *wlh = NULL;
struct ieee80211_vif *vif = adapter->vifs[0];
u8 q_num, tid = 0;
if ((!skb) || (!skb->len)) {
rsi_dbg(ERR_ZONE, "%s: Null skb/zero Length packet\n",
ven_rsi_dbg(ERR_ZONE, "%s: Null skb/zero Length packet\n",
__func__);
goto xmit_fail;
}
if (common->fsm_state != FSM_MAC_INIT_DONE) {
rsi_dbg(ERR_ZONE, "%s: FSM state not open\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: FSM state not open\n", __func__);
goto xmit_fail;
}
info = IEEE80211_SKB_CB(skb);
tx_params = (struct skb_info *)info->driver_data;
tmp_hdr = (struct ieee80211_hdr *)&skb->data[0];
wlh = (struct ieee80211_hdr *)&skb->data[0];
if ((ieee80211_is_mgmt(tmp_hdr->frame_control)) ||
(ieee80211_is_ctl(tmp_hdr->frame_control)) ||
(ieee80211_is_qos_nullfunc(tmp_hdr->frame_control))) {
if ((ieee80211_is_mgmt(wlh->frame_control)) ||
(ieee80211_is_ctl(wlh->frame_control)) ||
(ieee80211_is_qos_nullfunc(wlh->frame_control))) {
q_num = MGMT_SOFT_Q;
skb->priority = q_num;
if (ieee80211_is_probe_req(tmp_hdr->frame_control)) {
rsi_dbg(MGMT_TX_ZONE, "%s: Probe Request\n", __func__);
if (is_broadcast_ether_addr(tmp_hdr->addr1)) {
rsi_dbg(INFO_ZONE, "%s: Probe request backup\n", __func__);
memcpy(common->bgscan_probe_req, skb->data, skb->len);
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)) {
if ((is_broadcast_ether_addr(wlh->addr1)) &&
(skb->data[MIN_802_11_HDR_LEN + 1] == 0)) {
memcpy(common->bgscan_probe_req,
skb->data, skb->len);
common->bgscan_probe_req_len = skb->len;
}
} else if (ieee80211_is_auth(tmp_hdr->frame_control))
rsi_dbg(MGMT_TX_ZONE, "%s: Auth Request\n", __func__);
else if (ieee80211_is_assoc_req(tmp_hdr->frame_control))
rsi_dbg(MGMT_TX_ZONE, "%s: Assoc Request\n", __func__);
else
rsi_dbg(MGMT_TX_ZONE, "%s: pkt_type=%04x\n",
__func__, tmp_hdr->frame_control);
}
if (rsi_prepare_mgmt_desc(common, skb)) {
ven_rsi_dbg(ERR_ZONE, "Failed to prepeare desc\n");
goto xmit_fail;
}
} else {
rsi_dbg(DATA_TX_ZONE, "%s: Data Packet\n", __func__);
if (ieee80211_is_data_qos(tmp_hdr->frame_control)) {
tid = (skb->data[24] & IEEE80211_QOS_TID);
struct rsi_sta *sta = NULL;
ven_rsi_dbg(INFO_ZONE, "Core: TX Data Packet\n");
rsi_hex_dump(DATA_TX_ZONE, "TX Data Packet",
skb->data, skb->len);
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);
if ((vif->type == NL80211_IFTYPE_AP) &&
(!is_broadcast_ether_addr(wlh->addr1)) &&
(!is_multicast_ether_addr(wlh->addr1))) {
sta = rsi_find_sta(common, wlh->addr1);
if (!sta)
goto xmit_fail;
}
} 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)) {
sta = rsi_find_sta(common, wlh->addr1);
if (!sta)
goto xmit_fail;
}
}
q_num = skb->priority;
tx_params->tid = tid;
if (sta) {
wlh->seq_ctrl =
cpu_to_le16((sta->seq_no[skb->priority] << 4) &
IEEE80211_SCTL_SEQ);
sta->seq_no[skb->priority] =
(sta->seq_no[skb->priority] + 1) % IEEE80211_MAX_SN;
tx_params->sta_id = sta->sta_id;
} else {
if (vif->type == NL80211_IFTYPE_AP) {
wlh->seq_ctrl =
cpu_to_le16((common->bc_mc_seqno << 4) &
IEEE80211_SCTL_SEQ);
common->bc_mc_seqno =
(common->bc_mc_seqno + 1) % IEEE80211_MAX_SN;
}
tx_params->sta_id = 0;
}
#ifdef EAPOL_IN_MGMT_Q
if (skb->protocol == cpu_to_le16(ETH_P_PAE)) {
q_num = MGMT_SOFT_Q;
skb->priority = q_num;
}
#endif
if (rsi_prepare_data_desc(common, skb)) {
ven_rsi_dbg(ERR_ZONE, "Failed to prepare data desc\n");
goto xmit_fail;
}
}
if ((q_num != MGMT_SOFT_Q) &&
((skb_queue_len(&common->tx_queue[q_num]) + 1) >=
DATA_QUEUE_WATER_MARK)) {
rsi_dbg(ERR_ZONE, "%s: sw queue full\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: sw queue full\n", __func__);
if (!ieee80211_queue_stopped(adapter->hw, WME_AC(q_num)))
ieee80211_stop_queue(adapter->hw, WME_AC(q_num));
rsi_set_event(&common->tx_thread.event);
......@@ -389,13 +503,13 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
}
rsi_core_queue_pkt(common, skb);
rsi_dbg(DATA_TX_ZONE, "%s: ===> Scheduling TX thead <===\n", __func__);
ven_rsi_dbg(DATA_TX_ZONE, "%s: ===> Scheduling TX thead <===\n", __func__);
rsi_set_event(&common->tx_thread.event);
return;
xmit_fail:
rsi_dbg(ERR_ZONE, "%s: Failed to queue packet\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Failed to queue packet\n", __func__);
/* Dropping pkt here */
ieee80211_free_txskb(common->priv->hw, skb);
}
......@@ -206,9 +206,9 @@ static int rsi_stats_open(struct inode *inode,
*/
static int rsi_debug_zone_read(struct seq_file *seq, void *data)
{
rsi_dbg(FSM_ZONE, "%x: rsi_enabled zone", rsi_zone_enabled);
ven_rsi_dbg(FSM_ZONE, "%x: rsi_enabled zone", ven_rsi_zone_enabled);
seq_printf(seq, "The zones available are %#x\n",
rsi_zone_enabled);
ven_rsi_zone_enabled);
return 0;
}
......@@ -252,7 +252,7 @@ static ssize_t rsi_debug_zone_write(struct file *filp,
if (ret)
return ret;
rsi_zone_enabled = dbg_zone;
ven_rsi_zone_enabled = dbg_zone;
return len;
}
......@@ -280,8 +280,13 @@ static int rsi_bgscan_int_read(struct seq_file *file, void *data)
params->two_probe,
params->num_bg_channels);
for (cnt = 0; cnt < params->num_bg_channels; cnt++)
for (cnt = 0; cnt < params->num_bg_channels; cnt++) {
if (params->channels2scan[cnt] & (BIT(15)))
seq_printf(file, "%d[DFS] ",
(params->channels2scan[cnt] & 0x7FFF));
else
seq_printf(file, "%d ", params->channels2scan[cnt]);
}
seq_printf(file, "\n");
return 0;
......@@ -334,20 +339,26 @@ static ssize_t rsi_bgscan_write(struct file *file,
if (!g_bgscan_enable) {
/* return here if bgscan is already disabled */
if (!common->bgscan_en) {
rsi_dbg(ERR_ZONE, "bgscan already disabled\n");
#ifdef PLATFORM_X86
ven_rsi_dbg(ERR_ZONE, "bgscan already disabled\n");
#endif
return total_bytes;
}
mutex_lock(&common->mutex);
if (bss->assoc && !rsi_send_bgscan_params(common, 0)) {
rsi_dbg(ERR_ZONE, "*** bgscan disabled ***\n");
#ifdef PLATFORM_X86
ven_rsi_dbg(ERR_ZONE, "*** bgscan disabled ***\n");
#endif
common->bgscan_en = 0;
}
mutex_unlock(&common->mutex);
return total_bytes;
} else if (common->bgscan_en) {
rsi_dbg(ERR_ZONE, "bgscan already enabled\n");
#ifdef PLATFORM_X86
ven_rsi_dbg(ERR_ZONE, "bgscan already enabled\n");
#endif
return total_bytes;
}
......@@ -373,29 +384,39 @@ static ssize_t rsi_bgscan_write(struct file *file,
common->bgscan_info.active_scan_duration = bgscan_vals[3];
common->bgscan_info.passive_scan_duration = bgscan_vals[4];
common->bgscan_info.two_probe = bgscan_vals[5];
common->bgscan_info.num_bg_channels = bgscan_vals[6];
for (cnt = 0; cnt < common->bgscan_info.num_bg_channels; cnt++)
common->bgscan_info.channels2scan[cnt] = bgscan_vals[7 + cnt];
rsi_dbg(INFO_ZONE,
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 =
((bgscan_vals[6] > MAX_BGSCAN_CHANNELS) ?
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];
#ifdef PLATFORM_X86
ven_rsi_dbg(INFO_ZONE,
"bgscan_count = %d, roam_count = %d, periodicity = %d\n",
common->bgscan_info.bgscan_threshold,
common->bgscan_info.roam_threshold,
common->bgscan_info.bgscan_periodicity);
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"active_scan_dur = %d, passive_scan_dur = %d, two_probe = %d\n",
common->bgscan_info.active_scan_duration,
common->bgscan_info.passive_scan_duration,
common->bgscan_info.two_probe);
rsi_dbg(INFO_ZONE, "Number of scan channels = %d\n",
common->bgscan_info.num_bg_channels);
ven_rsi_dbg(INFO_ZONE, "Number of scan channels = %d\n",
common->bgscan_info.num_user_channels);
rsi_hex_dump(INFO_ZONE, "bgscan channels",
(u8 *)common->bgscan_info.channels2scan,
common->bgscan_info.num_bg_channels * 2);
(u8 *)common->bgscan_info.user_channels,
common->bgscan_info.num_user_channels * 2);
#endif
/* If connection is not done don't send bgscan params */
if (!bss->assoc) {
rsi_dbg(INFO_ZONE, "Station not connected; skip now\n");
#ifdef PLATFORM_X86
ven_rsi_dbg(INFO_ZONE, "Station not connected; skip now\n");
#endif
return total_bytes;
}
......@@ -403,15 +424,23 @@ static ssize_t rsi_bgscan_write(struct file *file,
mutex_lock(&common->mutex);
if (!rsi_send_bgscan_params(common, 1)) {
if (!rsi_send_bgscan_probe_req(common)) {
rsi_dbg(INFO_ZONE, "Background scan started ===>\n");
#ifdef PLATFORM_X86
ven_rsi_dbg(INFO_ZONE, "Background scan started ===>\n");
#endif
common->bgscan_en = 1;
} else {
rsi_dbg(ERR_ZONE, "Failed sending bgscan probe req\n");
#ifdef PLATFORM_X86
ven_rsi_dbg(ERR_ZONE, "Failed sending bgscan probe req\n");
#endif
common->bgscan_en = 0;
g_bgscan_enable = 0;
}
} else
rsi_dbg(ERR_ZONE, "Failed sending bgscan params req\n");
} else {
#ifdef PLATFORM_X86
ven_rsi_dbg(ERR_ZONE, "Failed sending bgscan params req\n");
#endif
}
mutex_unlock(&common->mutex);
return total_bytes;
......
......@@ -25,6 +25,12 @@
#include "rsi_hal.h"
#include "rsi_sdio.h"
#include "rsi_common.h"
#if defined(CONFIG_VEN_RSI_COEX) || defined(CONFIG_VEN_RSI_HCI)
#include "rsi_hci.h"
#endif
#ifdef CONFIG_VEN_RSI_COEX
#include "rsi_coex.h"
#endif
/* FLASH Firmware */
struct ta_metadata metadata_flash_content[] = {
......@@ -37,20 +43,49 @@ struct ta_metadata metadata_flash_content[] = {
};
/**
* rsi_send_data_pkt() - This function sends the received data packet from
* rsi_send_pkt() - This function sends the received packet from
* driver to device.
* @common: Pointer to the driver private structure.
* @skb: Pointer to the socket buffer structure.
*
* Return: status: 0 on success, -1 on failure.
*/
int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
int rsi_send_pkt(struct rsi_common *common, struct sk_buff *skb)
{
struct rsi_hw *adapter = common->priv;
#ifdef CONFIG_VEN_RSI_COEX
struct rsi_coex_ctrl_block *coex_cb =
(struct rsi_coex_ctrl_block *)common->coex_cb;
#endif
int status = -EINVAL;
#ifdef CONFIG_VEN_RSI_COEX
down(&coex_cb->tx_bus_lock);
#endif
status = adapter->host_intf_ops->write_pkt(common->priv,
skb->data, skb->len);
#ifdef CONFIG_VEN_RSI_COEX
up(&coex_cb->tx_bus_lock);
#endif
return status;
}
/**
* rsi_prepare_data_desc() - This function prepares the device specific descriptor
* for the given data packet
*
* @common: Pointer to the driver private structure.
* @skb: Pointer to the socket buffer structure.
*
* Return: status: 0 on success, negative error code on failure.
*/
int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
{
struct rsi_hw *adapter = common->priv;
struct ieee80211_vif *vif = adapter->vifs[0];
struct ieee80211_hdr *wh = NULL;
struct ieee80211_tx_info *info;
struct skb_info *tx_params;
struct ieee80211_bss_conf *bss = NULL;
int status = -EINVAL;
u8 ieee80211_hdr_size = MIN_802_11_HDR_LEN;
u8 dword_align_bytes = 0;
......@@ -60,28 +95,31 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
u16 seq_num = 0;
info = IEEE80211_SKB_CB(skb);
bss = &info->control.vif->bss_conf;
tx_params = (struct skb_info *)info->driver_data;
if (!bss->assoc)
header_size = FRAME_DESC_SZ + sizeof(struct xtended_desc);
if (header_size > skb_headroom(skb)) {
ven_rsi_dbg(ERR_ZONE, "%s: Not enough headroom\n", __func__);
status = -ENOSPC;
goto err;
dword_align_bytes = ((uintptr_t)skb->data & 0x3f);
header_size = dword_align_bytes + FRAME_DESC_SZ +
sizeof(struct xtended_desc);
}
skb_push(skb, header_size);
dword_align_bytes = ((unsigned long)skb->data & 0x3f);
if (header_size > skb_headroom(skb)) {
rsi_dbg(ERR_ZONE, "%s: Not enough headroom\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Not enough headroom\n", __func__);
status = -ENOSPC;
goto err;
}
skb_push(skb, dword_align_bytes);
header_size += dword_align_bytes;
skb_push(skb, header_size);
tx_params->internal_hdr_size = header_size;
frame_desc = (__le16 *)&skb->data[0];
xtend_desc = (struct xtended_desc *)&skb->data[FRAME_DESC_SZ];
memset((u8 *)frame_desc, 0, header_size);
wh = (struct ieee80211_hdr *)&skb->data[header_size];
seq_num = (le16_to_cpu(wh->seq_ctrl) >> 4);
seq_num = le16_to_cpu(IEEE80211_SEQ_TO_SN(wh->seq_ctrl));
frame_desc[2] = cpu_to_le16(header_size - FRAME_DESC_SZ);
if (ieee80211_is_data_qos(wh->frame_control)) {
......@@ -89,7 +127,8 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
frame_desc[6] |= cpu_to_le16(BIT(12));
}
if (adapter->ps_state == PS_ENABLED)
if ((vif->type == NL80211_IFTYPE_STATION) &&
(adapter->ps_state == PS_ENABLED))
wh->frame_control |= BIT(12);
if ((!(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) &&
......@@ -120,23 +159,40 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
}
if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
rsi_dbg(INFO_ZONE, "*** Tx EAPOL ***\n");
ven_rsi_dbg(INFO_ZONE, "*** Tx EAPOL ***\n");
frame_desc[6] |= cpu_to_le16(BIT(13));
frame_desc[1] |= cpu_to_le16(BIT(12));
#define EAPOL_RETRY_CNT 15
xtend_desc->retry_cnt = EAPOL_RETRY_CNT;
#ifdef EAPOL_IN_MGMT_Q
skb->priority = VO_Q;
#endif
}
frame_desc[6] |= cpu_to_le16(seq_num & 0xfff);
frame_desc[6] |= cpu_to_le16(seq_num);
frame_desc[7] = cpu_to_le16(((tx_params->tid & 0xf) << 4) |
(skb->priority & 0xf) |
(tx_params->sta_id << 8));
rsi_hex_dump(DATA_TX_ZONE, "TX data pkt", skb->data, skb->len);
status = adapter->host_intf_ops->write_pkt(common->priv,
skb->data, skb->len);
if (status)
rsi_dbg(ERR_ZONE, "%s: Failed to write data pkt\n", __func__);
if ((is_broadcast_ether_addr(wh->addr1)) ||
(is_multicast_ether_addr(wh->addr1))) {
frame_desc[3] = cpu_to_le16(RATE_INFO_ENABLE);
frame_desc[3] |= cpu_to_le16(RSI_BROADCAST_PKT);
#if 0
if (common->min_rate == 0xffff) {
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) &&
(ieee80211_has_moredata(wh->frame_control)))
frame_desc[3] |= cpu_to_le16(MORE_DATA_PRESENT);
return 0;
err:
++common->tx_stats.total_tx_pkt_freed[skb->priority];
......@@ -145,70 +201,62 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
}
/**
* rsi_send_mgmt_pkt() - This functions prepares the descriptor for
* the given management packet and send to device.
* rsi_prepare_mgmt_desc() - This functions prepares the descriptor for
* the given management packet.
*
* @common: Pointer to the driver private structure.
* @skb: Pointer to the socket buffer structure.
*
* Return: status: 0 on success, -1 on failure.
*/
int rsi_send_mgmt_pkt(struct rsi_common *common,
struct sk_buff *skb)
int rsi_prepare_mgmt_desc(struct rsi_common *common,struct sk_buff *skb)
{
struct rsi_hw *adapter = common->priv;
struct ieee80211_hdr *wh = NULL;
struct ieee80211_tx_info *info;
struct ieee80211_bss_conf *bss = NULL;
struct ieee80211_hw *hw = adapter->hw;
struct ieee80211_conf *conf = &hw->conf;
struct ieee80211_conf *conf = &adapter->hw->conf;
struct ieee80211_vif *vif = adapter->vifs[0];
struct skb_info *tx_params;
int status = -E2BIG;
int status = -EINVAL;
__le16 *desc = NULL;
struct xtended_desc *xtend_desc = NULL;
u8 header_size = 0;
u8 vap_id = 0;
u32 dword_align_req_bytes = 0;
u32 dword_align_bytes = 0;
info = IEEE80211_SKB_CB(skb);
tx_params = (struct skb_info *)info->driver_data;
if (tx_params->flags & INTERNAL_MGMT_PKT) {
skb->data[1] |= BIT(7); /* Immediate Wakeup bit*/
rsi_hex_dump(MGMT_TX_ZONE,
"Tx Command Packet",
skb->data, skb->len);
status = adapter->host_intf_ops->write_pkt(common->priv,
(u8 *)skb->data,
skb->len);
if (status) {
rsi_dbg(ERR_ZONE,
"%s: Failed to write the packet\n",
__func__);
}
dev_kfree_skb(skb);
return status;
}
/* Update header size */
header_size = FRAME_DESC_SZ + sizeof(struct xtended_desc) +
dword_align_req_bytes;
header_size = FRAME_DESC_SZ + sizeof(struct xtended_desc);
if (header_size > skb_headroom(skb)) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to add extended descriptor\n",
__func__);
status = -ENOSPC;
goto err;
}
skb_push(skb, header_size);
dword_align_bytes = ((unsigned long)skb->data & 0x3f);
if (dword_align_bytes > skb_headroom(skb)) {
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to add dword align\n", __func__);
status = -ENOSPC;
goto err;
}
skb_push(skb, dword_align_bytes);
header_size += dword_align_bytes;
tx_params->internal_hdr_size = header_size;
memset(&skb->data[0], 0, header_size);
bss = &info->control.vif->bss_conf;
wh = (struct ieee80211_hdr *)&skb->data[header_size];
desc = (__le16 *)skb->data;
xtend_desc = (struct xtended_desc *)&skb->data[FRAME_DESC_SZ];
if (skb->len > MAX_MGMT_PKT_SIZE) {
rsi_dbg(INFO_ZONE, "%s: Dropping mgmt pkt > 512\n", __func__);
ven_rsi_dbg(INFO_ZONE, "%s: Dropping mgmt pkt > 512\n", __func__);
goto err;
}
......@@ -220,7 +268,7 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
desc[3] = cpu_to_le16(RATE_INFO_ENABLE);
if (wh->addr1[0] & BIT(0))
desc[3] |= cpu_to_le16(RSI_BROADCAST_PKT);
desc[6] = cpu_to_le16(le16_to_cpu(wh->seq_ctrl) >> 4);
desc[6] = cpu_to_le16(IEEE80211_SEQ_TO_SN(wh->seq_ctrl));
if (common->band == NL80211_BAND_2GHZ)
desc[4] = cpu_to_le16(RSI_11B_MODE);
......@@ -228,17 +276,135 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
desc[4] = cpu_to_le16((RSI_RATE_6 & 0x0f) | RSI_11G_MODE);
if (conf_is_ht40(conf)) {
desc[5] = cpu_to_le16(0x6);
desc[5] = cpu_to_le16(FULL40M_ENABLE);
}
if (ieee80211_is_probe_resp(wh->frame_control)) {
desc[1] |= cpu_to_le16(ADD_DELTA_TSF_VAP_ID |
FETCH_RETRY_CNT_FRM_HST);
#define PROBE_RESP_RETRY_CNT 3
xtend_desc->retry_cnt = PROBE_RESP_RETRY_CNT;
}
if ((vif->type == NL80211_IFTYPE_AP) &&
(ieee80211_is_action(wh->frame_control))) {
struct rsi_sta *sta = rsi_find_sta(common, wh->addr1);
if (sta)
desc[7] |= cpu_to_le16(sta->sta_id << 8);
else
goto err;
} else
desc[7] |= cpu_to_le16(vap_id << 8); /* Station ID */
desc[4] |= cpu_to_le16(vap_id << 14);
return 0;
err:
return status;
}
/**
* rsi_send_data_pkt() - This function sends the received data packet from
* driver to device.
* @common: Pointer to the driver private structure.
* @skb: Pointer to the socket buffer structure.
*
* Return: status: 0 on success, -1 on failure.
*/
int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
{
struct rsi_hw *adapter = common->priv;
struct ieee80211_vif *vif = adapter->vifs[0];
struct ieee80211_hdr *wh = NULL;
struct ieee80211_tx_info *info;
struct skb_info *tx_params;
struct ieee80211_bss_conf *bss = NULL;
int status = -EINVAL;
u8 header_size = 0;
info = IEEE80211_SKB_CB(skb);
bss = &info->control.vif->bss_conf;
tx_params = (struct skb_info *)info->driver_data;
header_size = tx_params->internal_hdr_size;
wh = (struct ieee80211_hdr *)&skb->data[header_size];
if (vif->type == NL80211_IFTYPE_STATION) {
if (!bss->assoc)
goto err;
if (!ether_addr_equal(wh->addr1, bss->bssid))
goto err;
}
ven_rsi_dbg(INFO_ZONE, "hal: Sending data pkt");
rsi_hex_dump(DATA_TX_ZONE, "TX data pkt", skb->data, skb->len);
status = rsi_send_pkt(common, skb);
if (status)
ven_rsi_dbg(ERR_ZONE, "%s: Failed to write data pkt\n", __func__);
err:
++common->tx_stats.total_tx_pkt_freed[skb->priority];
rsi_indicate_tx_status(common->priv, skb, status);
return status;
}
/**
* rsi_send_mgmt_pkt() - This function prepares sends the given mgmt packet
* to device.
*
* @common: Pointer to the driver private structure.
* @skb: Pointer to the socket buffer structure.
*
* Return: status: 0 on success, -1 on failure.
*/
int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb)
{
struct rsi_hw *adapter = common->priv;
struct ieee80211_hdr *wh = NULL;
struct ieee80211_tx_info *info;
struct skb_info *tx_params;
u8 header_size = 0;
int status = -EINVAL;
struct ieee80211_bss_conf *bss = NULL;
__le16 *desc = NULL;
struct xtended_desc *xtend_desc = NULL;
info = IEEE80211_SKB_CB(skb);
tx_params = (struct skb_info *)info->driver_data;
header_size = tx_params->internal_hdr_size;
if (tx_params->flags & INTERNAL_MGMT_PKT) {
skb->data[1] |= BIT(7); /* Immediate Wakeup bit*/
rsi_hex_dump(MGMT_TX_ZONE,
"Tx Command Packet",
skb->data, skb->len);
status = rsi_send_pkt(common, skb);
if (status) {
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to write the packet\n",
__func__);
}
dev_kfree_skb(skb);
return status;
}
bss = &info->control.vif->bss_conf;
wh = (struct ieee80211_hdr *)&skb->data[header_size];
desc = (__le16 *)skb->data;
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 (!bss->assoc) {
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;
rsi_dbg(INFO_ZONE, "Mgmt queue blocked\n");
ven_rsi_dbg(INFO_ZONE, "Mgmt queue blocked\n");
} else if (common->bgscan_en) {
/* Drop off channel probe request */
if (common->mac80211_cur_channel !=
......@@ -251,30 +417,22 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
return 0;
}
}
rsi_dbg(MGMT_TX_ZONE, "Sending PROBE REQUEST =====>\n");
} else if (ieee80211_is_auth(wh->frame_control))
rsi_dbg(MGMT_TX_ZONE, "Sending AUTH REQUEST ======>\n");
else if (ieee80211_is_assoc_req(wh->frame_control))
rsi_dbg(MGMT_TX_ZONE, "Sending ASSOC REQUEST ======>\n");
else
rsi_dbg(MGMT_TX_ZONE,
"Sending Packet Type = %04x =====>\n",
wh->frame_control);
ven_rsi_dbg(MGMT_TX_ZONE, "Sending PROBE REQUEST =====>\n");
}
desc[7] |= cpu_to_le16(vap_id << 8); /* Station ID */
desc[4] |= cpu_to_le16(vap_id << 14);
ven_rsi_dbg(MGMT_TX_ZONE,
"Sending Packet : %s =====>\n",
dot11_pkt_type(wh->frame_control));
rsi_hex_dump(MGMT_TX_ZONE, "Tx Mgmt Packet", skb->data, skb->len);
status = adapter->host_intf_ops->write_pkt(common->priv,
(u8 *)desc,
skb->len);
status = rsi_send_pkt(common, skb);
if (status) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to write the packet\n",
__func__);
}
err:
rsi_indicate_tx_status(common->priv, skb, status);
return status;
}
......@@ -288,7 +446,7 @@ int rsi_send_bt_pkt(struct rsi_common *common, struct sk_buff *skb)
header_size = FRAME_DESC_SZ;
if (header_size > skb_headroom(skb)) {
rsi_dbg(ERR_ZONE, "%s: Not enough headroom\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Not enough headroom\n", __func__);
status = -ENOSPC;
goto err;
}
......@@ -297,7 +455,7 @@ int rsi_send_bt_pkt(struct rsi_common *common, struct sk_buff *skb)
memset((u8 *)frame_desc, 0, header_size);
frame_desc[0] = cpu_to_le16(skb->len - FRAME_DESC_SZ);
frame_desc[0] |= (cpu_to_le16 (RSI_BT_DATA_Q )& 0x7) << 12;
frame_desc[0] |= (cpu_to_le16(RSI_BT_DATA_Q) & 0x7) << 12;
frame_desc[7] = cpu_to_le16(bt_cb(skb)->pkt_type);
......@@ -305,13 +463,82 @@ int rsi_send_bt_pkt(struct rsi_common *common, struct sk_buff *skb)
status = adapter->host_intf_ops->write_pkt(common->priv,
skb->data, skb->len);
if (status)
rsi_dbg(ERR_ZONE, "%s: Failed to write bt pkt\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Failed to write bt pkt\n", __func__);
err:
dev_kfree_skb(skb);
return status;
}
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;
struct ieee80211_hw *hw = common->priv->hw;
struct ieee80211_conf *conf = &hw->conf;
u8 vap_id = 0;
u8 dword_align_bytes = 0;
u8 header_size = 0;
skb = dev_alloc_skb(FRAME_DESC_SZ + bcn_len + 64);
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);
common->beacon_cnt++;
bcn_frm = (struct rsi_mac_frame *)skb->data;
bcn_frm->desc_word[0] = cpu_to_le16(bcn_len | (RSI_WIFI_DATA_Q << 12));
bcn_frm->desc_word[1] = 0; // FIXME: Fill type later
bcn_frm->desc_word[2] = cpu_to_le16((MIN_802_11_HDR_LEN << 8) |
dword_align_bytes);
bcn_frm->desc_word[3] = cpu_to_le16(MAC_BBP_INFO | NO_ACK_IND |
BEACON_FRAME | INSERT_TSF |
INSERT_SEQ_NO);
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);
} else if (conf_is_ht40_minus(conf)) {
bcn_frm->desc_word[5] = cpu_to_le16(UPPER_20_ENABLE);
bcn_frm->desc_word[5] |= cpu_to_le16(UPPER_20_ENABLE >> 12);
}
if (common->band == NL80211_BAND_2GHZ)
bcn_frm->desc_word[4] |= cpu_to_le16(0xB | RSI_11G_MODE);
else
bcn_frm->desc_word[4] |= cpu_to_le16(RSI_11B_MODE);
//if (!(common->beacon_cnt % common->dtim_cnt))
if (1) //FIXME check this
bcn_frm->desc_word[3] |= cpu_to_le16(DTIM_BEACON);
memcpy(&skb->data[header_size], common->beacon_frame, bcn_len);
skb_put(skb, bcn_len + header_size);
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) {
ven_rsi_dbg(ERR_ZONE, "Failed to send Beacon\n");
goto err;
}
return 0;
err:
dev_kfree_skb(skb);
return -1;
}
/**
* bl_cmd_timeout() - This function is called when BL command timed out
* @priv: Pointer to the hardware structure.
......@@ -385,7 +612,7 @@ int bl_write_cmd(struct rsi_hw *adapter, u8 cmd, u8 exp_resp, u16 *cmd_resp)
SWBL_REGIN,
&regin_val,
2) < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Command %0x REGIN reading failed..\n",
__func__, cmd);
goto fail;
......@@ -395,13 +622,13 @@ int bl_write_cmd(struct rsi_hw *adapter, u8 cmd, u8 exp_resp, u16 *cmd_resp)
break;
}
if (adapter->blcmd_timer_expired) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Command %0x REGIN reading timed out..\n",
__func__, cmd);
goto fail;
}
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"Issuing write to Regin regin_val:%0x sending cmd:%0x\n",
regin_val, (cmd | regin_input << 8));
if ((hif_ops->master_reg_write(adapter,
......@@ -425,7 +652,7 @@ int bl_write_cmd(struct rsi_hw *adapter, u8 cmd, u8 exp_resp, u16 *cmd_resp)
SWBL_REGOUT,
&regout_val,
2) < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Command %0x REGOUT reading failed..\n",
__func__, cmd);
goto fail;
......@@ -435,7 +662,7 @@ int bl_write_cmd(struct rsi_hw *adapter, u8 cmd, u8 exp_resp, u16 *cmd_resp)
break;
}
if (adapter->blcmd_timer_expired) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Command %0x REGOUT reading timed out..\n",
__func__, cmd);
goto fail;
......@@ -445,12 +672,12 @@ int bl_write_cmd(struct rsi_hw *adapter, u8 cmd, u8 exp_resp, u16 *cmd_resp)
output = ((u8 *)&regout_val)[0] & 0xff;
rsi_dbg(INFO_ZONE, "Invalidating regout\n");
ven_rsi_dbg(INFO_ZONE, "Invalidating regout\n");
if ((hif_ops->master_reg_write(adapter,
SWBL_REGOUT,
(cmd | REGOUT_INVALID << 8),
2)) < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Command %0x REGOUT writing failed..\n",
__func__, cmd);
goto fail;
......@@ -458,11 +685,11 @@ int bl_write_cmd(struct rsi_hw *adapter, u8 cmd, u8 exp_resp, u16 *cmd_resp)
mdelay(1);
if (output == exp_resp) {
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"%s: Recvd Expected resp %x for cmd %0x\n",
__func__, output, cmd);
} else {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Recvd resp %x for cmd %0x\n",
__func__, output, cmd);
goto fail;
......@@ -487,7 +714,7 @@ int bl_cmd(struct rsi_hw *adapter, u8 cmd, u8 exp_resp, char *str)
u16 regout_val = 0;
u32 timeout = 0;
rsi_dbg(INFO_ZONE, "Issuing cmd: \"%s\"\n", str);
ven_rsi_dbg(INFO_ZONE, "Issuing cmd: \"%s\"\n", str);
if ((cmd == EOF_REACHED) || (cmd == PING_VALID) || (cmd == PONG_VALID))
timeout = BL_BURN_TIMEOUT;
......@@ -496,7 +723,7 @@ int bl_cmd(struct rsi_hw *adapter, u8 cmd, u8 exp_resp, char *str)
bl_start_cmd_timer(adapter, timeout);
if (bl_write_cmd(adapter, cmd, exp_resp, &regout_val) < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Command %s (%0x) writing failed..\n",
__func__, str, cmd);
goto fail;
......@@ -542,7 +769,7 @@ static int bl_write_header(struct rsi_hw *adapter,
write_addr,
(u8 *)&bl_hdr,
write_len)) < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to load Version/CRC structure\n",
__func__);
goto fail;
......@@ -550,7 +777,7 @@ static int bl_write_header(struct rsi_hw *adapter,
} else {
write_addr = PING_BUFFER_ADDRESS >> 16;
if ((hif_ops->master_access_msword(adapter, write_addr)) < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Unable to set ms word to common reg\n",
__func__);
goto fail;
......@@ -561,7 +788,7 @@ static int bl_write_header(struct rsi_hw *adapter,
write_addr,
(u8 *)&bl_hdr,
write_len)) < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to load Version/CRC structure\n",
__func__);
goto fail;
......@@ -586,12 +813,12 @@ static u32 read_flash_capacity(struct rsi_hw *adapter)
if ((adapter->host_intf_ops->master_reg_read(adapter,
FLASH_SIZE_ADDR,
&flash_sz, 2)) < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Flash size reading failed..\n",
__func__);
return 0;
}
rsi_dbg(INIT_ZONE, "Flash capacity: %d KiloBytes\n", flash_sz);
ven_rsi_dbg(INIT_ZONE, "Flash capacity: %d KiloBytes\n", flash_sz);
return (flash_sz * 1024); /* Return size in kbytes */
}
......@@ -636,7 +863,7 @@ static int ping_pong_write(struct rsi_hw *adapter, u8 cmd, u8 *addr, u32 size)
size,
block_size,
addr)) {
rsi_dbg(ERR_ZONE, "%s: Unable to write blk at addr %0x\n",
ven_rsi_dbg(ERR_ZONE, "%s: Unable to write blk at addr %0x\n",
__func__, *addr);
goto fail;
}
......@@ -672,7 +899,7 @@ static int auto_fw_upgrade(struct rsi_hw *adapter,
temp_flash_content = flash_content;
if (content_size > MAX_FLASH_FILE_SIZE) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Flash Content size is more than 400K %u\n",
__func__, MAX_FLASH_FILE_SIZE);
goto fail;
......@@ -680,24 +907,24 @@ static int auto_fw_upgrade(struct rsi_hw *adapter,
flash_start_address = cpu_to_le32(
*(u32 *)&flash_content[FLASHING_START_ADDRESS]);
rsi_dbg(INFO_ZONE, "flash start address: %08x\n", flash_start_address);
ven_rsi_dbg(INFO_ZONE, "flash start address: %08x\n", flash_start_address);
if (flash_start_address < FW_IMAGE_MIN_ADDRESS) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Fw image Flash Start Address is less than 64K\n",
__func__);
goto fail;
}
if (flash_start_address % FLASH_SECTOR_SIZE) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Flash Start Address is not multiple of 4K\n",
__func__);
goto fail;
}
if ((flash_start_address + content_size) > adapter->flash_capacity) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Flash Content will cross max flash size\n",
__func__);
goto fail;
......@@ -706,24 +933,24 @@ static int auto_fw_upgrade(struct rsi_hw *adapter,
temp_content_size = content_size;
num_flash = content_size / FLASH_WRITE_CHUNK_SIZE;
rsi_dbg(INFO_ZONE, "content_size: %d\n", content_size);
rsi_dbg(INFO_ZONE, "num_flash: %d\n", num_flash);
ven_rsi_dbg(INFO_ZONE, "content_size: %d\n", content_size);
ven_rsi_dbg(INFO_ZONE, "num_flash: %d\n", num_flash);
for (index = 0; index <= num_flash; index++) {
rsi_dbg(INFO_ZONE, "flash index: %d\n", index);
ven_rsi_dbg(INFO_ZONE, "flash index: %d\n", index);
if (index != num_flash) {
content_size = FLASH_WRITE_CHUNK_SIZE;
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"QSPI content_size:%d\n",
content_size);
} else {
content_size =
temp_content_size % FLASH_WRITE_CHUNK_SIZE;
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"Writing last sector content_size:%d\n",
content_size);
if (!content_size) {
rsi_dbg(INFO_ZONE, "INSTRUCTION SIZE ZERO\n");
ven_rsi_dbg(INFO_ZONE, "INSTRUCTION SIZE ZERO\n");
break;
}
}
......@@ -737,13 +964,13 @@ static int auto_fw_upgrade(struct rsi_hw *adapter,
cmd,
flash_content,
content_size)) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Unable to load %d block\n",
__func__, index);
goto fail;
}
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"%s: Successfully loaded %d instructions\n",
__func__, index);
flash_content += content_size;
......@@ -754,7 +981,7 @@ static int auto_fw_upgrade(struct rsi_hw *adapter,
bl_stop_cmd_timer(adapter);
goto fail;
}
rsi_dbg(INFO_ZONE, "FW loading is done and FW is running..\n");
ven_rsi_dbg(INFO_ZONE, "FW loading is done and FW is running..\n");
return 0;
fail:
......@@ -778,7 +1005,7 @@ static int read_flash_content(struct rsi_hw *adapter,
if (adapter->rsi_host_intf == RSI_HOST_INTF_SDIO) {
if (hif_ops->master_access_msword(adapter,
address >> 16) < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Unable to set ms word to common reg\n",
__func__);
return -1;
......@@ -828,33 +1055,33 @@ int verify_flash_content(struct rsi_hw *adapter,
if (read_mode != EEPROM_READ_MODE) {
dest_addr = kzalloc(instructions_sz, GFP_KERNEL);
if (!dest_addr) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Memory allocation for dest_addr failed\n",
__func__);
return -1;
}
}
rsi_dbg(INFO_ZONE, "Number of loops required: %d\n", num_loops);
ven_rsi_dbg(INFO_ZONE, "Number of loops required: %d\n", num_loops);
for (idx = 0; idx < num_loops; idx++) {
if (instructions_sz < flash_chunk_size)
chunk_size = instructions_sz;
else
chunk_size = flash_chunk_size;
rsi_dbg(INFO_ZONE, "idx is %d and chunk size is %d\n",
ven_rsi_dbg(INFO_ZONE, "idx is %d and chunk size is %d\n",
idx, chunk_size);
if (read_mode == EEPROM_READ_MODE) {
adapter->eeprom.offset = eeprom_offset;
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"eeprom offset is %x\n", eeprom_offset);
adapter->eeprom.length = chunk_size;
status = rsi_flash_read(adapter);
if (status == 0) {
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"%s: BLOCK/SECTOR READING SUCCESSFUL\n",
__func__);
} else {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: READING FROM FLASH FAILED\n",
__func__);
return -1;
......@@ -862,11 +1089,11 @@ int verify_flash_content(struct rsi_hw *adapter,
} else {
memset(dest_addr, 0, chunk_size);
addr = SOC_FLASH_ADDR + eeprom_offset;
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"Reading flash addr 0x%0x\n", addr);
if (read_flash_content(adapter, dest_addr, addr,
flash_chunk_size) < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s:Failed to read calib data\n",
__func__);
status = -1;
......@@ -878,7 +1105,7 @@ int verify_flash_content(struct rsi_hw *adapter,
mdelay(10);
dest_addr = adapter->priv->rx_data_pkt;
if (!dest_addr) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"Failed reading flash content\n");
status = -1;
goto out;
......@@ -887,7 +1114,7 @@ int verify_flash_content(struct rsi_hw *adapter,
if (memcmp(&flash_content[idx * flash_chunk_size],
dest_addr,
chunk_size)) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: VERIFICATION OF FLASH CHUNK FAILED\n",
__func__);
kfree(dest_addr);
......@@ -928,7 +1155,7 @@ int rsi_load_9113_firmware(struct rsi_hw *adapter)
SWBL_REGOUT,
&regout_val,
2)) < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: REGOUT read failed\n", __func__);
goto fail;
}
......@@ -937,21 +1164,21 @@ int rsi_load_9113_firmware(struct rsi_hw *adapter)
break;
}
if (adapter->blcmd_timer_expired) {
rsi_dbg(ERR_ZONE, "%s: REGOUT read timedout\n", __func__);
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE, "%s: REGOUT read timedout\n", __func__);
ven_rsi_dbg(ERR_ZONE,
"%s: Soft boot loader not present\n", __func__);
goto fail;
}
bl_stop_cmd_timer(adapter);
rsi_dbg(INFO_ZONE, "Received Board Version Number: %x\n",
ven_rsi_dbg(INFO_ZONE, "Received Board Version Number: %x\n",
(regout_val & 0xff));
if ((hif_ops->master_reg_write(adapter,
SWBL_REGOUT,
(REGOUT_INVALID | REGOUT_INVALID << 8),
2)) < 0) {
rsi_dbg(ERR_ZONE, "%s: REGOUT writing failed..\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: REGOUT writing failed..\n", __func__);
goto fail;
}
mdelay(1);
......@@ -962,7 +1189,7 @@ int rsi_load_9113_firmware(struct rsi_hw *adapter)
adapter->flash_capacity = read_flash_capacity(adapter);
if (adapter->flash_capacity <= 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Unable to read flash size from EEPROM\n",
__func__);
goto fail;
......@@ -970,24 +1197,24 @@ int rsi_load_9113_firmware(struct rsi_hw *adapter)
metadata_p = &metadata_flash_content[adapter->priv->coex_mode];
rsi_dbg(INIT_ZONE, "%s: loading file %s\n", __func__, metadata_p->name);
ven_rsi_dbg(INIT_ZONE, "%s: loading file %s\n", __func__, metadata_p->name);
if ((request_firmware(&fw_entry, metadata_p->name,
adapter->device)) < 0) {
rsi_dbg(ERR_ZONE, "%s: Failed to open file %s\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed to open file %s\n",
__func__, metadata_p->name);
goto fail;
}
flash_content = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
if (!flash_content) {
rsi_dbg(ERR_ZONE, "%s: Failed to copy firmware\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Failed to copy firmware\n", __func__);
goto fail;
}
content_size = fw_entry->size;
rsi_dbg(INFO_ZONE, "FW Length = %d bytes\n", content_size);
ven_rsi_dbg(INFO_ZONE, "FW Length = %d bytes\n", content_size);
if (bl_write_header(adapter, flash_content, content_size)) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: RPS Image header loading failed\n",
__func__);
goto fail;
......@@ -996,11 +1223,11 @@ int rsi_load_9113_firmware(struct rsi_hw *adapter)
bl_start_cmd_timer(adapter, BL_CMD_TIMEOUT);
if (bl_write_cmd(adapter, CHECK_CRC, CMD_PASS, &tmp_regout_val) < 0) {
bl_stop_cmd_timer(adapter);
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: CHECK_CRC Command writing failed..\n",
__func__);
if ((tmp_regout_val & 0xff) == CMD_FAIL) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"CRC Fail.. Proceeding to Upgrade mode\n");
goto fw_upgrade;
}
......@@ -1016,7 +1243,7 @@ int rsi_load_9113_firmware(struct rsi_hw *adapter)
LOADING_INITIATED,
"LOAD_HOSTED_FW")) < 0)
goto fail;
rsi_dbg(INFO_ZONE, "Load Image command passed..\n");
ven_rsi_dbg(INFO_ZONE, "Load Image command passed..\n");
goto success;
fw_upgrade:
......@@ -1026,10 +1253,10 @@ int rsi_load_9113_firmware(struct rsi_hw *adapter)
if (bl_cmd(adapter, BURN_HOSTED_FW, SEND_RPS_FILE, "FW_UPGRADE") < 0)
goto fail;
rsi_dbg(INFO_ZONE, "Burn Command Pass.. Upgrading the firmware\n");
ven_rsi_dbg(INFO_ZONE, "Burn Command Pass.. Upgrading the firmware\n");
if (auto_fw_upgrade(adapter, flash_content, content_size) == 0) {
rsi_dbg(ERR_ZONE, "***** Auto firmware successful *****\n");
ven_rsi_dbg(ERR_ZONE, "***** Auto firmware successful *****\n");
goto load_image_cmd;
}
......@@ -1039,14 +1266,14 @@ int rsi_load_9113_firmware(struct rsi_hw *adapter)
/* Not required for current flash mode */
#if 0
rsi_dbg(INFO_ZONE, "Starting Flash Verification Process\n");
ven_rsi_dbg(INFO_ZONE, "Starting Flash Verification Process\n");
if ((verify_flash_content(adapter,
flash_content,
EEPROM_DATA_SIZE,
0,
EEPROM_READ_MODE)) < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: FLASHING SBL failed in Calib VERIFICATION phase\n",
__func__);
goto fail;
......@@ -1056,15 +1283,15 @@ int rsi_load_9113_firmware(struct rsi_hw *adapter)
(content_size - BL_HEADER),
EEPROM_DATA_SIZE,
MASTER_READ_MODE)) < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s:FLASHING SBL failed in SBL VERIFICATION phase\n",
__func__);
goto fail;
}
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"Flash Verification Process Completed Successfully\n");
#endif
rsi_dbg(INFO_ZONE, "SWBL FLASHING THROUGH SWBL PASSED...\n");
ven_rsi_dbg(INFO_ZONE, "SWBL FLASHING THROUGH SWBL PASSED...\n");
success:
kfree(flash_content);
......@@ -1085,12 +1312,17 @@ int rsi_load_9113_firmware(struct rsi_hw *adapter)
*/
int rsi_hal_device_init(struct rsi_hw *adapter)
{
#ifdef CONFIG_VEN_RSI_HCI
adapter->priv->coex_mode = 4;
#if defined(CONFIG_VEN_RSI_HCI)
adapter->priv->coex_mode = 2;
#elif defined(CONFIG_VEN_RSI_COEX)
adapter->priv->coex_mode = 2;
#else
adapter->priv->coex_mode = 1;
#endif
#ifdef CONFIG_RSI_BT_LE
adapter->priv->coex_mode = 2;
#endif
adapter->device_model = RSI_DEV_9113;
switch (adapter->device_model) {
case RSI_DEV_9110:
......@@ -1098,7 +1330,7 @@ int rsi_hal_device_init(struct rsi_hw *adapter)
break;
case RSI_DEV_9113:
if (rsi_load_9113_firmware(adapter)) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to load TA instructions\n",
__func__);
return -1;
......@@ -1112,8 +1344,11 @@ int rsi_hal_device_init(struct rsi_hw *adapter)
}
adapter->common_hal_fsm = COMMAN_HAL_WAIT_FOR_CARD_READY;
#if defined(CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX)
adapter->priv->bt_fsm_state = BT_DEVICE_NOT_READY;
#endif
return 0;
}
EXPORT_SYMBOL_GPL(rsi_hal_device_init);
......@@ -55,10 +55,10 @@ static struct genl_cb *global_gcb;
*/
static int rsi_hci_open(struct hci_dev *hdev)
{
rsi_dbg(ERR_ZONE, "RSI HCI DEVICE \"%s\" open\n", hdev->name);
ven_rsi_dbg(ERR_ZONE, "RSI HCI DEVICE \"%s\" open\n", hdev->name);
if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
rsi_dbg(ERR_ZONE, "%s: device `%s' already running\n",
ven_rsi_dbg(ERR_ZONE, "%s: device `%s' already running\n",
__func__, hdev->name);
return 0;
......@@ -73,10 +73,10 @@ static int rsi_hci_open(struct hci_dev *hdev)
*/
static int rsi_hci_close(struct hci_dev *hdev)
{
rsi_dbg(ERR_ZONE, "RSI HCI DEVICE \"%s\" closed\n", hdev->name);
ven_rsi_dbg(ERR_ZONE, "RSI HCI DEVICE \"%s\" closed\n", hdev->name);
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
rsi_dbg(ERR_ZONE, "%s: device `%s' not running\n",
ven_rsi_dbg(ERR_ZONE, "%s: device `%s' not running\n",
__func__, hdev->name);
return 0;
......@@ -96,7 +96,7 @@ static int rsi_hci_flush(struct hci_dev *hdev)
if (!(h_adapter = hci_get_drvdata(hdev)))
return -EFAULT;
rsi_dbg(ERR_ZONE, "RSI `%s' flush\n", hdev->name);
ven_rsi_dbg(ERR_ZONE, "RSI `%s' flush\n", hdev->name);
return 0;
}
......@@ -124,7 +124,7 @@ static int rsi_hci_send_pkt(struct hci_dev *hdev, struct sk_buff *skb)
int status = 0;
if (skb->len <= 0) {
rsi_dbg(ERR_ZONE, "Zero length packet\n");
ven_rsi_dbg(ERR_ZONE, "Zero length packet\n");
//hdev->sta.err_tx++;
status = -EINVAL;
goto fail;
......@@ -136,8 +136,8 @@ static int rsi_hci_send_pkt(struct hci_dev *hdev, struct sk_buff *skb)
goto fail;
}
if (h_adapter->fsm_state != BT_DEVICE_READY) {
rsi_dbg(ERR_ZONE, "BT Device not ready\n");
if (h_adapter->priv->bt_fsm_state != BT_DEVICE_READY) {
ven_rsi_dbg(ERR_ZONE, "BT Device not ready\n");
status = -ENODEV;
goto fail;
}
......@@ -173,7 +173,7 @@ static int rsi_hci_send_pkt(struct hci_dev *hdev, struct sk_buff *skb)
new_skb = dev_alloc_skb(new_len);
if (!new_skb) {
rsi_dbg(ERR_ZONE, "%s: Failed to alloc skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed to alloc skb\n",
__func__);
return -ENOMEM;
}
......@@ -188,7 +188,7 @@ static int rsi_hci_send_pkt(struct hci_dev *hdev, struct sk_buff *skb)
rsi_hex_dump(DATA_RX_ZONE, "TX BT Pkt", skb->data, skb->len);
#ifdef CONFIG_VEN_RSI_COEX
rsi_coex_send_pkt(h_adapter->priv, skb, RSI_BT_Q);
rsi_coex_send_pkt(h_adapter->priv, skb, BT_Q);
#else
rsi_send_bt_pkt(h_adapter->priv, skb);
#endif
......@@ -198,43 +198,72 @@ static int rsi_hci_send_pkt(struct hci_dev *hdev, struct sk_buff *skb)
return status;
}
void rsi_hci_scheduler_thread(struct rsi_common *common)
{
struct rsi_hw *adapter = common->priv;
int status = 0;
do {
status = adapter->check_intr_status_reg(adapter);
if (adapter->isr_pending)
adapter->isr_pending = 0;
msleep(20);
} while (atomic_read(&common->hci_thread.thread_done) == 0);
complete_and_exit(&common->hci_thread.completion, 0);
}
int rsi_hci_recv_pkt(struct rsi_common *common, u8 *pkt)
{
struct rsi_hci_adapter *h_adapter =
(struct rsi_hci_adapter *)common->hci_adapter;
struct sk_buff *skb = NULL;
struct rsi_hci_adapter *h_adapter;
struct hci_dev *hdev = NULL;
int pkt_len = rsi_get_length(pkt, 0);
u8 queue_no = rsi_get_queueno(pkt, 0);
rsi_dbg(INFO_ZONE, "qno:%d, len:%d, fsm:%d",
queue_no, pkt_len, common->fsm_state);
if (pkt[14] == BT_CARD_READY_IND) {
rsi_dbg(INIT_ZONE, "%s: ===> BT Card Ready Received <===\n",
if ((common->bt_fsm_state == BT_DEVICE_NOT_READY) &&
(pkt[14] == BT_CARD_READY_IND)) {
ven_rsi_dbg(INIT_ZONE, "%s: ===> BT Card Ready Received <===\n",
__func__);
rsi_dbg(INFO_ZONE, "Attaching HCI module\n");
ven_rsi_dbg(INFO_ZONE, "Attaching HCI module\n");
if (rsi_hci_attach(common)) {
rsi_dbg(ERR_ZONE, "Failed to attach HCI module\n");
ven_rsi_dbg(ERR_ZONE, "Failed to attach HCI module\n");
return 0;
}
#ifdef CONFIG_VEN_RSI_COEX
if (rsi_coex_init(common)) {
rsi_dbg(ERR_ZONE, "Failed to init COEX module\n");
goto err;
/* 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
h_adapter = (struct rsi_hci_adapter *)common->hci_adapter;
h_adapter->fsm_state = BT_DEVICE_READY;
#endif
return 0;
}
h_adapter = (struct rsi_hci_adapter *)common->hci_adapter;
if (h_adapter->fsm_state != BT_DEVICE_READY) {
rsi_dbg(INFO_ZONE, "BT Device not ready\n");
if (common->bt_fsm_state != BT_DEVICE_READY) {
ven_rsi_dbg(INFO_ZONE, "BT Device not ready\n");
return 0;
}
......@@ -243,16 +272,13 @@ int rsi_hci_recv_pkt(struct rsi_common *common, u8 *pkt)
switch (msg_type) {
case RESULT_CONFIRM:
rsi_dbg(MGMT_RX_ZONE, "%s: BT Result Confirm\n", __func__);
return 0;
case BT_PER:
rsi_dbg(MGMT_RX_ZONE, "%s: BT Result Confirm\n", __func__);
ven_rsi_dbg(MGMT_RX_ZONE, "BT Result Confirm\n");
return 0;
case BT_BER:
rsi_dbg(MGMT_RX_ZONE, "%s: BT Result Confirm\n", __func__);
ven_rsi_dbg(MGMT_RX_ZONE, "BT Ber\n");
return 0;
case BT_CW:
rsi_dbg(MGMT_RX_ZONE, "%s: BT Result Confirm\n", __func__);
ven_rsi_dbg(MGMT_RX_ZONE, "BT CW\n");
return 0;
default:
break;
......@@ -261,7 +287,7 @@ int rsi_hci_recv_pkt(struct rsi_common *common, u8 *pkt)
skb = dev_alloc_skb(pkt_len);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed to alloc skb\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Failed to alloc skb\n", __func__);
return -ENOMEM;
}
hdev = h_adapter->hdev;
......@@ -311,13 +337,13 @@ int rsi_genl_recv(struct sk_buff *skb, struct genl_info *info)
if (na) {
data = (u8 *)nla_data(na);
if (!data) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: no data recevied on family `%s'\n",
__func__, gcb->gc_name);
goto err;
}
} else {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: netlink attr is NULL on family `%s'\n",
__func__, gcb->gc_name);
goto err;
......@@ -330,14 +356,14 @@ int rsi_genl_recv(struct sk_buff *skb, struct genl_info *info)
data += 16;
rsi_dbg(ERR_ZONE, "%s: len %x pkt_type %x\n",
ven_rsi_dbg(ERR_ZONE, "%s: len %x pkt_type %x\n",
__func__, len, pkttype);
rsi_hex_dump (DATA_RX_ZONE, "BT TX data", data, len);
skb = dev_alloc_skb(len + REQUIRED_HEADROOM_FOR_BT_HAL);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed to alloc skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed to alloc skb\n",
__func__);
return -ENOMEM;
}
......@@ -355,7 +381,7 @@ int rsi_genl_recv(struct sk_buff *skb, struct genl_info *info)
#endif
err:
rsi_dbg(ERR_ZONE, "%s: error(%d) occured\n", __func__, rc);
ven_rsi_dbg(ERR_ZONE, "%s: error(%d) occured\n", __func__, rc);
return rc;
}
......@@ -374,12 +400,11 @@ int rsi_hci_attach(struct rsi_common *common)
struct hci_dev *hdev;
int status = 0;
rsi_dbg (ERR_ZONE, "%s: In alloc HCI adapter\n", __func__);
/* Allocate HCI adapter */
/* TODO: Check GFP_ATOMIC */
h_adapter = kzalloc(sizeof (*h_adapter), GFP_KERNEL);
if (!h_adapter) {
rsi_dbg (ERR_ZONE, "%s: Failed to alloc HCI adapter\n", __func__);
ven_rsi_dbg (ERR_ZONE, "Failed to alloc HCI adapter\n");
return -ENOMEM;
}
h_adapter->priv = common;
......@@ -387,7 +412,7 @@ int rsi_hci_attach(struct rsi_common *common)
/* Create HCI Interface */
hdev = hci_alloc_dev();
if (!hdev) {
rsi_dbg (ERR_ZONE, "%s: Failed to alloc HCI device\n", __func__);
ven_rsi_dbg (ERR_ZONE, "Failed to alloc HCI device\n");
goto err;
}
h_adapter->hdev = hdev;
......@@ -412,22 +437,22 @@ int rsi_hci_attach(struct rsi_common *common)
/* Initialize TX queue */
skb_queue_head_init(&h_adapter->hci_tx_queue);
common->hci_adapter = (void *)h_adapter;
rsi_dbg (ERR_ZONE, "%s: In alloc HCI adapter\n", __func__);
ven_rsi_dbg (ERR_ZONE, "%s: In alloc HCI adapter\n", __func__);
status = hci_register_dev(hdev);
if (status < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: HCI registration failed with errcode %d\n",
__func__, status);
goto err;
}
rsi_dbg(INIT_ZONE, "HCI Interface Created with name \'%s\'\n",
ven_rsi_dbg(INIT_ZONE, "HCI Interface Created with name \'%s\'\n",
hdev->name);
/* Register for general netlink operations */
/* TODO: Check GFP_ATOMIC */
gcb = kzalloc(sizeof(*gcb), GFP_KERNEL);
if (!gcb) {
rsi_dbg (ERR_ZONE, "%s: Failed to alloc genl control block\n",
ven_rsi_dbg (ERR_ZONE, "%s: Failed to alloc genl control block\n",
__func__);
goto err;
}
......@@ -442,7 +467,7 @@ int rsi_hci_attach(struct rsi_common *common)
gcb->gc_name = RSI_BT_GENL_FAMILY;
gcb->gc_pid = gcb->gc_done = 0;
rsi_dbg(INIT_ZONE, "genl-register: nl_family `%s'\n", gcb->gc_name);
ven_rsi_dbg(INIT_ZONE, "genl-register: nl_family `%s'\n", gcb->gc_name);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
gcb->gc_family->ops = gcb->gc_ops;
......@@ -450,22 +475,21 @@ int rsi_hci_attach(struct rsi_common *common)
#endif
if (genl_register_family(gcb->gc_family)) {
rsi_dbg(ERR_ZONE, "%s: genl_register_family failed\n",
ven_rsi_dbg(ERR_ZONE, "%s: genl_register_family failed\n",
__func__);
goto err;
}
#if LINUX_VERSION_CODE <= KERNEL_VERSION (3, 12, 34)
if (genl_register_ops(gcb->gc_family, gcb->gc_ops)) {
rsi_dbg(ERR_ZONE, "%s: genl_register_ops failed\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: genl_register_ops failed\n", __func__);
genl_unregister_family(family);
goto err;
}
#endif
gcb->gc_done = 1;
//h_adapter->fsm_state = BT_DEVICE_READY;
rsi_dbg(ERR_ZONE, " HCI module init done...\n");
common->bt_fsm_state = BT_DEVICE_READY;
ven_rsi_dbg(ERR_ZONE, " HCI module init done...\n");
return 0;
......@@ -486,6 +510,7 @@ int rsi_hci_attach(struct rsi_common *common)
return -EINVAL;
}
EXPORT_SYMBOL_GPL(rsi_hci_attach);
/**
* rsi_hci_attach () - This function initializes HCI interface
......@@ -501,7 +526,7 @@ void rsi_hci_detach(struct rsi_common *common)
struct hci_dev *hdev;
struct genl_cb *gcb;
rsi_dbg(INFO_ZONE, "Detaching HCI...\n");
ven_rsi_dbg(INFO_ZONE, "Detaching HCI...\n");
if (!h_adapter)
return;
......@@ -527,6 +552,5 @@ void rsi_hci_detach(struct rsi_common *common)
return;
}
EXPORT_SYMBOL_GPL(rsi_hci_attach);
EXPORT_SYMBOL_GPL(rsi_hci_detach);
......@@ -189,14 +189,65 @@ static void rsi_register_rates_channels(struct rsi_hw *adapter, int band)
/* sbands->ht_cap.mcs.rx_highest = 0x82; */
}
static void rsi_set_min_rate(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
struct rsi_common *common)
{
struct ieee80211_vif *vif = common->priv->vifs[0];
u8 band = hw->conf.chandef.chan->band;
u8 ii;
u32 rate_bitmap;
bool matched = false;
if (vif->type == NL80211_IFTYPE_AP) {
common->bitrate_mask[band] = common->fixedrate_mask[band];
rate_bitmap = common->bitrate_mask[band];
} else {
common->bitrate_mask[band] = sta->supp_rates[band];
rate_bitmap = (common->fixedrate_mask[band] &
sta->supp_rates[band]);
}
ven_rsi_dbg(INFO_ZONE, "bitrate_mask = %x\n", common->bitrate_mask[band]);
ven_rsi_dbg(INFO_ZONE, "rate_bitmap = %x\n", rate_bitmap);
if (rate_bitmap & 0xfff) {
/* Find out the min rate */
for (ii = 0; ii < ARRAY_SIZE(rsi_rates); ii++) {
if (rate_bitmap & BIT(ii)) {
common->min_rate = rsi_rates[ii].hw_value;
matched = true;
break;
}
}
}
if (vif->type == NL80211_IFTYPE_STATION)
common->vif_info[0].is_ht = sta->ht_cap.ht_supported;
if ((common->vif_info[0].is_ht) && (rate_bitmap >> 12)) {
for (ii = 0; ii < ARRAY_SIZE(rsi_mcsrates); ii++) {
if ((rate_bitmap >> 12) & BIT(ii)) {
common->min_rate = rsi_mcsrates[ii];
matched = true;
break;
}
}
}
if (!matched)
common->min_rate = 0xffff;
ven_rsi_dbg(INFO_ZONE, "Min Rate = %d\n", common->min_rate);
}
/**
* rsi_mac80211_detach() - This function is used to de-initialize the
* ven_rsi_mac80211_detach() - This function is used to de-initialize the
* Mac80211 stack.
* @adapter: Pointer to the adapter structure.
*
* Return: None.
*/
void rsi_mac80211_detach(struct rsi_hw *adapter)
void ven_rsi_mac80211_detach(struct rsi_hw *adapter)
{
struct ieee80211_hw *hw = adapter->hw;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
......@@ -205,12 +256,13 @@ void rsi_mac80211_detach(struct rsi_hw *adapter)
int band;
#endif
rsi_dbg(INFO_ZONE, "Detach mac80211...\n");
ven_rsi_dbg(INFO_ZONE, "Detach mac80211...\n");
if (hw) {
ieee80211_stop_queues(hw);
ieee80211_unregister_hw(hw);
ieee80211_free_hw(hw);
adapter->hw = NULL;
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
......@@ -229,7 +281,7 @@ void rsi_mac80211_detach(struct rsi_hw *adapter)
kfree(adapter->dfsentry);
#endif
}
EXPORT_SYMBOL_GPL(rsi_mac80211_detach);
EXPORT_SYMBOL_GPL(ven_rsi_mac80211_detach);
/**
* rsi_indicate_tx_status() - This function indicates the transmit status.
......@@ -245,6 +297,11 @@ void rsi_indicate_tx_status(struct rsi_hw *adapter,
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
if (!adapter->hw) {
ven_rsi_dbg(ERR_ZONE, "##### No Hardware #####\n");
return;
}
memset(info->driver_data, 0, IEEE80211_TX_INFO_DRIVER_DATA_SIZE);
if (!status)
......@@ -269,6 +326,12 @@ static void rsi_mac80211_tx(struct ieee80211_hw *hw,
{
struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv;
struct ieee80211_hdr *wlh = (struct ieee80211_hdr *)skb->data;
if (ieee80211_is_beacon(wlh->frame_control)) {
ieee80211_free_txskb(common->priv->hw, skb);
return;
}
#ifndef CONFIG_VEN_RSI_HCI
rsi_core_xmit(common, skb);
......@@ -292,7 +355,7 @@ static int rsi_mac80211_start(struct ieee80211_hw *hw)
struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv;
rsi_dbg(ERR_ZONE, "===> Interface UP <===\n");
ven_rsi_dbg(ERR_ZONE, "===> Interface UP <===\n");
mutex_lock(&common->mutex);
common->iface_down = false;
......@@ -315,7 +378,7 @@ static void rsi_mac80211_stop(struct ieee80211_hw *hw)
struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv;
rsi_dbg(ERR_ZONE, "===> Interface DOWN <===\n");
ven_rsi_dbg(ERR_ZONE, "===> Interface DOWN <===\n");
mutex_lock(&common->mutex);
......@@ -341,30 +404,47 @@ static int rsi_mac80211_add_interface(struct ieee80211_hw *hw,
{
struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv;
enum opmode intf_mode;
int ret = 0;
rsi_dbg(INFO_ZONE, "Add Interface Called\n");
ven_rsi_dbg(INFO_ZONE, "Add Interface Called\n");
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
#endif
if ((vif->type != NL80211_IFTYPE_STATION) &&
(vif->type != NL80211_IFTYPE_AP))
return -1;
mutex_lock(&common->mutex);
/* Not supporting concurrent mode now */
if (adapter->sc_nvifs > 0)
return -1;
adapter->vifs[adapter->sc_nvifs++] = vif;
switch (vif->type) {
case NL80211_IFTYPE_STATION:
if (!adapter->sc_nvifs) {
++adapter->sc_nvifs;
adapter->vifs[0] = vif;
ret = rsi_set_vap_capabilities(common,
STA_OPMODE,
VAP_ADD);
}
intf_mode = STA_OPMODE;
break;
case NL80211_IFTYPE_AP:
intf_mode = AP_OPMODE;
break;
default:
rsi_dbg(ERR_ZONE,
"%s: Interface type %d not supported\n",
__func__, vif->type);
return -1;
}
ret = rsi_set_vap_capabilities(common, intf_mode, VAP_ADD);
if (ret) {
ven_rsi_dbg(ERR_ZONE, "Failed to send VAP capabilities\n");
return ret;
}
if (vif->type == NL80211_IFTYPE_AP) {
common->bc_mc_seqno = 1;
rsi_send_rx_filter_frame(common, DISALLOW_BEACONS);
rsi_set_min_rate(hw, NULL, common);
}
mutex_unlock(&common->mutex);
......@@ -386,13 +466,14 @@ static void rsi_mac80211_remove_interface(struct ieee80211_hw *hw,
struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv;
rsi_dbg(INFO_ZONE, "Remove Interface Called\n");
ven_rsi_dbg(INFO_ZONE, "Remove Interface Called\n");
mutex_lock(&common->mutex);
if (vif->type == NL80211_IFTYPE_STATION) {
adapter->sc_nvifs--;
if (vif->type == NL80211_IFTYPE_STATION)
rsi_set_vap_capabilities(common, STA_OPMODE, VAP_DELETE);
}
else if (vif->type == NL80211_IFTYPE_AP)
rsi_set_vap_capabilities(common, AP_OPMODE, VAP_DELETE);
if (!memcmp(adapter->vifs[0], vif, sizeof(struct ieee80211_vif)))
adapter->vifs[0] = NULL;
......@@ -415,33 +496,47 @@ static int rsi_channel_change(struct ieee80211_hw *hw)
struct ieee80211_channel *curchan = hw->conf.chandef.chan;
u16 channel = curchan->hw_value;
struct ieee80211_bss_conf *bss = NULL;
struct ieee80211_vif *vif = adapter->vifs[0];
if (adapter->sc_nvifs <= 0) {
rsi_dbg(ERR_ZONE, "%s: No virtual interface found\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: No virtual interface found\n", __func__);
return -EINVAL;
}
bss = &adapter->vifs[0]->bss_conf;
bss = &vif->bss_conf;
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"%s: Set channel: %d MHz type: %d channel_no %d\n",
__func__, curchan->center_freq,
curchan->flags, channel);
if (vif->type == NL80211_IFTYPE_AP) {
ven_rsi_dbg(INFO_ZONE, "Configure channel %d for AP\n", channel);
if (rsi_band_check(common)) {
ven_rsi_dbg(ERR_ZONE, "Failed to set band\n");
return -EINVAL;
}
if (rsi_set_channel(common, curchan)) {
ven_rsi_dbg(ERR_ZONE, "Failed to set the channel\n");
return -EINVAL;
}
common->ap_channel = curchan;
return 0;
}
common->mac80211_cur_channel = channel;
if (bss->assoc) {
rsi_dbg(INFO_ZONE, "%s: connected\n", __func__);
ven_rsi_dbg(INFO_ZONE, "%s: connected\n", __func__);
if (common->bgscan_en)
return 0;
if (!common->hw_data_qs_blocked &&
(rsi_get_connected_channel(adapter) != channel)) {
rsi_dbg(INFO_ZONE, "blk data q %d\n", channel);
ven_rsi_dbg(INFO_ZONE, "blk data q %d\n", channel);
if (!rsi_send_block_unblock_frame(common, true))
common->hw_data_qs_blocked = true;
}
} else {
rsi_dbg(INFO_ZONE, "assoc status:%d channel:%d\n",
ven_rsi_dbg(INFO_ZONE, "assoc status:%d channel:%d\n",
bss->assoc, channel);
}
......@@ -452,13 +547,13 @@ static int rsi_channel_change(struct ieee80211_hw *hw)
if (bss->assoc) {
if (common->hw_data_qs_blocked &&
(rsi_get_connected_channel(adapter) == channel)) {
rsi_dbg(INFO_ZONE, "unblk data q %d\n", channel);
ven_rsi_dbg(INFO_ZONE, "unblk data q %d\n", channel);
if (!rsi_send_block_unblock_frame(common, false))
common->hw_data_qs_blocked = false;
}
} else {
if (common->hw_data_qs_blocked) {
rsi_dbg(INFO_ZONE, "unblk data q %d\n", channel);
ven_rsi_dbg(INFO_ZONE, "unblk data q %d\n", channel);
if (!rsi_send_block_unblock_frame(common, false))
common->hw_data_qs_blocked = false;
}
......@@ -481,11 +576,11 @@ static int rsi_config_power(struct ieee80211_hw *hw)
int status;
if (adapter->sc_nvifs <= 0) {
rsi_dbg(ERR_ZONE, "%s: No virtual interface found\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: No virtual interface found\n", __func__);
return -EINVAL;
}
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"%s: Set tx power: %d dBM\n", __func__, conf->power_level);
if (conf->power_level == common->tx_power)
......@@ -512,6 +607,7 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
{
struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv;
struct ieee80211_vif *vif = adapter->vifs[0];
struct ieee80211_conf *conf = &hw->conf;
int status = -EOPNOTSUPP;
......@@ -523,14 +619,14 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
/* listen interval */
if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"listen_int = %d\n", conf->listen_interval);
adapter->ps_info.num_bcns_per_lis_int = conf->listen_interval;
}
/* tx power */
if (changed & IEEE80211_CONF_CHANGE_POWER) {
rsi_dbg(INFO_ZONE, "%s: Configuring Power\n", __func__);
ven_rsi_dbg(INFO_ZONE, "%s: Configuring Power\n", __func__);
status = rsi_config_power(hw);
}
......@@ -540,7 +636,8 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
}
/* Power save parameters */
if (changed & IEEE80211_CONF_CHANGE_PS) {
if ((changed & IEEE80211_CONF_CHANGE_PS) &&
(vif->type == NL80211_IFTYPE_STATION)) {
unsigned long flags;
spin_lock_irqsave(&adapter->ps_lock, flags);
......@@ -553,9 +650,9 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
/* RTS threshold */
if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
rsi_dbg(INFO_ZONE,"RTS threshold\n");
ven_rsi_dbg(INFO_ZONE,"RTS threshold\n");
if ((common->rts_threshold) <= IEEE80211_MAX_RTS_THRESHOLD) {
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"%s: Sending vap updates....\n", __func__);
status = rsi_send_vap_dynamic_update(common);
}
......@@ -608,6 +705,27 @@ void rsi_resume_conn_channel(struct rsi_hw *adapter)
mutex_unlock(&common->mutex);
}
static void rsi_update_beacon(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv;
struct ieee80211_mutable_offsets offs = {};
struct sk_buff *bcn;
bcn = ieee80211_beacon_get_template(hw, vif, &offs);
if (!bcn) {
ven_rsi_dbg(ERR_ZONE,
"failed to get beacon template from mac80211\n");
return;
}
memcpy(common->beacon_frame, bcn->data, bcn->len);
common->beacon_frame_len = bcn->len;
rsi_hex_dump(INFO_ZONE, "mac80211: Beacon",
common->beacon_frame, common->beacon_frame_len);
}
/**
* rsi_mac80211_bss_info_changed() - This function is a handler for config
* requests related to BSS parameters that
......@@ -629,33 +747,38 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf;
u16 rx_filter_word = 0;
rsi_dbg(INFO_ZONE, "%s: BSS status changed\n", __func__);
ven_rsi_dbg(INFO_ZONE, "%s: BSS status changed\n", __func__);
mutex_lock(&common->mutex);
if (changed & BSS_CHANGED_ASSOC) {
rsi_dbg(INFO_ZONE, "%s: Changed Association status: %d\n",
if ((changed & BSS_CHANGED_ASSOC) &&
(vif->type == NL80211_IFTYPE_STATION)) {
ven_rsi_dbg(INFO_ZONE, "%s: Changed Association status: %d\n",
__func__, bss_conf->assoc);
rsi_hex_dump(INFO_ZONE, "BSSID: ", bss->bssid, ETH_ALEN);
bss->assoc = bss_conf->assoc;
if (bss_conf->assoc) {
if (bss->assoc) {
/* Send the RX filter frame */
rx_filter_word = (ALLOW_DATA_ASSOC_PEER |
ALLOW_CTRL_ASSOC_PEER |
ALLOW_MGMT_ASSOC_PEER);// |
//DISALLOW_BEACONS);
ALLOW_MGMT_ASSOC_PEER |
#ifdef RSI_HW_CONN_MONITOR
DISALLOW_BEACONS |
#endif
0);
rsi_send_rx_filter_frame(common, rx_filter_word);
}
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"assoc_status=%d, qos=%d, aid=%d\n",
bss->assoc, bss->qos, bss->aid);
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"bssid=%02x:%02x:%02x:%02x:%02x:%02x",
bss->bssid[0], bss->bssid[1], bss->bssid[2],
bss->bssid[3], bss->bssid[4], bss->bssid[5]);
rsi_inform_bss_status(common,
bss->assoc,
bss->bssid,
bss->qos,
bss->aid);
/* 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);
adapter->ps_info.listen_interval =
bss->beacon_int * adapter->ps_info.num_bcns_per_lis_int;
......@@ -663,33 +786,48 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
/* If UAPSD is updated send ps params */
if (common->uapsd_bitmap) {
rsi_dbg(INFO_ZONE, "Configuring UAPSD\n");
ven_rsi_dbg(INFO_ZONE, "Configuring UAPSD\n");
rsi_conf_uapsd(adapter);
}
}
if (changed & BSS_CHANGED_CQM) {
rsi_dbg(INFO_ZONE, "%s: Changed CQM\n", __func__);
if ((vif->type == NL80211_IFTYPE_STATION) &&
changed & BSS_CHANGED_CQM) {
ven_rsi_dbg(INFO_ZONE, "%s: Changed CQM\n", __func__);
common->cqm_info.last_cqm_event_rssi = 0;
common->cqm_info.rssi_thold = bss_conf->cqm_rssi_thold;
common->cqm_info.rssi_hyst = bss_conf->cqm_rssi_hyst;
rsi_dbg(INFO_ZONE, "RSSI throld & hysteresis are: %d %d\n",
ven_rsi_dbg(INFO_ZONE, "RSSI throld & hysteresis are: %d %d\n",
common->cqm_info.rssi_thold,
common->cqm_info.rssi_hyst);
}
if (changed & BSS_CHANGED_TXPOWER) {
rsi_dbg(INFO_ZONE, "%s: Changed TX power: %d\n",
ven_rsi_dbg(INFO_ZONE, "%s: Changed TX power: %d\n",
__func__, bss_conf->txpower);
}
if (changed & BSS_CHANGED_BEACON_INT) {
rsi_dbg(INFO_ZONE, "%s: Changed Beacon interval: %d\n",
ven_rsi_dbg(INFO_ZONE, "%s: Changed Beacon interval: %d\n",
__func__, bss_conf->beacon_int);
adapter->ps_info.listen_interval =
bss->beacon_int * adapter->ps_info.num_bcns_per_lis_int;
}
if ((changed & BSS_CHANGED_BEACON) &&
(vif->type == NL80211_IFTYPE_AP)) {
ven_rsi_dbg(INFO_ZONE, "%s: Changed Beacon\n", __func__);
rsi_update_beacon(hw, vif);
}
if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
(vif->type == NL80211_IFTYPE_AP)) {
if (bss->enable_beacon)
ven_rsi_dbg(INFO_ZONE, "===> BEACON ENABLED <===\n");
else
ven_rsi_dbg(INFO_ZONE, "===> BEACON DISABLED <===\n");
}
mutex_unlock(&common->mutex);
}
......@@ -741,7 +879,7 @@ static int rsi_mac80211_conf_tx(struct ieee80211_hw *hw,
if (queue >= IEEE80211_NUM_ACS)
return 0;
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"[Conf] queue:%d, aifs:%d, cwmin:%d cwmax:%d, txop:%d uapsd:%d\n",
queue, params->aifs, params->cw_min, params->cw_max,
params->txop, params->uapsd);
......@@ -769,11 +907,11 @@ static int rsi_mac80211_conf_tx(struct ieee80211_hw *hw,
memcpy(&common->edca_params[idx],
params,
sizeof(struct ieee80211_tx_queue_params));
mutex_unlock(&common->mutex);
if (params->uapsd)
common->uapsd_bitmap |= idx;
mutex_unlock(&common->mutex);
return 0;
}
......@@ -787,19 +925,32 @@ static int rsi_mac80211_conf_tx(struct ieee80211_hw *hw,
*/
static int rsi_hal_key_config(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_key_conf *key)
struct ieee80211_key_conf *key,
struct ieee80211_sta *sta)
{
struct rsi_hw *adapter = hw->priv;
int status;
u8 key_type;
s16 sta_id;
if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
key_type = RSI_PAIRWISE_KEY;
else
key_type = RSI_GROUP_KEY;
rsi_dbg(ERR_ZONE, "%s: Cipher 0x%x key_type: %d key_len: %d\n",
ven_rsi_dbg(ERR_ZONE, "%s: Cipher 0x%x key_type: %d key_len: %d\n",
__func__, key->cipher, key_type, key->keylen);
ven_rsi_dbg(INFO_ZONE, "hw_key_idx %d\n", key->hw_key_idx);
if (sta && vif->type == NL80211_IFTYPE_AP) {
struct rsi_sta *rsta = rsi_find_sta(adapter->priv, sta->addr);
if (rsta)
sta_id = rsta->sta_id;
else
return -EINVAL;
} else
sta_id = 0;
if ((key->cipher == WLAN_CIPHER_SUITE_WEP104) ||
(key->cipher == WLAN_CIPHER_SUITE_WEP40)) {
......@@ -808,7 +959,8 @@ static int rsi_hal_key_config(struct ieee80211_hw *hw,
key->keylen,
RSI_PAIRWISE_KEY,
key->keyidx,
key->cipher);
key->cipher,
sta_id);
if (status)
return status;
}
......@@ -817,7 +969,8 @@ static int rsi_hal_key_config(struct ieee80211_hw *hw,
key->keylen,
key_type,
key->keyidx,
key->cipher);
key->cipher,
sta_id);
}
/**
......@@ -845,7 +998,7 @@ static int rsi_mac80211_set_key(struct ieee80211_hw *hw,
switch (cmd) {
case SET_KEY:
secinfo->security_enable = true;
status = rsi_hal_key_config(hw, vif, key);
status = rsi_hal_key_config(hw, vif, key, sta);
if (status) {
mutex_unlock(&common->mutex);
return status;
......@@ -859,14 +1012,14 @@ static int rsi_mac80211_set_key(struct ieee80211_hw *hw,
key->hw_key_idx = key->keyidx;
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
rsi_dbg(ERR_ZONE, "%s: RSI set_key\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: RSI set_key\n", __func__);
break;
case DISABLE_KEY:
secinfo->security_enable = false;
rsi_dbg(ERR_ZONE, "%s: RSI del key\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: RSI del key\n", __func__);
memset(key, 0, sizeof(struct ieee80211_key_conf));
status = rsi_hal_key_config(hw, vif, key);
status = rsi_hal_key_config(hw, vif, key, sta);
break;
default:
......@@ -942,13 +1095,13 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
seq_no = params->ssn;
#endif
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"%s: AMPDU action tid=%d ssn=0x%x, buf_size=%d\n",
__func__, tid, seq_no, buf_size);
switch (action) {
case IEEE80211_AMPDU_RX_START:
rsi_dbg(INFO_ZONE, "AMPDU action RX_START (%d)\n", action);
ven_rsi_dbg(INFO_ZONE, "AMPDU action RX_START (%d)\n", action);
status = rsi_send_aggr_params_frame(common,
tid,
seq_no,
......@@ -957,7 +1110,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
break;
case IEEE80211_AMPDU_RX_STOP:
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"AMPDU action RX_STOP (%d) called\n", action);
status = rsi_send_aggr_params_frame(common,
tid,
......@@ -967,7 +1120,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
break;
case IEEE80211_AMPDU_TX_START:
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"AMPDU action TX_START (%d) called\n", action);
common->vif_info[ii].seq_start = seq_no;
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
......@@ -977,7 +1130,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
case IEEE80211_AMPDU_TX_STOP_CONT:
case IEEE80211_AMPDU_TX_STOP_FLUSH:
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"AMPDU action TX_STOP_CONT / TX_STOP_FLUSH /"
" TX_STOP_FLUSH_CONT (%d) called\n", action);
status = rsi_send_aggr_params_frame(common,
......@@ -990,7 +1143,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
break;
case IEEE80211_AMPDU_TX_OPERATIONAL:
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"AMPDU action TX_OPERATIONAL(%d) called\n",
action);
status = rsi_send_aggr_params_frame(common,
......@@ -1001,7 +1154,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
break;
default:
rsi_dbg(ERR_ZONE, "%s: Uknown AMPDU action\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Uknown AMPDU action\n", __func__);
break;
}
......@@ -1052,8 +1205,7 @@ static int rsi_mac80211_set_rate_mask(struct ieee80211_hw *hw,
common->fixedrate_mask[band] =
(mask->control[band].ht_mcs[0] << 12);
} else {
common->fixedrate_mask[band] =
mask->control[band].legacy;
common->fixedrate_mask[band] = mask->control[band].legacy;
}
mutex_unlock(&common->mutex);
......@@ -1085,7 +1237,7 @@ static void rsi_perform_cqm(struct rsi_common *common,
return;
common->cqm_info.last_cqm_event_rssi = rssi;
rsi_dbg(INFO_ZONE, "CQM: Notifying event: %d\n", event);
ven_rsi_dbg(INFO_ZONE, "CQM: Notifying event: %d\n", event);
ieee80211_cqm_rssi_notify(adapter->vifs[0], event, GFP_KERNEL);
}
......@@ -1093,7 +1245,7 @@ void rsi_indicate_bcnmiss(struct rsi_common *common)
{
struct rsi_hw *adapter = common->priv;
rsi_dbg(INFO_ZONE, "CQM: Notifying beacon miss\n" );
ven_rsi_dbg(INFO_ZONE, "CQM: Notifying beacon miss\n" );
ieee80211_beacon_loss(adapter->vifs[0]);
return;
}
......@@ -1113,7 +1265,8 @@ static void rsi_fill_rx_status(struct ieee80211_hw *hw,
struct rsi_common *common,
struct ieee80211_rx_status *rxs)
{
struct ieee80211_bss_conf *bss = &common->priv->vifs[0]->bss_conf;
struct ieee80211_vif *vif = common->priv->vifs[0];
struct ieee80211_bss_conf *bss = &vif->bss_conf;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct skb_info *rx_params = (struct skb_info *)info->driver_data;
struct ieee80211_hdr *hdr;
......@@ -1150,7 +1303,8 @@ static void rsi_fill_rx_status(struct ieee80211_hw *hw,
}
/* CQM only for connected AP beacons, the RSSI is a weighted avg */
if (bss->assoc && ether_addr_equal(bss->bssid, hdr->addr2)) {
if ((vif->type == NL80211_IFTYPE_STATION) && bss->assoc &&
ether_addr_equal(bss->bssid, hdr->addr2)) {
if (ieee80211_is_beacon(hdr->frame_control))
rsi_perform_cqm(common, hdr->addr2, rxs->signal);
}
......@@ -1182,46 +1336,6 @@ void rsi_indicate_pkt_to_os(struct rsi_common *common,
ieee80211_rx_irqsafe(hw, skb);
}
static void rsi_set_min_rate(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
struct rsi_common *common)
{
u8 band = hw->conf.chandef.chan->band;
u8 ii;
u32 rate_bitmap;
bool matched = false;
common->bitrate_mask[band] = sta->supp_rates[band];
rate_bitmap = (common->fixedrate_mask[band] & sta->supp_rates[band]);
if (rate_bitmap & 0xfff) {
/* Find out the min rate */
for (ii = 0; ii < ARRAY_SIZE(rsi_rates); ii++) {
if (rate_bitmap & BIT(ii)) {
common->min_rate = rsi_rates[ii].hw_value;
matched = true;
break;
}
}
}
common->vif_info[0].is_ht = sta->ht_cap.ht_supported;
if ((common->vif_info[0].is_ht) && (rate_bitmap >> 12)) {
for (ii = 0; ii < ARRAY_SIZE(rsi_mcsrates); ii++) {
if ((rate_bitmap >> 12) & BIT(ii)) {
common->min_rate = rsi_mcsrates[ii];
matched = true;
break;
}
}
}
if (!matched)
common->min_rate = 0xffff;
}
/**
* rsi_mac80211_sta_add() - This function notifies driver about a peer getting
* connected.
......@@ -1237,28 +1351,60 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
{
struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv;
bool sta_exist = 0;
rsi_hex_dump(INFO_ZONE, "Station Add: ", sta->addr, ETH_ALEN);
mutex_lock(&common->mutex);
rsi_set_min_rate(hw, sta, common);
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++) {
if (!memcmp(common->stations[i].sta->addr,
sta->addr, ETH_ALEN)) {
ven_rsi_dbg(INFO_ZONE, "Station exists\n");
sta_exist = 1;
break;
}
}
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);
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;
common->num_stations++;
} else {
common->stations[i].sta = sta;
for (j = 0; j < IEEE80211_NUM_ACS; j++)
common->stations[i].seq_no[j] = 1;
}
}
if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ||
(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)) {
common->vif_info[0].sgi = true;
}
if (vif->type == NL80211_IFTYPE_STATION) {
rsi_set_min_rate(hw, sta, common);
if (g_bgscan_enable) {
if (!rsi_send_bgscan_params(common, 1)) {
if (!rsi_send_bgscan_probe_req(common)) {
rsi_dbg(INFO_ZONE,
"Background scan started ===>\n");
ven_rsi_dbg(INFO_ZONE,
"Bgscan started ===>\n");
common->bgscan_en = 1;
}
}
}
}
if (sta->ht_cap.ht_supported)
if ((vif->type == NL80211_IFTYPE_STATION) &&
sta->ht_cap.ht_supported)
ieee80211_start_tx_ba_session(sta, 0, 0);
mutex_unlock(&common->mutex);
......@@ -1285,6 +1431,30 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
rsi_hex_dump(INFO_ZONE, "Station Removed: ", sta->addr, ETH_ALEN);
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++) {
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);
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--;
break;
}
}
if (i >= RSI_MAX_ASSOC_STAS)
ven_rsi_dbg(ERR_ZONE, "%s: No station found\n", __func__);
}
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);
......@@ -1303,6 +1473,7 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
if (!common->iface_down)
rsi_send_rx_filter_frame(common, 0);
}
return 0;
}
#if 0
......@@ -1323,7 +1494,7 @@ static void rsi_mac80211_sw_scan_start(struct ieee80211_hw *hw,
status = rsi_send_bgscan_params(common, 1);
if (!status) {
rsi_dbg(INFO_ZONE, "Background scan commensing\n");
ven_rsi_dbg(INFO_ZONE, "Background scan commensing\n");
if (!rsi_send_bgscan_probe_req(common))
common->bgscan_en = 1;
}
......@@ -1386,15 +1557,15 @@ static int rsi_mac80211_set_antenna(struct ieee80211_hw *hw,
u32 antenna = 0;
if (tx_ant > 1 || rx_ant > 1) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"Invalid antenna selection (tx: %d, rx:%d)\n",
tx_ant, rx_ant);
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"Use 0 for int_ant, 1 for ext_ant\n");
return -EINVAL;
}
rsi_dbg(INFO_ZONE, "%s: Antenna map Tx %x Rx %d\n",
ven_rsi_dbg(INFO_ZONE, "%s: Antenna map Tx %x Rx %d\n",
__func__, tx_ant, rx_ant);
mutex_lock(&common->mutex);
......@@ -1404,7 +1575,7 @@ static int rsi_mac80211_set_antenna(struct ieee80211_hw *hw,
if (rsi_set_antenna(common, antenna))
goto fail_set_antenna;
rsi_dbg(INFO_ZONE, "(%s) Antenna path configured successfully\n",
ven_rsi_dbg(INFO_ZONE, "(%s) Antenna path configured successfully\n",
tx_ant ? "UFL" : "INT");
common->ant_in_use = antenna;
......@@ -1414,7 +1585,7 @@ static int rsi_mac80211_set_antenna(struct ieee80211_hw *hw,
return 0;
fail_set_antenna:
rsi_dbg(ERR_ZONE, "%s: Failed.\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Failed.\n", __func__);
mutex_unlock(&common->mutex);
return -EINVAL;
}
......@@ -1449,11 +1620,14 @@ static void rsi_reg_notify(struct wiphy *wiphy,
struct regulatory_request *request)
{
struct ieee80211_supported_band *sband;
struct ieee80211_channel *ch;
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct rsi_hw * adapter = hw->priv;
struct rsi_common *common = adapter->priv;
struct ieee80211_channel *ch;
int i;
mutex_lock(&common->mutex);
sband = wiphy->bands[NL80211_BAND_5GHZ];
for (i = 0; i < sband->n_channels; i++) {
......@@ -1465,10 +1639,27 @@ static void rsi_reg_notify(struct wiphy *wiphy,
ch->flags |= IEEE80211_CHAN_NO_IR;
}
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"country = %s dfs_region = %d\n",
request->alpha2, request->dfs_region);
/* If DFS region or country is changed configure back ground scan
* params to device again */
if ((adapter->dfs_region != request->dfs_region) ||
(memcmp(adapter->country, request->alpha2, 2))) {
if (common->bgscan_en) {
rsi_send_bgscan_params(common, 0);
common->bgscan_en = 0;
mdelay(10);
rsi_send_bgscan_params(common, 1);
common->bgscan_en = 1;
}
}
adapter->dfs_region = request->dfs_region;
adapter->country[0] = request->alpha2[0];
adapter->country[1] = request->alpha2[1];
mutex_unlock(&common->mutex);
}
void rsi_mac80211_rfkill_poll(struct ieee80211_hw *hw)
......@@ -1486,6 +1677,85 @@ void rsi_mac80211_rfkill_poll(struct ieee80211_hw *hw)
mutex_unlock(&common->mutex);
}
#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,
.n_patterns = 0,
.pattern_min_len = 1,
.pattern_max_len = 0,
};
static u16 rsi_wow_map_triggers(struct rsi_common *common,
struct cfg80211_wowlan *wowlan)
{
u16 wow_triggers = 0;
ven_rsi_dbg(INFO_ZONE,"Mapping wowlan triggers\n");
if (wowlan->any)
wow_triggers |= RSI_WOW_ANY;
if (wowlan->magic_pkt)
wow_triggers |= RSI_WOW_MAGIC_PKT;
if (wowlan->disconnect)
wow_triggers |= RSI_WOW_DISCONNECT;
if (wowlan->gtk_rekey_failure || wowlan->eap_identity_req ||
wowlan->four_way_handshake)
wow_triggers |= RSI_WOW_SUPPORTS_GTK_REKEY;
return wow_triggers;
}
#endif
#ifdef CONFIG_PM
int rsi_mac80211_suspend(struct ieee80211_hw *hw,
struct cfg80211_wowlan *wowlan)
{
#ifdef CONFIG_RSI_WOW
struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv;
u16 triggers;
#endif
int ret = 0;
ven_rsi_dbg(INFO_ZONE, "***** mac80211 suspend called ******\n");
#ifdef CONFIG_RSI_WOW
if (WARN_ON(!wowlan)) {
ven_rsi_dbg(ERR_ZONE,
"##### WoW triggers not enabled #####\n");
ret = -EINVAL;
goto fail_wow;
}
triggers = rsi_wow_map_triggers(common, wowlan);
if (!triggers) {
ven_rsi_dbg(ERR_ZONE, "%s:No valid WoW triggers\n",__func__);
ret = 1;
goto fail_wow;
}
ven_rsi_dbg(INFO_ZONE, "TRIGGERS %x\n", triggers);
rsi_send_wowlan_request(common, triggers, wowlan);
fail_wow:
#endif
return ret;
}
static int rsi_mac80211_resume(struct ieee80211_hw *hw)
{
ven_rsi_dbg(INFO_ZONE, "%s: mac80211 resume\n", __func__);
return 0;
}
#endif
static struct ieee80211_ops mac80211_ops = {
.tx = rsi_mac80211_tx,
.start = rsi_mac80211_start,
......@@ -1504,7 +1774,12 @@ 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
.rfkill_poll = rsi_mac80211_rfkill_poll,
#ifdef CONFIG_PM
.suspend = rsi_mac80211_suspend,
.resume = rsi_mac80211_resume,
#endif
};
/**
......@@ -1521,11 +1796,11 @@ int rsi_mac80211_attach(struct rsi_common *common)
struct rsi_hw *adapter = common->priv;
u8 addr_mask[ETH_ALEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x3};
rsi_dbg(INIT_ZONE, "%s: Performing mac80211 attach\n", __func__);
ven_rsi_dbg(INIT_ZONE, "%s: Performing mac80211 attach\n", __func__);
hw = ieee80211_alloc_hw(sizeof(struct rsi_hw), &mac80211_ops);
if (!hw) {
rsi_dbg(ERR_ZONE, "%s: ieee80211 hw alloc failed\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: ieee80211 hw alloc failed\n", __func__);
return -ENOMEM;
}
......@@ -1572,26 +1847,34 @@ int rsi_mac80211_attach(struct rsi_common *common)
rsi_register_rates_channels(adapter, NL80211_BAND_2GHZ);
rsi_register_rates_channels(adapter, NL80211_BAND_5GHZ);
hw->rate_control_algorithm = "AARF";
hw->sta_data_size = sizeof(struct rsi_sta);
SET_IEEE80211_PERM_ADDR(hw, common->mac_addr);
ether_addr_copy(hw->wiphy->addr_mask, addr_mask);
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP);
wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
wiphy->retry_short = RETRY_SHORT;
wiphy->retry_long = RETRY_LONG;
wiphy->frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
wiphy->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
wiphy->flags = 0;
wiphy->available_antennas_tx = 1;
wiphy->available_antennas_rx = 1;
wiphy->bands[NL80211_BAND_2GHZ] =
&adapter->sbands[NL80211_BAND_2GHZ];
wiphy->bands[NL80211_BAND_5GHZ] =
&adapter->sbands[NL80211_BAND_5GHZ];
wiphy->max_ap_assoc_sta = RSI_MAX_ASSOC_STAS;
wiphy->flags = WIPHY_FLAG_REPORTS_OBSS;
wiphy->reg_notifier = rsi_reg_notify;
#ifdef CONFIG_RSI_WOW
wiphy->wowlan = &rsi_wowlan_support;
#endif
status = ieee80211_register_hw(hw);
if (status)
return status;
......
......@@ -21,14 +21,14 @@
#include "rsi_mgmt.h"
#include "rsi_common.h"
#include "rsi_hal.h"
#ifdef CONFIG_VEN_RSI_HCI
#if defined(CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX)
#include "rsi_hci.h"
#endif
#ifdef CONFIG_VEN_RSI_COEX
#include "rsi_coex.h"
#endif
u32 rsi_zone_enabled = //INFO_ZONE |
u32 ven_rsi_zone_enabled = //INFO_ZONE |
INIT_ZONE |
//MGMT_TX_ZONE |
//MGMT_RX_ZONE |
......@@ -38,16 +38,16 @@ u32 rsi_zone_enabled = //INFO_ZONE |
//ISR_ZONE |
ERR_ZONE |
0;
EXPORT_SYMBOL_GPL(rsi_zone_enabled);
EXPORT_SYMBOL_GPL(ven_rsi_zone_enabled);
/**
* rsi_dbg() - This function outputs informational messages.
* ven_rsi_dbg() - This function outputs informational messages.
* @zone: Zone of interest for output message.
* @fmt: printf-style format for output message.
*
* Return: none
*/
void rsi_dbg(u32 zone, const char *fmt, ...)
void ven_rsi_dbg(u32 zone, const char *fmt, ...)
{
struct va_format vaf;
va_list args;
......@@ -57,11 +57,11 @@ void rsi_dbg(u32 zone, const char *fmt, ...)
vaf.fmt = fmt;
vaf.va = &args;
if (zone & rsi_zone_enabled)
if (zone & ven_rsi_zone_enabled)
pr_info("%pV", &vaf);
va_end(args);
}
EXPORT_SYMBOL_GPL(rsi_dbg);
EXPORT_SYMBOL_GPL(ven_rsi_dbg);
/**
* rsi_hex_dump() - This function prints the packet (/msg) in hex bytes.
......@@ -76,7 +76,7 @@ void rsi_hex_dump(u32 zone, char *msg_str, const u8 *msg, u32 len)
{
int ii;
if (!(zone & rsi_zone_enabled))
if (!(zone & ven_rsi_zone_enabled))
return;
printk("%s: (length = %d)\n", msg_str, len);
for (ii = 0; ii < len; ii++) {
......@@ -111,7 +111,7 @@ static struct sk_buff *rsi_prepare_skb(struct rsi_common *common,
return NULL;
if (pkt_len > (RSI_RCV_BUFFER_LEN * 4)) {
rsi_dbg(ERR_ZONE, "%s: Pkt size > max rx buf size %d\n",
ven_rsi_dbg(ERR_ZONE, "%s: Pkt size > max rx buf size %d\n",
__func__, pkt_len);
pkt_len = RSI_RCV_BUFFER_LEN * 4;
}
......@@ -128,19 +128,23 @@ static struct sk_buff *rsi_prepare_skb(struct rsi_common *common,
info = IEEE80211_SKB_CB(skb);
rx_params = (struct skb_info *)info->driver_data;
rx_params->rssi = rsi_get_rssi(buffer);
// if (vif->type == NL80211_IFTYPE_STATION)
rx_params->channel = rsi_get_connected_channel(common->priv);
// else
// rx_params->channel = common->ap_channel->hw_value;
return skb;
}
/**
* rsi_read_pkt() - This function reads frames from the card.
* ven_rsi_read_pkt() - This function reads frames from the card.
* @common: Pointer to the driver private structure.
* @rcv_pkt_len: Received pkt length. In case of USB it is 0.
*
* Return: 0 on success, -1 on failure.
*/
int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
int ven_rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
{
u8 *frame_desc = NULL, extended_desc = 0;
u32 index = 0, length = 0, queueno = 0;
......@@ -153,7 +157,7 @@ int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
offset = *(u16 *)&frame_desc[2];
if ((actual_length < (4 + FRAME_DESC_SZ)) || (offset < 4)) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: actual_length (%d) is less than 20 or"
" offset(%d) is less than 4\n",
__func__, actual_length, offset);
......@@ -168,10 +172,14 @@ int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
switch (queueno) {
case RSI_COEX_Q:
rsi_hex_dump(MGMT_RX_ZONE,
"RX Command packet",
"RX Command co ex packet",
frame_desc + offset,
FRAME_DESC_SZ + length);
#ifdef CONFIG_VEN_RSI_COEX
rsi_coex_recv_pkt(common, (frame_desc + offset));
#else
rsi_mgmt_pkt_recv(common, (frame_desc + offset));
#endif
break;
case RSI_WIFI_DATA_Q:
rsi_hex_dump(DATA_RX_ZONE,
......@@ -191,7 +199,7 @@ int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
case RSI_WIFI_MGMT_Q:
rsi_mgmt_pkt_recv(common, (frame_desc + offset));
break;
#ifdef CONFIG_VEN_RSI_HCI
#if defined(CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX)
case RSI_BT_MGMT_Q:
case RSI_BT_DATA_Q:
rsi_hex_dump(DATA_RX_ZONE,
......@@ -203,7 +211,7 @@ int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
#endif
default:
rsi_dbg(ERR_ZONE, "%s: pkt from invalid queue: %d\n",
ven_rsi_dbg(ERR_ZONE, "%s: pkt from invalid queue: %d\n",
__func__, queueno);
goto fail;
}
......@@ -216,7 +224,7 @@ int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
fail:
return -EINVAL;
}
EXPORT_SYMBOL_GPL(rsi_read_pkt);
EXPORT_SYMBOL_GPL(ven_rsi_read_pkt);
/**
* rsi_tx_scheduler_thread() - This function is a kernel thread to send the
......@@ -243,12 +251,12 @@ static void rsi_tx_scheduler_thread(struct rsi_common *common)
}
/**
* rsi_91x_init() - This function initializes os interface operations.
* ven_rsi_91x_init() - This function initializes os interface operations.
* @void: Void.
*
* Return: Pointer to the adapter structure on success, NULL on failure .
*/
struct rsi_hw *rsi_91x_init(void)
struct rsi_hw *ven_rsi_91x_init(void)
{
struct rsi_hw *adapter = NULL;
struct rsi_common *common = NULL;
......@@ -260,7 +268,7 @@ struct rsi_hw *rsi_91x_init(void)
adapter->priv = kzalloc(sizeof(*common), GFP_KERNEL);
if (!adapter->priv) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of priv\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of priv\n",
__func__);
kfree(adapter);
return NULL;
......@@ -268,6 +276,11 @@ struct rsi_hw *rsi_91x_init(void)
common = adapter->priv;
common->priv = adapter;
common->beacon_frame = kzalloc(512, GFP_KERNEL);
if (!common->beacon_frame)
goto err;
common->beacon_frame_len = 0;
for (ii = 0; ii < NUM_SOFT_QUEUES; ii++)
skb_queue_head_init(&common->tx_queue[ii]);
......@@ -280,9 +293,16 @@ struct rsi_hw *rsi_91x_init(void)
&common->tx_thread,
rsi_tx_scheduler_thread,
"Tx-Thread")) {
rsi_dbg(ERR_ZONE, "%s: Unable to init tx thrd\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Unable to init tx thrd\n", __func__);
goto err;
}
#ifdef CONFIG_VEN_RSI_COEX
if (rsi_coex_init(common)) {
ven_rsi_dbg(ERR_ZONE, "Failed to init COEX module\n");
goto err;
}
#endif
rsi_default_ps_params(adapter);
spin_lock_init(&adapter->ps_lock);
common->uapsd_bitmap = 0;
......@@ -296,33 +316,36 @@ struct rsi_hw *rsi_91x_init(void)
kfree(adapter);
return NULL;
}
EXPORT_SYMBOL_GPL(rsi_91x_init);
EXPORT_SYMBOL_GPL(ven_rsi_91x_init);
/**
* rsi_91x_deinit() - This function de-intializes os intf operations.
* ven_rsi_91x_deinit() - This function de-intializes os intf operations.
* @adapter: Pointer to the adapter structure.
*
* Return: None.
*/
void rsi_91x_deinit(struct rsi_hw *adapter)
void ven_rsi_91x_deinit(struct rsi_hw *adapter)
{
struct rsi_common *common = adapter->priv;
u8 ii;
rsi_dbg(INFO_ZONE, "%s: Deinit core module...\n", __func__);
ven_rsi_dbg(INFO_ZONE, "%s: Deinit core module...\n", __func__);
rsi_kill_thread(&common->tx_thread);
for (ii = 0; ii < NUM_SOFT_QUEUES; ii++)
skb_queue_purge(&common->tx_queue[ii]);
#ifdef CONFIG_VEN_RSI_COEX
rsi_coex_deinit(common);
#endif
common->init_done = false;
kfree(common);
kfree(adapter->rsi_dev);
kfree(adapter);
}
EXPORT_SYMBOL_GPL(rsi_91x_deinit);
EXPORT_SYMBOL_GPL(ven_rsi_91x_deinit);
/**
* rsi_91x_hal_module_init() - This function is invoked when the module is
......@@ -334,7 +357,7 @@ EXPORT_SYMBOL_GPL(rsi_91x_deinit);
*/
static int rsi_91x_hal_module_init(void)
{
rsi_dbg(INIT_ZONE, "%s: Module init called\n", __func__);
ven_rsi_dbg(INIT_ZONE, "%s: Module init called\n", __func__);
return 0;
}
......@@ -348,7 +371,7 @@ static int rsi_91x_hal_module_init(void)
*/
static void rsi_91x_hal_module_exit(void)
{
rsi_dbg(INIT_ZONE, "%s: Module exit called\n", __func__);
ven_rsi_dbg(INIT_ZONE, "%s: Module exit called\n", __func__);
}
module_init(rsi_91x_hal_module_init);
......
......@@ -18,6 +18,10 @@
#include "rsi_mgmt.h"
#include "rsi_common.h"
#include "rsi_ps.h"
#include "rsi_hal.h"
#ifdef CONFIG_VEN_RSI_COEX
#include "rsi_coex.h"
#endif
struct rsi_config_vals dev_config_vals[] = {
{
......@@ -309,13 +313,21 @@ static void rsi_set_default_parameters(struct rsi_common *common)
common->iface_down = true;
common->endpoint = EP_2GHZ_20MHZ;
common->driver_mode = 1; /* End-to-End Mode */
#ifdef CONFIG_VEN_RSI_HCI
common->coex_mode = 4;
#if defined(CONFIG_VEN_RSI_HCI)
common->coex_mode = 2;
common->oper_mode = 4;
#elif defined(CONFIG_VEN_RSI_COEX)
common->coex_mode = 2; /*Default coex mode is WIFI alone */
common->oper_mode = 5;
#else
common->coex_mode = 1; /*Default coex mode is WIFI alone */
common->oper_mode = 1;
#endif
#ifdef CONFIG_RSI_BT_LE
common->coex_mode = 2;
common->oper_mode = 8;
#endif
common->ta_aggr = 0;
common->skip_fw_load = 0; /* Default disable skipping fw loading */
common->lp_ps_handshake_mode = 0; /* Default No HandShake mode*/
......@@ -328,6 +340,7 @@ static void rsi_set_default_parameters(struct rsi_common *common)
common->obm_ant_sel_val = 2;
common->antenna_diversity = 0;
common->tx_power = RSI_TXPOWER_MAX;
common->dtim_cnt = 2;
}
void init_bgscan_params(struct rsi_common *common)
......@@ -403,12 +416,13 @@ static int rsi_send_internal_mgmt_frame(struct rsi_common *common,
struct skb_info *tx_params;
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: SKB is NULL\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: SKB is NULL\n", __func__);
return -EINVAL;
}
skb->data[1] |= BIT(7);
tx_params = (struct skb_info *)&IEEE80211_SKB_CB(skb)->driver_data;
tx_params->flags |= INTERNAL_MGMT_PKT;
skb->priority = MGMT_SOFT_Q;
skb_queue_tail(&common->tx_queue[MGMT_SOFT_Q], skb);
rsi_set_event(&common->tx_thread.event);
return 0;
......@@ -435,7 +449,7 @@ static int rsi_load_radio_caps(struct rsi_common *common)
0xf0, 0xf0, 0xf0, 0xf0};
struct sk_buff *skb;
rsi_dbg(INFO_ZONE, "%s: Sending rate symbol req frame\n", __func__);
ven_rsi_dbg(INFO_ZONE, "%s: Sending rate symbol req frame\n", __func__);
skb = dev_alloc_skb(sizeof(struct rsi_radio_caps));
if (!skb)
......@@ -531,8 +545,7 @@ static int rsi_load_radio_caps(struct rsi_common *common)
*/
static int rsi_mgmt_pkt_to_core(struct rsi_common *common,
u8 *msg,
s32 msg_len,
u8 type)
s32 msg_len)
{
struct rsi_hw *adapter = common->priv;
struct ieee80211_tx_info *info;
......@@ -541,14 +554,14 @@ static int rsi_mgmt_pkt_to_core(struct rsi_common *common,
u8 pkt_recv;
struct sk_buff *skb;
char *buffer;
struct ieee80211_hdr *wlh;
if (type == RX_DOT11_MGMT) {
if (!adapter->sc_nvifs)
return -ENOLINK;
msg_len -= pad_bytes;
if ((msg_len <= 0) || (!msg)) {
rsi_dbg(MGMT_RX_ZONE,
ven_rsi_dbg(MGMT_RX_ZONE,
"%s: Invalid rx msg of len = %d\n",
__func__, msg_len);
return -EINVAL;
......@@ -570,12 +583,13 @@ static int rsi_mgmt_pkt_to_core(struct rsi_common *common,
rx_params = (struct skb_info *)info->driver_data;
rx_params->rssi = rsi_get_rssi(msg);
rx_params->channel = rsi_get_channel(msg);
rsi_dbg(MGMT_RX_ZONE,
ven_rsi_dbg(MGMT_RX_ZONE,
"%s: rssi=%d channel=%d\n",
__func__, rx_params->rssi, rx_params->channel);
wlh = (struct ieee80211_hdr *)skb->data;
ven_rsi_dbg(INFO_ZONE, "RX Dot11 Mgmt Pkt Type: %s\n",
dot11_pkt_type(wlh->frame_control));
rsi_indicate_pkt_to_os(common, skb);
} else
rsi_dbg(MGMT_TX_ZONE, "%s: Internal Packet\n", __func__);
return 0;
}
......@@ -593,23 +607,25 @@ static int rsi_mgmt_pkt_to_core(struct rsi_common *common,
* Return: status: 0 on success, corresponding negative error code on failure.
*/
static int rsi_send_sta_notify_frame(struct rsi_common *common,
u8 opmode,
enum opmode opmode,
u8 notify_event,
const unsigned char *bssid,
u8 qos_enable,
u16 aid)
u16 aid,
u16 sta_id)
{
struct ieee80211_vif *vif = common->priv->vifs[0];
struct sk_buff *skb = NULL;
struct rsi_peer_notify *peer_notify;
int status;
u16 vap_id = 0;
int frame_len = sizeof(*peer_notify);
rsi_dbg(MGMT_TX_ZONE, "%s: Sending station notify frame\n", __func__);
ven_rsi_dbg(MGMT_TX_ZONE, "%s: Sending station notify frame\n", __func__);
skb = dev_alloc_skb(frame_len);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
......@@ -617,7 +633,10 @@ static int rsi_send_sta_notify_frame(struct rsi_common *common,
peer_notify = (struct rsi_peer_notify *)skb->data;
peer_notify->command = 0; //cpu_to_le16(opmode << 1);
if (opmode == STA_OPMODE)
peer_notify->command = cpu_to_le16(PEER_TYPE_AP << 1);
else if (opmode == AP_OPMODE)
peer_notify->command = cpu_to_le16(PEER_TYPE_STA << 1);
switch (notify_event) {
case STA_CONNECTED:
......@@ -629,21 +648,22 @@ static int rsi_send_sta_notify_frame(struct rsi_common *common,
default:
break;
}
peer_notify->command |= cpu_to_le16((aid & 0xfff) << 4);
ether_addr_copy(peer_notify->mac_addr, bssid);
peer_notify->mpdu_density = cpu_to_le16(0x08);
peer_notify->mpdu_density = cpu_to_le16(0x08); //FIXME check this
peer_notify->sta_flags = cpu_to_le32((qos_enable) ? 1 : 0);
peer_notify->desc_word[0] = cpu_to_le16((frame_len - FRAME_DESC_SZ) |
(RSI_WIFI_MGMT_Q << 12));
peer_notify->desc_word[1] = cpu_to_le16(PEER_NOTIFY);
peer_notify->desc_word[7] |= cpu_to_le16(vap_id << 8);
peer_notify->desc_word[7] |= cpu_to_le16(sta_id | vap_id << 8);
skb_put(skb, frame_len);
status = rsi_send_internal_mgmt_frame(common, skb);
if (!status && qos_enable) {
if ((vif->type == NL80211_IFTYPE_STATION) &&
(!status) && qos_enable) {
rsi_set_contention_vals(common);
mdelay(1);
status = rsi_load_radio_caps(common);
}
......@@ -674,7 +694,7 @@ int rsi_send_aggr_params_frame(struct rsi_common *common,
skb = dev_alloc_skb(FRAME_DESC_SZ);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
......@@ -682,7 +702,7 @@ int rsi_send_aggr_params_frame(struct rsi_common *common,
memset(skb->data, 0, FRAME_DESC_SZ);
mgmt_frame = (struct rsi_mac_frame *)skb->data;
rsi_dbg(MGMT_TX_ZONE,
ven_rsi_dbg(MGMT_TX_ZONE,
"%s: Sending AMPDU indication frame\n",
__func__);
......@@ -731,11 +751,11 @@ int rsi_program_bb_rf(struct rsi_common *common)
struct sk_buff *skb;
struct rsi_mac_frame *mgmt_frame;
rsi_dbg(MGMT_TX_ZONE, "%s: Sending BB/RF program frame\n", __func__);
ven_rsi_dbg(MGMT_TX_ZONE, "%s: Sending BB/RF program frame\n", __func__);
skb = dev_alloc_skb(FRAME_DESC_SZ);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
......@@ -750,7 +770,7 @@ int rsi_program_bb_rf(struct rsi_common *common)
if (common->rf_reset) {
mgmt_frame->desc_word[7] = cpu_to_le16(RF_RESET_ENABLE);
rsi_dbg(MGMT_TX_ZONE, "%s: ===> RF RESET REQUEST SENT <===\n",
ven_rsi_dbg(MGMT_TX_ZONE, "%s: ===> RF RESET REQUEST SENT <===\n",
__func__);
common->rf_reset = 0;
}
......@@ -781,12 +801,12 @@ int rsi_set_vap_capabilities(struct rsi_common *common,
struct ieee80211_conf *conf = &hw->conf;
u16 vap_id = 0;
rsi_dbg(MGMT_TX_ZONE,
ven_rsi_dbg(MGMT_TX_ZONE,
"%s: Sending VAP capabilities frame\n", __func__);
skb = dev_alloc_skb(sizeof(struct rsi_vap_caps));
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
......@@ -849,8 +869,10 @@ int rsi_set_vap_capabilities(struct rsi_common *common,
vap_caps->default_data_rate = 0;
vap_caps->beacon_interval = cpu_to_le16(200);
vap_caps->dtim_period = cpu_to_le16(4);
vap_caps->dtim_period = cpu_to_le16(common->dtim_cnt);
// vap_caps->beacon_miss_threshold = cpu_to_le16(10);
if (mode == AP_OPMODE)
vap_caps->beacon_miss_threshold = cpu_to_le16(10);
skb_put(skb, sizeof(*vap_caps));
......@@ -873,17 +895,21 @@ int rsi_load_key(struct rsi_common *common,
u16 key_len,
u8 key_type,
u8 key_id,
u32 cipher)
u32 cipher,
s16 sta_id)
{
struct ieee80211_vif *vif = common->priv->vifs[0];
struct sk_buff *skb = NULL;
struct rsi_set_key *set_key;
u16 key_descriptor = 0;
u8 key_t1 = 0;
u8 vap_id = 0;
rsi_dbg(MGMT_TX_ZONE, "%s: Sending load key frame\n", __func__);
ven_rsi_dbg(MGMT_TX_ZONE, "%s: Sending load key frame\n", __func__);
skb = dev_alloc_skb(sizeof(struct rsi_set_key));
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
......@@ -891,6 +917,38 @@ int rsi_load_key(struct rsi_common *common,
memset(skb->data, 0, sizeof(struct rsi_set_key));
set_key = (struct rsi_set_key *)skb->data;
switch (key_type) {
case RSI_GROUP_KEY:
key_t1 = 1 << 1;
if (vif->type == NL80211_IFTYPE_AP)
key_descriptor = BIT(7);
break;
case RSI_PAIRWISE_KEY:
if ((vif->type == NL80211_IFTYPE_AP) &&
(sta_id >= RSI_MAX_ASSOC_STAS)) {
ven_rsi_dbg(INFO_ZONE, "Invalid Sta_id %d\n", sta_id);
return -1;
}
key_t1 = 0 << 1;
if ((cipher != WLAN_CIPHER_SUITE_WEP40) &&
(cipher != WLAN_CIPHER_SUITE_WEP104))
key_id = 0;
break;
}
if ((cipher == WLAN_CIPHER_SUITE_WEP40) ||
(cipher == WLAN_CIPHER_SUITE_WEP104)) {
key_descriptor |= BIT(2);
if (key_len >= 13) {
key_descriptor |= BIT(3);
}
} else if (cipher != KEY_TYPE_CLEAR) {
key_descriptor |= BIT(4);
if (cipher == WLAN_CIPHER_SUITE_TKIP)
key_descriptor |= BIT(5);
}
key_descriptor |= (key_t1 | BIT(13) | (key_id << 14));
#if 0
if ((cipher == WLAN_CIPHER_SUITE_WEP40) ||
(cipher == WLAN_CIPHER_SUITE_WEP104)) {
key_len += 1;
......@@ -905,22 +963,32 @@ int rsi_load_key(struct rsi_common *common,
key_descriptor |= BIT(5);
}
key_descriptor |= (key_type | BIT(13) | (key_id << 14));
#endif
set_key->desc_word[0] = cpu_to_le16((sizeof(struct rsi_set_key) -
FRAME_DESC_SZ) |
(RSI_WIFI_MGMT_Q << 12));
set_key->desc_word[1] = cpu_to_le16(SET_KEY_REQ);
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);
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);
}
skb_put(skb, sizeof(struct rsi_set_key));
......@@ -940,7 +1008,7 @@ int rsi_send_common_dev_params(struct rsi_common *common)
u32 *soc_gpio, len;
u16 *frame, *ulp_gpio, *desc;
rsi_dbg(INFO_ZONE, "Sending common dev config params\n");
ven_rsi_dbg(INFO_ZONE, "Sending common dev config params\n");
len = 0x20;
......@@ -985,12 +1053,12 @@ int rsi_send_common_dev_params(struct rsi_common *common)
frame_len = sizeof(struct rsi_config_vals);
rsi_dbg(MGMT_TX_ZONE,
ven_rsi_dbg(MGMT_TX_ZONE,
"%s: Sending common device config params frame\n",
__func__);
skb = dev_alloc_skb(frame_len);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Unable to allocate skb\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Unable to allocate skb\n", __func__);
return -ENOMEM;
}
......@@ -1047,10 +1115,10 @@ static int rsi_load_bootup_params(struct rsi_common *common)
struct sk_buff *skb;
struct rsi_boot_params *boot_params;
rsi_dbg(MGMT_TX_ZONE, "%s: Sending boot params frame\n", __func__);
ven_rsi_dbg(MGMT_TX_ZONE, "%s: Sending boot params frame\n", __func__);
skb = dev_alloc_skb(sizeof(struct rsi_boot_params));
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
......@@ -1058,13 +1126,13 @@ static int rsi_load_bootup_params(struct rsi_common *common)
memset(skb->data, 0, sizeof(struct rsi_boot_params));
boot_params = (struct rsi_boot_params *)skb->data;
rsi_dbg(MGMT_TX_ZONE, "%s:\n", __func__);
ven_rsi_dbg(MGMT_TX_ZONE, "%s:\n", __func__);
if (common->channel_width == BW_40MHZ) {
memcpy(&boot_params->bootup_params,
&boot_params_40,
sizeof(struct bootup_params));
rsi_dbg(MGMT_TX_ZONE,
ven_rsi_dbg(MGMT_TX_ZONE,
"%s: Packet 40MHZ <=== %d\n", __func__,
UMAC_CLK_40BW);
boot_params->desc_word[7] = cpu_to_le16(UMAC_CLK_40BW);
......@@ -1074,12 +1142,12 @@ static int rsi_load_bootup_params(struct rsi_common *common)
sizeof(struct bootup_params));
if (boot_params_20.valid != cpu_to_le32(VALID_20)) {
boot_params->desc_word[7] = cpu_to_le16(UMAC_CLK_20BW);
rsi_dbg(MGMT_TX_ZONE,
ven_rsi_dbg(MGMT_TX_ZONE,
"%s: Packet 20MHZ <=== %d\n", __func__,
UMAC_CLK_20BW);
} else {
boot_params->desc_word[7] = cpu_to_le16(UMAC_CLK_40MHZ);
rsi_dbg(MGMT_TX_ZONE,
ven_rsi_dbg(MGMT_TX_ZONE,
"%s: Packet 20MHZ <=== %d\n", __func__,
UMAC_CLK_40MHZ);
}
......@@ -1110,11 +1178,11 @@ static int rsi_send_reset_mac(struct rsi_common *common)
struct sk_buff *skb;
struct rsi_mac_frame *mgmt_frame;
rsi_dbg(MGMT_TX_ZONE, "%s: Sending reset MAC frame\n", __func__);
ven_rsi_dbg(MGMT_TX_ZONE, "%s: Sending reset MAC frame\n", __func__);
skb = dev_alloc_skb(FRAME_DESC_SZ);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
......@@ -1210,12 +1278,12 @@ int rsi_set_channel(struct rsi_common *common,
struct sk_buff *skb = NULL;
struct rsi_mac_frame *mgmt_frame;
rsi_dbg(MGMT_TX_ZONE,
ven_rsi_dbg(MGMT_TX_ZONE,
"%s: Sending scan req frame\n", __func__);
skb = dev_alloc_skb(FRAME_DESC_SZ);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
......@@ -1240,12 +1308,16 @@ int rsi_set_channel(struct rsi_common *common,
BBP_REG_WRITE |
(RSI_RF_TYPE << 4));
if (!(channel->flags & IEEE80211_CHAN_NO_IR) &&
!(channel->flags & IEEE80211_CHAN_RADAR)) {
if ((channel->flags & IEEE80211_CHAN_NO_IR) ||
(channel->flags & IEEE80211_CHAN_RADAR)) {
mgmt_frame->desc_word[4] |= BIT(15);
} else {
if (common->tx_power < channel->max_power)
mgmt_frame->desc_word[6] = cpu_to_le16(common->tx_power);
mgmt_frame->desc_word[6] =
cpu_to_le16(common->tx_power);
else
mgmt_frame->desc_word[6] = cpu_to_le16(channel->max_power);
mgmt_frame->desc_word[6] =
cpu_to_le16(channel->max_power);
}
mgmt_frame->desc_word[7] = cpu_to_le16(common->priv->dfs_region);
......@@ -1272,12 +1344,12 @@ int rsi_send_radio_params_update(struct rsi_common *common)
struct rsi_mac_frame *mgmt_frame;
struct sk_buff *skb = NULL;
rsi_dbg(MGMT_TX_ZONE,
ven_rsi_dbg(MGMT_TX_ZONE,
"%s: Sending Radio Params update frame\n", __func__);
skb = dev_alloc_skb(FRAME_DESC_SZ);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
......@@ -1307,12 +1379,12 @@ int rsi_send_vap_dynamic_update(struct rsi_common *common)
struct sk_buff *skb = NULL;
struct rsi_dynamic_s *dynamic_frame = NULL;
rsi_dbg(MGMT_TX_ZONE,
ven_rsi_dbg(MGMT_TX_ZONE,
"%s: Sending vap update indication frame\n", __func__);
skb = dev_alloc_skb(sizeof(struct rsi_dynamic_s));
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
......@@ -1360,7 +1432,7 @@ int rsi_flash_read(struct rsi_hw *adapter)
struct rsi_mac_frame *cmd_frame = NULL;
struct sk_buff *skb;
rsi_dbg(MGMT_TX_ZONE, "%s: Sending flash read frame\n", __func__);
ven_rsi_dbg(MGMT_TX_ZONE, "%s: Sending flash read frame\n", __func__);
skb = dev_alloc_skb(FRAME_DESC_SZ);
if (!skb)
......@@ -1378,13 +1450,13 @@ int rsi_flash_read(struct rsi_hw *adapter)
cmd_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
/* Number of bytes to read */
rsi_dbg(INFO_ZONE, " eeprom length 0x%x, %d\n",
ven_rsi_dbg(INFO_ZONE, " eeprom length 0x%x, %d\n",
adapter->eeprom.length, adapter->eeprom.length);
cmd_frame->desc_word[3] = cpu_to_le16(adapter->eeprom.length << 4);
cmd_frame->desc_word[2] |= cpu_to_le16(3 << 8);
if (adapter->eeprom_init) {
rsi_dbg(INFO_ZONE, "spi init sent");
ven_rsi_dbg(INFO_ZONE, "spi init sent");
cmd_frame->desc_word[2] |= cpu_to_le16(BIT(13));
}
......@@ -1453,7 +1525,8 @@ 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)
static int rsi_send_auto_rate_request(struct rsi_common *common,
u16 sta_id)
{
struct sk_buff *skb;
struct rsi_auto_rate *auto_rate;
......@@ -1465,19 +1538,19 @@ static int rsi_send_auto_rate_request(struct rsi_common *common)
u32 rate_bitmap = common->bitrate_mask[band];
u16 *selected_rates, min_rate;
rsi_dbg(MGMT_TX_ZONE,
ven_rsi_dbg(MGMT_TX_ZONE,
"%s: Sending auto rate request frame\n", __func__);
skb = dev_alloc_skb(sizeof(struct rsi_auto_rate));
skb = dev_alloc_skb(MAX_MGMT_PKT_SIZE);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
selected_rates = kzalloc(2 * RSI_TBL_SZ, GFP_KERNEL);
if (!selected_rates) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of mem\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of mem\n",
__func__);
dev_kfree_skb(skb);
return -ENOMEM;
......@@ -1497,7 +1570,8 @@ static int rsi_send_auto_rate_request(struct rsi_common *common)
auto_rate->desc_word[1] = cpu_to_le16(AUTO_RATE_IND);
if (common->channel_width == BW_40MHZ)
auto_rate->desc_word[7] |= cpu_to_le16(1);
auto_rate->desc_word[7] = cpu_to_le16(1);
auto_rate->desc_word[7] |= cpu_to_le16(sta_id << 8);
if (band == NL80211_BAND_2GHZ) {
min_rate = RSI_RATE_1;
......@@ -1560,41 +1634,93 @@ static int rsi_send_auto_rate_request(struct rsi_common *common)
auto_rate->num_supported_rates = cpu_to_le16(num_supported_rates * 2);
auto_rate->moderate_rate_inx = cpu_to_le16(num_supported_rates / 2);
auto_rate->desc_word[7] |= cpu_to_le16(0 << 8);
num_supported_rates *= 2;
auto_rate->desc_word[0] = cpu_to_le16((sizeof(*auto_rate) -
FRAME_DESC_SZ) |
(RSI_WIFI_MGMT_Q << 12));
skb_put(skb,
sizeof(struct rsi_auto_rate));
skb_put(skb, sizeof(struct rsi_auto_rate));
kfree(selected_rates);
return rsi_send_internal_mgmt_frame(common, skb);
}
/**
* rsi_channel_valid() - This function is used to check
* the user channel is valid or not.
* rsi_validate_bgscan_channels() - This function is used to validate
* the user configured bgscan channels for
* current regulatory domain
* @chn_num: It holds the user or default channel for validation.
*
* Return: 0 on success, corresponding error code on failure.
*/
static int rsi_channel_valid(u16 chn_num)
static void rsi_validate_bgscan_channels(struct rsi_hw *adapter,
struct bgscan_config_params *params)
{
int status = -1;
struct ieee80211_supported_band *sband;
struct ieee80211_channel *ch;
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,
104, 108, 112, 116, 120, 124,
128, 132, 136, 140, 149, 153,
157, 161, 165};
int ch_num, i;
int num_valid_chs = 0, cnt;
/* If user passes 0 for num of bgscan channels, take all channels */
if (params->num_user_channels == 0) {
params->num_user_channels = MAX_BGSCAN_CHANNELS;
for (cnt = 0; cnt < MAX_BGSCAN_CHANNELS; cnt++)
params->user_channels[cnt] = bgscan_channels[cnt];
}
ven_rsi_dbg(INFO_ZONE, "Final bgscan channels:\n");
for (cnt = 0; cnt < params->num_user_channels; cnt++) {
ch_num = params->user_channels[cnt];
if ((ch_num < 1) ||
((ch_num > 14) && (ch_num < 36)) ||
((ch_num > 64) && (ch_num < 100)) ||
((ch_num > 140) && (ch_num < 149)) ||
(ch_num > 165))
continue;
if ((ch_num >= 36) && (ch_num < 149) && (ch_num % 4))
continue;
if (ch_num > 14)
sband = wiphy->bands[NL80211_BAND_5GHZ];
else
sband = wiphy->bands[NL80211_BAND_2GHZ];
chn_num &= ~(BIT(15)); /* clearing DFS indication in channel num */
for (i = 0; i < sband->n_channels; i++) {
ch = &sband->channels[i];
if (((chn_num >= 1) && (chn_num <= 14)) ||
((chn_num >= 36) && (chn_num <= 64)) ||
((chn_num >= 100) && (chn_num <= 140)) ||
((chn_num >= 149) && (chn_num <= 165))) {
return 0;
if (ch->hw_value == ch_num)
break;
}
if (i >= sband->n_channels)
continue;
return status;
/* Check channel availablity for the current reg domain */
if (ch->flags & IEEE80211_CHAN_DISABLED)
continue;
params->channels2scan[num_valid_chs] = ch_num;
printk("%d ", ch_num);
if ((ch->flags & IEEE80211_CHAN_NO_IR) ||
(ch->flags & IEEE80211_CHAN_RADAR)) {
printk("[DFS]");
params->channels2scan[num_valid_chs] |=
(cpu_to_le16(BIT(15))); /* DFS indication */
}
num_valid_chs++;
printk(" ");
}
printk("\n");
params->num_bg_channels = num_valid_chs;
}
/**
......@@ -1611,22 +1737,20 @@ int rsi_send_bgscan_params(struct rsi_common *common, int enable)
struct bgscan_config_params *info = &common->bgscan_info;
struct sk_buff *skb;
u16 frame_len = sizeof(*bgscan);
u8 ii;
rsi_dbg(MGMT_TX_ZONE, "%s: Sending bgscan params frame\n", __func__);
ven_rsi_dbg(MGMT_TX_ZONE, "%s: Sending bgscan params frame\n", __func__);
rsi_validate_bgscan_channels(common->priv, info);
if (!info->num_bg_channels) {
ven_rsi_dbg(ERR_ZONE, "##### No valid bgscan channels #####\n");
return -1;
}
skb = dev_alloc_skb(frame_len);
if (!skb)
return -ENOMEM;
memset(skb->data, 0, frame_len);
if (!info->num_bg_channels) {
rsi_dbg(ERR_ZONE, "%s: BG Scan failed,No valid channel found\n",
__func__);
return -EINVAL;
}
memset(skb->data, 0, frame_len);
bgscan = (struct rsi_bgscan_params *)skb->data;
bgscan->desc_word[0] = cpu_to_le16((frame_len - FRAME_DESC_SZ) |
......@@ -1644,14 +1768,9 @@ int rsi_send_bgscan_params(struct rsi_common *common, int enable)
cpu_to_le16(info->passive_scan_duration);
bgscan->two_probe = info->two_probe;
for (ii = 0; ii < info->num_bg_channels; ii++) {
int channel = info->channels2scan[ii];
if (!rsi_channel_valid(channel))
bgscan->channels2scan[ii] =
cpu_to_le16(info->channels2scan[ii]);
}
memcpy(bgscan->channels2scan,
info->channels2scan,
info->num_bg_channels * 2);
bgscan->num_bg_channels = info->num_bg_channels;
skb_put(skb, frame_len);
......@@ -1676,7 +1795,7 @@ int rsi_send_bgscan_probe_req(struct rsi_common *common)
u16 len = 1500;
u16 pbreq_len = 0;
rsi_dbg(MGMT_TX_ZONE,
ven_rsi_dbg(MGMT_TX_ZONE,
"%s: Sending bgscan probe req frame\n", __func__);
skb = dev_alloc_skb(frame_len + len);
......@@ -1700,9 +1819,8 @@ int rsi_send_bgscan_probe_req(struct rsi_common *common)
if (common->bgscan_probe_req_len > 0) {
pbreq_len = common->bgscan_probe_req_len;
bgscan->probe_req_length = pbreq_len;
memcpy(&skb->data[frame_len], common->bgscan_probe_req, len);
*(u16 *)&skb->data[frame_len + 22] =
common->bgscan_probe_req[22] + 1;
memcpy(&skb->data[frame_len], common->bgscan_probe_req,
common->bgscan_probe_req_len);
}
bgscan->desc_word[0] = cpu_to_le16((frame_len - FRAME_DESC_SZ + pbreq_len) |
......@@ -1726,33 +1844,42 @@ int rsi_send_bgscan_probe_req(struct rsi_common *common)
* Return: None.
*/
void rsi_inform_bss_status(struct rsi_common *common,
enum opmode opmode,
u8 status,
const unsigned char *bssid,
u8 *bssid,
u8 qos_enable,
u16 aid)
u16 aid,
u16 sta_id)
{
if (status) {
if (opmode == STA_OPMODE)
common->hw_data_qs_blocked = true;
rsi_send_sta_notify_frame(common,
RSI_IFTYPE_STATION,
opmode,
STA_CONNECTED,
bssid,
qos_enable,
aid);
aid,
sta_id);
if (common->min_rate == 0xffff) {
rsi_dbg(INFO_ZONE, "Send auto rate request\n");
rsi_send_auto_rate_request(common);
ven_rsi_dbg(INFO_ZONE, "Send auto rate request\n");
rsi_send_auto_rate_request(common, sta_id);
}
if (opmode == STA_OPMODE) {
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;
rsi_send_sta_notify_frame(common,
RSI_IFTYPE_STATION,
opmode,
STA_DISCONNECTED,
bssid,
qos_enable,
aid);
aid,
sta_id);
if (opmode == STA_OPMODE)
rsi_send_block_unblock_frame(common, true);
}
}
......@@ -1770,12 +1897,12 @@ static int rsi_eeprom_read(struct rsi_common *common)
struct rsi_hw *adapter = common->priv;
struct sk_buff *skb;
rsi_dbg(MGMT_TX_ZONE,
ven_rsi_dbg(MGMT_TX_ZONE,
"%s: Sending EEPROM read req frame\n", __func__);
skb = dev_alloc_skb(FRAME_DESC_SZ);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
......@@ -1814,11 +1941,11 @@ int rsi_send_block_unblock_frame(struct rsi_common *common, bool block_event)
struct rsi_mac_frame *mgmt_frame;
struct sk_buff *skb;
rsi_dbg(MGMT_TX_ZONE, "%s: Sending block/unblock frame\n", __func__);
ven_rsi_dbg(MGMT_TX_ZONE, "%s: Sending block/unblock frame\n", __func__);
skb = dev_alloc_skb(FRAME_DESC_SZ);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
......@@ -1831,11 +1958,11 @@ int rsi_send_block_unblock_frame(struct rsi_common *common, bool block_event)
mgmt_frame->desc_word[3] = cpu_to_le16(0x1);
if (block_event == true) {
rsi_dbg(INFO_ZONE, "blocking the data qs\n");
ven_rsi_dbg(INFO_ZONE, "blocking the data qs\n");
mgmt_frame->desc_word[4] = cpu_to_le16(0xf);
mgmt_frame->desc_word[4] |= cpu_to_le16(0xf << 4);
} else {
rsi_dbg(INFO_ZONE, "unblocking the data qs\n");
ven_rsi_dbg(INFO_ZONE, "unblocking the data qs\n");
mgmt_frame->desc_word[5] = cpu_to_le16(0xf);
mgmt_frame->desc_word[5] |= cpu_to_le16(0xf << 4);
}
......@@ -1857,11 +1984,11 @@ int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word)
struct rsi_mac_frame *mgmt_frame;
struct sk_buff *skb;
rsi_dbg(MGMT_TX_ZONE, "%s: Sending RX filter frame\n", __func__);
ven_rsi_dbg(MGMT_TX_ZONE, "%s: Sending RX filter frame\n", __func__);
skb = dev_alloc_skb(FRAME_DESC_SZ);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
......@@ -1957,7 +2084,7 @@ int rsi_set_antenna(struct rsi_common *common,
skb = dev_alloc_skb(FRAME_DESC_SZ);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
......@@ -1986,11 +2113,11 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg)
struct rsi_hw *adapter = common->priv;
u8 sub_type = (msg[15] & 0xff);
rsi_dbg(MGMT_RX_ZONE, "%s: subtype=%d\n", __func__, sub_type);
ven_rsi_dbg(MGMT_RX_ZONE, "%s: subtype=%d\n", __func__, sub_type);
switch (sub_type) {
case COMMON_DEV_CONFIG:
rsi_dbg(FSM_ZONE,
ven_rsi_dbg(FSM_ZONE,
"Common Dev Config params confirm received\n");
if (common->fsm_state == FSM_COMMON_DEV_PARAMS_SENT) {
if (rsi_load_bootup_params(common)) {
......@@ -2000,7 +2127,7 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg)
common->fsm_state = FSM_BOOT_PARAMS_SENT;
}
} else {
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"%s: Received common dev config params cfm in %d state\n",
__func__, common->fsm_state);
return 0;
......@@ -2008,7 +2135,7 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg)
break;
case BOOTUP_PARAMS_REQUEST:
rsi_dbg(FSM_ZONE, "Bootup params confirmation.\n");
ven_rsi_dbg(FSM_ZONE, "Bootup params confirmation.\n");
if (common->fsm_state == FSM_BOOT_PARAMS_SENT) {
adapter->eeprom.length = (IEEE80211_ADDR_LEN +
WLAN_MAC_MAGIC_WORD_LEN +
......@@ -2020,7 +2147,7 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg)
} else
common->fsm_state = FSM_EEPROM_READ_MAC_ADDR;
} else {
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"%s: Received bootup params cfm in %d state\n",
__func__, common->fsm_state);
return 0;
......@@ -2028,12 +2155,12 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg)
break;
case EEPROM_READ:
rsi_dbg(FSM_ZONE, "EEPROM READ confirm received\n");
ven_rsi_dbg(FSM_ZONE, "EEPROM READ confirm received\n");
if (common->fsm_state == FSM_EEPROM_READ_MAC_ADDR) {
u32 msg_len = ((u16 *)msg)[0] & 0xfff;
if (msg_len <= 0) {
rsi_dbg(FSM_ZONE,
ven_rsi_dbg(FSM_ZONE,
"%s: [EEPROM_READ] Invalid len %d\n",
__func__, msg_len);
goto out;
......@@ -2054,7 +2181,7 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg)
adapter->eeprom.offset =
WLAN_EEPROM_RFTYPE_ADDR;
if (rsi_eeprom_read(common)) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed reading RF band\n",
__func__);
common->fsm_state = FSM_CARD_NOT_READY;
......@@ -2070,18 +2197,18 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg)
u32 msg_len = ((u16 *)msg)[0] & 0xfff;
if (msg_len <= 0) {
rsi_dbg(FSM_ZONE,
ven_rsi_dbg(FSM_ZONE,
"%s:[EEPROM_READ_CFM] Invalid len %d\n",
__func__, msg_len);
goto out;
}
if (msg[16] == MAGIC_WORD) {
if ((msg[17] & 0x3) == 0x3) {
rsi_dbg(INIT_ZONE,
ven_rsi_dbg(INIT_ZONE,
"Dual band supported\n");
common->band = NL80211_BAND_5GHZ;
} else if ((msg[17] & 0x3) == 0x1) {
rsi_dbg(INIT_ZONE,
ven_rsi_dbg(INIT_ZONE,
"Only 2.4Ghz band supported\n");
common->band = NL80211_BAND_2GHZ;
}
......@@ -2094,7 +2221,7 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg)
else
common->fsm_state = FSM_RESET_MAC_SENT;
} else {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Received eeprom read in %d state\n",
__func__, common->fsm_state);
return 0;
......@@ -2103,14 +2230,14 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg)
case RESET_MAC_REQ:
if (common->fsm_state == FSM_RESET_MAC_SENT) {
rsi_dbg(FSM_ZONE, "Reset MAC confirm\n");
ven_rsi_dbg(FSM_ZONE, "Reset MAC confirm\n");
if (rsi_load_radio_caps(common))
goto out;
else
common->fsm_state = FSM_RADIO_CAPS_SENT;
} else {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Received reset mac cfm in %d state\n",
__func__, common->fsm_state);
return 0;
......@@ -2124,10 +2251,10 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg)
goto out;
} else {
common->fsm_state = FSM_BB_RF_PROG_SENT;
rsi_dbg(FSM_ZONE, "Radio caps confirm\n");
ven_rsi_dbg(FSM_ZONE, "Radio caps confirm\n");
}
} else {
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"%s: Received radio caps cfm in %d state\n",
__func__, common->fsm_state);
return 0;
......@@ -2137,7 +2264,7 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg)
case BB_PROG_VALUES_REQUEST:
case RF_PROG_VALUES_REQUEST:
case BBP_PROG_IN_TA:
rsi_dbg(FSM_ZONE, "BB/RF confirmation.\n");
ven_rsi_dbg(FSM_ZONE, "BB/RF confirmation.\n");
if (common->fsm_state == FSM_BB_RF_PROG_SENT) {
common->bb_rf_prog_count--;
if (!common->bb_rf_prog_count) {
......@@ -2145,7 +2272,7 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg)
return rsi_mac80211_attach(common);
}
} else {
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"%s: Received bb_rf cfm in %d state\n",
__func__, common->fsm_state);
return 0;
......@@ -2153,30 +2280,30 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg)
break;
case AMPDU_IND:
rsi_dbg(FSM_ZONE, "AMPDU indication.\n");
ven_rsi_dbg(INFO_ZONE, "AMPDU indication.\n");
break;
case SCAN_REQUEST:
rsi_dbg(FSM_ZONE, "Scan confirm.\n");
ven_rsi_dbg(INFO_ZONE, "Scan confirm.\n");
break;
case SET_RX_FILTER:
rsi_dbg(FSM_ZONE, "RX Filter confirmation.\n");
ven_rsi_dbg(INFO_ZONE, "RX Filter confirmation.\n");
break;
case WAKEUP_SLEEP_REQUEST:
rsi_dbg(INFO_ZONE, "Wakeup/Sleep confirmation.\n");
ven_rsi_dbg(INFO_ZONE, "Wakeup/Sleep confirmation.\n");
return rsi_handle_ps_confirm(adapter, msg);
case BG_SCAN_PROBE_REQ:
rsi_dbg(INFO_ZONE, "BG scan complete event\n");
ven_rsi_dbg(INFO_ZONE, "BG scan complete event\n");
/* resume to connected channel if associated */
rsi_resume_conn_channel(adapter);
break;
default:
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"%s: Invalid TA confirm type : %x\n",
__func__, sub_type);
break;
......@@ -2184,7 +2311,7 @@ static int rsi_handle_ta_confirm(struct rsi_common *common, u8 *msg)
return 0;
out:
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Unable to send pkt/Invalid frame received\n",
__func__);
return -EINVAL;
......@@ -2201,14 +2328,14 @@ int rsi_handle_card_ready(struct rsi_common *common)
{
switch (common->fsm_state) {
case FSM_CARD_NOT_READY:
rsi_dbg(INIT_ZONE, "Card ready indication from wlan.\n");
ven_rsi_dbg(INIT_ZONE, "Card ready indication from Common HAL\n");
rsi_set_default_parameters(common);
if (rsi_send_common_dev_params(common) < 0)
return -EINVAL;
common->fsm_state = FSM_COMMON_DEV_PARAMS_SENT;
break;
case FSM_COMMON_DEV_PARAMS_SENT:
rsi_dbg(INIT_ZONE, "Common dev config params confirm\n");
ven_rsi_dbg(INIT_ZONE, "Common dev config params confirm\n");
if (rsi_load_bootup_params(common)) {
common->fsm_state = FSM_CARD_NOT_READY;
return -EINVAL;
......@@ -2216,7 +2343,7 @@ int rsi_handle_card_ready(struct rsi_common *common)
common->fsm_state = FSM_BOOT_PARAMS_SENT;
break;
default:
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: card ready indication in invalid state %d.\n",
__func__, common->fsm_state);
return -EINVAL;
......@@ -2225,6 +2352,45 @@ int rsi_handle_card_ready(struct rsi_common *common)
return 0;
}
#ifdef CONFIG_RSI_WOW
int rsi_send_wowlan_request(struct rsi_common *common, u16 flags,
struct cfg80211_wowlan *wowlan)
{
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);
skb_put(skb, length);
return rsi_send_internal_mgmt_frame(common, skb);
}
#endif
/**
* rsi_mgmt_pkt_recv() - This function processes the management packets
* received from the hardware.
......@@ -2243,44 +2409,59 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg)
return rsi_handle_ta_confirm(common, msg);
case CARD_READY_IND:
ven_rsi_dbg(INIT_ZONE, "CARD READY INDICATION FROM WLAN.\n");
return rsi_handle_card_ready(common);
case TX_STATUS_IND:
if (msg[15] == PROBEREQ_CONFIRM) {
common->mgmt_q_block = false;
rsi_dbg(INFO_ZONE, "Mgmt queue unblocked\n");
ven_rsi_dbg(INFO_ZONE, "Mgmt queue unblocked\n");
}
break;
case PS_NOTIFY_IND:
rsi_dbg(FSM_ZONE, "Powersave notify indication.\n");
ven_rsi_dbg(FSM_ZONE, "Powersave notify indication.\n");
break;
case SLEEP_NOTIFY_IND:
rsi_dbg(FSM_ZONE, "Sleep notify indication.\n");
ven_rsi_dbg(FSM_ZONE, "Sleep notify indication.\n");
break;
case DECRYPT_ERROR_IND:
rsi_dbg(INFO_ZONE, "Error in decrypt.\n");
ven_rsi_dbg(INFO_ZONE, "Error in decrypt.\n");
break;
case DEBUG_IND:
rsi_dbg(INFO_ZONE, "Debugging indication.\n");
ven_rsi_dbg(INFO_ZONE, "Debugging indication.\n");
break;
case RX_MISC_IND:
rsi_dbg(INFO_ZONE, "RX misc indication.\n");
ven_rsi_dbg(INFO_ZONE, "RX misc indication.\n");
break;
case HW_BMISS_EVENT:
rsi_dbg(INFO_ZONE, "Hardware beacon miss event\n");
ven_rsi_dbg(INFO_ZONE, "Hardware beacon miss event\n");
rsi_indicate_bcnmiss(common);
//if (common->bgscan_en)
rsi_resume_conn_channel(common->priv);
break;
case BEACON_EVENT_IND:
ven_rsi_dbg(INFO_ZONE, "Beacon event\n");
if (common->fsm_state != FSM_MAC_INIT_DONE)
return -1;
if (common->iface_down)
return -1;
mutex_lock(&common->mutex);
rsi_send_beacon(common);
mutex_unlock(&common->mutex);
break;
case RX_DOT11_MGMT:
return rsi_mgmt_pkt_to_core(common, msg, msg_len);
default:
return rsi_mgmt_pkt_to_core(common, msg, msg_len, msg_type);
ven_rsi_dbg(INFO_ZONE, "Cmd Frame Type: %d\n", msg_type);
break;
}
return 0;
......
......@@ -57,7 +57,7 @@ char *str_psstate(enum ps_state state)
static inline void rsi_modify_ps_state(struct rsi_hw *adapter,
enum ps_state nstate)
{
rsi_dbg(INFO_ZONE, "PS state changed %s => %s\n",
ven_rsi_dbg(INFO_ZONE, "PS state changed %s => %s\n",
str_psstate(adapter->ps_state),
str_psstate(nstate));
......@@ -100,14 +100,14 @@ EXPORT_SYMBOL_GPL(rsi_default_ps_params);
void rsi_enable_ps(struct rsi_hw *adapter)
{
if (adapter->ps_state != PS_NONE) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Cannot accept enable PS in %s state\n",
__func__, str_psstate(adapter->ps_state));
return;
}
if (rsi_send_ps_request(adapter, true)) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to send PS request to device\n",
__func__);
return;
......@@ -126,14 +126,14 @@ void rsi_enable_ps(struct rsi_hw *adapter)
void rsi_disable_ps(struct rsi_hw *adapter)
{
if (adapter->ps_state != PS_ENABLED) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Cannot accept disable PS in %s state\n",
__func__, str_psstate(adapter->ps_state));
return;
}
if (rsi_send_ps_request(adapter, false)) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to send PS request to device\n",
__func__);
return;
......@@ -155,14 +155,14 @@ void rsi_conf_uapsd(struct rsi_hw *adapter)
return;
if (rsi_send_ps_request(adapter, false)) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to send PS request to device\n",
__func__);
return;
}
if (rsi_send_ps_request(adapter, true)) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to send PS request to device\n",
__func__);
}
......@@ -192,7 +192,7 @@ int rsi_handle_ps_confirm(struct rsi_hw *adapter, u8 *msg)
rsi_modify_ps_state(adapter, PS_NONE);
break;
default:
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"Invalid PS confirm type %x in state %s\n",
cfm_type, str_psstate(adapter->ps_state));
return -1;
......
......@@ -130,6 +130,11 @@ static int rsi_issue_sdiocommand(struct sdio_func *func,
return err;
}
static void rsi_dummy_isr(struct sdio_func *function)
{
return;
}
/**
* rsi_handle_interrupt() - This function is called upon the occurrence
* of an interrupt.
......@@ -140,10 +145,12 @@ static int rsi_issue_sdiocommand(struct sdio_func *func,
static void rsi_handle_interrupt(struct sdio_func *function)
{
struct rsi_hw *adapter = sdio_get_drvdata(function);
struct rsi_91x_sdiodev *dev =
(struct rsi_91x_sdiodev *)adapter->rsi_dev;
sdio_release_host(function);
dev->sdio_irq_task = current;
rsi_interrupt_handler(adapter);
sdio_claim_host(function);
dev->sdio_irq_task = NULL;
}
void rsi_gspi_init(struct rsi_hw *adapter)
......@@ -196,12 +203,12 @@ static void rsi_reset_chip(struct rsi_hw *adapter)
u8 sdio_interrupt_status = 0;
u8 request = 1;
rsi_dbg(INFO_ZONE, "Writing disable to wakeup register\n");
ven_rsi_dbg(INFO_ZONE, "Writing disable to wakeup register\n");
if (rsi_sdio_write_register(adapter,
0,
SDIO_WAKEUP_REG,
&request) < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to Write SDIO WAKEUP REG\n", __func__);
return;
}
......@@ -209,16 +216,16 @@ static void rsi_reset_chip(struct rsi_hw *adapter)
if (rsi_sdio_read_register(adapter,
RSI_FN1_INT_REGISTER,
&sdio_interrupt_status) < 0) {
rsi_dbg(ERR_ZONE, "%s: Failed to Read Intr Status Register\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed to Read Intr Status Register\n",
__func__);
return;
}
rsi_dbg(INFO_ZONE, "%s: Intr Status Register value = %d \n",
ven_rsi_dbg(INFO_ZONE, "%s: Intr Status Register value = %d \n",
__func__, sdio_interrupt_status);
/* Put TA on hold */
if (rsi_sdio_master_access_msword(adapter, 0x2200)) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Unable to set ms word to common reg\n",
__func__);
return ;
......@@ -229,7 +236,7 @@ static void rsi_reset_chip(struct rsi_hw *adapter)
TA_HOLD_THREAD_REG | SD_REQUEST_MASTER,
(u8 *)&data,
4)) {
rsi_dbg(ERR_ZONE, "%s: Unable to hold TA threads\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Unable to hold TA threads\n", __func__);
return ;
}
......@@ -267,22 +274,27 @@ static void rsi_reset_card(struct sdio_func *pfunction)
u8 cmd52_resp = 0;
u32 clock, resp, i;
u16 rca;
u32 cmd_delay = 0;
#if 0
#ifdef CONFIG_DELL_BOARD
/* Reset 9110 chip */
ret = rsi_cmd52writebyte(pfunction->card,
err = rsi_cmd52writebyte(pfunction->card,
SDIO_CCCR_ABORT,
(1 << 3));
/* Card will not send any response as it is getting reset immediately
* Hence expect a timeout status from host controller
*/
if (ret != -ETIMEDOUT)
rsi_dbg(ERR_ZONE, "%s: Reset failed : %d\n", __func__, ret);
if (err != -ETIMEDOUT)
ven_rsi_dbg(ERR_ZONE, "%s: Reset failed : %d\n", __func__, err);
cmd_delay = 20;
#else
cmd_delay = 2;
#endif
/* Wait for few milli seconds to get rid of residue charges if any */
msleep(2);
msleep(cmd_delay);
/* Initialize the SDIO card */
host->ios.vdd = bit;
......@@ -297,7 +309,7 @@ static void rsi_reset_card(struct sdio_func *pfunction)
* This delay should be sufficient to allow the power supply
* to reach the minimum voltage.
*/
msleep(2);
msleep(cmd_delay);
host->ios.clock = host->f_min;
host->ios.power_mode = MMC_POWER_ON;
......@@ -307,12 +319,12 @@ static void rsi_reset_card(struct sdio_func *pfunction)
* This delay must be at least 74 clock sizes, or 1 ms, or the
* time required to reach a stable voltage.
*/
msleep(2);
msleep(cmd_delay);
/* Issue CMD0. Goto idle state */
host->ios.chip_select = MMC_CS_HIGH;
host->ops->set_ios(host, &host->ios);
msleep(1);
msleep(cmd_delay);
err = rsi_issue_sdiocommand(pfunction,
MMC_GO_IDLE_STATE,
0,
......@@ -320,14 +332,17 @@ static void rsi_reset_card(struct sdio_func *pfunction)
NULL);
host->ios.chip_select = MMC_CS_DONTCARE;
host->ops->set_ios(host, &host->ios);
msleep(1);
msleep(cmd_delay);
host->use_spi_crc = 0;
if (err)
rsi_dbg(ERR_ZONE, "%s: CMD0 failed : %d\n", __func__, err);
ven_rsi_dbg(ERR_ZONE, "%s: CMD0 failed : %d\n", __func__, err);
// if (!host->ocr_avail) {
#ifdef CONFIG_DELL_BOARD
if (!host->ocr_avail) {
#else
if (1) {
#endif
/* Issue CMD5, arg = 0 */
err = rsi_issue_sdiocommand(pfunction,
SD_IO_SEND_OP_COND,
......@@ -335,31 +350,39 @@ static void rsi_reset_card(struct sdio_func *pfunction)
(MMC_RSP_R4 | MMC_CMD_BCR),
&resp);
if (err)
rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n",
ven_rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n",
__func__, err);
#ifdef CONFIG_DELL_BOARD
host->ocr_avail = resp;
#else
card->ocr = resp;
#endif
}
/* Issue CMD5, arg = ocr. Wait till card is ready */
for (i = 0; i < 100; i++) {
err = rsi_issue_sdiocommand(pfunction,
SD_IO_SEND_OP_COND,
#ifdef CONFIG_DELL_BOARD
host->ocr_avail,
#else
card->ocr,
#endif
(MMC_RSP_R4 | MMC_CMD_BCR),
&resp);
if (err) {
rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n",
ven_rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n",
__func__, err);
break;
}
if (resp & MMC_CARD_BUSY)
break;
msleep(10);
msleep(cmd_delay);
}
if ((i == 100) || (err)) {
rsi_dbg(ERR_ZONE, "%s: card in not ready : %d %d\n",
ven_rsi_dbg(ERR_ZONE, "%s: card in not ready : %d %d\n",
__func__, i, err);
return;
}
......@@ -371,7 +394,7 @@ static void rsi_reset_card(struct sdio_func *pfunction)
(MMC_RSP_R6 | MMC_CMD_BCR),
&resp);
if (err) {
rsi_dbg(ERR_ZONE, "%s: CMD3 failed : %d\n", __func__, err);
ven_rsi_dbg(ERR_ZONE, "%s: CMD3 failed : %d\n", __func__, err);
return;
}
rca = resp >> 16;
......@@ -385,23 +408,23 @@ static void rsi_reset_card(struct sdio_func *pfunction)
(MMC_RSP_R1 | MMC_CMD_AC),
NULL);
if (err) {
rsi_dbg(ERR_ZONE, "%s: CMD7 failed : %d\n", __func__, err);
ven_rsi_dbg(ERR_ZONE, "%s: CMD7 failed : %d\n", __func__, err);
return;
}
/* Enable high speed */
if (card->host->caps & MMC_CAP_SD_HIGHSPEED) {
rsi_dbg(ERR_ZONE, "%s: Set high speed mode\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Set high speed mode\n", __func__);
err = rsi_cmd52readbyte(card, SDIO_CCCR_SPEED, &cmd52_resp);
if (err) {
rsi_dbg(ERR_ZONE, "%s: CCCR speed reg read failed: %d\n",
ven_rsi_dbg(ERR_ZONE, "%s: CCCR speed reg read failed: %d\n",
__func__, err);
} else {
err = rsi_cmd52writebyte(card,
SDIO_CCCR_SPEED,
(cmd52_resp | SDIO_SPEED_EHS));
if (err) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: CCR speed regwrite failed %d\n",
__func__, err);
return;
......@@ -430,13 +453,14 @@ static void rsi_reset_card(struct sdio_func *pfunction)
(SDIO_BUS_CD_DISABLE |
SDIO_BUS_WIDTH_4BIT));
if (err) {
rsi_dbg(ERR_ZONE, "%s: Set bus mode failed : %d\n",
ven_rsi_dbg(ERR_ZONE, "%s: Set bus mode failed : %d\n",
__func__, err);
return;
}
host->ios.bus_width = MMC_BUS_WIDTH_4;
host->ops->set_ios(host, &host->ios);
}
mdelay(cmd_delay);
}
/**
......@@ -473,12 +497,12 @@ static int rsi_setblocklength(struct rsi_hw *adapter, u32 length)
(struct rsi_91x_sdiodev *)adapter->rsi_dev;
int status;
rsi_dbg(INIT_ZONE, "%s: Setting the block length\n", __func__);
ven_rsi_dbg(INIT_ZONE, "%s: Setting the block length\n", __func__);
status = sdio_set_block_size(dev->pfunction, length);
dev->pfunction->max_blksize = 256;
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"%s: Operational blk length is %d\n", __func__, length);
return status;
}
......@@ -501,7 +525,7 @@ static int rsi_setupcard(struct rsi_hw *adapter)
adapter->tx_blk_size = dev->tx_blk_size;
status = rsi_setblocklength(adapter, dev->tx_blk_size);
if (status)
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Unable to set block length\n", __func__);
return status;
}
......@@ -524,6 +548,7 @@ int rsi_sdio_read_register(struct rsi_hw *adapter,
u8 fun_num = 0;
int status;
if (likely(dev->sdio_irq_task != current))
sdio_claim_host(dev->pfunction);
if (fun_num == 0)
......@@ -531,6 +556,7 @@ int rsi_sdio_read_register(struct rsi_hw *adapter,
else
*data = sdio_readb(dev->pfunction, addr, &status);
if (likely(dev->sdio_irq_task != current))
sdio_release_host(dev->pfunction);
return status;
......@@ -555,6 +581,7 @@ int rsi_sdio_write_register(struct rsi_hw *adapter,
(struct rsi_91x_sdiodev *)adapter->rsi_dev;
int status = 0;
if (likely(dev->sdio_irq_task != current))
sdio_claim_host(dev->pfunction);
if (function == 0)
......@@ -562,6 +589,7 @@ int rsi_sdio_write_register(struct rsi_hw *adapter,
else
sdio_writeb(dev->pfunction, *data, addr, &status);
if (likely(dev->sdio_irq_task != current))
sdio_release_host(dev->pfunction);
return status;
......@@ -584,7 +612,7 @@ void rsi_sdio_ack_intr(struct rsi_hw *adapter, u8 int_bit)
SD_REQUEST_MASTER),
&int_bit);
if (status)
rsi_dbg(ERR_ZONE, "%s: unable to send ack\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: unable to send ack\n", __func__);
}
/**
......@@ -606,14 +634,16 @@ int rsi_sdio_read_register_multiple(struct rsi_hw *adapter,
(struct rsi_91x_sdiodev *)adapter->rsi_dev;
u32 status = 0;
if (likely(dev->sdio_irq_task != current))
sdio_claim_host(dev->pfunction);
status = sdio_readsb(dev->pfunction, data, addr, count);
if (likely(dev->sdio_irq_task != current))
sdio_release_host(dev->pfunction);
if (status != 0)
rsi_dbg(ERR_ZONE, "%s: Synch Cmd53 read failed\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Synch Cmd53 read failed\n", __func__);
return status;
}
......@@ -637,25 +667,27 @@ int rsi_sdio_write_register_multiple(struct rsi_hw *adapter,
int status;
if (dev->write_fail > 1) {
rsi_dbg(ERR_ZONE, "%s: Stopping card writes\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Stopping card writes\n", __func__);
return 0;
} else if (dev->write_fail == 1) {
/**
* Assuming it is a CRC failure, we want to allow another
* card write
*/
rsi_dbg(ERR_ZONE, "%s: Continue card writes\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Continue card writes\n", __func__);
dev->write_fail++;
}
if (likely(dev->sdio_irq_task != current))
sdio_claim_host(dev->pfunction);
status = sdio_writesb(dev->pfunction, addr, data, count);
if (likely(dev->sdio_irq_task != current))
sdio_release_host(dev->pfunction);
if (status) {
rsi_dbg(ERR_ZONE, "%s: Synch Cmd53 write failed %d\n",
ven_rsi_dbg(ERR_ZONE, "%s: Synch Cmd53 write failed %d\n",
__func__, status);
dev->write_fail = 2;
} else {
......@@ -679,12 +711,12 @@ int rsi_sdio_load_data_master_write(struct rsi_hw *adapter,
num_blocks = instructions_sz / block_size;
msb_address = base_address >> 16;
rsi_dbg(INFO_ZONE, "ins_size: %d\n", instructions_sz);
rsi_dbg(INFO_ZONE, "num_blocks: %d\n", num_blocks);
ven_rsi_dbg(INFO_ZONE, "ins_size: %d\n", instructions_sz);
ven_rsi_dbg(INFO_ZONE, "num_blocks: %d\n", num_blocks);
/* Loading DM ms word in the sdio slave */
if (rsi_sdio_master_access_msword(adapter, msb_address)) {
rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", __func__);
return -1;
}
......@@ -695,10 +727,10 @@ int rsi_sdio_load_data_master_write(struct rsi_hw *adapter,
if (rsi_sdio_write_register_multiple(adapter,
lsb_address | SD_REQUEST_MASTER,
temp_buf, block_size)) {
rsi_dbg(ERR_ZONE, "%s: failed to write\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: failed to write\n", __func__);
return -1;
}
rsi_dbg(INFO_ZONE, "%s: loading block: %d\n", __func__, ii);
ven_rsi_dbg(INFO_ZONE, "%s: loading block: %d\n", __func__, ii);
base_address += block_size;
if ((base_address >> 16) != msb_address) {
......@@ -707,7 +739,7 @@ int rsi_sdio_load_data_master_write(struct rsi_hw *adapter,
/* Loading DM ms word in the sdio slave */
if (rsi_sdio_master_access_msword(adapter,
msb_address)) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Unable to set ms word reg\n",
__func__);
return -1;
......@@ -727,15 +759,13 @@ int rsi_sdio_load_data_master_write(struct rsi_hw *adapter,
instructions_sz % block_size)) {
return -1;
}
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"Written Last Block in Address 0x%x Successfully\n",
offset | SD_REQUEST_MASTER);
}
return 0;
}
#define align_address(a) ((unsigned long)(a) & ~0x7)
int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr,
u32 *read_buf, u16 size)
{
......@@ -744,11 +774,11 @@ int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr,
u32 align[2] = {};
u32 addr_on_bus;
data = (u32 *)align_address(&align[1]);
data = PTR_ALIGN(&align[0], 8);
ms_addr = (addr >> 16);
if (rsi_sdio_master_access_msword(adapter, ms_addr)) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Unable to set ms word to common reg\n",
__func__);
return -1;
......@@ -766,7 +796,7 @@ int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr,
if (rsi_sdio_read_register_multiple(adapter,
(addr_on_bus | SD_REQUEST_MASTER),
(u8 *)data, 4)) {
rsi_dbg(ERR_ZONE, "%s: AHB register read failed\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: AHB register read failed\n", __func__);
return -1;
}
if (size == 2) {
......@@ -798,27 +828,27 @@ int rsi_sdio_master_reg_write(struct rsi_hw *adapter,
u16 size)
{
unsigned long data1[2];
unsigned long *data_alligned;
unsigned long *data_aligned;
data_alligned = (unsigned long *)align_address(&data1[1]);
data_aligned = PTR_ALIGN(&data1[0], 8);
if (size == 2) {
*data_alligned = ((data << 16) | (data & 0xFFFF));
*data_aligned = ((data << 16) | (data & 0xFFFF));
} else if (size == 1) {
u32 temp_data;
temp_data = (data & 0xFF);
*data_alligned = ((temp_data << 24) |
*data_aligned = ((temp_data << 24) |
(temp_data << 16) |
(temp_data << 8) |
(temp_data));
} else {
*data_alligned = data;
*data_aligned = data;
}
size = 4;
if (rsi_sdio_master_access_msword(adapter, (addr >> 16))) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Unable to set ms word to common reg\n",
__func__);
return -1;
......@@ -828,8 +858,8 @@ int rsi_sdio_master_reg_write(struct rsi_hw *adapter,
/* Bringing TA out of reset */
if (rsi_sdio_write_register_multiple(adapter,
(addr | SD_REQUEST_MASTER),
(u8 *)data_alligned, size)) {
rsi_dbg(ERR_ZONE,
(u8 *)data_aligned, size)) {
ven_rsi_dbg(ERR_ZONE,
"%s: Unable to do AHB reg write\n", __func__);
return -1;
}
......@@ -872,9 +902,9 @@ int rsi_sdio_host_intf_write_pkt(struct rsi_hw *adapter,
pkt,
length);
if (status < 0)
rsi_dbg(ERR_ZONE, "%s: Unable to write onto the card: %d\n",
ven_rsi_dbg(ERR_ZONE, "%s: Unable to write onto the card: %d\n",
__func__, status);
rsi_dbg(DATA_TX_ZONE, "%s: Successfully written onto card\n", __func__);
ven_rsi_dbg(DATA_TX_ZONE, "%s: Successfully written onto card\n", __func__);
return status;
}
......@@ -894,7 +924,7 @@ int rsi_sdio_host_intf_read_pkt(struct rsi_hw *adapter,
int status = -EINVAL;
if (!length) {
rsi_dbg(ERR_ZONE, "%s: Pkt size is zero\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Pkt size is zero\n", __func__);
return status;
}
......@@ -904,7 +934,7 @@ int rsi_sdio_host_intf_read_pkt(struct rsi_hw *adapter,
length);
if (status)
rsi_dbg(ERR_ZONE, "%s: Failed to read frame: %d\n", __func__,
ven_rsi_dbg(ERR_ZONE, "%s: Failed to read frame: %d\n", __func__,
status);
return status;
}
......@@ -929,18 +959,19 @@ static int rsi_init_sdio_interface(struct rsi_hw *adapter,
return status;
adapter->rsi_dev = rsi_91x_dev;
rsi_91x_dev->sdio_irq_task = NULL;
sdio_claim_host(pfunction);
pfunction->enable_timeout = 100;
status = sdio_enable_func(pfunction);
if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed to enable interface\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Failed to enable interface\n", __func__);
sdio_release_host(pfunction);
return status;
}
rsi_dbg(INIT_ZONE, "%s: Enabled the interface\n", __func__);
ven_rsi_dbg(INIT_ZONE, "%s: Enabled the interface\n", __func__);
rsi_91x_dev->pfunction = pfunction;
adapter->device = &pfunction->dev;
......@@ -949,21 +980,23 @@ static int rsi_init_sdio_interface(struct rsi_hw *adapter,
status = rsi_setupcard(adapter);
if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed to setup card\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Failed to setup card\n", __func__);
goto fail;
}
rsi_dbg(INIT_ZONE, "%s: Setup card successfully\n", __func__);
ven_rsi_dbg(INIT_ZONE, "%s: Setup card successfully\n", __func__);
status = rsi_init_sdio_slave_regs(adapter);
if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed to init slave regs\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Failed to init slave regs\n", __func__);
goto fail;
}
sdio_release_host(pfunction);
adapter->determine_event_timeout = rsi_sdio_determine_event_timeout;
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;
......@@ -1000,11 +1033,11 @@ static int rsi_probe(struct sdio_func *pfunction,
{
struct rsi_hw *adapter;
rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__);
ven_rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__);
adapter = rsi_91x_init();
adapter = ven_rsi_91x_init();
if (!adapter) {
rsi_dbg(ERR_ZONE, "%s: Failed to init os intf ops\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed to init os intf ops\n",
__func__);
return 1;
}
......@@ -1012,42 +1045,52 @@ static int rsi_probe(struct sdio_func *pfunction,
adapter->host_intf_ops = &sdio_host_intf_ops;
if (rsi_init_sdio_interface(adapter, pfunction)) {
rsi_dbg(ERR_ZONE, "%s: Failed to init sdio interface\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed to init sdio interface\n",
__func__);
goto fail;
}
sdio_claim_host(pfunction);
if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) {
rsi_dbg(ERR_ZONE, "%s: Failed to request IRQ\n", __func__);
// if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) {
if (sdio_claim_irq(pfunction, rsi_dummy_isr)) {
ven_rsi_dbg(ERR_ZONE, "%s: Failed to request IRQ\n", __func__);
sdio_release_host(pfunction);
goto fail;
}
sdio_release_host(pfunction);
rsi_dbg(INIT_ZONE, "%s: Registered Interrupt handler\n", __func__);
ven_rsi_dbg(INIT_ZONE, "%s: Registered Interrupt handler\n", __func__);
if (rsi_hal_device_init(adapter)) {
rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", __func__);
sdio_claim_host(pfunction);
sdio_release_irq(pfunction);
sdio_disable_func(pfunction);
sdio_release_host(pfunction);
goto fail;
}
rsi_dbg(INFO_ZONE, "===> RSI Device Init Done <===\n");
ven_rsi_dbg(INFO_ZONE, "===> RSI Device Init Done <===\n");
if (rsi_sdio_master_access_msword(adapter, MISC_CFG_BASE_ADDR)) {
rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", __func__);
return -1;
}
rsi_dbg(INIT_ZONE, "%s: Setting ms word to 0x41050000\n", __func__);
ven_rsi_dbg(INIT_ZONE, "%s: Setting ms word to 0x41050000\n", __func__);
sdio_claim_host(pfunction);
sdio_release_irq(pfunction);
mdelay(10);
if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) {
ven_rsi_dbg(ERR_ZONE, "%s: Failed to request IRQ\n", __func__);
sdio_release_host(pfunction);
goto fail;
}
sdio_release_host(pfunction);
return 0;
fail:
rsi_91x_deinit(adapter);
rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__);
ven_rsi_91x_deinit(adapter);
ven_rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__);
return 1;
}
......@@ -1067,13 +1110,20 @@ static void rsi_disconnect(struct sdio_func *pfunction)
dev = (struct rsi_91x_sdiodev *)adapter->rsi_dev;
rsi_mac80211_detach(adapter);
mdelay(10);
#ifdef CONFIG_VEN_RSI_HCI
rsi_hci_detach(adapter->priv);
#if defined(CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX)
#if defined(CONFIG_DELL_BOARD)
if (adapter->rsi_host_intf == RSI_HOST_INTF_SDIO)
rsi_kill_thread(&adapter->priv->hci_thread);
#endif
#endif
ven_rsi_mac80211_detach(adapter);
mdelay(10);
#if defined(CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX)
rsi_hci_detach(adapter->priv);
mdelay(10);
#endif
sdio_claim_host(pfunction);
sdio_release_irq(pfunction);
sdio_release_host(pfunction);
......@@ -1088,21 +1138,80 @@ static void rsi_disconnect(struct sdio_func *pfunction)
sdio_disable_func(pfunction);
sdio_release_host(pfunction);
dev->write_fail = 2;
rsi_91x_deinit(adapter);
rsi_dbg(ERR_ZONE, "##### RSI SDIO device disconnected #####\n");
ven_rsi_91x_deinit(adapter);
ven_rsi_dbg(ERR_ZONE, "##### RSI SDIO device disconnected #####\n");
}
#ifdef CONFIG_PM
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) {
ven_rsi_dbg(ERR_ZONE, "set sdio keep pwr flag failed: %d\n", ret);
return ret;
}
/* sdio irq wakes up host */
ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
if (ret)
ven_rsi_dbg(ERR_ZONE,"set sdio wake irq flag failed: %d\n", ret);
return ret;
}
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)
{
/* Not yet implemented */
return -ENOSYS;
int ret = 0;
struct sdio_func *pfunction = dev_to_sdio_func(dev);
struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
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);
if (ret && ret != -ENOTCONN)
ven_rsi_dbg(ERR_ZONE,"wow suspend failed: %d\n", ret);
return 0;
}
static int rsi_resume(struct device *dev)
int rsi_resume(struct device *dev)
{
/* Not yet implemented */
return -ENOSYS;
ven_rsi_dbg(INFO_ZONE,"rsi_sdio_resume returning\n");
return 0;
}
static const struct dev_pm_ops rsi_pm_ops = {
......@@ -1142,7 +1251,7 @@ static int rsi_module_init(void)
int ret;
ret = sdio_register_driver(&rsi_driver);
rsi_dbg(INIT_ZONE, "%s: Registering driver\n", __func__);
ven_rsi_dbg(INIT_ZONE, "%s: Registering driver\n", __func__);
return ret;
}
......@@ -1155,7 +1264,7 @@ static int rsi_module_init(void)
static void rsi_module_exit(void)
{
sdio_unregister_driver(&rsi_driver);
rsi_dbg(INFO_ZONE, "%s: Unregistering driver\n", __func__);
ven_rsi_dbg(INFO_ZONE, "%s: Unregistering driver\n", __func__);
}
module_init(rsi_module_init);
......
......@@ -37,7 +37,7 @@ int rsi_sdio_master_access_msword(struct rsi_hw *adapter,
byte = (u8)(ms_word & 0x00FF);
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"%s: MASTER_ACCESS_MSBYTE:0x%x\n", __func__, byte);
status = rsi_sdio_write_register(adapter,
......@@ -45,7 +45,7 @@ int rsi_sdio_master_access_msword(struct rsi_hw *adapter,
SDIO_MASTER_ACCESS_MSBYTE,
&byte);
if (status) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: fail to access MASTER_ACCESS_MSBYTE\n",
__func__);
return -1;
......@@ -53,7 +53,7 @@ int rsi_sdio_master_access_msword(struct rsi_hw *adapter,
byte = (u8)(ms_word >> 8);
rsi_dbg(INFO_ZONE, "%s:MASTER_ACCESS_LSBYTE:0x%x\n", __func__, byte);
ven_rsi_dbg(INFO_ZONE, "%s:MASTER_ACCESS_LSBYTE:0x%x\n", __func__, byte);
status = rsi_sdio_write_register(adapter,
function,
SDIO_MASTER_ACCESS_LSBYTE,
......@@ -91,7 +91,7 @@ static int rsi_process_pkt(struct rsi_common *common)
SDIO_RX_NUM_BLOCKS_REG,
&value);
if (status) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to read pkt length from the card:\n",
__func__);
return status;
......@@ -118,7 +118,7 @@ static int rsi_process_pkt(struct rsi_common *common)
common->rx_data_pkt = kmalloc(rcv_pkt_len, GFP_KERNEL);
if (!common->rx_data_pkt) {
rsi_dbg(ERR_ZONE, "%s: Failed in memory allocation\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in memory allocation\n",
__func__);
return -ENOMEM;
}
......@@ -127,12 +127,12 @@ static int rsi_process_pkt(struct rsi_common *common)
common->rx_data_pkt,
rcv_pkt_len);
if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed to read packet from card\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed to read packet from card\n",
__func__);
goto fail;
}
status = rsi_read_pkt(common, common->rx_data_pkt, rcv_pkt_len);
status = ven_rsi_read_pkt(common, common->rx_data_pkt, rcv_pkt_len);
fail:
kfree(common->rx_data_pkt);
......@@ -161,7 +161,7 @@ int rsi_init_sdio_slave_regs(struct rsi_hw *adapter)
SDIO_NXT_RD_DELAY2,
&byte);
if (status) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to write SDIO_NXT_RD_DELAY2\n",
__func__);
return -1;
......@@ -169,7 +169,7 @@ int rsi_init_sdio_slave_regs(struct rsi_hw *adapter)
}
if (dev->sdio_high_speed_enable) {
rsi_dbg(INIT_ZONE, "%s: Enabling SDIO High speed\n", __func__);
ven_rsi_dbg(INIT_ZONE, "%s: Enabling SDIO High speed\n", __func__);
byte = 0x3;
status = rsi_sdio_write_register(adapter,
......@@ -177,7 +177,7 @@ int rsi_init_sdio_slave_regs(struct rsi_hw *adapter)
SDIO_REG_HIGH_SPEED,
&byte);
if (status) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to enable SDIO high speed\n",
__func__);
return -1;
......@@ -185,7 +185,7 @@ int rsi_init_sdio_slave_regs(struct rsi_hw *adapter)
}
/* This tells SDIO FIFO when to start read to host */
rsi_dbg(INIT_ZONE, "%s: Initialzing SDIO read start level\n", __func__);
ven_rsi_dbg(INIT_ZONE, "%s: Initialzing SDIO read start level\n", __func__);
byte = 0x24;
status = rsi_sdio_write_register(adapter,
......@@ -193,12 +193,12 @@ int rsi_init_sdio_slave_regs(struct rsi_hw *adapter)
SDIO_READ_START_LVL,
&byte);
if (status) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to write SDIO_READ_START_LVL\n", __func__);
return -1;
}
rsi_dbg(INIT_ZONE, "%s: Initialzing FIFO ctrl registers\n", __func__);
ven_rsi_dbg(INIT_ZONE, "%s: Initialzing FIFO ctrl registers\n", __func__);
byte = (128 - 32);
status = rsi_sdio_write_register(adapter,
......@@ -206,7 +206,7 @@ int rsi_init_sdio_slave_regs(struct rsi_hw *adapter)
SDIO_READ_FIFO_CTL,
&byte);
if (status) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to write SDIO_READ_FIFO_CTL\n", __func__);
return -1;
}
......@@ -217,7 +217,7 @@ int rsi_init_sdio_slave_regs(struct rsi_hw *adapter)
SDIO_WRITE_FIFO_CTL,
&byte);
if (status) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to write SDIO_WRITE_FIFO_CTL\n", __func__);
return -1;
}
......@@ -225,6 +225,22 @@ int rsi_init_sdio_slave_regs(struct rsi_hw *adapter)
return 0;
}
int rsi_read_intr_status_reg(struct rsi_hw *adapter)
{
u8 isr_status = 0;
struct rsi_common *common = adapter->priv;
int status;
status = rsi_sdio_read_register(common->priv,
RSI_FN1_INT_REGISTER,
&isr_status);
isr_status &= 0xE;
if(isr_status & BIT(MSDU_PKT_PENDING))
adapter->isr_pending = 1;
return 0;
}
/**
* rsi_interrupt_handler() - This function read and process SDIO interrupts.
* @adapter: Pointer to the adapter structure.
......@@ -249,7 +265,7 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
RSI_FN1_INT_REGISTER,
&isr_status);
if (status) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to Read Intr Status Register\n",
__func__);
mutex_unlock(&common->rx_lock);
......@@ -269,7 +285,7 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
// adapter->interrupt_status = isr_status;
// isr_status &= 0xE;
rsi_dbg(ISR_ZONE, "%s: Intr_status = %x %d %d\n",
ven_rsi_dbg(ISR_ZONE, "%s: Intr_status = %x %d %d\n",
__func__, isr_status, (1 << MSDU_PKT_PENDING),
(1 << FW_ASSERT_IND));
......@@ -286,25 +302,26 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
(1 << PKT_BUFF_AVAILABLE));
rsi_set_event(&common->tx_thread.event);
rsi_dbg(ISR_ZONE,
ven_rsi_dbg(ISR_ZONE,
"%s: ==> BUFFER_AVAILABLE <==\n",
__func__);
dev->rx_info.buf_available_counter++;
dev->buff_status_updated = 1;
break;
case FIRMWARE_ASSERT_IND:
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: ==> FIRMWARE Assert <==\n",
__func__);
status = rsi_sdio_read_register(common->priv,
SDIO_FW_STATUS_REG,
&fw_status);
if (status) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to read f/w reg\n",
__func__);
} else {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Firmware Status is 0x%x\n",
__func__, fw_status);
rsi_sdio_ack_intr(common->priv,
......@@ -315,12 +332,12 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
break;
case MSDU_PACKET_PENDING:
rsi_dbg(ISR_ZONE, "Pkt pending interrupt\n");
ven_rsi_dbg(ISR_ZONE, "Pkt pending interrupt\n");
dev->rx_info.total_sdio_msdu_pending_intr++;
status = rsi_process_pkt(common);
if (status) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to read pkt\n",
__func__);
mutex_unlock(&common->rx_lock);
......@@ -331,7 +348,7 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
rsi_sdio_ack_intr(common->priv, isr_status);
dev->rx_info.total_sdio_unknown_intr++;
isr_status = 0;
rsi_dbg(ISR_ZONE,
ven_rsi_dbg(ISR_ZONE,
"Unknown Interrupt %x\n",
isr_status);
break;
......@@ -359,13 +376,22 @@ 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;
if ((!dev->buff_status_updated) && counter) {
counter--;
goto out;
}
#endif
dev->buff_status_updated = 0;
status = rsi_sdio_read_register(common->priv,
RSI_DEVICE_BUFFER_STATUS_REGISTER,
&buf_status);
if (status) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed to read status register\n", __func__);
return -1;
}
......@@ -393,7 +419,9 @@ int rsi_sdio_read_buffer_status_register(struct rsi_hw *adapter, u8 q_num)
} else {
dev->rx_info.semi_buffer_full = false;
}
// (dev->rx_info.semi_buffer_full ? (counter = 4) : (counter = 1));
out:
if ((q_num == MGMT_SOFT_Q) && (dev->rx_info.mgmt_buffer_full))
return QUEUE_FULL;
......
......@@ -64,12 +64,12 @@ static int rsi_usb_card_write(struct rsi_hw *adapter,
&transfer,
HZ * 5);
if (status < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"Card write failed with error code :%d\n", status);
dev->write_fail = 1;
goto fail;
}
rsi_dbg(MGMT_TX_ZONE, "%s: Sent Message successfully\n", __func__);
ven_rsi_dbg(MGMT_TX_ZONE, "%s: Sent Message successfully\n", __func__);
fail:
return status;
......@@ -94,7 +94,7 @@ static int rsi_write_multiple(struct rsi_hw *adapter,
(struct rsi_91x_usbdev *)adapter->rsi_dev;
if (!adapter || addr == 0) {
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"%s: Unable to write to card\n", __func__);
return -1;
}
......@@ -141,7 +141,7 @@ static int rsi_usb_reg_read(struct usb_device *usbdev,
*value = (buf[0] | (buf[1] << 8));
if (status < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Reg read failed with error code :%d\n",
__func__, status);
}
......@@ -185,7 +185,7 @@ static int rsi_usb_reg_write(struct usb_device *usbdev,
len,
USB_CTRL_SET_TIMEOUT);
if (status < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Reg write failed with error code :%d\n",
__func__, status);
}
......@@ -235,7 +235,7 @@ int rsi_usb_read_register_multiple(struct rsi_hw *adapter,
transfer,
USB_CTRL_GET_TIMEOUT);
if (status < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"Reg read failed with error code :%d\n",
status);
kfree(buf);
......@@ -293,7 +293,7 @@ int rsi_usb_write_register_multiple(struct rsi_hw *adapter,
transfer,
USB_CTRL_SET_TIMEOUT);
if (status < 0) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"Reg write failed with error code :%d\n",
status);
kfree(buf);
......@@ -324,7 +324,7 @@ static void rsi_rx_done_handler(struct urb *urb)
return;
if (urb->actual_length <= 0) {
rsi_dbg(INFO_ZONE, "%s: Zero length packet\n", __func__);
ven_rsi_dbg(INFO_ZONE, "%s: Zero length packet\n", __func__);
return;
}
rx_cb->pend = 1;
......@@ -356,7 +356,7 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num)
status = usb_submit_urb(urb, GFP_KERNEL);
if (status)
rsi_dbg(ERR_ZONE, "%s: Failed in urb submission\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Failed in urb submission\n", __func__);
return status;
}
......@@ -377,7 +377,7 @@ int rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter,
u32 queueno = ((pkt[1] >> 4) & 0x7);
u8 endpoint;
rsi_dbg(DATA_TX_ZONE, "%s: queueno=%d\n", __func__, queueno);
ven_rsi_dbg(DATA_TX_ZONE, "%s: queueno=%d\n", __func__, queueno);
endpoint = ((queueno == RSI_WIFI_MGMT_Q || queueno == RSI_COEX_Q ||
queueno == RSI_WIFI_DATA_Q) ?
MGMT_EP : DATA_EP);
......@@ -421,7 +421,7 @@ int rsi_usb_load_data_master_write(struct rsi_hw *adapter,
u8 temp_buf[256];
num_blocks = instructions_sz / block_size;
rsi_dbg(INFO_ZONE, "num_blocks: %d\n", num_blocks);
ven_rsi_dbg(INFO_ZONE, "num_blocks: %d\n", num_blocks);
for (cur_indx = 0, ii = 0;
ii < num_blocks;
......@@ -434,7 +434,7 @@ int rsi_usb_load_data_master_write(struct rsi_hw *adapter,
block_size)) < 0)
return -1;
rsi_dbg(INFO_ZONE, "%s: loading block: %d\n", __func__, ii);
ven_rsi_dbg(INFO_ZONE, "%s: loading block: %d\n", __func__, ii);
base_address += block_size;
}
......@@ -447,7 +447,7 @@ int rsi_usb_load_data_master_write(struct rsi_hw *adapter,
(u8 *)temp_buf,
instructions_sz % block_size)) < 0)
return -1;
rsi_dbg(INFO_ZONE,
ven_rsi_dbg(INFO_ZONE,
"Written Last Block in Address 0x%x Successfully\n",
cur_indx);
}
......@@ -464,12 +464,12 @@ static void rsi_deinit_usb_interface(struct rsi_hw *adapter)
{
struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
rsi_dbg(INFO_ZONE, "Deinitializing USB interface...\n");
ven_rsi_dbg(INFO_ZONE, "Deinitializing USB interface...\n");
rsi_kill_thread(&dev->rx_thread);
kfree(dev->rx_cb[0].rx_buffer);
usb_free_urb(dev->rx_cb[0].rx_urb);
#ifdef CONFIG_VEN_RSI_HCI
#if defined (CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX)
kfree(dev->rx_cb[1].rx_buffer);
usb_free_urb(dev->rx_cb[1].rx_urb);
#endif
......@@ -556,7 +556,7 @@ static int rsi_usb_init_rx(struct rsi_hw *adapter)
rx_cb->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!rx_cb->rx_urb) {
rsi_dbg(ERR_ZONE, "Failed alloc rx urb[%d]\n", idx);
ven_rsi_dbg(ERR_ZONE, "Failed alloc rx urb[%d]\n", idx);
goto err;
}
rx_cb->rx_urb->transfer_buffer = rx_cb->rx_buffer;
......@@ -614,7 +614,7 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
/* Initialize RX handle */
if (rsi_usb_init_rx(adapter)) {
rsi_dbg(ERR_ZONE, "Failed to init RX handle\n");
ven_rsi_dbg(ERR_ZONE, "Failed to init RX handle\n");
goto fail_1;
}
......@@ -632,7 +632,7 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
status = rsi_create_kthread(common, &rsi_dev->rx_thread,
rsi_usb_rx_thread, "RX-Thread");
if (status) {
rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__);
goto fail_2;
}
......@@ -642,7 +642,7 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
adapter->num_debugfs_entries = MAX_DEBUGFS_ENTRIES - 1;
#endif
rsi_dbg(INIT_ZONE, "%s: Enabled the interface\n", __func__);
ven_rsi_dbg(INIT_ZONE, "%s: Enabled the interface\n", __func__);
return 0;
fail_2:
......@@ -710,7 +710,7 @@ static int rsi_reset_card(struct rsi_hw *adapter)
{
u16 temp[4] = {0};
rsi_dbg(INFO_ZONE, "Resetting Card...\n");
ven_rsi_dbg(INFO_ZONE, "Resetting Card...\n");
#define TA_HOLD_REG 0x22000844
rsi_usb_master_reg_write(adapter, TA_HOLD_REG, 0xE, 4);
......@@ -749,11 +749,11 @@ static int rsi_reset_card(struct rsi_hw *adapter)
temp, 32)) < 0) {
goto fail;
}
rsi_dbg(INFO_ZONE, "Card Reset Done\n");
ven_rsi_dbg(INFO_ZONE, "Card Reset Done\n");
return 0;
fail:
rsi_dbg(ERR_ZONE, "Reset card Failed\n");
ven_rsi_dbg(ERR_ZONE, "Reset card Failed\n");
return -1;
}
......@@ -774,11 +774,11 @@ static int rsi_probe(struct usb_interface *pfunction,
u32 fw_status = 0;
int status = 0;
rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__);
ven_rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__);
adapter = rsi_91x_init();
adapter = ven_rsi_91x_init();
if (!adapter) {
rsi_dbg(ERR_ZONE, "%s: Failed to init os intf ops\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed to init os intf ops\n",
__func__);
return -ENOMEM;
}
......@@ -786,12 +786,12 @@ static int rsi_probe(struct usb_interface *pfunction,
status = rsi_init_usb_interface(adapter, pfunction);
if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed to init usb interface\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed to init usb interface\n",
__func__);
goto err;
}
rsi_dbg(ERR_ZONE, "%s: Initialized os intf ops\n", __func__);
ven_rsi_dbg(ERR_ZONE, "%s: Initialized os intf ops\n", __func__);
dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
......@@ -802,21 +802,21 @@ static int rsi_probe(struct usb_interface *pfunction,
fw_status &= 1;
if (!fw_status) {
rsi_dbg(INIT_ZONE, "Loading firmware...\n");
ven_rsi_dbg(INIT_ZONE, "Loading firmware...\n");
status = rsi_hal_device_init(adapter);
if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed in device init\n",
ven_rsi_dbg(ERR_ZONE, "%s: Failed in device init\n",
__func__);
goto err1;
}
rsi_dbg(INIT_ZONE, "%s: Device Init Done\n", __func__);
ven_rsi_dbg(INIT_ZONE, "%s: Device Init Done\n", __func__);
}
status = rsi_rx_urb_submit(adapter, 1 /* RX_WLAN_EP */);
if (status)
goto err1;
#ifdef CONFIG_VEN_RSI_HCI
#if defined(CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX)
status = rsi_rx_urb_submit(adapter, 2 /* RX_BT_EP */);
if (status)
goto err1;
......@@ -826,8 +826,8 @@ static int rsi_probe(struct usb_interface *pfunction,
err1:
rsi_deinit_usb_interface(adapter);
err:
rsi_91x_deinit(adapter);
rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__);
ven_rsi_91x_deinit(adapter);
ven_rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__);
return status;
}
......@@ -844,22 +844,22 @@ static void rsi_disconnect(struct usb_interface *pfunction)
if (!adapter)
return;
rsi_mac80211_detach(adapter);
rsi_dbg(INFO_ZONE, "mac80211 detach done\n");
ven_rsi_mac80211_detach(adapter);
ven_rsi_dbg(INFO_ZONE, "mac80211 detach done\n");
rsi_reset_card(adapter);
#ifdef CONFIG_VEN_RSI_HCI
#if defined(CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX)
rsi_hci_detach(adapter->priv);
rsi_dbg(INFO_ZONE, "HCI Detach Done\n");
ven_rsi_dbg(INFO_ZONE, "HCI Detach Done\n");
#endif
rsi_reset_card(adapter);
rsi_deinit_usb_interface(adapter);
rsi_dbg(INFO_ZONE, "USB interface down\n");
ven_rsi_dbg(INFO_ZONE, "USB interface down\n");
rsi_91x_deinit(adapter);
ven_rsi_91x_deinit(adapter);
rsi_dbg(INFO_ZONE, "%s: Deinitialization completed\n", __func__);
ven_rsi_dbg(INFO_ZONE, "%s: Deinitialization completed\n", __func__);
}
#ifdef CONFIG_PM
......@@ -898,7 +898,7 @@ static struct usb_driver rsi_driver = {
static int __init rsi_usb_module_init(void)
{
rsi_dbg(INIT_ZONE,
ven_rsi_dbg(INIT_ZONE,
"=====> RSI USB Module Initialize <=====\n");
return usb_register(&rsi_driver);
}
......
......@@ -44,9 +44,9 @@ void rsi_usb_rx_thread(struct rsi_common *common)
continue;
mutex_lock(&common->rx_lock);
status = rsi_read_pkt(common, rx_cb->rx_buffer, 0);
status = ven_rsi_read_pkt(common, rx_cb->rx_buffer, 0);
if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed To read data",
ven_rsi_dbg(ERR_ZONE, "%s: Failed To read data",
__func__);
mutex_unlock(&common->rx_lock);
break;
......@@ -55,7 +55,7 @@ void rsi_usb_rx_thread(struct rsi_common *common)
mutex_unlock(&common->rx_lock);
if (adapter->rx_urb_submit(adapter, rx_cb->ep_num)) {
rsi_dbg(ERR_ZONE,
ven_rsi_dbg(ERR_ZONE,
"%s: Failed in urb submission", __func__);
break;
}
......@@ -64,7 +64,7 @@ void rsi_usb_rx_thread(struct rsi_common *common)
} while (1);
rsi_dbg(INFO_ZONE, "%s: Terminated USB RX thread\n", __func__);
ven_rsi_dbg(INFO_ZONE, "%s: Terminated USB RX thread\n", __func__);
atomic_inc(&dev->rx_thread.thread_done);
complete_and_exit(&dev->rx_thread.completion, 0);
}
......
......@@ -21,6 +21,7 @@
#define RSI_COEX_TXQ_MAX_PKTS 64
#define RSI_COEX_TXQ_WATER_MARK 50
#define COMMON_CARD_READY_IND 0
#define COEX_Q 0
#define BT_Q 1
......@@ -39,14 +40,14 @@ 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 rsi_thread coex_tx_thread;
struct mutex coex_tx_lock;
};
int rsi_coex_init(struct rsi_common *common);
int rsi_coex_send_pkt(struct rsi_common *common,
struct sk_buff *skb,
u8 proto_type);
int rsi_coex_recv_pkt(struct rsi_common *common, u8 *msg);
void rsi_coex_deinit(struct rsi_common *common);
#endif
......@@ -80,12 +80,14 @@ static inline int rsi_kill_thread(struct rsi_thread *handle)
return kthread_stop(handle->task);
}
void rsi_mac80211_detach(struct rsi_hw *hw);
void ven_rsi_mac80211_detach(struct rsi_hw *hw);
u16 rsi_get_connected_channel(struct rsi_hw *adapter);
struct rsi_hw *rsi_91x_init(void);
void rsi_91x_deinit(struct rsi_hw *adapter);
int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len);
struct rsi_hw *ven_rsi_91x_init(void);
void ven_rsi_91x_deinit(struct rsi_hw *adapter);
int ven_rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len);
void rsi_indicate_bcnmiss(struct rsi_common *common);
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);
#endif
......@@ -14,8 +14,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __RSI_DEBUGFS_H__
#define __RSI_DEBUGFS_H__
#ifndef __VEN_RSI_DEBUGFS_H__
#define __VEN_RSI_DEBUGFS_H__
#include "rsi_main.h"
#include <linux/debugfs.h>
......
......@@ -145,8 +145,11 @@ struct ta_metadata {
unsigned int address;
};
int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb);
int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb);
int rsi_hal_device_init(struct rsi_hw *adapter);
int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb);
int rsi_send_bt_pkt(struct rsi_common *common, struct sk_buff *skb);
int rsi_send_beacon(struct rsi_common *common);
#endif
......@@ -93,13 +93,11 @@ struct rsi_hci_adapter {
struct hci_dev *hdev;
struct genl_cb *gcb;
struct sk_buff_head hci_tx_queue;
int fsm_state;
};
int rsi_genl_recv (struct sk_buff *skb, struct genl_info *info);
int rsi_hci_attach (struct rsi_common *common);
void rsi_hci_detach(struct rsi_common *common);
//int rsi_hci_recv_pkt(struct rsi_hci_adapter *h_adapter, u8 *pkt);
int rsi_hci_recv_pkt(struct rsi_common *common, u8 *pkt);
#endif
......@@ -28,7 +28,7 @@ struct rsi_hw;
#include "rsi_ps.h"
#define ERR_ZONE BIT(0) /* Error Msgs */
#define INFO_ZONE BIT(1) /* General Debug Msgs */
#define INFO_ZONE BIT(1) /* Generic Debug Msgs */
#define INIT_ZONE BIT(2) /* Driver Init Msgs */
#define MGMT_TX_ZONE BIT(3) /* TX Mgmt Path Msgs */
#define MGMT_RX_ZONE BIT(4) /* RX Mgmt Path Msgs */
......@@ -47,8 +47,8 @@ struct rsi_hw;
#define FSM_BB_RF_PROG_SENT 7
#define FSM_MAC_INIT_DONE 8
extern u32 rsi_zone_enabled;
extern __printf(2, 3) void rsi_dbg(u32 zone, const char *fmt, ...);
extern u32 ven_rsi_zone_enabled;
extern __printf(2, 3) void ven_rsi_dbg(u32 zone, const char *fmt, ...);
void rsi_hex_dump(u32 zone, char *msg_str, const u8 *msg, u32 len);
#define RSI_MAX_VIFS 1
......@@ -73,7 +73,6 @@ void rsi_hex_dump(u32 zone, char *msg_str, const u8 *msg, u32 len);
*/
#define BROADCAST_HW_Q 9
#define BEACON_HW_Q 11
#define MAX_NUM_SCAN_BGCHANS 24
/* Queue information */
#define RSI_COEX_Q 0x0
......@@ -87,10 +86,13 @@ void rsi_hex_dump(u32 zone, char *msg_str, const u8 *msg, u32 len);
#define IEEE80211_MGMT_FRAME 0x00
#define IEEE80211_CTL_FRAME 0x04
#define RSI_MAX_ASSOC_STAS 4
#define IEEE80211_QOS_TID 0x0f
#define IEEE80211_NONQOS_TID 16
#define MAX_DEBUGFS_ENTRIES 5
#define MAX_BGSCAN_CHANNELS 38
#define TID_TO_WME_AC(_tid) ( \
((_tid) == 0 || (_tid) == 3) ? BE_Q : \
......@@ -117,6 +119,8 @@ struct skb_info {
u16 channel;
s8 tid;
s8 sta_id;
u8 internal_hdr_size;
struct ieee80211_sta *sta;
};
enum edca_queue {
......@@ -174,11 +178,13 @@ struct bgscan_config_params {
u16 bgscan_threshold;
u16 roam_threshold;
u16 bgscan_periodicity;
u8 num_user_channels;
u8 num_bg_channels;
u8 two_probe;
u16 active_scan_duration;
u16 passive_scan_duration;
u16 channels2scan[MAX_NUM_SCAN_BGCHANS];
u16 user_channels[MAX_BGSCAN_CHANNELS];
u16 channels2scan[MAX_BGSCAN_CHANNELS];
};
struct xtended_desc {
......@@ -187,6 +193,12 @@ struct xtended_desc {
u16 reserved;
};
struct rsi_sta {
struct ieee80211_sta *sta;
s16 sta_id;
u16 seq_no[IEEE80211_NUM_ACS];
};
struct rsi_hw;
struct rsi_common {
......@@ -198,6 +210,7 @@ struct rsi_common {
struct version_info fw_ver;
struct rsi_thread tx_thread;
struct rsi_thread hci_thread;
struct sk_buff_head tx_queue[NUM_EDCA_QUEUES + 1];
/* Mutex declaration */
struct mutex mutex;
......@@ -224,6 +237,7 @@ struct rsi_common {
/* state related */
u32 fsm_state;
u8 bt_fsm_state;
bool init_done;
u8 bb_rf_prog_count;
bool iface_down;
......@@ -274,13 +288,23 @@ struct rsi_common {
int tx_power;
u8 ant_in_use;
#ifdef CONFIG_VEN_RSI_HCI
#if defined (CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX)
void *hci_adapter;
#endif
#ifdef CONFIG_VEN_RSI_COEX
void *coex_cb;
#endif
/* AP mode related */
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;
struct ieee80211_channel *ap_channel;
};
enum host_intf {
......@@ -326,7 +350,7 @@ struct rsi_hw {
enum ps_state ps_state;
struct rsi_ps_info ps_info;
spinlock_t ps_lock;
u32 isr_pending;
#ifdef CONFIG_VEN_RSI_DEBUGFS
struct rsi_debugfs *dfsentry;
u8 num_debugfs_entries;
......@@ -342,12 +366,15 @@ struct rsi_hw {
u32 interrupt_status;
u8 dfs_region;
char country[2];
void *rsi_dev;
struct rsi_host_intf_ops *host_intf_ops;
int (*check_hw_queue_status)(struct rsi_hw *adapter, u8 q_num);
int (*rx_urb_submit)(struct rsi_hw *adapter, u8 ep_num);
int (*determine_event_timeout)(struct rsi_hw *adapter);
void (*process_isr_hci)(struct rsi_hw *adapter);
int (*check_intr_status_reg)(struct rsi_hw *adapter);
};
struct rsi_host_intf_ops {
......
......@@ -66,6 +66,10 @@ enum rx_cmd_type {
ANTENNA_SELECT = 0xf,
};
#ifdef RSI_ENABLE_WOW
#define WOW_MAX_FILTERS_PER_LIST 16
#define WOW_PATTERN_SIZE 256
#endif
#define EAPOL4_CONFIRM 1
#define PROBEREQ_CONFIRM 2
#define NULLDATA_CONFIRM 3
......@@ -80,9 +84,12 @@ enum rx_cmd_type {
#define BBP_REG_WRITE 0
#define RF_RESET_ENABLE BIT(3)
#define RATE_INFO_ENABLE BIT(0)
#define MORE_DATA_PRESENT BIT(1)
#define RSI_BROADCAST_PKT BIT(9)
#define RSI_DESC_11G_MODE BIT(7)
#define RSI_DESC_REQUIRE_CFM_TO_HOST BIT(10)
#define ADD_DELTA_TSF_VAP_ID BIT(11)
#define FETCH_RETRY_CNT_FRM_HST BIT(12)
#define UPPER_20_ENABLE (0x2 << 12)
#define LOWER_20_ENABLE (0x4 << 12)
......@@ -202,9 +209,28 @@ enum rx_cmd_type {
IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
#define IEEE80211_STA_SP_ALL_PKTS 0x00
/* Tx data frame format */
#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 BEACON_FRAME BIT(11)
#define DTIM_BEACON BIT(10) | BIT(11)
#define INSERT_TSF BIT(15)
#define INSERT_SEQ_NO BIT(2)
#ifdef CONFIG_PM
#define RSI_WOW_ANY BIT(0)
#define RSI_WOW_SUPPORTS_GTK_REKEY BIT(3)
#define RSI_WOW_MAGIC_PKT BIT(4)
#define RSI_WOW_DISCONNECT BIT(5)
#endif
enum opmode {
AP_OPMODE,
STA_OPMODE = 1,
AP_OPMODE = 2
};
enum vap_status {
......@@ -213,6 +239,14 @@ enum vap_status {
VAP_UPDATE = 3
};
enum peer_type {
PEER_TYPE_AP,
PEER_TYPE_STA,
PEER_TYPE_P2P_GO,
PEER_TYPE_P2P_CLIENT,
PEER_TYPE_IBSS
};
/*
* Subtypes for RX_MISC_IND frame
* Frame sub types from LMAC to Host
......@@ -337,7 +371,7 @@ struct rsi_bgscan_params {
u8 two_probe;
__le16 active_scan_duration;
__le16 passive_scan_duration;
__le16 channels2scan[MAX_NUM_SCAN_BGCHANS];
__le16 channels2scan[MAX_BGSCAN_CHANNELS];
} __packed;
struct rsi_bgscan_probe {
......@@ -456,6 +490,14 @@ struct rsi_request_ps {
u16 ps_num_dtim_intervals;
} __packed;
struct rsi_wowlan_req {
__le16 desc_word[8];
u8 sourceid[ETH_ALEN];
u16 wow_flags;
u16 host_sleep_status;
} __packed;
static inline u32 rsi_get_queueno(u8 *addr, u16 offset)
{
return (le16_to_cpu(*(__le16 *)&addr[offset]) & 0x7000) >> 12;
......@@ -487,13 +529,14 @@ int rsi_set_vap_capabilities(struct rsi_common *common, enum opmode mode,
int rsi_send_aggr_params_frame(struct rsi_common *common, u16 tid,
u16 ssn, u8 buf_size, u8 event);
int rsi_load_key(struct rsi_common *common, u8 *data, u16 key_len,
u8 key_type, u8 key_id, u32 cipher);
u8 key_type, u8 key_id, u32 cipher, s16 sta_id);
int rsi_set_channel(struct rsi_common *common,
struct ieee80211_channel *channel);
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, u8 status,
const u8 *bssid, u8 qos_enable, u16 aid);
void rsi_inform_bss_status(struct rsi_common *common, enum opmode opmode,
u8 status, u8 *bssid, u8 qos_enable, u16 aid,
u16 sta_id);
void rsi_indicate_pkt_to_os(struct rsi_common *common, struct sk_buff *skb);
int rsi_mac80211_attach(struct rsi_common *common);
int rsi_send_bgscan_params(struct rsi_common *common, int enable);
......@@ -513,5 +556,9 @@ int rsi_send_radio_params_update(struct rsi_common *common);
void init_bgscan_params(struct rsi_common *common);
int rsi_set_antenna(struct rsi_common *common, u8 antenna);
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);
#endif
#endif
......@@ -112,7 +112,7 @@ struct receive_info {
struct rsi_91x_sdiodev {
struct sdio_func *pfunction;
struct task_struct *in_sdio_litefi_irq;
struct task_struct *sdio_irq_task;
struct receive_info rx_info;
u32 next_read_delay;
u32 sdio_high_speed_enable;
......@@ -121,6 +121,7 @@ struct rsi_91x_sdiodev {
u8 prev_desc[16];
u32 tx_blk_size;
u8 write_fail;
u8 buff_status_updated;
};
void rsi_interrupt_handler(struct rsi_hw *adapter);
......@@ -149,4 +150,5 @@ int rsi_sdio_master_reg_write(struct rsi_hw *adapter,
void rsi_sdio_ack_intr(struct rsi_hw *adapter, u8 int_bit);
int rsi_sdio_determine_event_timeout(struct rsi_hw *adapter);
int rsi_sdio_read_buffer_status_register(struct rsi_hw *adapter, u8 q_num);
int rsi_read_intr_status_reg(struct rsi_hw *adapter);
#endif
......@@ -29,7 +29,7 @@
#define RSI_USB_TX_HEAD_ROOM 128
#define MAX_TX_URBS 1
#ifdef CONFIG_VEN_RSI_HCI
#if defined (CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX)
#define MAX_RX_URBS 2
#else
#define MAX_RX_URBS 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment