Skip to content

Commit c0b0479

Browse files
committed
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Johan Hedberg says: ==================== pull request: bluetooth-next 2016-04-26 Here's another set of Bluetooth & 802.15.4 patches for the 4.7 kernel: - Cleanups & refactoring of ieee802154 & 6lowpan code - Security related additions to ieee802154 and mrf24j40 driver - Memory corruption fix to Bluetooth 6lowpan code - Race condition fix in vhci driver - Enhancements to the atusb 802.15.4 driver Please let me know if there are any issues pulling. Thanks. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 9c9f261 + 5544107 commit c0b0479

File tree

19 files changed

+356
-167
lines changed

19 files changed

+356
-167
lines changed

drivers/bluetooth/ath3k.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,8 @@ static int ath3k_load_firmware(struct usb_device *udev,
206206
const struct firmware *firmware)
207207
{
208208
u8 *send_buf;
209-
int err, pipe, len, size, sent = 0;
209+
int len = 0;
210+
int err, pipe, size, sent = 0;
210211
int count = firmware->size;
211212

212213
BT_DBG("udev %p", udev);
@@ -302,7 +303,8 @@ static int ath3k_load_fwfile(struct usb_device *udev,
302303
const struct firmware *firmware)
303304
{
304305
u8 *send_buf;
305-
int err, pipe, len, size, count, sent = 0;
306+
int len = 0;
307+
int err, pipe, size, count, sent = 0;
306308
int ret;
307309

308310
count = firmware->size;

drivers/bluetooth/hci_vhci.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct vhci_data {
5050
wait_queue_head_t read_wait;
5151
struct sk_buff_head readq;
5252

53+
struct mutex open_mutex;
5354
struct delayed_work open_timeout;
5455
};
5556

@@ -87,12 +88,15 @@ static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
8788
return 0;
8889
}
8990

90-
static int vhci_create_device(struct vhci_data *data, __u8 opcode)
91+
static int __vhci_create_device(struct vhci_data *data, __u8 opcode)
9192
{
9293
struct hci_dev *hdev;
9394
struct sk_buff *skb;
9495
__u8 dev_type;
9596

97+
if (data->hdev)
98+
return -EBADFD;
99+
96100
/* bits 0-1 are dev_type (BR/EDR or AMP) */
97101
dev_type = opcode & 0x03;
98102

@@ -151,6 +155,17 @@ static int vhci_create_device(struct vhci_data *data, __u8 opcode)
151155
return 0;
152156
}
153157

158+
static int vhci_create_device(struct vhci_data *data, __u8 opcode)
159+
{
160+
int err;
161+
162+
mutex_lock(&data->open_mutex);
163+
err = __vhci_create_device(data, opcode);
164+
mutex_unlock(&data->open_mutex);
165+
166+
return err;
167+
}
168+
154169
static inline ssize_t vhci_get_user(struct vhci_data *data,
155170
struct iov_iter *from)
156171
{
@@ -191,11 +206,6 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
191206
case HCI_VENDOR_PKT:
192207
cancel_delayed_work_sync(&data->open_timeout);
193208

194-
if (data->hdev) {
195-
kfree_skb(skb);
196-
return -EBADFD;
197-
}
198-
199209
opcode = *((__u8 *) skb->data);
200210
skb_pull(skb, 1);
201211

@@ -320,6 +330,7 @@ static int vhci_open(struct inode *inode, struct file *file)
320330
skb_queue_head_init(&data->readq);
321331
init_waitqueue_head(&data->read_wait);
322332

333+
mutex_init(&data->open_mutex);
323334
INIT_DELAYED_WORK(&data->open_timeout, vhci_open_timeout);
324335

325336
file->private_data = data;

drivers/net/ieee802154/at86rf230.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,7 +1340,7 @@ static struct at86rf2xx_chip_data at86rf233_data = {
13401340
.t_off_to_aack = 80,
13411341
.t_off_to_tx_on = 80,
13421342
.t_off_to_sleep = 35,
1343-
.t_sleep_to_off = 210,
1343+
.t_sleep_to_off = 1000,
13441344
.t_frame = 4096,
13451345
.t_p_ack = 545,
13461346
.rssi_base_val = -91,
@@ -1355,7 +1355,7 @@ static struct at86rf2xx_chip_data at86rf231_data = {
13551355
.t_off_to_aack = 110,
13561356
.t_off_to_tx_on = 110,
13571357
.t_off_to_sleep = 35,
1358-
.t_sleep_to_off = 380,
1358+
.t_sleep_to_off = 1000,
13591359
.t_frame = 4096,
13601360
.t_p_ack = 545,
13611361
.rssi_base_val = -91,
@@ -1370,7 +1370,7 @@ static struct at86rf2xx_chip_data at86rf212_data = {
13701370
.t_off_to_aack = 200,
13711371
.t_off_to_tx_on = 200,
13721372
.t_off_to_sleep = 35,
1373-
.t_sleep_to_off = 380,
1373+
.t_sleep_to_off = 1000,
13741374
.t_frame = 4096,
13751375
.t_p_ack = 545,
13761376
.rssi_base_val = -100,

drivers/net/ieee802154/atusb.c

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
*
44
* Written 2013 by Werner Almesberger <[email protected]>
55
*
6+
* Copyright (c) 2015 - 2016 Stefan Schmidt <[email protected]>
7+
*
68
* This program is free software; you can redistribute it and/or
79
* modify it under the terms of the GNU General Public License as
810
* published by the Free Software Foundation, version 2
@@ -472,6 +474,76 @@ atusb_set_txpower(struct ieee802154_hw *hw, s32 mbm)
472474
return -EINVAL;
473475
}
474476

477+
#define ATUSB_MAX_ED_LEVELS 0xF
478+
static const s32 atusb_ed_levels[ATUSB_MAX_ED_LEVELS + 1] = {
479+
-9100, -8900, -8700, -8500, -8300, -8100, -7900, -7700, -7500, -7300,
480+
-7100, -6900, -6700, -6500, -6300, -6100,
481+
};
482+
483+
static int
484+
atusb_set_cca_mode(struct ieee802154_hw *hw, const struct wpan_phy_cca *cca)
485+
{
486+
struct atusb *atusb = hw->priv;
487+
u8 val;
488+
489+
/* mapping 802.15.4 to driver spec */
490+
switch (cca->mode) {
491+
case NL802154_CCA_ENERGY:
492+
val = 1;
493+
break;
494+
case NL802154_CCA_CARRIER:
495+
val = 2;
496+
break;
497+
case NL802154_CCA_ENERGY_CARRIER:
498+
switch (cca->opt) {
499+
case NL802154_CCA_OPT_ENERGY_CARRIER_AND:
500+
val = 3;
501+
break;
502+
case NL802154_CCA_OPT_ENERGY_CARRIER_OR:
503+
val = 0;
504+
break;
505+
default:
506+
return -EINVAL;
507+
}
508+
break;
509+
default:
510+
return -EINVAL;
511+
}
512+
513+
return atusb_write_subreg(atusb, SR_CCA_MODE, val);
514+
}
515+
516+
static int
517+
atusb_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm)
518+
{
519+
struct atusb *atusb = hw->priv;
520+
u32 i;
521+
522+
for (i = 0; i < hw->phy->supported.cca_ed_levels_size; i++) {
523+
if (hw->phy->supported.cca_ed_levels[i] == mbm)
524+
return atusb_write_subreg(atusb, SR_CCA_ED_THRES, i);
525+
}
526+
527+
return -EINVAL;
528+
}
529+
530+
static int
531+
atusb_set_csma_params(struct ieee802154_hw *hw, u8 min_be, u8 max_be, u8 retries)
532+
{
533+
struct atusb *atusb = hw->priv;
534+
int ret;
535+
536+
ret = atusb_write_subreg(atusb, SR_MIN_BE, min_be);
537+
if (ret)
538+
return ret;
539+
540+
ret = atusb_write_subreg(atusb, SR_MAX_BE, max_be);
541+
if (ret)
542+
return ret;
543+
544+
return atusb_write_subreg(atusb, SR_MAX_CSMA_RETRIES, retries);
545+
}
546+
475547
static int
476548
atusb_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on)
477549
{
@@ -508,6 +580,9 @@ static struct ieee802154_ops atusb_ops = {
508580
.stop = atusb_stop,
509581
.set_hw_addr_filt = atusb_set_hw_addr_filt,
510582
.set_txpower = atusb_set_txpower,
583+
.set_cca_mode = atusb_set_cca_mode,
584+
.set_cca_ed_level = atusb_set_cca_ed_level,
585+
.set_csma_params = atusb_set_csma_params,
511586
.set_promiscuous_mode = atusb_set_promiscuous_mode,
512587
};
513588

@@ -636,9 +711,20 @@ static int atusb_probe(struct usb_interface *interface,
636711

637712
hw->parent = &usb_dev->dev;
638713
hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT |
639-
IEEE802154_HW_PROMISCUOUS;
714+
IEEE802154_HW_PROMISCUOUS | IEEE802154_HW_CSMA_PARAMS;
715+
716+
hw->phy->flags = WPAN_PHY_FLAG_TXPOWER | WPAN_PHY_FLAG_CCA_ED_LEVEL |
717+
WPAN_PHY_FLAG_CCA_MODE;
718+
719+
hw->phy->supported.cca_modes = BIT(NL802154_CCA_ENERGY) |
720+
BIT(NL802154_CCA_CARRIER) | BIT(NL802154_CCA_ENERGY_CARRIER);
721+
hw->phy->supported.cca_opts = BIT(NL802154_CCA_OPT_ENERGY_CARRIER_AND) |
722+
BIT(NL802154_CCA_OPT_ENERGY_CARRIER_OR);
723+
724+
hw->phy->supported.cca_ed_levels = atusb_ed_levels;
725+
hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(atusb_ed_levels);
640726

641-
hw->phy->flags = WPAN_PHY_FLAG_TXPOWER;
727+
hw->phy->cca.mode = NL802154_CCA_ENERGY;
642728

643729
hw->phy->current_page = 0;
644730
hw->phy->current_channel = 11; /* reset default */
@@ -647,6 +733,7 @@ static int atusb_probe(struct usb_interface *interface,
647733
hw->phy->supported.tx_powers_size = ARRAY_SIZE(atusb_powers);
648734
hw->phy->transmit_power = hw->phy->supported.tx_powers[0];
649735
ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
736+
hw->phy->cca_ed_level = hw->phy->supported.cca_ed_levels[7];
650737

651738
atusb_command(atusb, ATUSB_RF_RESET, 0);
652739
atusb_get_and_show_chip(atusb);

drivers/net/ieee802154/mrf24j40.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#define REG_TXBCON0 0x1A
6262
#define REG_TXNCON 0x1B /* Transmit Normal FIFO Control */
6363
#define BIT_TXNTRIG BIT(0)
64+
#define BIT_TXNSECEN BIT(1)
6465
#define BIT_TXNACKREQ BIT(2)
6566

6667
#define REG_TXG1CON 0x1C
@@ -85,10 +86,13 @@
8586
#define REG_INTSTAT 0x31 /* Interrupt Status */
8687
#define BIT_TXNIF BIT(0)
8788
#define BIT_RXIF BIT(3)
89+
#define BIT_SECIF BIT(4)
90+
#define BIT_SECIGNORE BIT(7)
8891

8992
#define REG_INTCON 0x32 /* Interrupt Control */
9093
#define BIT_TXNIE BIT(0)
9194
#define BIT_RXIE BIT(3)
95+
#define BIT_SECIE BIT(4)
9296

9397
#define REG_GPIO 0x33 /* GPIO */
9498
#define REG_TRISGPIO 0x34 /* GPIO direction */
@@ -548,6 +552,9 @@ static void write_tx_buf_complete(void *context)
548552
u8 val = BIT_TXNTRIG;
549553
int ret;
550554

555+
if (ieee802154_is_secen(fc))
556+
val |= BIT_TXNSECEN;
557+
551558
if (ieee802154_is_ackreq(fc))
552559
val |= BIT_TXNACKREQ;
553560

@@ -616,7 +623,7 @@ static int mrf24j40_start(struct ieee802154_hw *hw)
616623

617624
/* Clear TXNIE and RXIE. Enable interrupts */
618625
return regmap_update_bits(devrec->regmap_short, REG_INTCON,
619-
BIT_TXNIE | BIT_RXIE, 0);
626+
BIT_TXNIE | BIT_RXIE | BIT_SECIE, 0);
620627
}
621628

622629
static void mrf24j40_stop(struct ieee802154_hw *hw)
@@ -1025,6 +1032,11 @@ static void mrf24j40_intstat_complete(void *context)
10251032

10261033
enable_irq(devrec->spi->irq);
10271034

1035+
/* Ignore Rx security decryption */
1036+
if (intstat & BIT_SECIF)
1037+
regmap_write_async(devrec->regmap_short, REG_SECCON0,
1038+
BIT_SECIGNORE);
1039+
10281040
/* Check for TX complete */
10291041
if (intstat & BIT_TXNIF)
10301042
ieee802154_xmit_complete(devrec->hw, devrec->tx_skb, false);

include/linux/ieee802154.h

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#define IEEE802154_ADDR_SHORT_UNSPEC 0xfffe
4848

4949
#define IEEE802154_EXTENDED_ADDR_LEN 8
50+
#define IEEE802154_SHORT_ADDR_LEN 2
5051

5152
#define IEEE802154_LIFS_PERIOD 40
5253
#define IEEE802154_SIFS_PERIOD 12
@@ -218,6 +219,7 @@ enum {
218219
/* frame control handling */
219220
#define IEEE802154_FCTL_FTYPE 0x0003
220221
#define IEEE802154_FCTL_ACKREQ 0x0020
222+
#define IEEE802154_FCTL_SECEN 0x0004
221223
#define IEEE802154_FCTL_INTRA_PAN 0x0040
222224

223225
#define IEEE802154_FTYPE_DATA 0x0001
@@ -232,6 +234,15 @@ static inline int ieee802154_is_data(__le16 fc)
232234
cpu_to_le16(IEEE802154_FTYPE_DATA);
233235
}
234236

237+
/**
238+
* ieee802154_is_secen - check if Security bit is set
239+
* @fc: frame control bytes in little-endian byteorder
240+
*/
241+
static inline bool ieee802154_is_secen(__le16 fc)
242+
{
243+
return fc & cpu_to_le16(IEEE802154_FCTL_SECEN);
244+
}
245+
235246
/**
236247
* ieee802154_is_ackreq - check if acknowledgment request bit is set
237248
* @fc: frame control bytes in little-endian byteorder
@@ -260,17 +271,17 @@ static inline bool ieee802154_is_intra_pan(__le16 fc)
260271
*
261272
* @len: psdu len with (MHR + payload + MFR)
262273
*/
263-
static inline bool ieee802154_is_valid_psdu_len(const u8 len)
274+
static inline bool ieee802154_is_valid_psdu_len(u8 len)
264275
{
265276
return (len == IEEE802154_ACK_PSDU_LEN ||
266277
(len >= IEEE802154_MIN_PSDU_LEN && len <= IEEE802154_MTU));
267278
}
268279

269280
/**
270-
* ieee802154_is_valid_psdu_len - check if extended addr is valid
281+
* ieee802154_is_valid_extended_unicast_addr - check if extended addr is valid
271282
* @addr: extended addr to check
272283
*/
273-
static inline bool ieee802154_is_valid_extended_unicast_addr(const __le64 addr)
284+
static inline bool ieee802154_is_valid_extended_unicast_addr(__le64 addr)
274285
{
275286
/* Bail out if the address is all zero, or if the group
276287
* address bit is set.
@@ -279,6 +290,34 @@ static inline bool ieee802154_is_valid_extended_unicast_addr(const __le64 addr)
279290
!(addr & cpu_to_le64(0x0100000000000000ULL)));
280291
}
281292

293+
/**
294+
* ieee802154_is_broadcast_short_addr - check if short addr is broadcast
295+
* @addr: short addr to check
296+
*/
297+
static inline bool ieee802154_is_broadcast_short_addr(__le16 addr)
298+
{
299+
return (addr == cpu_to_le16(IEEE802154_ADDR_SHORT_BROADCAST));
300+
}
301+
302+
/**
303+
* ieee802154_is_unspec_short_addr - check if short addr is unspecified
304+
* @addr: short addr to check
305+
*/
306+
static inline bool ieee802154_is_unspec_short_addr(__le16 addr)
307+
{
308+
return (addr == cpu_to_le16(IEEE802154_ADDR_SHORT_UNSPEC));
309+
}
310+
311+
/**
312+
* ieee802154_is_valid_src_short_addr - check if source short address is valid
313+
* @addr: short addr to check
314+
*/
315+
static inline bool ieee802154_is_valid_src_short_addr(__le16 addr)
316+
{
317+
return !(ieee802154_is_broadcast_short_addr(addr) ||
318+
ieee802154_is_unspec_short_addr(addr));
319+
}
320+
282321
/**
283322
* ieee802154_random_extended_addr - generates a random extended address
284323
* @addr: extended addr pointer to place the random address

0 commit comments

Comments
 (0)