cnss2: Fix MAC address setup on late DMS server arrival

Process QMI socket connection in DMS server arrival callback to avoid
MAC address setup failure on late DMS service connection.

Change-Id: I949b409e09afc7f98decc5f05912467df0d997b8
Signed-off-by: Manikandan Mohan <manikand@codeaurora.org>
This commit is contained in:
Manikandan Mohan 2020-10-21 21:01:08 -07:00
commit 6404ccc934
4 changed files with 18 additions and 76 deletions

View file

@ -412,6 +412,10 @@ static int cnss_setup_dms_mac(struct cnss_plat_data *plat_priv)
u32 i;
int ret = 0;
ret = cnss_qmi_get_dms_mac(plat_priv);
if (ret == 0 && plat_priv->dms.mac_valid)
goto qmi_send;
/* DTSI property use-nv-mac is used to force DMS MAC address for WLAN.
* Thus assert on failure to get MAC from DMS even after retries
*/
@ -426,11 +430,12 @@ static int cnss_setup_dms_mac(struct cnss_plat_data *plat_priv)
msleep(CNSS_DMS_QMI_CONNECTION_WAIT_MS);
}
if (!plat_priv->dms.mac_valid) {
cnss_pr_err("Unable to get MAC from DMS\n");
cnss_pr_err("Unable to get MAC from DMS after retries\n");
CNSS_ASSERT(0);
return -EINVAL;
}
}
qmi_send:
if (plat_priv->dms.mac_valid)
ret =
cnss_wlfw_wlan_mac_req_send_sync(plat_priv, plat_priv->dms.mac,
@ -532,10 +537,6 @@ static char *cnss_driver_event_to_str(enum cnss_driver_event_type type)
return "QDSS_TRACE_SAVE";
case CNSS_DRIVER_EVENT_QDSS_TRACE_FREE:
return "QDSS_TRACE_FREE";
case CNSS_DRIVER_EVENT_DMS_SERVER_ARRIVE:
return "DMS_SERVER_ARRIVE";
case CNSS_DRIVER_EVENT_DMS_SERVER_EXIT:
return "DMS_SERVER_EXIT";
case CNSS_DRIVER_EVENT_MAX:
return "EVENT_MAX";
}
@ -1695,12 +1696,6 @@ static void cnss_driver_event_work(struct work_struct *work)
case CNSS_DRIVER_EVENT_QDSS_TRACE_FREE:
ret = cnss_qdss_trace_free_hdlr(plat_priv);
break;
case CNSS_DRIVER_EVENT_DMS_SERVER_ARRIVE:
ret = cnss_dms_server_arrive(plat_priv, event->data);
break;
case CNSS_DRIVER_EVENT_DMS_SERVER_EXIT:
ret = cnss_dms_server_exit(plat_priv);
break;
default:
cnss_pr_err("Invalid driver event type: %d",
event->type);

View file

@ -261,8 +261,6 @@ enum cnss_driver_event_type {
CNSS_DRIVER_EVENT_QDSS_TRACE_REQ_MEM,
CNSS_DRIVER_EVENT_QDSS_TRACE_SAVE,
CNSS_DRIVER_EVENT_QDSS_TRACE_FREE,
CNSS_DRIVER_EVENT_DMS_SERVER_ARRIVE,
CNSS_DRIVER_EVENT_DMS_SERVER_EXIT,
CNSS_DRIVER_EVENT_MAX,
};

View file

