blob: c32bdd92595215f69e997a312c4d659d65518858 [file] [log] [blame]
Naveen Rawat685bf252018-04-05 11:56:36 -07001/*
2 * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
3 *
Naveen Rawat685bf252018-04-05 11:56:36 -07004 * 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
Naveen Rawat685bf252018-04-05 11:56:36 -070019#ifndef __WLAN_OSIF_REQUEST_MANAGER_H__
20#define __WLAN_OSIF_REQUEST_MANAGER_H__
21
22/**
23 * DOC: WLAN OSIF REQUEST MANAGER
24 *
25 * Many operations within the wlan driver occur in an asynchronous
26 * manner. Requests are received by OSIF via one of the kernel
27 * interfaces (ioctl, nl80211, virtual file system, etc.). The
28 * requests are translated to an internal format and are then passed
29 * to lower layers, usually via SME, for processing. For requests
30 * which require a response, that response comes up from the lower
31 * layers in a separate thread of execution, ultimately resulting in a
32 * call to a callback function that was provided by OSIF as part of the
33 * initial request. So a mechanism is needed to synchronize the
34 * request and response. This framework provides that mechanism.
35 *
36 * Once the framework has been initialized, the typical sequence of
37 * events is as follows:
38 *
39 * Request Thread:
40 * 1. Create a &struct osif_request_params which describes the request.
41 * 2. Call osif_request_alloc() to allocate a &struct osif_request.
42 * 3. Call osif_request_priv() to get a pointer to the private data.
43 * 4. Place any information which must be shared with the Response
44 * Callback in the private data area.
45 * 5. Call osif_request_cookie() to get the unique cookie assigned
46 * to the request.
47 * 6. Call the underlying request handling API, passing the cookie
48 * as the callback's private context.
49 * 7. Call osif_request_wait_for_response() to wait for the response
50 * (or for the request to time out).
51 * 8. Use the return status to see if the request was successful. If
52 * it was, retrieve any response information from the private
53 * structure and prepare a response for userspace.
54 * 9. Call osif_request_put() to relinquish access to the request.
55 * 10. Return status to the caller.
56 *
57 * Response Callback:
58 * 1. Call osif_request_get() with the provided cookie to see if the
59 * request structure is still valid. If it returns %NULL then
60 * return since this means the request thread has already timed
61 * out.
62 * 2. Call osif_request_priv() to get access to the private data area.
63 * 3. Write response data into the private data area.
64 * 4. Call osif_request_complete() to indicate that the response is
65 * ready to be processed by the request thread.
66 * 5. Call osif_request_put() to relinquish the callback function's
67 * reference to the request.
68 */
69
70/* this is opaque to clients */
71struct osif_request;
72
73/**
74 * typedef osif_request_dealloc - Private data deallocation function
75 */
76typedef void (*osif_request_dealloc)(void *priv);
77
78/**
79 * struct osif_request_params - OSIF request parameters
80 * @priv_size: Size of the private data area required to pass
81 * information between the request thread and the response callback.
82 * @timeout_ms: The amount of time to wait for a response in milliseconds.
83 * @dealloc: Function to be called when the request is destroyed to
84 * deallocate any allocations made in the private area of the
85 * request struct. Can be %NULL if no private allocations are
86 * made.
87 */
88struct osif_request_params {
89 uint32_t priv_size;
90 uint32_t timeout_ms;
91 osif_request_dealloc dealloc;
92};
93
94/**
95 * osif_request_alloc() - Allocate a request struct
96 * @params: parameter block that specifies the attributes of the
97 * request
98 *
99 * This function will attempt to allocate a &struct osif_request with
100 * the specified @params. If successful, the caller can then use
101 * request struct to make an asynchronous request. Once the request is
102 * no longer needed, the reference should be relinquished via a call
103 * to osif_request_put().
104 *
105 * Return: A pointer to an allocated &struct osif_request (which also
106 * contains room for the private buffer) if the allocation is
107 * successful, %NULL if the allocation fails.
108 */
109struct osif_request *osif_request_alloc(const struct osif_request_params *params);
110
111/**
112 * osif_request_priv() - Get pointer to request private data
113 * @request: The request struct that contains the private data
114 *
115 * This function will return a pointer to the private data area that
116 * is part of the request struct. The caller must already have a valid
117 * reference to @request from either osif_request_alloc() or
118 * osif_request_get().
119 *
120 * Returns: pointer to the private data area. Note that this pointer
121 * will always be an offset from the input @request pointer and hence
122 * this function will never return %NULL.
123 */
124void *osif_request_priv(struct osif_request *request);
125
126/**
127 * osif_request_cookie() - Get cookie of a request
128 * @request: The request struct associated with the request
129 *
130 * This function will return the unique cookie that has been assigned
131 * to the request. This cookie can subsequently be passed to
132 * osif_request_get() to retrieve the request.
133 *
134 * Note that the cookie is defined as a void pointer as it is intended
135 * to be passed as an opaque context pointer from OSIF to underlying
136 * layers when making a request, and subsequently passed back to OSIF
137 * as an opaque pointer in an asynchronous callback.
138 *
139 * Returns: The cookie assigned to the request.
140 */
141void *osif_request_cookie(struct osif_request *request);
142
143/**
144 * osif_request_get() - Get a reference to a request struct
145 * @cookie: The cookie of the request struct that needs to be
146 * referenced
147 *
148 * This function will use the cookie to determine if the associated
149 * request struct is valid, and if so, will increment the reference
150 * count of the struct. This means the caller is guaranteed that the
151 * request struct is valid and the underlying private data can be
152 * dereferenced.
153 *
154 * Returns: The pointer to the request struct associated with @cookie
155 * if the request is still valid, %NULL if the underlying request
156 * struct is no longer valid.
157 */
158struct osif_request *osif_request_get(void *cookie);
159
160/**
161 * osif_request_put() - Release a reference to a request struct
162 * @request: The request struct that no longer needs to be referenced
163 *
164 * This function will decrement the reference count of the struct, and
165 * will clean up the request if this is the last reference. The caller
166 * must already have a valid reference to @request, either from
167 * osif_request_alloc() or osif_request_get().
168 *
169 * Returns: Nothing
170 */
171void osif_request_put(struct osif_request *request);
172
173/**
174 * osif_request_wait_for_response() - Wait for a response
175 * @request: The request struct associated with the request
176 *
177 * This function will wait until either a response is received and
178 * communicated via osif_request_complete(), or until the request
179 * timeout period expires.
180 *
181 * Returns: 0 if a response was received, -ETIMEDOUT if the response
182 * timed out.
183 */
184int osif_request_wait_for_response(struct osif_request *request);
185
186/**
187 * osif_request_complete() - Complete a request
188 * @request: The request struct associated with the request
189 *
190 * This function is used to indicate that a response has been received
191 * and that any information required by the request thread has been
192 * copied into the private data area of the request struct. This will
193 * unblock any osif_request_wait_for_response() that is pending on this
194 * @request.
195 *
196 * Returns: Nothing
197 */
198void osif_request_complete(struct osif_request *request);
199
200/**
201 * osif_request_manager_init() - Initialize the OSIF Request Manager
202 *
203 * This function must be called during system initialization to
204 * initialize the OSIF Request Manager.
205 *
206 * Returns: Nothing
207 */
208void osif_request_manager_init(void);
209
210/**
211 * osif_request_manager_deinit() - Deinitialize the OSIF Request Manager
212 *
213 * This function must be called during system shutdown to deinitialize
214 * the OSIF Request Manager.
215 *
216 * Returns: Nothing
217 */
218void osif_request_manager_deinit(void);
219
220#endif /* __WLAN_OSIF_REQUEST_MANAGER_H__ */