Commit da633aa3 authored by M Chetan Kumar's avatar M Chetan Kumar Committed by Jakub Kicinski

net: wwan: iosm: release data channel in case no active IP session

If there is no active IP session (interface up & running) then
release the data channel.

Use nr_sessions variable to track current active IP sessions.
If the count drops to 0, then send pipe close ctrl message to
release the data channel.
Signed-off-by: default avatarM Chetan Kumar <m.chetan.kumar@linux.intel.com>
Reviewed-by: default avatarSergey Ryazanov <ryazanov.s.a@gmail.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 5d710dc3
...@@ -134,7 +134,6 @@ static int ipc_imem_setup_cp_mux_cap_init(struct iosm_imem *ipc_imem, ...@@ -134,7 +134,6 @@ static int ipc_imem_setup_cp_mux_cap_init(struct iosm_imem *ipc_imem,
* for channel alloc function. * for channel alloc function.
*/ */
cfg->instance_id = IPC_MEM_MUX_IP_CH_IF_ID; cfg->instance_id = IPC_MEM_MUX_IP_CH_IF_ID;
cfg->nr_sessions = IPC_MEM_MUX_IP_SESSION_ENTRIES;
return 0; return 0;
} }
......
...@@ -97,7 +97,7 @@ static bool ipc_mux_session_open(struct iosm_mux *ipc_mux, ...@@ -97,7 +97,7 @@ static bool ipc_mux_session_open(struct iosm_mux *ipc_mux,
/* Search for a free session interface id. */ /* Search for a free session interface id. */
if_id = le32_to_cpu(session_open->if_id); if_id = le32_to_cpu(session_open->if_id);
if (if_id < 0 || if_id >= ipc_mux->nr_sessions) { if (if_id < 0 || if_id >= IPC_MEM_MUX_IP_SESSION_ENTRIES) {
dev_err(ipc_mux->dev, "invalid interface id=%d", if_id); dev_err(ipc_mux->dev, "invalid interface id=%d", if_id);
return false; return false;
} }
...@@ -129,6 +129,7 @@ static bool ipc_mux_session_open(struct iosm_mux *ipc_mux, ...@@ -129,6 +129,7 @@ static bool ipc_mux_session_open(struct iosm_mux *ipc_mux,
/* Save and return the assigned if id. */ /* Save and return the assigned if id. */
session_open->if_id = cpu_to_le32(if_id); session_open->if_id = cpu_to_le32(if_id);
ipc_mux->nr_sessions++;
return true; return true;
} }
...@@ -151,7 +152,7 @@ static void ipc_mux_session_close(struct iosm_mux *ipc_mux, ...@@ -151,7 +152,7 @@ static void ipc_mux_session_close(struct iosm_mux *ipc_mux,
/* Copy the session interface id. */ /* Copy the session interface id. */
if_id = le32_to_cpu(msg->if_id); if_id = le32_to_cpu(msg->if_id);
if (if_id < 0 || if_id >= ipc_mux->nr_sessions) { if (if_id < 0 || if_id >= IPC_MEM_MUX_IP_SESSION_ENTRIES) {
dev_err(ipc_mux->dev, "invalid session id %d", if_id); dev_err(ipc_mux->dev, "invalid session id %d", if_id);
return; return;
} }
...@@ -170,6 +171,7 @@ static void ipc_mux_session_close(struct iosm_mux *ipc_mux, ...@@ -170,6 +171,7 @@ static void ipc_mux_session_close(struct iosm_mux *ipc_mux,
ipc_mux->session[if_id].flow_ctl_mask = 0; ipc_mux->session[if_id].flow_ctl_mask = 0;
ipc_mux_session_reset(ipc_mux, if_id); ipc_mux_session_reset(ipc_mux, if_id);
ipc_mux->nr_sessions--;
} }
static void ipc_mux_channel_close(struct iosm_mux *ipc_mux, static void ipc_mux_channel_close(struct iosm_mux *ipc_mux,
...@@ -178,7 +180,7 @@ static void ipc_mux_channel_close(struct iosm_mux *ipc_mux, ...@@ -178,7 +180,7 @@ static void ipc_mux_channel_close(struct iosm_mux *ipc_mux,
int i; int i;
/* Free pending session UL packet. */ /* Free pending session UL packet. */
for (i = 0; i < ipc_mux->nr_sessions; i++) for (i = 0; i < IPC_MEM_MUX_IP_SESSION_ENTRIES; i++)
if (ipc_mux->session[i].wwan) if (ipc_mux->session[i].wwan)
ipc_mux_session_reset(ipc_mux, i); ipc_mux_session_reset(ipc_mux, i);
...@@ -244,6 +246,11 @@ static int ipc_mux_schedule(struct iosm_mux *ipc_mux, union mux_msg *msg) ...@@ -244,6 +246,11 @@ static int ipc_mux_schedule(struct iosm_mux *ipc_mux, union mux_msg *msg)
/* Release an IP session. */ /* Release an IP session. */
ipc_mux->event = MUX_E_MUX_SESSION_CLOSE; ipc_mux->event = MUX_E_MUX_SESSION_CLOSE;
ipc_mux_session_close(ipc_mux, &msg->session_close); ipc_mux_session_close(ipc_mux, &msg->session_close);
if (!ipc_mux->nr_sessions) {
ipc_mux->event = MUX_E_MUX_CHANNEL_CLOSE;
ipc_mux_channel_close(ipc_mux,
&msg->channel_close);
}
ret = ipc_mux->channel_id; ret = ipc_mux->channel_id;
goto out; goto out;
...@@ -281,7 +288,6 @@ struct iosm_mux *ipc_mux_init(struct ipc_mux_config *mux_cfg, ...@@ -281,7 +288,6 @@ struct iosm_mux *ipc_mux_init(struct ipc_mux_config *mux_cfg,
ipc_mux->protocol = mux_cfg->protocol; ipc_mux->protocol = mux_cfg->protocol;
ipc_mux->ul_flow = mux_cfg->ul_flow; ipc_mux->ul_flow = mux_cfg->ul_flow;
ipc_mux->nr_sessions = mux_cfg->nr_sessions;
ipc_mux->instance_id = mux_cfg->instance_id; ipc_mux->instance_id = mux_cfg->instance_id;
ipc_mux->wwan_q_offset = 0; ipc_mux->wwan_q_offset = 0;
...@@ -340,7 +346,7 @@ static void ipc_mux_restart_tx_for_all_sessions(struct iosm_mux *ipc_mux) ...@@ -340,7 +346,7 @@ static void ipc_mux_restart_tx_for_all_sessions(struct iosm_mux *ipc_mux)
struct mux_session *session; struct mux_session *session;
int idx; int idx;
for (idx = 0; idx < ipc_mux->nr_sessions; idx++) { for (idx = 0; idx < IPC_MEM_MUX_IP_SESSION_ENTRIES; idx++) {
session = &ipc_mux->session[idx]; session = &ipc_mux->session[idx];
if (!session->wwan) if (!session->wwan)
...@@ -365,7 +371,7 @@ static void ipc_mux_stop_netif_for_all_sessions(struct iosm_mux *ipc_mux) ...@@ -365,7 +371,7 @@ static void ipc_mux_stop_netif_for_all_sessions(struct iosm_mux *ipc_mux)
struct mux_session *session; struct mux_session *session;
int idx; int idx;
for (idx = 0; idx < ipc_mux->nr_sessions; idx++) { for (idx = 0; idx < IPC_MEM_MUX_IP_SESSION_ENTRIES; idx++) {
session = &ipc_mux->session[idx]; session = &ipc_mux->session[idx];
if (!session->wwan) if (!session->wwan)
...@@ -387,7 +393,7 @@ void ipc_mux_check_n_restart_tx(struct iosm_mux *ipc_mux) ...@@ -387,7 +393,7 @@ void ipc_mux_check_n_restart_tx(struct iosm_mux *ipc_mux)
int ipc_mux_get_max_sessions(struct iosm_mux *ipc_mux) int ipc_mux_get_max_sessions(struct iosm_mux *ipc_mux)
{ {
return ipc_mux ? ipc_mux->nr_sessions : -EFAULT; return ipc_mux ? IPC_MEM_MUX_IP_SESSION_ENTRIES : -EFAULT;
} }
enum ipc_mux_protocol ipc_mux_get_active_protocol(struct iosm_mux *ipc_mux) enum ipc_mux_protocol ipc_mux_get_active_protocol(struct iosm_mux *ipc_mux)
...@@ -435,9 +441,11 @@ void ipc_mux_deinit(struct iosm_mux *ipc_mux) ...@@ -435,9 +441,11 @@ void ipc_mux_deinit(struct iosm_mux *ipc_mux)
return; return;
ipc_mux_stop_netif_for_all_sessions(ipc_mux); ipc_mux_stop_netif_for_all_sessions(ipc_mux);
if (ipc_mux->state == MUX_S_ACTIVE) {
channel_close = &mux_msg.channel_close; channel_close = &mux_msg.channel_close;
channel_close->event = MUX_E_MUX_CHANNEL_CLOSE; channel_close->event = MUX_E_MUX_CHANNEL_CLOSE;
ipc_mux_schedule(ipc_mux, &mux_msg); ipc_mux_schedule(ipc_mux, &mux_msg);
}
/* Empty the ADB free list. */ /* Empty the ADB free list. */
free_list = &ipc_mux->ul_adb.free_list; free_list = &ipc_mux->ul_adb.free_list;
......
...@@ -278,7 +278,6 @@ struct iosm_mux { ...@@ -278,7 +278,6 @@ struct iosm_mux {
struct ipc_mux_config { struct ipc_mux_config {
enum ipc_mux_protocol protocol; enum ipc_mux_protocol protocol;
enum ipc_mux_ul_flow ul_flow; enum ipc_mux_ul_flow ul_flow;
int nr_sessions;
int instance_id; int instance_id;
}; };
......
...@@ -175,7 +175,7 @@ static int ipc_mux_dl_dlcmds_decode_process(struct iosm_mux *ipc_mux, ...@@ -175,7 +175,7 @@ static int ipc_mux_dl_dlcmds_decode_process(struct iosm_mux *ipc_mux,
switch (le32_to_cpu(cmdh->command_type)) { switch (le32_to_cpu(cmdh->command_type)) {
case MUX_LITE_CMD_FLOW_CTL: case MUX_LITE_CMD_FLOW_CTL:
if (cmdh->if_id >= ipc_mux->nr_sessions) { if (cmdh->if_id >= IPC_MEM_MUX_IP_SESSION_ENTRIES) {
dev_err(ipc_mux->dev, "if_id [%d] not valid", dev_err(ipc_mux->dev, "if_id [%d] not valid",
cmdh->if_id); cmdh->if_id);
return -EINVAL; /* No session interface id. */ return -EINVAL; /* No session interface id. */
...@@ -307,13 +307,13 @@ static void ipc_mux_dl_fcth_decode(struct iosm_mux *ipc_mux, ...@@ -307,13 +307,13 @@ static void ipc_mux_dl_fcth_decode(struct iosm_mux *ipc_mux,
} }
if_id = fct->if_id; if_id = fct->if_id;
if (if_id >= ipc_mux->nr_sessions) { if (if_id >= IPC_MEM_MUX_IP_SESSION_ENTRIES) {
dev_err(ipc_mux->dev, "not supported if_id: %d", if_id); dev_err(ipc_mux->dev, "not supported if_id: %d", if_id);
return; return;
} }
/* Is the session active ? */ /* Is the session active ? */
if_id = array_index_nospec(if_id, ipc_mux->nr_sessions); if_id = array_index_nospec(if_id, IPC_MEM_MUX_IP_SESSION_ENTRIES);
wwan = ipc_mux->session[if_id].wwan; wwan = ipc_mux->session[if_id].wwan;
if (!wwan) { if (!wwan) {
dev_err(ipc_mux->dev, "session Net ID is NULL"); dev_err(ipc_mux->dev, "session Net ID is NULL");
...@@ -355,13 +355,13 @@ static void ipc_mux_dl_adgh_decode(struct iosm_mux *ipc_mux, ...@@ -355,13 +355,13 @@ static void ipc_mux_dl_adgh_decode(struct iosm_mux *ipc_mux,
} }
if_id = adgh->if_id; if_id = adgh->if_id;
if (if_id >= ipc_mux->nr_sessions) { if (if_id >= IPC_MEM_MUX_IP_SESSION_ENTRIES) {
dev_err(ipc_mux->dev, "invalid if_id while decoding %d", if_id); dev_err(ipc_mux->dev, "invalid if_id while decoding %d", if_id);
return; return;
} }
/* Is the session active ? */ /* Is the session active ? */
if_id = array_index_nospec(if_id, ipc_mux->nr_sessions); if_id = array_index_nospec(if_id, IPC_MEM_MUX_IP_SESSION_ENTRIES);
wwan = ipc_mux->session[if_id].wwan; wwan = ipc_mux->session[if_id].wwan;
if (!wwan) { if (!wwan) {
dev_err(ipc_mux->dev, "session Net ID is NULL"); dev_err(ipc_mux->dev, "session Net ID is NULL");
...@@ -538,7 +538,7 @@ static void ipc_mux_stop_tx_for_all_sessions(struct iosm_mux *ipc_mux) ...@@ -538,7 +538,7 @@ static void ipc_mux_stop_tx_for_all_sessions(struct iosm_mux *ipc_mux)
struct mux_session *session; struct mux_session *session;
int idx; int idx;
for (idx = 0; idx < ipc_mux->nr_sessions; idx++) { for (idx = 0; idx < IPC_MEM_MUX_IP_SESSION_ENTRIES; idx++) {
session = &ipc_mux->session[idx]; session = &ipc_mux->session[idx];
if (!session->wwan) if (!session->wwan)
...@@ -563,7 +563,7 @@ static bool ipc_mux_lite_send_qlt(struct iosm_mux *ipc_mux) ...@@ -563,7 +563,7 @@ static bool ipc_mux_lite_send_qlt(struct iosm_mux *ipc_mux)
qlt_size = offsetof(struct ipc_mem_lite_gen_tbl, vfl) + qlt_size = offsetof(struct ipc_mem_lite_gen_tbl, vfl) +
MUX_QUEUE_LEVEL * sizeof(struct mux_lite_vfl); MUX_QUEUE_LEVEL * sizeof(struct mux_lite_vfl);
for (i = 0; i < ipc_mux->nr_sessions; i++) { for (i = 0; i < IPC_MEM_MUX_IP_SESSION_ENTRIES; i++) {
session = &ipc_mux->session[i]; session = &ipc_mux->session[i];
if (!session->wwan || session->flow_ctl_mask) if (!session->wwan || session->flow_ctl_mask)
...@@ -777,13 +777,13 @@ bool ipc_mux_ul_data_encode(struct iosm_mux *ipc_mux) ...@@ -777,13 +777,13 @@ bool ipc_mux_ul_data_encode(struct iosm_mux *ipc_mux)
ipc_mux->adb_prep_ongoing = true; ipc_mux->adb_prep_ongoing = true;
for (i = 0; i < ipc_mux->nr_sessions; i++) { for (i = 0; i < IPC_MEM_MUX_IP_SESSION_ENTRIES; i++) {
session_id = ipc_mux->rr_next_session; session_id = ipc_mux->rr_next_session;
session = &ipc_mux->session[session_id]; session = &ipc_mux->session[session_id];
/* Go to next handle rr_next_session overflow */ /* Go to next handle rr_next_session overflow */
ipc_mux->rr_next_session++; ipc_mux->rr_next_session++;
if (ipc_mux->rr_next_session >= ipc_mux->nr_sessions) if (ipc_mux->rr_next_session >= IPC_MEM_MUX_IP_SESSION_ENTRIES)
ipc_mux->rr_next_session = 0; ipc_mux->rr_next_session = 0;
if (!session->wwan || session->flow_ctl_mask || if (!session->wwan || session->flow_ctl_mask ||
......
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