Signed-off-by: Jon Smirl <[email protected]>
---
drivers/ieee802154/serial.c | 54 +++++++++++++++++++++++++++++++++++++++++--
include/net/mac802154.h | 2 ++
net/ipv6/addrconf.c | 12 ++++++++++
net/mac802154/6lowpan.c | 9 ++++++-
net/mac802154/main.c | 9 +++++++
5 files changed, 83 insertions(+), 3 deletions(-)
diff --git a/drivers/ieee802154/serial.c b/drivers/ieee802154/serial.c
index 033ef2a..5f787d8 100644
--- a/drivers/ieee802154/serial.c
+++ b/drivers/ieee802154/serial.c
@@ -77,6 +77,7 @@ enum {
CMD_SET_STATE = 0x07, /* u8 id, u8 flag */
DATA_XMIT_BLOCK = 0x09, /* u8 id, u8 len, u8 data[len] */
RESP_RECV_BLOCK = 0x0b, /* u8 id, u8 status */
+ CMD_ADDRESS = 0x0d, /* u8 id */
/* Firmware to Driver */
RESP_OPEN = 0x81, /* u8 id, u8 status */
@@ -87,6 +88,7 @@ enum {
RESP_SET_STATE = 0x87, /* u8 id, u8 status */
RESP_XMIT_BLOCK = 0x89, /* u8 id, u8 status */
DATA_RECV_BLOCK = 0x8b, /* u8 id, u8 lq, u8 len, u8 data[len] */
+ RESP_ADDRESS = 0x8d, /* u8 id, u8 status, u8 u8 u8 u8 u8 u8
u8 u8 address */
};
enum {
@@ -314,6 +316,7 @@ is_command(unsigned char c)
case RESP_SET_STATE:
case RESP_XMIT_BLOCK:
case DATA_RECV_BLOCK:
+ case RESP_ADDRESS:
return 1;
}
return 0;
@@ -336,7 +339,9 @@ _match_pending_id(struct zb_device *zbdev)
RESP_SET_STATE == zbdev->id) ||
(DATA_XMIT_BLOCK == zbdev->pending_id &&
RESP_XMIT_BLOCK == zbdev->id) ||
- DATA_RECV_BLOCK == zbdev->id);
+ (DATA_RECV_BLOCK == zbdev->id) ||
+ (CMD_ADDRESS == zbdev->pending_id &&
+ RESP_ADDRESS == zbdev->id));
}
static void serial_net_rx(struct zb_device *zbdev)
@@ -396,6 +401,11 @@ process_command(struct zb_device *zbdev)
/* zbdev->param1 is LQ, zbdev->param2 is length */
serial_net_rx(zbdev);
break;
+ case RESP_ADDRESS:
+ pr_debug("Received address,
%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ zbdev->data[0], zbdev->data[1], zbdev->data[2],
zbdev->data[3],
+ zbdev->data[4], zbdev->data[5], zbdev->data[6],
zbdev->data[7]);
+ break;
}
wake_up(&zbdev->wq);
@@ -433,7 +443,10 @@ process_char(struct zb_device *zbdev, unsigned char c)
zbdev->param1 = c;
if ((RESP_ED == zbdev->id) || (DATA_RECV_BLOCK == zbdev->id))
zbdev->state = STATE_WAIT_PARAM2;
- else {
+ else if (RESP_ADDRESS == zbdev->id) {
+ zbdev->param2 = 8;
+ zbdev->state = STATE_WAIT_DATA;
+ } else {
process_command(zbdev);
cleanup(zbdev);
}
@@ -623,6 +636,42 @@ out:
}
static int
+ieee802154_serial_address(struct ieee802154_dev *dev, u8
addr[IEEE802154_ADDR_LEN])
+{
+ struct zb_device *zbdev;
+ int ret = 0;
+
+ pr_debug("%s\n", __func__);
+
+ zbdev = dev->priv;
+ if (NULL == zbdev) {
+ printk(KERN_ERR "%s: wrong phy\n", __func__);
+ return -EINVAL;
+ }
+
+ if (mutex_lock_interruptible(&zbdev->mutex))
+ return -EINTR;
+
+ ret = send_cmd(zbdev, CMD_ADDRESS);
+ if (ret)
+ goto out;
+
+ if (wait_event_interruptible_timeout(zbdev->wq,
+ zbdev->status != STATUS_WAIT,
+ msecs_to_jiffies(1000)) > 0) {
+ memcpy(addr, zbdev->data, sizeof addr);
+ if (zbdev->status != STATUS_SUCCESS)
+ ret = -EBUSY;
+ } else
+ ret = -ETIMEDOUT;
+out:
+
+ mutex_unlock(&zbdev->mutex);
+ pr_debug("%s end\n", __func__);
+ return ret;
+}
+
+static int
ieee802154_serial_start(struct ieee802154_dev *dev)
{
struct zb_device *zbdev;
@@ -782,6 +831,7 @@ static struct ieee802154_ops serial_ops = {
.set_channel = ieee802154_serial_set_channel,
.start = ieee802154_serial_start,
.stop = ieee802154_serial_stop,
+ .ieee_addr = ieee802154_serial_address,
};
/*
diff --git a/include/net/mac802154.h b/include/net/mac802154.h
index d3f7867..73ac652 100644
--- a/include/net/mac802154.h
+++ b/include/net/mac802154.h
@@ -138,6 +138,8 @@ struct ieee802154_ops {
int (*set_hw_addr_filt)(struct ieee802154_dev *dev,
struct ieee802154_hw_addr_filt *filt,
unsigned long changed);
+ int (*ieee_addr)(struct ieee802154_dev *dev,
+ u8 addr[IEEE802154_ADDR_LEN]);
};
struct ieee802154_dev *ieee802154_alloc_device(size_t priv_size,
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 784f34d..f8d9593 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -50,6 +50,7 @@
#include <linux/if_arp.h>
#include <linux/if_arcnet.h>
#include <linux/if_infiniband.h>
+#include <net/af_ieee802154.h>
#include <linux/route.h>
#include <linux/inetdevice.h>
#include <linux/init.h>
@@ -1523,6 +1524,14 @@ static int addrconf_ifid_eui48(u8 *eui, struct
net_device *dev)
return 0;
}
+static int addrconf_ifid_eui64(u8 *eui, struct net_device *dev)
+{
+ if (dev->addr_len != IEEE802154_ADDR_LEN)
+ return -1;
+ memcpy(eui, dev->dev_addr, 8);
+ return 0;
+}
+
static int addrconf_ifid_arcnet(u8 *eui, struct net_device *dev)
{
/* XXX: inherit EUI-64 from other interface -- yoshfuji */
@@ -1580,6 +1589,8 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device
*dev)
return addrconf_ifid_infiniband(eui, dev);
case ARPHRD_SIT:
return addrconf_ifid_sit(eui, dev);
+ case ARPHRD_IEEE802154:
+ return addrconf_ifid_eui64(eui, dev);
}
return -1;
}
@@ -2375,6 +2386,7 @@ static void addrconf_dev_config(struct net_device *dev)
(dev->type != ARPHRD_FDDI) &&
(dev->type != ARPHRD_IEEE802_TR) &&
(dev->type != ARPHRD_ARCNET) &&
+ (dev->type != ARPHRD_IEEE802154) &&
(dev->type != ARPHRD_INFINIBAND)) {
/* Alas, we support only Ethernet autoconfiguration. */
return;
diff --git a/net/mac802154/6lowpan.c b/net/mac802154/6lowpan.c
index 99b1202..6525e18 100644
--- a/net/mac802154/6lowpan.c
+++ b/net/mac802154/6lowpan.c
@@ -60,7 +60,14 @@ static int lowpan_header_create(struct sk_buff *skb,
u8 head[24] = {};
int pos;
- printk("JDS - %s\n", __func__);
+ printk("JDS - %s type %x len %d\n", __func__, type, len);
+ if (type != ETH_P_IPV6)
+ return mac802154_header_create(skb, dev, type, _daddr, _saddr,
skb->len);
+
+
+ for (pos = 0; pos < 60; pos++)
+ printk("%02x ", skb->data[pos]);
+ printk("\n");
pos = 0;
head[pos++] = 0x41; /* temp force uncompressed ipv6 */
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
index d4611fe..52c593e 100644
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -27,6 +27,7 @@
#include <net/wpan-phy.h>
#include "mac802154.h"
+#include "mib.h"
#include "6lowpan.h"
int mac802154_slave_open(struct net_device *dev)
@@ -41,6 +42,14 @@ int mac802154_slave_open(struct net_device *dev)
goto err;
}
+ if (priv->hw->ops->ieee_addr) {
+ res = priv->hw->ops->ieee_addr(&priv->hw->hw, dev->dev_addr);
+ WARN_ON(res);
+ if (res)
+ goto err;
+ mac802154_dev_set_ieee_addr(dev);
+ }
+
netif_start_queue(dev);
return 0;
err:
------------------------------------------------------------------------------
This SF.net email is sponsored by
Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev
_______________________________________________
Linux-zigbee-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel