• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Ultra Wide Band
3  * UWB basic command support and radio reset
4  *
5  * Copyright (C) 2005-2006 Intel Corporation
6  * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License version
10  * 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301, USA.
21  *
22  *
23  * FIXME:
24  *
25  *  - docs
26  *
27  *  - Now we are serializing (using the uwb_dev->mutex) the command
28  *    execution; it should be parallelized as much as possible some
29  *    day.
30  */
31 #include <linux/kernel.h>
32 #include <linux/err.h>
33 
34 #include "uwb-internal.h"
35 
36 /**
37  * Command result codes (WUSB1.0[T8-69])
38  */
39 static
40 const char *__strerror[] = {
41 	"success",
42 	"failure",
43 	"hardware failure",
44 	"no more slots",
45 	"beacon is too large",
46 	"invalid parameter",
47 	"unsupported power level",
48 	"time out (wa) or invalid ie data (whci)",
49 	"beacon size exceeded",
50 	"cancelled",
51 	"invalid state",
52 	"invalid size",
53 	"ack not recieved",
54 	"no more asie notification",
55 };
56 
57 
58 /** Return a string matching the given error code */
uwb_rc_strerror(unsigned code)59 const char *uwb_rc_strerror(unsigned code)
60 {
61 	if (code == 255)
62 		return "time out";
63 	if (code >= ARRAY_SIZE(__strerror))
64 		return "unknown error";
65 	return __strerror[code];
66 }
67 
uwb_rc_cmd_async(struct uwb_rc * rc,const char * cmd_name,struct uwb_rccb * cmd,size_t cmd_size,u8 expected_type,u16 expected_event,uwb_rc_cmd_cb_f cb,void * arg)68 int uwb_rc_cmd_async(struct uwb_rc *rc, const char *cmd_name,
69 		     struct uwb_rccb *cmd, size_t cmd_size,
70 		     u8 expected_type, u16 expected_event,
71 		     uwb_rc_cmd_cb_f cb, void *arg)
72 {
73 	struct device *dev = &rc->uwb_dev.dev;
74 	struct uwb_rc_neh *neh;
75 	int needtofree = 0;
76 	int result;
77 
78 	uwb_dev_lock(&rc->uwb_dev);	/* Protect against rc->priv being removed */
79 	if (rc->priv == NULL) {
80 		uwb_dev_unlock(&rc->uwb_dev);
81 		return -ESHUTDOWN;
82 	}
83 
84 	if (rc->filter_cmd) {
85 		needtofree = rc->filter_cmd(rc, &cmd, &cmd_size);
86 		if (needtofree < 0 && needtofree != -ENOANO) {
87 			dev_err(dev, "%s: filter error: %d\n",
88 				cmd_name, needtofree);
89 			uwb_dev_unlock(&rc->uwb_dev);
90 			return needtofree;
91 		}
92 	}
93 
94 	neh = uwb_rc_neh_add(rc, cmd, expected_type, expected_event, cb, arg);
95 	if (IS_ERR(neh)) {
96 		result = PTR_ERR(neh);
97 		goto out;
98 	}
99 
100 	result = rc->cmd(rc, cmd, cmd_size);
101 	uwb_dev_unlock(&rc->uwb_dev);
102 	if (result < 0)
103 		uwb_rc_neh_rm(rc, neh);
104 	else
105 		uwb_rc_neh_arm(rc, neh);
106 	uwb_rc_neh_put(neh);
107 out:
108 	if (needtofree == 1)
109 		kfree(cmd);
110 	return result < 0 ? result : 0;
111 }
112 EXPORT_SYMBOL_GPL(uwb_rc_cmd_async);
113 
114 struct uwb_rc_cmd_done_params {
115 	struct completion completion;
116 	struct uwb_rceb *reply;
117 	ssize_t reply_size;
118 };
119 
uwb_rc_cmd_done(struct uwb_rc * rc,void * arg,struct uwb_rceb * reply,ssize_t reply_size)120 static void uwb_rc_cmd_done(struct uwb_rc *rc, void *arg,
121 			    struct uwb_rceb *reply, ssize_t reply_size)
122 {
123 	struct uwb_rc_cmd_done_params *p = (struct uwb_rc_cmd_done_params *)arg;
124 
125 	if (reply_size > 0) {
126 		if (p->reply)
127 			reply_size = min(p->reply_size, reply_size);
128 		else
129 			p->reply = kmalloc(reply_size, GFP_ATOMIC);
130 
131 		if (p->reply)
132 			memcpy(p->reply, reply, reply_size);
133 		else
134 			reply_size = -ENOMEM;
135 	}
136 	p->reply_size = reply_size;
137 	complete(&p->completion);
138 }
139 
140 
141 /**
142  * Generic function for issuing commands to the Radio Control Interface
143  *
144  * @rc:       UWB Radio Control descriptor
145  * @cmd_name: Name of the command being issued (for error messages)
146  * @cmd:      Pointer to rccb structure containing the command;
147  *            normally you embed this structure as the first member of
148  *            the full command structure.
149  * @cmd_size: Size of the whole command buffer pointed to by @cmd.
150  * @reply:    Pointer to where to store the reply
151  * @reply_size: @reply's size
152  * @expected_type: Expected type in the return event
153  * @expected_event: Expected event code in the return event
154  * @preply:   Here a pointer to where the event data is received will
155  *            be stored. Once done with the data, free with kfree().
156  *
157  * This function is generic; it works for commands that return a fixed
158  * and known size or for commands that return a variable amount of data.
159  *
160  * If a buffer is provided, that is used, although it could be chopped
161  * to the maximum size of the buffer. If the buffer is NULL, then one
162  * be allocated in *preply with the whole contents of the reply.
163  *
164  * @rc needs to be referenced
165  */
166 static
__uwb_rc_cmd(struct uwb_rc * rc,const char * cmd_name,struct uwb_rccb * cmd,size_t cmd_size,struct uwb_rceb * reply,size_t reply_size,u8 expected_type,u16 expected_event,struct uwb_rceb ** preply)167 ssize_t __uwb_rc_cmd(struct uwb_rc *rc, const char *cmd_name,
168 		     struct uwb_rccb *cmd, size_t cmd_size,
169 		     struct uwb_rceb *reply, size_t reply_size,
170 		     u8 expected_type, u16 expected_event,
171 		     struct uwb_rceb **preply)
172 {
173 	ssize_t result = 0;
174 	struct device *dev = &rc->uwb_dev.dev;
175 	struct uwb_rc_cmd_done_params params;
176 
177 	init_completion(&params.completion);
178 	params.reply = reply;
179 	params.reply_size = reply_size;
180 
181 	result = uwb_rc_cmd_async(rc, cmd_name, cmd, cmd_size,
182 				  expected_type, expected_event,
183 				  uwb_rc_cmd_done, &params);
184 	if (result)
185 		return result;
186 
187 	wait_for_completion(&params.completion);
188 
189 	if (preply)
190 		*preply = params.reply;
191 
192 	if (params.reply_size < 0)
193 		dev_err(dev, "%s: confirmation event 0x%02x/%04x/%02x "
194 			"reception failed: %d\n", cmd_name,
195 			expected_type, expected_event, cmd->bCommandContext,
196 			(int)params.reply_size);
197 	return params.reply_size;
198 }
199 
200 
201 /**
202  * Generic function for issuing commands to the Radio Control Interface
203  *
204  * @rc:       UWB Radio Control descriptor
205  * @cmd_name: Name of the command being issued (for error messages)
206  * @cmd:      Pointer to rccb structure containing the command;
207  *            normally you embed this structure as the first member of
208  *            the full command structure.
209  * @cmd_size: Size of the whole command buffer pointed to by @cmd.
210  * @reply:    Pointer to the beginning of the confirmation event
211  *            buffer. Normally bigger than an 'struct hwarc_rceb'.
212  *            You need to fill out reply->bEventType and reply->wEvent (in
213  *            cpu order) as the function will use them to verify the
214  *            confirmation event.
215  * @reply_size: Size of the reply buffer
216  *
217  * The function checks that the length returned in the reply is at
218  * least as big as @reply_size; if not, it will be deemed an error and
219  * -EIO returned.
220  *
221  * @rc needs to be referenced
222  */
uwb_rc_cmd(struct uwb_rc * rc,const char * cmd_name,struct uwb_rccb * cmd,size_t cmd_size,struct uwb_rceb * reply,size_t reply_size)223 ssize_t uwb_rc_cmd(struct uwb_rc *rc, const char *cmd_name,
224 		   struct uwb_rccb *cmd, size_t cmd_size,
225 		   struct uwb_rceb *reply, size_t reply_size)
226 {
227 	struct device *dev = &rc->uwb_dev.dev;
228 	ssize_t result;
229 
230 	result = __uwb_rc_cmd(rc, cmd_name,
231 			      cmd, cmd_size, reply, reply_size,
232 			      reply->bEventType, reply->wEvent, NULL);
233 
234 	if (result > 0 && result < reply_size) {
235 		dev_err(dev, "%s: not enough data returned for decoding reply "
236 			"(%zu bytes received vs at least %zu needed)\n",
237 			cmd_name, result, reply_size);
238 		result = -EIO;
239 	}
240 	return result;
241 }
242 EXPORT_SYMBOL_GPL(uwb_rc_cmd);
243 
244 
245 /**
246  * Generic function for issuing commands to the Radio Control
247  * Interface that return an unknown amount of data
248  *
249  * @rc:       UWB Radio Control descriptor
250  * @cmd_name: Name of the command being issued (for error messages)
251  * @cmd:      Pointer to rccb structure containing the command;
252  *            normally you embed this structure as the first member of
253  *            the full command structure.
254  * @cmd_size: Size of the whole command buffer pointed to by @cmd.
255  * @expected_type: Expected type in the return event
256  * @expected_event: Expected event code in the return event
257  * @preply:   Here a pointer to where the event data is received will
258  *            be stored. Once done with the data, free with kfree().
259  *
260  * The function checks that the length returned in the reply is at
261  * least as big as a 'struct uwb_rceb *'; if not, it will be deemed an
262  * error and -EIO returned.
263  *
264  * @rc needs to be referenced
265  */
uwb_rc_vcmd(struct uwb_rc * rc,const char * cmd_name,struct uwb_rccb * cmd,size_t cmd_size,u8 expected_type,u16 expected_event,struct uwb_rceb ** preply)266 ssize_t uwb_rc_vcmd(struct uwb_rc *rc, const char *cmd_name,
267 		    struct uwb_rccb *cmd, size_t cmd_size,
268 		    u8 expected_type, u16 expected_event,
269 		    struct uwb_rceb **preply)
270 {
271 	return __uwb_rc_cmd(rc, cmd_name, cmd, cmd_size, NULL, 0,
272 			    expected_type, expected_event, preply);
273 }
274 EXPORT_SYMBOL_GPL(uwb_rc_vcmd);
275 
276 
277 /**
278  * Reset a UWB Host Controller (and all radio settings)
279  *
280  * @rc:      Host Controller descriptor
281  * @returns: 0 if ok, < 0 errno code on error
282  *
283  * We put the command on kmalloc'ed memory as some arches cannot do
284  * USB from the stack. The reply event is copied from an stage buffer,
285  * so it can be in the stack. See WUSB1.0[8.6.2.4] for more details.
286  */
uwb_rc_reset(struct uwb_rc * rc)287 int uwb_rc_reset(struct uwb_rc *rc)
288 {
289 	int result = -ENOMEM;
290 	struct uwb_rc_evt_confirm reply;
291 	struct uwb_rccb *cmd;
292 	size_t cmd_size = sizeof(*cmd);
293 
294 	mutex_lock(&rc->uwb_dev.mutex);
295 	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
296 	if (cmd == NULL)
297 		goto error_kzalloc;
298 	cmd->bCommandType = UWB_RC_CET_GENERAL;
299 	cmd->wCommand = cpu_to_le16(UWB_RC_CMD_RESET);
300 	reply.rceb.bEventType = UWB_RC_CET_GENERAL;
301 	reply.rceb.wEvent = UWB_RC_CMD_RESET;
302 	result = uwb_rc_cmd(rc, "RESET", cmd, cmd_size,
303 			    &reply.rceb, sizeof(reply));
304 	if (result < 0)
305 		goto error_cmd;
306 	if (reply.bResultCode != UWB_RC_RES_SUCCESS) {
307 		dev_err(&rc->uwb_dev.dev,
308 			"RESET: command execution failed: %s (%d)\n",
309 			uwb_rc_strerror(reply.bResultCode), reply.bResultCode);
310 		result = -EIO;
311 	}
312 error_cmd:
313 	kfree(cmd);
314 error_kzalloc:
315 	mutex_unlock(&rc->uwb_dev.mutex);
316 	return result;
317 }
318 
uwbd_msg_handle_reset(struct uwb_event * evt)319 int uwbd_msg_handle_reset(struct uwb_event *evt)
320 {
321 	struct uwb_rc *rc = evt->rc;
322 	int ret;
323 
324 	dev_info(&rc->uwb_dev.dev, "resetting radio controller\n");
325 	ret = rc->reset(rc);
326 	if (ret) {
327 		dev_err(&rc->uwb_dev.dev, "failed to reset hardware: %d\n", ret);
328 		goto error;
329 	}
330 	return 0;
331 error:
332 	/* Nothing can be done except try the reset again. */
333 	uwb_rc_reset_all(rc);
334 	return ret;
335 }
336 
337 /**
338  * uwb_rc_reset_all - request a reset of the radio controller and PALs
339  * @rc: the radio controller of the hardware device to be reset.
340  *
341  * The full hardware reset of the radio controller and all the PALs
342  * will be scheduled.
343  */
uwb_rc_reset_all(struct uwb_rc * rc)344 void uwb_rc_reset_all(struct uwb_rc *rc)
345 {
346 	struct uwb_event *evt;
347 
348 	evt = kzalloc(sizeof(struct uwb_event), GFP_ATOMIC);
349 	if (unlikely(evt == NULL))
350 		return;
351 
352 	evt->rc = __uwb_rc_get(rc);	/* will be put by uwbd's uwbd_event_handle() */
353 	evt->ts_jiffies = jiffies;
354 	evt->type = UWB_EVT_TYPE_MSG;
355 	evt->message = UWB_EVT_MSG_RESET;
356 
357 	uwbd_event_queue(evt);
358 }
359 EXPORT_SYMBOL_GPL(uwb_rc_reset_all);
360 
uwb_rc_pre_reset(struct uwb_rc * rc)361 void uwb_rc_pre_reset(struct uwb_rc *rc)
362 {
363 	rc->stop(rc);
364 	uwbd_flush(rc);
365 
366 	uwb_radio_reset_state(rc);
367 	uwb_rsv_remove_all(rc);
368 }
369 EXPORT_SYMBOL_GPL(uwb_rc_pre_reset);
370 
uwb_rc_post_reset(struct uwb_rc * rc)371 void uwb_rc_post_reset(struct uwb_rc *rc)
372 {
373 	int ret;
374 
375 	ret = rc->start(rc);
376 	if (ret)
377 		goto error;
378 	ret = uwb_rc_mac_addr_set(rc, &rc->uwb_dev.mac_addr);
379 	if (ret)
380 		goto error;
381 	ret = uwb_rc_dev_addr_set(rc, &rc->uwb_dev.dev_addr);
382 	if (ret)
383 		goto error;
384 	return;
385 error:
386 	/* Nothing can be done except try the reset again. */
387 	uwb_rc_reset_all(rc);
388 }
389 EXPORT_SYMBOL_GPL(uwb_rc_post_reset);
390