Commit 19961780 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'net-wwan-iosm-bug-fixes'

M Chetan Kumar says:

====================
net: wwan: iosm: bug fixes

This patch series brings in IOSM driver bug fixes. Patch details are
explained below.

PATCH1: stop sending unnecessary doorbell in IP tx flow.
PATCH2: Restore the IP channel configuration after fw flash.
PATCH3: Removed the unnecessary check around control port TX transfer.
====================

Link: https://lore.kernel.org/r/20211209101629.2940877-1-m.chetan.kumar@linux.intel.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents e8b1d769 383451ce
...@@ -181,9 +181,9 @@ void ipc_imem_hrtimer_stop(struct hrtimer *hr_timer) ...@@ -181,9 +181,9 @@ void ipc_imem_hrtimer_stop(struct hrtimer *hr_timer)
bool ipc_imem_ul_write_td(struct iosm_imem *ipc_imem) bool ipc_imem_ul_write_td(struct iosm_imem *ipc_imem)
{ {
struct ipc_mem_channel *channel; struct ipc_mem_channel *channel;
bool hpda_ctrl_pending = false;
struct sk_buff_head *ul_list; struct sk_buff_head *ul_list;
bool hpda_pending = false; bool hpda_pending = false;
bool forced_hpdu = false;
struct ipc_pipe *pipe; struct ipc_pipe *pipe;
int i; int i;
...@@ -200,15 +200,19 @@ bool ipc_imem_ul_write_td(struct iosm_imem *ipc_imem) ...@@ -200,15 +200,19 @@ bool ipc_imem_ul_write_td(struct iosm_imem *ipc_imem)
ul_list = &channel->ul_list; ul_list = &channel->ul_list;
/* Fill the transfer descriptor with the uplink buffer info. */ /* Fill the transfer descriptor with the uplink buffer info. */
hpda_pending |= ipc_protocol_ul_td_send(ipc_imem->ipc_protocol, if (!ipc_imem_check_wwan_ips(channel)) {
hpda_ctrl_pending |=
ipc_protocol_ul_td_send(ipc_imem->ipc_protocol,
pipe, ul_list); pipe, ul_list);
} else {
/* forced HP update needed for non data channels */ hpda_pending |=
if (hpda_pending && !ipc_imem_check_wwan_ips(channel)) ipc_protocol_ul_td_send(ipc_imem->ipc_protocol,
forced_hpdu = true; pipe, ul_list);
}
} }
if (forced_hpdu) { /* forced HP update needed for non data channels */
if (hpda_ctrl_pending) {
hpda_pending = false; hpda_pending = false;
ipc_protocol_doorbell_trigger(ipc_imem->ipc_protocol, ipc_protocol_doorbell_trigger(ipc_imem->ipc_protocol,
IPC_HP_UL_WRITE_TD); IPC_HP_UL_WRITE_TD);
...@@ -527,6 +531,9 @@ static void ipc_imem_run_state_worker(struct work_struct *instance) ...@@ -527,6 +531,9 @@ static void ipc_imem_run_state_worker(struct work_struct *instance)
return; return;
} }
if (test_and_clear_bit(IOSM_DEVLINK_INIT, &ipc_imem->flag))
ipc_devlink_deinit(ipc_imem->ipc_devlink);
if (!ipc_imem_setup_cp_mux_cap_init(ipc_imem, &mux_cfg)) if (!ipc_imem_setup_cp_mux_cap_init(ipc_imem, &mux_cfg))
ipc_imem->mux = ipc_mux_init(&mux_cfg, ipc_imem); ipc_imem->mux = ipc_mux_init(&mux_cfg, ipc_imem);
...@@ -1167,7 +1174,7 @@ void ipc_imem_cleanup(struct iosm_imem *ipc_imem) ...@@ -1167,7 +1174,7 @@ void ipc_imem_cleanup(struct iosm_imem *ipc_imem)
ipc_port_deinit(ipc_imem->ipc_port); ipc_port_deinit(ipc_imem->ipc_port);
} }
if (ipc_imem->ipc_devlink) if (test_and_clear_bit(IOSM_DEVLINK_INIT, &ipc_imem->flag))
ipc_devlink_deinit(ipc_imem->ipc_devlink); ipc_devlink_deinit(ipc_imem->ipc_devlink);
ipc_imem_device_ipc_uninit(ipc_imem); ipc_imem_device_ipc_uninit(ipc_imem);
...@@ -1263,7 +1270,6 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id, ...@@ -1263,7 +1270,6 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id,
ipc_imem->pci_device_id = device_id; ipc_imem->pci_device_id = device_id;
ipc_imem->ev_cdev_write_pending = false;
ipc_imem->cp_version = 0; ipc_imem->cp_version = 0;
ipc_imem->device_sleep = IPC_HOST_SLEEP_ENTER_SLEEP; ipc_imem->device_sleep = IPC_HOST_SLEEP_ENTER_SLEEP;
...@@ -1331,6 +1337,8 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id, ...@@ -1331,6 +1337,8 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id,
if (ipc_flash_link_establish(ipc_imem)) if (ipc_flash_link_establish(ipc_imem))
goto devlink_channel_fail; goto devlink_channel_fail;
set_bit(IOSM_DEVLINK_INIT, &ipc_imem->flag);
} }
return ipc_imem; return ipc_imem;
devlink_channel_fail: devlink_channel_fail:
......
...@@ -101,6 +101,7 @@ struct ipc_chnl_cfg; ...@@ -101,6 +101,7 @@ struct ipc_chnl_cfg;
#define IOSM_CHIP_INFO_SIZE_MAX 100 #define IOSM_CHIP_INFO_SIZE_MAX 100
#define FULLY_FUNCTIONAL 0 #define FULLY_FUNCTIONAL 0
#define IOSM_DEVLINK_INIT 1
/* List of the supported UL/DL pipes. */ /* List of the supported UL/DL pipes. */
enum ipc_mem_pipes { enum ipc_mem_pipes {
...@@ -335,8 +336,6 @@ enum ipc_phase { ...@@ -335,8 +336,6 @@ enum ipc_phase {
* process the irq actions. * process the irq actions.
* @flag: Flag to monitor the state of driver * @flag: Flag to monitor the state of driver
* @td_update_timer_suspended: if true then td update timer suspend * @td_update_timer_suspended: if true then td update timer suspend
* @ev_cdev_write_pending: 0 means inform the IPC tasklet to pass
* the accumulated uplink buffers to CP.
* @ev_mux_net_transmit_pending:0 means inform the IPC tasklet to pass * @ev_mux_net_transmit_pending:0 means inform the IPC tasklet to pass
* @reset_det_n: Reset detect flag * @reset_det_n: Reset detect flag
* @pcie_wake_n: Pcie wake flag * @pcie_wake_n: Pcie wake flag
...@@ -374,7 +373,6 @@ struct iosm_imem { ...@@ -374,7 +373,6 @@ struct iosm_imem {
u8 ev_irq_pending[IPC_IRQ_VECTORS]; u8 ev_irq_pending[IPC_IRQ_VECTORS];
unsigned long flag; unsigned long flag;
u8 td_update_timer_suspended:1, u8 td_update_timer_suspended:1,
ev_cdev_write_pending:1,
ev_mux_net_transmit_pending:1, ev_mux_net_transmit_pending:1,
reset_det_n:1, reset_det_n:1,
pcie_wake_n:1; pcie_wake_n:1;
......
...@@ -41,7 +41,6 @@ void ipc_imem_sys_wwan_close(struct iosm_imem *ipc_imem, int if_id, ...@@ -41,7 +41,6 @@ void ipc_imem_sys_wwan_close(struct iosm_imem *ipc_imem, int if_id,
static int ipc_imem_tq_cdev_write(struct iosm_imem *ipc_imem, int arg, static int ipc_imem_tq_cdev_write(struct iosm_imem *ipc_imem, int arg,
void *msg, size_t size) void *msg, size_t size)
{ {
ipc_imem->ev_cdev_write_pending = false;
ipc_imem_ul_send(ipc_imem); ipc_imem_ul_send(ipc_imem);
return 0; return 0;
...@@ -50,11 +49,6 @@ static int ipc_imem_tq_cdev_write(struct iosm_imem *ipc_imem, int arg, ...@@ -50,11 +49,6 @@ static int ipc_imem_tq_cdev_write(struct iosm_imem *ipc_imem, int arg,
/* Through tasklet to do sio write. */ /* Through tasklet to do sio write. */
static int ipc_imem_call_cdev_write(struct iosm_imem *ipc_imem) static int ipc_imem_call_cdev_write(struct iosm_imem *ipc_imem)
{ {
if (ipc_imem->ev_cdev_write_pending)
return -1;
ipc_imem->ev_cdev_write_pending = true;
return ipc_task_queue_send_task(ipc_imem, ipc_imem_tq_cdev_write, 0, return ipc_task_queue_send_task(ipc_imem, ipc_imem_tq_cdev_write, 0,
NULL, 0, false); NULL, 0, false);
} }
...@@ -450,6 +444,7 @@ void ipc_imem_sys_devlink_close(struct iosm_devlink *ipc_devlink) ...@@ -450,6 +444,7 @@ void ipc_imem_sys_devlink_close(struct iosm_devlink *ipc_devlink)
/* Release the pipe resources */ /* Release the pipe resources */
ipc_imem_pipe_cleanup(ipc_imem, &channel->ul_pipe); ipc_imem_pipe_cleanup(ipc_imem, &channel->ul_pipe);
ipc_imem_pipe_cleanup(ipc_imem, &channel->dl_pipe); ipc_imem_pipe_cleanup(ipc_imem, &channel->dl_pipe);
ipc_imem->nr_of_channels--;
} }
void ipc_imem_sys_devlink_notify_rx(struct iosm_devlink *ipc_devlink, void ipc_imem_sys_devlink_notify_rx(struct iosm_devlink *ipc_devlink,
......
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