diff options
Diffstat (limited to 'drivers/net/ieee802154')
-rw-r--r-- | drivers/net/ieee802154/adf7242.c | 3 | ||||
-rw-r--r-- | drivers/net/ieee802154/at86rf230.c | 16 | ||||
-rw-r--r-- | drivers/net/ieee802154/atusb.c | 81 | ||||
-rw-r--r-- | drivers/net/ieee802154/atusb.h | 11 | ||||
-rw-r--r-- | drivers/net/ieee802154/fakelb.c | 2 |
5 files changed, 94 insertions, 19 deletions
diff --git a/drivers/net/ieee802154/adf7242.c b/drivers/net/ieee802154/adf7242.c index 9fa7ac9f8e68..3e4c8b21403c 100644 --- a/drivers/net/ieee802154/adf7242.c +++ b/drivers/net/ieee802154/adf7242.c @@ -20,7 +20,6 @@ #include <linux/skbuff.h> #include <linux/of.h> #include <linux/irq.h> -#include <linux/delay.h> #include <linux/debugfs.h> #include <linux/bitops.h> #include <linux/ieee802154.h> @@ -874,7 +873,7 @@ static int adf7242_rx(struct adf7242_local *lp) return 0; } -static struct ieee802154_ops adf7242_ops = { +static const struct ieee802154_ops adf7242_ops = { .owner = THIS_MODULE, .xmit_sync = adf7242_xmit, .ed = adf7242_ed, diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 9f10da60e02d..057025722e3d 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -990,7 +990,12 @@ at86rf23x_set_channel(struct at86rf230_local *lp, u8 page, u8 channel) } #define AT86RF2XX_MAX_ED_LEVELS 0xF -static const s32 at86rf23x_ed_levels[AT86RF2XX_MAX_ED_LEVELS + 1] = { +static const s32 at86rf233_ed_levels[AT86RF2XX_MAX_ED_LEVELS + 1] = { + -9400, -9200, -9000, -8800, -8600, -8400, -8200, -8000, -7800, -7600, + -7400, -7200, -7000, -6800, -6600, -6400, +}; + +static const s32 at86rf231_ed_levels[AT86RF2XX_MAX_ED_LEVELS + 1] = { -9100, -8900, -8700, -8500, -8300, -8100, -7900, -7700, -7500, -7300, -7100, -6900, -6700, -6500, -6300, -6100, }; @@ -1343,7 +1348,7 @@ static struct at86rf2xx_chip_data at86rf233_data = { .t_sleep_to_off = 1000, .t_frame = 4096, .t_p_ack = 545, - .rssi_base_val = -91, + .rssi_base_val = -94, .set_channel = at86rf23x_set_channel, .set_txpower = at86rf23x_set_txpower, }; @@ -1557,9 +1562,6 @@ at86rf230_detect_device(struct at86rf230_local *lp) lp->hw->phy->supported.cca_opts = BIT(NL802154_CCA_OPT_ENERGY_CARRIER_AND) | BIT(NL802154_CCA_OPT_ENERGY_CARRIER_OR); - lp->hw->phy->supported.cca_ed_levels = at86rf23x_ed_levels; - lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf23x_ed_levels); - lp->hw->phy->cca.mode = NL802154_CCA_ENERGY; switch (part) { @@ -1575,6 +1577,8 @@ at86rf230_detect_device(struct at86rf230_local *lp) lp->hw->phy->symbol_duration = 16; lp->hw->phy->supported.tx_powers = at86rf231_powers; lp->hw->phy->supported.tx_powers_size = ARRAY_SIZE(at86rf231_powers); + lp->hw->phy->supported.cca_ed_levels = at86rf231_ed_levels; + lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf231_ed_levels); break; case 7: chip = "at86rf212"; @@ -1598,6 +1602,8 @@ at86rf230_detect_device(struct at86rf230_local *lp) lp->hw->phy->symbol_duration = 16; lp->hw->phy->supported.tx_powers = at86rf233_powers; lp->hw->phy->supported.tx_powers_size = ARRAY_SIZE(at86rf233_powers); + lp->hw->phy->supported.cca_ed_levels = at86rf233_ed_levels; + lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf233_ed_levels); break; default: chip = "unknown"; diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c index 1056ed142411..1253f864737a 100644 --- a/drivers/net/ieee802154/atusb.c +++ b/drivers/net/ieee802154/atusb.c @@ -58,6 +58,11 @@ struct atusb { struct urb *tx_urb; struct sk_buff *tx_skb; uint8_t tx_ack_seq; /* current TX ACK sequence number */ + + /* Firmware variable */ + unsigned char fw_ver_maj; /* Firmware major version number */ + unsigned char fw_ver_min; /* Firmware minor version number */ + unsigned char fw_hw_type; /* Firmware hardware type */ }; /* ----- USB commands without data ----------------------------------------- */ @@ -541,6 +546,21 @@ atusb_set_csma_params(struct ieee802154_hw *hw, u8 min_be, u8 max_be, u8 retries } static int +atusb_set_frame_retries(struct ieee802154_hw *hw, s8 retries) +{ + struct atusb *atusb = hw->priv; + struct device *dev = &atusb->usb_dev->dev; + + if (atusb->fw_ver_maj == 0 && atusb->fw_ver_min < 3) { + dev_info(dev, "Automatic frame retransmission is only available from " + "firmware version 0.3. Please update if you want this feature."); + return -EINVAL; + } + + return atusb_write_subreg(atusb, SR_MAX_FRAME_RETRIES, retries); +} + +static int atusb_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on) { struct atusb *atusb = hw->priv; @@ -567,7 +587,7 @@ atusb_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on) return 0; } -static struct ieee802154_ops atusb_ops = { +static const struct ieee802154_ops atusb_ops = { .owner = THIS_MODULE, .xmit_async = atusb_xmit, .ed = atusb_ed, @@ -579,6 +599,7 @@ static struct ieee802154_ops atusb_ops = { .set_cca_mode = atusb_set_cca_mode, .set_cca_ed_level = atusb_set_cca_ed_level, .set_csma_params = atusb_set_csma_params, + .set_frame_retries = atusb_set_frame_retries, .set_promiscuous_mode = atusb_set_promiscuous_mode, }; @@ -594,14 +615,19 @@ static int atusb_get_and_show_revision(struct atusb *atusb) ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0), ATUSB_ID, ATUSB_REQ_FROM_DEV, 0, 0, buffer, 3, 1000); - if (ret >= 0) + if (ret >= 0) { + atusb->fw_ver_maj = buffer[0]; + atusb->fw_ver_min = buffer[1]; + atusb->fw_hw_type = buffer[2]; + dev_info(&usb_dev->dev, "Firmware: major: %u, minor: %u, hardware type: %u\n", - buffer[0], buffer[1], buffer[2]); - if (buffer[0] == 0 && buffer[1] < 2) { + atusb->fw_ver_maj, atusb->fw_ver_min, atusb->fw_hw_type); + } + if (atusb->fw_ver_maj == 0 && atusb->fw_ver_min < 2) { dev_info(&usb_dev->dev, - "Firmware version (%u.%u) is predates our first public release.", - buffer[0], buffer[1]); + "Firmware version (%u.%u) predates our first public release.", + atusb->fw_ver_maj, atusb->fw_ver_min); dev_info(&usb_dev->dev, "Please update to version 0.2 or newer"); } @@ -669,6 +695,43 @@ fail: 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, @@ -707,7 +770,8 @@ static int atusb_probe(struct usb_interface *interface, hw->parent = &usb_dev->dev; hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT | - IEEE802154_HW_PROMISCUOUS | IEEE802154_HW_CSMA_PARAMS; + IEEE802154_HW_PROMISCUOUS | IEEE802154_HW_CSMA_PARAMS | + IEEE802154_HW_FRAME_RETRIES; hw->phy->flags = WPAN_PHY_FLAG_TXPOWER | WPAN_PHY_FLAG_CCA_ED_LEVEL | WPAN_PHY_FLAG_CCA_MODE; @@ -728,13 +792,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, diff --git a/drivers/net/ieee802154/atusb.h b/drivers/net/ieee802154/atusb.h index 0690edcad57b..b22bbaa77590 100644 --- a/drivers/net/ieee802154/atusb.h +++ b/drivers/net/ieee802154/atusb.h @@ -13,8 +13,8 @@ * Firmware: ben-wpan/atusb/fw/include/atusb/atusb.h */ -#ifndef _ATUSB_H -#define _ATUSB_H +#ifndef _ATUSB_H +#define _ATUSB_H #define ATUSB_VENDOR_ID 0x20b7 /* Qi Hardware*/ #define ATUSB_PRODUCT_ID 0x1540 /* 802.15.4, device 0 */ @@ -46,9 +46,12 @@ enum atusb_requests { ATUSB_SPI_WRITE2_SYNC, ATUSB_RX_MODE = 0x40, /* HardMAC group */ ATUSB_TX, + ATUSB_EUI64_WRITE = 0x50, /* Parameter in EEPROM grp */ + ATUSB_EUI64_READ, }; -/* Direction bRequest wValue wIndex wLength +/* + * Direction bRequest wValue wIndex wLength * * ->host ATUSB_ID - - 3 * ->host ATUSB_BUILD - - #bytes @@ -76,6 +79,8 @@ enum atusb_requests { * * host-> ATUSB_RX_MODE on - 0 * host-> ATUSB_TX flags ack_seq #bytes + * host-> ATUSB_EUI64_WRITE - - #bytes (8) + * ->host ATUSB_EUI64_READ - - #bytes (8) */ #define ATUSB_REQ_FROM_DEV (USB_TYPE_VENDOR | USB_DIR_IN) diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index ec387efb61d0..0d673f7682ee 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -218,7 +218,7 @@ static int fakelb_probe(struct platform_device *pdev) goto err_slave; } - dev_info(&pdev->dev, "added ieee802154 hardware\n"); + dev_info(&pdev->dev, "added %i fake ieee802154 hardware devices\n", numlbs); return 0; err_slave: |