1*5113495bSYour Name /*
2*5113495bSYour Name * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
3*5113495bSYour Name *
4*5113495bSYour Name * Permission to use, copy, modify, and/or distribute this software for any
5*5113495bSYour Name * purpose with or without fee is hereby granted, provided that the above
6*5113495bSYour Name * copyright notice and this permission notice appear in all copies.
7*5113495bSYour Name *
8*5113495bSYour Name * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9*5113495bSYour Name * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10*5113495bSYour Name * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11*5113495bSYour Name * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12*5113495bSYour Name * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13*5113495bSYour Name * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14*5113495bSYour Name * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*5113495bSYour Name */
16*5113495bSYour Name
17*5113495bSYour Name #include <qdf_types.h>
18*5113495bSYour Name #include "osif_pre_cac.h"
19*5113495bSYour Name #include "wlan_pre_cac_public_struct.h"
20*5113495bSYour Name #include "wlan_pre_cac_ucfg_api.h"
21*5113495bSYour Name #include "wlan_cfg80211.h"
22*5113495bSYour Name #include "wlan_objmgr_vdev_obj.h"
23*5113495bSYour Name #include "wlan_osif_priv.h"
24*5113495bSYour Name #include "osif_vdev_sync.h"
25*5113495bSYour Name
26*5113495bSYour Name static struct osif_pre_cac_legacy_ops *osif_pre_cac_legacy_ops;
27*5113495bSYour Name
28*5113495bSYour Name static void
osif_pre_cac_complete_legacy_cb(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,QDF_STATUS status)29*5113495bSYour Name osif_pre_cac_complete_legacy_cb(struct wlan_objmgr_psoc *psoc,
30*5113495bSYour Name uint8_t vdev_id,
31*5113495bSYour Name QDF_STATUS status)
32*5113495bSYour Name {
33*5113495bSYour Name osif_pre_cac_complete_status_legacy_cb cb = NULL;
34*5113495bSYour Name
35*5113495bSYour Name if (osif_pre_cac_legacy_ops)
36*5113495bSYour Name cb = osif_pre_cac_legacy_ops->pre_cac_complete_legacy_cb;
37*5113495bSYour Name
38*5113495bSYour Name if (cb)
39*5113495bSYour Name cb(psoc, vdev_id, status);
40*5113495bSYour Name }
41*5113495bSYour Name
osif_pre_cac_complete_cb(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,QDF_STATUS status)42*5113495bSYour Name static void osif_pre_cac_complete_cb(struct wlan_objmgr_psoc *psoc,
43*5113495bSYour Name uint8_t vdev_id,
44*5113495bSYour Name QDF_STATUS status)
45*5113495bSYour Name {
46*5113495bSYour Name struct vdev_osif_priv *osif_priv;
47*5113495bSYour Name struct osif_vdev_sync *vdev_sync;
48*5113495bSYour Name int errno;
49*5113495bSYour Name struct wlan_objmgr_vdev *vdev;
50*5113495bSYour Name
51*5113495bSYour Name vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
52*5113495bSYour Name psoc, vdev_id,
53*5113495bSYour Name WLAN_PRE_CAC_ID);
54*5113495bSYour Name if (!vdev) {
55*5113495bSYour Name osif_err("Invalid vdev for %d", vdev_id);
56*5113495bSYour Name return;
57*5113495bSYour Name }
58*5113495bSYour Name osif_priv = wlan_vdev_get_ospriv(vdev);
59*5113495bSYour Name errno = osif_vdev_sync_trans_start_wait(osif_priv->wdev->netdev,
60*5113495bSYour Name &vdev_sync);
61*5113495bSYour Name wlan_objmgr_vdev_release_ref(vdev, WLAN_PRE_CAC_ID);
62*5113495bSYour Name if (errno)
63*5113495bSYour Name return;
64*5113495bSYour Name
65*5113495bSYour Name osif_pre_cac_complete_legacy_cb(psoc, vdev_id, status);
66*5113495bSYour Name
67*5113495bSYour Name osif_vdev_sync_trans_stop(vdev_sync);
68*5113495bSYour Name }
69*5113495bSYour Name
70*5113495bSYour Name static void
osif_pre_cac_conditional_csa_ind_legacy_cb(struct wlan_objmgr_vdev * vdev,bool completed)71*5113495bSYour Name osif_pre_cac_conditional_csa_ind_legacy_cb(struct wlan_objmgr_vdev *vdev,
72*5113495bSYour Name bool completed)
73*5113495bSYour Name {
74*5113495bSYour Name osif_conditional_csa_ind_legacy_cb cb = NULL;
75*5113495bSYour Name
76*5113495bSYour Name if (osif_pre_cac_legacy_ops)
77*5113495bSYour Name cb = osif_pre_cac_legacy_ops->conditional_csa_ind_legacy_cb;
78*5113495bSYour Name
79*5113495bSYour Name if (cb)
80*5113495bSYour Name cb(vdev, completed);
81*5113495bSYour Name }
82*5113495bSYour Name
83*5113495bSYour Name static void
osif_pre_cac_send_conditional_freq_switch_status(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,bool status)84*5113495bSYour Name osif_pre_cac_send_conditional_freq_switch_status(struct wlan_objmgr_psoc *psoc,
85*5113495bSYour Name uint8_t vdev_id,
86*5113495bSYour Name bool status)
87*5113495bSYour Name {
88*5113495bSYour Name struct vdev_osif_priv *osif_priv;
89*5113495bSYour Name struct wlan_objmgr_vdev *vdev;
90*5113495bSYour Name struct wireless_dev *wdev;
91*5113495bSYour Name struct sk_buff *event;
92*5113495bSYour Name
93*5113495bSYour Name vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
94*5113495bSYour Name WLAN_PRE_CAC_ID);
95*5113495bSYour Name if (!vdev) {
96*5113495bSYour Name osif_err("vdev is null");
97*5113495bSYour Name return;
98*5113495bSYour Name }
99*5113495bSYour Name
100*5113495bSYour Name osif_priv = wlan_vdev_get_ospriv(vdev);
101*5113495bSYour Name if (!osif_priv) {
102*5113495bSYour Name osif_err("osif_priv is null");
103*5113495bSYour Name goto fail;
104*5113495bSYour Name }
105*5113495bSYour Name
106*5113495bSYour Name wdev = osif_priv->wdev;
107*5113495bSYour Name if (!wdev) {
108*5113495bSYour Name osif_err("wireless dev is null");
109*5113495bSYour Name goto fail;
110*5113495bSYour Name }
111*5113495bSYour Name
112*5113495bSYour Name event = wlan_cfg80211_vendor_event_alloc(wdev->wiphy,
113*5113495bSYour Name wdev, sizeof(uint32_t) + NLMSG_HDRLEN,
114*5113495bSYour Name QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH_INDEX,
115*5113495bSYour Name GFP_KERNEL);
116*5113495bSYour Name if (!event) {
117*5113495bSYour Name osif_err("wlan_cfg80211_vendor_event_alloc failed");
118*5113495bSYour Name goto fail;
119*5113495bSYour Name }
120*5113495bSYour Name
121*5113495bSYour Name if (nla_put_u32(event,
122*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_STATUS,
123*5113495bSYour Name status)) {
124*5113495bSYour Name osif_err("nla put failed");
125*5113495bSYour Name wlan_cfg80211_vendor_free_skb(event);
126*5113495bSYour Name goto fail;
127*5113495bSYour Name }
128*5113495bSYour Name
129*5113495bSYour Name wlan_cfg80211_vendor_event(event, GFP_KERNEL);
130*5113495bSYour Name osif_pre_cac_conditional_csa_ind_legacy_cb(vdev, status);
131*5113495bSYour Name
132*5113495bSYour Name fail:
133*5113495bSYour Name wlan_objmgr_vdev_release_ref(vdev, WLAN_PRE_CAC_ID);
134*5113495bSYour Name }
135*5113495bSYour Name
osif_pre_cac_set_legacy_cb(struct osif_pre_cac_legacy_ops * osif_legacy_ops)136*5113495bSYour Name void osif_pre_cac_set_legacy_cb(struct osif_pre_cac_legacy_ops *osif_legacy_ops)
137*5113495bSYour Name {
138*5113495bSYour Name osif_pre_cac_legacy_ops = osif_legacy_ops;
139*5113495bSYour Name }
140*5113495bSYour Name
osif_pre_cac_reset_legacy_cb(void)141*5113495bSYour Name void osif_pre_cac_reset_legacy_cb(void)
142*5113495bSYour Name {
143*5113495bSYour Name osif_pre_cac_legacy_ops = NULL;
144*5113495bSYour Name }
145*5113495bSYour Name
146*5113495bSYour Name static struct pre_cac_ops pre_cac_ops = {
147*5113495bSYour Name .pre_cac_conditional_csa_ind_cb =
148*5113495bSYour Name osif_pre_cac_send_conditional_freq_switch_status,
149*5113495bSYour Name .pre_cac_complete_cb = osif_pre_cac_complete_cb,
150*5113495bSYour Name };
151*5113495bSYour Name
osif_pre_cac_register_cb(void)152*5113495bSYour Name QDF_STATUS osif_pre_cac_register_cb(void)
153*5113495bSYour Name {
154*5113495bSYour Name ucfg_pre_cac_set_osif_cb(&pre_cac_ops);
155*5113495bSYour Name
156*5113495bSYour Name return QDF_STATUS_SUCCESS;
157*5113495bSYour Name }
158