2017-07-06 14:41:22

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 00/21] rsi driver enhancements

From: Amitkumar Karwar <[email protected]>

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.

Changes in v3 series:
1/21: Newly added patch in v3 which makes use of BUILD_BUG_ON to avoid
potential issue in future(Kalle Valo)
2/21: Added missing change in debugfs fsm_state array(Kalle Valo)
12/21, 14/21, 15/21, 16/21: Pavani's name corrected

Changes in v2 series:
1/20: Get rid of __LITTLE_ENDIAN flag usage
11/20: Get rid of __LITTLE_ENDIAN flag usage
12/20: Changes to match modified 11/20
13/20: Get rid of __LITTLE_ENDIAN flag usage
14/20: Changes to match modified 13/20
15/20: Changes to match modified 13/20
19/20: mutex_init was missed for rx_lock in v1

Amitkumar Karwar (2):
rsi: use BUILD_BUG_ON check for fsm_state
rsi: correct the logic of deriving queue number

Karun Eagalapati (13):
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: 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.

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

Prameela Rani Garnepudi (2):
rsi: changes in eeprom read frame
rsi: separate function for management packet descriptor

drivers/net/wireless/rsi/rsi_91x_core.c | 10 +-
drivers/net/wireless/rsi/rsi_91x_debugfs.c | 3 +
drivers/net/wireless/rsi/rsi_91x_hal.c | 270 ++++++++++++++++++----------
drivers/net/wireless/rsi/rsi_91x_main.c | 3 +-
drivers/net/wireless/rsi/rsi_91x_mgmt.c | 90 +++++++---
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 | 64 +++++++
drivers/net/wireless/rsi/rsi_main.h | 34 +++-
drivers/net/wireless/rsi/rsi_mgmt.h | 26 ++-
drivers/net/wireless/rsi/rsi_sdio.h | 4 +-
drivers/net/wireless/rsi/rsi_usb.h | 5 +-
14 files changed, 623 insertions(+), 208 deletions(-)

--
2.7.4


2017-07-06 14:43:15

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 18/21] rsi: Optimise sdio claim and release host

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]>
Signed-off-by: Prameela Rani Garnepudi <[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

2017-07-28 14:24:42

by Kalle Valo

[permalink] [raw]
Subject: Re: [v3,01/21] rsi: use BUILD_BUG_ON check for fsm_state

Amitkumar Karwar <[email protected]> wrote:

> From: Amitkumar Karwar <[email protected]>
>
> Whenever new fsm_state enum element is added, fsm_state array
> also needs to be updated. If this change is missed, we may end
> up doing invalid access in array. BUILD_BUG_ON check will help
> to avoid this problem.
>
> Signed-off-by: Amitkumar Karwar <[email protected]>

21 patches applied to wireless-drivers-next.git, thanks.

e0d0ae8a4304 rsi: use BUILD_BUG_ON check for fsm_state
09cfb41f3579 rsi: changes in eeprom read frame
f95bbd979df7 rsi: fix sdio card reset problem
49ddac0d4b80 rsi: chip reset for SDIO interface
f746606a51ed rsi: correct SDIO disconnect path handling
ea0676c47085 rsi: card reset for USB interface
ed833be6faa0 rsi: USB tx headroom cleanup
ac6107caa0d8 rsi: correct the logic of deriving queue number
5d16a1c1ae11 rsi: rename USB endpoint macros
d1f69e418f66 rsi: choose correct endpoint based on queue.
015240018b0a rsi: set immediate wakeup bit
de2dea16ec9f rsi: management frame descriptor preparation cleanup
6507de6df900 rsi: separate function for management packet descriptor
af1930977678 rsi: data packet descriptor code cleanup
0eb42586cf87 rsi: data packet descriptor enhancements
ceb2e4eab994 rsi: separate function for data packet descriptor
5f6ae7cae211 rsi: rename variable in_sdio_litefi_irq
72bccf51d459 rsi: Optimise sdio claim and release host
ebf084ea0ec7 rsi: SDIO Rx packet processing enhancement
6c409cad3d2b rsi: use separate mutex lock for receive thread
cb16453565f8 rsi: Rename mutex tx_rxlock to the tx_lock.

--
https://patchwork.kernel.org/patch/9828403/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2017-07-06 14:41:38

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 02/21] rsi: changes in eeprom read frame

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_debugfs.c | 1 +
drivers/net/wireless/rsi/rsi_91x_mgmt.c | 90 ++++++++++++++++++++----------
drivers/net/wireless/rsi/rsi_main.h | 16 ++++++
drivers/net/wireless/rsi/rsi_mgmt.h | 19 ++++++-
4 files changed, 96 insertions(+), 30 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_debugfs.c b/drivers/net/wireless/rsi/rsi_91x_debugfs.c
index f3b91b6..e98eb55 100644
--- a/drivers/net/wireless/rsi/rsi_91x_debugfs.c
+++ b/drivers/net/wireless/rsi/rsi_91x_debugfs.c
@@ -130,6 +130,7 @@ static int rsi_stats_read(struct seq_file *seq, void *data)
"FSM_COMMON_DEV_PARAMS_SENT",
"FSM_BOOT_PARAMS_SENT",
"FSM_EEPROM_READ_MAC_ADDR",
+ "FSM_EEPROM_READ_RF_TYPE",
"FSM_RESET_MAC_SENT",
"FSM_RADIO_CAPS_SENT",
"FSM_BB_RF_PROG_SENT",
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index d4d365b..ebd1e56 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -1276,7 +1276,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__);
@@ -1289,18 +1290,21 @@ 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);
+ rsi_set_len_qno(&mgmt_frame->len_qno, 0, RSI_WIFI_MGMT_Q);
+ mgmt_frame->pkt_type = EEPROM_READ;
+
/* 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->pkt_info =
+ cpu_to_le32((adapter->eeprom.length << RSI_EEPROM_LEN_OFFSET) &
+ RSI_EEPROM_LEN_MASK);
+ mgmt_frame->pkt_info |= cpu_to_le32((3 << RSI_EEPROM_HDR_SIZE_OFFSET) &
+ RSI_EEPROM_HDR_SIZE_MASK);
+
/* 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);

@@ -1426,19 +1430,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",
@@ -1447,30 +1457,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 72675eb..cbf29c3 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -37,6 +37,7 @@ enum RSI_FSM_STATES {
FSM_COMMON_DEV_PARAMS_SENT,
FSM_BOOT_PARAMS_SENT,
FSM_EEPROM_READ_MAC_ADDR,
+ FSM_EEPROM_READ_RF_TYPE,
FSM_RESET_MAC_SENT,
FSM_RADIO_CAPS_SENT,
FSM_BB_RF_PROG_SENT,
@@ -177,6 +178,7 @@ struct rsi_common {

/* Channel/band related */
u8 band;
+ u8 num_supp_bands;
u8 channel_width;

