* [RFCv2 0/6] Draft Software/Virtual AMP80211
@ 2012-04-24 13:17 Andrei Emeltchenko
2012-04-24 13:17 ` [RFCv2 1/6] mac80211: softamp: Adds Bluetooth Software AMP Andrei Emeltchenko
` (5 more replies)
0 siblings, 6 replies; 12+ messages in thread
From: Andrei Emeltchenko @ 2012-04-24 13:17 UTC (permalink / raw)
To: linux-bluetooth, linux-wireless
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
RFC for Software / Virtual _DRAFT_ implementation of Bluetooth High Speed
by using wireless driver. Currently it can be used for testing Bluetooth
A2MP protocol.
Changes:
RFCv2: Process basic HCI commands and basic data traffic; added skeleton
for Netlink comms, took comments from reviewers.
RFCv1: Initial release.
TODO:
Change names from vamp to <softamp|bt_softamp|etc>
Main ideas:
- Use existing wireless infrastructure nl80211, mac80211.
- Use virtual interface of type NL80211_IFTYPE_BLUETOOTH_AMP. Then all
drivers supporting virtual interface should work.
After modifying iw it will be enabled by adding new virtual interface.
# iw phy <physical device> interface add vamp type vamp
# iw dev
phy#0
Interface vamp
ifindex 6
type Virtual AMP
...
# hciconfig
hci1: Type: AMP Bus: VIRTUAL
BD Address: 00:00:00:00:00:00 ACL MTU: 0:0 SCO MTU: 0:0
DOWN
RX bytes:0 acl:0 sco:0 events:0 errors:0
TX bytes:0 acl:0 sco:0 commands:0 errors:0
...
Andrei Emeltchenko (6):
mac80211: softamp: Adds Bluetooth Software AMP
mac80211: softamp: Adds build config option
hwsim: Adds support for BT SOFTAMP for testing
mac80211: softamp: Handle assoc request
mac80211: softamp: Netlink interface to softamp
mac80211: softamp: Handle data traffic
drivers/net/wireless/mac80211_hwsim.c | 3 +-
include/linux/ieee80211.h | 13 +
include/linux/nl80211.h | 1 +
net/mac80211/Kconfig | 9 +
net/mac80211/Makefile | 2 +
net/mac80211/ieee80211_i.h | 5 +
net/mac80211/iface.c | 9 +
net/mac80211/rx.c | 4 +
net/mac80211/sta_info.h | 4 +
net/mac80211/util.c | 1 +
net/mac80211/virtual_amp.c | 675 +++++++++++++++++++++++++++++++++
net/mac80211/virtual_amp.h | 96 +++++
12 files changed, 821 insertions(+), 1 deletion(-)
create mode 100644 net/mac80211/virtual_amp.c
create mode 100644 net/mac80211/virtual_amp.h
--
1.7.9.5
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFCv2 1/6] mac80211: softamp: Adds Bluetooth Software AMP
2012-04-24 13:17 [RFCv2 0/6] Draft Software/Virtual AMP80211 Andrei Emeltchenko
@ 2012-04-24 13:17 ` Andrei Emeltchenko
2012-05-07 11:41 ` Johannes Berg
2012-04-24 13:17 ` [RFCv2 2/6] mac80211: softamp: Adds build config option Andrei Emeltchenko
` (4 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Andrei Emeltchenko @ 2012-04-24 13:17 UTC (permalink / raw)
To: linux-bluetooth, linux-wireless
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Add new interface type BLUETOOTH_SOFTAMP which emulates Bluetooth AMP
Controller. AMP is Alternate MAC/PHYs Controller for Bluetooth subsystem.
When an AMP is common between the two devices, the Bluetooth system
provides mechanisms for moving data traffic from BR/EDR Controller to
an AMP Controller.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
include/linux/nl80211.h | 1 +
net/mac80211/ieee80211_i.h | 5 +
net/mac80211/iface.c | 9 ++
net/mac80211/util.c | 1 +
net/mac80211/virtual_amp.c | 341 ++++++++++++++++++++++++++++++++++++++++++++
net/mac80211/virtual_amp.h | 37 +++++
6 files changed, 394 insertions(+)
create mode 100644 net/mac80211/virtual_amp.c
create mode 100644 net/mac80211/virtual_amp.h
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index e474f6e..ed1bf6d 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1546,6 +1546,7 @@ enum nl80211_iftype {
NL80211_IFTYPE_MESH_POINT,
NL80211_IFTYPE_P2P_CLIENT,
NL80211_IFTYPE_P2P_GO,
+ NL80211_IFTYPE_BLUETOOTH_SOFTAMP,
/* keep last */
NUM_NL80211_IFTYPES,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index d9798a3..1e0af56 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -602,6 +602,10 @@ struct ieee80211_if_mesh {
} security;
};
+struct ieee80211_if_bt_softamp {
+ struct hci_dev *hdev;
+};
+
#ifdef CONFIG_MAC80211_MESH
#define IEEE80211_IFSTA_MESH_CTR_INC(msh, name) \
do { (msh)->mshstats.name++; } while (0)
@@ -716,6 +720,7 @@ struct ieee80211_sub_if_data {
struct ieee80211_if_managed mgd;
struct ieee80211_if_ibss ibss;
struct ieee80211_if_mesh mesh;
+ struct ieee80211_if_bt_softamp softamp;
u32 mntr_flags;
} u;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 96f8773..b92d8e3 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -25,6 +25,7 @@
#include "driver-ops.h"
#include "wme.h"
#include "rate.h"
+#include "virtual_amp.h"
/**
* DOC: Interface list locking
@@ -211,6 +212,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_MONITOR:
case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_BLUETOOTH_SOFTAMP:
/* no special treatment */
break;
case NL80211_IFTYPE_UNSPECIFIED:
@@ -898,6 +900,9 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
case NL80211_IFTYPE_WDS:
case NL80211_IFTYPE_AP_VLAN:
break;
+ case NL80211_IFTYPE_BLUETOOTH_SOFTAMP:
+ ieee80211_vamp_setup_sdata(sdata);
+ break;
case NL80211_IFTYPE_UNSPECIFIED:
case NUM_NL80211_IFTYPES:
BUG();
@@ -914,6 +919,10 @@ static void ieee80211_clean_sdata(struct ieee80211_sub_if_data *sdata)
mesh_path_flush_by_iface(sdata);
break;
+ case NL80211_IFTYPE_BLUETOOTH_SOFTAMP:
+ ieee80211_vamp_clean_sdata(sdata);
+ break;
+
default:
break;
}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 32f7a3b..8b7b40a 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1290,6 +1290,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
ieee80211_bss_info_change_notify(sdata, changed);
break;
case NL80211_IFTYPE_WDS:
+ case NL80211_IFTYPE_BLUETOOTH_SOFTAMP:
break;
case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_MONITOR:
diff --git a/net/mac80211/virtual_amp.c b/net/mac80211/virtual_amp.c
new file mode 100644
index 0000000..3c81fda
--- /dev/null
+++ b/net/mac80211/virtual_amp.c
@@ -0,0 +1,341 @@
+/*
+ * Virtual/Software AMP 80211 BT Controller. AMP is Alternate MAC/PHYs
+ * Controller for Bluetooth subsystem. When an AMP is common between the
+ * two devices, the Bluetooth system provides mechanisms for moving data
+ * traffic from BR/EDR Controller to an AMP Controller.
+ *
+ * Copyright 2012 Intel Corp.
+ *
+ * Written by andrei.emeltchenko@intel.com
+ *
+ * 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.
+ */
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/l2cap.h>
+#include "virtual_amp.h"
+
+static int vamp_open_dev(struct hci_dev *hdev)
+{
+ BT_DBG("%s", hdev->name);
+
+ set_bit(HCI_RUNNING, &hdev->flags);
+
+ return 0;
+}
+
+static int vamp_close_dev(struct hci_dev *hdev)
+{
+ struct vamp_data *data = hci_get_drvdata(hdev);
+
+ BT_DBG("%s", hdev->name);
+
+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
+ return 0;
+
+ skb_queue_purge(&data->txq);
+
+ return 0;
+}
+
+static int vamp_send_frame(struct sk_buff *skb)
+{
+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+ struct vamp_data *data;
+
+ BT_DBG("%s", hdev->name);
+
+ if (!hdev) {
+ BT_ERR("Frame for unknown HCI device (hdev=NULL)");
+ return -ENODEV;
+ }
+
+ if (!test_bit(HCI_RUNNING, &hdev->flags))
+ return -EBUSY;
+
+ data = hci_get_drvdata(hdev);
+
+ skb_queue_tail(&data->txq, skb);
+
+ schedule_work(&data->work);
+
+ return 0;
+}
+
+static int vamp_flush(struct hci_dev *hdev)
+{
+ struct vamp_data *data = hci_get_drvdata(hdev);
+
+ BT_DBG("%s", hdev->name);
+
+ skb_queue_purge(&data->txq);
+
+ return 0;
+}
+
+static struct sk_buff *__hci_alloc_evt(size_t plen, __u8 evt_type)
+{
+ size_t len = HCI_EVENT_HDR_SIZE + plen;
+ struct hci_event_hdr *hdr;
+ struct sk_buff *skb;
+
+ skb = bt_skb_alloc(len, GFP_KERNEL);
+ if (!skb) {
+ BT_ERR("No memory for HCI event");
+ return NULL;
+ }
+
+ hdr = (struct hci_event_hdr *) skb_put(skb, HCI_EVENT_HDR_SIZE);
+ hdr->evt = evt_type;
+ hdr->plen = plen;
+
+ return skb;
+}
+
+static int hci_send_evt_cmplt(struct hci_dev *hdev, __u16 opcode, __u32 plen,
+ void *param)
+{
+ struct hci_ev_cmd_complete *hdr_cmplt;
+ struct sk_buff *skb;
+
+ skb = __hci_alloc_evt(plen + sizeof(*hdr_cmplt), HCI_EV_CMD_COMPLETE);
+ if (!skb)
+ return -ENOMEM;
+
+ hdr_cmplt = (struct hci_ev_cmd_complete *) skb_put(skb,
+ sizeof(*hdr_cmplt));
+ hdr_cmplt->ncmd = 1;
+ hdr_cmplt->opcode = cpu_to_le16(opcode);
+
+ if (plen)
+ memcpy(skb_put(skb, plen), param, plen);
+
+ bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
+ skb->dev = (void *) hdev;
+
+ return hci_recv_frame(skb);
+}
+
+/* Process HCI command packets */
+static void vamp_cmd_read_bd_addr(struct vamp_data *data, struct sk_buff *skb)
+{
+ struct hci_rp_read_bd_addr rp;
+ struct hci_dev *hdev = data->hdev;
+ struct ieee80211_sub_if_data *sdata = data->sdata;
+
+ rp.status = 0;
+
+ /* Use vif address as BT address */
+ baswap(&rp.bdaddr, (bdaddr_t *) sdata->vif.addr);
+
+ BT_DBG("Read BDADDR %pM", sdata->vif.addr);
+
+ hci_send_evt_cmplt(hdev, HCI_OP_READ_BD_ADDR, sizeof(rp), &rp);
+}
+
+static void vamp_cmd_read_local_version(struct vamp_data *data,
+ struct sk_buff *skb)
+{
+ struct hci_rp_read_local_version rp;
+ struct hci_dev *hdev = data->hdev;
+
+ BT_DBG("%s", hdev->name);
+
+ rp.status = 0x00;
+
+ rp.hci_ver = 0x06;
+ rp.hci_rev = cpu_to_le16(0x0000);
+ rp.lmp_ver = 0x06;
+
+ /* Not Assigned */
+ rp.manufacturer = cpu_to_le16(0xffff);
+ rp.lmp_subver = cpu_to_le16(0x0000);
+
+ hci_send_evt_cmplt(hdev, HCI_OP_READ_LOCAL_VERSION, sizeof(rp), &rp);
+}
+
+static void vamp_cmd_read_local_amp_info(struct vamp_data *data,
+ struct sk_buff *skb)
+{
+ struct hci_dev *hdev = data->hdev;
+ struct hci_rp_read_local_amp_info rp;
+
+ memset(&rp, 0, sizeof(rp));
+
+ rp.status = 0x00;
+
+ /* BT only */
+ rp.amp_status = 0x01;
+ rp.max_pdu = cpu_to_le32(L2CAP_DEFAULT_MTU);
+ rp.amp_type = HCI_AMP;
+ rp.max_assoc_size = cpu_to_le16(HCI_MAX_ACL_SIZE);
+ /* No flushing at all */
+ rp.max_flush_to = cpu_to_le32(0xFFFFFFFF);
+ rp.be_flush_to = cpu_to_le32(0xFFFFFFFF);
+
+ hci_send_evt_cmplt(hdev, HCI_OP_READ_LOCAL_AMP_INFO, sizeof(rp), &rp);
+}
+
+static void vamp_cmd_reset(struct vamp_data *data, struct sk_buff *skb)
+{
+ struct hci_dev *hdev = data->hdev;
+ u8 status;
+
+ BT_DBG("Reset %s", hdev->name);
+
+ hci_send_evt_cmplt(hdev, HCI_OP_RESET, sizeof(status), &status);
+}
+
+static void vamp_command_packet(struct vamp_data *data, struct sk_buff *skb)
+{
+ struct hci_command_hdr *hdr = (void *) skb->data;
+ __u16 opcode = le16_to_cpu(hdr->opcode);
+
+ /* Check packet size */
+ if (skb->len < sizeof(*hdr) || skb->len != hdr->plen + sizeof(*hdr))
+ goto drop;
+
+ BT_DBG("%s opcode 0x%x", data->hdev->name, opcode);
+
+ skb_pull(skb, HCI_COMMAND_HDR_SIZE);
+
+ switch (opcode) {
+ case HCI_OP_READ_BD_ADDR:
+ vamp_cmd_read_bd_addr(data, skb);
+ break;
+
+ case HCI_OP_READ_LOCAL_VERSION:
+ vamp_cmd_read_local_version(data, skb);
+ break;
+
+ case HCI_OP_READ_LOCAL_AMP_INFO:
+ vamp_cmd_read_local_amp_info(data, skb);
+ break;
+
+ case HCI_OP_RESET:
+ vamp_cmd_reset(data, skb);
+ break;
+
+ default:
+ break;
+ }
+
+drop:
+ kfree_skb(skb);
+}
+
+static void vamp_acldata_packet(struct vamp_data *data, struct sk_buff *skb)
+{
+ struct hci_acl_hdr *hdr = (void *) skb->data;
+ __u16 handle, flags;
+
+ if (skb->len < sizeof(*hdr))
+ goto drop;
+
+ skb_pull(skb, HCI_ACL_HDR_SIZE);
+
+ handle = __le16_to_cpu(hdr->handle);
+ flags = hci_flags(handle);
+ handle = hci_handle(handle);
+
+ BT_DBG("%s len %d handle 0x%x flags 0x%x", data->hdev->name, skb->len,
+ handle, flags);
+
+ /* Send data through WIFI */
+
+drop:
+ kfree_skb(skb);
+}
+
+static void vamp_work(struct work_struct *work)
+{
+ struct vamp_data *data = container_of(work, struct vamp_data, work);
+ struct sk_buff *skb;
+
+ BT_DBG("%s", data->hdev->name);
+
+ while ((skb = skb_dequeue(&data->txq))) {
+ /* Process frame */
+ switch (bt_cb(skb)->pkt_type) {
+ case HCI_COMMAND_PKT:
+ vamp_command_packet(data, skb);
+ break;
+
+ case HCI_ACLDATA_PKT:
+ vamp_acldata_packet(data, skb);
+ break;
+
+ default:
+ BT_ERR("Unknown frame type %d", bt_cb(skb)->pkt_type);
+ kfree_skb(skb);
+ break;
+ }
+
+ }
+}
+
+static int virtual_amp_init(struct ieee80211_sub_if_data *sdata)
+{
+ struct hci_dev *hdev;
+ struct vamp_data *data;
+
+ data = kzalloc(sizeof(struct vamp_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ hdev = hci_alloc_dev();
+ if (!hdev) {
+ kfree(data);
+ return -ENOMEM;
+ }
+
+ skb_queue_head_init(&data->txq);
+
+ INIT_WORK(&data->work, vamp_work);
+
+ data->hdev = hdev;
+ data->sdata = sdata;
+
+ hdev->bus = HCI_VIRTUAL;
+ hci_set_drvdata(hdev, data);
+
+ hdev->dev_type = HCI_AMP;
+
+ hdev->open = vamp_open_dev;
+ hdev->close = vamp_close_dev;
+ hdev->flush = vamp_flush;
+ hdev->send = vamp_send_frame;
+
+ if (hci_register_dev(hdev) < 0) {
+ BT_ERR("Can't register HCI device");
+ kfree(data);
+ hci_free_dev(hdev);
+ return -EBUSY;
+ }
+
+ sdata->u.softamp.hdev = hdev;
+
+ return 0;
+}
+
+void ieee80211_vamp_setup_sdata(struct ieee80211_sub_if_data *sdata)
+{
+ virtual_amp_init(sdata);
+
+ pr_info("Created virtual AMP device %s", sdata->u.softamp.hdev->name);
+}
+
+void ieee80211_vamp_clean_sdata(struct ieee80211_sub_if_data *sdata)
+{
+ struct hci_dev *hdev = sdata->u.softamp.hdev;
+ struct vamp_data *data = hci_get_drvdata(hdev);
+
+ pr_info("Clean up virtual AMP device %s", hdev->name);
+
+ hci_unregister_dev(hdev);
+ hci_free_dev(hdev);
+ kfree(data);
+}
diff --git a/net/mac80211/virtual_amp.h b/net/mac80211/virtual_amp.h
new file mode 100644
index 0000000..e45f58b
--- /dev/null
+++ b/net/mac80211/virtual_amp.h
@@ -0,0 +1,37 @@
+/*
+ * Virtual / Software AMP 80211 BT Controller header
+ *
+ * Copyright 2012 Intel Corp.
+ *
+ * Written by andrei.emeltchenko@intel.com
+ *
+ * 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.
+ */
+
+#include "ieee80211_i.h"
+
+#ifdef CONFIG_MAC80211_BLUETOOTH_SOFTAMP
+
+void ieee80211_vamp_setup_sdata(struct ieee80211_sub_if_data *sdata);
+void ieee80211_vamp_clean_sdata(struct ieee80211_sub_if_data *sdata);
+
+struct vamp_data {
+ struct hci_dev *hdev;
+ struct ieee80211_sub_if_data *sdata;
+ unsigned long flags;
+
+ struct work_struct work;
+ struct sk_buff_head txq;
+};
+
+#else /* CONFIG_MAC80211_BLUETOOTH_SOFTAMP */
+
+static inline void
+ieee80211_vamp_setup_sdata(struct ieee80211_sub_if_data *sdata) {}
+
+static inline void
+ieee80211_vamp_clean_sdata(struct ieee80211_sub_if_data *sdata) {}
+
+#endif /* CONFIG_MAC80211_BLUETOOTH_SOFTAMP */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [RFCv2 2/6] mac80211: softamp: Adds build config option
2012-04-24 13:17 [RFCv2 0/6] Draft Software/Virtual AMP80211 Andrei Emeltchenko
2012-04-24 13:17 ` [RFCv2 1/6] mac80211: softamp: Adds Bluetooth Software AMP Andrei Emeltchenko
@ 2012-04-24 13:17 ` Andrei Emeltchenko
2012-04-24 13:17 ` [RFCv2 3/6] hwsim: Adds support for BT SOFTAMP for testing Andrei Emeltchenko
` (3 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Andrei Emeltchenko @ 2012-04-24 13:17 UTC (permalink / raw)
To: linux-bluetooth, linux-wireless
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
net/mac80211/Kconfig | 9 +++++++++
net/mac80211/Makefile | 2 ++
2 files changed, 11 insertions(+)
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 96ddb72..661b679 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -67,6 +67,15 @@ config MAC80211_RC_DEFAULT_MINSTREL
endchoice
+config MAC80211_BLUETOOTH_SOFTAMP
+ bool "Bluetooth Soft AMP80211 device"
+ depends on BT
+ ---help---
+ Enable Bluetooth Virtual / Software AMP 80211 controller.
+ When AMP is common between two devices data may be routed
+ through fast 80211 connection from standard Bluetooth BR/EDR
+ connection.
+
config MAC80211_RC_DEFAULT
string
default "minstrel_ht" if MAC80211_RC_DEFAULT_MINSTREL && MAC80211_RC_MINSTREL_HT
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 1be7a45..ff0131e 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -40,6 +40,8 @@ mac80211-$(CONFIG_MAC80211_MESH) += \
mesh_plink.o \
mesh_hwmp.o
+mac80211-$(CONFIG_MAC80211_BLUETOOTH_SOFTAMP) += virtual_amp.o
+
mac80211-$(CONFIG_PM) += pm.o
CFLAGS_driver-trace.o := -I$(src)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [RFCv2 3/6] hwsim: Adds support for BT SOFTAMP for testing
2012-04-24 13:17 [RFCv2 0/6] Draft Software/Virtual AMP80211 Andrei Emeltchenko
2012-04-24 13:17 ` [RFCv2 1/6] mac80211: softamp: Adds Bluetooth Software AMP Andrei Emeltchenko
2012-04-24 13:17 ` [RFCv2 2/6] mac80211: softamp: Adds build config option Andrei Emeltchenko
@ 2012-04-24 13:17 ` Andrei Emeltchenko
2012-04-24 13:17 ` [RFCv2 4/6] mac80211: softamp: Handle assoc request Andrei Emeltchenko
` (2 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Andrei Emeltchenko @ 2012-04-24 13:17 UTC (permalink / raw)
To: linux-bluetooth, linux-wireless
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
drivers/net/wireless/mac80211_hwsim.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index b7ce6a6..bff3699 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1783,7 +1783,8 @@ static int __init init_mac80211_hwsim(void)
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_ADHOC) |
- BIT(NL80211_IFTYPE_MESH_POINT);
+ BIT(NL80211_IFTYPE_MESH_POINT) |
+ BIT(NL80211_IFTYPE_BLUETOOTH_SOFTAMP);
hw->flags = IEEE80211_HW_MFP_CAPABLE |
IEEE80211_HW_SIGNAL_DBM |
--
1.7.9.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [RFCv2 4/6] mac80211: softamp: Handle assoc request
2012-04-24 13:17 [RFCv2 0/6] Draft Software/Virtual AMP80211 Andrei Emeltchenko
` (2 preceding siblings ...)
2012-04-24 13:17 ` [RFCv2 3/6] hwsim: Adds support for BT SOFTAMP for testing Andrei Emeltchenko
@ 2012-04-24 13:17 ` Andrei Emeltchenko
2012-05-07 11:42 ` Johannes Berg
2012-04-24 13:17 ` [RFCv2 5/6] mac80211: softamp: Netlink interface to softamp Andrei Emeltchenko
2012-04-24 13:17 ` [RFCv2 6/6] mac80211: softamp: Handle data traffic Andrei Emeltchenko
5 siblings, 1 reply; 12+ messages in thread
From: Andrei Emeltchenko @ 2012-04-24 13:17 UTC (permalink / raw)
To: linux-bluetooth, linux-wireless
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Handle AMP assoc request.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
net/mac80211/virtual_amp.c | 138 ++++++++++++++++++++++++++++++++++++++++++++
net/mac80211/virtual_amp.h | 20 +++++++
2 files changed, 158 insertions(+)
diff --git a/net/mac80211/virtual_amp.c b/net/mac80211/virtual_amp.c
index 3c81fda..19e5530 100644
--- a/net/mac80211/virtual_amp.c
+++ b/net/mac80211/virtual_amp.c
@@ -179,6 +179,140 @@ static void vamp_cmd_read_local_amp_info(struct vamp_data *data,
hci_send_evt_cmplt(hdev, HCI_OP_READ_LOCAL_AMP_INFO, sizeof(rp), &rp);
}
+/* Add Type-Length-Value to buffer */
+static u16 tlv_add(u8 *msg, u8 type, u16 len, u8 *val)
+{
+ struct tlv *tlvmsg = (struct tlv *) msg;
+
+ tlvmsg->type = type;
+ tlvmsg->len = cpu_to_le16(len);
+
+ memcpy(tlvmsg->val, val, len);
+
+ return len + sizeof(*tlvmsg);
+}
+
+static void vamp_cmd_read_local_amp_assoc(struct vamp_data *data,
+ struct sk_buff *skb)
+{
+ struct hci_dev *hdev = data->hdev;
+ struct ieee80211_sub_if_data *sdata = data->sdata;
+ struct hci_cp_read_local_amp_assoc *cp = (void *) skb->data;
+ struct hci_rp_read_local_amp_assoc *rp;
+ struct softamp_pref_chans pref_chans = {
+ .country_code = { 'X', 'X', 'X' }
+ };
+ enum ieee80211_band band;
+ int buf_len = 0, triplet_size;
+ u8 num_triplet = 0;
+
+ char buf[670];
+ char mac[ETH_ALEN];
+
+ char pal_cap[] = { 0x00, 0x00, 0x00, 0x00 };
+ char pal_ver[] = {
+ 0x01 /*PAL version*/,
+ 0x00, 0x01 /* PAL company ID*/,
+ 0x00, 0x01 /* PAL sub version */
+ };
+
+ BT_DBG("%s", hdev->name);
+
+ memcpy(mac, sdata->vif.addr, ETH_ALEN);
+
+ /* Add wireless MAC address */
+ buf_len += tlv_add(buf, SOFTAMP_MAC_ADDR_TYPE, sizeof(mac), mac);
+
+ /* Add PAL capacities */
+ buf_len += tlv_add(buf + buf_len, SOFTAMP_PAL_CAP_TYPE,
+ sizeof(pal_cap), pal_cap);
+
+ /* Add PAL version info */
+ buf_len += tlv_add(buf + buf_len, SOFTAMP_PAL_VER_INFO,
+ sizeof(pal_ver), pal_ver);
+
+ /* Add Preffered Channel list */
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_country_ie_triplet *t;
+ u8 flag = 0, first_chan = 0, prev_chan = 0, max_power = 0;
+ u8 j, chan_num = 0, num_parsed_chans = 0;
+
+ sband = sdata->wdev.wiphy->bands[band];
+
+ for (j = 0; j < sband->n_channels; j++) {
+ struct ieee80211_channel *ch = &sband->channels[j];
+
+ if (ch->flags & IEEE80211_CHAN_DISABLED)
+ continue;
+
+ chan_num = ieee80211_frequency_to_channel(
+ ch->center_freq);
+
+ if (!flag) {
+ /* First channel in a range */
+ flag = 1;
+ first_chan = chan_num;
+ prev_chan = first_chan;
+ max_power = ch->max_power;
+ num_parsed_chans = 1;
+
+ continue;
+ }
+
+ if (chan_num == prev_chan + 1 &&
+ ch->max_power == max_power) {
+ prev_chan++;
+ num_parsed_chans++;
+ } else {
+ /* Add channel previous triplet*/
+ t = &pref_chans.triplets[num_triplet];
+
+ t->chans.first_channel = first_chan;
+ t->chans.num_channels = num_parsed_chans;
+ t->chans.max_power = max_power;
+ num_triplet++;
+
+ first_chan = chan_num;
+ prev_chan = first_chan;
+ max_power = ch->max_power;
+ num_parsed_chans = 1;
+ }
+ }
+
+ /* Add whole range */
+ if (flag && num_parsed_chans != 1) {
+ t = &pref_chans.triplets[num_triplet];
+
+ t->chans.first_channel = first_chan;
+ t->chans.num_channels = num_parsed_chans;
+ t->chans.max_power = max_power;
+ num_triplet++;
+ }
+ }
+
+ triplet_size = num_triplet *
+ sizeof(struct ieee80211_country_ie_triplet) +
+ IEEE80211_COUNTRY_STRING_LEN;
+
+ buf_len += tlv_add(buf + buf_len, SOFTAMP_PREF_CHANLIST_TYPE,
+ triplet_size, (u8 *) &pref_chans);
+
+ rp = kzalloc(sizeof(*rp) + buf_len, GFP_KERNEL);
+ if (!rp)
+ return;
+
+ rp->status = 0;
+ rp->handle = cp->handle;
+ rp->rem_len = cpu_to_le16(buf_len);
+
+ memcpy(rp->frag, buf, buf_len);
+ hci_send_evt_cmplt(hdev, HCI_OP_READ_LOCAL_AMP_ASSOC,
+ buf_len + sizeof(*rp), rp);
+
+ kfree(rp);
+}
+
static void vamp_cmd_reset(struct vamp_data *data, struct sk_buff *skb)
{
struct hci_dev *hdev = data->hdev;
@@ -215,6 +349,10 @@ static void vamp_command_packet(struct vamp_data *data, struct sk_buff *skb)
vamp_cmd_read_local_amp_info(data, skb);
break;
+ case HCI_OP_READ_LOCAL_AMP_ASSOC:
+ vamp_cmd_read_local_amp_assoc(data, skb);
+ break;
+
case HCI_OP_RESET:
vamp_cmd_reset(data, skb);
break;
diff --git a/net/mac80211/virtual_amp.h b/net/mac80211/virtual_amp.h
index e45f58b..3717530 100644
--- a/net/mac80211/virtual_amp.h
+++ b/net/mac80211/virtual_amp.h
@@ -14,6 +14,26 @@
#ifdef CONFIG_MAC80211_BLUETOOTH_SOFTAMP
+#define SOFTAMP_MAC_ADDR_TYPE 1
+#define SOFTAMP_PREF_CHANLIST_TYPE 2
+#define SOFTAMP_CONNECTED_CHAN 3
+#define SOFTAMP_PAL_CAP_TYPE 4
+#define SOFTAMP_PAL_VER_INFO 5
+
+/* Data types related to ASSOC data */
+struct tlv {
+ __u8 type;
+ __u16 len;
+ __u8 val[0];
+} __packed;
+
+#define MAX_11D_TRIPLETS 83
+
+struct softamp_pref_chans {
+ __u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
+ struct ieee80211_country_ie_triplet triplets[MAX_11D_TRIPLETS];
+} __packed;
+
void ieee80211_vamp_setup_sdata(struct ieee80211_sub_if_data *sdata);
void ieee80211_vamp_clean_sdata(struct ieee80211_sub_if_data *sdata);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [RFCv2 5/6] mac80211: softamp: Netlink interface to softamp
2012-04-24 13:17 [RFCv2 0/6] Draft Software/Virtual AMP80211 Andrei Emeltchenko
` (3 preceding siblings ...)
2012-04-24 13:17 ` [RFCv2 4/6] mac80211: softamp: Handle assoc request Andrei Emeltchenko
@ 2012-04-24 13:17 ` Andrei Emeltchenko
2012-05-07 11:42 ` Johannes Berg
2012-04-24 13:17 ` [RFCv2 6/6] mac80211: softamp: Handle data traffic Andrei Emeltchenko
5 siblings, 1 reply; 12+ messages in thread
From: Andrei Emeltchenko @ 2012-04-24 13:17 UTC (permalink / raw)
To: linux-bluetooth, linux-wireless
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Adds basic netlink interface. Those packets which are not handled in
softamp will be sent via netlink for processing in user space.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
net/mac80211/virtual_amp.c | 67 ++++++++++++++++++++++++++++++++++++++++++++
net/mac80211/virtual_amp.h | 20 +++++++++++++
2 files changed, 87 insertions(+)
diff --git a/net/mac80211/virtual_amp.c b/net/mac80211/virtual_amp.c
index 19e5530..62ebb50 100644
--- a/net/mac80211/virtual_amp.c
+++ b/net/mac80211/virtual_amp.c
@@ -323,6 +323,72 @@ static void vamp_cmd_reset(struct vamp_data *data, struct sk_buff *skb)
hci_send_evt_cmplt(hdev, HCI_OP_RESET, sizeof(status), &status);
}
+static struct nla_policy softamp_policy[__NL80211_CMD_SOFTAMP_LAST] = {
+ [NL80211_CMD_SOFTAMP_HCI_EVENT] = { .type = NLA_BINARY,
+ .len = IEEE80211_MAX_DATA_LEN },
+};
+
+static int softamp_hci_event_nl(struct sk_buff *skb, struct genl_info *info)
+{
+ const u8 *frame;
+ size_t frame_len;
+
+ if (!info->attrs[NL80211_ATTR_FRAME])
+ return -EINVAL;
+
+ frame = nla_data(info->attrs[NL80211_ATTR_FRAME]);
+ frame_len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
+
+ /* Handle NL event */
+
+ return 0;
+}
+
+/* Generic Netlink operations array */
+static struct genl_ops softamp_ops[] = {
+ {
+ .cmd = NL80211_CMD_SOFTAMP_HCI_EVENT,
+ .policy = softamp_policy,
+ .doit = softamp_hci_event_nl,
+ .flags = GENL_ADMIN_PERM,
+ },
+};
+
+void softamp_hci_cmd_nl(struct vamp_data *data, struct sk_buff *skb)
+{
+ struct cfg80211_registered_device *rdev;
+ struct hci_dev *hdev = data->hdev;
+ struct sk_buff *msg;
+ void *hdr;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg)
+ return;
+
+ hdr = genlmsg_put(msg, 0, 0, &softamp_fam, 0,
+ NL80211_CMD_SOFTAMP_HCI_EVENT);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ rdev = wiphy_to_dev(data->sdata->wdev.wiphy);
+
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+ NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, (unsigned long) hdev->id);
+ NLA_PUT(msg, NL80211_ATTR_FRAME, skb->len, skb->data);
+
+ if (genlmsg_end(msg, hdr) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, data->nlpid);
+
+nla_put_failure:
+ BT_ERR("%s", hdev->name);
+}
+
static void vamp_command_packet(struct vamp_data *data, struct sk_buff *skb)
{
struct hci_command_hdr *hdr = (void *) skb->data;
@@ -358,6 +424,7 @@ static void vamp_command_packet(struct vamp_data *data, struct sk_buff *skb)
break;
default:
+ softamp_hci_cmd_nl(data, skb);
break;
}
diff --git a/net/mac80211/virtual_amp.h b/net/mac80211/virtual_amp.h
index 3717530..a353ac3 100644
--- a/net/mac80211/virtual_amp.h
+++ b/net/mac80211/virtual_amp.h
@@ -10,7 +10,11 @@
* published by the Free Software Foundation.
*/
+#include <net/cfg80211.h>
+#include <net/mac80211.h>
+
#include "ieee80211_i.h"
+#include "../wireless/core.h"
#ifdef CONFIG_MAC80211_BLUETOOTH_SOFTAMP
@@ -41,11 +45,27 @@ struct vamp_data {
struct hci_dev *hdev;
struct ieee80211_sub_if_data *sdata;
unsigned long flags;
+ __u32 nlpid;
struct work_struct work;
struct sk_buff_head txq;
};
+/* Netlink */
+enum {
+ NL80211_CMD_SOFTAMP_HCI_EVENT,
+ __NL80211_CMD_SOFTAMP_LAST,
+};
+
+/* Soft AMP netlinf family */
+static struct genl_family softamp_fam = {
+ .id = GENL_ID_GENERATE,
+ .hdrsize = 0,
+ .name = "Soft AMP",
+ .version = 1,
+ .maxattr = __NL80211_CMD_SOFTAMP_LAST,
+};
+
#else /* CONFIG_MAC80211_BLUETOOTH_SOFTAMP */
static inline void
--
1.7.9.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [RFCv2 6/6] mac80211: softamp: Handle data traffic
2012-04-24 13:17 [RFCv2 0/6] Draft Software/Virtual AMP80211 Andrei Emeltchenko
` (4 preceding siblings ...)
2012-04-24 13:17 ` [RFCv2 5/6] mac80211: softamp: Netlink interface to softamp Andrei Emeltchenko
@ 2012-04-24 13:17 ` Andrei Emeltchenko
5 siblings, 0 replies; 12+ messages in thread
From: Andrei Emeltchenko @ 2012-04-24 13:17 UTC (permalink / raw)
To: linux-bluetooth, linux-wireless
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Adds handling for data traffic. The patch is partly based on patch:
"mac80211: BT3 AMP support".
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
include/linux/ieee80211.h | 13 +++++
net/mac80211/rx.c | 4 ++
net/mac80211/sta_info.h | 4 ++
net/mac80211/virtual_amp.c | 131 +++++++++++++++++++++++++++++++++++++++++++-
net/mac80211/virtual_amp.h | 19 +++++++
5 files changed, 170 insertions(+), 1 deletion(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 210e2c3..f19728e 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -184,6 +184,19 @@ struct ieee80211_qos_hdr {
__le16 qos_ctrl;
} __attribute__ ((packed));
+#define P80211_OUI_LEN 3
+
+struct ieee80211_llc_snap_hdr {
+ /* LLC */
+ u8 dsap; /* always 0xAA */
+ u8 ssap; /* always 0xAA */
+ u8 ctrl; /* always 0x03 */
+
+ /* SNAP */
+ u8 oui[P80211_OUI_LEN]; /* organizational universal id */
+ __be16 proto;
+} __attribute__ ((packed));
+
/**
* ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set
* @fc: frame control bytes in little-endian byteorder
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index bcfe8c7..760d20c 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -30,6 +30,7 @@
#include "tkip.h"
#include "wme.h"
#include "rate.h"
+#include "virtual_amp.h"
/*
* monitor mode reception
@@ -1767,6 +1768,9 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
skb = NULL;
}
}
+ } else if (ieee80211_vif_is_softamp(&sdata->vif)) {
+ ieee80211_softamp_receive_skb(sdata, rx->skb, rx->sta);
+ return;
}
if (skb) {
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index ab05768..47ed9f0 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -362,6 +362,10 @@ struct sta_info {
} debugfs;
#endif
+#ifdef CONFIG_MAC80211_BLUETOOTH_SOFTAMP
+ u16 hci_handle;
+#endif
+
unsigned int lost_packets;
unsigned int beacon_loss_count;
diff --git a/net/mac80211/virtual_amp.c b/net/mac80211/virtual_amp.c
index 62ebb50..6d2ffef 100644
--- a/net/mac80211/virtual_amp.c
+++ b/net/mac80211/virtual_amp.c
@@ -432,14 +432,137 @@ drop:
kfree_skb(skb);
}
+void ieee80211_softamp_receive_skb(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb, struct sta_info *sta)
+{
+ struct ethhdr *hdr = (void *) skb->data;
+ struct ieee80211_llc_snap_hdr *snap_hdr;
+ struct hci_acl_hdr *acl_hdr;
+ int min_hdr = sizeof(*hdr) + sizeof(*snap_hdr);
+ u16 proto;
+
+ if (!sta)
+ goto drop;
+
+ if (skb->len < min_hdr)
+ goto drop;
+
+ if (compare_ether_addr(sta->sta.addr, hdr->h_source) ||
+ compare_ether_addr(sdata->vif.addr, hdr->h_dest))
+ goto drop;
+
+ skb_pull(skb, sizeof(*hdr));
+
+ snap_hdr = (void *) skb->data;
+ if (snap_hdr->dsap != 0xAA || snap_hdr->ssap != 0xAA ||
+ snap_hdr->ctrl != 0x03 || snap_hdr->oui[0] != 0x00 ||
+ snap_hdr->oui[1] != 0x19 || snap_hdr->oui[2] != 0x58)
+ goto drop;
+
+ skb_pull(skb, sizeof(*snap_hdr));
+
+ proto = ntohs(snap_hdr->proto);
+ switch (proto) {
+ case SOFTAMP_ACL_DATA:
+ acl_hdr = (void *) skb_push(skb, sizeof(*acl_hdr));
+ acl_hdr->handle = 0;
+ acl_hdr->dlen = cpu_to_le16(skb->len - sizeof(*acl_hdr));
+ memset(skb->cb, 0, sizeof(skb->cb));
+ bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
+ skb->dev = (void *)sdata->u.softamp.hdev;
+ hci_recv_frame(skb);
+ break;
+ }
+
+drop:
+ kfree_skb(skb);
+}
+
+static struct sta_info *find_sta_for_hndl(struct ieee80211_sub_if_data *sdata,
+ u16 handle)
+{
+ struct sta_info *sta;
+
+ list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) {
+ if (sta->sdata != sdata)
+ continue;
+ if (sta->hci_handle == handle)
+ return sta;
+ }
+
+ return NULL;
+}
+
+static void softamp_xmit_sta(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb, struct sta_info *sta,
+ u16 proto)
+{
+ struct ieee80211_tx_info *info;
+ struct ieee80211_hdr *hdr;
+ struct ieee80211_llc_snap_hdr *snap_hdr;
+ struct sk_buff *nskb;
+ u16 fc;
+ __le16 *qos;
+
+ fc = IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS |
+ IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
+
+ nskb = skb_copy_expand(skb, sizeof(*hdr) + sizeof(*snap_hdr) +
+ sizeof(*qos), 0, GFP_ATOMIC);
+ kfree_skb(skb);
+
+ if (!nskb)
+ return;
+
+ skb = nskb;
+
+ snap_hdr = (void *) skb_push(skb, sizeof(*snap_hdr));
+
+ /* 802.11 AMP LLC/SNAP encapsulation. All fields except proto
+ are hardcoded in Bluetooth Core Specification v4.0 */
+ snap_hdr->dsap = 0xAA;
+ snap_hdr->ssap = 0xAA;
+ snap_hdr->ctrl = 0x03;
+ snap_hdr->oui[0] = 0x00;
+ snap_hdr->oui[1] = 0x19;
+ snap_hdr->oui[2] = 0x58;
+
+ /* Apparently this is __be */
+ snap_hdr->proto = htons(proto);
+
+ /* QoS */
+ if (test_sta_flag(sta, WLAN_STA_WME) && sdata->local->hw.queues >= 4) {
+ fc |= IEEE80211_STYPE_QOS_DATA;
+ qos = (void *)skb_push(skb, sizeof(*qos));
+ *qos = 0;
+ }
+
+ hdr = (void *) skb_put(skb, sizeof(*hdr));
+ memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN);
+ memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
+ memcpy(hdr->addr3, sta->sta.addr, ETH_ALEN);
+ memcpy(hdr->addr4, sdata->vif.addr, ETH_ALEN);
+ hdr->frame_control = cpu_to_le16(fc);
+
+ info = IEEE80211_SKB_CB(skb);
+ memset(info, 0, sizeof(*info));
+
+ ieee80211_tx_skb(sdata, skb);
+}
+
static void vamp_acldata_packet(struct vamp_data *data, struct sk_buff *skb)
{
struct hci_acl_hdr *hdr = (void *) skb->data;
+ struct ieee80211_sub_if_data *sdata = data->sdata;
+ struct sta_info *sta;
__u16 handle, flags;
if (skb->len < sizeof(*hdr))
goto drop;
+ if (skb->len != sizeof(*hdr) + le16_to_cpu(hdr->dlen))
+ goto drop;
+
skb_pull(skb, HCI_ACL_HDR_SIZE);
handle = __le16_to_cpu(hdr->handle);
@@ -449,7 +572,13 @@ static void vamp_acldata_packet(struct vamp_data *data, struct sk_buff *skb)
BT_DBG("%s len %d handle 0x%x flags 0x%x", data->hdev->name, skb->len,
handle, flags);
- /* Send data through WIFI */
+ rcu_read_lock();
+
+ sta = find_sta_for_hndl(sdata, handle);
+ if (sta)
+ softamp_xmit_sta(sdata, skb, sta, 1);
+
+ rcu_read_unlock();
drop:
kfree_skb(skb);
diff --git a/net/mac80211/virtual_amp.h b/net/mac80211/virtual_amp.h
index a353ac3..d55da78 100644
--- a/net/mac80211/virtual_amp.h
+++ b/net/mac80211/virtual_amp.h
@@ -24,6 +24,13 @@
#define SOFTAMP_PAL_CAP_TYPE 4
#define SOFTAMP_PAL_VER_INFO 5
+/* Protocol identifiers for LLC/SNAP hdr */
+#define SOFTAMP_ACL_DATA 1
+#define SOFTAMP_ACTIVITY_REPORT 2
+#define SOFTAMP_SECURITY_FRAME 3
+#define SOFTAMP_LINK_SUPERVISION_REQ 4
+#define SOFTAMP_LINK_SUPERVISION_REPLY 5
+
/* Data types related to ASSOC data */
struct tlv {
__u8 type;
@@ -40,6 +47,8 @@ struct softamp_pref_chans {
void ieee80211_vamp_setup_sdata(struct ieee80211_sub_if_data *sdata);
void ieee80211_vamp_clean_sdata(struct ieee80211_sub_if_data *sdata);
+void ieee80211_softamp_receive_skb(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb, struct sta_info *sta);
struct vamp_data {
struct hci_dev *hdev;
@@ -74,4 +83,14 @@ ieee80211_vamp_setup_sdata(struct ieee80211_sub_if_data *sdata) {}
static inline void
ieee80211_vamp_clean_sdata(struct ieee80211_sub_if_data *sdata) {}
+static inline void
+ieee80211_softamp_receive_skb(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb, struct sta_info *sta)
+{}
+
#endif /* CONFIG_MAC80211_BLUETOOTH_SOFTAMP */
+
+static inline bool ieee80211_vif_is_softamp(struct ieee80211_vif *vif)
+{
+ return vif->type == NL80211_IFTYPE_BLUETOOTH_SOFTAMP;
+}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [RFCv2 1/6] mac80211: softamp: Adds Bluetooth Software AMP
2012-04-24 13:17 ` [RFCv2 1/6] mac80211: softamp: Adds Bluetooth Software AMP Andrei Emeltchenko
@ 2012-05-07 11:41 ` Johannes Berg
2012-05-07 11:56 ` Andrei Emeltchenko
0 siblings, 1 reply; 12+ messages in thread
From: Johannes Berg @ 2012-05-07 11:41 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth, linux-wireless
On Tue, 2012-04-24 at 16:17 +0300, Andrei Emeltchenko wrote:
> --- a/include/linux/nl80211.h
> +++ b/include/linux/nl80211.h
> @@ -1546,6 +1546,7 @@ enum nl80211_iftype {
> NL80211_IFTYPE_MESH_POINT,
> NL80211_IFTYPE_P2P_CLIENT,
> NL80211_IFTYPE_P2P_GO,
> + NL80211_IFTYPE_BLUETOOTH_SOFTAMP,
That should probably be a separate patch also updating cfg80211 (and
maybe mac80211) where needed (at least to suppress the warnings you
saw). Also documentation is needed.
> @@ -211,6 +212,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
> case NL80211_IFTYPE_STATION:
> case NL80211_IFTYPE_MONITOR:
> case NL80211_IFTYPE_ADHOC:
> + case NL80211_IFTYPE_BLUETOOTH_SOFTAMP:
> /* no special treatment */
> break;
You should never be able to come here with this interface type -- maybe
make it a warning or something.
> +static int vamp_send_frame(struct sk_buff *skb)
> +{
> + struct hci_dev *hdev = (struct hci_dev *) skb->dev;
> + struct vamp_data *data;
> +
> + BT_DBG("%s", hdev->name);
> +
> + if (!hdev) {
> + BT_ERR("Frame for unknown HCI device (hdev=NULL)");
> + return -ENODEV;
> + }
> +
> + if (!test_bit(HCI_RUNNING, &hdev->flags))
> + return -EBUSY;
> +
> + data = hci_get_drvdata(hdev);
> +
> + skb_queue_tail(&data->txq, skb);
> +
> + schedule_work(&data->work);
I don't understand the need for the asynchronous handling.
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFCv2 4/6] mac80211: softamp: Handle assoc request
2012-04-24 13:17 ` [RFCv2 4/6] mac80211: softamp: Handle assoc request Andrei Emeltchenko
@ 2012-05-07 11:42 ` Johannes Berg
0 siblings, 0 replies; 12+ messages in thread
From: Johannes Berg @ 2012-05-07 11:42 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth, linux-wireless
On Tue, 2012-04-24 at 16:17 +0300, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Handle AMP assoc request.
This needs knowledge about channel preferences etc. I think it should be
done in wpa_supplicant.
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFCv2 5/6] mac80211: softamp: Netlink interface to softamp
2012-04-24 13:17 ` [RFCv2 5/6] mac80211: softamp: Netlink interface to softamp Andrei Emeltchenko
@ 2012-05-07 11:42 ` Johannes Berg
0 siblings, 0 replies; 12+ messages in thread
From: Johannes Berg @ 2012-05-07 11:42 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth, linux-wireless
On Tue, 2012-04-24 at 16:17 +0300, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Adds basic netlink interface. Those packets which are not handled in
> softamp will be sent via netlink for processing in user space.
You must be kidding -- we have nl80211.
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFCv2 1/6] mac80211: softamp: Adds Bluetooth Software AMP
2012-05-07 11:41 ` Johannes Berg
@ 2012-05-07 11:56 ` Andrei Emeltchenko
2012-05-07 11:59 ` Johannes Berg
0 siblings, 1 reply; 12+ messages in thread
From: Andrei Emeltchenko @ 2012-05-07 11:56 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-bluetooth, linux-wireless
Hi Johannes,
On Mon, May 07, 2012 at 01:41:19PM +0200, Johannes Berg wrote:
> On Tue, 2012-04-24 at 16:17 +0300, Andrei Emeltchenko wrote:
>
> > --- a/include/linux/nl80211.h
> > +++ b/include/linux/nl80211.h
> > @@ -1546,6 +1546,7 @@ enum nl80211_iftype {
> > NL80211_IFTYPE_MESH_POINT,
> > NL80211_IFTYPE_P2P_CLIENT,
> > NL80211_IFTYPE_P2P_GO,
> > + NL80211_IFTYPE_BLUETOOTH_SOFTAMP,
>
> That should probably be a separate patch also updating cfg80211 (and
> maybe mac80211) where needed (at least to suppress the warnings you
> saw). Also documentation is needed.
>
> > @@ -211,6 +212,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
> > case NL80211_IFTYPE_STATION:
> > case NL80211_IFTYPE_MONITOR:
> > case NL80211_IFTYPE_ADHOC:
> > + case NL80211_IFTYPE_BLUETOOTH_SOFTAMP:
> > /* no special treatment */
> > break;
>
> You should never be able to come here with this interface type -- maybe
> make it a warning or something.
>
> > +static int vamp_send_frame(struct sk_buff *skb)
> > +{
> > + struct hci_dev *hdev = (struct hci_dev *) skb->dev;
> > + struct vamp_data *data;
> > +
> > + BT_DBG("%s", hdev->name);
> > +
> > + if (!hdev) {
> > + BT_ERR("Frame for unknown HCI device (hdev=NULL)");
> > + return -ENODEV;
> > + }
> > +
> > + if (!test_bit(HCI_RUNNING, &hdev->flags))
> > + return -EBUSY;
> > +
> > + data = hci_get_drvdata(hdev);
> > +
> > + skb_queue_tail(&data->txq, skb);
> > +
> > + schedule_work(&data->work);
>
> I don't understand the need for the asynchronous handling.
This is standard way for hci dev. Can be changed so that skb is handled
right here.
Best regards
Andrei Emeltchenko
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFCv2 1/6] mac80211: softamp: Adds Bluetooth Software AMP
2012-05-07 11:56 ` Andrei Emeltchenko
@ 2012-05-07 11:59 ` Johannes Berg
0 siblings, 0 replies; 12+ messages in thread
From: Johannes Berg @ 2012-05-07 11:59 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth, linux-wireless
On Mon, 2012-05-07 at 14:56 +0300, Andrei Emeltchenko wrote:
> Hi Johannes,
>
> On Mon, May 07, 2012 at 01:41:19PM +0200, Johannes Berg wrote:
> > On Tue, 2012-04-24 at 16:17 +0300, Andrei Emeltchenko wrote:
> >
> > > --- a/include/linux/nl80211.h
> > > +++ b/include/linux/nl80211.h
> > > @@ -1546,6 +1546,7 @@ enum nl80211_iftype {
> > > NL80211_IFTYPE_MESH_POINT,
> > > NL80211_IFTYPE_P2P_CLIENT,
> > > NL80211_IFTYPE_P2P_GO,
> > > + NL80211_IFTYPE_BLUETOOTH_SOFTAMP,
> >
> > That should probably be a separate patch also updating cfg80211 (and
> > maybe mac80211) where needed (at least to suppress the warnings you
> > saw). Also documentation is needed.
> >
> > > @@ -211,6 +212,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
> > > case NL80211_IFTYPE_STATION:
> > > case NL80211_IFTYPE_MONITOR:
> > > case NL80211_IFTYPE_ADHOC:
> > > + case NL80211_IFTYPE_BLUETOOTH_SOFTAMP:
> > > /* no special treatment */
> > > break;
> >
> > You should never be able to come here with this interface type -- maybe
> > make it a warning or something.
> >
> > > +static int vamp_send_frame(struct sk_buff *skb)
> > > +{
> > > + struct hci_dev *hdev = (struct hci_dev *) skb->dev;
> > > + struct vamp_data *data;
> > > +
> > > + BT_DBG("%s", hdev->name);
> > > +
> > > + if (!hdev) {
> > > + BT_ERR("Frame for unknown HCI device (hdev=NULL)");
> > > + return -ENODEV;
> > > + }
> > > +
> > > + if (!test_bit(HCI_RUNNING, &hdev->flags))
> > > + return -EBUSY;
> > > +
> > > + data = hci_get_drvdata(hdev);
> > > +
> > > + skb_queue_tail(&data->txq, skb);
> > > +
> > > + schedule_work(&data->work);
> >
> > I don't understand the need for the asynchronous handling.
>
> This is standard way for hci dev. Can be changed so that skb is handled
> right here.
"standard" doesn't explain why it's needed though, and I don't think it
is needed here.
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2012-05-07 11:59 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-04-24 13:17 [RFCv2 0/6] Draft Software/Virtual AMP80211 Andrei Emeltchenko
2012-04-24 13:17 ` [RFCv2 1/6] mac80211: softamp: Adds Bluetooth Software AMP Andrei Emeltchenko
2012-05-07 11:41 ` Johannes Berg
2012-05-07 11:56 ` Andrei Emeltchenko
2012-05-07 11:59 ` Johannes Berg
2012-04-24 13:17 ` [RFCv2 2/6] mac80211: softamp: Adds build config option Andrei Emeltchenko
2012-04-24 13:17 ` [RFCv2 3/6] hwsim: Adds support for BT SOFTAMP for testing Andrei Emeltchenko
2012-04-24 13:17 ` [RFCv2 4/6] mac80211: softamp: Handle assoc request Andrei Emeltchenko
2012-05-07 11:42 ` Johannes Berg
2012-04-24 13:17 ` [RFCv2 5/6] mac80211: softamp: Netlink interface to softamp Andrei Emeltchenko
2012-05-07 11:42 ` Johannes Berg
2012-04-24 13:17 ` [RFCv2 6/6] mac80211: softamp: Handle data traffic Andrei Emeltchenko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).