summaryrefslogtreecommitdiff
path: root/docs/reference/class/network.rst
blob: b0f8c8b46aa17ee6404d52763525a50f0a6dfb0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
***********
USB Network
***********

Role: device only.  TinyUSB can present an Ethernet-style interface using
CDC-ECM, RNDIS, or CDC-NCM.  The application connects Ethernet frames to a
network stack such as lwIP.

Choose one driver
=================

``CFG_TUD_ECM_RNDIS`` and ``CFG_TUD_NCM`` are mutually exclusive.

* The ECM/RNDIS driver can expose separate configurations so Windows selects
  RNDIS and macOS selects ECM; Linux can use either.
* NCM aggregates Ethernet datagrams into Network Transfer Blocks and is the
  preferred starting point for current, higher-throughput designs.  Windows
  binding may require the Microsoft OS 2.0 descriptors shown by the example.

Use the matching descriptor macro: ``TUD_CDC_ECM_DESCRIPTOR``,
``TUD_RNDIS_DESCRIPTOR``, or ``TUD_CDC_NCM_DESCRIPTOR``.  Provide a unique
48-bit ``tud_network_mac_address`` and return the same address as a 12-digit
hexadecimal USB string descriptor where the class descriptor references it.

Configuration options
=====================

.. list-table::
   :header-rows: 1
   :widths: 42 16 42

   * - Option
     - Default
     - What it controls
   * - ``CFG_TUD_ECM_RNDIS`` / ``CFG_TUD_NCM``
     - ``0``
     - Selects one network class implementation.  Enabling both is a build
       error.
   * - ``CFG_TUD_NET_MTU``
     - ``1514`` bytes
     - Maximum Ethernet frame including its 14-byte Ethernet header.
   * - ``CFG_TUD_NCM_OUT_NTB_MAX_SIZE``
     - ``3200`` bytes
     - Largest host-to-device NTB received.  Linux expects at least 2048 bytes.
   * - ``CFG_TUD_NCM_IN_NTB_MAX_SIZE``
     - ``3200`` bytes
     - Largest device-to-host NTB assembled for transmission.
   * - ``CFG_TUD_NCM_OUT_NTB_N`` / ``CFG_TUD_NCM_IN_NTB_N``
     - ``1`` each
     - Number of receive/transmit NTB buffers.  Increasing these can reduce
       stalls at a proportional RAM cost; benchmark before changing them.
   * - ``CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB``
     - ``8``
     - Maximum Ethernet frames TinyUSB aggregates into a transmit NTB.
   * - ``CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB``
     - ``6``
     - Maximum frames the device tells the host to place in one receive NTB.

Frame flow
==========

For host-to-device frames, TinyUSB calls
``tud_network_recv_cb(src, size)``.  Copy or pass the frame to the network stack
and call ``tud_network_recv_renew()`` when the supplied packet storage is no
longer needed.  Return ``false`` if the frame cannot be accepted.

For device-to-host frames:

1. Call ``tud_network_can_xmit(size)``.
2. If it returns true, call ``tud_network_xmit(ref, arg)`` once.
3. TinyUSB calls ``tud_network_xmit_cb(dst, ref, arg)``; copy the complete
   Ethernet frame into ``dst`` and return its length.

Use ``tud_network_link_state()`` to notify the host when the logical or physical
link changes.  A mounted USB device is not necessarily a link-up network
interface.

.. list-table::
   :header-rows: 1
   :widths: 40 60

   * - API or callback
     - What it does
   * - ``tud_network_recv_cb()``
     - Offers one received Ethernet frame.  Return ``true`` only if the
       application accepted the buffer or copied the frame.
   * - ``tud_network_recv_renew()``
     - Releases the offered receive storage and permits the next host packet.
   * - ``tud_network_can_xmit()`` / ``tud_network_xmit()``
     - Reserves room and requests one device-to-host frame.  Call ``xmit`` only
       once after a successful capacity check.
   * - ``tud_network_xmit_cb()``
     - Copies the complete frame into TinyUSB's destination and returns its
       actual byte length.
   * - ``tud_network_init_cb()``
     - Resets the application network state when the ECM/RNDIS driver is
       initialized or reset.
   * - ``tud_network_set_packet_filter_cb()``
     - Reports NCM host filter bits so the application can adjust multicast or
       promiscuous delivery.
   * - ``tud_network_default_link_state_cb()`` /
       ``tud_network_link_state()``
     - Supplies the initial NCM link state and later sends link up/down changes
       to the host.

NCM sizing
==========

NCM buffer sizes have a direct RAM/throughput tradeoff.  The class requires an
OUT NTB size of at least 2048 bytes.  Begin with one IN and one OUT NTB, then
measure before increasing ``CFG_TUD_NCM_IN_NTB_MAX_SIZE``,
``CFG_TUD_NCM_OUT_NTB_MAX_SIZE``, or their ``*_NTB_N`` counts.  Keep descriptor
capabilities and runtime responses consistent with the enabled NCM features.

The :doc:`../../examples/device/net_lwip_webserver` example includes NCM and
ECM/RNDIS descriptor sets, lwIP integration, DHCP, DNS, link-state changes, and
host setup notes.

Specifications used: *CDC Ethernet Control Model*, Revision 1.2, and *CDC
Network Control Model*, Revision 1.0 (Errata 1).  RNDIS is a vendor protocol,
not a USB-IF CDC subclass.