xref: /wlan-dirver/qca-wifi-host-cmn/target_if/green_ap/src/target_if_green_ap.c (revision 503663c6daafffe652fa360bde17243568cd6d2a)
1 /*
2  * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * DOC: offload lmac interface APIs definitions for Green ap
21  */
22 
23 #include <target_if_green_ap.h>
24 #include <wlan_green_ap_api.h>
25 #include <../../core/src/wlan_green_ap_main_i.h>
26 #include <target_if.h>
27 #include <wmi_unified_api.h>
28 
29 QDF_STATUS target_if_register_green_ap_tx_ops(
30 		struct wlan_lmac_if_tx_ops *tx_ops)
31 {
32 	struct wlan_lmac_if_green_ap_tx_ops *green_ap_tx_ops;
33 
34 	if (!tx_ops) {
35 		target_if_err("invalid tx_ops");
36 		return QDF_STATUS_E_FAILURE;
37 	}
38 
39 	green_ap_tx_ops = &tx_ops->green_ap_tx_ops;
40 
41 	green_ap_tx_ops->enable_egap = target_if_green_ap_enable_egap;
42 	green_ap_tx_ops->ps_on_off_send = target_if_green_ap_set_ps_on_off;
43 	green_ap_tx_ops->reset_dev = NULL;
44 	green_ap_tx_ops->get_current_channel = NULL;
45 	green_ap_tx_ops->get_current_channel_flags = NULL;
46 	green_ap_tx_ops->get_capab = NULL;
47 
48 	return QDF_STATUS_SUCCESS;
49 }
50 
51 /**
52  * target_if_green_ap_egap_status_info_event() - egap status info event
53  * @scn: pointer to scn handle
54  * @evt_buf: pointer to event buffer
55  * @data_len: data len of the event buffer
56  *
57  * Return: 0 for success, otherwise appropriate error code
58  */
59 static int target_if_green_ap_egap_status_info_event(
60 		ol_scn_t scn, uint8_t *evt_buf, uint32_t data_len)
61 {
62 	struct wlan_objmgr_pdev *pdev;
63 	struct wlan_green_ap_egap_status_info egap_status_info_params;
64 	void *wmi_hdl;
65 
66 	pdev = target_if_get_pdev_from_scn_hdl(scn);
67 	if (!pdev) {
68 		green_ap_err("pdev is null");
69 		return QDF_STATUS_E_FAILURE;
70 	}
71 
72 	wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev);
73 	if (!wmi_hdl) {
74 		green_ap_err("null wmi_hdl");
75 		return QDF_STATUS_E_FAILURE;
76 	}
77 
78 	if (wmi_extract_green_ap_egap_status_info(wmi_hdl,
79 						  evt_buf,
80 						  &egap_status_info_params) !=
81 						  QDF_STATUS_SUCCESS) {
82 		green_ap_err("unable to extract green ap egap status info");
83 		return QDF_STATUS_E_FAILURE;
84 	}
85 
86 	green_ap_debug("mac_id: %d, status: %d, tx_mask: %x, rx_mask: %d",
87 		       egap_status_info_params.mac_id,
88 		       egap_status_info_params.status,
89 		       egap_status_info_params.tx_chainmask,
90 		       egap_status_info_params.rx_chainmask);
91 
92 	return 0;
93 }
94 
95 QDF_STATUS target_if_green_ap_register_egap_event_handler(
96 			struct wlan_objmgr_pdev *pdev)
97 {
98 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
99 	struct wlan_green_ap_egap_params *egap_params;
100 	int ret;
101 	void *wmi_hdl;
102 
103 	if (!pdev) {
104 		green_ap_err("pdev is null");
105 		return QDF_STATUS_E_INVAL;
106 	}
107 
108 	wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev);
109 	if (!wmi_hdl) {
110 		green_ap_err("null wmi_hdl");
111 		return QDF_STATUS_E_FAILURE;
112 	}
113 
114 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
115 			pdev, WLAN_UMAC_COMP_GREEN_AP);
116 	if (!green_ap_ctx) {
117 		green_ap_err("green ap context obtained is NULL");
118 		return QDF_STATUS_E_FAILURE;
119 	}
120 	egap_params = &green_ap_ctx->egap_params;
121 
122 	ret = wmi_unified_register_event_handler(
123 			wmi_hdl,
124 			wmi_ap_ps_egap_info_event_id,
125 			target_if_green_ap_egap_status_info_event,
126 			WMI_RX_UMAC_CTX);
127 	if (ret < 0) {
128 		green_ap_err("Failed to register Enhance Green AP event");
129 		egap_params->fw_egap_support = false;
130 	} else {
131 		green_ap_info("Set the Enhance Green AP event handler");
132 		egap_params->fw_egap_support = true;
133 	}
134 
135 	return QDF_STATUS_SUCCESS;
136 }
137 
138 QDF_STATUS target_if_green_ap_enable_egap(
139 		struct wlan_objmgr_pdev *pdev,
140 		struct wlan_green_ap_egap_params *egap_params)
141 {
142 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
143 	wmi_unified_t wmi_hdl;
144 
145 	if (!pdev) {
146 		green_ap_err("pdev context passed is NULL");
147 		return QDF_STATUS_E_INVAL;
148 	}
149 
150 	wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev);
151 	if (!wmi_hdl) {
152 		green_ap_err("null wmi_hdl");
153 		return QDF_STATUS_E_FAILURE;
154 	}
155 
156 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
157 			pdev, WLAN_UMAC_COMP_GREEN_AP);
158 	if (!green_ap_ctx) {
159 		green_ap_err("green ap context obtained is NULL");
160 		return QDF_STATUS_E_FAILURE;
161 	}
162 
163 	qdf_spin_lock_bh(&green_ap_ctx->lock);
164 	if (!wlan_is_egap_enabled(green_ap_ctx)) {
165 		green_ap_info("enhanced green ap support is not present");
166 		qdf_spin_unlock_bh(&green_ap_ctx->lock);
167 		return QDF_STATUS_SUCCESS;
168 	}
169 	qdf_spin_unlock_bh(&green_ap_ctx->lock);
170 
171 	return wmi_unified_egap_conf_params_cmd(wmi_hdl,
172 							egap_params);
173 }
174 
175 QDF_STATUS target_if_green_ap_set_ps_on_off(struct wlan_objmgr_pdev *pdev,
176 					    bool value, uint8_t pdev_id)
177 {
178 	wmi_unified_t wmi_hdl;
179 
180 	if (!pdev) {
181 		green_ap_err("pdev context passed is NULL");
182 		return QDF_STATUS_E_INVAL;
183 	}
184 
185 	wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev);
186 	if (!wmi_hdl) {
187 		green_ap_err("null wmi_hdl");
188 		return QDF_STATUS_E_FAILURE;
189 	}
190 
191 	return wmi_unified_green_ap_ps_send(wmi_hdl,
192 					    value, pdev_id);
193 }
194