Lines Matching refs:ipc_mux

9 static int ipc_mux_channel_create(struct iosm_mux *ipc_mux)  in ipc_mux_channel_create()  argument
13 channel_id = ipc_imem_channel_alloc(ipc_mux->imem, ipc_mux->instance_id, in ipc_mux_channel_create()
17 dev_err(ipc_mux->dev, in ipc_mux_channel_create()
19 ipc_mux->state = MUX_S_ERROR; in ipc_mux_channel_create()
20 ipc_mux->event = MUX_E_NOT_APPLICABLE; in ipc_mux_channel_create()
25 ipc_mux->channel = ipc_imem_channel_open(ipc_mux->imem, channel_id, in ipc_mux_channel_create()
28 if (!ipc_mux->channel) { in ipc_mux_channel_create()
29 dev_err(ipc_mux->dev, "ipc_imem_channel_open failed"); in ipc_mux_channel_create()
30 ipc_mux->state = MUX_S_ERROR; in ipc_mux_channel_create()
31 ipc_mux->event = MUX_E_NOT_APPLICABLE; in ipc_mux_channel_create()
36 ipc_mux->state = MUX_S_ACTIVE; in ipc_mux_channel_create()
37 ipc_mux->event = MUX_E_NO_ORDERS; in ipc_mux_channel_create()
44 static void ipc_mux_session_free(struct iosm_mux *ipc_mux, int if_id) in ipc_mux_session_free() argument
48 if_entry = &ipc_mux->session[if_id]; in ipc_mux_session_free()
55 ipc_mux_session_open_send(struct iosm_mux *ipc_mux, int if_id) in ipc_mux_session_open_send() argument
58 struct mux_acb *acb = &ipc_mux->acb; in ipc_mux_session_open_send()
71 if (ipc_mux_dl_acb_send_cmds(ipc_mux, MUX_CMD_OPEN_SESSION, if_id, 0, in ipc_mux_session_open_send()
75 dev_err(ipc_mux->dev, "if_id %d: OPEN_SESSION send failed", in ipc_mux_session_open_send()
80 open_session_resp = &ipc_mux->acb.got_param.open_session_resp; in ipc_mux_session_open_send()
82 dev_err(ipc_mux->dev, in ipc_mux_session_open_send()
92 static bool ipc_mux_session_open(struct iosm_mux *ipc_mux, in ipc_mux_session_open() argument
101 dev_err(ipc_mux->dev, "invalid interface id=%d", if_id); in ipc_mux_session_open()
108 open_session_resp = ipc_mux_session_open_send(ipc_mux, if_id); in ipc_mux_session_open()
110 ipc_mux_session_free(ipc_mux, if_id); in ipc_mux_session_open()
116 skb_queue_head_init(&ipc_mux->session[if_id].ul_list); in ipc_mux_session_open()
118 ipc_mux->session[if_id].dl_head_pad_len = IPC_MEM_DL_ETH_OFFSET; in ipc_mux_session_open()
119 ipc_mux->session[if_id].ul_head_pad_len = in ipc_mux_session_open()
121 ipc_mux->session[if_id].wwan = ipc_mux->wwan; in ipc_mux_session_open()
124 ipc_mux->session[if_id].flow_ctl_en_cnt = 0; in ipc_mux_session_open()
125 ipc_mux->session[if_id].flow_ctl_dis_cnt = 0; in ipc_mux_session_open()
126 ipc_mux->session[if_id].ul_flow_credits = 0; in ipc_mux_session_open()
127 ipc_mux->session[if_id].net_tx_stop = false; in ipc_mux_session_open()
128 ipc_mux->session[if_id].flow_ctl_mask = 0; in ipc_mux_session_open()
132 ipc_mux->nr_sessions++; in ipc_mux_session_open()
138 static void ipc_mux_session_reset(struct iosm_mux *ipc_mux, int if_id) in ipc_mux_session_reset() argument
141 ipc_mux_session_free(ipc_mux, if_id); in ipc_mux_session_reset()
144 skb_queue_purge(&ipc_mux->session[if_id].ul_list); in ipc_mux_session_reset()
147 static void ipc_mux_session_close(struct iosm_mux *ipc_mux, in ipc_mux_session_close() argument
156 dev_err(ipc_mux->dev, "invalid session id %d", if_id); in ipc_mux_session_close()
163 if (ipc_mux_dl_acb_send_cmds(ipc_mux, MUX_CMD_CLOSE_SESSION, if_id, 0, in ipc_mux_session_close()
165 dev_err(ipc_mux->dev, "if_id %d: CLOSE_SESSION send failed", in ipc_mux_session_close()
169 ipc_mux->session[if_id].flow_ctl_en_cnt = 0; in ipc_mux_session_close()
170 ipc_mux->session[if_id].flow_ctl_dis_cnt = 0; in ipc_mux_session_close()
171 ipc_mux->session[if_id].flow_ctl_mask = 0; in ipc_mux_session_close()
173 ipc_mux_session_reset(ipc_mux, if_id); in ipc_mux_session_close()
174 ipc_mux->nr_sessions--; in ipc_mux_session_close()
177 static void ipc_mux_channel_close(struct iosm_mux *ipc_mux, in ipc_mux_channel_close() argument
184 if (ipc_mux->session[i].wwan) in ipc_mux_channel_close()
185 ipc_mux_session_reset(ipc_mux, i); in ipc_mux_channel_close()
187 ipc_imem_channel_close(ipc_mux->imem, ipc_mux->channel_id); in ipc_mux_channel_close()
190 ipc_mux->state = MUX_S_INACTIVE; in ipc_mux_channel_close()
191 ipc_mux->event = MUX_E_INACTIVE; in ipc_mux_channel_close()
195 static int ipc_mux_schedule(struct iosm_mux *ipc_mux, union mux_msg *msg) in ipc_mux_schedule() argument
201 if (!ipc_mux->initialized) { in ipc_mux_schedule()
208 switch (ipc_mux->state) { in ipc_mux_schedule()
213 if (ipc_mux->event == MUX_E_INACTIVE) in ipc_mux_schedule()
215 ipc_mux->channel_id = ipc_mux_channel_create(ipc_mux); in ipc_mux_schedule()
217 if (ipc_mux->state != MUX_S_ACTIVE) { in ipc_mux_schedule()
218 ret = ipc_mux->channel_id; /* Missing the MUX channel */ in ipc_mux_schedule()
223 ipc_imem_td_update_timer_suspend(ipc_mux->imem, true); in ipc_mux_schedule()
224 ipc_mux->event = MUX_E_MUX_SESSION_OPEN; in ipc_mux_schedule()
225 success = ipc_mux_session_open(ipc_mux, &msg->session_open); in ipc_mux_schedule()
227 ipc_imem_td_update_timer_suspend(ipc_mux->imem, false); in ipc_mux_schedule()
229 ret = ipc_mux->channel_id; in ipc_mux_schedule()
236 ipc_imem_td_update_timer_suspend(ipc_mux->imem, true); in ipc_mux_schedule()
237 ipc_mux->event = MUX_E_MUX_SESSION_OPEN; in ipc_mux_schedule()
238 success = ipc_mux_session_open(ipc_mux, in ipc_mux_schedule()
240 ipc_imem_td_update_timer_suspend(ipc_mux->imem, false); in ipc_mux_schedule()
242 ret = ipc_mux->channel_id; in ipc_mux_schedule()
247 ipc_mux->event = MUX_E_MUX_SESSION_CLOSE; in ipc_mux_schedule()
248 ipc_mux_session_close(ipc_mux, &msg->session_close); in ipc_mux_schedule()
249 if (!ipc_mux->nr_sessions) { in ipc_mux_schedule()
250 ipc_mux->event = MUX_E_MUX_CHANNEL_CLOSE; in ipc_mux_schedule()
251 ipc_mux_channel_close(ipc_mux, in ipc_mux_schedule()
254 ret = ipc_mux->channel_id; in ipc_mux_schedule()
259 ipc_mux->event = MUX_E_MUX_CHANNEL_CLOSE; in ipc_mux_schedule()
260 ipc_mux_channel_close(ipc_mux, &msg->channel_close); in ipc_mux_schedule()
261 ret = ipc_mux->channel_id; in ipc_mux_schedule()
270 dev_err(ipc_mux->dev, in ipc_mux_schedule()
272 ipc_mux->state, ipc_mux->event); in ipc_mux_schedule()
281 struct iosm_mux *ipc_mux = kzalloc(sizeof(*ipc_mux), GFP_KERNEL); in ipc_mux_init() local
287 if (!ipc_mux) in ipc_mux_init()
290 ipc_mux->protocol = mux_cfg->protocol; in ipc_mux_init()
291 ipc_mux->ul_flow = mux_cfg->ul_flow; in ipc_mux_init()
292 ipc_mux->instance_id = mux_cfg->instance_id; in ipc_mux_init()
293 ipc_mux->wwan_q_offset = 0; in ipc_mux_init()
295 ipc_mux->pcie = imem->pcie; in ipc_mux_init()
296 ipc_mux->imem = imem; in ipc_mux_init()
297 ipc_mux->ipc_protocol = imem->ipc_protocol; in ipc_mux_init()
298 ipc_mux->dev = imem->dev; in ipc_mux_init()
299 ipc_mux->wwan = imem->wwan; in ipc_mux_init()
302 free_list = &ipc_mux->ul_adb.free_list; in ipc_mux_init()
311 ipc_mux->ul_adb.dest_skb = NULL; in ipc_mux_init()
313 ipc_mux->initialized = true; in ipc_mux_init()
314 ipc_mux->adb_prep_ongoing = false; in ipc_mux_init()
315 ipc_mux->size_needed = 0; in ipc_mux_init()
316 ipc_mux->ul_data_pend_bytes = 0; in ipc_mux_init()
317 ipc_mux->state = MUX_S_INACTIVE; in ipc_mux_init()
318 ipc_mux->ev_mux_net_transmit_pending = false; in ipc_mux_init()
319 ipc_mux->tx_transaction_id = 0; in ipc_mux_init()
320 ipc_mux->rr_next_session = 0; in ipc_mux_init()
321 ipc_mux->event = MUX_E_INACTIVE; in ipc_mux_init()
322 ipc_mux->channel_id = -1; in ipc_mux_init()
323 ipc_mux->channel = NULL; in ipc_mux_init()
325 if (ipc_mux->protocol != MUX_LITE) { in ipc_mux_init()
330 ipc_mux->ul_adb.pp_qlt[i] = kzalloc(qlt_size, in ipc_mux_init()
332 if (!ipc_mux->ul_adb.pp_qlt[i]) { in ipc_mux_init()
334 kfree(ipc_mux->ul_adb.pp_qlt[j]); in ipc_mux_init()
347 skb = ipc_pcie_alloc_skb(ipc_mux->pcie, ul_td_size, GFP_ATOMIC, in ipc_mux_init()
350 ipc_mux_deinit(ipc_mux); in ipc_mux_init()
357 return ipc_mux; in ipc_mux_init()
363 static void ipc_mux_restart_tx_for_all_sessions(struct iosm_mux *ipc_mux) in ipc_mux_restart_tx_for_all_sessions() argument
369 session = &ipc_mux->session[idx]; in ipc_mux_restart_tx_for_all_sessions()
388 static void ipc_mux_stop_netif_for_all_sessions(struct iosm_mux *ipc_mux) in ipc_mux_stop_netif_for_all_sessions() argument
394 session = &ipc_mux->session[idx]; in ipc_mux_stop_netif_for_all_sessions()
403 void ipc_mux_check_n_restart_tx(struct iosm_mux *ipc_mux) in ipc_mux_check_n_restart_tx() argument
405 if (ipc_mux->ul_flow == MUX_UL) { in ipc_mux_check_n_restart_tx()
408 if (ipc_mux->ul_data_pend_bytes < low_thresh) in ipc_mux_check_n_restart_tx()
409 ipc_mux_restart_tx_for_all_sessions(ipc_mux); in ipc_mux_check_n_restart_tx()
413 int ipc_mux_get_max_sessions(struct iosm_mux *ipc_mux) in ipc_mux_get_max_sessions() argument
415 return ipc_mux ? IPC_MEM_MUX_IP_SESSION_ENTRIES : -EFAULT; in ipc_mux_get_max_sessions()
418 enum ipc_mux_protocol ipc_mux_get_active_protocol(struct iosm_mux *ipc_mux) in ipc_mux_get_active_protocol() argument
420 return ipc_mux ? ipc_mux->protocol : MUX_UNKNOWN; in ipc_mux_get_active_protocol()
423 int ipc_mux_open_session(struct iosm_mux *ipc_mux, int session_nr) in ipc_mux_open_session() argument
432 ipc_mux->session[session_nr].flags |= IPC_MEM_WWAN_MUX; in ipc_mux_open_session()
433 return ipc_mux_schedule(ipc_mux, &mux_msg); in ipc_mux_open_session()
436 int ipc_mux_close_session(struct iosm_mux *ipc_mux, int session_nr) in ipc_mux_close_session() argument
446 ret_val = ipc_mux_schedule(ipc_mux, &mux_msg); in ipc_mux_close_session()
447 ipc_mux->session[session_nr].flags &= ~IPC_MEM_WWAN_MUX; in ipc_mux_close_session()
452 void ipc_mux_deinit(struct iosm_mux *ipc_mux) in ipc_mux_deinit() argument
459 if (!ipc_mux->initialized) in ipc_mux_deinit()
461 ipc_mux_stop_netif_for_all_sessions(ipc_mux); in ipc_mux_deinit()
463 if (ipc_mux->state == MUX_S_ACTIVE) { in ipc_mux_deinit()
466 ipc_mux_schedule(ipc_mux, &mux_msg); in ipc_mux_deinit()
470 free_list = &ipc_mux->ul_adb.free_list; in ipc_mux_deinit()
474 ipc_pcie_kfree_skb(ipc_mux->pcie, skb); in ipc_mux_deinit()
476 if (ipc_mux->channel) { in ipc_mux_deinit()
477 ipc_mux->channel->ul_pipe.is_open = false; in ipc_mux_deinit()
478 ipc_mux->channel->dl_pipe.is_open = false; in ipc_mux_deinit()
481 kfree(ipc_mux); in ipc_mux_deinit()