Skip to content

Commit 6cc33eb

Browse files
Stefan Schmidtholtmann
authored andcommitted
ieee802154: atusb: try to read permanent extended address from device
With version 0.3 the atusb firmware offers an interface to read a permanent EUI64 address from the devices EEPROM. This patch checks if the firmware is new enough and tries to read out and use the address. If this does not work we fall back to the original randomly generated address. Signed-off-by: Stefan Schmidt <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent 4655156 commit 6cc33eb

File tree

1 file changed

+39
-1
lines changed

1 file changed

+39
-1
lines changed

drivers/net/ieee802154/atusb.c

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,43 @@ static int atusb_get_and_show_chip(struct atusb *atusb)
679679
return -ENODEV;
680680
}
681681

682+
static int atusb_set_extended_addr(struct atusb *atusb)
683+
{
684+
struct usb_device *usb_dev = atusb->usb_dev;
685+
unsigned char buffer[IEEE802154_EXTENDED_ADDR_LEN];
686+
__le64 extended_addr;
687+
u64 addr;
688+
int ret;
689+
690+
/* Firmware versions before 0.3 do not support the EUI64_READ command.
691+
* Just use a random address and be done */
692+
if (atusb->fw_ver_maj == 0 && atusb->fw_ver_min < 3) {
693+
ieee802154_random_extended_addr(&atusb->hw->phy->perm_extended_addr);
694+
return 0;
695+
}
696+
697+
/* Firmware is new enough so we fetch the address from EEPROM */
698+
ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
699+
ATUSB_EUI64_READ, ATUSB_REQ_FROM_DEV, 0, 0,
700+
buffer, IEEE802154_EXTENDED_ADDR_LEN, 1000);
701+
if (ret < 0)
702+
dev_err(&usb_dev->dev, "failed to fetch extended address\n");
703+
704+
memcpy(&extended_addr, buffer, IEEE802154_EXTENDED_ADDR_LEN);
705+
/* Check if read address is not empty and the unicast bit is set correctly */
706+
if (!ieee802154_is_valid_extended_unicast_addr(extended_addr)) {
707+
dev_info(&usb_dev->dev, "no permanent extended address found, random address set\n");
708+
ieee802154_random_extended_addr(&atusb->hw->phy->perm_extended_addr);
709+
} else {
710+
atusb->hw->phy->perm_extended_addr = extended_addr;
711+
addr = swab64((__force u64)atusb->hw->phy->perm_extended_addr);
712+
dev_info(&usb_dev->dev, "Read permanent extended address %8phC from device\n",
713+
&addr);
714+
}
715+
716+
return ret;
717+
}
718+
682719
/* ----- Setup ------------------------------------------------------------- */
683720

684721
static int atusb_probe(struct usb_interface *interface,
@@ -738,13 +775,14 @@ static int atusb_probe(struct usb_interface *interface,
738775
hw->phy->supported.tx_powers = atusb_powers;
739776
hw->phy->supported.tx_powers_size = ARRAY_SIZE(atusb_powers);
740777
hw->phy->transmit_power = hw->phy->supported.tx_powers[0];
741-
ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
742778
hw->phy->cca_ed_level = hw->phy->supported.cca_ed_levels[7];
743779

744780
atusb_command(atusb, ATUSB_RF_RESET, 0);
745781
atusb_get_and_show_chip(atusb);
746782
atusb_get_and_show_revision(atusb);
747783
atusb_get_and_show_build(atusb);
784+
atusb_set_extended_addr(atusb);
785+
748786
ret = atusb_get_and_clear_error(atusb);
749787
if (ret) {
750788
dev_err(&atusb->usb_dev->dev,

0 commit comments

Comments
 (0)