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: Prameela Rani Garnepudi <redacted>
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 <redacted>
Signed-off-by: Amitkumar Karwar <redacted>
---
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(-)
@@ -1327,18 +1328,18 @@ static int rsi_eeprom_read(struct rsi_common *common)}memset(skb->data,0,FRAME_DESC_SZ);-mgmt_frame=(structrsi_mac_frame*)skb->data;+mgmt_frame=(structrsi_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)staticintrsi_handle_ta_confirm_type(structrsi_common*common,u8*msg){+structrsi_hw*adapter=common->priv;u8sub_type=(msg[15]&0xff);+u16msg_len=((u16*)msg)[0]&0xfff;+u8offset;switch(sub_type){caseBOOTUP_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;gotoout;-}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;-caseEEPROM_READ_TYPE:+caseEEPROM_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);+gotoout;+}+if(msg[16]!=MAGIC_WORD){+rsi_dbg(FSM_ZONE,+"%s: [EEPROM_READ] Invalid token\n",__func__);+common->fsm_state=FSM_CARD_NOT_READY;+gotoout;+}if(common->fsm_state==FSM_EEPROM_READ_MAC_ADDR){-if(msg[16]==MAGIC_WORD){-u8offset=(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(structversion_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;+gotoout;+}+common->fsm_state=FSM_EEPROM_READ_RF_TYPE;+}elseif(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;+}elseif((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))gotoout;-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__);return0;}break;
From: Karun Eagalapati <redacted>
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 <redacted>
Signed-off-by: Amitkumar Karwar <redacted>
---
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(-)
@@ -933,6 +933,84 @@ static int rsi_probe(struct sdio_func *pfunction,return1;}+staticvoidulp_read_write(structrsi_hw*adapter,u16addr,u32data,+u16len_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.*/+staticvoidrsi_reset_chip(structrsi_hw*adapter)+{+__le32data;+u8sdio_interrupt_status=0;+u8request=1;+intret;++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+*andanypendingdmatransferstorfspiindevicetofinish.+*/+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+*readwriteoperationstocompleteforchipreset.+*/+msleep(500);+}+/***rsi_disconnect()-Thisfunctionperformsthereverseoftheprobefunction.*@pfunction:Pointertothesdio_funcstructure.
@@ -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);}
From: Karun Eagalapati <redacted>
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 <redacted>
Signed-off-by: Amitkumar Karwar <redacted>
---
drivers/net/wireless/rsi/rsi_91x_sdio.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
@@ -1026,17 +1026,26 @@ static void rsi_disconnect(struct sdio_func *pfunction)return;dev=(structrsi_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
From: Karun Eagalapati <redacted>
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 <redacted>
Signed-off-by: Amitkumar Karwar <redacted>
---
drivers/net/wireless/rsi/rsi_91x_usb.c | 72 ++++++++++++++++++++++++++++++++++
drivers/net/wireless/rsi/rsi_usb.h | 1 +
2 files changed, 73 insertions(+)
@@ -558,6 +558,77 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,returnstatus;}+staticintusb_ulp_read_write(structrsi_hw*adapter,u16addr,u32data,+u16len_in_bits)+{+intret;++ret=rsi_usb_master_reg_write+(adapter,RSI_GSPI_DATA_REG1,+((addr<<6)|((data>>16)&0xffff)),2);+if(ret<0)+returnret;++ret=rsi_usb_master_reg_write(adapter,RSI_GSPI_DATA_REG0,+(data&0xffff),2);+if(ret<0)+returnret;++/* 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)+returnret;++msleep(20);++return0;+}++staticintrsi_reset_card(structrsi_hw*adapter)+{+intret;++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+*andanypendingdmatransferstorfindevicetofinish.+*/+msleep(100);++ret=usb_ulp_read_write(adapter,RSI_WATCH_DOG_TIMER_1,+RSI_ULP_WRITE_2,32);+if(ret<0)+gotofail;+ret=usb_ulp_read_write(adapter,RSI_WATCH_DOG_TIMER_2,+RSI_ULP_WRITE_0,32);+if(ret<0)+gotofail;+ret=usb_ulp_read_write(adapter,RSI_WATCH_DOG_DELAY_TIMER_1,+RSI_ULP_WRITE_50,32);+if(ret<0)+gotofail;+ret=usb_ulp_read_write(adapter,RSI_WATCH_DOG_DELAY_TIMER_2,+RSI_ULP_WRITE_0,32);+if(ret<0)+gotofail;+ret=usb_ulp_read_write(adapter,RSI_WATCH_DOG_TIMER_ENABLE,+RSI_ULP_TIMER_ENABLE,32);+if(ret<0)+gotofail;++rsi_dbg(INFO_ZONE,"Reset card done\n");+returnret;++fail:+rsi_dbg(ERR_ZONE,"Reset card failed\n");+returnret;+}+/***rsi_probe()-Thisfunctioniscalledbykernelwhenthedriverprovided*VendoranddeviceIDsarematched.Alltheinitialization
From: Karun Eagalapati <redacted>
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 <redacted>
Signed-off-by: Amitkumar Karwar <redacted>
---
drivers/net/wireless/rsi/rsi_91x_usb.c | 41 +++++++++++++++++-----------------
1 file changed, 21 insertions(+), 20 deletions(-)
From: Amitkumar Karwar <redacted>
Maximum valid queue number is 0x5. So anding with 0x7 should be
ok here.
Signed-off-by: Amitkumar Karwar <redacted>
---
drivers/net/wireless/rsi/rsi_91x_usb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: "pavani.muthyala" <redacted>
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 <redacted>
Signed-off-by: Amitkumar Karwar <redacted>
---
drivers/net/wireless/rsi/rsi_91x_hal.c | 37 +++++++++++++++++-----------------
drivers/net/wireless/rsi/rsi_hal.h | 23 +++++++++++++++++++++
2 files changed, 41 insertions(+), 19 deletions(-)
@@ -138,9 +138,9 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,structieee80211_bss_conf*bss;structieee80211_hw*hw=adapter->hw;structieee80211_conf*conf=&hw->conf;+structrsi_mgmt_desc*mgmt_desc;structskb_info*tx_params;intstatus=-E2BIG;-__le16*msg;u8extnd_size;u8vap_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=(structrsi_mgmt_desc*)skb->data;if(skb->len>MAX_MGMT_PKT_SIZE){rsi_dbg(INFO_ZONE,"%s: Dropping mgmt pkt > 512\n",__func__);gotoerr;}-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__);
@@ -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 */++staticintrsi_prepare_mgmt_desc(structrsi_common*common,structsk_buff*skb)+{+structrsi_hw*adapter=common->priv;+structieee80211_hdr*wh=NULL;+structieee80211_tx_info*info;+structieee80211_conf*conf=&adapter->hw->conf;+structieee80211_vif*vif=NULL;+structrsi_mgmt_desc*mgmt_desc;+structskb_info*tx_params;+intstatus=-EINVAL;+structieee80211_bss_conf*bss=NULL;+structxtended_desc*xtend_desc=NULL;+u8header_size;+u32dword_align_bytes=0;++info=IEEE80211_SKB_CB(skb);+tx_params=(structskb_info*)info->driver_data;++/* Update header size */+header_size=FRAME_DESC_SZ+sizeof(structxtended_desc);+if(header_size>skb_headroom(skb)){+rsi_dbg(ERR_ZONE,+"%s: Failed to add extended descriptor\n",+__func__);+status=-ENOSPC;+returnstatus;+}+skb_push(skb,header_size);+dword_align_bytes=((unsignedlong)skb->data&0x3f);+if(dword_align_bytes>skb_headroom(skb)){+rsi_dbg(ERR_ZONE,+"%s: Failed to add dword align\n",__func__);+status=-ENOSPC;+returnstatus;+}+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=(structieee80211_hdr*)&skb->data[header_size];+vif=adapter->vifs[0];++mgmt_desc=(structrsi_mgmt_desc*)skb->data;+xtend_desc=(structxtended_desc*)&skb->data[FRAME_DESC_SZ];++if(skb->len>MAX_MGMT_PKT_SIZE){+rsi_dbg(INFO_ZONE,"%s: Dropping mgmt pkt > 512\n",__func__);+returnstatus;+}+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");+}+}++return0;+}+/***rsi_send_data_pkt()-Thisfunctionsendstherecieveddatapacketfrom*drivertodevice.
@@ -133,16 +219,10 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,structsk_buff*skb){structrsi_hw*adapter=common->priv;-structieee80211_hdr*wh;structieee80211_tx_info*info;-structieee80211_bss_conf*bss;-structieee80211_hw*hw=adapter->hw;-structieee80211_conf*conf=&hw->conf;-structrsi_mgmt_desc*mgmt_desc;structskb_info*tx_params;intstatus=-E2BIG;u8extnd_size;-u8vap_id=0;info=IEEE80211_SKB_CB(skb);tx_params=(structskb_info*)info->driver_data;
@@ -168,51 +248,12 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,returnstatus;}-bss=&info->control.vif->bss_conf;-wh=(structieee80211_hdr*)&skb->data[0];-if(FRAME_DESC_SZ>skb_headroom(skb))gotoerr;-skb_push(skb,FRAME_DESC_SZ);-memset(skb->data,0,FRAME_DESC_SZ);-mgmt_desc=(structrsi_mgmt_desc*)skb->data;--if(skb->len>MAX_MGMT_PKT_SIZE){-rsi_dbg(INFO_ZONE,"%s: Dropping mgmt pkt > 512\n",__func__);-gotoerr;-}--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__);
From: "pavani.muthyala" <redacted>
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 <redacted>
Signed-off-by: Amitkumar Karwar <redacted>
---
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(-)
@@ -111,15 +111,8 @@ static int rsi_prepare_mgmt_desc(struct rsi_common *common, struct sk_buff *skb)return0;}-/**-*rsi_send_data_pkt()-Thisfunctionsendstherecieveddatapacketfrom-*drivertodevice.-*@common:Pointertothedriverprivatestructure.-*@skb:Pointertothesocketbufferstructure.-*-*Return:status:0onsuccess,-1onfailure.-*/-intrsi_send_data_pkt(structrsi_common*common,structsk_buff*skb)+/* This function prepares descriptor for given data packet */+staticintrsi_prepare_data_desc(structrsi_common*common,structsk_buff*skb){structrsi_hw*adapter=common->priv;structieee80211_hdr*wh=NULL;
@@ -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=(structskb_info*)info->driver_data;-if(!bss->assoc){-status=-EINVAL;-gotoerr;-}+if(!bss->assoc)+return-EINVAL;+header_size=FRAME_DESC_SZ+sizeof(structxtended_desc);if(header_size>skb_headroom(skb)){rsi_dbg(ERR_ZONE,"%s: Unable to send pkt\n",__func__);-status=-ENOSPC;-gotoerr;+return-ENOSPC;}skb_push(skb,header_size);dword_align_bytes=((unsignedlong)skb->data&0x3f);if(header_size>skb_headroom(skb)){rsi_dbg(ERR_ZONE,"%s: Not enough headroom\n",__func__);-status=-ENOSPC;-gotoerr;+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;}+return0;+}++/* This function sends received data packet from driver to device */+intrsi_send_data_pkt(structrsi_common*common,structsk_buff*skb)+{+structrsi_hw*adapter=common->priv;+intstatus;++status=rsi_prepare_data_desc(common,skb);+if(status)+gotoerr;+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];
From: Karun Eagalapati <redacted>
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 <redacted>
Signed-off-by: Amitkumar Karwar <redacted>
---
drivers/net/wireless/rsi/rsi_91x_sdio.c | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)
From: Karun Eagalapati <redacted>
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 <redacted>
Signed-off-by: Amitkumar Karwar <redacted>
---
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(-)
@@ -69,20 +69,37 @@ int rsi_sdio_master_access_msword(struct rsi_hw *adapter, u16 ms_word)staticintrsi_process_pkt(structrsi_common*common){structrsi_hw*adapter=common->priv;+structrsi_91x_sdiodev*dev=+(structrsi_91x_sdiodev*)adapter->rsi_dev;u8num_blks=0;u32rcv_pkt_len=0;intstatus=0;+u8value=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__);-returnstatus;+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__);+returnstatus;+}+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);
From: Karun Eagalapati <redacted>
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 <redacted>
Signed-off-by: Amitkumar Karwar <redacted>
---
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(-)
@@ -179,6 +179,8 @@ struct rsi_common {structmutexmutex;/* Mutex used between tx/rx threads */structmutextx_rxlock;+/* Mutex used for rx thread */+structmutexrx_lock;u8endpoint;/* Channel/band related */
From: Karun Eagalapati <redacted>
We have now added separate lock for Rx. This lock is used to protect
tx path only
Signed-off-by: Karun Eagalapati <redacted>
Signed-off-by: Amitkumar Karwar <redacted>
---
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(-)
@@ -177,8 +177,8 @@ struct rsi_common {structsk_buff_headtx_queue[NUM_EDCA_QUEUES+1];/* Mutex declaration */structmutexmutex;-/* Mutex used between tx/rx threads */-structmutextx_rxlock;+/* Mutex used for tx thread */+structmutextx_lock;/* Mutex used for rx thread */structmutexrx_lock;u8endpoint;
Hi Alexey,
On Tue, Jun 13, 2017 at 9:13 PM, Alexey Brodkin
[off-list ref] wrote:
Hi Amitkumar,
On Tue, 2017-06-13 at 20:18 +0530, Amitkumar Karwar wrote:
quoted
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