1 /* $FreeBSD$ */
2 /*-
3 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 *
5 * Copyright (c) 2009 Andrew Thompson (thompsa@FreeBSD.org)
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <lwip/netifapi.h>
33
34 #include "implementation/global_implementation.h"
35 #include "net/usb_ethernet.h"
36
37 #define USE_LWIP_BUFFER 0
38
39 static usb_proc_callback_t ue_attach_post_task;
40 static usb_proc_callback_t ue_tick_task;
41 static usb_proc_callback_t ue_start_task;
42 static usb_proc_callback_t ue_stop_task;
43
44 struct netif *pnetif_usb0 = NULL;
45
46 #define IFQ_MAXLEN 50
47 int ifqmaxlen = IFQ_MAXLEN;
48
49 static void ue_init(struct los_eth_driver *sc,
50 unsigned char *enaddr,
51 int flags);
52 static void ue_start(struct los_eth_driver *sc,
53 struct eth_drv_sg *sg_list,
54 int sg_len,
55 int total_len,
56 UINTPTR key);
57 static void ue_watchdog(void *);
58 static void ue_start_task(struct usb_proc_msg *_task);
59
60 /*
61 * Return values:
62 * 0: success
63 * Else: device has been detached
64 */
65 uint8_t
uether_pause(struct usb_ether * ue,unsigned int _ticks)66 uether_pause(struct usb_ether *ue, unsigned int _ticks)
67 {
68 if (usb_proc_is_gone(&ue->ue_tq)) {
69 /* nothing to do */
70 return (1);
71 }
72 usb_pause_mtx(ue->ue_mtx, _ticks);
73 return (0);
74 }
75
76 static void
ue_queue_command(struct usb_ether * ue,usb_proc_callback_t * fn,struct usb_proc_msg * t0,struct usb_proc_msg * t1)77 ue_queue_command(struct usb_ether *ue,
78 usb_proc_callback_t *fn,
79 struct usb_proc_msg *t0, struct usb_proc_msg *t1)
80 {
81 struct usb_ether_cfg_task *task;
82
83 UE_LOCK_ASSERT(ue, MA_OWNED);
84
85 if (usb_proc_is_gone(&ue->ue_tq)) {
86 return; /* nothing to do */
87 }
88 /*
89 * NOTE: The task cannot get executed before we drop the
90 * "sc_mtx" mutex. It is safe to update fields in the message
91 * structure after that the message got queued.
92 */
93 task = (struct usb_ether_cfg_task *)
94 usb_proc_msignal(&ue->ue_tq, t0, t1);
95
96 /* Setup callback and self pointers */
97 task->hdr.pm_callback = fn;
98 task->ue = ue;
99
100 /*
101 * Start and stop must be synchronous!
102 */
103 if ((fn == ue_start_task) || (fn == ue_stop_task))
104 usb_proc_mwait(&ue->ue_tq, t0, t1);
105 }
106
107 void *
uether_getsc(struct usb_ether * ue)108 uether_getsc(struct usb_ether *ue)
109 {
110 return (ue->ue_sc);
111 }
112
113 int
uether_ifattach(struct usb_ether * ue)114 uether_ifattach(struct usb_ether *ue)
115 {
116 int ret = EFAULT;
117
118 /* check some critical parameters */
119 if ((ue->ue_dev == NULL) ||
120 (ue->ue_udev == NULL) ||
121 (ue->ue_mtx == NULL) ||
122 (ue->ue_methods == NULL))
123 return (EINVAL);
124
125 if (LOS_EventInit(&ue->ue_event) != LOS_OK) {
126 device_printf(ue->ue_dev, "event init fail\n");
127 goto error;
128 }
129
130 ret = usb_proc_create(&ue->ue_tq, ue->ue_mtx,
131 device_get_nameunit(ue->ue_dev), USB_PRI_MED);
132 if (ret)
133 {
134 device_printf(ue->ue_dev, "could not setup taskqueue\n");
135 (void)LOS_EventDestroy(&ue->ue_event);
136 goto error;
137 }
138
139 /* fork rest of the attach code */
140 UE_LOCK(ue);
141 ue_queue_command(ue, ue_attach_post_task,
142 &ue->ue_sync_task[0].hdr,
143 &ue->ue_sync_task[1].hdr);
144 UE_UNLOCK(ue);
145
146 error:
147 return (ret);
148 }
149
150 void
uether_ifattach_wait(struct usb_ether * ue)151 uether_ifattach_wait(struct usb_ether *ue)
152 {
153
154 UE_LOCK(ue);
155 usb_proc_mwait(&ue->ue_tq,
156 &ue->ue_sync_task[0].hdr,
157 &ue->ue_sync_task[1].hdr);
158 UE_UNLOCK(ue);
159 }
160
161 /* allocating space for eth_driver */
162 static struct los_eth_driver *
if_alloc(void)163 if_alloc(void)
164 {
165 struct los_eth_driver *sc;
166 struct eth_drv_sc *drv_sc;
167
168 sc = (struct los_eth_driver *)zalloc(sizeof(struct los_eth_driver));
169 if (sc == NULL) {
170 return (NULL);
171 }
172
173 drv_sc = (struct eth_drv_sc *)zalloc(sizeof(struct eth_drv_sc));
174 if (drv_sc == NULL) {
175 free(sc);
176 return (NULL);
177 }
178
179 drv_sc->funs = (struct eth_hwr_funs*)zalloc(sizeof(struct eth_hwr_funs));
180 if (drv_sc->funs == NULL) {
181 PRINTK("could not allocate eth_hwr_funs\n");
182 free(sc);
183 free(drv_sc);
184 return (NULL);
185 }
186 sc->driver_context = drv_sc;
187
188 return (sc);
189 }
190
191 static void
if_free(struct los_eth_driver * sc)192 if_free(struct los_eth_driver * sc)
193 {
194 struct eth_drv_sc *drv_sc;
195 if (sc == NULL) {
196 return;
197 }
198
199 drv_sc = (struct eth_drv_sc *)sc->driver_context;
200 if (drv_sc != NULL) {
201 if (drv_sc->funs) {
202 free(drv_sc->funs);
203 drv_sc->funs = NULL;
204 }
205 free(drv_sc);
206 sc->driver_context = NULL;
207 free(sc);
208 }
209 }
210
211 void
ue_recv(struct los_eth_driver * sc,struct eth_drv_sg * sg_list,int sg_len)212 ue_recv(struct los_eth_driver *sc,struct eth_drv_sg *sg_list,int sg_len)
213 {
214 struct eth_drv_sc *drv_sc = (struct eth_drv_sc *)sc->driver_context;
215 struct usb_ether *ue = (struct usb_ether *)drv_sc->driver_private;
216 struct pbuf *m;
217 UINT32 bytes_in_buffer;
218 UINT32 bytes_in_list;
219 UINT32 bytes_needed_list;
220 UINT32 buffer_pos = 0;
221 UINT8 *sg_buf;
222 UINT8 *hw_rxbuf;
223 int i;
224 int ret;
225
226 IF_DEQUEUE(&ue->ue_rxq, m);
227 if (m == NULL) {
228 PRINTK("no buffer! can not happen!\n");
229 /* Delete the space */
230 return;
231 }
232
233 for(i = 0; i < sg_len; ++i) {
234 bytes_in_list = 0;
235 while (bytes_in_list < sg_list[i].len) {
236 bytes_needed_list = sg_list[i].len - bytes_in_list;
237 bytes_in_buffer = m->len;
238 bytes_in_buffer -= buffer_pos;
239
240 sg_buf = (UINT8 *)(sg_list[i].buf);
241 hw_rxbuf = (UINT8 *)(m->payload);
242 if (bytes_needed_list < bytes_in_buffer) {
243 if (sg_buf != NULL) {
244 ret = memcpy_s(&sg_buf[bytes_in_list], bytes_needed_list,
245 (UINT8 *)&hw_rxbuf[buffer_pos], bytes_needed_list);
246 if (ret != EOK) {
247 goto END;
248 }
249 }
250 bytes_in_list += bytes_needed_list;
251 buffer_pos += bytes_needed_list;
252 } else {
253 if (sg_buf != NULL) {
254 ret = memcpy_s(&sg_buf[bytes_in_list], bytes_needed_list,
255 (UINT8 *)&hw_rxbuf[buffer_pos], bytes_in_buffer);
256 if (ret != EOK) {
257 goto END;
258 }
259 }
260
261 bytes_in_list += bytes_in_buffer;
262 buffer_pos = 0;
263 }
264 }
265 }
266
267 END:
268 uether_freebuf(m);
269 }
270
271 int
ue_can_send(struct los_eth_driver * sc)272 ue_can_send(struct los_eth_driver *sc)
273 {
274 (void)sc;
275 return (true);
276 }
277
278 static const char usb_eth_name[3] = "ue";
279
280 static void
ue_attach_post_task(struct usb_proc_msg * _task)281 ue_attach_post_task(struct usb_proc_msg *_task)
282 {
283 struct usb_ether_cfg_task *task =
284 (struct usb_ether_cfg_task *)_task;
285 struct usb_ether *ue = task->ue;
286 struct los_eth_driver *sc;
287 struct eth_drv_sc *drv_sc;
288 int error;
289
290 UE_UNLOCK(ue);
291
292 callout_init_mtx(&ue->ue_watchdog, ue->ue_mtx, 0);
293
294 error = 0;
295 sc = if_alloc();
296 if (sc == NULL) {
297 device_printf(ue->ue_dev, "could not allocate eth_drv_sc\n");
298 goto fail;
299 }
300
301 drv_sc = (struct eth_drv_sc *)sc->driver_context;
302 drv_sc->driver_private = ue;
303 drv_sc->dev_name = usb_eth_name;
304 if (ue->ue_methods->ue_attach_post_sub != NULL) {
305 ue->ue_drv_sc = sc;
306 error = ue->ue_methods->ue_attach_post_sub(ue);
307 } else {
308 drv_sc->funs->send = ue_start;
309 drv_sc->funs->can_send = ue_can_send;
310 drv_sc->funs->start = ue_init;
311 drv_sc->funs->recv = ue_recv;
312 drv_sc->funs->eth_drv = ð_drv_funs_usb;
313 ue->ue_drv_sc = sc;
314 }
315
316 if (error) {
317 device_printf(ue->ue_dev, "attaching PHYs failed\n");
318 goto fail;
319 }
320
321 (drv_sc->funs->eth_drv->init)(sc, ue->ue_eaddr);
322
323 if (LOS_EventWrite(&ue->ue_event, 0x01) != LOS_OK) {
324 device_printf(ue->ue_dev, "event write fail\n");
325 goto fail;
326 }
327
328 pnetif_usb0 = &sc->ac_if;
329
330 UE_LOCK(ue);
331 return;
332
333 fail:
334
335 if (ue->ue_drv_sc != NULL) {
336 if_free(sc);
337 ue->ue_drv_sc = NULL;
338 }
339 UE_LOCK(ue);
340 return;
341 }
342
343 void
uether_ifdetach(struct usb_ether * ue)344 uether_ifdetach(struct usb_ether *ue)
345 {
346 struct los_eth_driver *sc;
347 struct eth_drv_sc *drv_sc;
348 struct pbuf *m;
349
350 /* wait for any post attach or other command to complete */
351 usb_proc_drain(&ue->ue_tq);
352
353 /* read "ifnet" pointer after taskqueue drain */
354 sc = ue->ue_drv_sc;
355 if (sc != NULL) {
356 drv_sc = ( struct eth_drv_sc *)sc->driver_context;
357 /* we are not running any more */
358 UE_LOCK(ue);
359 drv_sc->state &= ~IFF_DRV_RUNNING;
360 UE_UNLOCK(ue);
361
362 /* drain any callouts */
363 callout_drain(&ue->ue_watchdog);
364
365 /* detach ethernet */
366 for (;;) {
367 UE_LOCK(ue);
368 IF_DEQUEUE(&(ue->ue_txq), m);
369 UE_UNLOCK(ue);
370 if (m == NULL)
371 break;
372 uether_freebuf(m);
373 }
374 for (;;) {
375 UE_LOCK(ue);
376 IF_DEQUEUE(&(ue->ue_rxq), m);
377 UE_UNLOCK(ue);
378 if (m == NULL)
379 break;
380 uether_freebuf(m);
381 }
382
383 (void)netifapi_dhcp_stop(&sc->ac_if);
384 (void)netifapi_dhcp_cleanup(&sc->ac_if);
385 (void)netifapi_netif_remove(&sc->ac_if);
386
387 /* free interface instance */
388 if_free(sc);
389 ue->ue_drv_sc = NULL;
390 }
391
392 /* free taskqueue, if any */
393 usb_proc_free(&ue->ue_tq);
394
395 (void)LOS_EventDestroy(&ue->ue_event);
396 }
397
398 uint8_t
uether_is_gone(struct usb_ether * ue)399 uether_is_gone(struct usb_ether *ue)
400 {
401 return (usb_proc_is_gone(&ue->ue_tq));
402 }
403
404 static void
ue_init(struct los_eth_driver * sc,unsigned char * enaddr,int flags)405 ue_init(struct los_eth_driver *sc,
406 unsigned char *enaddr,
407 int flags)
408 {
409 struct eth_drv_sc *drv_sc = (struct eth_drv_sc *)sc->driver_context;
410 struct usb_ether *ue = (struct usb_ether *)drv_sc->driver_private;
411
412 UE_LOCK(ue);
413 ue_start_task(&ue->ue_sync_task[0].hdr);
414 UE_UNLOCK(ue);
415 }
416
417 static void
ue_start_task(struct usb_proc_msg * _task)418 ue_start_task(struct usb_proc_msg *_task)
419 {
420 struct usb_ether_cfg_task *task =
421 (struct usb_ether_cfg_task *)_task;
422 struct usb_ether *ue = task->ue;
423 struct los_eth_driver *sc = ue->ue_drv_sc;
424 struct eth_drv_sc *drv_sc = (struct eth_drv_sc *)sc->driver_context;
425
426 UE_LOCK_ASSERT(ue, MA_OWNED);
427
428 ue->ue_methods->ue_init(ue);
429
430 if ((drv_sc->state & IFF_DRV_RUNNING) == 0)
431 return;
432
433 if (ue->ue_methods->ue_tick != NULL)
434 callout_reset(&ue->ue_watchdog, hz, ue_watchdog, ue);
435 }
436
437 static void
ue_stop_task(struct usb_proc_msg * _task)438 ue_stop_task(struct usb_proc_msg *_task)
439 {
440 struct usb_ether_cfg_task *task =
441 (struct usb_ether_cfg_task *)_task;
442 struct usb_ether *ue = task->ue;
443
444 UE_LOCK_ASSERT(ue, MA_OWNED);
445
446 callout_stop(&ue->ue_watchdog);
447
448 ue->ue_methods->ue_stop(ue);
449 }
450
451 static void
ue_start(struct los_eth_driver * sc,struct eth_drv_sg * sg_list,int sg_len,int total_len,UINTPTR key)452 ue_start(struct los_eth_driver *sc,
453 struct eth_drv_sg *sg_list,
454 int sg_len,
455 int total_len,
456 UINTPTR key)
457 {
458 struct eth_drv_sc *drv_sc = (struct eth_drv_sc *)sc->driver_context;
459 struct usb_ether *ue = (struct usb_ether *)drv_sc->driver_private;
460 struct pbuf *m;
461 int len = 0;
462 int i;
463 int ret;
464
465 m = uether_newbuf(total_len);
466 if (m == NULL) {
467 return;
468 }
469
470 for (i = 0; i < sg_len; i++) {
471 ret = memcpy_s((void *)((char *)m->payload + len), (size_t)(total_len - len),
472 (const void *)(sg_list[i].buf), sg_list[i].len);
473 if (ret != EOK) {
474 uether_freebuf(m);
475 return;
476 }
477 len += sg_list[i].len;
478 }
479
480 UE_LOCK(ue);
481 if ((drv_sc->state & IFF_DRV_RUNNING) == 0) {
482 UE_UNLOCK(ue);
483 uether_freebuf(m);
484 return;
485 }
486 IF_ENQUEUE(&(ue->ue_txq), m);
487
488 ue->ue_methods->ue_start(ue);
489 UE_UNLOCK(ue);
490 }
491
492 static void
ue_watchdog(void * arg)493 ue_watchdog(void *arg)
494 {
495 struct usb_ether *ue = (struct usb_ether *)arg;
496 struct los_eth_driver *sc = ue->ue_drv_sc;
497 struct eth_drv_sc *drv_sc = (struct eth_drv_sc *)sc->driver_context;
498
499 if ((drv_sc->state & IFF_DRV_RUNNING) == 0)
500 return;
501
502 ue_queue_command(ue, ue_tick_task,
503 &ue->ue_tick_task[0].hdr,
504 &ue->ue_tick_task[1].hdr);
505
506 callout_reset(&ue->ue_watchdog, hz, ue_watchdog, ue);
507 }
508
509 static void
ue_tick_task(struct usb_proc_msg * _task)510 ue_tick_task(struct usb_proc_msg *_task)
511 {
512 struct usb_ether_cfg_task *task =
513 (struct usb_ether_cfg_task *)_task;
514 struct usb_ether *ue = task->ue;
515 struct los_eth_driver *sc = ue->ue_drv_sc;
516 struct eth_drv_sc *drv_sc = (struct eth_drv_sc *)sc->driver_context;
517
518 if ((drv_sc->state & IFF_DRV_RUNNING) == 0)
519 return;
520
521 ue->ue_methods->ue_tick(ue);
522 }
523
524 #if USE_LWIP_BUFFER
525 struct pbuf *
uether_newbuf(int length)526 uether_newbuf(int length)
527 {
528 struct pbuf *m_new;
529 m_new = pbuf_alloc(PBUF_RAW, length, PBUF_RAM);
530
531 if (m_new == NULL) {
532 PRINTK("pbuf_alloc fail\n");
533 return (NULL);
534 }
535 #if ETH_PAD_SIZE
536 pbuf_header(m_new, -ETH_PAD_SIZE); /* drop the padding word */
537 #endif
538
539 return (m_new);
540 }
541 #else
542 struct pbuf *
uether_newbuf(int length)543 uether_newbuf(int length)
544 {
545 struct pbuf *m_new = (struct pbuf *)zalloc(sizeof(struct pbuf));
546 if (m_new == NULL) {
547 PRINTK("pbuf_alloc fail\n");
548 return (NULL);
549 }
550 m_new->payload = memalign(USB_CACHE_ALIGN_SIZE, SKB_DATA_ALIGN(length));
551 if (m_new->payload == NULL) {
552 PRINTK("pbuf_alloc fail\n");
553 free(m_new);
554 return (NULL);
555 }
556 (void)memset_s(m_new->payload, SKB_DATA_ALIGN(length), 0, SKB_DATA_ALIGN(length));
557
558 m_new->len = length;
559
560 return (m_new);
561 }
562
563 void
uether_freebuf(struct pbuf * buf)564 uether_freebuf(struct pbuf *buf)
565 {
566 if(buf != NULL) {
567 if(buf->payload) {
568 free(buf->payload);
569 buf->payload = NULL;
570 }
571 free(buf);
572 }
573 }
574 #endif
575 int
uether_rxmbuf(struct usb_ether * ue,struct pbuf * m,unsigned int len)576 uether_rxmbuf(struct usb_ether *ue, struct pbuf *m, unsigned int len)
577 {
578 UE_LOCK_ASSERT(ue, MA_OWNED);
579
580 m->len = len;
581
582 /* enqueue for later when the lock can be released */
583 IF_ENQUEUE(&(ue->ue_rxq), m);
584 ue->ue_rxq.ifq_head->tot_len += len;
585 return (0);
586 }
587
588 #if USE_LWIP_BUFFER
589 void
uether_rxflush(struct usb_ether * ue)590 uether_rxflush(struct usb_ether *ue)
591 {
592 struct netif *netif = &(ue->ue_drv_sc->ac_if);
593 struct pbuf *m = ue->ue_rxq.ifq_head;
594 int tot_len = 0;
595 struct pbuf *q;
596
597 UE_LOCK_ASSERT(ue, MA_OWNED);
598
599 PRINTK("uether_rxflush \n");
600 for (q = m; q != NULL; q = q->next) {
601 tot_len += q->len;
602 }
603 m->tot_len = tot_len;
604
605 #if ETH_PAD_SIZE
606 pbuf_header(m, ETH_PAD_SIZE); /* drop the padding word */
607 #endif
608
609 /*
610 * The USB xfer has been resubmitted so its safe to unlock now.
611 */
612 UE_UNLOCK(ue);
613
614 driverif_input(netif, m);
615 UE_LOCK(ue);
616 }
617 #else
618 void
uether_rxflush(struct usb_ether * ue)619 uether_rxflush(struct usb_ether *ue)
620 {
621 struct los_eth_driver *sc = ue->ue_drv_sc;
622 struct eth_drv_sc *drv_sc = (struct eth_drv_sc *)sc->driver_context;
623 struct pbuf *m;
624
625 UE_LOCK_ASSERT(ue, MA_OWNED);
626 for (;;) {
627 m = ue->ue_rxq.ifq_head;
628 if (m == NULL)
629 break;
630
631 (drv_sc->funs->eth_drv->recv)(sc, m->len);
632 }
633 }
634 #endif
635