Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142374400
D42463.id129936.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D42463.id129936.diff
View Options
diff --git a/sys/dev/usb/net/if_smsc.c b/sys/dev/usb/net/if_smsc.c
--- a/sys/dev/usb/net/if_smsc.c
+++ b/sys/dev/usb/net/if_smsc.c
@@ -179,6 +179,8 @@
#define ETHER_IS_VALID(addr) \
(!ETHER_IS_MULTICAST(addr) && !ETHER_IS_ZERO(addr))
+#define BOOTARGS_SMSC95XX "smsc95xx.macaddr"
+
static device_probe_t smsc_probe;
static device_attach_t smsc_attach;
static device_detach_t smsc_detach;
@@ -1538,6 +1540,62 @@
return (rc);
}
+#ifdef FDT
+static bool
+smsc_get_smsc95xx_macaddr(char* bootargs, size_t bootargs_len, struct usb_ether *ue)
+{
+ int values[6];
+ int i;
+ char* p;
+
+ p = strnstr(bootargs, BOOTARGS_SMSC95XX, bootargs_len);
+
+ if (p == NULL || 6 != sscanf(p, BOOTARGS_SMSC95XX "=%x:%x:%x:%x:%x:%x%*c",
+ &values[0], &values[1], &values[2],
+ &values[3], &values[4], &values[5])) {
+ smsc_err_printf((struct smsc_softc *)ue->ue_sc, "invalid mac from bootargs '%s'.\n", p);
+ return false;
+ }
+
+ for (i = 0; i < ETHER_ADDR_LEN; ++i)
+ ue->ue_eaddr[i] = values[i];
+
+ smsc_dbg_printf((struct smsc_softc *)ue->ue_sc, "bootargs mac=%x:%x:%x:%x:%x:%x.\n",
+ ue->ue_eaddr[0], ue->ue_eaddr[1], ue->ue_eaddr[2],
+ ue->ue_eaddr[3], ue->ue_eaddr[4], ue->ue_eaddr[5]);
+ return true;
+}
+
+/**
+ * Raspberry Pi is known to pass smsc95xx.macaddr=XX:XX:XX:XX:XX:XX via bootargs.
+ */
+static int
+smsc_bootargs_get_mac_addr(device_t dev, struct usb_ether *ue) {
+ char bootargs[2048]; /* early stack supposedly big enough */
+ phandle_t node;
+
+ /* only use bootargs for the first device to prevent duplicate mac addresses */
+ if (device_get_unit(dev) != 0)
+ return 1;
+ node = OF_finddevice("/chosen");
+ if (node == -1)
+ return 1;
+ if (OF_getproplen(node, "bootargs") > sizeof(bootargs)) {
+ smsc_err_printf((struct smsc_softc *)ue->ue_sc, "bootargs too large (%lu) for buffer", OF_getproplen(node, "bootargs"));
+ return 1;
+ }
+ if (OF_getprop(node, "bootargs", bootargs, sizeof(bootargs)) == -1)
+ return 1;
+ smsc_dbg_printf((struct smsc_softc *)ue->ue_sc, "bootargs: %s.\n", bootargs);
+ if (!smsc_get_smsc95xx_macaddr(bootargs, sizeof(bootargs), ue))
+ return 1;
+ device_printf(dev, "Ethernet address found in bootargs %x:%x:%x:%x:%x:%x.\n",
+ ue->ue_eaddr[0], ue->ue_eaddr[1], ue->ue_eaddr[2],
+ ue->ue_eaddr[3], ue->ue_eaddr[4], ue->ue_eaddr[5]);
+ return 0;
+}
+#endif
+
/**
* smsc_attach_post - Called after the driver attached to the USB interface
* @ue: the USB ethernet device
@@ -1552,8 +1610,10 @@
smsc_attach_post(struct usb_ether *ue)
{
struct smsc_softc *sc = uether_getsc(ue);
+ struct ether_addr eaddr;
uint32_t mac_h, mac_l;
int err;
+ int i;
smsc_dbg_printf(sc, "smsc_attach_post\n");
@@ -1585,11 +1645,14 @@
#ifdef FDT
if ((err != 0) || (!ETHER_IS_VALID(sc->sc_ue.ue_eaddr)))
err = usb_fdt_get_mac_addr(sc->sc_ue.ue_dev, &sc->sc_ue);
+ if ((err != 0) || (!ETHER_IS_VALID(sc->sc_ue.ue_eaddr)))
+ err = smsc_bootargs_get_mac_addr(sc->sc_ue.ue_dev, &sc->sc_ue);
#endif
if ((err != 0) || (!ETHER_IS_VALID(sc->sc_ue.ue_eaddr))) {
- read_random(sc->sc_ue.ue_eaddr, ETHER_ADDR_LEN);
- sc->sc_ue.ue_eaddr[0] &= ~0x01; /* unicast */
- sc->sc_ue.ue_eaddr[0] |= 0x02; /* locally administered */
+ smsc_dbg_printf(sc, "No MAC address found. Using ether_gen_addr().\n");
+ ether_gen_addr_byname(device_get_nameunit(ue->ue_dev), &eaddr);
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ sc->sc_ue.ue_eaddr[i] = eaddr.octet[i];
}
}
diff --git a/sys/net/ethernet.h b/sys/net/ethernet.h
--- a/sys/net/ethernet.h
+++ b/sys/net/ethernet.h
@@ -448,6 +448,7 @@
bool ether_8021q_frame(struct mbuf **mp, struct ifnet *ife,
struct ifnet *p, const struct ether_8021q_tag *);
void ether_gen_addr(struct ifnet *ifp, struct ether_addr *hwaddr);
+void ether_gen_addr_byname(const char *nameunit, struct ether_addr *hwaddr);
static __inline struct mbuf *ether_vlanencap(struct mbuf *m, uint16_t tag)
{
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -1489,7 +1489,7 @@
* allocate non-locally-administered addresses.
*/
void
-ether_gen_addr(struct ifnet *ifp, struct ether_addr *hwaddr)
+ether_gen_addr_byname(const char *nameunit, struct ether_addr *hwaddr)
{
SHA1_CTX ctx;
char *buf;
@@ -1508,7 +1508,7 @@
/* If each (vnet) jail would also have a unique hostuuid this would not
* be necessary. */
getjailname(curthread->td_ucred, jailname, sizeof(jailname));
- sz = asprintf(&buf, M_TEMP, "%s-%s-%s", uuid, if_name(ifp),
+ sz = asprintf(&buf, M_TEMP, "%s-%s-%s", uuid, nameunit,
jailname);
if (sz < 0) {
/* Fall back to a random mac address. */
@@ -1537,5 +1537,10 @@
hwaddr->octet[0] |= 0x02;
}
+void
+ether_gen_addr(struct ifnet *ifp, struct ether_addr *hwaddr) {
+ ether_gen_addr_byname(if_name(ifp), hwaddr);
+}
+
DECLARE_MODULE(ether, ether_mod, SI_SUB_INIT_IF, SI_ORDER_ANY);
MODULE_VERSION(ether, 1);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 20, 6:43 AM (12 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27760252
Default Alt Text
D42463.id129936.diff (4 KB)
Attached To
Mode
D42463: Teach if_smsc to get MAC from bootargs.
Attached
Detach File
Event Timeline
Log In to Comment