1 /*
2  * Copyright (c) 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: wlan_interop_issues_ap_api.c
21  */
22 #include <wlan_interop_issues_ap_ucfg_api.h>
23 #include <wlan_interop_issues_ap_api.h>
24 #include <target_if_interop_issues_ap.h>
25 
26 /**
27  * interop_issues_ap_psoc_obj_created_notification() - PSOC obj create callback
28  * @psoc: PSOC object
29  * @arg_list: Variable argument list
30  *
31  * This callback is registered with object manager during initialization to
32  * get notified when the object is created.
33  *
34  * Return: Success or Failure
35  */
36 static QDF_STATUS
interop_issues_ap_psoc_obj_created_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)37 interop_issues_ap_psoc_obj_created_notification(struct wlan_objmgr_psoc *psoc,
38 						void *arg_list)
39 {
40 	QDF_STATUS status = QDF_STATUS_SUCCESS;
41 	struct interop_issues_ap_psoc_priv_obj *interop_issues_ap_obj;
42 
43 	interop_issues_ap_obj = qdf_mem_malloc(sizeof(*interop_issues_ap_obj));
44 	if (!interop_issues_ap_obj)
45 		return QDF_STATUS_E_NOMEM;
46 
47 	qdf_spinlock_create(&interop_issues_ap_obj->lock);
48 	status = wlan_objmgr_psoc_component_obj_attach(psoc,
49 					WLAN_UMAC_COMP_INTEROP_ISSUES_AP,
50 					interop_issues_ap_obj,
51 					QDF_STATUS_SUCCESS);
52 	if (QDF_IS_STATUS_ERROR(status)) {
53 		interop_issues_ap_err("obj attach with psoc failed");
54 		goto interop_issues_ap_psoc_attach_failed;
55 	}
56 
57 	target_if_interop_issues_ap_register_tx_ops(psoc,
58 					&interop_issues_ap_obj->tx_ops);
59 
60 	return QDF_STATUS_SUCCESS;
61 
62 interop_issues_ap_psoc_attach_failed:
63 	qdf_spinlock_destroy(&interop_issues_ap_obj->lock);
64 	qdf_mem_free(interop_issues_ap_obj);
65 	return status;
66 }
67 
68 /**
69  * interop_issues_ap_psoc_obj_destroyed_notification() - obj delete callback
70  * @psoc: PSOC object
71  * @arg_list: Variable argument list
72  *
73  * This callback is registered with object manager during initialization to
74  * get notified when the object is deleted.
75  *
76  * Return: Success or Failure
77  */
78 static QDF_STATUS
interop_issues_ap_psoc_obj_destroyed_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)79 interop_issues_ap_psoc_obj_destroyed_notification(struct wlan_objmgr_psoc *psoc,
80 						  void *arg_list)
81 {
82 	QDF_STATUS status = QDF_STATUS_SUCCESS;
83 	struct interop_issues_ap_psoc_priv_obj *interop_issues_ap_obj;
84 
85 	interop_issues_ap_obj = interop_issues_ap_get_psoc_priv_obj(psoc);
86 
87 	if (!interop_issues_ap_obj) {
88 		interop_issues_ap_err("interop_issues_ap_obj is NULL");
89 		return QDF_STATUS_E_FAULT;
90 	}
91 	target_if_interop_issues_ap_unregister_tx_ops(psoc,
92 					&interop_issues_ap_obj->tx_ops);
93 
94 	status = wlan_objmgr_psoc_component_obj_detach(psoc,
95 					WLAN_UMAC_COMP_INTEROP_ISSUES_AP,
96 					interop_issues_ap_obj);
97 	if (QDF_IS_STATUS_ERROR(status))
98 		interop_issues_ap_err("interop_issues_ap_obj detach failed");
99 
100 	qdf_spinlock_destroy(&interop_issues_ap_obj->lock);
101 	qdf_mem_free(interop_issues_ap_obj);
102 
103 	return status;
104 }
105 
wlan_interop_issues_ap_psoc_enable(struct wlan_objmgr_psoc * psoc)106 QDF_STATUS wlan_interop_issues_ap_psoc_enable(struct wlan_objmgr_psoc *psoc)
107 {
108 	return target_if_interop_issues_ap_register_event_handler(psoc);
109 }
110 
wlan_interop_issues_ap_psoc_disable(struct wlan_objmgr_psoc * psoc)111 QDF_STATUS wlan_interop_issues_ap_psoc_disable(struct wlan_objmgr_psoc *psoc)
112 {
113 	return target_if_interop_issues_ap_unregister_event_handler(psoc);
114 }
115 
wlan_interop_issues_ap_init(void)116 QDF_STATUS wlan_interop_issues_ap_init(void)
117 {
118 	QDF_STATUS status;
119 
120 	/* register psoc create handler functions. */
121 	status = wlan_objmgr_register_psoc_create_handler(
122 			WLAN_UMAC_COMP_INTEROP_ISSUES_AP,
123 			interop_issues_ap_psoc_obj_created_notification,
124 			NULL);
125 	if (QDF_IS_STATUS_ERROR(status)) {
126 		interop_issues_ap_err("register create handler failed");
127 		return status;
128 	}
129 
130 	/* register psoc delete handler functions. */
131 	status = wlan_objmgr_register_psoc_destroy_handler(
132 			WLAN_UMAC_COMP_INTEROP_ISSUES_AP,
133 			interop_issues_ap_psoc_obj_destroyed_notification,
134 			NULL);
135 	if (QDF_IS_STATUS_ERROR(status)) {
136 		interop_issues_ap_err("register destroy handler failed");
137 		status = wlan_objmgr_unregister_psoc_create_handler(
138 				WLAN_UMAC_COMP_INTEROP_ISSUES_AP,
139 				interop_issues_ap_psoc_obj_created_notification,
140 				NULL);
141 	}
142 
143 	return status;
144 }
145 
wlan_interop_issues_ap_deinit(void)146 QDF_STATUS wlan_interop_issues_ap_deinit(void)
147 {
148 	QDF_STATUS ret = QDF_STATUS_SUCCESS, status;
149 
150 	/* unregister psoc delete handler functions. */
151 	status = wlan_objmgr_unregister_psoc_destroy_handler(
152 			WLAN_UMAC_COMP_INTEROP_ISSUES_AP,
153 			interop_issues_ap_psoc_obj_destroyed_notification,
154 			NULL);
155 	if (QDF_IS_STATUS_ERROR(status)) {
156 		interop_issues_ap_err("unregister destroy handler failed");
157 		ret = status;
158 	}
159 
160 	/* unregister psoc create handler functions. */
161 	status = wlan_objmgr_unregister_psoc_create_handler(
162 			WLAN_UMAC_COMP_INTEROP_ISSUES_AP,
163 			interop_issues_ap_psoc_obj_created_notification,
164 			NULL);
165 	if (QDF_IS_STATUS_ERROR(status)) {
166 		interop_issues_ap_err("unregister create handler failed");
167 		ret = status;
168 	}
169 
170 	return ret;
171 }
172