diff options
Diffstat (limited to 'core/utils')
| -rw-r--r-- | core/utils/fwlog/dbglog_host.c | 51 | ||||
| -rw-r--r-- | core/utils/logging/src/wlan_logging_sock_svc.c | 36 | ||||
| -rw-r--r-- | core/utils/nlink/inc/wlan_nlink_common.h | 6 | ||||
| -rw-r--r-- | core/utils/nlink/inc/wlan_nlink_srv.h | 4 | ||||
| -rw-r--r-- | core/utils/nlink/src/wlan_nlink_srv.c | 208 | ||||
| -rw-r--r-- | core/utils/ptt/inc/wlan_ptt_sock_svc.h | 5 |
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 */ |
