/* Card will not send any response as it is getting reset immediately *Henceexpectatimeoutstatusfromhostcontroller
*/ if (ret != -ETIMEDOUT)
rsi_dbg(ERR_ZONE, "%s: Reset failed : %d\n", __func__, ret);
/* Wait for few milli seconds to get rid of residue charges if any */
msleep(20);
/** *rsi_setupcard()-Thisfunctionqueriesandsetsthecard'sfeatures. *@adapter:Pointertotheadapterstructure. * *Return:status:0onsuccess,-1onfailure.
*/ staticint rsi_setupcard(struct rsi_hw *adapter)
{ struct rsi_91x_sdiodev *dev = adapter->rsi_dev; int status = 0;
rsi_setclock(adapter, 50000);
dev->tx_blk_size = 256;
status = rsi_setblocklength(adapter, dev->tx_blk_size); if (status)
rsi_dbg(ERR_ZONE, "%s: Unable to set block length\n", __func__); return status;
}
temp_buf = kmalloc(block_size, GFP_KERNEL); if (!temp_buf) return -ENOMEM;
/* Loading DM ms word in the sdio slave */
status = rsi_sdio_master_access_msword(adapter, msb_address); if (status < 0) {
rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", __func__); goto out_free;
}
for (offset = 0, i = 0; i < num_blocks; i++, offset += block_size) {
memcpy(temp_buf, ta_firmware + offset, block_size);
lsb_address = (u16)base_address;
status = rsi_sdio_write_register_multiple
(adapter,
lsb_address | RSI_SD_REQUEST_MASTER,
temp_buf, block_size); if (status < 0) {
rsi_dbg(ERR_ZONE, "%s: failed to write\n", __func__); goto out_free;
}
rsi_dbg(INFO_ZONE, "%s: loading block: %d\n", __func__, i);
base_address += block_size;
if ((base_address >> 16) != msb_address) {
msb_address += 1;
/* Loading DM ms word in the sdio slave */
status = rsi_sdio_master_access_msword(adapter,
msb_address); if (status < 0) {
rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n",
__func__); goto out_free;
}
}
}
if (instructions_sz % block_size) {
memset(temp_buf, 0, block_size);
memcpy(temp_buf, ta_firmware + offset,
instructions_sz % block_size);
lsb_address = (u16)base_address;
status = rsi_sdio_write_register_multiple
(adapter,
lsb_address | RSI_SD_REQUEST_MASTER,
temp_buf,
instructions_sz % block_size); if (status < 0) goto out_free;
rsi_dbg(INFO_ZONE, "Written Last Block in Address 0x%x Successfully\n",
offset | RSI_SD_REQUEST_MASTER);
}
status = 0;
out_free:
kfree(temp_buf); return status;
}
data = kzalloc(RSI_MASTER_REG_BUF_SIZE, GFP_KERNEL); if (!data) return -ENOMEM;
ms_addr = (addr >> 16);
status = rsi_sdio_master_access_msword(adapter, ms_addr); if (status < 0) {
rsi_dbg(ERR_ZONE, "%s: Unable to set ms word to common reg\n",
__func__); goto err;
}
addr &= 0xFFFF;
status = rsi_sdio_master_access_msword(adapter, (addr >> 16)); if (status < 0) {
rsi_dbg(ERR_ZONE, "%s: Unable to set ms word to common reg\n",
__func__);
kfree(data_aligned); return -EIO;
}
addr = addr & 0xFFFF;
/* Bring TA out of reset */
status = rsi_sdio_write_register_multiple
(adapter,
(addr | RSI_SD_REQUEST_MASTER),
(u8 *)data_aligned, size); if (status < 0)
rsi_dbg(ERR_ZONE, "%s: Unable to do AHB reg write\n", __func__);
data = kzalloc(RSI_9116_REG_SIZE, GFP_KERNEL); if (!data) return -ENOMEM;
status = rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR); if (status < 0) {
rsi_dbg(ERR_ZONE, "Unable to set ms word to common reg\n"); goto err;
}
rsi_dbg(INIT_ZONE, "%s: Bring TA out of reset\n", __func__);
put_unaligned_le32(TA_HOLD_THREAD_VALUE, data);
addr = TA_HOLD_THREAD_REG | RSI_SD_REQUEST_MASTER;
status = rsi_sdio_write_register_multiple(adapter, addr,
(u8 *)data,
RSI_9116_REG_SIZE); if (status < 0) {
rsi_dbg(ERR_ZONE, "Unable to hold TA threads\n"); goto err;
}
put_unaligned_le32(TA_SOFT_RST_CLR, data);
addr = TA_SOFT_RESET_REG | RSI_SD_REQUEST_MASTER;
status = rsi_sdio_write_register_multiple(adapter, addr,
(u8 *)data,
RSI_9116_REG_SIZE); if (status < 0) {
rsi_dbg(ERR_ZONE, "Unable to get TA out of reset\n"); goto err;
}
put_unaligned_le32(TA_PC_ZERO, data);
addr = TA_TH0_PC_REG | RSI_SD_REQUEST_MASTER;
status = rsi_sdio_write_register_multiple(adapter, addr,
(u8 *)data,
RSI_9116_REG_SIZE); if (status < 0) {
rsi_dbg(ERR_ZONE, "Unable to Reset TA PC value\n");
status = -EINVAL; goto err;
}
put_unaligned_le32(TA_RELEASE_THREAD_VALUE, data);
addr = TA_RELEASE_THREAD_REG | RSI_SD_REQUEST_MASTER;
status = rsi_sdio_write_register_multiple(adapter, addr,
(u8 *)data,
RSI_9116_REG_SIZE); if (status < 0) {
rsi_dbg(ERR_ZONE, "Unable to release TA threads\n"); goto err;
}
status = rsi_sdio_master_access_msword(adapter, MISC_CFG_BASE_ADDR); if (status < 0) {
rsi_dbg(ERR_ZONE, "Unable to set ms word to common reg\n"); goto err;
}
rsi_dbg(INIT_ZONE, "***** TA Reset done *****\n");
sdev = adapter->rsi_dev;
rsi_init_event(&sdev->rx_thread.event);
status = rsi_create_kthread(adapter->priv, &sdev->rx_thread,
rsi_sdio_rx_thread, "SDIO-RX-Thread"); if (status) {
rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__); goto fail_kill_thread;
}
sdio_claim_host(pfunction); if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) {
rsi_dbg(ERR_ZONE, "%s: Failed to request IRQ\n", __func__);
sdio_release_host(pfunction);
status = -EIO; goto fail_claim_irq;
}
sdio_release_host(pfunction);
rsi_dbg(INIT_ZONE, "%s: Registered Interrupt handler\n", __func__);
if (rsi_hal_device_init(adapter)) {
rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", __func__);
status = -EINVAL; goto fail_dev_init;
}
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__);
status = -EIO; goto fail_dev_init;
}
/*This function resets and re-initializes the chip.*/ staticvoid rsi_reset_chip(struct rsi_hw *adapter)
{
u8 *data;
u8 sdio_interrupt_status = 0;
u8 request = 1; int ret;
data = kzalloc(sizeof(u32), GFP_KERNEL); if (!data) return;
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__); goto err;
}
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__); goto err;
}
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__); goto err;
}
put_unaligned_le32(TA_HOLD_THREAD_VALUE, data); if (rsi_sdio_write_register_multiple(adapter, TA_HOLD_THREAD_REG |
RSI_SD_REQUEST_MASTER,
data, 4)) {
rsi_dbg(ERR_ZONE, "%s: Unable to hold Thread-Arch processor threads\n",
__func__); goto err;
}
/* This msleep will ensure Thread-Arch processor to go to hold *andanypendingdmatransferstorfspiindevicetofinish.
*/
msleep(100); if (adapter->device_model != RSI_DEV_9116) {
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);
} else { if ((rsi_sdio_master_reg_write(adapter,
NWP_WWD_INTERRUPT_TIMER,
NWP_WWD_INT_TIMER_CLKS,
RSI_9116_REG_SIZE)) < 0) {
rsi_dbg(ERR_ZONE, "Failed to write to intr timer\n");
} if ((rsi_sdio_master_reg_write(adapter,
NWP_WWD_SYSTEM_RESET_TIMER,
NWP_WWD_SYS_RESET_TIMER_CLKS,
RSI_9116_REG_SIZE)) < 0) {
rsi_dbg(ERR_ZONE, "Failed to write to system reset timer\n");
} if ((rsi_sdio_master_reg_write(adapter,
NWP_WWD_MODE_AND_RSTART,
NWP_WWD_TIMER_DISABLE,
RSI_9116_REG_SIZE)) < 0) {
rsi_dbg(ERR_ZONE, "Failed to write to mode and restart\n");
}
rsi_dbg(ERR_ZONE, "***** Watch Dog Reset Successful *****\n");
} /* This msleep will be sufficient for the ulp *readwriteoperationstocompleteforchipreset.
*/
msleep(500);
err:
kfree(data); return;
}
/* 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");
sdio_claim_host(pfunc);
ret = rsi_cmd52readbyte(pfunc->card, RSI_INT_ENABLE_REGISTER, &data); if (ret < 0) {
rsi_dbg(ERR_ZONE, "%s: Failed to read int enable register\n", __func__); goto done;
}
data |= ~RSI_INT_ENABLE_MASK & 0xff;
ret = rsi_cmd52writebyte(pfunc->card, RSI_INT_ENABLE_REGISTER, data); if (ret < 0) {
rsi_dbg(ERR_ZONE, "%s: Failed to write to int enable register\n",
__func__); goto done;
}
if ((common->wow_flags & RSI_WOW_ENABLED) &&
(common->wow_flags & RSI_WOW_NO_CONNECTION))
rsi_dbg(ERR_ZONE, "##### Device can not wake up through WLAN\n");
ret = rsi_cmd52readbyte(pfunc->card, RSI_INT_ENABLE_REGISTER, &data); if (ret < 0) {
rsi_dbg(ERR_ZONE, "%s: Failed to read int enable register\n", __func__); goto done;
}
rsi_dbg(INFO_ZONE, "int enable reg content = %x\n", data);
if (!adapter) {
rsi_dbg(ERR_ZONE, "Device is not ready\n"); return -ENODEV;
}
common = adapter->priv;
sdev = adapter->rsi_dev;
if ((common->wow_flags & RSI_WOW_ENABLED) &&
(common->wow_flags & RSI_WOW_NO_CONNECTION))
rsi_dbg(ERR_ZONE, "##### Device can not wake up through WLAN\n");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.