u16 rts_threshold;
@@ -230,6 +232,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;
@@ -252,6 +267,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 dcb6db7..47926c9 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,
@@ -353,6 +354,22 @@ struct rsi_config_vals {
u8 reserved2[16];
} __packed;

+/* Packet info flags */
+#define RSI_EEPROM_HDR_SIZE_OFFSET 8
+#define RSI_EEPROM_HDR_SIZE_MASK 0x300
+#define RSI_EEPROM_LEN_OFFSET 20
+#define RSI_EEPROM_LEN_MASK 0xFFF00000
+
+struct rsi_eeprom_read_frame {
+ __le16 len_qno;
+ u8 pkt_type;
+ u8 misc_flags;
+ __le32 pkt_info;
+ __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

2017-07-06 14:42:40

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 12/21] rsi: management frame descriptor preparation cleanup

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 | 17 ++++++++++++++++
2 files changed, 35 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..9eaa0a2 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);
+ rsi_set_len_qno(&mgmt_desc->len_qno, (skb->len - FRAME_DESC_SZ),
+ 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..da115dd 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,21 @@ struct ta_metadata {
unsigned int address;
};

+struct rsi_mgmt_desc {
+ __le16 len_qno;
+ 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

2017-07-06 14:41:50

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 04/21] rsi: chip reset for SDIO interface

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

2017-07-06 14:43:00

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 14/21] rsi: data packet descriptor code cleanup

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 | 41 +++++++++++++++++-----------------
drivers/net/wireless/rsi/rsi_hal.h | 13 +++++++++++
drivers/net/wireless/rsi/rsi_mgmt.h | 3 +++
3 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index f8ccb1c..9da2fc8 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -123,10 +123,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);
@@ -150,12 +150,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)) &&
@@ -164,35 +164,34 @@ 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);
}
+ rsi_set_len_qno(&data_desc->len_qno, (skb->len - FRAME_DESC_SZ),
+ 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_tid = ((skb->priority & 0xf) |
+ ((tx_params->tid & 0xf) << 4));
+ data_desc->sta_id = tx_params->sta_id;

- status = adapter->host_intf_ops->write_pkt(common->priv, skb->data,
+ status = adapter->host_intf_ops->write_pkt(adapter, skb->data,
skb->len);
if (status)
rsi_dbg(ERR_ZONE, "%s: Failed to write pkt\n",
@@ -200,7 +199,7 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)

err:
++common->tx_stats.total_tx_pkt_freed[skb->priority];
- rsi_indicate_tx_status(common->priv, skb, status);
+ rsi_indicate_tx_status(adapter, skb, status);
return status;
}

diff --git a/drivers/net/wireless/rsi/rsi_hal.h b/drivers/net/wireless/rsi/rsi_hal.h
index adbe54e..2ae5863 100644
--- a/drivers/net/wireless/rsi/rsi_hal.h
+++ b/drivers/net/wireless/rsi/rsi_hal.h
@@ -129,6 +129,19 @@ struct rsi_mgmt_desc {
u8 vap_info;
} __packed;

+struct rsi_data_desc {
+ __le16 len_qno;
+ u16 reserved;
+ u8 xtend_desc_size;
+ u8 header_len;
+ __le16 frame_info;
+ __le16 rate_info;
+ __le16 bbp_info;
+ __le16 mac_flags;
+ u8 qid_tid;
+ 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 8e05e0b..058dfe5 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

2017-07-06 14:43:31

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 20/21] rsi: use separate mutex lock for receive thread

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]>
Signed-off-by: Prameela Rani Garnepudi <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_main.c | 1 +
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 ++
4 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c
index f1cde0c..939f568 100644
--- a/drivers/net/wireless/rsi/rsi_91x_main.c
+++ b/drivers/net/wireless/rsi/rsi_91x_main.c
@@ -221,6 +221,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->rx_lock);

if (rsi_create_kthread(common,
&common->tx_thread,
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 c2e1c1c..29bccb7 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -181,6 +181,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

2017-07-06 14:42:10

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 07/21] rsi: USB tx headroom cleanup

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

2017-07-06 14:42:49

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 13/21] rsi: separate function for management packet descriptor

From: Prameela Rani Garnepudi <[email protected]>

Management descriptor preparation is move to a separate function
as it will be called from a different context in upcoming patches.

Signed-off-by: Prameela Rani Garnepudi <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_hal.c | 132 +++++++++++++++++++++------------
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, 98 insertions(+), 52 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index 9eaa0a2..f8ccb1c 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -25,6 +25,89 @@ 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;
+ 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__);
+ return -ENOSPC;
+ }
+ 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__);
+ return -ENOSPC;
+ }
+ 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 -EINVAL;
+ }
+ rsi_set_len_qno(&mgmt_desc->len_qno, (skb->len - FRAME_DESC_SZ),
+ 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 +216,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 +245,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;
- }
-
- rsi_set_len_qno(&mgmt_desc->len_qno, (skb->len - FRAME_DESC_SZ),
- 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 da115dd..adbe54e 100644
--- a/drivers/net/wireless/rsi/rsi_hal.h
+++ b/drivers/net/wireless/rsi/rsi_hal.h
@@ -118,14 +118,14 @@ struct rsi_mgmt_desc {
__le16 len_qno;
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 cbf29c3..699e9da 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -105,6 +105,7 @@ struct skb_info {
u16 channel;
s8 tid;
s8 sta_id;
+ u8 internal_hdr_size;
};

enum edca_queue {
@@ -158,6 +159,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 47926c9..8e05e0b 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

2017-07-06 14:43:01

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 15/21] rsi: data packet descriptor enhancements

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]>
Signed-off-by: Prameela Rani Garnepudi <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_hal.c | 64 ++++++++++++++++++++++++++--------
drivers/net/wireless/rsi/rsi_hal.h | 3 +-
drivers/net/wireless/rsi/rsi_mgmt.h | 3 ++
3 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index 9da2fc8..af7fe87 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -119,14 +119,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;
+ u8 vap_id = 0;
+ u8 dword_align_bytes;
u16 seq_num;

info = IEEE80211_SKB_CB(skb);
@@ -137,23 +141,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);
}
@@ -169,7 +184,6 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
rsi_set_len_qno(&data_desc->len_qno, (skb->len - FRAME_DESC_SZ),
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 */
@@ -184,6 +198,21 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
data_desc->rate_info |=
cpu_to_le16(ENABLE_SHORTGI_RATE);
}
+
+ }
+
+ 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);
@@ -191,7 +220,14 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
((tx_params->tid & 0xf) << 4));
data_desc->sta_id = tx_params->sta_id;

