Commit 3fb5ec06 authored by David S. Miller's avatar David S. Miller

Merge branch 'ieee802154-for-davem-2017-09-20' of...

Merge branch 'ieee802154-for-davem-2017-09-20' of git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan-next

Stefan Schmidt says:

====================
pull-request: ieee802154 2017-09-20

Here comes a pull request for ieee802154 changes I have queued up for
this merge window.

Normally these have been coming through the bluetooth tree but as this
three have been falling through the cracks so far and I have to review
and ack all of them anyway I think it makes sense if I save the
bluetooth people some work and handle them directly.

Its the first pull request I send to you so please let me know if I did
something wrong or if you prefer a different format.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents cddd9523 d5dd29e4
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
* *
* USB initialization is * USB initialization is
* Copyright (c) 2013 Alexander Aring <alex.aring@gmail.com> * Copyright (c) 2013 Alexander Aring <alex.aring@gmail.com>
*
* Busware HUL support is
* Copyright (c) 2017 Josef Filzmaier <j.filzmaier@gmx.at>
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -42,9 +45,12 @@ ...@@ -42,9 +45,12 @@
#define ATUSB_ALLOC_DELAY_MS 100 /* delay after failed allocation */ #define ATUSB_ALLOC_DELAY_MS 100 /* delay after failed allocation */
#define ATUSB_TX_TIMEOUT_MS 200 /* on the air timeout */ #define ATUSB_TX_TIMEOUT_MS 200 /* on the air timeout */
struct atusb_chip_data;
struct atusb { struct atusb {
struct ieee802154_hw *hw; struct ieee802154_hw *hw;
struct usb_device *usb_dev; struct usb_device *usb_dev;
struct atusb_chip_data *data;
int shutdown; /* non-zero if shutting down */ int shutdown; /* non-zero if shutting down */
int err; /* set by first error */ int err; /* set by first error */
...@@ -65,6 +71,14 @@ struct atusb { ...@@ -65,6 +71,14 @@ struct atusb {
unsigned char fw_hw_type; /* Firmware hardware type */ unsigned char fw_hw_type; /* Firmware hardware type */
}; };
struct atusb_chip_data {
u16 t_channel_switch;
int rssi_base_val;
int (*set_channel)(struct ieee802154_hw*, u8, u8);
int (*set_txpower)(struct ieee802154_hw*, s32);
};
/* ----- USB commands without data ----------------------------------------- */ /* ----- USB commands without data ----------------------------------------- */
/* To reduce the number of error checks in the code, we record the first error /* To reduce the number of error checks in the code, we record the first error
...@@ -163,6 +177,18 @@ static int atusb_write_subreg(struct atusb *atusb, uint8_t reg, uint8_t mask, ...@@ -163,6 +177,18 @@ static int atusb_write_subreg(struct atusb *atusb, uint8_t reg, uint8_t mask,
return ret; return ret;
} }
static int atusb_read_subreg(struct atusb *lp,
unsigned int addr, unsigned int mask,
unsigned int shift)
{
int rc;
rc = atusb_read_reg(lp, addr);
rc = (rc & mask) >> shift;
return rc;
}
static int atusb_get_and_clear_error(struct atusb *atusb) static int atusb_get_and_clear_error(struct atusb *atusb)
{ {
int err = atusb->err; int err = atusb->err;
...@@ -379,18 +405,6 @@ static int atusb_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) ...@@ -379,18 +405,6 @@ static int atusb_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
return ret; return ret;
} }
static int atusb_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
{
struct atusb *atusb = hw->priv;
int ret;
ret = atusb_write_subreg(atusb, SR_CHANNEL, channel);
if (ret < 0)
return ret;
msleep(1); /* @@@ ugly synchronization */
return 0;
}
static int atusb_ed(struct ieee802154_hw *hw, u8 *level) static int atusb_ed(struct ieee802154_hw *hw, u8 *level)
{ {
BUG_ON(!level); BUG_ON(!level);
...@@ -474,6 +488,17 @@ static const s32 atusb_powers[ATUSB_MAX_TX_POWERS + 1] = { ...@@ -474,6 +488,17 @@ static const s32 atusb_powers[ATUSB_MAX_TX_POWERS + 1] = {
-900, -1200, -1700, -900, -1200, -1700,
}; };
static int
atusb_txpower(struct ieee802154_hw *hw, s32 mbm)
{
struct atusb *atusb = hw->priv;
if (atusb->data)
return atusb->data->set_txpower(hw, mbm);
else
return -ENOTSUPP;
}
static int static int
atusb_set_txpower(struct ieee802154_hw *hw, s32 mbm) atusb_set_txpower(struct ieee802154_hw *hw, s32 mbm)
{ {
...@@ -488,12 +513,43 @@ atusb_set_txpower(struct ieee802154_hw *hw, s32 mbm) ...@@ -488,12 +513,43 @@ atusb_set_txpower(struct ieee802154_hw *hw, s32 mbm)
return -EINVAL; return -EINVAL;
} }
static int
hulusb_set_txpower(struct ieee802154_hw *hw, s32 mbm)
{
u32 i;
for (i = 0; i < hw->phy->supported.tx_powers_size; i++) {
if (hw->phy->supported.tx_powers[i] == mbm)
return atusb_write_subreg(hw->priv, SR_TX_PWR_212, i);
}
return -EINVAL;
}
#define ATUSB_MAX_ED_LEVELS 0xF #define ATUSB_MAX_ED_LEVELS 0xF
static const s32 atusb_ed_levels[ATUSB_MAX_ED_LEVELS + 1] = { static const s32 atusb_ed_levels[ATUSB_MAX_ED_LEVELS + 1] = {
-9100, -8900, -8700, -8500, -8300, -8100, -7900, -7700, -7500, -7300, -9100, -8900, -8700, -8500, -8300, -8100, -7900, -7700, -7500, -7300,
-7100, -6900, -6700, -6500, -6300, -6100, -7100, -6900, -6700, -6500, -6300, -6100,
}; };
#define AT86RF212_MAX_TX_POWERS 0x1F
static const s32 at86rf212_powers[AT86RF212_MAX_TX_POWERS + 1] = {
500, 400, 300, 200, 100, 0, -100, -200, -300, -400, -500, -600, -700,
-800, -900, -1000, -1100, -1200, -1300, -1400, -1500, -1600, -1700,
-1800, -1900, -2000, -2100, -2200, -2300, -2400, -2500, -2600,
};
#define AT86RF2XX_MAX_ED_LEVELS 0xF
static const s32 at86rf212_ed_levels_100[AT86RF2XX_MAX_ED_LEVELS + 1] = {
-10000, -9800, -9600, -9400, -9200, -9000, -8800, -8600, -8400, -8200,
-8000, -7800, -7600, -7400, -7200, -7000,
};
static const s32 at86rf212_ed_levels_98[AT86RF2XX_MAX_ED_LEVELS + 1] = {
-9800, -9600, -9400, -9200, -9000, -8800, -8600, -8400, -8200, -8000,
-7800, -7600, -7400, -7200, -7000, -6800,
};
static int static int
atusb_set_cca_mode(struct ieee802154_hw *hw, const struct wpan_phy_cca *cca) atusb_set_cca_mode(struct ieee802154_hw *hw, const struct wpan_phy_cca *cca)
{ {
...@@ -527,6 +583,30 @@ atusb_set_cca_mode(struct ieee802154_hw *hw, const struct wpan_phy_cca *cca) ...@@ -527,6 +583,30 @@ atusb_set_cca_mode(struct ieee802154_hw *hw, const struct wpan_phy_cca *cca)
return atusb_write_subreg(atusb, SR_CCA_MODE, val); return atusb_write_subreg(atusb, SR_CCA_MODE, val);
} }
static int hulusb_set_cca_ed_level(struct atusb *lp, int rssi_base_val)
{
unsigned int cca_ed_thres;
cca_ed_thres = atusb_read_subreg(lp, SR_CCA_ED_THRES);
switch (rssi_base_val) {
case -98:
lp->hw->phy->supported.cca_ed_levels = at86rf212_ed_levels_98;
lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf212_ed_levels_98);
lp->hw->phy->cca_ed_level = at86rf212_ed_levels_98[cca_ed_thres];
break;
case -100:
lp->hw->phy->supported.cca_ed_levels = at86rf212_ed_levels_100;
lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf212_ed_levels_100);
lp->hw->phy->cca_ed_level = at86rf212_ed_levels_100[cca_ed_thres];
break;
default:
WARN_ON(1);
}
return 0;
}
static int static int
atusb_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm) atusb_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm)
{ {
...@@ -541,6 +621,92 @@ atusb_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm) ...@@ -541,6 +621,92 @@ atusb_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm)
return -EINVAL; return -EINVAL;
} }
static int atusb_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
{
struct atusb *atusb = hw->priv;
int ret = -ENOTSUPP;
if (atusb->data) {
ret = atusb->data->set_channel(hw, page, channel);
/* @@@ ugly synchronization */
msleep(atusb->data->t_channel_switch);
}
return ret;
}
static int atusb_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
{
struct atusb *atusb = hw->priv;
int ret;
ret = atusb_write_subreg(atusb, SR_CHANNEL, channel);
if (ret < 0)
return ret;
return 0;
}
static int hulusb_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
{
int rc;
int rssi_base_val;
struct atusb *lp = hw->priv;
if (channel == 0)
rc = atusb_write_subreg(lp, SR_SUB_MODE, 0);
else
rc = atusb_write_subreg(lp, SR_SUB_MODE, 1);
if (rc < 0)
return rc;
if (page == 0) {
rc = atusb_write_subreg(lp, SR_BPSK_QPSK, 0);
rssi_base_val = -100;
} else {
rc = atusb_write_subreg(lp, SR_BPSK_QPSK, 1);
rssi_base_val = -98;
}
if (rc < 0)
return rc;
rc = hulusb_set_cca_ed_level(lp, rssi_base_val);
if (rc < 0)
return rc;
/* This sets the symbol_duration according frequency on the 212.
* TODO move this handling while set channel and page in cfg802154.
* We can do that, this timings are according 802.15.4 standard.
* If we do that in cfg802154, this is a more generic calculation.
*
* This should also protected from ifs_timer. Means cancel timer and
* init with a new value. For now, this is okay.
*/
if (channel == 0) {
if (page == 0) {
/* SUB:0 and BPSK:0 -> BPSK-20 */
lp->hw->phy->symbol_duration = 50;
} else {
/* SUB:1 and BPSK:0 -> BPSK-40 */
lp->hw->phy->symbol_duration = 25;
}
} else {
if (page == 0)
/* SUB:0 and BPSK:1 -> OQPSK-100/200/400 */
lp->hw->phy->symbol_duration = 40;
else
/* SUB:1 and BPSK:1 -> OQPSK-250/500/1000 */
lp->hw->phy->symbol_duration = 16;
}
lp->hw->phy->lifs_period = IEEE802154_LIFS_PERIOD *
lp->hw->phy->symbol_duration;
lp->hw->phy->sifs_period = IEEE802154_SIFS_PERIOD *
lp->hw->phy->symbol_duration;
return atusb_write_subreg(lp, SR_CHANNEL, channel);
}
static int static int
atusb_set_csma_params(struct ieee802154_hw *hw, u8 min_be, u8 max_be, u8 retries) atusb_set_csma_params(struct ieee802154_hw *hw, u8 min_be, u8 max_be, u8 retries)
{ {
...@@ -558,6 +724,14 @@ atusb_set_csma_params(struct ieee802154_hw *hw, u8 min_be, u8 max_be, u8 retries ...@@ -558,6 +724,14 @@ atusb_set_csma_params(struct ieee802154_hw *hw, u8 min_be, u8 max_be, u8 retries
return atusb_write_subreg(atusb, SR_MAX_CSMA_RETRIES, retries); return atusb_write_subreg(atusb, SR_MAX_CSMA_RETRIES, retries);
} }
static int
hulusb_set_lbt(struct ieee802154_hw *hw, bool on)
{
struct atusb *atusb = hw->priv;
return atusb_write_subreg(atusb, SR_CSMA_LBT_MODE, on);
}
static int static int
atusb_set_frame_retries(struct ieee802154_hw *hw, s8 retries) atusb_set_frame_retries(struct ieee802154_hw *hw, s8 retries)
{ {
...@@ -593,6 +767,20 @@ atusb_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on) ...@@ -593,6 +767,20 @@ atusb_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on)
return 0; return 0;
} }
struct atusb_chip_data atusb_chip_data = {
.t_channel_switch = 1,
.rssi_base_val = -91,
.set_txpower = atusb_set_txpower,
.set_channel = atusb_set_channel,
};
struct atusb_chip_data hulusb_chip_data = {
.t_channel_switch = 11,
.rssi_base_val = -100,
.set_txpower = hulusb_set_txpower,
.set_channel = hulusb_set_channel,
};
static const struct ieee802154_ops atusb_ops = { static const struct ieee802154_ops atusb_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.xmit_async = atusb_xmit, .xmit_async = atusb_xmit,
...@@ -601,7 +789,8 @@ static const struct ieee802154_ops atusb_ops = { ...@@ -601,7 +789,8 @@ static const struct ieee802154_ops atusb_ops = {
.start = atusb_start, .start = atusb_start,
.stop = atusb_stop, .stop = atusb_stop,
.set_hw_addr_filt = atusb_set_hw_addr_filt, .set_hw_addr_filt = atusb_set_hw_addr_filt,
.set_txpower = atusb_set_txpower, .set_txpower = atusb_txpower,
.set_lbt = hulusb_set_lbt,
.set_cca_mode = atusb_set_cca_mode, .set_cca_mode = atusb_set_cca_mode,
.set_cca_ed_level = atusb_set_cca_ed_level, .set_cca_ed_level = atusb_set_cca_ed_level,
.set_csma_params = atusb_set_csma_params, .set_csma_params = atusb_set_csma_params,
...@@ -614,6 +803,7 @@ static const struct ieee802154_ops atusb_ops = { ...@@ -614,6 +803,7 @@ static const struct ieee802154_ops atusb_ops = {
static int atusb_get_and_show_revision(struct atusb *atusb) static int atusb_get_and_show_revision(struct atusb *atusb)
{ {
struct usb_device *usb_dev = atusb->usb_dev; struct usb_device *usb_dev = atusb->usb_dev;
char *hw_name;
unsigned char *buffer; unsigned char *buffer;
int ret; int ret;
...@@ -630,9 +820,31 @@ static int atusb_get_and_show_revision(struct atusb *atusb) ...@@ -630,9 +820,31 @@ static int atusb_get_and_show_revision(struct atusb *atusb)
atusb->fw_ver_min = buffer[1]; atusb->fw_ver_min = buffer[1];
atusb->fw_hw_type = buffer[2]; atusb->fw_hw_type = buffer[2];
switch (atusb->fw_hw_type) {
case ATUSB_HW_TYPE_100813:
case ATUSB_HW_TYPE_101216:
case ATUSB_HW_TYPE_110131:
hw_name = "ATUSB";
atusb->data = &atusb_chip_data;
break;
case ATUSB_HW_TYPE_RZUSB:
hw_name = "RZUSB";
atusb->data = &atusb_chip_data;
break;
case ATUSB_HW_TYPE_HULUSB:
hw_name = "HULUSB";
atusb->data = &hulusb_chip_data;
break;
default:
hw_name = "UNKNOWN";
atusb->err = -ENOTSUPP;
ret = -ENOTSUPP;
break;
}
dev_info(&usb_dev->dev, dev_info(&usb_dev->dev,
"Firmware: major: %u, minor: %u, hardware type: %u\n", "Firmware: major: %u, minor: %u, hardware type: %s (%d)\n",
atusb->fw_ver_maj, atusb->fw_ver_min, atusb->fw_hw_type); atusb->fw_ver_maj, atusb->fw_ver_min, hw_name, atusb->fw_hw_type);
} }
if (atusb->fw_ver_maj == 0 && atusb->fw_ver_min < 2) { if (atusb->fw_ver_maj == 0 && atusb->fw_ver_min < 2) {
dev_info(&usb_dev->dev, dev_info(&usb_dev->dev,
...@@ -667,11 +879,12 @@ static int atusb_get_and_show_build(struct atusb *atusb) ...@@ -667,11 +879,12 @@ static int atusb_get_and_show_build(struct atusb *atusb)
return ret; return ret;
} }
static int atusb_get_and_show_chip(struct atusb *atusb) static int atusb_get_and_conf_chip(struct atusb *atusb)
{ {
struct usb_device *usb_dev = atusb->usb_dev; struct usb_device *usb_dev = atusb->usb_dev;
uint8_t man_id_0, man_id_1, part_num, version_num; uint8_t man_id_0, man_id_1, part_num, version_num;
const char *chip; const char *chip;
struct ieee802154_hw *hw = atusb->hw;
man_id_0 = atusb_read_reg(atusb, RG_MAN_ID_0); man_id_0 = atusb_read_reg(atusb, RG_MAN_ID_0);
man_id_1 = atusb_read_reg(atusb, RG_MAN_ID_1); man_id_1 = atusb_read_reg(atusb, RG_MAN_ID_1);
...@@ -681,6 +894,22 @@ static int atusb_get_and_show_chip(struct atusb *atusb) ...@@ -681,6 +894,22 @@ static int atusb_get_and_show_chip(struct atusb *atusb)
if (atusb->err) if (atusb->err)
return atusb->err; return atusb->err;
hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT |
IEEE802154_HW_PROMISCUOUS | IEEE802154_HW_CSMA_PARAMS;
hw->phy->flags = WPAN_PHY_FLAG_TXPOWER | WPAN_PHY_FLAG_CCA_ED_LEVEL |
WPAN_PHY_FLAG_CCA_MODE;
hw->phy->supported.cca_modes = BIT(NL802154_CCA_ENERGY) |
BIT(NL802154_CCA_CARRIER) |
BIT(NL802154_CCA_ENERGY_CARRIER);
hw->phy->supported.cca_opts = BIT(NL802154_CCA_OPT_ENERGY_CARRIER_AND) |
BIT(NL802154_CCA_OPT_ENERGY_CARRIER_OR);
hw->phy->cca.mode = NL802154_CCA_ENERGY;
hw->phy->current_page = 0;
if ((man_id_1 << 8 | man_id_0) != ATUSB_JEDEC_ATMEL) { if ((man_id_1 << 8 | man_id_0) != ATUSB_JEDEC_ATMEL) {
dev_err(&usb_dev->dev, dev_err(&usb_dev->dev,
"non-Atmel transceiver xxxx%02x%02x\n", "non-Atmel transceiver xxxx%02x%02x\n",
...@@ -691,9 +920,36 @@ static int atusb_get_and_show_chip(struct atusb *atusb) ...@@ -691,9 +920,36 @@ static int atusb_get_and_show_chip(struct atusb *atusb)
switch (part_num) { switch (part_num) {
case 2: case 2:
chip = "AT86RF230"; chip = "AT86RF230";
atusb->hw->phy->supported.channels[0] = 0x7FFF800;
atusb->hw->phy->current_channel = 11; /* reset default */
atusb->hw->phy->symbol_duration = 16;
atusb->hw->phy->supported.tx_powers = atusb_powers;
atusb->hw->phy->supported.tx_powers_size = ARRAY_SIZE(atusb_powers);
hw->phy->supported.cca_ed_levels = atusb_ed_levels;
hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(atusb_ed_levels);
break; break;
case 3: case 3:
chip = "AT86RF231"; chip = "AT86RF231";
atusb->hw->phy->supported.channels[0] = 0x7FFF800;
atusb->hw->phy->current_channel = 11; /* reset default */
atusb->hw->phy->symbol_duration = 16;
atusb->hw->phy->supported.tx_powers = atusb_powers;
atusb->hw->phy->supported.tx_powers_size = ARRAY_SIZE(atusb_powers);
hw->phy->supported.cca_ed_levels = atusb_ed_levels;
hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(atusb_ed_levels);
break;
case 7:
chip = "AT86RF212";
atusb->hw->flags |= IEEE802154_HW_LBT;
atusb->hw->phy->supported.channels[0] = 0x00007FF;
atusb->hw->phy->supported.channels[2] = 0x00007FF;
atusb->hw->phy->current_channel = 5;
atusb->hw->phy->symbol_duration = 25;
atusb->hw->phy->supported.lbt = NL802154_SUPPORTED_BOOL_BOTH;
atusb->hw->phy->supported.tx_powers = at86rf212_powers;
atusb->hw->phy->supported.tx_powers_size = ARRAY_SIZE(at86rf212_powers);
atusb->hw->phy->supported.cca_ed_levels = at86rf212_ed_levels_100;
atusb->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf212_ed_levels_100);
break; break;
default: default:
dev_err(&usb_dev->dev, dev_err(&usb_dev->dev,
...@@ -702,6 +958,9 @@ static int atusb_get_and_show_chip(struct atusb *atusb) ...@@ -702,6 +958,9 @@ static int atusb_get_and_show_chip(struct atusb *atusb)
goto fail; goto fail;
} }
hw->phy->transmit_power = hw->phy->supported.tx_powers[0];
hw->phy->cca_ed_level = hw->phy->supported.cca_ed_levels[7];
dev_info(&usb_dev->dev, "ATUSB: %s version %d\n", chip, version_num); dev_info(&usb_dev->dev, "ATUSB: %s version %d\n", chip, version_num);
return 0; return 0;
...@@ -794,32 +1053,9 @@ static int atusb_probe(struct usb_interface *interface, ...@@ -794,32 +1053,9 @@ static int atusb_probe(struct usb_interface *interface,
goto fail; goto fail;
hw->parent = &usb_dev->dev; hw->parent = &usb_dev->dev;
hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT |
IEEE802154_HW_PROMISCUOUS | IEEE802154_HW_CSMA_PARAMS;
hw->phy->flags = WPAN_PHY_FLAG_TXPOWER | WPAN_PHY_FLAG_CCA_ED_LEVEL |
WPAN_PHY_FLAG_CCA_MODE;
hw->phy->supported.cca_modes = BIT(NL802154_CCA_ENERGY) |
BIT(NL802154_CCA_CARRIER) | BIT(NL802154_CCA_ENERGY_CARRIER);
hw->phy->supported.cca_opts = BIT(NL802154_CCA_OPT_ENERGY_CARRIER_AND) |
BIT(NL802154_CCA_OPT_ENERGY_CARRIER_OR);
hw->phy->supported.cca_ed_levels = atusb_ed_levels;
hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(atusb_ed_levels);
hw->phy->cca.mode = NL802154_CCA_ENERGY;
hw->phy->current_page = 0;
hw->phy->current_channel = 11; /* reset default */
hw->phy->supported.channels[0] = 0x7FFF800;
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];
hw->phy->cca_ed_level = hw->phy->supported.cca_ed_levels[7];
atusb_command(atusb, ATUSB_RF_RESET, 0); atusb_command(atusb, ATUSB_RF_RESET, 0);
atusb_get_and_show_chip(atusb); atusb_get_and_conf_chip(atusb);
atusb_get_and_show_revision(atusb); atusb_get_and_show_revision(atusb);
atusb_get_and_show_build(atusb); atusb_get_and_show_build(atusb);
atusb_set_extended_addr(atusb); atusb_set_extended_addr(atusb);
...@@ -941,5 +1177,6 @@ MODULE_AUTHOR("Alexander Aring <alex.aring@gmail.com>"); ...@@ -941,5 +1177,6 @@ MODULE_AUTHOR("Alexander Aring <alex.aring@gmail.com>");
MODULE_AUTHOR("Richard Sharpe <realrichardsharpe@gmail.com>"); MODULE_AUTHOR("Richard Sharpe <realrichardsharpe@gmail.com>");
MODULE_AUTHOR("Stefan Schmidt <stefan@datenfreihafen.org>"); MODULE_AUTHOR("Stefan Schmidt <stefan@datenfreihafen.org>");
MODULE_AUTHOR("Werner Almesberger <werner@almesberger.net>"); MODULE_AUTHOR("Werner Almesberger <werner@almesberger.net>");
MODULE_AUTHOR("Josef Filzmaier <j.filzmaier@gmx.at>");
MODULE_DESCRIPTION("ATUSB IEEE 802.15.4 Driver"); MODULE_DESCRIPTION("ATUSB IEEE 802.15.4 Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -50,6 +50,14 @@ enum atusb_requests { ...@@ -50,6 +50,14 @@ enum atusb_requests {
ATUSB_EUI64_READ, ATUSB_EUI64_READ,
}; };
enum {
ATUSB_HW_TYPE_100813, /* 2010-08-13 */
ATUSB_HW_TYPE_101216, /* 2010-12-16 */
ATUSB_HW_TYPE_110131, /* 2011-01-31, ATmega32U2-based */
ATUSB_HW_TYPE_RZUSB, /* Atmel Raven USB dongle with at86rf230 */
ATUSB_HW_TYPE_HULUSB, /* Busware HUL USB dongle with at86rf212 */
};
/* /*
* Direction bRequest wValue wIndex wLength * Direction bRequest wValue wIndex wLength
* *
......
...@@ -623,13 +623,18 @@ llsec_do_encrypt_unauth(struct sk_buff *skb, const struct mac802154_llsec *sec, ...@@ -623,13 +623,18 @@ llsec_do_encrypt_unauth(struct sk_buff *skb, const struct mac802154_llsec *sec,
u8 iv[16]; u8 iv[16];
struct scatterlist src; struct scatterlist src;
SKCIPHER_REQUEST_ON_STACK(req, key->tfm0); SKCIPHER_REQUEST_ON_STACK(req, key->tfm0);
int err; int err, datalen;
unsigned char *data;
llsec_geniv(iv, sec->params.hwaddr, &hdr->sec); llsec_geniv(iv, sec->params.hwaddr, &hdr->sec);
sg_init_one(&src, skb->data, skb->len); /* Compute data payload offset and data length */
data = skb_mac_header(skb) + skb->mac_len;
datalen = skb_tail_pointer(skb) - data;
sg_init_one(&src, data, datalen);
skcipher_request_set_tfm(req, key->tfm0); skcipher_request_set_tfm(req, key->tfm0);
skcipher_request_set_callback(req, 0, NULL, NULL); skcipher_request_set_callback(req, 0, NULL, NULL);
skcipher_request_set_crypt(req, &src, &src, skb->len, iv); skcipher_request_set_crypt(req, &src, &src, datalen, iv);
err = crypto_skcipher_encrypt(req); err = crypto_skcipher_encrypt(req);
skcipher_request_zero(req); skcipher_request_zero(req);
return err; return err;
...@@ -713,7 +718,8 @@ int mac802154_llsec_encrypt(struct mac802154_llsec *sec, struct sk_buff *skb) ...@@ -713,7 +718,8 @@ int mac802154_llsec_encrypt(struct mac802154_llsec *sec, struct sk_buff *skb)
if (hlen < 0 || hdr.fc.type != IEEE802154_FC_TYPE_DATA) if (hlen < 0 || hdr.fc.type != IEEE802154_FC_TYPE_DATA)
return -EINVAL; return -EINVAL;
if (!hdr.fc.security_enabled || hdr.sec.level == 0) { if (!hdr.fc.security_enabled ||
(hdr.sec.level == IEEE802154_SCF_SECLEVEL_NONE)) {
skb_push(skb, hlen); skb_push(skb, hlen);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment