This patch series includes some fixes and enhancements in Tx and Rx
data paths. Connection in open security and data traffic has been
verified with SDIO and USB variants of 9113 chipset.
Amitkumar Karwar (1):
rsi: correct the logic of deriving queue number
Karun Eagalapati (14):
rsi: fix sdio card reset problem
rsi: chip reset for SDIO interface
rsi: correct SDIO disconnect path handling
rsi: card reset for USB interface
rsi: USB tx headroom cleanup
rsi: rename USB endpoint macros
rsi: choose correct endpoint based on queue.
rsi: set immediate wakeup bit
rsi: separate function for management packet descriptor
rsi: rename variable in_sdio_litefi_irq
rsi: Optimise sdio claim and release host
rsi: SDIO Rx packet processing enhancement
rsi: use separate mutex lock for receive thread
rsi: Rename mutex tx_rxlock to the tx_lock.
Prameela Rani Garnepudi (1):
rsi: changes in eeprom read frame
pavani.muthyala (4):
rsi: management frame descriptor preparation cleanup
rsi: data packet descriptor code cleanup
rsi: data packet descriptor enhancements
rsi: separate function for data packet descriptor
drivers/net/wireless/rsi/rsi_91x_core.c | 10 +-
drivers/net/wireless/rsi/rsi_91x_hal.c | 269 ++++++++++++++++++----------
drivers/net/wireless/rsi/rsi_91x_main.c | 2 +-
drivers/net/wireless/rsi/rsi_91x_mgmt.c | 87 ++++++---
drivers/net/wireless/rsi/rsi_91x_sdio.c | 154 ++++++++++++----
drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 44 +++--
drivers/net/wireless/rsi/rsi_91x_usb.c | 118 +++++++++---
drivers/net/wireless/rsi/rsi_91x_usb_ops.c | 6 +-
drivers/net/wireless/rsi/rsi_hal.h | 82 +++++++++
drivers/net/wireless/rsi/rsi_main.h | 29 ++-
drivers/net/wireless/rsi/rsi_mgmt.h | 40 ++++-
drivers/net/wireless/rsi/rsi_sdio.h | 4 +-
drivers/net/wireless/rsi/rsi_usb.h | 5 +-
13 files changed, 644 insertions(+), 206 deletions(-)
--
2.7.4
From: Karun Eagalapati <[email protected]>
management packet descriptor preparation code is moved a separate
function.
Signed-off-by: Karun Eagalapati <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_hal.c | 135 +++++++++++++++++++++------------
drivers/net/wireless/rsi/rsi_hal.h | 10 +--
drivers/net/wireless/rsi/rsi_main.h | 7 ++
drivers/net/wireless/rsi/rsi_mgmt.h | 1 +
4 files changed, 101 insertions(+), 52 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index 461352a..bc2ee8c 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -25,6 +25,92 @@ static struct ta_metadata metadata_flash_content[] = {
{"rsi/rs9113_wlan_qspi.rps", 0x00010000},
};
+/* This function prepares descriptor for given management packet */
+
+static 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_conf *conf = &adapter->hw->conf;
+ struct ieee80211_vif *vif = NULL;
+ struct rsi_mgmt_desc *mgmt_desc;
+ struct skb_info *tx_params;
+ int status = -EINVAL;
+ struct ieee80211_bss_conf *bss = NULL;
+ struct xtended_desc *xtend_desc = NULL;
+ u8 header_size;
+ u32 dword_align_bytes = 0;
+
+ info = IEEE80211_SKB_CB(skb);
+ tx_params = (struct skb_info *)info->driver_data;
+
+ /* Update header size */
+ header_size = FRAME_DESC_SZ + sizeof(struct xtended_desc);
+ if (header_size > skb_headroom(skb)) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Failed to add extended descriptor\n",
+ __func__);
+ status = -ENOSPC;
+ return status;
+ }
+ skb_push(skb, header_size);
+ dword_align_bytes = ((unsigned long)skb->data & 0x3f);
+ if (dword_align_bytes > skb_headroom(skb)) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Failed to add dword align\n", __func__);
+ status = -ENOSPC;
+ return status;
+ }
+ 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];
+ vif = adapter->vifs[0];
+
+ mgmt_desc = (struct rsi_mgmt_desc *)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__);
+ return status;
+ }
+ mgmt_desc->length = skb->len - FRAME_DESC_SZ;
+ mgmt_desc->q_num = RSI_WIFI_MGMT_Q;
+ mgmt_desc->frame_type = TX_DOT11_MGMT;
+ mgmt_desc->header_len = MIN_802_11_HDR_LEN;
+ mgmt_desc->xtend_desc_size = header_size - FRAME_DESC_SZ;
+ mgmt_desc->frame_info |= cpu_to_le16(RATE_INFO_ENABLE);
+ if (is_broadcast_ether_addr(wh->addr1))
+ mgmt_desc->frame_info |= cpu_to_le16(RSI_BROADCAST_PKT);
+
+ mgmt_desc->seq_ctrl =
+ cpu_to_le16(IEEE80211_SEQ_TO_SN(le16_to_cpu(wh->seq_ctrl)));
+ if (common->band == NL80211_BAND_2GHZ)
+ mgmt_desc->rate_info = RSI_RATE_1;
+ else
+ mgmt_desc->rate_info = RSI_RATE_6;
+
+ if (conf_is_ht40(conf))
+ mgmt_desc->bbp_info = cpu_to_le16(FULL40M_ENABLE);
+
+ if (ieee80211_is_probe_req(wh->frame_control)) {
+ if (!bss->assoc) {
+ rsi_dbg(INFO_ZONE,
+ "%s: blocking mgmt queue\n", __func__);
+ mgmt_desc->misc_flags = 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");
+ }
+ }
+
+ return 0;
+}
+
/**
* rsi_send_data_pkt() - This function sends the recieved data packet from
* driver to device.
@@ -133,16 +219,10 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
struct sk_buff *skb)
{
struct rsi_hw *adapter = common->priv;
- struct ieee80211_hdr *wh;
struct ieee80211_tx_info *info;
- struct ieee80211_bss_conf *bss;
- struct ieee80211_hw *hw = adapter->hw;
- struct ieee80211_conf *conf = &hw->conf;
- struct rsi_mgmt_desc *mgmt_desc;
struct skb_info *tx_params;
int status = -E2BIG;
u8 extnd_size;
- u8 vap_id = 0;
info = IEEE80211_SKB_CB(skb);
tx_params = (struct skb_info *)info->driver_data;
@@ -168,51 +248,12 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
return status;
}
- bss = &info->control.vif->bss_conf;
- wh = (struct ieee80211_hdr *)&skb->data[0];
-
if (FRAME_DESC_SZ > skb_headroom(skb))
goto err;
- skb_push(skb, FRAME_DESC_SZ);
- memset(skb->data, 0, FRAME_DESC_SZ);
- mgmt_desc = (struct rsi_mgmt_desc *)skb->data;
-
- if (skb->len > MAX_MGMT_PKT_SIZE) {
- rsi_dbg(INFO_ZONE, "%s: Dropping mgmt pkt > 512\n", __func__);
- goto err;
- }
-
- mgmt_desc->length = skb->len - FRAME_DESC_SZ;
- mgmt_desc->q_num = RSI_WIFI_MGMT_Q;
- mgmt_desc->frame_type = TX_DOT11_MGMT;
- mgmt_desc->header_len = MIN_802_11_HDR_LEN;
- mgmt_desc->info_cap |= cpu_to_le16(RATE_INFO_ENABLE);
- mgmt_desc->seq_ctrl = cpu_to_le16(le16_to_cpu(wh->seq_ctrl) >> 4);
-
- if (wh->addr1[0] & BIT(0))
- mgmt_desc->info_cap |= cpu_to_le16(RSI_BROADCAST_PKT);
-
- if (common->band == NL80211_BAND_2GHZ)
- mgmt_desc->rate_info = RSI_11B_MODE;
- else
- mgmt_desc->rate_info = (RSI_RATE_6 & 0x0f) | RSI_11G_MODE;
-
- if (conf_is_ht40(conf)) {
- mgmt_desc->rate_info = 0xB | RSI_11G_MODE;
- mgmt_desc->bbp_info = BBP_INFO_40MHZ;
- }
-
- /* Indicate to firmware to give cfm */
- if ((skb->data[16] == IEEE80211_STYPE_PROBE_REQ) && (!bss->assoc)) {
- mgmt_desc->misc_flags |= BIT(2);
- mgmt_desc->cfm_frame_type = PROBEREQ_CONFIRM;
- common->mgmt_q_block = true;
- }
- mgmt_desc->vap_info = vap_id << 8;
-
+ rsi_prepare_mgmt_desc(common, skb);
status = adapter->host_intf_ops->write_pkt(common->priv,
- (u8 *)mgmt_desc, skb->len);
+ (u8 *)skb->data, skb->len);
if (status)
rsi_dbg(ERR_ZONE, "%s: Failed to write the packet\n", __func__);
diff --git a/drivers/net/wireless/rsi/rsi_hal.h b/drivers/net/wireless/rsi/rsi_hal.h
index 921123e..aa58125 100644
--- a/drivers/net/wireless/rsi/rsi_hal.h
+++ b/drivers/net/wireless/rsi/rsi_hal.h
@@ -124,14 +124,14 @@ struct rsi_mgmt_desc {
#endif
u8 frame_type;
u8 misc_flags;
- u8 reserved1;
+ u8 xtend_desc_size;
u8 header_len;
- __le16 info_cap;
+ __le16 frame_info;
u8 rate_info;
- u8 reserved2;
- u16 bbp_info;
+ u8 reserved1;
+ __le16 bbp_info;
__le16 seq_ctrl;
- u8 cfm_frame_type;
+ u8 reserved2;
u8 vap_info;
} __packed;
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index fc99c17..4b4312e 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -103,6 +103,7 @@ struct skb_info {
u16 channel;
s8 tid;
s8 sta_id;
+ u8 internal_hdr_size;
};
enum edca_queue {
@@ -156,6 +157,12 @@ struct cqm_info {
u32 rssi_hyst;
};
+struct xtended_desc {
+ u8 confirm_frame_type;
+ u8 retry_cnt;
+ u16 reserved;
+};
+
struct rsi_hw;
struct rsi_common {
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index f5cc4c6..04c491d 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -63,6 +63,7 @@
#define RF_RESET_ENABLE BIT(3)
#define RATE_INFO_ENABLE BIT(0)
#define RSI_BROADCAST_PKT BIT(9)
+#define RSI_DESC_REQUIRE_CFM_TO_HOST BIT(2)
#define UPPER_20_ENABLE (0x2 << 12)
#define LOWER_20_ENABLE (0x4 << 12)
--
2.7.4
From: Prameela Rani Garnepudi <[email protected]>
EEPROM read frame is sent during device initialization to read mac address.
The format of the frame is modified in firmware to include eeprom length
and offset. This frame does not return firmware version now. Also same
frame is sent again to read rf type and band information.
Signed-off-by: Prameela Rani Garnepudi <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_mgmt.c | 87 ++++++++++++++++++++++-----------
drivers/net/wireless/rsi/rsi_main.h | 15 ++++++
drivers/net/wireless/rsi/rsi_mgmt.h | 33 ++++++++++++-
3 files changed, 105 insertions(+), 30 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 237e59a..65a221f 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -1314,7 +1314,8 @@ void rsi_inform_bss_status(struct rsi_common *common,
*/
static int rsi_eeprom_read(struct rsi_common *common)
{
- struct rsi_mac_frame *mgmt_frame;
+ struct rsi_eeprom_read_frame *mgmt_frame;
+ struct rsi_hw *adapter = common->priv;
struct sk_buff *skb;
rsi_dbg(MGMT_TX_ZONE, "%s: Sending EEPROM read req frame\n", __func__);
@@ -1327,18 +1328,18 @@ static int rsi_eeprom_read(struct rsi_common *common)
}
memset(skb->data, 0, FRAME_DESC_SZ);
- mgmt_frame = (struct rsi_mac_frame *)skb->data;
+ mgmt_frame = (struct rsi_eeprom_read_frame *)skb->data;
/* FrameType */
- mgmt_frame->desc_word[1] = cpu_to_le16(EEPROM_READ_TYPE);
- mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
+ mgmt_frame->pkt_type = EEPROM_READ;
+ mgmt_frame->q_no = RSI_WIFI_MGMT_Q;
+
/* Number of bytes to read */
- mgmt_frame->desc_word[3] = cpu_to_le16(ETH_ALEN +
- WLAN_MAC_MAGIC_WORD_LEN +
- WLAN_HOST_MODE_LEN +
- WLAN_FW_VERSION_LEN);
+ mgmt_frame->eeprom_len = adapter->eeprom.length;
+ mgmt_frame->hdr_size = 3;
+
/* Address to read */
- mgmt_frame->desc_word[4] = cpu_to_le16(WLAN_MAC_EEPROM_ADDR);
+ mgmt_frame->eeprom_offset = cpu_to_le32(adapter->eeprom.offset);
skb_put(skb, FRAME_DESC_SZ);
@@ -1464,19 +1465,25 @@ int rsi_set_antenna(struct rsi_common *common, u8 antenna)
static int rsi_handle_ta_confirm_type(struct rsi_common *common,
u8 *msg)
{
+ struct rsi_hw *adapter = common->priv;
u8 sub_type = (msg[15] & 0xff);
+ u16 msg_len = ((u16 *)msg)[0] & 0xfff;
+ u8 offset;
switch (sub_type) {
case BOOTUP_PARAMS_REQUEST:
rsi_dbg(FSM_ZONE, "%s: Boot up params confirm received\n",
__func__);
if (common->fsm_state == FSM_BOOT_PARAMS_SENT) {
+ adapter->eeprom.length = (IEEE80211_ADDR_LEN +
+ WLAN_MAC_MAGIC_WORD_LEN +
+ WLAN_HOST_MODE_LEN);
+ adapter->eeprom.offset = WLAN_MAC_EEPROM_ADDR;
if (rsi_eeprom_read(common)) {
common->fsm_state = FSM_CARD_NOT_READY;
goto out;
- } else {
- common->fsm_state = FSM_EEPROM_READ_MAC_ADDR;
}
+ common->fsm_state = FSM_EEPROM_READ_MAC_ADDR;
} else {
rsi_dbg(INFO_ZONE,
"%s: Received bootup params cfm in %d state\n",
@@ -1485,30 +1492,52 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common,
}
break;
- case EEPROM_READ_TYPE:
+ case EEPROM_READ:
+ rsi_dbg(FSM_ZONE, "EEPROM READ confirm received\n");
+ if (msg_len <= 0) {
+ rsi_dbg(FSM_ZONE,
+ "%s: [EEPROM_READ] Invalid len %d\n",
+ __func__, msg_len);
+ goto out;
+ }
+ if (msg[16] != MAGIC_WORD) {
+ rsi_dbg(FSM_ZONE,
+ "%s: [EEPROM_READ] Invalid token\n", __func__);
+ common->fsm_state = FSM_CARD_NOT_READY;
+ goto out;
+ }
if (common->fsm_state == FSM_EEPROM_READ_MAC_ADDR) {
- if (msg[16] == MAGIC_WORD) {
- u8 offset = (FRAME_DESC_SZ + WLAN_HOST_MODE_LEN
- + WLAN_MAC_MAGIC_WORD_LEN);
- memcpy(common->mac_addr,
- &msg[offset],
- ETH_ALEN);
- memcpy(&common->fw_ver,
- &msg[offset + ETH_ALEN],
- sizeof(struct version_info));
-
- } else {
+ offset = (FRAME_DESC_SZ + WLAN_HOST_MODE_LEN +
+ WLAN_MAC_MAGIC_WORD_LEN);
+ memcpy(common->mac_addr, &msg[offset], ETH_ALEN);
+ adapter->eeprom.length =
+ ((WLAN_MAC_MAGIC_WORD_LEN + 3) & (~3));
+ adapter->eeprom.offset = WLAN_EEPROM_RFTYPE_ADDR;
+ if (rsi_eeprom_read(common)) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Failed reading RF band\n",
+ __func__);
common->fsm_state = FSM_CARD_NOT_READY;
- break;
+ goto out;
+ }
+ common->fsm_state = FSM_EEPROM_READ_RF_TYPE;
+ } else if (common->fsm_state == FSM_EEPROM_READ_RF_TYPE) {
+ if ((msg[17] & 0x3) == 0x3) {
+ rsi_dbg(INIT_ZONE, "Dual band supported\n");
+ common->band = NL80211_BAND_5GHZ;
+ common->num_supp_bands = 2;
+ } else if ((msg[17] & 0x3) == 0x1) {
+ rsi_dbg(INIT_ZONE,
+ "Only 2.4Ghz band supported\n");
+ common->band = NL80211_BAND_2GHZ;
+ common->num_supp_bands = 1;
}
if (rsi_send_reset_mac(common))
goto out;
- else
- common->fsm_state = FSM_RESET_MAC_SENT;
+ common->fsm_state = FSM_RESET_MAC_SENT;
} else {
- rsi_dbg(ERR_ZONE,
- "%s: Received eeprom mac addr in %d state\n",
- __func__, common->fsm_state);
+ rsi_dbg(ERR_ZONE, "%s: Invalid EEPROM read type\n",
+ __func__);
return 0;
}
break;
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index 43c74a5..fc99c17 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -176,6 +176,7 @@ struct rsi_common {
/* Channel/band related */
u8 band;
+ u8 num_supp_bands;
u8 channel_width;
u16 rts_threshold;
@@ -229,6 +230,19 @@ enum host_intf {
RSI_HOST_INTF_USB
};
+struct eepromrw_info {
+ u32 offset;
+ u32 length;
+ u8 write;
+ u16 eeprom_erase;
+ u8 data[480];
+};
+
+struct eeprom_read {
+ u16 length;
+ u16 off_set;
+};
+
struct rsi_hw {
struct rsi_common *priv;
u8 device_model;
@@ -251,6 +265,7 @@ struct rsi_hw {
struct timer_list bl_cmd_timer;
bool blcmd_timer_expired;
u32 flash_capacity;
+ struct eepromrw_info eeprom;
u8 dfs_region;
void *rsi_dev;
struct rsi_host_intf_ops *host_intf_ops;
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index 4cff27d..f5cc4c6 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -43,6 +43,7 @@
#define WLAN_HOST_MODE_LEN 0x04
#define WLAN_FW_VERSION_LEN 0x08
#define MAGIC_WORD 0x5A
+#define WLAN_EEPROM_RFTYPE_ADDR 424
/* Receive Frame Types */
#define TA_CONFIRM_TYPE 0x01
@@ -192,7 +193,7 @@ enum cmd_frame_type {
AUTO_RATE_IND,
BOOTUP_PARAMS_REQUEST,
VAP_CAPABILITIES,
- EEPROM_READ_TYPE ,
+ EEPROM_READ,
EEPROM_WRITE,
GPIO_PIN_CONFIG ,
SET_RX_FILTER,
@@ -379,6 +380,36 @@ struct rsi_config_vals {
u8 reserved2[16];
} __packed;
+struct rsi_eeprom_read_frame {
+#ifdef __LITTLE_ENDIAN
+ u16 pkt_len:12;
+ u16 q_no:4;
+#else
+ u16 q_no:4;
+ u16 pkt_len:12;
+#endif
+ u8 pkt_type;
+ u8 misc_flags;
+#ifdef __LITTLE_ENDIAN
+ u32 xtend_desc_size:8;
+ u32 hdr_size:2;
+ u32 reserved0:3;
+ u32 spi_init_req:1;
+ u32 reserved1:6;
+ u32 eeprom_len:12;
+#else
+ u32 eeprom_len:12;
+ u32 reserved1:6;
+ u32 spi_init_req:1;
+ u32 reserved0:3;
+ u32 hdr_size:2;
+ u32 xtend_desc_size:8;
+#endif
+ __le32 eeprom_offset;
+ __le16 delay_ms;
+ __le16 reserved3;
+} __packed;
+
static inline u32 rsi_get_queueno(u8 *addr, u16 offset)
{
return (le16_to_cpu(*(__le16 *)&addr[offset]) & 0x7000) >> 12;
--
2.7.4
From: Karun Eagalapati <[email protected]>
card reset is not working with recent kernels. Using
host->card->ocr instead of host->ocr_avail solved the problem.
Signed-off-by: Karun Eagalapati <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_sdio.c | 26 +++++++++-----------------
1 file changed, 9 insertions(+), 17 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
index e5ea99b..b5ac503 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -219,26 +219,18 @@ static void rsi_reset_card(struct sdio_func *pfunction)
if (err)
rsi_dbg(ERR_ZONE, "%s: CMD0 failed : %d\n", __func__, err);
- if (!host->ocr_avail) {
- /* Issue CMD5, arg = 0 */
- err = rsi_issue_sdiocommand(pfunction,
- SD_IO_SEND_OP_COND,
- 0,
- (MMC_RSP_R4 | MMC_CMD_BCR),
- &resp);
- if (err)
- rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n",
- __func__, err);
- host->ocr_avail = resp;
- }
+ /* Issue CMD5, arg = 0 */
+ err = rsi_issue_sdiocommand(pfunction, SD_IO_SEND_OP_COND, 0,
+ (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
+ if (err)
+ rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n", __func__, err);
+ card->ocr = resp;
/* 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,
- host->ocr_avail,
- (MMC_RSP_R4 | MMC_CMD_BCR),
- &resp);
+ err = rsi_issue_sdiocommand(pfunction, SD_IO_SEND_OP_COND,
+ card->ocr,
+ (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
if (err) {
rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n",
__func__, err);
--
2.7.4
From: "pavani.muthyala" <[email protected]>
Currently this descriptor is prepared with the help of __le16
pointer. This patch makes use of a structure to prepare the
descriptor in a cleaner way.
Signed-off-by: pavani.muthyala <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_hal.c | 36 +++++++++++++++++-----------------
drivers/net/wireless/rsi/rsi_hal.h | 25 +++++++++++++++++++++++
drivers/net/wireless/rsi/rsi_mgmt.h | 3 +++
3 files changed, 46 insertions(+), 18 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index bc2ee8c..8a66edd 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -126,10 +126,10 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
struct ieee80211_tx_info *info;
struct skb_info *tx_params;
struct ieee80211_bss_conf *bss;
+ struct rsi_data_desc *data_desc;
int status;
u8 ieee80211_size = MIN_802_11_HDR_LEN;
u8 extnd_size;
- __le16 *frame_desc;
u16 seq_num;
info = IEEE80211_SKB_CB(skb);
@@ -153,12 +153,12 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
}
skb_push(skb, (FRAME_DESC_SZ + extnd_size));
- frame_desc = (__le16 *)&skb->data[0];
- memset((u8 *)frame_desc, 0, FRAME_DESC_SZ);
+ data_desc = (struct rsi_data_desc *)skb->data;
+ memset(data_desc, 0, sizeof(*data_desc));
if (ieee80211_is_data_qos(tmp_hdr->frame_control)) {
ieee80211_size += 2;
- frame_desc[6] |= cpu_to_le16(BIT(12));
+ data_desc->mac_flags |= cpu_to_le16(RSI_QOS_ENABLE);
}
if ((!(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) &&
@@ -167,33 +167,33 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
ieee80211_size += 4;
else
ieee80211_size += 8;
- frame_desc[6] |= cpu_to_le16(BIT(15));
+ data_desc->mac_flags |= cpu_to_le16(RSI_ENCRYPT_PKT);
}
+ data_desc->length = skb->len - FRAME_DESC_SZ;
+ data_desc->q_num = RSI_WIFI_DATA_Q;
+ data_desc->header_len = ieee80211_size;
+ data_desc->xtend_desc_size = extnd_size;
- frame_desc[0] = cpu_to_le16((skb->len - FRAME_DESC_SZ) |
- (RSI_WIFI_DATA_Q << 12));
- frame_desc[2] = cpu_to_le16((extnd_size) | (ieee80211_size) << 8);
-
- if (common->min_rate != 0xffff) {
+ if (common->min_rate != RSI_RATE_AUTO) {
/* Send fixed rate */
- frame_desc[3] = cpu_to_le16(RATE_INFO_ENABLE);
- frame_desc[4] = cpu_to_le16(common->min_rate);
+ data_desc->frame_info = cpu_to_le16(RATE_INFO_ENABLE);
+ data_desc->rate_info = cpu_to_le16(common->min_rate);
if (conf_is_ht40(&common->priv->hw->conf))
- frame_desc[5] = cpu_to_le16(FULL40M_ENABLE);
+ data_desc->bbp_info = cpu_to_le16(FULL40M_ENABLE);
if (common->vif_info[0].sgi) {
if (common->min_rate & 0x100) /* Only MCS rates */
- frame_desc[4] |=
+ data_desc->rate_info |=
cpu_to_le16(ENABLE_SHORTGI_RATE);
}
}
- frame_desc[6] |= cpu_to_le16(seq_num & 0xfff);
- frame_desc[7] = cpu_to_le16(((tx_params->tid & 0xf) << 4) |
- (skb->priority & 0xf) |
- (tx_params->sta_id << 8));
+ data_desc->mac_flags = cpu_to_le16(seq_num & 0xfff);
+ data_desc->qid = skb->priority & 0xf;
+ data_desc->tid = tx_params->tid & 0xf;
+ data_desc->sta_id = tx_params->sta_id;
status = adapter->host_intf_ops->write_pkt(common->priv, skb->data,
skb->len);
diff --git a/drivers/net/wireless/rsi/rsi_hal.h b/drivers/net/wireless/rsi/rsi_hal.h
index aa58125..b137de2 100644
--- a/drivers/net/wireless/rsi/rsi_hal.h
+++ b/drivers/net/wireless/rsi/rsi_hal.h
@@ -135,6 +135,31 @@ struct rsi_mgmt_desc {
u8 vap_info;
} __packed;
+struct rsi_data_desc {
+#ifdef __LITTLE_ENDIAN
+ u16 length : 12;
+ u16 q_num :4;
+#else
+ u16 q_num :4;
+ u16 length : 12;
+#endif
+ u16 reserved;
+ u8 xtend_desc_size;
+ u8 header_len;
+ __le16 frame_info;
+ __le16 rate_info;
+ __le16 bbp_info;
+ __le16 mac_flags;
+#ifdef __LITTLE_ENDIAN
+ u8 qid : 4;
+ u8 tid : 4;
+#else
+ u8 tid : 4;
+ u8 qid : 4;
+#endif
+ u8 sta_id;
+} __packed;
+
int rsi_hal_device_init(struct rsi_hw *adapter);
#endif
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index 04c491d..2a223a6 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -64,6 +64,8 @@
#define RATE_INFO_ENABLE BIT(0)
#define RSI_BROADCAST_PKT BIT(9)
#define RSI_DESC_REQUIRE_CFM_TO_HOST BIT(2)
+#define RSI_QOS_ENABLE BIT(12)
+#define RSI_ENCRYPT_PKT BIT(15)
#define UPPER_20_ENABLE (0x2 << 12)
#define LOWER_20_ENABLE (0x4 << 12)
@@ -122,6 +124,7 @@
#define RSI_RATE_MCS6 0x106
#define RSI_RATE_MCS7 0x107
#define RSI_RATE_MCS7_SG 0x307
+#define RSI_RATE_AUTO 0xffff
#define BW_20MHZ 0
#define BW_40MHZ 1
--
2.7.4
From: Amitkumar Karwar <[email protected]>
Maximum valid queue number is 0x5. So anding with 0x7 should be
ok here.
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_usb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c
index 25f6195..dc0a0b2 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
@@ -381,7 +381,7 @@ static int rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter,
u8 *pkt,
u32 len)
{
- u32 queueno = ((pkt[1] >> 4) & 0xf);
+ u32 queueno = ((pkt[1] >> 4) & 0x7);
u8 endpoint;
endpoint = ((queueno == RSI_WIFI_MGMT_Q) ? MGMT_EP : DATA_EP);
--
2.7.4
From: "pavani.muthyala" <[email protected]>
This patch covers some enhancements in data packet descriptor
preparation especially for EAPOL, multicast/broadcast packets.
Signed-off-by: pavani.muthyala <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_hal.c | 63 +++++++++++++++++++++++++++-------
drivers/net/wireless/rsi/rsi_hal.h | 3 +-
drivers/net/wireless/rsi/rsi_mgmt.h | 3 ++
3 files changed, 55 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index 8a66edd..20cb608 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -122,14 +122,18 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
{
struct rsi_hw *adapter = common->priv;
- struct ieee80211_hdr *tmp_hdr;
+ struct ieee80211_hdr *wh = NULL;
struct ieee80211_tx_info *info;
+ struct ieee80211_vif *vif = NULL;
struct skb_info *tx_params;
struct ieee80211_bss_conf *bss;
struct rsi_data_desc *data_desc;
+ struct xtended_desc *xtend_desc;
int status;
u8 ieee80211_size = MIN_802_11_HDR_LEN;
- u8 extnd_size;
+ u8 header_size = 0;
+ u8 vap_id = 0;
+ u8 dword_align_bytes = 0;
u16 seq_num;
info = IEEE80211_SKB_CB(skb);
@@ -140,23 +144,34 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
status = -EINVAL;
goto err;
}
-
- tmp_hdr = (struct ieee80211_hdr *)&skb->data[0];
- seq_num = (le16_to_cpu(tmp_hdr->seq_ctrl) >> 4);
-
- extnd_size = ((uintptr_t)skb->data & 0x3);
-
- if ((FRAME_DESC_SZ + extnd_size) > skb_headroom(skb)) {
+ header_size = FRAME_DESC_SZ + sizeof(struct xtended_desc);
+ if (header_size > skb_headroom(skb)) {
rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__);
status = -ENOSPC;
goto err;
}
+ 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__);
+ status = -ENOSPC;
+ goto err;
+ }
+ skb_push(skb, dword_align_bytes);
+ header_size += dword_align_bytes;
- skb_push(skb, (FRAME_DESC_SZ + extnd_size));
+ tx_params->internal_hdr_size = header_size;
data_desc = (struct rsi_data_desc *)skb->data;
- memset(data_desc, 0, sizeof(*data_desc));
+ memset(data_desc, 0, header_size);
+
+ xtend_desc = (struct xtended_desc *)&skb->data[FRAME_DESC_SZ];
+ wh = (struct ieee80211_hdr *)&skb->data[header_size];
+ seq_num = (le16_to_cpu(wh->seq_ctrl) >> 4);
+ vif = adapter->vifs[0];
- if (ieee80211_is_data_qos(tmp_hdr->frame_control)) {
+ data_desc->xtend_desc_size = header_size - FRAME_DESC_SZ;
+
+ if (ieee80211_is_data_qos(wh->frame_control)) {
ieee80211_size += 2;
data_desc->mac_flags |= cpu_to_le16(RSI_QOS_ENABLE);
}
@@ -172,7 +187,6 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
data_desc->length = skb->len - FRAME_DESC_SZ;
data_desc->q_num = RSI_WIFI_DATA_Q;
data_desc->header_len = ieee80211_size;
- data_desc->xtend_desc_size = extnd_size;
if (common->min_rate != RSI_RATE_AUTO) {
/* Send fixed rate */
@@ -190,11 +204,34 @@ 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");
+
+ data_desc->frame_info = cpu_to_le16(RATE_INFO_ENABLE);
+ if (common->band == NL80211_BAND_5GHZ)
+ data_desc->rate_info = cpu_to_le16(RSI_RATE_6);
+ else
+ data_desc->rate_info = cpu_to_le16(RSI_RATE_1);
+ data_desc->mac_flags |= cpu_to_le16(RSI_REKEY_PURPOSE);
+ data_desc->misc_flags |= RSI_FETCH_RETRY_CNT_FRM_HST;
+#define EAPOL_RETRY_CNT 15
+ xtend_desc->retry_cnt = EAPOL_RETRY_CNT;
+ }
+
data_desc->mac_flags = cpu_to_le16(seq_num & 0xfff);
data_desc->qid = skb->priority & 0xf;
data_desc->tid = tx_params->tid & 0xf;
data_desc->sta_id = tx_params->sta_id;
+ if ((is_broadcast_ether_addr(wh->addr1)) ||
+ (is_multicast_ether_addr(wh->addr1))) {
+ data_desc->frame_info = cpu_to_le16(RATE_INFO_ENABLE);
+ data_desc->frame_info |= cpu_to_le16(RSI_BROADCAST_PKT);
+ data_desc->qid = skb->priority & 0xf;
+ data_desc->tid = tx_params->tid & 0xf;
+ data_desc->sta_id = vap_id;
+ }
+
status = adapter->host_intf_ops->write_pkt(common->priv, skb->data,
skb->len);
if (status)
diff --git a/drivers/net/wireless/rsi/rsi_hal.h b/drivers/net/wireless/rsi/rsi_hal.h
index b137de2..9d6c6f9 100644
--- a/drivers/net/wireless/rsi/rsi_hal.h
+++ b/drivers/net/wireless/rsi/rsi_hal.h
@@ -143,7 +143,8 @@ struct rsi_data_desc {
u16 q_num :4;
u16 length : 12;
#endif
- u16 reserved;
+ u8 cfm_frame_type;
+ u8 misc_flags;
u8 xtend_desc_size;
u8 header_len;
__le16 frame_info;
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index 2a223a6..78ea1c7 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -64,7 +64,10 @@
#define RATE_INFO_ENABLE BIT(0)
#define RSI_BROADCAST_PKT BIT(9)
#define RSI_DESC_REQUIRE_CFM_TO_HOST BIT(2)
+#define RSI_ADD_DELTA_TSF_VAP_ID BIT(3)
+#define RSI_FETCH_RETRY_CNT_FRM_HST BIT(4)
#define RSI_QOS_ENABLE BIT(12)
+#define RSI_REKEY_PURPOSE BIT(13)
#define RSI_ENCRYPT_PKT BIT(15)
#define UPPER_20_ENABLE (0x2 << 12)
--
2.7.4
From: Karun Eagalapati <[email protected]>
USB headroom is added while submitting the data to URB as per
firmware's requirement. This logic is moved to rsi_usb_card_write() so
that caller need not worry about it.
Signed-off-by: Karun Eagalapati <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_usb.c | 41 +++++++++++++++++-----------------
1 file changed, 21 insertions(+), 20 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c
index 1d7bb9d..25f6195 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
@@ -29,19 +29,24 @@
* Return: status: 0 on success, a negative error code on failure.
*/
static int rsi_usb_card_write(struct rsi_hw *adapter,
- void *buf,
+ u8 *buf,
u16 len,
u8 endpoint)
{
struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
int status;
- s32 transfer;
+ u8 *seg = dev->tx_buffer;
+ int transfer;
+ int ep = dev->bulkout_endpoint_addr[endpoint - 1];
+ memset(seg, 0, len + RSI_USB_TX_HEAD_ROOM);
+ memcpy(seg + RSI_USB_TX_HEAD_ROOM, buf, len);
+ len += RSI_USB_TX_HEAD_ROOM;
+ transfer = len;
status = usb_bulk_msg(dev->usbdev,
- usb_sndbulkpipe(dev->usbdev,
- dev->bulkout_endpoint_addr[endpoint - 1]),
- buf,
- len,
+ usb_sndbulkpipe(dev->usbdev, ep),
+ (void *)seg,
+ (int)len,
&transfer,
HZ * 5);
@@ -68,23 +73,19 @@ static int rsi_write_multiple(struct rsi_hw *adapter,
u8 *data,
u32 count)
{
- struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
- u8 *seg = dev->tx_buffer;
+ struct rsi_91x_usbdev *dev =
+ (struct rsi_91x_usbdev *)adapter->rsi_dev;
- if (dev->write_fail)
- return 0;
+ if (!adapter)
+ return -ENODEV;
- if (endpoint == MGMT_EP) {
- memset(seg, 0, RSI_USB_TX_HEAD_ROOM);
- memcpy(seg + RSI_USB_TX_HEAD_ROOM, data, count);
- } else {
- seg = ((u8 *)data - RSI_USB_TX_HEAD_ROOM);
- }
+ if (endpoint == 0)
+ return -EINVAL;
+
+ if (dev->write_fail)
+ return -ENETDOWN;
- return rsi_usb_card_write(adapter,
- seg,
- count + RSI_USB_TX_HEAD_ROOM,
- endpoint);
+ return rsi_usb_card_write(adapter, data, count, endpoint);
}
/**
--
2.7.4
From: Karun Eagalapati <[email protected]>
We have now added separate lock for Rx. This lock is used to protect
tx path only
Signed-off-by: Karun Eagalapati <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_core.c | 10 +++++-----
drivers/net/wireless/rsi/rsi_91x_main.c | 2 +-
drivers/net/wireless/rsi/rsi_main.h | 4 ++--
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_core.c b/drivers/net/wireless/rsi/rsi_91x_core.c
index 68f04a7..88a1a56 100644
--- a/drivers/net/wireless/rsi/rsi_91x_core.c
+++ b/drivers/net/wireless/rsi/rsi_91x_core.c
@@ -268,11 +268,11 @@ void rsi_core_qos_processor(struct rsi_common *common)
break;
}
- mutex_lock(&common->tx_rxlock);
+ mutex_lock(&common->tx_lock);
status = adapter->check_hw_queue_status(adapter, q_num);
if ((status <= 0)) {
- mutex_unlock(&common->tx_rxlock);
+ mutex_unlock(&common->tx_lock);
break;
}
@@ -287,7 +287,7 @@ void rsi_core_qos_processor(struct rsi_common *common)
skb = rsi_core_dequeue_pkt(common, q_num);
if (skb == NULL) {
rsi_dbg(ERR_ZONE, "skb null\n");
- mutex_unlock(&common->tx_rxlock);
+ mutex_unlock(&common->tx_lock);
break;
}
@@ -297,14 +297,14 @@ void rsi_core_qos_processor(struct rsi_common *common)
status = rsi_send_data_pkt(common, skb);
if (status) {
- mutex_unlock(&common->tx_rxlock);
+ mutex_unlock(&common->tx_lock);
break;
}
common->tx_stats.total_tx_pkt_send[q_num]++;
tstamp_2 = jiffies;
- mutex_unlock(&common->tx_rxlock);
+ mutex_unlock(&common->tx_lock);
if (time_after(tstamp_2, tstamp_1 + (300 * HZ) / 1000))
schedule();
diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c
index f1cde0c..34ab8f0 100644
--- a/drivers/net/wireless/rsi/rsi_91x_main.c
+++ b/drivers/net/wireless/rsi/rsi_91x_main.c
@@ -220,7 +220,7 @@ struct rsi_hw *rsi_91x_init(void)
rsi_init_event(&common->tx_thread.event);
mutex_init(&common->mutex);
- mutex_init(&common->tx_rxlock);
+ mutex_init(&common->tx_lock);
if (rsi_create_kthread(common,
&common->tx_thread,
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index 6d41c9b..d3bf7ac 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -177,8 +177,8 @@ struct rsi_common {
struct sk_buff_head tx_queue[NUM_EDCA_QUEUES + 1];
/* Mutex declaration */
struct mutex mutex;
- /* Mutex used between tx/rx threads */
- struct mutex tx_rxlock;
+ /* Mutex used for tx thread */
+ struct mutex tx_lock;
/* Mutex used for rx thread */
struct mutex rx_lock;
u8 endpoint;
--
2.7.4
SGnCoEFtaXRrdW1hciwNCg0KT24gVHVlLCAyMDE3LTA2LTEzIGF0IDIwOjE4ICswNTMwLCBBbWl0
a3VtYXIgS2Fyd2FyIHdyb3RlOg0KPiBUaGlzIHBhdGNoIHNlcmllcyBpbmNsdWRlcyBzb21lIGZp
eGVzIGFuZCBlbmhhbmNlbWVudHMgaW4gVHggYW5kIFJ4DQo+IGRhdGEgcGF0aHMuIENvbm5lY3Rp
b24gaW4gb3BlbiBzZWN1cml0eSBhbmQgZGF0YSB0cmFmZmljIGhhcyBiZWVuDQo+IHZlcmlmaWVk
IHdpdGggU0RJTyBhbmQgVVNCIHZhcmlhbnRzIG9mIDkxMTMgY2hpcHNldC4NCj4gDQo+IEFtaXRr
dW1hciBLYXJ3YXIgKDEpOg0KPiDCoCByc2k6IGNvcnJlY3QgdGhlIGxvZ2ljIG9mIGRlcml2aW5n
IHF1ZXVlIG51bWJlcg0KPiANCj4gS2FydW4gRWFnYWxhcGF0aSAoMTQpOg0KPiDCoCByc2k6IGZp
eCBzZGlvIGNhcmQgcmVzZXQgcHJvYmxlbQ0KPiDCoCByc2k6IGNoaXAgcmVzZXQgZm9yIFNESU8g
aW50ZXJmYWNlDQo+IMKgIHJzaTogY29ycmVjdCBTRElPIGRpc2Nvbm5lY3QgcGF0aCBoYW5kbGlu
Zw0KPiDCoCByc2k6IGNhcmQgcmVzZXQgZm9yIFVTQiBpbnRlcmZhY2UNCj4gwqAgcnNpOiBVU0Ig
dHggaGVhZHJvb20gY2xlYW51cA0KPiDCoCByc2k6IHJlbmFtZSBVU0IgZW5kcG9pbnQgbWFjcm9z
DQo+IMKgIHJzaTogY2hvb3NlIGNvcnJlY3QgZW5kcG9pbnQgYmFzZWQgb24gcXVldWUuDQo+IMKg
IHJzaTogc2V0IGltbWVkaWF0ZSB3YWtldXAgYml0DQo+IMKgIHJzaTogc2VwYXJhdGUgZnVuY3Rp
b24gZm9yIG1hbmFnZW1lbnQgcGFja2V0IGRlc2NyaXB0b3INCj4gwqAgcnNpOiByZW5hbWUgdmFy
aWFibGUgaW5fc2Rpb19saXRlZmlfaXJxDQo+IMKgIHJzaTogT3B0aW1pc2Ugc2RpbyBjbGFpbSBh
bmQgcmVsZWFzZSBob3N0DQo+IMKgIHJzaTogU0RJTyBSeCBwYWNrZXQgcHJvY2Vzc2luZyBlbmhh
bmNlbWVudA0KPiDCoCByc2k6IHVzZSBzZXBhcmF0ZSBtdXRleCBsb2NrIGZvciByZWNlaXZlIHRo
cmVhZA0KPiDCoCByc2k6IFJlbmFtZSBtdXRleCB0eF9yeGxvY2sgdG8gdGhlIHR4X2xvY2suDQo+
IA0KPiBQcmFtZWVsYSBSYW5pIEdhcm5lcHVkaSAoMSk6DQo+IMKgIHJzaTogY2hhbmdlcyBpbiBl
ZXByb20gcmVhZCBmcmFtZQ0KPiANCj4gcGF2YW5pLm11dGh5YWxhICg0KToNCj4gwqAgcnNpOiBt
YW5hZ2VtZW50IGZyYW1lIGRlc2NyaXB0b3IgcHJlcGFyYXRpb24gY2xlYW51cA0KPiDCoCByc2k6
IGRhdGEgcGFja2V0IGRlc2NyaXB0b3IgY29kZSBjbGVhbnVwDQo+IMKgIHJzaTogZGF0YSBwYWNr
ZXQgZGVzY3JpcHRvciBlbmhhbmNlbWVudHMNCj4gwqAgcnNpOiBzZXBhcmF0ZSBmdW5jdGlvbiBm
b3IgZGF0YSBwYWNrZXQgZGVzY3JpcHRvcg0KDQpGaW5hbGx5IHdpdGggdGhpcyBwYXRjaC1zZXQg
SSBnb3QgbmV3IGZpcm13YXJlIFsxXSBzdWNjZXNzZnVsbHkgbG9hZGVkDQppbiByczkxMTMgbW9k
dWxlIHZpYSBTRElPIChidXQgbm90IHZpYSBVU0IsIHJlYWQtb24pLg0KLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tPjgtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KcnNpXzkxeDogKioqKiog
RmlybXdhcmUgTG9hZGluZyBzdWNjZXNzZnVsICoqKioqDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0+OC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCkFsc28gSSBtYXkgbm93IGV4ZWN1
dGUgImlmY29uZmlnIHdsYW4wIHVwIiBzdWNjZXNmdWxseToNCi0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLT44LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgaWZjb25maWcgd2xhbjANCnds
YW4wwqDCoMKgwqDCoExpbmsgZW5jYXA6RXRoZXJuZXTCoMKgSFdhZGRyIDAwOjIzOkE3OjkwOjNG
OjJDwqDCoA0KwqDCoMKgwqDCoMKgwqDCoMKgwqBVUCBCUk9BRENBU1QgTVVMVElDQVNUwqDCoE1U
VToxNTAwwqDCoE1ldHJpYzoxDQrCoMKgwqDCoMKgwqDCoMKgwqDCoFJYIHBhY2tldHM6MCBlcnJv
cnM6MCBkcm9wcGVkOjAgb3ZlcnJ1bnM6MCBmcmFtZTowDQrCoMKgwqDCoMKgwqDCoMKgwqDCoFRY
IHBhY2tldHM6MCBlcnJvcnM6MCBkcm9wcGVkOjAgb3ZlcnJ1bnM6MCBjYXJyaWVyOjANCsKgwqDC
oMKgwqDCoMKgwqDCoMKgY29sbGlzaW9uczowIHR4cXVldWVsZW46MTAwMMKgDQrCoMKgwqDCoMKg
wqDCoMKgwqDCoFJYIGJ5dGVzOjAgKDAuMCBCKcKgwqBUWCBieXRlczowICgwLjAgQikNCi0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLT44LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KTmV4
dCB0aGluZyBJIHRyaWVkIChhbmQgdGhhdCdzIHdoYXQgSSBkbyB3aXRoIGFueSBvdGhlciB3aXJl
bGVzcw0KYWRhcHRlciB0aGF0IHN1cHBvcnRzIEFQIG1vZGUpIGlzIGFkZGluZyB3bGFuMCB0byBh
IGJyaWRnZSB3aXRoIGV0aDANCndpdGggc3Vic2VxdWVudCBleGVjdXRpb24gb2YgaG9zdGFwZCB0
byBnZXQgbWUgc28tY2FsbGVkIGR1bWIgQVAuDQoNClVzdWFsbHkgdGhhdCdzIHdoYXQgSSBkbzoN
Ci0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT44LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0N
CmlmY29uZmlnIHdsYW4wIHVwDQppZmNvbmZpZyBldGgwIHVwDQpicmN0bCBhZGRiciBicjANCmJy
Y3RsIGFkZGlmIGJyMCBldGgwDQppdyBkZXYgd2xhbjAgc2V0IDRhZGRyIG9uDQpicmN0bCBhZGRp
ZiBicjAgd2xhbjANCmJyY3RsIHNob3cNCmlmY29uZmlnIGJyMCB1cA0KdWRoY3BjIC1pIGJyMA0K
aG9zdGFwZCAtQiAvZXRjL2hvc3RhcGQuY29uZg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
PjgtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpCdXQgbm93IHdpdGggcnM5MTEzIEkgZ290
Og0KMSkNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT44LS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0NCiMgaXcgZGV2IHdsYW4wIHNldCA0YWRkciBvbg0KY29tbWFuZCBmYWlsZWQ6IE9wZXJh
dGlvbiBub3Qgc3VwcG9ydGVkICgtOTUpDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+OC0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCjIpDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0+OC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIGhvc3RhcGQgLUIgL2V0Yy9ob3N0YXBk
LmNvbmYNCkNvbmZpZ3VyYXRpb24gZmlsZTogL2V0Yy9ob3N0YXBkLmNvbmYNCm5sODAyMTE6IENv
dWxkIG5vdCBjb25maWd1cmUgZHJpdmVyIG1vZGUNCm5sODAyMTE6IGRlaW5pdCBpZm5hbWU9d2xh
bjAgZGlzYWJsZWRfMTFiX3JhdGVzPTANCm5sODAyMTEgZHJpdmVyIGluaXRpYWxpemF0aW9uIGZh
aWxlZC4NCndsYW4wOiBpbnRlcmZhY2Ugc3RhdGUgVU5JTklUSUFMSVpFRC0+RElTQUJMRUQNCnds
YW4wOiBBUC1ESVNBQkxFRMKgDQpob3N0YXBkX2ZyZWVfaGFwZF9kYXRhOiBJbnRlcmZhY2Ugd2xh
bjAgd2Fzbid0IHN0YXJ0ZWQNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT44LS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0NCg0KRm9yIGV4YW1wbGUgZXhhY3RseSB0aGUgc2FtZSBwcm9jZWR1
cmUgd29ya3MgcGVyZmVjdGx5IGZpbmUgZm9yDQphdGg5a19odGMtYmFzZWQgVVNCIGRvbmdsZXMu
DQoNCk5vdyBmb3IgVVNCLWNhc2UgdGhlcmUgc2VlbXMgdG8gcmVtYWluIHNpbWlsYXIgcHJvYmxl
bSB3aXRoIGZpcm13YXJlIGxvYWRpbmc6DQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+OC0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQp1c2IgMS0xOiBuZXcgaGlnaC1zcGVlZCBVU0IgZGV2
aWNlIG51bWJlciAyIHVzaW5nIGVoY2ktcGxhdGZvcm0NCnVzYiAxLTE6IGNvbmZpZyAxIGludGVy
ZmFjZSAwIGFsdHNldHRpbmcgMCBlbmRwb2ludCAweDgzIGhhcyBhbiBpbnZhbGlkIGJJbnRlcnZh
bCAyNTUsIGNoYW5naW5nIHRvIDExDQpyc2lfOTF4OiByc2lfcHJvYmU6IEluaXRpYWxpemVkIG9z
IGludGYgb3BzDQpyc2lfOTF4OiByc2lfbG9hZF9maXJtd2FyZTogUkVHT1VUIHJlYWQgdGltZWRv
dXQNCnJzaV85MXg6IHJzaV9sb2FkX2Zpcm13YXJlOiBTb2Z0IGJvb3QgbG9hZGVyIG5vdCBwcmVz
ZW50DQpyc2lfOTF4OiByc2lfaGFsX2RldmljZV9pbml0OiBGYWlsZWQgdG8gbG9hZCBUQSBpbnN0
cnVjdGlvbnMNCnJzaV85MXg6IHJzaV9wcm9iZTogRmFpbGVkIGluIGRldmljZSBpbml0DQpyc2lf
OTF4OiByc2lfcHJvYmU6IEZhaWxlZCBpbiBwcm9iZS4uLkV4aXRpbmcNClJTSS1VU0IgV0xBTjog
cHJvYmUgb2YgMS0xOjEuMCBmYWlsZWQgd2l0aCBlcnJvciAtMjINCi0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLT44LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KQW55IHRob3VnaHRzPw0K
DQotQWxleGV5DQoNClsxXcKgaHR0cHM6Ly9naXQua2VybmVsLm9yZy9wdWIvc2NtL2xpbnV4L2tl
cm5lbC9naXQvZmlybXdhcmUvbGludXgtZmlybXdhcmUuZ2l0L3RyZWUvcnNpL3JzOTExM193bGFu
X3FzcGkucnBz
From: Karun Eagalapati <[email protected]>
SDIO host is already claimed in our interrupt handler. Some lower
level APIs claims host while performing SDIO read or write operations.
Let's use sdio_irq_task variable to check if we are in interrupt
context and claim/release the host accordingly.
Signed-off-by: Karun Eagalapati <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_sdio.c | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
index f1ba8ac..42d558b 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -138,12 +138,15 @@ 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;
if (adapter->priv->fsm_state == FSM_FW_NOT_LOADED)
return;
- sdio_release_host(function);
+
+ dev->sdio_irq_task = current;
rsi_interrupt_handler(adapter);
- sdio_claim_host(function);
+ dev->sdio_irq_task = NULL;
}
/**
@@ -407,14 +410,16 @@ int rsi_sdio_read_register(struct rsi_hw *adapter,
u8 fun_num = 0;
int status;
- sdio_claim_host(dev->pfunction);
+ if (likely(dev->sdio_irq_task != current))
+ sdio_claim_host(dev->pfunction);
if (fun_num == 0)
*data = sdio_f0_readb(dev->pfunction, addr, &status);
else
*data = sdio_readb(dev->pfunction, addr, &status);
- sdio_release_host(dev->pfunction);
+ if (likely(dev->sdio_irq_task != current))
+ sdio_release_host(dev->pfunction);
return status;
}
@@ -438,14 +443,16 @@ int rsi_sdio_write_register(struct rsi_hw *adapter,
(struct rsi_91x_sdiodev *)adapter->rsi_dev;
int status = 0;
- sdio_claim_host(dev->pfunction);
+ if (likely(dev->sdio_irq_task != current))
+ sdio_claim_host(dev->pfunction);
if (function == 0)
sdio_f0_writeb(dev->pfunction, *data, addr, &status);
else
sdio_writeb(dev->pfunction, *data, addr, &status);
- sdio_release_host(dev->pfunction);
+ if (likely(dev->sdio_irq_task != current))
+ sdio_release_host(dev->pfunction);
return status;
}
@@ -490,11 +497,13 @@ static int rsi_sdio_read_register_multiple(struct rsi_hw *adapter,
(struct rsi_91x_sdiodev *)adapter->rsi_dev;
u32 status;
- sdio_claim_host(dev->pfunction);
+ if (likely(dev->sdio_irq_task != current))
+ sdio_claim_host(dev->pfunction);
status = sdio_readsb(dev->pfunction, data, addr, count);
- sdio_release_host(dev->pfunction);
+ 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__);
@@ -532,11 +541,13 @@ int rsi_sdio_write_register_multiple(struct rsi_hw *adapter,
dev->write_fail++;
}
- sdio_claim_host(dev->pfunction);
+ if (likely(dev->sdio_irq_task != current))
+ sdio_claim_host(dev->pfunction);
status = sdio_writesb(dev->pfunction, addr, data, count);
- sdio_release_host(dev->pfunction);
+ 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",
--
2.7.4
From: Karun Eagalapati <[email protected]>
These endpoints are for WLAN and BT protocols.
Signed-off-by: Karun Eagalapati <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_usb.c | 2 +-
drivers/net/wireless/rsi/rsi_usb.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c
index dc0a0b2..99967ce 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
@@ -384,7 +384,7 @@ static int rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter,
u32 queueno = ((pkt[1] >> 4) & 0x7);
u8 endpoint;
- endpoint = ((queueno == RSI_WIFI_MGMT_Q) ? MGMT_EP : DATA_EP);
+ endpoint = ((queueno == RSI_WIFI_MGMT_Q) ? WLAN_EP : BT_EP);
return rsi_write_multiple(adapter,
endpoint,
diff --git a/drivers/net/wireless/rsi/rsi_usb.h b/drivers/net/wireless/rsi/rsi_usb.h
index 2c5c0e7..3babf81 100644
--- a/drivers/net/wireless/rsi/rsi_usb.h
+++ b/drivers/net/wireless/rsi/rsi_usb.h
@@ -33,8 +33,8 @@
#define MAX_RX_URBS 1
#define MAX_BULK_EP 8
-#define MGMT_EP 1
-#define DATA_EP 2
+#define WLAN_EP 1
+#define BT_EP 2
#define RSI_USB_BUF_SIZE 4096
--
2.7.4
From: Karun Eagalapati <[email protected]>
The variable in_sdio_litefi_irq is renamed to sdio_irq_task,
as it is more relevant here.
Signed-off-by: Karun Eagalapati <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_sdio.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/rsi/rsi_sdio.h b/drivers/net/wireless/rsi/rsi_sdio.h
index f11f818..cbbc0448 100644
--- a/drivers/net/wireless/rsi/rsi_sdio.h
+++ b/drivers/net/wireless/rsi/rsi_sdio.h
@@ -104,7 +104,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;
--
2.7.4
From: Karun Eagalapati <[email protected]>
Till now only management packets were handled. Let's enhance
the logic for choosing endpoint to accommodate other packets.
Signed-off-by: Karun Eagalapati <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_usb.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c
index 99967ce..3febf24 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
@@ -384,7 +384,8 @@ static int rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter,
u32 queueno = ((pkt[1] >> 4) & 0x7);
u8 endpoint;
- endpoint = ((queueno == RSI_WIFI_MGMT_Q) ? WLAN_EP : BT_EP);
+ endpoint = ((queueno == RSI_WIFI_MGMT_Q || queueno == RSI_WIFI_DATA_Q ||
+ queueno == RSI_COEX_Q) ? WLAN_EP : BT_EP);
return rsi_write_multiple(adapter,
endpoint,
--
2.7.4
From: Karun Eagalapati <[email protected]>
Newer firmware sends information about number of blocks through
interrupt only. We don't need to read extra register for this.
This patch adds needed driver changes for this enhancment. The
change here is backward compatible
Signed-off-by: Karun Eagalapati <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 34 ++++++++++++++++++++++-------
drivers/net/wireless/rsi/rsi_main.h | 1 +
drivers/net/wireless/rsi/rsi_sdio.h | 1 +
3 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
index df2a63b..b6d0e2a 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
@@ -69,20 +69,37 @@ int rsi_sdio_master_access_msword(struct rsi_hw *adapter, u16 ms_word)
static int rsi_process_pkt(struct rsi_common *common)
{
struct rsi_hw *adapter = common->priv;
+ struct rsi_91x_sdiodev *dev =
+ (struct rsi_91x_sdiodev *)adapter->rsi_dev;
u8 num_blks = 0;
u32 rcv_pkt_len = 0;
int status = 0;
+ u8 value = 0;
- status = rsi_sdio_read_register(adapter,
- SDIO_RX_NUM_BLOCKS_REG,
- &num_blks);
+ num_blks = ((adapter->interrupt_status & 1) |
+ ((adapter->interrupt_status >> RECV_NUM_BLOCKS) << 1));
- if (status) {
- rsi_dbg(ERR_ZONE,
- "%s: Failed to read pkt length from the card:\n",
- __func__);
- return status;
+ if (!num_blks) {
+ status = rsi_sdio_read_register(adapter,
+ SDIO_RX_NUM_BLOCKS_REG,
+ &value);
+ if (status) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Failed to read pkt length from the card:\n",
+ __func__);
+ return status;
+ }
+ num_blks = value & 0x1f;
}
+
+ if (dev->write_fail == 2)
+ rsi_sdio_ack_intr(common->priv, (1 << MSDU_PKT_PENDING));
+
+ if (unlikely(!num_blks)) {
+ dev->write_fail = 2;
+ return -1;
+ }
+
rcv_pkt_len = (num_blks * 256);
common->rx_data_pkt = kmalloc(rcv_pkt_len, GFP_KERNEL);
@@ -224,6 +241,7 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
mutex_unlock(&common->tx_rxlock);
return;
}
+ adapter->interrupt_status = isr_status;
if (isr_status == 0) {
rsi_set_event(&common->tx_thread.event);
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index 4b4312e..febecbd 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -273,6 +273,7 @@ struct rsi_hw {
bool blcmd_timer_expired;
u32 flash_capacity;
struct eepromrw_info eeprom;
+ u32 interrupt_status;
u8 dfs_region;
void *rsi_dev;
struct rsi_host_intf_ops *host_intf_ops;
diff --git a/drivers/net/wireless/rsi/rsi_sdio.h b/drivers/net/wireless/rsi/rsi_sdio.h
index cbbc0448..3cf6756 100644
--- a/drivers/net/wireless/rsi/rsi_sdio.h
+++ b/drivers/net/wireless/rsi/rsi_sdio.h
@@ -41,6 +41,7 @@ enum sdio_interrupt_type {
#define PKT_BUFF_FULL 1
#define PKT_MGMT_BUFF_FULL 2
#define MSDU_PKT_PENDING 3
+#define RECV_NUM_BLOCKS 4
/* Interrupt Bit Related Macros */
#define PKT_BUFF_AVAILABLE 1
#define FW_ASSERT_IND 2
--
2.7.4
From: Karun Eagalapati <[email protected]>
immediate wakeup bit is set while sending internal management
frame to the firmware.
Signed-off-by: Karun Eagalapati <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_hal.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index c230359..7c9224f 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -149,6 +149,7 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
extnd_size = ((uintptr_t)skb->data & 0x3);
if (tx_params->flags & INTERNAL_MGMT_PKT) {
+ skb->data[1] |= BIT(7); /* Immediate Wakeup bit*/
if ((extnd_size) > skb_headroom(skb)) {
rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__);
dev_kfree_skb(skb);
--
2.7.4
Hi Alexey,
On Tue, Jun 13, 2017 at 9:13 PM, Alexey Brodkin
<[email protected]> wrote:
> Hi Amitkumar,
>
> On Tue, 2017-06-13 at 20:18 +0530, Amitkumar Karwar wrote:
>> This patch series includes some fixes and enhancements in Tx and Rx
>> data paths. Connection in open security and data traffic has been
>> verified with SDIO and USB variants of 9113 chipset.
>>
>> Amitkumar Karwar (1):
>> rsi: correct the logic of deriving queue number
>>
>> Karun Eagalapati (14):
>> rsi: fix sdio card reset problem
>> rsi: chip reset for SDIO interface
>> rsi: correct SDIO disconnect path handling
>> rsi: card reset for USB interface
>> rsi: USB tx headroom cleanup
>> rsi: rename USB endpoint macros
>> rsi: choose correct endpoint based on queue.
>> rsi: set immediate wakeup bit
>> rsi: separate function for management packet descriptor
>> rsi: rename variable in_sdio_litefi_irq
>> rsi: Optimise sdio claim and release host
>> rsi: SDIO Rx packet processing enhancement
>> rsi: use separate mutex lock for receive thread
>> rsi: Rename mutex tx_rxlock to the tx_lock.
>>
>> Prameela Rani Garnepudi (1):
>> rsi: changes in eeprom read frame
>>
>> pavani.muthyala (4):
>> rsi: management frame descriptor preparation cleanup
>> rsi: data packet descriptor code cleanup
>> rsi: data packet descriptor enhancements
>> rsi: separate function for data packet descriptor
>
> Finally with this patch-set I got new firmware [1] successfully loaded
> in rs9113 module via SDIO (but not via USB, read-on).
> --------------------------->8--------------------------
> rsi_91x: ***** Firmware Loading successful *****
> --------------------------->8--------------------------
>
> Also I may now execute "ifconfig wlan0 up" succesfully:
Good to know this.
> --------------------------->8--------------------------
> # ifconfig wlan0
> wlan0 Link encap:Ethernet HWaddr 00:23:A7:90:3F:2C
> UP BROADCAST MULTICAST MTU:1500 Metric:1
> RX packets:0 errors:0 dropped:0 overruns:0 frame:0
> TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
> collisions:0 txqueuelen:1000
> RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
> --------------------------->8--------------------------
>
> Next thing I tried (and that's what I do with any other wireless
> adapter that supports AP mode) is adding wlan0 to a bridge with eth0
> with subsequent execution of hostapd to get me so-called dumb AP.
AP mode is not supported yet. We will be submitting patches for AP
mode in couple of weeks.
>
> Usually that's what I do:
> --------------------------->8--------------------------
> ifconfig wlan0 up
> ifconfig eth0 up
> brctl addbr br0
> brctl addif br0 eth0
> iw dev wlan0 set 4addr on
> brctl addif br0 wlan0
> brctl show
> ifconfig br0 up
> udhcpc -i br0
> hostapd -B /etc/hostapd.conf
> --------------------------->8--------------------------
>
> But now with rs9113 I got:
> 1)
> --------------------------->8--------------------------
> # iw dev wlan0 set 4addr on
> command failed: Operation not supported (-95)
> --------------------------->8--------------------------
>
> 2)
> --------------------------->8--------------------------
> # hostapd -B /etc/hostapd.conf
> Configuration file: /etc/hostapd.conf
> nl80211: Could not configure driver mode
> nl80211: deinit ifname=wlan0 disabled_11b_rates=0
> nl80211 driver initialization failed.
> wlan0: interface state UNINITIALIZED->DISABLED
> wlan0: AP-DISABLED
> hostapd_free_hapd_data: Interface wlan0 wasn't started
> --------------------------->8--------------------------
>
> For example exactly the same procedure works perfectly fine for
> ath9k_htc-based USB dongles.
>
> Now for USB-case there seems to remain similar problem with firmware loading:
> --------------------------->8--------------------------
> usb 1-1: new high-speed USB device number 2 using ehci-platform
> usb 1-1: config 1 interface 0 altsetting 0 endpoint 0x83 has an invalid bInterval 255, changing to 11
> rsi_91x: rsi_probe: Initialized os intf ops
> rsi_91x: rsi_load_firmware: REGOUT read timedout
> rsi_91x: rsi_load_firmware: Soft boot loader not present
> rsi_91x: rsi_hal_device_init: Failed to load TA instructions
> rsi_91x: rsi_probe: Failed in device init
> rsi_91x: rsi_probe: Failed in probe...Exiting
> RSI-USB WLAN: probe of 1-1:1.0 failed with error -22
> --------------------------->8--------------------------
>
> Any thoughts?
We are reading a ROM register here. If expected signature value is
present, we go ahead and download the firmware. In your case that
value isn't found. This could be USB connection/setup problem. Not
sure if it's related to the problem notified by "endpoint 0x83 has an
invalid bInterval" warning.
Regards,
Amitkumar Karwar
From: Karun Eagalapati <[email protected]>
Sometimes it's observed that we get interrupt/Rx frame when device is
already detached from mac80211. In this case couple of error messages
are displayed in dmesg log. This patch corrects the order so that
disconnection will happen cleanly
Signed-off-by: Karun Eagalapati <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_sdio.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
index ebfd29c..f1ba8ac 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -1026,17 +1026,26 @@ static void rsi_disconnect(struct sdio_func *pfunction)
return;
dev = (struct rsi_91x_sdiodev *)adapter->rsi_dev;
+ sdio_claim_host(pfunction);
+ sdio_release_irq(pfunction);
+ sdio_release_host(pfunction);
+ mdelay(10);
- dev->write_fail = 2;
rsi_mac80211_detach(adapter);
+ mdelay(10);
- sdio_claim_host(pfunction);
- sdio_release_irq(pfunction);
- sdio_disable_func(pfunction);
- rsi_91x_deinit(adapter);
+ /* Reset Chip */
rsi_reset_chip(adapter);
+
+ /* Resetting to take care of the case, where-in driver is re-loaded */
+ sdio_claim_host(pfunction);
rsi_reset_card(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");
+
}
#ifdef CONFIG_PM
--
2.7.4
From: Karun Eagalapati <[email protected]>
We need to reset the chip in teardown path so that it can work
next time when driver is loaded. This patch adds support for this
reset configuration for USB.
Signed-off-by: Karun Eagalapati <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_usb.c | 72 ++++++++++++++++++++++++++++++++++
drivers/net/wireless/rsi/rsi_usb.h | 1 +
2 files changed, 73 insertions(+)
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c
index bcd7f45..1d7bb9d 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
@@ -558,6 +558,77 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
return status;
}
+static int usb_ulp_read_write(struct rsi_hw *adapter, u16 addr, u32 data,
+ u16 len_in_bits)
+{
+ int ret;
+
+ ret = rsi_usb_master_reg_write
+ (adapter, RSI_GSPI_DATA_REG1,
+ ((addr << 6) | ((data >> 16) & 0xffff)), 2);
+ if (ret < 0)
+ return ret;
+
+ ret = rsi_usb_master_reg_write(adapter, RSI_GSPI_DATA_REG0,
+ (data & 0xffff), 2);
+ if (ret < 0)
+ return ret;
+
+ /* Initializing GSPI for ULP read/writes */
+ rsi_usb_master_reg_write(adapter, RSI_GSPI_CTRL_REG0,
+ RSI_GSPI_CTRL_REG0_VALUE, 2);
+
+ ret = rsi_usb_master_reg_write(adapter, RSI_GSPI_CTRL_REG1,
+ ((len_in_bits - 1) | RSI_GSPI_TRIG), 2);
+ if (ret < 0)
+ return ret;
+
+ msleep(20);
+
+ return 0;
+}
+
+static int rsi_reset_card(struct rsi_hw *adapter)
+{
+ int ret;
+
+ rsi_dbg(INFO_ZONE, "Resetting Card...\n");
+ rsi_usb_master_reg_write(adapter, RSI_TA_HOLD_REG, 0xE, 4);
+
+ /* This msleep will ensure Thread-Arch processor to go to hold
+ * and any pending dma transfers to rf in device to finish.
+ */
+ msleep(100);
+
+ ret = usb_ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_1,
+ RSI_ULP_WRITE_2, 32);
+ if (ret < 0)
+ goto fail;
+ ret = usb_ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_2,
+ RSI_ULP_WRITE_0, 32);
+ if (ret < 0)
+ goto fail;
+ ret = usb_ulp_read_write(adapter, RSI_WATCH_DOG_DELAY_TIMER_1,
+ RSI_ULP_WRITE_50, 32);
+ if (ret < 0)
+ goto fail;
+ ret = usb_ulp_read_write(adapter, RSI_WATCH_DOG_DELAY_TIMER_2,
+ RSI_ULP_WRITE_0, 32);
+ if (ret < 0)
+ goto fail;
+ ret = usb_ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_ENABLE,
+ RSI_ULP_TIMER_ENABLE, 32);
+ if (ret < 0)
+ goto fail;
+
+ rsi_dbg(INFO_ZONE, "Reset card done\n");
+ return ret;
+
+fail:
+ rsi_dbg(ERR_ZONE, "Reset card failed\n");
+ return ret;
+}
+
/**
* rsi_probe() - This function is called by kernel when the driver provided
* Vendor and device IDs are matched. All the initialization
@@ -641,6 +712,7 @@ static void rsi_disconnect(struct usb_interface *pfunction)
return;
rsi_mac80211_detach(adapter);
+ rsi_reset_card(adapter);
rsi_deinit_usb_interface(adapter);
rsi_91x_deinit(adapter);
diff --git a/drivers/net/wireless/rsi/rsi_usb.h b/drivers/net/wireless/rsi/rsi_usb.h
index 59513ac..2c5c0e7 100644
--- a/drivers/net/wireless/rsi/rsi_usb.h
+++ b/drivers/net/wireless/rsi/rsi_usb.h
@@ -25,6 +25,7 @@
#define USB_INTERNAL_REG_1 0x25000
#define RSI_USB_READY_MAGIC_NUM 0xab
#define FW_STATUS_REG 0x41050012
+#define RSI_TA_HOLD_REG 0x22000844
#define USB_VENDOR_REGISTER_READ 0x15
#define USB_VENDOR_REGISTER_WRITE 0x16
--
2.7.4
From: Karun Eagalapati <[email protected]>
We need to reset the chip in teardown path so that it can work
next time when driver is loaded. This patch adds support for
this reset configuration for SDIO.
Signed-off-by: Karun Eagalapati <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_sdio.c | 80 ++++++++++++++++++++++++++++++++-
drivers/net/wireless/rsi/rsi_hal.h | 33 ++++++++++++++
drivers/net/wireless/rsi/rsi_sdio.h | 1 +
3 files changed, 113 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
index b5ac503..ebfd29c 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -933,6 +933,84 @@ static int rsi_probe(struct sdio_func *pfunction,
return 1;
}
+static void ulp_read_write(struct rsi_hw *adapter, u16 addr, u32 data,
+ u16 len_in_bits)
+{
+ rsi_sdio_master_reg_write(adapter, RSI_GSPI_DATA_REG1,
+ ((addr << 6) | ((data >> 16) & 0xffff)), 2);
+ rsi_sdio_master_reg_write(adapter, RSI_GSPI_DATA_REG0,
+ (data & 0xffff), 2);
+ rsi_sdio_master_reg_write(adapter, RSI_GSPI_CTRL_REG0,
+ RSI_GSPI_CTRL_REG0_VALUE, 2);
+ rsi_sdio_master_reg_write(adapter, RSI_GSPI_CTRL_REG1,
+ ((len_in_bits - 1) | RSI_GSPI_TRIG), 2);
+ msleep(20);
+}
+
+/*This function resets and re-initializes the chip.*/
+static void rsi_reset_chip(struct rsi_hw *adapter)
+{
+ __le32 data;
+ u8 sdio_interrupt_status = 0;
+ u8 request = 1;
+ int ret;
+
+ rsi_dbg(INFO_ZONE, "Writing disable to wakeup register\n");
+ ret = rsi_sdio_write_register(adapter, 0, SDIO_WAKEUP_REG, &request);
+ if (ret < 0) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Failed to write SDIO wakeup register\n", __func__);
+ return;
+ }
+ msleep(20);
+ ret = rsi_sdio_read_register(adapter, RSI_FN1_INT_REGISTER,
+ &sdio_interrupt_status);
+ if (ret < 0) {
+ 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",
+ __func__, sdio_interrupt_status);
+
+ /* Put Thread-Arch processor on hold */
+ if (rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR)) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Unable to set ms word to common reg\n",
+ __func__);
+ return;
+ }
+
+ data = TA_HOLD_THREAD_VALUE;
+ if (rsi_sdio_write_register_multiple(adapter, TA_HOLD_THREAD_REG |
+ RSI_SD_REQUEST_MASTER,
+ (u8 *)&data, 4)) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Unable to hold Thread-Arch processor threads\n",
+ __func__);
+ return;
+ }
+
+ /* This msleep will ensure Thread-Arch processor to go to hold
+ * and any pending dma transfers to rf spi in device to finish.
+ */
+ msleep(100);
+
+ ulp_read_write(adapter, RSI_ULP_RESET_REG, RSI_ULP_WRITE_0, 32);
+ ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_1, RSI_ULP_WRITE_2, 32);
+ ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_2, RSI_ULP_WRITE_0, 32);
+ ulp_read_write(adapter, RSI_WATCH_DOG_DELAY_TIMER_1, RSI_ULP_WRITE_50,
+ 32);
+ ulp_read_write(adapter, RSI_WATCH_DOG_DELAY_TIMER_2, RSI_ULP_WRITE_0,
+ 32);
+ ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_ENABLE,
+ RSI_ULP_TIMER_ENABLE, 32);
+ /* This msleep will be sufficient for the ulp
+ * read write operations to complete for chip reset.
+ */
+ msleep(500);
+}
+
/**
* rsi_disconnect() - This function performs the reverse of the probe function.
* @pfunction: Pointer to the sdio_func structure.
@@ -956,7 +1034,7 @@ static void rsi_disconnect(struct sdio_func *pfunction)
sdio_release_irq(pfunction);
sdio_disable_func(pfunction);
rsi_91x_deinit(adapter);
- /* Resetting to take care of the case, where-in driver is re-loaded */
+ rsi_reset_chip(adapter);
rsi_reset_card(pfunction);
sdio_release_host(pfunction);
}
diff --git a/drivers/net/wireless/rsi/rsi_hal.h b/drivers/net/wireless/rsi/rsi_hal.h
index 902dc54..3179e86 100644
--- a/drivers/net/wireless/rsi/rsi_hal.h
+++ b/drivers/net/wireless/rsi/rsi_hal.h
@@ -52,6 +52,39 @@
#define FW_LOADING_SUCCESSFUL 'S'
#define LOADING_INITIATED '1'
+#define RSI_ULP_RESET_REG 0x161
+#define RSI_WATCH_DOG_TIMER_1 0x16c
+#define RSI_WATCH_DOG_TIMER_2 0x16d
+#define RSI_WATCH_DOG_DELAY_TIMER_1 0x16e
+#define RSI_WATCH_DOG_DELAY_TIMER_2 0x16f
+#define RSI_WATCH_DOG_TIMER_ENABLE 0x170
+
+#define RSI_ULP_WRITE_0 00
+#define RSI_ULP_WRITE_2 02
+#define RSI_ULP_WRITE_50 50
+
+#define RSI_RESTART_WDT BIT(11)
+#define RSI_BYPASS_ULP_ON_WDT BIT(1)
+
+#define RSI_ULP_TIMER_ENABLE ((0xaa000) | RSI_RESTART_WDT | \
+ RSI_BYPASS_ULP_ON_WDT)
+#define RSI_RF_SPI_PROG_REG_BASE_ADDR 0x40080000
+
+#define RSI_GSPI_CTRL_REG0 (RSI_RF_SPI_PROG_REG_BASE_ADDR)
+#define RSI_GSPI_CTRL_REG1 (RSI_RF_SPI_PROG_REG_BASE_ADDR + 0x2)
+#define RSI_GSPI_DATA_REG0 (RSI_RF_SPI_PROG_REG_BASE_ADDR + 0x4)
+#define RSI_GSPI_DATA_REG1 (RSI_RF_SPI_PROG_REG_BASE_ADDR + 0x6)
+#define RSI_GSPI_DATA_REG2 (RSI_RF_SPI_PROG_REG_BASE_ADDR + 0x8)
+
+#define RSI_GSPI_CTRL_REG0_VALUE 0x340
+
+#define RSI_GSPI_DMA_MODE BIT(13)
+
+#define RSI_GSPI_2_ULP BIT(12)
+#define RSI_GSPI_TRIG BIT(7)
+#define RSI_GSPI_READ BIT(6)
+#define RSI_GSPI_RF_SPI_ACTIVE BIT(8)
+
/* Boot loader commands */
#define SEND_RPS_FILE '2'
diff --git a/drivers/net/wireless/rsi/rsi_sdio.h b/drivers/net/wireless/rsi/rsi_sdio.h
index 9fb73f6..f11f818 100644
--- a/drivers/net/wireless/rsi/rsi_sdio.h
+++ b/drivers/net/wireless/rsi/rsi_sdio.h
@@ -58,6 +58,7 @@ enum sdio_interrupt_type {
#define SDIO_READ_START_LVL 0x000FC
#define SDIO_READ_FIFO_CTL 0x000FD
#define SDIO_WRITE_FIFO_CTL 0x000FE
+#define SDIO_WAKEUP_REG 0x000FF
#define SDIO_FUN1_INTR_CLR_REG 0x0008
#define SDIO_REG_HIGH_SPEED 0x0013
--
2.7.4
From: "pavani.muthyala" <[email protected]>
Currently this descriptor is prepared with the help of __le16
pointer. This patch makes use of a structure to prepare the
descriptor in a cleaner way.
Signed-off-by: pavani.muthyala <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_hal.c | 37 +++++++++++++++++-----------------
drivers/net/wireless/rsi/rsi_hal.h | 23 +++++++++++++++++++++
2 files changed, 41 insertions(+), 19 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index 7c9224f..461352a 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -138,9 +138,9 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
struct ieee80211_bss_conf *bss;
struct ieee80211_hw *hw = adapter->hw;
struct ieee80211_conf *conf = &hw->conf;
+ struct rsi_mgmt_desc *mgmt_desc;
struct skb_info *tx_params;
int status = -E2BIG;
- __le16 *msg;
u8 extnd_size;
u8 vap_id = 0;
@@ -176,44 +176,43 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
skb_push(skb, FRAME_DESC_SZ);
memset(skb->data, 0, FRAME_DESC_SZ);
- msg = (__le16 *)skb->data;
+ mgmt_desc = (struct rsi_mgmt_desc *)skb->data;
if (skb->len > MAX_MGMT_PKT_SIZE) {
rsi_dbg(INFO_ZONE, "%s: Dropping mgmt pkt > 512\n", __func__);
goto err;
}
- msg[0] = cpu_to_le16((skb->len - FRAME_DESC_SZ) |
- (RSI_WIFI_MGMT_Q << 12));
- msg[1] = cpu_to_le16(TX_DOT11_MGMT);
- msg[2] = cpu_to_le16(MIN_802_11_HDR_LEN << 8);
- msg[3] = cpu_to_le16(RATE_INFO_ENABLE);
- msg[6] = cpu_to_le16(le16_to_cpu(wh->seq_ctrl) >> 4);
+ mgmt_desc->length = skb->len - FRAME_DESC_SZ;
+ mgmt_desc->q_num = RSI_WIFI_MGMT_Q;
+ mgmt_desc->frame_type = TX_DOT11_MGMT;
+ mgmt_desc->header_len = MIN_802_11_HDR_LEN;
+ mgmt_desc->info_cap |= cpu_to_le16(RATE_INFO_ENABLE);
+ mgmt_desc->seq_ctrl = cpu_to_le16(le16_to_cpu(wh->seq_ctrl) >> 4);
if (wh->addr1[0] & BIT(0))
- msg[3] |= cpu_to_le16(RSI_BROADCAST_PKT);
+ mgmt_desc->info_cap |= cpu_to_le16(RSI_BROADCAST_PKT);
if (common->band == NL80211_BAND_2GHZ)
- msg[4] = cpu_to_le16(RSI_11B_MODE);
+ mgmt_desc->rate_info = RSI_11B_MODE;
else
- msg[4] = cpu_to_le16((RSI_RATE_6 & 0x0f) | RSI_11G_MODE);
+ mgmt_desc->rate_info = (RSI_RATE_6 & 0x0f) | RSI_11G_MODE;
if (conf_is_ht40(conf)) {
- msg[4] = cpu_to_le16(0xB | RSI_11G_MODE);
- msg[5] = cpu_to_le16(0x6);
+ mgmt_desc->rate_info = 0xB | RSI_11G_MODE;
+ mgmt_desc->bbp_info = BBP_INFO_40MHZ;
}
/* Indicate to firmware to give cfm */
if ((skb->data[16] == IEEE80211_STYPE_PROBE_REQ) && (!bss->assoc)) {
- msg[1] |= cpu_to_le16(BIT(10));
- msg[7] = cpu_to_le16(PROBEREQ_CONFIRM);
+ mgmt_desc->misc_flags |= BIT(2);
+ mgmt_desc->cfm_frame_type = PROBEREQ_CONFIRM;
common->mgmt_q_block = true;
}
+ mgmt_desc->vap_info = vap_id << 8;
- msg[7] |= cpu_to_le16(vap_id << 8);
-
- status = adapter->host_intf_ops->write_pkt(common->priv, (u8 *)msg,
- skb->len);
+ status = adapter->host_intf_ops->write_pkt(common->priv,
+ (u8 *)mgmt_desc, skb->len);
if (status)
rsi_dbg(ERR_ZONE, "%s: Failed to write the packet\n", __func__);
diff --git a/drivers/net/wireless/rsi/rsi_hal.h b/drivers/net/wireless/rsi/rsi_hal.h
index 3179e86..921123e 100644
--- a/drivers/net/wireless/rsi/rsi_hal.h
+++ b/drivers/net/wireless/rsi/rsi_hal.h
@@ -99,6 +99,8 @@
#define RSI_DEV_OPMODE_WIFI_ALONE 1
#define RSI_DEV_COEX_MODE_WIFI_ALONE 1
+#define BBP_INFO_40MHZ 0x6
+
struct bl_header {
__le32 flags;
__le32 image_no;
@@ -112,6 +114,27 @@ struct ta_metadata {
unsigned int address;
};
+struct rsi_mgmt_desc {
+#ifdef __LITTLE_ENDIAN
+ u16 length : 12;
+ u16 q_num :4;
+#else
+ u16 q_num :4;
+ u16 length : 12;
+#endif
+ u8 frame_type;
+ u8 misc_flags;
+ u8 reserved1;
+ u8 header_len;
+ __le16 info_cap;
+ u8 rate_info;
+ u8 reserved2;
+ u16 bbp_info;
+ __le16 seq_ctrl;
+ u8 cfm_frame_type;
+ u8 vap_info;
+} __packed;
+
int rsi_hal_device_init(struct rsi_hw *adapter);
#endif
--
2.7.4
From: Karun Eagalapati <[email protected]>
Deadlock issue is observed during our stress tests. The root
cause for the issue is same lock is used between tx and rx threads.
This patch adds a separate mutex lock for rx thread to resolve
the problem.
Signed-off-by: Karun Eagalapati <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 10 +++++-----
drivers/net/wireless/rsi/rsi_91x_usb_ops.c | 6 +++---
drivers/net/wireless/rsi/rsi_main.h | 2 ++
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
index b6d0e2a..b3f7adc 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
@@ -230,7 +230,7 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
dev->rx_info.sdio_int_counter++;
do {
- mutex_lock(&common->tx_rxlock);
+ mutex_lock(&common->rx_lock);
status = rsi_sdio_read_register(common->priv,
RSI_FN1_INT_REGISTER,
&isr_status);
@@ -238,7 +238,7 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
rsi_dbg(ERR_ZONE,
"%s: Failed to Read Intr Status Register\n",
__func__);
- mutex_unlock(&common->tx_rxlock);
+ mutex_unlock(&common->rx_lock);
return;
}
adapter->interrupt_status = isr_status;
@@ -246,7 +246,7 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
if (isr_status == 0) {
rsi_set_event(&common->tx_thread.event);
dev->rx_info.sdio_intr_status_zero++;
- mutex_unlock(&common->tx_rxlock);
+ mutex_unlock(&common->rx_lock);
return;
}
@@ -304,7 +304,7 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
rsi_dbg(ERR_ZONE,
"%s: Failed to read pkt\n",
__func__);
- mutex_unlock(&common->tx_rxlock);
+ mutex_unlock(&common->rx_lock);
return;
}
break;
@@ -319,7 +319,7 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
}
isr_status ^= BIT(isr_type - 1);
} while (isr_status);
- mutex_unlock(&common->tx_rxlock);
+ mutex_unlock(&common->rx_lock);
} while (1);
}
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb_ops.c b/drivers/net/wireless/rsi/rsi_91x_usb_ops.c
index d3e0a07..465692b 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb_ops.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb_ops.c
@@ -37,14 +37,14 @@ void rsi_usb_rx_thread(struct rsi_common *common)
if (atomic_read(&dev->rx_thread.thread_done))
goto out;
- mutex_lock(&common->tx_rxlock);
+ mutex_lock(&common->rx_lock);
status = rsi_read_pkt(common, 0);
if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed To read data", __func__);
- mutex_unlock(&common->tx_rxlock);
+ mutex_unlock(&common->rx_lock);
return;
}
- mutex_unlock(&common->tx_rxlock);
+ mutex_unlock(&common->rx_lock);
rsi_reset_event(&dev->rx_thread.event);
if (adapter->rx_urb_submit(adapter)) {
rsi_dbg(ERR_ZONE,
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index febecbd..6d41c9b 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -179,6 +179,8 @@ struct rsi_common {
struct mutex mutex;
/* Mutex used between tx/rx threads */
struct mutex tx_rxlock;
+ /* Mutex used for rx thread */
+ struct mutex rx_lock;
u8 endpoint;
/* Channel/band related */
--
2.7.4
From: "pavani.muthyala" <[email protected]>
Data packet descriptor preparation code is moved a separate
function.
Signed-off-by: pavani.muthyala <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_hal.c | 41 +++++++++++++++++-----------------
1 file changed, 21 insertions(+), 20 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index 20cb608..8fcbadc 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -111,15 +111,8 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)
return 0;
}
-/**
- * rsi_send_data_pkt() - This function sends the recieved 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)
+/* This function prepares descriptor for given data packet */
+static int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
{
struct rsi_hw *adapter = common->priv;
struct ieee80211_hdr *wh = NULL;
@@ -129,7 +122,6 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
struct ieee80211_bss_conf *bss;
struct rsi_data_desc *data_desc;
struct xtended_desc *xtend_desc;
- int status;
u8 ieee80211_size = MIN_802_11_HDR_LEN;
u8 header_size = 0;
u8 vap_id = 0;
@@ -140,22 +132,19 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
bss = &info->control.vif->bss_conf;
tx_params = (struct skb_info *)info->driver_data;
- if (!bss->assoc) {
- status = -EINVAL;
- goto err;
- }
+ if (!bss->assoc)
+ return -EINVAL;
+
header_size = FRAME_DESC_SZ + sizeof(struct xtended_desc);
if (header_size > skb_headroom(skb)) {
rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__);
- status = -ENOSPC;
- goto err;
+ return -ENOSPC;
}
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__);
- status = -ENOSPC;
- goto err;
+ return -ENOSPC;
}
skb_push(skb, dword_align_bytes);
header_size += dword_align_bytes;
@@ -232,11 +221,23 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
data_desc->sta_id = vap_id;
}
+ return 0;
+}
+
+/* This function sends received data packet from driver to device */
+int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
+{
+ struct rsi_hw *adapter = common->priv;
+ int status;
+
+ status = rsi_prepare_data_desc(common, skb);
+ if (status)
+ goto err;
+
status = adapter->host_intf_ops->write_pkt(common->priv, skb->data,
skb->len);
if (status)
- rsi_dbg(ERR_ZONE, "%s: Failed to write pkt\n",
- __func__);
+ rsi_dbg(ERR_ZONE, "%s: Failed to write pkt\n", __func__);
err:
++common->tx_stats.total_tx_pkt_freed[skb->priority];
--
2.7.4