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

Reply via email to