iwlwifi: consolidate the start_device flow
Now there is only one transport function that launch a specific fw: trans_ops->start_fw. This one replaces trans_ops->start_device and trans_ops->kick_nic. The code that actually loads the fw to the device has been moved to the transport specific code. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
This commit is contained in:
parent
d48e2074e2
commit
cf6142975b
4 changed files with 103 additions and 120 deletions
|
@ -1130,11 +1130,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
|
||||||
isr_stats->tx++;
|
isr_stats->tx++;
|
||||||
handled |= CSR_INT_BIT_FH_TX;
|
handled |= CSR_INT_BIT_FH_TX;
|
||||||
/* Wake up uCode load routine, now that load is complete */
|
/* Wake up uCode load routine, now that load is complete */
|
||||||
#ifdef CONFIG_IWLWIFI_IDI
|
|
||||||
trans->shrd->trans->ucode_write_complete = 1;
|
|
||||||
#else
|
|
||||||
trans->ucode_write_complete = 1;
|
trans->ucode_write_complete = 1;
|
||||||
#endif
|
|
||||||
wake_up(&trans->shrd->wait_command_queue);
|
wake_up(&trans->shrd->wait_command_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@
|
||||||
#include <linux/pci-aspm.h>
|
#include <linux/pci-aspm.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/gfp.h>
|
#include <linux/gfp.h>
|
||||||
|
|
||||||
|
@ -895,7 +896,79 @@ static const u8 iwlagn_pan_ac_to_queue[] = {
|
||||||
7, 6, 5, 4,
|
7, 6, 5, 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int iwl_trans_pcie_start_device(struct iwl_trans *trans)
|
/*
|
||||||
|
* ucode
|
||||||
|
*/
|
||||||
|
static int iwl_load_section(struct iwl_trans *trans, const char *name,
|
||||||
|
struct fw_desc *image, u32 dst_addr)
|
||||||
|
{
|
||||||
|
dma_addr_t phy_addr = image->p_addr;
|
||||||
|
u32 byte_cnt = image->len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
trans->ucode_write_complete = 0;
|
||||||
|
|
||||||
|
iwl_write_direct32(trans,
|
||||||
|
FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
|
||||||
|
FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
|
||||||
|
|
||||||
|
iwl_write_direct32(trans,
|
||||||
|
FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr);
|
||||||
|
|
||||||
|
iwl_write_direct32(trans,
|
||||||
|
FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
|
||||||
|
phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
|
||||||
|
|
||||||
|
iwl_write_direct32(trans,
|
||||||
|
FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
|
||||||
|
(iwl_get_dma_hi_addr(phy_addr)
|
||||||
|
<< FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
|
||||||
|
|
||||||
|
iwl_write_direct32(trans,
|
||||||
|
FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL),
|
||||||
|
1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
|
||||||
|
1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
|
||||||
|
FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
|
||||||
|
|
||||||
|
iwl_write_direct32(trans,
|
||||||
|
FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
|
||||||
|
FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
|
||||||
|
FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
|
||||||
|
FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
|
||||||
|
|
||||||
|
IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name);
|
||||||
|
ret = wait_event_timeout(trans->shrd->wait_command_queue,
|
||||||
|
trans->ucode_write_complete, 5 * HZ);
|
||||||
|
if (!ret) {
|
||||||
|
IWL_ERR(trans, "Could not load the %s uCode section\n",
|
||||||
|
name);
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = iwl_load_section(trans, "INST", &image->code,
|
||||||
|
IWLAGN_RTC_INST_LOWER_BOUND);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = iwl_load_section(trans, "DATA", &image->data,
|
||||||
|
IWLAGN_RTC_DATA_LOWER_BOUND);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* Remove all resets to allow NIC to operate */
|
||||||
|
iwl_write32(trans, CSR_RESET, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct iwl_trans_pcie *trans_pcie =
|
struct iwl_trans_pcie *trans_pcie =
|
||||||
|
@ -951,6 +1024,9 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans)
|
||||||
iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
||||||
iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
||||||
|
|
||||||
|
/* Load the given image to the HW */
|
||||||
|
iwl_load_given_ucode(trans, fw);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1353,12 +1429,6 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iwl_trans_pcie_kick_nic(struct iwl_trans *trans)
|
|
||||||
{
|
|
||||||
/* Remove all resets to allow NIC to operate */
|
|
||||||
iwl_write32(trans, CSR_RESET, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
|
static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
|
||||||
{
|
{
|
||||||
struct iwl_trans_pcie *trans_pcie =
|
struct iwl_trans_pcie *trans_pcie =
|
||||||
|
@ -2086,7 +2156,7 @@ const struct iwl_trans_ops trans_ops_pcie = {
|
||||||
.start_hw = iwl_trans_pcie_start_hw,
|
.start_hw = iwl_trans_pcie_start_hw,
|
||||||
.stop_hw = iwl_trans_pcie_stop_hw,
|
.stop_hw = iwl_trans_pcie_stop_hw,
|
||||||
.fw_alive = iwl_trans_pcie_fw_alive,
|
.fw_alive = iwl_trans_pcie_fw_alive,
|
||||||
.start_device = iwl_trans_pcie_start_device,
|
.start_fw = iwl_trans_pcie_start_fw,
|
||||||
.stop_device = iwl_trans_pcie_stop_device,
|
.stop_device = iwl_trans_pcie_stop_device,
|
||||||
|
|
||||||
.wake_any_queue = iwl_trans_pcie_wake_any_queue,
|
.wake_any_queue = iwl_trans_pcie_wake_any_queue,
|
||||||
|
@ -2100,8 +2170,6 @@ const struct iwl_trans_ops trans_ops_pcie = {
|
||||||
.tx_agg_alloc = iwl_trans_pcie_tx_agg_alloc,
|
.tx_agg_alloc = iwl_trans_pcie_tx_agg_alloc,
|
||||||
.tx_agg_setup = iwl_trans_pcie_tx_agg_setup,
|
.tx_agg_setup = iwl_trans_pcie_tx_agg_setup,
|
||||||
|
|
||||||
.kick_nic = iwl_trans_pcie_kick_nic,
|
|
||||||
|
|
||||||
.free = iwl_trans_pcie_free,
|
.free = iwl_trans_pcie_free,
|
||||||
.stop_queue = iwl_trans_pcie_stop_queue,
|
.stop_queue = iwl_trans_pcie_stop_queue,
|
||||||
|
|
||||||
|
|
|
@ -131,13 +131,25 @@ struct iwl_host_cmd {
|
||||||
u8 id;
|
u8 id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* one for each uCode image (inst/data, boot/init/runtime) */
|
||||||
|
struct fw_desc {
|
||||||
|
dma_addr_t p_addr; /* hardware address */
|
||||||
|
void *v_addr; /* software address */
|
||||||
|
u32 len; /* size in bytes */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fw_img {
|
||||||
|
struct fw_desc code; /* firmware code image */
|
||||||
|
struct fw_desc data; /* firmware data image */
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct iwl_trans_ops - transport specific operations
|
* struct iwl_trans_ops - transport specific operations
|
||||||
* @start_hw: starts the HW- from that point on, the HW can send interrupts
|
* @start_hw: starts the HW- from that point on, the HW can send interrupts
|
||||||
* @stop_hw: stops the HW- from that point on, the HW will be in low power but
|
* @stop_hw: stops the HW- from that point on, the HW will be in low power but
|
||||||
* will still issue interrupt if the HW RF kill is triggered.
|
* will still issue interrupt if the HW RF kill is triggered.
|
||||||
* @start_device: allocates and inits all the resources for the transport
|
* @start_fw: allocates and inits all the resources for the transport
|
||||||
* layer.
|
* layer. Also kick a fw image. This handler may sleep.
|
||||||
* @fw_alive: called when the fw sends alive notification
|
* @fw_alive: called when the fw sends alive notification
|
||||||
* @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_*
|
* @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_*
|
||||||
* @stop_device:stops the whole device (embedded CPU put to reset)
|
* @stop_device:stops the whole device (embedded CPU put to reset)
|
||||||
|
@ -148,7 +160,6 @@ struct iwl_host_cmd {
|
||||||
* @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is
|
* @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is
|
||||||
* ready and a successful ADDBA response has been received.
|
* ready and a successful ADDBA response has been received.
|
||||||
* @tx_agg_disable: de-configure a Tx queue to send AMPDUs
|
* @tx_agg_disable: de-configure a Tx queue to send AMPDUs
|
||||||
* @kick_nic: remove the RESET from the embedded CPU and let it run
|
|
||||||
* @free: release all the ressource for the transport layer itself such as
|
* @free: release all the ressource for the transport layer itself such as
|
||||||
* irq, tasklet etc...
|
* irq, tasklet etc...
|
||||||
* @stop_queue: stop a specific queue
|
* @stop_queue: stop a specific queue
|
||||||
|
@ -166,7 +177,7 @@ struct iwl_trans_ops {
|
||||||
|
|
||||||
int (*start_hw)(struct iwl_trans *iwl_trans);
|
int (*start_hw)(struct iwl_trans *iwl_trans);
|
||||||
void (*stop_hw)(struct iwl_trans *iwl_trans);
|
void (*stop_hw)(struct iwl_trans *iwl_trans);
|
||||||
int (*start_device)(struct iwl_trans *trans);
|
int (*start_fw)(struct iwl_trans *trans, struct fw_img *fw);
|
||||||
void (*fw_alive)(struct iwl_trans *trans);
|
void (*fw_alive)(struct iwl_trans *trans);
|
||||||
void (*stop_device)(struct iwl_trans *trans);
|
void (*stop_device)(struct iwl_trans *trans);
|
||||||
|
|
||||||
|
@ -191,8 +202,6 @@ struct iwl_trans_ops {
|
||||||
enum iwl_rxon_context_id ctx, int sta_id, int tid,
|
enum iwl_rxon_context_id ctx, int sta_id, int tid,
|
||||||
int frame_limit, u16 ssn);
|
int frame_limit, u16 ssn);
|
||||||
|
|
||||||
void (*kick_nic)(struct iwl_trans *trans);
|
|
||||||
|
|
||||||
void (*free)(struct iwl_trans *trans);
|
void (*free)(struct iwl_trans *trans);
|
||||||
|
|
||||||
void (*stop_queue)(struct iwl_trans *trans, int q, const char *msg);
|
void (*stop_queue)(struct iwl_trans *trans, int q, const char *msg);
|
||||||
|
@ -209,18 +218,6 @@ struct iwl_trans_ops {
|
||||||
u32 (*read32)(struct iwl_trans *trans, u32 ofs);
|
u32 (*read32)(struct iwl_trans *trans, u32 ofs);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* one for each uCode image (inst/data, boot/init/runtime) */
|
|
||||||
struct fw_desc {
|
|
||||||
dma_addr_t p_addr; /* hardware address */
|
|
||||||
void *v_addr; /* software address */
|
|
||||||
u32 len; /* size in bytes */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fw_img {
|
|
||||||
struct fw_desc code; /* firmware code image */
|
|
||||||
struct fw_desc data; /* firmware data image */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Opaque calibration results */
|
/* Opaque calibration results */
|
||||||
struct iwl_calib_result {
|
struct iwl_calib_result {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
@ -284,9 +281,11 @@ static inline void iwl_trans_fw_alive(struct iwl_trans *trans)
|
||||||
trans->ops->fw_alive(trans);
|
trans->ops->fw_alive(trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int iwl_trans_start_device(struct iwl_trans *trans)
|
static inline int iwl_trans_start_fw(struct iwl_trans *trans, struct fw_img *fw)
|
||||||
{
|
{
|
||||||
return trans->ops->start_device(trans);
|
might_sleep();
|
||||||
|
|
||||||
|
return trans->ops->start_fw(trans, fw);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void iwl_trans_stop_device(struct iwl_trans *trans)
|
static inline void iwl_trans_stop_device(struct iwl_trans *trans)
|
||||||
|
@ -347,11 +346,6 @@ static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans,
|
||||||
trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn);
|
trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void iwl_trans_kick_nic(struct iwl_trans *trans)
|
|
||||||
{
|
|
||||||
trans->ops->kick_nic(trans);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void iwl_trans_free(struct iwl_trans *trans)
|
static inline void iwl_trans_free(struct iwl_trans *trans)
|
||||||
{
|
{
|
||||||
trans->ops->free(trans);
|
trans->ops->free(trans);
|
||||||
|
|
|
@ -120,58 +120,6 @@ int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* ucode
|
|
||||||
*/
|
|
||||||
static int iwl_load_section(struct iwl_trans *trans, const char *name,
|
|
||||||
struct fw_desc *image, u32 dst_addr)
|
|
||||||
{
|
|
||||||
dma_addr_t phy_addr = image->p_addr;
|
|
||||||
u32 byte_cnt = image->len;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
trans->ucode_write_complete = 0;
|
|
||||||
|
|
||||||
iwl_write_direct32(trans,
|
|
||||||
FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
|
|
||||||
FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
|
|
||||||
|
|
||||||
iwl_write_direct32(trans,
|
|
||||||
FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr);
|
|
||||||
|
|
||||||
iwl_write_direct32(trans,
|
|
||||||
FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
|
|
||||||
phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
|
|
||||||
|
|
||||||
iwl_write_direct32(trans,
|
|
||||||
FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
|
|
||||||
(iwl_get_dma_hi_addr(phy_addr)
|
|
||||||
<< FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
|
|
||||||
|
|
||||||
iwl_write_direct32(trans,
|
|
||||||
FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL),
|
|
||||||
1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
|
|
||||||
1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
|
|
||||||
FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
|
|
||||||
|
|
||||||
iwl_write_direct32(trans,
|
|
||||||
FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
|
|
||||||
FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
|
|
||||||
FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
|
|
||||||
FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
|
|
||||||
|
|
||||||
IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name);
|
|
||||||
ret = wait_event_timeout(trans->shrd->wait_command_queue,
|
|
||||||
trans->ucode_write_complete, 5 * HZ);
|
|
||||||
if (!ret) {
|
|
||||||
IWL_ERR(trans, "Could not load the %s uCode section\n",
|
|
||||||
name);
|
|
||||||
return -ETIMEDOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans,
|
static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans,
|
||||||
enum iwl_ucode_type ucode_type)
|
enum iwl_ucode_type ucode_type)
|
||||||
{
|
{
|
||||||
|
@ -188,28 +136,6 @@ static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iwl_load_given_ucode(struct iwl_trans *trans,
|
|
||||||
enum iwl_ucode_type ucode_type)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
struct fw_img *image = iwl_get_ucode_image(trans, ucode_type);
|
|
||||||
|
|
||||||
|
|
||||||
if (!image) {
|
|
||||||
IWL_ERR(trans, "Invalid ucode requested (%d)\n",
|
|
||||||
ucode_type);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = iwl_load_section(trans, "INST", &image->code,
|
|
||||||
IWLAGN_RTC_INST_LOWER_BOUND);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return iwl_load_section(trans, "DATA", &image->data,
|
|
||||||
IWLAGN_RTC_DATA_LOWER_BOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calibration
|
* Calibration
|
||||||
*/
|
*/
|
||||||
|
@ -646,28 +572,27 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans,
|
||||||
{
|
{
|
||||||
struct iwl_notification_wait alive_wait;
|
struct iwl_notification_wait alive_wait;
|
||||||
struct iwl_alive_data alive_data;
|
struct iwl_alive_data alive_data;
|
||||||
|
struct fw_img *fw;
|
||||||
int ret;
|
int ret;
|
||||||
enum iwl_ucode_type old_type;
|
enum iwl_ucode_type old_type;
|
||||||
|
|
||||||
ret = iwl_trans_start_device(trans);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE,
|
iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE,
|
||||||
iwl_alive_fn, &alive_data);
|
iwl_alive_fn, &alive_data);
|
||||||
|
|
||||||
old_type = trans->shrd->ucode_type;
|
old_type = trans->shrd->ucode_type;
|
||||||
trans->shrd->ucode_type = ucode_type;
|
trans->shrd->ucode_type = ucode_type;
|
||||||
|
fw = iwl_get_ucode_image(trans, ucode_type);
|
||||||
|
|
||||||
ret = iwl_load_given_ucode(trans, ucode_type);
|
if (!fw)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ret = iwl_trans_start_fw(trans, fw);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
trans->shrd->ucode_type = old_type;
|
trans->shrd->ucode_type = old_type;
|
||||||
iwl_remove_notification(trans->shrd, &alive_wait);
|
iwl_remove_notification(trans->shrd, &alive_wait);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
iwl_trans_kick_nic(trans);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some things may run in the background now, but we
|
* Some things may run in the background now, but we
|
||||||
* just wait for the ALIVE notification here.
|
* just wait for the ALIVE notification here.
|
||||||
|
|
Loading…
Add table
Reference in a new issue