summaryrefslogtreecommitdiff
path: root/core/utils
diff options
context:
space:
mode:
Diffstat (limited to 'core/utils')
-rw-r--r--core/utils/fwlog/dbglog_host.c51
-rw-r--r--core/utils/logging/src/wlan_logging_sock_svc.c36
-rw-r--r--core/utils/nlink/inc/wlan_nlink_common.h6
-rw-r--r--core/utils/nlink/inc/wlan_nlink_srv.h4
-rw-r--r--core/utils/nlink/src/wlan_nlink_srv.c208
-rw-r--r--core/utils/ptt/inc/wlan_ptt_sock_svc.h5
6 files changed, 283 insertions, 27 deletions
diff --git a/core/utils/fwlog/dbglog_host.c b/core/utils/fwlog/dbglog_host.c
index e4c8f1278820..09e5f959e7f3 100644
--- a/core/utils/fwlog/dbglog_host.c
+++ b/core/utils/fwlog/dbglog_host.c
@@ -1608,6 +1608,9 @@ int send_fw_diag_nl_data(const uint8_t *buffer, A_UINT32 len,
struct sk_buff *skb_out;
struct nlmsghdr *nlh;
int res = 0;
+ tAniNlHdr *wnl;
+ int radio;
+ int msg_len;
if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE))
return -ENODEV;
@@ -1615,15 +1618,25 @@ int send_fw_diag_nl_data(const uint8_t *buffer, A_UINT32 len,
if (nl_srv_is_initialized() != 0)
return -EIO;
+ radio = cds_get_radio_index();
+ if (radio == -EINVAL)
+ return -EIO;
+
if (cds_is_multicast_logging()) {
- skb_out = nlmsg_new(len, 0);
+ msg_len = len + sizeof(radio);
+ skb_out = nlmsg_new(msg_len, GFP_KERNEL);
if (!skb_out) {
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
("Failed to allocate new skb\n"));
return -ENOMEM;
}
- nlh = nlmsg_put(skb_out, 0, 0, WLAN_NL_MSG_CNSS_DIAG, len, 0);
- memcpy(nlmsg_data(nlh), buffer, len);
+ nlh = nlmsg_put(skb_out, 0, 0, WLAN_NL_MSG_CNSS_DIAG, msg_len,
+ 0);
+ wnl = (tAniNlHdr *)nlh;
+ wnl->radio = radio;
+
+ /* data buffer offset from nlmsg_hdr + sizeof(int) radio */
+ memcpy(nlmsg_data(nlh) + sizeof(radio), buffer, len);
res = nl_srv_bcast(skb_out);
if (res < 0) {
@@ -1684,6 +1697,8 @@ send_diag_netlink_data(const uint8_t *buffer, A_UINT32 len, A_UINT32 cmd)
int res = 0;
struct dbglog_slot *slot;
size_t slot_len;
+ tAniNlHdr *wnl;
+ int radio;
if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE))
return -ENODEV;
@@ -1691,10 +1706,15 @@ send_diag_netlink_data(const uint8_t *buffer, A_UINT32 len, A_UINT32 cmd)
if (nl_srv_is_initialized() != 0)
return -EIO;
+ radio = cds_get_radio_index();
+ if (radio == -EINVAL)
+ return -EIO;
+
if (cds_is_multicast_logging()) {
- slot_len = sizeof(*slot) + ATH6KL_FWLOG_PAYLOAD_SIZE;
+ slot_len = sizeof(*slot) + ATH6KL_FWLOG_PAYLOAD_SIZE +
+ sizeof(radio);
- skb_out = nlmsg_new(slot_len, 0);
+ skb_out = nlmsg_new(slot_len, GFP_KERNEL);
if (!skb_out) {
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
("Failed to allocate new skb\n"));
@@ -1703,7 +1723,10 @@ send_diag_netlink_data(const uint8_t *buffer, A_UINT32 len, A_UINT32 cmd)
nlh = nlmsg_put(skb_out, 0, 0, WLAN_NL_MSG_CNSS_DIAG,
slot_len, 0);
- slot = (struct dbglog_slot *)nlmsg_data(nlh);
+ wnl = (tAniNlHdr *)nlh;
+ wnl->radio = radio;
+ /* data buffer offset from: nlmsg_hdr + sizeof(int) radio */
+ slot = (struct dbglog_slot *) (nlmsg_data(nlh) + sizeof(radio));
slot->diag_type = cmd;
slot->timestamp = cpu_to_le32(jiffies);
slot->length = cpu_to_le32(len);
@@ -1731,6 +1754,8 @@ dbglog_process_netlink_data(wmi_unified_t wmi_handle, const uint8_t *buffer,
int res = 0;
struct dbglog_slot *slot;
size_t slot_len;
+ tAniNlHdr *wnl;
+ int radio;
if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE))
return -ENODEV;
@@ -1738,10 +1763,15 @@ dbglog_process_netlink_data(wmi_unified_t wmi_handle, const uint8_t *buffer,
if (nl_srv_is_initialized() != 0)
return -EIO;
+ radio = cds_get_radio_index();
+ if (radio == -EINVAL)
+ return -EIO;
+
if (cds_is_multicast_logging()) {
- slot_len = sizeof(*slot) + ATH6KL_FWLOG_PAYLOAD_SIZE;
+ slot_len = sizeof(*slot) + ATH6KL_FWLOG_PAYLOAD_SIZE +
+ sizeof(radio);
- skb_out = nlmsg_new(slot_len, 0);
+ skb_out = nlmsg_new(slot_len, GFP_KERNEL);
if (!skb_out) {
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
("Failed to allocate new skb\n"));
@@ -1750,7 +1780,10 @@ dbglog_process_netlink_data(wmi_unified_t wmi_handle, const uint8_t *buffer,
nlh = nlmsg_put(skb_out, 0, 0, WLAN_NL_MSG_CNSS_DIAG,
slot_len, 0);
- slot = (struct dbglog_slot *)nlmsg_data(nlh);
+ wnl = (tAniNlHdr *)nlh;
+ wnl->radio = radio;
+ /* data buffer offset from: nlmsg_hdr + sizeof(int) radio */
+ slot = (struct dbglog_slot *) (nlmsg_data(nlh) + sizeof(radio));
slot->diag_type = (A_UINT32) DIAG_TYPE_FW_DEBUG_MSG;
slot->timestamp = cpu_to_le32(jiffies);
slot->length = cpu_to_le32(len);
diff --git a/core/utils/logging/src/wlan_logging_sock_svc.c b/core/utils/logging/src/wlan_logging_sock_svc.c
index c0c854f05bd4..b11a6ca38357 100644
--- a/core/utils/logging/src/wlan_logging_sock_svc.c
+++ b/core/utils/logging/src/wlan_logging_sock_svc.c
@@ -253,10 +253,11 @@ static int wlan_queue_logmsg_for_app(void)
#ifdef QCA_WIFI_3_0_ADRASTEA
/**
- * wlan_add_user_log_time_stamp() - add time stamp in WLAN log buffer
+ * wlan_add_user_log_radio_time_stamp() - add radio and time stamp in log buffer
* @tbuf: Pointer to time stamp buffer
* @tbuf_sz: Time buffer size
* @ts: Time stamp value
+ * @radoi: the radio index
*
* For adrastea time stamp is QTIMER raw tick which will be used by cnss_diag
* to convert it into user visible time stamp. In adrstea FW also uses QTIMER
@@ -266,19 +267,22 @@ static int wlan_queue_logmsg_for_app(void)
* For discrete solution e.g rome use system tick and convert it into
* seconds.milli seconds
*/
-static int wlan_add_user_log_time_stamp(char *tbuf, size_t tbuf_sz, uint64_t ts)
+static int wlan_add_user_log_radio_time_stamp(char *tbuf, size_t tbuf_sz,
+ uint64_t ts, int radio)
{
int tlen;
- tlen = scnprintf(tbuf, tbuf_sz, "[%s][%llu] ", current->comm, ts);
+ tlen = scnprintf(tbuf, tbuf_sz, "R%d: [%s][%llu] ",
+ radio, current->comm, ts);
return tlen;
}
#else
/**
- * wlan_add_user_log_time_stamp() - add time stamp in WLAN log buffer
+ * wlan_add_user_log_radio_time_stamp() - add radio and time stamp in log buffer
* @tbuf: Pointer to time stamp buffer
* @tbuf_sz: Time buffer size
* @ts: Time stamp value
+ * @radio: the radio index
*
* For adrastea time stamp QTIMER raw tick which will be used by cnss_diag
* to convert it into user visible time stamp
@@ -286,14 +290,15 @@ static int wlan_add_user_log_time_stamp(char *tbuf, size_t tbuf_sz, uint64_t ts)
* For discrete solution e.g rome use system tick and convert it into
* seconds.milli seconds
*/
-static int wlan_add_user_log_time_stamp(char *tbuf, size_t tbuf_sz, uint64_t ts)
+static int wlan_add_user_log_radio_time_stamp(char *tbuf, size_t tbuf_sz,
+ uint64_t ts, int radio)
{
int tlen;
uint32_t rem;
rem = do_div(ts, QDF_MC_TIMER_TO_SEC_UNIT);
- tlen = scnprintf(tbuf, tbuf_sz, "[%s][%lu.%06lu] ", current->comm,
- (unsigned long) ts, (unsigned long)rem);
+ tlen = scnprintf(tbuf, tbuf_sz, "R%d: [%s][%lu.%06lu] ", radio,
+ current->comm, (unsigned long) ts, (unsigned long)rem);
return tlen;
}
#endif
@@ -309,8 +314,11 @@ int wlan_log_to_user(QDF_TRACE_LEVEL log_level, char *to_be_sent, int length)
bool wake_up_thread = false;
unsigned long flags;
uint64_t ts;
+ int radio;
+
+ radio = cds_get_radio_index();
- if (!cds_is_multicast_logging()) {
+ if (!cds_is_multicast_logging() || radio == -EINVAL) {
/*
* This is to make sure that we print the logs to kmsg console
* when no logger app is running. This is also needed to
@@ -319,12 +327,20 @@ int wlan_log_to_user(QDF_TRACE_LEVEL log_level, char *to_be_sent, int length)
* register with driver immediately and start logging all the
* messages.
*/
- pr_info("%s\n", to_be_sent);
+ /*
+ * R%d: if the radio index is invalid, just post the message
+ * to console.
+ * Also the radio index shouldn't happen to be EINVAL, but if
+ * that happen just print it, so that the logging would be
+ * aware the cnss_logger is somehow failed.
+ */
+ pr_info("R%d: %s\n", radio, to_be_sent);
return 0;
}
ts = qdf_get_log_timestamp();
- tlen = wlan_add_user_log_time_stamp(tbuf, sizeof(tbuf), ts);
+ tlen = wlan_add_user_log_radio_time_stamp(tbuf, sizeof(tbuf), ts,
+ radio);
/* 1+1 indicate '\n'+'\0' */
total_log_len = length + tlen + 1 + 1;
diff --git a/core/utils/nlink/inc/wlan_nlink_common.h b/core/utils/nlink/inc/wlan_nlink_common.h
index 1120016d7a97..f714d1bd6aa7 100644
--- a/core/utils/nlink/inc/wlan_nlink_common.h
+++ b/core/utils/nlink/inc/wlan_nlink_common.h
@@ -108,6 +108,12 @@ typedef struct sAniHdr {
unsigned short length;
} tAniHdr, tAniMsgHdr;
+typedef struct sAniNlMsg {
+ struct nlmsghdr nlh; /* Netlink Header */
+ int radio; /* unit number of the radio */
+ tAniHdr wmsg; /* Airgo Message Header */
+} tAniNlHdr;
+
struct wlan_status_data {
uint8_t lpss_support;
uint8_t is_on;
diff --git a/core/utils/nlink/inc/wlan_nlink_srv.h b/core/utils/nlink/inc/wlan_nlink_srv.h
index a973a7b1bfe2..b455b64d583f 100644
--- a/core/utils/nlink/inc/wlan_nlink_srv.h
+++ b/core/utils/nlink/inc/wlan_nlink_srv.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -49,7 +49,7 @@
typedef int (*nl_srv_msg_callback)(struct sk_buff *skb);
-int nl_srv_init(void);
+int nl_srv_init(void *wiphy);
void nl_srv_exit(void);
int nl_srv_register(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler);
int nl_srv_unregister(tWlanNlModTypes msg_type,
diff --git a/core/utils/nlink/src/wlan_nlink_srv.c b/core/utils/nlink/src/wlan_nlink_srv.c
index d3b56faef10b..49bc0812a61a 100644
--- a/core/utils/nlink/src/wlan_nlink_srv.c
+++ b/core/utils/nlink/src/wlan_nlink_srv.c
@@ -43,6 +43,210 @@
#include <wlan_nlink_srv.h>
#include <qdf_trace.h>
+#if defined(CONFIG_CNSS_LOGGER)
+
+#include <net/cnss_logger.h>
+
+static int radio_idx = -EINVAL;
+static void *wiphy_ptr;
+static bool logger_initialized;
+
+/**
+ * nl_srv_init() - wrapper function to register to cnss_logger
+ * @wiphy: the pointer to the wiphy structure
+ *
+ * The netlink socket is no longer initialized in the driver itself, instead
+ * will be initialized in the cnss_logger module, the driver should register
+ * itself to cnss_logger module to get the radio_index for all the netlink
+ * operation. (cfg80211 vendor command is using different netlink socket).
+ *
+ * The cnss_logger_device_register() use to register the driver with the
+ * wiphy structure and the module name (debug purpose) and then return the
+ * radio_index depending on the availibility.
+ *
+ * Return: radio index for success and -EINVAL for failure
+ */
+int nl_srv_init(void *wiphy)
+{
+ if (logger_initialized)
+ goto initialized;
+
+ wiphy_ptr = wiphy;
+ radio_idx = cnss_logger_device_register(wiphy, THIS_MODULE->name);
+ QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR
+ "%s: radio_index: %d, wiphy_ptr: %p",
+ __func__, radio_idx, wiphy_ptr);
+
+ if (radio_idx >= 0)
+ logger_initialized = true;
+
+initialized:
+ return radio_idx;
+}
+
+/**
+ * nl_srv_exit() - wrapper function to unregister from cnss_logger
+ *
+ * The cnss_logger_device_unregister() use to unregister the driver with
+ * the radio_index assigned and wiphy structure from cnss_logger.
+ *
+ * Return: None
+ */
+void nl_srv_exit(void)
+{
+ if (logger_initialized) {
+ cnss_logger_device_unregister(radio_idx, wiphy_ptr);
+ radio_idx = -EINVAL;
+ wiphy_ptr = NULL;
+ logger_initialized = false;
+ }
+}
+
+/**
+ * nl_srv_ucast() - wrapper function to do unicast tx through cnss_logger
+ * @skb: the socket buffer to send
+ * @dst_pid: the port id
+ * @flag: the blocking or nonblocking flag
+ *
+ * The nl_srv_is_initialized() is used to do sanity check if the netlink
+ * service is ready, e.g if the radio_index is assigned properly, if not
+ * the driver should take the responsibility to free the skb.
+ *
+ * The cnss_logger_nl_ucast() use the same parameters to send the socket
+ * buffers.
+ *
+ * Return: the error of the transmission status
+ */
+int nl_srv_ucast(struct sk_buff *skb, int dst_pid, int flag)
+{
+ int err = -EINVAL;
+
+ /* sender's pid */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
+ NETLINK_CB(skb).pid = 0;
+#else
+ NETLINK_CB(skb).portid = 0;
+#endif
+ /* not multicast */
+ NETLINK_CB(skb).dst_group = 0;
+
+ if (nl_srv_is_initialized() == 0)
+ err = cnss_logger_nl_ucast(skb, dst_pid, flag);
+ else
+ dev_kfree_skb(skb);
+ return err;
+}
+
+/**
+ * nl_srv_bcast() - wrapper function to do broadcast tx through cnss_logger
+ * @skb: the socket buffer to send
+ *
+ * The cnss_logger_nl_bcast() is used to transmit the socket buffer.
+ *
+ * Return: status of transmission
+ */
+int nl_srv_bcast(struct sk_buff *skb)
+{
+ int err = -EINVAL;
+ int flags = GFP_KERNEL;
+
+ if (in_interrupt() || irqs_disabled() || in_atomic())
+ flags = GFP_ATOMIC;
+
+ /* sender's pid */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
+ NETLINK_CB(skb).pid = 0;
+#else
+ NETLINK_CB(skb).portid = 0;
+#endif
+ /* destination group */
+ NETLINK_CB(skb).dst_group = WLAN_NLINK_MCAST_GRP_ID;
+
+ if (nl_srv_is_initialized() == 0)
+ err = cnss_logger_nl_bcast(skb, WLAN_NLINK_MCAST_GRP_ID, flags);
+ else
+ dev_kfree_skb(skb);
+ return err;
+}
+
+/**
+ * nl_srv_unregister() - wrapper function to unregister event to cnss_logger
+ * @msg_type: the message to unregister
+ * @msg_handler: the message handler
+ *
+ * The cnss_logger_event_unregister() is used to unregister the message and
+ * message handler.
+ *
+ * Return: 0 if successfully unregister, otherwise proper error code
+ */
+int nl_srv_unregister(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler)
+{
+ int ret = -EINVAL;
+
+ if (nl_srv_is_initialized() != 0)
+ return ret;
+
+ if ((msg_type >= WLAN_NL_MSG_BASE) && (msg_type < WLAN_NL_MSG_MAX) &&
+ msg_handler != NULL) {
+ ret = cnss_logger_event_unregister(radio_idx, msg_type,
+ msg_handler);
+ } else {
+ QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
+ "NLINK: nl_srv_unregister failed for msg_type %d",
+ msg_type);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+/**
+ * nl_srv_register() - wrapper function to register event to cnss_logger
+ * @msg_type: the message to register
+ * @msg_handler: the message handler
+ *
+ * The cnss_logger_event_register() is used to register the message and
+ * message handler.
+ *
+ * Return: 0 if successfully register, otherwise proper error code
+ */
+int nl_srv_register(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler)
+{
+ int ret = -EINVAL;
+
+ if (nl_srv_is_initialized() != 0)
+ return ret;
+
+ if ((msg_type >= WLAN_NL_MSG_BASE) && (msg_type < WLAN_NL_MSG_MAX) &&
+ msg_handler != NULL) {
+ ret = cnss_logger_event_register(radio_idx, msg_type,
+ msg_handler);
+ } else {
+ QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
+ "NLINK: nl_srv_register failed for msg_type %d",
+ msg_type);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+/**
+ * nl_srv_is_initialized() - check if netlink service is initialized
+ *
+ * Return: 0 if it is initialized, otherwise error code
+ */
+inline int nl_srv_is_initialized(void)
+{
+ if (logger_initialized)
+ return 0;
+ else
+ return -EPERM;
+}
+
+#else
+
+
/* Global variables */
static DEFINE_MUTEX(nl_srv_sem);
static struct sock *nl_srv_sock;
@@ -57,7 +261,7 @@ static void nl_srv_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh);
* Initialize the netlink service.
* Netlink service is usable after this.
*/
-int nl_srv_init(void)
+int nl_srv_init(void *wiphy)
{
int retcode = 0;
struct netlink_kernel_cfg cfg = {
@@ -286,3 +490,5 @@ int nl_srv_is_initialized(void)
return -EPERM;
}
+
+#endif
diff --git a/core/utils/ptt/inc/wlan_ptt_sock_svc.h b/core/utils/ptt/inc/wlan_ptt_sock_svc.h
index 08c149053446..44587480e7ac 100644
--- a/core/utils/ptt/inc/wlan_ptt_sock_svc.h
+++ b/core/utils/ptt/inc/wlan_ptt_sock_svc.h
@@ -115,11 +115,6 @@ static inline int ptt_sock_send_msg_to_app(tAniHdr *wmsg, int radio,
* WLAN Driver, in either direction. Each msg will begin with this header and
* will followed by the Quarky message
*/
-typedef struct sAniNlMsg {
- struct nlmsghdr nlh; /* Netlink Header */
- int radio; /* unit number of the radio */
- tAniHdr wmsg; /* Airgo Message Header */
-} tAniNlHdr;
typedef struct sAniAppRegReq {
tAniNlModTypes type; /* module id */
int pid; /* process id */