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