|
@@ -1,11 +1,11 @@
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
/*
|
|
- * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
|
|
|
|
|
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
|
*/
|
|
*/
|
|
|
|
|
|
#include <net/pkt_sched.h>
|
|
#include <net/pkt_sched.h>
|
|
#include <linux/module.h>
|
|
#include <linux/module.h>
|
|
-#include "rmnet_ctl.h"
|
|
|
|
|
|
+#include "rmnet_qmap.h"
|
|
#include "dfc_defs.h"
|
|
#include "dfc_defs.h"
|
|
#include "rmnet_qmi.h"
|
|
#include "rmnet_qmi.h"
|
|
#include "qmi_rmnet.h"
|
|
#include "qmi_rmnet.h"
|
|
@@ -13,39 +13,6 @@
|
|
|
|
|
|
#define QMAP_DFC_VER 1
|
|
#define QMAP_DFC_VER 1
|
|
|
|
|
|
-#define QMAP_CMD_DONE -1
|
|
|
|
-
|
|
|
|
-#define QMAP_CMD_REQUEST 0
|
|
|
|
-#define QMAP_CMD_ACK 1
|
|
|
|
-#define QMAP_CMD_UNSUPPORTED 2
|
|
|
|
-#define QMAP_CMD_INVALID 3
|
|
|
|
-
|
|
|
|
-#define QMAP_DFC_CONFIG 10
|
|
|
|
-#define QMAP_DFC_IND 11
|
|
|
|
-#define QMAP_DFC_QUERY 12
|
|
|
|
-#define QMAP_DFC_END_MARKER 13
|
|
|
|
-
|
|
|
|
-struct qmap_hdr {
|
|
|
|
- u8 cd_pad;
|
|
|
|
- u8 mux_id;
|
|
|
|
- __be16 pkt_len;
|
|
|
|
-} __aligned(1);
|
|
|
|
-
|
|
|
|
-#define QMAP_HDR_LEN sizeof(struct qmap_hdr)
|
|
|
|
-
|
|
|
|
-struct qmap_cmd_hdr {
|
|
|
|
- u8 pad_len:6;
|
|
|
|
- u8 reserved_bit:1;
|
|
|
|
- u8 cd_bit:1;
|
|
|
|
- u8 mux_id;
|
|
|
|
- __be16 pkt_len;
|
|
|
|
- u8 cmd_name;
|
|
|
|
- u8 cmd_type:2;
|
|
|
|
- u8 reserved:6;
|
|
|
|
- u16 reserved2;
|
|
|
|
- __be32 tx_id;
|
|
|
|
-} __aligned(1);
|
|
|
|
-
|
|
|
|
struct qmap_dfc_config {
|
|
struct qmap_dfc_config {
|
|
struct qmap_cmd_hdr hdr;
|
|
struct qmap_cmd_hdr hdr;
|
|
u8 cmd_ver;
|
|
u8 cmd_ver;
|
|
@@ -125,43 +92,12 @@ struct qmap_dfc_end_marker_cnf {
|
|
static struct dfc_flow_status_ind_msg_v01 qmap_flow_ind;
|
|
static struct dfc_flow_status_ind_msg_v01 qmap_flow_ind;
|
|
static struct dfc_tx_link_status_ind_msg_v01 qmap_tx_ind;
|
|
static struct dfc_tx_link_status_ind_msg_v01 qmap_tx_ind;
|
|
static struct dfc_qmi_data __rcu *qmap_dfc_data;
|
|
static struct dfc_qmi_data __rcu *qmap_dfc_data;
|
|
-static atomic_t qmap_txid;
|
|
|
|
-static void *rmnet_ctl_handle;
|
|
|
|
static bool dfc_config_acked;
|
|
static bool dfc_config_acked;
|
|
|
|
|
|
-static struct rmnet_ctl_client_if *rmnet_ctl;
|
|
|
|
-
|
|
|
|
static void dfc_qmap_send_config(struct dfc_qmi_data *data);
|
|
static void dfc_qmap_send_config(struct dfc_qmi_data *data);
|
|
static void dfc_qmap_send_end_marker_cnf(struct qos_info *qos,
|
|
static void dfc_qmap_send_end_marker_cnf(struct qos_info *qos,
|
|
- u8 bearer_id, u16 seq, u32 tx_id);
|
|
|
|
-
|
|
|
|
-static void dfc_qmap_send_cmd(struct sk_buff *skb)
|
|
|
|
-{
|
|
|
|
- trace_dfc_qmap(skb->data, skb->len, false);
|
|
|
|
-
|
|
|
|
- if (unlikely(!rmnet_ctl || !rmnet_ctl->send) ||
|
|
|
|
- rmnet_ctl->send(rmnet_ctl_handle, skb)) {
|
|
|
|
- pr_err("Failed to send to rmnet ctl\n");
|
|
|
|
- kfree_skb(skb);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void dfc_qmap_send_inband_ack(struct dfc_qmi_data *dfc,
|
|
|
|
- struct sk_buff *skb)
|
|
|
|
-{
|
|
|
|
- struct qmap_cmd_hdr *cmd;
|
|
|
|
-
|
|
|
|
- cmd = (struct qmap_cmd_hdr *)skb->data;
|
|
|
|
-
|
|
|
|
- skb->protocol = htons(ETH_P_MAP);
|
|
|
|
- skb->dev = rmnet_get_real_dev(dfc->rmnet_port);
|
|
|
|
-
|
|
|
|
- if (likely(rmnet_ctl && rmnet_ctl->log))
|
|
|
|
- rmnet_ctl->log(RMNET_CTL_LOG_DEBUG, "TXI", 0,
|
|
|
|
- skb->data, skb->len);
|
|
|
|
- trace_dfc_qmap(skb->data, skb->len, false);
|
|
|
|
- dev_queue_xmit(skb);
|
|
|
|
-}
|
|
|
|
|
|
+ struct rmnet_bearer_map *bearer,
|
|
|
|
+ u16 seq, u32 tx_id);
|
|
|
|
|
|
static int dfc_qmap_handle_ind(struct dfc_qmi_data *dfc,
|
|
static int dfc_qmap_handle_ind(struct dfc_qmi_data *dfc,
|
|
struct sk_buff *skb)
|
|
struct sk_buff *skb)
|
|
@@ -254,33 +190,40 @@ static int dfc_qmap_handle_query_resp(struct dfc_qmi_data *dfc,
|
|
return QMAP_CMD_DONE;
|
|
return QMAP_CMD_DONE;
|
|
}
|
|
}
|
|
|
|
|
|
-static void dfc_qmap_set_end_marker(struct dfc_qmi_data *dfc, u8 mux_id,
|
|
|
|
- u8 bearer_id, u16 seq_num, u32 tx_id)
|
|
|
|
|
|
+static int dfc_qmap_set_end_marker(struct dfc_qmi_data *dfc, u8 mux_id,
|
|
|
|
+ u8 bearer_id, u16 seq_num, u32 tx_id)
|
|
{
|
|
{
|
|
struct net_device *dev;
|
|
struct net_device *dev;
|
|
struct qos_info *qos;
|
|
struct qos_info *qos;
|
|
struct rmnet_bearer_map *bearer;
|
|
struct rmnet_bearer_map *bearer;
|
|
|
|
+ int rc = QMAP_CMD_ACK;
|
|
|
|
|
|
dev = rmnet_get_rmnet_dev(dfc->rmnet_port, mux_id);
|
|
dev = rmnet_get_rmnet_dev(dfc->rmnet_port, mux_id);
|
|
if (!dev)
|
|
if (!dev)
|
|
- return;
|
|
|
|
|
|
+ return rc;
|
|
|
|
|
|
qos = (struct qos_info *)rmnet_get_qos_pt(dev);
|
|
qos = (struct qos_info *)rmnet_get_qos_pt(dev);
|
|
if (!qos)
|
|
if (!qos)
|
|
- return;
|
|
|
|
|
|
+ return rc;
|
|
|
|
|
|
spin_lock_bh(&qos->qos_lock);
|
|
spin_lock_bh(&qos->qos_lock);
|
|
|
|
|
|
bearer = qmi_rmnet_get_bearer_map(qos, bearer_id);
|
|
bearer = qmi_rmnet_get_bearer_map(qos, bearer_id);
|
|
|
|
+ if (!bearer) {
|
|
|
|
+ spin_unlock_bh(&qos->qos_lock);
|
|
|
|
+ return rc;
|
|
|
|
+ }
|
|
|
|
|
|
- if (bearer && bearer->last_seq == seq_num && bearer->grant_size) {
|
|
|
|
|
|
+ if (bearer->last_seq == seq_num && bearer->grant_size) {
|
|
bearer->ack_req = 1;
|
|
bearer->ack_req = 1;
|
|
bearer->ack_txid = tx_id;
|
|
bearer->ack_txid = tx_id;
|
|
} else {
|
|
} else {
|
|
- dfc_qmap_send_end_marker_cnf(qos, bearer_id, seq_num, tx_id);
|
|
|
|
|
|
+ dfc_qmap_send_end_marker_cnf(qos, bearer, seq_num, tx_id);
|
|
}
|
|
}
|
|
|
|
|
|
spin_unlock_bh(&qos->qos_lock);
|
|
spin_unlock_bh(&qos->qos_lock);
|
|
|
|
+
|
|
|
|
+ return QMAP_CMD_DONE;
|
|
}
|
|
}
|
|
|
|
|
|
static int dfc_qmap_handle_end_marker_req(struct dfc_qmi_data *dfc,
|
|
static int dfc_qmap_handle_end_marker_req(struct dfc_qmi_data *dfc,
|
|
@@ -293,47 +236,32 @@ static int dfc_qmap_handle_end_marker_req(struct dfc_qmi_data *dfc,
|
|
|
|
|
|
cmd = (struct qmap_dfc_end_marker_req *)skb->data;
|
|
cmd = (struct qmap_dfc_end_marker_req *)skb->data;
|
|
|
|
|
|
- dfc_qmap_set_end_marker(dfc, cmd->hdr.mux_id, cmd->bearer_id,
|
|
|
|
- ntohs(cmd->seq_num), ntohl(cmd->hdr.tx_id));
|
|
|
|
-
|
|
|
|
- return QMAP_CMD_DONE;
|
|
|
|
|
|
+ return dfc_qmap_set_end_marker(dfc, cmd->hdr.mux_id, cmd->bearer_id,
|
|
|
|
+ ntohs(cmd->seq_num),
|
|
|
|
+ ntohl(cmd->hdr.tx_id));
|
|
}
|
|
}
|
|
|
|
|
|
-static void dfc_qmap_cmd_handler(struct sk_buff *skb)
|
|
|
|
|
|
+int dfc_qmap_cmd_handler(struct sk_buff *skb)
|
|
{
|
|
{
|
|
struct qmap_cmd_hdr *cmd;
|
|
struct qmap_cmd_hdr *cmd;
|
|
struct dfc_qmi_data *dfc;
|
|
struct dfc_qmi_data *dfc;
|
|
int rc = QMAP_CMD_DONE;
|
|
int rc = QMAP_CMD_DONE;
|
|
|
|
|
|
- if (!skb)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- trace_dfc_qmap(skb->data, skb->len, true);
|
|
|
|
-
|
|
|
|
- if (skb->len < sizeof(struct qmap_cmd_hdr))
|
|
|
|
- goto free_skb;
|
|
|
|
-
|
|
|
|
cmd = (struct qmap_cmd_hdr *)skb->data;
|
|
cmd = (struct qmap_cmd_hdr *)skb->data;
|
|
- if (!cmd->cd_bit || skb->len != ntohs(cmd->pkt_len) + QMAP_HDR_LEN)
|
|
|
|
- goto free_skb;
|
|
|
|
|
|
|
|
if (cmd->cmd_name == QMAP_DFC_QUERY) {
|
|
if (cmd->cmd_name == QMAP_DFC_QUERY) {
|
|
if (cmd->cmd_type != QMAP_CMD_ACK)
|
|
if (cmd->cmd_type != QMAP_CMD_ACK)
|
|
- goto free_skb;
|
|
|
|
|
|
+ return rc;
|
|
} else if (cmd->cmd_type != QMAP_CMD_REQUEST) {
|
|
} else if (cmd->cmd_type != QMAP_CMD_REQUEST) {
|
|
if (cmd->cmd_type == QMAP_CMD_ACK &&
|
|
if (cmd->cmd_type == QMAP_CMD_ACK &&
|
|
cmd->cmd_name == QMAP_DFC_CONFIG)
|
|
cmd->cmd_name == QMAP_DFC_CONFIG)
|
|
dfc_config_acked = true;
|
|
dfc_config_acked = true;
|
|
- goto free_skb;
|
|
|
|
|
|
+ return rc;
|
|
}
|
|
}
|
|
|
|
|
|
- rcu_read_lock();
|
|
|
|
-
|
|
|
|
dfc = rcu_dereference(qmap_dfc_data);
|
|
dfc = rcu_dereference(qmap_dfc_data);
|
|
- if (!dfc || READ_ONCE(dfc->restart_state)) {
|
|
|
|
- rcu_read_unlock();
|
|
|
|
- goto free_skb;
|
|
|
|
- }
|
|
|
|
|
|
+ if (!dfc || READ_ONCE(dfc->restart_state))
|
|
|
|
+ return rc;
|
|
|
|
|
|
/* Re-send DFC config once if needed */
|
|
/* Re-send DFC config once if needed */
|
|
if (unlikely(!dfc_config_acked)) {
|
|
if (unlikely(!dfc_config_acked)) {
|
|
@@ -356,25 +284,11 @@ static void dfc_qmap_cmd_handler(struct sk_buff *skb)
|
|
break;
|
|
break;
|
|
|
|
|
|
default:
|
|
default:
|
|
- rc = QMAP_CMD_UNSUPPORTED;
|
|
|
|
|
|
+ if (cmd->cmd_type == QMAP_CMD_REQUEST)
|
|
|
|
+ rc = QMAP_CMD_UNSUPPORTED;
|
|
}
|
|
}
|
|
|
|
|
|
- /* Send ack */
|
|
|
|
- if (rc != QMAP_CMD_DONE) {
|
|
|
|
- cmd->cmd_type = rc;
|
|
|
|
- if (cmd->cmd_name == QMAP_DFC_IND)
|
|
|
|
- dfc_qmap_send_inband_ack(dfc, skb);
|
|
|
|
- else
|
|
|
|
- dfc_qmap_send_cmd(skb);
|
|
|
|
-
|
|
|
|
- rcu_read_unlock();
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- rcu_read_unlock();
|
|
|
|
-
|
|
|
|
-free_skb:
|
|
|
|
- kfree_skb(skb);
|
|
|
|
|
|
+ return rc;
|
|
}
|
|
}
|
|
|
|
|
|
static void dfc_qmap_send_config(struct dfc_qmi_data *data)
|
|
static void dfc_qmap_send_config(struct dfc_qmi_data *data)
|
|
@@ -396,7 +310,7 @@ static void dfc_qmap_send_config(struct dfc_qmi_data *data)
|
|
dfc_config->hdr.pkt_len = htons(len - QMAP_HDR_LEN);
|
|
dfc_config->hdr.pkt_len = htons(len - QMAP_HDR_LEN);
|
|
dfc_config->hdr.cmd_name = QMAP_DFC_CONFIG;
|
|
dfc_config->hdr.cmd_name = QMAP_DFC_CONFIG;
|
|
dfc_config->hdr.cmd_type = QMAP_CMD_REQUEST;
|
|
dfc_config->hdr.cmd_type = QMAP_CMD_REQUEST;
|
|
- dfc_config->hdr.tx_id = htonl(atomic_inc_return(&qmap_txid));
|
|
|
|
|
|
+ dfc_config->hdr.tx_id = htonl(rmnet_qmap_next_txid());
|
|
|
|
|
|
dfc_config->cmd_ver = QMAP_DFC_VER;
|
|
dfc_config->cmd_ver = QMAP_DFC_VER;
|
|
dfc_config->cmd_id = QMAP_DFC_IND;
|
|
dfc_config->cmd_id = QMAP_DFC_IND;
|
|
@@ -404,7 +318,7 @@ static void dfc_qmap_send_config(struct dfc_qmi_data *data)
|
|
dfc_config->ep_type = htonl(data->svc.ep_type);
|
|
dfc_config->ep_type = htonl(data->svc.ep_type);
|
|
dfc_config->iface_id = htonl(data->svc.iface_id);
|
|
dfc_config->iface_id = htonl(data->svc.iface_id);
|
|
|
|
|
|
- dfc_qmap_send_cmd(skb);
|
|
|
|
|
|
+ rmnet_qmap_send(skb, RMNET_CH_CTL, false);
|
|
}
|
|
}
|
|
|
|
|
|
static void dfc_qmap_send_query(u8 mux_id, u8 bearer_id)
|
|
static void dfc_qmap_send_query(u8 mux_id, u8 bearer_id)
|
|
@@ -426,16 +340,17 @@ static void dfc_qmap_send_query(u8 mux_id, u8 bearer_id)
|
|
dfc_query->hdr.pkt_len = htons(len - QMAP_HDR_LEN);
|
|
dfc_query->hdr.pkt_len = htons(len - QMAP_HDR_LEN);
|
|
dfc_query->hdr.cmd_name = QMAP_DFC_QUERY;
|
|
dfc_query->hdr.cmd_name = QMAP_DFC_QUERY;
|
|
dfc_query->hdr.cmd_type = QMAP_CMD_REQUEST;
|
|
dfc_query->hdr.cmd_type = QMAP_CMD_REQUEST;
|
|
- dfc_query->hdr.tx_id = htonl(atomic_inc_return(&qmap_txid));
|
|
|
|
|
|
+ dfc_query->hdr.tx_id = htonl(rmnet_qmap_next_txid());
|
|
|
|
|
|
dfc_query->cmd_ver = QMAP_DFC_VER;
|
|
dfc_query->cmd_ver = QMAP_DFC_VER;
|
|
dfc_query->bearer_id = bearer_id;
|
|
dfc_query->bearer_id = bearer_id;
|
|
|
|
|
|
- dfc_qmap_send_cmd(skb);
|
|
|
|
|
|
+ rmnet_qmap_send(skb, RMNET_CH_CTL, false);
|
|
}
|
|
}
|
|
|
|
|
|
static void dfc_qmap_send_end_marker_cnf(struct qos_info *qos,
|
|
static void dfc_qmap_send_end_marker_cnf(struct qos_info *qos,
|
|
- u8 bearer_id, u16 seq, u32 tx_id)
|
|
|
|
|
|
+ struct rmnet_bearer_map *bearer,
|
|
|
|
+ u16 seq, u32 tx_id)
|
|
{
|
|
{
|
|
struct sk_buff *skb;
|
|
struct sk_buff *skb;
|
|
struct qmap_dfc_end_marker_cnf *em_cnf;
|
|
struct qmap_dfc_end_marker_cnf *em_cnf;
|
|
@@ -456,18 +371,17 @@ static void dfc_qmap_send_end_marker_cnf(struct qos_info *qos,
|
|
em_cnf->hdr.tx_id = htonl(tx_id);
|
|
em_cnf->hdr.tx_id = htonl(tx_id);
|
|
|
|
|
|
em_cnf->cmd_ver = QMAP_DFC_VER;
|
|
em_cnf->cmd_ver = QMAP_DFC_VER;
|
|
- em_cnf->bearer_id = bearer_id;
|
|
|
|
|
|
+ em_cnf->bearer_id = bearer->bearer_id;
|
|
em_cnf->seq_num = htons(seq);
|
|
em_cnf->seq_num = htons(seq);
|
|
|
|
|
|
- skb->protocol = htons(ETH_P_MAP);
|
|
|
|
- skb->dev = qos->real_dev;
|
|
|
|
-
|
|
|
|
- /* This cmd needs to be sent in-band */
|
|
|
|
- if (likely(rmnet_ctl && rmnet_ctl->log))
|
|
|
|
- rmnet_ctl->log(RMNET_CTL_LOG_INFO, "TXI", 0,
|
|
|
|
- skb->data, skb->len);
|
|
|
|
- trace_dfc_qmap(skb->data, skb->len, false);
|
|
|
|
- rmnet_map_tx_qmap_cmd(skb);
|
|
|
|
|
|
+ /* This cmd needs to be sent in-band after data on the currnet
|
|
|
|
+ * channel. But due to IPA bug, it cannot be sent over LLC so send
|
|
|
|
+ * it over QMAP channel if current channel is LLC.
|
|
|
|
+ */
|
|
|
|
+ if (bearer->ch_switch.current_ch == RMNET_CH_DEFAULT)
|
|
|
|
+ rmnet_qmap_send(skb, bearer->ch_switch.current_ch, true);
|
|
|
|
+ else
|
|
|
|
+ rmnet_qmap_send(skb, RMNET_CH_CTL, false);
|
|
}
|
|
}
|
|
|
|
|
|
void dfc_qmap_send_ack(struct qos_info *qos, u8 bearer_id, u16 seq, u8 type)
|
|
void dfc_qmap_send_ack(struct qos_info *qos, u8 bearer_id, u16 seq, u8 type)
|
|
@@ -477,17 +391,13 @@ void dfc_qmap_send_ack(struct qos_info *qos, u8 bearer_id, u16 seq, u8 type)
|
|
if (type == DFC_ACK_TYPE_DISABLE) {
|
|
if (type == DFC_ACK_TYPE_DISABLE) {
|
|
bearer = qmi_rmnet_get_bearer_map(qos, bearer_id);
|
|
bearer = qmi_rmnet_get_bearer_map(qos, bearer_id);
|
|
if (bearer)
|
|
if (bearer)
|
|
- dfc_qmap_send_end_marker_cnf(qos, bearer_id,
|
|
|
|
|
|
+ dfc_qmap_send_end_marker_cnf(qos, bearer,
|
|
seq, bearer->ack_txid);
|
|
seq, bearer->ack_txid);
|
|
} else if (type == DFC_ACK_TYPE_THRESHOLD) {
|
|
} else if (type == DFC_ACK_TYPE_THRESHOLD) {
|
|
dfc_qmap_send_query(qos->mux_id, bearer_id);
|
|
dfc_qmap_send_query(qos->mux_id, bearer_id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static struct rmnet_ctl_client_hooks cb = {
|
|
|
|
- .ctl_dl_client_hook = dfc_qmap_cmd_handler,
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
int dfc_qmap_client_init(void *port, int index, struct svc_info *psvc,
|
|
int dfc_qmap_client_init(void *port, int index, struct svc_info *psvc,
|
|
struct qmi_info *qmi)
|
|
struct qmi_info *qmi)
|
|
{
|
|
{
|
|
@@ -512,19 +422,7 @@ int dfc_qmap_client_init(void *port, int index, struct svc_info *psvc,
|
|
qmi->dfc_clients[index] = (void *)data;
|
|
qmi->dfc_clients[index] = (void *)data;
|
|
rcu_assign_pointer(qmap_dfc_data, data);
|
|
rcu_assign_pointer(qmap_dfc_data, data);
|
|
|
|
|
|
- atomic_set(&qmap_txid, 0);
|
|
|
|
-
|
|
|
|
- rmnet_ctl = rmnet_ctl_if();
|
|
|
|
- if (!rmnet_ctl) {
|
|
|
|
- pr_err("rmnet_ctl module not loaded\n");
|
|
|
|
- goto out;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (rmnet_ctl->reg)
|
|
|
|
- rmnet_ctl_handle = rmnet_ctl->reg(&cb);
|
|
|
|
-
|
|
|
|
- if (!rmnet_ctl_handle)
|
|
|
|
- pr_err("Failed to register with rmnet ctl\n");
|
|
|
|
|
|
+ rmnet_qmap_init(port);
|
|
|
|
|
|
trace_dfc_client_state_up(data->index, data->svc.instance,
|
|
trace_dfc_client_state_up(data->index, data->svc.instance,
|
|
data->svc.ep_type, data->svc.iface_id);
|
|
data->svc.ep_type, data->svc.iface_id);
|
|
@@ -534,7 +432,6 @@ int dfc_qmap_client_init(void *port, int index, struct svc_info *psvc,
|
|
dfc_config_acked = false;
|
|
dfc_config_acked = false;
|
|
dfc_qmap_send_config(data);
|
|
dfc_qmap_send_config(data);
|
|
|
|
|
|
-out:
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -549,16 +446,13 @@ void dfc_qmap_client_exit(void *dfc_data)
|
|
|
|
|
|
trace_dfc_client_state_down(data->index, 0);
|
|
trace_dfc_client_state_down(data->index, 0);
|
|
|
|
|
|
- if (rmnet_ctl && rmnet_ctl->dereg)
|
|
|
|
- rmnet_ctl->dereg(rmnet_ctl_handle);
|
|
|
|
- rmnet_ctl_handle = NULL;
|
|
|
|
|
|
+ rmnet_qmap_exit();
|
|
|
|
|
|
WRITE_ONCE(data->restart_state, 1);
|
|
WRITE_ONCE(data->restart_state, 1);
|
|
RCU_INIT_POINTER(qmap_dfc_data, NULL);
|
|
RCU_INIT_POINTER(qmap_dfc_data, NULL);
|
|
synchronize_rcu();
|
|
synchronize_rcu();
|
|
|
|
|
|
kfree(data);
|
|
kfree(data);
|
|
- rmnet_ctl = NULL;
|
|
|
|
|
|
|
|
pr_info("DFC QMAP exit\n");
|
|
pr_info("DFC QMAP exit\n");
|
|
}
|
|
}
|