aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/bluetooth/btusb.c7
-rw-r--r--drivers/bluetooth/hci_h5.c13
-rw-r--r--drivers/net/ieee802154/at86rf230.c13
-rw-r--r--drivers/net/ieee802154/cc2520.c1
-rw-r--r--include/linux/ieee802154.h32
-rw-r--r--include/linux/netdevice.h3
-rw-r--r--include/net/bluetooth/hci.h15
-rw-r--r--include/net/bluetooth/hci_core.h21
-rw-r--r--include/net/cfg802154.h24
-rw-r--r--include/net/ieee802154_netdev.h12
-rw-r--r--include/net/mac802154.h33
-rw-r--r--include/net/nl802154.h122
-rw-r--r--net/6lowpan/iphc.c41
-rw-r--r--net/bluetooth/6lowpan.c15
-rw-r--r--net/bluetooth/Kconfig20
-rw-r--r--net/bluetooth/bnep/Kconfig2
-rw-r--r--net/bluetooth/cmtp/Kconfig2
-rw-r--r--net/bluetooth/hci_core.c72
-rw-r--r--net/bluetooth/hci_event.c61
-rw-r--r--net/bluetooth/hidp/Kconfig2
-rw-r--r--net/bluetooth/mgmt.c56
-rw-r--r--net/bluetooth/rfcomm/Kconfig2
-rw-r--r--net/bluetooth/rfcomm/core.c6
-rw-r--r--net/ieee802154/6lowpan_rtnl.c38
-rw-r--r--net/ieee802154/core.c64
-rw-r--r--net/ieee802154/core.h29
-rw-r--r--net/ieee802154/nl-mac.c203
-rw-r--r--net/ieee802154/nl-phy.c23
-rw-r--r--net/ieee802154/rdev-ops.h23
-rw-r--r--net/ieee802154/sysfs.c16
-rw-r--r--net/mac802154/Makefile2
-rw-r--r--net/mac802154/cfg.c47
-rw-r--r--net/mac802154/cfg.h9
-rw-r--r--net/mac802154/ieee802154_i.h17
-rw-r--r--net/mac802154/iface.c195
-rw-r--r--net/mac802154/mac_cmd.c42
-rw-r--r--net/mac802154/main.c102
-rw-r--r--net/mac802154/mib.c71
-rw-r--r--net/mac802154/rx.c4
40 files changed, 678 insertions, 783 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 7ec37a396ffe..b42eb50b7426 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4699,7 +4699,6 @@ F: net/mac802154/
4699F: drivers/net/ieee802154/ 4699F: drivers/net/ieee802154/
4700F: include/linux/nl802154.h 4700F: include/linux/nl802154.h
4701F: include/linux/ieee802154.h 4701F: include/linux/ieee802154.h
4702F: include/net/nl802154.h
4703F: include/net/mac802154.h 4702F: include/net/mac802154.h
4704F: include/net/af_ieee802154.h 4703F: include/net/af_ieee802154.h
4705F: include/net/cfg802154.h 4704F: include/net/cfg802154.h
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 03ce301fca92..cd634f3b76d3 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -299,6 +299,8 @@ struct btusb_data {
299 unsigned int sco_num; 299 unsigned int sco_num;
300 int isoc_altsetting; 300 int isoc_altsetting;
301 int suspend_count; 301 int suspend_count;
302
303 int (*recv_bulk)(struct btusb_data *data, void *buffer, int count);
302}; 304};
303 305
304static inline void btusb_free_frags(struct btusb_data *data) 306static inline void btusb_free_frags(struct btusb_data *data)
@@ -590,7 +592,7 @@ static void btusb_bulk_complete(struct urb *urb)
590 if (urb->status == 0) { 592 if (urb->status == 0) {
591 hdev->stat.byte_rx += urb->actual_length; 593 hdev->stat.byte_rx += urb->actual_length;
592 594
593 if (btusb_recv_bulk(data, urb->transfer_buffer, 595 if (data->recv_bulk(data, urb->transfer_buffer,
594 urb->actual_length) < 0) { 596 urb->actual_length) < 0) {
595 BT_ERR("%s corrupted ACL packet", hdev->name); 597 BT_ERR("%s corrupted ACL packet", hdev->name);
596 hdev->stat.err_rx++; 598 hdev->stat.err_rx++;
@@ -2012,6 +2014,8 @@ static int btusb_probe(struct usb_interface *intf,
2012 init_usb_anchor(&data->isoc_anchor); 2014 init_usb_anchor(&data->isoc_anchor);
2013 spin_lock_init(&data->rxlock); 2015 spin_lock_init(&data->rxlock);
2014 2016
2017 data->recv_bulk = btusb_recv_bulk;
2018
2015 hdev = hci_alloc_dev(); 2019 hdev = hci_alloc_dev();
2016 if (!hdev) 2020 if (!hdev)
2017 return -ENOMEM; 2021 return -ENOMEM;
@@ -2035,6 +2039,7 @@ static int btusb_probe(struct usb_interface *intf,
2035 if (id->driver_info & BTUSB_BCM_PATCHRAM) { 2039 if (id->driver_info & BTUSB_BCM_PATCHRAM) {
2036 hdev->setup = btusb_setup_bcm_patchram; 2040 hdev->setup = btusb_setup_bcm_patchram;
2037 hdev->set_bdaddr = btusb_set_bdaddr_bcm; 2041 hdev->set_bdaddr = btusb_set_bdaddr_bcm;
2042 set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
2038 } 2043 }
2039 2044
2040 if (id->driver_info & BTUSB_INTEL) { 2045 if (id->driver_info & BTUSB_INTEL) {
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index 20bdd71559b1..ec0fa7732c0d 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -171,8 +171,6 @@ wakeup:
171static void h5_peer_reset(struct hci_uart *hu) 171static void h5_peer_reset(struct hci_uart *hu)
172{ 172{
173 struct h5 *h5 = hu->priv; 173 struct h5 *h5 = hu->priv;
174 struct sk_buff *skb;
175 const unsigned char hard_err[] = { 0x10, 0x01, 0x00 };
176 174
177 BT_ERR("Peer device has reset"); 175 BT_ERR("Peer device has reset");
178 176
@@ -187,15 +185,8 @@ static void h5_peer_reset(struct hci_uart *hu)
187 h5->tx_seq = 0; 185 h5->tx_seq = 0;
188 h5->tx_ack = 0; 186 h5->tx_ack = 0;
189 187
190 skb = bt_skb_alloc(3, GFP_ATOMIC); 188 /* Send reset request to upper stack */
191 if (!skb) 189 hci_reset_dev(hu->hdev);
192 return;
193
194 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
195 memcpy(skb_put(skb, 3), hard_err, 3);
196
197 /* Send Hardware Error to upper stack */
198 hci_recv_frame(hu->hdev, skb);
199} 190}
200 191
201static int h5_open(struct hci_uart *hu) 192static int h5_open(struct hci_uart *hu)
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index 9ad2d432ef43..ebcbeb3a06e8 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -1047,7 +1047,7 @@ at86rf230_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
1047 struct at86rf230_local *lp = hw->priv; 1047 struct at86rf230_local *lp = hw->priv;
1048 int rc; 1048 int rc;
1049 1049
1050 if (page < 0 || page > 31 || 1050 if (page > 31 ||
1051 !(lp->hw->phy->channels_supported[page] & BIT(channel))) { 1051 !(lp->hw->phy->channels_supported[page] & BIT(channel))) {
1052 WARN_ON(1); 1052 WARN_ON(1);
1053 return -EINVAL; 1053 return -EINVAL;
@@ -1358,7 +1358,11 @@ static int at86rf230_hw_init(struct at86rf230_local *lp)
1358 return -EINVAL; 1358 return -EINVAL;
1359 } 1359 }
1360 1360
1361 return 0; 1361 /* Force setting slotted operation bit to 0. Sometimes the atben
1362 * sets this bit and I don't know why. We set this always force
1363 * to zero while probing.
1364 */
1365 return at86rf230_write_subreg(lp, SR_SLOTTED_OPERATION, 0);
1362} 1366}
1363 1367
1364static struct at86rf230_platform_data * 1368static struct at86rf230_platform_data *
@@ -1427,6 +1431,7 @@ at86rf230_detect_device(struct at86rf230_local *lp)
1427 chip = "at86rf231"; 1431 chip = "at86rf231";
1428 lp->data = &at86rf231_data; 1432 lp->data = &at86rf231_data;
1429 lp->hw->phy->channels_supported[0] = 0x7FFF800; 1433 lp->hw->phy->channels_supported[0] = 0x7FFF800;
1434 lp->hw->phy->current_channel = 11;
1430 break; 1435 break;
1431 case 7: 1436 case 7:
1432 chip = "at86rf212"; 1437 chip = "at86rf212";
@@ -1435,6 +1440,7 @@ at86rf230_detect_device(struct at86rf230_local *lp)
1435 lp->hw->flags |= IEEE802154_HW_LBT; 1440 lp->hw->flags |= IEEE802154_HW_LBT;
1436 lp->hw->phy->channels_supported[0] = 0x00007FF; 1441 lp->hw->phy->channels_supported[0] = 0x00007FF;
1437 lp->hw->phy->channels_supported[2] = 0x00007FF; 1442 lp->hw->phy->channels_supported[2] = 0x00007FF;
1443 lp->hw->phy->current_channel = 5;
1438 } else { 1444 } else {
1439 rc = -ENOTSUPP; 1445 rc = -ENOTSUPP;
1440 } 1446 }
@@ -1443,6 +1449,7 @@ at86rf230_detect_device(struct at86rf230_local *lp)
1443 chip = "at86rf233"; 1449 chip = "at86rf233";
1444 lp->data = &at86rf233_data; 1450 lp->data = &at86rf233_data;
1445 lp->hw->phy->channels_supported[0] = 0x7FFF800; 1451 lp->hw->phy->channels_supported[0] = 0x7FFF800;
1452 lp->hw->phy->current_channel = 13;
1446 break; 1453 break;
1447 default: 1454 default:
1448 chip = "unkown"; 1455 chip = "unkown";
@@ -1530,6 +1537,8 @@ static int at86rf230_probe(struct spi_device *spi)
1530 lp->hw = hw; 1537 lp->hw = hw;
1531 lp->spi = spi; 1538 lp->spi = spi;
1532 hw->parent = &spi->dev; 1539 hw->parent = &spi->dev;
1540 hw->vif_data_size = sizeof(*lp);
1541 ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
1533 1542
1534 lp->regmap = devm_regmap_init_spi(spi, &at86rf230_regmap_spi_config); 1543 lp->regmap = devm_regmap_init_spi(spi, &at86rf230_regmap_spi_config);
1535 if (IS_ERR(lp->regmap)) { 1544 if (IS_ERR(lp->regmap)) {
diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c
index 340671b747b1..ccbb082f3391 100644
--- a/drivers/net/ieee802154/cc2520.c
+++ b/drivers/net/ieee802154/cc2520.c
@@ -651,6 +651,7 @@ static int cc2520_register(struct cc2520_private *priv)
651 priv->hw->priv = priv; 651 priv->hw->priv = priv;
652 priv->hw->parent = &priv->spi->dev; 652 priv->hw->parent = &priv->spi->dev;
653 priv->hw->extra_tx_headroom = 0; 653 priv->hw->extra_tx_headroom = 0;
654 priv->hw->vif_data_size = sizeof(*priv);
654 655
655 /* We do support only 2.4 Ghz */ 656 /* We do support only 2.4 Ghz */
656 priv->hw->phy->channels_supported[0] = 0x7FFF800; 657 priv->hw->phy->channels_supported[0] = 0x7FFF800;
diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h
index 6e50a2a1d485..d043449a079d 100644
--- a/include/linux/ieee802154.h
+++ b/include/linux/ieee802154.h
@@ -24,10 +24,14 @@
24#define LINUX_IEEE802154_H 24#define LINUX_IEEE802154_H
25 25
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/random.h>
28#include <asm/byteorder.h>
27 29
28#define IEEE802154_MTU 127 30#define IEEE802154_MTU 127
29#define IEEE802154_MIN_PSDU_LEN 5 31#define IEEE802154_MIN_PSDU_LEN 5
30 32
33#define IEEE802154_EXTENDED_ADDR_LEN 8
34
31#define IEEE802154_FC_TYPE_BEACON 0x0 /* Frame is beacon */ 35#define IEEE802154_FC_TYPE_BEACON 0x0 /* Frame is beacon */
32#define IEEE802154_FC_TYPE_DATA 0x1 /* Frame is data */ 36#define IEEE802154_FC_TYPE_DATA 0x1 /* Frame is data */
33#define IEEE802154_FC_TYPE_ACK 0x2 /* Frame is acknowledgment */ 37#define IEEE802154_FC_TYPE_ACK 0x2 /* Frame is acknowledgment */
@@ -197,4 +201,32 @@ static inline bool ieee802154_is_valid_psdu_len(const u8 len)
197 return (len >= IEEE802154_MIN_PSDU_LEN && len <= IEEE802154_MTU); 201 return (len >= IEEE802154_MIN_PSDU_LEN && len <= IEEE802154_MTU);
198} 202}
199 203
204/**
205 * ieee802154_is_valid_psdu_len - check if extended addr is valid
206 * @addr: extended addr to check
207 */
208static inline bool ieee802154_is_valid_extended_addr(const __le64 addr)
209{
210 /* These EUI-64 addresses are reserved by IEEE. 0xffffffffffffffff
211 * is used internally as extended to short address broadcast mapping.
212 * This is currently a workaround because neighbor discovery can't
213 * deal with short addresses types right now.
214 */
215 return ((addr != cpu_to_le64(0x0000000000000000ULL)) &&
216 (addr != cpu_to_le64(0xffffffffffffffffULL)));
217}
218
219/**
220 * ieee802154_random_extended_addr - generates a random extended address
221 * @addr: extended addr pointer to place the random address
222 */
223static inline void ieee802154_random_extended_addr(__le64 *addr)
224{
225 get_random_bytes(addr, IEEE802154_EXTENDED_ADDR_LEN);
226
227 /* toggle some bit if we hit an invalid extended addr */
228 if (!ieee802154_is_valid_extended_addr(*addr))
229 ((u8 *)addr)[IEEE802154_EXTENDED_ADDR_LEN - 1] ^= 0x01;
230}
231
200#endif /* LINUX_IEEE802154_H */ 232#endif /* LINUX_IEEE802154_H */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 74fd5d37f15a..c9bcf33efb47 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -57,6 +57,8 @@ struct device;
57struct phy_device; 57struct phy_device;
58/* 802.11 specific */ 58/* 802.11 specific */
59struct wireless_dev; 59struct wireless_dev;
60/* 802.15.4 specific */
61struct wpan_dev;
60 62
61void netdev_set_default_ethtool_ops(struct net_device *dev, 63void netdev_set_default_ethtool_ops(struct net_device *dev,
62 const struct ethtool_ops *ops); 64 const struct ethtool_ops *ops);
@@ -1572,6 +1574,7 @@ struct net_device {
1572 struct inet6_dev __rcu *ip6_ptr; 1574 struct inet6_dev __rcu *ip6_ptr;
1573 void *ax25_ptr; 1575 void *ax25_ptr;
1574 struct wireless_dev *ieee80211_ptr; 1576 struct wireless_dev *ieee80211_ptr;
1577 struct wpan_dev *ieee802154_ptr;
1575 1578
1576/* 1579/*
1577 * Cache lines mostly used on receive path (including eth_type_trans()) 1580 * Cache lines mostly used on receive path (including eth_type_trans())
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 6e8f24967308..d5f85d7746bc 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -129,6 +129,15 @@ enum {
129 * during the hdev->setup vendor callback. 129 * during the hdev->setup vendor callback.
130 */ 130 */
131 HCI_QUIRK_INVALID_BDADDR, 131 HCI_QUIRK_INVALID_BDADDR,
132
133 /* When this quirk is set, the duplicate filtering during
134 * scanning is based on Bluetooth devices addresses. To allow
135 * RSSI based updates, restart scanning if needed.
136 *
137 * This quirk can be set before hci_register_dev is called or
138 * during the hdev->setup vendor callback.
139 */
140 HCI_QUIRK_STRICT_DUPLICATE_FILTER,
132}; 141};
133 142
134/* HCI device flags */ 143/* HCI device flags */
@@ -265,6 +274,7 @@ enum {
265/* Low Energy links do not have defined link type. Use invented one */ 274/* Low Energy links do not have defined link type. Use invented one */
266#define LE_LINK 0x80 275#define LE_LINK 0x80
267#define AMP_LINK 0x81 276#define AMP_LINK 0x81
277#define INVALID_LINK 0xff
268 278
269/* LMP features */ 279/* LMP features */
270#define LMP_3SLOT 0x01 280#define LMP_3SLOT 0x01
@@ -1463,6 +1473,11 @@ struct hci_ev_cmd_status {
1463 __le16 opcode; 1473 __le16 opcode;
1464} __packed; 1474} __packed;
1465 1475
1476#define HCI_EV_HARDWARE_ERROR 0x10
1477struct hci_ev_hardware_error {
1478 __u8 code;
1479} __packed;
1480
1466#define HCI_EV_ROLE_CHANGE 0x12 1481#define HCI_EV_ROLE_CHANGE 0x12
1467struct hci_ev_role_change { 1482struct hci_ev_role_change {
1468 __u8 status; 1483 __u8 status;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index b8685a77a15e..4e39a5adfcab 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -646,6 +646,26 @@ static inline unsigned int hci_conn_count(struct hci_dev *hdev)
646 return c->acl_num + c->amp_num + c->sco_num + c->le_num; 646 return c->acl_num + c->amp_num + c->sco_num + c->le_num;
647} 647}
648 648
649static inline __u8 hci_conn_lookup_type(struct hci_dev *hdev, __u16 handle)
650{
651 struct hci_conn_hash *h = &hdev->conn_hash;
652 struct hci_conn *c;
653 __u8 type = INVALID_LINK;
654
655 rcu_read_lock();
656
657 list_for_each_entry_rcu(c, &h->list, list) {
658 if (c->handle == handle) {
659 type = c->type;
660 break;
661 }
662 }
663
664 rcu_read_unlock();
665
666 return type;
667}
668
649static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev, 669static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
650 __u16 handle) 670 __u16 handle)
651{ 671{
@@ -856,6 +876,7 @@ int hci_register_dev(struct hci_dev *hdev);
856void hci_unregister_dev(struct hci_dev *hdev); 876void hci_unregister_dev(struct hci_dev *hdev);
857int hci_suspend_dev(struct hci_dev *hdev); 877int hci_suspend_dev(struct hci_dev *hdev);
858int hci_resume_dev(struct hci_dev *hdev); 878int hci_resume_dev(struct hci_dev *hdev);
879int hci_reset_dev(struct hci_dev *hdev);
859int hci_dev_open(__u16 dev); 880int hci_dev_open(__u16 dev);
860int hci_dev_close(__u16 dev); 881int hci_dev_close(__u16 dev);
861int hci_dev_reset(__u16 dev); 882int hci_dev_reset(__u16 dev);
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 440b9bece9c6..9d99b9655760 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -29,6 +29,16 @@
29#define WPAN_NUM_CHANNELS 27 29#define WPAN_NUM_CHANNELS 27
30#define WPAN_NUM_PAGES 32 30#define WPAN_NUM_PAGES 32
31 31
32struct wpan_phy;
33
34struct cfg802154_ops {
35 struct net_device * (*add_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
36 const char *name,
37 int type);
38 void (*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
39 struct net_device *dev);
40};
41
32struct wpan_phy { 42struct wpan_phy {
33 struct mutex pib_lock; 43 struct mutex pib_lock;
34 44
@@ -47,22 +57,24 @@ struct wpan_phy {
47 u8 csma_retries; 57 u8 csma_retries;
48 s8 frame_retries; 58 s8 frame_retries;
49 59
60 __le64 perm_extended_addr;
61
50 bool lbt; 62 bool lbt;
51 s32 cca_ed_level; 63 s32 cca_ed_level;
52 64
53 struct device dev; 65 struct device dev;
54 int idx;
55
56 struct net_device *(*add_iface)(struct wpan_phy *phy,
57 const char *name, int type);
58 void (*del_iface)(struct wpan_phy *phy, struct net_device *dev);
59 66
60 char priv[0] __aligned(NETDEV_ALIGN); 67 char priv[0] __aligned(NETDEV_ALIGN);
61}; 68};
62 69
70struct wpan_dev {
71 struct wpan_phy *wpan_phy;
72};
73
63#define to_phy(_dev) container_of(_dev, struct wpan_phy, dev) 74#define to_phy(_dev) container_of(_dev, struct wpan_phy, dev)
64 75
65struct wpan_phy *wpan_phy_alloc(size_t priv_size); 76struct wpan_phy *
77wpan_phy_alloc(const struct cfg802154_ops *ops, size_t priv_size);
66static inline void wpan_phy_set_dev(struct wpan_phy *phy, struct device *dev) 78static inline void wpan_phy_set_dev(struct wpan_phy *phy, struct device *dev)
67{ 79{
68 phy->dev.parent = dev; 80 phy->dev.parent = dev;
diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
index 5e62d758eea5..83bb8a73d23c 100644
--- a/include/net/ieee802154_netdev.h
+++ b/include/net/ieee802154_netdev.h
@@ -423,8 +423,6 @@ struct ieee802154_mlme_ops {
423 423
424 /* The fields below are required. */ 424 /* The fields below are required. */
425 425
426 struct wpan_phy *(*get_phy)(const struct net_device *dev);
427
428 /* 426 /*
429 * FIXME: these should become the part of PIB/MIB interface. 427 * FIXME: these should become the part of PIB/MIB interface.
430 * However we still don't have IB interface of any kind 428 * However we still don't have IB interface of any kind
@@ -434,16 +432,6 @@ struct ieee802154_mlme_ops {
434 u8 (*get_dsn)(const struct net_device *dev); 432 u8 (*get_dsn)(const struct net_device *dev);
435}; 433};
436 434
437/* The IEEE 802.15.4 standard defines 2 type of the devices:
438 * - FFD - full functionality device
439 * - RFD - reduce functionality device
440 *
441 * So 2 sets of mlme operations are needed
442 */
443struct ieee802154_reduced_mlme_ops {
444 struct wpan_phy *(*get_phy)(const struct net_device *dev);
445};
446
447static inline struct ieee802154_mlme_ops * 435static inline struct ieee802154_mlme_ops *
448ieee802154_mlme_ops(const struct net_device *dev) 436ieee802154_mlme_ops(const struct net_device *dev)
449{ 437{
diff --git a/include/net/mac802154.h b/include/net/mac802154.h
index 8f1de6844cb0..632f6566adb5 100644
--- a/include/net/mac802154.h
+++ b/include/net/mac802154.h
@@ -17,6 +17,7 @@
17#define NET_MAC802154_H 17#define NET_MAC802154_H
18 18
19#include <net/af_ieee802154.h> 19#include <net/af_ieee802154.h>
20#include <linux/ieee802154.h>
20#include <linux/skbuff.h> 21#include <linux/skbuff.h>
21 22
22/* General MAC frame format: 23/* General MAC frame format:
@@ -52,6 +53,13 @@ struct ieee802154_hw_addr_filt {
52 u8 pan_coord; 53 u8 pan_coord;
53}; 54};
54 55
56struct ieee802154_vif {
57 int type;
58
59 /* must be last */
60 u8 drv_priv[0] __aligned(sizeof(void *));
61};
62
55struct ieee802154_hw { 63struct ieee802154_hw {
56 /* filled by the driver */ 64 /* filled by the driver */
57 int extra_tx_headroom; 65 int extra_tx_headroom;
@@ -62,6 +70,7 @@ struct ieee802154_hw {
62 struct ieee802154_hw_addr_filt hw_filt; 70 struct ieee802154_hw_addr_filt hw_filt;
63 void *priv; 71 void *priv;
64 struct wpan_phy *phy; 72 struct wpan_phy *phy;
73 size_t vif_data_size;
65}; 74};
66 75
67/* Checksum is in hardware and is omitted from a packet 76/* Checksum is in hardware and is omitted from a packet
@@ -214,6 +223,30 @@ struct ieee802154_ops {
214 const bool on); 223 const bool on);
215}; 224};
216 225
226/**
227 * ieee802154_be64_to_le64 - copies and convert be64 to le64
228 * @le64_dst: le64 destination pointer
229 * @be64_src: be64 source pointer
230 */
231static inline void ieee802154_be64_to_le64(void *le64_dst, const void *be64_src)
232{
233 __le64 tmp = (__force __le64)swab64p(be64_src);
234
235 memcpy(le64_dst, &tmp, IEEE802154_EXTENDED_ADDR_LEN);
236}
237
238/**
239 * ieee802154_le64_to_be64 - copies and convert le64 to be64
240 * @be64_dst: be64 destination pointer
241 * @le64_src: le64 source pointer
242 */
243static inline void ieee802154_le64_to_be64(void *be64_dst, const void *le64_src)
244{
245 __be64 tmp = (__force __be64)swab64p(le64_src);
246
247 memcpy(be64_dst, &tmp, IEEE802154_EXTENDED_ADDR_LEN);
248}
249
217/* Basic interface to register ieee802154 hwice */ 250/* Basic interface to register ieee802154 hwice */
218struct ieee802154_hw * 251struct ieee802154_hw *
219ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops); 252ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops);
diff --git a/include/net/nl802154.h b/include/net/nl802154.h
deleted file mode 100644
index b5cdea29d9d9..000000000000
--- a/include/net/nl802154.h
+++ /dev/null
@@ -1,122 +0,0 @@
1/*
2 * nl802154.h
3 *
4 * Copyright (C) 2007, 2008, 2009 Siemens AG
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef IEEE802154_NL_H
18#define IEEE802154_NL_H
19
20struct net_device;
21struct ieee802154_addr;
22
23/**
24 * ieee802154_nl_assoc_indic - Notify userland of an association request.
25 * @dev: The network device on which this association request was
26 * received.
27 * @addr: The address of the device requesting association.
28 * @cap: The capability information field from the device.
29 *
30 * This informs a userland coordinator of a device requesting to
31 * associate with the PAN controlled by the coordinator.
32 *
33 * Note: This is in section 7.3.1 of the IEEE 802.15.4-2006 document.
34 */
35int ieee802154_nl_assoc_indic(struct net_device *dev,
36 struct ieee802154_addr *addr, u8 cap);
37
38/**
39 * ieee802154_nl_assoc_confirm - Notify userland of association.
40 * @dev: The device which has completed association.
41 * @short_addr: The short address assigned to the device.
42 * @status: The status of the association.
43 *
44 * Inform userland of the result of an association request. If the
45 * association request included asking the coordinator to allocate
46 * a short address then it is returned in @short_addr.
47 *
48 * Note: This is in section 7.3.2 of the IEEE 802.15.4 document.
49 */
50int ieee802154_nl_assoc_confirm(struct net_device *dev,
51 __le16 short_addr, u8 status);
52
53/**
54 * ieee802154_nl_disassoc_indic - Notify userland of disassociation.
55 * @dev: The device on which disassociation was indicated.
56 * @addr: The device which is disassociating.
57 * @reason: The reason for the disassociation.
58 *
59 * Inform userland that a device has disassociated from the network.
60 *
61 * Note: This is in section 7.3.3 of the IEEE 802.15.4 document.
62 */
63int ieee802154_nl_disassoc_indic(struct net_device *dev,
64 struct ieee802154_addr *addr, u8 reason);
65
66/**
67 * ieee802154_nl_disassoc_confirm - Notify userland of disassociation
68 * completion.
69 * @dev: The device on which disassociation was ordered.
70 * @status: The result of the disassociation.
71 *
72 * Inform userland of the result of requesting that a device
73 * disassociate, or the result of requesting that we disassociate from
74 * a PAN managed by another coordinator.
75 *
76 * Note: This is in section 7.1.4.3 of the IEEE 802.15.4 document.
77 */
78int ieee802154_nl_disassoc_confirm(struct net_device *dev,
79 u8 status);
80
81/**
82 * ieee802154_nl_scan_confirm - Notify userland of completion of scan.
83 * @dev: The device which was instructed to scan.
84 * @status: The status of the scan operation.
85 * @scan_type: What type of scan was performed.
86 * @unscanned: Any channels that the device was unable to scan.
87 * @edl: The energy levels (if a passive scan).
88 *
89 *
90 * Note: This is in section 7.1.11 of the IEEE 802.15.4 document.
91 * Note: This API does not permit the return of an active scan result.
92 */
93int ieee802154_nl_scan_confirm(struct net_device *dev,
94 u8 status, u8 scan_type, u32 unscanned, u8 page,
95 u8 *edl/*, struct list_head *pan_desc_list */);
96
97/**
98 * ieee802154_nl_beacon_indic - Notify userland of a received beacon.
99 * @dev: The device on which a beacon was received.
100 * @panid: The PAN of the coordinator.
101 * @coord_addr: The short address of the coordinator on that PAN.
102 *
103 * Note: This is in section 7.1.5 of the IEEE 802.15.4 document.
104 * Note: This API does not provide extended information such as what
105 * channel the PAN is on or what the LQI of the beacon frame was on
106 * receipt.
107 * Note: This API cannot indicate a beacon frame for a coordinator
108 * operating in long addressing mode.
109 */
110int ieee802154_nl_beacon_indic(struct net_device *dev, __le16 panid,
111 __le16 coord_addr);
112
113/**
114 * ieee802154_nl_start_confirm - Notify userland of completion of start.
115 * @dev: The device which was instructed to scan.
116 * @status: The status of the scan operation.
117 *
118 * Note: This is in section 7.1.14 of the IEEE 802.15.4 document.
119 */
120int ieee802154_nl_start_confirm(struct net_device *dev, u8 status);
121
122#endif
diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c
index 73a7065f0c6b..aced97db62f0 100644
--- a/net/6lowpan/iphc.c
+++ b/net/6lowpan/iphc.c
@@ -319,7 +319,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
319 if (iphc1 & LOWPAN_IPHC_CID) { 319 if (iphc1 & LOWPAN_IPHC_CID) {
320 pr_debug("CID flag is set, increase header with one\n"); 320 pr_debug("CID flag is set, increase header with one\n");
321 if (lowpan_fetch_skb(skb, &num_context, sizeof(num_context))) 321 if (lowpan_fetch_skb(skb, &num_context, sizeof(num_context)))
322 goto drop; 322 return -EINVAL;
323 } 323 }
324 324
325 hdr.version = 6; 325 hdr.version = 6;
@@ -331,7 +331,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
331 */ 331 */
332 case 0: /* 00b */ 332 case 0: /* 00b */
333 if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp))) 333 if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp)))
334 goto drop; 334 return -EINVAL;
335 335
336 memcpy(&hdr.flow_lbl, &skb->data[0], 3); 336 memcpy(&hdr.flow_lbl, &skb->data[0], 3);
337 skb_pull(skb, 3); 337 skb_pull(skb, 3);
@@ -344,7 +344,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
344 */ 344 */
345 case 2: /* 10b */ 345 case 2: /* 10b */
346 if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp))) 346 if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp)))
347 goto drop; 347 return -EINVAL;
348 348
349 hdr.priority = ((tmp >> 2) & 0x0f); 349 hdr.priority = ((tmp >> 2) & 0x0f);
350 hdr.flow_lbl[0] = ((tmp << 6) & 0xC0) | ((tmp >> 2) & 0x30); 350 hdr.flow_lbl[0] = ((tmp << 6) & 0xC0) | ((tmp >> 2) & 0x30);
@@ -354,7 +354,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
354 */ 354 */
355 case 1: /* 01b */ 355 case 1: /* 01b */
356 if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp))) 356 if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp)))
357 goto drop; 357 return -EINVAL;
358 358
359 hdr.flow_lbl[0] = (skb->data[0] & 0x0F) | ((tmp >> 2) & 0x30); 359 hdr.flow_lbl[0] = (skb->data[0] & 0x0F) | ((tmp >> 2) & 0x30);
360 memcpy(&hdr.flow_lbl[1], &skb->data[0], 2); 360 memcpy(&hdr.flow_lbl[1], &skb->data[0], 2);
@@ -371,7 +371,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
371 if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) { 371 if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) {
372 /* Next header is carried inline */ 372 /* Next header is carried inline */
373 if (lowpan_fetch_skb(skb, &hdr.nexthdr, sizeof(hdr.nexthdr))) 373 if (lowpan_fetch_skb(skb, &hdr.nexthdr, sizeof(hdr.nexthdr)))
374 goto drop; 374 return -EINVAL;
375 375
376 pr_debug("NH flag is set, next header carried inline: %02x\n", 376 pr_debug("NH flag is set, next header carried inline: %02x\n",
377 hdr.nexthdr); 377 hdr.nexthdr);
@@ -383,7 +383,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
383 } else { 383 } else {
384 if (lowpan_fetch_skb(skb, &hdr.hop_limit, 384 if (lowpan_fetch_skb(skb, &hdr.hop_limit,
385 sizeof(hdr.hop_limit))) 385 sizeof(hdr.hop_limit)))
386 goto drop; 386 return -EINVAL;
387 } 387 }
388 388
389 /* Extract SAM to the tmp variable */ 389 /* Extract SAM to the tmp variable */
@@ -402,7 +402,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
402 402
403 /* Check on error of previous branch */ 403 /* Check on error of previous branch */
404 if (err) 404 if (err)
405 goto drop; 405 return -EINVAL;
406 406
407 /* Extract DAM to the tmp variable */ 407 /* Extract DAM to the tmp variable */
408 tmp = ((iphc1 & LOWPAN_IPHC_DAM_11) >> LOWPAN_IPHC_DAM_BIT) & 0x03; 408 tmp = ((iphc1 & LOWPAN_IPHC_DAM_11) >> LOWPAN_IPHC_DAM_BIT) & 0x03;
@@ -417,7 +417,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
417 tmp); 417 tmp);
418 418
419 if (err) 419 if (err)
420 goto drop; 420 return -EINVAL;
421 } 421 }
422 } else { 422 } else {
423 err = uncompress_addr(skb, &hdr.daddr, tmp, daddr, 423 err = uncompress_addr(skb, &hdr.daddr, tmp, daddr,
@@ -425,7 +425,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
425 pr_debug("dest: stateless compression mode %d dest %pI6c\n", 425 pr_debug("dest: stateless compression mode %d dest %pI6c\n",
426 tmp, &hdr.daddr); 426 tmp, &hdr.daddr);
427 if (err) 427 if (err)
428 goto drop; 428 return -EINVAL;
429 } 429 }
430 430
431 /* UDP data uncompression */ 431 /* UDP data uncompression */
@@ -434,16 +434,14 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
434 const int needed = sizeof(struct udphdr) + sizeof(hdr); 434 const int needed = sizeof(struct udphdr) + sizeof(hdr);
435 435
436 if (uncompress_udp_header(skb, &uh)) 436 if (uncompress_udp_header(skb, &uh))
437 goto drop; 437 return -EINVAL;
438 438
439 /* replace the compressed UDP head by the uncompressed UDP 439 /* replace the compressed UDP head by the uncompressed UDP
440 * header 440 * header
441 */ 441 */
442 err = skb_cow(skb, needed); 442 err = skb_cow(skb, needed);
443 if (unlikely(err)) { 443 if (unlikely(err))
444 kfree_skb(skb);
445 return err; 444 return err;
446 }
447 445
448 skb_push(skb, sizeof(struct udphdr)); 446 skb_push(skb, sizeof(struct udphdr));
449 skb_reset_transport_header(skb); 447 skb_reset_transport_header(skb);
@@ -455,10 +453,8 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
455 hdr.nexthdr = UIP_PROTO_UDP; 453 hdr.nexthdr = UIP_PROTO_UDP;
456 } else { 454 } else {
457 err = skb_cow(skb, sizeof(hdr)); 455 err = skb_cow(skb, sizeof(hdr));
458 if (unlikely(err)) { 456 if (unlikely(err))
459 kfree_skb(skb);
460 return err; 457 return err;
461 }
462 } 458 }
463 459
464 hdr.payload_len = htons(skb->len); 460 hdr.payload_len = htons(skb->len);
@@ -478,9 +474,6 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
478 raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr)); 474 raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr));
479 475
480 return 0; 476 return 0;
481drop:
482 kfree_skb(skb);
483 return -EINVAL;
484} 477}
485EXPORT_SYMBOL_GPL(lowpan_header_decompress); 478EXPORT_SYMBOL_GPL(lowpan_header_decompress);
486 479
@@ -512,9 +505,17 @@ static u8 lowpan_compress_addr_64(u8 **hc_ptr, u8 shift,
512 505
513static void compress_udp_header(u8 **hc_ptr, struct sk_buff *skb) 506static void compress_udp_header(u8 **hc_ptr, struct sk_buff *skb)
514{ 507{
515 struct udphdr *uh = udp_hdr(skb); 508 struct udphdr *uh;
516 u8 tmp; 509 u8 tmp;
517 510
511 /* In the case of RAW sockets the transport header is not set by
512 * the ip6 stack so we must set it ourselves
513 */
514 if (skb->transport_header == skb->network_header)
515 skb_set_transport_header(skb, sizeof(struct ipv6hdr));
516
517 uh = udp_hdr(skb);
518
518 if (((ntohs(uh->source) & LOWPAN_NHC_UDP_4BIT_MASK) == 519 if (((ntohs(uh->source) & LOWPAN_NHC_UDP_4BIT_MASK) ==
519 LOWPAN_NHC_UDP_4BIT_PORT) && 520 LOWPAN_NHC_UDP_4BIT_PORT) &&
520 ((ntohs(uh->dest) & LOWPAN_NHC_UDP_4BIT_MASK) == 521 ((ntohs(uh->dest) & LOWPAN_NHC_UDP_4BIT_MASK) ==
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index eef298d17452..dc23c55f1ab6 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -294,20 +294,20 @@ static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev,
294 peer = __peer_lookup_chan(dev, chan); 294 peer = __peer_lookup_chan(dev, chan);
295 rcu_read_unlock(); 295 rcu_read_unlock();
296 if (!peer) 296 if (!peer)
297 goto drop; 297 return -EINVAL;
298 298
299 saddr = peer->eui64_addr; 299 saddr = peer->eui64_addr;
300 daddr = dev->netdev->dev_addr; 300 daddr = dev->netdev->dev_addr;
301 301
302 /* at least two bytes will be used for the encoding */ 302 /* at least two bytes will be used for the encoding */
303 if (skb->len < 2) 303 if (skb->len < 2)
304 goto drop; 304 return -EINVAL;
305 305
306 if (lowpan_fetch_skb_u8(skb, &iphc0)) 306 if (lowpan_fetch_skb_u8(skb, &iphc0))
307 goto drop; 307 return -EINVAL;
308 308
309 if (lowpan_fetch_skb_u8(skb, &iphc1)) 309 if (lowpan_fetch_skb_u8(skb, &iphc1))
310 goto drop; 310 return -EINVAL;
311 311
312 return lowpan_header_decompress(skb, netdev, 312 return lowpan_header_decompress(skb, netdev,
313 saddr, IEEE802154_ADDR_LONG, 313 saddr, IEEE802154_ADDR_LONG,
@@ -315,9 +315,6 @@ static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev,
315 IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, 315 IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
316 iphc0, iphc1); 316 iphc0, iphc1);
317 317
318drop:
319 kfree_skb(skb);
320 return -EINVAL;
321} 318}
322 319
323static int recv_pkt(struct sk_buff *skb, struct net_device *dev, 320static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
@@ -370,8 +367,10 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
370 goto drop; 367 goto drop;
371 368
372 ret = iphc_decompress(local_skb, dev, chan); 369 ret = iphc_decompress(local_skb, dev, chan);
373 if (ret < 0) 370 if (ret < 0) {
371 kfree_skb(local_skb);
374 goto drop; 372 goto drop;
373 }
375 374
376 local_skb->protocol = htons(ETH_P_IPV6); 375 local_skb->protocol = htons(ETH_P_IPV6);
377 local_skb->pkt_type = PACKET_HOST; 376 local_skb->pkt_type = PACKET_HOST;
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 600fb29288f4..5e97a8ff850b 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -39,11 +39,10 @@ menuconfig BT
39 to Bluetooth kernel modules are provided in the BlueZ packages. For 39 to Bluetooth kernel modules are provided in the BlueZ packages. For
40 more information, see <http://www.bluez.org/>. 40 more information, see <http://www.bluez.org/>.
41 41
42config BT_6LOWPAN 42config BT_BREDR
43 tristate "Bluetooth 6LoWPAN support" 43 bool "Bluetooth Classic (BR/EDR) features"
44 depends on BT && 6LOWPAN 44 depends on BT
45 help 45 default y
46 IPv6 compression over Bluetooth Low Energy.
47 46
48source "net/bluetooth/rfcomm/Kconfig" 47source "net/bluetooth/rfcomm/Kconfig"
49 48
@@ -53,4 +52,15 @@ source "net/bluetooth/cmtp/Kconfig"
53 52
54source "net/bluetooth/hidp/Kconfig" 53source "net/bluetooth/hidp/Kconfig"
55 54
55config BT_LE
56 bool "Bluetooth Low Energy (LE) features"
57 depends on BT
58 default y
59
60config BT_6LOWPAN
61 tristate "Bluetooth 6LoWPAN support"
62 depends on BT_LE && 6LOWPAN
63 help
64 IPv6 compression over Bluetooth Low Energy.
65
56source "drivers/bluetooth/Kconfig" 66source "drivers/bluetooth/Kconfig"
diff --git a/net/bluetooth/bnep/Kconfig b/net/bluetooth/bnep/Kconfig
index 71791fc9f6b1..9b70317c49dc 100644
--- a/net/bluetooth/bnep/Kconfig
+++ b/net/bluetooth/bnep/Kconfig
@@ -1,6 +1,6 @@
1config BT_BNEP 1config BT_BNEP
2 tristate "BNEP protocol support" 2 tristate "BNEP protocol support"
3 depends on BT 3 depends on BT_BREDR
4 select CRC32 4 select CRC32
5 help 5 help
6 BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet 6 BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet
diff --git a/net/bluetooth/cmtp/Kconfig b/net/bluetooth/cmtp/Kconfig
index 94cbf42ce155..939da0fbdd88 100644
--- a/net/bluetooth/cmtp/Kconfig
+++ b/net/bluetooth/cmtp/Kconfig
@@ -1,6 +1,6 @@
1config BT_CMTP 1config BT_CMTP
2 tristate "CMTP protocol support" 2 tristate "CMTP protocol support"
3 depends on BT && ISDN_CAPI 3 depends on BT_BREDR && ISDN_CAPI
4 help 4 help
5 CMTP (CAPI Message Transport Protocol) is a transport layer 5 CMTP (CAPI Message Transport Protocol) is a transport layer
6 for CAPI messages. CMTP is required for the Bluetooth Common 6 for CAPI messages. CMTP is required for the Bluetooth Common
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 91995f8ab0a0..6c162c8809cf 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -200,31 +200,6 @@ static const struct file_operations blacklist_fops = {
200 .release = single_release, 200 .release = single_release,
201}; 201};
202 202
203static int whitelist_show(struct seq_file *f, void *p)
204{
205 struct hci_dev *hdev = f->private;
206 struct bdaddr_list *b;
207
208 hci_dev_lock(hdev);
209 list_for_each_entry(b, &hdev->whitelist, list)
210 seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
211 hci_dev_unlock(hdev);
212
213 return 0;
214}
215
216static int whitelist_open(struct inode *inode, struct file *file)
217{
218 return single_open(file, whitelist_show, inode->i_private);
219}
220
221static const struct file_operations whitelist_fops = {
222 .open = whitelist_open,
223 .read = seq_read,
224 .llseek = seq_lseek,
225 .release = single_release,
226};
227
228static int uuids_show(struct seq_file *f, void *p) 203static int uuids_show(struct seq_file *f, void *p)
229{ 204{
230 struct hci_dev *hdev = f->private; 205 struct hci_dev *hdev = f->private;
@@ -1030,10 +1005,13 @@ static int device_list_show(struct seq_file *f, void *ptr)
1030{ 1005{
1031 struct hci_dev *hdev = f->private; 1006 struct hci_dev *hdev = f->private;
1032 struct hci_conn_params *p; 1007 struct hci_conn_params *p;
1008 struct bdaddr_list *b;
1033 1009
1034 hci_dev_lock(hdev); 1010 hci_dev_lock(hdev);
1011 list_for_each_entry(b, &hdev->whitelist, list)
1012 seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
1035 list_for_each_entry(p, &hdev->le_conn_params, list) { 1013 list_for_each_entry(p, &hdev->le_conn_params, list) {
1036 seq_printf(f, "%pMR %u %u\n", &p->addr, p->addr_type, 1014 seq_printf(f, "%pMR (type %u) %u\n", &p->addr, p->addr_type,
1037 p->auto_connect); 1015 p->auto_connect);
1038 } 1016 }
1039 hci_dev_unlock(hdev); 1017 hci_dev_unlock(hdev);
@@ -1147,13 +1125,15 @@ struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
1147 1125
1148 hdev->req_status = HCI_REQ_PEND; 1126 hdev->req_status = HCI_REQ_PEND;
1149 1127
1150 err = hci_req_run(&req, hci_req_sync_complete);
1151 if (err < 0)
1152 return ERR_PTR(err);
1153
1154 add_wait_queue(&hdev->req_wait_q, &wait); 1128 add_wait_queue(&hdev->req_wait_q, &wait);
1155 set_current_state(TASK_INTERRUPTIBLE); 1129 set_current_state(TASK_INTERRUPTIBLE);
1156 1130
1131 err = hci_req_run(&req, hci_req_sync_complete);
1132 if (err < 0) {
1133 remove_wait_queue(&hdev->req_wait_q, &wait);
1134 return ERR_PTR(err);
1135 }
1136
1157 schedule_timeout(timeout); 1137 schedule_timeout(timeout);
1158 1138
1159 remove_wait_queue(&hdev->req_wait_q, &wait); 1139 remove_wait_queue(&hdev->req_wait_q, &wait);
@@ -1211,10 +1191,15 @@ static int __hci_req_sync(struct hci_dev *hdev,
1211 1191
1212 func(&req, opt); 1192 func(&req, opt);
1213 1193
1194 add_wait_queue(&hdev->req_wait_q, &wait);
1195 set_current_state(TASK_INTERRUPTIBLE);
1196
1214 err = hci_req_run(&req, hci_req_sync_complete); 1197 err = hci_req_run(&req, hci_req_sync_complete);
1215 if (err < 0) { 1198 if (err < 0) {
1216 hdev->req_status = 0; 1199 hdev->req_status = 0;
1217 1200
1201 remove_wait_queue(&hdev->req_wait_q, &wait);
1202
1218 /* ENODATA means the HCI request command queue is empty. 1203 /* ENODATA means the HCI request command queue is empty.
1219 * This can happen when a request with conditionals doesn't 1204 * This can happen when a request with conditionals doesn't
1220 * trigger any commands to be sent. This is normal behavior 1205 * trigger any commands to be sent. This is normal behavior
@@ -1226,9 +1211,6 @@ static int __hci_req_sync(struct hci_dev *hdev,
1226 return err; 1211 return err;
1227 } 1212 }
1228 1213
1229 add_wait_queue(&hdev->req_wait_q, &wait);
1230 set_current_state(TASK_INTERRUPTIBLE);
1231
1232 schedule_timeout(timeout); 1214 schedule_timeout(timeout);
1233 1215
1234 remove_wait_queue(&hdev->req_wait_q, &wait); 1216 remove_wait_queue(&hdev->req_wait_q, &wait);
@@ -1811,10 +1793,10 @@ static int __hci_init(struct hci_dev *hdev)
1811 &hdev->manufacturer); 1793 &hdev->manufacturer);
1812 debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver); 1794 debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver);
1813 debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev); 1795 debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
1796 debugfs_create_file("device_list", 0444, hdev->debugfs, hdev,
1797 &device_list_fops);
1814 debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev, 1798 debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
1815 &blacklist_fops); 1799 &blacklist_fops);
1816 debugfs_create_file("whitelist", 0444, hdev->debugfs, hdev,
1817 &whitelist_fops);
1818 debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); 1800 debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
1819 1801
1820 debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev, 1802 debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev,
@@ -1893,8 +1875,6 @@ static int __hci_init(struct hci_dev *hdev)
1893 hdev, &adv_min_interval_fops); 1875 hdev, &adv_min_interval_fops);
1894 debugfs_create_file("adv_max_interval", 0644, hdev->debugfs, 1876 debugfs_create_file("adv_max_interval", 0644, hdev->debugfs,
1895 hdev, &adv_max_interval_fops); 1877 hdev, &adv_max_interval_fops);
1896 debugfs_create_file("device_list", 0444, hdev->debugfs, hdev,
1897 &device_list_fops);
1898 debugfs_create_u16("discov_interleaved_timeout", 0644, 1878 debugfs_create_u16("discov_interleaved_timeout", 0644,
1899 hdev->debugfs, 1879 hdev->debugfs,
1900 &hdev->discov_interleaved_timeout); 1880 &hdev->discov_interleaved_timeout);
@@ -4244,6 +4224,24 @@ int hci_resume_dev(struct hci_dev *hdev)
4244} 4224}
4245EXPORT_SYMBOL(hci_resume_dev); 4225EXPORT_SYMBOL(hci_resume_dev);
4246 4226
4227/* Reset HCI device */
4228int hci_reset_dev(struct hci_dev *hdev)
4229{
4230 const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
4231 struct sk_buff *skb;
4232
4233 skb = bt_skb_alloc(3, GFP_ATOMIC);
4234 if (!skb)
4235 return -ENOMEM;
4236
4237 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
4238 memcpy(skb_put(skb, 3), hw_err, 3);
4239
4240 /* Send Hardware Error to upper stack */
4241 return hci_recv_frame(hdev, skb);
4242}
4243EXPORT_SYMBOL(hci_reset_dev);
4244
4247/* Receive frame from HCI drivers */ 4245/* Receive frame from HCI drivers */
4248int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) 4246int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
4249{ 4247{
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index aa152140c3e2..5e7be804c709 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -189,6 +189,9 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
189 189
190 clear_bit(HCI_RESET, &hdev->flags); 190 clear_bit(HCI_RESET, &hdev->flags);
191 191
192 if (status)
193 return;
194
192 /* Reset all non-persistent flags */ 195 /* Reset all non-persistent flags */
193 hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 196 hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
194 197
@@ -1944,6 +1947,29 @@ unlock:
1944 hci_dev_unlock(hdev); 1947 hci_dev_unlock(hdev);
1945} 1948}
1946 1949
1950static void hci_cs_switch_role(struct hci_dev *hdev, u8 status)
1951{
1952 struct hci_cp_switch_role *cp;
1953 struct hci_conn *conn;
1954
1955 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1956
1957 if (!status)
1958 return;
1959
1960 cp = hci_sent_cmd_data(hdev, HCI_OP_SWITCH_ROLE);
1961 if (!cp)
1962 return;
1963
1964 hci_dev_lock(hdev);
1965
1966 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1967 if (conn)
1968 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
1969
1970 hci_dev_unlock(hdev);
1971}
1972
1947static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 1973static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1948{ 1974{
1949 __u8 status = *((__u8 *) skb->data); 1975 __u8 status = *((__u8 *) skb->data);
@@ -2847,6 +2873,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2847 hci_cs_create_conn(hdev, ev->status); 2873 hci_cs_create_conn(hdev, ev->status);
2848 break; 2874 break;
2849 2875
2876 case HCI_OP_DISCONNECT:
2877 hci_cs_disconnect(hdev, ev->status);
2878 break;
2879
2850 case HCI_OP_ADD_SCO: 2880 case HCI_OP_ADD_SCO:
2851 hci_cs_add_sco(hdev, ev->status); 2881 hci_cs_add_sco(hdev, ev->status);
2852 break; 2882 break;
@@ -2875,24 +2905,24 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2875 hci_cs_setup_sync_conn(hdev, ev->status); 2905 hci_cs_setup_sync_conn(hdev, ev->status);
2876 break; 2906 break;
2877 2907
2878 case HCI_OP_SNIFF_MODE: 2908 case HCI_OP_CREATE_PHY_LINK:
2879 hci_cs_sniff_mode(hdev, ev->status); 2909 hci_cs_create_phylink(hdev, ev->status);
2880 break; 2910 break;
2881 2911
2882 case HCI_OP_EXIT_SNIFF_MODE: 2912 case HCI_OP_ACCEPT_PHY_LINK:
2883 hci_cs_exit_sniff_mode(hdev, ev->status); 2913 hci_cs_accept_phylink(hdev, ev->status);
2884 break; 2914 break;
2885 2915
2886 case HCI_OP_DISCONNECT: 2916 case HCI_OP_SNIFF_MODE:
2887 hci_cs_disconnect(hdev, ev->status); 2917 hci_cs_sniff_mode(hdev, ev->status);
2888 break; 2918 break;
2889 2919
2890 case HCI_OP_CREATE_PHY_LINK: 2920 case HCI_OP_EXIT_SNIFF_MODE:
2891 hci_cs_create_phylink(hdev, ev->status); 2921 hci_cs_exit_sniff_mode(hdev, ev->status);
2892 break; 2922 break;
2893 2923
2894 case HCI_OP_ACCEPT_PHY_LINK: 2924 case HCI_OP_SWITCH_ROLE:
2895 hci_cs_accept_phylink(hdev, ev->status); 2925 hci_cs_switch_role(hdev, ev->status);
2896 break; 2926 break;
2897 2927
2898 case HCI_OP_LE_CREATE_CONN: 2928 case HCI_OP_LE_CREATE_CONN:
@@ -2922,6 +2952,13 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2922 } 2952 }
2923} 2953}
2924 2954
2955static void hci_hardware_error_evt(struct hci_dev *hdev, struct sk_buff *skb)
2956{
2957 struct hci_ev_hardware_error *ev = (void *) skb->data;
2958
2959 BT_ERR("%s hardware error 0x%2.2x", hdev->name, ev->code);
2960}
2961
2925static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 2962static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2926{ 2963{
2927 struct hci_ev_role_change *ev = (void *) skb->data; 2964 struct hci_ev_role_change *ev = (void *) skb->data;
@@ -4743,6 +4780,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
4743 hci_cmd_status_evt(hdev, skb); 4780 hci_cmd_status_evt(hdev, skb);
4744 break; 4781 break;
4745 4782
4783 case HCI_EV_HARDWARE_ERROR:
4784 hci_hardware_error_evt(hdev, skb);
4785 break;
4786
4746 case HCI_EV_ROLE_CHANGE: 4787 case HCI_EV_ROLE_CHANGE:
4747 hci_role_change_evt(hdev, skb); 4788 hci_role_change_evt(hdev, skb);
4748 break; 4789 break;
diff --git a/net/bluetooth/hidp/Kconfig b/net/bluetooth/hidp/Kconfig
index 9332bc7aa851..bc8610b24077 100644
--- a/net/bluetooth/hidp/Kconfig
+++ b/net/bluetooth/hidp/Kconfig
@@ -1,6 +1,6 @@
1config BT_HIDP 1config BT_HIDP
2 tristate "HIDP protocol support" 2 tristate "HIDP protocol support"
3 depends on BT && INPUT 3 depends on BT_BREDR && INPUT
4 select HID 4 select HID
5 help 5 help
6 HIDP (Human Interface Device Protocol) is a transport layer 6 HIDP (Human Interface Device Protocol) is a transport layer
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 9c4daf715cf8..ce0272c6f71f 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -3727,20 +3727,23 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
3727 hci_dev_lock(hdev); 3727 hci_dev_lock(hdev);
3728 3728
3729 if (!hdev_is_powered(hdev)) { 3729 if (!hdev_is_powered(hdev)) {
3730 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, 3730 err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY,
3731 MGMT_STATUS_NOT_POWERED); 3731 MGMT_STATUS_NOT_POWERED,
3732 &cp->type, sizeof(cp->type));
3732 goto failed; 3733 goto failed;
3733 } 3734 }
3734 3735
3735 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) { 3736 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) {
3736 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, 3737 err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY,
3737 MGMT_STATUS_BUSY); 3738 MGMT_STATUS_BUSY, &cp->type,
3739 sizeof(cp->type));
3738 goto failed; 3740 goto failed;
3739 } 3741 }
3740 3742
3741 if (hdev->discovery.state != DISCOVERY_STOPPED) { 3743 if (hdev->discovery.state != DISCOVERY_STOPPED) {
3742 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, 3744 err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY,
3743 MGMT_STATUS_BUSY); 3745 MGMT_STATUS_BUSY, &cp->type,
3746 sizeof(cp->type));
3744 goto failed; 3747 goto failed;
3745 } 3748 }
3746 3749
@@ -3758,15 +3761,18 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
3758 case DISCOV_TYPE_BREDR: 3761 case DISCOV_TYPE_BREDR:
3759 status = mgmt_bredr_support(hdev); 3762 status = mgmt_bredr_support(hdev);
3760 if (status) { 3763 if (status) {
3761 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, 3764 err = cmd_complete(sk, hdev->id,
3762 status); 3765 MGMT_OP_START_DISCOVERY, status,
3766 &cp->type, sizeof(cp->type));
3763 mgmt_pending_remove(cmd); 3767 mgmt_pending_remove(cmd);
3764 goto failed; 3768 goto failed;
3765 } 3769 }
3766 3770
3767 if (test_bit(HCI_INQUIRY, &hdev->flags)) { 3771 if (test_bit(HCI_INQUIRY, &hdev->flags)) {
3768 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, 3772 err = cmd_complete(sk, hdev->id,
3769 MGMT_STATUS_BUSY); 3773 MGMT_OP_START_DISCOVERY,
3774 MGMT_STATUS_BUSY, &cp->type,
3775 sizeof(cp->type));
3770 mgmt_pending_remove(cmd); 3776 mgmt_pending_remove(cmd);
3771 goto failed; 3777 goto failed;
3772 } 3778 }
@@ -3783,16 +3789,19 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
3783 case DISCOV_TYPE_INTERLEAVED: 3789 case DISCOV_TYPE_INTERLEAVED:
3784 status = mgmt_le_support(hdev); 3790 status = mgmt_le_support(hdev);
3785 if (status) { 3791 if (status) {
3786 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, 3792 err = cmd_complete(sk, hdev->id,
3787 status); 3793 MGMT_OP_START_DISCOVERY, status,
3794 &cp->type, sizeof(cp->type));
3788 mgmt_pending_remove(cmd); 3795 mgmt_pending_remove(cmd);
3789 goto failed; 3796 goto failed;
3790 } 3797 }
3791 3798
3792 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED && 3799 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
3793 !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { 3800 !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
3794 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, 3801 err = cmd_complete(sk, hdev->id,
3795 MGMT_STATUS_NOT_SUPPORTED); 3802 MGMT_OP_START_DISCOVERY,
3803 MGMT_STATUS_NOT_SUPPORTED,
3804 &cp->type, sizeof(cp->type));
3796 mgmt_pending_remove(cmd); 3805 mgmt_pending_remove(cmd);
3797 goto failed; 3806 goto failed;
3798 } 3807 }
@@ -3804,9 +3813,11 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
3804 */ 3813 */
3805 if (hci_conn_hash_lookup_state(hdev, LE_LINK, 3814 if (hci_conn_hash_lookup_state(hdev, LE_LINK,
3806 BT_CONNECT)) { 3815 BT_CONNECT)) {
3807 err = cmd_status(sk, hdev->id, 3816 err = cmd_complete(sk, hdev->id,
3808 MGMT_OP_START_DISCOVERY, 3817 MGMT_OP_START_DISCOVERY,
3809 MGMT_STATUS_REJECTED); 3818 MGMT_STATUS_REJECTED,
3819 &cp->type,
3820 sizeof(cp->type));
3810 mgmt_pending_remove(cmd); 3821 mgmt_pending_remove(cmd);
3811 goto failed; 3822 goto failed;
3812 } 3823 }
@@ -3829,8 +3840,10 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
3829 */ 3840 */
3830 err = hci_update_random_address(&req, true, &own_addr_type); 3841 err = hci_update_random_address(&req, true, &own_addr_type);
3831 if (err < 0) { 3842 if (err < 0) {
3832 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, 3843 err = cmd_complete(sk, hdev->id,
3833 MGMT_STATUS_FAILED); 3844 MGMT_OP_START_DISCOVERY,
3845 MGMT_STATUS_FAILED,
3846 &cp->type, sizeof(cp->type));
3834 mgmt_pending_remove(cmd); 3847 mgmt_pending_remove(cmd);
3835 goto failed; 3848 goto failed;
3836 } 3849 }
@@ -3850,8 +3863,9 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
3850 break; 3863 break;
3851 3864
3852 default: 3865 default:
3853 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, 3866 err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY,
3854 MGMT_STATUS_INVALID_PARAMS); 3867 MGMT_STATUS_INVALID_PARAMS,
3868 &cp->type, sizeof(cp->type));
3855 mgmt_pending_remove(cmd); 3869 mgmt_pending_remove(cmd);
3856 goto failed; 3870 goto failed;
3857 } 3871 }
diff --git a/net/bluetooth/rfcomm/Kconfig b/net/bluetooth/rfcomm/Kconfig
index 18d352ea2bc7..335df7515220 100644
--- a/net/bluetooth/rfcomm/Kconfig
+++ b/net/bluetooth/rfcomm/Kconfig
@@ -1,6 +1,6 @@
1config BT_RFCOMM 1config BT_RFCOMM
2 tristate "RFCOMM protocol support" 2 tristate "RFCOMM protocol support"
3 depends on BT 3 depends on BT_BREDR
4 help 4 help
5 RFCOMM provides connection oriented stream transport. RFCOMM 5 RFCOMM provides connection oriented stream transport. RFCOMM
6 support is required for Dialup Networking, OBEX and other Bluetooth 6 support is required for Dialup Networking, OBEX and other Bluetooth
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index bce9c3d39324..64e20dde4837 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -81,6 +81,8 @@ static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s);
81#define __test_cr(b) (!!(b & 0x02)) 81#define __test_cr(b) (!!(b & 0x02))
82#define __test_pf(b) (!!(b & 0x10)) 82#define __test_pf(b) (!!(b & 0x10))
83 83
84#define __session_dir(s) ((s)->initiator ? 0x00 : 0x01)
85
84#define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01) 86#define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01)
85#define __ctrl(type, pf) (((type & 0xef) | (pf << 4))) 87#define __ctrl(type, pf) (((type & 0xef) | (pf << 4)))
86#define __dlci(dir, chn) (((chn & 0x1f) << 1) | dir) 88#define __dlci(dir, chn) (((chn & 0x1f) << 1) | dir)
@@ -388,7 +390,7 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
388 return err; 390 return err;
389 } 391 }
390 392
391 dlci = __dlci(!s->initiator, channel); 393 dlci = __dlci(__session_dir(s), channel);
392 394
393 /* Check if DLCI already exists */ 395 /* Check if DLCI already exists */
394 if (rfcomm_dlc_get(s, dlci)) 396 if (rfcomm_dlc_get(s, dlci))
@@ -543,7 +545,7 @@ struct rfcomm_dlc *rfcomm_dlc_exists(bdaddr_t *src, bdaddr_t *dst, u8 channel)
543 rfcomm_lock(); 545 rfcomm_lock();
544 s = rfcomm_session_get(src, dst); 546 s = rfcomm_session_get(src, dst);
545 if (s) { 547 if (s) {
546 dlci = __dlci(!s->initiator, channel); 548 dlci = __dlci(__session_dir(s), channel);
547 dlc = rfcomm_dlc_get(s, dlci); 549 dlc = rfcomm_dlc_get(s, dlci);
548 } 550 }
549 rfcomm_unlock(); 551 rfcomm_unlock();
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c
index 519a65452d90..290e14f2e92e 100644
--- a/net/ieee802154/6lowpan_rtnl.c
+++ b/net/ieee802154/6lowpan_rtnl.c
@@ -176,13 +176,13 @@ iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
176 raw_dump_table(__func__, "raw skb data dump", skb->data, skb->len); 176 raw_dump_table(__func__, "raw skb data dump", skb->data, skb->len);
177 /* at least two bytes will be used for the encoding */ 177 /* at least two bytes will be used for the encoding */
178 if (skb->len < 2) 178 if (skb->len < 2)
179 goto drop; 179 return -EINVAL;
180 180
181 if (lowpan_fetch_skb_u8(skb, &iphc0)) 181 if (lowpan_fetch_skb_u8(skb, &iphc0))
182 goto drop; 182 return -EINVAL;
183 183
184 if (lowpan_fetch_skb_u8(skb, &iphc1)) 184 if (lowpan_fetch_skb_u8(skb, &iphc1))
185 goto drop; 185 return -EINVAL;
186 186
187 ieee802154_addr_to_sa(&sa, &hdr->source); 187 ieee802154_addr_to_sa(&sa, &hdr->source);
188 ieee802154_addr_to_sa(&da, &hdr->dest); 188 ieee802154_addr_to_sa(&da, &hdr->dest);
@@ -200,23 +200,6 @@ iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
200 return lowpan_header_decompress(skb, skb->dev, sap, sa.addr_type, 200 return lowpan_header_decompress(skb, skb->dev, sap, sa.addr_type,
201 IEEE802154_ADDR_LEN, dap, da.addr_type, 201 IEEE802154_ADDR_LEN, dap, da.addr_type,
202 IEEE802154_ADDR_LEN, iphc0, iphc1); 202 IEEE802154_ADDR_LEN, iphc0, iphc1);
203
204drop:
205 kfree_skb(skb);
206 return -EINVAL;
207}
208
209static int lowpan_set_address(struct net_device *dev, void *p)
210{
211 struct sockaddr *sa = p;
212
213 if (netif_running(dev))
214 return -EBUSY;
215
216 /* TODO: validate addr */
217 memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
218
219 return 0;
220} 203}
221 204
222static struct sk_buff* 205static struct sk_buff*
@@ -420,13 +403,6 @@ static netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev)
420 } 403 }
421} 404}
422 405
423static struct wpan_phy *lowpan_get_phy(const struct net_device *dev)
424{
425 struct net_device *real_dev = lowpan_dev_info(dev)->real_dev;
426
427 return ieee802154_mlme_ops(real_dev)->get_phy(real_dev);
428}
429
430static __le16 lowpan_get_pan_id(const struct net_device *dev) 406static __le16 lowpan_get_pan_id(const struct net_device *dev)
431{ 407{
432 struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; 408 struct net_device *real_dev = lowpan_dev_info(dev)->real_dev;
@@ -474,12 +450,10 @@ static int lowpan_dev_init(struct net_device *dev)
474static const struct net_device_ops lowpan_netdev_ops = { 450static const struct net_device_ops lowpan_netdev_ops = {
475 .ndo_init = lowpan_dev_init, 451 .ndo_init = lowpan_dev_init,
476 .ndo_start_xmit = lowpan_xmit, 452 .ndo_start_xmit = lowpan_xmit,
477 .ndo_set_mac_address = lowpan_set_address,
478}; 453};
479 454
480static struct ieee802154_mlme_ops lowpan_mlme = { 455static struct ieee802154_mlme_ops lowpan_mlme = {
481 .get_pan_id = lowpan_get_pan_id, 456 .get_pan_id = lowpan_get_pan_id,
482 .get_phy = lowpan_get_phy,
483 .get_short_addr = lowpan_get_short_addr, 457 .get_short_addr = lowpan_get_short_addr,
484 .get_dsn = lowpan_get_dsn, 458 .get_dsn = lowpan_get_dsn,
485}; 459};
@@ -544,7 +518,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
544 case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ 518 case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
545 ret = iphc_decompress(skb, &hdr); 519 ret = iphc_decompress(skb, &hdr);
546 if (ret < 0) 520 if (ret < 0)
547 goto drop; 521 goto drop_skb;
548 522
549 return lowpan_give_skb_to_devices(skb, NULL); 523 return lowpan_give_skb_to_devices(skb, NULL);
550 case LOWPAN_DISPATCH_FRAG1: /* first fragment header */ 524 case LOWPAN_DISPATCH_FRAG1: /* first fragment header */
@@ -552,7 +526,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
552 if (ret == 1) { 526 if (ret == 1) {
553 ret = iphc_decompress(skb, &hdr); 527 ret = iphc_decompress(skb, &hdr);
554 if (ret < 0) 528 if (ret < 0)
555 goto drop; 529 goto drop_skb;
556 530
557 return lowpan_give_skb_to_devices(skb, NULL); 531 return lowpan_give_skb_to_devices(skb, NULL);
558 } else if (ret == -1) { 532 } else if (ret == -1) {
@@ -565,7 +539,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
565 if (ret == 1) { 539 if (ret == 1) {
566 ret = iphc_decompress(skb, &hdr); 540 ret = iphc_decompress(skb, &hdr);
567 if (ret < 0) 541 if (ret < 0)
568 goto drop; 542 goto drop_skb;
569 543
570 return lowpan_give_skb_to_devices(skb, NULL); 544 return lowpan_give_skb_to_devices(skb, NULL);
571 } else if (ret == -1) { 545 } else if (ret == -1) {
diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c
index 620abc2ba5fc..d1cd0edfb149 100644
--- a/net/ieee802154/core.c
+++ b/net/ieee802154/core.c
@@ -21,9 +21,7 @@
21 21
22#include "ieee802154.h" 22#include "ieee802154.h"
23#include "sysfs.h" 23#include "sysfs.h"
24 24#include "core.h"
25static DEFINE_MUTEX(wpan_phy_mutex);
26static int wpan_phy_idx;
27 25
28static int wpan_phy_match(struct device *dev, const void *data) 26static int wpan_phy_match(struct device *dev, const void *data)
29{ 27{
@@ -71,42 +69,41 @@ int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data),
71} 69}
72EXPORT_SYMBOL(wpan_phy_for_each); 70EXPORT_SYMBOL(wpan_phy_for_each);
73 71
74static int wpan_phy_idx_valid(int idx) 72struct wpan_phy *
73wpan_phy_alloc(const struct cfg802154_ops *ops, size_t priv_size)
75{ 74{
76 return idx >= 0; 75 static atomic_t wpan_phy_counter = ATOMIC_INIT(0);
77} 76 struct cfg802154_registered_device *rdev;
77 size_t alloc_size;
78 78
79struct wpan_phy *wpan_phy_alloc(size_t priv_size) 79 alloc_size = sizeof(*rdev) + priv_size;
80{ 80 rdev = kzalloc(alloc_size, GFP_KERNEL);
81 struct wpan_phy *phy = kzalloc(sizeof(*phy) + priv_size, 81 if (!rdev)
82 GFP_KERNEL); 82 return NULL;
83 83
84 if (!phy) 84 rdev->ops = ops;
85 goto out;
86 mutex_lock(&wpan_phy_mutex);
87 phy->idx = wpan_phy_idx++;
88 if (unlikely(!wpan_phy_idx_valid(phy->idx))) {
89 wpan_phy_idx--;
90 mutex_unlock(&wpan_phy_mutex);
91 kfree(phy);
92 goto out;
93 }
94 mutex_unlock(&wpan_phy_mutex);
95 85
96 mutex_init(&phy->pib_lock); 86 rdev->wpan_phy_idx = atomic_inc_return(&wpan_phy_counter);
97 87
98 device_initialize(&phy->dev); 88 if (unlikely(rdev->wpan_phy_idx < 0)) {
99 dev_set_name(&phy->dev, "wpan-phy%d", phy->idx); 89 /* ugh, wrapped! */
90 atomic_dec(&wpan_phy_counter);
91 kfree(rdev);
92 return NULL;
93 }
94
95 /* atomic_inc_return makes it start at 1, make it start at 0 */
96 rdev->wpan_phy_idx--;
100 97
101 phy->dev.class = &wpan_phy_class; 98 mutex_init(&rdev->wpan_phy.pib_lock);
102 99
103 phy->current_channel = -1; /* not initialised */ 100 device_initialize(&rdev->wpan_phy.dev);
104 phy->current_page = 0; /* for compatibility */ 101 dev_set_name(&rdev->wpan_phy.dev, "wpan-phy%d", rdev->wpan_phy_idx);
105 102
106 return phy; 103 rdev->wpan_phy.dev.class = &wpan_phy_class;
104 rdev->wpan_phy.dev.platform_data = rdev;
107 105
108out: 106 return &rdev->wpan_phy;
109 return NULL;
110} 107}
111EXPORT_SYMBOL(wpan_phy_alloc); 108EXPORT_SYMBOL(wpan_phy_alloc);
112 109
@@ -128,6 +125,11 @@ void wpan_phy_free(struct wpan_phy *phy)
128} 125}
129EXPORT_SYMBOL(wpan_phy_free); 126EXPORT_SYMBOL(wpan_phy_free);
130 127
128void cfg802154_dev_free(struct cfg802154_registered_device *rdev)
129{
130 kfree(rdev);
131}
132
131static int __init wpan_phy_class_init(void) 133static int __init wpan_phy_class_init(void)
132{ 134{
133 int rc; 135 int rc;
diff --git a/net/ieee802154/core.h b/net/ieee802154/core.h
new file mode 100644
index 000000000000..fea60b3a8846
--- /dev/null
+++ b/net/ieee802154/core.h
@@ -0,0 +1,29 @@
1#ifndef __IEEE802154_CORE_H
2#define __IEEE802154_CORE_H
3
4#include <net/cfg802154.h>
5
6struct cfg802154_registered_device {
7 const struct cfg802154_ops *ops;
8
9 /* wpan_phy index, internal only */
10 int wpan_phy_idx;
11
12 /* must be last because of the way we do wpan_phy_priv(),
13 * and it should at least be aligned to NETDEV_ALIGN
14 */
15 struct wpan_phy wpan_phy __aligned(NETDEV_ALIGN);
16};
17
18static inline struct cfg802154_registered_device *
19wpan_phy_to_rdev(struct wpan_phy *wpan_phy)
20{
21 BUG_ON(!wpan_phy);
22 return container_of(wpan_phy, struct cfg802154_registered_device,
23 wpan_phy);
24}
25
26/* free object */
27void cfg802154_dev_free(struct cfg802154_registered_device *rdev);
28
29#endif /* __IEEE802154_CORE_H */
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index abd0f31bdc66..7127b9d1a684 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -29,7 +29,6 @@
29#include <linux/nl802154.h> 29#include <linux/nl802154.h>
30#include <linux/export.h> 30#include <linux/export.h>
31#include <net/af_ieee802154.h> 31#include <net/af_ieee802154.h>
32#include <net/nl802154.h>
33#include <net/ieee802154_netdev.h> 32#include <net/ieee802154_netdev.h>
34#include <net/cfg802154.h> 33#include <net/cfg802154.h>
35 34
@@ -55,186 +54,7 @@ static __le16 nla_get_shortaddr(const struct nlattr *nla)
55 return cpu_to_le16(nla_get_u16(nla)); 54 return cpu_to_le16(nla_get_u16(nla));
56} 55}
57 56
58int ieee802154_nl_assoc_indic(struct net_device *dev, 57static int ieee802154_nl_start_confirm(struct net_device *dev, u8 status)
59 struct ieee802154_addr *addr,
60 u8 cap)
61{
62 struct sk_buff *msg;
63
64 pr_debug("%s\n", __func__);
65
66 if (addr->mode != IEEE802154_ADDR_LONG) {
67 pr_err("%s: received non-long source address!\n", __func__);
68 return -EINVAL;
69 }
70
71 msg = ieee802154_nl_create(0, IEEE802154_ASSOCIATE_INDIC);
72 if (!msg)
73 return -ENOBUFS;
74
75 if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
76 nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) ||
77 nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
78 dev->dev_addr) ||
79 nla_put_hwaddr(msg, IEEE802154_ATTR_SRC_HW_ADDR,
80 addr->extended_addr) ||
81 nla_put_u8(msg, IEEE802154_ATTR_CAPABILITY, cap))
82 goto nla_put_failure;
83
84 return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP);
85
86nla_put_failure:
87 nlmsg_free(msg);
88 return -ENOBUFS;
89}
90EXPORT_SYMBOL(ieee802154_nl_assoc_indic);
91
92int ieee802154_nl_assoc_confirm(struct net_device *dev, __le16 short_addr,
93 u8 status)
94{
95 struct sk_buff *msg;
96
97 pr_debug("%s\n", __func__);
98
99 msg = ieee802154_nl_create(0, IEEE802154_ASSOCIATE_CONF);
100 if (!msg)
101 return -ENOBUFS;
102
103 if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
104 nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) ||
105 nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
106 dev->dev_addr) ||
107 nla_put_shortaddr(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr) ||
108 nla_put_u8(msg, IEEE802154_ATTR_STATUS, status))
109 goto nla_put_failure;
110 return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP);
111
112nla_put_failure:
113 nlmsg_free(msg);
114 return -ENOBUFS;
115}
116EXPORT_SYMBOL(ieee802154_nl_assoc_confirm);
117
118int ieee802154_nl_disassoc_indic(struct net_device *dev,
119 struct ieee802154_addr *addr,
120 u8 reason)
121{
122 struct sk_buff *msg;
123
124 pr_debug("%s\n", __func__);
125
126 msg = ieee802154_nl_create(0, IEEE802154_DISASSOCIATE_INDIC);
127 if (!msg)
128 return -ENOBUFS;
129
130 if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
131 nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) ||
132 nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
133 dev->dev_addr))
134 goto nla_put_failure;
135 if (addr->mode == IEEE802154_ADDR_LONG) {
136 if (nla_put_hwaddr(msg, IEEE802154_ATTR_SRC_HW_ADDR,
137 addr->extended_addr))
138 goto nla_put_failure;
139 } else {
140 if (nla_put_shortaddr(msg, IEEE802154_ATTR_SRC_SHORT_ADDR,
141 addr->short_addr))
142 goto nla_put_failure;
143 }
144 if (nla_put_u8(msg, IEEE802154_ATTR_REASON, reason))
145 goto nla_put_failure;
146 return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP);
147
148nla_put_failure:
149 nlmsg_free(msg);
150 return -ENOBUFS;
151}
152EXPORT_SYMBOL(ieee802154_nl_disassoc_indic);
153
154int ieee802154_nl_disassoc_confirm(struct net_device *dev, u8 status)
155{
156 struct sk_buff *msg;
157
158 pr_debug("%s\n", __func__);
159
160 msg = ieee802154_nl_create(0, IEEE802154_DISASSOCIATE_CONF);
161 if (!msg)
162 return -ENOBUFS;
163
164 if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
165 nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) ||
166 nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
167 dev->dev_addr) ||
168 nla_put_u8(msg, IEEE802154_ATTR_STATUS, status))
169 goto nla_put_failure;
170 return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP);
171
172nla_put_failure:
173 nlmsg_free(msg);
174 return -ENOBUFS;
175}
176EXPORT_SYMBOL(ieee802154_nl_disassoc_confirm);
177
178int ieee802154_nl_beacon_indic(struct net_device *dev, __le16 panid,
179 __le16 coord_addr)
180{
181 struct sk_buff *msg;
182
183 pr_debug("%s\n", __func__);
184
185 msg = ieee802154_nl_create(0, IEEE802154_BEACON_NOTIFY_INDIC);
186 if (!msg)
187 return -ENOBUFS;
188
189 if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
190 nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) ||
191 nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
192 dev->dev_addr) ||
193 nla_put_shortaddr(msg, IEEE802154_ATTR_COORD_SHORT_ADDR,
194 coord_addr) ||
195 nla_put_shortaddr(msg, IEEE802154_ATTR_COORD_PAN_ID, panid))
196 goto nla_put_failure;
197 return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP);
198
199nla_put_failure:
200 nlmsg_free(msg);
201 return -ENOBUFS;
202}
203EXPORT_SYMBOL(ieee802154_nl_beacon_indic);
204
205int ieee802154_nl_scan_confirm(struct net_device *dev,
206 u8 status, u8 scan_type,
207 u32 unscanned, u8 page,
208 u8 *edl/* , struct list_head *pan_desc_list */)
209{
210 struct sk_buff *msg;
211
212 pr_debug("%s\n", __func__);
213
214 msg = ieee802154_nl_create(0, IEEE802154_SCAN_CONF);
215 if (!msg)
216 return -ENOBUFS;
217
218 if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
219 nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) ||
220 nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
221 dev->dev_addr) ||
222 nla_put_u8(msg, IEEE802154_ATTR_STATUS, status) ||
223 nla_put_u8(msg, IEEE802154_ATTR_SCAN_TYPE, scan_type) ||
224 nla_put_u32(msg, IEEE802154_ATTR_CHANNELS, unscanned) ||
225 nla_put_u8(msg, IEEE802154_ATTR_PAGE, page) ||
226 (edl &&
227 nla_put(msg, IEEE802154_ATTR_ED_LIST, 27, edl)))
228 goto nla_put_failure;
229 return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP);
230
231nla_put_failure:
232 nlmsg_free(msg);
233 return -ENOBUFS;
234}
235EXPORT_SYMBOL(ieee802154_nl_scan_confirm);
236
237int ieee802154_nl_start_confirm(struct net_device *dev, u8 status)
238{ 58{
239 struct sk_buff *msg; 59 struct sk_buff *msg;
240 60
@@ -274,8 +94,9 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 portid,
274 goto out; 94 goto out;
275 95
276 ops = ieee802154_mlme_ops(dev); 96 ops = ieee802154_mlme_ops(dev);
277 phy = ops->get_phy(dev); 97 phy = dev->ieee802154_ptr->wpan_phy;
278 BUG_ON(!phy); 98 BUG_ON(!phy);
99 get_device(&phy->dev);
279 100
280 short_addr = ops->get_short_addr(dev); 101 short_addr = ops->get_short_addr(dev);
281 pan_id = ops->get_pan_id(dev); 102 pan_id = ops->get_pan_id(dev);
@@ -477,7 +298,7 @@ int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info)
477 u8 channel, bcn_ord, sf_ord; 298 u8 channel, bcn_ord, sf_ord;
478 u8 page; 299 u8 page;
479 int pan_coord, blx, coord_realign; 300 int pan_coord, blx, coord_realign;
480 int ret = -EOPNOTSUPP; 301 int ret = -EBUSY;
481 302
482 if (!info->attrs[IEEE802154_ATTR_COORD_PAN_ID] || 303 if (!info->attrs[IEEE802154_ATTR_COORD_PAN_ID] ||
483 !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR] || 304 !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR] ||
@@ -493,8 +314,14 @@ int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info)
493 dev = ieee802154_nl_get_dev(info); 314 dev = ieee802154_nl_get_dev(info);
494 if (!dev) 315 if (!dev)
495 return -ENODEV; 316 return -ENODEV;
496 if (!ieee802154_mlme_ops(dev)->start_req) 317
318 if (netif_running(dev))
319 goto out;
320
321 if (!ieee802154_mlme_ops(dev)->start_req) {
322 ret = -EOPNOTSUPP;
497 goto out; 323 goto out;
324 }
498 325
499 addr.mode = IEEE802154_ADDR_SHORT; 326 addr.mode = IEEE802154_ADDR_SHORT;
500 addr.short_addr = nla_get_shortaddr( 327 addr.short_addr = nla_get_shortaddr(
@@ -524,6 +351,11 @@ int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info)
524 ret = ieee802154_mlme_ops(dev)->start_req(dev, &addr, channel, page, 351 ret = ieee802154_mlme_ops(dev)->start_req(dev, &addr, channel, page,
525 bcn_ord, sf_ord, pan_coord, blx, coord_realign); 352 bcn_ord, sf_ord, pan_coord, blx, coord_realign);
526 353
354 /* FIXME: add validation for unused parameters to be sane
355 * for SoftMAC
356 */
357 ieee802154_nl_start_confirm(dev, IEEE802154_SUCCESS);
358
527out: 359out:
528 dev_put(dev); 360 dev_put(dev);
529 return ret; 361 return ret;
@@ -662,7 +494,8 @@ int ieee802154_set_macparams(struct sk_buff *skb, struct genl_info *info)
662 !info->attrs[IEEE802154_ATTR_FRAME_RETRIES]) 494 !info->attrs[IEEE802154_ATTR_FRAME_RETRIES])
663 goto out; 495 goto out;
664 496
665 phy = ops->get_phy(dev); 497 phy = dev->ieee802154_ptr->wpan_phy;
498 get_device(&phy->dev);
666 499
667 ops->get_mac_params(dev, &params); 500 ops->get_mac_params(dev, &params);
668 501
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
index 0afe760ff512..80a946dddd90 100644
--- a/net/ieee802154/nl-phy.c
+++ b/net/ieee802154/nl-phy.c
@@ -30,6 +30,8 @@
30#include <linux/nl802154.h> 30#include <linux/nl802154.h>
31 31
32#include "ieee802154.h" 32#include "ieee802154.h"
33#include "rdev-ops.h"
34#include "core.h"
33 35
34static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid, 36static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid,
35 u32 seq, int flags, struct wpan_phy *phy) 37 u32 seq, int flags, struct wpan_phy *phy)
@@ -203,11 +205,6 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info)
203 if (!msg) 205 if (!msg)
204 goto out_dev; 206 goto out_dev;
205 207
206 if (!phy->add_iface) {
207 rc = -EINVAL;
208 goto nla_put_failure;
209 }
210
211 if (info->attrs[IEEE802154_ATTR_HW_ADDR] && 208 if (info->attrs[IEEE802154_ATTR_HW_ADDR] &&
212 nla_len(info->attrs[IEEE802154_ATTR_HW_ADDR]) != 209 nla_len(info->attrs[IEEE802154_ATTR_HW_ADDR]) !=
213 IEEE802154_ADDR_LEN) { 210 IEEE802154_ADDR_LEN) {
@@ -223,11 +220,13 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info)
223 } 220 }
224 } 221 }
225 222
226 dev = phy->add_iface(phy, devname, type); 223 dev = rdev_add_virtual_intf_deprecated(wpan_phy_to_rdev(phy), devname,
224 type);
227 if (IS_ERR(dev)) { 225 if (IS_ERR(dev)) {
228 rc = PTR_ERR(dev); 226 rc = PTR_ERR(dev);
229 goto nla_put_failure; 227 goto nla_put_failure;
230 } 228 }
229 dev_hold(dev);
231 230
232 if (info->attrs[IEEE802154_ATTR_HW_ADDR]) { 231 if (info->attrs[IEEE802154_ATTR_HW_ADDR]) {
233 struct sockaddr addr; 232 struct sockaddr addr;
@@ -257,7 +256,7 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info)
257 256
258dev_unregister: 257dev_unregister:
259 rtnl_lock(); /* del_iface must be called with RTNL lock */ 258 rtnl_lock(); /* del_iface must be called with RTNL lock */
260 phy->del_iface(phy, dev); 259 rdev_del_virtual_intf_deprecated(wpan_phy_to_rdev(phy), dev);
261 dev_put(dev); 260 dev_put(dev);
262 rtnl_unlock(); 261 rtnl_unlock();
263nla_put_failure: 262nla_put_failure:
@@ -288,8 +287,9 @@ int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info)
288 if (!dev) 287 if (!dev)
289 return -ENODEV; 288 return -ENODEV;
290 289
291 phy = ieee802154_mlme_ops(dev)->get_phy(dev); 290 phy = dev->ieee802154_ptr->wpan_phy;
292 BUG_ON(!phy); 291 BUG_ON(!phy);
292 get_device(&phy->dev);
293 293
294 rc = -EINVAL; 294 rc = -EINVAL;
295 /* phy name is optional, but should be checked if it's given */ 295 /* phy name is optional, but should be checked if it's given */
@@ -319,13 +319,8 @@ int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info)
319 if (!msg) 319 if (!msg)
320 goto out_dev; 320 goto out_dev;
321 321
322 if (!phy->del_iface) {
323 rc = -EINVAL;
324 goto nla_put_failure;
325 }
326
327 rtnl_lock(); 322 rtnl_lock();
328 phy->del_iface(phy, dev); 323 rdev_del_virtual_intf_deprecated(wpan_phy_to_rdev(phy), dev);
329 324
330 /* We don't have device anymore */ 325 /* We don't have device anymore */
331 dev_put(dev); 326 dev_put(dev);
diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h
new file mode 100644
index 000000000000..ac8824ec168c
--- /dev/null
+++ b/net/ieee802154/rdev-ops.h
@@ -0,0 +1,23 @@
1#ifndef __CFG802154_RDEV_OPS
2#define __CFG802154_RDEV_OPS
3
4#include <net/cfg802154.h>
5
6#include "core.h"
7
8static inline struct net_device *
9rdev_add_virtual_intf_deprecated(struct cfg802154_registered_device *rdev,
10 const char *name, int type)
11{
12 return rdev->ops->add_virtual_intf_deprecated(&rdev->wpan_phy, name,
13 type);
14}
15
16static inline void
17rdev_del_virtual_intf_deprecated(struct cfg802154_registered_device *rdev,
18 struct net_device *dev)
19{
20 rdev->ops->del_virtual_intf_deprecated(&rdev->wpan_phy, dev);
21}
22
23#endif /* __CFG802154_RDEV_OPS */
diff --git a/net/ieee802154/sysfs.c b/net/ieee802154/sysfs.c
index eb9ca6f99122..88199980dae9 100644
--- a/net/ieee802154/sysfs.c
+++ b/net/ieee802154/sysfs.c
@@ -17,6 +17,16 @@
17 17
18#include <net/cfg802154.h> 18#include <net/cfg802154.h>
19 19
20#include "core.h"
21#include "sysfs.h"
22
23static inline struct cfg802154_registered_device *
24dev_to_rdev(struct device *dev)
25{
26 return container_of(dev, struct cfg802154_registered_device,
27 wpan_phy.dev);
28}
29
20#define MASTER_SHOW_COMPLEX(name, format_string, args...) \ 30#define MASTER_SHOW_COMPLEX(name, format_string, args...) \
21static ssize_t name ## _show(struct device *dev, \ 31static ssize_t name ## _show(struct device *dev, \
22 struct device_attribute *attr, char *buf) \ 32 struct device_attribute *attr, char *buf) \
@@ -60,11 +70,11 @@ static ssize_t channels_supported_show(struct device *dev,
60} 70}
61static DEVICE_ATTR_RO(channels_supported); 71static DEVICE_ATTR_RO(channels_supported);
62 72
63static void wpan_phy_release(struct device *d) 73static void wpan_phy_release(struct device *dev)
64{ 74{
65 struct wpan_phy *phy = container_of(d, struct wpan_phy, dev); 75 struct cfg802154_registered_device *rdev = dev_to_rdev(dev);
66 76
67 kfree(phy); 77 cfg802154_dev_free(rdev);
68} 78}
69 79
70static struct attribute *pmib_attrs[] = { 80static struct attribute *pmib_attrs[] = {
diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile
index 2e497d0c829a..702d8b466317 100644
--- a/net/mac802154/Makefile
+++ b/net/mac802154/Makefile
@@ -1,5 +1,5 @@
1obj-$(CONFIG_MAC802154) += mac802154.o 1obj-$(CONFIG_MAC802154) += mac802154.o
2mac802154-objs := main.o rx.o tx.o mac_cmd.o mib.o \ 2mac802154-objs := main.o rx.o tx.o mac_cmd.o mib.o \
3 iface.o llsec.o util.o 3 iface.o llsec.o util.o cfg.o
4 4
5ccflags-y += -D__CHECK_ENDIAN__ 5ccflags-y += -D__CHECK_ENDIAN__
diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c
new file mode 100644
index 000000000000..d2c4e8f89720
--- /dev/null
+++ b/net/mac802154/cfg.c
@@ -0,0 +1,47 @@
1/* This program is free software; you can redistribute it and/or modify
2 * it under the terms of the GNU General Public License version 2
3 * as published by the Free Software Foundation.
4 *
5 * This program is distributed in the hope that it will be useful,
6 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8 * GNU General Public License for more details.
9 *
10 * Authors:
11 * Alexander Aring <aar@pengutronix.de>
12 *
13 * Based on: net/mac80211/cfg.c
14 */
15
16#include <net/rtnetlink.h>
17#include <net/cfg802154.h>
18
19#include "ieee802154_i.h"
20#include "cfg.h"
21
22static struct net_device *
23ieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy,
24 const char *name, int type)
25{
26 struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
27 struct net_device *dev;
28
29 rtnl_lock();
30 dev = ieee802154_if_add(local, name, NULL, type);
31 rtnl_unlock();
32
33 return dev;
34}
35
36static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy,
37 struct net_device *dev)
38{
39 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
40
41 ieee802154_if_remove(sdata);
42}
43
44const struct cfg802154_ops mac802154_config_ops = {
45 .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated,
46 .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated,
47};
diff --git a/net/mac802154/cfg.h b/net/mac802154/cfg.h
new file mode 100644
index 000000000000..e2718f981e82
--- /dev/null
+++ b/net/mac802154/cfg.h
@@ -0,0 +1,9 @@
1/* mac802154 configuration hooks for cfg802154
2 */
3
4#ifndef __CFG_H
5#define __CFG_H
6
7extern const struct cfg802154_ops mac802154_config_ops;
8
9#endif /* __CFG_H */
diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h
index 1086a9d96f8f..4acacea0d371 100644
--- a/net/mac802154/ieee802154_i.h
+++ b/net/mac802154/ieee802154_i.h
@@ -20,6 +20,7 @@
20#define __IEEE802154_I_H 20#define __IEEE802154_I_H
21 21
22#include <linux/mutex.h> 22#include <linux/mutex.h>
23#include <net/cfg802154.h>
23#include <net/mac802154.h> 24#include <net/mac802154.h>
24#include <net/ieee802154_netdev.h> 25#include <net/ieee802154_netdev.h>
25 26
@@ -73,18 +74,20 @@ enum ieee802154_sdata_state_bits {
73struct ieee802154_sub_if_data { 74struct ieee802154_sub_if_data {
74 struct list_head list; /* the ieee802154_priv->slaves list */ 75 struct list_head list; /* the ieee802154_priv->slaves list */
75 76
77 struct wpan_dev wpan_dev;
78
76 struct ieee802154_local *local; 79 struct ieee802154_local *local;
77 struct net_device *dev; 80 struct net_device *dev;
78 81
79 int type;
80 unsigned long state; 82 unsigned long state;
83 char name[IFNAMSIZ];
81 84
82 spinlock_t mib_lock; 85 spinlock_t mib_lock;
83 86
84 __le16 pan_id; 87 __le16 pan_id;
85 __le16 short_addr; 88 __le16 short_addr;
86 __le64 extended_addr; 89 __le64 extended_addr;
87 bool promisuous_mode; 90 bool promiscuous_mode;
88 91
89 struct ieee802154_mac_params mac_params; 92 struct ieee802154_mac_params mac_params;
90 93
@@ -99,6 +102,8 @@ struct ieee802154_sub_if_data {
99 struct mutex sec_mtx; 102 struct mutex sec_mtx;
100 103
101 struct mac802154_llsec sec; 104 struct mac802154_llsec sec;
105 /* must be last, dynamically sized area in this! */
106 struct ieee802154_vif vif;
102}; 107};
103 108
104#define MAC802154_CHAN_NONE 0xff /* No channel is assigned */ 109#define MAC802154_CHAN_NONE 0xff /* No channel is assigned */
@@ -135,7 +140,6 @@ ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
135/* MIB callbacks */ 140/* MIB callbacks */
136void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val); 141void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val);
137__le16 mac802154_dev_get_short_addr(const struct net_device *dev); 142__le16 mac802154_dev_get_short_addr(const struct net_device *dev);
138void mac802154_dev_set_ieee_addr(struct net_device *dev);
139__le16 mac802154_dev_get_pan_id(const struct net_device *dev); 143__le16 mac802154_dev_get_pan_id(const struct net_device *dev);
140void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val); 144void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val);
141void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan); 145void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan);
@@ -174,4 +178,11 @@ void mac802154_get_table(struct net_device *dev,
174 struct ieee802154_llsec_table **t); 178 struct ieee802154_llsec_table **t);
175void mac802154_unlock_table(struct net_device *dev); 179void mac802154_unlock_table(struct net_device *dev);
176 180
181struct net_device *
182mac802154_add_iface(struct wpan_phy *phy, const char *name, int type);
183void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata);
184struct net_device *
185ieee802154_if_add(struct ieee802154_local *local, const char *name,
186 struct wpan_dev **new_wpan_dev, int type);
187
177#endif /* __IEEE802154_I_H */ 188#endif /* __IEEE802154_I_H */
diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
index f7a6f83301e2..384f4bb3c99b 100644
--- a/net/mac802154/iface.c
+++ b/net/mac802154/iface.c
@@ -24,7 +24,6 @@
24 24
25#include <net/rtnetlink.h> 25#include <net/rtnetlink.h>
26#include <linux/nl802154.h> 26#include <linux/nl802154.h>
27#include <net/af_ieee802154.h>
28#include <net/mac802154.h> 27#include <net/mac802154.h>
29#include <net/ieee802154_netdev.h> 28#include <net/ieee802154_netdev.h>
30#include <net/cfg802154.h> 29#include <net/cfg802154.h>
@@ -110,37 +109,21 @@ mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
110 109
111static int mac802154_wpan_mac_addr(struct net_device *dev, void *p) 110static int mac802154_wpan_mac_addr(struct net_device *dev, void *p)
112{ 111{
112 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
113 struct sockaddr *addr = p; 113 struct sockaddr *addr = p;
114 __le64 extended_addr;
114 115
115 if (netif_running(dev)) 116 if (netif_running(dev))
116 return -EBUSY; 117 return -EBUSY;
117 118
118 /* FIXME: validate addr */ 119 ieee802154_be64_to_le64(&extended_addr, addr->sa_data);
119 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 120 if (!ieee802154_is_valid_extended_addr(extended_addr))
120 mac802154_dev_set_ieee_addr(dev); 121 return -EINVAL;
121 return mac802154_wpan_update_llsec(dev);
122}
123
124int mac802154_set_mac_params(struct net_device *dev,
125 const struct ieee802154_mac_params *params)
126{
127 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
128
129 mutex_lock(&sdata->local->iflist_mtx);
130 sdata->mac_params = *params;
131 mutex_unlock(&sdata->local->iflist_mtx);
132
133 return 0;
134}
135 122
136void mac802154_get_mac_params(struct net_device *dev, 123 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
137 struct ieee802154_mac_params *params) 124 sdata->extended_addr = extended_addr;
138{
139 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
140 125
141 mutex_lock(&sdata->local->iflist_mtx); 126 return mac802154_wpan_update_llsec(dev);
142 *params = sdata->mac_params;
143 mutex_unlock(&sdata->local->iflist_mtx);
144} 127}
145 128
146static int mac802154_slave_open(struct net_device *dev) 129static int mac802154_slave_open(struct net_device *dev)
@@ -152,10 +135,11 @@ static int mac802154_slave_open(struct net_device *dev)
152 135
153 ASSERT_RTNL(); 136 ASSERT_RTNL();
154 137
155 if (sdata->type == IEEE802154_DEV_WPAN) { 138 if (sdata->vif.type == IEEE802154_DEV_WPAN) {
156 mutex_lock(&sdata->local->iflist_mtx); 139 mutex_lock(&sdata->local->iflist_mtx);
157 list_for_each_entry(subif, &sdata->local->interfaces, list) { 140 list_for_each_entry(subif, &sdata->local->interfaces, list) {
158 if (subif != sdata && subif->type == sdata->type && 141 if (subif != sdata &&
142 subif->vif.type == sdata->vif.type &&
159 ieee802154_sdata_running(subif)) { 143 ieee802154_sdata_running(subif)) {
160 mutex_unlock(&sdata->local->iflist_mtx); 144 mutex_unlock(&sdata->local->iflist_mtx);
161 return -EBUSY; 145 return -EBUSY;
@@ -197,32 +181,27 @@ static int mac802154_wpan_open(struct net_device *dev)
197 mutex_lock(&phy->pib_lock); 181 mutex_lock(&phy->pib_lock);
198 182
199 if (local->hw.flags & IEEE802154_HW_PROMISCUOUS) { 183 if (local->hw.flags & IEEE802154_HW_PROMISCUOUS) {
200 rc = drv_set_promiscuous_mode(local, sdata->promisuous_mode); 184 rc = drv_set_promiscuous_mode(local, sdata->promiscuous_mode);
201 if (rc < 0) 185 if (rc < 0)
202 goto out; 186 goto out;
203 } 187 }
204 188
205 if (local->hw.flags & IEEE802154_HW_TXPOWER) { 189 if (local->hw.flags & IEEE802154_HW_AFILT) {
206 rc = drv_set_tx_power(local, sdata->mac_params.transmit_power); 190 rc = drv_set_pan_id(local, sdata->pan_id);
207 if (rc < 0) 191 if (rc < 0)
208 goto out; 192 goto out;
209 }
210 193
211 if (local->hw.flags & IEEE802154_HW_LBT) { 194 rc = drv_set_extended_addr(local, sdata->extended_addr);
212 rc = drv_set_lbt_mode(local, sdata->mac_params.lbt);
213 if (rc < 0) 195 if (rc < 0)
214 goto out; 196 goto out;
215 }
216 197
217 if (local->hw.flags & IEEE802154_HW_CCA_MODE) { 198 rc = drv_set_short_addr(local, sdata->short_addr);
218 rc = drv_set_cca_mode(local, sdata->mac_params.cca_mode);
219 if (rc < 0) 199 if (rc < 0)
220 goto out; 200 goto out;
221 } 201 }
222 202
223 if (local->hw.flags & IEEE802154_HW_CCA_ED_LEVEL) { 203 if (local->hw.flags & IEEE802154_HW_LBT) {
224 rc = drv_set_cca_ed_level(local, 204 rc = drv_set_lbt_mode(local, sdata->mac_params.lbt);
225 sdata->mac_params.cca_ed_level);
226 if (rc < 0) 205 if (rc < 0)
227 goto out; 206 goto out;
228 } 207 }
@@ -402,30 +381,23 @@ static void mac802154_wpan_free(struct net_device *dev)
402 free_netdev(dev); 381 free_netdev(dev);
403} 382}
404 383
405void mac802154_wpan_setup(struct net_device *dev) 384static void ieee802154_if_setup(struct net_device *dev)
406{ 385{
407 struct ieee802154_sub_if_data *sdata; 386 dev->addr_len = IEEE802154_EXTENDED_ADDR_LEN;
408 387 memset(dev->broadcast, 0xff, IEEE802154_EXTENDED_ADDR_LEN);
409 dev->addr_len = IEEE802154_ADDR_LEN;
410 memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN);
411 388
412 dev->hard_header_len = MAC802154_FRAME_HARD_HEADER_LEN; 389 dev->hard_header_len = MAC802154_FRAME_HARD_HEADER_LEN;
413 dev->header_ops = &mac802154_header_ops;
414 dev->needed_tailroom = 2 + 16; /* FCS + MIC */ 390 dev->needed_tailroom = 2 + 16; /* FCS + MIC */
415 dev->mtu = IEEE802154_MTU; 391 dev->mtu = IEEE802154_MTU;
416 dev->tx_queue_len = 300; 392 dev->tx_queue_len = 300;
417 dev->type = ARPHRD_IEEE802154;
418 dev->flags = IFF_NOARP | IFF_BROADCAST; 393 dev->flags = IFF_NOARP | IFF_BROADCAST;
394}
419 395
420 dev->destructor = mac802154_wpan_free; 396static int
421 dev->netdev_ops = &mac802154_wpan_ops; 397ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, int type)
422 dev->ml_priv = &mac802154_mlme_wpan; 398{
423 399 /* set some type-dependent values */
424 sdata = IEEE802154_DEV_TO_SUB_IF(dev); 400 sdata->vif.type = type;
425 sdata->type = IEEE802154_DEV_WPAN;
426
427 spin_lock_init(&sdata->mib_lock);
428 mutex_init(&sdata->sec_mtx);
429 401
430 get_random_bytes(&sdata->bsn, 1); 402 get_random_bytes(&sdata->bsn, 1);
431 get_random_bytes(&sdata->dsn, 1); 403 get_random_bytes(&sdata->dsn, 1);
@@ -437,30 +409,113 @@ void mac802154_wpan_setup(struct net_device *dev)
437 /* for compatibility, actual default is 3 */ 409 /* for compatibility, actual default is 3 */
438 sdata->mac_params.frame_retries = -1; 410 sdata->mac_params.frame_retries = -1;
439 411
412 ieee802154_be64_to_le64(&sdata->extended_addr, sdata->dev->dev_addr);
440 sdata->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); 413 sdata->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST);
441 sdata->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); 414 sdata->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
442 415
443 sdata->promisuous_mode = false; 416 switch (type) {
417 case IEEE802154_DEV_WPAN:
418 sdata->dev->header_ops = &mac802154_header_ops;
419 sdata->dev->destructor = mac802154_wpan_free;
420 sdata->dev->netdev_ops = &mac802154_wpan_ops;
421 sdata->dev->ml_priv = &mac802154_mlme_wpan;
422 sdata->promiscuous_mode = false;
423
424 spin_lock_init(&sdata->mib_lock);
425 mutex_init(&sdata->sec_mtx);
426
427 mac802154_llsec_init(&sdata->sec);
428 break;
429 case IEEE802154_DEV_MONITOR:
430 sdata->dev->destructor = free_netdev;
431 sdata->dev->netdev_ops = &mac802154_monitor_ops;
432 sdata->promiscuous_mode = true;
433 break;
434 default:
435 BUG();
436 }
444 437
445 mac802154_llsec_init(&sdata->sec); 438 return 0;
446} 439}
447 440
448void mac802154_monitor_setup(struct net_device *dev) 441struct net_device *
442ieee802154_if_add(struct ieee802154_local *local, const char *name,
443 struct wpan_dev **new_wpan_dev, int type)
449{ 444{
450 struct ieee802154_sub_if_data *sdata; 445 struct net_device *ndev = NULL;
446 struct ieee802154_sub_if_data *sdata = NULL;
447 int ret = -ENOMEM;
451 448
452 dev->needed_tailroom = 2; /* room for FCS */ 449 ASSERT_RTNL();
453 dev->mtu = IEEE802154_MTU; 450
454 dev->tx_queue_len = 10; 451 ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size, name,
455 dev->type = ARPHRD_IEEE802154_MONITOR; 452 NET_NAME_UNKNOWN, ieee802154_if_setup);
456 dev->flags = IFF_NOARP | IFF_BROADCAST; 453 if (!ndev)
454 return ERR_PTR(-ENOMEM);
455
456 ndev->needed_headroom = local->hw.extra_tx_headroom;
457
458 ret = dev_alloc_name(ndev, ndev->name);
459 if (ret < 0)
460 goto err;
461
462 switch (type) {
463 case IEEE802154_DEV_WPAN:
464 ndev->type = ARPHRD_IEEE802154;
465 break;
466 case IEEE802154_DEV_MONITOR:
467 ndev->type = ARPHRD_IEEE802154_MONITOR;
468 break;
469 default:
470 ret = -EINVAL;
471 goto err;
472 }
473
474 ieee802154_le64_to_be64(ndev->perm_addr,
475 &local->hw.phy->perm_extended_addr);
476 memcpy(ndev->dev_addr, ndev->perm_addr, IEEE802154_EXTENDED_ADDR_LEN);
477 /* TODO check this */
478 SET_NETDEV_DEV(ndev, &local->phy->dev);
479 sdata = netdev_priv(ndev);
480 ndev->ieee802154_ptr = &sdata->wpan_dev;
481 memcpy(sdata->name, ndev->name, IFNAMSIZ);
482 sdata->dev = ndev;
483 sdata->wpan_dev.wpan_phy = local->hw.phy;
484 sdata->local = local;
485
486 /* setup type-dependent data */
487 ret = ieee802154_setup_sdata(sdata, type);
488 if (ret)
489 goto err;
490
491 if (ndev) {
492 ret = register_netdevice(ndev);
493 if (ret < 0)
494 goto err;
495 }
496
497 mutex_lock(&local->iflist_mtx);
498 list_add_tail_rcu(&sdata->list, &local->interfaces);
499 mutex_unlock(&local->iflist_mtx);
457 500
458 dev->destructor = free_netdev; 501 if (new_wpan_dev)
459 dev->netdev_ops = &mac802154_monitor_ops; 502 *new_wpan_dev = &sdata->wpan_dev;
460 dev->ml_priv = &mac802154_mlme_reduced;
461 503
462 sdata = IEEE802154_DEV_TO_SUB_IF(dev); 504 return ndev;
463 sdata->type = IEEE802154_DEV_MONITOR; 505
506err:
507 free_netdev(ndev);
508 return ERR_PTR(ret);
509}
510
511void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata)
512{
513 ASSERT_RTNL();
514
515 mutex_lock(&sdata->local->iflist_mtx);
516 list_del_rcu(&sdata->list);
517 mutex_unlock(&sdata->local->iflist_mtx);
464 518
465 sdata->promisuous_mode = true; 519 synchronize_rcu();
520 unregister_netdevice(sdata->dev);
466} 521}
diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c
index fc261ab33347..00b2b214770e 100644
--- a/net/mac802154/mac_cmd.c
+++ b/net/mac802154/mac_cmd.c
@@ -25,9 +25,9 @@
25#include <net/ieee802154_netdev.h> 25#include <net/ieee802154_netdev.h>
26#include <net/cfg802154.h> 26#include <net/cfg802154.h>
27#include <net/mac802154.h> 27#include <net/mac802154.h>
28#include <net/nl802154.h>
29 28
30#include "ieee802154_i.h" 29#include "ieee802154_i.h"
30#include "driver-ops.h"
31 31
32static int mac802154_mlme_start_req(struct net_device *dev, 32static int mac802154_mlme_start_req(struct net_device *dev,
33 struct ieee802154_addr *addr, 33 struct ieee802154_addr *addr,
@@ -43,7 +43,6 @@ static int mac802154_mlme_start_req(struct net_device *dev,
43 43
44 mac802154_dev_set_pan_id(dev, addr->pan_id); 44 mac802154_dev_set_pan_id(dev, addr->pan_id);
45 mac802154_dev_set_short_addr(dev, addr->short_addr); 45 mac802154_dev_set_short_addr(dev, addr->short_addr);
46 mac802154_dev_set_ieee_addr(dev);
47 mac802154_dev_set_page_channel(dev, page, channel); 46 mac802154_dev_set_page_channel(dev, page, channel);
48 47
49 if (ops->llsec) { 48 if (ops->llsec) {
@@ -65,32 +64,38 @@ static int mac802154_mlme_start_req(struct net_device *dev,
65 rc = ops->llsec->set_params(dev, &params, changed); 64 rc = ops->llsec->set_params(dev, &params, changed);
66 } 65 }
67 66
68 /* FIXME: add validation for unused parameters to be sane
69 * for SoftMAC
70 */
71 ieee802154_nl_start_confirm(dev, IEEE802154_SUCCESS);
72
73 return rc; 67 return rc;
74} 68}
75 69
76static struct wpan_phy *mac802154_get_phy(const struct net_device *dev)
77{
78 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
79
80 BUG_ON(dev->type != ARPHRD_IEEE802154);
81
82 return to_phy(get_device(&sdata->local->phy->dev));
83}
84
85static int mac802154_set_mac_params(struct net_device *dev, 70static int mac802154_set_mac_params(struct net_device *dev,
86 const struct ieee802154_mac_params *params) 71 const struct ieee802154_mac_params *params)
87{ 72{
88 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); 73 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
74 struct ieee802154_local *local = sdata->local;
75 int ret;
89 76
90 mutex_lock(&sdata->local->iflist_mtx); 77 mutex_lock(&sdata->local->iflist_mtx);
91 sdata->mac_params = *params; 78 sdata->mac_params = *params;
92 mutex_unlock(&sdata->local->iflist_mtx); 79 mutex_unlock(&sdata->local->iflist_mtx);
93 80
81 if (local->hw.flags & IEEE802154_HW_TXPOWER) {
82 ret = drv_set_tx_power(local, params->transmit_power);
83 if (ret < 0)
84 return ret;
85 }
86
87 if (local->hw.flags & IEEE802154_HW_CCA_MODE) {
88 ret = drv_set_cca_mode(local, params->cca_mode);
89 if (ret < 0)
90 return ret;
91 }
92
93 if (local->hw.flags & IEEE802154_HW_CCA_ED_LEVEL) {
94 ret = drv_set_cca_ed_level(local, params->cca_ed_level);
95 if (ret < 0)
96 return ret;
97 }
98
94 return 0; 99 return 0;
95} 100}
96 101
@@ -120,12 +125,7 @@ static struct ieee802154_llsec_ops mac802154_llsec_ops = {
120 .unlock_table = mac802154_unlock_table, 125 .unlock_table = mac802154_unlock_table,
121}; 126};
122 127
123struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced = {
124 .get_phy = mac802154_get_phy,
125};
126
127struct ieee802154_mlme_ops mac802154_mlme_wpan = { 128struct ieee802154_mlme_ops mac802154_mlme_wpan = {
128 .get_phy = mac802154_get_phy,
129 .start_req = mac802154_mlme_start_req, 129 .start_req = mac802154_mlme_start_req,
130 .get_pan_id = mac802154_dev_get_pan_id, 130 .get_pan_id = mac802154_dev_get_pan_id,
131 .get_short_addr = mac802154_dev_get_short_addr, 131 .get_short_addr = mac802154_dev_get_short_addr,
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
index 86e533ed3775..7d0ff7fd2cd4 100644
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -28,90 +28,7 @@
28#include <net/cfg802154.h> 28#include <net/cfg802154.h>
29 29
30#include "ieee802154_i.h" 30#include "ieee802154_i.h"
31 31#include "cfg.h"
32static int
33mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev)
34{
35 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
36 struct ieee802154_local *local;
37 int err;
38
39 local = wpan_phy_priv(phy);
40
41 sdata->dev = dev;
42 sdata->local = local;
43
44 dev->needed_headroom = local->hw.extra_tx_headroom;
45
46 SET_NETDEV_DEV(dev, &local->phy->dev);
47
48 err = register_netdev(dev);
49 if (err < 0)
50 return err;
51
52 rtnl_lock();
53 mutex_lock(&local->iflist_mtx);
54 list_add_tail_rcu(&sdata->list, &local->interfaces);
55 mutex_unlock(&local->iflist_mtx);
56 rtnl_unlock();
57
58 return 0;
59}
60
61static void
62mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev)
63{
64 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
65
66 ASSERT_RTNL();
67
68 BUG_ON(sdata->local->phy != phy);
69
70 mutex_lock(&sdata->local->iflist_mtx);
71 list_del_rcu(&sdata->list);
72 mutex_unlock(&sdata->local->iflist_mtx);
73
74 synchronize_rcu();
75 unregister_netdevice(sdata->dev);
76}
77
78static struct net_device *
79mac802154_add_iface(struct wpan_phy *phy, const char *name, int type)
80{
81 struct net_device *dev;
82 int err = -ENOMEM;
83
84 switch (type) {
85 case IEEE802154_DEV_MONITOR:
86 dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data),
87 name, NET_NAME_UNKNOWN,
88 mac802154_monitor_setup);
89 break;
90 case IEEE802154_DEV_WPAN:
91 dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data),
92 name, NET_NAME_UNKNOWN,
93 mac802154_wpan_setup);
94 break;
95 default:
96 dev = NULL;
97 err = -EINVAL;
98 break;
99 }
100 if (!dev)
101 goto err;
102
103 err = mac802154_netdev_register(phy, dev);
104 if (err)
105 goto err_free;
106
107 dev_hold(dev); /* we return an incremented device refcount */
108 return dev;
109
110err_free:
111 free_netdev(dev);
112err:
113 return ERR_PTR(err);
114}
115 32
116static void ieee802154_tasklet_handler(unsigned long data) 33static void ieee802154_tasklet_handler(unsigned long data)
117{ 34{
@@ -169,7 +86,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
169 86
170 priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len; 87 priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len;
171 88
172 phy = wpan_phy_alloc(priv_size); 89 phy = wpan_phy_alloc(&mac802154_config_ops, priv_size);
173 if (!phy) { 90 if (!phy) {
174 pr_err("failure to allocate master IEEE802.15.4 device\n"); 91 pr_err("failure to allocate master IEEE802.15.4 device\n");
175 return NULL; 92 return NULL;
@@ -209,6 +126,7 @@ EXPORT_SYMBOL(ieee802154_free_hw);
209int ieee802154_register_hw(struct ieee802154_hw *hw) 126int ieee802154_register_hw(struct ieee802154_hw *hw)
210{ 127{
211 struct ieee802154_local *local = hw_to_local(hw); 128 struct ieee802154_local *local = hw_to_local(hw);
129 struct net_device *dev;
212 int rc = -ENOSYS; 130 int rc = -ENOSYS;
213 131
214 local->workqueue = 132 local->workqueue =
@@ -220,13 +138,21 @@ int ieee802154_register_hw(struct ieee802154_hw *hw)
220 138
221 wpan_phy_set_dev(local->phy, local->hw.parent); 139 wpan_phy_set_dev(local->phy, local->hw.parent);
222 140
223 local->phy->add_iface = mac802154_add_iface;
224 local->phy->del_iface = mac802154_del_iface;
225
226 rc = wpan_phy_register(local->phy); 141 rc = wpan_phy_register(local->phy);
227 if (rc < 0) 142 if (rc < 0)
228 goto out_wq; 143 goto out_wq;
229 144
145 rtnl_lock();
146
147 dev = ieee802154_if_add(local, "wpan%d", NULL, IEEE802154_DEV_WPAN);
148 if (IS_ERR(dev)) {
149 rtnl_unlock();
150 rc = PTR_ERR(dev);
151 goto out_wq;
152 }
153
154 rtnl_unlock();
155
230 return 0; 156 return 0;
231 157
232out_wq: 158out_wq:
diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c
index 0184fced2f62..6fa749154baf 100644
--- a/net/mac802154/mib.c
+++ b/net/mac802154/mib.c
@@ -26,51 +26,6 @@
26#include "ieee802154_i.h" 26#include "ieee802154_i.h"
27#include "driver-ops.h" 27#include "driver-ops.h"
28 28
29struct hw_addr_filt_notify_work {
30 struct work_struct work;
31 struct net_device *dev;
32 unsigned long changed;
33};
34
35static struct ieee802154_local *mac802154_slave_get_priv(struct net_device *dev)
36{
37 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
38
39 BUG_ON(dev->type != ARPHRD_IEEE802154);
40
41 return sdata->local;
42}
43
44static void hw_addr_notify(struct work_struct *work)
45{
46 struct hw_addr_filt_notify_work *nw = container_of(work,
47 struct hw_addr_filt_notify_work, work);
48 struct ieee802154_local *local = mac802154_slave_get_priv(nw->dev);
49 int res;
50
51 res = local->ops->set_hw_addr_filt(&local->hw, &local->hw.hw_filt,
52 nw->changed);
53 if (res)
54 pr_debug("failed changed mask %lx\n", nw->changed);
55
56 kfree(nw);
57}
58
59static void set_hw_addr_filt(struct net_device *dev, unsigned long changed)
60{
61 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
62 struct hw_addr_filt_notify_work *work;
63
64 work = kzalloc(sizeof(*work), GFP_ATOMIC);
65 if (!work)
66 return;
67
68 INIT_WORK(&work->work, hw_addr_notify);
69 work->dev = dev;
70 work->changed = changed;
71 queue_work(sdata->local->workqueue, &work->work);
72}
73
74void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) 29void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val)
75{ 30{
76 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); 31 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
@@ -80,12 +35,6 @@ void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val)
80 spin_lock_bh(&sdata->mib_lock); 35 spin_lock_bh(&sdata->mib_lock);
81 sdata->short_addr = val; 36 sdata->short_addr = val;
82 spin_unlock_bh(&sdata->mib_lock); 37 spin_unlock_bh(&sdata->mib_lock);
83
84 if ((sdata->local->ops->set_hw_addr_filt) &&
85 (sdata->local->hw.hw_filt.short_addr != sdata->short_addr)) {
86 sdata->local->hw.hw_filt.short_addr = sdata->short_addr;
87 set_hw_addr_filt(dev, IEEE802154_AFILT_SADDR_CHANGED);
88 }
89} 38}
90 39
91__le16 mac802154_dev_get_short_addr(const struct net_device *dev) 40__le16 mac802154_dev_get_short_addr(const struct net_device *dev)
@@ -102,20 +51,6 @@ __le16 mac802154_dev_get_short_addr(const struct net_device *dev)
102 return ret; 51 return ret;
103} 52}
104 53
105void mac802154_dev_set_ieee_addr(struct net_device *dev)
106{
107 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
108 struct ieee802154_local *local = sdata->local;
109
110 sdata->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr);
111
112 if (local->ops->set_hw_addr_filt &&
113 local->hw.hw_filt.ieee_addr != sdata->extended_addr) {
114 local->hw.hw_filt.ieee_addr = sdata->extended_addr;
115 set_hw_addr_filt(dev, IEEE802154_AFILT_IEEEADDR_CHANGED);
116 }
117}
118
119__le16 mac802154_dev_get_pan_id(const struct net_device *dev) 54__le16 mac802154_dev_get_pan_id(const struct net_device *dev)
120{ 55{
121 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); 56 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
@@ -139,12 +74,6 @@ void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val)
139 spin_lock_bh(&sdata->mib_lock); 74 spin_lock_bh(&sdata->mib_lock);
140 sdata->pan_id = val; 75 sdata->pan_id = val;
141 spin_unlock_bh(&sdata->mib_lock); 76 spin_unlock_bh(&sdata->mib_lock);
142
143 if ((sdata->local->ops->set_hw_addr_filt) &&
144 (sdata->local->hw.hw_filt.pan_id != sdata->pan_id)) {
145 sdata->local->hw.hw_filt.pan_id = sdata->pan_id;
146 set_hw_addr_filt(dev, IEEE802154_AFILT_PANID_CHANGED);
147 }
148} 77}
149 78
150u8 mac802154_dev_get_dsn(const struct net_device *dev) 79u8 mac802154_dev_get_dsn(const struct net_device *dev)
diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
index 95961cccc253..4b54cf33e562 100644
--- a/net/mac802154/rx.c
+++ b/net/mac802154/rx.c
@@ -208,7 +208,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local,
208 } 208 }
209 209
210 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 210 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
211 if (sdata->type != IEEE802154_DEV_WPAN || 211 if (sdata->vif.type != IEEE802154_DEV_WPAN ||
212 !netif_running(sdata->dev)) 212 !netif_running(sdata->dev))
213 continue; 213 continue;
214 214
@@ -233,7 +233,7 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb)
233 skb->protocol = htons(ETH_P_IEEE802154); 233 skb->protocol = htons(ETH_P_IEEE802154);
234 234
235 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 235 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
236 if (sdata->type != IEEE802154_DEV_MONITOR) 236 if (sdata->vif.type != IEEE802154_DEV_MONITOR)
237 continue; 237 continue;
238 238
239 if (!ieee802154_sdata_running(sdata)) 239 if (!ieee802154_sdata_running(sdata))