diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c index 9fdea642ffadd20311f8cd164519dfe306ae02cf..3ed34cc8a2f84a686266f121ead06292172222cc 100644 --- a/drivers/net/ieee802154/atusb.c +++ b/drivers/net/ieee802154/atusb.c @@ -679,6 +679,43 @@ static int atusb_get_and_show_chip(struct atusb *atusb) return -ENODEV; } +static int atusb_set_extended_addr(struct atusb *atusb) +{ + struct usb_device *usb_dev = atusb->usb_dev; + unsigned char buffer[IEEE802154_EXTENDED_ADDR_LEN]; + __le64 extended_addr; + u64 addr; + int ret; + + /* Firmware versions before 0.3 do not support the EUI64_READ command. + * Just use a random address and be done */ + if (atusb->fw_ver_maj == 0 && atusb->fw_ver_min < 3) { + ieee802154_random_extended_addr(&atusb->hw->phy->perm_extended_addr); + return 0; + } + + /* Firmware is new enough so we fetch the address from EEPROM */ + ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0), + ATUSB_EUI64_READ, ATUSB_REQ_FROM_DEV, 0, 0, + buffer, IEEE802154_EXTENDED_ADDR_LEN, 1000); + if (ret < 0) + dev_err(&usb_dev->dev, "failed to fetch extended address\n"); + + memcpy(&extended_addr, buffer, IEEE802154_EXTENDED_ADDR_LEN); + /* Check if read address is not empty and the unicast bit is set correctly */ + if (!ieee802154_is_valid_extended_unicast_addr(extended_addr)) { + dev_info(&usb_dev->dev, "no permanent extended address found, random address set\n"); + ieee802154_random_extended_addr(&atusb->hw->phy->perm_extended_addr); + } else { + atusb->hw->phy->perm_extended_addr = extended_addr; + addr = swab64((__force u64)atusb->hw->phy->perm_extended_addr); + dev_info(&usb_dev->dev, "Read permanent extended address %8phC from device\n", + &addr); + } + + return ret; +} + /* ----- Setup ------------------------------------------------------------- */ static int atusb_probe(struct usb_interface *interface, @@ -738,13 +775,14 @@ static int atusb_probe(struct usb_interface *interface, hw->phy->supported.tx_powers = atusb_powers; hw->phy->supported.tx_powers_size = ARRAY_SIZE(atusb_powers); hw->phy->transmit_power = hw->phy->supported.tx_powers[0]; - ieee802154_random_extended_addr(&hw->phy->perm_extended_addr); hw->phy->cca_ed_level = hw->phy->supported.cca_ed_levels[7]; atusb_command(atusb, ATUSB_RF_RESET, 0); atusb_get_and_show_chip(atusb); atusb_get_and_show_revision(atusb); atusb_get_and_show_build(atusb); + atusb_set_extended_addr(atusb); + ret = atusb_get_and_clear_error(atusb); if (ret) { dev_err(&atusb->usb_dev->dev,