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
100 if (if_id < 0 || if_id >= ipc_mux->nr_sessions) { in ipc_mux_session_open()
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()
137 static void ipc_mux_session_reset(struct iosm_mux *ipc_mux, int if_id) in ipc_mux_session_reset() argument
140 ipc_mux_session_free(ipc_mux, if_id); in ipc_mux_session_reset()
143 skb_queue_purge(&ipc_mux->session[if_id].ul_list); in ipc_mux_session_reset()
146 static void ipc_mux_session_close(struct iosm_mux *ipc_mux, in ipc_mux_session_close() argument
154 if (if_id < 0 || if_id >= ipc_mux->nr_sessions) { in ipc_mux_session_close()
155 dev_err(ipc_mux->dev, "invalid session id %d", if_id); in ipc_mux_session_close()
162 if (ipc_mux_dl_acb_send_cmds(ipc_mux, MUX_CMD_CLOSE_SESSION, if_id, 0, in ipc_mux_session_close()
164 dev_err(ipc_mux->dev, "if_id %d: CLOSE_SESSION send failed", in ipc_mux_session_close()
168 ipc_mux->session[if_id].flow_ctl_en_cnt = 0; in ipc_mux_session_close()
169 ipc_mux->session[if_id].flow_ctl_dis_cnt = 0; in ipc_mux_session_close()
170 ipc_mux->session[if_id].flow_ctl_mask = 0; in ipc_mux_session_close()
172 ipc_mux_session_reset(ipc_mux, if_id); in ipc_mux_session_close()
175 static void ipc_mux_channel_close(struct iosm_mux *ipc_mux, in ipc_mux_channel_close() argument
181 for (i = 0; i < ipc_mux->nr_sessions; i++) in ipc_mux_channel_close()
182 if (ipc_mux->session[i].wwan) in ipc_mux_channel_close()
183 ipc_mux_session_reset(ipc_mux, i); in ipc_mux_channel_close()
185 ipc_imem_channel_close(ipc_mux->imem, ipc_mux->channel_id); in ipc_mux_channel_close()
188 ipc_mux->state = MUX_S_INACTIVE; in ipc_mux_channel_close()
189 ipc_mux->event = MUX_E_INACTIVE; in ipc_mux_channel_close()
193 static int ipc_mux_schedule(struct iosm_mux *ipc_mux, union mux_msg *msg) in ipc_mux_schedule() argument
199 if (!ipc_mux->initialized) { in ipc_mux_schedule()
206 switch (ipc_mux->state) { in ipc_mux_schedule()
211 if (ipc_mux->event == MUX_E_INACTIVE) in ipc_mux_schedule()
213 ipc_mux->channel_id = ipc_mux_channel_create(ipc_mux); in ipc_mux_schedule()
215 if (ipc_mux->state != MUX_S_ACTIVE) { in ipc_mux_schedule()
216 ret = ipc_mux->channel_id; /* Missing the MUX channel */ in ipc_mux_schedule()
221 ipc_imem_td_update_timer_suspend(ipc_mux->imem, true); in ipc_mux_schedule()
222 ipc_mux->event = MUX_E_MUX_SESSION_OPEN; in ipc_mux_schedule()
223 success = ipc_mux_session_open(ipc_mux, &msg->session_open); in ipc_mux_schedule()
225 ipc_imem_td_update_timer_suspend(ipc_mux->imem, false); in ipc_mux_schedule()
227 ret = ipc_mux->channel_id; in ipc_mux_schedule()
234 ipc_imem_td_update_timer_suspend(ipc_mux->imem, true); in ipc_mux_schedule()
235 ipc_mux->event = MUX_E_MUX_SESSION_OPEN; in ipc_mux_schedule()
236 success = ipc_mux_session_open(ipc_mux, in ipc_mux_schedule()
238 ipc_imem_td_update_timer_suspend(ipc_mux->imem, false); in ipc_mux_schedule()
240 ret = ipc_mux->channel_id; in ipc_mux_schedule()
245 ipc_mux->event = MUX_E_MUX_SESSION_CLOSE; in ipc_mux_schedule()
246 ipc_mux_session_close(ipc_mux, &msg->session_close); in ipc_mux_schedule()
247 ret = ipc_mux->channel_id; in ipc_mux_schedule()
252 ipc_mux->event = MUX_E_MUX_CHANNEL_CLOSE; in ipc_mux_schedule()
253 ipc_mux_channel_close(ipc_mux, &msg->channel_close); in ipc_mux_schedule()
254 ret = ipc_mux->channel_id; in ipc_mux_schedule()
263 dev_err(ipc_mux->dev, in ipc_mux_schedule()
265 ipc_mux->state, ipc_mux->event); in ipc_mux_schedule()
274 struct iosm_mux *ipc_mux = kzalloc(sizeof(*ipc_mux), GFP_KERNEL); in ipc_mux_init() local
279 if (!ipc_mux) in ipc_mux_init()
282 ipc_mux->protocol = mux_cfg->protocol; in ipc_mux_init()
283 ipc_mux->ul_flow = mux_cfg->ul_flow; in ipc_mux_init()
284 ipc_mux->nr_sessions = mux_cfg->nr_sessions; in ipc_mux_init()
285 ipc_mux->instance_id = mux_cfg->instance_id; in ipc_mux_init()
286 ipc_mux->wwan_q_offset = 0; in ipc_mux_init()
288 ipc_mux->pcie = imem->pcie; in ipc_mux_init()
289 ipc_mux->imem = imem; in ipc_mux_init()
290 ipc_mux->ipc_protocol = imem->ipc_protocol; in ipc_mux_init()
291 ipc_mux->dev = imem->dev; in ipc_mux_init()
292 ipc_mux->wwan = imem->wwan; in ipc_mux_init()
295 free_list = &ipc_mux->ul_adb.free_list; in ipc_mux_init()
304 ipc_mux->ul_adb.dest_skb = NULL; in ipc_mux_init()
306 ipc_mux->initialized = true; in ipc_mux_init()
307 ipc_mux->adb_prep_ongoing = false; in ipc_mux_init()
308 ipc_mux->size_needed = 0; in ipc_mux_init()
309 ipc_mux->ul_data_pend_bytes = 0; in ipc_mux_init()
310 ipc_mux->state = MUX_S_INACTIVE; in ipc_mux_init()
311 ipc_mux->ev_mux_net_transmit_pending = false; in ipc_mux_init()
312 ipc_mux->tx_transaction_id = 0; in ipc_mux_init()
313 ipc_mux->rr_next_session = 0; in ipc_mux_init()
314 ipc_mux->event = MUX_E_INACTIVE; in ipc_mux_init()
315 ipc_mux->channel_id = -1; in ipc_mux_init()
316 ipc_mux->channel = NULL; in ipc_mux_init()
322 skb = ipc_pcie_alloc_skb(ipc_mux->pcie, ul_td_size, GFP_ATOMIC, in ipc_mux_init()
325 ipc_mux_deinit(ipc_mux); in ipc_mux_init()
332 return ipc_mux; in ipc_mux_init()
338 static void ipc_mux_restart_tx_for_all_sessions(struct iosm_mux *ipc_mux) in ipc_mux_restart_tx_for_all_sessions() argument
343 for (idx = 0; idx < ipc_mux->nr_sessions; idx++) { in ipc_mux_restart_tx_for_all_sessions()
344 session = &ipc_mux->session[idx]; in ipc_mux_restart_tx_for_all_sessions()
363 static void ipc_mux_stop_netif_for_all_sessions(struct iosm_mux *ipc_mux) in ipc_mux_stop_netif_for_all_sessions() argument
368 for (idx = 0; idx < ipc_mux->nr_sessions; idx++) { in ipc_mux_stop_netif_for_all_sessions()
369 session = &ipc_mux->session[idx]; in ipc_mux_stop_netif_for_all_sessions()
378 void ipc_mux_check_n_restart_tx(struct iosm_mux *ipc_mux) in ipc_mux_check_n_restart_tx() argument
380 if (ipc_mux->ul_flow == MUX_UL) { in ipc_mux_check_n_restart_tx()
383 if (ipc_mux->ul_data_pend_bytes < low_thresh) in ipc_mux_check_n_restart_tx()
384 ipc_mux_restart_tx_for_all_sessions(ipc_mux); in ipc_mux_check_n_restart_tx()
388 int ipc_mux_get_max_sessions(struct iosm_mux *ipc_mux) in ipc_mux_get_max_sessions() argument
390 return ipc_mux ? ipc_mux->nr_sessions : -EFAULT; in ipc_mux_get_max_sessions()
393 enum ipc_mux_protocol ipc_mux_get_active_protocol(struct iosm_mux *ipc_mux) in ipc_mux_get_active_protocol() argument
395 return ipc_mux ? ipc_mux->protocol : MUX_UNKNOWN; in ipc_mux_get_active_protocol()
398 int ipc_mux_open_session(struct iosm_mux *ipc_mux, int session_nr) in ipc_mux_open_session() argument
407 ipc_mux->session[session_nr].flags |= IPC_MEM_WWAN_MUX; in ipc_mux_open_session()
408 return ipc_mux_schedule(ipc_mux, &mux_msg); in ipc_mux_open_session()
411 int ipc_mux_close_session(struct iosm_mux *ipc_mux, int session_nr) in ipc_mux_close_session() argument
421 ret_val = ipc_mux_schedule(ipc_mux, &mux_msg); in ipc_mux_close_session()
422 ipc_mux->session[session_nr].flags &= ~IPC_MEM_WWAN_MUX; in ipc_mux_close_session()
427 void ipc_mux_deinit(struct iosm_mux *ipc_mux) in ipc_mux_deinit() argument
434 if (!ipc_mux->initialized) in ipc_mux_deinit()
436 ipc_mux_stop_netif_for_all_sessions(ipc_mux); in ipc_mux_deinit()
440 ipc_mux_schedule(ipc_mux, &mux_msg); in ipc_mux_deinit()
443 free_list = &ipc_mux->ul_adb.free_list; in ipc_mux_deinit()
447 ipc_pcie_kfree_skb(ipc_mux->pcie, skb); in ipc_mux_deinit()
449 if (ipc_mux->channel) { in ipc_mux_deinit()
450 ipc_mux->channel->ul_pipe.is_open = false; in ipc_mux_deinit()
451 ipc_mux->channel->dl_pipe.is_open = false; in ipc_mux_deinit()
454 kfree(ipc_mux); in ipc_mux_deinit()