Commit b78e91bc authored by Prameela Rani Garnepudi's avatar Prameela Rani Garnepudi Committed by Kalle Valo

rsi: Add new firmware loading method

The older firmware loading method has been deprecated and not in use
for any chipets. New method is introduced which works based on soft
boot loader. In this method, complete RAM image and FLASH image are
present in the flash. Before loading the functional firmware, host
issues boot loader commands to verify whether firmware to load is
different from the current functional firmware. If not, firmware
upgrade progresses and boot loader will switch to the new functional
firmware.

"rs9113_wlan_qspi.rps" is the firmware filename used in this patch.
Signed-off-by: default avatarPrameela Rani Garnepudi <prameela.j04cs@gmail.com>
Signed-off-by: default avatarAmitkumar Karwar <amit.karwar@redpinesignals.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent b97e9b94
This diff is collapsed.
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/module.h> #include <linux/module.h>
#include "rsi_sdio.h" #include "rsi_sdio.h"
#include "rsi_common.h" #include "rsi_common.h"
#include "rsi_hal.h"
/** /**
* rsi_sdio_set_cmd52_arg() - This function prepares cmd 52 read/write arg. * rsi_sdio_set_cmd52_arg() - This function prepares cmd 52 read/write arg.
...@@ -365,6 +366,7 @@ static int rsi_setblocklength(struct rsi_hw *adapter, u32 length) ...@@ -365,6 +366,7 @@ static int rsi_setblocklength(struct rsi_hw *adapter, u32 length)
status = sdio_set_block_size(dev->pfunction, length); status = sdio_set_block_size(dev->pfunction, length);
dev->pfunction->max_blksize = 256; dev->pfunction->max_blksize = 256;
adapter->block_size = dev->pfunction->max_blksize;
rsi_dbg(INFO_ZONE, rsi_dbg(INFO_ZONE,
"%s: Operational blk length is %d\n", __func__, length); "%s: Operational blk length is %d\n", __func__, length);
...@@ -868,6 +870,7 @@ static int rsi_init_sdio_interface(struct rsi_hw *adapter, ...@@ -868,6 +870,7 @@ static int rsi_init_sdio_interface(struct rsi_hw *adapter,
static struct rsi_host_intf_ops sdio_host_intf_ops = { static struct rsi_host_intf_ops sdio_host_intf_ops = {
.write_pkt = rsi_sdio_host_intf_write_pkt, .write_pkt = rsi_sdio_host_intf_write_pkt,
.read_pkt = rsi_sdio_host_intf_read_pkt, .read_pkt = rsi_sdio_host_intf_read_pkt,
.master_access_msword = rsi_sdio_master_access_msword,
.read_reg_multiple = rsi_sdio_read_register_multiple, .read_reg_multiple = rsi_sdio_read_register_multiple,
.write_reg_multiple = rsi_sdio_write_register_multiple, .write_reg_multiple = rsi_sdio_write_register_multiple,
.master_reg_read = rsi_sdio_master_reg_read, .master_reg_read = rsi_sdio_master_reg_read,
...@@ -906,13 +909,19 @@ static int rsi_probe(struct sdio_func *pfunction, ...@@ -906,13 +909,19 @@ static int rsi_probe(struct sdio_func *pfunction,
goto fail; goto fail;
} }
if (rsi_sdio_device_init(adapter->priv)) { if (rsi_hal_device_init(adapter)) {
rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", __func__); rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", __func__);
sdio_claim_host(pfunction); sdio_claim_host(pfunction);
sdio_disable_func(pfunction); sdio_disable_func(pfunction);
sdio_release_host(pfunction); sdio_release_host(pfunction);
goto fail; goto fail;
} }
rsi_dbg(INFO_ZONE, "===> RSI Device Init Done <===\n");
if (rsi_sdio_master_access_msword(adapter, MISC_CFG_BASE_ADDR)) {
rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", __func__);
return -EIO;
}
sdio_claim_host(pfunction); sdio_claim_host(pfunction);
if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) { if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) {
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/module.h> #include <linux/module.h>
#include "rsi_usb.h" #include "rsi_usb.h"
#include "rsi_hal.h"
/** /**
* rsi_usb_card_write() - This function writes to the USB Card. * rsi_usb_card_write() - This function writes to the USB Card.
...@@ -525,6 +526,7 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter, ...@@ -525,6 +526,7 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
} }
rsi_dev->rx_usb_urb[0]->transfer_buffer = adapter->priv->rx_data_pkt; rsi_dev->rx_usb_urb[0]->transfer_buffer = adapter->priv->rx_data_pkt;
rsi_dev->tx_blk_size = 252; rsi_dev->tx_blk_size = 252;
adapter->block_size = rsi_dev->tx_blk_size;
/* Initializing function callbacks */ /* Initializing function callbacks */
adapter->rx_urb_submit = rsi_rx_urb_submit; adapter->rx_urb_submit = rsi_rx_urb_submit;
...@@ -583,6 +585,7 @@ static int rsi_probe(struct usb_interface *pfunction, ...@@ -583,6 +585,7 @@ static int rsi_probe(struct usb_interface *pfunction,
__func__); __func__);
return -ENOMEM; return -ENOMEM;
} }
adapter->rsi_host_intf = RSI_HOST_INTF_USB;
status = rsi_init_usb_interface(adapter, pfunction); status = rsi_init_usb_interface(adapter, pfunction);
if (status) { if (status) {
...@@ -596,25 +599,20 @@ static int rsi_probe(struct usb_interface *pfunction, ...@@ -596,25 +599,20 @@ static int rsi_probe(struct usb_interface *pfunction,
dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
status = rsi_usb_reg_read(dev->usbdev, FW_STATUS_REG, &fw_status, 2); status = rsi_usb_reg_read(dev->usbdev, FW_STATUS_REG, &fw_status, 2);
if (status) if (status < 0)
goto err1; goto err1;
else else
fw_status &= 1; fw_status &= 1;
if (!fw_status) { if (!fw_status) {
status = rsi_usb_device_init(adapter->priv); rsi_dbg(INIT_ZONE, "Loading firmware...\n");
status = rsi_hal_device_init(adapter);
if (status) { if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", rsi_dbg(ERR_ZONE, "%s: Failed in device init\n",
__func__); __func__);
goto err1; goto err1;
} }
rsi_dbg(INIT_ZONE, "%s: Device Init Done\n", __func__);
status = rsi_usb_reg_write(dev->usbdev,
USB_INTERNAL_REG_1,
RSI_USB_READY_MAGIC_NUM, 1);
if (status)
goto err1;
rsi_dbg(INIT_ZONE, "%s: Performed device init\n", __func__);
} }
status = rsi_rx_urb_submit(adapter); status = rsi_rx_urb_submit(adapter);
......
/**
* Copyright (c) 2017 Redpine Signals Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __RSI_HAL_H__
#define __RSI_HAL_H__
#define FLASH_WRITE_CHUNK_SIZE (4 * 1024)
#define FLASH_SECTOR_SIZE (4 * 1024)
#define FLASH_SIZE_ADDR 0x04000016
#define PING_BUFFER_ADDRESS 0x19000
#define PONG_BUFFER_ADDRESS 0x1a000
#define SWBL_REGIN 0x41050034
#define SWBL_REGOUT 0x4105003c
#define PING_WRITE 0x1
#define PONG_WRITE 0x2
#define BL_CMD_TIMEOUT 2000
#define BL_BURN_TIMEOUT (50 * 1000)
#define REGIN_VALID 0xA
#define REGIN_INPUT 0xA0
#define REGOUT_VALID 0xAB
#define REGOUT_INVALID (~0xAB)
#define CMD_PASS 0xAA
#define CMD_FAIL 0xCC
#define LOAD_HOSTED_FW 'A'
#define BURN_HOSTED_FW 'B'
#define PING_VALID 'I'
#define PONG_VALID 'O'
#define PING_AVAIL 'I'
#define PONG_AVAIL 'O'
#define EOF_REACHED 'E'
#define CHECK_CRC 'K'
#define POLLING_MODE 'P'
#define CONFIG_AUTO_READ_MODE 'R'
#define JUMP_TO_ZERO_PC 'J'
#define FW_LOADING_SUCCESSFUL 'S'
#define LOADING_INITIATED '1'
/* Boot loader commands */
#define SEND_RPS_FILE '2'
#define FW_IMAGE_MIN_ADDRESS (68 * 1024)
#define MAX_FLASH_FILE_SIZE (400 * 1024) //400K
#define FLASH_START_ADDRESS 16
#define COMMON_HAL_CARD_READY_IND 0x0
#define COMMAN_HAL_WAIT_FOR_CARD_READY 1
struct bl_header {
__le32 flags;
__le32 image_no;
__le32 check_sum;
__le32 flash_start_address;
__le32 flash_len;
} __packed;
struct ta_metadata {
char *name;
unsigned int address;
};
int rsi_hal_device_init(struct rsi_hw *adapter);
#endif
...@@ -82,6 +82,8 @@ extern __printf(2, 3) void rsi_dbg(u32 zone, const char *fmt, ...); ...@@ -82,6 +82,8 @@ extern __printf(2, 3) void rsi_dbg(u32 zone, const char *fmt, ...);
((_q) == VI_Q) ? IEEE80211_AC_VI : \ ((_q) == VI_Q) ? IEEE80211_AC_VI : \
IEEE80211_AC_VO) IEEE80211_AC_VO)
#define RSI_DEV_9113 1
struct version_info { struct version_info {
u16 major; u16 major;
u16 minor; u16 minor;
...@@ -204,6 +206,7 @@ struct rsi_common { ...@@ -204,6 +206,7 @@ struct rsi_common {
struct cqm_info cqm_info; struct cqm_info cqm_info;
bool hw_data_qs_blocked; bool hw_data_qs_blocked;
u8 coex_mode;
int tx_power; int tx_power;
u8 ant_in_use; u8 ant_in_use;
...@@ -216,6 +219,7 @@ enum host_intf { ...@@ -216,6 +219,7 @@ enum host_intf {
struct rsi_hw { struct rsi_hw {
struct rsi_common *priv; struct rsi_common *priv;
u8 device_model;
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
struct ieee80211_vif *vifs[RSI_MAX_VIFS]; struct ieee80211_vif *vifs[RSI_MAX_VIFS];
struct ieee80211_tx_queue_params edca_params[NUM_EDCA_QUEUES]; struct ieee80211_tx_queue_params edca_params[NUM_EDCA_QUEUES];
...@@ -225,10 +229,15 @@ struct rsi_hw { ...@@ -225,10 +229,15 @@ struct rsi_hw {
u8 sc_nvifs; u8 sc_nvifs;
enum host_intf rsi_host_intf; enum host_intf rsi_host_intf;
u16 block_size;
#ifdef CONFIG_RSI_DEBUGFS #ifdef CONFIG_RSI_DEBUGFS
struct rsi_debugfs *dfsentry; struct rsi_debugfs *dfsentry;
u8 num_debugfs_entries; u8 num_debugfs_entries;
#endif #endif
char *fw_file_name;
struct timer_list bl_cmd_timer;
bool blcmd_timer_expired;
u32 flash_capacity;
u8 dfs_region; u8 dfs_region;
void *rsi_dev; void *rsi_dev;
struct rsi_host_intf_ops *host_intf_ops; struct rsi_host_intf_ops *host_intf_ops;
...@@ -240,6 +249,7 @@ struct rsi_hw { ...@@ -240,6 +249,7 @@ struct rsi_hw {
struct rsi_host_intf_ops { struct rsi_host_intf_ops {
int (*read_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len); int (*read_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len);
int (*write_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len); int (*write_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len);
int (*master_access_msword)(struct rsi_hw *adapter, u16 ms_word);
int (*read_reg_multiple)(struct rsi_hw *adapter, u32 addr, int (*read_reg_multiple)(struct rsi_hw *adapter, u32 addr,
u8 *data, u16 count); u8 *data, u16 count);
int (*write_reg_multiple)(struct rsi_hw *adapter, u32 addr, int (*write_reg_multiple)(struct rsi_hw *adapter, u32 addr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment