mirror of https://gitee.com/openkylin/linux.git
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Johan Hedberg says: ==================== pull request: bluetooth-next 2015-12-11 Here's another set of Bluetooth & 802.15.4 patches for the 4.5 kernel: - 6LoWPAN debugfs support - New 802.15.4 driver for ADF7242 MAC IEEE802154 - Initial code for 6LoWPAN Generic Header Compression (GHC) support - Refactor Bluetooth LE scan & advertising behind dedicated workqueue - Cleanups to Bluetooth H:5 HCI driver - Support for Toshiba Broadcom based Bluetooth controllers - Use continuous scanning when establishing Bluetooth LE connections Please let me know if there are any issues pulling. Thanks. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
5148371a75
|
@ -0,0 +1,18 @@
|
|||
* ADF7242 IEEE 802.15.4 *
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "adi,adf7242"
|
||||
- spi-max-frequency: maximal bus speed (12.5 MHz)
|
||||
- reg: the chipselect index
|
||||
- interrupts: the interrupt generated by the device via pin IRQ1.
|
||||
IRQ_TYPE_LEVEL_HIGH (4) or IRQ_TYPE_EDGE_FALLING (1)
|
||||
|
||||
Example:
|
||||
|
||||
adf7242@0 {
|
||||
compatible = "adi,adf7242";
|
||||
spi-max-frequency = <10000000>;
|
||||
reg = <0>;
|
||||
interrupts = <98 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-parent = <&gpio3>;
|
||||
};
|
|
@ -371,6 +371,15 @@ ADDRESS SPACE LAYOUT RANDOMIZATION (ASLR)
|
|||
M: Jiri Kosina <jikos@kernel.org>
|
||||
S: Maintained
|
||||
|
||||
ADF7242 IEEE 802.15.4 RADIO DRIVER
|
||||
M: Michael Hennerich <michael.hennerich@analog.com>
|
||||
W: https://wiki.analog.com/ADF7242
|
||||
W: http://ez.analog.com/community/linux-device-drivers
|
||||
L: linux-wpan@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/net/ieee802154/adf7242.c
|
||||
F: Documentation/devicetree/bindings/net/ieee802154/adf7242.txt
|
||||
|
||||
ADM1025 HARDWARE MONITOR DRIVER
|
||||
M: Jean Delvare <jdelvare@suse.com>
|
||||
L: lm-sensors@lm-sensors.org
|
||||
|
|
|
@ -73,6 +73,48 @@ int btintel_check_bdaddr(struct hci_dev *hdev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(btintel_check_bdaddr);
|
||||
|
||||
int btintel_enter_mfg(struct hci_dev *hdev)
|
||||
{
|
||||
const u8 param[] = { 0x01, 0x00 };
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_CMD_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
bt_dev_err(hdev, "Entering manufacturer mode failed (%ld)",
|
||||
PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(btintel_enter_mfg);
|
||||
|
||||
int btintel_exit_mfg(struct hci_dev *hdev, bool reset, bool patched)
|
||||
{
|
||||
u8 param[] = { 0x00, 0x00 };
|
||||
struct sk_buff *skb;
|
||||
|
||||
/* The 2nd command parameter specifies the manufacturing exit method:
|
||||
* 0x00: Just disable the manufacturing mode (0x00).
|
||||
* 0x01: Disable manufacturing mode and reset with patches deactivated.
|
||||
* 0x02: Disable manufacturing mode and reset with patches activated.
|
||||
*/
|
||||
if (reset)
|
||||
param[1] |= patched ? 0x02 : 0x01;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_CMD_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
bt_dev_err(hdev, "Exiting manufacturer mode failed (%ld)",
|
||||
PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(btintel_exit_mfg);
|
||||
|
||||
int btintel_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
@ -126,37 +168,19 @@ EXPORT_SYMBOL_GPL(btintel_set_diag);
|
|||
|
||||
int btintel_set_diag_mfg(struct hci_dev *hdev, bool enable)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
u8 param[2];
|
||||
int err;
|
||||
int err, ret;
|
||||
|
||||
param[0] = 0x01;
|
||||
param[1] = 0x00;
|
||||
err = btintel_enter_mfg(hdev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
err = PTR_ERR(skb);
|
||||
BT_ERR("%s: Entering Intel manufacturer mode failed (%d)",
|
||||
hdev->name, err);
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
kfree_skb(skb);
|
||||
ret = btintel_set_diag(hdev, enable);
|
||||
|
||||
err = btintel_set_diag(hdev, enable);
|
||||
err = btintel_exit_mfg(hdev, false, false);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
param[0] = 0x00;
|
||||
param[1] = 0x00;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
err = PTR_ERR(skb);
|
||||
BT_ERR("%s: Leaving Intel manufacturer mode failed (%d)",
|
||||
hdev->name, err);
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
kfree_skb(skb);
|
||||
|
||||
return err;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(btintel_set_diag_mfg);
|
||||
|
||||
|
@ -309,40 +333,47 @@ EXPORT_SYMBOL_GPL(btintel_set_event_mask);
|
|||
|
||||
int btintel_set_event_mask_mfg(struct hci_dev *hdev, bool debug)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
u8 param[2];
|
||||
int err;
|
||||
int err, ret;
|
||||
|
||||
param[0] = 0x01;
|
||||
param[1] = 0x00;
|
||||
err = btintel_enter_mfg(hdev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
err = PTR_ERR(skb);
|
||||
BT_ERR("%s: Entering Intel manufacturer mode failed (%d)",
|
||||
hdev->name, err);
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
kfree_skb(skb);
|
||||
ret = btintel_set_event_mask(hdev, debug);
|
||||
|
||||
err = btintel_set_event_mask(hdev, debug);
|
||||
err = btintel_exit_mfg(hdev, false, false);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
param[0] = 0x00;
|
||||
param[1] = 0x00;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
err = PTR_ERR(skb);
|
||||
BT_ERR("%s: Leaving Intel manufacturer mode failed (%d)",
|
||||
hdev->name, err);
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
kfree_skb(skb);
|
||||
|
||||
return err;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(btintel_set_event_mask_mfg);
|
||||
|
||||
int btintel_read_version(struct hci_dev *hdev, struct intel_version *ver)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_CMD_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
bt_dev_err(hdev, "Reading Intel version information failed (%ld)",
|
||||
PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
|
||||
if (skb->len != sizeof(*ver)) {
|
||||
bt_dev_err(hdev, "Intel version event size mismatch");
|
||||
kfree_skb(skb);
|
||||
return -EILSEQ;
|
||||
}
|
||||
|
||||
memcpy(ver, skb->data, sizeof(*ver));
|
||||
|
||||
kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(btintel_read_version);
|
||||
|
||||
/* ------- REGMAP IBT SUPPORT ------- */
|
||||
|
||||
#define IBT_REG_MODE_8BIT 0x00
|
||||
|
|
|
@ -72,6 +72,8 @@ struct intel_secure_send_result {
|
|||
#if IS_ENABLED(CONFIG_BT_INTEL)
|
||||
|
||||
int btintel_check_bdaddr(struct hci_dev *hdev);
|
||||
int btintel_enter_mfg(struct hci_dev *hdev);
|
||||
int btintel_exit_mfg(struct hci_dev *hdev, bool reset, bool patched);
|
||||
int btintel_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
|
||||
int btintel_set_diag(struct hci_dev *hdev, bool enable);
|
||||
int btintel_set_diag_mfg(struct hci_dev *hdev, bool enable);
|
||||
|
@ -83,6 +85,7 @@ int btintel_secure_send(struct hci_dev *hdev, u8 fragment_type, u32 plen,
|
|||
int btintel_load_ddc_config(struct hci_dev *hdev, const char *ddc_name);
|
||||
int btintel_set_event_mask(struct hci_dev *hdev, bool debug);
|
||||
int btintel_set_event_mask_mfg(struct hci_dev *hdev, bool debug);
|
||||
int btintel_read_version(struct hci_dev *hdev, struct intel_version *ver);
|
||||
|
||||
struct regmap *btintel_regmap_init(struct hci_dev *hdev, u16 opcode_read,
|
||||
u16 opcode_write);
|
||||
|
@ -94,6 +97,16 @@ static inline int btintel_check_bdaddr(struct hci_dev *hdev)
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int btintel_enter_mfg(struct hci_dev *hdev)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int btintel_exit_mfg(struct hci_dev *hdev, bool reset, bool patched)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int btintel_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
|
@ -140,6 +153,12 @@ static inline int btintel_set_event_mask_mfg(struct hci_dev *hdev, bool debug)
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int btintel_read_version(struct hci_dev *hdev,
|
||||
struct intel_version *ver)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline struct regmap *btintel_regmap_init(struct hci_dev *hdev,
|
||||
u16 opcode_read,
|
||||
u16 opcode_write)
|
||||
|
|
|
@ -153,6 +153,10 @@ static const struct usb_device_id btusb_table[] = {
|
|||
{ USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01),
|
||||
.driver_info = BTUSB_BCM_PATCHRAM },
|
||||
|
||||
/* Toshiba Corp - Broadcom based */
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(0x0930, 0xff, 0x01, 0x01),
|
||||
.driver_info = BTUSB_BCM_PATCHRAM },
|
||||
|
||||
/* Intel Bluetooth USB Bootloader (RAM module) */
|
||||
{ USB_DEVICE(0x8087, 0x0a5a),
|
||||
.driver_info = BTUSB_INTEL_BOOT | BTUSB_BROKEN_ISOC },
|
||||
|
@ -1642,13 +1646,8 @@ static int btusb_setup_intel(struct hci_dev *hdev)
|
|||
struct sk_buff *skb;
|
||||
const struct firmware *fw;
|
||||
const u8 *fw_ptr;
|
||||
int disable_patch;
|
||||
struct intel_version *ver;
|
||||
|
||||
const u8 mfg_enable[] = { 0x01, 0x00 };
|
||||
const u8 mfg_disable[] = { 0x00, 0x00 };
|
||||
const u8 mfg_reset_deactivate[] = { 0x00, 0x01 };
|
||||
const u8 mfg_reset_activate[] = { 0x00, 0x02 };
|
||||
int disable_patch, err;
|
||||
struct intel_version ver;
|
||||
|
||||
BT_DBG("%s", hdev->name);
|
||||
|
||||
|
@ -1674,35 +1673,22 @@ static int btusb_setup_intel(struct hci_dev *hdev)
|
|||
* The returned information are hardware variant and revision plus
|
||||
* firmware variant, revision and build number.
|
||||
*/
|
||||
skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
BT_ERR("%s reading Intel fw version command failed (%ld)",
|
||||
hdev->name, PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
|
||||
if (skb->len != sizeof(*ver)) {
|
||||
BT_ERR("%s Intel version event length mismatch", hdev->name);
|
||||
kfree_skb(skb);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ver = (struct intel_version *)skb->data;
|
||||
err = btintel_read_version(hdev, &ver);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
BT_INFO("%s: read Intel version: %02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
hdev->name, ver->hw_platform, ver->hw_variant,
|
||||
ver->hw_revision, ver->fw_variant, ver->fw_revision,
|
||||
ver->fw_build_num, ver->fw_build_ww, ver->fw_build_yy,
|
||||
ver->fw_patch_num);
|
||||
hdev->name, ver.hw_platform, ver.hw_variant, ver.hw_revision,
|
||||
ver.fw_variant, ver.fw_revision, ver.fw_build_num,
|
||||
ver.fw_build_ww, ver.fw_build_yy, ver.fw_patch_num);
|
||||
|
||||
/* fw_patch_num indicates the version of patch the device currently
|
||||
* have. If there is no patch data in the device, it is always 0x00.
|
||||
* So, if it is other than 0x00, no need to patch the device again.
|
||||
*/
|
||||
if (ver->fw_patch_num) {
|
||||
if (ver.fw_patch_num) {
|
||||
BT_INFO("%s: Intel device is already patched. patch num: %02x",
|
||||
hdev->name, ver->fw_patch_num);
|
||||
kfree_skb(skb);
|
||||
hdev->name, ver.fw_patch_num);
|
||||
goto complete;
|
||||
}
|
||||
|
||||
|
@ -1712,31 +1698,21 @@ static int btusb_setup_intel(struct hci_dev *hdev)
|
|||
* If no patch file is found, allow the device to operate without
|
||||
* a patch.
|
||||
*/
|
||||
fw = btusb_setup_intel_get_fw(hdev, ver);
|
||||
if (!fw) {
|
||||
kfree_skb(skb);
|
||||
fw = btusb_setup_intel_get_fw(hdev, &ver);
|
||||
if (!fw)
|
||||
goto complete;
|
||||
}
|
||||
fw_ptr = fw->data;
|
||||
|
||||
kfree_skb(skb);
|
||||
|
||||
/* This Intel specific command enables the manufacturer mode of the
|
||||
* controller.
|
||||
*
|
||||
/* Enable the manufacturer mode of the controller.
|
||||
* Only while this mode is enabled, the driver can download the
|
||||
* firmware patch data and configuration parameters.
|
||||
*/
|
||||
skb = __hci_cmd_sync(hdev, 0xfc11, 2, mfg_enable, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
BT_ERR("%s entering Intel manufacturer mode failed (%ld)",
|
||||
hdev->name, PTR_ERR(skb));
|
||||
err = btintel_enter_mfg(hdev);
|
||||
if (err) {
|
||||
release_firmware(fw);
|
||||
return PTR_ERR(skb);
|
||||
return err;
|
||||
}
|
||||
|
||||
kfree_skb(skb);
|
||||
|
||||
disable_patch = 1;
|
||||
|
||||
/* The firmware data file consists of list of Intel specific HCI
|
||||
|
@ -1776,14 +1752,9 @@ static int btusb_setup_intel(struct hci_dev *hdev)
|
|||
/* Patching completed successfully and disable the manufacturer mode
|
||||
* with reset and activate the downloaded firmware patches.
|
||||
*/
|
||||
skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_reset_activate),
|
||||
mfg_reset_activate, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
|
||||
hdev->name, PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
kfree_skb(skb);
|
||||
err = btintel_exit_mfg(hdev, true, true);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
BT_INFO("%s: Intel Bluetooth firmware patch completed and activated",
|
||||
hdev->name);
|
||||
|
@ -1792,14 +1763,9 @@ static int btusb_setup_intel(struct hci_dev *hdev)
|
|||
|
||||
exit_mfg_disable:
|
||||
/* Disable the manufacturer mode without reset */
|
||||
skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_disable), mfg_disable,
|
||||
HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
|
||||
hdev->name, PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
kfree_skb(skb);
|
||||
err = btintel_exit_mfg(hdev, false, false);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name);
|
||||
|
||||
|
@ -1811,14 +1777,9 @@ static int btusb_setup_intel(struct hci_dev *hdev)
|
|||
/* Patching failed. Disable the manufacturer mode with reset and
|
||||
* deactivate the downloaded firmware patches.
|
||||
*/
|
||||
skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_reset_deactivate),
|
||||
mfg_reset_deactivate, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
|
||||
hdev->name, PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
kfree_skb(skb);
|
||||
err = btintel_exit_mfg(hdev, true, false);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated",
|
||||
hdev->name);
|
||||
|
@ -2005,7 +1966,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
|
|||
0x00, 0x08, 0x04, 0x00 };
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
struct sk_buff *skb;
|
||||
struct intel_version *ver;
|
||||
struct intel_version ver;
|
||||
struct intel_boot_params *params;
|
||||
const struct firmware *fw;
|
||||
const u8 *fw_ptr;
|
||||
|
@ -2023,28 +1984,16 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
|
|||
* is in bootloader mode or if it already has operational firmware
|
||||
* loaded.
|
||||
*/
|
||||
skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
BT_ERR("%s: Reading Intel version information failed (%ld)",
|
||||
hdev->name, PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
|
||||
if (skb->len != sizeof(*ver)) {
|
||||
BT_ERR("%s: Intel version event size mismatch", hdev->name);
|
||||
kfree_skb(skb);
|
||||
return -EILSEQ;
|
||||
}
|
||||
|
||||
ver = (struct intel_version *)skb->data;
|
||||
err = btintel_read_version(hdev, &ver);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* The hardware platform number has a fixed value of 0x37 and
|
||||
* for now only accept this single value.
|
||||
*/
|
||||
if (ver->hw_platform != 0x37) {
|
||||
if (ver.hw_platform != 0x37) {
|
||||
BT_ERR("%s: Unsupported Intel hardware platform (%u)",
|
||||
hdev->name, ver->hw_platform);
|
||||
kfree_skb(skb);
|
||||
hdev->name, ver.hw_platform);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -2053,14 +2002,13 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
|
|||
* put in place to ensure correct forward compatibility options
|
||||
* when newer hardware variants come along.
|
||||
*/
|
||||
if (ver->hw_variant != 0x0b) {
|
||||
if (ver.hw_variant != 0x0b) {
|
||||
BT_ERR("%s: Unsupported Intel hardware variant (%u)",
|
||||
hdev->name, ver->hw_variant);
|
||||
kfree_skb(skb);
|
||||
hdev->name, ver.hw_variant);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
btintel_version_info(hdev, ver);
|
||||
btintel_version_info(hdev, &ver);
|
||||
|
||||
/* The firmware variant determines if the device is in bootloader
|
||||
* mode or is running operational firmware. The value 0x06 identifies
|
||||
|
@ -2075,8 +2023,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
|
|||
* It is not possible to use the Secure Boot Parameters in this
|
||||
* case since that command is only available in bootloader mode.
|
||||
*/
|
||||
if (ver->fw_variant == 0x23) {
|
||||
kfree_skb(skb);
|
||||
if (ver.fw_variant == 0x23) {
|
||||
clear_bit(BTUSB_BOOTLOADER, &data->flags);
|
||||
btintel_check_bdaddr(hdev);
|
||||
return 0;
|
||||
|
@ -2085,15 +2032,12 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
|
|||
/* If the device is not in bootloader mode, then the only possible
|
||||
* choice is to return an error and abort the device initialization.
|
||||
*/
|
||||
if (ver->fw_variant != 0x06) {
|
||||
if (ver.fw_variant != 0x06) {
|
||||
BT_ERR("%s: Unsupported Intel firmware variant (%u)",
|
||||
hdev->name, ver->fw_variant);
|
||||
kfree_skb(skb);
|
||||
hdev->name, ver.fw_variant);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
kfree_skb(skb);
|
||||
|
||||
/* Read the secure boot parameters to identify the operating
|
||||
* details of the bootloader.
|
||||
*/
|
||||
|
|
|
@ -116,18 +116,14 @@ static void h5_link_control(struct hci_uart *hu, const void *data, size_t len)
|
|||
|
||||
static u8 h5_cfg_field(struct h5 *h5)
|
||||
{
|
||||
u8 field = 0;
|
||||
|
||||
/* Sliding window size (first 3 bits) */
|
||||
field |= (h5->tx_win & 0x07);
|
||||
|
||||
return field;
|
||||
return h5->tx_win & 0x07;
|
||||
}
|
||||
|
||||
static void h5_timed_event(unsigned long arg)
|
||||
{
|
||||
const unsigned char sync_req[] = { 0x01, 0x7e };
|
||||
unsigned char conf_req[] = { 0x03, 0xfc, 0x01 };
|
||||
unsigned char conf_req[3] = { 0x03, 0xfc };
|
||||
struct hci_uart *hu = (struct hci_uart *)arg;
|
||||
struct h5 *h5 = hu->priv;
|
||||
struct sk_buff *skb;
|
||||
|
@ -285,7 +281,7 @@ static void h5_handle_internal_rx(struct hci_uart *hu)
|
|||
struct h5 *h5 = hu->priv;
|
||||
const unsigned char sync_req[] = { 0x01, 0x7e };
|
||||
const unsigned char sync_rsp[] = { 0x02, 0x7d };
|
||||
unsigned char conf_req[] = { 0x03, 0xfc, 0x01 };
|
||||
unsigned char conf_req[3] = { 0x03, 0xfc };
|
||||
const unsigned char conf_rsp[] = { 0x04, 0x7b };
|
||||
const unsigned char wakeup_req[] = { 0x05, 0xfa };
|
||||
const unsigned char woken_req[] = { 0x06, 0xf9 };
|
||||
|
@ -317,7 +313,7 @@ static void h5_handle_internal_rx(struct hci_uart *hu)
|
|||
h5_link_control(hu, conf_req, 3);
|
||||
} else if (memcmp(data, conf_rsp, 2) == 0) {
|
||||
if (H5_HDR_LEN(hdr) > 2)
|
||||
h5->tx_win = (data[2] & 7);
|
||||
h5->tx_win = (data[2] & 0x07);
|
||||
BT_DBG("Three-wire init complete. tx_win %u", h5->tx_win);
|
||||
h5->state = H5_ACTIVE;
|
||||
hci_uart_init_ready(hu);
|
||||
|
|
|
@ -502,7 +502,7 @@ static int intel_set_baudrate(struct hci_uart *hu, unsigned int speed)
|
|||
/* Device will not accept speed change if Intel version has not been
|
||||
* previously requested.
|
||||
*/
|
||||
skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT);
|
||||
skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_CMD_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
bt_dev_err(hdev, "Reading Intel version information failed (%ld)",
|
||||
PTR_ERR(skb));
|
||||
|
@ -542,7 +542,7 @@ static int intel_setup(struct hci_uart *hu)
|
|||
struct intel_device *idev = NULL;
|
||||
struct hci_dev *hdev = hu->hdev;
|
||||
struct sk_buff *skb;
|
||||
struct intel_version *ver;
|
||||
struct intel_version ver;
|
||||
struct intel_boot_params *params;
|
||||
struct list_head *p;
|
||||
const struct firmware *fw;
|
||||
|
@ -590,35 +590,16 @@ static int intel_setup(struct hci_uart *hu)
|
|||
* is in bootloader mode or if it already has operational firmware
|
||||
* loaded.
|
||||
*/
|
||||
skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
bt_dev_err(hdev, "Reading Intel version information failed (%ld)",
|
||||
PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
|
||||
if (skb->len != sizeof(*ver)) {
|
||||
bt_dev_err(hdev, "Intel version event size mismatch");
|
||||
kfree_skb(skb);
|
||||
return -EILSEQ;
|
||||
}
|
||||
|
||||
ver = (struct intel_version *)skb->data;
|
||||
if (ver->status) {
|
||||
bt_dev_err(hdev, "Intel version command failure (%02x)",
|
||||
ver->status);
|
||||
err = -bt_to_errno(ver->status);
|
||||
kfree_skb(skb);
|
||||
err = btintel_read_version(hdev, &ver);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* The hardware platform number has a fixed value of 0x37 and
|
||||
* for now only accept this single value.
|
||||
*/
|
||||
if (ver->hw_platform != 0x37) {
|
||||
if (ver.hw_platform != 0x37) {
|
||||
bt_dev_err(hdev, "Unsupported Intel hardware platform (%u)",
|
||||
ver->hw_platform);
|
||||
kfree_skb(skb);
|
||||
ver.hw_platform);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -627,14 +608,13 @@ static int intel_setup(struct hci_uart *hu)
|
|||
* put in place to ensure correct forward compatibility options
|
||||
* when newer hardware variants come along.
|
||||
*/
|
||||
if (ver->hw_variant != 0x0b) {
|
||||
if (ver.hw_variant != 0x0b) {
|
||||
bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)",
|
||||
ver->hw_variant);
|
||||
kfree_skb(skb);
|
||||
ver.hw_variant);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
btintel_version_info(hdev, ver);
|
||||
btintel_version_info(hdev, &ver);
|
||||
|
||||
/* The firmware variant determines if the device is in bootloader
|
||||
* mode or is running operational firmware. The value 0x06 identifies
|
||||
|
@ -649,8 +629,7 @@ static int intel_setup(struct hci_uart *hu)
|
|||
* It is not possible to use the Secure Boot Parameters in this
|
||||
* case since that command is only available in bootloader mode.
|
||||
*/
|
||||
if (ver->fw_variant == 0x23) {
|
||||
kfree_skb(skb);
|
||||
if (ver.fw_variant == 0x23) {
|
||||
clear_bit(STATE_BOOTLOADER, &intel->flags);
|
||||
btintel_check_bdaddr(hdev);
|
||||
return 0;
|
||||
|
@ -659,19 +638,16 @@ static int intel_setup(struct hci_uart *hu)
|
|||
/* If the device is not in bootloader mode, then the only possible
|
||||
* choice is to return an error and abort the device initialization.
|
||||
*/
|
||||
if (ver->fw_variant != 0x06) {
|
||||
if (ver.fw_variant != 0x06) {
|
||||
bt_dev_err(hdev, "Unsupported Intel firmware variant (%u)",
|
||||
ver->fw_variant);
|
||||
kfree_skb(skb);
|
||||
ver.fw_variant);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
kfree_skb(skb);
|
||||
|
||||
/* Read the secure boot parameters to identify the operating
|
||||
* details of the bootloader.
|
||||
*/
|
||||
skb = __hci_cmd_sync(hdev, 0xfc0d, 0, NULL, HCI_INIT_TIMEOUT);
|
||||
skb = __hci_cmd_sync(hdev, 0xfc0d, 0, NULL, HCI_CMD_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
bt_dev_err(hdev, "Reading Intel boot parameters failed (%ld)",
|
||||
PTR_ERR(skb));
|
||||
|
@ -881,7 +857,7 @@ static int intel_setup(struct hci_uart *hu)
|
|||
set_bit(STATE_BOOTING, &intel->flags);
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfc01, sizeof(reset_param), reset_param,
|
||||
HCI_INIT_TIMEOUT);
|
||||
HCI_CMD_TIMEOUT);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
|
|
|
@ -462,13 +462,7 @@ static int hci_uart_tty_open(struct tty_struct *tty)
|
|||
INIT_WORK(&hu->init_ready, hci_uart_init_work);
|
||||
INIT_WORK(&hu->write_work, hci_uart_write_work);
|
||||
|
||||
/* Flush any pending characters in the driver and line discipline. */
|
||||
|
||||
/* FIXME: why is this needed. Note don't use ldisc_ref here as the
|
||||
open path is before the ldisc is referencable */
|
||||
|
||||
if (tty->ldisc->ops->flush_buffer)
|
||||
tty->ldisc->ops->flush_buffer(tty);
|
||||
/* Flush any pending characters in the driver */
|
||||
tty_driver_flush_buffer(tty);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -71,3 +71,14 @@ config IEEE802154_ATUSB
|
|||
|
||||
This driver can also be built as a module. To do so say M here.
|
||||
The module will be called 'atusb'.
|
||||
|
||||
config IEEE802154_ADF7242
|
||||
tristate "ADF7242 transceiver driver"
|
||||
depends on IEEE802154_DRIVERS && MAC802154
|
||||
depends on SPI
|
||||
---help---
|
||||
Say Y here to enable the ADF7242 SPI 802.15.4 wireless
|
||||
controller.
|
||||
|
||||
This driver can also be built as a module. To do so, say M here.
|
||||
the module will be called 'adf7242'.
|
||||
|
|
|
@ -3,3 +3,4 @@ obj-$(CONFIG_IEEE802154_AT86RF230) += at86rf230.o
|
|||
obj-$(CONFIG_IEEE802154_MRF24J40) += mrf24j40.o
|
||||
obj-$(CONFIG_IEEE802154_CC2520) += cc2520.o
|
||||
obj-$(CONFIG_IEEE802154_ATUSB) += atusb.o
|
||||
obj-$(CONFIG_IEEE802154_ADF7242) += adf7242.o
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -310,8 +310,7 @@ static void atusb_free_urbs(struct atusb *atusb)
|
|||
urb = usb_get_from_anchor(&atusb->idle_urbs);
|
||||
if (!urb)
|
||||
break;
|
||||
if (urb->context)
|
||||
kfree_skb(urb->context);
|
||||
kfree_skb(urb->context);
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,8 @@
|
|||
#ifndef __6LOWPAN_H__
|
||||
#define __6LOWPAN_H__
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
|
||||
#include <net/ipv6.h>
|
||||
#include <net/net_namespace.h>
|
||||
|
||||
|
@ -98,6 +100,7 @@ enum lowpan_lltypes {
|
|||
|
||||
struct lowpan_priv {
|
||||
enum lowpan_lltypes lltype;
|
||||
struct dentry *iface_debugfs;
|
||||
|
||||
/* must be last */
|
||||
u8 priv[0] __aligned(sizeof(void *));
|
||||
|
@ -185,7 +188,12 @@ static inline void lowpan_push_hc_data(u8 **hc_ptr, const void *data,
|
|||
*hc_ptr += len;
|
||||
}
|
||||
|
||||
void lowpan_netdev_setup(struct net_device *dev, enum lowpan_lltypes lltype);
|
||||
int lowpan_register_netdevice(struct net_device *dev,
|
||||
enum lowpan_lltypes lltype);
|
||||
int lowpan_register_netdev(struct net_device *dev,
|
||||
enum lowpan_lltypes lltype);
|
||||
void lowpan_unregister_netdevice(struct net_device *dev);
|
||||
void lowpan_unregister_netdev(struct net_device *dev);
|
||||
|
||||
/**
|
||||
* lowpan_header_decompress - replace 6LoWPAN header with IPv6 header
|
||||
|
|
|
@ -239,7 +239,6 @@ enum {
|
|||
HCI_LE_ENABLED,
|
||||
HCI_ADVERTISING,
|
||||
HCI_ADVERTISING_CONNECTABLE,
|
||||
HCI_ADVERTISING_INSTANCE,
|
||||
HCI_CONNECTABLE,
|
||||
HCI_DISCOVERABLE,
|
||||
HCI_LIMITED_DISCOVERABLE,
|
||||
|
|
|
@ -329,6 +329,9 @@ struct hci_dev {
|
|||
|
||||
struct work_struct discov_update;
|
||||
struct work_struct bg_scan_update;
|
||||
struct work_struct scan_update;
|
||||
struct work_struct connectable_update;
|
||||
struct work_struct discoverable_update;
|
||||
struct delayed_work le_scan_disable;
|
||||
struct delayed_work le_scan_restart;
|
||||
|
||||
|
@ -1432,10 +1435,8 @@ int mgmt_new_settings(struct hci_dev *hdev);
|
|||
void mgmt_index_added(struct hci_dev *hdev);
|
||||
void mgmt_index_removed(struct hci_dev *hdev);
|
||||
void mgmt_set_powered_failed(struct hci_dev *hdev, int err);
|
||||
int mgmt_powered(struct hci_dev *hdev, u8 powered);
|
||||
int mgmt_update_adv_data(struct hci_dev *hdev);
|
||||
void mgmt_discoverable_timeout(struct hci_dev *hdev);
|
||||
void mgmt_adv_timeout_expired(struct hci_dev *hdev);
|
||||
void mgmt_power_on(struct hci_dev *hdev, int err);
|
||||
void __mgmt_power_off(struct hci_dev *hdev);
|
||||
void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
|
||||
bool persistent);
|
||||
void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn,
|
||||
|
@ -1490,8 +1491,15 @@ void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
|
|||
void mgmt_new_conn_param(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
||||
u8 bdaddr_type, u8 store_hint, u16 min_interval,
|
||||
u16 max_interval, u16 latency, u16 timeout);
|
||||
void mgmt_reenable_advertising(struct hci_dev *hdev);
|
||||
void mgmt_smp_complete(struct hci_conn *conn, bool complete);
|
||||
bool mgmt_get_connectable(struct hci_dev *hdev);
|
||||
void mgmt_set_connectable_complete(struct hci_dev *hdev, u8 status);
|
||||
void mgmt_set_discoverable_complete(struct hci_dev *hdev, u8 status);
|
||||
u8 mgmt_get_adv_discov_flags(struct hci_dev *hdev);
|
||||
void mgmt_advertising_added(struct sock *sk, struct hci_dev *hdev,
|
||||
u8 instance);
|
||||
void mgmt_advertising_removed(struct sock *sk, struct hci_dev *hdev,
|
||||
u8 instance);
|
||||
|
||||
u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
|
||||
u16 to_multiplier);
|
||||
|
|
|
@ -401,6 +401,21 @@ static inline void ipv6_addr_prefix(struct in6_addr *pfx,
|
|||
pfx->s6_addr[o] = addr->s6_addr[o] & (0xff00 >> b);
|
||||
}
|
||||
|
||||
static inline void ipv6_addr_prefix_copy(struct in6_addr *addr,
|
||||
const struct in6_addr *pfx,
|
||||
int plen)
|
||||
{
|
||||
/* caller must guarantee 0 <= plen <= 128 */
|
||||
int o = plen >> 3,
|
||||
b = plen & 0x7;
|
||||
|
||||
memcpy(addr->s6_addr, pfx, o);
|
||||
if (b != 0) {
|
||||
addr->s6_addr[o] &= ~(0xff00 >> b);
|
||||
addr->s6_addr[o] |= (pfx->s6_addr[o] & (0xff00 >> b));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void __ipv6_addr_set_half(__be32 *addr,
|
||||
__be32 wh, __be32 wl)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef __6LOWPAN_I_H
|
||||
#define __6LOWPAN_I_H
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
#ifdef CONFIG_6LOWPAN_DEBUGFS
|
||||
int lowpan_dev_debugfs_init(struct net_device *dev);
|
||||
void lowpan_dev_debugfs_exit(struct net_device *dev);
|
||||
|
||||
int __init lowpan_debugfs_init(void);
|
||||
void lowpan_debugfs_exit(void);
|
||||
#else
|
||||
static inline int lowpan_dev_debugfs_init(struct net_device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void lowpan_dev_debugfs_exit(struct net_device *dev) { }
|
||||
|
||||
static inline int __init lowpan_debugfs_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void lowpan_debugfs_exit(void) { }
|
||||
#endif /* CONFIG_6LOWPAN_DEBUGFS */
|
||||
|
||||
#endif /* __6LOWPAN_I_H */
|
|
@ -5,12 +5,21 @@ menuconfig 6LOWPAN
|
|||
This enables IPv6 over Low power Wireless Personal Area Network -
|
||||
"6LoWPAN" which is supported by IEEE 802.15.4 or Bluetooth stacks.
|
||||
|
||||
config 6LOWPAN_DEBUGFS
|
||||
bool "6LoWPAN debugfs support"
|
||||
depends on 6LOWPAN
|
||||
depends on DEBUG_FS
|
||||
---help---
|
||||
This enables 6LoWPAN debugfs support. For example to manipulate
|
||||
IPHC context information at runtime.
|
||||
|
||||
menuconfig 6LOWPAN_NHC
|
||||
tristate "Next Header Compression Support"
|
||||
tristate "Next Header and Generic Header Compression Support"
|
||||
depends on 6LOWPAN
|
||||
default y
|
||||
---help---
|
||||
Support for next header compression.
|
||||
Support for next header and generic header compression defined in
|
||||
RFC6282 and RFC7400.
|
||||
|
||||
if 6LOWPAN_NHC
|
||||
|
||||
|
@ -58,4 +67,38 @@ config 6LOWPAN_NHC_UDP
|
|||
---help---
|
||||
6LoWPAN IPv6 UDP Header compression according to RFC6282.
|
||||
|
||||
config 6LOWPAN_GHC_EXT_HDR_HOP
|
||||
tristate "GHC Hop-by-Hop Options Header Support"
|
||||
---help---
|
||||
6LoWPAN IPv6 Hop-by-Hop option generic header compression according
|
||||
to RFC7400.
|
||||
|
||||
config 6LOWPAN_GHC_UDP
|
||||
tristate "GHC UDP Support"
|
||||
---help---
|
||||
6LoWPAN IPv6 UDP generic header compression according to RFC7400.
|
||||
|
||||
config 6LOWPAN_GHC_ICMPV6
|
||||
tristate "GHC ICMPv6 Support"
|
||||
---help---
|
||||
6LoWPAN IPv6 ICMPv6 generic header compression according to RFC7400.
|
||||
|
||||
config 6LOWPAN_GHC_EXT_HDR_DEST
|
||||
tristate "GHC Destination Options Header Support"
|
||||
---help---
|
||||
6LoWPAN IPv6 destination option generic header compression according
|
||||
to RFC7400.
|
||||
|
||||
config 6LOWPAN_GHC_EXT_HDR_FRAG
|
||||
tristate "GHC Fragmentation Options Header Support"
|
||||
---help---
|
||||
6LoWPAN IPv6 fragmentation option generic header compression
|
||||
according to RFC7400.
|
||||
|
||||
config 6LOWPAN_GHC_EXT_HDR_ROUTE
|
||||
tristate "GHC Routing Options Header Support"
|
||||
---help---
|
||||
6LoWPAN IPv6 routing option generic header compression according
|
||||
to RFC7400.
|
||||
|
||||
endif
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
obj-$(CONFIG_6LOWPAN) += 6lowpan.o
|
||||
|
||||
6lowpan-y := core.o iphc.o nhc.o
|
||||
6lowpan-$(CONFIG_6LOWPAN_DEBUGFS) += debugfs.o
|
||||
|
||||
#rfc6282 nhcs
|
||||
obj-$(CONFIG_6LOWPAN_NHC_DEST) += nhc_dest.o
|
||||
|
@ -10,3 +11,11 @@ obj-$(CONFIG_6LOWPAN_NHC_IPV6) += nhc_ipv6.o
|
|||
obj-$(CONFIG_6LOWPAN_NHC_MOBILITY) += nhc_mobility.o
|
||||
obj-$(CONFIG_6LOWPAN_NHC_ROUTING) += nhc_routing.o
|
||||
obj-$(CONFIG_6LOWPAN_NHC_UDP) += nhc_udp.o
|
||||
|
||||
#rfc7400 ghcs
|
||||
obj-$(CONFIG_6LOWPAN_GHC_EXT_HDR_HOP) += nhc_ghc_ext_hop.o
|
||||
obj-$(CONFIG_6LOWPAN_GHC_UDP) += nhc_ghc_udp.o
|
||||
obj-$(CONFIG_6LOWPAN_GHC_ICMPV6) += nhc_ghc_icmpv6.o
|
||||
obj-$(CONFIG_6LOWPAN_GHC_EXT_HDR_DEST) += nhc_ghc_ext_dest.o
|
||||
obj-$(CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG) += nhc_ghc_ext_frag.o
|
||||
obj-$(CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE) += nhc_ghc_ext_route.o
|
||||
|
|
|
@ -15,19 +15,67 @@
|
|||
|
||||
#include <net/6lowpan.h>
|
||||
|
||||
void lowpan_netdev_setup(struct net_device *dev, enum lowpan_lltypes lltype)
|
||||
#include "6lowpan_i.h"
|
||||
|
||||
int lowpan_register_netdevice(struct net_device *dev,
|
||||
enum lowpan_lltypes lltype)
|
||||
{
|
||||
int ret;
|
||||
|
||||
dev->addr_len = EUI64_ADDR_LEN;
|
||||
dev->type = ARPHRD_6LOWPAN;
|
||||
dev->mtu = IPV6_MIN_MTU;
|
||||
dev->priv_flags |= IFF_NO_QUEUE;
|
||||
|
||||
lowpan_priv(dev)->lltype = lltype;
|
||||
|
||||
ret = lowpan_dev_debugfs_init(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = register_netdevice(dev);
|
||||
if (ret < 0)
|
||||
lowpan_dev_debugfs_exit(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(lowpan_netdev_setup);
|
||||
EXPORT_SYMBOL(lowpan_register_netdevice);
|
||||
|
||||
int lowpan_register_netdev(struct net_device *dev,
|
||||
enum lowpan_lltypes lltype)
|
||||
{
|
||||
int ret;
|
||||
|
||||
rtnl_lock();
|
||||
ret = lowpan_register_netdevice(dev, lltype);
|
||||
rtnl_unlock();
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(lowpan_register_netdev);
|
||||
|
||||
void lowpan_unregister_netdevice(struct net_device *dev)
|
||||
{
|
||||
unregister_netdevice(dev);
|
||||
lowpan_dev_debugfs_exit(dev);
|
||||
}
|
||||
EXPORT_SYMBOL(lowpan_unregister_netdevice);
|
||||
|
||||
void lowpan_unregister_netdev(struct net_device *dev)
|
||||
{
|
||||
rtnl_lock();
|
||||
lowpan_unregister_netdevice(dev);
|
||||
rtnl_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL(lowpan_unregister_netdev);
|
||||
|
||||
static int __init lowpan_module_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = lowpan_debugfs_init();
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
request_module_nowait("ipv6");
|
||||
|
||||
request_module_nowait("nhc_dest");
|
||||
|
@ -40,6 +88,13 @@ static int __init lowpan_module_init(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit lowpan_module_exit(void)
|
||||
{
|
||||
lowpan_debugfs_exit();
|
||||
}
|
||||
|
||||
module_init(lowpan_module_init);
|
||||
module_exit(lowpan_module_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Authors:
|
||||
* (C) 2015 Pengutronix, Alexander Aring <aar@pengutronix.de>
|
||||
* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <net/6lowpan.h>
|
||||
|
||||
#include "6lowpan_i.h"
|
||||
|
||||
static struct dentry *lowpan_debugfs;
|
||||
|
||||
int lowpan_dev_debugfs_init(struct net_device *dev)
|
||||
{
|
||||
struct lowpan_priv *lpriv = lowpan_priv(dev);
|
||||
|
||||
/* creating the root */
|
||||
lpriv->iface_debugfs = debugfs_create_dir(dev->name, lowpan_debugfs);
|
||||
if (!lpriv->iface_debugfs)
|
||||
goto fail;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void lowpan_dev_debugfs_exit(struct net_device *dev)
|
||||
{
|
||||
debugfs_remove_recursive(lowpan_priv(dev)->iface_debugfs);
|
||||
}
|
||||
|
||||
int __init lowpan_debugfs_init(void)
|
||||
{
|
||||
lowpan_debugfs = debugfs_create_dir("6lowpan", NULL);
|
||||
if (!lowpan_debugfs)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lowpan_debugfs_exit(void)
|
||||
{
|
||||
debugfs_remove_recursive(lowpan_debugfs);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 6LoWPAN Extension Header compression according to RFC7400
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include "nhc.h"
|
||||
|
||||
#define LOWPAN_GHC_EXT_DEST_IDLEN 1
|
||||
#define LOWPAN_GHC_EXT_DEST_ID_0 0xb6
|
||||
#define LOWPAN_GHC_EXT_DEST_MASK_0 0xfe
|
||||
|
||||
static void dest_ghid_setup(struct lowpan_nhc *nhc)
|
||||
{
|
||||
nhc->id[0] = LOWPAN_GHC_EXT_DEST_ID_0;
|
||||
nhc->idmask[0] = LOWPAN_GHC_EXT_DEST_MASK_0;
|
||||
}
|
||||
|
||||
LOWPAN_NHC(ghc_ext_dest, "RFC7400 Destination Extension Header", NEXTHDR_DEST,
|
||||
0, dest_ghid_setup, LOWPAN_GHC_EXT_DEST_IDLEN, NULL, NULL);
|
||||
|
||||
module_lowpan_nhc(ghc_ext_dest);
|
||||
MODULE_DESCRIPTION("6LoWPAN generic header destination extension compression");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 6LoWPAN Extension Header compression according to RFC7400
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include "nhc.h"
|
||||
|
||||
#define LOWPAN_GHC_EXT_FRAG_IDLEN 1
|
||||
#define LOWPAN_GHC_EXT_FRAG_ID_0 0xb4
|
||||
#define LOWPAN_GHC_EXT_FRAG_MASK_0 0xfe
|
||||
|
||||
static void frag_ghid_setup(struct lowpan_nhc *nhc)
|
||||
{
|
||||
nhc->id[0] = LOWPAN_GHC_EXT_FRAG_ID_0;
|
||||
nhc->idmask[0] = LOWPAN_GHC_EXT_FRAG_MASK_0;
|
||||
}
|
||||
|
||||
LOWPAN_NHC(ghc_ext_frag, "RFC7400 Fragmentation Extension Header",
|
||||
NEXTHDR_FRAGMENT, 0, frag_ghid_setup,
|
||||
LOWPAN_GHC_EXT_FRAG_IDLEN, NULL, NULL);
|
||||
|
||||
module_lowpan_nhc(ghc_ext_frag);
|
||||
MODULE_DESCRIPTION("6LoWPAN generic header fragmentation extension compression");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 6LoWPAN Extension Header compression according to RFC7400
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include "nhc.h"
|
||||
|
||||
#define LOWPAN_GHC_EXT_HOP_IDLEN 1
|
||||
#define LOWPAN_GHC_EXT_HOP_ID_0 0xb0
|
||||
#define LOWPAN_GHC_EXT_HOP_MASK_0 0xfe
|
||||
|
||||
static void hop_ghid_setup(struct lowpan_nhc *nhc)
|
||||
{
|
||||
nhc->id[0] = LOWPAN_GHC_EXT_HOP_ID_0;
|
||||
nhc->idmask[0] = LOWPAN_GHC_EXT_HOP_MASK_0;
|
||||
}
|
||||
|
||||
LOWPAN_NHC(ghc_ext_hop, "RFC7400 Hop-by-Hop Extension Header", NEXTHDR_HOP, 0,
|
||||
hop_ghid_setup, LOWPAN_GHC_EXT_HOP_IDLEN, NULL, NULL);
|
||||
|
||||
module_lowpan_nhc(ghc_ext_hop);
|
||||
MODULE_DESCRIPTION("6LoWPAN generic header hop-by-hop extension compression");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 6LoWPAN Extension Header compression according to RFC7400
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include "nhc.h"
|
||||
|
||||
#define LOWPAN_GHC_EXT_ROUTE_IDLEN 1
|
||||
#define LOWPAN_GHC_EXT_ROUTE_ID_0 0xb2
|
||||
#define LOWPAN_GHC_EXT_ROUTE_MASK_0 0xfe
|
||||
|
||||
static void route_ghid_setup(struct lowpan_nhc *nhc)
|
||||
{
|
||||
nhc->id[0] = LOWPAN_GHC_EXT_ROUTE_ID_0;
|
||||
nhc->idmask[0] = LOWPAN_GHC_EXT_ROUTE_MASK_0;
|
||||
}
|
||||
|
||||
LOWPAN_NHC(ghc_ext_route, "RFC7400 Routing Extension Header", NEXTHDR_ROUTING,
|
||||
0, route_ghid_setup, LOWPAN_GHC_EXT_ROUTE_IDLEN, NULL, NULL);
|
||||
|
||||
module_lowpan_nhc(ghc_ext_route);
|
||||
MODULE_DESCRIPTION("6LoWPAN generic header routing extension compression");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 6LoWPAN ICMPv6 compression according to RFC7400
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include "nhc.h"
|
||||
|
||||
#define LOWPAN_GHC_ICMPV6_IDLEN 1
|
||||
#define LOWPAN_GHC_ICMPV6_ID_0 0xdf
|
||||
#define LOWPAN_GHC_ICMPV6_MASK_0 0xff
|
||||
|
||||
static void icmpv6_ghid_setup(struct lowpan_nhc *nhc)
|
||||
{
|
||||
nhc->id[0] = LOWPAN_GHC_ICMPV6_ID_0;
|
||||
nhc->idmask[0] = LOWPAN_GHC_ICMPV6_MASK_0;
|
||||
}
|
||||
|
||||
LOWPAN_NHC(ghc_icmpv6, "RFC7400 ICMPv6", NEXTHDR_ICMP, 0,
|
||||
icmpv6_ghid_setup, LOWPAN_GHC_ICMPV6_IDLEN, NULL, NULL);
|
||||
|
||||
module_lowpan_nhc(ghc_icmpv6);
|
||||
MODULE_DESCRIPTION("6LoWPAN generic header ICMPv6 compression");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 6LoWPAN UDP compression according to RFC7400
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include "nhc.h"
|
||||
|
||||
#define LOWPAN_GHC_UDP_IDLEN 1
|
||||
#define LOWPAN_GHC_UDP_ID_0 0xd0
|
||||
#define LOWPAN_GHC_UDP_MASK_0 0xf8
|
||||
|
||||
static void udp_ghid_setup(struct lowpan_nhc *nhc)
|
||||
{
|
||||
nhc->id[0] = LOWPAN_GHC_UDP_ID_0;
|
||||
nhc->idmask[0] = LOWPAN_GHC_UDP_MASK_0;
|
||||
}
|
||||
|
||||
LOWPAN_NHC(ghc_udp, "RFC7400 UDP", NEXTHDR_UDP, 0,
|
||||
udp_ghid_setup, LOWPAN_GHC_UDP_IDLEN, NULL, NULL);
|
||||
|
||||
module_lowpan_nhc(ghc_udp);
|
||||
MODULE_DESCRIPTION("6LoWPAN generic header UDP compression");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -825,9 +825,7 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
|
|||
list_add_rcu(&(*dev)->list, &bt_6lowpan_devices);
|
||||
spin_unlock(&devices_lock);
|
||||
|
||||
lowpan_netdev_setup(netdev, LOWPAN_LLTYPE_BTLE);
|
||||
|
||||
err = register_netdev(netdev);
|
||||
err = lowpan_register_netdev(netdev, LOWPAN_LLTYPE_BTLE);
|
||||
if (err < 0) {
|
||||
BT_INFO("register_netdev failed %d", err);
|
||||
spin_lock(&devices_lock);
|
||||
|
@ -890,7 +888,7 @@ static void delete_netdev(struct work_struct *work)
|
|||
struct lowpan_dev *entry = container_of(work, struct lowpan_dev,
|
||||
delete_netdev);
|
||||
|
||||
unregister_netdev(entry->netdev);
|
||||
lowpan_unregister_netdev(entry->netdev);
|
||||
|
||||
/* The entry pointer is deleted by the netdev destructor. */
|
||||
}
|
||||
|
@ -1348,7 +1346,7 @@ static void disconnect_devices(void)
|
|||
ifdown(entry->netdev);
|
||||
BT_DBG("Unregistering netdev %s %p",
|
||||
entry->netdev->name, entry->netdev);
|
||||
unregister_netdev(entry->netdev);
|
||||
lowpan_unregister_netdev(entry->netdev);
|
||||
kfree(entry);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,8 +186,8 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
|
|||
|
||||
/* FIXME: Is this check still needed */
|
||||
if (sk->sk_state == BT_CLOSED) {
|
||||
release_sock(sk);
|
||||
bt_accept_unlink(sk);
|
||||
release_sock(sk);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -608,8 +608,11 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
|
|||
s->msg.msg_flags = MSG_NOSIGNAL;
|
||||
|
||||
#ifdef CONFIG_BT_BNEP_MC_FILTER
|
||||
/* Set default mc filter */
|
||||
set_bit(bnep_mc_hash(dev->broadcast), (ulong *) &s->mc_filter);
|
||||
/* Set default mc filter to not filter out any mc addresses
|
||||
* as defined in the BNEP specification (revision 0.95a)
|
||||
* http://grouper.ieee.org/groups/802/15/Bluetooth/BNEP.pdf
|
||||
*/
|
||||
s->mc_filter = ~0LL;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_BNEP_PROTO_FILTER
|
||||
|
|
|
@ -668,8 +668,16 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)
|
|||
|
||||
conn->state = BT_CLOSED;
|
||||
|
||||
mgmt_connect_failed(hdev, &conn->dst, conn->type, conn->dst_type,
|
||||
status);
|
||||
/* If the status indicates successful cancellation of
|
||||
* the attempt (i.e. Unkown Connection Id) there's no point of
|
||||
* notifying failure since we'll go back to keep trying to
|
||||
* connect. The only exception is explicit connect requests
|
||||
* where a timeout + cancel does indicate an actual failure.
|
||||
*/
|
||||
if (status != HCI_ERROR_UNKNOWN_CONN_ID ||
|
||||
(params && params->explicit_connect))
|
||||
mgmt_connect_failed(hdev, &conn->dst, conn->type,
|
||||
conn->dst_type, status);
|
||||
|
||||
hci_connect_cfm(conn, status);
|
||||
|
||||
|
@ -683,7 +691,7 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)
|
|||
/* Re-enable advertising in case this was a failed connection
|
||||
* attempt as a peripheral.
|
||||
*/
|
||||
mgmt_reenable_advertising(hdev);
|
||||
hci_req_reenable_advertising(hdev);
|
||||
}
|
||||
|
||||
static void create_le_conn_complete(struct hci_dev *hdev, u8 status, u16 opcode)
|
||||
|
@ -726,8 +734,12 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
|
|||
if (hci_update_random_address(req, false, &own_addr_type))
|
||||
return;
|
||||
|
||||
/* Set window to be the same value as the interval to enable
|
||||
* continuous scanning.
|
||||
*/
|
||||
cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
|
||||
cp.scan_window = cpu_to_le16(hdev->le_scan_window);
|
||||
cp.scan_window = cp.scan_interval;
|
||||
|
||||
bacpy(&cp.peer_addr, &conn->dst);
|
||||
cp.peer_addr_type = conn->dst_type;
|
||||
cp.own_address_type = own_addr_type;
|
||||
|
|
|
@ -1399,10 +1399,10 @@ static int hci_dev_do_open(struct hci_dev *hdev)
|
|||
!hci_dev_test_flag(hdev, HCI_CONFIG) &&
|
||||
!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
|
||||
!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
|
||||
hci_dev_test_flag(hdev, HCI_MGMT) &&
|
||||
hdev->dev_type == HCI_BREDR) {
|
||||
hci_dev_lock(hdev);
|
||||
mgmt_powered(hdev, 1);
|
||||
hci_dev_unlock(hdev);
|
||||
ret = __hci_req_hci_power_on(hdev);
|
||||
mgmt_power_on(hdev, ret);
|
||||
}
|
||||
} else {
|
||||
/* Init failed, cleanup */
|
||||
|
@ -1537,7 +1537,6 @@ int hci_dev_do_close(struct hci_dev *hdev)
|
|||
flush_work(&hdev->rx_work);
|
||||
|
||||
if (hdev->discov_timeout > 0) {
|
||||
cancel_delayed_work(&hdev->discov_off);
|
||||
hdev->discov_timeout = 0;
|
||||
hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
|
||||
hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
|
||||
|
@ -1549,11 +1548,6 @@ int hci_dev_do_close(struct hci_dev *hdev)
|
|||
if (hci_dev_test_flag(hdev, HCI_MGMT))
|
||||
cancel_delayed_work_sync(&hdev->rpa_expired);
|
||||
|
||||
if (hdev->adv_instance_timeout) {
|
||||
cancel_delayed_work_sync(&hdev->adv_instance_expire);
|
||||
hdev->adv_instance_timeout = 0;
|
||||
}
|
||||
|
||||
/* Avoid potential lockdep warnings from the *_flush() calls by
|
||||
* ensuring the workqueue is empty up front.
|
||||
*/
|
||||
|
@ -1565,8 +1559,9 @@ int hci_dev_do_close(struct hci_dev *hdev)
|
|||
|
||||
auto_off = hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF);
|
||||
|
||||
if (!auto_off && hdev->dev_type == HCI_BREDR)
|
||||
mgmt_powered(hdev, 0);
|
||||
if (!auto_off && hdev->dev_type == HCI_BREDR &&
|
||||
hci_dev_test_flag(hdev, HCI_MGMT))
|
||||
__mgmt_power_off(hdev);
|
||||
|
||||
hci_inquiry_cache_flush(hdev);
|
||||
hci_pend_le_actions_clear(hdev);
|
||||
|
@ -1774,7 +1769,7 @@ static void hci_update_scan_state(struct hci_dev *hdev, u8 scan)
|
|||
hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
|
||||
|
||||
if (hci_dev_test_flag(hdev, HCI_LE_ENABLED))
|
||||
mgmt_update_adv_data(hdev);
|
||||
hci_req_update_adv_data(hdev, hdev->cur_adv_instance);
|
||||
|
||||
mgmt_new_settings(hdev);
|
||||
}
|
||||
|
@ -2019,6 +2014,16 @@ static void hci_power_on(struct work_struct *work)
|
|||
|
||||
BT_DBG("%s", hdev->name);
|
||||
|
||||
if (test_bit(HCI_UP, &hdev->flags) &&
|
||||
hci_dev_test_flag(hdev, HCI_MGMT) &&
|
||||
hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
|
||||
hci_req_sync_lock(hdev);
|
||||
err = __hci_req_hci_power_on(hdev);
|
||||
hci_req_sync_unlock(hdev);
|
||||
mgmt_power_on(hdev, err);
|
||||
return;
|
||||
}
|
||||
|
||||
err = hci_dev_do_open(hdev);
|
||||
if (err < 0) {
|
||||
hci_dev_lock(hdev);
|
||||
|
@ -2101,28 +2106,6 @@ static void hci_error_reset(struct work_struct *work)
|
|||
hci_dev_do_open(hdev);
|
||||
}
|
||||
|
||||
static void hci_discov_off(struct work_struct *work)
|
||||
{
|
||||
struct hci_dev *hdev;
|
||||
|
||||
hdev = container_of(work, struct hci_dev, discov_off.work);
|
||||
|
||||
BT_DBG("%s", hdev->name);
|
||||
|
||||
mgmt_discoverable_timeout(hdev);
|
||||
}
|
||||
|
||||
static void hci_adv_timeout_expire(struct work_struct *work)
|
||||
{
|
||||
struct hci_dev *hdev;
|
||||
|
||||
hdev = container_of(work, struct hci_dev, adv_instance_expire.work);
|
||||
|
||||
BT_DBG("%s", hdev->name);
|
||||
|
||||
mgmt_adv_timeout_expired(hdev);
|
||||
}
|
||||
|
||||
void hci_uuids_clear(struct hci_dev *hdev)
|
||||
{
|
||||
struct bt_uuid *uuid, *tmp;
|
||||
|
@ -2627,9 +2610,12 @@ int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance)
|
|||
|
||||
BT_DBG("%s removing %dMR", hdev->name, instance);
|
||||
|
||||
if (hdev->cur_adv_instance == instance && hdev->adv_instance_timeout) {
|
||||
cancel_delayed_work(&hdev->adv_instance_expire);
|
||||
hdev->adv_instance_timeout = 0;
|
||||
if (hdev->cur_adv_instance == instance) {
|
||||
if (hdev->adv_instance_timeout) {
|
||||
cancel_delayed_work(&hdev->adv_instance_expire);
|
||||
hdev->adv_instance_timeout = 0;
|
||||
}
|
||||
hdev->cur_adv_instance = 0x00;
|
||||
}
|
||||
|
||||
list_del(&adv_instance->list);
|
||||
|
@ -2656,6 +2642,7 @@ void hci_adv_instances_clear(struct hci_dev *hdev)
|
|||
}
|
||||
|
||||
hdev->adv_instance_cnt = 0;
|
||||
hdev->cur_adv_instance = 0x00;
|
||||
}
|
||||
|
||||
/* This function requires the caller holds hdev->lock */
|
||||
|
@ -3002,8 +2989,6 @@ struct hci_dev *hci_alloc_dev(void)
|
|||
INIT_WORK(&hdev->error_reset, hci_error_reset);
|
||||
|
||||
INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
|
||||
INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
|
||||
INIT_DELAYED_WORK(&hdev->adv_instance_expire, hci_adv_timeout_expire);
|
||||
|
||||
skb_queue_head_init(&hdev->rx_q);
|
||||
skb_queue_head_init(&hdev->cmd_q);
|
||||
|
|
|
@ -1183,7 +1183,7 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
|
|||
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
|
||||
else if (!hci_dev_test_flag(hdev, HCI_LE_ADV) &&
|
||||
hdev->discovery.state == DISCOVERY_FINDING)
|
||||
mgmt_reenable_advertising(hdev);
|
||||
hci_req_reenable_advertising(hdev);
|
||||
|
||||
break;
|
||||
|
||||
|
@ -2176,7 +2176,7 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
|
||||
sizeof(cp), &cp);
|
||||
|
||||
hci_update_page_scan(hdev);
|
||||
hci_req_update_scan(hdev);
|
||||
}
|
||||
|
||||
/* Set packet type for incoming connection */
|
||||
|
@ -2362,7 +2362,7 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
if (test_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
|
||||
hci_remove_link_key(hdev, &conn->dst);
|
||||
|
||||
hci_update_page_scan(hdev);
|
||||
hci_req_update_scan(hdev);
|
||||
}
|
||||
|
||||
params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
|
||||
|
@ -2401,7 +2401,7 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
* is timed out due to Directed Advertising."
|
||||
*/
|
||||
if (type == LE_LINK)
|
||||
mgmt_reenable_advertising(hdev);
|
||||
hci_req_reenable_advertising(hdev);
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -55,14 +55,38 @@ void hci_req_sync_cancel(struct hci_dev *hdev, int err);
|
|||
struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen,
|
||||
const void *param);
|
||||
|
||||
int __hci_req_hci_power_on(struct hci_dev *hdev);
|
||||
|
||||
void __hci_req_write_fast_connectable(struct hci_request *req, bool enable);
|
||||
void __hci_req_update_name(struct hci_request *req);
|
||||
void __hci_req_update_eir(struct hci_request *req);
|
||||
|
||||
void hci_req_add_le_scan_disable(struct hci_request *req);
|
||||
void hci_req_add_le_passive_scan(struct hci_request *req);
|
||||
|
||||
void hci_req_reenable_advertising(struct hci_dev *hdev);
|
||||
void __hci_req_enable_advertising(struct hci_request *req);
|
||||
void __hci_req_disable_advertising(struct hci_request *req);
|
||||
void __hci_req_update_adv_data(struct hci_request *req, u8 instance);
|
||||
int hci_req_update_adv_data(struct hci_dev *hdev, u8 instance);
|
||||
void __hci_req_update_scan_rsp_data(struct hci_request *req, u8 instance);
|
||||
|
||||
int __hci_req_schedule_adv_instance(struct hci_request *req, u8 instance,
|
||||
bool force);
|
||||
void hci_req_clear_adv_instance(struct hci_dev *hdev, struct hci_request *req,
|
||||
u8 instance, bool force);
|
||||
|
||||
void __hci_req_update_class(struct hci_request *req);
|
||||
|
||||
/* Returns true if HCI commands were queued */
|
||||
bool hci_req_stop_discovery(struct hci_request *req);
|
||||
|
||||
void hci_update_page_scan(struct hci_dev *hdev);
|
||||
void __hci_update_page_scan(struct hci_request *req);
|
||||
static inline void hci_req_update_scan(struct hci_dev *hdev)
|
||||
{
|
||||
queue_work(hdev->req_workqueue, &hdev->scan_update);
|
||||
}
|
||||
|
||||
void __hci_req_update_scan(struct hci_request *req);
|
||||
|
||||
int hci_update_random_address(struct hci_request *req, bool require_privacy,
|
||||
u8 *own_addr_type);
|
||||
|
|
1255
net/bluetooth/mgmt.c
1255
net/bluetooth/mgmt.c
File diff suppressed because it is too large
Load Diff
|
@ -161,9 +161,7 @@ static int lowpan_newlink(struct net *src_net, struct net_device *ldev,
|
|||
wdev->needed_headroom;
|
||||
ldev->needed_tailroom = wdev->needed_tailroom;
|
||||
|
||||
lowpan_netdev_setup(ldev, LOWPAN_LLTYPE_IEEE802154);
|
||||
|
||||
ret = register_netdevice(ldev);
|
||||
ret = lowpan_register_netdevice(ldev, LOWPAN_LLTYPE_IEEE802154);
|
||||
if (ret < 0) {
|
||||
dev_put(wdev);
|
||||
return ret;
|
||||
|
@ -180,7 +178,7 @@ static void lowpan_dellink(struct net_device *ldev, struct list_head *head)
|
|||
ASSERT_RTNL();
|
||||
|
||||
wdev->ieee802154_ptr->lowpan_dev = NULL;
|
||||
unregister_netdevice(ldev);
|
||||
lowpan_unregister_netdevice(ldev);
|
||||
dev_put(wdev);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,9 +18,6 @@ drv_xmit_async(struct ieee802154_local *local, struct sk_buff *skb)
|
|||
static inline int
|
||||
drv_xmit_sync(struct ieee802154_local *local, struct sk_buff *skb)
|
||||
{
|
||||
/* don't allow other operations while sync xmit */
|
||||
ASSERT_RTNL();
|
||||
|
||||
might_sleep();
|
||||
|
||||
return local->ops->xmit_sync(&local->hw, skb);
|
||||
|
|
|
@ -38,12 +38,6 @@ void ieee802154_xmit_worker(struct work_struct *work)
|
|||
struct net_device *dev = skb->dev;
|
||||
int res;
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
/* check if ifdown occurred while schedule */
|
||||
if (!netif_running(dev))
|
||||
goto err_tx;
|
||||
|
||||
res = drv_xmit_sync(local, skb);
|
||||
if (res)
|
||||
goto err_tx;
|
||||
|
@ -53,14 +47,11 @@ void ieee802154_xmit_worker(struct work_struct *work)
|
|||
dev->stats.tx_packets++;
|
||||
dev->stats.tx_bytes += skb->len;
|
||||
|
||||
rtnl_unlock();
|
||||
|
||||
return;
|
||||
|
||||
err_tx:
|
||||
/* Restart the netif queue on each sub_if_data object. */
|
||||
ieee802154_wake_queue(&local->hw);
|
||||
rtnl_unlock();
|
||||
kfree_skb(skb);
|
||||
netdev_dbg(dev, "transmission failed\n");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue