diff options
| author | Ryan Hsu <ryanhsu@qca.qualcomm.com> | 2016-03-24 16:43:30 -0700 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-04-22 10:23:11 +0530 |
| commit | 6e6deb97a9a0bd2a39c5fd1bf97fef72206ce4e7 (patch) | |
| tree | 94b78c0eed7f677595906091e9b889deac75c969 /CORE/SVC/src | |
| parent | 36cd27ee15883dca8886f1b5d2fe318be973ed45 (diff) | |
qcacld-2.0: Add support for cnss logger module
CONFIG_CNSS_LOGGER is introduced to move the logging feature from
CLD driver to kernel module.
This change will mainly benefit for two things for CLD driver.
- To support for dual wifi driver instances and also
future plan of moving out the logging thread and buffer
management to the kernel module.
- While debugging the critical feature that triggers the
autoshutdown and SSR, the log buffer in the CLD driver will
be lost after the driver restart or unload.
The CLD driver will register itself to the cnss logging module and
get the radio index as the indentification for rest of the operation.
Also the message sent from CLD driver to usespace need to be packed with
struct tAniNlHdr; and the hddctx.radio_index need to be filled along with
the message, so that usespace can differentiate the message.
Change-Id: I7ea6cdefac0916b9d4dd76da175607bf7169a8fa
CRs-fixed: 995073
Diffstat (limited to 'CORE/SVC/src')
| -rw-r--r-- | CORE/SVC/src/logging/wlan_logging_sock_svc.c | 24 | ||||
| -rw-r--r-- | CORE/SVC/src/nlink/wlan_nlink_srv.c | 215 |
2 files changed, 221 insertions, 18 deletions
diff --git a/CORE/SVC/src/logging/wlan_logging_sock_svc.c b/CORE/SVC/src/logging/wlan_logging_sock_svc.c index 2d91826ff799..08ef067eef73 100644 --- a/CORE/SVC/src/logging/wlan_logging_sock_svc.c +++ b/CORE/SVC/src/logging/wlan_logging_sock_svc.c @@ -347,9 +347,12 @@ int wlan_log_to_user(VOS_TRACE_LEVEL log_level, char *to_be_sent, int length) struct timeval tv; struct rtc_time tm; unsigned long local_time; + int radio; + + radio = vos_get_radio_index(); - if ((!vos_is_multicast_logging()) || - (!gwlan_logging.is_active)) { + if ((!vos_is_multicast_logging()) || (!gwlan_logging.is_active) || + (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 @@ -358,18 +361,25 @@ int wlan_log_to_user(VOS_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); } else { - /* Format the Log time [hr:min:sec.microsec] */ + /* Format the Log time R#: [hr:min:sec.microsec] */ do_gettimeofday(&tv); /* Convert rtc to local time */ local_time = (u32)(tv.tv_sec - (sys_tz.tz_minuteswest * 60)); rtc_time_to_tm(local_time, &tm); tlen = snprintf(tbuf, sizeof(tbuf), - "[%s][%02d:%02d:%02d.%06lu] ", - current->comm, tm.tm_hour, tm.tm_min, tm.tm_sec, - tv.tv_usec); + "R%d: [%s][%02d:%02d:%02d.%06lu] ", + radio, current->comm, tm.tm_hour, + tm.tm_min, tm.tm_sec, tv.tv_usec); /* 1+1 indicate '\n'+'\0' */ total_log_len = length + tlen + 1 + 1; diff --git a/CORE/SVC/src/nlink/wlan_nlink_srv.c b/CORE/SVC/src/nlink/wlan_nlink_srv.c index 275e70715d1b..61d5e096e1c5 100644 --- a/CORE/SVC/src/nlink/wlan_nlink_srv.c +++ b/CORE/SVC/src/nlink/wlan_nlink_srv.c @@ -32,15 +32,6 @@ * ******************************************************************************/ -/* - * If MULTI_IF_NAME is not defined, then this is the primary instance of the - * driver and the diagnostics netlink socket will be available. If - * MULTI_IF_NAME is defined then this is not the primary instance of the driver - * and the diagnotics netlink socket will not be available since this - * diagnostics netlink socket can only be exposed by one instance of the driver. - */ -#ifndef MULTI_IF_NAME - #include <linux/version.h> #include <linux/kernel.h> #include <linux/module.h> @@ -52,6 +43,208 @@ #include <wlan_nlink_srv.h> #include <vos_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); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_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 { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_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 { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_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; +} + +#elif !defined(MULTI_IF_NAME) /* Global variables */ static DEFINE_MUTEX(nl_srv_sem); static struct sock *nl_srv_sock; @@ -66,7 +259,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; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) @@ -217,7 +410,7 @@ int nl_srv_bcast(struct sk_buff *skb) * all the netlink messages in that skb, before moving * to the next skb. */ -static void nl_srv_rcv (struct sk_buff *sk) +static void nl_srv_rcv(struct sk_buff *sk) { mutex_lock(&nl_srv_sem); nl_srv_rcv_skb(sk); |