- status = adapter->host_intf_ops->write_pkt(adapter, skb->data,
+ 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->sta_id = vap_id;
+ }
+
+ 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",
diff --git a/drivers/net/wireless/rsi/rsi_hal.h b/drivers/net/wireless/rsi/rsi_hal.h
index 2ae5863..00c6a0c 100644
--- a/drivers/net/wireless/rsi/rsi_hal.h
+++ b/drivers/net/wireless/rsi/rsi_hal.h
@@ -131,7 +131,8 @@ struct rsi_mgmt_desc {

struct rsi_data_desc {
__le16 len_qno;
- 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 058dfe5..a8a195e 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

2017-07-06 14:41:33

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 01/21] rsi: use BUILD_BUG_ON check for fsm_state

From: Amitkumar Karwar <[email protected]>

Whenever new fsm_state enum element is added, fsm_state array
also needs to be updated. If this change is missed, we may end
up doing invalid access in array. BUILD_BUG_ON check will help
to avoid this problem.

Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_debugfs.c | 2 ++
drivers/net/wireless/rsi/rsi_main.h | 4 +++-
2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_debugfs.c b/drivers/net/wireless/rsi/rsi_91x_debugfs.c
index 4c0a493..f3b91b6 100644
--- a/drivers/net/wireless/rsi/rsi_91x_debugfs.c
+++ b/drivers/net/wireless/rsi/rsi_91x_debugfs.c
@@ -138,6 +138,8 @@ static int rsi_stats_read(struct seq_file *seq, void *data)
seq_puts(seq, "==> RSI STA DRIVER STATUS <==\n");
seq_puts(seq, "DRIVER_FSM_STATE: ");

+ BUILD_BUG_ON(ARRAY_SIZE(fsm_state) != NUM_FSM_STATES);
+
if (common->fsm_state <= FSM_MAC_INIT_DONE)
seq_printf(seq, "%s", fsm_state[common->fsm_state]);

diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index f398525..72675eb 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -40,7 +40,9 @@ enum RSI_FSM_STATES {
FSM_RESET_MAC_SENT,
FSM_RADIO_CAPS_SENT,
FSM_BB_RF_PROG_SENT,
- FSM_MAC_INIT_DONE
+ FSM_MAC_INIT_DONE,
+
+ NUM_FSM_STATES
};

extern u32 rsi_zone_enabled;
--
2.7.4

2017-07-06 14:41:44

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 03/21] rsi: fix sdio card reset problem

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

2017-07-06 14:42:15

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 06/21] rsi: card reset for USB interface

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

2017-07-06 14:41:54

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 05/21] rsi: correct SDIO disconnect path handling

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

2017-07-06 14:43:24

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 19/21] rsi: SDIO Rx packet processing enhancement

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]>
Signed-off-by: Prameela Rani Garnepudi <[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 699e9da..c2e1c1c 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -275,6 +275,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

2017-07-06 14:42:15

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 08/21] rsi: correct the logic of deriving queue number

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

2017-07-06 14:43:44

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 21/21] rsi: Rename mutex tx_rxlock to the tx_lock.

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]>
Signed-off-by: Prameela Rani Garnepudi <[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 939f568..bb0febb 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);
mutex_init(&common->rx_lock);

if (rsi_create_kthread(common,
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index 29bccb7..709f767 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -179,8 +179,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

2017-07-06 14:42:32

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 11/21] rsi: set immediate wakeup bit

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

2017-07-06 14:43:11

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 17/21] rsi: rename variable in_sdio_litefi_irq

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]>
Signed-off-by: Prameela Rani Garnepudi <[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

2017-07-06 14:42:22

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 09/21] rsi: rename USB endpoint macros

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

2017-07-06 14:42:27

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 10/21] rsi: choose correct endpoint based on queue.

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

2017-07-06 14:43:07

by Amitkumar Karwar

[permalink] [raw]
Subject: [v3 16/21] rsi: separate function for data packet descriptor

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]>
Signed-off-by: Prameela Rani Garnepudi <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_hal.c | 51 +++++++++++++++++++---------------
1 file changed, 28 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index af7fe87..b0a7a15 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -108,25 +108,15 @@ 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;
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 header_size;
u8 vap_id = 0;
@@ -137,22 +127,16 @@ 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;
- }
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;
@@ -164,7 +148,6 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
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];

data_desc->xtend_desc_size = header_size - FRAME_DESC_SZ;

@@ -227,11 +210,33 @@ 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;
+ struct ieee80211_tx_info *info;
+ struct ieee80211_bss_conf *bss;
+ int status = -EIO;
+
+ info = IEEE80211_SKB_CB(skb);
+ bss = &info->control.vif->bss_conf;
+
+ if (!bss->assoc) {
+ status = -EINVAL;
+ goto err;
+ }
+
+ 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