diff options
author | Edayilliam Jayadev <ejayadev@codeaurora.org> | 2019-06-18 19:20:11 +0530 |
---|---|---|
committer | nshrivas <nshrivas@codeaurora.org> | 2019-09-21 15:51:31 -0700 |
commit | f7da616e59478c9158527ff20ebc7ad8011f4b4d (patch) | |
tree | 5890060a31133e4dffb16528c8e3a79bd2408278 | |
parent | 987c25d3342d83e8d51b6e106decc2c19c4526d7 (diff) | |
download | qca-wfi-host-cmn-f7da616e59478c9158527ff20ebc7ad8011f4b4d.tar.gz |
qcacmn: Make RX path changes for Agile Spectral
Change Spectral report processing logic to handle
Agile Spectral reports. 160 MHz state machine is not
affected by Agile Spectral reports.
CRs-Fixed: 2458359
Change-Id: Iead6427f57edddd61f7d64a961cc6d936d54ab9e
-rw-r--r-- | os_if/linux/spectral/inc/os_if_spectral_netlink.h | 8 | ||||
-rw-r--r-- | os_if/linux/spectral/src/os_if_spectral_netlink.c | 229 | ||||
-rw-r--r-- | spectral/core/spectral_defs_i.h | 2 | ||||
-rw-r--r-- | spectral/dispatcher/inc/wlan_spectral_public_structs.h | 44 | ||||
-rw-r--r-- | target_if/spectral/target_if_spectral.c | 12 | ||||
-rw-r--r-- | target_if/spectral/target_if_spectral.h | 141 | ||||
-rw-r--r-- | target_if/spectral/target_if_spectral_netlink.c | 37 | ||||
-rw-r--r-- | target_if/spectral/target_if_spectral_phyerr.c | 185 |
8 files changed, 367 insertions, 291 deletions
diff --git a/os_if/linux/spectral/inc/os_if_spectral_netlink.h b/os_if/linux/spectral/inc/os_if_spectral_netlink.h index b94815c74..156eaac00 100644 --- a/os_if/linux/spectral/inc/os_if_spectral_netlink.h +++ b/os_if/linux/spectral/inc/os_if_spectral_netlink.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2017-2019 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -56,12 +56,16 @@ void os_if_spectral_netlink_init(struct wlan_objmgr_pdev *pdev); /** * os_if_spectral_prep_skb() - Prepare socket buffer * @pdev : Pointer to pdev + * @smsg_type: Spectral scan message type + * @buf_type: Spectral report buffer type * * Prepare socket buffer to send the data to application layer * * Return: NLMSG_DATA of the created skb or NULL if no memory */ -void *os_if_spectral_prep_skb(struct wlan_objmgr_pdev *pdev); +void *os_if_spectral_prep_skb(struct wlan_objmgr_pdev *pdev, + enum spectral_msg_type smsg_type, + enum spectral_msg_buf_type buf_type); /** * os_if_spectral_netlink_deinit() - De-initialize Spectral Netlink data diff --git a/os_if/linux/spectral/src/os_if_spectral_netlink.c b/os_if/linux/spectral/src/os_if_spectral_netlink.c index d345ec799..9ec2d155f 100644 --- a/os_if/linux/spectral/src/os_if_spectral_netlink.c +++ b/os_if/linux/spectral/src/os_if_spectral_netlink.c @@ -26,6 +26,7 @@ #ifdef CNSS_GENL #include <net/cnss_nl.h> #endif +#include <wlan_cfg80211.h> /** * os_if_spectral_remove_nbuf_debug_entry() - Remove nbuf from nbuf debug table @@ -161,14 +162,14 @@ os_if_spectral_init_nl(struct wlan_objmgr_pdev *pdev) memset(&cfg, 0, sizeof(cfg)); if (!pdev) { - spectral_err("PDEV is NULL!"); + cfg80211_err("PDEV is NULL!"); return -EINVAL; } ps = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_SPECTRAL); if (!ps) { - spectral_err("PDEV SPECTRAL object is NULL!"); + cfg80211_err("PDEV SPECTRAL object is NULL!"); return -EINVAL; } os_if_spectral_init_nl_cfg(&cfg); @@ -177,14 +178,14 @@ os_if_spectral_init_nl(struct wlan_objmgr_pdev *pdev) os_if_spectral_create_nl_sock(&cfg); if (!os_if_spectral_nl_sock) { - spectral_err("NETLINK_KERNEL_CREATE FAILED"); + cfg80211_err("NETLINK_KERNEL_CREATE FAILED"); return -ENODEV; } } ps->spectral_sock = os_if_spectral_nl_sock; if (!ps->spectral_sock) { - spectral_err("ps->spectral_sock is NULL"); + cfg80211_err("ps->spectral_sock is NULL"); return -ENODEV; } atomic_inc(&spectral_nl_users); @@ -205,14 +206,14 @@ os_if_spectral_destroy_netlink(struct wlan_objmgr_pdev *pdev) struct pdev_spectral *ps = NULL; if (!pdev) { - spectral_err("PDEV is NULL!"); + cfg80211_err("PDEV is NULL!"); return -EINVAL; } ps = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_SPECTRAL); if (!ps) { - spectral_err("PDEV SPECTRAL object is NULL!"); + cfg80211_err("PDEV SPECTRAL object is NULL!"); return -EINVAL; } ps->spectral_sock = NULL; @@ -238,48 +239,79 @@ os_if_spectral_destroy_netlink(struct wlan_objmgr_pdev *pdev) #endif void * -os_if_spectral_prep_skb(struct wlan_objmgr_pdev *pdev) +os_if_spectral_prep_skb(struct wlan_objmgr_pdev *pdev, + enum spectral_msg_type smsg_type, + enum spectral_msg_buf_type buf_type) { struct pdev_spectral *ps = NULL; struct nlmsghdr *spectral_nlh = NULL; + void *buf = NULL; if (!pdev) { - spectral_err("PDEV is NULL!"); + cfg80211_err("PDEV is NULL!"); return NULL; } - ps = wlan_objmgr_pdev_get_comp_private_obj(pdev, - WLAN_UMAC_COMP_SPECTRAL); - if (!ps) { - spectral_err("PDEV SPECTRAL object is NULL!"); + if (smsg_type >= SPECTRAL_MSG_TYPE_MAX) { + cfg80211_err("Invalid Spectral message type %u", smsg_type); return NULL; } - ps->skb = qdf_nbuf_alloc(NULL, MAX_SPECTRAL_PAYLOAD, 0, 0, false); - if (!ps->skb) { - spectral_err("allocate skb (len=%u) failed", - MAX_SPECTRAL_PAYLOAD); + if (buf_type >= SPECTRAL_MSG_BUF_TYPE_MAX) { + cfg80211_err("Invalid Spectral message buffer type %u", + buf_type); return NULL; } - qdf_nbuf_put_tail(ps->skb, MAX_SPECTRAL_PAYLOAD); - spectral_nlh = (struct nlmsghdr *)ps->skb->data; + ps = wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_SPECTRAL); - qdf_mem_zero(spectral_nlh, sizeof(*spectral_nlh)); + if (!ps) { + cfg80211_err("PDEV SPECTRAL object is NULL!"); + return NULL; + } - /* - * Possible bug that size of struct spectral_samp_msg and - * SPECTRAL_MSG differ by 3 bytes so we miss 3 bytes - */ + if (buf_type == SPECTRAL_MSG_BUF_NEW) { + QDF_ASSERT(!ps->skb[smsg_type]); + ps->skb[smsg_type] = + qdf_nbuf_alloc(NULL, MAX_SPECTRAL_PAYLOAD, + 0, 0, false); - spectral_nlh->nlmsg_len = NLMSG_SPACE(sizeof(struct spectral_samp_msg)); - spectral_nlh->nlmsg_pid = 0; - spectral_nlh->nlmsg_flags = 0; - spectral_nlh->nlmsg_type = WLAN_NL_MSG_SPECTRAL_SCAN; + if (!ps->skb[smsg_type]) { + cfg80211_err("alloc skb (len=%u, msg_type=%u) failed", + MAX_SPECTRAL_PAYLOAD, smsg_type); + return NULL; + } + + qdf_nbuf_put_tail(ps->skb[smsg_type], MAX_SPECTRAL_PAYLOAD); + spectral_nlh = (struct nlmsghdr *)ps->skb[smsg_type]->data; + + qdf_mem_zero(spectral_nlh, sizeof(*spectral_nlh)); + + /* + * Possible bug that size of struct spectral_samp_msg and + * SPECTRAL_MSG differ by 3 bytes so we miss 3 bytes + */ + + spectral_nlh->nlmsg_len = + NLMSG_SPACE(sizeof(struct spectral_samp_msg)); + spectral_nlh->nlmsg_pid = 0; + spectral_nlh->nlmsg_flags = 0; + spectral_nlh->nlmsg_type = WLAN_NL_MSG_SPECTRAL_SCAN; + + qdf_mem_zero(NLMSG_DATA(spectral_nlh), + sizeof(struct spectral_samp_msg)); + buf = NLMSG_DATA(spectral_nlh); + } else if (buf_type == SPECTRAL_MSG_BUF_SAVED) { + QDF_ASSERT(ps->skb[smsg_type]); + spectral_nlh = (struct nlmsghdr *)ps->skb[smsg_type]->data; + buf = NLMSG_DATA(spectral_nlh); + } else { + cfg80211_err("Failed to get spectral report buffer"); + buf = NULL; + } - qdf_mem_zero(NLMSG_DATA(spectral_nlh), - sizeof(struct spectral_samp_msg)); - return NLMSG_DATA(spectral_nlh); + return buf; } #if (KERNEL_VERSION(2, 6, 31) > LINUX_VERSION_CODE) @@ -319,91 +351,108 @@ os_if_init_spectral_skb_pid_portid(struct sk_buff *skb) * os_if_spectral_nl_unicast_msg() - Sends unicast Spectral message to user * space * @pdev : Pointer to pdev + * @smsg_type: Spectral message type * * Return: void */ #ifndef CNSS_GENL static int -os_if_spectral_nl_unicast_msg(struct wlan_objmgr_pdev *pdev) +os_if_spectral_nl_unicast_msg(struct wlan_objmgr_pdev *pdev, + enum spectral_msg_type smsg_type) { struct pdev_spectral *ps = NULL; int status; if (!pdev) { - spectral_err("PDEV is NULL!"); + cfg80211_err("PDEV is NULL!"); + return -EINVAL; + } + + if (smsg_type >= SPECTRAL_MSG_TYPE_MAX) { + cfg80211_err("Invalid Spectral message type %u", smsg_type); return -EINVAL; } ps = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_SPECTRAL); if (!ps) { - spectral_err("PDEV SPECTRAL object is NULL!"); + cfg80211_err("PDEV SPECTRAL object is NULL!"); return -EINVAL; } - if (!ps->skb) { - spectral_err("Socket buffer is null"); + if (!ps->skb[smsg_type]) { + cfg80211_err("Socket buffer is null, msg_type= %u", smsg_type); return -EINVAL; } if (!ps->spectral_sock) { - spectral_err("Spectral Socket is invalid"); - qdf_nbuf_free(ps->skb); + cfg80211_err("Spectral Socket is invalid, msg_type= %u", + smsg_type); + qdf_nbuf_free(ps->skb[smsg_type]); + ps->skb[smsg_type] = NULL; + return -EINVAL; } - os_if_init_spectral_skb_dst_pid(ps->skb, ps); + os_if_init_spectral_skb_dst_pid(ps->skb[smsg_type], ps); - os_if_init_spectral_skb_pid_portid(ps->skb); + os_if_init_spectral_skb_pid_portid(ps->skb[smsg_type]); /* to mcast group 1<<0 */ - NETLINK_CB(ps->skb).dst_group = 0; + NETLINK_CB(ps->skb[smsg_type]).dst_group = 0; - os_if_spectral_remove_nbuf_debug_entry(ps->skb); + os_if_spectral_remove_nbuf_debug_entry(ps->skb[smsg_type]); status = netlink_unicast(ps->spectral_sock, - ps->skb, + ps->skb[smsg_type], ps->spectral_pid, MSG_DONTWAIT); - /* clear the local copy */ - ps->skb = NULL; + /* clear the local copy, free would be done by netlink layer */ + ps->skb[smsg_type] = NULL; return status; } #else static int -os_if_spectral_nl_unicast_msg(struct wlan_objmgr_pdev *pdev) +os_if_spectral_nl_unicast_msg(struct wlan_objmgr_pdev *pdev, + enum spectral_msg_type smsg_type) { struct pdev_spectral *ps = NULL; int status; if (!pdev) { - spectral_err("PDEV is NULL!"); + cfg80211_err("PDEV is NULL!"); + return -EINVAL; + } + + if (smsg_type >= SPECTRAL_MSG_TYPE_MAX) { + cfg80211_err("Invalid Spectral message type %u", smsg_type); return -EINVAL; } ps = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_SPECTRAL); if (!ps) { - spectral_err("PDEV SPECTRAL object is NULL!"); + cfg80211_err("PDEV SPECTRAL object is NULL!"); return -EINVAL; } - if (!ps->skb) { - spectral_err("Socket buffer is null"); + if (!ps->skb[smsg_type]) { + cfg80211_err("Socket buffer is null, msg_type= %u", smsg_type); return -EINVAL; } - os_if_init_spectral_skb_pid_portid(ps->skb); + os_if_init_spectral_skb_pid_portid(ps->skb[smsg_type]); - os_if_spectral_remove_nbuf_debug_entry(ps->skb); - status = nl_srv_ucast(ps->skb, ps->spectral_pid, MSG_DONTWAIT, - WLAN_NL_MSG_SPECTRAL_SCAN, CLD80211_MCGRP_OEM_MSGS); + os_if_spectral_remove_nbuf_debug_entry(ps->skb[smsg_type]); + status = nl_srv_ucast(ps->skb[smsg_type], ps->spectral_pid, + MSG_DONTWAIT, WLAN_NL_MSG_SPECTRAL_SCAN, + CLD80211_MCGRP_OEM_MSGS); if (status < 0) - spectral_err("failed to send to spectral scan app"); + cfg80211_err("failed to send to spectral scan app"); - /* clear the local copy */ - ps->skb = NULL; + /* clear the local copy, free would be done by netlink layer */ + ps->skb[smsg_type] = NULL; return status; } @@ -414,11 +463,13 @@ os_if_spectral_nl_unicast_msg(struct wlan_objmgr_pdev *pdev) * os_if_spectral_nl_bcast_msg() - Sends broadcast Spectral message to user * space * @pdev : Pointer to pdev + * @smsg_type: Spectral message type * * Return: void */ static int -os_if_spectral_nl_bcast_msg(struct wlan_objmgr_pdev *pdev) +os_if_spectral_nl_bcast_msg(struct wlan_objmgr_pdev *pdev, + enum spectral_msg_type smsg_type) { #if (KERNEL_VERSION(2, 6, 31) >= LINUX_VERSION_CODE) fd_set write_set; @@ -431,34 +482,42 @@ os_if_spectral_nl_bcast_msg(struct wlan_objmgr_pdev *pdev) #endif if (!pdev) { - spectral_err("PDEV is NULL!"); + cfg80211_err("PDEV is NULL!"); + return -EINVAL; + } + + if (smsg_type >= SPECTRAL_MSG_TYPE_MAX) { + cfg80211_err("Invalid Spectral message type %u", smsg_type); return -EINVAL; } + ps = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_SPECTRAL); if (!ps) { - spectral_err("PDEV SPECTRAL object is NULL!"); + cfg80211_err("PDEV SPECTRAL object is NULL!"); return -EINVAL; } - if (!ps->skb) { - spectral_err("Socket buffer is null"); + if (!ps->skb[smsg_type]) { + cfg80211_err("Socket buffer is null, msg_type= %u", smsg_type); return -EINVAL; } if (!ps->spectral_sock) { - qdf_nbuf_free(ps->skb); + qdf_nbuf_free(ps->skb[smsg_type]); + ps->skb[smsg_type] = NULL; + return -EINVAL; } - os_if_spectral_remove_nbuf_debug_entry(ps->skb); + os_if_spectral_remove_nbuf_debug_entry(ps->skb[smsg_type]); status = netlink_broadcast(ps->spectral_sock, - ps->skb, + ps->skb[smsg_type], 0, 1, GFP_ATOMIC); - /* clear the local copy */ - ps->skb = NULL; + /* clear the local copy, free would be done by netlink layer */ + ps->skb[smsg_type] = NULL; return status; } @@ -467,36 +526,44 @@ os_if_spectral_nl_bcast_msg(struct wlan_objmgr_pdev *pdev) * os_if_spectral_free_skb() - Free spectral SAMP message skb * * @pdev : Pointer to pdev + * @smsg_type: Spectral message type * * Return: void */ static void -os_if_spectral_free_skb(struct wlan_objmgr_pdev *pdev) +os_if_spectral_free_skb(struct wlan_objmgr_pdev *pdev, + enum spectral_msg_type smsg_type) { struct pdev_spectral *ps = NULL; if (!pdev) { - spectral_err("PDEV is NULL!"); + cfg80211_err("PDEV is NULL!"); return; } + + if (smsg_type >= SPECTRAL_MSG_TYPE_MAX) { + cfg80211_err("Invalid Spectral message type %u", smsg_type); + return; + } + ps = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_SPECTRAL); if (!ps) { - spectral_err("PDEV SPECTRAL object is NULL!"); + cfg80211_err("PDEV SPECTRAL object is NULL!"); return; } - if (!ps->skb) { - spectral_err("Socket buffer is null"); + if (!ps->skb[smsg_type]) { + cfg80211_info("Socket buffer is null, msg_type= %u", smsg_type); return; } /* Free buffer */ - qdf_nbuf_free(ps->skb); + qdf_nbuf_free(ps->skb[smsg_type]); /* clear the local copy */ - ps->skb = NULL; + ps->skb[smsg_type] = NULL; } qdf_export_symbol(os_if_spectral_free_skb); @@ -508,24 +575,24 @@ os_if_spectral_netlink_init(struct wlan_objmgr_pdev *pdev) struct spectral_context *sptrl_ctx; if (!pdev) { - spectral_err("PDEV is NULL!"); + cfg80211_err("PDEV is NULL!"); return; } sptrl_ctx = spectral_get_spectral_ctx_from_pdev(pdev); if (!sptrl_ctx) { - spectral_err("Spectral context is NULL!"); + cfg80211_err("Spectral context is NULL!"); return; } os_if_spectral_init_nl(pdev); /* Register Netlink handlers */ - nl_cb.get_nbuff = os_if_spectral_prep_skb; + nl_cb.get_sbuff = os_if_spectral_prep_skb; nl_cb.send_nl_bcast = os_if_spectral_nl_bcast_msg; nl_cb.send_nl_unicast = os_if_spectral_nl_unicast_msg; - nl_cb.free_nbuff = os_if_spectral_free_skb; + nl_cb.free_sbuff = os_if_spectral_free_skb; if (sptrl_ctx->sptrlc_register_netlink_cb) sptrl_ctx->sptrlc_register_netlink_cb(pdev, &nl_cb); @@ -535,20 +602,22 @@ qdf_export_symbol(os_if_spectral_netlink_init); void os_if_spectral_netlink_deinit(struct wlan_objmgr_pdev *pdev) { struct spectral_context *sptrl_ctx; + enum spectral_msg_type msg_type = SPECTRAL_MSG_NORMAL_MODE; if (!pdev) { - spectral_err("PDEV is NULL!"); + cfg80211_err("PDEV is NULL!"); return; } sptrl_ctx = spectral_get_spectral_ctx_from_pdev(pdev); if (!sptrl_ctx) { - spectral_err("Spectral context is NULL!"); + cfg80211_err("Spectral context is NULL!"); return; } - os_if_spectral_free_skb(pdev); + for (; msg_type < SPECTRAL_MSG_TYPE_MAX; msg_type++) + os_if_spectral_free_skb(pdev, msg_type); if (sptrl_ctx->sptrlc_deregister_netlink_cb) sptrl_ctx->sptrlc_deregister_netlink_cb(pdev); diff --git a/spectral/core/spectral_defs_i.h b/spectral/core/spectral_defs_i.h index a90df27f9..1ad39001e 100644 --- a/spectral/core/spectral_defs_i.h +++ b/spectral/core/spectral_defs_i.h @@ -89,7 +89,7 @@ struct pdev_spectral { struct wlan_objmgr_pdev *psptrl_pdev; struct sock *spectral_sock; void *psptrl_target_handle; - struct sk_buff *skb; + struct sk_buff *skb[SPECTRAL_MSG_TYPE_MAX]; uint32_t spectral_pid; }; diff --git a/spectral/dispatcher/inc/wlan_spectral_public_structs.h b/spectral/dispatcher/inc/wlan_spectral_public_structs.h index f12f3537c..4e23fda61 100644 --- a/spectral/dispatcher/inc/wlan_spectral_public_structs.h +++ b/spectral/dispatcher/inc/wlan_spectral_public_structs.h @@ -133,6 +133,34 @@ /* End of temporary section for hard-coded values */ /** + * enum spectral_msg_buf_type - Spectral message buffer type + * @SPECTRAL_MSG_BUF_NEW: Allocate new buffer + * @SPECTRAL_MSG_BUF_SAVED: Reuse last buffer, used for secondary segment report + * in case of 160 MHz. + */ +enum spectral_msg_buf_type { + SPECTRAL_MSG_BUF_NEW, + SPECTRAL_MSG_BUF_SAVED, + SPECTRAL_MSG_BUF_TYPE_MAX, +}; + +/** + * enum spectral_msg_type - Spectral SAMP message type + * @SPECTRAL_MSG_NORMAL_MODE: Normal mode Spectral SAMP message + * @SPECTRAL_MSG_AGILE_MODE: Agile mode Spectral SAMP message + * @SPECTRAL_MSG_INTERFERENCE_NOTIFICATION: Interference notification to + * external auto channel selection + * entity + * @SPECTRAL_MSG_TYPE_MAX: Spectral SAMP message type max + */ +enum spectral_msg_type { + SPECTRAL_MSG_NORMAL_MODE, + SPECTRAL_MSG_AGILE_MODE, + SPECTRAL_MSG_INTERFERENCE_NOTIFICATION, + SPECTRAL_MSG_TYPE_MAX, +}; + +/** * enum wlan_cfg80211_spectral_vendorcmd_handler_idx - Indices to cfg80211 * spectral vendor command handlers * @SPECTRAL_SCAN_START_HANDLER_IDX: Index to SPECTRAL_SCAN_START handler @@ -246,15 +274,21 @@ struct wlan_objmgr_pdev; /** * struct spectral_nl_cb - Spectral Netlink callbacks - * @get_nbuff: Get the socket buffer to send the data to the application + * @get_sbuff: Get the socket buffer to send the data to the application * @send_nl_bcast: Send data to the application using netlink broadcast * @send_nl_unicast: Send data to the application using netlink unicast + * @free_sbuff: Free the socket buffer for a particular message type */ struct spectral_nl_cb { - void *(*get_nbuff)(struct wlan_objmgr_pdev *pdev); - int (*send_nl_bcast)(struct wlan_objmgr_pdev *pdev); - int (*send_nl_unicast)(struct wlan_objmgr_pdev *pdev); - void (*free_nbuff)(struct wlan_objmgr_pdev *pdev); + void *(*get_sbuff)(struct wlan_objmgr_pdev *pdev, + enum spectral_msg_type smsg_type, + enum spectral_msg_buf_type buf_type); + int (*send_nl_bcast)(struct wlan_objmgr_pdev *pdev, + enum spectral_msg_type smsg_type); + int (*send_nl_unicast)(struct wlan_objmgr_pdev *pdev, + enum spectral_msg_type smsg_type); + void (*free_sbuff)(struct wlan_objmgr_pdev *pdev, + enum spectral_msg_type smsg_type); }; #ifndef __KERNEL__ diff --git a/target_if/spectral/target_if_spectral.c b/target_if/spectral/target_if_spectral.c index b9a6f7de2..94c1371c0 100644 --- a/target_if/spectral/target_if_spectral.c +++ b/target_if/spectral/target_if_spectral.c @@ -1824,8 +1824,6 @@ target_if_spectral_detach(struct target_if_spectral *spectral) spectral_info("spectral detach"); if (spectral) { - if (spectral->spectral_gen == SPECTRAL_GEN3) - deinit_160mhz_delivery_state_machine(spectral); qdf_spinlock_destroy(&spectral->param_info.osps_lock); target_if_spectral_detach_simulation(spectral); @@ -2893,8 +2891,10 @@ target_if_spectral_send_intf_found_msg(struct wlan_objmgr_pdev *pdev, struct target_if_spectral *spectral = NULL; spectral = get_target_if_spectral_handle_from_pdev(pdev); - msg = (struct spectral_samp_msg *)spectral->nl_cb.get_nbuff( - spectral->pdev_obj); + msg = (struct spectral_samp_msg *)spectral->nl_cb.get_sbuff( + spectral->pdev_obj, + SPECTRAL_MSG_INTERFERENCE_NOTIFICATION, + SPECTRAL_MSG_BUF_NEW); if (msg) { msg->int_type = cw_int ? @@ -2903,7 +2903,9 @@ target_if_spectral_send_intf_found_msg(struct wlan_objmgr_pdev *pdev, msg->signature = SPECTRAL_SIGNATURE; p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); p_sops->get_mac_address(spectral, msg->macaddr); - if (spectral->send_phy_data(pdev) == 0) + if (spectral->send_phy_data + (pdev, + SPECTRAL_MSG_INTERFERENCE_NOTIFICATION) == 0) spectral->spectral_sent_msg++; } } diff --git a/target_if/spectral/target_if_spectral.h b/target_if/spectral/target_if_spectral.h index 39470d984..19d078ca3 100644 --- a/target_if/spectral/target_if_spectral.h +++ b/target_if/spectral/target_if_spectral.h @@ -145,18 +145,6 @@ enum spectral_detector_id { }; /** - * enum spectral_160mhz_report_delivery_event - 160 MHz state machine event - * @SPECTRAL_REPORT_EVENT_DETECTORID0: Received detector id 0 - * @SPECTRAL_REPORT_EVENT_DETECTORID1: Received detector id 1 - * @SPECTRAL_REPORT_EVENT_DETECTORID_INVALID: Received invalid detector id - */ -enum spectral_160mhz_report_delivery_event { - SPECTRAL_REPORT_EVENT_DETECTORID0, - SPECTRAL_REPORT_EVENT_DETECTORID1, - SPECTRAL_REPORT_EVENT_DETECTORID_INVALID, -}; - -/** * struct spectral_search_fft_info_gen2 - spectral search fft report for gen2 * @relpwr_db: Total bin power in db * @num_str_bins_ib: Number of strong bins @@ -788,7 +776,7 @@ struct wmi_spectral_cmd_ops { * generation * @nl_cb: Netlink callbacks * @use_nl_bcast: Whether to use Netlink broadcast/unicast - * @send_phy_data: Send data to the applicaton layer + * @send_phy_data: Send data to the application layer for a particular msg type * @inband_fftbin_size_adj: Whether to carry out FFT bin size adjustment for * in-band report format. This would be required on some chipsets under the * following circumstances: In report mode 2 only the in-band bins are DMA'ed. @@ -908,7 +896,8 @@ struct target_if_spectral { struct wmi_spectral_cmd_ops param_wmi_cmd_ops; struct spectral_nl_cb nl_cb; bool use_nl_bcast; - int (*send_phy_data)(struct wlan_objmgr_pdev *pdev); + int (*send_phy_data)(struct wlan_objmgr_pdev *pdev, + enum spectral_msg_type smsg_type); enum spectral_fftbin_size_war fftbin_size_war; u_int8_t inband_fftbin_size_adj; u_int8_t null_fftbin_adj; @@ -997,6 +986,7 @@ struct target_if_samp_msg_params { uint8_t agc_total_gain_sec80; uint8_t gainchange; uint8_t gainchange_sec80; + enum spectral_scan_mode smode; }; #ifdef WLAN_CONV_SPECTRAL_ENABLE @@ -1375,65 +1365,25 @@ void target_if_spectral_process_phyerr( tsf64, acs_stats); } -/** - * save_spectral_report_skb() - Save Spectral report skb - * @spectral: Pointer to Spectral - * @skb: Pointer to skb - * - * Save spectral report skb - * - * Return: void - */ -static inline void -save_spectral_report_skb(struct target_if_spectral *spectral, void *skb) { - if (spectral->ch_width == CH_WIDTH_160MHZ) - spectral->spectral_report_cache = skb; -} +static QDF_STATUS +target_if_get_spectral_msg_type(enum spectral_scan_mode smode, + enum spectral_msg_type *msg_type) { -/** - * restore_spectral_report_skb() - Restore Spectral report skb - * @spectral: Pointer to Spectral - * @skb: Pointer to restore location - * - * Restore spectral report skb - * - * Return: void - */ -static inline void -restore_spectral_report_skb(struct target_if_spectral *spectral, void **dest) { - if (spectral->ch_width == CH_WIDTH_160MHZ) { - QDF_ASSERT(spectral->spectral_report_cache); - *dest = spectral->spectral_report_cache; - } -} + switch (smode) { + case SPECTRAL_SCAN_MODE_NORMAL: + *msg_type = SPECTRAL_MSG_NORMAL_MODE; + break; -/** - * clear_spectral_report_skb() - Clear Spectral report skb - * @spectral: Pointer to Spectral - * - * Clear spectral report skb - * - * Return: void - */ -static inline void -clear_spectral_report_skb(struct target_if_spectral *spectral) { - if (spectral->ch_width == CH_WIDTH_160MHZ) - spectral->spectral_report_cache = NULL; -} + case SPECTRAL_SCAN_MODE_AGILE: + *msg_type = SPECTRAL_MSG_AGILE_MODE; + break; -/** - * free_and_clear_spectral_report_skb() - Free and clear Spectral report skb - * @spectral: Pointer to Spectral - * - * Free and clear spectral report skb - * - * Return: void - */ -static inline void -free_and_clear_spectral_report_skb(struct target_if_spectral *spectral) { - if (spectral->spectral_report_cache) - spectral->nl_cb.free_nbuff(spectral->pdev_obj); - spectral->spectral_report_cache = NULL; + default: + spectral_err("Invalid spectral mode"); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; } /** @@ -1446,27 +1396,10 @@ free_and_clear_spectral_report_skb(struct target_if_spectral *spectral) { * Return: void */ static inline void -init_160mhz_delivery_state_machine(struct target_if_spectral *spectral) { +init_160mhz_delivery_state_machine(struct target_if_spectral *spectral) +{ spectral->state_160mhz_delivery = SPECTRAL_REPORT_WAIT_PRIMARY80; - spectral->spectral_report_cache = NULL; -} - -/** - * deinit_160mhz_delivery_state_machine() - Deinitialize 160MHz Spectral - * state machine - * @spectral: Pointer to Spectral - * - * Deinitialize 160MHz Spectral state machine - * - * Return: void - */ -static inline void -deinit_160mhz_delivery_state_machine(struct target_if_spectral *spectral) { - if (spectral->spectral_report_cache && spectral->nl_cb.free_nbuff) { - spectral->nl_cb.free_nbuff(spectral->pdev_obj); - spectral->spectral_report_cache = NULL; - } } /** @@ -1478,11 +1411,24 @@ deinit_160mhz_delivery_state_machine(struct target_if_spectral *spectral) { * Return: void */ static inline void -reset_160mhz_delivery_state_machine(struct target_if_spectral *spectral) { +reset_160mhz_delivery_state_machine(struct target_if_spectral *spectral, + enum spectral_scan_mode smode) +{ + enum spectral_msg_type smsg_type; + QDF_STATUS ret; + if (spectral->ch_width == CH_WIDTH_160MHZ) { spectral->state_160mhz_delivery = SPECTRAL_REPORT_WAIT_PRIMARY80; - free_and_clear_spectral_report_skb(spectral); + + ret = target_if_get_spectral_msg_type(smode, &smsg_type); + if (QDF_IS_STATUS_ERROR(ret)) { + spectral_err("Failed to reset 160 MHz state machine"); + return; + } + + spectral->nl_cb.free_sbuff(spectral->pdev_obj, + smsg_type); } } @@ -1872,19 +1818,6 @@ void target_if_get_spectral_capinfo( void target_if_get_spectral_diagstats(struct wlan_objmgr_pdev *pdev, void *outdata); -/* - * target_if_spectral_send_tlv_to_host - target_if_spectral_send_tlv_to_host - * @spectral: Send the TLV information to Host - * @data: Pointer to the TLV - * @datalen: tlv length - * - * Return: Success/Failure - * - */ -int target_if_spectral_send_tlv_to_host( - struct target_if_spectral *spectral, - uint8_t *data, uint32_t datalen); - void target_if_register_wmi_spectral_cmd_ops( struct wlan_objmgr_pdev *pdev, struct wmi_spectral_cmd_ops *cmd_ops); diff --git a/target_if/spectral/target_if_spectral_netlink.c b/target_if/spectral/target_if_spectral_netlink.c index 85f2e2e78..a57746ac7 100644 --- a/target_if/spectral/target_if_spectral_netlink.c +++ b/target_if/spectral/target_if_spectral_netlink.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011,2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011,2017-2019 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -49,23 +49,31 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral, static int samp_msg_index; size_t pwr_count = 0; size_t pwr_count_sec80 = 0; + enum spectral_msg_type msg_type; + QDF_STATUS ret; - if (is_primaryseg_rx_inprog(spectral)) { + ret = target_if_get_spectral_msg_type(params->smode, &msg_type); + if (QDF_IS_STATUS_ERROR(ret)) + return; + + if ((params->smode == SPECTRAL_SCAN_MODE_AGILE) || + is_primaryseg_rx_inprog(spectral)) { spec_samp_msg = (struct spectral_samp_msg *) - spectral->nl_cb.get_nbuff(spectral->pdev_obj); + spectral->nl_cb.get_sbuff(spectral->pdev_obj, + msg_type, + SPECTRAL_MSG_BUF_NEW); if (!spec_samp_msg) return; samp_data = &spec_samp_msg->samp_data; - if (spectral->spectral_gen == SPECTRAL_GEN3) - save_spectral_report_skb(spectral, spec_samp_msg); p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); bin_pwr_data = params->bin_pwr_data; spec_samp_msg->signature = SPECTRAL_SIGNATURE; spec_samp_msg->freq = params->freq; spec_samp_msg->freq_loading = params->freq_loading; + samp_data->spectral_mode = params->smode; samp_data->spectral_data_len = params->datalen; samp_data->spectral_rssi = params->rssi; samp_data->ch_width = spectral->ch_width; @@ -150,9 +158,11 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral, } if (is_secondaryseg_rx_inprog(spectral)) { - if (spectral->spectral_gen == SPECTRAL_GEN3) - restore_spectral_report_skb(spectral, - (void **)&spec_samp_msg); + spec_samp_msg = (struct spectral_samp_msg *) + spectral->nl_cb.get_sbuff(spectral->pdev_obj, + msg_type, + SPECTRAL_MSG_BUF_SAVED); + if (!spec_samp_msg) { spectral_err("Spectral SAMP message is NULL"); return; @@ -214,17 +224,18 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral, } if ((spectral->ch_width != CH_WIDTH_160MHZ) || + (params->smode == SPECTRAL_SCAN_MODE_AGILE) || is_secondaryseg_rx_inprog(spectral)) { - if (spectral->send_phy_data(spectral->pdev_obj) == 0) + if (spectral->send_phy_data(spectral->pdev_obj, + msg_type) == 0) spectral->spectral_sent_msg++; samp_msg_index++; - if (spectral->spectral_gen == SPECTRAL_GEN3) - clear_spectral_report_skb(spectral); } /* Take care of state transitions for 160MHz/ 80p80 */ - if (spectral->spectral_gen == SPECTRAL_GEN3) + if ((spectral->spectral_gen == SPECTRAL_GEN3) && + (params->smode != SPECTRAL_SCAN_MODE_AGILE)) target_if_160mhz_delivery_state_change( spectral, - SPECTRAL_REPORT_EVENT_DETECTORID_INVALID); + SPECTRAL_DETECTOR_INVALID); } diff --git a/target_if/spectral/target_if_spectral_phyerr.c b/target_if/spectral/target_if_spectral_phyerr.c index 6d4dd7539..819cf5115 100644 --- a/target_if/spectral/target_if_spectral_phyerr.c +++ b/target_if/spectral/target_if_spectral_phyerr.c @@ -100,33 +100,6 @@ target_if_spectral_dump_fft(uint8_t *pfft, int fftlen) return 0; } -/** - * target_if_spectral_send_tlv_to_host() - Send the TLV information to Host - * @spectral: Pointer to target_if spectral object - * @data: Pointer to the TLV - * @datalen: data length - * - * Send the TLV information to Host - * - * Return: Success or failure - */ -int -target_if_spectral_send_tlv_to_host(struct target_if_spectral *spectral, - uint8_t *data, uint32_t datalen) -{ - int status = true; - void *nl_data = spectral->nl_cb.get_nbuff(spectral->pdev_obj); - - if (nl_data) { - memcpy(nl_data, data, datalen); - if (spectral->send_phy_data(spectral->pdev_obj) == 0) - spectral->spectral_sent_msg++; - } else { - status = false; - } - return status; -} - void target_if_dbg_print_samp_param(struct target_if_samp_msg_params *p) { @@ -806,6 +779,8 @@ target_if_process_phyerr_gen2(struct target_if_spectral *spectral, } OS_MEMZERO(¶ms, sizeof(params)); + /* Gen 2 only supports normal Spectral scan currently */ + params.smode = SPECTRAL_SCAN_MODE_NORMAL; if (ptlv->tag == TLV_TAG_SEARCH_FFT_REPORT_GEN2) { if (spectral->is_160_format) { @@ -1307,6 +1282,12 @@ target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral, if (spectral->ch_width != CH_WIDTH_160MHZ) return QDF_STATUS_E_FAILURE; + /* agile reports should not be coupled with 160 MHz state machine + * for normal Spectral + */ + if (detector_id == SPECTRAL_DETECTOR_AGILE) + return QDF_STATUS_SUCCESS; + switch (spectral->state_160mhz_delivery) { case SPECTRAL_REPORT_WAIT_PRIMARY80: if (detector_id == SPECTRAL_DETECTOR_PRIMARY) @@ -1331,8 +1312,9 @@ target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral, break; case SPECTRAL_REPORT_RX_SECONDARY80: - /* We don't care about detector id in this state */ - reset_160mhz_delivery_state_machine(spectral); + /* We don't care about detector id in this state. */ + reset_160mhz_delivery_state_machine(spectral, + SPECTRAL_SCAN_MODE_NORMAL); break; case SPECTRAL_REPORT_RX_PRIMARY80: @@ -1444,6 +1426,27 @@ target_if_spectral_get_lowest_chn_idx(uint8_t chainmask) return idx; } +static QDF_STATUS +target_if_get_spectral_mode(enum spectral_detector_id detector_id, + enum spectral_scan_mode *smode) { + switch (detector_id) { + case SPECTRAL_DETECTOR_PRIMARY: + case SPECTRAL_DETECTOR_SECONDARY: + *smode = SPECTRAL_SCAN_MODE_NORMAL; + break; + + case SPECTRAL_DETECTOR_AGILE: + *smode = SPECTRAL_SCAN_MODE_AGILE; + break; + + default: + spectral_err("Invalid Spectral detector id"); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + int target_if_consume_spectral_report_gen3( struct target_if_spectral *spectral, @@ -1490,41 +1493,45 @@ target_if_consume_spectral_report_gen3( struct wlan_objmgr_vdev *vdev; uint8_t vdev_rxchainmask; struct sscan_report_fields_gen3 sscan_report_fields; - uint8_t detector_id; + enum spectral_detector_id detector_id; QDF_STATUS ret; - if (is_primaryseg_expected(spectral)) { - /* Process Spectral scan summary report */ - if (target_if_verify_sig_and_tag_gen3( - spectral, data, - TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN3) != 0) { - spectral_err_rl("Wrong tag/sig in sscan summary(0)"); - goto fail; - } + params.smode = SPECTRAL_SCAN_MODE_NORMAL; - detector_id = target_if_get_detector_id_sscan_report_gen3(data); - /* Agile detector is not supported */ - if (detector_id >= SPECTRAL_DETECTOR_AGILE) { - spectral->diag_stats.spectral_invalid_detector_id++; - spectral_err("Invalid detector id %u, expected is 0", - detector_id); - goto fail; - } - target_if_consume_sscan_report_gen3(spectral, data, - &sscan_report_fields); + /* Process Spectral scan summary report */ + if (target_if_verify_sig_and_tag_gen3( + spectral, data, + TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN3) != 0) { + spectral_err_rl("Wrong tag/sig in sscan summary"); + goto fail; + } + + detector_id = target_if_get_detector_id_sscan_report_gen3(data); + if (detector_id > SPECTRAL_DETECTOR_AGILE) { + spectral->diag_stats.spectral_invalid_detector_id++; + spectral_err("Invalid detector id %u, expected is 0/1/2", + detector_id); + goto fail; + } + target_if_consume_sscan_report_gen3(spectral, data, + &sscan_report_fields); + /* Advance buf pointer to the search fft report */ + data += sizeof(struct spectral_sscan_report_gen3); + + if ((detector_id == SPECTRAL_DETECTOR_AGILE) || + is_primaryseg_expected(spectral)) { /* RSSI is in 1/2 dBm steps, Covert it to dBm scale */ rssi = (sscan_report_fields.inband_pwr_db) >> 1; params.agc_total_gain = sscan_report_fields.sscan_agc_total_gain; params.gainchange = sscan_report_fields.sscan_gainchange; - /* Advance buf pointer to the search fft report */ - data += sizeof(struct spectral_sscan_report_gen3); /* Process Spectral search FFT report */ if (target_if_verify_sig_and_tag_gen3( spectral, data, TLV_TAG_SEARCH_FFT_REPORT_GEN3) != 0) { - spectral_err_rl("Unexpected tag/signature in sfft(0)"); + spectral_err_rl("Unexpected tag/sig in sfft, detid= %u", + detector_id); goto fail; } p_fft_report = (struct spectral_phyerr_fft_report_gen3 *)data; @@ -1569,7 +1576,23 @@ target_if_consume_spectral_report_gen3( } target_if_process_sfft_report_gen3(p_fft_report, p_sfft); + /* It is expected to have same detector id for + * summary and fft report + */ + if (detector_id != p_sfft->fft_detector_id) { + spectral_err_rl + ("Different detid in ssummary(%u) and sfft(%u)", + detector_id, p_sfft->fft_detector_id); + goto fail; + } + detector_id = p_sfft->fft_detector_id; + ret = target_if_get_spectral_mode(detector_id, ¶ms.smode); + if (QDF_IS_STATUS_ERROR(ret)) { + spectral_err_rl("Failed to get mode from detid= %u", + detector_id); + goto fail; + } if (report->reset_delay) { spectral->timestamp_war_offset += (report->reset_delay + @@ -1579,10 +1602,9 @@ target_if_consume_spectral_report_gen3( spectral->last_fft_timestamp = p_sfft->timestamp; tsf64 += spectral->timestamp_war_offset; - /* Agile detector is not supported */ - if (detector_id >= SPECTRAL_DETECTOR_AGILE) { + if (detector_id > SPECTRAL_DETECTOR_AGILE) { spectral->diag_stats.spectral_invalid_detector_id++; - spectral_err("Invalid detector id %u, expected is 0", + spectral_err("Invalid detector id %u, expected is 0/2", detector_id); goto fail; } @@ -1605,7 +1627,9 @@ target_if_consume_spectral_report_gen3( vdev = target_if_spectral_get_vdev(spectral); if (!vdev) { spectral_info("First vdev is NULL"); - reset_160mhz_delivery_state_machine(spectral); + reset_160mhz_delivery_state_machine + (spectral, + SPECTRAL_SCAN_MODE_NORMAL); return -EPERM; } vdev_rxchainmask = wlan_vdev_mlme_get_rxchainmask(vdev); @@ -1638,37 +1662,18 @@ target_if_consume_spectral_report_gen3( params.pwr_count = fft_bin_len; params.tstamp = (tsf64 & SPECTRAL_TSMASK); } else if (is_secondaryseg_expected(spectral)) { - /* Process Spectral scan summary report */ - if (target_if_verify_sig_and_tag_gen3( - spectral, data, - TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN3) != 0) { - spectral_err_rl("Wrong tag/sig in sscan summary(1)"); - goto fail; - } - - detector_id = target_if_get_detector_id_sscan_report_gen3(data); - /* Agile detector is not supported */ - if (detector_id >= SPECTRAL_DETECTOR_AGILE) { - spectral->diag_stats.spectral_invalid_detector_id++; - spectral_err("Invalid detector id %u, expected is 1", - detector_id); - goto fail; - } - target_if_consume_sscan_report_gen3(spectral, data, - &sscan_report_fields); /* RSSI is in 1/2 dBm steps, Covert it to dBm scale */ rssi = (sscan_report_fields.inband_pwr_db) >> 1; params.agc_total_gain_sec80 = sscan_report_fields.sscan_agc_total_gain; params.gainchange_sec80 = sscan_report_fields.sscan_gainchange; - /* Advance buf pointer to the search fft report */ - data += sizeof(struct spectral_sscan_report_gen3); /* Process Spectral search FFT report */ if (target_if_verify_sig_and_tag_gen3( spectral, data, TLV_TAG_SEARCH_FFT_REPORT_GEN3) != 0) { - spectral_err_rl("Unexpected tag/signature in sfft(1)"); + spectral_err_rl("Unexpected tag/sig in sfft, detid= %u", + detector_id); goto fail; } p_fft_report = (struct spectral_phyerr_fft_report_gen3 *)data; @@ -1714,15 +1719,30 @@ target_if_consume_spectral_report_gen3( } target_if_process_sfft_report_gen3(p_fft_report, p_sfft); - detector_id = p_sfft->fft_detector_id; - /* Agile detector is not supported */ - if (detector_id >= SPECTRAL_DETECTOR_AGILE) { + if (detector_id > SPECTRAL_DETECTOR_AGILE) { spectral->diag_stats.spectral_invalid_detector_id++; spectral_err("Invalid detector id %u, expected is 1", detector_id); goto fail; } + /* It is expected to have same detector id for + * summary and fft report + */ + if (detector_id != p_sfft->fft_detector_id) { + spectral_err_rl + ("Different detid in ssummary(%u) and sfft(%u)", + detector_id, p_sfft->fft_detector_id); + goto fail; + } + detector_id = p_sfft->fft_detector_id; + ret = target_if_get_spectral_mode(detector_id, ¶ms.smode); + if (QDF_IS_STATUS_ERROR(ret)) { + spectral_err("Failed to get mode from detid= %u", + detector_id); + goto fail; + } + /* Take care of state transitions for 160 MHz and 80p80 */ if (spectral->ch_width == CH_WIDTH_160MHZ) { ret = target_if_160mhz_delivery_state_change( @@ -1744,7 +1764,9 @@ target_if_consume_spectral_report_gen3( vdev = target_if_spectral_get_vdev(spectral); if (!vdev) { spectral_info("First vdev is NULL"); - reset_160mhz_delivery_state_machine(spectral); + reset_160mhz_delivery_state_machine + (spectral, + SPECTRAL_SCAN_MODE_NORMAL); return -EPERM; } vdev_rxchainmask = wlan_vdev_mlme_get_rxchainmask(vdev); @@ -1786,7 +1808,8 @@ target_if_consume_spectral_report_gen3( fail: spectral_err_rl("Error while processing Spectral report"); - reset_160mhz_delivery_state_machine(spectral); + reset_160mhz_delivery_state_machine(spectral, + SPECTRAL_SCAN_MODE_NORMAL); return -EPERM; } |