Skip to content

Commit 4a52afd

Browse files
pdgendtnashif
authored andcommitted
doc: connectivity: networking: Add MAC address configuration page
Add a page with information on how ethernet drivers can be assigned a MAC address, using the MAC address configuration mechanism. Signed-off-by: Pieter De Gendt <[email protected]>
1 parent fb6e2c5 commit 4a52afd

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed

doc/connectivity/networking/api/ethernet.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Ethernet
1010
.. toctree::
1111
:maxdepth: 1
1212

13+
mac_config.rst
1314
vlan.rst
1415
lldp.rst
1516
8021Qav.rst
@@ -29,6 +30,7 @@ Zephyr supports following Ethernet features:
2930
* Promiscuous mode
3031
* TX and RX checksum offloading
3132
* MAC address filtering
33+
* :ref:`MAC address configuration <mac_address_config>`
3234
* :ref:`Virtual LANs <vlan_interface>`
3335
* :ref:`Priority queues <traffic-class-support>`
3436
* :ref:`IEEE 802.1AS (gPTP) <gptp_interface>`
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
.. _mac_address_config:
2+
3+
MAC Address Configuration
4+
*************************
5+
6+
Ethernet drivers can delegate most MAC address handling during initialization to
7+
:c:struct:`net_eth_mac_config` and :c:func:`net_eth_mac_load`. The structure
8+
is typically stored in the driver configuration and initialized with
9+
:c:macro:`NET_ETH_MAC_DT_CONFIG_INIT` or :c:macro:`NET_ETH_MAC_DT_INST_CONFIG_INIT`,
10+
which translate the devicetree properties into one of the following behaviors:
11+
12+
* :c:enumerator:`NET_ETH_MAC_STATIC` – use the full ``local-mac-address`` property.
13+
* :c:enumerator:`NET_ETH_MAC_RANDOM` – generate a random locally administered MAC address,
14+
optionally using the bytes provided in ``zephyr,mac-address-prefix`` as the first octets.
15+
* :c:enumerator:`NET_ETH_MAC_NVMEM` – read the remaining bytes from the ``"mac-address"``
16+
:ref:`NVMEM<nvmem>` cell, again optionally prefixed by ``zephyr,mac-address-prefix``.
17+
* :c:enumerator:`NET_ETH_MAC_DEFAULT` – fall back to the driver's default logic (for
18+
example, a factory-programmed MAC address stored in peripheral registers).
19+
20+
Driver integration
21+
==================
22+
23+
Embed the :c:struct:`net_eth_mac_config` structure inside the driver's configuration
24+
and a static buffer inside the driver's data:
25+
26+
.. code-block:: c
27+
28+
struct my_eth_config {
29+
struct net_eth_mac_config mac_cfg;
30+
/* more config fields */
31+
};
32+
33+
struct my_eth_data {
34+
uint8_t mac_addr[NET_ETH_ADDR_LEN];
35+
/* more data fields */
36+
};
37+
38+
static const struct my_eth_config my_eth_config_0 = {
39+
.mac_cfg = NET_ETH_MAC_DT_INST_CONFIG_INIT(0),
40+
};
41+
static struct my_eth_data my_eth_data_0;
42+
43+
During initialization, call :c:func:`net_eth_mac_load` before registering
44+
the address with the network interface. The helper copies any statically provided
45+
bytes, fills the remaining octets, and performs the necessary validation.
46+
Drivers can still fall back to SoC-specific storage when no configuration was provided:
47+
48+
.. code-block:: c
49+
50+
static int my_eth_init(const struct device *dev)
51+
{
52+
const struct my_eth_config *cfg = dev->config;
53+
struct my_eth_data *data = dev->data;
54+
int ret;
55+
56+
ret = net_eth_mac_load(&cfg->mac_cfg, data->mac_addr);
57+
if (ret == -ENODATA) {
58+
ret = my_eth_hw_read_mac(dev, data->mac_addr);
59+
}
60+
61+
return ret;
62+
}
63+
64+
static void my_eth_iface_init(struct net_if *iface)
65+
{
66+
const struct device *dev = net_if_get_device(iface);
67+
struct my_eth_data *data = dev->data;
68+
69+
net_if_set_link_addr(iface, data->mac_addr, sizeof(data->mac_addr), NET_LINK_ETHERNET);
70+
}
71+
72+
Devicetree examples
73+
===================
74+
75+
The examples below show how to pick a MAC address configuration for an ethernet controller node
76+
such as ``&eth0``.
77+
78+
Static MAC address
79+
------------------
80+
81+
.. code-block:: devicetree
82+
83+
&eth0 {
84+
local-mac-address = [00 11 22 33 44 55];
85+
};
86+
87+
Random MAC address with prefix
88+
------------------------------
89+
90+
.. code-block:: devicetree
91+
92+
&eth0 {
93+
zephyr,mac-address-prefix = [00 04 25];
94+
zephyr,random-mac-address;
95+
};
96+
97+
NVMEM-provided MAC address with prefix
98+
--------------------------------------
99+
100+
.. code-block:: devicetree
101+
102+
&eth0 {
103+
zephyr,mac-address-prefix = [00 12 34];
104+
nvmem-cells = <&macaddr_cell>;
105+
nvmem-cell-names = "mac-address";
106+
};
107+
108+
&eeprom0 {
109+
nvmem-layout {
110+
compatible = "fixed-layout";
111+
#address-cells = <1>;
112+
#size-cells = <1>;
113+
114+
macaddr_cell: cell@0 {
115+
reg = <0x0 0x6>;
116+
#nvmem-cell-cells = <0>;
117+
};
118+
};
119+
};
120+
121+
When no MAC-related properties are present, :c:func:`net_eth_mac_load` returns ``-ENODATA`` and
122+
the driver is expected to use its existing mechanism (for example, reading the hardware registers or
123+
using a build-time constant).
124+
125+
Changing the MAC address at runtime
126+
===================================
127+
128+
Applications that need to set MAC addresses dynamically (for example to adopt an address obtained
129+
from a management interface) need to enable the networking management API with
130+
:kconfig:option:`CONFIG_NET_MGMT` and use :c:macro:`net_mgmt` with
131+
:c:macro:`NET_REQUEST_ETHERNET_SET_MAC_ADDRESS`.
132+
The request internally calls the driver's :c:func:`ethernet_api.set_config` implementation.
133+
134+
.. code-block:: c
135+
136+
static int app_set_mac_address(const struct device *dev)
137+
{
138+
struct net_if *iface = net_if_lookup_by_dev(dev);
139+
struct ethernet_req_params params = {
140+
.mac_address = { { 0x02, 0x00, 0x5E, 0x01, 0x02, 0x03 } },
141+
};
142+
143+
/* Make sure the iface is down */
144+
145+
return net_mgmt(NET_REQUEST_ETHERNET_SET_MAC_ADDRESS, iface,
146+
&params, sizeof(params));
147+
}

0 commit comments

Comments
 (0)