All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework
@ 2015-05-17 19:44 Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 01/34] nl802154: cleanup invalid argument handling Alexander Aring
                   ` (34 more replies)
  0 siblings, 35 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

Hi Marcel,

this patch series contains mainly the following changes:

 - add support for phy capabilities
 - add support for atusb transceiver
 - rework fakelb driver implementation

Some of them patches was already send to wpan mailinglist, I did few
changes. These are:

 - add "atusb" prefix in some of the static function in atusb driver
 - a cleanup which move dev_consume_skb_any(skb) out of if and else
   branch. It's just called always, before it the call was in the
   if and else branch. See patch ("mac802154: tx: allow xmit complete
   from hard irq")
 - fix typo s/serveral/several in patch ("fakelb: cleanup code")

This patch series does _not_ include the mib/pib locks removal and
atomic_t for the data/beacon sequence number. These patches depends
on another patch ("mac802154: fix hold rtnl while ioctl") which should
go into bluetooth. I will send in the next days a patch series for bluetooth
which contains the ("mac802154: fix hold rtnl while ioctl") patch. If I seeing
this patch inside of bluetooth-next then I will send the mib/pib locks removal
and atomic_t for the data/beacon sequence number again for bluetooth-next.
Please let me know if this handling is fine. I think this avoids some merge
conflicts then.

Thanks.

- Alex

Alexander Aring (33):
  nl802154: cleanup invalid argument handling
  ieee802154: move validation check out of softmac
  ieee802154: change transmit power to s32
  ieee802154: change transmit power to mbm
  ieee802154: change cca ed level to mbm
  ieee802154: introduce wpan_phy_supported
  ieee802154: add several phy supported handling
  mac802154: check for really changes
  mac802154: remove check if operation is supported
  cfg802154: introduce wpan phy flags
  ieee802154: add iftypes capability
  at86rf230: set cca_modes supported flags
  at86rf230: rework tx power support
  at86rf230: rework tx cca energy detection level
  at86rf230: add cca ed level reset value
  at86rf230: add reset states of tx power level
  nl802154: add support for dump phy capabilities
  at86rf230: fix callback for aret handling
  mac802154: tx: allow xmit complete from hard irq
  ieee802154: add support for atusb transceiver
  fakelb: creating two virtual phys per default
  fakelb: use list_for_each_entry_safe
  fakelb: rename fakelb_dev_priv to fakelb_phy
  fakelb: don't deliver when one phy
  fakelb: declare rwlock static
  fakelb: declare fakelb list static
  fakelb: move lock out of iteration
  fakelb: introduce fakelb ifup phys list
  fakelb: use own channel and page attributes
  fakelb: add virtual phy reset defaults
  fakelb: remove fakelb_hw_deliver
  fakelb: add support for async xmit handling
  fakelb: cleanup code

Martin Townsend (1):
  mac802154: fakelb: Fix potential NULL pointer dereference.

 drivers/net/ieee802154/Kconfig     |  10 +
 drivers/net/ieee802154/Makefile    |   1 +
 drivers/net/ieee802154/at86rf230.c | 376 ++++++++------------
 drivers/net/ieee802154/at86rf230.h | 220 ++++++++++++
 drivers/net/ieee802154/atusb.c     | 692 +++++++++++++++++++++++++++++++++++++
 drivers/net/ieee802154/atusb.h     |  84 +++++
 drivers/net/ieee802154/cc2520.c    |   2 +-
 drivers/net/ieee802154/fakelb.c    | 209 +++++------
 drivers/net/ieee802154/mrf24j40.c  |   2 +-
 include/net/cfg802154.h            |  62 +++-
 include/net/mac802154.h            |  38 +-
 include/net/nl802154.h             |  79 +++++
 net/ieee802154/nl-mac.c            |   8 +-
 net/ieee802154/nl-phy.c            |   4 +-
 net/ieee802154/nl802154.c          | 209 +++++++++--
 net/mac802154/cfg.c                |  63 +---
 net/mac802154/driver-ops.h         |   8 +-
 net/mac802154/mac_cmd.c            |   6 +-
 net/mac802154/main.c               |  32 ++
 net/mac802154/util.c               |   5 +-
 20 files changed, 1639 insertions(+), 471 deletions(-)
 create mode 100644 drivers/net/ieee802154/at86rf230.h
 create mode 100644 drivers/net/ieee802154/atusb.c
 create mode 100644 drivers/net/ieee802154/atusb.h

-- 
2.3.7


^ permalink raw reply	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 01/34] nl802154: cleanup invalid argument handling
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 02/34] ieee802154: move validation check out of softmac Alexander Aring
                   ` (33 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch cleanups the -EINVAL cases by combining them in one
condition.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 net/ieee802154/nl802154.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
index f3c12f6..c01f4bb 100644
--- a/net/ieee802154/nl802154.c
+++ b/net/ieee802154/nl802154.c
@@ -668,10 +668,8 @@ static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info)
 		return -EBUSY;
 
 	/* don't change address fields on monitor */
-	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
-		return -EINVAL;
-
-	if (!info->attrs[NL802154_ATTR_PAN_ID])
+	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR ||
+	    !info->attrs[NL802154_ATTR_PAN_ID])
 		return -EINVAL;
 
 	pan_id = nla_get_le16(info->attrs[NL802154_ATTR_PAN_ID]);
@@ -691,10 +689,8 @@ static int nl802154_set_short_addr(struct sk_buff *skb, struct genl_info *info)
 		return -EBUSY;
 
 	/* don't change address fields on monitor */
-	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
-		return -EINVAL;
-
-	if (!info->attrs[NL802154_ATTR_SHORT_ADDR])
+	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR ||
+	    !info->attrs[NL802154_ATTR_SHORT_ADDR])
 		return -EINVAL;
 
 	short_addr = nla_get_le16(info->attrs[NL802154_ATTR_SHORT_ADDR]);
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 02/34] ieee802154: move validation check out of softmac
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 01/34] nl802154: cleanup invalid argument handling Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 03/34] ieee802154: change transmit power to s32 Alexander Aring
                   ` (32 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch moves the value validation out of softmac layer. We need
to be sure now that this value is accepted by the transceiver/mac802154 or
"possible" hardmac drivers before calling rdev-ops.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 net/ieee802154/nl802154.c | 28 +++++++++++++++++++++++++++-
 net/mac802154/cfg.c       | 29 -----------------------------
 2 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
index c01f4bb..d750d97 100644
--- a/net/ieee802154/nl802154.c
+++ b/net/ieee802154/nl802154.c
@@ -625,7 +625,8 @@ static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info)
 	channel = nla_get_u8(info->attrs[NL802154_ATTR_CHANNEL]);
 
 	/* check 802.15.4 constraints */
-	if (page > IEEE802154_MAX_PAGE || channel > IEEE802154_MAX_CHANNEL)
+	if (page > IEEE802154_MAX_PAGE || channel > IEEE802154_MAX_CHANNEL ||
+	    !(rdev->wpan_phy.channels_supported[page] & BIT(channel)))
 		return -EINVAL;
 
 	return rdev_set_channel(rdev, page, channel);
@@ -674,6 +675,16 @@ static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info)
 
 	pan_id = nla_get_le16(info->attrs[NL802154_ATTR_PAN_ID]);
 
+	/* TODO
+	 * I am not sure about to check here on broadcast pan_id.
+	 * Broadcast is a valid setting, comment from 802.15.4:
+	 * If this value is 0xffff, the device is not associated.
+	 *
+	 * This could useful to simple deassociate an device.
+	 */
+	if (pan_id == cpu_to_le16(IEEE802154_PAN_ID_BROADCAST))
+		return -EINVAL;
+
 	return rdev_set_pan_id(rdev, wpan_dev, pan_id);
 }
 
@@ -695,6 +706,21 @@ static int nl802154_set_short_addr(struct sk_buff *skb, struct genl_info *info)
 
 	short_addr = nla_get_le16(info->attrs[NL802154_ATTR_SHORT_ADDR]);
 
+	/* TODO
+	 * I am not sure about to check here on broadcast short_addr.
+	 * Broadcast is a valid setting, comment from 802.15.4:
+	 * A value of 0xfffe indicates that the device has
+	 * associated but has not been allocated an address. A
+	 * value of 0xffff indicates that the device does not
+	 * have a short address.
+	 *
+	 * I think we should allow to set these settings but
+	 * don't allow to allow socket communication with it.
+	 */
+	if (short_addr == cpu_to_le16(IEEE802154_ADDR_SHORT_UNSPEC) ||
+	    short_addr == cpu_to_le16(IEEE802154_ADDR_SHORT_BROADCAST))
+		return -EINVAL;
+
 	return rdev_set_short_addr(rdev, wpan_dev, short_addr);
 }
 
diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c
index 70be9c7..c636015 100644
--- a/net/mac802154/cfg.c
+++ b/net/mac802154/cfg.c
@@ -73,10 +73,6 @@ ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel)
 
 	ASSERT_RTNL();
 
-	/* check if phy support this setting */
-	if (!(wpan_phy->channels_supported[page] & BIT(channel)))
-		return -EINVAL;
-
 	ret = drv_set_channel(local, page, channel);
 	if (!ret) {
 		wpan_phy->current_page = page;
@@ -112,16 +108,6 @@ ieee802154_set_pan_id(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 {
 	ASSERT_RTNL();
 
-	/* TODO
-	 * I am not sure about to check here on broadcast pan_id.
-	 * Broadcast is a valid setting, comment from 802.15.4:
-	 * If this value is 0xffff, the device is not associated.
-	 *
-	 * This could useful to simple deassociate an device.
-	 */
-	if (pan_id == cpu_to_le16(IEEE802154_PAN_ID_BROADCAST))
-		return -EINVAL;
-
 	wpan_dev->pan_id = pan_id;
 	return 0;
 }
@@ -149,21 +135,6 @@ ieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 {
 	ASSERT_RTNL();
 
-	/* TODO
-	 * I am not sure about to check here on broadcast short_addr.
-	 * Broadcast is a valid setting, comment from 802.15.4:
-	 * A value of 0xfffe indicates that the device has
-	 * associated but has not been allocated an address. A
-	 * value of 0xffff indicates that the device does not
-	 * have a short address.
-	 *
-	 * I think we should allow to set these settings but
-	 * don't allow to allow socket communication with it.
-	 */
-	if (short_addr == cpu_to_le16(IEEE802154_ADDR_SHORT_UNSPEC) ||
-	    short_addr == cpu_to_le16(IEEE802154_ADDR_SHORT_BROADCAST))
-		return -EINVAL;
-
 	wpan_dev->short_addr = short_addr;
 	return 0;
 }
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 03/34] ieee802154: change transmit power to s32
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 01/34] nl802154: cleanup invalid argument handling Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 02/34] ieee802154: move validation check out of softmac Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 04/34] ieee802154: change transmit power to mbm Alexander Aring
                   ` (31 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch change the transmit power from s8 to s32. This prepares to store a
mbm value instead dbm inside the transmit power variable. The old
interface keep the a s8 dbm value, which should be backward compatibility
when assign s8 to s32.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/at86rf230.c | 2 +-
 include/net/cfg802154.h            | 2 +-
 include/net/mac802154.h            | 2 +-
 net/ieee802154/nl802154.c          | 6 +++---
 net/mac802154/driver-ops.h         | 2 +-
 5 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index 67d00fb..02b6bb7 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -1194,7 +1194,7 @@ at86rf230_set_hw_addr_filt(struct ieee802154_hw *hw,
 }
 
 static int
-at86rf230_set_txpower(struct ieee802154_hw *hw, s8 db)
+at86rf230_set_txpower(struct ieee802154_hw *hw, s32 db)
 {
 	struct at86rf230_local *lp = hw->priv;
 
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 6ea16c8..47804cd 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -85,7 +85,7 @@ struct wpan_phy {
 	u8 current_channel;
 	u8 current_page;
 	u32 channels_supported[IEEE802154_MAX_PAGE + 1];
-	s8 transmit_power;
+	s32 transmit_power;
 	struct wpan_phy_cca cca;
 
 	__le64 perm_extended_addr;
diff --git a/include/net/mac802154.h b/include/net/mac802154.h
index 7df28a4..400e4e8 100644
--- a/include/net/mac802154.h
+++ b/include/net/mac802154.h
@@ -213,7 +213,7 @@ struct ieee802154_ops {
 	int		(*set_hw_addr_filt)(struct ieee802154_hw *hw,
 					    struct ieee802154_hw_addr_filt *filt,
 					    unsigned long changed);
-	int		(*set_txpower)(struct ieee802154_hw *hw, s8 dbm);
+	int		(*set_txpower)(struct ieee802154_hw *hw, s32 dbm);
 	int		(*set_lbt)(struct ieee802154_hw *hw, bool on);
 	int		(*set_cca_mode)(struct ieee802154_hw *hw,
 					const struct wpan_phy_cca *cca);
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
index d750d97..f3185c7 100644
--- a/net/ieee802154/nl802154.c
+++ b/net/ieee802154/nl802154.c
@@ -207,7 +207,7 @@ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = {
 	[NL802154_ATTR_PAGE] = { .type = NLA_U8, },
 	[NL802154_ATTR_CHANNEL] = { .type = NLA_U8, },
 
-	[NL802154_ATTR_TX_POWER] = { .type = NLA_S8, },
+	[NL802154_ATTR_TX_POWER] = { .type = NLA_S32, },
 
 	[NL802154_ATTR_CCA_MODE] = { .type = NLA_U32, },
 	[NL802154_ATTR_CCA_OPT] = { .type = NLA_U32, },
@@ -301,8 +301,8 @@ static int nl802154_send_wpan_phy(struct cfg802154_registered_device *rdev,
 			goto nla_put_failure;
 	}
 
-	if (nla_put_s8(msg, NL802154_ATTR_TX_POWER,
-		       rdev->wpan_phy.transmit_power))
+	if (nla_put_s32(msg, NL802154_ATTR_TX_POWER,
+			rdev->wpan_phy.transmit_power))
 		goto nla_put_failure;
 
 finish:
diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h
index a053335..57c1bdb 100644
--- a/net/mac802154/driver-ops.h
+++ b/net/mac802154/driver-ops.h
@@ -58,7 +58,7 @@ drv_set_channel(struct ieee802154_local *local, u8 page, u8 channel)
 	return local->ops->set_channel(&local->hw, page, channel);
 }
 
-static inline int drv_set_tx_power(struct ieee802154_local *local, s8 dbm)
+static inline int drv_set_tx_power(struct ieee802154_local *local, s32 dbm)
 {
 	might_sleep();
 
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 04/34] ieee802154: change transmit power to mbm
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (2 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 03/34] ieee802154: change transmit power to s32 Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 05/34] ieee802154: change cca ed level " Alexander Aring
                   ` (30 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch change the handling of transmit power level from dbm to mbm.
This prepares to handle floating point transmit power levels values. The
old netlink 802.15.4 will convert the dbm value to mbm for handling
backward compatibility.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/at86rf230.c | 3 ++-
 include/net/cfg802154.h            | 1 +
 include/net/mac802154.h            | 4 ++--
 net/ieee802154/nl-mac.c            | 4 ++--
 net/mac802154/driver-ops.h         | 4 ++--
 5 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index 02b6bb7..3a303e4 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -1194,9 +1194,10 @@ at86rf230_set_hw_addr_filt(struct ieee802154_hw *hw,
 }
 
 static int
-at86rf230_set_txpower(struct ieee802154_hw *hw, s32 db)
+at86rf230_set_txpower(struct ieee802154_hw *hw, s32 mbm)
 {
 	struct at86rf230_local *lp = hw->priv;
+	s8 db = mbm / 100;
 
 	/* typical maximum output is 5dBm with RG_PHY_TX_PWR 0x60, lower five
 	 * bits decrease power in 1dB steps. 0x60 represents extra PA gain of
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 47804cd..b5b3f9f 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -85,6 +85,7 @@ struct wpan_phy {
 	u8 current_channel;
 	u8 current_page;
 	u32 channels_supported[IEEE802154_MAX_PAGE + 1];
+	/* current transmit_power in mBm */
 	s32 transmit_power;
 	struct wpan_phy_cca cca;
 
diff --git a/include/net/mac802154.h b/include/net/mac802154.h
index 400e4e8..e863a85 100644
--- a/include/net/mac802154.h
+++ b/include/net/mac802154.h
@@ -171,7 +171,7 @@ struct ieee802154_hw {
  *	  Returns either zero, or negative errno.
  *
  * set_txpower:
- *	  Set radio transmit power in dB. Called with pib_lock held.
+ *	  Set radio transmit power in mBm. Called with pib_lock held.
  *	  Returns either zero, or negative errno.
  *
  * set_lbt
@@ -213,7 +213,7 @@ struct ieee802154_ops {
 	int		(*set_hw_addr_filt)(struct ieee802154_hw *hw,
 					    struct ieee802154_hw_addr_filt *filt,
 					    unsigned long changed);
-	int		(*set_txpower)(struct ieee802154_hw *hw, s32 dbm);
+	int		(*set_txpower)(struct ieee802154_hw *hw, s32 mbm);
 	int		(*set_lbt)(struct ieee802154_hw *hw, bool on);
 	int		(*set_cca_mode)(struct ieee802154_hw *hw,
 					const struct wpan_phy_cca *cca);
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index 2b4955d..4ba2e13 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -117,7 +117,7 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 portid,
 		rtnl_unlock();
 
 		if (nla_put_s8(msg, IEEE802154_ATTR_TXPOWER,
-			       params.transmit_power) ||
+			       params.transmit_power / 100) ||
 		    nla_put_u8(msg, IEEE802154_ATTR_LBT_ENABLED, params.lbt) ||
 		    nla_put_u8(msg, IEEE802154_ATTR_CCA_MODE,
 			       params.cca.mode) ||
@@ -510,7 +510,7 @@ int ieee802154_set_macparams(struct sk_buff *skb, struct genl_info *info)
 	ops->get_mac_params(dev, &params);
 
 	if (info->attrs[IEEE802154_ATTR_TXPOWER])
-		params.transmit_power = nla_get_s8(info->attrs[IEEE802154_ATTR_TXPOWER]);
+		params.transmit_power = nla_get_s8(info->attrs[IEEE802154_ATTR_TXPOWER]) * 100;
 
 	if (info->attrs[IEEE802154_ATTR_LBT_ENABLED])
 		params.lbt = nla_get_u8(info->attrs[IEEE802154_ATTR_LBT_ENABLED]);
diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h
index 57c1bdb..d289ae3 100644
--- a/net/mac802154/driver-ops.h
+++ b/net/mac802154/driver-ops.h
@@ -58,7 +58,7 @@ drv_set_channel(struct ieee802154_local *local, u8 page, u8 channel)
 	return local->ops->set_channel(&local->hw, page, channel);
 }
 
-static inline int drv_set_tx_power(struct ieee802154_local *local, s32 dbm)
+static inline int drv_set_tx_power(struct ieee802154_local *local, s32 mbm)
 {
 	might_sleep();
 
@@ -67,7 +67,7 @@ static inline int drv_set_tx_power(struct ieee802154_local *local, s32 dbm)
 		return -EOPNOTSUPP;
 	}
 
-	return local->ops->set_txpower(&local->hw, dbm);
+	return local->ops->set_txpower(&local->hw, mbm);
 }
 
 static inline int drv_set_cca_mode(struct ieee802154_local *local,
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 05/34] ieee802154: change cca ed level to mbm
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (3 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 04/34] ieee802154: change transmit power to mbm Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 06/34] ieee802154: introduce wpan_phy_supported Alexander Aring
                   ` (29 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch change the handling of cca energy detection level from dbm to
mbm. This prepares to handle floating point cca energy detection levels
values. The old netlink 802.15.4 will convert the dbm value to mbm for
handling backward compatibility.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/at86rf230.c | 3 ++-
 include/net/cfg802154.h            | 1 +
 include/net/mac802154.h            | 5 ++---
 net/ieee802154/nl-mac.c            | 4 ++--
 net/mac802154/driver-ops.h         | 4 ++--
 5 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index 3a303e4..e68d45e 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -1268,9 +1268,10 @@ at86rf23x_get_desens_steps(struct at86rf230_local *lp, s32 level)
 }
 
 static int
-at86rf230_set_cca_ed_level(struct ieee802154_hw *hw, s32 level)
+at86rf230_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm)
 {
 	struct at86rf230_local *lp = hw->priv;
+	s32 level = mbm / 100;
 
 	if (level < lp->data->rssi_base_val || level > 30)
 		return -EINVAL;
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index b5b3f9f..9ced2c9 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -91,6 +91,7 @@ struct wpan_phy {
 
 	__le64 perm_extended_addr;
 
+	/* current cca ed threshold in mBm */
 	s32 cca_ed_level;
 
 	/* PHY depended MAC PIB values */
diff --git a/include/net/mac802154.h b/include/net/mac802154.h
index e863a85..71e2456 100644
--- a/include/net/mac802154.h
+++ b/include/net/mac802154.h
@@ -184,7 +184,7 @@ struct ieee802154_hw {
  *	  Returns either zero, or negative errno.
  *
  * set_cca_ed_level
- *	  Sets the CCA energy detection threshold in dBm. Called with pib_lock
+ *	  Sets the CCA energy detection threshold in mBm. Called with pib_lock
  *	  held.
  *	  Returns either zero, or negative errno.
  *
@@ -217,8 +217,7 @@ struct ieee802154_ops {
 	int		(*set_lbt)(struct ieee802154_hw *hw, bool on);
 	int		(*set_cca_mode)(struct ieee802154_hw *hw,
 					const struct wpan_phy_cca *cca);
-	int		(*set_cca_ed_level)(struct ieee802154_hw *hw,
-					    s32 level);
+	int		(*set_cca_ed_level)(struct ieee802154_hw *hw, s32 mbm);
 	int		(*set_csma_params)(struct ieee802154_hw *hw,
 					   u8 min_be, u8 max_be, u8 retries);
 	int		(*set_frame_retries)(struct ieee802154_hw *hw,
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index 4ba2e13..cdc1cc3 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -122,7 +122,7 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 portid,
 		    nla_put_u8(msg, IEEE802154_ATTR_CCA_MODE,
 			       params.cca.mode) ||
 		    nla_put_s32(msg, IEEE802154_ATTR_CCA_ED_LEVEL,
-				params.cca_ed_level) ||
+				params.cca_ed_level / 100) ||
 		    nla_put_u8(msg, IEEE802154_ATTR_CSMA_RETRIES,
 			       params.csma_retries) ||
 		    nla_put_u8(msg, IEEE802154_ATTR_CSMA_MIN_BE,
@@ -519,7 +519,7 @@ int ieee802154_set_macparams(struct sk_buff *skb, struct genl_info *info)
 		params.cca.mode = nla_get_u8(info->attrs[IEEE802154_ATTR_CCA_MODE]);
 
 	if (info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL])
-		params.cca_ed_level = nla_get_s32(info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]);
+		params.cca_ed_level = nla_get_s32(info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]) * 100;
 
 	if (info->attrs[IEEE802154_ATTR_CSMA_RETRIES])
 		params.csma_retries = nla_get_u8(info->attrs[IEEE802154_ATTR_CSMA_RETRIES]);
diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h
index d289ae3..caecd5f 100644
--- a/net/mac802154/driver-ops.h
+++ b/net/mac802154/driver-ops.h
@@ -96,7 +96,7 @@ static inline int drv_set_lbt_mode(struct ieee802154_local *local, bool mode)
 }
 
 static inline int
-drv_set_cca_ed_level(struct ieee802154_local *local, s32 ed_level)
+drv_set_cca_ed_level(struct ieee802154_local *local, s32 mbm)
 {
 	might_sleep();
 
@@ -105,7 +105,7 @@ drv_set_cca_ed_level(struct ieee802154_local *local, s32 ed_level)
 		return -EOPNOTSUPP;
 	}
 
-	return local->ops->set_cca_ed_level(&local->hw, ed_level);
+	return local->ops->set_cca_ed_level(&local->hw, mbm);
 }
 
 static inline int drv_set_pan_id(struct ieee802154_local *local, __le16 pan_id)
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 06/34] ieee802154: introduce wpan_phy_supported
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (4 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 05/34] ieee802154: change cca ed level " Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-18 10:19   ` Varka Bhadram
  2015-05-17 19:44 ` [PATCH bluetooth-next 07/34] ieee802154: add several phy supported handling Alexander Aring
                   ` (28 subsequent siblings)
  34 siblings, 1 reply; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring, Varka Bhadram, Alan Ott

This patch introduce the wpan_phy_supported struct for wpan_phy. There
is currently no way to check if a transceiver can handle IEEE 802.15.4
complaint values. With this struct we can check before if the
transceiver supports these values before sending to driver layer.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Suggested-by: Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>
Cc: Varka Bhadram <varkabhadram@gmail.com>
Cc: Alan Ott <alan@signal11.us>
---
 drivers/net/ieee802154/at86rf230.c |  8 ++++----
 drivers/net/ieee802154/cc2520.c    |  2 +-
 drivers/net/ieee802154/fakelb.c    | 30 +++++++++++++++---------------
 drivers/net/ieee802154/mrf24j40.c  |  2 +-
 include/net/cfg802154.h            |  6 +++++-
 net/ieee802154/nl-phy.c            |  4 ++--
 net/ieee802154/nl802154.c          |  4 ++--
 7 files changed, 30 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index e68d45e..151d57f 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -1579,7 +1579,7 @@ at86rf230_detect_device(struct at86rf230_local *lp)
 	case 3:
 		chip = "at86rf231";
 		lp->data = &at86rf231_data;
-		lp->hw->phy->channels_supported[0] = 0x7FFF800;
+		lp->hw->phy->supported.channels[0] = 0x7FFF800;
 		lp->hw->phy->current_channel = 11;
 		lp->hw->phy->symbol_duration = 16;
 		break;
@@ -1587,15 +1587,15 @@ at86rf230_detect_device(struct at86rf230_local *lp)
 		chip = "at86rf212";
 		lp->data = &at86rf212_data;
 		lp->hw->flags |= IEEE802154_HW_LBT;
-		lp->hw->phy->channels_supported[0] = 0x00007FF;
-		lp->hw->phy->channels_supported[2] = 0x00007FF;
+		lp->hw->phy->supported.channels[0] = 0x00007FF;
+		lp->hw->phy->supported.channels[2] = 0x00007FF;
 		lp->hw->phy->current_channel = 5;
 		lp->hw->phy->symbol_duration = 25;
 		break;
 	case 11:
 		chip = "at86rf233";
 		lp->data = &at86rf233_data;
-		lp->hw->phy->channels_supported[0] = 0x7FFF800;
+		lp->hw->phy->supported.channels[0] = 0x7FFF800;
 		lp->hw->phy->current_channel = 13;
 		lp->hw->phy->symbol_duration = 16;
 		break;
diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c
index f833b8b..84b28a0 100644
--- a/drivers/net/ieee802154/cc2520.c
+++ b/drivers/net/ieee802154/cc2520.c
@@ -653,7 +653,7 @@ static int cc2520_register(struct cc2520_private *priv)
 	ieee802154_random_extended_addr(&priv->hw->phy->perm_extended_addr);
 
 	/* We do support only 2.4 Ghz */
-	priv->hw->phy->channels_supported[0] = 0x7FFF800;
+	priv->hw->phy->supported.channels[0] = 0x7FFF800;
 	priv->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK |
 			  IEEE802154_HW_AFILT;
 
diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index dc2bfb6..91bbf03 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -149,35 +149,35 @@ static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake)
 	priv->hw = hw;
 
 	/* 868 MHz BPSK	802.15.4-2003 */
-	hw->phy->channels_supported[0] |= 1;
+	hw->phy->supported.channels[0] |= 1;
 	/* 915 MHz BPSK	802.15.4-2003 */
-	hw->phy->channels_supported[0] |= 0x7fe;
+	hw->phy->supported.channels[0] |= 0x7fe;
 	/* 2.4 GHz O-QPSK 802.15.4-2003 */
-	hw->phy->channels_supported[0] |= 0x7FFF800;
+	hw->phy->supported.channels[0] |= 0x7FFF800;
 	/* 868 MHz ASK 802.15.4-2006 */
-	hw->phy->channels_supported[1] |= 1;
+	hw->phy->supported.channels[1] |= 1;
 	/* 915 MHz ASK 802.15.4-2006 */
-	hw->phy->channels_supported[1] |= 0x7fe;
+	hw->phy->supported.channels[1] |= 0x7fe;
 	/* 868 MHz O-QPSK 802.15.4-2006 */
-	hw->phy->channels_supported[2] |= 1;
+	hw->phy->supported.channels[2] |= 1;
 	/* 915 MHz O-QPSK 802.15.4-2006 */
-	hw->phy->channels_supported[2] |= 0x7fe;
+	hw->phy->supported.channels[2] |= 0x7fe;
 	/* 2.4 GHz CSS 802.15.4a-2007 */
-	hw->phy->channels_supported[3] |= 0x3fff;
+	hw->phy->supported.channels[3] |= 0x3fff;
 	/* UWB Sub-gigahertz 802.15.4a-2007 */
-	hw->phy->channels_supported[4] |= 1;
+	hw->phy->supported.channels[4] |= 1;
 	/* UWB Low band 802.15.4a-2007 */
-	hw->phy->channels_supported[4] |= 0x1e;
+	hw->phy->supported.channels[4] |= 0x1e;
 	/* UWB High band 802.15.4a-2007 */
-	hw->phy->channels_supported[4] |= 0xffe0;
+	hw->phy->supported.channels[4] |= 0xffe0;
 	/* 750 MHz O-QPSK 802.15.4c-2009 */
-	hw->phy->channels_supported[5] |= 0xf;
+	hw->phy->supported.channels[5] |= 0xf;
 	/* 750 MHz MPSK 802.15.4c-2009 */
-	hw->phy->channels_supported[5] |= 0xf0;
+	hw->phy->supported.channels[5] |= 0xf0;
 	/* 950 MHz BPSK 802.15.4d-2009 */
-	hw->phy->channels_supported[6] |= 0x3ff;
+	hw->phy->supported.channels[6] |= 0x3ff;
 	/* 950 MHz GFSK 802.15.4d-2009 */
-	hw->phy->channels_supported[6] |= 0x3ffc00;
+	hw->phy->supported.channels[6] |= 0x3ffc00;
 
 	INIT_LIST_HEAD(&priv->list);
 	priv->fake = fake;
diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c
index fba2dfd..f2a1bd1 100644
--- a/drivers/net/ieee802154/mrf24j40.c
+++ b/drivers/net/ieee802154/mrf24j40.c
@@ -750,7 +750,7 @@ static int mrf24j40_probe(struct spi_device *spi)
 
 	devrec->hw->priv = devrec;
 	devrec->hw->parent = &devrec->spi->dev;
-	devrec->hw->phy->channels_supported[0] = CHANNEL_MASK;
+	devrec->hw->phy->supported.channels[0] = CHANNEL_MASK;
 	devrec->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK |
 			    IEEE802154_HW_AFILT;
 
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 9ced2c9..1941d7a 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -61,6 +61,10 @@ struct cfg802154_ops {
 				struct wpan_dev *wpan_dev, bool mode);
 };
 
+struct wpan_phy_supported {
+	u32 channels[IEEE802154_MAX_PAGE + 1];
+};
+
 struct wpan_phy_cca {
 	enum nl802154_cca_modes mode;
 	enum nl802154_cca_opts opt;
@@ -84,7 +88,7 @@ struct wpan_phy {
 	 */
 	u8 current_channel;
 	u8 current_page;
-	u32 channels_supported[IEEE802154_MAX_PAGE + 1];
+	struct wpan_phy_supported supported;
 	/* current transmit_power in mBm */
 	s32 transmit_power;
 	struct wpan_phy_cca cca;
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
index 346c666..cbc0d09 100644
--- a/net/ieee802154/nl-phy.c
+++ b/net/ieee802154/nl-phy.c
@@ -56,8 +56,8 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid,
 	    nla_put_u8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel))
 		goto nla_put_failure;
 	for (i = 0; i < 32; i++) {
-		if (phy->channels_supported[i])
-			buf[pages++] = phy->channels_supported[i] | (i << 27);
+		if (phy->supported.channels[i])
+			buf[pages++] = phy->supported.channels[i] | (i << 27);
 	}
 	if (pages &&
 	    nla_put(msg, IEEE802154_ATTR_CHANNEL_PAGE_LIST,
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
index f3185c7..d271879 100644
--- a/net/ieee802154/nl802154.c
+++ b/net/ieee802154/nl802154.c
@@ -248,7 +248,7 @@ nl802154_send_wpan_phy_channels(struct cfg802154_registered_device *rdev,
 
 	for (page = 0; page <= IEEE802154_MAX_PAGE; page++) {
 		if (nla_put_u32(msg, NL802154_ATTR_SUPPORTED_CHANNEL,
-				rdev->wpan_phy.channels_supported[page]))
+				rdev->wpan_phy.supported.channels[page]))
 			return -ENOBUFS;
 	}
 	nla_nest_end(msg, nl_page);
@@ -626,7 +626,7 @@ static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info)
 
 	/* check 802.15.4 constraints */
 	if (page > IEEE802154_MAX_PAGE || channel > IEEE802154_MAX_CHANNEL ||
-	    !(rdev->wpan_phy.channels_supported[page] & BIT(channel)))
+	    !(rdev->wpan_phy.supported.channels[page] & BIT(channel)))
 		return -EINVAL;
 
 	return rdev_set_channel(rdev, page, channel);
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 07/34] ieee802154: add several phy supported handling
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (5 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 06/34] ieee802154: introduce wpan_phy_supported Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 08/34] mac802154: check for really changes Alexander Aring
                   ` (27 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch adds support for phy supported handling for all other already
existing handling 802.15.4 functionality. We assume now a fully 802.15.4
complaint transceiver at phy allocation. If a transceiver can support
802.15.4 default values only, then the values should be overwirtten by
values the transceiver supports. If the transceiver doesn't set the
according hardware flags, we assume the 802.15.4 defaults now which
cannot be changed.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Suggested-by: Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>
---
 include/net/cfg802154.h   | 26 +++++++++++++++++++++++++-
 include/net/nl802154.h    | 22 ++++++++++++++++++++++
 net/ieee802154/nl802154.c | 22 +++++++++++++++++-----
 net/mac802154/main.c      | 26 ++++++++++++++++++++++++++
 4 files changed, 90 insertions(+), 6 deletions(-)

diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 1941d7a..23abd08 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -61,8 +61,32 @@ struct cfg802154_ops {
 				struct wpan_dev *wpan_dev, bool mode);
 };
 
+static inline bool
+wpan_phy_supported_bool(bool b, enum nl802154_supported_bool_states st)
+{
+	switch (st) {
+	case NL802154_SUPPORTED_BOOL_TRUE:
+		return b;
+	case NL802154_SUPPORTED_BOOL_FALSE:
+		return !b;
+	case NL802154_SUPPORTED_BOOL_BOTH:
+		return true;
+	default:
+		WARN_ON(1);
+	}
+
+	return false;
+}
+
 struct wpan_phy_supported {
-	u32 channels[IEEE802154_MAX_PAGE + 1];
+	u32 channels[IEEE802154_MAX_PAGE + 1],
+	    cca_modes, cca_opts;
+	enum nl802154_supported_bool_states lbt;
+	u8 min_minbe, max_minbe, min_maxbe, max_maxbe,
+	   min_csma_backoffs, max_csma_backoffs;
+	s8 min_frame_retries, max_frame_retries;
+	size_t tx_powers_size, cca_ed_levels_size;
+	const s32 *tx_powers, *cca_ed_levels;
 };
 
 struct wpan_phy_cca {
diff --git a/include/net/nl802154.h b/include/net/nl802154.h
index f8b5bc9..0552771 100644
--- a/include/net/nl802154.h
+++ b/include/net/nl802154.h
@@ -162,4 +162,26 @@ enum nl802154_cca_opts {
 	NL802154_CCA_OPT_ATTR_MAX = __NL802154_CCA_OPT_ATTR_AFTER_LAST - 1
 };
 
+/**
+ * enum nl802154_supported_bool_states - bool states for bool capability entry
+ *
+ * @NL802154_SUPPORTED_BOOL_FALSE: indicates to set false
+ * @NL802154_SUPPORTED_BOOL_TRUE: indicates to set true
+ * @__NL802154_SUPPORTED_BOOL_INVALD: reserved
+ * @NL802154_SUPPORTED_BOOL_BOTH: indicates to set true and false
+ * @__NL802154_SUPPORTED_BOOL_AFTER_LAST: Internal
+ * @NL802154_SUPPORTED_BOOL_MAX: highest value for bool states
+ */
+enum nl802154_supported_bool_states {
+	NL802154_SUPPORTED_BOOL_FALSE,
+	NL802154_SUPPORTED_BOOL_TRUE,
+	/* to handle them in a mask */
+	__NL802154_SUPPORTED_BOOL_INVALD,
+	NL802154_SUPPORTED_BOOL_BOTH,
+
+	/* keep last */
+	__NL802154_SUPPORTED_BOOL_AFTER_LAST,
+	NL802154_SUPPORTED_BOOL_MAX = __NL802154_SUPPORTED_BOOL_AFTER_LAST - 1
+};
+
 #endif /* __NL802154_H */
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
index d271879..fa0c404 100644
--- a/net/ieee802154/nl802154.c
+++ b/net/ieee802154/nl802154.c
@@ -642,7 +642,9 @@ static int nl802154_set_cca_mode(struct sk_buff *skb, struct genl_info *info)
 
 	cca.mode = nla_get_u32(info->attrs[NL802154_ATTR_CCA_MODE]);
 	/* checking 802.15.4 constraints */
-	if (cca.mode < NL802154_CCA_ENERGY || cca.mode > NL802154_CCA_ATTR_MAX)
+	if (cca.mode < NL802154_CCA_ENERGY ||
+	    cca.mode > NL802154_CCA_ATTR_MAX ||
+	    !(rdev->wpan_phy.supported.cca_modes & BIT(cca.mode)))
 		return -EINVAL;
 
 	if (cca.mode == NL802154_CCA_ENERGY_CARRIER) {
@@ -650,7 +652,8 @@ static int nl802154_set_cca_mode(struct sk_buff *skb, struct genl_info *info)
 			return -EINVAL;
 
 		cca.opt = nla_get_u32(info->attrs[NL802154_ATTR_CCA_OPT]);
-		if (cca.opt > NL802154_CCA_OPT_ATTR_MAX)
+		if (cca.opt > NL802154_CCA_OPT_ATTR_MAX ||
+		    !(rdev->wpan_phy.supported.cca_opts & BIT(cca.opt)))
 			return -EINVAL;
 	}
 
@@ -744,7 +747,11 @@ nl802154_set_backoff_exponent(struct sk_buff *skb, struct genl_info *info)
 	max_be = nla_get_u8(info->attrs[NL802154_ATTR_MAX_BE]);
 
 	/* check 802.15.4 constraints */
-	if (max_be < 3 || max_be > 8 || min_be > max_be)
+	if (min_be < rdev->wpan_phy.supported.min_minbe ||
+	    min_be > rdev->wpan_phy.supported.max_minbe ||
+	    max_be < rdev->wpan_phy.supported.min_maxbe ||
+	    max_be > rdev->wpan_phy.supported.max_maxbe ||
+	    min_be > max_be)
 		return -EINVAL;
 
 	return rdev_set_backoff_exponent(rdev, wpan_dev, min_be, max_be);
@@ -769,7 +776,8 @@ nl802154_set_max_csma_backoffs(struct sk_buff *skb, struct genl_info *info)
 			info->attrs[NL802154_ATTR_MAX_CSMA_BACKOFFS]);
 
 	/* check 802.15.4 constraints */
-	if (max_csma_backoffs > 5)
+	if (max_csma_backoffs < rdev->wpan_phy.supported.min_csma_backoffs ||
+	    max_csma_backoffs > rdev->wpan_phy.supported.max_csma_backoffs)
 		return -EINVAL;
 
 	return rdev_set_max_csma_backoffs(rdev, wpan_dev, max_csma_backoffs);
@@ -793,7 +801,8 @@ nl802154_set_max_frame_retries(struct sk_buff *skb, struct genl_info *info)
 			info->attrs[NL802154_ATTR_MAX_FRAME_RETRIES]);
 
 	/* check 802.15.4 constraints */
-	if (max_frame_retries < -1 || max_frame_retries > 7)
+	if (max_frame_retries < rdev->wpan_phy.supported.min_frame_retries ||
+	    max_frame_retries > rdev->wpan_phy.supported.max_frame_retries)
 		return -EINVAL;
 
 	return rdev_set_max_frame_retries(rdev, wpan_dev, max_frame_retries);
@@ -813,6 +822,9 @@ static int nl802154_set_lbt_mode(struct sk_buff *skb, struct genl_info *info)
 		return -EINVAL;
 
 	mode = !!nla_get_u8(info->attrs[NL802154_ATTR_LBT_MODE]);
+	if (!wpan_phy_supported_bool(mode, rdev->wpan_phy.supported.lbt))
+		return -EINVAL;
+
 	return rdev_set_lbt_mode(rdev, wpan_dev, mode);
 }
 
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
index 08cb32d..ddcd6ff 100644
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -107,6 +107,15 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
 
 	skb_queue_head_init(&local->skb_queue);
 
+	/* init supported flags with 802.15.4 default ranges */
+	phy->supported.max_minbe = 8;
+	phy->supported.min_maxbe = 3;
+	phy->supported.max_maxbe = 8;
+	phy->supported.min_frame_retries = -1;
+	phy->supported.max_frame_retries = 7;
+	phy->supported.max_csma_backoffs = 5;
+	phy->supported.lbt = NL802154_SUPPORTED_BOOL_FALSE;
+
 	return &local->hw;
 }
 EXPORT_SYMBOL(ieee802154_alloc_hw);
@@ -155,6 +164,23 @@ int ieee802154_register_hw(struct ieee802154_hw *hw)
 
 	ieee802154_setup_wpan_phy_pib(local->phy);
 
+	if (!(hw->flags & IEEE802154_HW_CSMA_PARAMS)) {
+		local->phy->supported.min_csma_backoffs = 4;
+		local->phy->supported.max_csma_backoffs = 4;
+		local->phy->supported.min_maxbe = 5;
+		local->phy->supported.max_maxbe = 5;
+		local->phy->supported.min_minbe = 3;
+		local->phy->supported.max_minbe = 3;
+	}
+
+	if (!(hw->flags & IEEE802154_HW_FRAME_RETRIES)) {
+		/* TODO should be 3, but our default value is -1 which means
+		 * no ARET handling.
+		 */
+		local->phy->supported.min_frame_retries = -1;
+		local->phy->supported.max_frame_retries = -1;
+	}
+
 	rc = wpan_phy_register(local->phy);
 	if (rc < 0)
 		goto out_wq;
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 08/34] mac802154: check for really changes
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (6 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 07/34] ieee802154: add several phy supported handling Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 09/34] mac802154: remove check if operation is supported Alexander Aring
                   ` (26 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch adds check if the value is really changed inside pib/mib.
If a transceiver do support only one value for e.g. max_be then this
will also handle that the driver layer doesn't need to care about
handling to set one value only.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 include/net/cfg802154.h | 12 ++++++++++++
 net/mac802154/cfg.c     | 26 ++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 23abd08..37abc16 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -94,6 +94,18 @@ struct wpan_phy_cca {
 	enum nl802154_cca_opts opt;
 };
 
+static inline bool
+wpan_phy_cca_cmp(const struct wpan_phy_cca *a, const struct wpan_phy_cca *b)
+{
+	if (a->mode != b->mode)
+		return false;
+
+	if (a->mode == NL802154_CCA_ENERGY_CARRIER)
+		return a->opt == b->opt;
+
+	return true;
+}
+
 struct wpan_phy {
 	struct mutex pib_lock;
 
diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c
index c636015..45c4dc3 100644
--- a/net/mac802154/cfg.c
+++ b/net/mac802154/cfg.c
@@ -73,6 +73,10 @@ ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel)
 
 	ASSERT_RTNL();
 
+	if (wpan_phy->current_page == page &&
+	    wpan_phy->current_channel == channel)
+		return 0;
+
 	ret = drv_set_channel(local, page, channel);
 	if (!ret) {
 		wpan_phy->current_page = page;
@@ -91,6 +95,9 @@ ieee802154_set_cca_mode(struct wpan_phy *wpan_phy,
 
 	ASSERT_RTNL();
 
+	if (wpan_phy_cca_cmp(&wpan_phy->cca, cca))
+		return 0;
+
 	/* check if phy support this setting */
 	if (!(local->hw.flags & IEEE802154_HW_CCA_MODE))
 		return -EOPNOTSUPP;
@@ -108,6 +115,9 @@ ieee802154_set_pan_id(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 {
 	ASSERT_RTNL();
 
+	if (wpan_dev->pan_id == pan_id)
+		return 0;
+
 	wpan_dev->pan_id = pan_id;
 	return 0;
 }
@@ -121,6 +131,10 @@ ieee802154_set_backoff_exponent(struct wpan_phy *wpan_phy,
 
 	ASSERT_RTNL();
 
+	if (wpan_dev->min_be == min_be &&
+	    wpan_dev->max_be == max_be)
+		return 0;
+
 	if (!(local->hw.flags & IEEE802154_HW_CSMA_PARAMS))
 		return -EOPNOTSUPP;
 
@@ -135,6 +149,9 @@ ieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 {
 	ASSERT_RTNL();
 
+	if (wpan_dev->short_addr == short_addr)
+		return 0;
+
 	wpan_dev->short_addr = short_addr;
 	return 0;
 }
@@ -148,6 +165,9 @@ ieee802154_set_max_csma_backoffs(struct wpan_phy *wpan_phy,
 
 	ASSERT_RTNL();
 
+	if (wpan_dev->csma_retries == max_csma_backoffs)
+		return 0;
+
 	if (!(local->hw.flags & IEEE802154_HW_CSMA_PARAMS))
 		return -EOPNOTSUPP;
 
@@ -164,6 +184,9 @@ ieee802154_set_max_frame_retries(struct wpan_phy *wpan_phy,
 
 	ASSERT_RTNL();
 
+	if (wpan_dev->frame_retries == max_frame_retries)
+		return 0;
+
 	if (!(local->hw.flags & IEEE802154_HW_FRAME_RETRIES))
 		return -EOPNOTSUPP;
 
@@ -179,6 +202,9 @@ ieee802154_set_lbt_mode(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 
 	ASSERT_RTNL();
 
+	if (wpan_dev->lbt == mode)
+		return 0;
+
 	if (!(local->hw.flags & IEEE802154_HW_LBT))
 		return -EOPNOTSUPP;
 
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 09/34] mac802154: remove check if operation is supported
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (7 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 08/34] mac802154: check for really changes Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 10/34] cfg802154: introduce wpan phy flags Alexander Aring
                   ` (25 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch removes the check if operation is supported by driver layer.
This is done now by capabilities flags, if these are valid then the
driver should support the operation, otherwise a WARN_ON occurs.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 net/mac802154/cfg.c | 24 ------------------------
 1 file changed, 24 deletions(-)

diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c
index 45c4dc3..d5290ea 100644
--- a/net/mac802154/cfg.c
+++ b/net/mac802154/cfg.c
@@ -98,10 +98,6 @@ ieee802154_set_cca_mode(struct wpan_phy *wpan_phy,
 	if (wpan_phy_cca_cmp(&wpan_phy->cca, cca))
 		return 0;
 
-	/* check if phy support this setting */
-	if (!(local->hw.flags & IEEE802154_HW_CCA_MODE))
-		return -EOPNOTSUPP;
-
 	ret = drv_set_cca_mode(local, cca);
 	if (!ret)
 		wpan_phy->cca = *cca;
@@ -127,17 +123,12 @@ ieee802154_set_backoff_exponent(struct wpan_phy *wpan_phy,
 				struct wpan_dev *wpan_dev,
 				u8 min_be, u8 max_be)
 {
-	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
-
 	ASSERT_RTNL();
 
 	if (wpan_dev->min_be == min_be &&
 	    wpan_dev->max_be == max_be)
 		return 0;
 
-	if (!(local->hw.flags & IEEE802154_HW_CSMA_PARAMS))
-		return -EOPNOTSUPP;
-
 	wpan_dev->min_be = min_be;
 	wpan_dev->max_be = max_be;
 	return 0;
@@ -161,16 +152,11 @@ ieee802154_set_max_csma_backoffs(struct wpan_phy *wpan_phy,
 				 struct wpan_dev *wpan_dev,
 				 u8 max_csma_backoffs)
 {
-	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
-
 	ASSERT_RTNL();
 
 	if (wpan_dev->csma_retries == max_csma_backoffs)
 		return 0;
 
-	if (!(local->hw.flags & IEEE802154_HW_CSMA_PARAMS))
-		return -EOPNOTSUPP;
-
 	wpan_dev->csma_retries = max_csma_backoffs;
 	return 0;
 }
@@ -180,16 +166,11 @@ ieee802154_set_max_frame_retries(struct wpan_phy *wpan_phy,
 				 struct wpan_dev *wpan_dev,
 				 s8 max_frame_retries)
 {
-	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
-
 	ASSERT_RTNL();
 
 	if (wpan_dev->frame_retries == max_frame_retries)
 		return 0;
 
-	if (!(local->hw.flags & IEEE802154_HW_FRAME_RETRIES))
-		return -EOPNOTSUPP;
-
 	wpan_dev->frame_retries = max_frame_retries;
 	return 0;
 }
@@ -198,16 +179,11 @@ static int
 ieee802154_set_lbt_mode(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 			bool mode)
 {
-	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
-
 	ASSERT_RTNL();
 
 	if (wpan_dev->lbt == mode)
 		return 0;
 
-	if (!(local->hw.flags & IEEE802154_HW_LBT))
-		return -EOPNOTSUPP;
-
 	wpan_dev->lbt = mode;
 	return 0;
 }
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 10/34] cfg802154: introduce wpan phy flags
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (8 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 09/34] mac802154: remove check if operation is supported Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 11/34] ieee802154: add iftypes capability Alexander Aring
                   ` (24 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch introduce a flag property for the wpan phy structure.
The current flag settings in ieee802154_hw are accessable in mac802154
layer only which is okay for flags which indicates MAC handling which
are done by phy. For real PHY layer settings like cca mode, transmit
power, cca energy detection level.

The difference between these flags are that the MAC handling flags are
only handled in mac802154/HardMac layer e.g. on an interface up. The phy
settings are direct netlink calls from nl802154 into the driver layer
and the nl802154 need to have a chance to check if the driver supports
this handling before sending to the next layer.

We also check now on PHY flags while dumping and setting pib attributes.
In comparing with MIB attributes the 802.15.4 gives us an default value
which we assume when a transceiver implement less functionality. In case
of MIB settings the nl802154 layer doesn't need to check on the
ieee802154_hw flags then.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/at86rf230.c |  9 +++++++--
 include/net/cfg802154.h            | 16 ++++++++++++++++
 include/net/mac802154.h            | 29 +++++++----------------------
 net/ieee802154/nl802154.c          | 27 +++++++++++++++++----------
 net/mac802154/mac_cmd.c            |  6 +++---
 5 files changed, 50 insertions(+), 37 deletions(-)

diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index 151d57f..b0ffd1c 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -1566,8 +1566,13 @@ at86rf230_detect_device(struct at86rf230_local *lp)
 	}
 
 	lp->hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AACK |
-			IEEE802154_HW_TXPOWER | IEEE802154_HW_ARET |
-			IEEE802154_HW_AFILT | IEEE802154_HW_PROMISCUOUS;
+			IEEE802154_HW_CSMA_PARAMS |
+			IEEE802154_HW_FRAME_RETRIES | IEEE802154_HW_AFILT |
+			IEEE802154_HW_PROMISCUOUS;
+
+	lp->hw->phy->flags = WPAN_PHY_FLAG_TXPOWER |
+			     WPAN_PHY_FLAG_CCA_ED_LEVEL |
+			     WPAN_PHY_FLAG_CCA_MODE;
 
 	lp->hw->phy->cca.mode = NL802154_CCA_ENERGY;
 
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 37abc16..a12c6c52 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -106,6 +106,20 @@ wpan_phy_cca_cmp(const struct wpan_phy_cca *a, const struct wpan_phy_cca *b)
 	return true;
 }
 
+/**
+ * @WPAN_PHY_FLAG_TRANSMIT_POWER: Indicates that transceiver will support
+ *	transmit power setting.
+ * @WPAN_PHY_FLAG_CCA_ED_LEVEL: Indicates that transceiver will support cca ed
+ *	level setting.
+ * @WPAN_PHY_FLAG_CCA_MODE: Indicates that transceiver will support cca mode
+ *	setting.
+ */
+enum wpan_phy_flags {
+	WPAN_PHY_FLAG_TXPOWER		= BIT(1),
+	WPAN_PHY_FLAG_CCA_ED_LEVEL	= BIT(2),
+	WPAN_PHY_FLAG_CCA_MODE		= BIT(3),
+};
+
 struct wpan_phy {
 	struct mutex pib_lock;
 
@@ -117,6 +131,8 @@ struct wpan_phy {
 	 */
 	const void *privid;
 
+	u32 flags;
+
 	/*
 	 * This is a PIB according to 802.15.4-2011.
 	 * We do not provide timing-related variables, as they
diff --git a/include/net/mac802154.h b/include/net/mac802154.h
index 71e2456..9605c7f 100644
--- a/include/net/mac802154.h
+++ b/include/net/mac802154.h
@@ -89,41 +89,26 @@ struct ieee802154_hw {
 #define IEEE802154_HW_TX_OMIT_CKSUM	0x00000001
 /* Indicates that receiver will autorespond with ACK frames. */
 #define IEEE802154_HW_AACK		0x00000002
-/* Indicates that transceiver will support transmit power setting. */
-#define IEEE802154_HW_TXPOWER		0x00000004
 /* Indicates that transceiver will support listen before transmit. */
-#define IEEE802154_HW_LBT		0x00000008
-/* Indicates that transceiver will support cca mode setting. */
-#define IEEE802154_HW_CCA_MODE		0x00000010
-/* Indicates that transceiver will support cca ed level setting. */
-#define IEEE802154_HW_CCA_ED_LEVEL	0x00000020
+#define IEEE802154_HW_LBT		0x00000004
 /* Indicates that transceiver will support csma (max_be, min_be, csma retries)
  * settings. */
-#define IEEE802154_HW_CSMA_PARAMS	0x00000040
+#define IEEE802154_HW_CSMA_PARAMS	0x00000008
 /* Indicates that transceiver will support ARET frame retries setting. */
-#define IEEE802154_HW_FRAME_RETRIES	0x00000080
+#define IEEE802154_HW_FRAME_RETRIES	0x00000010
 /* Indicates that transceiver will support hardware address filter setting. */
-#define IEEE802154_HW_AFILT		0x00000100
+#define IEEE802154_HW_AFILT		0x00000020
 /* Indicates that transceiver will support promiscuous mode setting. */
-#define IEEE802154_HW_PROMISCUOUS	0x00000200
+#define IEEE802154_HW_PROMISCUOUS	0x00000040
 /* Indicates that receiver omits FCS. */
-#define IEEE802154_HW_RX_OMIT_CKSUM	0x00000400
+#define IEEE802154_HW_RX_OMIT_CKSUM	0x00000080
 /* Indicates that receiver will not filter frames with bad checksum. */
-#define IEEE802154_HW_RX_DROP_BAD_CKSUM	0x00000800
+#define IEEE802154_HW_RX_DROP_BAD_CKSUM	0x00000100
 
 /* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */
 #define IEEE802154_HW_OMIT_CKSUM	(IEEE802154_HW_TX_OMIT_CKSUM | \
 					 IEEE802154_HW_RX_OMIT_CKSUM)
 
-/* This groups the most common CSMA support fields into one. */
-#define IEEE802154_HW_CSMA		(IEEE802154_HW_CCA_MODE | \
-					 IEEE802154_HW_CCA_ED_LEVEL | \
-					 IEEE802154_HW_CSMA_PARAMS)
-
-/* This groups the most common ARET support fields into one. */
-#define IEEE802154_HW_ARET		(IEEE802154_HW_CSMA | \
-					 IEEE802154_HW_FRAME_RETRIES)
-
 /* struct ieee802154_ops - callbacks from mac802154 to the driver
  *
  * This structure contains various callbacks that the driver may
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
index fa0c404..40fb0be 100644
--- a/net/ieee802154/nl802154.c
+++ b/net/ieee802154/nl802154.c
@@ -291,19 +291,23 @@ static int nl802154_send_wpan_phy(struct cfg802154_registered_device *rdev,
 		goto nla_put_failure;
 
 	/* cca mode */
-	if (nla_put_u32(msg, NL802154_ATTR_CCA_MODE,
-			rdev->wpan_phy.cca.mode))
-		goto nla_put_failure;
-
-	if (rdev->wpan_phy.cca.mode == NL802154_CCA_ENERGY_CARRIER) {
-		if (nla_put_u32(msg, NL802154_ATTR_CCA_OPT,
-				rdev->wpan_phy.cca.opt))
+	if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE) {
+		if (nla_put_u32(msg, NL802154_ATTR_CCA_MODE,
+				rdev->wpan_phy.cca.mode))
 			goto nla_put_failure;
+
+		if (rdev->wpan_phy.cca.mode == NL802154_CCA_ENERGY_CARRIER) {
+			if (nla_put_u32(msg, NL802154_ATTR_CCA_OPT,
+					rdev->wpan_phy.cca.opt))
+				goto nla_put_failure;
+		}
 	}
 
-	if (nla_put_s32(msg, NL802154_ATTR_TX_POWER,
-			rdev->wpan_phy.transmit_power))
-		goto nla_put_failure;
+	if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER) {
+		if (nla_put_s32(msg, NL802154_ATTR_TX_POWER,
+				rdev->wpan_phy.transmit_power))
+			goto nla_put_failure;
+	}
 
 finish:
 	genlmsg_end(msg, hdr);
@@ -637,6 +641,9 @@ static int nl802154_set_cca_mode(struct sk_buff *skb, struct genl_info *info)
 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
 	struct wpan_phy_cca cca;
 
+	if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE)
+		return -EOPNOTSUPP;
+
 	if (!info->attrs[NL802154_ATTR_CCA_MODE])
 		return -EINVAL;
 
diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c
index bdccb4e..6dcbb3b 100644
--- a/net/mac802154/mac_cmd.c
+++ b/net/mac802154/mac_cmd.c
@@ -91,19 +91,19 @@ static int mac802154_set_mac_params(struct net_device *dev,
 	wpan_dev->frame_retries = params->frame_retries;
 	wpan_dev->lbt = params->lbt;
 
-	if (local->hw.flags & IEEE802154_HW_TXPOWER) {
+	if (local->hw.phy->flags & WPAN_PHY_FLAG_TXPOWER) {
 		ret = drv_set_tx_power(local, params->transmit_power);
 		if (ret < 0)
 			return ret;
 	}
 
-	if (local->hw.flags & IEEE802154_HW_CCA_MODE) {
+	if (local->hw.phy->flags & WPAN_PHY_FLAG_CCA_MODE) {
 		ret = drv_set_cca_mode(local, &params->cca);
 		if (ret < 0)
 			return ret;
 	}
 
-	if (local->hw.flags & IEEE802154_HW_CCA_ED_LEVEL) {
+	if (local->hw.phy->flags & WPAN_PHY_FLAG_CCA_ED_LEVEL) {
 		ret = drv_set_cca_ed_level(local, params->cca_ed_level);
 		if (ret < 0)
 			return ret;
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 11/34] ieee802154: add iftypes capability
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (9 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 10/34] cfg802154: introduce wpan phy flags Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 12/34] at86rf230: set cca_modes supported flags Alexander Aring
                   ` (23 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch adds capability flags for supported interface types.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 include/net/cfg802154.h   | 2 +-
 net/ieee802154/nl802154.c | 3 ++-
 net/mac802154/main.c      | 6 ++++++
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index a12c6c52..11bbf17 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -80,7 +80,7 @@ wpan_phy_supported_bool(bool b, enum nl802154_supported_bool_states st)
 
 struct wpan_phy_supported {
 	u32 channels[IEEE802154_MAX_PAGE + 1],
-	    cca_modes, cca_opts;
+	    cca_modes, cca_opts, iftypes;
 	enum nl802154_supported_bool_states lbt;
 	u8 min_minbe, max_minbe, min_maxbe, max_maxbe,
 	   min_csma_backoffs, max_csma_backoffs;
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
index 40fb0be..3afb20e 100644
--- a/net/ieee802154/nl802154.c
+++ b/net/ieee802154/nl802154.c
@@ -579,7 +579,8 @@ static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info)
 
 	if (info->attrs[NL802154_ATTR_IFTYPE]) {
 		type = nla_get_u32(info->attrs[NL802154_ATTR_IFTYPE]);
-		if (type > NL802154_IFTYPE_MAX)
+		if (type > NL802154_IFTYPE_MAX ||
+		    !(rdev->wpan_phy.supported.iftypes & BIT(type)))
 			return -EINVAL;
 	}
 
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
index ddcd6ff..356b346 100644
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -116,6 +116,9 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
 	phy->supported.max_csma_backoffs = 5;
 	phy->supported.lbt = NL802154_SUPPORTED_BOOL_FALSE;
 
+	/* always supported */
+	phy->supported.iftypes = BIT(NL802154_IFTYPE_NODE);
+
 	return &local->hw;
 }
 EXPORT_SYMBOL(ieee802154_alloc_hw);
@@ -181,6 +184,9 @@ int ieee802154_register_hw(struct ieee802154_hw *hw)
 		local->phy->supported.max_frame_retries = -1;
 	}
 
+	if (hw->flags & IEEE802154_HW_PROMISCUOUS)
+		local->phy->supported.iftypes |= BIT(NL802154_IFTYPE_MONITOR);
+
 	rc = wpan_phy_register(local->phy);
 	if (rc < 0)
 		goto out_wq;
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 12/34] at86rf230: set cca_modes supported flags
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (10 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 11/34] ieee802154: add iftypes capability Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 13/34] at86rf230: rework tx power support Alexander Aring
                   ` (22 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch sets the at86rf230 supported cca modes. In case of at86rf212
it also can support listen before transmit.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/at86rf230.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index b0ffd1c..fabde3a 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -1574,6 +1574,11 @@ at86rf230_detect_device(struct at86rf230_local *lp)
 			     WPAN_PHY_FLAG_CCA_ED_LEVEL |
 			     WPAN_PHY_FLAG_CCA_MODE;
 
+	lp->hw->phy->supported.cca_modes = BIT(NL802154_CCA_ENERGY) |
+		BIT(NL802154_CCA_CARRIER) | BIT(NL802154_CCA_ENERGY_CARRIER);
+	lp->hw->phy->supported.cca_opts = BIT(NL802154_CCA_OPT_ENERGY_CARRIER_AND) |
+		BIT(NL802154_CCA_OPT_ENERGY_CARRIER_OR);
+
 	lp->hw->phy->cca.mode = NL802154_CCA_ENERGY;
 
 	switch (part) {
@@ -1596,6 +1601,7 @@ at86rf230_detect_device(struct at86rf230_local *lp)
 		lp->hw->phy->supported.channels[2] = 0x00007FF;
 		lp->hw->phy->current_channel = 5;
 		lp->hw->phy->symbol_duration = 25;
+		lp->hw->phy->supported.lbt = NL802154_SUPPORTED_BOOL_BOTH;
 		break;
 	case 11:
 		chip = "at86rf233";
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 13/34] at86rf230: rework tx power support
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (11 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 12/34] at86rf230: set cca_modes supported flags Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 14/34] at86rf230: rework tx cca energy detection level Alexander Aring
                   ` (21 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch adds support for get transmit power levels and reworks the
set of transmit power levels which was broken before.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/at86rf230.c | 83 +++++++++++++++++++++++++++++---------
 1 file changed, 64 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index fabde3a..dff7e47 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -51,6 +51,7 @@ struct at86rf2xx_chip_data {
 
 	int (*set_channel)(struct at86rf230_local *, u8, u8);
 	int (*get_desense_steps)(struct at86rf230_local *, s32);
+	int (*set_txpower)(struct at86rf230_local *, s32);
 };
 
 #define AT86RF2XX_MAX_BUF		(127 + 3)
@@ -124,9 +125,12 @@ struct at86rf230_local {
 #define SR_IRQ_2_EXT_EN		0x04, 0x40, 6
 #define SR_PA_EXT_EN		0x04, 0x80, 7
 #define RG_PHY_TX_PWR	(0x05)
-#define SR_TX_PWR		0x05, 0x0f, 0
-#define SR_PA_LT		0x05, 0x30, 4
-#define SR_PA_BUF_LT		0x05, 0xc0, 6
+#define SR_TX_PWR_23X		0x05, 0x0f, 0
+#define SR_PA_LT_230		0x05, 0x30, 4
+#define SR_PA_BUF_LT_230	0x05, 0xc0, 6
+#define SR_TX_PWR_212		0x05, 0x1f, 0
+#define SR_GC_PA_212		0x05, 0x60, 5
+#define SR_PA_BOOST_LT_212	0x05, 0x80, 7
 #define RG_PHY_RSSI	(0x06)
 #define SR_RSSI			0x06, 0x1f, 0
 #define SR_RND_VALUE		0x06, 0x60, 5
@@ -1193,24 +1197,56 @@ at86rf230_set_hw_addr_filt(struct ieee802154_hw *hw,
 	return 0;
 }
 
+#define AT86RF23X_MAX_TX_POWERS 0xF
+static const s32 at86rf233_powers[AT86RF23X_MAX_TX_POWERS + 1] = {
+	400, 370, 340, 300, 250, 200, 100, 0, -100, -200, -300, -400, -600,
+	-800, -1200, -1700,
+};
+
+static const s32 at86rf231_powers[AT86RF23X_MAX_TX_POWERS + 1] = {
+	300, 280, 230, 180, 130, 70, 0, -100, -200, -300, -400, -500, -700,
+	-900, -1200, -1700,
+};
+
+#define AT86RF212_MAX_TX_POWERS 0x1F
+static const s32 at86rf212_powers[AT86RF212_MAX_TX_POWERS + 1] = {
+	500, 400, 300, 200, 100, 0, -100, -200, -300, -400, -500, -600, -700,
+	-800, -900, -1000, -1100, -1200, -1300, -1400, -1500, -1600, -1700,
+	-1800, -1900, -2000, -2100, -2200, -2300, -2400, -2500, -2600,
+};
+
 static int
-at86rf230_set_txpower(struct ieee802154_hw *hw, s32 mbm)
+at86rf23x_set_txpower(struct at86rf230_local *lp, s32 mbm)
 {
-	struct at86rf230_local *lp = hw->priv;
-	s8 db = mbm / 100;
+	u32 i;
 
-	/* typical maximum output is 5dBm with RG_PHY_TX_PWR 0x60, lower five
-	 * bits decrease power in 1dB steps. 0x60 represents extra PA gain of
-	 * 0dB.
-	 * thus, supported values for db range from -26 to 5, for 31dB of
-	 * reduction to 0dB of reduction.
-	 */
-	if (db > 5 || db < -26)
-		return -EINVAL;
+	for (i = 0; i < lp->hw->phy->supported.tx_powers_size; i++) {
+		if (lp->hw->phy->supported.tx_powers[i] == mbm)
+			return at86rf230_write_subreg(lp, SR_TX_PWR_23X, i);
+	}
+
+	return -EINVAL;
+}
+
+static int
+at86rf212_set_txpower(struct at86rf230_local *lp, s32 mbm)
+{
+	u32 i;
+
+	for (i = 0; i < lp->hw->phy->supported.tx_powers_size; i++) {
+		if (lp->hw->phy->supported.tx_powers[i] == mbm)
+			return at86rf230_write_subreg(lp, SR_TX_PWR_212, i);
+	}
 
-	db = -(db - 5);
+	return -EINVAL;
+}
+
+static int
+at86rf230_set_txpower(struct ieee802154_hw *hw, s32 mbm)
+{
+	struct at86rf230_local *lp = hw->priv;
 
-	return __at86rf230_write(lp, RG_PHY_TX_PWR, 0x60 | db);
+	return lp->data->set_txpower(lp, mbm);
 }
 
 static int
@@ -1367,7 +1403,8 @@ static struct at86rf2xx_chip_data at86rf233_data = {
 	.t_p_ack = 545,
 	.rssi_base_val = -91,
 	.set_channel = at86rf23x_set_channel,
-	.get_desense_steps = at86rf23x_get_desens_steps
+	.get_desense_steps = at86rf23x_get_desens_steps,
+	.set_txpower = at86rf23x_set_txpower,
 };
 
 static struct at86rf2xx_chip_data at86rf231_data = {
@@ -1380,7 +1417,8 @@ static struct at86rf2xx_chip_data at86rf231_data = {
 	.t_p_ack = 545,
 	.rssi_base_val = -91,
 	.set_channel = at86rf23x_set_channel,
-	.get_desense_steps = at86rf23x_get_desens_steps
+	.get_desense_steps = at86rf23x_get_desens_steps,
+	.set_txpower = at86rf23x_set_txpower,
 };
 
 static struct at86rf2xx_chip_data at86rf212_data = {
@@ -1393,7 +1431,8 @@ static struct at86rf2xx_chip_data at86rf212_data = {
 	.t_p_ack = 545,
 	.rssi_base_val = -100,
 	.set_channel = at86rf212_set_channel,
-	.get_desense_steps = at86rf212_get_desens_steps
+	.get_desense_steps = at86rf212_get_desens_steps,
+	.set_txpower = at86rf212_set_txpower,
 };
 
 static int at86rf230_hw_init(struct at86rf230_local *lp, u8 xtal_trim)
@@ -1592,6 +1631,8 @@ at86rf230_detect_device(struct at86rf230_local *lp)
 		lp->hw->phy->supported.channels[0] = 0x7FFF800;
 		lp->hw->phy->current_channel = 11;
 		lp->hw->phy->symbol_duration = 16;
+		lp->hw->phy->supported.tx_powers = at86rf231_powers;
+		lp->hw->phy->supported.tx_powers_size = ARRAY_SIZE(at86rf231_powers);
 		break;
 	case 7:
 		chip = "at86rf212";
@@ -1602,6 +1643,8 @@ at86rf230_detect_device(struct at86rf230_local *lp)
 		lp->hw->phy->current_channel = 5;
 		lp->hw->phy->symbol_duration = 25;
 		lp->hw->phy->supported.lbt = NL802154_SUPPORTED_BOOL_BOTH;
+		lp->hw->phy->supported.tx_powers = at86rf212_powers;
+		lp->hw->phy->supported.tx_powers_size = ARRAY_SIZE(at86rf212_powers);
 		break;
 	case 11:
 		chip = "at86rf233";
@@ -1609,6 +1652,8 @@ at86rf230_detect_device(struct at86rf230_local *lp)
 		lp->hw->phy->supported.channels[0] = 0x7FFF800;
 		lp->hw->phy->current_channel = 13;
 		lp->hw->phy->symbol_duration = 16;
+		lp->hw->phy->supported.tx_powers = at86rf233_powers;
+		lp->hw->phy->supported.tx_powers_size = ARRAY_SIZE(at86rf233_powers);
 		break;
 	default:
 		chip = "unknown";
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 14/34] at86rf230: rework tx cca energy detection level
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (12 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 13/34] at86rf230: rework tx power support Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 15/34] at86rf230: add cca ed level reset value Alexander Aring
                   ` (20 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch reworks the cca energy detection level handling. This
contains a calculation which works on all transceiver types and
add support for dump cca energy detection levels.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/at86rf230.c | 79 ++++++++++++++++++++++++++++----------
 1 file changed, 59 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index dff7e47..833c426 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -50,7 +50,6 @@ struct at86rf2xx_chip_data {
 	int rssi_base_val;
 
 	int (*set_channel)(struct at86rf230_local *, u8, u8);
-	int (*get_desense_steps)(struct at86rf230_local *, s32);
 	int (*set_txpower)(struct at86rf230_local *, s32);
 };
 
@@ -1080,6 +1079,50 @@ at86rf23x_set_channel(struct at86rf230_local *lp, u8 page, u8 channel)
 	return at86rf230_write_subreg(lp, SR_CHANNEL, channel);
 }
 
+#define AT86RF2XX_MAX_ED_LEVELS 0xF
+static const s32 at86rf23x_ed_levels[AT86RF2XX_MAX_ED_LEVELS + 1] = {
+	-9100, -8900, -8700, -8500, -8300, -8100, -7900, -7700, -7500, -7300,
+	-7100, -6900, -6700, -6500, -6300, -6100,
+};
+
+static const s32 at86rf212_ed_levels_100[AT86RF2XX_MAX_ED_LEVELS + 1] = {
+	-10000, -9800, -9600, -9400, -9200, -9000, -8800, -8600, -8400, -8200,
+	-8000, -7800, -7600, -7400, -7200,
+};
+
+static const s32 at86rf212_ed_levels_98[AT86RF2XX_MAX_ED_LEVELS + 1] = {
+	-9800, -9600, -9400, -9200, -9000, -8800, -8600, -8400, -8200, -8000,
+	-7800, -7600, -7400, -7200, -7000,
+};
+
+static inline int
+at86rf212_update_cca_ed_level(struct at86rf230_local *lp, int rssi_base_val)
+{
+	unsigned int cca_ed_thres;
+	int rc;
+
+	rc = at86rf230_read_subreg(lp, SR_CCA_ED_THRES, &cca_ed_thres);
+	if (rc < 0)
+		return rc;
+
+	switch (rssi_base_val) {
+	case -98:
+		lp->hw->phy->supported.cca_ed_levels = at86rf212_ed_levels_98;
+		lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf212_ed_levels_98);
+		lp->hw->phy->cca_ed_level = at86rf212_ed_levels_98[cca_ed_thres];
+		break;
+	case -100:
+		lp->hw->phy->supported.cca_ed_levels = at86rf212_ed_levels_100;
+		lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf212_ed_levels_100);
+		lp->hw->phy->cca_ed_level = at86rf212_ed_levels_100[cca_ed_thres];
+		break;
+	default:
+		WARN_ON(1);
+	}
+
+	return 0;
+}
+
 static int
 at86rf212_set_channel(struct at86rf230_local *lp, u8 page, u8 channel)
 {
@@ -1102,6 +1145,10 @@ at86rf212_set_channel(struct at86rf230_local *lp, u8 page, u8 channel)
 	if (rc < 0)
 		return rc;
 
+	rc = at86rf212_update_cca_ed_level(lp, lp->data->rssi_base_val);
+	if (rc < 0)
+		return rc;
+
 	/* This sets the symbol_duration according frequency on the 212.
 	 * TODO move this handling while set channel and page in cfg802154.
 	 * We can do that, this timings are according 802.15.4 standard.
@@ -1291,29 +1338,19 @@ at86rf230_set_cca_mode(struct ieee802154_hw *hw,
 	return at86rf230_write_subreg(lp, SR_CCA_MODE, val);
 }
 
-static int
-at86rf212_get_desens_steps(struct at86rf230_local *lp, s32 level)
-{
-	return (level - lp->data->rssi_base_val) * 100 / 207;
-}
-
-static int
-at86rf23x_get_desens_steps(struct at86rf230_local *lp, s32 level)
-{
-	return (level - lp->data->rssi_base_val) / 2;
-}
 
 static int
 at86rf230_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm)
 {
 	struct at86rf230_local *lp = hw->priv;
-	s32 level = mbm / 100;
+	u32 i;
 
-	if (level < lp->data->rssi_base_val || level > 30)
-		return -EINVAL;
+	for (i = 0; i < hw->phy->supported.cca_ed_levels_size; i++) {
+		if (hw->phy->supported.cca_ed_levels[i] == mbm)
+			return at86rf230_write_subreg(lp, SR_CCA_ED_THRES, i);
+	}
 
-	return at86rf230_write_subreg(lp, SR_CCA_ED_THRES,
-				      lp->data->get_desense_steps(lp, level));
+	return -EINVAL;
 }
 
 static int
@@ -1403,7 +1440,6 @@ static struct at86rf2xx_chip_data at86rf233_data = {
 	.t_p_ack = 545,
 	.rssi_base_val = -91,
 	.set_channel = at86rf23x_set_channel,
-	.get_desense_steps = at86rf23x_get_desens_steps,
 	.set_txpower = at86rf23x_set_txpower,
 };
 
@@ -1417,7 +1453,6 @@ static struct at86rf2xx_chip_data at86rf231_data = {
 	.t_p_ack = 545,
 	.rssi_base_val = -91,
 	.set_channel = at86rf23x_set_channel,
-	.get_desense_steps = at86rf23x_get_desens_steps,
 	.set_txpower = at86rf23x_set_txpower,
 };
 
@@ -1431,7 +1466,6 @@ static struct at86rf2xx_chip_data at86rf212_data = {
 	.t_p_ack = 545,
 	.rssi_base_val = -100,
 	.set_channel = at86rf212_set_channel,
-	.get_desense_steps = at86rf212_get_desens_steps,
 	.set_txpower = at86rf212_set_txpower,
 };
 
@@ -1618,6 +1652,9 @@ at86rf230_detect_device(struct at86rf230_local *lp)
 	lp->hw->phy->supported.cca_opts = BIT(NL802154_CCA_OPT_ENERGY_CARRIER_AND) |
 		BIT(NL802154_CCA_OPT_ENERGY_CARRIER_OR);
 
+	lp->hw->phy->supported.cca_ed_levels = at86rf23x_ed_levels;
+	lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf23x_ed_levels);
+
 	lp->hw->phy->cca.mode = NL802154_CCA_ENERGY;
 
 	switch (part) {
@@ -1645,6 +1682,8 @@ at86rf230_detect_device(struct at86rf230_local *lp)
 		lp->hw->phy->supported.lbt = NL802154_SUPPORTED_BOOL_BOTH;
 		lp->hw->phy->supported.tx_powers = at86rf212_powers;
 		lp->hw->phy->supported.tx_powers_size = ARRAY_SIZE(at86rf212_powers);
+		lp->hw->phy->supported.cca_ed_levels = at86rf212_ed_levels_100;
+		lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf212_ed_levels_100);
 		break;
 	case 11:
 		chip = "at86rf233";
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 15/34] at86rf230: add cca ed level reset value
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (13 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 14/34] at86rf230: rework tx cca energy detection level Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 16/34] at86rf230: add reset states of tx power level Alexander Aring
                   ` (19 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch adds reset values for cca ed level values after running reset
procedure.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/at86rf230.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index 833c426..3aa7bc9 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -1661,7 +1661,7 @@ at86rf230_detect_device(struct at86rf230_local *lp)
 	case 2:
 		chip = "at86rf230";
 		rc = -ENOTSUPP;
-		break;
+		goto not_supp;
 	case 3:
 		chip = "at86rf231";
 		lp->data = &at86rf231_data;
@@ -1697,9 +1697,12 @@ at86rf230_detect_device(struct at86rf230_local *lp)
 	default:
 		chip = "unknown";
 		rc = -ENOTSUPP;
-		break;
+		goto not_supp;
 	}
 
+	lp->hw->phy->cca_ed_level = lp->hw->phy->supported.cca_ed_levels[7];
+
+not_supp:
 	dev_info(&lp->spi->dev, "Detected %s chip version %d\n", chip, version);
 
 	return rc;
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 16/34] at86rf230: add reset states of tx power level
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (14 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 15/34] at86rf230: add cca ed level reset value Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 17/34] nl802154: add support for dump phy capabilities Alexander Aring
                   ` (18 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch adds the reset states for tx power levels after running reset
procedure.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/at86rf230.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index 3aa7bc9..5601c74 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -1701,6 +1701,7 @@ at86rf230_detect_device(struct at86rf230_local *lp)
 	}
 
 	lp->hw->phy->cca_ed_level = lp->hw->phy->supported.cca_ed_levels[7];
+	lp->hw->phy->transmit_power = lp->hw->phy->supported.tx_powers[0];
 
 not_supp:
 	dev_info(&lp->spi->dev, "Detected %s chip version %d\n", chip, version);
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 17/34] nl802154: add support for dump phy capabilities
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (15 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 16/34] at86rf230: add reset states of tx power level Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 18/34] mac802154: fakelb: Fix potential NULL pointer dereference Alexander Aring
                   ` (17 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch add support to nl802154 to dump all phy capabilities which is
inside the wpan_phy_supported struct. Also we introduce a new method to
dumping supported channels. The new method will offer a easier interface
and has lesser netlink traffic.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 include/net/nl802154.h    |  57 ++++++++++++++++++++++
 net/ieee802154/nl802154.c | 117 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 173 insertions(+), 1 deletion(-)

diff --git a/include/net/nl802154.h b/include/net/nl802154.h
index 0552771..0badebd 100644
--- a/include/net/nl802154.h
+++ b/include/net/nl802154.h
@@ -100,6 +100,8 @@ enum nl802154_attrs {
 
 	NL802154_ATTR_EXTENDED_ADDR,
 
+	NL802154_ATTR_WPAN_PHY_CAPS,
+
 	/* add attributes here, update the policy in nl802154.c */
 
 	__NL802154_ATTR_AFTER_LAST,
@@ -120,6 +122,61 @@ enum nl802154_iftype {
 };
 
 /**
+ * enum nl802154_wpan_phy_capability_attr - wpan phy capability attributes
+ *
+ * @__NL802154_CAP_ATTR_INVALID: attribute number 0 is reserved
+ * @NL802154_CAP_ATTR_CHANNELS: a nested attribute for nl802154_channel_attr
+ * @NL802154_CAP_ATTR_TX_POWERS: a nested attribute for
+ *	nl802154_wpan_phy_tx_power
+ * @NL802154_CAP_ATTR_MIN_CCA_ED_LEVEL: minimum value for cca_ed_level
+ * @NL802154_CAP_ATTR_MAX_CCA_ED_LEVEL: maxmimum value for cca_ed_level
+ * @NL802154_CAP_ATTR_CCA_MODES: nl802154_cca_modes flags
+ * @NL802154_CAP_ATTR_CCA_OPTS: nl802154_cca_opts flags
+ * @NL802154_CAP_ATTR_MIN_MINBE: minimum of minbe value
+ * @NL802154_CAP_ATTR_MAX_MINBE: maximum of minbe value
+ * @NL802154_CAP_ATTR_MIN_MAXBE: minimum of maxbe value
+ * @NL802154_CAP_ATTR_MAX_MINBE: maximum of maxbe value
+ * @NL802154_CAP_ATTR_MIN_CSMA_BACKOFFS: minimum of csma backoff value
+ * @NL802154_CAP_ATTR_MAX_CSMA_BACKOFFS: maximum of csma backoffs value
+ * @NL802154_CAP_ATTR_MIN_FRAME_RETRIES: minimum of frame retries value
+ * @NL802154_CAP_ATTR_MAX_FRAME_RETRIES: maximum of frame retries value
+ * @NL802154_CAP_ATTR_IFTYPES: nl802154_iftype flags
+ * @NL802154_CAP_ATTR_LBT: nl802154_supported_bool_states flags
+ * @NL802154_CAP_ATTR_MAX: highest cap attribute currently defined
+ * @__NL802154_CAP_ATTR_AFTER_LAST: internal use
+ */
+enum nl802154_wpan_phy_capability_attr {
+	__NL802154_CAP_ATTR_INVALID,
+
+	NL802154_CAP_ATTR_IFTYPES,
+
+	NL802154_CAP_ATTR_CHANNELS,
+	NL802154_CAP_ATTR_TX_POWERS,
+
+	NL802154_CAP_ATTR_CCA_ED_LEVELS,
+	NL802154_CAP_ATTR_CCA_MODES,
+	NL802154_CAP_ATTR_CCA_OPTS,
+
+	NL802154_CAP_ATTR_MIN_MINBE,
+	NL802154_CAP_ATTR_MAX_MINBE,
+
+	NL802154_CAP_ATTR_MIN_MAXBE,
+	NL802154_CAP_ATTR_MAX_MAXBE,
+
+	NL802154_CAP_ATTR_MIN_CSMA_BACKOFFS,
+	NL802154_CAP_ATTR_MAX_CSMA_BACKOFFS,
+
+	NL802154_CAP_ATTR_MIN_FRAME_RETRIES,
+	NL802154_CAP_ATTR_MAX_FRAME_RETRIES,
+
+	NL802154_CAP_ATTR_LBT,
+
+	/* keep last */
+	__NL802154_CAP_ATTR_AFTER_LAST,
+	NL802154_CAP_ATTR_MAX = __NL802154_CAP_ATTR_AFTER_LAST - 1
+};
+
+/**
  * enum nl802154_cca_modes - cca modes
  *
  * @__NL802154_CCA_INVALID: cca mode number 0 is reserved
diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
index 3afb20e..54f4959 100644
--- a/net/ieee802154/nl802154.c
+++ b/net/ieee802154/nl802154.c
@@ -225,6 +225,8 @@ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = {
 	[NL802154_ATTR_MAX_FRAME_RETRIES] = { .type = NLA_S8, },
 
 	[NL802154_ATTR_LBT_MODE] = { .type = NLA_U8, },
+
+	[NL802154_ATTR_WPAN_PHY_CAPS] = { .type = NLA_NESTED },
 };
 
 /* message building helper */
@@ -236,6 +238,28 @@ static inline void *nl802154hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
 }
 
 static int
+nl802154_put_flags(struct sk_buff *msg, int attr, u32 mask)
+{
+	struct nlattr *nl_flags = nla_nest_start(msg, attr);
+	int i;
+
+	if (!nl_flags)
+		return -ENOBUFS;
+
+	i = 0;
+	while (mask) {
+		if ((mask & 1) && nla_put_flag(msg, i))
+			return -ENOBUFS;
+
+		mask >>= 1;
+		i++;
+	}
+
+	nla_nest_end(msg, nl_flags);
+	return 0;
+}
+
+static int
 nl802154_send_wpan_phy_channels(struct cfg802154_registered_device *rdev,
 				struct sk_buff *msg)
 {
@@ -256,6 +280,92 @@ nl802154_send_wpan_phy_channels(struct cfg802154_registered_device *rdev,
 	return 0;
 }
 
+static int
+nl802154_put_capabilities(struct sk_buff *msg,
+			  struct cfg802154_registered_device *rdev)
+{
+	const struct wpan_phy_supported *caps = &rdev->wpan_phy.supported;
+	struct nlattr *nl_caps, *nl_channels;
+	int i;
+
+	nl_caps = nla_nest_start(msg, NL802154_ATTR_WPAN_PHY_CAPS);
+	if (!nl_caps)
+		return -ENOBUFS;
+
+	nl_channels = nla_nest_start(msg, NL802154_CAP_ATTR_CHANNELS);
+	if (!nl_channels)
+		return -ENOBUFS;
+
+	for (i = 0; i <= IEEE802154_MAX_PAGE; i++) {
+		if (caps->channels[i]) {
+			if (nl802154_put_flags(msg, i, caps->channels[i]))
+				return -ENOBUFS;
+		}
+	}
+
+	nla_nest_end(msg, nl_channels);
+
+	if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_ED_LEVEL) {
+		struct nlattr *nl_ed_lvls;
+
+		nl_ed_lvls = nla_nest_start(msg,
+					    NL802154_CAP_ATTR_CCA_ED_LEVELS);
+		if (!nl_ed_lvls)
+			return -ENOBUFS;
+
+		for (i = 0; i < caps->cca_ed_levels_size; i++) {
+			if (nla_put_s32(msg, i, caps->cca_ed_levels[i]))
+				return -ENOBUFS;
+		}
+
+		nla_nest_end(msg, nl_ed_lvls);
+	}
+
+	if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER) {
+		struct nlattr *nl_tx_pwrs;
+
+		nl_tx_pwrs = nla_nest_start(msg, NL802154_CAP_ATTR_TX_POWERS);
+		if (!nl_tx_pwrs)
+			return -ENOBUFS;
+
+		for (i = 0; i < caps->tx_powers_size; i++) {
+			if (nla_put_s32(msg, i, caps->tx_powers[i]))
+				return -ENOBUFS;
+		}
+
+		nla_nest_end(msg, nl_tx_pwrs);
+	}
+
+	if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE) {
+		if (nl802154_put_flags(msg, NL802154_CAP_ATTR_CCA_MODES,
+				       caps->cca_modes) ||
+		    nl802154_put_flags(msg, NL802154_CAP_ATTR_CCA_OPTS,
+				       caps->cca_opts))
+			return -ENOBUFS;
+	}
+
+	if (nla_put_u8(msg, NL802154_CAP_ATTR_MIN_MINBE, caps->min_minbe) ||
+	    nla_put_u8(msg, NL802154_CAP_ATTR_MAX_MINBE, caps->max_minbe) ||
+	    nla_put_u8(msg, NL802154_CAP_ATTR_MIN_MAXBE, caps->min_maxbe) ||
+	    nla_put_u8(msg, NL802154_CAP_ATTR_MAX_MAXBE, caps->max_maxbe) ||
+	    nla_put_u8(msg, NL802154_CAP_ATTR_MIN_CSMA_BACKOFFS,
+		       caps->min_csma_backoffs) ||
+	    nla_put_u8(msg, NL802154_CAP_ATTR_MAX_CSMA_BACKOFFS,
+		       caps->max_csma_backoffs) ||
+	    nla_put_s8(msg, NL802154_CAP_ATTR_MIN_FRAME_RETRIES,
+		       caps->min_frame_retries) ||
+	    nla_put_s8(msg, NL802154_CAP_ATTR_MAX_FRAME_RETRIES,
+		       caps->max_frame_retries) ||
+	    nl802154_put_flags(msg, NL802154_CAP_ATTR_IFTYPES,
+			       caps->iftypes) ||
+	    nla_put_u32(msg, NL802154_CAP_ATTR_LBT, caps->lbt))
+		return -ENOBUFS;
+
+	nla_nest_end(msg, nl_caps);
+
+	return 0;
+}
+
 static int nl802154_send_wpan_phy(struct cfg802154_registered_device *rdev,
 				  enum nl802154_commands cmd,
 				  struct sk_buff *msg, u32 portid, u32 seq,
@@ -286,7 +396,9 @@ static int nl802154_send_wpan_phy(struct cfg802154_registered_device *rdev,
 		       rdev->wpan_phy.current_channel))
 		goto nla_put_failure;
 
-	/* supported channels array */
+	/* TODO remove this behaviour, we still keep support it for a while
+	 * so users can change the behaviour to the new one.
+	 */
 	if (nl802154_send_wpan_phy_channels(rdev, msg))
 		goto nla_put_failure;
 
@@ -309,6 +421,9 @@ static int nl802154_send_wpan_phy(struct cfg802154_registered_device *rdev,
 			goto nla_put_failure;
 	}
 
+	if (nl802154_put_capabilities(msg, rdev))
+		goto nla_put_failure;
+
 finish:
 	genlmsg_end(msg, hdr);
 	return 0;
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 18/34] mac802154: fakelb: Fix potential NULL pointer dereference.
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (16 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 17/34] nl802154: add support for dump phy capabilities Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 19/34] at86rf230: fix callback for aret handling Alexander Aring
                   ` (16 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan
  Cc: kernel, marcel, Martin Townsend, Martin Townsend, Alexander Aring

From: Martin Townsend <mtownsend1973@gmail.com>

fakelb_hw_deliver creates a copy of the skb's header which can
potentially return NULL so we now check for this before actually
delivering to the 802.15.4 MAC layer.

Signed-off-by: Martin Townsend <martin.townsend@xsilon.com>
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/fakelb.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index 91bbf03..230f7da 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -69,7 +69,8 @@ fakelb_hw_deliver(struct fakelb_dev_priv *priv, struct sk_buff *skb)
 	spin_lock(&priv->lock);
 	if (priv->working) {
 		newskb = pskb_copy(skb, GFP_ATOMIC);
-		ieee802154_rx_irqsafe(priv->hw, newskb, 0xcc);
+		if (newskb)
+			ieee802154_rx_irqsafe(priv->hw, newskb, 0xcc);
 	}
 	spin_unlock(&priv->lock);
 }
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 19/34] at86rf230: fix callback for aret handling
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (17 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 18/34] mac802154: fakelb: Fix potential NULL pointer dereference Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 20/34] mac802154: tx: allow xmit complete from hard irq Alexander Aring
                   ` (15 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch fix the complete callback for going into aret on. Currently
we starting after a state change into aret on again a state change into
aret on which is not necessary.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/at86rf230.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index 5601c74..8d5ed6e 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -1013,7 +1013,7 @@ at86rf230_xmit_start(void *context)
 		if (lp->is_tx_from_off) {
 			lp->is_tx_from_off = false;
 			at86rf230_async_state_change(lp, ctx, STATE_TX_ARET_ON,
-						     at86rf230_xmit_tx_on,
+						     at86rf230_write_frame,
 						     false);
 		} else {
 			at86rf230_async_state_change(lp, ctx, STATE_TX_ON,
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 20/34] mac802154: tx: allow xmit complete from hard irq
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (18 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 19/34] at86rf230: fix callback for aret handling Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 21/34] ieee802154: add support for atusb transceiver Alexander Aring
                   ` (14 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

Replace consume_skb with dev_consume_skb_any in ieee802154_xmit_complete
which can be called in hard irq and other contexts.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 net/mac802154/util.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/net/mac802154/util.c b/net/mac802154/util.c
index 150bf80..583435f 100644
--- a/net/mac802154/util.c
+++ b/net/mac802154/util.c
@@ -85,11 +85,10 @@ void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
 			hrtimer_start(&local->ifs_timer,
 				      ktime_set(0, hw->phy->sifs_period * NSEC_PER_USEC),
 				      HRTIMER_MODE_REL);
-
-		consume_skb(skb);
 	} else {
 		ieee802154_wake_queue(hw);
-		consume_skb(skb);
 	}
+
+	dev_consume_skb_any(skb);
 }
 EXPORT_SYMBOL(ieee802154_xmit_complete);
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 21/34] ieee802154: add support for atusb transceiver
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (19 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 20/34] mac802154: tx: allow xmit complete from hard irq Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-19 10:49   ` Stefan Schmidt
  2015-05-17 19:44 ` [PATCH bluetooth-next 22/34] fakelb: creating two virtual phys per default Alexander Aring
                   ` (13 subsequent siblings)
  34 siblings, 1 reply; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan
  Cc: kernel, marcel, Alexander Aring, Werner Almesberger,
	Stefan Schmidt, Richard Sharpe

This patch adds support for the atusb transceiver.

The current driver supports basic functionality only. Possible further
tasks would be to sync functionality with the at86rf230 driver, because
the atusb use internally an at86rf231 transceiver. Some of these
features need a firmware update like AACK and ARET handling.

I did small changes to this driver to work with xmit_async callback and
setting of a random extended perm address.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Cc: Werner Almesberger <werner@almesberger.net>
Cc: Stefan Schmidt <s.schmidt@samsung.com>
Cc: Richard Sharpe <realrichardsharpe@gmail.com>
---
 drivers/net/ieee802154/Kconfig     |  10 +
 drivers/net/ieee802154/Makefile    |   1 +
 drivers/net/ieee802154/at86rf230.c | 199 +----------
 drivers/net/ieee802154/at86rf230.h | 220 ++++++++++++
 drivers/net/ieee802154/atusb.c     | 692 +++++++++++++++++++++++++++++++++++++
 drivers/net/ieee802154/atusb.h     |  84 +++++
 6 files changed, 1009 insertions(+), 197 deletions(-)
 create mode 100644 drivers/net/ieee802154/at86rf230.h
 create mode 100644 drivers/net/ieee802154/atusb.c
 create mode 100644 drivers/net/ieee802154/atusb.h

diff --git a/drivers/net/ieee802154/Kconfig b/drivers/net/ieee802154/Kconfig
index 1a3c3e5..1dd5ab8 100644
--- a/drivers/net/ieee802154/Kconfig
+++ b/drivers/net/ieee802154/Kconfig
@@ -53,3 +53,13 @@ config IEEE802154_CC2520
 
 	  This driver can also be built as a module. To do so, say M here.
 	  the module will be called 'cc2520'.
+
+config IEEE802154_ATUSB
+	tristate "ATUSB transceiver driver"
+	depends on IEEE802154_DRIVERS && MAC802154 && USB
+	---help---
+	  Say Y here to enable the ATUSB IEEE 802.15.4 wireless
+	  controller.
+
+	  This driver can also be built as a module. To do so say M here.
+	  The module will be called 'atusb'.
diff --git a/drivers/net/ieee802154/Makefile b/drivers/net/ieee802154/Makefile
index d77fa4d..cf1d2a6 100644
--- a/drivers/net/ieee802154/Makefile
+++ b/drivers/net/ieee802154/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o
 obj-$(CONFIG_IEEE802154_AT86RF230) += at86rf230.o
 obj-$(CONFIG_IEEE802154_MRF24J40) += mrf24j40.o
 obj-$(CONFIG_IEEE802154_CC2520) += cc2520.o
+obj-$(CONFIG_IEEE802154_ATUSB) += atusb.o
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index 8d5ed6e..d417ceb 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -35,6 +35,8 @@
 #include <net/mac802154.h>
 #include <net/cfg802154.h>
 
+#include "at86rf230.h"
+
 struct at86rf230_local;
 /* at86rf2xx chip depend data.
  * All timings are in us.
@@ -102,203 +104,6 @@ struct at86rf230_local {
 	struct at86rf230_state_change tx;
 };
 
-#define RG_TRX_STATUS	(0x01)
-#define SR_TRX_STATUS		0x01, 0x1f, 0
-#define SR_RESERVED_01_3	0x01, 0x20, 5
-#define SR_CCA_STATUS		0x01, 0x40, 6
-#define SR_CCA_DONE		0x01, 0x80, 7
-#define RG_TRX_STATE	(0x02)
-#define SR_TRX_CMD		0x02, 0x1f, 0
-#define SR_TRAC_STATUS		0x02, 0xe0, 5
-#define RG_TRX_CTRL_0	(0x03)
-#define SR_CLKM_CTRL		0x03, 0x07, 0
-#define SR_CLKM_SHA_SEL		0x03, 0x08, 3
-#define SR_PAD_IO_CLKM		0x03, 0x30, 4
-#define SR_PAD_IO		0x03, 0xc0, 6
-#define RG_TRX_CTRL_1	(0x04)
-#define SR_IRQ_POLARITY		0x04, 0x01, 0
-#define SR_IRQ_MASK_MODE	0x04, 0x02, 1
-#define SR_SPI_CMD_MODE		0x04, 0x0c, 2
-#define SR_RX_BL_CTRL		0x04, 0x10, 4
-#define SR_TX_AUTO_CRC_ON	0x04, 0x20, 5
-#define SR_IRQ_2_EXT_EN		0x04, 0x40, 6
-#define SR_PA_EXT_EN		0x04, 0x80, 7
-#define RG_PHY_TX_PWR	(0x05)
-#define SR_TX_PWR_23X		0x05, 0x0f, 0
-#define SR_PA_LT_230		0x05, 0x30, 4
-#define SR_PA_BUF_LT_230	0x05, 0xc0, 6
-#define SR_TX_PWR_212		0x05, 0x1f, 0
-#define SR_GC_PA_212		0x05, 0x60, 5
-#define SR_PA_BOOST_LT_212	0x05, 0x80, 7
-#define RG_PHY_RSSI	(0x06)
-#define SR_RSSI			0x06, 0x1f, 0
-#define SR_RND_VALUE		0x06, 0x60, 5
-#define SR_RX_CRC_VALID		0x06, 0x80, 7
-#define RG_PHY_ED_LEVEL	(0x07)
-#define SR_ED_LEVEL		0x07, 0xff, 0
-#define RG_PHY_CC_CCA	(0x08)
-#define SR_CHANNEL		0x08, 0x1f, 0
-#define SR_CCA_MODE		0x08, 0x60, 5
-#define SR_CCA_REQUEST		0x08, 0x80, 7
-#define RG_CCA_THRES	(0x09)
-#define SR_CCA_ED_THRES		0x09, 0x0f, 0
-#define SR_RESERVED_09_1	0x09, 0xf0, 4
-#define RG_RX_CTRL	(0x0a)
-#define SR_PDT_THRES		0x0a, 0x0f, 0
-#define SR_RESERVED_0a_1	0x0a, 0xf0, 4
-#define RG_SFD_VALUE	(0x0b)
-#define SR_SFD_VALUE		0x0b, 0xff, 0
-#define RG_TRX_CTRL_2	(0x0c)
-#define SR_OQPSK_DATA_RATE	0x0c, 0x03, 0
-#define SR_SUB_MODE		0x0c, 0x04, 2
-#define SR_BPSK_QPSK		0x0c, 0x08, 3
-#define SR_OQPSK_SUB1_RC_EN	0x0c, 0x10, 4
-#define SR_RESERVED_0c_5	0x0c, 0x60, 5
-#define SR_RX_SAFE_MODE		0x0c, 0x80, 7
-#define RG_ANT_DIV	(0x0d)
-#define SR_ANT_CTRL		0x0d, 0x03, 0
-#define SR_ANT_EXT_SW_EN	0x0d, 0x04, 2
-#define SR_ANT_DIV_EN		0x0d, 0x08, 3
-#define SR_RESERVED_0d_2	0x0d, 0x70, 4
-#define SR_ANT_SEL		0x0d, 0x80, 7
-#define RG_IRQ_MASK	(0x0e)
-#define SR_IRQ_MASK		0x0e, 0xff, 0
-#define RG_IRQ_STATUS	(0x0f)
-#define SR_IRQ_0_PLL_LOCK	0x0f, 0x01, 0
-#define SR_IRQ_1_PLL_UNLOCK	0x0f, 0x02, 1
-#define SR_IRQ_2_RX_START	0x0f, 0x04, 2
-#define SR_IRQ_3_TRX_END	0x0f, 0x08, 3
-#define SR_IRQ_4_CCA_ED_DONE	0x0f, 0x10, 4
-#define SR_IRQ_5_AMI		0x0f, 0x20, 5
-#define SR_IRQ_6_TRX_UR		0x0f, 0x40, 6
-#define SR_IRQ_7_BAT_LOW	0x0f, 0x80, 7
-#define RG_VREG_CTRL	(0x10)
-#define SR_RESERVED_10_6	0x10, 0x03, 0
-#define SR_DVDD_OK		0x10, 0x04, 2
-#define SR_DVREG_EXT		0x10, 0x08, 3
-#define SR_RESERVED_10_3	0x10, 0x30, 4
-#define SR_AVDD_OK		0x10, 0x40, 6
-#define SR_AVREG_EXT		0x10, 0x80, 7
-#define RG_BATMON	(0x11)
-#define SR_BATMON_VTH		0x11, 0x0f, 0
-#define SR_BATMON_HR		0x11, 0x10, 4
-#define SR_BATMON_OK		0x11, 0x20, 5
-#define SR_RESERVED_11_1	0x11, 0xc0, 6
-#define RG_XOSC_CTRL	(0x12)
-#define SR_XTAL_TRIM		0x12, 0x0f, 0
-#define SR_XTAL_MODE		0x12, 0xf0, 4
-#define RG_RX_SYN	(0x15)
-#define SR_RX_PDT_LEVEL		0x15, 0x0f, 0
-#define SR_RESERVED_15_2	0x15, 0x70, 4
-#define SR_RX_PDT_DIS		0x15, 0x80, 7
-#define RG_XAH_CTRL_1	(0x17)
-#define SR_RESERVED_17_8	0x17, 0x01, 0
-#define SR_AACK_PROM_MODE	0x17, 0x02, 1
-#define SR_AACK_ACK_TIME	0x17, 0x04, 2
-#define SR_RESERVED_17_5	0x17, 0x08, 3
-#define SR_AACK_UPLD_RES_FT	0x17, 0x10, 4
-#define SR_AACK_FLTR_RES_FT	0x17, 0x20, 5
-#define SR_CSMA_LBT_MODE	0x17, 0x40, 6
-#define SR_RESERVED_17_1	0x17, 0x80, 7
-#define RG_FTN_CTRL	(0x18)
-#define SR_RESERVED_18_2	0x18, 0x7f, 0
-#define SR_FTN_START		0x18, 0x80, 7
-#define RG_PLL_CF	(0x1a)
-#define SR_RESERVED_1a_2	0x1a, 0x7f, 0
-#define SR_PLL_CF_START		0x1a, 0x80, 7
-#define RG_PLL_DCU	(0x1b)
-#define SR_RESERVED_1b_3	0x1b, 0x3f, 0
-#define SR_RESERVED_1b_2	0x1b, 0x40, 6
-#define SR_PLL_DCU_START	0x1b, 0x80, 7
-#define RG_PART_NUM	(0x1c)
-#define SR_PART_NUM		0x1c, 0xff, 0
-#define RG_VERSION_NUM	(0x1d)
-#define SR_VERSION_NUM		0x1d, 0xff, 0
-#define RG_MAN_ID_0	(0x1e)
-#define SR_MAN_ID_0		0x1e, 0xff, 0
-#define RG_MAN_ID_1	(0x1f)
-#define SR_MAN_ID_1		0x1f, 0xff, 0
-#define RG_SHORT_ADDR_0	(0x20)
-#define SR_SHORT_ADDR_0		0x20, 0xff, 0
-#define RG_SHORT_ADDR_1	(0x21)
-#define SR_SHORT_ADDR_1		0x21, 0xff, 0
-#define RG_PAN_ID_0	(0x22)
-#define SR_PAN_ID_0		0x22, 0xff, 0
-#define RG_PAN_ID_1	(0x23)
-#define SR_PAN_ID_1		0x23, 0xff, 0
-#define RG_IEEE_ADDR_0	(0x24)
-#define SR_IEEE_ADDR_0		0x24, 0xff, 0
-#define RG_IEEE_ADDR_1	(0x25)
-#define SR_IEEE_ADDR_1		0x25, 0xff, 0
-#define RG_IEEE_ADDR_2	(0x26)
-#define SR_IEEE_ADDR_2		0x26, 0xff, 0
-#define RG_IEEE_ADDR_3	(0x27)
-#define SR_IEEE_ADDR_3		0x27, 0xff, 0
-#define RG_IEEE_ADDR_4	(0x28)
-#define SR_IEEE_ADDR_4		0x28, 0xff, 0
-#define RG_IEEE_ADDR_5	(0x29)
-#define SR_IEEE_ADDR_5		0x29, 0xff, 0
-#define RG_IEEE_ADDR_6	(0x2a)
-#define SR_IEEE_ADDR_6		0x2a, 0xff, 0
-#define RG_IEEE_ADDR_7	(0x2b)
-#define SR_IEEE_ADDR_7		0x2b, 0xff, 0
-#define RG_XAH_CTRL_0	(0x2c)
-#define SR_SLOTTED_OPERATION	0x2c, 0x01, 0
-#define SR_MAX_CSMA_RETRIES	0x2c, 0x0e, 1
-#define SR_MAX_FRAME_RETRIES	0x2c, 0xf0, 4
-#define RG_CSMA_SEED_0	(0x2d)
-#define SR_CSMA_SEED_0		0x2d, 0xff, 0
-#define RG_CSMA_SEED_1	(0x2e)
-#define SR_CSMA_SEED_1		0x2e, 0x07, 0
-#define SR_AACK_I_AM_COORD	0x2e, 0x08, 3
-#define SR_AACK_DIS_ACK		0x2e, 0x10, 4
-#define SR_AACK_SET_PD		0x2e, 0x20, 5
-#define SR_AACK_FVN_MODE	0x2e, 0xc0, 6
-#define RG_CSMA_BE	(0x2f)
-#define SR_MIN_BE		0x2f, 0x0f, 0
-#define SR_MAX_BE		0x2f, 0xf0, 4
-
-#define CMD_REG		0x80
-#define CMD_REG_MASK	0x3f
-#define CMD_WRITE	0x40
-#define CMD_FB		0x20
-
-#define IRQ_BAT_LOW	(1 << 7)
-#define IRQ_TRX_UR	(1 << 6)
-#define IRQ_AMI		(1 << 5)
-#define IRQ_CCA_ED	(1 << 4)
-#define IRQ_TRX_END	(1 << 3)
-#define IRQ_RX_START	(1 << 2)
-#define IRQ_PLL_UNL	(1 << 1)
-#define IRQ_PLL_LOCK	(1 << 0)
-
-#define IRQ_ACTIVE_HIGH	0
-#define IRQ_ACTIVE_LOW	1
-
-#define STATE_P_ON		0x00	/* BUSY */
-#define STATE_BUSY_RX		0x01
-#define STATE_BUSY_TX		0x02
-#define STATE_FORCE_TRX_OFF	0x03
-#define STATE_FORCE_TX_ON	0x04	/* IDLE */
-/* 0x05 */				/* INVALID_PARAMETER */
-#define STATE_RX_ON		0x06
-/* 0x07 */				/* SUCCESS */
-#define STATE_TRX_OFF		0x08
-#define STATE_TX_ON		0x09
-/* 0x0a - 0x0e */			/* 0x0a - UNSUPPORTED_ATTRIBUTE */
-#define STATE_SLEEP		0x0F
-#define STATE_PREP_DEEP_SLEEP	0x10
-#define STATE_BUSY_RX_AACK	0x11
-#define STATE_BUSY_TX_ARET	0x12
-#define STATE_RX_AACK_ON	0x16
-#define STATE_TX_ARET_ON	0x19
-#define STATE_RX_ON_NOCLK	0x1C
-#define STATE_RX_AACK_ON_NOCLK	0x1D
-#define STATE_BUSY_RX_AACK_NOCLK 0x1E
-#define STATE_TRANSITION_IN_PROGRESS 0x1F
-
-#define TRX_STATE_MASK		(0x1F)
-
 #define AT86RF2XX_NUMREGS 0x3F
 
 static void
diff --git a/drivers/net/ieee802154/at86rf230.h b/drivers/net/ieee802154/at86rf230.h
new file mode 100644
index 0000000..1e6d1cc
--- /dev/null
+++ b/drivers/net/ieee802154/at86rf230.h
@@ -0,0 +1,220 @@
+/*
+ * AT86RF230/RF231 driver
+ *
+ * Copyright (C) 2009-2012 Siemens AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Written by:
+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
+ */
+
+#ifndef _AT86RF230_H
+#define _AT86RF230_H
+
+#define RG_TRX_STATUS	(0x01)
+#define SR_TRX_STATUS		0x01, 0x1f, 0
+#define SR_RESERVED_01_3	0x01, 0x20, 5
+#define SR_CCA_STATUS		0x01, 0x40, 6
+#define SR_CCA_DONE		0x01, 0x80, 7
+#define RG_TRX_STATE	(0x02)
+#define SR_TRX_CMD		0x02, 0x1f, 0
+#define SR_TRAC_STATUS		0x02, 0xe0, 5
+#define RG_TRX_CTRL_0	(0x03)
+#define SR_CLKM_CTRL		0x03, 0x07, 0
+#define SR_CLKM_SHA_SEL		0x03, 0x08, 3
+#define SR_PAD_IO_CLKM		0x03, 0x30, 4
+#define SR_PAD_IO		0x03, 0xc0, 6
+#define RG_TRX_CTRL_1	(0x04)
+#define SR_IRQ_POLARITY		0x04, 0x01, 0
+#define SR_IRQ_MASK_MODE	0x04, 0x02, 1
+#define SR_SPI_CMD_MODE		0x04, 0x0c, 2
+#define SR_RX_BL_CTRL		0x04, 0x10, 4
+#define SR_TX_AUTO_CRC_ON	0x04, 0x20, 5
+#define SR_IRQ_2_EXT_EN		0x04, 0x40, 6
+#define SR_PA_EXT_EN		0x04, 0x80, 7
+#define RG_PHY_TX_PWR	(0x05)
+#define SR_TX_PWR_23X		0x05, 0x0f, 0
+#define SR_PA_LT_230		0x05, 0x30, 4
+#define SR_PA_BUF_LT_230	0x05, 0xc0, 6
+#define SR_TX_PWR_212		0x05, 0x1f, 0
+#define SR_GC_PA_212		0x05, 0x60, 5
+#define SR_PA_BOOST_LT_212	0x05, 0x80, 7
+#define RG_PHY_RSSI	(0x06)
+#define SR_RSSI			0x06, 0x1f, 0
+#define SR_RND_VALUE		0x06, 0x60, 5
+#define SR_RX_CRC_VALID		0x06, 0x80, 7
+#define RG_PHY_ED_LEVEL	(0x07)
+#define SR_ED_LEVEL		0x07, 0xff, 0
+#define RG_PHY_CC_CCA	(0x08)
+#define SR_CHANNEL		0x08, 0x1f, 0
+#define SR_CCA_MODE		0x08, 0x60, 5
+#define SR_CCA_REQUEST		0x08, 0x80, 7
+#define RG_CCA_THRES	(0x09)
+#define SR_CCA_ED_THRES		0x09, 0x0f, 0
+#define SR_RESERVED_09_1	0x09, 0xf0, 4
+#define RG_RX_CTRL	(0x0a)
+#define SR_PDT_THRES		0x0a, 0x0f, 0
+#define SR_RESERVED_0a_1	0x0a, 0xf0, 4
+#define RG_SFD_VALUE	(0x0b)
+#define SR_SFD_VALUE		0x0b, 0xff, 0
+#define RG_TRX_CTRL_2	(0x0c)
+#define SR_OQPSK_DATA_RATE	0x0c, 0x03, 0
+#define SR_SUB_MODE		0x0c, 0x04, 2
+#define SR_BPSK_QPSK		0x0c, 0x08, 3
+#define SR_OQPSK_SUB1_RC_EN	0x0c, 0x10, 4
+#define SR_RESERVED_0c_5	0x0c, 0x60, 5
+#define SR_RX_SAFE_MODE		0x0c, 0x80, 7
+#define RG_ANT_DIV	(0x0d)
+#define SR_ANT_CTRL		0x0d, 0x03, 0
+#define SR_ANT_EXT_SW_EN	0x0d, 0x04, 2
+#define SR_ANT_DIV_EN		0x0d, 0x08, 3
+#define SR_RESERVED_0d_2	0x0d, 0x70, 4
+#define SR_ANT_SEL		0x0d, 0x80, 7
+#define RG_IRQ_MASK	(0x0e)
+#define SR_IRQ_MASK		0x0e, 0xff, 0
+#define RG_IRQ_STATUS	(0x0f)
+#define SR_IRQ_0_PLL_LOCK	0x0f, 0x01, 0
+#define SR_IRQ_1_PLL_UNLOCK	0x0f, 0x02, 1
+#define SR_IRQ_2_RX_START	0x0f, 0x04, 2
+#define SR_IRQ_3_TRX_END	0x0f, 0x08, 3
+#define SR_IRQ_4_CCA_ED_DONE	0x0f, 0x10, 4
+#define SR_IRQ_5_AMI		0x0f, 0x20, 5
+#define SR_IRQ_6_TRX_UR		0x0f, 0x40, 6
+#define SR_IRQ_7_BAT_LOW	0x0f, 0x80, 7
+#define RG_VREG_CTRL	(0x10)
+#define SR_RESERVED_10_6	0x10, 0x03, 0
+#define SR_DVDD_OK		0x10, 0x04, 2
+#define SR_DVREG_EXT		0x10, 0x08, 3
+#define SR_RESERVED_10_3	0x10, 0x30, 4
+#define SR_AVDD_OK		0x10, 0x40, 6
+#define SR_AVREG_EXT		0x10, 0x80, 7
+#define RG_BATMON	(0x11)
+#define SR_BATMON_VTH		0x11, 0x0f, 0
+#define SR_BATMON_HR		0x11, 0x10, 4
+#define SR_BATMON_OK		0x11, 0x20, 5
+#define SR_RESERVED_11_1	0x11, 0xc0, 6
+#define RG_XOSC_CTRL	(0x12)
+#define SR_XTAL_TRIM		0x12, 0x0f, 0
+#define SR_XTAL_MODE		0x12, 0xf0, 4
+#define RG_RX_SYN	(0x15)
+#define SR_RX_PDT_LEVEL		0x15, 0x0f, 0
+#define SR_RESERVED_15_2	0x15, 0x70, 4
+#define SR_RX_PDT_DIS		0x15, 0x80, 7
+#define RG_XAH_CTRL_1	(0x17)
+#define SR_RESERVED_17_8	0x17, 0x01, 0
+#define SR_AACK_PROM_MODE	0x17, 0x02, 1
+#define SR_AACK_ACK_TIME	0x17, 0x04, 2
+#define SR_RESERVED_17_5	0x17, 0x08, 3
+#define SR_AACK_UPLD_RES_FT	0x17, 0x10, 4
+#define SR_AACK_FLTR_RES_FT	0x17, 0x20, 5
+#define SR_CSMA_LBT_MODE	0x17, 0x40, 6
+#define SR_RESERVED_17_1	0x17, 0x80, 7
+#define RG_FTN_CTRL	(0x18)
+#define SR_RESERVED_18_2	0x18, 0x7f, 0
+#define SR_FTN_START		0x18, 0x80, 7
+#define RG_PLL_CF	(0x1a)
+#define SR_RESERVED_1a_2	0x1a, 0x7f, 0
+#define SR_PLL_CF_START		0x1a, 0x80, 7
+#define RG_PLL_DCU	(0x1b)
+#define SR_RESERVED_1b_3	0x1b, 0x3f, 0
+#define SR_RESERVED_1b_2	0x1b, 0x40, 6
+#define SR_PLL_DCU_START	0x1b, 0x80, 7
+#define RG_PART_NUM	(0x1c)
+#define SR_PART_NUM		0x1c, 0xff, 0
+#define RG_VERSION_NUM	(0x1d)
+#define SR_VERSION_NUM		0x1d, 0xff, 0
+#define RG_MAN_ID_0	(0x1e)
+#define SR_MAN_ID_0		0x1e, 0xff, 0
+#define RG_MAN_ID_1	(0x1f)
+#define SR_MAN_ID_1		0x1f, 0xff, 0
+#define RG_SHORT_ADDR_0	(0x20)
+#define SR_SHORT_ADDR_0		0x20, 0xff, 0
+#define RG_SHORT_ADDR_1	(0x21)
+#define SR_SHORT_ADDR_1		0x21, 0xff, 0
+#define RG_PAN_ID_0	(0x22)
+#define SR_PAN_ID_0		0x22, 0xff, 0
+#define RG_PAN_ID_1	(0x23)
+#define SR_PAN_ID_1		0x23, 0xff, 0
+#define RG_IEEE_ADDR_0	(0x24)
+#define SR_IEEE_ADDR_0		0x24, 0xff, 0
+#define RG_IEEE_ADDR_1	(0x25)
+#define SR_IEEE_ADDR_1		0x25, 0xff, 0
+#define RG_IEEE_ADDR_2	(0x26)
+#define SR_IEEE_ADDR_2		0x26, 0xff, 0
+#define RG_IEEE_ADDR_3	(0x27)
+#define SR_IEEE_ADDR_3		0x27, 0xff, 0
+#define RG_IEEE_ADDR_4	(0x28)
+#define SR_IEEE_ADDR_4		0x28, 0xff, 0
+#define RG_IEEE_ADDR_5	(0x29)
+#define SR_IEEE_ADDR_5		0x29, 0xff, 0
+#define RG_IEEE_ADDR_6	(0x2a)
+#define SR_IEEE_ADDR_6		0x2a, 0xff, 0
+#define RG_IEEE_ADDR_7	(0x2b)
+#define SR_IEEE_ADDR_7		0x2b, 0xff, 0
+#define RG_XAH_CTRL_0	(0x2c)
+#define SR_SLOTTED_OPERATION	0x2c, 0x01, 0
+#define SR_MAX_CSMA_RETRIES	0x2c, 0x0e, 1
+#define SR_MAX_FRAME_RETRIES	0x2c, 0xf0, 4
+#define RG_CSMA_SEED_0	(0x2d)
+#define SR_CSMA_SEED_0		0x2d, 0xff, 0
+#define RG_CSMA_SEED_1	(0x2e)
+#define SR_CSMA_SEED_1		0x2e, 0x07, 0
+#define SR_AACK_I_AM_COORD	0x2e, 0x08, 3
+#define SR_AACK_DIS_ACK		0x2e, 0x10, 4
+#define SR_AACK_SET_PD		0x2e, 0x20, 5
+#define SR_AACK_FVN_MODE	0x2e, 0xc0, 6
+#define RG_CSMA_BE	(0x2f)
+#define SR_MIN_BE		0x2f, 0x0f, 0
+#define SR_MAX_BE		0x2f, 0xf0, 4
+
+#define CMD_REG		0x80
+#define CMD_REG_MASK	0x3f
+#define CMD_WRITE	0x40
+#define CMD_FB		0x20
+
+#define IRQ_BAT_LOW	BIT(7)
+#define IRQ_TRX_UR	BIT(6)
+#define IRQ_AMI		BIT(5)
+#define IRQ_CCA_ED	BIT(4)
+#define IRQ_TRX_END	BIT(3)
+#define IRQ_RX_START	BIT(2)
+#define IRQ_PLL_UNL	BIT(1)
+#define IRQ_PLL_LOCK	BIT(0)
+
+#define IRQ_ACTIVE_HIGH	0
+#define IRQ_ACTIVE_LOW	1
+
+#define STATE_P_ON		0x00	/* BUSY */
+#define STATE_BUSY_RX		0x01
+#define STATE_BUSY_TX		0x02
+#define STATE_FORCE_TRX_OFF	0x03
+#define STATE_FORCE_TX_ON	0x04	/* IDLE */
+/* 0x05 */				/* INVALID_PARAMETER */
+#define STATE_RX_ON		0x06
+/* 0x07 */				/* SUCCESS */
+#define STATE_TRX_OFF		0x08
+#define STATE_TX_ON		0x09
+/* 0x0a - 0x0e */			/* 0x0a - UNSUPPORTED_ATTRIBUTE */
+#define STATE_SLEEP		0x0F
+#define STATE_PREP_DEEP_SLEEP	0x10
+#define STATE_BUSY_RX_AACK	0x11
+#define STATE_BUSY_TX_ARET	0x12
+#define STATE_RX_AACK_ON	0x16
+#define STATE_TX_ARET_ON	0x19
+#define STATE_RX_ON_NOCLK	0x1C
+#define STATE_RX_AACK_ON_NOCLK	0x1D
+#define STATE_BUSY_RX_AACK_NOCLK 0x1E
+#define STATE_TRANSITION_IN_PROGRESS 0x1F
+
+#define TRX_STATE_MASK		(0x1F)
+
+#endif /* !_AT86RF230_H */
diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c
new file mode 100644
index 0000000..ea1259e
--- /dev/null
+++ b/drivers/net/ieee802154/atusb.c
@@ -0,0 +1,692 @@
+/*
+ * atusb.c - Driver for the ATUSB IEEE 802.15.4 dongle
+ *
+ * Written 2013 by Werner Almesberger <werner@almesberger.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2
+ *
+ * Based on at86rf230.c and spi_atusb.c.
+ * at86rf230.c is
+ * Copyright (C) 2009 Siemens AG
+ * Written by: Dmitry Eremin-Solenikov <dmitry.baryshkov@siemens.com>
+ *
+ * spi_atusb.c is
+ * Copyright (c) 2011 Richard Sharpe <realrichardsharpe@gmail.com>
+ * Copyright (c) 2011 Stefan Schmidt <stefan@datenfreihafen.org>
+ * Copyright (c) 2011 Werner Almesberger <werner@almesberger.net>
+ *
+ * USB initialization is
+ * Copyright (c) 2013 Alexander Aring <alex.aring@gmail.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/usb.h>
+#include <linux/skbuff.h>
+
+#include <net/cfg802154.h>
+#include <net/mac802154.h>
+
+#include "at86rf230.h"
+#include "atusb.h"
+
+#define ATUSB_JEDEC_ATMEL	0x1f	/* JEDEC manufacturer ID */
+
+#define ATUSB_NUM_RX_URBS	4	/* allow for a bit of local latency */
+#define ATUSB_ALLOC_DELAY_MS	100	/* delay after failed allocation */
+#define ATUSB_TX_TIMEOUT_MS	200	/* on the air timeout */
+
+struct atusb {
+	struct ieee802154_hw *hw;
+	struct usb_device *usb_dev;
+	int shutdown;			/* non-zero if shutting down */
+	int err;			/* set by first error */
+
+	/* RX variables */
+	struct delayed_work work;	/* memory allocations */
+	struct usb_anchor idle_urbs;	/* URBs waiting to be submitted */
+	struct usb_anchor rx_urbs;	/* URBs waiting for reception */
+
+	/* TX variables */
+	struct usb_ctrlrequest tx_dr;
+	struct urb *tx_urb;
+	struct sk_buff *tx_skb;
+	uint8_t tx_ack_seq;		/* current TX ACK sequence number */
+};
+
+/* at86rf230.h defines values as <reg, mask, shift> tuples. We use the more
+ * traditional style of having registers and or-able values. SR_REG extracts
+ * the register number. SR_VALUE uses the shift to prepare a value accordingly.
+ */
+
+#define __SR_REG(reg, mask, shift)	(reg)
+#define SR_REG(sr)			__SR_REG(sr)
+
+#define __SR_VALUE(reg, mask, shift, val)	((val) << (shift))
+#define SR_VALUE(sr, val)			__SR_VALUE(sr, (val))
+
+/* ----- USB commands without data ----------------------------------------- */
+
+/* To reduce the number of error checks in the code, we record the first error
+ * in atusb->err and reject all subsequent requests until the error is cleared.
+ */
+
+static int atusb_control_msg(struct atusb *atusb, unsigned int pipe,
+			     __u8 request, __u8 requesttype,
+			     __u16 value, __u16 index,
+			     void *data, __u16 size, int timeout)
+{
+	struct usb_device *usb_dev = atusb->usb_dev;
+	int ret;
+
+	if (atusb->err)
+		return atusb->err;
+
+	ret = usb_control_msg(usb_dev, pipe, request, requesttype,
+			      value, index, data, size, timeout);
+	if (ret < 0) {
+		atusb->err = ret;
+		dev_err(&usb_dev->dev,
+			"atusb_control_msg: req 0x%02x val 0x%x idx 0x%x, error %d\n",
+			request, value, index, ret);
+	}
+	return ret;
+}
+
+static int atusb_command(struct atusb *atusb, uint8_t cmd, uint8_t arg)
+{
+	struct usb_device *usb_dev = atusb->usb_dev;
+
+	dev_dbg(&usb_dev->dev, "atusb_command: cmd = 0x%x\n", cmd);
+	return atusb_control_msg(atusb, usb_sndctrlpipe(usb_dev, 0),
+				 cmd, ATUSB_REQ_TO_DEV, arg, 0, NULL, 0, 1000);
+}
+
+static int atusb_write_reg(struct atusb *atusb, uint8_t reg, uint8_t value)
+{
+	struct usb_device *usb_dev = atusb->usb_dev;
+
+	dev_dbg(&usb_dev->dev, "atusb_write_reg: 0x%02x <- 0x%02x\n",
+		reg, value);
+	return atusb_control_msg(atusb, usb_sndctrlpipe(usb_dev, 0),
+				 ATUSB_REG_WRITE, ATUSB_REQ_TO_DEV,
+				 value, reg, NULL, 0, 1000);
+}
+
+static int atusb_read_reg(struct atusb *atusb, uint8_t reg)
+{
+	struct usb_device *usb_dev = atusb->usb_dev;
+	int ret;
+	uint8_t value;
+
+	dev_dbg(&usb_dev->dev, "atusb: reg = 0x%x\n", reg);
+	ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
+				ATUSB_REG_READ, ATUSB_REQ_FROM_DEV,
+				0, reg, &value, 1, 1000);
+	return ret >= 0 ? value : ret;
+}
+
+static int atusb_get_and_clear_error(struct atusb *atusb)
+{
+	int err = atusb->err;
+
+	atusb->err = 0;
+	return err;
+}
+
+/* ----- skb allocation ---------------------------------------------------- */
+
+#define MAX_PSDU	127
+#define MAX_RX_XFER	(1 + MAX_PSDU + 2 + 1)	/* PHR+PSDU+CRC+LQI */
+
+#define SKB_ATUSB(skb)	(*(struct atusb **)(skb)->cb)
+
+static void atusb_in(struct urb *urb);
+
+static int atusb_submit_rx_urb(struct atusb *atusb, struct urb *urb)
+{
+	struct usb_device *usb_dev = atusb->usb_dev;
+	struct sk_buff *skb = urb->context;
+	int ret;
+
+	if (!skb) {
+		skb = alloc_skb(MAX_RX_XFER, GFP_KERNEL);
+		if (!skb) {
+			dev_warn_ratelimited(&usb_dev->dev,
+					     "atusb_in: can't allocate skb\n");
+			return -ENOMEM;
+		}
+		skb_put(skb, MAX_RX_XFER);
+		SKB_ATUSB(skb) = atusb;
+	}
+
+	usb_fill_bulk_urb(urb, usb_dev, usb_rcvbulkpipe(usb_dev, 1),
+			  skb->data, MAX_RX_XFER, atusb_in, skb);
+	usb_anchor_urb(urb, &atusb->rx_urbs);
+
+	ret = usb_submit_urb(urb, GFP_KERNEL);
+	if (ret) {
+		usb_unanchor_urb(urb);
+		kfree_skb(skb);
+		urb->context = NULL;
+	}
+	return ret;
+}
+
+static void atusb_work_urbs(struct work_struct *work)
+{
+	struct atusb *atusb =
+	    container_of(to_delayed_work(work), struct atusb, work);
+	struct usb_device *usb_dev = atusb->usb_dev;
+	struct urb *urb;
+	int ret;
+
+	if (atusb->shutdown)
+		return;
+
+	do {
+		urb = usb_get_from_anchor(&atusb->idle_urbs);
+		if (!urb)
+			return;
+		ret = atusb_submit_rx_urb(atusb, urb);
+	} while (!ret);
+
+	usb_anchor_urb(urb, &atusb->idle_urbs);
+	dev_warn_ratelimited(&usb_dev->dev,
+			     "atusb_in: can't allocate/submit URB (%d)\n", ret);
+	schedule_delayed_work(&atusb->work,
+			      msecs_to_jiffies(ATUSB_ALLOC_DELAY_MS) + 1);
+}
+
+/* ----- Asynchronous USB -------------------------------------------------- */
+
+static void atusb_tx_done(struct atusb *atusb, uint8_t seq)
+{
+	struct usb_device *usb_dev = atusb->usb_dev;
+	uint8_t expect = atusb->tx_ack_seq;
+
+	dev_dbg(&usb_dev->dev, "atusb_tx_done (0x%02x/0x%02x)\n", seq, expect);
+	if (seq == expect) {
+		/* TODO check for ifs handling in firmware */
+		ieee802154_xmit_complete(atusb->hw, atusb->tx_skb, false);
+	} else {
+		/* TODO I experience this case when atusb has a tx complete
+		 * irq before probing, we should fix the firmware it's an
+		 * unlikely case now that seq == expect is then true, but can
+		 * happen and fail with a tx_skb = NULL;
+		 */
+		ieee802154_wake_queue(atusb->hw);
+		if (atusb->tx_skb)
+			dev_kfree_skb_irq(atusb->tx_skb);
+	}
+}
+
+static void atusb_in_good(struct urb *urb)
+{
+	struct usb_device *usb_dev = urb->dev;
+	struct sk_buff *skb = urb->context;
+	struct atusb *atusb = SKB_ATUSB(skb);
+	uint8_t len, lqi;
+
+	if (!urb->actual_length) {
+		dev_dbg(&usb_dev->dev, "atusb_in: zero-sized URB ?\n");
+		return;
+	}
+
+	len = *skb->data;
+
+	if (urb->actual_length == 1) {
+		atusb_tx_done(atusb, len);
+		return;
+	}
+
+	if (len + 1 > urb->actual_length - 1) {
+		dev_dbg(&usb_dev->dev, "atusb_in: frame len %d+1 > URB %u-1\n",
+			len, urb->actual_length);
+		return;
+	}
+
+	if (!ieee802154_is_valid_psdu_len(len)) {
+		dev_dbg(&usb_dev->dev, "atusb_in: frame corrupted\n");
+		return;
+	}
+
+	lqi = skb->data[len + 1];
+	dev_dbg(&usb_dev->dev, "atusb_in: rx len %d lqi 0x%02x\n", len, lqi);
+	skb_pull(skb, 1);	/* remove PHR */
+	skb_trim(skb, len);	/* get payload only */
+	ieee802154_rx_irqsafe(atusb->hw, skb, lqi);
+	urb->context = NULL;	/* skb is gone */
+}
+
+static void atusb_in(struct urb *urb)
+{
+	struct usb_device *usb_dev = urb->dev;
+	struct sk_buff *skb = urb->context;
+	struct atusb *atusb = SKB_ATUSB(skb);
+
+	dev_dbg(&usb_dev->dev, "atusb_in: status %d len %d\n",
+		urb->status, urb->actual_length);
+	if (urb->status) {
+		if (urb->status == -ENOENT) { /* being killed */
+			kfree_skb(skb);
+			urb->context = NULL;
+			return;
+		}
+		dev_dbg(&usb_dev->dev, "atusb_in: URB error %d\n", urb->status);
+	} else {
+		atusb_in_good(urb);
+	}
+
+	usb_anchor_urb(urb, &atusb->idle_urbs);
+	if (!atusb->shutdown)
+		schedule_delayed_work(&atusb->work, 0);
+}
+
+/* ----- URB allocation/deallocation --------------------------------------- */
+
+static void atusb_free_urbs(struct atusb *atusb)
+{
+	struct urb *urb;
+
+	while (1) {
+		urb = usb_get_from_anchor(&atusb->idle_urbs);
+		if (!urb)
+			break;
+		if (urb->context)
+			kfree_skb(urb->context);
+		usb_free_urb(urb);
+	}
+}
+
+static int atusb_alloc_urbs(struct atusb *atusb, int n)
+{
+	struct urb *urb;
+
+	while (n) {
+		urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!urb) {
+			atusb_free_urbs(atusb);
+			return -ENOMEM;
+		}
+		usb_anchor_urb(urb, &atusb->idle_urbs);
+		n--;
+	}
+	return 0;
+}
+
+/* ----- IEEE 802.15.4 interface operations -------------------------------- */
+
+static void atusb_xmit_complete(struct urb *urb)
+{
+	dev_dbg(&urb->dev->dev, "atusb_xmit urb completed");
+}
+
+static int atusb_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
+{
+	struct atusb *atusb = hw->priv;
+	struct usb_device *usb_dev = atusb->usb_dev;
+	int ret;
+
+	dev_dbg(&usb_dev->dev, "atusb_xmit (%d)\n", skb->len);
+	atusb->tx_skb = skb;
+	atusb->tx_ack_seq++;
+	atusb->tx_dr.wIndex = cpu_to_le16(atusb->tx_ack_seq);
+	atusb->tx_dr.wLength = cpu_to_le16(skb->len);
+
+	usb_fill_control_urb(atusb->tx_urb, usb_dev,
+			     usb_sndctrlpipe(usb_dev, 0),
+			     (unsigned char *)&atusb->tx_dr, skb->data,
+			     skb->len, atusb_xmit_complete, NULL);
+	ret = usb_submit_urb(atusb->tx_urb, GFP_ATOMIC);
+	dev_dbg(&usb_dev->dev, "atusb_xmit done (%d)\n", ret);
+	return ret;
+}
+
+static int atusb_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
+{
+	struct atusb *atusb = hw->priv;
+	int ret;
+
+	/* This implicitly sets the CCA (Clear Channel Assessment) mode to 0,
+	 * "Mode 3a, Carrier sense OR energy above threshold".
+	 * We should probably make this configurable. @@@
+	 */
+	ret = atusb_write_reg(atusb, RG_PHY_CC_CCA, channel);
+	if (ret < 0)
+		return ret;
+	msleep(1);	/* @@@ ugly synchronization */
+	return 0;
+}
+
+static int atusb_ed(struct ieee802154_hw *hw, u8 *level)
+{
+	/* @@@ not used by the stack yet */
+	*level = 0;
+	return 0;
+}
+
+static int atusb_set_hw_addr_filt(struct ieee802154_hw *hw,
+				  struct ieee802154_hw_addr_filt *filt,
+				  unsigned long changed)
+{
+	struct atusb *atusb = hw->priv;
+	struct device *dev = &atusb->usb_dev->dev;
+	uint8_t reg;
+
+	if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
+		u16 addr = le16_to_cpu(filt->short_addr);
+
+		dev_vdbg(dev, "atusb_set_hw_addr_filt called for saddr\n");
+		atusb_write_reg(atusb, RG_SHORT_ADDR_0, addr);
+		atusb_write_reg(atusb, RG_SHORT_ADDR_1, addr >> 8);
+	}
+
+	if (changed & IEEE802154_AFILT_PANID_CHANGED) {
+		u16 pan = le16_to_cpu(filt->pan_id);
+
+		dev_vdbg(dev, "atusb_set_hw_addr_filt called for pan id\n");
+		atusb_write_reg(atusb, RG_PAN_ID_0, pan);
+		atusb_write_reg(atusb, RG_PAN_ID_1, pan >> 8);
+	}
+
+	if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
+		u8 i, addr[IEEE802154_EXTENDED_ADDR_LEN];
+
+		memcpy(addr, &filt->ieee_addr, IEEE802154_EXTENDED_ADDR_LEN);
+		dev_vdbg(dev, "atusb_set_hw_addr_filt called for IEEE addr\n");
+		for (i = 0; i < 8; i++)
+			atusb_write_reg(atusb, RG_IEEE_ADDR_0 + i, addr[i]);
+	}
+
+	if (changed & IEEE802154_AFILT_PANC_CHANGED) {
+		dev_vdbg(dev,
+			 "atusb_set_hw_addr_filt called for panc change\n");
+		reg = atusb_read_reg(atusb, SR_REG(SR_AACK_I_AM_COORD));
+		if (filt->pan_coord)
+			reg |= SR_VALUE(SR_AACK_I_AM_COORD, 1);
+		else
+			reg &= ~SR_VALUE(SR_AACK_I_AM_COORD, 1);
+		atusb_write_reg(atusb, SR_REG(SR_AACK_I_AM_COORD), reg);
+	}
+
+	return atusb_get_and_clear_error(atusb);
+}
+
+static int atusb_start(struct ieee802154_hw *hw)
+{
+	struct atusb *atusb = hw->priv;
+	struct usb_device *usb_dev = atusb->usb_dev;
+	int ret;
+
+	dev_dbg(&usb_dev->dev, "atusb_start\n");
+	schedule_delayed_work(&atusb->work, 0);
+	atusb_command(atusb, ATUSB_RX_MODE, 1);
+	ret = atusb_get_and_clear_error(atusb);
+	if (ret < 0)
+		usb_kill_anchored_urbs(&atusb->idle_urbs);
+	return ret;
+}
+
+static void atusb_stop(struct ieee802154_hw *hw)
+{
+	struct atusb *atusb = hw->priv;
+	struct usb_device *usb_dev = atusb->usb_dev;
+
+	dev_dbg(&usb_dev->dev, "atusb_stop\n");
+	usb_kill_anchored_urbs(&atusb->idle_urbs);
+	atusb_command(atusb, ATUSB_RX_MODE, 0);
+	atusb_get_and_clear_error(atusb);
+}
+
+static struct ieee802154_ops atusb_ops = {
+	.owner			= THIS_MODULE,
+	.xmit_async		= atusb_xmit,
+	.ed			= atusb_ed,
+	.set_channel		= atusb_channel,
+	.start			= atusb_start,
+	.stop			= atusb_stop,
+	.set_hw_addr_filt	= atusb_set_hw_addr_filt,
+};
+
+/* ----- Firmware and chip version information ----------------------------- */
+
+static int atusb_get_and_show_revision(struct atusb *atusb)
+{
+	struct usb_device *usb_dev = atusb->usb_dev;
+	unsigned char buffer[3];
+	int ret;
+
+	/* Get a couple of the ATMega Firmware values */
+	ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
+				ATUSB_ID, ATUSB_REQ_FROM_DEV, 0, 0,
+				buffer, 3, 1000);
+	if (ret >= 0)
+		dev_info(&usb_dev->dev,
+			 "Firmware: major: %u, minor: %u, hardware type: %u\n",
+			 buffer[0], buffer[1], buffer[2]);
+
+	return ret;
+}
+
+static int atusb_get_and_show_build(struct atusb *atusb)
+{
+	struct usb_device *usb_dev = atusb->usb_dev;
+	char build[ATUSB_BUILD_SIZE + 1];
+	int ret;
+
+	ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
+				ATUSB_BUILD, ATUSB_REQ_FROM_DEV, 0, 0,
+				build, ATUSB_BUILD_SIZE, 1000);
+	if (ret >= 0) {
+		build[ret] = 0;
+		dev_info(&usb_dev->dev, "Firmware: build %s\n", build);
+	}
+
+	return ret;
+}
+
+static int atusb_get_and_show_chip(struct atusb *atusb)
+{
+	struct usb_device *usb_dev = atusb->usb_dev;
+	uint8_t man_id_0, man_id_1, part_num, version_num;
+
+	man_id_0 = atusb_read_reg(atusb, RG_MAN_ID_0);
+	man_id_1 = atusb_read_reg(atusb, RG_MAN_ID_1);
+	part_num = atusb_read_reg(atusb, RG_PART_NUM);
+	version_num = atusb_read_reg(atusb, RG_VERSION_NUM);
+
+	if (atusb->err)
+		return atusb->err;
+
+	if ((man_id_1 << 8 | man_id_0) != ATUSB_JEDEC_ATMEL) {
+		dev_err(&usb_dev->dev,
+			"non-Atmel transceiver xxxx%02x%02x\n",
+			man_id_1, man_id_0);
+		goto fail;
+	}
+	if (part_num != 3) {
+		dev_err(&usb_dev->dev,
+			"unexpected transceiver, part 0x%02x version 0x%02x\n",
+			part_num, version_num);
+		goto fail;
+	}
+
+	dev_info(&usb_dev->dev, "ATUSB: AT86RF231 version %d\n", version_num);
+
+	return 0;
+
+fail:
+	atusb->err = -ENODEV;
+	return -ENODEV;
+}
+
+/* ----- Setup ------------------------------------------------------------- */
+
+static int atusb_probe(struct usb_interface *interface,
+		       const struct usb_device_id *id)
+{
+	struct usb_device *usb_dev = interface_to_usbdev(interface);
+	struct ieee802154_hw *hw;
+	struct atusb *atusb = NULL;
+	int ret = -ENOMEM;
+
+	hw = ieee802154_alloc_hw(sizeof(struct atusb), &atusb_ops);
+	if (!hw)
+		return -ENOMEM;
+
+	atusb = hw->priv;
+	atusb->hw = hw;
+	atusb->usb_dev = usb_get_dev(usb_dev);
+	usb_set_intfdata(interface, atusb);
+
+	atusb->shutdown = 0;
+	atusb->err = 0;
+	INIT_DELAYED_WORK(&atusb->work, atusb_work_urbs);
+	init_usb_anchor(&atusb->idle_urbs);
+	init_usb_anchor(&atusb->rx_urbs);
+
+	if (atusb_alloc_urbs(atusb, ATUSB_NUM_RX_URBS))
+		goto fail;
+
+	atusb->tx_dr.bRequestType = ATUSB_REQ_TO_DEV;
+	atusb->tx_dr.bRequest = ATUSB_TX;
+	atusb->tx_dr.wValue = cpu_to_le16(0);
+
+	atusb->tx_urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (!atusb->tx_urb)
+		goto fail;
+
+	hw->parent = &usb_dev->dev;
+	hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT;
+
+	hw->phy->current_page = 0;
+	hw->phy->current_channel = 11;	/* reset default */
+	hw->phy->supported.channels[0] = 0x7FFF800;
+	ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
+
+	atusb_command(atusb, ATUSB_RF_RESET, 0);
+	atusb_get_and_show_chip(atusb);
+	atusb_get_and_show_revision(atusb);
+	atusb_get_and_show_build(atusb);
+	ret = atusb_get_and_clear_error(atusb);
+	if (ret) {
+		dev_err(&atusb->usb_dev->dev,
+			"%s: initialization failed, error = %d\n",
+			__func__, ret);
+		goto fail;
+	}
+
+	ret = ieee802154_register_hw(hw);
+	if (ret)
+		goto fail;
+
+	/* If we just powered on, we're now in P_ON and need to enter TRX_OFF
+	 * explicitly. Any resets after that will send us straight to TRX_OFF,
+	 * making the command below redundant.
+	 */
+	atusb_write_reg(atusb, RG_TRX_STATE, STATE_FORCE_TRX_OFF);
+	msleep(1);	/* reset => TRX_OFF, tTR13 = 37 us */
+
+#if 0
+	/* Calculating the maximum time available to empty the frame buffer
+	 * on reception:
+	 *
+	 * According to [1], the inter-frame gap is
+	 * R * 20 * 16 us + 128 us
+	 * where R is a random number from 0 to 7. Furthermore, we have 20 bit
+	 * times (80 us at 250 kbps) of SHR of the next frame before the
+	 * transceiver begins storing data in the frame buffer.
+	 *
+	 * This yields a minimum time of 208 us between the last data of a
+	 * frame and the first data of the next frame. This time is further
+	 * reduced by interrupt latency in the atusb firmware.
+	 *
+	 * atusb currently needs about 500 us to retrieve a maximum-sized
+	 * frame. We therefore have to allow reception of a new frame to begin
+	 * while we retrieve the previous frame.
+	 *
+	 * [1] "JN-AN-1035 Calculating data rates in an IEEE 802.15.4-based
+	 *      network", Jennic 2006.
+	 *     http://www.jennic.com/download_file.php?supportFile=JN-AN-1035%20Calculating%20802-15-4%20Data%20Rates-1v0.pdf
+	 */
+
+	atusb_write_reg(atusb,
+			SR_REG(SR_RX_SAFE_MODE), SR_VALUE(SR_RX_SAFE_MODE, 1));
+#endif
+	atusb_write_reg(atusb, RG_IRQ_MASK, 0xff);
+
+	ret = atusb_get_and_clear_error(atusb);
+	if (!ret)
+		return 0;
+
+	dev_err(&atusb->usb_dev->dev,
+		"%s: setup failed, error = %d\n",
+		__func__, ret);
+
+	ieee802154_unregister_hw(hw);
+fail:
+	atusb_free_urbs(atusb);
+	usb_kill_urb(atusb->tx_urb);
+	usb_free_urb(atusb->tx_urb);
+	usb_put_dev(usb_dev);
+	ieee802154_free_hw(hw);
+	return ret;
+}
+
+static void atusb_disconnect(struct usb_interface *interface)
+{
+	struct atusb *atusb = usb_get_intfdata(interface);
+
+	dev_dbg(&atusb->usb_dev->dev, "atusb_disconnect\n");
+
+	atusb->shutdown = 1;
+	cancel_delayed_work_sync(&atusb->work);
+
+	usb_kill_anchored_urbs(&atusb->rx_urbs);
+	atusb_free_urbs(atusb);
+	usb_kill_urb(atusb->tx_urb);
+	usb_free_urb(atusb->tx_urb);
+
+	ieee802154_unregister_hw(atusb->hw);
+
+	ieee802154_free_hw(atusb->hw);
+
+	usb_set_intfdata(interface, NULL);
+	usb_put_dev(atusb->usb_dev);
+
+	pr_debug("atusb_disconnect done\n");
+}
+
+/* The devices we work with */
+static const struct usb_device_id atusb_device_table[] = {
+	{
+		.match_flags		= USB_DEVICE_ID_MATCH_DEVICE |
+					  USB_DEVICE_ID_MATCH_INT_INFO,
+		.idVendor		= ATUSB_VENDOR_ID,
+		.idProduct		= ATUSB_PRODUCT_ID,
+		.bInterfaceClass	= USB_CLASS_VENDOR_SPEC
+	},
+	/* end with null element */
+	{}
+};
+MODULE_DEVICE_TABLE(usb, atusb_device_table);
+
+static struct usb_driver atusb_driver = {
+	.name		= "atusb",
+	.probe		= atusb_probe,
+	.disconnect	= atusb_disconnect,
+	.id_table	= atusb_device_table,
+};
+module_usb_driver(atusb_driver);
+
+MODULE_AUTHOR("Alexander Aring <alex.aring@gmail.com>");
+MODULE_AUTHOR("Richard Sharpe <realrichardsharpe@gmail.com>");
+MODULE_AUTHOR("Stefan Schmidt <stefan@datenfreihafen.org>");
+MODULE_AUTHOR("Werner Almesberger <werner@almesberger.net>");
+MODULE_DESCRIPTION("ATUSB IEEE 802.15.4 Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ieee802154/atusb.h b/drivers/net/ieee802154/atusb.h
new file mode 100644
index 0000000..0690edc
--- /dev/null
+++ b/drivers/net/ieee802154/atusb.h
@@ -0,0 +1,84 @@
+/*
+ * atusb.h - Definitions shared between kernel and ATUSB firmware
+ *
+ * Written 2013 by Werner Almesberger <werner@almesberger.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2, or
+ * (at your option) any later version.
+ *
+ * This file should be identical for kernel and firmware.
+ * Kernel: drivers/net/ieee802154/atusb.h
+ * Firmware: ben-wpan/atusb/fw/include/atusb/atusb.h
+ */
+
+#ifndef _ATUSB_H
+#define _ATUSB_H
+
+#define ATUSB_VENDOR_ID	0x20b7	/* Qi Hardware*/
+#define ATUSB_PRODUCT_ID 0x1540	/* 802.15.4, device 0 */
+				/*     -- -         - */
+
+#define ATUSB_BUILD_SIZE 256	/* maximum build version/date message length */
+
+/* Commands to our device. Make sure this is synced with the firmware */
+enum atusb_requests {
+	ATUSB_ID			= 0x00,	/* system status/control grp */
+	ATUSB_BUILD,
+	ATUSB_RESET,
+	ATUSB_RF_RESET			= 0x10,	/* debug/test group */
+	ATUSB_POLL_INT,
+	ATUSB_TEST,			/* atusb-sil only */
+	ATUSB_TIMER,
+	ATUSB_GPIO,
+	ATUSB_SLP_TR,
+	ATUSB_GPIO_CLEANUP,
+	ATUSB_REG_WRITE			= 0x20,	/* transceiver group */
+	ATUSB_REG_READ,
+	ATUSB_BUF_WRITE,
+	ATUSB_BUF_READ,
+	ATUSB_SRAM_WRITE,
+	ATUSB_SRAM_READ,
+	ATUSB_SPI_WRITE			= 0x30,	/* SPI group */
+	ATUSB_SPI_READ1,
+	ATUSB_SPI_READ2,
+	ATUSB_SPI_WRITE2_SYNC,
+	ATUSB_RX_MODE			= 0x40, /* HardMAC group */
+	ATUSB_TX,
+};
+
+/* Direction	bRequest		wValue		wIndex	wLength
+ *
+ * ->host	ATUSB_ID		-		-	3
+ * ->host	ATUSB_BUILD		-		-	#bytes
+ * host->	ATUSB_RESET		-		-	0
+ *
+ * host->	ATUSB_RF_RESET		-		-	0
+ * ->host	ATUSB_POLL_INT		-		-	1
+ * host->	ATUSB_TEST		-		-	0
+ * ->host	ATUSB_TIMER		-		-	#bytes (6)
+ * ->host	ATUSB_GPIO		dir+data	mask+p#	3
+ * host->	ATUSB_SLP_TR		-		-	0
+ * host->	ATUSB_GPIO_CLEANUP	-		-	0
+ *
+ * host->	ATUSB_REG_WRITE		value		addr	0
+ * ->host	ATUSB_REG_READ		-		addr	1
+ * host->	ATUSB_BUF_WRITE		-		-	#bytes
+ * ->host	ATUSB_BUF_READ		-		-	#bytes
+ * host->	ATUSB_SRAM_WRITE	-		addr	#bytes
+ * ->host	ATUSB_SRAM_READ		-		addr	#bytes
+ *
+ * host->	ATUSB_SPI_WRITE		byte0		byte1	#bytes
+ * ->host	ATUSB_SPI_READ1		byte0		-	#bytes
+ * ->host	ATUSB_SPI_READ2		byte0		byte1	#bytes
+ * ->host	ATUSB_SPI_WRITE2_SYNC	byte0		byte1	0/1
+ *
+ * host->	ATUSB_RX_MODE		on		-	0
+ * host->	ATUSB_TX		flags		ack_seq	#bytes
+ */
+
+#define ATUSB_REQ_FROM_DEV	(USB_TYPE_VENDOR | USB_DIR_IN)
+#define ATUSB_REQ_TO_DEV	(USB_TYPE_VENDOR | USB_DIR_OUT)
+
+#endif /* !_ATUSB_H */
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 22/34] fakelb: creating two virtual phys per default
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (20 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 21/34] ieee802154: add support for atusb transceiver Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:44 ` [PATCH bluetooth-next 23/34] fakelb: use list_for_each_entry_safe Alexander Aring
                   ` (12 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch change the default virtual wpan phys of fakelb driver from
one to two. To have one virtual phy makes no sense, because it need at
least two virtual phy's to speak to each other.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/fakelb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index 230f7da..cc1c7df 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -27,7 +27,7 @@
 #include <net/mac802154.h>
 #include <net/cfg802154.h>
 
-static int numlbs = 1;
+static int numlbs = 2;
 
 struct fakelb_dev_priv {
 	struct ieee802154_hw *hw;
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 23/34] fakelb: use list_for_each_entry_safe
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (21 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 22/34] fakelb: creating two virtual phys per default Alexander Aring
@ 2015-05-17 19:44 ` Alexander Aring
  2015-05-17 19:45 ` [PATCH bluetooth-next 24/34] fakelb: rename fakelb_dev_priv to fakelb_phy Alexander Aring
                   ` (11 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:44 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

Iterate and removing items from a list, we should use
list_for_each_entry_safe instead list_for_each_entry to avoid accidents
by removing.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/fakelb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index cc1c7df..66f99c4 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -215,7 +215,7 @@ static void fakelb_del(struct fakelb_dev_priv *priv)
 static int fakelb_probe(struct platform_device *pdev)
 {
 	struct fakelb_priv *priv;
-	struct fakelb_dev_priv *dp;
+	struct fakelb_dev_priv *dp, *tmp;
 	int err = -ENOMEM;
 	int i;
 
@@ -238,7 +238,7 @@ static int fakelb_probe(struct platform_device *pdev)
 	return 0;
 
 err_slave:
-	list_for_each_entry(dp, &priv->list, list)
+	list_for_each_entry_safe(dp, tmp, &priv->list, list)
 		fakelb_del(dp);
 err_alloc:
 	return err;
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 24/34] fakelb: rename fakelb_dev_priv to fakelb_phy
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (22 preceding siblings ...)
  2015-05-17 19:44 ` [PATCH bluetooth-next 23/34] fakelb: use list_for_each_entry_safe Alexander Aring
@ 2015-05-17 19:45 ` Alexander Aring
  2015-05-17 19:45 ` [PATCH bluetooth-next 25/34] fakelb: don't deliver when one phy Alexander Aring
                   ` (10 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:45 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch renames fakelb_dev_priv to fakelb_phy. We don't faking
devices here, we fake wpan phys. This avoids also confusing with the
variable priv, which is used several times in this driver to represent
this structure.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/fakelb.c | 93 +++++++++++++++++++++--------------------
 1 file changed, 47 insertions(+), 46 deletions(-)

diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index 66f99c4..5c4fbb8 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -29,7 +29,7 @@
 
 static int numlbs = 2;
 
-struct fakelb_dev_priv {
+struct fakelb_phy {
 	struct ieee802154_hw *hw;
 
 	struct list_head list;
@@ -62,36 +62,37 @@ fakelb_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
 }
 
 static void
-fakelb_hw_deliver(struct fakelb_dev_priv *priv, struct sk_buff *skb)
+fakelb_hw_deliver(struct fakelb_phy *phy, struct sk_buff *skb)
 {
 	struct sk_buff *newskb;
 
-	spin_lock(&priv->lock);
-	if (priv->working) {
+	spin_lock(&phy->lock);
+	if (phy->working) {
 		newskb = pskb_copy(skb, GFP_ATOMIC);
 		if (newskb)
-			ieee802154_rx_irqsafe(priv->hw, newskb, 0xcc);
+			ieee802154_rx_irqsafe(phy->hw, newskb, 0xcc);
 	}
-	spin_unlock(&priv->lock);
+	spin_unlock(&phy->lock);
 }
 
 static int
 fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
 {
-	struct fakelb_dev_priv *priv = hw->priv;
-	struct fakelb_priv *fake = priv->fake;
+	struct fakelb_phy *current_phy = hw->priv;
+	struct fakelb_priv *fake = current_phy->fake;
 
 	read_lock_bh(&fake->lock);
-	if (priv->list.next == priv->list.prev) {
+	if (current_phy->list.next == current_phy->list.prev) {
 		/* we are the only one device */
-		fakelb_hw_deliver(priv, skb);
+		fakelb_hw_deliver(current_phy, skb);
 	} else {
-		struct fakelb_dev_priv *dp;
-		list_for_each_entry(dp, &priv->fake->list, list) {
-			if (dp != priv &&
-			    (dp->hw->phy->current_channel ==
-			     priv->hw->phy->current_channel))
-				fakelb_hw_deliver(dp, skb);
+		struct fakelb_phy *phy;
+
+		list_for_each_entry(phy, &current_phy->fake->list, list) {
+			if (current_phy != phy &&
+			    (phy->hw->phy->current_channel ==
+			     current_phy->hw->phy->current_channel))
+				fakelb_hw_deliver(phy, skb);
 		}
 	}
 	read_unlock_bh(&fake->lock);
@@ -101,26 +102,26 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
 
 static int
 fakelb_hw_start(struct ieee802154_hw *hw) {
-	struct fakelb_dev_priv *priv = hw->priv;
+	struct fakelb_phy *phy = hw->priv;
 	int ret = 0;
 
-	spin_lock(&priv->lock);
-	if (priv->working)
+	spin_lock(&phy->lock);
+	if (phy->working)
 		ret = -EBUSY;
 	else
-		priv->working = 1;
-	spin_unlock(&priv->lock);
+		phy->working = 1;
+	spin_unlock(&phy->lock);
 
 	return ret;
 }
 
 static void
 fakelb_hw_stop(struct ieee802154_hw *hw) {
-	struct fakelb_dev_priv *priv = hw->priv;
+	struct fakelb_phy *phy = hw->priv;
 
-	spin_lock(&priv->lock);
-	priv->working = 0;
-	spin_unlock(&priv->lock);
+	spin_lock(&phy->lock);
+	phy->working = 0;
+	spin_unlock(&phy->lock);
 }
 
 static const struct ieee802154_ops fakelb_ops = {
@@ -138,16 +139,16 @@ MODULE_PARM_DESC(numlbs, " number of pseudo devices");
 
 static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake)
 {
-	struct fakelb_dev_priv *priv;
+	struct fakelb_phy *phy;
 	int err;
 	struct ieee802154_hw *hw;
 
-	hw = ieee802154_alloc_hw(sizeof(*priv), &fakelb_ops);
+	hw = ieee802154_alloc_hw(sizeof(*phy), &fakelb_ops);
 	if (!hw)
 		return -ENOMEM;
 
-	priv = hw->priv;
-	priv->hw = hw;
+	phy = hw->priv;
+	phy->hw = hw;
 
 	/* 868 MHz BPSK	802.15.4-2003 */
 	hw->phy->supported.channels[0] |= 1;
@@ -180,10 +181,10 @@ static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake)
 	/* 950 MHz GFSK 802.15.4d-2009 */
 	hw->phy->supported.channels[6] |= 0x3ffc00;
 
-	INIT_LIST_HEAD(&priv->list);
-	priv->fake = fake;
+	INIT_LIST_HEAD(&phy->list);
+	phy->fake = fake;
 
-	spin_lock_init(&priv->lock);
+	spin_lock_init(&phy->lock);
 
 	hw->parent = dev;
 
@@ -192,30 +193,30 @@ static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake)
 		goto err_reg;
 
 	write_lock_bh(&fake->lock);
-	list_add_tail(&priv->list, &fake->list);
+	list_add_tail(&phy->list, &fake->list);
 	write_unlock_bh(&fake->lock);
 
 	return 0;
 
 err_reg:
-	ieee802154_free_hw(priv->hw);
+	ieee802154_free_hw(phy->hw);
 	return err;
 }
 
-static void fakelb_del(struct fakelb_dev_priv *priv)
+static void fakelb_del(struct fakelb_phy *phy)
 {
-	write_lock_bh(&priv->fake->lock);
-	list_del(&priv->list);
-	write_unlock_bh(&priv->fake->lock);
+	write_lock_bh(&phy->fake->lock);
+	list_del(&phy->list);
+	write_unlock_bh(&phy->fake->lock);
 
-	ieee802154_unregister_hw(priv->hw);
-	ieee802154_free_hw(priv->hw);
+	ieee802154_unregister_hw(phy->hw);
+	ieee802154_free_hw(phy->hw);
 }
 
 static int fakelb_probe(struct platform_device *pdev)
 {
 	struct fakelb_priv *priv;
-	struct fakelb_dev_priv *dp, *tmp;
+	struct fakelb_phy *phy, *tmp;
 	int err = -ENOMEM;
 	int i;
 
@@ -238,8 +239,8 @@ static int fakelb_probe(struct platform_device *pdev)
 	return 0;
 
 err_slave:
-	list_for_each_entry_safe(dp, tmp, &priv->list, list)
-		fakelb_del(dp);
+	list_for_each_entry_safe(phy, tmp, &priv->list, list)
+		fakelb_del(phy);
 err_alloc:
 	return err;
 }
@@ -247,10 +248,10 @@ err_alloc:
 static int fakelb_remove(struct platform_device *pdev)
 {
 	struct fakelb_priv *priv = platform_get_drvdata(pdev);
-	struct fakelb_dev_priv *dp, *temp;
+	struct fakelb_phy *phy, *temp;
 
-	list_for_each_entry_safe(dp, temp, &priv->list, list)
-		fakelb_del(dp);
+	list_for_each_entry_safe(phy, temp, &priv->list, list)
+		fakelb_del(phy);
 
 	return 0;
 }
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 25/34] fakelb: don't deliver when one phy
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (23 preceding siblings ...)
  2015-05-17 19:45 ` [PATCH bluetooth-next 24/34] fakelb: rename fakelb_dev_priv to fakelb_phy Alexander Aring
@ 2015-05-17 19:45 ` Alexander Aring
  2015-05-17 19:45 ` [PATCH bluetooth-next 26/34] fakelb: declare rwlock static Alexander Aring
                   ` (9 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:45 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

A real phy don't transmit the transmitted frame back to the phy. This
behaviour will confuse the 6LoWPAN and the upper IPv6 neighbour
discovery cache. We need now at least two virtual phy's to creating a
virtual wpan network.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/fakelb.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index 5c4fbb8..d5fb776 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -80,20 +80,16 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
 {
 	struct fakelb_phy *current_phy = hw->priv;
 	struct fakelb_priv *fake = current_phy->fake;
+	struct fakelb_phy *phy;
 
 	read_lock_bh(&fake->lock);
-	if (current_phy->list.next == current_phy->list.prev) {
-		/* we are the only one device */
-		fakelb_hw_deliver(current_phy, skb);
-	} else {
-		struct fakelb_phy *phy;
-
-		list_for_each_entry(phy, &current_phy->fake->list, list) {
-			if (current_phy != phy &&
-			    (phy->hw->phy->current_channel ==
-			     current_phy->hw->phy->current_channel))
-				fakelb_hw_deliver(phy, skb);
-		}
+	list_for_each_entry(phy, &current_phy->fake->list, list) {
+		if (current_phy == phy)
+			continue;
+
+		if (phy->hw->phy->current_channel ==
+		    current_phy->hw->phy->current_channel)
+			fakelb_hw_deliver(phy, skb);
 	}
 	read_unlock_bh(&fake->lock);
 
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 26/34] fakelb: declare rwlock static
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (24 preceding siblings ...)
  2015-05-17 19:45 ` [PATCH bluetooth-next 25/34] fakelb: don't deliver when one phy Alexander Aring
@ 2015-05-17 19:45 ` Alexander Aring
  2015-05-17 19:45 ` [PATCH bluetooth-next 27/34] fakelb: declare fakelb list static Alexander Aring
                   ` (8 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:45 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch moves the rwlock declarition into a static variable.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/fakelb.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index d5fb776..43370fb 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -28,6 +28,7 @@
 #include <net/cfg802154.h>
 
 static int numlbs = 2;
+static DEFINE_RWLOCK(fakelb_lock);
 
 struct fakelb_phy {
 	struct ieee802154_hw *hw;
@@ -41,7 +42,6 @@ struct fakelb_phy {
 
 struct fakelb_priv {
 	struct list_head list;
-	rwlock_t lock;
 };
 
 static int
@@ -79,10 +79,9 @@ static int
 fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
 {
 	struct fakelb_phy *current_phy = hw->priv;
-	struct fakelb_priv *fake = current_phy->fake;
 	struct fakelb_phy *phy;
 
-	read_lock_bh(&fake->lock);
+	read_lock_bh(&fakelb_lock);
 	list_for_each_entry(phy, &current_phy->fake->list, list) {
 		if (current_phy == phy)
 			continue;
@@ -91,7 +90,7 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
 		    current_phy->hw->phy->current_channel)
 			fakelb_hw_deliver(phy, skb);
 	}
-	read_unlock_bh(&fake->lock);
+	read_unlock_bh(&fakelb_lock);
 
 	return 0;
 }
@@ -188,9 +187,9 @@ static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake)
 	if (err)
 		goto err_reg;
 
-	write_lock_bh(&fake->lock);
+	write_lock_bh(&fakelb_lock);
 	list_add_tail(&phy->list, &fake->list);
-	write_unlock_bh(&fake->lock);
+	write_unlock_bh(&fakelb_lock);
 
 	return 0;
 
@@ -201,9 +200,9 @@ err_reg:
 
 static void fakelb_del(struct fakelb_phy *phy)
 {
-	write_lock_bh(&phy->fake->lock);
+	write_lock_bh(&fakelb_lock);
 	list_del(&phy->list);
-	write_unlock_bh(&phy->fake->lock);
+	write_unlock_bh(&fakelb_lock);
 
 	ieee802154_unregister_hw(phy->hw);
 	ieee802154_free_hw(phy->hw);
@@ -222,7 +221,6 @@ static int fakelb_probe(struct platform_device *pdev)
 		goto err_alloc;
 
 	INIT_LIST_HEAD(&priv->list);
-	rwlock_init(&priv->lock);
 
 	for (i = 0; i < numlbs; i++) {
 		err = fakelb_add_one(&pdev->dev, priv);
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 27/34] fakelb: declare fakelb list static
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (25 preceding siblings ...)
  2015-05-17 19:45 ` [PATCH bluetooth-next 26/34] fakelb: declare rwlock static Alexander Aring
@ 2015-05-17 19:45 ` Alexander Aring
  2015-05-17 19:45 ` [PATCH bluetooth-next 28/34] fakelb: move lock out of iteration Alexander Aring
                   ` (7 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:45 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch moves the fakelb list of all registered phy's in a static
declaration in the fakelb driver.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/fakelb.c | 32 +++++++-------------------------
 1 file changed, 7 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index 43370fb..c7e7d50 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -29,21 +29,17 @@
 
 static int numlbs = 2;
 static DEFINE_RWLOCK(fakelb_lock);
+static LIST_HEAD(fakelb_phys);
 
 struct fakelb_phy {
 	struct ieee802154_hw *hw;
 
 	struct list_head list;
-	struct fakelb_priv *fake;
 
 	spinlock_t lock;
 	bool working;
 };
 
-struct fakelb_priv {
-	struct list_head list;
-};
-
 static int
 fakelb_hw_ed(struct ieee802154_hw *hw, u8 *level)
 {
@@ -82,7 +78,7 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
 	struct fakelb_phy *phy;
 
 	read_lock_bh(&fakelb_lock);
-	list_for_each_entry(phy, &current_phy->fake->list, list) {
+	list_for_each_entry(phy, &fakelb_phys, list) {
 		if (current_phy == phy)
 			continue;
 
@@ -132,7 +128,7 @@ static const struct ieee802154_ops fakelb_ops = {
 module_param(numlbs, int, 0);
 MODULE_PARM_DESC(numlbs, " number of pseudo devices");
 
-static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake)
+static int fakelb_add_one(struct device *dev)
 {
 	struct fakelb_phy *phy;
 	int err;
@@ -176,9 +172,6 @@ static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake)
 	/* 950 MHz GFSK 802.15.4d-2009 */
 	hw->phy->supported.channels[6] |= 0x3ffc00;
 
-	INIT_LIST_HEAD(&phy->list);
-	phy->fake = fake;
-
 	spin_lock_init(&phy->lock);
 
 	hw->parent = dev;
@@ -188,7 +181,7 @@ static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake)
 		goto err_reg;
 
 	write_lock_bh(&fakelb_lock);
-	list_add_tail(&phy->list, &fake->list);
+	list_add_tail(&phy->list, &fakelb_phys);
 	write_unlock_bh(&fakelb_lock);
 
 	return 0;
@@ -210,41 +203,30 @@ static void fakelb_del(struct fakelb_phy *phy)
 
 static int fakelb_probe(struct platform_device *pdev)
 {
-	struct fakelb_priv *priv;
 	struct fakelb_phy *phy, *tmp;
 	int err = -ENOMEM;
 	int i;
 
-	priv = devm_kzalloc(&pdev->dev, sizeof(struct fakelb_priv),
-			    GFP_KERNEL);
-	if (!priv)
-		goto err_alloc;
-
-	INIT_LIST_HEAD(&priv->list);
-
 	for (i = 0; i < numlbs; i++) {
-		err = fakelb_add_one(&pdev->dev, priv);
+		err = fakelb_add_one(&pdev->dev);
 		if (err < 0)
 			goto err_slave;
 	}
 
-	platform_set_drvdata(pdev, priv);
 	dev_info(&pdev->dev, "added ieee802154 hardware\n");
 	return 0;
 
 err_slave:
-	list_for_each_entry_safe(phy, tmp, &priv->list, list)
+	list_for_each_entry_safe(phy, tmp, &fakelb_phys, list)
 		fakelb_del(phy);
-err_alloc:
 	return err;
 }
 
 static int fakelb_remove(struct platform_device *pdev)
 {
-	struct fakelb_priv *priv = platform_get_drvdata(pdev);
 	struct fakelb_phy *phy, *temp;
 
-	list_for_each_entry_safe(phy, temp, &priv->list, list)
+	list_for_each_entry_safe(phy, temp, &fakelb_phys, list)
 		fakelb_del(phy);
 
 	return 0;
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 28/34] fakelb: move lock out of iteration
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (26 preceding siblings ...)
  2015-05-17 19:45 ` [PATCH bluetooth-next 27/34] fakelb: declare fakelb list static Alexander Aring
@ 2015-05-17 19:45 ` Alexander Aring
  2015-05-17 19:45 ` [PATCH bluetooth-next 29/34] fakelb: introduce fakelb ifup phys list Alexander Aring
                   ` (6 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:45 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

The list need to be protected while iteration which is need when other
list iterates at the same time over this list.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/fakelb.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index c7e7d50..e1c0195 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -193,9 +193,7 @@ err_reg:
 
 static void fakelb_del(struct fakelb_phy *phy)
 {
-	write_lock_bh(&fakelb_lock);
 	list_del(&phy->list);
-	write_unlock_bh(&fakelb_lock);
 
 	ieee802154_unregister_hw(phy->hw);
 	ieee802154_free_hw(phy->hw);
@@ -217,8 +215,10 @@ static int fakelb_probe(struct platform_device *pdev)
 	return 0;
 
 err_slave:
+	write_lock_bh(&fakelb_lock);
 	list_for_each_entry_safe(phy, tmp, &fakelb_phys, list)
 		fakelb_del(phy);
+	write_unlock_bh(&fakelb_lock);
 	return err;
 }
 
@@ -226,9 +226,10 @@ static int fakelb_remove(struct platform_device *pdev)
 {
 	struct fakelb_phy *phy, *temp;
 
+	write_lock_bh(&fakelb_lock);
 	list_for_each_entry_safe(phy, temp, &fakelb_phys, list)
 		fakelb_del(phy);
-
+	write_unlock_bh(&fakelb_lock);
 	return 0;
 }
 
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 29/34] fakelb: introduce fakelb ifup phys list
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (27 preceding siblings ...)
  2015-05-17 19:45 ` [PATCH bluetooth-next 28/34] fakelb: move lock out of iteration Alexander Aring
@ 2015-05-17 19:45 ` Alexander Aring
  2015-05-17 19:45 ` [PATCH bluetooth-next 30/34] fakelb: use own channel and page attributes Alexander Aring
                   ` (5 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:45 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch introduce a fakelb ifup phys list, which stores all
registered phys which are in an operated mode. This will reduce the
iterations of non-operated phys while transmit frames. There exists two
locks now, one rwlock for the operated interfaces and the spinlock for
protecting the list for all registered virtual phys.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/fakelb.c | 58 ++++++++++++++++++-----------------------
 1 file changed, 25 insertions(+), 33 deletions(-)

diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index e1c0195..83957de 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -28,16 +28,18 @@
 #include <net/cfg802154.h>
 
 static int numlbs = 2;
-static DEFINE_RWLOCK(fakelb_lock);
+
 static LIST_HEAD(fakelb_phys);
+static DEFINE_SPINLOCK(fakelb_phys_lock);
+
+static LIST_HEAD(fakelb_ifup_phys);
+static DEFINE_RWLOCK(fakelb_ifup_phys_lock);
 
 struct fakelb_phy {
 	struct ieee802154_hw *hw;
 
 	struct list_head list;
-
-	spinlock_t lock;
-	bool working;
+	struct list_head list_ifup;
 };
 
 static int
@@ -62,13 +64,9 @@ fakelb_hw_deliver(struct fakelb_phy *phy, struct sk_buff *skb)
 {
 	struct sk_buff *newskb;
 
-	spin_lock(&phy->lock);
-	if (phy->working) {
-		newskb = pskb_copy(skb, GFP_ATOMIC);
-		if (newskb)
-			ieee802154_rx_irqsafe(phy->hw, newskb, 0xcc);
-	}
-	spin_unlock(&phy->lock);
+	newskb = pskb_copy(skb, GFP_ATOMIC);
+	if (newskb)
+		ieee802154_rx_irqsafe(phy->hw, newskb, 0xcc);
 }
 
 static int
@@ -77,8 +75,8 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
 	struct fakelb_phy *current_phy = hw->priv;
 	struct fakelb_phy *phy;
 
-	read_lock_bh(&fakelb_lock);
-	list_for_each_entry(phy, &fakelb_phys, list) {
+	read_lock_bh(&fakelb_ifup_phys_lock);
+	list_for_each_entry(phy, &fakelb_ifup_phys, list_ifup) {
 		if (current_phy == phy)
 			continue;
 
@@ -86,7 +84,7 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
 		    current_phy->hw->phy->current_channel)
 			fakelb_hw_deliver(phy, skb);
 	}
-	read_unlock_bh(&fakelb_lock);
+	read_unlock_bh(&fakelb_ifup_phys_lock);
 
 	return 0;
 }
@@ -94,25 +92,21 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
 static int
 fakelb_hw_start(struct ieee802154_hw *hw) {
 	struct fakelb_phy *phy = hw->priv;
-	int ret = 0;
 
-	spin_lock(&phy->lock);
-	if (phy->working)
-		ret = -EBUSY;
-	else
-		phy->working = 1;
-	spin_unlock(&phy->lock);
+	write_lock_bh(&fakelb_ifup_phys_lock);
+	list_add(&phy->list_ifup, &fakelb_ifup_phys);
+	write_unlock_bh(&fakelb_ifup_phys_lock);
 
-	return ret;
+	return 0;
 }
 
 static void
 fakelb_hw_stop(struct ieee802154_hw *hw) {
 	struct fakelb_phy *phy = hw->priv;
 
-	spin_lock(&phy->lock);
-	phy->working = 0;
-	spin_unlock(&phy->lock);
+	write_lock_bh(&fakelb_ifup_phys_lock);
+	list_del(&phy->list_ifup);
+	write_unlock_bh(&fakelb_ifup_phys_lock);
 }
 
 static const struct ieee802154_ops fakelb_ops = {
@@ -172,17 +166,15 @@ static int fakelb_add_one(struct device *dev)
 	/* 950 MHz GFSK 802.15.4d-2009 */
 	hw->phy->supported.channels[6] |= 0x3ffc00;
 
-	spin_lock_init(&phy->lock);
-
 	hw->parent = dev;
 
 	err = ieee802154_register_hw(hw);
 	if (err)
 		goto err_reg;
 
-	write_lock_bh(&fakelb_lock);
+	spin_lock(&fakelb_phys_lock);
 	list_add_tail(&phy->list, &fakelb_phys);
-	write_unlock_bh(&fakelb_lock);
+	spin_unlock(&fakelb_phys_lock);
 
 	return 0;
 
@@ -215,10 +207,10 @@ static int fakelb_probe(struct platform_device *pdev)
 	return 0;
 
 err_slave:
-	write_lock_bh(&fakelb_lock);
+	spin_lock(&fakelb_phys_lock);
 	list_for_each_entry_safe(phy, tmp, &fakelb_phys, list)
 		fakelb_del(phy);
-	write_unlock_bh(&fakelb_lock);
+	spin_unlock(&fakelb_phys_lock);
 	return err;
 }
 
@@ -226,10 +218,10 @@ static int fakelb_remove(struct platform_device *pdev)
 {
 	struct fakelb_phy *phy, *temp;
 
-	write_lock_bh(&fakelb_lock);
+	spin_lock(&fakelb_phys_lock);
 	list_for_each_entry_safe(phy, temp, &fakelb_phys, list)
 		fakelb_del(phy);
-	write_unlock_bh(&fakelb_lock);
+	spin_unlock(&fakelb_phys_lock);
 	return 0;
 }
 
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 30/34] fakelb: use own channel and page attributes
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (28 preceding siblings ...)
  2015-05-17 19:45 ` [PATCH bluetooth-next 29/34] fakelb: introduce fakelb ifup phys list Alexander Aring
@ 2015-05-17 19:45 ` Alexander Aring
  2015-05-17 19:45 ` [PATCH bluetooth-next 31/34] fakelb: add virtual phy reset defaults Alexander Aring
                   ` (4 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:45 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch adds an own phy attribute for page and channel into
fakelb_phy. The current way is to use the internal mac802154 stored phy
pib values which can occur in locking issues while using it inside the
driver layer.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/fakelb.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index 83957de..c60837e 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -38,6 +38,9 @@ static DEFINE_RWLOCK(fakelb_ifup_phys_lock);
 struct fakelb_phy {
 	struct ieee802154_hw *hw;
 
+	u8 page;
+	u8 channel;
+
 	struct list_head list;
 	struct list_head list_ifup;
 };
@@ -54,8 +57,12 @@ fakelb_hw_ed(struct ieee802154_hw *hw, u8 *level)
 static int
 fakelb_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
 {
-	pr_debug("set channel to %d\n", channel);
+	struct fakelb_phy *phy = hw->priv;
 
+	write_lock_bh(&fakelb_ifup_phys_lock);
+	phy->page = page;
+	phy->channel = channel;
+	write_unlock_bh(&fakelb_ifup_phys_lock);
 	return 0;
 }
 
@@ -80,8 +87,8 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
 		if (current_phy == phy)
 			continue;
 
-		if (phy->hw->phy->current_channel ==
-		    current_phy->hw->phy->current_channel)
+		if (current_phy->page == phy->page &&
+		    current_phy->channel == phy->channel)
 			fakelb_hw_deliver(phy, skb);
 	}
 	read_unlock_bh(&fakelb_ifup_phys_lock);
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 31/34] fakelb: add virtual phy reset defaults
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (29 preceding siblings ...)
  2015-05-17 19:45 ` [PATCH bluetooth-next 30/34] fakelb: use own channel and page attributes Alexander Aring
@ 2015-05-17 19:45 ` Alexander Aring
  2015-05-17 19:45 ` [PATCH bluetooth-next 32/34] fakelb: remove fakelb_hw_deliver Alexander Aring
                   ` (3 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:45 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch adds reset defaults for the fakelb phy. I used the channel 13
and page 0 which is the same default like at86rf233.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/fakelb.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index c60837e..d693a53 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -173,6 +173,11 @@ static int fakelb_add_one(struct device *dev)
 	/* 950 MHz GFSK 802.15.4d-2009 */
 	hw->phy->supported.channels[6] |= 0x3ffc00;
 
+	ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
+	/* fake phy channel 13 as default */
+	hw->phy->current_channel = 13;
+	phy->channel = hw->phy->current_channel;
+
 	hw->parent = dev;
 
 	err = ieee802154_register_hw(hw);
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 32/34] fakelb: remove fakelb_hw_deliver
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (30 preceding siblings ...)
  2015-05-17 19:45 ` [PATCH bluetooth-next 31/34] fakelb: add virtual phy reset defaults Alexander Aring
@ 2015-05-17 19:45 ` Alexander Aring
  2015-05-17 19:45 ` [PATCH bluetooth-next 33/34] fakelb: add support for async xmit handling Alexander Aring
                   ` (2 subsequent siblings)
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:45 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch cleanups the fakelb_hw_deliver function by removing them.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/fakelb.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index d693a53..10e2d27 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -66,16 +66,6 @@ fakelb_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
 	return 0;
 }
 
-static void
-fakelb_hw_deliver(struct fakelb_phy *phy, struct sk_buff *skb)
-{
-	struct sk_buff *newskb;
-
-	newskb = pskb_copy(skb, GFP_ATOMIC);
-	if (newskb)
-		ieee802154_rx_irqsafe(phy->hw, newskb, 0xcc);
-}
-
 static int
 fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
 {
@@ -88,8 +78,12 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
 			continue;
 
 		if (current_phy->page == phy->page &&
-		    current_phy->channel == phy->channel)
-			fakelb_hw_deliver(phy, skb);
+		    current_phy->channel == phy->channel) {
+			struct sk_buff *newskb = pskb_copy(skb, GFP_ATOMIC);
+
+			if (newskb)
+				ieee802154_rx_irqsafe(phy->hw, newskb, 0xcc);
+		}
 	}
 	read_unlock_bh(&fakelb_ifup_phys_lock);
 
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 33/34] fakelb: add support for async xmit handling
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (31 preceding siblings ...)
  2015-05-17 19:45 ` [PATCH bluetooth-next 32/34] fakelb: remove fakelb_hw_deliver Alexander Aring
@ 2015-05-17 19:45 ` Alexander Aring
  2015-05-17 19:45 ` [PATCH bluetooth-next 34/34] fakelb: cleanup code Alexander Aring
  2015-05-19  9:50 ` [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Marcel Holtmann
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:45 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch will add async xmit support for the fakelb driver.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/fakelb.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index 10e2d27..8f37ea0 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -87,6 +87,7 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
 	}
 	read_unlock_bh(&fakelb_ifup_phys_lock);
 
+	ieee802154_xmit_complete(hw, skb, false);
 	return 0;
 }
 
@@ -112,7 +113,7 @@ fakelb_hw_stop(struct ieee802154_hw *hw) {
 
 static const struct ieee802154_ops fakelb_ops = {
 	.owner = THIS_MODULE,
-	.xmit_sync = fakelb_hw_xmit,
+	.xmit_async = fakelb_hw_xmit,
 	.ed = fakelb_hw_ed,
 	.set_channel = fakelb_hw_channel,
 	.start = fakelb_hw_start,
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH bluetooth-next 34/34] fakelb: cleanup code
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (32 preceding siblings ...)
  2015-05-17 19:45 ` [PATCH bluetooth-next 33/34] fakelb: add support for async xmit handling Alexander Aring
@ 2015-05-17 19:45 ` Alexander Aring
  2015-05-19  9:50 ` [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Marcel Holtmann
  34 siblings, 0 replies; 45+ messages in thread
From: Alexander Aring @ 2015-05-17 19:45 UTC (permalink / raw)
  To: linux-wpan; +Cc: kernel, marcel, Alexander Aring

This patch just cleanups the code at several places.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
 drivers/net/ieee802154/fakelb.c | 29 ++++++++++++-----------------
 1 file changed, 12 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index 8f37ea0..9d0da4e 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -45,8 +45,7 @@ struct fakelb_phy {
 	struct list_head list_ifup;
 };
 
-static int
-fakelb_hw_ed(struct ieee802154_hw *hw, u8 *level)
+static int fakelb_hw_ed(struct ieee802154_hw *hw, u8 *level)
 {
 	BUG_ON(!level);
 	*level = 0xbe;
@@ -54,8 +53,7 @@ fakelb_hw_ed(struct ieee802154_hw *hw, u8 *level)
 	return 0;
 }
 
-static int
-fakelb_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
+static int fakelb_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
 {
 	struct fakelb_phy *phy = hw->priv;
 
@@ -66,11 +64,9 @@ fakelb_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
 	return 0;
 }
 
-static int
-fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
+static int fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
 {
-	struct fakelb_phy *current_phy = hw->priv;
-	struct fakelb_phy *phy;
+	struct fakelb_phy *current_phy = hw->priv, *phy;
 
 	read_lock_bh(&fakelb_ifup_phys_lock);
 	list_for_each_entry(phy, &fakelb_ifup_phys, list_ifup) {
@@ -91,8 +87,8 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
 	return 0;
 }
 
-static int
-fakelb_hw_start(struct ieee802154_hw *hw) {
+static int fakelb_hw_start(struct ieee802154_hw *hw)
+{
 	struct fakelb_phy *phy = hw->priv;
 
 	write_lock_bh(&fakelb_ifup_phys_lock);
@@ -102,8 +98,8 @@ fakelb_hw_start(struct ieee802154_hw *hw) {
 	return 0;
 }
 
-static void
-fakelb_hw_stop(struct ieee802154_hw *hw) {
+static void fakelb_hw_stop(struct ieee802154_hw *hw)
+{
 	struct fakelb_phy *phy = hw->priv;
 
 	write_lock_bh(&fakelb_ifup_phys_lock);
@@ -126,9 +122,9 @@ MODULE_PARM_DESC(numlbs, " number of pseudo devices");
 
 static int fakelb_add_one(struct device *dev)
 {
+	struct ieee802154_hw *hw;
 	struct fakelb_phy *phy;
 	int err;
-	struct ieee802154_hw *hw;
 
 	hw = ieee802154_alloc_hw(sizeof(*phy), &fakelb_ops);
 	if (!hw)
@@ -201,8 +197,7 @@ static void fakelb_del(struct fakelb_phy *phy)
 static int fakelb_probe(struct platform_device *pdev)
 {
 	struct fakelb_phy *phy, *tmp;
-	int err = -ENOMEM;
-	int i;
+	int err, i;
 
 	for (i = 0; i < numlbs; i++) {
 		err = fakelb_add_one(&pdev->dev);
@@ -223,10 +218,10 @@ err_slave:
 
 static int fakelb_remove(struct platform_device *pdev)
 {
-	struct fakelb_phy *phy, *temp;
+	struct fakelb_phy *phy, *tmp;
 
 	spin_lock(&fakelb_phys_lock);
-	list_for_each_entry_safe(phy, temp, &fakelb_phys, list)
+	list_for_each_entry_safe(phy, tmp, &fakelb_phys, list)
 		fakelb_del(phy);
 	spin_unlock(&fakelb_phys_lock);
 	return 0;
-- 
2.3.7


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* Re: [PATCH bluetooth-next 06/34] ieee802154: introduce wpan_phy_supported
  2015-05-17 19:44 ` [PATCH bluetooth-next 06/34] ieee802154: introduce wpan_phy_supported Alexander Aring
@ 2015-05-18 10:19   ` Varka Bhadram
  0 siblings, 0 replies; 45+ messages in thread
From: Varka Bhadram @ 2015-05-18 10:19 UTC (permalink / raw)
  To: Alexander Aring, linux-wpan; +Cc: kernel, marcel, Alan Ott

Hi,

On 05/18/2015 01:14 AM, Alexander Aring wrote:

> This patch introduce the wpan_phy_supported struct for wpan_phy. There
> is currently no way to check if a transceiver can handle IEEE 802.15.4
> complaint values. With this struct we can check before if the
> transceiver supports these values before sending to driver layer.
>
> Signed-off-by: Alexander Aring <alex.aring@gmail.com>
> Suggested-by: Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>
> Cc: Varka Bhadram <varkabhadram@gmail.com>
> Cc: Alan Ott <alan@signal11.us>
> ---
>   drivers/net/ieee802154/at86rf230.c |  8 ++++----
>   drivers/net/ieee802154/cc2520.c    |  2 +-
>   drivers/net/ieee802154/fakelb.c    | 30 +++++++++++++++---------------
>   drivers/net/ieee802154/mrf24j40.c  |  2 +-
>   include/net/cfg802154.h            |  6 +++++-
>   net/ieee802154/nl-phy.c            |  4 ++--
>   net/ieee802154/nl802154.c          |  4 ++--
>   7 files changed, 30 insertions(+), 26 deletions(-)

Acked-by: Varka Bhadram <varkabhadram@gmail.com>

-- 
Varka Bhadram


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework
  2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
                   ` (33 preceding siblings ...)
  2015-05-17 19:45 ` [PATCH bluetooth-next 34/34] fakelb: cleanup code Alexander Aring
@ 2015-05-19  9:50 ` Marcel Holtmann
  34 siblings, 0 replies; 45+ messages in thread
From: Marcel Holtmann @ 2015-05-19  9:50 UTC (permalink / raw)
  To: Alexander Aring; +Cc: linux-wpan, kernel

Hi Alex,

> this patch series contains mainly the following changes:
> 
> - add support for phy capabilities
> - add support for atusb transceiver
> - rework fakelb driver implementation
> 
> Some of them patches was already send to wpan mailinglist, I did few
> changes. These are:
> 
> - add "atusb" prefix in some of the static function in atusb driver
> - a cleanup which move dev_consume_skb_any(skb) out of if and else
>   branch. It's just called always, before it the call was in the
>   if and else branch. See patch ("mac802154: tx: allow xmit complete
>   from hard irq")
> - fix typo s/serveral/several in patch ("fakelb: cleanup code")
> 
> This patch series does _not_ include the mib/pib locks removal and
> atomic_t for the data/beacon sequence number. These patches depends
> on another patch ("mac802154: fix hold rtnl while ioctl") which should
> go into bluetooth. I will send in the next days a patch series for bluetooth
> which contains the ("mac802154: fix hold rtnl while ioctl") patch. If I seeing
> this patch inside of bluetooth-next then I will send the mib/pib locks removal
> and atomic_t for the data/beacon sequence number again for bluetooth-next.
> Please let me know if this handling is fine. I think this avoids some merge
> conflicts then.
> 
> Thanks.
> 
> - Alex
> 
> Alexander Aring (33):
>  nl802154: cleanup invalid argument handling
>  ieee802154: move validation check out of softmac
>  ieee802154: change transmit power to s32
>  ieee802154: change transmit power to mbm
>  ieee802154: change cca ed level to mbm
>  ieee802154: introduce wpan_phy_supported
>  ieee802154: add several phy supported handling
>  mac802154: check for really changes
>  mac802154: remove check if operation is supported
>  cfg802154: introduce wpan phy flags
>  ieee802154: add iftypes capability
>  at86rf230: set cca_modes supported flags
>  at86rf230: rework tx power support
>  at86rf230: rework tx cca energy detection level
>  at86rf230: add cca ed level reset value
>  at86rf230: add reset states of tx power level
>  nl802154: add support for dump phy capabilities
>  at86rf230: fix callback for aret handling
>  mac802154: tx: allow xmit complete from hard irq
>  ieee802154: add support for atusb transceiver
>  fakelb: creating two virtual phys per default
>  fakelb: use list_for_each_entry_safe
>  fakelb: rename fakelb_dev_priv to fakelb_phy
>  fakelb: don't deliver when one phy
>  fakelb: declare rwlock static
>  fakelb: declare fakelb list static
>  fakelb: move lock out of iteration
>  fakelb: introduce fakelb ifup phys list
>  fakelb: use own channel and page attributes
>  fakelb: add virtual phy reset defaults
>  fakelb: remove fakelb_hw_deliver
>  fakelb: add support for async xmit handling
>  fakelb: cleanup code
> 
> Martin Townsend (1):
>  mac802154: fakelb: Fix potential NULL pointer dereference.
> 
> drivers/net/ieee802154/Kconfig     |  10 +
> drivers/net/ieee802154/Makefile    |   1 +
> drivers/net/ieee802154/at86rf230.c | 376 ++++++++------------
> drivers/net/ieee802154/at86rf230.h | 220 ++++++++++++
> drivers/net/ieee802154/atusb.c     | 692 +++++++++++++++++++++++++++++++++++++
> drivers/net/ieee802154/atusb.h     |  84 +++++
> drivers/net/ieee802154/cc2520.c    |   2 +-
> drivers/net/ieee802154/fakelb.c    | 209 +++++------
> drivers/net/ieee802154/mrf24j40.c  |   2 +-
> include/net/cfg802154.h            |  62 +++-
> include/net/mac802154.h            |  38 +-
> include/net/nl802154.h             |  79 +++++
> net/ieee802154/nl-mac.c            |   8 +-
> net/ieee802154/nl-phy.c            |   4 +-
> net/ieee802154/nl802154.c          | 209 +++++++++--
> net/mac802154/cfg.c                |  63 +---
> net/mac802154/driver-ops.h         |   8 +-
> net/mac802154/mac_cmd.c            |   6 +-
> net/mac802154/main.c               |  32 ++
> net/mac802154/util.c               |   5 +-
> 20 files changed, 1639 insertions(+), 471 deletions(-)
> create mode 100644 drivers/net/ieee802154/at86rf230.h
> create mode 100644 drivers/net/ieee802154/atusb.c
> create mode 100644 drivers/net/ieee802154/atusb.h

all 34 patches have been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH bluetooth-next 21/34] ieee802154: add support for atusb transceiver
  2015-05-17 19:44 ` [PATCH bluetooth-next 21/34] ieee802154: add support for atusb transceiver Alexander Aring
@ 2015-05-19 10:49   ` Stefan Schmidt
  2015-05-19 11:52     ` Alexander Aring
                       ` (2 more replies)
  0 siblings, 3 replies; 45+ messages in thread
From: Stefan Schmidt @ 2015-05-19 10:49 UTC (permalink / raw)
  To: Alexander Aring, linux-wpan
  Cc: kernel, marcel, Werner Almesberger, Richard Sharpe

Hello.

On 17/05/15 21:44, Alexander Aring wrote:
> This patch adds support for the atusb transceiver.
>
> The current driver supports basic functionality only. Possible further
> tasks would be to sync functionality with the at86rf230 driver, because
> the atusb use internally an at86rf231 transceiver. Some of these
> features need a firmware update like AACK and ARET handling.

We should really have a firmware release now that runs with the mainline 
driver. For new features we can then check the fw version in the driver 
and enable/disable accordingly.

Werner, is this something you would do? Making a release of the 
firmware? Or should Alexander or myself look into this?

> I did small changes to this driver to work with xmit_async callback and
> setting of a random extended perm address.

Thanks!

> Signed-off-by: Alexander Aring <alex.aring@gmail.com>
> Cc: Werner Almesberger <werner@almesberger.net>
> Cc: Stefan Schmidt <s.schmidt@samsung.com>
> Cc: Richard Sharpe <realrichardsharpe@gmail.com>
> ---
>   drivers/net/ieee802154/Kconfig     |  10 +
>   drivers/net/ieee802154/Makefile    |   1 +
>   drivers/net/ieee802154/at86rf230.c | 199 +----------
>   drivers/net/ieee802154/at86rf230.h | 220 ++++++++++++
>   drivers/net/ieee802154/atusb.c     | 692
> +++++++++++++++++++++++++++++++++++++
>   drivers/net/ieee802154/atusb.h     |  84 +++++
>   6 files changed, 1009 insertions(+), 197 deletions(-)
>   create mode 100644 drivers/net/ieee802154/at86rf230.h
>   create mode 100644 drivers/net/ieee802154/atusb.c
>   create mode 100644 drivers/net/ieee802154/atusb.h
>
> diff --git a/drivers/net/ieee802154/Kconfig
> b/drivers/net/ieee802154/Kconfig
> index 1a3c3e5..1dd5ab8 100644
> --- a/drivers/net/ieee802154/Kconfig
> +++ b/drivers/net/ieee802154/Kconfig
> @@ -53,3 +53,13 @@ config IEEE802154_CC2520
>
>   	  This driver can also be built as a module. To do so, say M here.
>   	  the module will be called 'cc2520'.
> +
> +config IEEE802154_ATUSB
> +	tristate "ATUSB transceiver driver"
> +	depends on IEEE802154_DRIVERS && MAC802154 && USB
> +	---help---
> +	  Say Y here to enable the ATUSB IEEE 802.15.4 wireless
> +	  controller.
> +
> +	  This driver can also be built as a module. To do so say M here.
> +	  The module will be called 'atusb'.
> diff --git a/drivers/net/ieee802154/Makefile
> b/drivers/net/ieee802154/Makefile
> index d77fa4d..cf1d2a6 100644
> --- a/drivers/net/ieee802154/Makefile
> +++ b/drivers/net/ieee802154/Makefile
> @@ -2,3 +2,4 @@ obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o
>   obj-$(CONFIG_IEEE802154_AT86RF230) += at86rf230.o
>   obj-$(CONFIG_IEEE802154_MRF24J40) += mrf24j40.o
>   obj-$(CONFIG_IEEE802154_CC2520) += cc2520.o
> +obj-$(CONFIG_IEEE802154_ATUSB) += atusb.o
> diff --git a/drivers/net/ieee802154/at86rf230.c
> b/drivers/net/ieee802154/at86rf230.c
> index 8d5ed6e..d417ceb 100644
> --- a/drivers/net/ieee802154/at86rf230.c
> +++ b/drivers/net/ieee802154/at86rf230.c
> @@ -35,6 +35,8 @@
>   #include <net/mac802154.h>
>   #include <net/cfg802154.h>
>
> +#include "at86rf230.h"
> +
>   struct at86rf230_local;
>   /* at86rf2xx chip depend data.
>    * All timings are in us.
> @@ -102,203 +104,6 @@ struct at86rf230_local {
>   	struct at86rf230_state_change tx;
>   };
>
> -#define RG_TRX_STATUS	(0x01)
> -#define SR_TRX_STATUS		0x01, 0x1f, 0
> -#define SR_RESERVED_01_3	0x01, 0x20, 5
> -#define SR_CCA_STATUS		0x01, 0x40, 6
> -#define SR_CCA_DONE		0x01, 0x80, 7
> -#define RG_TRX_STATE	(0x02)
> -#define SR_TRX_CMD		0x02, 0x1f, 0
> -#define SR_TRAC_STATUS		0x02, 0xe0, 5
> -#define RG_TRX_CTRL_0	(0x03)
> -#define SR_CLKM_CTRL		0x03, 0x07, 0
> -#define SR_CLKM_SHA_SEL		0x03, 0x08, 3
> -#define SR_PAD_IO_CLKM		0x03, 0x30, 4
> -#define SR_PAD_IO		0x03, 0xc0, 6
> -#define RG_TRX_CTRL_1	(0x04)
> -#define SR_IRQ_POLARITY		0x04, 0x01, 0
> -#define SR_IRQ_MASK_MODE	0x04, 0x02, 1
> -#define SR_SPI_CMD_MODE		0x04, 0x0c, 2
> -#define SR_RX_BL_CTRL		0x04, 0x10, 4
> -#define SR_TX_AUTO_CRC_ON	0x04, 0x20, 5
> -#define SR_IRQ_2_EXT_EN		0x04, 0x40, 6
> -#define SR_PA_EXT_EN		0x04, 0x80, 7
> -#define RG_PHY_TX_PWR	(0x05)
> -#define SR_TX_PWR_23X		0x05, 0x0f, 0
> -#define SR_PA_LT_230		0x05, 0x30, 4
> -#define SR_PA_BUF_LT_230	0x05, 0xc0, 6
> -#define SR_TX_PWR_212		0x05, 0x1f, 0
> -#define SR_GC_PA_212		0x05, 0x60, 5
> -#define SR_PA_BOOST_LT_212	0x05, 0x80, 7
> -#define RG_PHY_RSSI	(0x06)
> -#define SR_RSSI			0x06, 0x1f, 0
> -#define SR_RND_VALUE		0x06, 0x60, 5
> -#define SR_RX_CRC_VALID		0x06, 0x80, 7
> -#define RG_PHY_ED_LEVEL	(0x07)
> -#define SR_ED_LEVEL		0x07, 0xff, 0
> -#define RG_PHY_CC_CCA	(0x08)
> -#define SR_CHANNEL		0x08, 0x1f, 0
> -#define SR_CCA_MODE		0x08, 0x60, 5
> -#define SR_CCA_REQUEST		0x08, 0x80, 7
> -#define RG_CCA_THRES	(0x09)
> -#define SR_CCA_ED_THRES		0x09, 0x0f, 0
> -#define SR_RESERVED_09_1	0x09, 0xf0, 4
> -#define RG_RX_CTRL	(0x0a)
> -#define SR_PDT_THRES		0x0a, 0x0f, 0
> -#define SR_RESERVED_0a_1	0x0a, 0xf0, 4
> -#define RG_SFD_VALUE	(0x0b)
> -#define SR_SFD_VALUE		0x0b, 0xff, 0
> -#define RG_TRX_CTRL_2	(0x0c)
> -#define SR_OQPSK_DATA_RATE	0x0c, 0x03, 0
> -#define SR_SUB_MODE		0x0c, 0x04, 2
> -#define SR_BPSK_QPSK		0x0c, 0x08, 3
> -#define SR_OQPSK_SUB1_RC_EN	0x0c, 0x10, 4
> -#define SR_RESERVED_0c_5	0x0c, 0x60, 5
> -#define SR_RX_SAFE_MODE		0x0c, 0x80, 7
> -#define RG_ANT_DIV	(0x0d)
> -#define SR_ANT_CTRL		0x0d, 0x03, 0
> -#define SR_ANT_EXT_SW_EN	0x0d, 0x04, 2
> -#define SR_ANT_DIV_EN		0x0d, 0x08, 3
> -#define SR_RESERVED_0d_2	0x0d, 0x70, 4
> -#define SR_ANT_SEL		0x0d, 0x80, 7
> -#define RG_IRQ_MASK	(0x0e)
> -#define SR_IRQ_MASK		0x0e, 0xff, 0
> -#define RG_IRQ_STATUS	(0x0f)
> -#define SR_IRQ_0_PLL_LOCK	0x0f, 0x01, 0
> -#define SR_IRQ_1_PLL_UNLOCK	0x0f, 0x02, 1
> -#define SR_IRQ_2_RX_START	0x0f, 0x04, 2
> -#define SR_IRQ_3_TRX_END	0x0f, 0x08, 3
> -#define SR_IRQ_4_CCA_ED_DONE	0x0f, 0x10, 4
> -#define SR_IRQ_5_AMI		0x0f, 0x20, 5
> -#define SR_IRQ_6_TRX_UR		0x0f, 0x40, 6
> -#define SR_IRQ_7_BAT_LOW	0x0f, 0x80, 7
> -#define RG_VREG_CTRL	(0x10)
> -#define SR_RESERVED_10_6	0x10, 0x03, 0
> -#define SR_DVDD_OK		0x10, 0x04, 2
> -#define SR_DVREG_EXT		0x10, 0x08, 3
> -#define SR_RESERVED_10_3	0x10, 0x30, 4
> -#define SR_AVDD_OK		0x10, 0x40, 6
> -#define SR_AVREG_EXT		0x10, 0x80, 7
> -#define RG_BATMON	(0x11)
> -#define SR_BATMON_VTH		0x11, 0x0f, 0
> -#define SR_BATMON_HR		0x11, 0x10, 4
> -#define SR_BATMON_OK		0x11, 0x20, 5
> -#define SR_RESERVED_11_1	0x11, 0xc0, 6
> -#define RG_XOSC_CTRL	(0x12)
> -#define SR_XTAL_TRIM		0x12, 0x0f, 0
> -#define SR_XTAL_MODE		0x12, 0xf0, 4
> -#define RG_RX_SYN	(0x15)
> -#define SR_RX_PDT_LEVEL		0x15, 0x0f, 0
> -#define SR_RESERVED_15_2	0x15, 0x70, 4
> -#define SR_RX_PDT_DIS		0x15, 0x80, 7
> -#define RG_XAH_CTRL_1	(0x17)
> -#define SR_RESERVED_17_8	0x17, 0x01, 0
> -#define SR_AACK_PROM_MODE	0x17, 0x02, 1
> -#define SR_AACK_ACK_TIME	0x17, 0x04, 2
> -#define SR_RESERVED_17_5	0x17, 0x08, 3
> -#define SR_AACK_UPLD_RES_FT	0x17, 0x10, 4
> -#define SR_AACK_FLTR_RES_FT	0x17, 0x20, 5
> -#define SR_CSMA_LBT_MODE	0x17, 0x40, 6
> -#define SR_RESERVED_17_1	0x17, 0x80, 7
> -#define RG_FTN_CTRL	(0x18)
> -#define SR_RESERVED_18_2	0x18, 0x7f, 0
> -#define SR_FTN_START		0x18, 0x80, 7
> -#define RG_PLL_CF	(0x1a)
> -#define SR_RESERVED_1a_2	0x1a, 0x7f, 0
> -#define SR_PLL_CF_START		0x1a, 0x80, 7
> -#define RG_PLL_DCU	(0x1b)
> -#define SR_RESERVED_1b_3	0x1b, 0x3f, 0
> -#define SR_RESERVED_1b_2	0x1b, 0x40, 6
> -#define SR_PLL_DCU_START	0x1b, 0x80, 7
> -#define RG_PART_NUM	(0x1c)
> -#define SR_PART_NUM		0x1c, 0xff, 0
> -#define RG_VERSION_NUM	(0x1d)
> -#define SR_VERSION_NUM		0x1d, 0xff, 0
> -#define RG_MAN_ID_0	(0x1e)
> -#define SR_MAN_ID_0		0x1e, 0xff, 0
> -#define RG_MAN_ID_1	(0x1f)
> -#define SR_MAN_ID_1		0x1f, 0xff, 0
> -#define RG_SHORT_ADDR_0	(0x20)
> -#define SR_SHORT_ADDR_0		0x20, 0xff, 0
> -#define RG_SHORT_ADDR_1	(0x21)
> -#define SR_SHORT_ADDR_1		0x21, 0xff, 0
> -#define RG_PAN_ID_0	(0x22)
> -#define SR_PAN_ID_0		0x22, 0xff, 0
> -#define RG_PAN_ID_1	(0x23)
> -#define SR_PAN_ID_1		0x23, 0xff, 0
> -#define RG_IEEE_ADDR_0	(0x24)
> -#define SR_IEEE_ADDR_0		0x24, 0xff, 0
> -#define RG_IEEE_ADDR_1	(0x25)
> -#define SR_IEEE_ADDR_1		0x25, 0xff, 0
> -#define RG_IEEE_ADDR_2	(0x26)
> -#define SR_IEEE_ADDR_2		0x26, 0xff, 0
> -#define RG_IEEE_ADDR_3	(0x27)
> -#define SR_IEEE_ADDR_3		0x27, 0xff, 0
> -#define RG_IEEE_ADDR_4	(0x28)
> -#define SR_IEEE_ADDR_4		0x28, 0xff, 0
> -#define RG_IEEE_ADDR_5	(0x29)
> -#define SR_IEEE_ADDR_5		0x29, 0xff, 0
> -#define RG_IEEE_ADDR_6	(0x2a)
> -#define SR_IEEE_ADDR_6		0x2a, 0xff, 0
> -#define RG_IEEE_ADDR_7	(0x2b)
> -#define SR_IEEE_ADDR_7		0x2b, 0xff, 0
> -#define RG_XAH_CTRL_0	(0x2c)
> -#define SR_SLOTTED_OPERATION	0x2c, 0x01, 0
> -#define SR_MAX_CSMA_RETRIES	0x2c, 0x0e, 1
> -#define SR_MAX_FRAME_RETRIES	0x2c, 0xf0, 4
> -#define RG_CSMA_SEED_0	(0x2d)
> -#define SR_CSMA_SEED_0		0x2d, 0xff, 0
> -#define RG_CSMA_SEED_1	(0x2e)
> -#define SR_CSMA_SEED_1		0x2e, 0x07, 0
> -#define SR_AACK_I_AM_COORD	0x2e, 0x08, 3
> -#define SR_AACK_DIS_ACK		0x2e, 0x10, 4
> -#define SR_AACK_SET_PD		0x2e, 0x20, 5
> -#define SR_AACK_FVN_MODE	0x2e, 0xc0, 6
> -#define RG_CSMA_BE	(0x2f)
> -#define SR_MIN_BE		0x2f, 0x0f, 0
> -#define SR_MAX_BE		0x2f, 0xf0, 4
> -
> -#define CMD_REG		0x80
> -#define CMD_REG_MASK	0x3f
> -#define CMD_WRITE	0x40
> -#define CMD_FB		0x20
> -
> -#define IRQ_BAT_LOW	(1 << 7)
> -#define IRQ_TRX_UR	(1 << 6)
> -#define IRQ_AMI		(1 << 5)
> -#define IRQ_CCA_ED	(1 << 4)
> -#define IRQ_TRX_END	(1 << 3)
> -#define IRQ_RX_START	(1 << 2)
> -#define IRQ_PLL_UNL	(1 << 1)
> -#define IRQ_PLL_LOCK	(1 << 0)
> -
> -#define IRQ_ACTIVE_HIGH	0
> -#define IRQ_ACTIVE_LOW	1
> -
> -#define STATE_P_ON		0x00	/* BUSY */
> -#define STATE_BUSY_RX		0x01
> -#define STATE_BUSY_TX		0x02
> -#define STATE_FORCE_TRX_OFF	0x03
> -#define STATE_FORCE_TX_ON	0x04	/* IDLE */
> -/* 0x05 */				/* INVALID_PARAMETER */
> -#define STATE_RX_ON		0x06
> -/* 0x07 */				/* SUCCESS */
> -#define STATE_TRX_OFF		0x08
> -#define STATE_TX_ON		0x09
> -/* 0x0a - 0x0e */			/* 0x0a - UNSUPPORTED_ATTRIBUTE */
> -#define STATE_SLEEP		0x0F
> -#define STATE_PREP_DEEP_SLEEP	0x10
> -#define STATE_BUSY_RX_AACK	0x11
> -#define STATE_BUSY_TX_ARET	0x12
> -#define STATE_RX_AACK_ON	0x16
> -#define STATE_TX_ARET_ON	0x19
> -#define STATE_RX_ON_NOCLK	0x1C
> -#define STATE_RX_AACK_ON_NOCLK	0x1D
> -#define STATE_BUSY_RX_AACK_NOCLK 0x1E
> -#define STATE_TRANSITION_IN_PROGRESS 0x1F
> -
> -#define TRX_STATE_MASK		(0x1F)
> -
>   #define AT86RF2XX_NUMREGS 0x3F
>
>   static void
> diff --git a/drivers/net/ieee802154/at86rf230.h
> b/drivers/net/ieee802154/at86rf230.h
> new file mode 100644
> index 0000000..1e6d1cc
> --- /dev/null
> +++ b/drivers/net/ieee802154/at86rf230.h
> @@ -0,0 +1,220 @@
> +/*
> + * AT86RF230/RF231 driver
> + *
> + * Copyright (C) 2009-2012 Siemens AG
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2
> + * as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * Written by:
> + * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> + * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
> + */
> +
> +#ifndef _AT86RF230_H
> +#define _AT86RF230_H
> +
> +#define RG_TRX_STATUS	(0x01)
> +#define SR_TRX_STATUS		0x01, 0x1f, 0
> +#define SR_RESERVED_01_3	0x01, 0x20, 5
> +#define SR_CCA_STATUS		0x01, 0x40, 6
> +#define SR_CCA_DONE		0x01, 0x80, 7
> +#define RG_TRX_STATE	(0x02)
> +#define SR_TRX_CMD		0x02, 0x1f, 0
> +#define SR_TRAC_STATUS		0x02, 0xe0, 5
> +#define RG_TRX_CTRL_0	(0x03)
> +#define SR_CLKM_CTRL		0x03, 0x07, 0
> +#define SR_CLKM_SHA_SEL		0x03, 0x08, 3
> +#define SR_PAD_IO_CLKM		0x03, 0x30, 4
> +#define SR_PAD_IO		0x03, 0xc0, 6
> +#define RG_TRX_CTRL_1	(0x04)
> +#define SR_IRQ_POLARITY		0x04, 0x01, 0
> +#define SR_IRQ_MASK_MODE	0x04, 0x02, 1
> +#define SR_SPI_CMD_MODE		0x04, 0x0c, 2
> +#define SR_RX_BL_CTRL		0x04, 0x10, 4
> +#define SR_TX_AUTO_CRC_ON	0x04, 0x20, 5
> +#define SR_IRQ_2_EXT_EN		0x04, 0x40, 6
> +#define SR_PA_EXT_EN		0x04, 0x80, 7
> +#define RG_PHY_TX_PWR	(0x05)
> +#define SR_TX_PWR_23X		0x05, 0x0f, 0
> +#define SR_PA_LT_230		0x05, 0x30, 4
> +#define SR_PA_BUF_LT_230	0x05, 0xc0, 6
> +#define SR_TX_PWR_212		0x05, 0x1f, 0
> +#define SR_GC_PA_212		0x05, 0x60, 5
> +#define SR_PA_BOOST_LT_212	0x05, 0x80, 7
> +#define RG_PHY_RSSI	(0x06)
> +#define SR_RSSI			0x06, 0x1f, 0
> +#define SR_RND_VALUE		0x06, 0x60, 5
> +#define SR_RX_CRC_VALID		0x06, 0x80, 7
> +#define RG_PHY_ED_LEVEL	(0x07)
> +#define SR_ED_LEVEL		0x07, 0xff, 0
> +#define RG_PHY_CC_CCA	(0x08)
> +#define SR_CHANNEL		0x08, 0x1f, 0
> +#define SR_CCA_MODE		0x08, 0x60, 5
> +#define SR_CCA_REQUEST		0x08, 0x80, 7
> +#define RG_CCA_THRES	(0x09)
> +#define SR_CCA_ED_THRES		0x09, 0x0f, 0
> +#define SR_RESERVED_09_1	0x09, 0xf0, 4
> +#define RG_RX_CTRL	(0x0a)
> +#define SR_PDT_THRES		0x0a, 0x0f, 0
> +#define SR_RESERVED_0a_1	0x0a, 0xf0, 4
> +#define RG_SFD_VALUE	(0x0b)
> +#define SR_SFD_VALUE		0x0b, 0xff, 0
> +#define RG_TRX_CTRL_2	(0x0c)
> +#define SR_OQPSK_DATA_RATE	0x0c, 0x03, 0
> +#define SR_SUB_MODE		0x0c, 0x04, 2
> +#define SR_BPSK_QPSK		0x0c, 0x08, 3
> +#define SR_OQPSK_SUB1_RC_EN	0x0c, 0x10, 4
> +#define SR_RESERVED_0c_5	0x0c, 0x60, 5
> +#define SR_RX_SAFE_MODE		0x0c, 0x80, 7
> +#define RG_ANT_DIV	(0x0d)
> +#define SR_ANT_CTRL		0x0d, 0x03, 0
> +#define SR_ANT_EXT_SW_EN	0x0d, 0x04, 2
> +#define SR_ANT_DIV_EN		0x0d, 0x08, 3
> +#define SR_RESERVED_0d_2	0x0d, 0x70, 4
> +#define SR_ANT_SEL		0x0d, 0x80, 7
> +#define RG_IRQ_MASK	(0x0e)
> +#define SR_IRQ_MASK		0x0e, 0xff, 0
> +#define RG_IRQ_STATUS	(0x0f)
> +#define SR_IRQ_0_PLL_LOCK	0x0f, 0x01, 0
> +#define SR_IRQ_1_PLL_UNLOCK	0x0f, 0x02, 1
> +#define SR_IRQ_2_RX_START	0x0f, 0x04, 2
> +#define SR_IRQ_3_TRX_END	0x0f, 0x08, 3
> +#define SR_IRQ_4_CCA_ED_DONE	0x0f, 0x10, 4
> +#define SR_IRQ_5_AMI		0x0f, 0x20, 5
> +#define SR_IRQ_6_TRX_UR		0x0f, 0x40, 6
> +#define SR_IRQ_7_BAT_LOW	0x0f, 0x80, 7
> +#define RG_VREG_CTRL	(0x10)
> +#define SR_RESERVED_10_6	0x10, 0x03, 0
> +#define SR_DVDD_OK		0x10, 0x04, 2
> +#define SR_DVREG_EXT		0x10, 0x08, 3
> +#define SR_RESERVED_10_3	0x10, 0x30, 4
> +#define SR_AVDD_OK		0x10, 0x40, 6
> +#define SR_AVREG_EXT		0x10, 0x80, 7
> +#define RG_BATMON	(0x11)
> +#define SR_BATMON_VTH		0x11, 0x0f, 0
> +#define SR_BATMON_HR		0x11, 0x10, 4
> +#define SR_BATMON_OK		0x11, 0x20, 5
> +#define SR_RESERVED_11_1	0x11, 0xc0, 6
> +#define RG_XOSC_CTRL	(0x12)
> +#define SR_XTAL_TRIM		0x12, 0x0f, 0
> +#define SR_XTAL_MODE		0x12, 0xf0, 4
> +#define RG_RX_SYN	(0x15)
> +#define SR_RX_PDT_LEVEL		0x15, 0x0f, 0
> +#define SR_RESERVED_15_2	0x15, 0x70, 4
> +#define SR_RX_PDT_DIS		0x15, 0x80, 7
> +#define RG_XAH_CTRL_1	(0x17)
> +#define SR_RESERVED_17_8	0x17, 0x01, 0
> +#define SR_AACK_PROM_MODE	0x17, 0x02, 1
> +#define SR_AACK_ACK_TIME	0x17, 0x04, 2
> +#define SR_RESERVED_17_5	0x17, 0x08, 3
> +#define SR_AACK_UPLD_RES_FT	0x17, 0x10, 4
> +#define SR_AACK_FLTR_RES_FT	0x17, 0x20, 5
> +#define SR_CSMA_LBT_MODE	0x17, 0x40, 6
> +#define SR_RESERVED_17_1	0x17, 0x80, 7
> +#define RG_FTN_CTRL	(0x18)
> +#define SR_RESERVED_18_2	0x18, 0x7f, 0
> +#define SR_FTN_START		0x18, 0x80, 7
> +#define RG_PLL_CF	(0x1a)
> +#define SR_RESERVED_1a_2	0x1a, 0x7f, 0
> +#define SR_PLL_CF_START		0x1a, 0x80, 7
> +#define RG_PLL_DCU	(0x1b)
> +#define SR_RESERVED_1b_3	0x1b, 0x3f, 0
> +#define SR_RESERVED_1b_2	0x1b, 0x40, 6
> +#define SR_PLL_DCU_START	0x1b, 0x80, 7
> +#define RG_PART_NUM	(0x1c)
> +#define SR_PART_NUM		0x1c, 0xff, 0
> +#define RG_VERSION_NUM	(0x1d)
> +#define SR_VERSION_NUM		0x1d, 0xff, 0
> +#define RG_MAN_ID_0	(0x1e)
> +#define SR_MAN_ID_0		0x1e, 0xff, 0
> +#define RG_MAN_ID_1	(0x1f)
> +#define SR_MAN_ID_1		0x1f, 0xff, 0
> +#define RG_SHORT_ADDR_0	(0x20)
> +#define SR_SHORT_ADDR_0		0x20, 0xff, 0
> +#define RG_SHORT_ADDR_1	(0x21)
> +#define SR_SHORT_ADDR_1		0x21, 0xff, 0
> +#define RG_PAN_ID_0	(0x22)
> +#define SR_PAN_ID_0		0x22, 0xff, 0
> +#define RG_PAN_ID_1	(0x23)
> +#define SR_PAN_ID_1		0x23, 0xff, 0
> +#define RG_IEEE_ADDR_0	(0x24)
> +#define SR_IEEE_ADDR_0		0x24, 0xff, 0
> +#define RG_IEEE_ADDR_1	(0x25)
> +#define SR_IEEE_ADDR_1		0x25, 0xff, 0
> +#define RG_IEEE_ADDR_2	(0x26)
> +#define SR_IEEE_ADDR_2		0x26, 0xff, 0
> +#define RG_IEEE_ADDR_3	(0x27)
> +#define SR_IEEE_ADDR_3		0x27, 0xff, 0
> +#define RG_IEEE_ADDR_4	(0x28)
> +#define SR_IEEE_ADDR_4		0x28, 0xff, 0
> +#define RG_IEEE_ADDR_5	(0x29)
> +#define SR_IEEE_ADDR_5		0x29, 0xff, 0
> +#define RG_IEEE_ADDR_6	(0x2a)
> +#define SR_IEEE_ADDR_6		0x2a, 0xff, 0
> +#define RG_IEEE_ADDR_7	(0x2b)
> +#define SR_IEEE_ADDR_7		0x2b, 0xff, 0
> +#define RG_XAH_CTRL_0	(0x2c)
> +#define SR_SLOTTED_OPERATION	0x2c, 0x01, 0
> +#define SR_MAX_CSMA_RETRIES	0x2c, 0x0e, 1
> +#define SR_MAX_FRAME_RETRIES	0x2c, 0xf0, 4
> +#define RG_CSMA_SEED_0	(0x2d)
> +#define SR_CSMA_SEED_0		0x2d, 0xff, 0
> +#define RG_CSMA_SEED_1	(0x2e)
> +#define SR_CSMA_SEED_1		0x2e, 0x07, 0
> +#define SR_AACK_I_AM_COORD	0x2e, 0x08, 3
> +#define SR_AACK_DIS_ACK		0x2e, 0x10, 4
> +#define SR_AACK_SET_PD		0x2e, 0x20, 5
> +#define SR_AACK_FVN_MODE	0x2e, 0xc0, 6
> +#define RG_CSMA_BE	(0x2f)
> +#define SR_MIN_BE		0x2f, 0x0f, 0
> +#define SR_MAX_BE		0x2f, 0xf0, 4
> +
> +#define CMD_REG		0x80
> +#define CMD_REG_MASK	0x3f
> +#define CMD_WRITE	0x40
> +#define CMD_FB		0x20
> +
> +#define IRQ_BAT_LOW	BIT(7)
> +#define IRQ_TRX_UR	BIT(6)
> +#define IRQ_AMI		BIT(5)
> +#define IRQ_CCA_ED	BIT(4)
> +#define IRQ_TRX_END	BIT(3)
> +#define IRQ_RX_START	BIT(2)
> +#define IRQ_PLL_UNL	BIT(1)
> +#define IRQ_PLL_LOCK	BIT(0)
> +
> +#define IRQ_ACTIVE_HIGH	0
> +#define IRQ_ACTIVE_LOW	1
> +
> +#define STATE_P_ON		0x00	/* BUSY */
> +#define STATE_BUSY_RX		0x01
> +#define STATE_BUSY_TX		0x02
> +#define STATE_FORCE_TRX_OFF	0x03
> +#define STATE_FORCE_TX_ON	0x04	/* IDLE */
> +/* 0x05 */				/* INVALID_PARAMETER */
> +#define STATE_RX_ON		0x06
> +/* 0x07 */				/* SUCCESS */
> +#define STATE_TRX_OFF		0x08
> +#define STATE_TX_ON		0x09
> +/* 0x0a - 0x0e */			/* 0x0a - UNSUPPORTED_ATTRIBUTE */
> +#define STATE_SLEEP		0x0F
> +#define STATE_PREP_DEEP_SLEEP	0x10
> +#define STATE_BUSY_RX_AACK	0x11
> +#define STATE_BUSY_TX_ARET	0x12
> +#define STATE_RX_AACK_ON	0x16
> +#define STATE_TX_ARET_ON	0x19
> +#define STATE_RX_ON_NOCLK	0x1C
> +#define STATE_RX_AACK_ON_NOCLK	0x1D
> +#define STATE_BUSY_RX_AACK_NOCLK 0x1E
> +#define STATE_TRANSITION_IN_PROGRESS 0x1F
> +
> +#define TRX_STATE_MASK		(0x1F)
> +
> +#endif /* !_AT86RF230_H */

I think I updated some of these defines at some point. Will go through 
my changes and see if I have any updates for this. Nothing imprtant for 
the current functionality so this can go in as is and the other patch 
follow up later. Mostly updated to some former reserved areas iirc.

> diff --git a/drivers/net/ieee802154/atusb.c
> b/drivers/net/ieee802154/atusb.c
> new file mode 100644
> index 0000000..ea1259e
> --- /dev/null
> +++ b/drivers/net/ieee802154/atusb.c
> @@ -0,0 +1,692 @@
> +/*
> + * atusb.c - Driver for the ATUSB IEEE 802.15.4 dongle
> + *
> + * Written 2013 by Werner Almesberger <werner@almesberger.net>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation, version 2
> + *
> + * Based on at86rf230.c and spi_atusb.c.
> + * at86rf230.c is
> + * Copyright (C) 2009 Siemens AG
> + * Written by: Dmitry Eremin-Solenikov <dmitry.baryshkov@siemens.com>
> + *
> + * spi_atusb.c is
> + * Copyright (c) 2011 Richard Sharpe <realrichardsharpe@gmail.com>
> + * Copyright (c) 2011 Stefan Schmidt <stefan@datenfreihafen.org>
> + * Copyright (c) 2011 Werner Almesberger <werner@almesberger.net>
> + *
> + * USB initialization is
> + * Copyright (c) 2013 Alexander Aring <alex.aring@gmail.com>
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/slab.h>
> +#include <linux/module.h>
> +#include <linux/jiffies.h>
> +#include <linux/usb.h>
> +#include <linux/skbuff.h>
> +
> +#include <net/cfg802154.h>
> +#include <net/mac802154.h>
> +
> +#include "at86rf230.h"
> +#include "atusb.h"
> +
> +#define ATUSB_JEDEC_ATMEL	0x1f	/* JEDEC manufacturer ID */
> +
> +#define ATUSB_NUM_RX_URBS	4	/* allow for a bit of local
> latency */
> +#define ATUSB_ALLOC_DELAY_MS	100	/* delay after failed allocation
> */
> +#define ATUSB_TX_TIMEOUT_MS	200	/* on the air timeout */
> +
> +struct atusb {
> +	struct ieee802154_hw *hw;
> +	struct usb_device *usb_dev;
> +	int shutdown;			/* non-zero if shutting down */
> +	int err;			/* set by first error */
> +
> +	/* RX variables */
> +	struct delayed_work work;	/* memory allocations */
> +	struct usb_anchor idle_urbs;	/* URBs waiting to be submitted */
> +	struct usb_anchor rx_urbs;	/* URBs waiting for reception */
> +
> +	/* TX variables */
> +	struct usb_ctrlrequest tx_dr;
> +	struct urb *tx_urb;
> +	struct sk_buff *tx_skb;
> +	uint8_t tx_ack_seq;		/* current TX ACK sequence number
> */
> +};
> +
> +/* at86rf230.h defines values as <reg, mask, shift> tuples. We use the
> more
> + * traditional style of having registers and or-able values. SR_REG
> extracts
> + * the register number. SR_VALUE uses the shift to prepare a value
> accordingly.
> + */
> +
> +#define __SR_REG(reg, mask, shift)	(reg)
> +#define SR_REG(sr)			__SR_REG(sr)
> +
> +#define __SR_VALUE(reg, mask, shift, val)	((val) << (shift))
> +#define SR_VALUE(sr, val)			__SR_VALUE(sr, (val))
> +
> +/* ----- USB commands without data
> ----------------------------------------- */
> +
> +/* To reduce the number of error checks in the code, we record the first
> error
> + * in atusb->err and reject all subsequent requests until the error is
> cleared.
> + */
> +
> +static int atusb_control_msg(struct atusb *atusb, unsigned int pipe,
> +			     __u8 request, __u8 requesttype,
> +			     __u16 value, __u16 index,
> +			     void *data, __u16 size, int timeout)
> +{
> +	struct usb_device *usb_dev = atusb->usb_dev;
> +	int ret;
> +
> +	if (atusb->err)
> +		return atusb->err;
> +
> +	ret = usb_control_msg(usb_dev, pipe, request, requesttype,
> +			      value, index, data, size, timeout);
> +	if (ret < 0) {
> +		atusb->err = ret;
> +		dev_err(&usb_dev->dev,
> +			"atusb_control_msg: req 0x%02x val 0x%x idx 0x%x,
> error %d\n",
> +			request, value, index, ret);
> +	}
> +	return ret;
> +}
> +
> +static int atusb_command(struct atusb *atusb, uint8_t cmd, uint8_t arg)
> +{
> +	struct usb_device *usb_dev = atusb->usb_dev;
> +
> +	dev_dbg(&usb_dev->dev, "atusb_command: cmd = 0x%x\n", cmd);
> +	return atusb_control_msg(atusb, usb_sndctrlpipe(usb_dev, 0),
> +				 cmd, ATUSB_REQ_TO_DEV, arg, 0, NULL, 0,
> 1000);
> +}
> +
> +static int atusb_write_reg(struct atusb *atusb, uint8_t reg, uint8_t
> value)
> +{
> +	struct usb_device *usb_dev = atusb->usb_dev;
> +
> +	dev_dbg(&usb_dev->dev, "atusb_write_reg: 0x%02x <- 0x%02x\n",
> +		reg, value);
> +	return atusb_control_msg(atusb, usb_sndctrlpipe(usb_dev, 0),
> +				 ATUSB_REG_WRITE, ATUSB_REQ_TO_DEV,
> +				 value, reg, NULL, 0, 1000);
> +}
> +
> +static int atusb_read_reg(struct atusb *atusb, uint8_t reg)
> +{
> +	struct usb_device *usb_dev = atusb->usb_dev;
> +	int ret;
> +	uint8_t value;
> +
> +	dev_dbg(&usb_dev->dev, "atusb: reg = 0x%x\n", reg);
> +	ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
> +				ATUSB_REG_READ, ATUSB_REQ_FROM_DEV,
> +				0, reg, &value, 1, 1000);
> +	return ret >= 0 ? value : ret;
> +}
> +
> +static int atusb_get_and_clear_error(struct atusb *atusb)
> +{
> +	int err = atusb->err;
> +
> +	atusb->err = 0;
> +	return err;
> +}
> +
> +/* ----- skb allocation
> ---------------------------------------------------- */

I was never a fan of these markers but Werner likes them. Keep them in 
does not do any harm.

> +
> +#define MAX_PSDU	127
> +#define MAX_RX_XFER	(1 + MAX_PSDU + 2 + 1)	/* PHR+PSDU+CRC+LQI */
> +
> +#define SKB_ATUSB(skb)	(*(struct atusb **)(skb)->cb)
> +
> +static void atusb_in(struct urb *urb);
> +
> +static int atusb_submit_rx_urb(struct atusb *atusb, struct urb *urb)
> +{
> +	struct usb_device *usb_dev = atusb->usb_dev;
> +	struct sk_buff *skb = urb->context;
> +	int ret;
> +
> +	if (!skb) {
> +		skb = alloc_skb(MAX_RX_XFER, GFP_KERNEL);
> +		if (!skb) {
> +			dev_warn_ratelimited(&usb_dev->dev,
> +					     "atusb_in: can't allocate
> skb\n");
> +			return -ENOMEM;
> +		}
> +		skb_put(skb, MAX_RX_XFER);
> +		SKB_ATUSB(skb) = atusb;
> +	}
> +
> +	usb_fill_bulk_urb(urb, usb_dev, usb_rcvbulkpipe(usb_dev, 1),
> +			  skb->data, MAX_RX_XFER, atusb_in, skb);
> +	usb_anchor_urb(urb, &atusb->rx_urbs);
> +
> +	ret = usb_submit_urb(urb, GFP_KERNEL);
> +	if (ret) {
> +		usb_unanchor_urb(urb);
> +		kfree_skb(skb);
> +		urb->context = NULL;
> +	}
> +	return ret;
> +}
> +
> +static void atusb_work_urbs(struct work_struct *work)
> +{
> +	struct atusb *atusb =
> +	    container_of(to_delayed_work(work), struct atusb, work);
> +	struct usb_device *usb_dev = atusb->usb_dev;
> +	struct urb *urb;
> +	int ret;
> +
> +	if (atusb->shutdown)
> +		return;
> +
> +	do {
> +		urb = usb_get_from_anchor(&atusb->idle_urbs);
> +		if (!urb)
> +			return;
> +		ret = atusb_submit_rx_urb(atusb, urb);
> +	} while (!ret);
> +
> +	usb_anchor_urb(urb, &atusb->idle_urbs);
> +	dev_warn_ratelimited(&usb_dev->dev,
> +			     "atusb_in: can't allocate/submit URB (%d)\n",
> ret);
> +	schedule_delayed_work(&atusb->work,
> +			      msecs_to_jiffies(ATUSB_ALLOC_DELAY_MS) + 1);
> +}
> +
> +/* ----- Asynchronous USB
> -------------------------------------------------- */
> +
> +static void atusb_tx_done(struct atusb *atusb, uint8_t seq)
> +{
> +	struct usb_device *usb_dev = atusb->usb_dev;
> +	uint8_t expect = atusb->tx_ack_seq;
> +
> +	dev_dbg(&usb_dev->dev, "atusb_tx_done (0x%02x/0x%02x)\n", seq,
> expect);
> +	if (seq == expect) {
> +		/* TODO check for ifs handling in firmware */
> +		ieee802154_xmit_complete(atusb->hw, atusb->tx_skb, false);
> +	} else {
> +		/* TODO I experience this case when atusb has a tx
> complete
> +		 * irq before probing, we should fix the firmware it's an
> +		 * unlikely case now that seq == expect is then true, but
> can
> +		 * happen and fail with a tx_skb = NULL;
> +		 */


Ah, so that comes with the xmit_async change. Looks like a good 
candidate for what I mentioned at the top about haveing a fw release now 
(0.1) and once we fixed the bug in the fw and released a fixed version 
we can check for it here and act according to the fw version. That is 
the only sane way to handle various fw versions I fear without upsetting 
our users with forcing new fw versions for new drivers on them.

Only alternative I see is to ship compatible versions with 
linux-firmware to match the kernel version.

> +		ieee802154_wake_queue(atusb->hw);
> +		if (atusb->tx_skb)
> +			dev_kfree_skb_irq(atusb->tx_skb);
> +	}
> +}
> +
> +static void atusb_in_good(struct urb *urb)
> +{
> +	struct usb_device *usb_dev = urb->dev;
> +	struct sk_buff *skb = urb->context;
> +	struct atusb *atusb = SKB_ATUSB(skb);
> +	uint8_t len, lqi;
> +
> +	if (!urb->actual_length) {
> +		dev_dbg(&usb_dev->dev, "atusb_in: zero-sized URB ?\n");
> +		return;
> +	}
> +
> +	len = *skb->data;
> +
> +	if (urb->actual_length == 1) {
> +		atusb_tx_done(atusb, len);
> +		return;
> +	}
> +
> +	if (len + 1 > urb->actual_length - 1) {
> +		dev_dbg(&usb_dev->dev, "atusb_in: frame len %d+1 > URB
> %u-1\n",
> +			len, urb->actual_length);
> +		return;
> +	}
> +
> +	if (!ieee802154_is_valid_psdu_len(len)) {
> +		dev_dbg(&usb_dev->dev, "atusb_in: frame corrupted\n");
> +		return;
> +	}
> +
> +	lqi = skb->data[len + 1];
> +	dev_dbg(&usb_dev->dev, "atusb_in: rx len %d lqi 0x%02x\n", len,
> lqi);
> +	skb_pull(skb, 1);	/* remove PHR */
> +	skb_trim(skb, len);	/* get payload only */

Hmm, the code I used here still has this:
skb_trim(skb, len); /* remove CRC */

Do we now longer need this? Did you change the driver capabilities to 
match this?

> +	ieee802154_rx_irqsafe(atusb->hw, skb, lqi);
> +	urb->context = NULL;	/* skb is gone */
> +}
> +
> +static void atusb_in(struct urb *urb)
> +{
> +	struct usb_device *usb_dev = urb->dev;
> +	struct sk_buff *skb = urb->context;
> +	struct atusb *atusb = SKB_ATUSB(skb);
> +
> +	dev_dbg(&usb_dev->dev, "atusb_in: status %d len %d\n",
> +		urb->status, urb->actual_length);
> +	if (urb->status) {
> +		if (urb->status == -ENOENT) { /* being killed */
> +			kfree_skb(skb);
> +			urb->context = NULL;
> +			return;
> +		}
> +		dev_dbg(&usb_dev->dev, "atusb_in: URB error %d\n",
> urb->status);
> +	} else {
> +		atusb_in_good(urb);
> +	}
> +
> +	usb_anchor_urb(urb, &atusb->idle_urbs);
> +	if (!atusb->shutdown)
> +		schedule_delayed_work(&atusb->work, 0);
> +}
> +
> +/* ----- URB allocation/deallocation
> --------------------------------------- */
> +
> +static void atusb_free_urbs(struct atusb *atusb)
> +{
> +	struct urb *urb;
> +
> +	while (1) {
> +		urb = usb_get_from_anchor(&atusb->idle_urbs);
> +		if (!urb)
> +			break;
> +		if (urb->context)
> +			kfree_skb(urb->context);
> +		usb_free_urb(urb);
> +	}
> +}
> +
> +static int atusb_alloc_urbs(struct atusb *atusb, int n)
> +{
> +	struct urb *urb;
> +
> +	while (n) {
> +		urb = usb_alloc_urb(0, GFP_KERNEL);
> +		if (!urb) {
> +			atusb_free_urbs(atusb);
> +			return -ENOMEM;
> +		}
> +		usb_anchor_urb(urb, &atusb->idle_urbs);
> +		n--;
> +	}
> +	return 0;
> +}
> +
> +/* ----- IEEE 802.15.4 interface operations
> -------------------------------- */
> +
> +static void atusb_xmit_complete(struct urb *urb)
> +{
> +	dev_dbg(&urb->dev->dev, "atusb_xmit urb completed");
> +}
> +
> +static int atusb_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
> +{
> +	struct atusb *atusb = hw->priv;
> +	struct usb_device *usb_dev = atusb->usb_dev;
> +	int ret;
> +
> +	dev_dbg(&usb_dev->dev, "atusb_xmit (%d)\n", skb->len);
> +	atusb->tx_skb = skb;
> +	atusb->tx_ack_seq++;
> +	atusb->tx_dr.wIndex = cpu_to_le16(atusb->tx_ack_seq);
> +	atusb->tx_dr.wLength = cpu_to_le16(skb->len);
> +
> +	usb_fill_control_urb(atusb->tx_urb, usb_dev,
> +			     usb_sndctrlpipe(usb_dev, 0),
> +			     (unsigned char *)&atusb->tx_dr, skb->data,
> +			     skb->len, atusb_xmit_complete, NULL);
> +	ret = usb_submit_urb(atusb->tx_urb, GFP_ATOMIC);
> +	dev_dbg(&usb_dev->dev, "atusb_xmit done (%d)\n", ret);
> +	return ret;
> +}
> +
> +static int atusb_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
> +{
> +	struct atusb *atusb = hw->priv;
> +	int ret;
> +
> +	/* This implicitly sets the CCA (Clear Channel Assessment) mode to
> 0,
> +	 * "Mode 3a, Carrier sense OR energy above threshold".
> +	 * We should probably make this configurable. @@@
> +	 */
> +	ret = atusb_write_reg(atusb, RG_PHY_CC_CCA, channel);
> +	if (ret < 0)
> +		return ret;
> +	msleep(1);	/* @@@ ugly synchronization */

The hw->phy->current_channel = channel; is no longer needed here? Does 
the stack handle this part now?

> +	return 0;
> +}
> +
> +static int atusb_ed(struct ieee802154_hw *hw, u8 *level)
> +{
> +	/* @@@ not used by the stack yet */
> +	*level = 0;
> +	return 0;
> +}
> +
> +static int atusb_set_hw_addr_filt(struct ieee802154_hw *hw,
> +				  struct ieee802154_hw_addr_filt *filt,
> +				  unsigned long changed)
> +{
> +	struct atusb *atusb = hw->priv;
> +	struct device *dev = &atusb->usb_dev->dev;
> +	uint8_t reg;
> +
> +	if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
> +		u16 addr = le16_to_cpu(filt->short_addr);
> +
> +		dev_vdbg(dev, "atusb_set_hw_addr_filt called for
> saddr\n");
> +		atusb_write_reg(atusb, RG_SHORT_ADDR_0, addr);
> +		atusb_write_reg(atusb, RG_SHORT_ADDR_1, addr >> 8);
> +	}
> +
> +	if (changed & IEEE802154_AFILT_PANID_CHANGED) {
> +		u16 pan = le16_to_cpu(filt->pan_id);
> +
> +		dev_vdbg(dev, "atusb_set_hw_addr_filt called for pan
> id\n");
> +		atusb_write_reg(atusb, RG_PAN_ID_0, pan);
> +		atusb_write_reg(atusb, RG_PAN_ID_1, pan >> 8);
> +	}
> +
> +	if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
> +		u8 i, addr[IEEE802154_EXTENDED_ADDR_LEN];
> +
> +		memcpy(addr, &filt->ieee_addr,
> IEEE802154_EXTENDED_ADDR_LEN);
> +		dev_vdbg(dev, "atusb_set_hw_addr_filt called for IEEE
> addr\n");
> +		for (i = 0; i < 8; i++)
> +			atusb_write_reg(atusb, RG_IEEE_ADDR_0 + i,
> addr[i]);
> +	}
> +
> +	if (changed & IEEE802154_AFILT_PANC_CHANGED) {
> +		dev_vdbg(dev,
> +			 "atusb_set_hw_addr_filt called for panc
> change\n");
> +		reg = atusb_read_reg(atusb, SR_REG(SR_AACK_I_AM_COORD));
> +		if (filt->pan_coord)
> +			reg |= SR_VALUE(SR_AACK_I_AM_COORD, 1);
> +		else
> +			reg &= ~SR_VALUE(SR_AACK_I_AM_COORD, 1);
> +		atusb_write_reg(atusb, SR_REG(SR_AACK_I_AM_COORD), reg);
> +	}
> +
> +	return atusb_get_and_clear_error(atusb);
> +}
> +
> +static int atusb_start(struct ieee802154_hw *hw)
> +{
> +	struct atusb *atusb = hw->priv;
> +	struct usb_device *usb_dev = atusb->usb_dev;
> +	int ret;
> +
> +	dev_dbg(&usb_dev->dev, "atusb_start\n");
> +	schedule_delayed_work(&atusb->work, 0);
> +	atusb_command(atusb, ATUSB_RX_MODE, 1);
> +	ret = atusb_get_and_clear_error(atusb);
> +	if (ret < 0)
> +		usb_kill_anchored_urbs(&atusb->idle_urbs);
> +	return ret;
> +}
> +
> +static void atusb_stop(struct ieee802154_hw *hw)
> +{
> +	struct atusb *atusb = hw->priv;
> +	struct usb_device *usb_dev = atusb->usb_dev;
> +
> +	dev_dbg(&usb_dev->dev, "atusb_stop\n");
> +	usb_kill_anchored_urbs(&atusb->idle_urbs);
> +	atusb_command(atusb, ATUSB_RX_MODE, 0);
> +	atusb_get_and_clear_error(atusb);
> +}
> +
> +static struct ieee802154_ops atusb_ops = {
> +	.owner			= THIS_MODULE,
> +	.xmit_async		= atusb_xmit,
> +	.ed			= atusb_ed,
> +	.set_channel		= atusb_channel,
> +	.start			= atusb_start,
> +	.stop			= atusb_stop,
> +	.set_hw_addr_filt	= atusb_set_hw_addr_filt,
> +};
> +
> +/* ----- Firmware and chip version information
> ----------------------------- */
> +
> +static int atusb_get_and_show_revision(struct atusb *atusb)
> +{
> +	struct usb_device *usb_dev = atusb->usb_dev;
> +	unsigned char buffer[3];
> +	int ret;
> +
> +	/* Get a couple of the ATMega Firmware values */
> +	ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
> +				ATUSB_ID, ATUSB_REQ_FROM_DEV, 0, 0,
> +				buffer, 3, 1000);
> +	if (ret >= 0)
> +		dev_info(&usb_dev->dev,
> +			 "Firmware: major: %u, minor: %u, hardware type:
> %u\n",
> +			 buffer[0], buffer[1], buffer[2]);
> +
> +	return ret;
> +}
> +
> +static int atusb_get_and_show_build(struct atusb *atusb)
> +{
> +	struct usb_device *usb_dev = atusb->usb_dev;
> +	char build[ATUSB_BUILD_SIZE + 1];
> +	int ret;
> +
> +	ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
> +				ATUSB_BUILD, ATUSB_REQ_FROM_DEV, 0, 0,
> +				build, ATUSB_BUILD_SIZE, 1000);
> +	if (ret >= 0) {
> +		build[ret] = 0;
> +		dev_info(&usb_dev->dev, "Firmware: build %s\n", build);
> +	}
> +
> +	return ret;
> +}
> +
> +static int atusb_get_and_show_chip(struct atusb *atusb)
> +{
> +	struct usb_device *usb_dev = atusb->usb_dev;
> +	uint8_t man_id_0, man_id_1, part_num, version_num;
> +
> +	man_id_0 = atusb_read_reg(atusb, RG_MAN_ID_0);
> +	man_id_1 = atusb_read_reg(atusb, RG_MAN_ID_1);
> +	part_num = atusb_read_reg(atusb, RG_PART_NUM);
> +	version_num = atusb_read_reg(atusb, RG_VERSION_NUM);
> +
> +	if (atusb->err)
> +		return atusb->err;
> +
> +	if ((man_id_1 << 8 | man_id_0) != ATUSB_JEDEC_ATMEL) {
> +		dev_err(&usb_dev->dev,
> +			"non-Atmel transceiver xxxx%02x%02x\n",
> +			man_id_1, man_id_0);
> +		goto fail;
> +	}
> +	if (part_num != 3) {
> +		dev_err(&usb_dev->dev,
> +			"unexpected transceiver, part 0x%02x version
> 0x%02x\n",
> +			part_num, version_num);
> +		goto fail;
> +	}
> +
> +	dev_info(&usb_dev->dev, "ATUSB: AT86RF231 version %d\n",
> version_num);
> +
> +	return 0;
> +
> +fail:
> +	atusb->err = -ENODEV;
> +	return -ENODEV;
> +}
> +
> +/* ----- Setup
> ------------------------------------------------------------- */
> +
> +static int atusb_probe(struct usb_interface *interface,
> +		       const struct usb_device_id *id)
> +{
> +	struct usb_device *usb_dev = interface_to_usbdev(interface);
> +	struct ieee802154_hw *hw;
> +	struct atusb *atusb = NULL;
> +	int ret = -ENOMEM;
> +
> +	hw = ieee802154_alloc_hw(sizeof(struct atusb), &atusb_ops);
> +	if (!hw)
> +		return -ENOMEM;
> +
> +	atusb = hw->priv;
> +	atusb->hw = hw;
> +	atusb->usb_dev = usb_get_dev(usb_dev);
> +	usb_set_intfdata(interface, atusb);
> +
> +	atusb->shutdown = 0;
> +	atusb->err = 0;
> +	INIT_DELAYED_WORK(&atusb->work, atusb_work_urbs);
> +	init_usb_anchor(&atusb->idle_urbs);
> +	init_usb_anchor(&atusb->rx_urbs);
> +
> +	if (atusb_alloc_urbs(atusb, ATUSB_NUM_RX_URBS))
> +		goto fail;
> +
> +	atusb->tx_dr.bRequestType = ATUSB_REQ_TO_DEV;
> +	atusb->tx_dr.bRequest = ATUSB_TX;
> +	atusb->tx_dr.wValue = cpu_to_le16(0);

What are these three lines for? ^^

> +	atusb->tx_urb = usb_alloc_urb(0, GFP_ATOMIC);
> +	if (!atusb->tx_urb)
> +		goto fail;
> +
> +	hw->parent = &usb_dev->dev;
> +	hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT;
> +
> +	hw->phy->current_page = 0;
> +	hw->phy->current_channel = 11;	/* reset default */
> +	hw->phy->supported.channels[0] = 0x7FFF800;
> +	ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
> +
> +	atusb_command(atusb, ATUSB_RF_RESET, 0);
> +	atusb_get_and_show_chip(atusb);
> +	atusb_get_and_show_revision(atusb);
> +	atusb_get_and_show_build(atusb);
> +	ret = atusb_get_and_clear_error(atusb);
> +	if (ret) {
> +		dev_err(&atusb->usb_dev->dev,
> +			"%s: initialization failed, error = %d\n",
> +			__func__, ret);
> +		goto fail;
> +	}
> +
> +	ret = ieee802154_register_hw(hw);
> +	if (ret)
> +		goto fail;
> +
> +	/* If we just powered on, we're now in P_ON and need to enter
> TRX_OFF
> +	 * explicitly. Any resets after that will send us straight to
> TRX_OFF,
> +	 * making the command below redundant.
> +	 */
> +	atusb_write_reg(atusb, RG_TRX_STATE, STATE_FORCE_TRX_OFF);
> +	msleep(1);	/* reset => TRX_OFF, tTR13 = 37 us */
> +
> +#if 0
> +	/* Calculating the maximum time available to empty the frame
> buffer
> +	 * on reception:
> +	 *
> +	 * According to [1], the inter-frame gap is
> +	 * R * 20 * 16 us + 128 us
> +	 * where R is a random number from 0 to 7. Furthermore, we have 20
> bit
> +	 * times (80 us at 250 kbps) of SHR of the next frame before the
> +	 * transceiver begins storing data in the frame buffer.
> +	 *
> +	 * This yields a minimum time of 208 us between the last data of a
> +	 * frame and the first data of the next frame. This time is
> further
> +	 * reduced by interrupt latency in the atusb firmware.
> +	 *
> +	 * atusb currently needs about 500 us to retrieve a maximum-sized
> +	 * frame. We therefore have to allow reception of a new frame to
> begin
> +	 * while we retrieve the previous frame.
> +	 *
> +	 * [1] "JN-AN-1035 Calculating data rates in an IEEE
> 802.15.4-based
> +	 *      network", Jennic 2006.
> +	 *
> http://www.jennic.com/download_file.php?supportFile=JN-AN-1035%20Calculati
> ng%20802-15-4%20Data%20Rates-1v0.pdf
> +	 */
> +
> +	atusb_write_reg(atusb,
> +			SR_REG(SR_RX_SAFE_MODE), SR_VALUE(SR_RX_SAFE_MODE,
> 1));
> +#endif
> +	atusb_write_reg(atusb, RG_IRQ_MASK, 0xff);
> +
> +	ret = atusb_get_and_clear_error(atusb);
> +	if (!ret)
> +		return 0;
> +
> +	dev_err(&atusb->usb_dev->dev,
> +		"%s: setup failed, error = %d\n",
> +		__func__, ret);
> +
> +	ieee802154_unregister_hw(hw);
> +fail:
> +	atusb_free_urbs(atusb);
> +	usb_kill_urb(atusb->tx_urb);
> +	usb_free_urb(atusb->tx_urb);
> +	usb_put_dev(usb_dev);
> +	ieee802154_free_hw(hw);
> +	return ret;
> +}
> +
> +static void atusb_disconnect(struct usb_interface *interface)
> +{
> +	struct atusb *atusb = usb_get_intfdata(interface);
> +
> +	dev_dbg(&atusb->usb_dev->dev, "atusb_disconnect\n");
> +
> +	atusb->shutdown = 1;
> +	cancel_delayed_work_sync(&atusb->work);
> +
> +	usb_kill_anchored_urbs(&atusb->rx_urbs);
> +	atusb_free_urbs(atusb);
> +	usb_kill_urb(atusb->tx_urb);
> +	usb_free_urb(atusb->tx_urb);
> +
> +	ieee802154_unregister_hw(atusb->hw);
> +
> +	ieee802154_free_hw(atusb->hw);
> +
> +	usb_set_intfdata(interface, NULL);
> +	usb_put_dev(atusb->usb_dev);
> +
> +	pr_debug("atusb_disconnect done\n");
> +}
> +
> +/* The devices we work with */
> +static const struct usb_device_id atusb_device_table[] = {
> +	{
> +		.match_flags		= USB_DEVICE_ID_MATCH_DEVICE |
> +					  USB_DEVICE_ID_MATCH_INT_INFO,
> +		.idVendor		= ATUSB_VENDOR_ID,
> +		.idProduct		= ATUSB_PRODUCT_ID,
> +		.bInterfaceClass	= USB_CLASS_VENDOR_SPEC
> +	},
> +	/* end with null element */
> +	{}
> +};
> +MODULE_DEVICE_TABLE(usb, atusb_device_table);
> +
> +static struct usb_driver atusb_driver = {
> +	.name		= "atusb",
> +	.probe		= atusb_probe,
> +	.disconnect	= atusb_disconnect,
> +	.id_table	= atusb_device_table,
> +};
> +module_usb_driver(atusb_driver);
> +
> +MODULE_AUTHOR("Alexander Aring <alex.aring@gmail.com>");
> +MODULE_AUTHOR("Richard Sharpe <realrichardsharpe@gmail.com>");
> +MODULE_AUTHOR("Stefan Schmidt <stefan@datenfreihafen.org>");
> +MODULE_AUTHOR("Werner Almesberger <werner@almesberger.net>");
> +MODULE_DESCRIPTION("ATUSB IEEE 802.15.4 Driver");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/net/ieee802154/atusb.h
> b/drivers/net/ieee802154/atusb.h
> new file mode 100644
> index 0000000..0690edc
> --- /dev/null
> +++ b/drivers/net/ieee802154/atusb.h
> @@ -0,0 +1,84 @@
> +/*
> + * atusb.h - Definitions shared between kernel and ATUSB firmware
> + *
> + * Written 2013 by Werner Almesberger <werner@almesberger.net>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation, version 2, or
> + * (at your option) any later version.
> + *
> + * This file should be identical for kernel and firmware.
> + * Kernel: drivers/net/ieee802154/atusb.h
> + * Firmware: ben-wpan/atusb/fw/include/atusb/atusb.h
> + */
> +
> +#ifndef _ATUSB_H
> +#define _ATUSB_H
> +
> +#define ATUSB_VENDOR_ID	0x20b7	/* Qi Hardware*/
> +#define ATUSB_PRODUCT_ID 0x1540	/* 802.15.4, device 0 */
> +				/*     -- -         - */
> +
> +#define ATUSB_BUILD_SIZE 256	/* maximum build version/date message
> length */
> +
> +/* Commands to our device. Make sure this is synced with the firmware */
> +enum atusb_requests {
> +	ATUSB_ID			= 0x00,	/* system status/control
> grp */
> +	ATUSB_BUILD,
> +	ATUSB_RESET,
> +	ATUSB_RF_RESET			= 0x10,	/* debug/test group */
> +	ATUSB_POLL_INT,
> +	ATUSB_TEST,			/* atusb-sil only */
> +	ATUSB_TIMER,
> +	ATUSB_GPIO,
> +	ATUSB_SLP_TR,
> +	ATUSB_GPIO_CLEANUP,
> +	ATUSB_REG_WRITE			= 0x20,	/* transceiver group */
> +	ATUSB_REG_READ,
> +	ATUSB_BUF_WRITE,
> +	ATUSB_BUF_READ,
> +	ATUSB_SRAM_WRITE,
> +	ATUSB_SRAM_READ,
> +	ATUSB_SPI_WRITE			= 0x30,	/* SPI group */
> +	ATUSB_SPI_READ1,
> +	ATUSB_SPI_READ2,
> +	ATUSB_SPI_WRITE2_SYNC,
> +	ATUSB_RX_MODE			= 0x40, /* HardMAC group */
> +	ATUSB_TX,
> +};
> +
> +/* Direction	bRequest		wValue		wIndex	wLength
> + *
> + * ->host	ATUSB_ID		-		-	3
> + * ->host	ATUSB_BUILD		-		-	#bytes
> + * host->	ATUSB_RESET		-		-	0
> + *
> + * host->	ATUSB_RF_RESET		-		-	0
> + * ->host	ATUSB_POLL_INT		-		-	1
> + * host->	ATUSB_TEST		-		-	0
> + * ->host	ATUSB_TIMER		-		-	#bytes (6)
> + * ->host	ATUSB_GPIO		dir+data	mask+p#	3
> + * host->	ATUSB_SLP_TR		-		-	0
> + * host->	ATUSB_GPIO_CLEANUP	-		-	0
> + *
> + * host->	ATUSB_REG_WRITE		value		addr	0
> + * ->host	ATUSB_REG_READ		-		addr	1
> + * host->	ATUSB_BUF_WRITE		-		-	#bytes
> + * ->host	ATUSB_BUF_READ		-		-	#bytes
> + * host->	ATUSB_SRAM_WRITE	-		addr	#bytes
> + * ->host	ATUSB_SRAM_READ		-		addr	#bytes
> + *
> + * host->	ATUSB_SPI_WRITE		byte0		byte1	#bytes
> + * ->host	ATUSB_SPI_READ1		byte0		-	#bytes
> + * ->host	ATUSB_SPI_READ2		byte0		byte1	#bytes
> + * ->host	ATUSB_SPI_WRITE2_SYNC	byte0		byte1	0/1
> + *
> + * host->	ATUSB_RX_MODE		on		-	0
> + * host->	ATUSB_TX		flags		ack_seq	#bytes
> + */
> +
> +#define ATUSB_REQ_FROM_DEV	(USB_TYPE_VENDOR | USB_DIR_IN)
> +#define ATUSB_REQ_TO_DEV	(USB_TYPE_VENDOR | USB_DIR_OUT)
> +
> +#endif /* !_ATUSB_H */
>

Besides the mentioned things this looks fine. Will give it some testing 
later this week.

regards
Stefan Schmidt

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH bluetooth-next 21/34] ieee802154: add support for atusb transceiver
  2015-05-19 10:49   ` Stefan Schmidt
@ 2015-05-19 11:52     ` Alexander Aring
  2015-05-19 13:22       ` Stefan Schmidt
  2015-05-19 13:45     ` Werner Almesberger
  2015-05-20  8:45     ` Stefan Schmidt
  2 siblings, 1 reply; 45+ messages in thread
From: Alexander Aring @ 2015-05-19 11:52 UTC (permalink / raw)
  To: Stefan Schmidt
  Cc: linux-wpan, kernel, marcel, Werner Almesberger, Richard Sharpe

On Tue, May 19, 2015 at 12:49:21PM +0200, Stefan Schmidt wrote:
> Hello.
> 
> On 17/05/15 21:44, Alexander Aring wrote:
> >This patch adds support for the atusb transceiver.
> >
> >The current driver supports basic functionality only. Possible further
> >tasks would be to sync functionality with the at86rf230 driver, because
> >the atusb use internally an at86rf231 transceiver. Some of these
> >features need a firmware update like AACK and ARET handling.
> 
> We should really have a firmware release now that runs with the mainline
> driver. For new features we can then check the fw version in the driver and
> enable/disable accordingly.
> 

Yep, the current fw code in ben-wpan repository is working. For myself I
just change the RX_ON to RX_AACK_ON so the atusb works also in ARET
enabled networks.

> Werner, is this something you would do? Making a release of the firmware? Or
> should Alexander or myself look into this?
> 
> >I did small changes to this driver to work with xmit_async callback and
> >setting of a random extended perm address.
> 
> Thanks!
> 
> >Signed-off-by: Alexander Aring <alex.aring@gmail.com>
> >Cc: Werner Almesberger <werner@almesberger.net>
> >Cc: Stefan Schmidt <s.schmidt@samsung.com>
> >Cc: Richard Sharpe <realrichardsharpe@gmail.com>
> >---
> >  drivers/net/ieee802154/Kconfig     |  10 +
> >  drivers/net/ieee802154/Makefile    |   1 +
> >  drivers/net/ieee802154/at86rf230.c | 199 +----------
> >  drivers/net/ieee802154/at86rf230.h | 220 ++++++++++++
> >  drivers/net/ieee802154/atusb.c     | 692
> >+++++++++++++++++++++++++++++++++++++
> >  drivers/net/ieee802154/atusb.h     |  84 +++++
> >  6 files changed, 1009 insertions(+), 197 deletions(-)
> >  create mode 100644 drivers/net/ieee802154/at86rf230.h
> >  create mode 100644 drivers/net/ieee802154/atusb.c
> >  create mode 100644 drivers/net/ieee802154/atusb.h
> >
> >diff --git a/drivers/net/ieee802154/Kconfig
> >b/drivers/net/ieee802154/Kconfig
> >index 1a3c3e5..1dd5ab8 100644
> >--- a/drivers/net/ieee802154/Kconfig
> >+++ b/drivers/net/ieee802154/Kconfig
> >@@ -53,3 +53,13 @@ config IEEE802154_CC2520
> >
> >  	  This driver can also be built as a module. To do so, say M here.
> >  	  the module will be called 'cc2520'.
> >+
> >+config IEEE802154_ATUSB
> >+	tristate "ATUSB transceiver driver"
> >+	depends on IEEE802154_DRIVERS && MAC802154 && USB
> >+	---help---
> >+	  Say Y here to enable the ATUSB IEEE 802.15.4 wireless
> >+	  controller.
> >+
> >+	  This driver can also be built as a module. To do so say M here.
> >+	  The module will be called 'atusb'.
> >diff --git a/drivers/net/ieee802154/Makefile
> >b/drivers/net/ieee802154/Makefile
> >index d77fa4d..cf1d2a6 100644
> >--- a/drivers/net/ieee802154/Makefile
> >+++ b/drivers/net/ieee802154/Makefile
> >@@ -2,3 +2,4 @@ obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o
> >  obj-$(CONFIG_IEEE802154_AT86RF230) += at86rf230.o
> >  obj-$(CONFIG_IEEE802154_MRF24J40) += mrf24j40.o
> >  obj-$(CONFIG_IEEE802154_CC2520) += cc2520.o
> >+obj-$(CONFIG_IEEE802154_ATUSB) += atusb.o
> >diff --git a/drivers/net/ieee802154/at86rf230.c
> >b/drivers/net/ieee802154/at86rf230.c
> >index 8d5ed6e..d417ceb 100644
> >--- a/drivers/net/ieee802154/at86rf230.c
> >+++ b/drivers/net/ieee802154/at86rf230.c
> >@@ -35,6 +35,8 @@
> >  #include <net/mac802154.h>
> >  #include <net/cfg802154.h>
> >
> >+#include "at86rf230.h"
> >+
> >  struct at86rf230_local;
> >  /* at86rf2xx chip depend data.
> >   * All timings are in us.
> >@@ -102,203 +104,6 @@ struct at86rf230_local {
> >  	struct at86rf230_state_change tx;
> >  };
> >
> >-#define RG_TRX_STATUS	(0x01)
> >-#define SR_TRX_STATUS		0x01, 0x1f, 0
> >-#define SR_RESERVED_01_3	0x01, 0x20, 5
> >-#define SR_CCA_STATUS		0x01, 0x40, 6
> >-#define SR_CCA_DONE		0x01, 0x80, 7
> >-#define RG_TRX_STATE	(0x02)
> >-#define SR_TRX_CMD		0x02, 0x1f, 0
> >-#define SR_TRAC_STATUS		0x02, 0xe0, 5
> >-#define RG_TRX_CTRL_0	(0x03)
> >-#define SR_CLKM_CTRL		0x03, 0x07, 0
> >-#define SR_CLKM_SHA_SEL		0x03, 0x08, 3
> >-#define SR_PAD_IO_CLKM		0x03, 0x30, 4
> >-#define SR_PAD_IO		0x03, 0xc0, 6
> >-#define RG_TRX_CTRL_1	(0x04)
> >-#define SR_IRQ_POLARITY		0x04, 0x01, 0
> >-#define SR_IRQ_MASK_MODE	0x04, 0x02, 1
> >-#define SR_SPI_CMD_MODE		0x04, 0x0c, 2
> >-#define SR_RX_BL_CTRL		0x04, 0x10, 4
> >-#define SR_TX_AUTO_CRC_ON	0x04, 0x20, 5
> >-#define SR_IRQ_2_EXT_EN		0x04, 0x40, 6
> >-#define SR_PA_EXT_EN		0x04, 0x80, 7
> >-#define RG_PHY_TX_PWR	(0x05)
> >-#define SR_TX_PWR_23X		0x05, 0x0f, 0
> >-#define SR_PA_LT_230		0x05, 0x30, 4
> >-#define SR_PA_BUF_LT_230	0x05, 0xc0, 6
> >-#define SR_TX_PWR_212		0x05, 0x1f, 0
> >-#define SR_GC_PA_212		0x05, 0x60, 5
> >-#define SR_PA_BOOST_LT_212	0x05, 0x80, 7
> >-#define RG_PHY_RSSI	(0x06)
> >-#define SR_RSSI			0x06, 0x1f, 0
> >-#define SR_RND_VALUE		0x06, 0x60, 5
> >-#define SR_RX_CRC_VALID		0x06, 0x80, 7
> >-#define RG_PHY_ED_LEVEL	(0x07)
> >-#define SR_ED_LEVEL		0x07, 0xff, 0
> >-#define RG_PHY_CC_CCA	(0x08)
> >-#define SR_CHANNEL		0x08, 0x1f, 0
> >-#define SR_CCA_MODE		0x08, 0x60, 5
> >-#define SR_CCA_REQUEST		0x08, 0x80, 7
> >-#define RG_CCA_THRES	(0x09)
> >-#define SR_CCA_ED_THRES		0x09, 0x0f, 0
> >-#define SR_RESERVED_09_1	0x09, 0xf0, 4
> >-#define RG_RX_CTRL	(0x0a)
> >-#define SR_PDT_THRES		0x0a, 0x0f, 0
> >-#define SR_RESERVED_0a_1	0x0a, 0xf0, 4
> >-#define RG_SFD_VALUE	(0x0b)
> >-#define SR_SFD_VALUE		0x0b, 0xff, 0
> >-#define RG_TRX_CTRL_2	(0x0c)
> >-#define SR_OQPSK_DATA_RATE	0x0c, 0x03, 0
> >-#define SR_SUB_MODE		0x0c, 0x04, 2
> >-#define SR_BPSK_QPSK		0x0c, 0x08, 3
> >-#define SR_OQPSK_SUB1_RC_EN	0x0c, 0x10, 4
> >-#define SR_RESERVED_0c_5	0x0c, 0x60, 5
> >-#define SR_RX_SAFE_MODE		0x0c, 0x80, 7
> >-#define RG_ANT_DIV	(0x0d)
> >-#define SR_ANT_CTRL		0x0d, 0x03, 0
> >-#define SR_ANT_EXT_SW_EN	0x0d, 0x04, 2
> >-#define SR_ANT_DIV_EN		0x0d, 0x08, 3
> >-#define SR_RESERVED_0d_2	0x0d, 0x70, 4
> >-#define SR_ANT_SEL		0x0d, 0x80, 7
> >-#define RG_IRQ_MASK	(0x0e)
> >-#define SR_IRQ_MASK		0x0e, 0xff, 0
> >-#define RG_IRQ_STATUS	(0x0f)
> >-#define SR_IRQ_0_PLL_LOCK	0x0f, 0x01, 0
> >-#define SR_IRQ_1_PLL_UNLOCK	0x0f, 0x02, 1
> >-#define SR_IRQ_2_RX_START	0x0f, 0x04, 2
> >-#define SR_IRQ_3_TRX_END	0x0f, 0x08, 3
> >-#define SR_IRQ_4_CCA_ED_DONE	0x0f, 0x10, 4
> >-#define SR_IRQ_5_AMI		0x0f, 0x20, 5
> >-#define SR_IRQ_6_TRX_UR		0x0f, 0x40, 6
> >-#define SR_IRQ_7_BAT_LOW	0x0f, 0x80, 7
> >-#define RG_VREG_CTRL	(0x10)
> >-#define SR_RESERVED_10_6	0x10, 0x03, 0
> >-#define SR_DVDD_OK		0x10, 0x04, 2
> >-#define SR_DVREG_EXT		0x10, 0x08, 3
> >-#define SR_RESERVED_10_3	0x10, 0x30, 4
> >-#define SR_AVDD_OK		0x10, 0x40, 6
> >-#define SR_AVREG_EXT		0x10, 0x80, 7
> >-#define RG_BATMON	(0x11)
> >-#define SR_BATMON_VTH		0x11, 0x0f, 0
> >-#define SR_BATMON_HR		0x11, 0x10, 4
> >-#define SR_BATMON_OK		0x11, 0x20, 5
> >-#define SR_RESERVED_11_1	0x11, 0xc0, 6
> >-#define RG_XOSC_CTRL	(0x12)
> >-#define SR_XTAL_TRIM		0x12, 0x0f, 0
> >-#define SR_XTAL_MODE		0x12, 0xf0, 4
> >-#define RG_RX_SYN	(0x15)
> >-#define SR_RX_PDT_LEVEL		0x15, 0x0f, 0
> >-#define SR_RESERVED_15_2	0x15, 0x70, 4
> >-#define SR_RX_PDT_DIS		0x15, 0x80, 7
> >-#define RG_XAH_CTRL_1	(0x17)
> >-#define SR_RESERVED_17_8	0x17, 0x01, 0
> >-#define SR_AACK_PROM_MODE	0x17, 0x02, 1
> >-#define SR_AACK_ACK_TIME	0x17, 0x04, 2
> >-#define SR_RESERVED_17_5	0x17, 0x08, 3
> >-#define SR_AACK_UPLD_RES_FT	0x17, 0x10, 4
> >-#define SR_AACK_FLTR_RES_FT	0x17, 0x20, 5
> >-#define SR_CSMA_LBT_MODE	0x17, 0x40, 6
> >-#define SR_RESERVED_17_1	0x17, 0x80, 7
> >-#define RG_FTN_CTRL	(0x18)
> >-#define SR_RESERVED_18_2	0x18, 0x7f, 0
> >-#define SR_FTN_START		0x18, 0x80, 7
> >-#define RG_PLL_CF	(0x1a)
> >-#define SR_RESERVED_1a_2	0x1a, 0x7f, 0
> >-#define SR_PLL_CF_START		0x1a, 0x80, 7
> >-#define RG_PLL_DCU	(0x1b)
> >-#define SR_RESERVED_1b_3	0x1b, 0x3f, 0
> >-#define SR_RESERVED_1b_2	0x1b, 0x40, 6
> >-#define SR_PLL_DCU_START	0x1b, 0x80, 7
> >-#define RG_PART_NUM	(0x1c)
> >-#define SR_PART_NUM		0x1c, 0xff, 0
> >-#define RG_VERSION_NUM	(0x1d)
> >-#define SR_VERSION_NUM		0x1d, 0xff, 0
> >-#define RG_MAN_ID_0	(0x1e)
> >-#define SR_MAN_ID_0		0x1e, 0xff, 0
> >-#define RG_MAN_ID_1	(0x1f)
> >-#define SR_MAN_ID_1		0x1f, 0xff, 0
> >-#define RG_SHORT_ADDR_0	(0x20)
> >-#define SR_SHORT_ADDR_0		0x20, 0xff, 0
> >-#define RG_SHORT_ADDR_1	(0x21)
> >-#define SR_SHORT_ADDR_1		0x21, 0xff, 0
> >-#define RG_PAN_ID_0	(0x22)
> >-#define SR_PAN_ID_0		0x22, 0xff, 0
> >-#define RG_PAN_ID_1	(0x23)
> >-#define SR_PAN_ID_1		0x23, 0xff, 0
> >-#define RG_IEEE_ADDR_0	(0x24)
> >-#define SR_IEEE_ADDR_0		0x24, 0xff, 0
> >-#define RG_IEEE_ADDR_1	(0x25)
> >-#define SR_IEEE_ADDR_1		0x25, 0xff, 0
> >-#define RG_IEEE_ADDR_2	(0x26)
> >-#define SR_IEEE_ADDR_2		0x26, 0xff, 0
> >-#define RG_IEEE_ADDR_3	(0x27)
> >-#define SR_IEEE_ADDR_3		0x27, 0xff, 0
> >-#define RG_IEEE_ADDR_4	(0x28)
> >-#define SR_IEEE_ADDR_4		0x28, 0xff, 0
> >-#define RG_IEEE_ADDR_5	(0x29)
> >-#define SR_IEEE_ADDR_5		0x29, 0xff, 0
> >-#define RG_IEEE_ADDR_6	(0x2a)
> >-#define SR_IEEE_ADDR_6		0x2a, 0xff, 0
> >-#define RG_IEEE_ADDR_7	(0x2b)
> >-#define SR_IEEE_ADDR_7		0x2b, 0xff, 0
> >-#define RG_XAH_CTRL_0	(0x2c)
> >-#define SR_SLOTTED_OPERATION	0x2c, 0x01, 0
> >-#define SR_MAX_CSMA_RETRIES	0x2c, 0x0e, 1
> >-#define SR_MAX_FRAME_RETRIES	0x2c, 0xf0, 4
> >-#define RG_CSMA_SEED_0	(0x2d)
> >-#define SR_CSMA_SEED_0		0x2d, 0xff, 0
> >-#define RG_CSMA_SEED_1	(0x2e)
> >-#define SR_CSMA_SEED_1		0x2e, 0x07, 0
> >-#define SR_AACK_I_AM_COORD	0x2e, 0x08, 3
> >-#define SR_AACK_DIS_ACK		0x2e, 0x10, 4
> >-#define SR_AACK_SET_PD		0x2e, 0x20, 5
> >-#define SR_AACK_FVN_MODE	0x2e, 0xc0, 6
> >-#define RG_CSMA_BE	(0x2f)
> >-#define SR_MIN_BE		0x2f, 0x0f, 0
> >-#define SR_MAX_BE		0x2f, 0xf0, 4
> >-
> >-#define CMD_REG		0x80
> >-#define CMD_REG_MASK	0x3f
> >-#define CMD_WRITE	0x40
> >-#define CMD_FB		0x20
> >-
> >-#define IRQ_BAT_LOW	(1 << 7)
> >-#define IRQ_TRX_UR	(1 << 6)
> >-#define IRQ_AMI		(1 << 5)
> >-#define IRQ_CCA_ED	(1 << 4)
> >-#define IRQ_TRX_END	(1 << 3)
> >-#define IRQ_RX_START	(1 << 2)
> >-#define IRQ_PLL_UNL	(1 << 1)
> >-#define IRQ_PLL_LOCK	(1 << 0)
> >-
> >-#define IRQ_ACTIVE_HIGH	0
> >-#define IRQ_ACTIVE_LOW	1
> >-
> >-#define STATE_P_ON		0x00	/* BUSY */
> >-#define STATE_BUSY_RX		0x01
> >-#define STATE_BUSY_TX		0x02
> >-#define STATE_FORCE_TRX_OFF	0x03
> >-#define STATE_FORCE_TX_ON	0x04	/* IDLE */
> >-/* 0x05 */				/* INVALID_PARAMETER */
> >-#define STATE_RX_ON		0x06
> >-/* 0x07 */				/* SUCCESS */
> >-#define STATE_TRX_OFF		0x08
> >-#define STATE_TX_ON		0x09
> >-/* 0x0a - 0x0e */			/* 0x0a - UNSUPPORTED_ATTRIBUTE */
> >-#define STATE_SLEEP		0x0F
> >-#define STATE_PREP_DEEP_SLEEP	0x10
> >-#define STATE_BUSY_RX_AACK	0x11
> >-#define STATE_BUSY_TX_ARET	0x12
> >-#define STATE_RX_AACK_ON	0x16
> >-#define STATE_TX_ARET_ON	0x19
> >-#define STATE_RX_ON_NOCLK	0x1C
> >-#define STATE_RX_AACK_ON_NOCLK	0x1D
> >-#define STATE_BUSY_RX_AACK_NOCLK 0x1E
> >-#define STATE_TRANSITION_IN_PROGRESS 0x1F
> >-
> >-#define TRX_STATE_MASK		(0x1F)
> >-
> >  #define AT86RF2XX_NUMREGS 0x3F
> >
> >  static void
> >diff --git a/drivers/net/ieee802154/at86rf230.h
> >b/drivers/net/ieee802154/at86rf230.h
> >new file mode 100644
> >index 0000000..1e6d1cc
> >--- /dev/null
> >+++ b/drivers/net/ieee802154/at86rf230.h
> >@@ -0,0 +1,220 @@
> >+/*
> >+ * AT86RF230/RF231 driver
> >+ *
> >+ * Copyright (C) 2009-2012 Siemens AG
> >+ *
> >+ * This program is free software; you can redistribute it and/or modify
> >+ * it under the terms of the GNU General Public License version 2
> >+ * as published by the Free Software Foundation.
> >+ *
> >+ * This program is distributed in the hope that it will be useful,
> >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >+ * GNU General Public License for more details.
> >+ *
> >+ * Written by:
> >+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >+ * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
> >+ */
> >+
> >+#ifndef _AT86RF230_H
> >+#define _AT86RF230_H
> >+
> >+#define RG_TRX_STATUS	(0x01)
> >+#define SR_TRX_STATUS		0x01, 0x1f, 0
> >+#define SR_RESERVED_01_3	0x01, 0x20, 5
> >+#define SR_CCA_STATUS		0x01, 0x40, 6
> >+#define SR_CCA_DONE		0x01, 0x80, 7
> >+#define RG_TRX_STATE	(0x02)
> >+#define SR_TRX_CMD		0x02, 0x1f, 0
> >+#define SR_TRAC_STATUS		0x02, 0xe0, 5
> >+#define RG_TRX_CTRL_0	(0x03)
> >+#define SR_CLKM_CTRL		0x03, 0x07, 0
> >+#define SR_CLKM_SHA_SEL		0x03, 0x08, 3
> >+#define SR_PAD_IO_CLKM		0x03, 0x30, 4
> >+#define SR_PAD_IO		0x03, 0xc0, 6
> >+#define RG_TRX_CTRL_1	(0x04)
> >+#define SR_IRQ_POLARITY		0x04, 0x01, 0
> >+#define SR_IRQ_MASK_MODE	0x04, 0x02, 1
> >+#define SR_SPI_CMD_MODE		0x04, 0x0c, 2
> >+#define SR_RX_BL_CTRL		0x04, 0x10, 4
> >+#define SR_TX_AUTO_CRC_ON	0x04, 0x20, 5
> >+#define SR_IRQ_2_EXT_EN		0x04, 0x40, 6
> >+#define SR_PA_EXT_EN		0x04, 0x80, 7
> >+#define RG_PHY_TX_PWR	(0x05)
> >+#define SR_TX_PWR_23X		0x05, 0x0f, 0
> >+#define SR_PA_LT_230		0x05, 0x30, 4
> >+#define SR_PA_BUF_LT_230	0x05, 0xc0, 6
> >+#define SR_TX_PWR_212		0x05, 0x1f, 0
> >+#define SR_GC_PA_212		0x05, 0x60, 5
> >+#define SR_PA_BOOST_LT_212	0x05, 0x80, 7
> >+#define RG_PHY_RSSI	(0x06)
> >+#define SR_RSSI			0x06, 0x1f, 0
> >+#define SR_RND_VALUE		0x06, 0x60, 5
> >+#define SR_RX_CRC_VALID		0x06, 0x80, 7
> >+#define RG_PHY_ED_LEVEL	(0x07)
> >+#define SR_ED_LEVEL		0x07, 0xff, 0
> >+#define RG_PHY_CC_CCA	(0x08)
> >+#define SR_CHANNEL		0x08, 0x1f, 0
> >+#define SR_CCA_MODE		0x08, 0x60, 5
> >+#define SR_CCA_REQUEST		0x08, 0x80, 7
> >+#define RG_CCA_THRES	(0x09)
> >+#define SR_CCA_ED_THRES		0x09, 0x0f, 0
> >+#define SR_RESERVED_09_1	0x09, 0xf0, 4
> >+#define RG_RX_CTRL	(0x0a)
> >+#define SR_PDT_THRES		0x0a, 0x0f, 0
> >+#define SR_RESERVED_0a_1	0x0a, 0xf0, 4
> >+#define RG_SFD_VALUE	(0x0b)
> >+#define SR_SFD_VALUE		0x0b, 0xff, 0
> >+#define RG_TRX_CTRL_2	(0x0c)
> >+#define SR_OQPSK_DATA_RATE	0x0c, 0x03, 0
> >+#define SR_SUB_MODE		0x0c, 0x04, 2
> >+#define SR_BPSK_QPSK		0x0c, 0x08, 3
> >+#define SR_OQPSK_SUB1_RC_EN	0x0c, 0x10, 4
> >+#define SR_RESERVED_0c_5	0x0c, 0x60, 5
> >+#define SR_RX_SAFE_MODE		0x0c, 0x80, 7
> >+#define RG_ANT_DIV	(0x0d)
> >+#define SR_ANT_CTRL		0x0d, 0x03, 0
> >+#define SR_ANT_EXT_SW_EN	0x0d, 0x04, 2
> >+#define SR_ANT_DIV_EN		0x0d, 0x08, 3
> >+#define SR_RESERVED_0d_2	0x0d, 0x70, 4
> >+#define SR_ANT_SEL		0x0d, 0x80, 7
> >+#define RG_IRQ_MASK	(0x0e)
> >+#define SR_IRQ_MASK		0x0e, 0xff, 0
> >+#define RG_IRQ_STATUS	(0x0f)
> >+#define SR_IRQ_0_PLL_LOCK	0x0f, 0x01, 0
> >+#define SR_IRQ_1_PLL_UNLOCK	0x0f, 0x02, 1
> >+#define SR_IRQ_2_RX_START	0x0f, 0x04, 2
> >+#define SR_IRQ_3_TRX_END	0x0f, 0x08, 3
> >+#define SR_IRQ_4_CCA_ED_DONE	0x0f, 0x10, 4
> >+#define SR_IRQ_5_AMI		0x0f, 0x20, 5
> >+#define SR_IRQ_6_TRX_UR		0x0f, 0x40, 6
> >+#define SR_IRQ_7_BAT_LOW	0x0f, 0x80, 7
> >+#define RG_VREG_CTRL	(0x10)
> >+#define SR_RESERVED_10_6	0x10, 0x03, 0
> >+#define SR_DVDD_OK		0x10, 0x04, 2
> >+#define SR_DVREG_EXT		0x10, 0x08, 3
> >+#define SR_RESERVED_10_3	0x10, 0x30, 4
> >+#define SR_AVDD_OK		0x10, 0x40, 6
> >+#define SR_AVREG_EXT		0x10, 0x80, 7
> >+#define RG_BATMON	(0x11)
> >+#define SR_BATMON_VTH		0x11, 0x0f, 0
> >+#define SR_BATMON_HR		0x11, 0x10, 4
> >+#define SR_BATMON_OK		0x11, 0x20, 5
> >+#define SR_RESERVED_11_1	0x11, 0xc0, 6
> >+#define RG_XOSC_CTRL	(0x12)
> >+#define SR_XTAL_TRIM		0x12, 0x0f, 0
> >+#define SR_XTAL_MODE		0x12, 0xf0, 4
> >+#define RG_RX_SYN	(0x15)
> >+#define SR_RX_PDT_LEVEL		0x15, 0x0f, 0
> >+#define SR_RESERVED_15_2	0x15, 0x70, 4
> >+#define SR_RX_PDT_DIS		0x15, 0x80, 7
> >+#define RG_XAH_CTRL_1	(0x17)
> >+#define SR_RESERVED_17_8	0x17, 0x01, 0
> >+#define SR_AACK_PROM_MODE	0x17, 0x02, 1
> >+#define SR_AACK_ACK_TIME	0x17, 0x04, 2
> >+#define SR_RESERVED_17_5	0x17, 0x08, 3
> >+#define SR_AACK_UPLD_RES_FT	0x17, 0x10, 4
> >+#define SR_AACK_FLTR_RES_FT	0x17, 0x20, 5
> >+#define SR_CSMA_LBT_MODE	0x17, 0x40, 6
> >+#define SR_RESERVED_17_1	0x17, 0x80, 7
> >+#define RG_FTN_CTRL	(0x18)
> >+#define SR_RESERVED_18_2	0x18, 0x7f, 0
> >+#define SR_FTN_START		0x18, 0x80, 7
> >+#define RG_PLL_CF	(0x1a)
> >+#define SR_RESERVED_1a_2	0x1a, 0x7f, 0
> >+#define SR_PLL_CF_START		0x1a, 0x80, 7
> >+#define RG_PLL_DCU	(0x1b)
> >+#define SR_RESERVED_1b_3	0x1b, 0x3f, 0
> >+#define SR_RESERVED_1b_2	0x1b, 0x40, 6
> >+#define SR_PLL_DCU_START	0x1b, 0x80, 7
> >+#define RG_PART_NUM	(0x1c)
> >+#define SR_PART_NUM		0x1c, 0xff, 0
> >+#define RG_VERSION_NUM	(0x1d)
> >+#define SR_VERSION_NUM		0x1d, 0xff, 0
> >+#define RG_MAN_ID_0	(0x1e)
> >+#define SR_MAN_ID_0		0x1e, 0xff, 0
> >+#define RG_MAN_ID_1	(0x1f)
> >+#define SR_MAN_ID_1		0x1f, 0xff, 0
> >+#define RG_SHORT_ADDR_0	(0x20)
> >+#define SR_SHORT_ADDR_0		0x20, 0xff, 0
> >+#define RG_SHORT_ADDR_1	(0x21)
> >+#define SR_SHORT_ADDR_1		0x21, 0xff, 0
> >+#define RG_PAN_ID_0	(0x22)
> >+#define SR_PAN_ID_0		0x22, 0xff, 0
> >+#define RG_PAN_ID_1	(0x23)
> >+#define SR_PAN_ID_1		0x23, 0xff, 0
> >+#define RG_IEEE_ADDR_0	(0x24)
> >+#define SR_IEEE_ADDR_0		0x24, 0xff, 0
> >+#define RG_IEEE_ADDR_1	(0x25)
> >+#define SR_IEEE_ADDR_1		0x25, 0xff, 0
> >+#define RG_IEEE_ADDR_2	(0x26)
> >+#define SR_IEEE_ADDR_2		0x26, 0xff, 0
> >+#define RG_IEEE_ADDR_3	(0x27)
> >+#define SR_IEEE_ADDR_3		0x27, 0xff, 0
> >+#define RG_IEEE_ADDR_4	(0x28)
> >+#define SR_IEEE_ADDR_4		0x28, 0xff, 0
> >+#define RG_IEEE_ADDR_5	(0x29)
> >+#define SR_IEEE_ADDR_5		0x29, 0xff, 0
> >+#define RG_IEEE_ADDR_6	(0x2a)
> >+#define SR_IEEE_ADDR_6		0x2a, 0xff, 0
> >+#define RG_IEEE_ADDR_7	(0x2b)
> >+#define SR_IEEE_ADDR_7		0x2b, 0xff, 0
> >+#define RG_XAH_CTRL_0	(0x2c)
> >+#define SR_SLOTTED_OPERATION	0x2c, 0x01, 0
> >+#define SR_MAX_CSMA_RETRIES	0x2c, 0x0e, 1
> >+#define SR_MAX_FRAME_RETRIES	0x2c, 0xf0, 4
> >+#define RG_CSMA_SEED_0	(0x2d)
> >+#define SR_CSMA_SEED_0		0x2d, 0xff, 0
> >+#define RG_CSMA_SEED_1	(0x2e)
> >+#define SR_CSMA_SEED_1		0x2e, 0x07, 0
> >+#define SR_AACK_I_AM_COORD	0x2e, 0x08, 3
> >+#define SR_AACK_DIS_ACK		0x2e, 0x10, 4
> >+#define SR_AACK_SET_PD		0x2e, 0x20, 5
> >+#define SR_AACK_FVN_MODE	0x2e, 0xc0, 6
> >+#define RG_CSMA_BE	(0x2f)
> >+#define SR_MIN_BE		0x2f, 0x0f, 0
> >+#define SR_MAX_BE		0x2f, 0xf0, 4
> >+
> >+#define CMD_REG		0x80
> >+#define CMD_REG_MASK	0x3f
> >+#define CMD_WRITE	0x40
> >+#define CMD_FB		0x20
> >+
> >+#define IRQ_BAT_LOW	BIT(7)
> >+#define IRQ_TRX_UR	BIT(6)
> >+#define IRQ_AMI		BIT(5)
> >+#define IRQ_CCA_ED	BIT(4)
> >+#define IRQ_TRX_END	BIT(3)
> >+#define IRQ_RX_START	BIT(2)
> >+#define IRQ_PLL_UNL	BIT(1)
> >+#define IRQ_PLL_LOCK	BIT(0)
> >+
> >+#define IRQ_ACTIVE_HIGH	0
> >+#define IRQ_ACTIVE_LOW	1
> >+
> >+#define STATE_P_ON		0x00	/* BUSY */
> >+#define STATE_BUSY_RX		0x01
> >+#define STATE_BUSY_TX		0x02
> >+#define STATE_FORCE_TRX_OFF	0x03
> >+#define STATE_FORCE_TX_ON	0x04	/* IDLE */
> >+/* 0x05 */				/* INVALID_PARAMETER */
> >+#define STATE_RX_ON		0x06
> >+/* 0x07 */				/* SUCCESS */
> >+#define STATE_TRX_OFF		0x08
> >+#define STATE_TX_ON		0x09
> >+/* 0x0a - 0x0e */			/* 0x0a - UNSUPPORTED_ATTRIBUTE */
> >+#define STATE_SLEEP		0x0F
> >+#define STATE_PREP_DEEP_SLEEP	0x10
> >+#define STATE_BUSY_RX_AACK	0x11
> >+#define STATE_BUSY_TX_ARET	0x12
> >+#define STATE_RX_AACK_ON	0x16
> >+#define STATE_TX_ARET_ON	0x19
> >+#define STATE_RX_ON_NOCLK	0x1C
> >+#define STATE_RX_AACK_ON_NOCLK	0x1D
> >+#define STATE_BUSY_RX_AACK_NOCLK 0x1E
> >+#define STATE_TRANSITION_IN_PROGRESS 0x1F
> >+
> >+#define TRX_STATE_MASK		(0x1F)
> >+
> >+#endif /* !_AT86RF230_H */
> 
> I think I updated some of these defines at some point. Will go through my
> changes and see if I have any updates for this. Nothing imprtant for the
> current functionality so this can go in as is and the other patch follow up
> later. Mostly updated to some former reserved areas iirc.
> 

ok. That's good I just take the current defines from at86rf230 driver (I
did also some small changes there). Then we have fixed version for both
drivers.

> >diff --git a/drivers/net/ieee802154/atusb.c
> >b/drivers/net/ieee802154/atusb.c
> >new file mode 100644
> >index 0000000..ea1259e
> >--- /dev/null
> >+++ b/drivers/net/ieee802154/atusb.c
> >@@ -0,0 +1,692 @@
> >+/*
> >+ * atusb.c - Driver for the ATUSB IEEE 802.15.4 dongle
> >+ *
> >+ * Written 2013 by Werner Almesberger <werner@almesberger.net>
> >+ *
> >+ * This program is free software; you can redistribute it and/or
> >+ * modify it under the terms of the GNU General Public License as
> >+ * published by the Free Software Foundation, version 2
> >+ *
> >+ * Based on at86rf230.c and spi_atusb.c.
> >+ * at86rf230.c is
> >+ * Copyright (C) 2009 Siemens AG
> >+ * Written by: Dmitry Eremin-Solenikov <dmitry.baryshkov@siemens.com>
> >+ *
> >+ * spi_atusb.c is
> >+ * Copyright (c) 2011 Richard Sharpe <realrichardsharpe@gmail.com>
> >+ * Copyright (c) 2011 Stefan Schmidt <stefan@datenfreihafen.org>
> >+ * Copyright (c) 2011 Werner Almesberger <werner@almesberger.net>
> >+ *
> >+ * USB initialization is
> >+ * Copyright (c) 2013 Alexander Aring <alex.aring@gmail.com>
> >+ */
> >+
> >+#include <linux/kernel.h>
> >+#include <linux/slab.h>
> >+#include <linux/module.h>
> >+#include <linux/jiffies.h>
> >+#include <linux/usb.h>
> >+#include <linux/skbuff.h>
> >+
> >+#include <net/cfg802154.h>
> >+#include <net/mac802154.h>
> >+
> >+#include "at86rf230.h"
> >+#include "atusb.h"
> >+
> >+#define ATUSB_JEDEC_ATMEL	0x1f	/* JEDEC manufacturer ID */
> >+
> >+#define ATUSB_NUM_RX_URBS	4	/* allow for a bit of local
> >latency */
> >+#define ATUSB_ALLOC_DELAY_MS	100	/* delay after failed allocation
> >*/
> >+#define ATUSB_TX_TIMEOUT_MS	200	/* on the air timeout */
> >+
> >+struct atusb {
> >+	struct ieee802154_hw *hw;
> >+	struct usb_device *usb_dev;
> >+	int shutdown;			/* non-zero if shutting down */
> >+	int err;			/* set by first error */
> >+
> >+	/* RX variables */
> >+	struct delayed_work work;	/* memory allocations */
> >+	struct usb_anchor idle_urbs;	/* URBs waiting to be submitted */
> >+	struct usb_anchor rx_urbs;	/* URBs waiting for reception */
> >+
> >+	/* TX variables */
> >+	struct usb_ctrlrequest tx_dr;
> >+	struct urb *tx_urb;
> >+	struct sk_buff *tx_skb;
> >+	uint8_t tx_ack_seq;		/* current TX ACK sequence number
> >*/
> >+};
> >+
> >+/* at86rf230.h defines values as <reg, mask, shift> tuples. We use the
> >more
> >+ * traditional style of having registers and or-able values. SR_REG
> >extracts
> >+ * the register number. SR_VALUE uses the shift to prepare a value
> >accordingly.
> >+ */
> >+
> >+#define __SR_REG(reg, mask, shift)	(reg)
> >+#define SR_REG(sr)			__SR_REG(sr)
> >+
> >+#define __SR_VALUE(reg, mask, shift, val)	((val) << (shift))
> >+#define SR_VALUE(sr, val)			__SR_VALUE(sr, (val))
> >+
> >+/* ----- USB commands without data
> >----------------------------------------- */
> >+
> >+/* To reduce the number of error checks in the code, we record the first
> >error
> >+ * in atusb->err and reject all subsequent requests until the error is
> >cleared.
> >+ */
> >+
> >+static int atusb_control_msg(struct atusb *atusb, unsigned int pipe,
> >+			     __u8 request, __u8 requesttype,
> >+			     __u16 value, __u16 index,
> >+			     void *data, __u16 size, int timeout)
> >+{
> >+	struct usb_device *usb_dev = atusb->usb_dev;
> >+	int ret;
> >+
> >+	if (atusb->err)
> >+		return atusb->err;
> >+
> >+	ret = usb_control_msg(usb_dev, pipe, request, requesttype,
> >+			      value, index, data, size, timeout);
> >+	if (ret < 0) {
> >+		atusb->err = ret;
> >+		dev_err(&usb_dev->dev,
> >+			"atusb_control_msg: req 0x%02x val 0x%x idx 0x%x,
> >error %d\n",
> >+			request, value, index, ret);
> >+	}
> >+	return ret;
> >+}
> >+
> >+static int atusb_command(struct atusb *atusb, uint8_t cmd, uint8_t arg)
> >+{
> >+	struct usb_device *usb_dev = atusb->usb_dev;
> >+
> >+	dev_dbg(&usb_dev->dev, "atusb_command: cmd = 0x%x\n", cmd);
> >+	return atusb_control_msg(atusb, usb_sndctrlpipe(usb_dev, 0),
> >+				 cmd, ATUSB_REQ_TO_DEV, arg, 0, NULL, 0,
> >1000);
> >+}
> >+
> >+static int atusb_write_reg(struct atusb *atusb, uint8_t reg, uint8_t
> >value)
> >+{
> >+	struct usb_device *usb_dev = atusb->usb_dev;
> >+
> >+	dev_dbg(&usb_dev->dev, "atusb_write_reg: 0x%02x <- 0x%02x\n",
> >+		reg, value);
> >+	return atusb_control_msg(atusb, usb_sndctrlpipe(usb_dev, 0),
> >+				 ATUSB_REG_WRITE, ATUSB_REQ_TO_DEV,
> >+				 value, reg, NULL, 0, 1000);
> >+}
> >+
> >+static int atusb_read_reg(struct atusb *atusb, uint8_t reg)
> >+{
> >+	struct usb_device *usb_dev = atusb->usb_dev;
> >+	int ret;
> >+	uint8_t value;
> >+
> >+	dev_dbg(&usb_dev->dev, "atusb: reg = 0x%x\n", reg);
> >+	ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
> >+				ATUSB_REG_READ, ATUSB_REQ_FROM_DEV,
> >+				0, reg, &value, 1, 1000);
> >+	return ret >= 0 ? value : ret;
> >+}
> >+
> >+static int atusb_get_and_clear_error(struct atusb *atusb)
> >+{
> >+	int err = atusb->err;
> >+
> >+	atusb->err = 0;
> >+	return err;
> >+}
> >+
> >+/* ----- skb allocation
> >---------------------------------------------------- */
> 
> I was never a fan of these markers but Werner likes them. Keep them in does
> not do any harm.
> 

send patches. The driver isn't perfect but it's good to have them
mainline that we all can contribute now the work for this driver.

> >+
> >+#define MAX_PSDU	127
> >+#define MAX_RX_XFER	(1 + MAX_PSDU + 2 + 1)	/* PHR+PSDU+CRC+LQI */
> >+
> >+#define SKB_ATUSB(skb)	(*(struct atusb **)(skb)->cb)
> >+
> >+static void atusb_in(struct urb *urb);
> >+
> >+static int atusb_submit_rx_urb(struct atusb *atusb, struct urb *urb)
> >+{
> >+	struct usb_device *usb_dev = atusb->usb_dev;
> >+	struct sk_buff *skb = urb->context;
> >+	int ret;
> >+
> >+	if (!skb) {
> >+		skb = alloc_skb(MAX_RX_XFER, GFP_KERNEL);
> >+		if (!skb) {
> >+			dev_warn_ratelimited(&usb_dev->dev,
> >+					     "atusb_in: can't allocate
> >skb\n");
> >+			return -ENOMEM;
> >+		}
> >+		skb_put(skb, MAX_RX_XFER);
> >+		SKB_ATUSB(skb) = atusb;
> >+	}
> >+
> >+	usb_fill_bulk_urb(urb, usb_dev, usb_rcvbulkpipe(usb_dev, 1),
> >+			  skb->data, MAX_RX_XFER, atusb_in, skb);
> >+	usb_anchor_urb(urb, &atusb->rx_urbs);
> >+
> >+	ret = usb_submit_urb(urb, GFP_KERNEL);
> >+	if (ret) {
> >+		usb_unanchor_urb(urb);
> >+		kfree_skb(skb);
> >+		urb->context = NULL;
> >+	}
> >+	return ret;
> >+}
> >+
> >+static void atusb_work_urbs(struct work_struct *work)
> >+{
> >+	struct atusb *atusb =
> >+	    container_of(to_delayed_work(work), struct atusb, work);
> >+	struct usb_device *usb_dev = atusb->usb_dev;
> >+	struct urb *urb;
> >+	int ret;
> >+
> >+	if (atusb->shutdown)
> >+		return;
> >+
> >+	do {
> >+		urb = usb_get_from_anchor(&atusb->idle_urbs);
> >+		if (!urb)
> >+			return;
> >+		ret = atusb_submit_rx_urb(atusb, urb);
> >+	} while (!ret);
> >+
> >+	usb_anchor_urb(urb, &atusb->idle_urbs);
> >+	dev_warn_ratelimited(&usb_dev->dev,
> >+			     "atusb_in: can't allocate/submit URB (%d)\n",
> >ret);
> >+	schedule_delayed_work(&atusb->work,
> >+			      msecs_to_jiffies(ATUSB_ALLOC_DELAY_MS) + 1);
> >+}
> >+
> >+/* ----- Asynchronous USB
> >-------------------------------------------------- */
> >+
> >+static void atusb_tx_done(struct atusb *atusb, uint8_t seq)
> >+{
> >+	struct usb_device *usb_dev = atusb->usb_dev;
> >+	uint8_t expect = atusb->tx_ack_seq;
> >+
> >+	dev_dbg(&usb_dev->dev, "atusb_tx_done (0x%02x/0x%02x)\n", seq,
> >expect);
> >+	if (seq == expect) {
> >+		/* TODO check for ifs handling in firmware */
> >+		ieee802154_xmit_complete(atusb->hw, atusb->tx_skb, false);
> >+	} else {
> >+		/* TODO I experience this case when atusb has a tx
> >complete
> >+		 * irq before probing, we should fix the firmware it's an
> >+		 * unlikely case now that seq == expect is then true, but
> >can
> >+		 * happen and fail with a tx_skb = NULL;
> >+		 */
> 
> 
> Ah, so that comes with the xmit_async change. Looks like a good candidate
> for what I mentioned at the top about haveing a fw release now (0.1) and
> once we fixed the bug in the fw and released a fixed version we can check
> for it here and act according to the fw version. That is the only sane way
> to handle various fw versions I fear without upsetting our users with
> forcing new fw versions for new drivers on them.
> 

If somebody runs an old firmware on newer atusb driver then probing
fails with a message to update the firmware version, or should we
support all backwards supporting with all firmware versions?

> Only alternative I see is to ship compatible versions with linux-firmware to
> match the kernel version.
> 

This is what Marcel also told to me that we should doing that in this way.
The linux-firmware should also accept firmwares for persitent storage,
or is there some way to run dfu inside kernelspace to update the atusb
on the fly? I don't know if something like this exists.

> >+		ieee802154_wake_queue(atusb->hw);
> >+		if (atusb->tx_skb)
> >+			dev_kfree_skb_irq(atusb->tx_skb);
> >+	}
> >+}
> >+
> >+static void atusb_in_good(struct urb *urb)
> >+{
> >+	struct usb_device *usb_dev = urb->dev;
> >+	struct sk_buff *skb = urb->context;
> >+	struct atusb *atusb = SKB_ATUSB(skb);
> >+	uint8_t len, lqi;
> >+
> >+	if (!urb->actual_length) {
> >+		dev_dbg(&usb_dev->dev, "atusb_in: zero-sized URB ?\n");
> >+		return;
> >+	}
> >+
> >+	len = *skb->data;
> >+
> >+	if (urb->actual_length == 1) {
> >+		atusb_tx_done(atusb, len);
> >+		return;
> >+	}
> >+
> >+	if (len + 1 > urb->actual_length - 1) {
> >+		dev_dbg(&usb_dev->dev, "atusb_in: frame len %d+1 > URB
> >%u-1\n",
> >+			len, urb->actual_length);
> >+		return;
> >+	}
> >+
> >+	if (!ieee802154_is_valid_psdu_len(len)) {
> >+		dev_dbg(&usb_dev->dev, "atusb_in: frame corrupted\n");
> >+		return;
> >+	}
> >+
> >+	lqi = skb->data[len + 1];
> >+	dev_dbg(&usb_dev->dev, "atusb_in: rx len %d lqi 0x%02x\n", len,
> >lqi);
> >+	skb_pull(skb, 1);	/* remove PHR */
> >+	skb_trim(skb, len);	/* get payload only */
> 
> Hmm, the code I used here still has this:
> skb_trim(skb, len); /* remove CRC */
> 
> Do we now longer need this? Did you change the driver capabilities to match
> this?
> 

I splitted some times ago a hw flag IEEE802154_HW_OMIT_CKSUM. Which was
always that on transmit we have no FCS and while receive we have no
FCS.

But if you run as monitor you usually want to receive the CRC which was
on the air, not an own calculated one which is always correct even when
the frame was corrupted.

To handle backwards compatibility we have now:

#define IEEE802154_HW_OMIT_CKSUM        (IEEE802154_HW_TX_OMIT_CKSUM | \
					 IEEE802154_HW_RX_OMIT_CKSUM)

I changed the flag in atusb to have only IEEE802154_HW_TX_OMIT_CKSUM. We
deliver now the CRC to the next layer. This will remove the crc then
again before frame parsing, but when we support promisucous mode then
this handling will be more correct and the monitor will receive the CRC
which was on the air.

We still need to have:

skb_trim(skb, len);     /* get payload only */

because we need cut the last byte which is the lqi value, maybe this
handling can improved and we can drop this line.


btw: all drivers should be updated to not use IEEE802154_HW_OMIT_CKSUM
and cut the CRC while receiving.

> >+	ieee802154_rx_irqsafe(atusb->hw, skb, lqi);
> >+	urb->context = NULL;	/* skb is gone */
> >+}
> >+
> >+static void atusb_in(struct urb *urb)
> >+{
> >+	struct usb_device *usb_dev = urb->dev;
> >+	struct sk_buff *skb = urb->context;
> >+	struct atusb *atusb = SKB_ATUSB(skb);
> >+
> >+	dev_dbg(&usb_dev->dev, "atusb_in: status %d len %d\n",
> >+		urb->status, urb->actual_length);
> >+	if (urb->status) {
> >+		if (urb->status == -ENOENT) { /* being killed */
> >+			kfree_skb(skb);
> >+			urb->context = NULL;
> >+			return;
> >+		}
> >+		dev_dbg(&usb_dev->dev, "atusb_in: URB error %d\n",
> >urb->status);
> >+	} else {
> >+		atusb_in_good(urb);
> >+	}
> >+
> >+	usb_anchor_urb(urb, &atusb->idle_urbs);
> >+	if (!atusb->shutdown)
> >+		schedule_delayed_work(&atusb->work, 0);
> >+}
> >+
> >+/* ----- URB allocation/deallocation
> >--------------------------------------- */
> >+
> >+static void atusb_free_urbs(struct atusb *atusb)
> >+{
> >+	struct urb *urb;
> >+
> >+	while (1) {
> >+		urb = usb_get_from_anchor(&atusb->idle_urbs);
> >+		if (!urb)
> >+			break;
> >+		if (urb->context)
> >+			kfree_skb(urb->context);
> >+		usb_free_urb(urb);
> >+	}
> >+}
> >+
> >+static int atusb_alloc_urbs(struct atusb *atusb, int n)
> >+{
> >+	struct urb *urb;
> >+
> >+	while (n) {
> >+		urb = usb_alloc_urb(0, GFP_KERNEL);
> >+		if (!urb) {
> >+			atusb_free_urbs(atusb);
> >+			return -ENOMEM;
> >+		}
> >+		usb_anchor_urb(urb, &atusb->idle_urbs);
> >+		n--;
> >+	}
> >+	return 0;
> >+}
> >+
> >+/* ----- IEEE 802.15.4 interface operations
> >-------------------------------- */
> >+
> >+static void atusb_xmit_complete(struct urb *urb)
> >+{
> >+	dev_dbg(&urb->dev->dev, "atusb_xmit urb completed");
> >+}
> >+
> >+static int atusb_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
> >+{
> >+	struct atusb *atusb = hw->priv;
> >+	struct usb_device *usb_dev = atusb->usb_dev;
> >+	int ret;
> >+
> >+	dev_dbg(&usb_dev->dev, "atusb_xmit (%d)\n", skb->len);
> >+	atusb->tx_skb = skb;
> >+	atusb->tx_ack_seq++;
> >+	atusb->tx_dr.wIndex = cpu_to_le16(atusb->tx_ack_seq);
> >+	atusb->tx_dr.wLength = cpu_to_le16(skb->len);
> >+
> >+	usb_fill_control_urb(atusb->tx_urb, usb_dev,
> >+			     usb_sndctrlpipe(usb_dev, 0),
> >+			     (unsigned char *)&atusb->tx_dr, skb->data,
> >+			     skb->len, atusb_xmit_complete, NULL);
> >+	ret = usb_submit_urb(atusb->tx_urb, GFP_ATOMIC);
> >+	dev_dbg(&usb_dev->dev, "atusb_xmit done (%d)\n", ret);
> >+	return ret;
> >+}
> >+
> >+static int atusb_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
> >+{
> >+	struct atusb *atusb = hw->priv;
> >+	int ret;
> >+
> >+	/* This implicitly sets the CCA (Clear Channel Assessment) mode to
> >0,
> >+	 * "Mode 3a, Carrier sense OR energy above threshold".
> >+	 * We should probably make this configurable. @@@
> >+	 */
> >+	ret = atusb_write_reg(atusb, RG_PHY_CC_CCA, channel);
> >+	if (ret < 0)
> >+		return ret;
> >+	msleep(1);	/* @@@ ugly synchronization */
> 
> The hw->phy->current_channel = channel; is no longer needed here? Does the
> stack handle this part now?
> 

yes. See [0].

> >+	return 0;
> >+}
> >+
> >+static int atusb_ed(struct ieee802154_hw *hw, u8 *level)
> >+{
> >+	/* @@@ not used by the stack yet */
> >+	*level = 0;
> >+	return 0;
> >+}
> >+
> >+static int atusb_set_hw_addr_filt(struct ieee802154_hw *hw,
> >+				  struct ieee802154_hw_addr_filt *filt,
> >+				  unsigned long changed)
> >+{
> >+	struct atusb *atusb = hw->priv;
> >+	struct device *dev = &atusb->usb_dev->dev;
> >+	uint8_t reg;
> >+
> >+	if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
> >+		u16 addr = le16_to_cpu(filt->short_addr);
> >+
> >+		dev_vdbg(dev, "atusb_set_hw_addr_filt called for
> >saddr\n");
> >+		atusb_write_reg(atusb, RG_SHORT_ADDR_0, addr);
> >+		atusb_write_reg(atusb, RG_SHORT_ADDR_1, addr >> 8);
> >+	}
> >+
> >+	if (changed & IEEE802154_AFILT_PANID_CHANGED) {
> >+		u16 pan = le16_to_cpu(filt->pan_id);
> >+
> >+		dev_vdbg(dev, "atusb_set_hw_addr_filt called for pan
> >id\n");
> >+		atusb_write_reg(atusb, RG_PAN_ID_0, pan);
> >+		atusb_write_reg(atusb, RG_PAN_ID_1, pan >> 8);
> >+	}
> >+
> >+	if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
> >+		u8 i, addr[IEEE802154_EXTENDED_ADDR_LEN];
> >+
> >+		memcpy(addr, &filt->ieee_addr,
> >IEEE802154_EXTENDED_ADDR_LEN);
> >+		dev_vdbg(dev, "atusb_set_hw_addr_filt called for IEEE
> >addr\n");
> >+		for (i = 0; i < 8; i++)
> >+			atusb_write_reg(atusb, RG_IEEE_ADDR_0 + i,
> >addr[i]);
> >+	}
> >+
> >+	if (changed & IEEE802154_AFILT_PANC_CHANGED) {
> >+		dev_vdbg(dev,
> >+			 "atusb_set_hw_addr_filt called for panc
> >change\n");
> >+		reg = atusb_read_reg(atusb, SR_REG(SR_AACK_I_AM_COORD));
> >+		if (filt->pan_coord)
> >+			reg |= SR_VALUE(SR_AACK_I_AM_COORD, 1);
> >+		else
> >+			reg &= ~SR_VALUE(SR_AACK_I_AM_COORD, 1);
> >+		atusb_write_reg(atusb, SR_REG(SR_AACK_I_AM_COORD), reg);
> >+	}
> >+
> >+	return atusb_get_and_clear_error(atusb);
> >+}
> >+
> >+static int atusb_start(struct ieee802154_hw *hw)
> >+{
> >+	struct atusb *atusb = hw->priv;
> >+	struct usb_device *usb_dev = atusb->usb_dev;
> >+	int ret;
> >+
> >+	dev_dbg(&usb_dev->dev, "atusb_start\n");
> >+	schedule_delayed_work(&atusb->work, 0);
> >+	atusb_command(atusb, ATUSB_RX_MODE, 1);
> >+	ret = atusb_get_and_clear_error(atusb);
> >+	if (ret < 0)
> >+		usb_kill_anchored_urbs(&atusb->idle_urbs);
> >+	return ret;
> >+}
> >+
> >+static void atusb_stop(struct ieee802154_hw *hw)
> >+{
> >+	struct atusb *atusb = hw->priv;
> >+	struct usb_device *usb_dev = atusb->usb_dev;
> >+
> >+	dev_dbg(&usb_dev->dev, "atusb_stop\n");
> >+	usb_kill_anchored_urbs(&atusb->idle_urbs);
> >+	atusb_command(atusb, ATUSB_RX_MODE, 0);
> >+	atusb_get_and_clear_error(atusb);
> >+}
> >+
> >+static struct ieee802154_ops atusb_ops = {
> >+	.owner			= THIS_MODULE,
> >+	.xmit_async		= atusb_xmit,
> >+	.ed			= atusb_ed,
> >+	.set_channel		= atusb_channel,
> >+	.start			= atusb_start,
> >+	.stop			= atusb_stop,
> >+	.set_hw_addr_filt	= atusb_set_hw_addr_filt,
> >+};
> >+
> >+/* ----- Firmware and chip version information
> >----------------------------- */
> >+
> >+static int atusb_get_and_show_revision(struct atusb *atusb)
> >+{
> >+	struct usb_device *usb_dev = atusb->usb_dev;
> >+	unsigned char buffer[3];
> >+	int ret;
> >+
> >+	/* Get a couple of the ATMega Firmware values */
> >+	ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
> >+				ATUSB_ID, ATUSB_REQ_FROM_DEV, 0, 0,
> >+				buffer, 3, 1000);
> >+	if (ret >= 0)
> >+		dev_info(&usb_dev->dev,
> >+			 "Firmware: major: %u, minor: %u, hardware type:
> >%u\n",
> >+			 buffer[0], buffer[1], buffer[2]);
> >+
> >+	return ret;
> >+}
> >+
> >+static int atusb_get_and_show_build(struct atusb *atusb)
> >+{
> >+	struct usb_device *usb_dev = atusb->usb_dev;
> >+	char build[ATUSB_BUILD_SIZE + 1];
> >+	int ret;
> >+
> >+	ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
> >+				ATUSB_BUILD, ATUSB_REQ_FROM_DEV, 0, 0,
> >+				build, ATUSB_BUILD_SIZE, 1000);
> >+	if (ret >= 0) {
> >+		build[ret] = 0;
> >+		dev_info(&usb_dev->dev, "Firmware: build %s\n", build);
> >+	}
> >+
> >+	return ret;
> >+}
> >+
> >+static int atusb_get_and_show_chip(struct atusb *atusb)
> >+{
> >+	struct usb_device *usb_dev = atusb->usb_dev;
> >+	uint8_t man_id_0, man_id_1, part_num, version_num;
> >+
> >+	man_id_0 = atusb_read_reg(atusb, RG_MAN_ID_0);
> >+	man_id_1 = atusb_read_reg(atusb, RG_MAN_ID_1);
> >+	part_num = atusb_read_reg(atusb, RG_PART_NUM);
> >+	version_num = atusb_read_reg(atusb, RG_VERSION_NUM);
> >+
> >+	if (atusb->err)
> >+		return atusb->err;
> >+
> >+	if ((man_id_1 << 8 | man_id_0) != ATUSB_JEDEC_ATMEL) {
> >+		dev_err(&usb_dev->dev,
> >+			"non-Atmel transceiver xxxx%02x%02x\n",
> >+			man_id_1, man_id_0);
> >+		goto fail;
> >+	}
> >+	if (part_num != 3) {
> >+		dev_err(&usb_dev->dev,
> >+			"unexpected transceiver, part 0x%02x version
> >0x%02x\n",
> >+			part_num, version_num);
> >+		goto fail;
> >+	}
> >+
> >+	dev_info(&usb_dev->dev, "ATUSB: AT86RF231 version %d\n",
> >version_num);
> >+
> >+	return 0;
> >+
> >+fail:
> >+	atusb->err = -ENODEV;
> >+	return -ENODEV;
> >+}
> >+
> >+/* ----- Setup
> >------------------------------------------------------------- */
> >+
> >+static int atusb_probe(struct usb_interface *interface,
> >+		       const struct usb_device_id *id)
> >+{
> >+	struct usb_device *usb_dev = interface_to_usbdev(interface);
> >+	struct ieee802154_hw *hw;
> >+	struct atusb *atusb = NULL;
> >+	int ret = -ENOMEM;
> >+
> >+	hw = ieee802154_alloc_hw(sizeof(struct atusb), &atusb_ops);
> >+	if (!hw)
> >+		return -ENOMEM;
> >+
> >+	atusb = hw->priv;
> >+	atusb->hw = hw;
> >+	atusb->usb_dev = usb_get_dev(usb_dev);
> >+	usb_set_intfdata(interface, atusb);
> >+
> >+	atusb->shutdown = 0;
> >+	atusb->err = 0;
> >+	INIT_DELAYED_WORK(&atusb->work, atusb_work_urbs);
> >+	init_usb_anchor(&atusb->idle_urbs);
> >+	init_usb_anchor(&atusb->rx_urbs);
> >+
> >+	if (atusb_alloc_urbs(atusb, ATUSB_NUM_RX_URBS))
> >+		goto fail;
> >+
> >+	atusb->tx_dr.bRequestType = ATUSB_REQ_TO_DEV;
> >+	atusb->tx_dr.bRequest = ATUSB_TX;
> >+	atusb->tx_dr.wValue = cpu_to_le16(0);
> 
> What are these three lines for? ^^
> 

atusb->tx_dr is for async_xmit handling. These values are always the
same and I just setup this structure in probing time instead of setting
always the static value in async_xmit handling.

The async_xmit sets now only the tx_ack_seq which is a dynamic value and
skb->len.

> >+	atusb->tx_urb = usb_alloc_urb(0, GFP_ATOMIC);
> >+	if (!atusb->tx_urb)
> >+		goto fail;
> >+
> >+	hw->parent = &usb_dev->dev;
> >+	hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT;
> >+
> >+	hw->phy->current_page = 0;
> >+	hw->phy->current_channel = 11;	/* reset default */
> >+	hw->phy->supported.channels[0] = 0x7FFF800;
> >+	ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
> >+
> >+	atusb_command(atusb, ATUSB_RF_RESET, 0);
> >+	atusb_get_and_show_chip(atusb);
> >+	atusb_get_and_show_revision(atusb);
> >+	atusb_get_and_show_build(atusb);
> >+	ret = atusb_get_and_clear_error(atusb);
> >+	if (ret) {
> >+		dev_err(&atusb->usb_dev->dev,
> >+			"%s: initialization failed, error = %d\n",
> >+			__func__, ret);
> >+		goto fail;
> >+	}
> >+
> >+	ret = ieee802154_register_hw(hw);
> >+	if (ret)
> >+		goto fail;
> >+
> >+	/* If we just powered on, we're now in P_ON and need to enter
> >TRX_OFF
> >+	 * explicitly. Any resets after that will send us straight to
> >TRX_OFF,
> >+	 * making the command below redundant.
> >+	 */
> >+	atusb_write_reg(atusb, RG_TRX_STATE, STATE_FORCE_TRX_OFF);
> >+	msleep(1);	/* reset => TRX_OFF, tTR13 = 37 us */
> >+
> >+#if 0
> >+	/* Calculating the maximum time available to empty the frame
> >buffer
> >+	 * on reception:
> >+	 *
> >+	 * According to [1], the inter-frame gap is
> >+	 * R * 20 * 16 us + 128 us
> >+	 * where R is a random number from 0 to 7. Furthermore, we have 20
> >bit
> >+	 * times (80 us at 250 kbps) of SHR of the next frame before the
> >+	 * transceiver begins storing data in the frame buffer.
> >+	 *
> >+	 * This yields a minimum time of 208 us between the last data of a
> >+	 * frame and the first data of the next frame. This time is
> >further
> >+	 * reduced by interrupt latency in the atusb firmware.
> >+	 *
> >+	 * atusb currently needs about 500 us to retrieve a maximum-sized
> >+	 * frame. We therefore have to allow reception of a new frame to
> >begin
> >+	 * while we retrieve the previous frame.
> >+	 *
> >+	 * [1] "JN-AN-1035 Calculating data rates in an IEEE
> >802.15.4-based
> >+	 *      network", Jennic 2006.
> >+	 *
> >http://www.jennic.com/download_file.php?supportFile=JN-AN-1035%20Calculati
> >ng%20802-15-4%20Data%20Rates-1v0.pdf
> >+	 */
> >+
> >+	atusb_write_reg(atusb,
> >+			SR_REG(SR_RX_SAFE_MODE), SR_VALUE(SR_RX_SAFE_MODE,
> >1));
> >+#endif
> >+	atusb_write_reg(atusb, RG_IRQ_MASK, 0xff);
> >+
> >+	ret = atusb_get_and_clear_error(atusb);
> >+	if (!ret)
> >+		return 0;
> >+
> >+	dev_err(&atusb->usb_dev->dev,
> >+		"%s: setup failed, error = %d\n",
> >+		__func__, ret);
> >+
> >+	ieee802154_unregister_hw(hw);
> >+fail:
> >+	atusb_free_urbs(atusb);
> >+	usb_kill_urb(atusb->tx_urb);
> >+	usb_free_urb(atusb->tx_urb);
> >+	usb_put_dev(usb_dev);
> >+	ieee802154_free_hw(hw);
> >+	return ret;
> >+}
> >+
> >+static void atusb_disconnect(struct usb_interface *interface)
> >+{
> >+	struct atusb *atusb = usb_get_intfdata(interface);
> >+
> >+	dev_dbg(&atusb->usb_dev->dev, "atusb_disconnect\n");
> >+
> >+	atusb->shutdown = 1;
> >+	cancel_delayed_work_sync(&atusb->work);
> >+
> >+	usb_kill_anchored_urbs(&atusb->rx_urbs);
> >+	atusb_free_urbs(atusb);
> >+	usb_kill_urb(atusb->tx_urb);
> >+	usb_free_urb(atusb->tx_urb);
> >+
> >+	ieee802154_unregister_hw(atusb->hw);
> >+
> >+	ieee802154_free_hw(atusb->hw);
> >+
> >+	usb_set_intfdata(interface, NULL);
> >+	usb_put_dev(atusb->usb_dev);
> >+
> >+	pr_debug("atusb_disconnect done\n");
> >+}
> >+
> >+/* The devices we work with */
> >+static const struct usb_device_id atusb_device_table[] = {
> >+	{
> >+		.match_flags		= USB_DEVICE_ID_MATCH_DEVICE |
> >+					  USB_DEVICE_ID_MATCH_INT_INFO,
> >+		.idVendor		= ATUSB_VENDOR_ID,
> >+		.idProduct		= ATUSB_PRODUCT_ID,
> >+		.bInterfaceClass	= USB_CLASS_VENDOR_SPEC
> >+	},
> >+	/* end with null element */
> >+	{}
> >+};
> >+MODULE_DEVICE_TABLE(usb, atusb_device_table);
> >+
> >+static struct usb_driver atusb_driver = {
> >+	.name		= "atusb",
> >+	.probe		= atusb_probe,
> >+	.disconnect	= atusb_disconnect,
> >+	.id_table	= atusb_device_table,
> >+};
> >+module_usb_driver(atusb_driver);
> >+
> >+MODULE_AUTHOR("Alexander Aring <alex.aring@gmail.com>");
> >+MODULE_AUTHOR("Richard Sharpe <realrichardsharpe@gmail.com>");
> >+MODULE_AUTHOR("Stefan Schmidt <stefan@datenfreihafen.org>");
> >+MODULE_AUTHOR("Werner Almesberger <werner@almesberger.net>");
> >+MODULE_DESCRIPTION("ATUSB IEEE 802.15.4 Driver");
> >+MODULE_LICENSE("GPL");
> >diff --git a/drivers/net/ieee802154/atusb.h
> >b/drivers/net/ieee802154/atusb.h
> >new file mode 100644
> >index 0000000..0690edc
> >--- /dev/null
> >+++ b/drivers/net/ieee802154/atusb.h
> >@@ -0,0 +1,84 @@
> >+/*
> >+ * atusb.h - Definitions shared between kernel and ATUSB firmware
> >+ *
> >+ * Written 2013 by Werner Almesberger <werner@almesberger.net>
> >+ *
> >+ * This program is free software; you can redistribute it and/or
> >+ * modify it under the terms of the GNU General Public License as
> >+ * published by the Free Software Foundation, version 2, or
> >+ * (at your option) any later version.
> >+ *
> >+ * This file should be identical for kernel and firmware.
> >+ * Kernel: drivers/net/ieee802154/atusb.h
> >+ * Firmware: ben-wpan/atusb/fw/include/atusb/atusb.h
> >+ */
> >+
> >+#ifndef _ATUSB_H
> >+#define _ATUSB_H
> >+
> >+#define ATUSB_VENDOR_ID	0x20b7	/* Qi Hardware*/
> >+#define ATUSB_PRODUCT_ID 0x1540	/* 802.15.4, device 0 */
> >+				/*     -- -         - */
> >+
> >+#define ATUSB_BUILD_SIZE 256	/* maximum build version/date message
> >length */
> >+
> >+/* Commands to our device. Make sure this is synced with the firmware */
> >+enum atusb_requests {
> >+	ATUSB_ID			= 0x00,	/* system status/control
> >grp */
> >+	ATUSB_BUILD,
> >+	ATUSB_RESET,
> >+	ATUSB_RF_RESET			= 0x10,	/* debug/test group */
> >+	ATUSB_POLL_INT,
> >+	ATUSB_TEST,			/* atusb-sil only */
> >+	ATUSB_TIMER,
> >+	ATUSB_GPIO,
> >+	ATUSB_SLP_TR,
> >+	ATUSB_GPIO_CLEANUP,
> >+	ATUSB_REG_WRITE			= 0x20,	/* transceiver group */
> >+	ATUSB_REG_READ,
> >+	ATUSB_BUF_WRITE,
> >+	ATUSB_BUF_READ,
> >+	ATUSB_SRAM_WRITE,
> >+	ATUSB_SRAM_READ,
> >+	ATUSB_SPI_WRITE			= 0x30,	/* SPI group */
> >+	ATUSB_SPI_READ1,
> >+	ATUSB_SPI_READ2,
> >+	ATUSB_SPI_WRITE2_SYNC,
> >+	ATUSB_RX_MODE			= 0x40, /* HardMAC group */
> >+	ATUSB_TX,
> >+};
> >+
> >+/* Direction	bRequest		wValue		wIndex	wLength
> >+ *
> >+ * ->host	ATUSB_ID		-		-	3
> >+ * ->host	ATUSB_BUILD		-		-	#bytes
> >+ * host->	ATUSB_RESET		-		-	0
> >+ *
> >+ * host->	ATUSB_RF_RESET		-		-	0
> >+ * ->host	ATUSB_POLL_INT		-		-	1
> >+ * host->	ATUSB_TEST		-		-	0
> >+ * ->host	ATUSB_TIMER		-		-	#bytes (6)
> >+ * ->host	ATUSB_GPIO		dir+data	mask+p#	3
> >+ * host->	ATUSB_SLP_TR		-		-	0
> >+ * host->	ATUSB_GPIO_CLEANUP	-		-	0
> >+ *
> >+ * host->	ATUSB_REG_WRITE		value		addr	0
> >+ * ->host	ATUSB_REG_READ		-		addr	1
> >+ * host->	ATUSB_BUF_WRITE		-		-	#bytes
> >+ * ->host	ATUSB_BUF_READ		-		-	#bytes
> >+ * host->	ATUSB_SRAM_WRITE	-		addr	#bytes
> >+ * ->host	ATUSB_SRAM_READ		-		addr	#bytes
> >+ *
> >+ * host->	ATUSB_SPI_WRITE		byte0		byte1	#bytes
> >+ * ->host	ATUSB_SPI_READ1		byte0		-	#bytes
> >+ * ->host	ATUSB_SPI_READ2		byte0		byte1	#bytes
> >+ * ->host	ATUSB_SPI_WRITE2_SYNC	byte0		byte1	0/1
> >+ *
> >+ * host->	ATUSB_RX_MODE		on		-	0
> >+ * host->	ATUSB_TX		flags		ack_seq	#bytes
> >+ */
> >+
> >+#define ATUSB_REQ_FROM_DEV	(USB_TYPE_VENDOR | USB_DIR_IN)
> >+#define ATUSB_REQ_TO_DEV	(USB_TYPE_VENDOR | USB_DIR_OUT)
> >+
> >+#endif /* !_ATUSB_H */
> >
> 
> Besides the mentioned things this looks fine. Will give it some testing
> later this week.
> 

ok.

- Alex

[0] http://lxr.free-electrons.com/source/net/mac802154/cfg.c#L77

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH bluetooth-next 21/34] ieee802154: add support for atusb transceiver
  2015-05-19 11:52     ` Alexander Aring
@ 2015-05-19 13:22       ` Stefan Schmidt
  0 siblings, 0 replies; 45+ messages in thread
From: Stefan Schmidt @ 2015-05-19 13:22 UTC (permalink / raw)
  To: Alexander Aring
  Cc: linux-wpan, kernel, marcel, Werner Almesberger, Richard Sharpe

Hello.

On 19/05/15 13:52, Alexander Aring wrote:
> On Tue, May 19, 2015 at 12:49:21PM +0200, Stefan Schmidt wrote:
>> Hello.
>>
>> On 17/05/15 21:44, Alexander Aring wrote:
>>> This patch adds support for the atusb transceiver.
>>>
>>> The current driver supports basic functionality only. Possible further
>>> tasks would be to sync functionality with the at86rf230 driver, because
>>> the atusb use internally an at86rf231 transceiver. Some of these
>>> features need a firmware update like AACK and ARET handling.
>> We should really have a firmware release now that runs with the mainline
>> driver. For new features we can then check the fw version in the driver and
>> enable/disable accordingly.
>>
> Yep, the current fw code in ben-wpan repository is working. For myself I
> just change the RX_ON to RX_AACK_ON so the atusb works also in ARET
> enabled networks.

Which would make it a perfect moment to do an initial public release of 
the fw binary. Building it from scratch is nice for hacking but for 
people who only want to use the device it is annoying. If Werner has no 
time or motivation for this I think it is fine if either you or I 
prepare such a binary. Werner could upload it on the ben-wpan website or 
we add it to wpan.cakelab.org

>> Werner, is this something you would do? Making a release of the firmware? Or
>> should Alexander or myself look into this?
>>
>>> I did small changes to this driver to work with xmit_async callback and
>>> setting of a random extended perm address.
>> Thanks!
>>
>>> Signed-off-by: Alexander Aring <alex.aring@gmail.com>
>>> Cc: Werner Almesberger <werner@almesberger.net>
>>> Cc: Stefan Schmidt <s.schmidt@samsung.com>
>>> Cc: Richard Sharpe <realrichardsharpe@gmail.com>
>>> ---
>>>   drivers/net/ieee802154/Kconfig     |  10 +
>>>   drivers/net/ieee802154/Makefile    |   1 +
>>>   drivers/net/ieee802154/at86rf230.c | 199 +----------
>>>   drivers/net/ieee802154/at86rf230.h | 220 ++++++++++++
>>>   drivers/net/ieee802154/atusb.c     | 692
>>> +++++++++++++++++++++++++++++++++++++
>>>   drivers/net/ieee802154/atusb.h     |  84 +++++
>>>   6 files changed, 1009 insertions(+), 197 deletions(-)
>>>   create mode 100644 drivers/net/ieee802154/at86rf230.h
>>>   create mode 100644 drivers/net/ieee802154/atusb.c
>>>   create mode 100644 drivers/net/ieee802154/atusb.h
>>>
>>> diff --git a/drivers/net/ieee802154/Kconfig
>>> b/drivers/net/ieee802154/Kconfig
>>> index 1a3c3e5..1dd5ab8 100644
>>> --- a/drivers/net/ieee802154/Kconfig
>>> +++ b/drivers/net/ieee802154/Kconfig
>>> @@ -53,3 +53,13 @@ config IEEE802154_CC2520
>>>
>>>   	  This driver can also be built as a module. To do so, say M here.
>>>   	  the module will be called 'cc2520'.
>>> +
>>> +config IEEE802154_ATUSB
>>> +	tristate "ATUSB transceiver driver"
>>> +	depends on IEEE802154_DRIVERS && MAC802154 && USB
>>> +	---help---
>>> +	  Say Y here to enable the ATUSB IEEE 802.15.4 wireless
>>> +	  controller.
>>> +
>>> +	  This driver can also be built as a module. To do so say M here.
>>> +	  The module will be called 'atusb'.
>>> diff --git a/drivers/net/ieee802154/Makefile
>>> b/drivers/net/ieee802154/Makefile
>>> index d77fa4d..cf1d2a6 100644
>>> --- a/drivers/net/ieee802154/Makefile
>>> +++ b/drivers/net/ieee802154/Makefile
>>> @@ -2,3 +2,4 @@ obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o
>>>   obj-$(CONFIG_IEEE802154_AT86RF230) += at86rf230.o
>>>   obj-$(CONFIG_IEEE802154_MRF24J40) += mrf24j40.o
>>>   obj-$(CONFIG_IEEE802154_CC2520) += cc2520.o
>>> +obj-$(CONFIG_IEEE802154_ATUSB) += atusb.o
>>> diff --git a/drivers/net/ieee802154/at86rf230.c
>>> b/drivers/net/ieee802154/at86rf230.c
>>> index 8d5ed6e..d417ceb 100644
>>> --- a/drivers/net/ieee802154/at86rf230.c
>>> +++ b/drivers/net/ieee802154/at86rf230.c
>>> @@ -35,6 +35,8 @@
>>>   #include <net/mac802154.h>
>>>   #include <net/cfg802154.h>
>>>
>>> +#include "at86rf230.h"
>>> +
>>>   struct at86rf230_local;
>>>   /* at86rf2xx chip depend data.
>>>    * All timings are in us.
>>> @@ -102,203 +104,6 @@ struct at86rf230_local {
>>>   	struct at86rf230_state_change tx;
>>>   };
>>>
>>> -#define RG_TRX_STATUS	(0x01)
>>> -#define SR_TRX_STATUS		0x01, 0x1f, 0
>>> -#define SR_RESERVED_01_3	0x01, 0x20, 5
>>> -#define SR_CCA_STATUS		0x01, 0x40, 6
>>> -#define SR_CCA_DONE		0x01, 0x80, 7
>>> -#define RG_TRX_STATE	(0x02)
>>> -#define SR_TRX_CMD		0x02, 0x1f, 0
>>> -#define SR_TRAC_STATUS		0x02, 0xe0, 5
>>> -#define RG_TRX_CTRL_0	(0x03)
>>> -#define SR_CLKM_CTRL		0x03, 0x07, 0
>>> -#define SR_CLKM_SHA_SEL		0x03, 0x08, 3
>>> -#define SR_PAD_IO_CLKM		0x03, 0x30, 4
>>> -#define SR_PAD_IO		0x03, 0xc0, 6
>>> -#define RG_TRX_CTRL_1	(0x04)
>>> -#define SR_IRQ_POLARITY		0x04, 0x01, 0
>>> -#define SR_IRQ_MASK_MODE	0x04, 0x02, 1
>>> -#define SR_SPI_CMD_MODE		0x04, 0x0c, 2
>>> -#define SR_RX_BL_CTRL		0x04, 0x10, 4
>>> -#define SR_TX_AUTO_CRC_ON	0x04, 0x20, 5
>>> -#define SR_IRQ_2_EXT_EN		0x04, 0x40, 6
>>> -#define SR_PA_EXT_EN		0x04, 0x80, 7
>>> -#define RG_PHY_TX_PWR	(0x05)
>>> -#define SR_TX_PWR_23X		0x05, 0x0f, 0
>>> -#define SR_PA_LT_230		0x05, 0x30, 4
>>> -#define SR_PA_BUF_LT_230	0x05, 0xc0, 6
>>> -#define SR_TX_PWR_212		0x05, 0x1f, 0
>>> -#define SR_GC_PA_212		0x05, 0x60, 5
>>> -#define SR_PA_BOOST_LT_212	0x05, 0x80, 7
>>> -#define RG_PHY_RSSI	(0x06)
>>> -#define SR_RSSI			0x06, 0x1f, 0
>>> -#define SR_RND_VALUE		0x06, 0x60, 5
>>> -#define SR_RX_CRC_VALID		0x06, 0x80, 7
>>> -#define RG_PHY_ED_LEVEL	(0x07)
>>> -#define SR_ED_LEVEL		0x07, 0xff, 0
>>> -#define RG_PHY_CC_CCA	(0x08)
>>> -#define SR_CHANNEL		0x08, 0x1f, 0
>>> -#define SR_CCA_MODE		0x08, 0x60, 5
>>> -#define SR_CCA_REQUEST		0x08, 0x80, 7
>>> -#define RG_CCA_THRES	(0x09)
>>> -#define SR_CCA_ED_THRES		0x09, 0x0f, 0
>>> -#define SR_RESERVED_09_1	0x09, 0xf0, 4
>>> -#define RG_RX_CTRL	(0x0a)
>>> -#define SR_PDT_THRES		0x0a, 0x0f, 0
>>> -#define SR_RESERVED_0a_1	0x0a, 0xf0, 4
>>> -#define RG_SFD_VALUE	(0x0b)
>>> -#define SR_SFD_VALUE		0x0b, 0xff, 0
>>> -#define RG_TRX_CTRL_2	(0x0c)
>>> -#define SR_OQPSK_DATA_RATE	0x0c, 0x03, 0
>>> -#define SR_SUB_MODE		0x0c, 0x04, 2
>>> -#define SR_BPSK_QPSK		0x0c, 0x08, 3
>>> -#define SR_OQPSK_SUB1_RC_EN	0x0c, 0x10, 4
>>> -#define SR_RESERVED_0c_5	0x0c, 0x60, 5
>>> -#define SR_RX_SAFE_MODE		0x0c, 0x80, 7
>>> -#define RG_ANT_DIV	(0x0d)
>>> -#define SR_ANT_CTRL		0x0d, 0x03, 0
>>> -#define SR_ANT_EXT_SW_EN	0x0d, 0x04, 2
>>> -#define SR_ANT_DIV_EN		0x0d, 0x08, 3
>>> -#define SR_RESERVED_0d_2	0x0d, 0x70, 4
>>> -#define SR_ANT_SEL		0x0d, 0x80, 7
>>> -#define RG_IRQ_MASK	(0x0e)
>>> -#define SR_IRQ_MASK		0x0e, 0xff, 0
>>> -#define RG_IRQ_STATUS	(0x0f)
>>> -#define SR_IRQ_0_PLL_LOCK	0x0f, 0x01, 0
>>> -#define SR_IRQ_1_PLL_UNLOCK	0x0f, 0x02, 1
>>> -#define SR_IRQ_2_RX_START	0x0f, 0x04, 2
>>> -#define SR_IRQ_3_TRX_END	0x0f, 0x08, 3
>>> -#define SR_IRQ_4_CCA_ED_DONE	0x0f, 0x10, 4
>>> -#define SR_IRQ_5_AMI		0x0f, 0x20, 5
>>> -#define SR_IRQ_6_TRX_UR		0x0f, 0x40, 6
>>> -#define SR_IRQ_7_BAT_LOW	0x0f, 0x80, 7
>>> -#define RG_VREG_CTRL	(0x10)
>>> -#define SR_RESERVED_10_6	0x10, 0x03, 0
>>> -#define SR_DVDD_OK		0x10, 0x04, 2
>>> -#define SR_DVREG_EXT		0x10, 0x08, 3
>>> -#define SR_RESERVED_10_3	0x10, 0x30, 4
>>> -#define SR_AVDD_OK		0x10, 0x40, 6
>>> -#define SR_AVREG_EXT		0x10, 0x80, 7
>>> -#define RG_BATMON	(0x11)
>>> -#define SR_BATMON_VTH		0x11, 0x0f, 0
>>> -#define SR_BATMON_HR		0x11, 0x10, 4
>>> -#define SR_BATMON_OK		0x11, 0x20, 5
>>> -#define SR_RESERVED_11_1	0x11, 0xc0, 6
>>> -#define RG_XOSC_CTRL	(0x12)
>>> -#define SR_XTAL_TRIM		0x12, 0x0f, 0
>>> -#define SR_XTAL_MODE		0x12, 0xf0, 4
>>> -#define RG_RX_SYN	(0x15)
>>> -#define SR_RX_PDT_LEVEL		0x15, 0x0f, 0
>>> -#define SR_RESERVED_15_2	0x15, 0x70, 4
>>> -#define SR_RX_PDT_DIS		0x15, 0x80, 7
>>> -#define RG_XAH_CTRL_1	(0x17)
>>> -#define SR_RESERVED_17_8	0x17, 0x01, 0
>>> -#define SR_AACK_PROM_MODE	0x17, 0x02, 1
>>> -#define SR_AACK_ACK_TIME	0x17, 0x04, 2
>>> -#define SR_RESERVED_17_5	0x17, 0x08, 3
>>> -#define SR_AACK_UPLD_RES_FT	0x17, 0x10, 4
>>> -#define SR_AACK_FLTR_RES_FT	0x17, 0x20, 5
>>> -#define SR_CSMA_LBT_MODE	0x17, 0x40, 6
>>> -#define SR_RESERVED_17_1	0x17, 0x80, 7
>>> -#define RG_FTN_CTRL	(0x18)
>>> -#define SR_RESERVED_18_2	0x18, 0x7f, 0
>>> -#define SR_FTN_START		0x18, 0x80, 7
>>> -#define RG_PLL_CF	(0x1a)
>>> -#define SR_RESERVED_1a_2	0x1a, 0x7f, 0
>>> -#define SR_PLL_CF_START		0x1a, 0x80, 7
>>> -#define RG_PLL_DCU	(0x1b)
>>> -#define SR_RESERVED_1b_3	0x1b, 0x3f, 0
>>> -#define SR_RESERVED_1b_2	0x1b, 0x40, 6
>>> -#define SR_PLL_DCU_START	0x1b, 0x80, 7
>>> -#define RG_PART_NUM	(0x1c)
>>> -#define SR_PART_NUM		0x1c, 0xff, 0
>>> -#define RG_VERSION_NUM	(0x1d)
>>> -#define SR_VERSION_NUM		0x1d, 0xff, 0
>>> -#define RG_MAN_ID_0	(0x1e)
>>> -#define SR_MAN_ID_0		0x1e, 0xff, 0
>>> -#define RG_MAN_ID_1	(0x1f)
>>> -#define SR_MAN_ID_1		0x1f, 0xff, 0
>>> -#define RG_SHORT_ADDR_0	(0x20)
>>> -#define SR_SHORT_ADDR_0		0x20, 0xff, 0
>>> -#define RG_SHORT_ADDR_1	(0x21)
>>> -#define SR_SHORT_ADDR_1		0x21, 0xff, 0
>>> -#define RG_PAN_ID_0	(0x22)
>>> -#define SR_PAN_ID_0		0x22, 0xff, 0
>>> -#define RG_PAN_ID_1	(0x23)
>>> -#define SR_PAN_ID_1		0x23, 0xff, 0
>>> -#define RG_IEEE_ADDR_0	(0x24)
>>> -#define SR_IEEE_ADDR_0		0x24, 0xff, 0
>>> -#define RG_IEEE_ADDR_1	(0x25)
>>> -#define SR_IEEE_ADDR_1		0x25, 0xff, 0
>>> -#define RG_IEEE_ADDR_2	(0x26)
>>> -#define SR_IEEE_ADDR_2		0x26, 0xff, 0
>>> -#define RG_IEEE_ADDR_3	(0x27)
>>> -#define SR_IEEE_ADDR_3		0x27, 0xff, 0
>>> -#define RG_IEEE_ADDR_4	(0x28)
>>> -#define SR_IEEE_ADDR_4		0x28, 0xff, 0
>>> -#define RG_IEEE_ADDR_5	(0x29)
>>> -#define SR_IEEE_ADDR_5		0x29, 0xff, 0
>>> -#define RG_IEEE_ADDR_6	(0x2a)
>>> -#define SR_IEEE_ADDR_6		0x2a, 0xff, 0
>>> -#define RG_IEEE_ADDR_7	(0x2b)
>>> -#define SR_IEEE_ADDR_7		0x2b, 0xff, 0
>>> -#define RG_XAH_CTRL_0	(0x2c)
>>> -#define SR_SLOTTED_OPERATION	0x2c, 0x01, 0
>>> -#define SR_MAX_CSMA_RETRIES	0x2c, 0x0e, 1
>>> -#define SR_MAX_FRAME_RETRIES	0x2c, 0xf0, 4
>>> -#define RG_CSMA_SEED_0	(0x2d)
>>> -#define SR_CSMA_SEED_0		0x2d, 0xff, 0
>>> -#define RG_CSMA_SEED_1	(0x2e)
>>> -#define SR_CSMA_SEED_1		0x2e, 0x07, 0
>>> -#define SR_AACK_I_AM_COORD	0x2e, 0x08, 3
>>> -#define SR_AACK_DIS_ACK		0x2e, 0x10, 4
>>> -#define SR_AACK_SET_PD		0x2e, 0x20, 5
>>> -#define SR_AACK_FVN_MODE	0x2e, 0xc0, 6
>>> -#define RG_CSMA_BE	(0x2f)
>>> -#define SR_MIN_BE		0x2f, 0x0f, 0
>>> -#define SR_MAX_BE		0x2f, 0xf0, 4
>>> -
>>> -#define CMD_REG		0x80
>>> -#define CMD_REG_MASK	0x3f
>>> -#define CMD_WRITE	0x40
>>> -#define CMD_FB		0x20
>>> -
>>> -#define IRQ_BAT_LOW	(1 << 7)
>>> -#define IRQ_TRX_UR	(1 << 6)
>>> -#define IRQ_AMI		(1 << 5)
>>> -#define IRQ_CCA_ED	(1 << 4)
>>> -#define IRQ_TRX_END	(1 << 3)
>>> -#define IRQ_RX_START	(1 << 2)
>>> -#define IRQ_PLL_UNL	(1 << 1)
>>> -#define IRQ_PLL_LOCK	(1 << 0)
>>> -
>>> -#define IRQ_ACTIVE_HIGH	0
>>> -#define IRQ_ACTIVE_LOW	1
>>> -
>>> -#define STATE_P_ON		0x00	/* BUSY */
>>> -#define STATE_BUSY_RX		0x01
>>> -#define STATE_BUSY_TX		0x02
>>> -#define STATE_FORCE_TRX_OFF	0x03
>>> -#define STATE_FORCE_TX_ON	0x04	/* IDLE */
>>> -/* 0x05 */				/* INVALID_PARAMETER */
>>> -#define STATE_RX_ON		0x06
>>> -/* 0x07 */				/* SUCCESS */
>>> -#define STATE_TRX_OFF		0x08
>>> -#define STATE_TX_ON		0x09
>>> -/* 0x0a - 0x0e */			/* 0x0a - UNSUPPORTED_ATTRIBUTE */
>>> -#define STATE_SLEEP		0x0F
>>> -#define STATE_PREP_DEEP_SLEEP	0x10
>>> -#define STATE_BUSY_RX_AACK	0x11
>>> -#define STATE_BUSY_TX_ARET	0x12
>>> -#define STATE_RX_AACK_ON	0x16
>>> -#define STATE_TX_ARET_ON	0x19
>>> -#define STATE_RX_ON_NOCLK	0x1C
>>> -#define STATE_RX_AACK_ON_NOCLK	0x1D
>>> -#define STATE_BUSY_RX_AACK_NOCLK 0x1E
>>> -#define STATE_TRANSITION_IN_PROGRESS 0x1F
>>> -
>>> -#define TRX_STATE_MASK		(0x1F)
>>> -
>>>   #define AT86RF2XX_NUMREGS 0x3F
>>>
>>>   static void
>>> diff --git a/drivers/net/ieee802154/at86rf230.h
>>> b/drivers/net/ieee802154/at86rf230.h
>>> new file mode 100644
>>> index 0000000..1e6d1cc
>>> --- /dev/null
>>> +++ b/drivers/net/ieee802154/at86rf230.h
>>> @@ -0,0 +1,220 @@
>>> +/*
>>> + * AT86RF230/RF231 driver
>>> + *
>>> + * Copyright (C) 2009-2012 Siemens AG
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License version 2
>>> + * as published by the Free Software Foundation.
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>> + * GNU General Public License for more details.
>>> + *
>>> + * Written by:
>>> + * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>> + * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
>>> + */
>>> +
>>> +#ifndef _AT86RF230_H
>>> +#define _AT86RF230_H
>>> +
>>> +#define RG_TRX_STATUS	(0x01)
>>> +#define SR_TRX_STATUS		0x01, 0x1f, 0
>>> +#define SR_RESERVED_01_3	0x01, 0x20, 5
>>> +#define SR_CCA_STATUS		0x01, 0x40, 6
>>> +#define SR_CCA_DONE		0x01, 0x80, 7
>>> +#define RG_TRX_STATE	(0x02)
>>> +#define SR_TRX_CMD		0x02, 0x1f, 0
>>> +#define SR_TRAC_STATUS		0x02, 0xe0, 5
>>> +#define RG_TRX_CTRL_0	(0x03)
>>> +#define SR_CLKM_CTRL		0x03, 0x07, 0
>>> +#define SR_CLKM_SHA_SEL		0x03, 0x08, 3
>>> +#define SR_PAD_IO_CLKM		0x03, 0x30, 4
>>> +#define SR_PAD_IO		0x03, 0xc0, 6
>>> +#define RG_TRX_CTRL_1	(0x04)
>>> +#define SR_IRQ_POLARITY		0x04, 0x01, 0
>>> +#define SR_IRQ_MASK_MODE	0x04, 0x02, 1
>>> +#define SR_SPI_CMD_MODE		0x04, 0x0c, 2
>>> +#define SR_RX_BL_CTRL		0x04, 0x10, 4
>>> +#define SR_TX_AUTO_CRC_ON	0x04, 0x20, 5
>>> +#define SR_IRQ_2_EXT_EN		0x04, 0x40, 6
>>> +#define SR_PA_EXT_EN		0x04, 0x80, 7
>>> +#define RG_PHY_TX_PWR	(0x05)
>>> +#define SR_TX_PWR_23X		0x05, 0x0f, 0
>>> +#define SR_PA_LT_230		0x05, 0x30, 4
>>> +#define SR_PA_BUF_LT_230	0x05, 0xc0, 6
>>> +#define SR_TX_PWR_212		0x05, 0x1f, 0
>>> +#define SR_GC_PA_212		0x05, 0x60, 5
>>> +#define SR_PA_BOOST_LT_212	0x05, 0x80, 7
>>> +#define RG_PHY_RSSI	(0x06)
>>> +#define SR_RSSI			0x06, 0x1f, 0
>>> +#define SR_RND_VALUE		0x06, 0x60, 5
>>> +#define SR_RX_CRC_VALID		0x06, 0x80, 7
>>> +#define RG_PHY_ED_LEVEL	(0x07)
>>> +#define SR_ED_LEVEL		0x07, 0xff, 0
>>> +#define RG_PHY_CC_CCA	(0x08)
>>> +#define SR_CHANNEL		0x08, 0x1f, 0
>>> +#define SR_CCA_MODE		0x08, 0x60, 5
>>> +#define SR_CCA_REQUEST		0x08, 0x80, 7
>>> +#define RG_CCA_THRES	(0x09)
>>> +#define SR_CCA_ED_THRES		0x09, 0x0f, 0
>>> +#define SR_RESERVED_09_1	0x09, 0xf0, 4
>>> +#define RG_RX_CTRL	(0x0a)
>>> +#define SR_PDT_THRES		0x0a, 0x0f, 0
>>> +#define SR_RESERVED_0a_1	0x0a, 0xf0, 4
>>> +#define RG_SFD_VALUE	(0x0b)
>>> +#define SR_SFD_VALUE		0x0b, 0xff, 0
>>> +#define RG_TRX_CTRL_2	(0x0c)
>>> +#define SR_OQPSK_DATA_RATE	0x0c, 0x03, 0
>>> +#define SR_SUB_MODE		0x0c, 0x04, 2
>>> +#define SR_BPSK_QPSK		0x0c, 0x08, 3
>>> +#define SR_OQPSK_SUB1_RC_EN	0x0c, 0x10, 4
>>> +#define SR_RESERVED_0c_5	0x0c, 0x60, 5
>>> +#define SR_RX_SAFE_MODE		0x0c, 0x80, 7
>>> +#define RG_ANT_DIV	(0x0d)
>>> +#define SR_ANT_CTRL		0x0d, 0x03, 0
>>> +#define SR_ANT_EXT_SW_EN	0x0d, 0x04, 2
>>> +#define SR_ANT_DIV_EN		0x0d, 0x08, 3
>>> +#define SR_RESERVED_0d_2	0x0d, 0x70, 4
>>> +#define SR_ANT_SEL		0x0d, 0x80, 7
>>> +#define RG_IRQ_MASK	(0x0e)
>>> +#define SR_IRQ_MASK		0x0e, 0xff, 0
>>> +#define RG_IRQ_STATUS	(0x0f)
>>> +#define SR_IRQ_0_PLL_LOCK	0x0f, 0x01, 0
>>> +#define SR_IRQ_1_PLL_UNLOCK	0x0f, 0x02, 1
>>> +#define SR_IRQ_2_RX_START	0x0f, 0x04, 2
>>> +#define SR_IRQ_3_TRX_END	0x0f, 0x08, 3
>>> +#define SR_IRQ_4_CCA_ED_DONE	0x0f, 0x10, 4
>>> +#define SR_IRQ_5_AMI		0x0f, 0x20, 5
>>> +#define SR_IRQ_6_TRX_UR		0x0f, 0x40, 6
>>> +#define SR_IRQ_7_BAT_LOW	0x0f, 0x80, 7
>>> +#define RG_VREG_CTRL	(0x10)
>>> +#define SR_RESERVED_10_6	0x10, 0x03, 0
>>> +#define SR_DVDD_OK		0x10, 0x04, 2
>>> +#define SR_DVREG_EXT		0x10, 0x08, 3
>>> +#define SR_RESERVED_10_3	0x10, 0x30, 4
>>> +#define SR_AVDD_OK		0x10, 0x40, 6
>>> +#define SR_AVREG_EXT		0x10, 0x80, 7
>>> +#define RG_BATMON	(0x11)
>>> +#define SR_BATMON_VTH		0x11, 0x0f, 0
>>> +#define SR_BATMON_HR		0x11, 0x10, 4
>>> +#define SR_BATMON_OK		0x11, 0x20, 5
>>> +#define SR_RESERVED_11_1	0x11, 0xc0, 6
>>> +#define RG_XOSC_CTRL	(0x12)
>>> +#define SR_XTAL_TRIM		0x12, 0x0f, 0
>>> +#define SR_XTAL_MODE		0x12, 0xf0, 4
>>> +#define RG_RX_SYN	(0x15)
>>> +#define SR_RX_PDT_LEVEL		0x15, 0x0f, 0
>>> +#define SR_RESERVED_15_2	0x15, 0x70, 4
>>> +#define SR_RX_PDT_DIS		0x15, 0x80, 7
>>> +#define RG_XAH_CTRL_1	(0x17)
>>> +#define SR_RESERVED_17_8	0x17, 0x01, 0
>>> +#define SR_AACK_PROM_MODE	0x17, 0x02, 1
>>> +#define SR_AACK_ACK_TIME	0x17, 0x04, 2
>>> +#define SR_RESERVED_17_5	0x17, 0x08, 3
>>> +#define SR_AACK_UPLD_RES_FT	0x17, 0x10, 4
>>> +#define SR_AACK_FLTR_RES_FT	0x17, 0x20, 5
>>> +#define SR_CSMA_LBT_MODE	0x17, 0x40, 6
>>> +#define SR_RESERVED_17_1	0x17, 0x80, 7
>>> +#define RG_FTN_CTRL	(0x18)
>>> +#define SR_RESERVED_18_2	0x18, 0x7f, 0
>>> +#define SR_FTN_START		0x18, 0x80, 7
>>> +#define RG_PLL_CF	(0x1a)
>>> +#define SR_RESERVED_1a_2	0x1a, 0x7f, 0
>>> +#define SR_PLL_CF_START		0x1a, 0x80, 7
>>> +#define RG_PLL_DCU	(0x1b)
>>> +#define SR_RESERVED_1b_3	0x1b, 0x3f, 0
>>> +#define SR_RESERVED_1b_2	0x1b, 0x40, 6
>>> +#define SR_PLL_DCU_START	0x1b, 0x80, 7
>>> +#define RG_PART_NUM	(0x1c)
>>> +#define SR_PART_NUM		0x1c, 0xff, 0
>>> +#define RG_VERSION_NUM	(0x1d)
>>> +#define SR_VERSION_NUM		0x1d, 0xff, 0
>>> +#define RG_MAN_ID_0	(0x1e)
>>> +#define SR_MAN_ID_0		0x1e, 0xff, 0
>>> +#define RG_MAN_ID_1	(0x1f)
>>> +#define SR_MAN_ID_1		0x1f, 0xff, 0
>>> +#define RG_SHORT_ADDR_0	(0x20)
>>> +#define SR_SHORT_ADDR_0		0x20, 0xff, 0
>>> +#define RG_SHORT_ADDR_1	(0x21)
>>> +#define SR_SHORT_ADDR_1		0x21, 0xff, 0
>>> +#define RG_PAN_ID_0	(0x22)
>>> +#define SR_PAN_ID_0		0x22, 0xff, 0
>>> +#define RG_PAN_ID_1	(0x23)
>>> +#define SR_PAN_ID_1		0x23, 0xff, 0
>>> +#define RG_IEEE_ADDR_0	(0x24)
>>> +#define SR_IEEE_ADDR_0		0x24, 0xff, 0
>>> +#define RG_IEEE_ADDR_1	(0x25)
>>> +#define SR_IEEE_ADDR_1		0x25, 0xff, 0
>>> +#define RG_IEEE_ADDR_2	(0x26)
>>> +#define SR_IEEE_ADDR_2		0x26, 0xff, 0
>>> +#define RG_IEEE_ADDR_3	(0x27)
>>> +#define SR_IEEE_ADDR_3		0x27, 0xff, 0
>>> +#define RG_IEEE_ADDR_4	(0x28)
>>> +#define SR_IEEE_ADDR_4		0x28, 0xff, 0
>>> +#define RG_IEEE_ADDR_5	(0x29)
>>> +#define SR_IEEE_ADDR_5		0x29, 0xff, 0
>>> +#define RG_IEEE_ADDR_6	(0x2a)
>>> +#define SR_IEEE_ADDR_6		0x2a, 0xff, 0
>>> +#define RG_IEEE_ADDR_7	(0x2b)
>>> +#define SR_IEEE_ADDR_7		0x2b, 0xff, 0
>>> +#define RG_XAH_CTRL_0	(0x2c)
>>> +#define SR_SLOTTED_OPERATION	0x2c, 0x01, 0
>>> +#define SR_MAX_CSMA_RETRIES	0x2c, 0x0e, 1
>>> +#define SR_MAX_FRAME_RETRIES	0x2c, 0xf0, 4
>>> +#define RG_CSMA_SEED_0	(0x2d)
>>> +#define SR_CSMA_SEED_0		0x2d, 0xff, 0
>>> +#define RG_CSMA_SEED_1	(0x2e)
>>> +#define SR_CSMA_SEED_1		0x2e, 0x07, 0
>>> +#define SR_AACK_I_AM_COORD	0x2e, 0x08, 3
>>> +#define SR_AACK_DIS_ACK		0x2e, 0x10, 4
>>> +#define SR_AACK_SET_PD		0x2e, 0x20, 5
>>> +#define SR_AACK_FVN_MODE	0x2e, 0xc0, 6
>>> +#define RG_CSMA_BE	(0x2f)
>>> +#define SR_MIN_BE		0x2f, 0x0f, 0
>>> +#define SR_MAX_BE		0x2f, 0xf0, 4
>>> +
>>> +#define CMD_REG		0x80
>>> +#define CMD_REG_MASK	0x3f
>>> +#define CMD_WRITE	0x40
>>> +#define CMD_FB		0x20
>>> +
>>> +#define IRQ_BAT_LOW	BIT(7)
>>> +#define IRQ_TRX_UR	BIT(6)
>>> +#define IRQ_AMI		BIT(5)
>>> +#define IRQ_CCA_ED	BIT(4)
>>> +#define IRQ_TRX_END	BIT(3)
>>> +#define IRQ_RX_START	BIT(2)
>>> +#define IRQ_PLL_UNL	BIT(1)
>>> +#define IRQ_PLL_LOCK	BIT(0)
>>> +
>>> +#define IRQ_ACTIVE_HIGH	0
>>> +#define IRQ_ACTIVE_LOW	1
>>> +
>>> +#define STATE_P_ON		0x00	/* BUSY */
>>> +#define STATE_BUSY_RX		0x01
>>> +#define STATE_BUSY_TX		0x02
>>> +#define STATE_FORCE_TRX_OFF	0x03
>>> +#define STATE_FORCE_TX_ON	0x04	/* IDLE */
>>> +/* 0x05 */				/* INVALID_PARAMETER */
>>> +#define STATE_RX_ON		0x06
>>> +/* 0x07 */				/* SUCCESS */
>>> +#define STATE_TRX_OFF		0x08
>>> +#define STATE_TX_ON		0x09
>>> +/* 0x0a - 0x0e */			/* 0x0a - UNSUPPORTED_ATTRIBUTE */
>>> +#define STATE_SLEEP		0x0F
>>> +#define STATE_PREP_DEEP_SLEEP	0x10
>>> +#define STATE_BUSY_RX_AACK	0x11
>>> +#define STATE_BUSY_TX_ARET	0x12
>>> +#define STATE_RX_AACK_ON	0x16
>>> +#define STATE_TX_ARET_ON	0x19
>>> +#define STATE_RX_ON_NOCLK	0x1C
>>> +#define STATE_RX_AACK_ON_NOCLK	0x1D
>>> +#define STATE_BUSY_RX_AACK_NOCLK 0x1E
>>> +#define STATE_TRANSITION_IN_PROGRESS 0x1F
>>> +
>>> +#define TRX_STATE_MASK		(0x1F)
>>> +
>>> +#endif /* !_AT86RF230_H */
>> I think I updated some of these defines at some point. Will go through my
>> changes and see if I have any updates for this. Nothing imprtant for the
>> current functionality so this can go in as is and the other patch follow up
>> later. Mostly updated to some former reserved areas iirc.
>>
> ok. That's good I just take the current defines from at86rf230 driver (I
> did also some small changes there). Then we have fixed version for both
> drivers.

Yup, now that we have the defines shared we have it fixed for both. I 
will dig through my stuff and see if any changes are left.

>>> diff --git a/drivers/net/ieee802154/atusb.c
>>> b/drivers/net/ieee802154/atusb.c
>>> new file mode 100644
>>> index 0000000..ea1259e
>>> --- /dev/null
>>> +++ b/drivers/net/ieee802154/atusb.c
>>> @@ -0,0 +1,692 @@
>>> +/*
>>> + * atusb.c - Driver for the ATUSB IEEE 802.15.4 dongle
>>> + *
>>> + * Written 2013 by Werner Almesberger <werner@almesberger.net>
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> + * modify it under the terms of the GNU General Public License as
>>> + * published by the Free Software Foundation, version 2
>>> + *
>>> + * Based on at86rf230.c and spi_atusb.c.
>>> + * at86rf230.c is
>>> + * Copyright (C) 2009 Siemens AG
>>> + * Written by: Dmitry Eremin-Solenikov <dmitry.baryshkov@siemens.com>
>>> + *
>>> + * spi_atusb.c is
>>> + * Copyright (c) 2011 Richard Sharpe <realrichardsharpe@gmail.com>
>>> + * Copyright (c) 2011 Stefan Schmidt <stefan@datenfreihafen.org>
>>> + * Copyright (c) 2011 Werner Almesberger <werner@almesberger.net>
>>> + *
>>> + * USB initialization is
>>> + * Copyright (c) 2013 Alexander Aring <alex.aring@gmail.com>
>>> + */
>>> +
>>> +#include <linux/kernel.h>
>>> +#include <linux/slab.h>
>>> +#include <linux/module.h>
>>> +#include <linux/jiffies.h>
>>> +#include <linux/usb.h>
>>> +#include <linux/skbuff.h>
>>> +
>>> +#include <net/cfg802154.h>
>>> +#include <net/mac802154.h>
>>> +
>>> +#include "at86rf230.h"
>>> +#include "atusb.h"
>>> +
>>> +#define ATUSB_JEDEC_ATMEL	0x1f	/* JEDEC manufacturer ID */
>>> +
>>> +#define ATUSB_NUM_RX_URBS	4	/* allow for a bit of local
>>> latency */
>>> +#define ATUSB_ALLOC_DELAY_MS	100	/* delay after failed allocation
>>> */
>>> +#define ATUSB_TX_TIMEOUT_MS	200	/* on the air timeout */
>>> +
>>> +struct atusb {
>>> +	struct ieee802154_hw *hw;
>>> +	struct usb_device *usb_dev;
>>> +	int shutdown;			/* non-zero if shutting down */
>>> +	int err;			/* set by first error */
>>> +
>>> +	/* RX variables */
>>> +	struct delayed_work work;	/* memory allocations */
>>> +	struct usb_anchor idle_urbs;	/* URBs waiting to be submitted */
>>> +	struct usb_anchor rx_urbs;	/* URBs waiting for reception */
>>> +
>>> +	/* TX variables */
>>> +	struct usb_ctrlrequest tx_dr;
>>> +	struct urb *tx_urb;
>>> +	struct sk_buff *tx_skb;
>>> +	uint8_t tx_ack_seq;		/* current TX ACK sequence number
>>> */
>>> +};
>>> +
>>> +/* at86rf230.h defines values as <reg, mask, shift> tuples. We use the
>>> more
>>> + * traditional style of having registers and or-able values. SR_REG
>>> extracts
>>> + * the register number. SR_VALUE uses the shift to prepare a value
>>> accordingly.
>>> + */
>>> +
>>> +#define __SR_REG(reg, mask, shift)	(reg)
>>> +#define SR_REG(sr)			__SR_REG(sr)
>>> +
>>> +#define __SR_VALUE(reg, mask, shift, val)	((val) << (shift))
>>> +#define SR_VALUE(sr, val)			__SR_VALUE(sr, (val))
>>> +
>>> +/* ----- USB commands without data
>>> ----------------------------------------- */
>>> +
>>> +/* To reduce the number of error checks in the code, we record the first
>>> error
>>> + * in atusb->err and reject all subsequent requests until the error is
>>> cleared.
>>> + */
>>> +
>>> +static int atusb_control_msg(struct atusb *atusb, unsigned int pipe,
>>> +			     __u8 request, __u8 requesttype,
>>> +			     __u16 value, __u16 index,
>>> +			     void *data, __u16 size, int timeout)
>>> +{
>>> +	struct usb_device *usb_dev = atusb->usb_dev;
>>> +	int ret;
>>> +
>>> +	if (atusb->err)
>>> +		return atusb->err;
>>> +
>>> +	ret = usb_control_msg(usb_dev, pipe, request, requesttype,
>>> +			      value, index, data, size, timeout);
>>> +	if (ret < 0) {
>>> +		atusb->err = ret;
>>> +		dev_err(&usb_dev->dev,
>>> +			"atusb_control_msg: req 0x%02x val 0x%x idx 0x%x,
>>> error %d\n",
>>> +			request, value, index, ret);
>>> +	}
>>> +	return ret;
>>> +}
>>> +
>>> +static int atusb_command(struct atusb *atusb, uint8_t cmd, uint8_t arg)
>>> +{
>>> +	struct usb_device *usb_dev = atusb->usb_dev;
>>> +
>>> +	dev_dbg(&usb_dev->dev, "atusb_command: cmd = 0x%x\n", cmd);
>>> +	return atusb_control_msg(atusb, usb_sndctrlpipe(usb_dev, 0),
>>> +				 cmd, ATUSB_REQ_TO_DEV, arg, 0, NULL, 0,
>>> 1000);
>>> +}
>>> +
>>> +static int atusb_write_reg(struct atusb *atusb, uint8_t reg, uint8_t
>>> value)
>>> +{
>>> +	struct usb_device *usb_dev = atusb->usb_dev;
>>> +
>>> +	dev_dbg(&usb_dev->dev, "atusb_write_reg: 0x%02x <- 0x%02x\n",
>>> +		reg, value);
>>> +	return atusb_control_msg(atusb, usb_sndctrlpipe(usb_dev, 0),
>>> +				 ATUSB_REG_WRITE, ATUSB_REQ_TO_DEV,
>>> +				 value, reg, NULL, 0, 1000);
>>> +}
>>> +
>>> +static int atusb_read_reg(struct atusb *atusb, uint8_t reg)
>>> +{
>>> +	struct usb_device *usb_dev = atusb->usb_dev;
>>> +	int ret;
>>> +	uint8_t value;
>>> +
>>> +	dev_dbg(&usb_dev->dev, "atusb: reg = 0x%x\n", reg);
>>> +	ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
>>> +				ATUSB_REG_READ, ATUSB_REQ_FROM_DEV,
>>> +				0, reg, &value, 1, 1000);
>>> +	return ret >= 0 ? value : ret;
>>> +}
>>> +
>>> +static int atusb_get_and_clear_error(struct atusb *atusb)
>>> +{
>>> +	int err = atusb->err;
>>> +
>>> +	atusb->err = 0;
>>> +	return err;
>>> +}
>>> +
>>> +/* ----- skb allocation
>>> ---------------------------------------------------- */
>> I was never a fan of these markers but Werner likes them. Keep them in does
>> not do any harm.
>>
> send patches. The driver isn't perfect but it's good to have them
> mainline that we all can contribute now the work for this driver.
>
>>> +
>>> +#define MAX_PSDU	127
>>> +#define MAX_RX_XFER	(1 + MAX_PSDU + 2 + 1)	/* PHR+PSDU+CRC+LQI */
>>> +
>>> +#define SKB_ATUSB(skb)	(*(struct atusb **)(skb)->cb)
>>> +
>>> +static void atusb_in(struct urb *urb);
>>> +
>>> +static int atusb_submit_rx_urb(struct atusb *atusb, struct urb *urb)
>>> +{
>>> +	struct usb_device *usb_dev = atusb->usb_dev;
>>> +	struct sk_buff *skb = urb->context;
>>> +	int ret;
>>> +
>>> +	if (!skb) {
>>> +		skb = alloc_skb(MAX_RX_XFER, GFP_KERNEL);
>>> +		if (!skb) {
>>> +			dev_warn_ratelimited(&usb_dev->dev,
>>> +					     "atusb_in: can't allocate
>>> skb\n");
>>> +			return -ENOMEM;
>>> +		}
>>> +		skb_put(skb, MAX_RX_XFER);
>>> +		SKB_ATUSB(skb) = atusb;
>>> +	}
>>> +
>>> +	usb_fill_bulk_urb(urb, usb_dev, usb_rcvbulkpipe(usb_dev, 1),
>>> +			  skb->data, MAX_RX_XFER, atusb_in, skb);
>>> +	usb_anchor_urb(urb, &atusb->rx_urbs);
>>> +
>>> +	ret = usb_submit_urb(urb, GFP_KERNEL);
>>> +	if (ret) {
>>> +		usb_unanchor_urb(urb);
>>> +		kfree_skb(skb);
>>> +		urb->context = NULL;
>>> +	}
>>> +	return ret;
>>> +}
>>> +
>>> +static void atusb_work_urbs(struct work_struct *work)
>>> +{
>>> +	struct atusb *atusb =
>>> +	    container_of(to_delayed_work(work), struct atusb, work);
>>> +	struct usb_device *usb_dev = atusb->usb_dev;
>>> +	struct urb *urb;
>>> +	int ret;
>>> +
>>> +	if (atusb->shutdown)
>>> +		return;
>>> +
>>> +	do {
>>> +		urb = usb_get_from_anchor(&atusb->idle_urbs);
>>> +		if (!urb)
>>> +			return;
>>> +		ret = atusb_submit_rx_urb(atusb, urb);
>>> +	} while (!ret);
>>> +
>>> +	usb_anchor_urb(urb, &atusb->idle_urbs);
>>> +	dev_warn_ratelimited(&usb_dev->dev,
>>> +			     "atusb_in: can't allocate/submit URB (%d)\n",
>>> ret);
>>> +	schedule_delayed_work(&atusb->work,
>>> +			      msecs_to_jiffies(ATUSB_ALLOC_DELAY_MS) + 1);
>>> +}
>>> +
>>> +/* ----- Asynchronous USB
>>> -------------------------------------------------- */
>>> +
>>> +static void atusb_tx_done(struct atusb *atusb, uint8_t seq)
>>> +{
>>> +	struct usb_device *usb_dev = atusb->usb_dev;
>>> +	uint8_t expect = atusb->tx_ack_seq;
>>> +
>>> +	dev_dbg(&usb_dev->dev, "atusb_tx_done (0x%02x/0x%02x)\n", seq,
>>> expect);
>>> +	if (seq == expect) {
>>> +		/* TODO check for ifs handling in firmware */
>>> +		ieee802154_xmit_complete(atusb->hw, atusb->tx_skb, false);
>>> +	} else {
>>> +		/* TODO I experience this case when atusb has a tx
>>> complete
>>> +		 * irq before probing, we should fix the firmware it's an
>>> +		 * unlikely case now that seq == expect is then true, but
>>> can
>>> +		 * happen and fail with a tx_skb = NULL;
>>> +		 */
>>
>> Ah, so that comes with the xmit_async change. Looks like a good candidate
>> for what I mentioned at the top about haveing a fw release now (0.1) and
>> once we fixed the bug in the fw and released a fixed version we can check
>> for it here and act according to the fw version. That is the only sane way
>> to handle various fw versions I fear without upsetting our users with
>> forcing new fw versions for new drivers on them.
>>
> If somebody runs an old firmware on newer atusb driver then probing
> fails with a message to update the firmware version, or should we
> support all backwards supporting with all firmware versions?

Well, that is the question. I personally prefer that we have backward 
compatibility in the driver as it makes for a better experience of the 
user. He could use any fw release and have a working driver. For special 
features he might need the newest fw but the basic operations always work.

On the other hand this means more work and given the handful of active 
devices for this it might not be worth the time spent on it.

>> Only alternative I see is to ship compatible versions with linux-firmware to
>> match the kernel version.
>>
> This is what Marcel also told to me that we should doing that in this way.
> The linux-firmware should also accept firmwares for persitent storage,
> or is there some way to run dfu inside kernelspace to update the atusb
> on the fly? I don't know if something like this exists.

Hmm, good question. I think most fw's carried in there are hot loaded 
during init into the device. Need to check if they support DFU as mechanism.

>>> +		ieee802154_wake_queue(atusb->hw);
>>> +		if (atusb->tx_skb)
>>> +			dev_kfree_skb_irq(atusb->tx_skb);
>>> +	}
>>> +}
>>> +
>>> +static void atusb_in_good(struct urb *urb)
>>> +{
>>> +	struct usb_device *usb_dev = urb->dev;
>>> +	struct sk_buff *skb = urb->context;
>>> +	struct atusb *atusb = SKB_ATUSB(skb);
>>> +	uint8_t len, lqi;
>>> +
>>> +	if (!urb->actual_length) {
>>> +		dev_dbg(&usb_dev->dev, "atusb_in: zero-sized URB ?\n");
>>> +		return;
>>> +	}
>>> +
>>> +	len = *skb->data;
>>> +
>>> +	if (urb->actual_length == 1) {
>>> +		atusb_tx_done(atusb, len);
>>> +		return;
>>> +	}
>>> +
>>> +	if (len + 1 > urb->actual_length - 1) {
>>> +		dev_dbg(&usb_dev->dev, "atusb_in: frame len %d+1 > URB
>>> %u-1\n",
>>> +			len, urb->actual_length);
>>> +		return;
>>> +	}
>>> +
>>> +	if (!ieee802154_is_valid_psdu_len(len)) {
>>> +		dev_dbg(&usb_dev->dev, "atusb_in: frame corrupted\n");
>>> +		return;
>>> +	}
>>> +
>>> +	lqi = skb->data[len + 1];
>>> +	dev_dbg(&usb_dev->dev, "atusb_in: rx len %d lqi 0x%02x\n", len,
>>> lqi);
>>> +	skb_pull(skb, 1);	/* remove PHR */
>>> +	skb_trim(skb, len);	/* get payload only */
>> Hmm, the code I used here still has this:
>> skb_trim(skb, len); /* remove CRC */
>>
>> Do we now longer need this? Did you change the driver capabilities to match
>> this?
>>
> I splitted some times ago a hw flag IEEE802154_HW_OMIT_CKSUM. Which was
> always that on transmit we have no FCS and while receive we have no
> FCS.
>
> But if you run as monitor you usually want to receive the CRC which was
> on the air, not an own calculated one which is always correct even when
> the frame was corrupted.
>
> To handle backwards compatibility we have now:
>
> #define IEEE802154_HW_OMIT_CKSUM        (IEEE802154_HW_TX_OMIT_CKSUM | \
> 					 IEEE802154_HW_RX_OMIT_CKSUM)
>
> I changed the flag in atusb to have only IEEE802154_HW_TX_OMIT_CKSUM. We
> deliver now the CRC to the next layer. This will remove the crc then
> again before frame parsing, but when we support promisucous mode then
> this handling will be more correct and the monitor will receive the CRC
> which was on the air.
>
> We still need to have:
>
> skb_trim(skb, len);     /* get payload only */
>
> because we need cut the last byte which is the lqi value, maybe this
> handling can improved and we can drop this line.
>
>
> btw: all drivers should be updated to not use IEEE802154_HW_OMIT_CKSUM
> and cut the CRC while receiving.
>

Ah, that explains it. Missed the split. Thanks!

>>> +	ieee802154_rx_irqsafe(atusb->hw, skb, lqi);
>>> +	urb->context = NULL;	/* skb is gone */
>>> +}
>>> +
>>> +static void atusb_in(struct urb *urb)
>>> +{
>>> +	struct usb_device *usb_dev = urb->dev;
>>> +	struct sk_buff *skb = urb->context;
>>> +	struct atusb *atusb = SKB_ATUSB(skb);
>>> +
>>> +	dev_dbg(&usb_dev->dev, "atusb_in: status %d len %d\n",
>>> +		urb->status, urb->actual_length);
>>> +	if (urb->status) {
>>> +		if (urb->status == -ENOENT) { /* being killed */
>>> +			kfree_skb(skb);
>>> +			urb->context = NULL;
>>> +			return;
>>> +		}
>>> +		dev_dbg(&usb_dev->dev, "atusb_in: URB error %d\n",
>>> urb->status);
>>> +	} else {
>>> +		atusb_in_good(urb);
>>> +	}
>>> +
>>> +	usb_anchor_urb(urb, &atusb->idle_urbs);
>>> +	if (!atusb->shutdown)
>>> +		schedule_delayed_work(&atusb->work, 0);
>>> +}
>>> +
>>> +/* ----- URB allocation/deallocation
>>> --------------------------------------- */
>>> +
>>> +static void atusb_free_urbs(struct atusb *atusb)
>>> +{
>>> +	struct urb *urb;
>>> +
>>> +	while (1) {
>>> +		urb = usb_get_from_anchor(&atusb->idle_urbs);
>>> +		if (!urb)
>>> +			break;
>>> +		if (urb->context)
>>> +			kfree_skb(urb->context);
>>> +		usb_free_urb(urb);
>>> +	}
>>> +}
>>> +
>>> +static int atusb_alloc_urbs(struct atusb *atusb, int n)
>>> +{
>>> +	struct urb *urb;
>>> +
>>> +	while (n) {
>>> +		urb = usb_alloc_urb(0, GFP_KERNEL);
>>> +		if (!urb) {
>>> +			atusb_free_urbs(atusb);
>>> +			return -ENOMEM;
>>> +		}
>>> +		usb_anchor_urb(urb, &atusb->idle_urbs);
>>> +		n--;
>>> +	}
>>> +	return 0;
>>> +}
>>> +
>>> +/* ----- IEEE 802.15.4 interface operations
>>> -------------------------------- */
>>> +
>>> +static void atusb_xmit_complete(struct urb *urb)
>>> +{
>>> +	dev_dbg(&urb->dev->dev, "atusb_xmit urb completed");
>>> +}
>>> +
>>> +static int atusb_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
>>> +{
>>> +	struct atusb *atusb = hw->priv;
>>> +	struct usb_device *usb_dev = atusb->usb_dev;
>>> +	int ret;
>>> +
>>> +	dev_dbg(&usb_dev->dev, "atusb_xmit (%d)\n", skb->len);
>>> +	atusb->tx_skb = skb;
>>> +	atusb->tx_ack_seq++;
>>> +	atusb->tx_dr.wIndex = cpu_to_le16(atusb->tx_ack_seq);
>>> +	atusb->tx_dr.wLength = cpu_to_le16(skb->len);
>>> +
>>> +	usb_fill_control_urb(atusb->tx_urb, usb_dev,
>>> +			     usb_sndctrlpipe(usb_dev, 0),
>>> +			     (unsigned char *)&atusb->tx_dr, skb->data,
>>> +			     skb->len, atusb_xmit_complete, NULL);
>>> +	ret = usb_submit_urb(atusb->tx_urb, GFP_ATOMIC);
>>> +	dev_dbg(&usb_dev->dev, "atusb_xmit done (%d)\n", ret);
>>> +	return ret;
>>> +}
>>> +
>>> +static int atusb_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
>>> +{
>>> +	struct atusb *atusb = hw->priv;
>>> +	int ret;
>>> +
>>> +	/* This implicitly sets the CCA (Clear Channel Assessment) mode to
>>> 0,
>>> +	 * "Mode 3a, Carrier sense OR energy above threshold".
>>> +	 * We should probably make this configurable. @@@
>>> +	 */
>>> +	ret = atusb_write_reg(atusb, RG_PHY_CC_CCA, channel);
>>> +	if (ret < 0)
>>> +		return ret;
>>> +	msleep(1);	/* @@@ ugly synchronization */
>> The hw->phy->current_channel = channel; is no longer needed here? Does the
>> stack handle this part now?
>>
> yes. See [0].
>
>>> +	return 0;
>>> +}
>>> +
>>> +static int atusb_ed(struct ieee802154_hw *hw, u8 *level)
>>> +{
>>> +	/* @@@ not used by the stack yet */
>>> +	*level = 0;
>>> +	return 0;
>>> +}
>>> +
>>> +static int atusb_set_hw_addr_filt(struct ieee802154_hw *hw,
>>> +				  struct ieee802154_hw_addr_filt *filt,
>>> +				  unsigned long changed)
>>> +{
>>> +	struct atusb *atusb = hw->priv;
>>> +	struct device *dev = &atusb->usb_dev->dev;
>>> +	uint8_t reg;
>>> +
>>> +	if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
>>> +		u16 addr = le16_to_cpu(filt->short_addr);
>>> +
>>> +		dev_vdbg(dev, "atusb_set_hw_addr_filt called for
>>> saddr\n");
>>> +		atusb_write_reg(atusb, RG_SHORT_ADDR_0, addr);
>>> +		atusb_write_reg(atusb, RG_SHORT_ADDR_1, addr >> 8);
>>> +	}
>>> +
>>> +	if (changed & IEEE802154_AFILT_PANID_CHANGED) {
>>> +		u16 pan = le16_to_cpu(filt->pan_id);
>>> +
>>> +		dev_vdbg(dev, "atusb_set_hw_addr_filt called for pan
>>> id\n");
>>> +		atusb_write_reg(atusb, RG_PAN_ID_0, pan);
>>> +		atusb_write_reg(atusb, RG_PAN_ID_1, pan >> 8);
>>> +	}
>>> +
>>> +	if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
>>> +		u8 i, addr[IEEE802154_EXTENDED_ADDR_LEN];
>>> +
>>> +		memcpy(addr, &filt->ieee_addr,
>>> IEEE802154_EXTENDED_ADDR_LEN);
>>> +		dev_vdbg(dev, "atusb_set_hw_addr_filt called for IEEE
>>> addr\n");
>>> +		for (i = 0; i < 8; i++)
>>> +			atusb_write_reg(atusb, RG_IEEE_ADDR_0 + i,
>>> addr[i]);
>>> +	}
>>> +
>>> +	if (changed & IEEE802154_AFILT_PANC_CHANGED) {
>>> +		dev_vdbg(dev,
>>> +			 "atusb_set_hw_addr_filt called for panc
>>> change\n");
>>> +		reg = atusb_read_reg(atusb, SR_REG(SR_AACK_I_AM_COORD));
>>> +		if (filt->pan_coord)
>>> +			reg |= SR_VALUE(SR_AACK_I_AM_COORD, 1);
>>> +		else
>>> +			reg &= ~SR_VALUE(SR_AACK_I_AM_COORD, 1);
>>> +		atusb_write_reg(atusb, SR_REG(SR_AACK_I_AM_COORD), reg);
>>> +	}
>>> +
>>> +	return atusb_get_and_clear_error(atusb);
>>> +}
>>> +
>>> +static int atusb_start(struct ieee802154_hw *hw)
>>> +{
>>> +	struct atusb *atusb = hw->priv;
>>> +	struct usb_device *usb_dev = atusb->usb_dev;
>>> +	int ret;
>>> +
>>> +	dev_dbg(&usb_dev->dev, "atusb_start\n");
>>> +	schedule_delayed_work(&atusb->work, 0);
>>> +	atusb_command(atusb, ATUSB_RX_MODE, 1);
>>> +	ret = atusb_get_and_clear_error(atusb);
>>> +	if (ret < 0)
>>> +		usb_kill_anchored_urbs(&atusb->idle_urbs);
>>> +	return ret;
>>> +}
>>> +
>>> +static void atusb_stop(struct ieee802154_hw *hw)
>>> +{
>>> +	struct atusb *atusb = hw->priv;
>>> +	struct usb_device *usb_dev = atusb->usb_dev;
>>> +
>>> +	dev_dbg(&usb_dev->dev, "atusb_stop\n");
>>> +	usb_kill_anchored_urbs(&atusb->idle_urbs);
>>> +	atusb_command(atusb, ATUSB_RX_MODE, 0);
>>> +	atusb_get_and_clear_error(atusb);
>>> +}
>>> +
>>> +static struct ieee802154_ops atusb_ops = {
>>> +	.owner			= THIS_MODULE,
>>> +	.xmit_async		= atusb_xmit,
>>> +	.ed			= atusb_ed,
>>> +	.set_channel		= atusb_channel,
>>> +	.start			= atusb_start,
>>> +	.stop			= atusb_stop,
>>> +	.set_hw_addr_filt	= atusb_set_hw_addr_filt,
>>> +};
>>> +
>>> +/* ----- Firmware and chip version information
>>> ----------------------------- */
>>> +
>>> +static int atusb_get_and_show_revision(struct atusb *atusb)
>>> +{
>>> +	struct usb_device *usb_dev = atusb->usb_dev;
>>> +	unsigned char buffer[3];
>>> +	int ret;
>>> +
>>> +	/* Get a couple of the ATMega Firmware values */
>>> +	ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
>>> +				ATUSB_ID, ATUSB_REQ_FROM_DEV, 0, 0,
>>> +				buffer, 3, 1000);
>>> +	if (ret >= 0)
>>> +		dev_info(&usb_dev->dev,
>>> +			 "Firmware: major: %u, minor: %u, hardware type:
>>> %u\n",
>>> +			 buffer[0], buffer[1], buffer[2]);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>> +static int atusb_get_and_show_build(struct atusb *atusb)
>>> +{
>>> +	struct usb_device *usb_dev = atusb->usb_dev;
>>> +	char build[ATUSB_BUILD_SIZE + 1];
>>> +	int ret;
>>> +
>>> +	ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0),
>>> +				ATUSB_BUILD, ATUSB_REQ_FROM_DEV, 0, 0,
>>> +				build, ATUSB_BUILD_SIZE, 1000);
>>> +	if (ret >= 0) {
>>> +		build[ret] = 0;
>>> +		dev_info(&usb_dev->dev, "Firmware: build %s\n", build);
>>> +	}
>>> +
>>> +	return ret;
>>> +}
>>> +
>>> +static int atusb_get_and_show_chip(struct atusb *atusb)
>>> +{
>>> +	struct usb_device *usb_dev = atusb->usb_dev;
>>> +	uint8_t man_id_0, man_id_1, part_num, version_num;
>>> +
>>> +	man_id_0 = atusb_read_reg(atusb, RG_MAN_ID_0);
>>> +	man_id_1 = atusb_read_reg(atusb, RG_MAN_ID_1);
>>> +	part_num = atusb_read_reg(atusb, RG_PART_NUM);
>>> +	version_num = atusb_read_reg(atusb, RG_VERSION_NUM);
>>> +
>>> +	if (atusb->err)
>>> +		return atusb->err;
>>> +
>>> +	if ((man_id_1 << 8 | man_id_0) != ATUSB_JEDEC_ATMEL) {
>>> +		dev_err(&usb_dev->dev,
>>> +			"non-Atmel transceiver xxxx%02x%02x\n",
>>> +			man_id_1, man_id_0);
>>> +		goto fail;
>>> +	}
>>> +	if (part_num != 3) {
>>> +		dev_err(&usb_dev->dev,
>>> +			"unexpected transceiver, part 0x%02x version
>>> 0x%02x\n",
>>> +			part_num, version_num);
>>> +		goto fail;
>>> +	}
>>> +
>>> +	dev_info(&usb_dev->dev, "ATUSB: AT86RF231 version %d\n",
>>> version_num);
>>> +
>>> +	return 0;
>>> +
>>> +fail:
>>> +	atusb->err = -ENODEV;
>>> +	return -ENODEV;
>>> +}
>>> +
>>> +/* ----- Setup
>>> ------------------------------------------------------------- */
>>> +
>>> +static int atusb_probe(struct usb_interface *interface,
>>> +		       const struct usb_device_id *id)
>>> +{
>>> +	struct usb_device *usb_dev = interface_to_usbdev(interface);
>>> +	struct ieee802154_hw *hw;
>>> +	struct atusb *atusb = NULL;
>>> +	int ret = -ENOMEM;
>>> +
>>> +	hw = ieee802154_alloc_hw(sizeof(struct atusb), &atusb_ops);
>>> +	if (!hw)
>>> +		return -ENOMEM;
>>> +
>>> +	atusb = hw->priv;
>>> +	atusb->hw = hw;
>>> +	atusb->usb_dev = usb_get_dev(usb_dev);
>>> +	usb_set_intfdata(interface, atusb);
>>> +
>>> +	atusb->shutdown = 0;
>>> +	atusb->err = 0;
>>> +	INIT_DELAYED_WORK(&atusb->work, atusb_work_urbs);
>>> +	init_usb_anchor(&atusb->idle_urbs);
>>> +	init_usb_anchor(&atusb->rx_urbs);
>>> +
>>> +	if (atusb_alloc_urbs(atusb, ATUSB_NUM_RX_URBS))
>>> +		goto fail;
>>> +
>>> +	atusb->tx_dr.bRequestType = ATUSB_REQ_TO_DEV;
>>> +	atusb->tx_dr.bRequest = ATUSB_TX;
>>> +	atusb->tx_dr.wValue = cpu_to_le16(0);
>> What are these three lines for? ^^
>>
> atusb->tx_dr is for async_xmit handling. These values are always the
> same and I just setup this structure in probing time instead of setting
> always the static value in async_xmit handling.
>
> The async_xmit sets now only the tx_ack_seq which is a dynamic value and
> skb->len.
>
OK

regards
Stefan Schmidt

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH bluetooth-next 21/34] ieee802154: add support for atusb transceiver
  2015-05-19 10:49   ` Stefan Schmidt
  2015-05-19 11:52     ` Alexander Aring
@ 2015-05-19 13:45     ` Werner Almesberger
  2015-05-19 14:21       ` Stefan Schmidt
  2015-05-20  8:45     ` Stefan Schmidt
  2 siblings, 1 reply; 45+ messages in thread
From: Werner Almesberger @ 2015-05-19 13:45 UTC (permalink / raw)
  To: Stefan Schmidt
  Cc: Alexander Aring, linux-wpan, kernel, marcel, Richard Sharpe

Stefan Schmidt wrote:
> Werner, is this something you would do? Making a release of the
> firmware? Or should Alexander or myself look into this?

It would be great if you or Alexander could take care of that. I'm
not doing much with 802.15.4 these days, so for me that would be a
distraction at best, and - without a setup in active use - testing
would be awkward.

Thanks !

- Werner

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH bluetooth-next 21/34] ieee802154: add support for atusb transceiver
  2015-05-19 13:45     ` Werner Almesberger
@ 2015-05-19 14:21       ` Stefan Schmidt
  0 siblings, 0 replies; 45+ messages in thread
From: Stefan Schmidt @ 2015-05-19 14:21 UTC (permalink / raw)
  To: Werner Almesberger
  Cc: Alexander Aring, linux-wpan, kernel, marcel, Richard Sharpe

Hello.

On 19/05/15 15:45, Werner Almesberger wrote:
> Stefan Schmidt wrote:
>> Werner, is this something you would do? Making a release of the
>> firmware? Or should Alexander or myself look into this?
> It would be great if you or Alexander could take care of that. I'm
> not doing much with 802.15.4 these days, so for me that would be a
> distraction at best, and - without a setup in active use - testing
> would be awkward.
>
OK, I think I can handle this during the week. Will post a file here for 
further testing.

regards
Stefan Schmidt

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH bluetooth-next 21/34] ieee802154: add support for atusb transceiver
  2015-05-19 10:49   ` Stefan Schmidt
  2015-05-19 11:52     ` Alexander Aring
  2015-05-19 13:45     ` Werner Almesberger
@ 2015-05-20  8:45     ` Stefan Schmidt
  2015-05-20  9:03       ` Alexander Aring
  2 siblings, 1 reply; 45+ messages in thread
From: Stefan Schmidt @ 2015-05-20  8:45 UTC (permalink / raw)
  To: Alexander Aring, linux-wpan
  Cc: kernel, marcel, Werner Almesberger, Richard Sharpe

Hello.

On 19/05/15 12:49, Stefan Schmidt wrote:
>
> Besides the mentioned things this looks fine. Will give it some 
> testing later this week.

Testing showed no further problems. Driver loads fine, detects the 
hardware and I'm able to configure it and send ping's over 6LoWPAN to 
another node.

regards
Stefan Schmidt

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH bluetooth-next 21/34] ieee802154: add support for atusb transceiver
  2015-05-20  8:45     ` Stefan Schmidt
@ 2015-05-20  9:03       ` Alexander Aring
  2015-05-20  9:08         ` Stefan Schmidt
  0 siblings, 1 reply; 45+ messages in thread
From: Alexander Aring @ 2015-05-20  9:03 UTC (permalink / raw)
  To: Stefan Schmidt
  Cc: linux-wpan, kernel, marcel, Werner Almesberger, Richard Sharpe

Hi,

On Wed, May 20, 2015 at 10:45:25AM +0200, Stefan Schmidt wrote:
> Hello.
> 
> On 19/05/15 12:49, Stefan Schmidt wrote:
> >
> >Besides the mentioned things this looks fine. Will give it some testing
> >later this week.
> 
> Testing showed no further problems. Driver loads fine, detects the hardware
> and I'm able to configure it and send ping's over 6LoWPAN to another node.
> 

thanks, now I can sleep a little bit better.

Was it a little bit too fast for bringing the atusb driver mainline? I
really had only the issues with the xmit_sync handling otherwise this
driver looked always fine for me.

I know you worked a little bit on the driver and hope that I didn't
destroyed your work and you can rebase it.

- Alex

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH bluetooth-next 21/34] ieee802154: add support for atusb transceiver
  2015-05-20  9:03       ` Alexander Aring
@ 2015-05-20  9:08         ` Stefan Schmidt
  0 siblings, 0 replies; 45+ messages in thread
From: Stefan Schmidt @ 2015-05-20  9:08 UTC (permalink / raw)
  To: Alexander Aring
  Cc: linux-wpan, kernel, marcel, Werner Almesberger, Richard Sharpe

Hello.

On 20/05/15 11:03, Alexander Aring wrote:
> Hi,
>
> On Wed, May 20, 2015 at 10:45:25AM +0200, Stefan Schmidt wrote:
>> Hello.
>>
>> On 19/05/15 12:49, Stefan Schmidt wrote:
>>> Besides the mentioned things this looks fine. Will give it some testing
>>> later this week.
>> Testing showed no further problems. Driver loads fine, detects the hardware
>> and I'm able to configure it and send ping's over 6LoWPAN to another node.
>>
> thanks, now I can sleep a little bit better.

:)


> Was it a little bit too fast for bringing the atusb driver mainline? I
> really had only the issues with the xmit_sync handling otherwise this
> driver looked always fine for me.
>
> I know you worked a little bit on the driver and hope that I didn't
> destroyed your work and you can rebase it.

No, the timing was fine. It was actually me who has been a bit slow. To 
many other distractions. :)

Rebasing my work on it should be easy to handle. I will look into it 
once I finished preparing the fw release.

regards
Stefan Schmidt


^ permalink raw reply	[flat|nested] 45+ messages in thread

end of thread, other threads:[~2015-05-20  9:08 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-17 19:44 [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 01/34] nl802154: cleanup invalid argument handling Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 02/34] ieee802154: move validation check out of softmac Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 03/34] ieee802154: change transmit power to s32 Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 04/34] ieee802154: change transmit power to mbm Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 05/34] ieee802154: change cca ed level " Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 06/34] ieee802154: introduce wpan_phy_supported Alexander Aring
2015-05-18 10:19   ` Varka Bhadram
2015-05-17 19:44 ` [PATCH bluetooth-next 07/34] ieee802154: add several phy supported handling Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 08/34] mac802154: check for really changes Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 09/34] mac802154: remove check if operation is supported Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 10/34] cfg802154: introduce wpan phy flags Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 11/34] ieee802154: add iftypes capability Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 12/34] at86rf230: set cca_modes supported flags Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 13/34] at86rf230: rework tx power support Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 14/34] at86rf230: rework tx cca energy detection level Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 15/34] at86rf230: add cca ed level reset value Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 16/34] at86rf230: add reset states of tx power level Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 17/34] nl802154: add support for dump phy capabilities Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 18/34] mac802154: fakelb: Fix potential NULL pointer dereference Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 19/34] at86rf230: fix callback for aret handling Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 20/34] mac802154: tx: allow xmit complete from hard irq Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 21/34] ieee802154: add support for atusb transceiver Alexander Aring
2015-05-19 10:49   ` Stefan Schmidt
2015-05-19 11:52     ` Alexander Aring
2015-05-19 13:22       ` Stefan Schmidt
2015-05-19 13:45     ` Werner Almesberger
2015-05-19 14:21       ` Stefan Schmidt
2015-05-20  8:45     ` Stefan Schmidt
2015-05-20  9:03       ` Alexander Aring
2015-05-20  9:08         ` Stefan Schmidt
2015-05-17 19:44 ` [PATCH bluetooth-next 22/34] fakelb: creating two virtual phys per default Alexander Aring
2015-05-17 19:44 ` [PATCH bluetooth-next 23/34] fakelb: use list_for_each_entry_safe Alexander Aring
2015-05-17 19:45 ` [PATCH bluetooth-next 24/34] fakelb: rename fakelb_dev_priv to fakelb_phy Alexander Aring
2015-05-17 19:45 ` [PATCH bluetooth-next 25/34] fakelb: don't deliver when one phy Alexander Aring
2015-05-17 19:45 ` [PATCH bluetooth-next 26/34] fakelb: declare rwlock static Alexander Aring
2015-05-17 19:45 ` [PATCH bluetooth-next 27/34] fakelb: declare fakelb list static Alexander Aring
2015-05-17 19:45 ` [PATCH bluetooth-next 28/34] fakelb: move lock out of iteration Alexander Aring
2015-05-17 19:45 ` [PATCH bluetooth-next 29/34] fakelb: introduce fakelb ifup phys list Alexander Aring
2015-05-17 19:45 ` [PATCH bluetooth-next 30/34] fakelb: use own channel and page attributes Alexander Aring
2015-05-17 19:45 ` [PATCH bluetooth-next 31/34] fakelb: add virtual phy reset defaults Alexander Aring
2015-05-17 19:45 ` [PATCH bluetooth-next 32/34] fakelb: remove fakelb_hw_deliver Alexander Aring
2015-05-17 19:45 ` [PATCH bluetooth-next 33/34] fakelb: add support for async xmit handling Alexander Aring
2015-05-17 19:45 ` [PATCH bluetooth-next 34/34] fakelb: cleanup code Alexander Aring
2015-05-19  9:50 ` [PATCH bluetooth-next 00/34] ieee802154: capabilities, atusb support and fakelb rework Marcel Holtmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.