|
@@ -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
|