xref: /wlan-driver/qcacld-3.0/components/target_if/pmo/src/target_if_pmo_mc_addr_filtering.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1 /*
2  * Copyright (c) 2017-2018, 2021 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  * DOC: target_if_pmo_mc_addr_filtering.c
20  *
21  * Target interface file for pmo component to
22  * send mc address filtering offload related cmd and process event.
23  */
24 
25 
26 #include "target_if.h"
27 #include "target_if_pmo.h"
28 #include "wmi_unified_api.h"
29 
target_if_pmo_set_mc_filter_req(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr multicast_addr)30 QDF_STATUS target_if_pmo_set_mc_filter_req(
31 		struct wlan_objmgr_vdev *vdev,
32 		struct qdf_mac_addr multicast_addr)
33 {
34 	uint8_t vdev_id;
35 	struct wlan_objmgr_psoc *psoc;
36 	QDF_STATUS status;
37 	wmi_unified_t wmi_handle;
38 
39 	if (!vdev) {
40 		target_if_err("vdev ptr passed is NULL");
41 		return QDF_STATUS_E_INVAL;
42 	}
43 
44 	psoc = wlan_vdev_get_psoc(vdev);
45 	vdev_id = wlan_vdev_get_id(vdev);
46 	if (!psoc) {
47 		target_if_err("psoc handle is NULL");
48 		return QDF_STATUS_E_INVAL;
49 	}
50 
51 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
52 	if (!wmi_handle) {
53 		target_if_err("Invalid wmi handle");
54 		return QDF_STATUS_E_INVAL;
55 	}
56 
57 	status = wmi_unified_add_clear_mcbc_filter_cmd(wmi_handle, vdev_id,
58 						       multicast_addr, false);
59 	if (status)
60 		target_if_err("Failed to send add/clear mcbc filter cmd");
61 
62 	return status;
63 }
64 
target_if_pmo_clear_mc_filter_req(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr multicast_addr)65 QDF_STATUS target_if_pmo_clear_mc_filter_req(
66 		struct wlan_objmgr_vdev *vdev,
67 		struct qdf_mac_addr multicast_addr)
68 {
69 	uint8_t vdev_id;
70 	struct wlan_objmgr_psoc *psoc;
71 	QDF_STATUS status;
72 	wmi_unified_t wmi_handle;
73 
74 	if (!vdev) {
75 		target_if_err("vdev ptr passed is NULL");
76 		return QDF_STATUS_E_INVAL;
77 	}
78 
79 	psoc = wlan_vdev_get_psoc(vdev);
80 	vdev_id = wlan_vdev_get_id(vdev);
81 	if (!psoc) {
82 		target_if_err("psoc handle is NULL");
83 		return QDF_STATUS_E_INVAL;
84 	}
85 
86 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
87 	if (!wmi_handle) {
88 		target_if_err("Invalid wmi handle");
89 		return QDF_STATUS_E_INVAL;
90 	}
91 
92 	status = wmi_unified_add_clear_mcbc_filter_cmd(wmi_handle, vdev_id,
93 						       multicast_addr, true);
94 	if (status)
95 		target_if_err("Failed to send add/clear mcbc filter cmd");
96 
97 	return status;
98 
99 }
100 
target_if_pmo_get_multiple_mc_filter_support(struct wlan_objmgr_psoc * psoc)101 bool target_if_pmo_get_multiple_mc_filter_support(
102 		struct wlan_objmgr_psoc *psoc)
103 {
104 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
105 
106 	if (!wmi_handle) {
107 		target_if_err("Invalid wmi handle");
108 		return false;
109 	}
110 
111 	return wmi_service_enabled(wmi_handle,
112 				   wmi_service_multiple_mcast_filter_set);
113 }
114 
target_if_pmo_set_multiple_mc_filter_req(struct wlan_objmgr_vdev * vdev,struct pmo_mc_addr_list * mc_list)115 QDF_STATUS target_if_pmo_set_multiple_mc_filter_req(
116 		struct wlan_objmgr_vdev *vdev,
117 		struct pmo_mc_addr_list *mc_list)
118 {
119 	uint8_t vdev_id;
120 	struct wlan_objmgr_psoc *psoc;
121 	struct pmo_mcast_filter_params *filter_params;
122 	QDF_STATUS status;
123 	wmi_unified_t wmi_handle;
124 
125 	if (!vdev) {
126 		target_if_err("vdev ptr passed is NULL");
127 		return QDF_STATUS_E_INVAL;
128 	}
129 
130 	psoc = wlan_vdev_get_psoc(vdev);
131 	vdev_id = wlan_vdev_get_id(vdev);
132 	if (!psoc) {
133 		target_if_err("psoc handle is NULL");
134 		return QDF_STATUS_E_INVAL;
135 	}
136 
137 	filter_params = qdf_mem_malloc(sizeof(*filter_params));
138 	if (!filter_params) {
139 		target_if_err("memory alloc failed for filter_params");
140 		return QDF_STATUS_E_NOMEM;
141 	}
142 
143 	filter_params->multicast_addr_cnt = mc_list->mc_cnt;
144 	qdf_mem_copy(filter_params->multicast_addr,
145 		     mc_list->mc_addr,
146 		     mc_list->mc_cnt * ATH_MAC_LEN);
147 	/* add one/multiple mc list */
148 	filter_params->action = 1;
149 
150 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
151 	if (!wmi_handle) {
152 		target_if_err("Invalid wmi handle");
153 		qdf_mem_free(filter_params);
154 		return QDF_STATUS_E_INVAL;
155 	}
156 
157 	status = wmi_unified_multiple_add_clear_mcbc_filter_cmd(wmi_handle,
158 								vdev_id,
159 								filter_params);
160 	if (status)
161 		target_if_err("Failed to send add/clear mcbc filter cmd");
162 
163 	qdf_mem_free(filter_params);
164 
165 	return status;
166 }
167 
target_if_pmo_clear_multiple_mc_filter_req(struct wlan_objmgr_vdev * vdev,struct pmo_mc_addr_list * mc_list)168 QDF_STATUS target_if_pmo_clear_multiple_mc_filter_req(
169 		struct wlan_objmgr_vdev *vdev,
170 		struct pmo_mc_addr_list *mc_list)
171 {
172 	uint8_t vdev_id;
173 	struct wlan_objmgr_psoc *psoc;
174 	struct pmo_mcast_filter_params *filter_params;
175 	QDF_STATUS status;
176 	wmi_unified_t wmi_handle;
177 
178 	if (!vdev) {
179 		target_if_err("vdev ptr passed is NULL");
180 		return QDF_STATUS_E_INVAL;
181 	}
182 
183 	psoc = wlan_vdev_get_psoc(vdev);
184 	vdev_id = wlan_vdev_get_id(vdev);
185 	if (!psoc) {
186 		target_if_err("psoc handle is NULL");
187 		return QDF_STATUS_E_INVAL;
188 	}
189 
190 	filter_params = qdf_mem_malloc(sizeof(*filter_params));
191 	if (!filter_params) {
192 		target_if_err("memory alloc failed for filter_params");
193 		return QDF_STATUS_E_NOMEM;
194 	}
195 
196 	filter_params->multicast_addr_cnt = mc_list->mc_cnt;
197 	qdf_mem_copy(filter_params->multicast_addr,
198 		     mc_list->mc_addr,
199 		     mc_list->mc_cnt * ATH_MAC_LEN);
200 	/* delete one/multiple mc list */
201 	filter_params->action = 0;
202 
203 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
204 	if (!wmi_handle) {
205 		target_if_err("Invalid wmi handle");
206 		qdf_mem_free(filter_params);
207 		return QDF_STATUS_E_INVAL;
208 	}
209 
210 	status = wmi_unified_multiple_add_clear_mcbc_filter_cmd(wmi_handle,
211 								vdev_id,
212 								filter_params);
213 	if (status)
214 		target_if_err("Failed to send add/clear mcbc filter cmd");
215 
216 	qdf_mem_free(filter_params);
217 
218 	return status;
219 }
220 
221 
222