@ -2475,80 +2475,42 @@ out:
}
static int cnss_dms_connect_to_server(struct cnss_plat_data *plat_priv,
void *data)
unsigned int node, unsigned int port)
{
struct cnss_qmi_event_server_arrive_data *event_data = data;
struct qmi_handle *qmi_dms = &plat_priv->qmi_dms;
struct sockaddr_qrtr sq = {0};
int ret = 0;
if (!event_data)
return -EINVAL;
sq.sq_family = AF_QIPCRTR;
sq.sq_node = event_data->node;
sq.sq_port = event_data->port;
kfree(data);
sq.sq_node = node;
sq.sq_port = port;
ret = kernel_connect(qmi_dms->sock, (struct sockaddr *)&sq,
sizeof(sq), 0);
if (ret < 0) {
cnss_pr_err("Failed to connect to QMI DMS remote service port\n");
cnss_pr_err("Failed to connect to QMI DMS remote service Node: %d Port: %d\n",
node, port);
goto out;
}
set_bit(CNSS_QMI_DMS_CONNECTED, &plat_priv->driver_state);
cnss_pr_info("QMI DMS service connected, state: 0x%lx\n",
plat_priv->driver_state);
cnss_qmi_get_dms_mac(plat_priv);
out:
return ret;
}
int cnss_dms_server_arrive(struct cnss_plat_data *plat_priv, void *data)
{
int ret = 0;
if (!plat_priv) {
cnss_pr_err("Platform not initialized on DMS server arrive\n");
return -ENODEV;
}
ret = cnss_dms_connect_to_server(plat_priv, data);
return ret;
}
int cnss_dms_server_exit(struct cnss_plat_data *plat_priv)
{
if (!plat_priv)
return -ENODEV;
clear_bit(CNSS_QMI_DMS_CONNECTED, &plat_priv->driver_state);
cnss_pr_info("QMI DMS service disconnected, state: 0x%lx\n",
plat_priv->driver_state);
return 0;
}
static int dms_new_server(struct qmi_handle *qmi_dms,
struct qmi_service *service)
{
struct cnss_plat_data *plat_priv =
container_of(qmi_dms, struct cnss_plat_data, qmi_dms);
struct cnss_qmi_event_server_arrive_data *event_data;
cnss_pr_err("DMS server arriving: node %u port %u\n",
service->node, service->port);
if (!service)
return -EINVAL;
event_data = kzalloc(sizeof(*event_data), GFP_KERNEL);
if (!event_data)
return -ENOMEM;
event_data->node = service->node;
event_data->port = service->port;
cnss_driver_event_post(plat_priv, CNSS_DRIVER_EVENT_DMS_SERVER_ARRIVE,
0, event_data);
return 0;
return cnss_dms_connect_to_server(plat_priv, service->node,
service->port);
}
static void dms_del_server(struct qmi_handle *qmi_dms,
@ -2557,9 +2519,9 @@ static void dms_del_server(struct qmi_handle *qmi_dms,
struct cnss_plat_data *plat_priv =
container_of(qmi_dms, struct cnss_plat_data, qmi_dms);
cnss_pr_dbg("DMS server exiting\n");
cnss_driver_event_post(plat_priv, CNSS_DRIVER_EVENT_DMS_SERVER_EXIT, 0,
NULL);
clear_bit(CNSS_QMI_DMS_CONNECTED, &plat_priv->driver_state);
cnss_pr_info("QMI DMS service disconnected, state: 0x%lx\n",
plat_priv->driver_state);
}
static struct qmi_ops qmi_dms_ops = {

View file

@ -77,8 +77,6 @@ void cnss_ignore_qmi_failure(bool ignore);
int cnss_qmi_get_dms_mac(struct cnss_plat_data *plat_priv);
int cnss_wlfw_wlan_mac_req_send_sync(struct cnss_plat_data *plat_priv,
u8 *mac, u32 mac_len);
int cnss_dms_server_arrive(struct cnss_plat_data *plat_priv, void *data);
int cnss_dms_server_exit(struct cnss_plat_data *plat_priv);
int cnss_dms_init(struct cnss_plat_data *plat_priv);
void cnss_dms_deinit(struct cnss_plat_data *plat_priv);
#else
@ -259,17 +257,6 @@ int cnss_wlfw_wlan_mac_req_send_sync(struct cnss_plat_data *plat_priv,
return 0;
}
static inline
int cnss_dms_server_arrive(struct cnss_plat_data *plat_priv, void *data)
{
return 0;
}
static inline int cnss_dms_server_exit(struct cnss_plat_data *plat_priv)
{
return 0;
}
static inline int cnss_dms_init(struct cnss_plat_data *plat_priv)
{
return 0;