Date:2011-11-06 16:01:46 (2 years 5 months ago)
Author:Xiangfu Liu
Commit:79165fa5e2323da0578b1493d9e789abec9db7c9
Message:xburst: ben nanonote: first add WPAN(atben,atusb) driver

take from qi-kernel.git thanks to Werner
Files: target/linux/xburst/patches-3.0/0001-JZ4740-cache-quirks.patch (1 diff)
target/linux/xburst/patches-3.0/0002-Add-n516-board-support.patch (1 diff)
target/linux/xburst/patches-3.0/0003-Add-n526-board-support.patch (1 diff)
target/linux/xburst/patches-3.0/0004-MIPS-JZ4740-Add-id800wt-board.patch (1 diff)
target/linux/xburst/patches-3.0/0005-Add-N516-sound-SoC-board-driver.patch (1 diff)
target/linux/xburst/patches-3.0/0006-Add-n516-lpc-driver.patch (1 diff)
target/linux/xburst/patches-3.0/0007-Add-N526-sound-SoC-board-driver.patch (1 diff)
target/linux/xburst/patches-3.0/0008-i2c-Add-i2c-driver-for-JZ47XX-SoCs.patch (1 diff)
target/linux/xburst/patches-3.0/0009-MIPS-JZ4740-Fix-i2c-driver-name.patch (1 diff)
target/linux/xburst/patches-3.0/0010-MFD-jz4740-adc-Add-support-for-the-touchscreen-part-.patch (1 diff)
target/linux/xburst/patches-3.0/0011-input-Add-touchscreen-driver-for-the-JZ4740-SoC.patch (1 diff)
target/linux/xburst/patches-3.0/0012-Add-ili8960-lcd-driver.patch (1 diff)
target/linux/xburst/patches-3.0/0013-Add-jz4740-udc-driver.patch (1 diff)
target/linux/xburst/patches-3.0/0014-Framebuffer-notifier-Call-notifier-callbacks-prior-t.patch (1 diff)
target/linux/xburst/patches-3.0/0015-500-modifier-keys.patch.patch (1 diff)
target/linux/xburst/patches-3.0/0016-850-ks7010-support.patch.patch (1 diff)
target/linux/xburst/patches-3.0/0017-900-add-openwrt-logo.patch (1 diff)
target/linux/xburst/patches-3.0/0018-901-ubi-Read-only-the-vid-header-instead-of-the-whol.patch (1 diff)
target/linux/xburst/patches-3.0/0019-902-NAND-Optimize-NAND_ECC_HW_OOB_FIRST-read.patch.patch (1 diff)
target/linux/xburst/patches-3.0/0020-903-NAND-Add-support-for-subpage-reads-for-NAND_ECC_.patch (1 diff)
target/linux/xburst/patches-3.0/0021-904-NAND-Optimize-reading-the-eec-data-for-the-JZ474.patch (1 diff)
target/linux/xburst/patches-3.0/0022-qi_lb60-Don-t-use-3-wire-spi-mode-for-the-display-fo.patch (1 diff)
target/linux/xburst/patches-3.0/0023-qi_lb60-NAND-add-data-partition.patch (1 diff)
target/linux/xburst/patches-3.0/0024-forward-code-to-linux-3.0.patch (1 diff)
target/linux/xburst/patches-3.0/0025-Update-to-new-platform-code.patch (1 diff)
target/linux/xburst/patches-3.0/0026-sound-update-DMA-code.patch (1 diff)
target/linux/xburst/patches-3.0/0027-Add-DEVMEM-support.patch (1 diff)
target/linux/xburst/patches-3.0/0028-Add-cpufreq-support.patch (1 diff)
target/linux/xburst/patches-3.0/0029-Add-new-jz4740_lcd.h.patch (1 diff)
target/linux/xburst/patches-3.0/0030-fbcon-color-fonts.patch (13 diffs)
target/linux/xburst/patches-3.0/0031-first-patch-for-atBen.patch (1 diff)
target/linux/xburst/patches-3.0/0032-set-atben-GPIO-to-func_none.patch (1 diff)

Change Details

target/linux/xburst/patches-3.0/0001-JZ4740-cache-quirks.patch
11From 2f669aa98831b7248402bab6a07b1b6f722cb6e9 Mon Sep 17 00:00:00 2001
22From: Lars-Peter Clausen <lars@metafoo.de>
33Date: Sat, 24 Apr 2010 17:34:29 +0200
4Subject: [PATCH 01/29] JZ4740 cache quirks
4Subject: [PATCH 01/32] JZ4740 cache quirks
55
66---
77 arch/mips/include/asm/r4kcache.h | 231 ++++++++++++++++++++++++++++++++++++++
target/linux/xburst/patches-3.0/0002-Add-n516-board-support.patch
11From 633a1f02f183675e3448c45a5ddd5e942ecbc37c Mon Sep 17 00:00:00 2001
22From: Lars-Peter Clausen <lars@metafoo.de>
33Date: Sat, 24 Apr 2010 17:25:01 +0200
4Subject: [PATCH 02/29] Add n516 board support
4Subject: [PATCH 02/32] Add n516 board support
55
66---
77 arch/mips/include/asm/mach-jz4740/board-n516.h | 39 +++
target/linux/xburst/patches-3.0/0003-Add-n526-board-support.patch
11From dcc0d9f15146c100a843dfa62ba259e208330f07 Mon Sep 17 00:00:00 2001
22From: Lars-Peter Clausen <lars@metafoo.de>
33Date: Sat, 24 Apr 2010 17:25:23 +0200
4Subject: [PATCH 03/29] Add n526 board support
4Subject: [PATCH 03/32] Add n526 board support
55
66---
77 arch/mips/jz4740/Kconfig | 4 +
target/linux/xburst/patches-3.0/0004-MIPS-JZ4740-Add-id800wt-board.patch
11From 322d8e1ccf544f576d60622dc304f136cef64a3b Mon Sep 17 00:00:00 2001
22From: Lars-Peter Clausen <lars@metafoo.de>
33Date: Sun, 5 Sep 2010 20:34:08 +0200
4Subject: [PATCH 04/29] MIPS: JZ4740: Add id800wt board
4Subject: [PATCH 04/32] MIPS: JZ4740: Add id800wt board
55
66---
77 arch/mips/jz4740/Kconfig | 4 +
target/linux/xburst/patches-3.0/0005-Add-N516-sound-SoC-board-driver.patch
11From 523f9ca02b5c2c8b79f1d01fff03b1191a6aed6c Mon Sep 17 00:00:00 2001
22From: Lars-Peter Clausen <lars@metafoo.de>
33Date: Sun, 1 Aug 2010 21:34:54 +0200
4Subject: [PATCH 05/29] Add N516 sound SoC board driver
4Subject: [PATCH 05/32] Add N516 sound SoC board driver
55
66---
77 sound/soc/jz4740/Kconfig | 8 ++
target/linux/xburst/patches-3.0/0006-Add-n516-lpc-driver.patch
11From b02e39f1ba2310fedf212d2a6e5d99c4a14fc297 Mon Sep 17 00:00:00 2001
22From: Lars-Peter Clausen <lars@metafoo.de>
33Date: Wed, 12 May 2010 14:22:36 +0200
4Subject: [PATCH 06/29] Add n516 lpc driver
4Subject: [PATCH 06/32] Add n516 lpc driver
55
66---
77 drivers/misc/Kconfig | 8 +
target/linux/xburst/patches-3.0/0007-Add-N526-sound-SoC-board-driver.patch
11From 19d5c8c334a79951d927a1b6eb25bf6a896c9ab5 Mon Sep 17 00:00:00 2001
22From: Lars-Peter Clausen <lars@metafoo.de>
33Date: Sat, 24 Apr 2010 12:38:41 +0200
4Subject: [PATCH 07/29] Add N526 sound SoC board driver
4Subject: [PATCH 07/32] Add N526 sound SoC board driver
55
66---
77 sound/soc/jz4740/Kconfig | 8 ++
target/linux/xburst/patches-3.0/0008-i2c-Add-i2c-driver-for-JZ47XX-SoCs.patch
11From 5e219770079a61b8c8e59abe5510678361c94696 Mon Sep 17 00:00:00 2001
22From: Lars-Peter Clausen <lars@metafoo.de>
33Date: Sun, 5 Sep 2010 03:19:10 +0200
4Subject: [PATCH 08/29] i2c: Add i2c driver for JZ47XX SoCs
4Subject: [PATCH 08/32] i2c: Add i2c driver for JZ47XX SoCs
55
66This patch adds a driver for the i2c controller found in Ingenic JZ47XX based
77SoCs.
target/linux/xburst/patches-3.0/0009-MIPS-JZ4740-Fix-i2c-driver-name.patch
11From 05bc4140f9da08fa48d81131ffa785e3026773a8 Mon Sep 17 00:00:00 2001
22From: Lars-Peter Clausen <lars@metafoo.de>
33Date: Sun, 5 Sep 2010 03:21:51 +0200
4Subject: [PATCH 09/29] MIPS: JZ4740: Fix i2c driver name.
4Subject: [PATCH 09/32] MIPS: JZ4740: Fix i2c driver name.
55
66The i2c driver is generic to all JZ47XX based SoCs not only the JZ4740. Reflect
77this in the driver name.
target/linux/xburst/patches-3.0/0010-MFD-jz4740-adc-Add-support-for-the-touchscreen-part-.patch
11From 659b0bb01c8e567d4593ffbd7acd6b8ceab0edf3 Mon Sep 17 00:00:00 2001
22From: Lars-Peter Clausen <lars@metafoo.de>
33Date: Sun, 5 Sep 2010 20:36:59 +0200
4Subject: [PATCH 10/29] MFD: jz4740-adc: Add support for the touchscreen part of the adc unit
4Subject: [PATCH 10/32] MFD: jz4740-adc: Add support for the touchscreen part of the adc unit
55
66---
77 drivers/mfd/jz4740-adc.c | 27 ++++++++++++++++++++++++---
target/linux/xburst/patches-3.0/0011-input-Add-touchscreen-driver-for-the-JZ4740-SoC.patch
11From 71e0648ad022c6f05e1bed1fcca69abc8abde4d9 Mon Sep 17 00:00:00 2001
22From: Lars-Peter Clausen <lars@metafoo.de>
33Date: Sun, 5 Sep 2010 20:45:08 +0200
4Subject: [PATCH 11/29] input: Add touchscreen driver for the JZ4740 SoC
4Subject: [PATCH 11/32] input: Add touchscreen driver for the JZ4740 SoC
55
66This patch adds a touchscreen driver for the Ingenic JZ4740 SoC.
77The touchscreen controller is part of the ADC unit and thus this driver is a mfd
target/linux/xburst/patches-3.0/0012-Add-ili8960-lcd-driver.patch
11From d7a92f8ccdca40672a2a242c756fb52c31b2bdba Mon Sep 17 00:00:00 2001
22From: Lars-Peter Clausen <lars@metafoo.de>
33Date: Sun, 1 Aug 2010 21:19:40 +0200
4Subject: [PATCH 12/29] Add ili8960 lcd driver
4Subject: [PATCH 12/32] Add ili8960 lcd driver
55
66---
77 drivers/video/backlight/Kconfig | 7 +
target/linux/xburst/patches-3.0/0013-Add-jz4740-udc-driver.patch
11From ecd72bc68f9b9a39cb0f1ec456787c61f03be978 Mon Sep 17 00:00:00 2001
22From: Xiangfu Liu <xiangfu@macbook.openmobilefree.net>
33Date: Tue, 13 Sep 2011 16:07:41 +0800
4Subject: [PATCH 13/29] Add jz4740 udc driver
4Subject: [PATCH 13/32] Add jz4740 udc driver
55
66---
77 drivers/usb/gadget/Kconfig | 13 +
target/linux/xburst/patches-3.0/0014-Framebuffer-notifier-Call-notifier-callbacks-prior-t.patch
11From c7700fa672bf0a171ceb9f4b092de33e3b306243 Mon Sep 17 00:00:00 2001
22From: Lars-Peter Clausen <lars@metafoo.de>
33Date: Sat, 24 Apr 2010 12:23:28 +0200
4Subject: [PATCH 14/29] Framebuffer notifier: Call notifier callbacks prior to blanking the screen
4Subject: [PATCH 14/32] Framebuffer notifier: Call notifier callbacks prior to blanking the screen
55
66---
77 drivers/video/fbmem.c | 8 ++++++--
target/linux/xburst/patches-3.0/0015-500-modifier-keys.patch.patch
11From 15bd698ca3f4104f3e3c28dcc7619dcef21f40ad Mon Sep 17 00:00:00 2001
22From: Xiangfu Liu <xiangfu@macbook.(none)>
33Date: Fri, 19 Aug 2011 15:40:08 +0800
4Subject: [PATCH 15/29] 500-modifier-keys.patch
4Subject: [PATCH 15/32] 500-modifier-keys.patch
55
66---
77 drivers/tty/vt/defkeymap.c_shipped | 326 +++++++++++++++++++++++++++---------
target/linux/xburst/patches-3.0/0016-850-ks7010-support.patch.patch
11From f4c9a977dc405856676cd1ca435394faf49b5f1c Mon Sep 17 00:00:00 2001
22From: Xiangfu Liu <xiangfu@macbook.(none)>
33Date: Fri, 19 Aug 2011 15:44:15 +0800
4Subject: [PATCH 16/29] 850-ks7010-support.patch
4Subject: [PATCH 16/32] 850-ks7010-support.patch
55
66---
77 drivers/mmc/core/core.c | 4 ++--
target/linux/xburst/patches-3.0/0017-900-add-openwrt-logo.patch
11From a5d4cdf6165b2e324f6f55a0c6b2e3d29d303382 Mon Sep 17 00:00:00 2001
22From: Lars-Peter Clausen <lars@metafoo.de>
33Date: Wed, 12 May 2010 14:18:47 +0200
4Subject: [PATCH 17/29] 900-add-openwrt-logo
4Subject: [PATCH 17/32] 900-add-openwrt-logo
55
66---
77 drivers/video/logo/Kconfig | 4 +
target/linux/xburst/patches-3.0/0018-901-ubi-Read-only-the-vid-header-instead-of-the-whol.patch
11From e4334870d2348cc326cb9135e9da83cdbec9e95e Mon Sep 17 00:00:00 2001
22From: Xiangfu Liu <xiangfu@macbook.(none)>
33Date: Fri, 19 Aug 2011 15:45:19 +0800
4Subject: [PATCH 18/29] 901-ubi-Read-only-the-vid-header-instead-of-the-whole-pa.patch
4Subject: [PATCH 18/32] 901-ubi-Read-only-the-vid-header-instead-of-the-whole-pa.patch
55
66---
77 drivers/mtd/ubi/io.c | 2 +-
target/linux/xburst/patches-3.0/0019-902-NAND-Optimize-NAND_ECC_HW_OOB_FIRST-read.patch.patch
11From a525f2fabe86dfd4a1acc057afcb31de319ca3e5 Mon Sep 17 00:00:00 2001
22From: Xiangfu Liu <xiangfu@macbook.(none)>
33Date: Fri, 19 Aug 2011 15:45:39 +0800
4Subject: [PATCH 19/29] 902-NAND-Optimize-NAND_ECC_HW_OOB_FIRST-read.patch
4Subject: [PATCH 19/32] 902-NAND-Optimize-NAND_ECC_HW_OOB_FIRST-read.patch
55
66---
77 drivers/mtd/nand/nand_base.c | 14 ++++++++++----
target/linux/xburst/patches-3.0/0020-903-NAND-Add-support-for-subpage-reads-for-NAND_ECC_.patch
11From e4e1ca7caccf399366d8dbbf6539217e2c7ea852 Mon Sep 17 00:00:00 2001
22From: Xiangfu Liu <xiangfu@macbook.(none)>
33Date: Fri, 19 Aug 2011 15:45:59 +0800
4Subject: [PATCH 20/29] 903-NAND-Add-support-for-subpage-reads-for-NAND_ECC_HW_O.patch
4Subject: [PATCH 20/32] 903-NAND-Add-support-for-subpage-reads-for-NAND_ECC_HW_O.patch
55
66---
77 drivers/mtd/nand/nand_base.c | 78 ++++++++++++++++++++++++++++++++++++++++--
target/linux/xburst/patches-3.0/0021-904-NAND-Optimize-reading-the-eec-data-for-the-JZ474.patch
11From 5fa159fe903240a78136ba90bfefc91d899fcfe3 Mon Sep 17 00:00:00 2001
22From: Xiangfu Liu <xiangfu@macbook.(none)>
33Date: Fri, 19 Aug 2011 15:46:14 +0800
4Subject: [PATCH 21/29] 904-NAND-Optimize-reading-the-eec-data-for-the-JZ4740-ev.patch
4Subject: [PATCH 21/32] 904-NAND-Optimize-reading-the-eec-data-for-the-JZ4740-ev.patch
55
66---
77 drivers/mtd/nand/nand_base.c | 14 ++++----------
target/linux/xburst/patches-3.0/0022-qi_lb60-Don-t-use-3-wire-spi-mode-for-the-display-fo.patch
11From 1133e48ddc4c3082dfa78606cff16d3c3bde84c4 Mon Sep 17 00:00:00 2001
22From: Lars-Peter Clausen <lars@metafoo.de>
33Date: Wed, 13 Oct 2010 01:17:24 +0200
4Subject: [PATCH 22/29] qi_lb60: Don't use 3-wire spi mode for the display for now
4Subject: [PATCH 22/32] qi_lb60: Don't use 3-wire spi mode for the display for now
55
66The spi_gpio driver does not support 3-wire mode.
77---
target/linux/xburst/patches-3.0/0023-qi_lb60-NAND-add-data-partition.patch
11From 1878b22649c3ecde1795d6695b92ca02fa9110c2 Mon Sep 17 00:00:00 2001
22From: Xiangfu Liu <xiangfu@macbook.(none)>
33Date: Fri, 19 Aug 2011 15:46:52 +0800
4Subject: [PATCH 23/29] qi_lb60: NAND: add data partition
4Subject: [PATCH 23/32] qi_lb60: NAND: add data partition
55
66---
77 arch/mips/jz4740/board-qi_lb60.c | 7 ++++++-
target/linux/xburst/patches-3.0/0024-forward-code-to-linux-3.0.patch
11From 87eb40e63e1b149ef87fe05765b97328bfbd1c1f Mon Sep 17 00:00:00 2001
22From: Xiangfu Liu <xiangfu@macbook.openmobilefree.net>
33Date: Wed, 14 Sep 2011 14:29:37 +0800
4Subject: [PATCH 24/29] forward code to linux 3.0
4Subject: [PATCH 24/32] forward code to linux 3.0
55
66---
77 arch/mips/Kconfig | 2 +
target/linux/xburst/patches-3.0/0025-Update-to-new-platform-code.patch
11From 8a760f273f94b72e882d7f82b04ade72ae739a6b Mon Sep 17 00:00:00 2001
22From: Xiangfu Liu <xiangfu@sharism.cc>
33Date: Wed, 14 Sep 2011 15:12:41 +0800
4Subject: [PATCH 25/29] Update to new platform code
4Subject: [PATCH 25/32] Update to new platform code
55
66---
77 drivers/mtd/nand/jz4740_nand.c | 2 +-
target/linux/xburst/patches-3.0/0026-sound-update-DMA-code.patch
11From 5e689acca07bccdced123f82e8dde5459eca0d97 Mon Sep 17 00:00:00 2001
22From: Xiangfu Liu <xiangfu@macbook.openmobilefree.net>
33Date: Wed, 14 Sep 2011 14:30:01 +0800
4Subject: [PATCH 26/29] sound: update DMA code
4Subject: [PATCH 26/32] sound: update DMA code
55
66---
77 sound/soc/jz4740/jz4740-pcm.c | 21 ++++++++++++++++++---
target/linux/xburst/patches-3.0/0027-Add-DEVMEM-support.patch
11From ab59753a9df09b990822b15d2593c5c98905684c Mon Sep 17 00:00:00 2001
22From: Xiangfu Liu <xiangfu@macbook.openmobilefree.net>
33Date: Wed, 14 Sep 2011 14:29:51 +0800
4Subject: [PATCH 27/29] Add DEVMEM support
4Subject: [PATCH 27/32] Add DEVMEM support
55
66---
77 drivers/char/Kconfig | 10 ++++++++++
target/linux/xburst/patches-3.0/0028-Add-cpufreq-support.patch
11From b0b7794018b75ce33be133664fb58ab3e6efc2e8 Mon Sep 17 00:00:00 2001
22From: Xiangfu Liu <xiangfu@macbook.openmobilefree.net>
33Date: Wed, 14 Sep 2011 14:29:52 +0800
4Subject: [PATCH 28/29] Add cpufreq support
4Subject: [PATCH 28/32] Add cpufreq support
55
66---
77 drivers/cpufreq/cpufreq_stats.c | 161 ++++++++++++++++++++-------------------
target/linux/xburst/patches-3.0/0029-Add-new-jz4740_lcd.h.patch
11From 2dc84f90409839e6a85bd9e25394a387c86d12a1 Mon Sep 17 00:00:00 2001
22From: Xiangfu Liu <xiangfu@macbook.openmobilefree.net>
33Date: Wed, 14 Sep 2011 14:29:58 +0800
4Subject: [PATCH 29/29] Add new jz4740_lcd.h
4Subject: [PATCH 29/32] Add new jz4740_lcd.h
55
66---
77 drivers/video/jz4740_fb.c | 78 +----------------------------------
target/linux/xburst/patches-3.0/0030-fbcon-color-fonts.patch
1From 77de829067262bbe1f7435b087c11ad9a8ea0b06 Mon Sep 17 00:00:00 2001
2From: Xiangfu Liu <xiangfu@sharism.cc>
3Date: Tue, 18 Oct 2011 09:21:04 +0800
4Subject: [PATCH 30/32] fbcon-color-fonts
5
6---
7 drivers/tty/vt/vt.c | 3 +-
8 drivers/video/console/bitblit.c | 188 +++++++++++++++++++++++++++++++++------
9 drivers/video/console/fbcon.c | 14 +++-
10 3 files changed, 173 insertions(+), 32 deletions(-)
11
12diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
13index b3915b7..37eaac5 100644
114--- a/drivers/tty/vt/vt.c
215+++ b/drivers/tty/vt/vt.c
3@@ -4034,6 +4034,7 @@ static int con_font_set(struct vc_data *
16@@ -4034,6 +4034,7 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op)
417     struct console_font font;
518     int rc = -EINVAL;
619     int size;
...... 
821
922     if (vc->vc_mode != KD_TEXT)
1023         return -EINVAL;
11@@ -4063,7 +4064,7 @@ static int con_font_set(struct vc_data *
24@@ -4063,7 +4064,7 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op)
1225     }
1326     if (op->width <= 0 || op->width > 32 || op->height > 32)
1427         return -EINVAL;
...... 
1730     if (size > max_font_size)
1831         return -ENOSPC;
1932     font.charcount = op->charcount;
33diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
34index 28b1a83..8e559df 100644
2035--- a/drivers/video/console/bitblit.c
2136+++ b/drivers/video/console/bitblit.c
22@@ -105,6 +105,12 @@ static inline void bit_putcs_aligned(str
37@@ -105,6 +105,12 @@ static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info,
2338     info->fbops->fb_imageblit(info, image);
2439 }
2540
...... 
3247 static inline void bit_putcs_unaligned(struct vc_data *vc,
3348                        struct fb_info *info, const u16 *s,
3449                        u32 attr, u32 cnt, u32 d_pitch,
35@@ -140,12 +146,62 @@ static inline void bit_putcs_unaligned(s
50@@ -140,12 +146,62 @@ static inline void bit_putcs_unaligned(struct vc_data *vc,
3651
3752 }
3853
...... 
96111     u32 cellsize = width * vc->vc_font.height;
97112     u32 maxcnt = info->pixmap.size/cellsize;
98113     u32 scan_align = info->pixmap.scan_align - 1;
99@@ -153,6 +209,10 @@ static void bit_putcs(struct vc_data *vc
114@@ -153,6 +209,10 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,
100115     u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
101116     u32 attribute = get_attribute(info, scr_readw(s));
102117     u8 *dst, *buf = NULL;
...... 
107122
108123     image.fg_color = fg;
109124     image.bg_color = bg;
110@@ -167,31 +227,73 @@ static void bit_putcs(struct vc_data *vc
125@@ -167,31 +227,73 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,
111126             return;
112127     }
113128
...... 
206221     }
207222
208223     /* buf is always NULL except when in monochrome mode, so in this case
209@@ -234,6 +336,29 @@ static void bit_clear_margins(struct vc_
224@@ -234,6 +336,29 @@ static void bit_clear_margins(struct vc_data *vc, struct fb_info *info,
210225     }
211226 }
212227
...... 
236251 static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
237252                int softback_lines, int fg, int bg)
238253 {
239@@ -245,6 +370,7 @@ static void bit_cursor(struct vc_data *v
254@@ -245,6 +370,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
240255     int attribute, use_sw = (vc->vc_cursor_type & 0x10);
241256     int err = 1;
242257     char *src;
...... 
244259
245260     cursor.set = 0;
246261
247@@ -383,8 +509,14 @@ static void bit_cursor(struct vc_data *v
262@@ -383,8 +509,14 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
248263     if (info->fbops->fb_cursor)
249264         err = info->fbops->fb_cursor(info, &cursor);
250265
...... 
261276
262277     ops->cursor_reset = 0;
263278 }
279diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
280index 8745637..dea9d2c 100644
264281--- a/drivers/video/console/fbcon.c
265282+++ b/drivers/video/console/fbcon.c
266@@ -2552,7 +2552,8 @@ static int fbcon_set_font(struct vc_data
283@@ -2552,7 +2552,8 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne
267284     int size;
268285     int i, csum;
269286     u8 *new_data, *data = font->data;
...... 
273290
274291     /* Is there a reason why fbconsole couldn't handle any charcount >256?
275292      * If not this check should be changed to charcount < 256 */
276@@ -2571,6 +2572,7 @@ static int fbcon_set_font(struct vc_data
293@@ -2571,6 +2572,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne
277294     size = h * pitch * charcount;
278295
279296     new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER);
...... 
281298
282299     if (!new_data)
283300         return -ENOMEM;
284@@ -2579,8 +2581,14 @@ static int fbcon_set_font(struct vc_data
301@@ -2579,8 +2581,14 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne
285302     FNTSIZE(new_data) = size;
286303     FNTCHARCNT(new_data) = charcount;
287304     REFCOUNT(new_data) = 0; /* usage counter */
...... 
298315     }
299316
300317     /* Since linux has a nice crc32 function use it for counting font
318--
3191.7.4.1
320
target/linux/xburst/patches-3.0/0031-first-patch-for-atBen.patch
1From 84f38ed9a131b807927e4aed2f277d8a2fad5286 Mon Sep 17 00:00:00 2001
2From: Xiangfu Liu <xiangfu@sharism.cc>
3Date: Wed, 19 Oct 2011 10:59:47 +0800
4Subject: [PATCH 31/32] first patch for atBen
5
6---
7 drivers/ieee802154/Kconfig | 55 ++-
8 drivers/ieee802154/Makefile | 10 +-
9 drivers/ieee802154/adf7242.c | 1034 ++++++++++++++++++++++++++++++++++++++
10 drivers/ieee802154/at86rf230.c | 872 ++++++++++++++++++++++++++++++++
11 drivers/ieee802154/at86rf230.h | 211 ++++++++
12 drivers/ieee802154/cc2420.c | 859 ++++++++++++++++++++++++++++++++
13 drivers/ieee802154/fakehard.c | 14 +-
14 drivers/ieee802154/fakelb.c | 311 ++++++++++++
15 drivers/ieee802154/serial.c | 1047 +++++++++++++++++++++++++++++++++++++++
16 drivers/ieee802154/spi_atben.c | 421 ++++++++++++++++
17 drivers/ieee802154/spi_atusb.c | 750 ++++++++++++++++++++++++++++
18 include/linux/if.h | 2 +
19 include/linux/if_arp.h | 2 +
20 include/linux/if_ieee802154.h | 6 +
21 include/linux/nl802154.h | 10 +-
22 include/linux/spi/at86rf230.h | 34 ++
23 include/net/ieee802154_netdev.h | 17 +-
24 include/net/mac802154.h | 156 ++++++
25 include/net/wpan-phy.h | 8 +-
26 net/Kconfig | 2 +
27 net/Makefile | 1 +
28 net/ieee802154/Kconfig | 9 +
29 net/ieee802154/Makefile | 3 +
30 net/ieee802154/dgram.c | 3 +-
31 net/ieee802154/ieee802154.h | 4 +
32 net/ieee802154/nl-mac.c | 2 +-
33 net/ieee802154/nl-phy.c | 48 ++-
34 net/ieee802154/nl_policy.c | 1 +
35 net/ieee802154/wpan-class.c | 2 +-
36 net/mac802154/Kconfig | 24 +
37 net/mac802154/Makefile | 6 +
38 net/mac802154/beacon.c | 282 +++++++++++
39 net/mac802154/beacon_hash.c | 106 ++++
40 net/mac802154/beacon_hash.h | 41 ++
41 net/mac802154/mac802154.h | 126 +++++
42 net/mac802154/mac_cmd.c | 362 ++++++++++++++
43 net/mac802154/main.c | 282 +++++++++++
44 net/mac802154/mib.c | 249 ++++++++++
45 net/mac802154/mib.h | 35 ++
46 net/mac802154/monitor.c | 116 +++++
47 net/mac802154/rx.c | 117 +++++
48 net/mac802154/scan.c | 203 ++++++++
49 net/mac802154/smac.c | 127 +++++
50 net/mac802154/tx.c | 106 ++++
51 net/mac802154/wpan.c | 630 +++++++++++++++++++++++
52 net/zigbee/Kconfig | 7 +
53 net/zigbee/Makefile | 5 +
54 net/zigbee/af_zigbee.c | 285 +++++++++++
55 net/zigbee/dgram.c | 401 +++++++++++++++
56 49 files changed, 9380 insertions(+), 24 deletions(-)
57 create mode 100644 drivers/ieee802154/adf7242.c
58 create mode 100644 drivers/ieee802154/at86rf230.c
59 create mode 100644 drivers/ieee802154/at86rf230.h
60 create mode 100644 drivers/ieee802154/cc2420.c
61 create mode 100644 drivers/ieee802154/fakelb.c
62 create mode 100644 drivers/ieee802154/serial.c
63 create mode 100644 drivers/ieee802154/spi_atben.c
64 create mode 100644 drivers/ieee802154/spi_atusb.c
65 create mode 100644 include/linux/if_ieee802154.h
66 create mode 100644 include/linux/spi/at86rf230.h
67 create mode 100644 include/net/mac802154.h
68 create mode 100644 net/mac802154/Kconfig
69 create mode 100644 net/mac802154/Makefile
70 create mode 100644 net/mac802154/beacon.c
71 create mode 100644 net/mac802154/beacon_hash.c
72 create mode 100644 net/mac802154/beacon_hash.h
73 create mode 100644 net/mac802154/mac802154.h
74 create mode 100644 net/mac802154/mac_cmd.c
75 create mode 100644 net/mac802154/main.c
76 create mode 100644 net/mac802154/mib.c
77 create mode 100644 net/mac802154/mib.h
78 create mode 100644 net/mac802154/monitor.c
79 create mode 100644 net/mac802154/rx.c
80 create mode 100644 net/mac802154/scan.c
81 create mode 100644 net/mac802154/smac.c
82 create mode 100644 net/mac802154/tx.c
83 create mode 100644 net/mac802154/wpan.c
84 create mode 100644 net/zigbee/Kconfig
85 create mode 100644 net/zigbee/Makefile
86 create mode 100644 net/zigbee/af_zigbee.c
87 create mode 100644 net/zigbee/dgram.c
88
89diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig
90index 9b9f43a..a323dc1 100644
91--- a/drivers/ieee802154/Kconfig
92@@ -10,13 +10,64 @@ menuconfig IEEE802154_DRIVERS
93       If you say N, all options in this submenu will be skipped and
94       disabled.
95
96+config IEEE802154_DRIVER_DEBUG
97+ bool "Driver debugging messages"
98+ depends on IEEE802154_DRIVERS
99+ default y
100+ help
101+ Say Y here to make the IEEE 802.15.4 drivers generate extensive
102+ debugging messages.
103+
104 config IEEE802154_FAKEHARD
105     tristate "Fake LR-WPAN driver with several interconnected devices"
106     depends on IEEE802154_DRIVERS
107     ---help---
108       Say Y here to enable the fake driver that serves as an example
109- of HardMAC device driver.
110+ of HardMAC device driver.
111
112- This driver can also be built as a module. To do so say M here.
113+ This driver can also be built as a module. To do so say M here.
114       The module will be called 'fakehard'.
115
116+
117+config IEEE802154_FAKELB
118+ depends on IEEE802154_DRIVERS && MAC802154
119+ tristate "Fake LR-WPAN driver with several interconnected devices"
120+ ---help---
121+ Say Y here to enable the fake driver that can emulate a net
122+ of several interconnected radio devices.
123+
124+ This driver can also be built as a module. To do so say M here.
125+ The module will be called 'fakelb'.
126+
127+config IEEE802154_SERIAL
128+ depends on IEEE802154_DRIVERS && MAC802154
129+ tristate "Simple LR-WPAN UART driver"
130+
131+config IEEE802154_AT86RF230
132+ depends on IEEE802154_DRIVERS && MAC802154
133+ tristate "AT86RF230 transceiver driver"
134+ depends on SPI
135+
136+config SPI_ATBEN
137+ tristate "ATBEN 8:10 SPI interface"
138+ depends on JZ4740_QI_LB60 && IEEE802154_AT86RF230
139+ help
140+ Bit-banging SPI driver for the 8:10 interface of the Ben NanoNote
141+ when equipped with an ATBEN board.
142+
143+config SPI_ATUSB
144+ tristate "ATUSB SPI interface"
145+ depends on USB && IEEE802154_AT86RF230
146+ help
147+ SPI-over-USB driver for the ATUSB IEEE 802.15.4 board.
148+
149+config IEEE802154_CC2420
150+ tristate "CC2420 driver"
151+ depends on SPI
152+ depends on IEEE802154_DRIVERS
153+
154+config IEEE802154_ADF7242
155+ tristate "ADF7242 transceiver driver"
156+ depends on IEEE802154_DRIVERS && MAC802154
157+ depends on SPI
158+
159diff --git a/drivers/ieee802154/Makefile b/drivers/ieee802154/Makefile
160index 6899913..2a10a6a 100644
161--- a/drivers/ieee802154/Makefile
162@@ -1,3 +1,11 @@
163 obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o
164+obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o
165+obj-$(CONFIG_IEEE802154_SERIAL) += serial.o
166+obj-$(CONFIG_IEEE802154_AT86RF230) += at86rf230.o
167+obj-$(CONFIG_IEEE802154_CC2420) += cc2420.o
168+obj-$(CONFIG_IEEE802154_ADF7242) += adf7242.o
169+obj-$(CONFIG_SPI_ATUSB) += spi_atusb.o
170+obj-$(CONFIG_SPI_ATBEN) += spi_atben.o
171
172-ccflags-y := -DDEBUG -DCONFIG_FFD
173+ccflags-$(CONFIG_IEEE802154_DRIVER_DEBUG) += -DDEBUG
174+ccflags-y += -DCONFIG_FFD
175diff --git a/drivers/ieee802154/adf7242.c b/drivers/ieee802154/adf7242.c
176new file mode 100644
177index 0000000..b578a55
178--- /dev/null
179@@ -0,0 +1,1034 @@
180+/*
181+ * Analog Devices ADF7242 Low-Power IEEE 802.15.4 Transceiver
182+ *
183+ * Copyright 2009-2010 Analog Devices Inc.
184+ *
185+ * Licensed under the GPL-2 or later.
186+ */
187+
188+#include <linux/kernel.h>
189+#include <linux/module.h>
190+#include <linux/interrupt.h>
191+#include <linux/delay.h>
192+#include <linux/mutex.h>
193+#include <linux/workqueue.h>
194+#include <linux/spinlock.h>
195+#include <linux/firmware.h>
196+#include <linux/spi/spi.h>
197+#include <linux/spi/adf7242.h>
198+
199+#include <net/mac802154.h>
200+#include <net/wpan-phy.h>
201+
202+/*
203+ * DEBUG LEVEL
204+ * 0 OFF
205+ * 1 INFO
206+ * 2 INFO + TRACE
207+ */
208+
209+#define ADF_DEBUG 0
210+#define DBG(n, args...) do { if (ADF_DEBUG >= (n)) pr_debug(args); } while (0)
211+
212+#define FIRMWARE "adf7242_firmware.bin"
213+#define MAX_POLL_LOOPS 10
214+
215+/* All Registers */
216+
217+#define REG_EXT_CTRL 0x100 /* RW External LNA/PA and internal PA control configuration bits */
218+#define REG_TX_FSK_TEST 0x101 /* RW TX FSK test mode configuration */
219+#define REG_CCA1 0x105 /* RW RSSI threshold for CCA */
220+#define REG_CCA2 0x106 /* RW CCA mode configuration */
221+#define REG_BUFFERCFG 0x107 /* RW RX_BUFFER overwrite control */
222+#define REG_PKT_CFG 0x108 /* RW FCS evaluation configuration */
223+#define REG_DELAYCFG0 0x109 /* RW RC_RX command to SFD or sync word search delay */
224+#define REG_DELAYCFG1 0x10A /* RW RC_TX command to TX state */
225+#define REG_DELAYCFG2 0x10B /* RW Mac delay extention */
226+#define REG_SYNC_WORD0 0x10C /* RW sync word bits [7:0] of [23:0] */
227+#define REG_SYNC_WORD1 0x10D /* RW sync word bits [15:8] of [23:0] */
228+#define REG_SYNC_WORD2 0x10E /* RW sync word bits [23:16] of [23:0] */
229+#define REG_SYNC_CONFIG 0x10F /* RW sync word configuration */
230+#define REG_RC_CFG 0x13E /* RW RX / TX packet configuration */
231+#define REG_RC_VAR44 0x13F /* RW RESERVED */
232+#define REG_CH_FREQ0 0x300 /* RW Channel Frequency Settings - Low Byte */
233+#define REG_CH_FREQ1 0x301 /* RW Channel Frequency Settings - Middle Byte */
234+#define REG_CH_FREQ2 0x302 /* RW Channel Frequency Settings - 2 MSBs */
235+#define REG_TX_FD 0x304 /* RW TX Frequency Deviation Register */
236+#define REG_DM_CFG0 0x305 /* RW RX Discriminator BW Register */
237+#define REG_TX_M 0x306 /* RW TX Mode Register */
238+#define REG_RX_M 0x307 /* RW RX Mode Register */
239+#define REG_RRB 0x30C /* R RSSI Readback Register */
240+#define REG_LRB 0x30D /* R Link Quality Readback Register */
241+#define REG_DR0 0x30E /* RW bits [15:8] of [15:0] for data rate setting */
242+#define REG_DR1 0x30F /* RW bits [7:0] of [15:0] for data rate setting */
243+#define REG_PRAMPG 0x313 /* RW RESERVED */
244+#define REG_TXPB 0x314 /* RW TX Packet Storage Base Address */
245+#define REG_RXPB 0x315 /* RW RX Packet Storage Base Address */
246+#define REG_TMR_CFG0 0x316 /* RW Wake up Timer Configuration Register - High Byte */
247+#define REG_TMR_CFG1 0x317 /* RW Wake up Timer Configuration Register - Low Byte */
248+#define REG_TMR_RLD0 0x318 /* RW Wake up Timer Value Register - High Byte */
249+#define REG_TMR_RLD1 0x319 /* RW Wake up Timer Value Register - Low Byte */
250+#define REG_TMR_CTRL 0x31A /* RW Wake up Timer Timeout flag */
251+#define REG_PD_AUX 0x31E /* RW Battmon enable */
252+#define REG_GP_CFG 0x32C /* RW GPIO Configuration */
253+#define REG_GP_OUT 0x32D /* RW GPIO Configuration */
254+#define REG_GP_IN 0x32E /* R GPIO Configuration */
255+#define REG_SYNT 0x335 /* RW bandwidth calibration timers */
256+#define REG_CAL_CFG 0x33D /* RW Calibration Settings */
257+#define REG_SYNT_CAL 0x371 /* RW Oscillator and Doubler Configuration */
258+#define REG_IIRF_CFG 0x389 /* RW BB Filter Decimation Rate */
259+#define REG_CDR_CFG 0x38A /* RW CDR kVCO */
260+#define REG_DM_CFG1 0x38B /* RW Postdemodulator Filter */
261+#define REG_AGCSTAT 0x38E /* R RXBB Ref Osc Calibration Engine Readback */
262+#define REG_RXCAL0 0x395 /* RW RX BB filter tuning, LSB */
263+#define REG_RXCAL1 0x396 /* RW RX BB filter tuning, MSB */
264+#define REG_RXFE_CFG 0x39B /* RW RXBB Ref Osc & RXFE Calibration */
265+#define REG_PA_RR 0x3A7 /* RW Set PA ramp rate */
266+#define REG_PA_CFG 0x3A8 /* RW PA enable */
267+#define REG_EXTPA_CFG 0x3A9 /* RW External PA BIAS DAC */
268+#define REG_EXTPA_MSC 0x3AA /* RW PA Bias Mode */
269+#define REG_ADC_RBK 0x3AE /* R Readback temp */
270+#define REG_AGC_CFG1 0x3B2 /* RW GC Parameters */
271+#define REG_AGC_MAX 0x3B4 /* RW Slew rate */
272+#define REG_AGC_CFG2 0x3B6 /* RW RSSI Parameters */
273+#define REG_AGC_CFG3 0x3B7 /* RW RSSI Parameters */
274+#define REG_AGC_CFG4 0x3B8 /* RW RSSI Parameters */
275+#define REG_AGC_CFG5 0x3B9 /* RW RSSI & NDEC Parameters */
276+#define REG_AGC_CFG6 0x3BA /* RW NDEC Parameters */
277+#define REG_OCL_CFG1 0x3C4 /* RW OCL System Parameters */
278+#define REG_IRQ1_EN0 0x3C7 /* RW Interrupt Mask set bits [7:0] of [15:0] for IRQ1 */
279+#define REG_IRQ1_EN1 0x3C8 /* RW Interrupt Mask set bits [15:8] of [15:0] for IRQ1 */
280+#define REG_IRQ2_EN0 0x3C9 /* RW Interrupt Mask set bits [7:0] of [15:0] for IRQ2 */
281+#define REG_IRQ2_EN1 0x3CA /* RW Interrupt Mask set bits [15:8] of [15:0] for IRQ2 */
282+#define REG_IRQ1_SRC0 0x3CB /* RW Interrupt Source bits [7:0] of [15:0] for IRQ */
283+#define REG_IRQ1_SRC1 0x3CC /* RW Interrupt Source bits [15:8] of [15:0] for IRQ */
284+#define REG_OCL_BW0 0x3D2 /* RW OCL System Parameters */
285+#define REG_OCL_BW1 0x3D3 /* RW OCL System Parameters */
286+#define REG_OCL_BW2 0x3D4 /* RW OCL System Parameters */
287+#define REG_OCL_BW3 0x3D5 /* RW OCL System Parameters */
288+#define REG_OCL_BW4 0x3D6 /* RW OCL System Parameters */
289+#define REG_OCL_BWS 0x3D7 /* RW OCL System Parameters */
290+#define REG_OCL_CFG13 0x3E0 /* RW OCL System Parameters */
291+#define REG_GP_DRV 0x3E3 /* RW I/O pads Configuration and bg trim */
292+#define REG_BM_CFG 0x3E6 /* RW Battery Monitor Threshold Voltage setting */
293+#define REG_SFD_15_4 0x3F4 /* RW Option to set non standard SFD */
294+#define REG_AFC_CFG 0x3F7 /* RW AFC mode and polarity */
295+#define REG_AFC_KI_KP 0x3F8 /* RW AFC ki and kp */
296+#define REG_AFC_RANGE 0x3F9 /* RW AFC range */
297+#define REG_AFC_READ 0x3FA /* RW Readback frequency error */
298+
299+#define REG_PAN_ID0 0x112
300+#define REG_PAN_ID1 0x113
301+#define REG_SHORT_ADDR_0 0x114
302+#define REG_SHORT_ADDR_1 0x115
303+#define REG_IEEE_ADDR_0 0x116
304+#define REG_IEEE_ADDR_1 0x117
305+#define REG_IEEE_ADDR_2 0x118
306+#define REG_IEEE_ADDR_3 0x119
307+#define REG_IEEE_ADDR_4 0x11A
308+#define REG_IEEE_ADDR_5 0x11B
309+#define REG_IEEE_ADDR_6 0x11C
310+#define REG_IEEE_ADDR_7 0x11D
311+#define REG_FFILT_CFG 0x11E
312+#define REG_AUTO_CFG 0x11F
313+#define REG_AUTO_TX1 0x120
314+#define REG_AUTO_TX2 0x121
315+#define REG_AUTO_STATUS 0x122
316+
317+/* REG_FFILT_CFG */
318+#define ACCEPT_BEACON_FRAMES (1 << 0)
319+#define ACCEPT_DATA_FRAMES (1 << 1)
320+#define ACCEPT_ACK_FRAMES (1 << 2)
321+#define ACCEPT_MACCMD_FRAMES (1 << 3)
322+#define ACCEPT_RESERVED_FRAMES (1 << 4)
323+#define ACCEPT_ALL_ADDRESS (1 << 5)
324+
325+/* REG_AUTO_CFG */
326+#define AUTO_ACK_FRAMEPEND (1 << 0)
327+#define IS_PANCOORD (1 << 1)
328+#define RX_AUTO_ACK_EN (1 << 3)
329+#define CSMA_CA_RX_TURNAROUND (1 << 4)
330+
331+/* REG_AUTO_TX1 */
332+#define MAX_FRAME_RETRIES(x) ((x) & 0xF)
333+#define MAX_CCA_RETRIES(x) (((x) & 0x7) << 4)
334+
335+/* REG_AUTO_TX2 */
336+#define CSMA_MAX_BE(x) ((x) & 0xF)
337+#define CSMA_MIN_BE(x) (((x) & 0xF) << 4)
338+
339+#define CMD_SPI_NOP 0xFF /* No operation. Use for dummy writes */
340+#define CMD_SPI_PKT_WR 0x10 /* Write telegram to the Packet RAM starting from the TX packet base address pointer tx_packet_base */
341+#define CMD_SPI_PKT_RD 0x30 /* Read telegram from the Packet RAM starting from RX packet base address pointer rxpb.rx_packet_base */
342+#define CMD_SPI_MEM_WR(x) (0x18 + (x >> 8)) /* Write data to MCR or Packet RAM sequentially */
343+#define CMD_SPI_MEM_RD(x) (0x38 + (x >> 8)) /* Read data from MCR or Packet RAM sequentially */
344+#define CMD_SPI_MEMR_WR(x) (0x08 + (x >> 8)) /* Write data to MCR or Packet RAM as random block */
345+#define CMD_SPI_MEMR_RD(x) (0x28 + (x >> 8)) /* Read data from MCR or Packet RAM as random block */
346+#define CMD_SPI_PRAM_WR 0x1E /* Write data sequentially to current PRAM page selected */
347+#define CMD_RC_SLEEP 0xB1 /* Invoke transition of radio controller into SLEEP state */
348+#define CMD_RC_IDLE 0xB2 /* Invoke transition of radio controller into IDLE state */
349+#define CMD_RC_PHY_RDY 0xB3 /* Invoke transition of radio controller into PHY_RDY state */
350+#define CMD_RC_RX 0xB4 /* Invoke transition of radio controller into RX state */
351+#define CMD_RC_TX 0xB5 /* Invoke transition of radio controller into TX state */
352+#define CMD_RC_MEAS 0xB6 /* Invoke transition of radio controller into MEAS state */
353+#define CMD_RC_CCA 0xB7 /* Invoke Clear channel assessment */
354+#define CMD_RC_CSMACA 0xC1 /* initiates CSMA-CA channel access sequence and frame transmission */
355+
356+/* STATUS */
357+
358+#define STAT_SPI_READY (1 << 7)
359+#define STAT_IRQ_STATUS (1 << 6)
360+#define STAT_RC_READY (1 << 5)
361+#define STAT_CCA_RESULT (1 << 4)
362+#define RC_STATUS_IDLE 1
363+#define RC_STATUS_MEAS 2
364+#define RC_STATUS_PHY_RDY 3
365+#define RC_STATUS_RX 4
366+#define RC_STATUS_TX 5
367+#define RC_STATUS_MASK 0xF
368+
369+/* AUTO_STATUS */
370+
371+#define SUCCESS 0
372+#define SUCCESS_DATPEND 1
373+#define FAILURE_CSMACA 2
374+#define FAILURE_NOACK 3
375+#define AUTO_STATUS_MASK 0x3
376+
377+#define PRAM_PAGESIZE 256
378+
379+/* IRQ1 */
380+
381+#define IRQ_CCA_COMPLETE (1 << 0)
382+#define IRQ_SFD_RX (1 << 1)
383+#define IRQ_SFD_TX (1 << 2)
384+#define IRQ_RX_PKT_RCVD (1 << 3)
385+#define IRQ_TX_PKT_SENT (1 << 4)
386+#define IRQ_FRAME_VALID (1 << 5)
387+#define IRQ_ADDRESS_VALID (1 << 6)
388+#define IRQ_CSMA_CA (1 << 7)
389+
390+#define AUTO_TX_TURNAROUND (1 << 3)
391+#define ADDON_EN (1 << 4)
392+
393+struct adf7242_local {
394+ struct spi_device *spi;
395+ struct adf7242_platform_data *pdata;
396+ struct work_struct irqwork;
397+ struct completion tx_complete;
398+ struct ieee802154_dev *dev;
399+ struct mutex bmux;
400+ spinlock_t lock;
401+ unsigned irq_disabled:1; /* P: lock */
402+ unsigned is_tx:1; /* P: lock */
403+ unsigned mode;
404+ unsigned tx_irq;
405+ int tx_stat;
406+ u8 buf[3];
407+};
408+
409+static int adf7242_status(struct adf7242_local *lp, u8 *stat)
410+{
411+ int status;
412+ struct spi_message msg;
413+ u8 buf_tx[1], buf_rx[1];
414+
415+ struct spi_transfer xfer = {
416+ .len = 1,
417+ .tx_buf = buf_tx,
418+ .rx_buf = buf_rx,
419+ };
420+
421+ buf_tx[0] = CMD_SPI_NOP;
422+
423+ spi_message_init(&msg);
424+ spi_message_add_tail(&xfer, &msg);
425+
426+ mutex_lock(&lp->bmux);
427+ status = spi_sync(lp->spi, &msg);
428+ mutex_unlock(&lp->bmux);
429+
430+ *stat = buf_rx[0];
431+
432+ return status;
433+}
434+
435+static int adf7242_wait_ready(struct adf7242_local *lp)
436+{
437+ u8 stat;
438+ int cnt = 0;
439+
440+ DBG(2, "%s :Enter\n", __func__);
441+
442+ do {
443+ adf7242_status(lp, &stat);
444+ cnt++;
445+ } while (!(stat & STAT_RC_READY) && (cnt < MAX_POLL_LOOPS));
446+
447+ DBG(2, "%s :Exit loops=%d\n", __func__, cnt);
448+
449+ return 0;
450+}
451+
452+static int adf7242_wait_status(struct adf7242_local *lp, int status)
453+{
454+ u8 stat;
455+ int cnt = 0;
456+
457+ DBG(2, "%s :Enter\n", __func__);
458+
459+ do {
460+ adf7242_status(lp, &stat);
461+ stat &= RC_STATUS_MASK;
462+ cnt++;
463+ } while ((stat != status) && (cnt < MAX_POLL_LOOPS));
464+
465+ DBG(2, "%s :Exit loops=%d\n", __func__, cnt);
466+
467+ return 0;
468+}
469+
470+static int adf7242_write_fbuf(struct adf7242_local *lp, u8 *data, u8 len)
471+{
472+ u8 *buf = lp->buf;
473+ int status;
474+ struct spi_message msg;
475+ struct spi_transfer xfer_head = {
476+ .len = 2,
477+ .tx_buf = buf,
478+
479+ };
480+ struct spi_transfer xfer_buf = {
481+ .len = len,
482+ .tx_buf = data,
483+ };
484+
485+ DBG(2, "%s :Enter\n", __func__);
486+ adf7242_wait_ready(lp);
487+
488+ buf[0] = CMD_SPI_PKT_WR;
489+ buf[1] = len + 2;
490+
491+ spi_message_init(&msg);
492+ spi_message_add_tail(&xfer_head, &msg);
493+ spi_message_add_tail(&xfer_buf, &msg);
494+
495+ mutex_lock(&lp->bmux);
496+ status = spi_sync(lp->spi, &msg);
497+ mutex_unlock(&lp->bmux);
498+
499+ DBG(2, "%s :Exit\n", __func__);
500+ return status;
501+}
502+
503+static int adf7242_read_fbuf(struct adf7242_local *lp,
504+ u8 *data, u8 *len, u8 *lqi)
505+{
506+ u8 *buf = lp->buf;
507+ int status;
508+ struct spi_message msg;
509+ struct spi_transfer xfer_head = {
510+ .len = 3,
511+ .tx_buf = buf,
512+ .rx_buf = buf,
513+
514+ };
515+ struct spi_transfer xfer_buf = {
516+ .len = *len,
517+ .rx_buf = data,
518+ };
519+
520+ DBG(2, "%s :Enter\n", __func__);
521+ adf7242_wait_ready(lp);
522+
523+ mutex_lock(&lp->bmux);
524+ buf[0] = CMD_SPI_PKT_RD;
525+ buf[1] = CMD_SPI_NOP;
526+ buf[2] = 0; /* PHR */
527+
528+ spi_message_init(&msg);
529+ spi_message_add_tail(&xfer_head, &msg);
530+ spi_message_add_tail(&xfer_buf, &msg);
531+
532+ status = spi_sync(lp->spi, &msg);
533+
534+ if (!status) {
535+ *lqi = data[buf[2] - 1];
536+ *len = buf[2]; /* PHR */
537+ }
538+
539+ mutex_unlock(&lp->bmux);
540+ DBG(2, "%s :Exit\n", __func__);
541+ return status;
542+}
543+
544+static int adf7242_read_reg(struct adf7242_local *lp,
545+ u16 addr, u8 *data)
546+{
547+ int status;
548+ struct spi_message msg;
549+ u8 buf_tx[4], buf_rx[4];
550+
551+ struct spi_transfer xfer = {
552+ .len = 4,
553+ .tx_buf = buf_tx,
554+ .rx_buf = buf_rx,
555+ };
556+
557+ DBG(2, "%s :Enter\n", __func__);
558+ adf7242_wait_ready(lp);
559+
560+ mutex_lock(&lp->bmux);
561+ buf_tx[0] = CMD_SPI_MEM_RD(addr);
562+ buf_tx[1] = addr;
563+ buf_tx[2] = CMD_SPI_NOP;
564+ buf_tx[3] = CMD_SPI_NOP;
565+
566+ spi_message_init(&msg);
567+ spi_message_add_tail(&xfer, &msg);
568+
569+ status = spi_sync(lp->spi, &msg);
570+ if (msg.status)
571+ status = msg.status;
572+
573+ if (!status)
574+ *data = buf_rx[3];
575+
576+ mutex_unlock(&lp->bmux);
577+ DBG(2, "%s :Exit\n", __func__);
578+
579+ return status;
580+}
581+
582+static int adf7242_write_reg(struct adf7242_local *lp,
583+ u16 addr, u8 data)
584+{
585+ int status;
586+ struct spi_message msg;
587+ u8 buf_tx[4];
588+
589+ struct spi_transfer xfer = {
590+ .len = 3,
591+ .tx_buf = buf_tx,
592+ };
593+ DBG(2, "%s :Enter\n", __func__);
594+ adf7242_wait_ready(lp);
595+
596+ buf_tx[0] = CMD_SPI_MEM_WR(addr);
597+ buf_tx[1] = addr;
598+ buf_tx[2] = data;
599+
600+ spi_message_init(&msg);
601+ spi_message_add_tail(&xfer, &msg);
602+
603+ mutex_lock(&lp->bmux);
604+ status = spi_sync(lp->spi, &msg);
605+ mutex_unlock(&lp->bmux);
606+ DBG(2, "%s :Exit\n", __func__);
607+
608+ return status;
609+}
610+
611+static int adf7242_cmd(struct adf7242_local *lp, u8 cmd)
612+{
613+ int status;
614+ struct spi_message msg;
615+ u8 buf_tx[1];
616+
617+ struct spi_transfer xfer = {
618+ .len = 1,
619+ .tx_buf = buf_tx,
620+ };
621+
622+ DBG(2, "%s :Enter CMD=0x%X\n", __func__, cmd);
623+ adf7242_wait_ready(lp);
624+
625+ buf_tx[0] = cmd;
626+ spi_message_init(&msg);
627+ spi_message_add_tail(&xfer, &msg);
628+
629+ mutex_lock(&lp->bmux);
630+ status = spi_sync(lp->spi, &msg);
631+ mutex_unlock(&lp->bmux);
632+ DBG(2, "%s :Exit\n", __func__);
633+
634+ return status;
635+}
636+
637+static int adf7242_upload_firmware(struct adf7242_local *lp,
638+ u8 *data, u16 len)
639+{
640+ int status, i, page = 0;
641+ struct spi_message msg;
642+ struct spi_transfer xfer_buf = {};
643+ u8 buf[2];
644+
645+ struct spi_transfer xfer_head = {
646+ .len = 2,
647+ .tx_buf = buf,
648+ };
649+
650+ buf[0] = CMD_SPI_PRAM_WR;
651+ buf[1] = 0;
652+
653+ for (i = len; i >= 0 ; i -= PRAM_PAGESIZE) {
654+ adf7242_write_reg(lp, REG_PRAMPG, page);
655+
656+ xfer_buf.len = i >= PRAM_PAGESIZE ? PRAM_PAGESIZE : i,
657+ xfer_buf.tx_buf = &data[page * PRAM_PAGESIZE],
658+
659+ spi_message_init(&msg);
660+ spi_message_add_tail(&xfer_head, &msg);
661+ spi_message_add_tail(&xfer_buf, &msg);
662+
663+ mutex_lock(&lp->bmux);
664+ status = spi_sync(lp->spi, &msg);
665+ mutex_unlock(&lp->bmux);
666+ page++;
667+ }
668+
669+ return status;
670+}
671+
672+static int adf7242_ed(struct ieee802154_dev *dev, u8 *level)
673+{
674+ struct adf7242_local *lp = dev->priv;
675+ int ret;
676+
677+ DBG(2, "%s :Enter\n", __func__);
678+#if 0
679+ adf7242_cmd(lp, CMD_RC_PHY_RDY);
680+ adf7242_cmd(lp, CMD_RC_CCA);
681+ adf7242_wait_status(lp, RC_STATUS_PHY_RDY);
682+#else
683+ udelay(128);
684+#endif
685+ ret = adf7242_read_reg(lp, REG_RRB, level);
686+ adf7242_cmd(lp, CMD_RC_RX);
687+ DBG(2, "%s :Exit\n", __func__);
688+
689+ return ret;
690+}
691+
692+static int adf7242_start(struct ieee802154_dev *dev)
693+{
694+ struct adf7242_local *lp = dev->priv;
695+ int ret;
696+
697+ DBG(2, "%s :Enter\n", __func__);
698+ ret = adf7242_cmd(lp, CMD_RC_RX);
699+ DBG(2, "%s :Exit\n", __func__);
700+
701+ return ret;
702+}
703+
704+static void adf7242_stop(struct ieee802154_dev *dev)
705+{
706+ struct adf7242_local *lp = dev->priv;
707+
708+ DBG(2, "%s :Enter\n", __func__);
709+ adf7242_cmd(lp, CMD_RC_PHY_RDY);
710+ DBG(2, "%s :Exit\n", __func__);
711+}
712+
713+static int adf7242_channel(struct ieee802154_dev *dev, int page, int channel)
714+{
715+ struct adf7242_local *lp = dev->priv;
716+ unsigned long freq;
717+
718+ DBG(2, "%s :Enter\n", __func__);
719+ DBG(1, "%s :Channel=%d\n", __func__, channel);
720+
721+ might_sleep();
722+
723+ BUG_ON(page != 0);
724+ BUG_ON(channel < 11);
725+ BUG_ON(channel > 26);
726+
727+ freq = (2405 + 5 * (channel - 11)) * 100;
728+
729+ adf7242_cmd(lp, CMD_RC_PHY_RDY);
730+
731+ adf7242_write_reg(lp, REG_CH_FREQ0, freq);
732+ adf7242_write_reg(lp, REG_CH_FREQ1, freq >> 8);
733+ adf7242_write_reg(lp, REG_CH_FREQ2, freq >> 16);
734+
735+ adf7242_cmd(lp, CMD_RC_RX);
736+
737+ dev->phy->current_channel = channel;
738+ DBG(2, "%s :Exit\n", __func__);
739+
740+ return 0;
741+}
742+
743+static int adf7242_set_hw_addr_filt(struct ieee802154_dev *dev,
744+ struct ieee802154_hw_addr_filt *filt,
745+ unsigned long changed)
746+{
747+ struct adf7242_local *lp = dev->priv;
748+ u8 reg;
749+
750+ DBG(2, "%s :Enter\n", __func__);
751+ DBG(1, "%s :Changed=0x%lX\n", __func__, changed);
752+
753+ might_sleep();
754+
755+ if (changed & IEEE802515_IEEEADDR_CHANGED) {
756+ adf7242_write_reg(lp, REG_IEEE_ADDR_0, filt->ieee_addr[7]);
757+ adf7242_write_reg(lp, REG_IEEE_ADDR_1, filt->ieee_addr[6]);
758+ adf7242_write_reg(lp, REG_IEEE_ADDR_2, filt->ieee_addr[5]);
759+ adf7242_write_reg(lp, REG_IEEE_ADDR_3, filt->ieee_addr[4]);
760+ adf7242_write_reg(lp, REG_IEEE_ADDR_4, filt->ieee_addr[3]);
761+ adf7242_write_reg(lp, REG_IEEE_ADDR_5, filt->ieee_addr[2]);
762+ adf7242_write_reg(lp, REG_IEEE_ADDR_6, filt->ieee_addr[1]);
763+ adf7242_write_reg(lp, REG_IEEE_ADDR_7, filt->ieee_addr[0]);
764+ }
765+
766+ if (changed & IEEE802515_SADDR_CHANGED) {
767+ adf7242_write_reg(lp, REG_SHORT_ADDR_0, filt->short_addr);
768+ adf7242_write_reg(lp, REG_SHORT_ADDR_1, filt->short_addr >> 8);
769+ }
770+
771+ if (changed & IEEE802515_PANID_CHANGED) {
772+ adf7242_write_reg(lp, REG_PAN_ID0, filt->pan_id);
773+ adf7242_write_reg(lp, REG_PAN_ID1, filt->pan_id >> 8);
774+ }
775+
776+ if (changed & IEEE802515_PANC_CHANGED) {
777+ adf7242_read_reg(lp, REG_AUTO_CFG, &reg);
778+ if (filt->pan_coord)
779+ reg |= IS_PANCOORD;
780+ else
781+ reg &= ~IS_PANCOORD;
782+ adf7242_write_reg(lp, REG_AUTO_CFG, reg);
783+ }
784+
785+ DBG(2, "%s :Exit\n", __func__);
786+ return 0;
787+}
788+
789+static int adf7242_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
790+{
791+ struct adf7242_local *lp = dev->priv;
792+ int ret;
793+ unsigned long flags;
794+
795+ DBG(2, "%s :Enter\n", __func__);
796+
797+ spin_lock_irqsave(&lp->lock, flags);
798+ BUG_ON(lp->is_tx);
799+ lp->is_tx = 1;
800+ spin_unlock_irqrestore(&lp->lock, flags);
801+
802+ ret = adf7242_write_fbuf(lp, skb->data, skb->len);
803+ if (ret)
804+ goto err_rx;
805+
806+ if (lp->mode & ADF_IEEE802154_AUTO_CSMA_CA) {
807+ ret = adf7242_cmd(lp, CMD_RC_PHY_RDY);
808+ ret |= adf7242_cmd(lp, CMD_RC_CSMACA);
809+ } else {
810+ ret = adf7242_cmd(lp, CMD_RC_TX);
811+ }
812+
813+ if (ret)
814+ goto err_rx;
815+
816+ ret = wait_for_completion_interruptible(&lp->tx_complete);
817+
818+ if (ret < 0)
819+ goto err_rx;
820+
821+ DBG(2, "%s :Exit\n", __func__);
822+ return ret;
823+
824+err_rx:
825+ spin_lock_irqsave(&lp->lock, flags);
826+ lp->is_tx = 0;
827+ spin_unlock_irqrestore(&lp->lock, flags);
828+ return ret;
829+}
830+
831+static int adf7242_rx(struct adf7242_local *lp)
832+{
833+ u8 len = 128;
834+ u8 lqi = 0;
835+ int ret;
836+ struct sk_buff *skb;
837+
838+ DBG(2, "%s :Enter\n", __func__);
839+
840+ skb = alloc_skb(len, GFP_KERNEL);
841+ if (!skb)
842+ return -ENOMEM;
843+
844+ ret = adf7242_read_fbuf(lp, skb_put(skb, len), &len, &lqi);
845+
846+ adf7242_cmd(lp, CMD_RC_RX);
847+
848+ skb_trim(skb, len - 2); /* We do not put RSSI/LQI or CRC into the frame */
849+
850+ if (len < 2) {
851+ kfree_skb(skb);
852+ return -EINVAL;
853+ }
854+
855+ ieee802154_rx_irqsafe(lp->dev, skb, lqi);
856+
857+ DBG(1, "%s: %d %d %x\n", __func__, ret, len, lqi);
858+ DBG(2, "%s :Exit\n", __func__);
859+
860+ return 0;
861+}
862+
863+static struct ieee802154_ops adf7242_ops = {
864+ .owner = THIS_MODULE,
865+ .xmit = adf7242_xmit,
866+ .ed = adf7242_ed,
867+ .set_channel = adf7242_channel,
868+ .set_hw_addr_filt = adf7242_set_hw_addr_filt,
869+ .start = adf7242_start,
870+ .stop = adf7242_stop,
871+};
872+
873+static void adf7242_irqwork(struct work_struct *work)
874+{
875+ struct adf7242_local *lp =
876+ container_of(work, struct adf7242_local, irqwork);
877+ u8 irq1, auto_stat = 0, stat = 0;
878+ int ret;
879+ unsigned long flags;
880+
881+ DBG(2, "%s :Enter\n", __func__);
882+
883+ ret = adf7242_read_reg(lp, REG_IRQ1_SRC1, &irq1);
884+
885+ DBG(1, "%s IRQ1 = %X:\n%s%s%s%s%s%s%s%s\n", __func__, irq1,
886+ irq1 & IRQ_CCA_COMPLETE ? "IRQ_CCA_COMPLETE\n" : "",
887+ irq1 & IRQ_SFD_RX ? "IRQ_SFD_RX\n" : "",
888+ irq1 & IRQ_SFD_TX ? "IRQ_SFD_TX\n" : "",
889+ irq1 & IRQ_RX_PKT_RCVD ? "IRQ_RX_PKT_RCVD\n" : "",
890+ irq1 & IRQ_TX_PKT_SENT ? "IRQ_TX_PKT_SENT\n" : "",
891+ irq1 & IRQ_CSMA_CA ? "IRQ_CSMA_CA\n" : "",
892+ irq1 & IRQ_FRAME_VALID ? "IRQ_FRAME_VALID\n" : "",
893+ irq1 & IRQ_ADDRESS_VALID ? "IRQ_ADDRESS_VALID\n" : "");
894+
895+ adf7242_status(lp, &stat);
896+
897+ DBG(1, "%s STATUS = %X:\n%s\n%s%s%s%s%s\n", __func__, stat,
898+ stat & STAT_RC_READY ? "RC_READY" : "RC_BUSY",
899+ (stat & 0xf) == RC_STATUS_IDLE ? "RC_STATUS_IDLE" : "",
900+ (stat & 0xf) == RC_STATUS_MEAS ? "RC_STATUS_MEAS" : "",
901+ (stat & 0xf) == RC_STATUS_PHY_RDY ? "RC_STATUS_PHY_RDY" : "",
902+ (stat & 0xf) == RC_STATUS_RX ? "RC_STATUS_RX" : "",
903+ (stat & 0xf) == RC_STATUS_TX ? "RC_STATUS_TX" : "");
904+
905+ adf7242_write_reg(lp, REG_IRQ1_SRC1, irq1);
906+
907+ if (irq1 & IRQ_RX_PKT_RCVD) {
908+
909+ /* Wait until ACK is processed */
910+ if ((lp->mode & ADF_IEEE802154_HW_AACK) &&
911+ ((stat & RC_STATUS_MASK) != RC_STATUS_PHY_RDY))
912+ adf7242_wait_status(lp, RC_STATUS_PHY_RDY);
913+
914+ adf7242_rx(lp);
915+ }
916+
917+ if (irq1 & lp->tx_irq) {
918+
919+ if (lp->mode & ADF_IEEE802154_AUTO_CSMA_CA) {
920+ adf7242_read_reg(lp, REG_AUTO_STATUS, &auto_stat);
921+ auto_stat &= AUTO_STATUS_MASK;
922+
923+ DBG(1, "%s AUTO_STATUS = %X:\n%s%s%s%s\n",
924+ __func__, auto_stat,
925+ auto_stat == SUCCESS ? "SUCCESS" : "",
926+ auto_stat == SUCCESS_DATPEND ? "SUCCESS_DATPEND" : "",
927+ auto_stat == FAILURE_CSMACA ? "FAILURE_CSMACA" : "",
928+ auto_stat == FAILURE_NOACK ? "FAILURE_NOACK" : "");
929+
930+ /* save CSMA-CA completion status */
931+ lp->tx_stat = auto_stat;
932+ }
933+ spin_lock_irqsave(&lp->lock, flags);
934+ if (lp->is_tx) {
935+ lp->is_tx = 0;
936+ complete(&lp->tx_complete);
937+ }
938+ spin_unlock_irqrestore(&lp->lock, flags);
939+
940+ /* in case we just received a frame we are already in PHY_RX */
941+
942+ if (!(irq1 & IRQ_RX_PKT_RCVD))
943+ adf7242_cmd(lp, CMD_RC_RX);
944+ }
945+
946+ spin_lock_irqsave(&lp->lock, flags);
947+ if (lp->irq_disabled) {
948+ lp->irq_disabled = 0;
949+ enable_irq(lp->spi->irq);
950+ }
951+ spin_unlock_irqrestore(&lp->lock, flags);
952+
953+ DBG(2, "%s :Exit\n", __func__);
954+}
955+
956+static irqreturn_t adf7242_isr(int irq, void *data)
957+{
958+ struct adf7242_local *lp = data;
959+
960+ DBG(2, "%s :Enter\n", __func__);
961+
962+ spin_lock(&lp->lock);
963+ if (!lp->irq_disabled) {
964+ disable_irq_nosync(irq);
965+ lp->irq_disabled = 1;
966+ }
967+ spin_unlock(&lp->lock);
968+
969+ schedule_work(&lp->irqwork);
970+
971+ DBG(2, "%s :Exit\n", __func__);
972+
973+ return IRQ_HANDLED;
974+}
975+
976+
977+static int adf7242_hw_init(struct adf7242_local *lp)
978+{
979+ int ret;
980+ const struct firmware *fw;
981+
982+ DBG(2, "%s :Enter\n", __func__);
983+
984+ adf7242_cmd(lp, CMD_RC_IDLE);
985+
986+ if (lp->mode) {
987+ /* get ADF7242 addon firmware
988+ * build this driver as module
989+ * and place under /lib/firmware/adf7242_firmware.bin
990+ */
991+ ret = request_firmware(&fw, FIRMWARE, &lp->spi->dev);
992+ if (ret) {
993+ dev_err(&lp->spi->dev,
994+ "request_firmware() failed with %i\n", ret);
995+ return ret;
996+ }
997+
998+ adf7242_upload_firmware(lp, (u8 *) fw->data, fw->size);
999+ release_firmware(fw);
1000+
1001+ adf7242_write_reg(lp, REG_FFILT_CFG,
1002+ ACCEPT_BEACON_FRAMES |
1003+ ACCEPT_DATA_FRAMES |
1004+ ACCEPT_ACK_FRAMES |
1005+ ACCEPT_MACCMD_FRAMES |
1006+ (lp->mode & ADF_IEEE802154_PROMISCUOUS_MODE ?
1007+ ACCEPT_ALL_ADDRESS : 0) |
1008+ ACCEPT_RESERVED_FRAMES);
1009+
1010+ adf7242_write_reg(lp, REG_AUTO_TX1,
1011+ MAX_FRAME_RETRIES(lp->pdata->max_frame_retries) |
1012+ MAX_CCA_RETRIES(lp->pdata->max_cca_retries));
1013+
1014+ adf7242_write_reg(lp, REG_AUTO_TX2,
1015+ CSMA_MAX_BE(lp->pdata->max_csma_be) |
1016+ CSMA_MIN_BE(lp->pdata->min_csma_be));
1017+
1018+ adf7242_write_reg(lp, REG_AUTO_CFG,
1019+ (lp->mode & ADF_IEEE802154_HW_AACK ?
1020+ RX_AUTO_ACK_EN : 0));
1021+ }
1022+
1023+ adf7242_write_reg(lp, REG_PKT_CFG, lp->mode ? ADDON_EN : 0);
1024+
1025+ adf7242_write_reg(lp, REG_EXTPA_MSC, 0xF1);
1026+ adf7242_write_reg(lp, REG_RXFE_CFG, 0x1D);
1027+ adf7242_write_reg(lp, REG_IRQ1_EN0, 0);
1028+
1029+ adf7242_write_reg(lp, REG_IRQ1_EN1, IRQ_RX_PKT_RCVD | lp->tx_irq);
1030+
1031+ adf7242_write_reg(lp, REG_IRQ1_SRC1, 0xFF);
1032+ adf7242_write_reg(lp, REG_IRQ1_SRC0, 0xFF);
1033+
1034+ adf7242_cmd(lp, CMD_RC_PHY_RDY);
1035+
1036+ DBG(2, "%s :Exit\n", __func__);
1037+
1038+ return 0;
1039+}
1040+
1041+static int adf7242_suspend(struct spi_device *spi, pm_message_t message)
1042+{
1043+ return 0;
1044+}
1045+
1046+static int adf7242_resume(struct spi_device *spi)
1047+{
1048+ return 0;
1049+}
1050+
1051+static ssize_t adf7242_show(struct device *dev,
1052+ struct device_attribute *devattr,
1053+ char *buf)
1054+{
1055+ struct adf7242_local *lp = dev_get_drvdata(dev);
1056+ u8 stat;
1057+
1058+ adf7242_status(lp, &stat);
1059+
1060+ return sprintf(buf, "STATUS = %X:\n%s\n%s%s%s%s%s\n", stat,
1061+ stat & STAT_RC_READY ? "RC_READY" : "RC_BUSY",
1062+ (stat & 0xf) == RC_STATUS_IDLE ? "RC_STATUS_IDLE" : "",
1063+ (stat & 0xf) == RC_STATUS_MEAS ? "RC_STATUS_MEAS" : "",
1064+ (stat & 0xf) == RC_STATUS_PHY_RDY ? "RC_STATUS_PHY_RDY" : "",
1065+ (stat & 0xf) == RC_STATUS_RX ? "RC_STATUS_RX" : "",
1066+ (stat & 0xf) == RC_STATUS_TX ? "RC_STATUS_TX" : "");
1067+
1068+}
1069+static DEVICE_ATTR(status, 0664, adf7242_show, NULL);
1070+
1071+static struct attribute *adf7242_attributes[] = {
1072+ &dev_attr_status.attr,
1073+ NULL
1074+};
1075+
1076+static const struct attribute_group adf7242_attr_group = {
1077+ .attrs = adf7242_attributes,
1078+};
1079+
1080+static int __devinit adf7242_probe(struct spi_device *spi)
1081+{
1082+ struct adf7242_platform_data *pdata = spi->dev.platform_data;
1083+ struct ieee802154_dev *dev;
1084+ struct adf7242_local *lp;
1085+ int ret;
1086+
1087+ if (!spi->irq) {
1088+ dev_err(&spi->dev, "no IRQ specified\n");
1089+ return -EINVAL;
1090+ }
1091+
1092+ if (!pdata) {
1093+ dev_err(&spi->dev, "no platform data?\n");
1094+ return -ENODEV;
1095+ }
1096+
1097+ dev = ieee802154_alloc_device(sizeof(*lp), &adf7242_ops);
1098+ if (!dev)
1099+ return -ENOMEM;
1100+
1101+ lp = dev->priv;
1102+ lp->dev = dev;
1103+ lp->spi = spi;
1104+ lp->pdata = pdata;
1105+ lp->mode = pdata->mode;
1106+
1107+ dev->priv = lp;
1108+ dev->parent = &spi->dev;
1109+ dev->extra_tx_headroom = 0;
1110+ /* We do support only 2.4 Ghz */
1111+
1112+ dev->phy->channels_supported[0] = 0x7FFF800;
1113+
1114+ if (!lp->mode) {
1115+ adf7242_ops.set_hw_addr_filt = NULL;
1116+ lp->tx_irq = IRQ_TX_PKT_SENT;
1117+ } else {
1118+ if ((lp->mode & ADF_IEEE802154_PROMISCUOUS_MODE) &&
1119+ (lp->mode & ADF_IEEE802154_HW_AACK))
1120+ lp->mode &= ~ADF_IEEE802154_HW_AACK;
1121+
1122+ if (lp->mode & ADF_IEEE802154_AUTO_CSMA_CA)
1123+ lp->tx_irq = IRQ_CSMA_CA;
1124+ else
1125+ lp->tx_irq = IRQ_TX_PKT_SENT;
1126+ }
1127+
1128+ dev->flags = IEEE802154_HW_OMIT_CKSUM |
1129+ (lp->mode & ADF_IEEE802154_HW_AACK ?
1130+ IEEE802154_HW_AACK : 0);
1131+
1132+ mutex_init(&lp->bmux);
1133+ INIT_WORK(&lp->irqwork, adf7242_irqwork);
1134+ spin_lock_init(&lp->lock);
1135+ init_completion(&lp->tx_complete);
1136+
1137+ spi_set_drvdata(spi, lp);
1138+
1139+ ret = adf7242_hw_init(lp);
1140+ if (ret)
1141+ goto err_hw_init;
1142+
1143+ ret = request_irq(spi->irq, adf7242_isr, IRQF_TRIGGER_HIGH,
1144+ dev_name(&spi->dev), lp);
1145+ if (ret)
1146+ goto err_hw_init;
1147+
1148+ ret = ieee802154_register_device(lp->dev);
1149+ if (ret)
1150+ goto err_irq;
1151+
1152+ dev_set_drvdata(&spi->dev, lp);
1153+
1154+ ret = sysfs_create_group(&spi->dev.kobj, &adf7242_attr_group);
1155+ if (ret)
1156+ goto out;
1157+
1158+ dev_info(&spi->dev, "mac802154 IRQ-%d registered\n", spi->irq);
1159+
1160+ return ret;
1161+
1162+out:
1163+ ieee802154_unregister_device(lp->dev);
1164+err_irq:
1165+ free_irq(spi->irq, lp);
1166+ flush_work(&lp->irqwork);
1167+err_hw_init:
1168+ spi_set_drvdata(spi, NULL);
1169+ mutex_destroy(&lp->bmux);
1170+ ieee802154_free_device(lp->dev);
1171+ return ret;
1172+}
1173+
1174+static int __devexit adf7242_remove(struct spi_device *spi)
1175+{
1176+ struct adf7242_local *lp = spi_get_drvdata(spi);
1177+
1178+ ieee802154_unregister_device(lp->dev);
1179+ free_irq(spi->irq, lp);
1180+ flush_work(&lp->irqwork);
1181+ spi_set_drvdata(spi, NULL);
1182+ mutex_destroy(&lp->bmux);
1183+ ieee802154_free_device(lp->dev);
1184+
1185+ return 0;
1186+}
1187+
1188+static struct spi_driver adf7242_driver = {
1189+ .driver = {
1190+ .name = "adf7242",
1191+ .owner = THIS_MODULE,
1192+ },
1193+ .probe = adf7242_probe,
1194+ .remove = __devexit_p(adf7242_remove),
1195+ .suspend = adf7242_suspend,
1196+ .resume = adf7242_resume,
1197+};
1198+
1199+static int __init adf7242_init(void)
1200+{
1201+ return spi_register_driver(&adf7242_driver);
1202+}
1203+module_init(adf7242_init);
1204+
1205+static void __exit adf7242_exit(void)
1206+{
1207+ spi_unregister_driver(&adf7242_driver);
1208+}
1209+module_exit(adf7242_exit);
1210+
1211+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
1212+MODULE_DESCRIPTION("ADF7242 Transceiver Driver");
1213+MODULE_LICENSE("GPL");
1214diff --git a/drivers/ieee802154/at86rf230.c b/drivers/ieee802154/at86rf230.c
1215new file mode 100644
1216index 0000000..8da82cf
1217--- /dev/null
1218@@ -0,0 +1,872 @@
1219+/*
1220+ * AT86RF230/RF231 driver
1221+ *
1222+ * Copyright (C) 2009 Siemens AG
1223+ *
1224+ * This program is free software; you can redistribute it and/or modify
1225+ * it under the terms of the GNU General Public License version 2
1226+ * as published by the Free Software Foundation.
1227+ *
1228+ * This program is distributed in the hope that it will be useful,
1229+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1230+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1231+ * GNU General Public License for more details.
1232+ *
1233+ * You should have received a copy of the GNU General Public License along
1234+ * with this program; if not, write to the Free Software Foundation, Inc.,
1235+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1236+ *
1237+ * Written by:
1238+ * Dmitry Eremin-Solenikov <dmitry.baryshkov@siemens.com>
1239+ */
1240+#include <linux/kernel.h>
1241+#include <linux/module.h>
1242+#include <linux/interrupt.h>
1243+#include <linux/gpio.h>
1244+#include <linux/delay.h>
1245+#include <linux/mutex.h>
1246+#include <linux/workqueue.h>
1247+#include <linux/spi/spi.h>
1248+#include <linux/spi/at86rf230.h>
1249+
1250+#ifdef CONFIG_OF
1251+#include <linux/of.h>
1252+#include <linux/of_gpio.h>
1253+#endif
1254+
1255+#include <net/mac802154.h>
1256+#include <net/wpan-phy.h>
1257+
1258+#include "at86rf230.h"
1259+
1260+
1261+struct at86rf230_local {
1262+ struct spi_device *spi;
1263+ int rstn, slp_tr, dig2;
1264+ void (*reset)(void *reset_data);
1265+ void *reset_data;
1266+
1267+ u8 part;
1268+ u8 vers;
1269+
1270+ u8 buf[2];
1271+ struct mutex bmux;
1272+
1273+ struct work_struct irqwork;
1274+ struct completion tx_complete;
1275+
1276+ struct ieee802154_dev *dev;
1277+
1278+ volatile unsigned is_tx:1;
1279+};
1280+
1281+
1282+static int
1283+__at86rf230_write(struct at86rf230_local *lp, u8 addr, u8 data)
1284+{
1285+ u8 *buf = lp->buf;
1286+ int status;
1287+ struct spi_message msg;
1288+ struct spi_transfer xfer = {
1289+ .len = 2,
1290+ .tx_buf = buf,
1291+ };
1292+
1293+ buf[0] = (addr & CMD_REG_MASK) | CMD_REG | CMD_WRITE;
1294+ buf[1] = data;
1295+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
1296+ dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
1297+ spi_message_init(&msg);
1298+ spi_message_add_tail(&xfer, &msg);
1299+
1300+ status = spi_sync(lp->spi, &msg);
1301+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
1302+ if (msg.status)
1303+ status = msg.status;
1304+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
1305+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
1306+ dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
1307+
1308+ return status;
1309+}
1310+
1311+static int
1312+__at86rf230_read_subreg(struct at86rf230_local *lp,
1313+ u8 addr, u8 mask, int shift, u8 *data)
1314+{
1315+ u8 *buf = lp->buf;
1316+ int status;
1317+ struct spi_message msg;
1318+ struct spi_transfer xfer = {
1319+ .len = 2,
1320+ .tx_buf = buf,
1321+ .rx_buf = buf,
1322+ };
1323+
1324+ buf[0] = (addr & CMD_REG_MASK) | CMD_REG;
1325+ buf[1] = 0xff;
1326+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
1327+ spi_message_init(&msg);
1328+ spi_message_add_tail(&xfer, &msg);
1329+
1330+ status = spi_sync(lp->spi, &msg);
1331+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
1332+ if (msg.status)
1333+ status = msg.status;
1334+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
1335+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
1336+ dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
1337+
1338+ if (status == 0)
1339+ *data = buf[1];
1340+
1341+ return status;
1342+}
1343+
1344+static int
1345+at86rf230_read_subreg(struct at86rf230_local *lp,
1346+ u8 addr, u8 mask, int shift, u8 *data)
1347+{
1348+ int status;
1349+
1350+ mutex_lock(&lp->bmux);
1351+ status = __at86rf230_read_subreg(lp, addr, mask, shift, data);
1352+ mutex_unlock(&lp->bmux);
1353+
1354+ return status;
1355+}
1356+
1357+static int
1358+at86rf230_write_subreg(struct at86rf230_local *lp,
1359+ u8 addr, u8 mask, int shift, u8 data)
1360+{
1361+ int status;
1362+ u8 val;
1363+
1364+ mutex_lock(&lp->bmux);
1365+ status = __at86rf230_read_subreg(lp, addr, 0xff, 0, &val);
1366+ if (status)
1367+ goto out;
1368+
1369+ val &= ~mask;
1370+ val |= (data << shift) & mask;
1371+
1372+ status = __at86rf230_write(lp, addr, val);
1373+out:
1374+ mutex_unlock(&lp->bmux);
1375+
1376+ return status;
1377+}
1378+
1379+static int
1380+at86rf230_write_fbuf(struct at86rf230_local *lp, u8 *data, u8 len)
1381+{
1382+ u8 *buf = lp->buf;
1383+ int status;
1384+ struct spi_message msg;
1385+ struct spi_transfer xfer_head = {
1386+ .len = 2,
1387+ .tx_buf = buf,
1388+
1389+ };
1390+ struct spi_transfer xfer_buf = {
1391+ .len = len,
1392+ .tx_buf = data,
1393+ };
1394+
1395+ mutex_lock(&lp->bmux);
1396+ buf[0] = CMD_WRITE | CMD_FB;
1397+ buf[1] = len + 2; /* 2 bytes for CRC that isn't written */
1398+
1399+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
1400+ dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
1401+
1402+ spi_message_init(&msg);
1403+ spi_message_add_tail(&xfer_head, &msg);
1404+ spi_message_add_tail(&xfer_buf, &msg);
1405+
1406+ status = spi_sync(lp->spi, &msg);
1407+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
1408+ if (msg.status)
1409+ status = msg.status;
1410+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
1411+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
1412+ dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
1413+
1414+ mutex_unlock(&lp->bmux);
1415+ return status;
1416+}
1417+
1418+static int
1419+at86rf230_read_fbuf(struct at86rf230_local *lp, u8 *data, u8 *len, u8 *lqi)
1420+{
1421+ u8 *buf = lp->buf;
1422+ int status;
1423+ struct spi_message msg;
1424+ struct spi_transfer xfer_head = {
1425+ .len = 2,
1426+ .tx_buf = buf,
1427+ .rx_buf = buf,
1428+ };
1429+ struct spi_transfer xfer_head1 = {
1430+ .len = 2,
1431+ .tx_buf = buf,
1432+ .rx_buf = buf,
1433+ };
1434+ struct spi_transfer xfer_buf = {
1435+ .len = 0,
1436+ .rx_buf = data,
1437+ };
1438+
1439+ mutex_lock(&lp->bmux);
1440+
1441+ buf[0] = CMD_FB;
1442+ buf[1] = 0x00;
1443+
1444+ spi_message_init(&msg);
1445+ spi_message_add_tail(&xfer_head, &msg);
1446+
1447+ status = spi_sync(lp->spi, &msg);
1448+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
1449+
1450+ if (buf[1] & 0x80) {
1451+ dev_err(&lp->spi->dev, "invalid PHR 0x%02x\n", buf[1]);
1452+ status = -EIO;
1453+ goto fail;
1454+ }
1455+ if (buf[1] >= *len) {
1456+ dev_err(&lp->spi->dev, "PHR 0x%02x >= buffer %d bytes\n",
1457+ buf[1], *len);
1458+ status = -EMSGSIZE;
1459+ goto fail;
1460+ }
1461+ xfer_buf.len = *(buf + 1) + 1;
1462+ *len = buf[1];
1463+
1464+ buf[0] = CMD_FB;
1465+ buf[1] = 0x00;
1466+
1467+ spi_message_init(&msg);
1468+ spi_message_add_tail(&xfer_head1, &msg);
1469+ spi_message_add_tail(&xfer_buf, &msg);
1470+
1471+ status = spi_sync(lp->spi, &msg);
1472+
1473+ if (msg.status)
1474+ status = msg.status;
1475+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
1476+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
1477+ dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
1478+
1479+ if (!status) {
1480+ if (lqi && *len > lp->buf[1])
1481+ *lqi = data[lp->buf[1]];
1482+ }
1483+
1484+fail:
1485+ mutex_unlock(&lp->bmux);
1486+
1487+ return status;
1488+}
1489+
1490+static int
1491+at86rf230_ed(struct ieee802154_dev *dev, u8 *level)
1492+{
1493+ pr_debug("%s\n", __func__);
1494+ might_sleep();
1495+ BUG_ON(!level);
1496+ *level = 0xbe;
1497+ return 0;
1498+}
1499+
1500+static int
1501+at86rf230_state(struct ieee802154_dev *dev, int state)
1502+{
1503+ struct at86rf230_local *lp = dev->priv;
1504+ int rc;
1505+ u8 val;
1506+ u8 desired_status;
1507+
1508+ pr_debug("%s %d\n", __func__/*, priv->cur_state*/, state);
1509+ might_sleep();
1510+
1511+ if (state == STATE_FORCE_TX_ON)
1512+ desired_status = STATE_TX_ON;
1513+ else if (state == STATE_FORCE_TRX_OFF)
1514+ desired_status = STATE_TRX_OFF;
1515+ else
1516+ desired_status = state;
1517+
1518+ do {
1519+ rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &val);
1520+ if (rc)
1521+ goto err;
1522+ pr_debug("%s val1 = %x\n", __func__, val);
1523+ } while (val == STATE_TRANSITION_IN_PROGRESS);
1524+
1525+ if (val == desired_status)
1526+ return 0;
1527+
1528+ /* state is equal to phy states */
1529+ rc = at86rf230_write_subreg(lp, SR_TRX_CMD, state);
1530+ if (rc)
1531+ goto err;
1532+
1533+ do {
1534+ rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &val);
1535+ if (rc)
1536+ goto err;
1537+ pr_debug("%s val2 = %x\n", __func__, val);
1538+ } while (val == STATE_TRANSITION_IN_PROGRESS);
1539+
1540+
1541+ if (val == desired_status)
1542+ return 0;
1543+ if (state == STATE_RX_ON && val == STATE_BUSY_RX)
1544+ return 0;
1545+
1546+ pr_err("%s unexpected state change: %d, asked for %d\n", __func__,
1547+ val, state);
1548+ return -EBUSY;
1549+
1550+err:
1551+ pr_err("%s error: %d\n", __func__, rc);
1552+ return rc;
1553+}
1554+
1555+static int
1556+at86rf230_start(struct ieee802154_dev *dev)
1557+{
1558+ struct at86rf230_local *lp = dev->priv;
1559+ u8 rc;
1560+
1561+ rc = at86rf230_write_subreg(lp, SR_RX_SAFE_MODE, 1);
1562+ if (rc)
1563+ return rc;
1564+ return at86rf230_state(dev, STATE_RX_ON);
1565+}
1566+
1567+static void
1568+at86rf230_stop(struct ieee802154_dev *dev)
1569+{
1570+ at86rf230_state(dev, STATE_FORCE_TRX_OFF);
1571+}
1572+
1573+static int
1574+at86rf230_channel(struct ieee802154_dev *dev, int page, int channel)
1575+{
1576+ struct at86rf230_local *lp = dev->priv;
1577+ int rc;
1578+
1579+ pr_debug("%s %d\n", __func__, channel);
1580+ might_sleep();
1581+
1582+ BUG_ON(page != 0);
1583+ BUG_ON(channel < 11);
1584+ BUG_ON(channel > 26);
1585+
1586+ rc = at86rf230_write_subreg(lp, SR_CHANNEL, channel);
1587+ msleep(1); /* Wait for PLL */
1588+ dev->phy->current_channel = channel;
1589+
1590+ return 0;
1591+}
1592+
1593+/* FIXME:
1594+ * This function currently is a mess. It uses flush_work to guard
1595+ * against concurrent irqwork, etc. One has to use mutexes intead. */
1596+static int
1597+at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
1598+{
1599+ struct at86rf230_local *lp = dev->priv;
1600+ int rc;
1601+
1602+ pr_debug("%s\n", __func__);
1603+
1604+ might_sleep();
1605+
1606+ BUG_ON(lp->is_tx);
1607+ INIT_COMPLETION(lp->tx_complete);
1608+
1609+ rc = at86rf230_state(dev, STATE_FORCE_TX_ON);
1610+ if (rc)
1611+ goto err;
1612+
1613+ synchronize_irq(lp->spi->irq);
1614+ flush_work(&lp->irqwork);
1615+
1616+ lp->is_tx = 1;
1617+
1618+ rc = at86rf230_write_fbuf(lp, skb->data, skb->len);
1619+ if (rc)
1620+ goto err_rx;
1621+
1622+ if (gpio_is_valid(lp->slp_tr)) {
1623+ gpio_set_value(lp->slp_tr, 1);
1624+ udelay(80); /* > 62.5 */
1625+ gpio_set_value(lp->slp_tr, 0);
1626+ } else {
1627+ rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_BUSY_TX);
1628+ if (rc)
1629+ goto err_rx;
1630+ }
1631+
1632+ /* FIXME: the logic is really strange here. Datasheet doesn't
1633+ * provide us enough info about behaviour in such cases.
1634+ * Basically either we were interrupted here, or we have lost
1635+ * the interrupt. Most probably this should be changed to
1636+ * wait_for_completion_timeout() and handle it's results
1637+ */
1638+ rc = wait_for_completion_interruptible(&lp->tx_complete);
1639+ if (rc < 0)
1640+ goto err_state;
1641+
1642+ lp->is_tx = 0;
1643+
1644+ rc = at86rf230_start(dev);
1645+ return rc;
1646+
1647+err_state:
1648+ /* try to recover from possibly problematic state */
1649+ at86rf230_state(dev, STATE_FORCE_TX_ON);
1650+ synchronize_irq(lp->spi->irq);
1651+ flush_work(&lp->irqwork);
1652+ lp->is_tx = 0;
1653+err_rx:
1654+ at86rf230_start(dev);
1655+err:
1656+ if (rc)
1657+ pr_err("%s error: %d\n", __func__, rc);
1658+
1659+ return rc;
1660+}
1661+
1662+static int at86rf230_rx(struct at86rf230_local *lp)
1663+{
1664+ u8 len = 128, lqi = 0;
1665+ int rc, rc2;
1666+ struct sk_buff *skb;
1667+
1668+ skb = alloc_skb(len, GFP_KERNEL);
1669+ if (!skb)
1670+ return -ENOMEM;
1671+
1672+ /* FIXME: process return status */
1673+ rc = at86rf230_write_subreg(lp, SR_RX_PDT_DIS, 1);
1674+ rc2 = at86rf230_read_fbuf(lp, skb_put(skb, len), &len, &lqi);
1675+ rc = at86rf230_write_subreg(lp, SR_RX_SAFE_MODE, 1);
1676+ rc = at86rf230_write_subreg(lp, SR_RX_PDT_DIS, 0);
1677+ if (rc2 < 0)
1678+ goto err_fbuf;
1679+
1680+ if (len < 2)
1681+ goto err;
1682+
1683+ skb_trim(skb, len-2); /* We do not put CRC into the frame */
1684+
1685+
1686+ ieee802154_rx_irqsafe(lp->dev, skb, lqi);
1687+
1688+ dev_dbg(&lp->spi->dev, "READ_FBUF: %d %d %x\n", rc, len, lqi);
1689+
1690+ return 0;
1691+err:
1692+ pr_debug("%s: received frame is too small\n", __func__);
1693+
1694+err_fbuf:
1695+ kfree_skb(skb);
1696+ return -EINVAL;
1697+}
1698+
1699+static struct ieee802154_ops at86rf230_ops = {
1700+ .owner = THIS_MODULE,
1701+ .xmit = at86rf230_xmit,
1702+ .ed = at86rf230_ed,
1703+ .set_channel = at86rf230_channel,
1704+ .start = at86rf230_start,
1705+ .stop = at86rf230_stop,
1706+};
1707+
1708+static void at86rf230_irqwork(struct work_struct *work)
1709+{
1710+ struct at86rf230_local *lp =
1711+ container_of(work, struct at86rf230_local, irqwork);
1712+ u8 status = 0, val;
1713+ int rc;
1714+
1715+ dev_dbg(&lp->spi->dev, "IRQ Worker\n");
1716+
1717+ do {
1718+ rc = at86rf230_read_subreg(lp, RG_IRQ_STATUS, 0xff, 0, &val);
1719+ status |= val;
1720+ dev_dbg(&lp->spi->dev, "IRQ Status: %02x\n", status);
1721+
1722+ status &= ~IRQ_PLL_LOCK; /* ignore */
1723+ status &= ~IRQ_RX_START; /* ignore */
1724+ status &= ~IRQ_AMI; /* ignore */
1725+ status &= ~IRQ_TRX_UR; /* FIXME: possibly handle ???*/
1726+
1727+ if (status & IRQ_TRX_END) {
1728+ status &= ~IRQ_TRX_END;
1729+ if (lp->is_tx)
1730+ complete(&lp->tx_complete);
1731+ else
1732+ at86rf230_rx(lp);
1733+ }
1734+
1735+ } while (status != 0);
1736+
1737+ enable_irq(lp->spi->irq);
1738+}
1739+
1740+static irqreturn_t at86rf230_isr(int irq, void *data)
1741+{
1742+ struct at86rf230_local *lp = data;
1743+
1744+ dev_dbg(&lp->spi->dev, "IRQ!\n");
1745+
1746+ disable_irq_nosync(irq);
1747+ schedule_work(&lp->irqwork);
1748+
1749+ return IRQ_HANDLED;
1750+}
1751+
1752+
1753+static int at86rf230_hw_init(struct at86rf230_local *lp)
1754+{
1755+ u8 status;
1756+ int rc;
1757+
1758+ rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &status);
1759+ if (rc)
1760+ return rc;
1761+
1762+ dev_info(&lp->spi->dev, "Status: %02x\n", status);
1763+ if (status == STATE_P_ON) {
1764+ rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_TRX_OFF);
1765+ if (rc)
1766+ return rc;
1767+ msleep(1);
1768+ rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &status);
1769+ if (rc)
1770+ return rc;
1771+ dev_info(&lp->spi->dev, "Status: %02x\n", status);
1772+ }
1773+
1774+ rc = at86rf230_write_subreg(lp, SR_IRQ_MASK,
1775+ /*IRQ_TRX_UR | IRQ_CCA_ED | IRQ_TRX_END | IRQ_PLL_UNL | IRQ_PLL_LOCK*/ 0xff);
1776+ if (rc)
1777+ return rc;
1778+
1779+ /* CLKM changes are applied immediately */
1780+ rc = at86rf230_write_subreg(lp, SR_CLKM_SHA_SEL, 0x00);
1781+ if (rc)
1782+ return rc;
1783+
1784+ /* Turn CLKM Off */
1785+ rc = at86rf230_write_subreg(lp, SR_CLKM_CTRL, 0x00);
1786+ if (rc)
1787+ return rc;
1788+
1789+ msleep(100);
1790+
1791+ rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_TX_ON);
1792+ if (rc)
1793+ return rc;
1794+ msleep(1);
1795+
1796+ rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &status);
1797+ if (rc)
1798+ return rc;
1799+ dev_info(&lp->spi->dev, "Status: %02x\n", status);
1800+
1801+ rc = at86rf230_read_subreg(lp, SR_DVDD_OK, &status);
1802+ if (rc)
1803+ return rc;
1804+ if (!status) {
1805+ dev_err(&lp->spi->dev, "DVDD error\n");
1806+ return -EINVAL;
1807+ }
1808+
1809+ rc = at86rf230_read_subreg(lp, SR_AVDD_OK, &status);
1810+ if (rc)
1811+ return rc;
1812+ if (!status) {
1813+ dev_err(&lp->spi->dev, "AVDD error\n");
1814+ return -EINVAL;
1815+ }
1816+
1817+ return 0;
1818+}
1819+
1820+static int at86rf230_suspend(struct spi_device *spi, pm_message_t message)
1821+{
1822+ return 0;
1823+}
1824+
1825+static int at86rf230_resume(struct spi_device *spi)
1826+{
1827+ return 0;
1828+}
1829+
1830+#ifdef CONFIG_OF
1831+static int at86rf230_fill_data(struct spi_device *spi)
1832+{
1833+ struct device_node *np = spi->dev.of_node;
1834+ struct at86rf230_local *lp = spi_get_drvdata(spi);
1835+ struct at86rf230_platform_data *pdata = spi->dev.platform_data;
1836+ enum of_gpio_flags gpio_flags;
1837+
1838+ if (pdata) {
1839+ lp->rstn = pdata->rstn;
1840+ lp->slp_tr = pdata->slp_tr;
1841+ lp->dig2 = pdata->dig2;
1842+ lp->reset = pdata->reset;
1843+ lp->reset_data = pdata->reset_data;
1844+
1845+ return 0;
1846+ }
1847+
1848+ if (!np) {
1849+ dev_err(&spi->dev, "no platform_data and no node data\n");
1850+ return -EINVAL;
1851+ }
1852+
1853+ lp->rstn = of_get_gpio_flags(np, 0, &gpio_flags);
1854+ if (!gpio_is_valid(lp->rstn)) {
1855+ dev_err(&spi->dev, "no RSTN GPIO!\n");
1856+ return -EINVAL;
1857+ }
1858+
1859+ lp->slp_tr = of_get_gpio_flags(np, 1, &gpio_flags);
1860+ lp->dig2 = of_get_gpio_flags(np, 2, &gpio_flags);
1861+
1862+ lp->reset = NULL;
1863+
1864+ return 0;
1865+}
1866+#else
1867+static int at86rf230_fill_data(struct spi_device *spi)
1868+{
1869+ struct at86rf230_local *lp = spi_get_drvdata(spi);
1870+ struct at86rf230_platform_data *pdata = spi->dev.platform_data;
1871+
1872+ if (!pdata) {
1873+ dev_err(&spi->dev, "no platform_data\n");
1874+ return -EINVAL;
1875+ }
1876+
1877+ lp->rstn = pdata->rstn;
1878+ lp->slp_tr = pdata->slp_tr;
1879+ lp->dig2 = pdata->dig2;
1880+ lp->reset = pdata->reset;
1881+ lp->reset_data = pdata->reset_data;
1882+
1883+ return 0;
1884+}
1885+#endif
1886+
1887+static int __devinit at86rf230_probe(struct spi_device *spi)
1888+{
1889+ struct ieee802154_dev *dev;
1890+ struct at86rf230_local *lp;
1891+ u8 man_id_0, man_id_1;
1892+ int rc;
1893+ const char *chip;
1894+ int supported = 0;
1895+
1896+ if (spi->irq < 0) {
1897+ dev_err(&spi->dev, "no IRQ specified\n");
1898+ return -EINVAL;
1899+ }
1900+
1901+ dev = ieee802154_alloc_device(sizeof(*lp), &at86rf230_ops);
1902+ if (!dev)
1903+ return -ENOMEM;
1904+
1905+ lp = dev->priv;
1906+ lp->dev = dev;
1907+
1908+ lp->spi = spi;
1909+
1910+ dev->priv = lp;
1911+ dev->parent = &spi->dev;
1912+ dev->extra_tx_headroom = 0;
1913+ /* We do support only 2.4 Ghz */
1914+ dev->phy->channels_supported[0] = 0x7FFF800;
1915+ dev->flags = IEEE802154_HW_OMIT_CKSUM;
1916+
1917+ mutex_init(&lp->bmux);
1918+ INIT_WORK(&lp->irqwork, at86rf230_irqwork);
1919+ init_completion(&lp->tx_complete);
1920+
1921+ spi_set_drvdata(spi, lp);
1922+
1923+ rc = at86rf230_fill_data(spi);
1924+ if (rc)
1925+ goto err_fill;
1926+
1927+ if (gpio_is_valid(lp->rstn)) {
1928+ rc = gpio_request(lp->rstn, "rstn");
1929+ if (rc)
1930+ goto err_rstn;
1931+ }
1932+
1933+ if (gpio_is_valid(lp->slp_tr)) {
1934+ rc = gpio_request(lp->slp_tr, "slp_tr");
1935+ if (rc)
1936+ goto err_slp_tr;
1937+ }
1938+
1939+ if (gpio_is_valid(lp->rstn)) {
1940+ rc = gpio_direction_output(lp->rstn, 1);
1941+ if (rc)
1942+ goto err_gpio_dir;
1943+ }
1944+
1945+ if (gpio_is_valid(lp->slp_tr)) {
1946+ rc = gpio_direction_output(lp->slp_tr, 0);
1947+ if (rc)
1948+ goto err_gpio_dir;
1949+ }
1950+
1951+ /* Reset */
1952+ if (lp->reset)
1953+ lp->reset(lp->reset_data);
1954+ else {
1955+ msleep(1);
1956+ gpio_set_value(lp->rstn, 0);
1957+ msleep(1);
1958+ gpio_set_value(lp->rstn, 1);
1959+ msleep(1);
1960+ }
1961+
1962+ rc = at86rf230_read_subreg(lp, SR_MAN_ID_0, &man_id_0);
1963+ if (rc)
1964+ goto err_gpio_dir;
1965+ rc = at86rf230_read_subreg(lp, SR_MAN_ID_1, &man_id_1);
1966+ if (rc)
1967+ goto err_gpio_dir;
1968+
1969+ if (man_id_1 != 0x00 || man_id_0 != 0x1f) {
1970+ dev_err(&spi->dev, "Non-Atmel device found (MAN_ID:"
1971+ "%02x %02x)\n", man_id_1, man_id_0);
1972+ rc = -EINVAL;
1973+ goto err_gpio_dir;
1974+ }
1975+
1976+ rc = at86rf230_read_subreg(lp, SR_PART_NUM, &lp->part);
1977+ if (rc)
1978+ goto err_gpio_dir;
1979+
1980+ rc = at86rf230_read_subreg(lp, SR_VERSION_NUM, &lp->vers);
1981+ if (rc)
1982+ goto err_gpio_dir;
1983+
1984+ switch (lp->part) {
1985+ case 2:
1986+ chip = "at86rf230";
1987+ /* supported = 1; FIXME: should be easy to support; */
1988+ break;
1989+ case 3:
1990+ chip = "at86rf231";
1991+ supported = 1;
1992+ break;
1993+ default:
1994+ chip = "UNKNOWN";
1995+ break;
1996+ }
1997+
1998+ dev_info(&spi->dev, "Detected %s chip version %d\n", chip, lp->vers);
1999+ if (!supported) {
2000+ rc = -ENOTSUPP;
2001+ goto err_gpio_dir;
2002+ }
2003+
2004+ rc = at86rf230_hw_init(lp);
2005+ if (rc)
2006+ goto err_gpio_dir;
2007+
2008+ rc = request_irq(spi->irq, at86rf230_isr, IRQF_SHARED,
2009+ dev_name(&spi->dev), lp);
2010+ if (rc)
2011+ goto err_gpio_dir;
2012+
2013+ dev_dbg(&spi->dev, "registered at86rf230\n");
2014+
2015+ rc = ieee802154_register_device(lp->dev);
2016+ if (rc)
2017+ goto err_irq;
2018+
2019+ return rc;
2020+
2021+err_irq:
2022+ disable_irq(spi->irq);
2023+ flush_work(&lp->irqwork);
2024+ free_irq(spi->irq, lp);
2025+err_gpio_dir:
2026+ if (gpio_is_valid(lp->slp_tr))
2027+ gpio_free(lp->slp_tr);
2028+err_slp_tr:
2029+ if (gpio_is_valid(lp->rstn))
2030+ gpio_free(lp->rstn);
2031+err_rstn:
2032+err_fill:
2033+ spi_set_drvdata(spi, NULL);
2034+ mutex_destroy(&lp->bmux);
2035+ ieee802154_free_device(lp->dev);
2036+ return rc;
2037+}
2038+
2039+static int __devexit at86rf230_remove(struct spi_device *spi)
2040+{
2041+ struct at86rf230_local *lp = spi_get_drvdata(spi);
2042+
2043+ /*
2044+ * @@@ this looks wrong - what if a frame arrives before
2045+ * disable_irq ? -- wa
2046+ */
2047+ ieee802154_unregister_device(lp->dev);
2048+
2049+ disable_irq(spi->irq);
2050+ flush_work(&lp->irqwork);
2051+ free_irq(spi->irq, lp);
2052+
2053+ if (gpio_is_valid(lp->slp_tr))
2054+ gpio_free(lp->slp_tr);
2055+ if (gpio_is_valid(lp->rstn))
2056+ gpio_free(lp->rstn);
2057+
2058+ spi_set_drvdata(spi, NULL);
2059+ mutex_destroy(&lp->bmux);
2060+ ieee802154_free_device(lp->dev);
2061+
2062+ dev_dbg(&spi->dev, "unregistered at86rf230\n");
2063+ return 0;
2064+}
2065+
2066+static struct spi_driver at86rf230_driver = {
2067+ .driver = {
2068+ .name = "at86rf230",
2069+ .owner = THIS_MODULE,
2070+ },
2071+ .probe = at86rf230_probe,
2072+ .remove = __devexit_p(at86rf230_remove),
2073+ .suspend = at86rf230_suspend,
2074+ .resume = at86rf230_resume,
2075+};
2076+
2077+static int __init at86rf230_init(void)
2078+{
2079+ return spi_register_driver(&at86rf230_driver);
2080+}
2081+module_init(at86rf230_init);
2082+
2083+static void __exit at86rf230_exit(void)
2084+{
2085+ spi_unregister_driver(&at86rf230_driver);
2086+}
2087+module_exit(at86rf230_exit);
2088+
2089+MODULE_DESCRIPTION("AT86RF230 Transceiver Driver");
2090+MODULE_LICENSE("GPL v2");
2091diff --git a/drivers/ieee802154/at86rf230.h b/drivers/ieee802154/at86rf230.h
2092new file mode 100644
2093index 0000000..fcb0e11
2094--- /dev/null
2095@@ -0,0 +1,211 @@
2096+/*
2097+ * AT86RF230/RF231 register and protocol definitions
2098+ *
2099+ * Copyright (C) 2009 Siemens AG
2100+ *
2101+ * This program is free software; you can redistribute it and/or modify
2102+ * it under the terms of the GNU General Public License version 2
2103+ * as published by the Free Software Foundation.
2104+ *
2105+ * This program is distributed in the hope that it will be useful,
2106+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2107+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2108+ * GNU General Public License for more details.
2109+ *
2110+ * You should have received a copy of the GNU General Public License along
2111+ * with this program; if not, write to the Free Software Foundation, Inc.,
2112+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2113+ *
2114+ * Written by:
2115+ * Dmitry Eremin-Solenikov <dmitry.baryshkov@siemens.com>
2116+ */
2117+
2118+#ifndef ATR86F230_H
2119+#define ATR86F230_H
2120+
2121+#define RG_TRX_STATUS (0x01)
2122+#define SR_TRX_STATUS 0x01, 0x1f, 0
2123+#define SR_RESERVED_01_3 0x01, 0x20, 5
2124+#define SR_CCA_STATUS 0x01, 0x40, 6
2125+#define SR_CCA_DONE 0x01, 0x80, 7
2126+#define RG_TRX_STATE (0x02)
2127+#define SR_TRX_CMD 0x02, 0x1f, 0
2128+#define SR_TRAC_STATUS 0x02, 0xe0, 5
2129+#define RG_TRX_CTRL_0 (0x03)
2130+#define SR_CLKM_CTRL 0x03, 0x07, 0
2131+#define SR_CLKM_SHA_SEL 0x03, 0x08, 3
2132+#define SR_PAD_IO_CLKM 0x03, 0x30, 4
2133+#define SR_PAD_IO 0x03, 0xc0, 6
2134+#define RG_TRX_CTRL_1 (0x04)
2135+#define SR_IRQ_POLARITY 0x04, 0x01, 0
2136+#define SR_IRQ_MASK_MODE 0x04, 0x02, 1
2137+#define SR_SPI_CMD_MODE 0x04, 0x0c, 2
2138+#define SR_RX_BL_CTRL 0x04, 0x10, 4
2139+#define SR_TX_AUTO_CRC_ON 0x04, 0x20, 5
2140+#define SR_IRQ_2_EXT_EN 0x04, 0x40, 6
2141+#define SR_PA_EXT_EN 0x04, 0x80, 7
2142+#define RG_PHY_TX_PWR (0x05)
2143+#define SR_TX_PWR 0x05, 0x0f, 0
2144+#define SR_PA_LT 0x05, 0x30, 4
2145+#define SR_PA_BUF_LT 0x05, 0xc0, 6
2146+#define RG_PHY_RSSI (0x06)
2147+#define SR_RSSI 0x06, 0x1f, 0
2148+#define SR_RND_VALUE 0x06, 0x60, 5
2149+#define SR_RX_CRC_VALID 0x06, 0x80, 7
2150+#define RG_PHY_ED_LEVEL (0x07)
2151+#define SR_ED_LEVEL 0x07, 0xff, 0
2152+#define RG_PHY_CC_CCA (0x08)
2153+#define SR_CHANNEL 0x08, 0x1f, 0
2154+#define SR_CCA_MODE 0x08, 0x60, 5
2155+#define SR_CCA_REQUEST 0x08, 0x80, 7
2156+#define RG_CCA_THRES (0x09)
2157+#define SR_CCA_ED_THRES 0x09, 0x0f, 0
2158+#define SR_RESERVED_09_1 0x09, 0xf0, 4
2159+#define RG_RX_CTRL (0x0a)
2160+#define SR_PDT_THRES 0x0a, 0x0f, 0
2161+#define SR_RESERVED_0a_1 0x0a, 0xf0, 4
2162+#define RG_SFD_VALUE (0x0b)
2163+#define SR_SFD_VALUE 0x0b, 0xff, 0
2164+#define RG_TRX_CTRL_2 (0x0c)
2165+#define SR_OQPSK_DATA_RATE 0x0c, 0x03, 0
2166+#define SR_RESERVED_0c_2 0x0c, 0x7c, 2
2167+#define SR_RX_SAFE_MODE 0x0c, 0x80, 7
2168+#define RG_ANT_DIV (0x0d)
2169+#define SR_ANT_CTRL 0x0d, 0x03, 0
2170+#define SR_ANT_EXT_SW_EN 0x0d, 0x04, 2
2171+#define SR_ANT_DIV_EN 0x0d, 0x08, 3
2172+#define SR_RESERVED_0d_2 0x0d, 0x70, 4
2173+#define SR_ANT_SEL 0x0d, 0x80, 7
2174+#define RG_IRQ_MASK (0x0e)
2175+#define SR_IRQ_MASK 0x0e, 0xff, 0
2176+#define RG_IRQ_STATUS (0x0f)
2177+#define SR_IRQ_0_PLL_LOCK 0x0f, 0x01, 0
2178+#define SR_IRQ_1_PLL_UNLOCK 0x0f, 0x02, 1
2179+#define SR_IRQ_2_RX_START 0x0f, 0x04, 2
2180+#define SR_IRQ_3_TRX_END 0x0f, 0x08, 3
2181+#define SR_IRQ_4_CCA_ED_DONE 0x0f, 0x10, 4
2182+#define SR_IRQ_5_AMI 0x0f, 0x20, 5
2183+#define SR_IRQ_6_TRX_UR 0x0f, 0x40, 6
2184+#define SR_IRQ_7_BAT_LOW 0x0f, 0x80, 7
2185+#define RG_VREG_CTRL (0x10)
2186+#define SR_RESERVED_10_6 0x10, 0x03, 0
2187+#define SR_DVDD_OK 0x10, 0x04, 2
2188+#define SR_DVREG_EXT 0x10, 0x08, 3
2189+#define SR_RESERVED_10_3 0x10, 0x30, 4
2190+#define SR_AVDD_OK 0x10, 0x40, 6
2191+#define SR_AVREG_EXT 0x10, 0x80, 7
2192+#define RG_BATMON (0x11)
2193+#define SR_BATMON_VTH 0x11, 0x0f, 0
2194+#define SR_BATMON_HR 0x11, 0x10, 4
2195+#define SR_BATMON_OK 0x11, 0x20, 5
2196+#define SR_RESERVED_11_1 0x11, 0xc0, 6
2197+#define RG_XOSC_CTRL (0x12)
2198+#define SR_XTAL_TRIM 0x12, 0x0f, 0
2199+#define SR_XTAL_MODE 0x12, 0xf0, 4
2200+#define RG_RX_SYN (0x15)
2201+#define SR_RX_PDT_LEVEL 0x15, 0x0f, 0
2202+#define SR_RESERVED_15_2 0x15, 0x70, 4
2203+#define SR_RX_PDT_DIS 0x15, 0x80, 7
2204+#define RG_XAH_CTRL_1 (0x17)
2205+#define SR_RESERVED_17_8 0x17, 0x01, 0
2206+#define SR_AACK_PROM_MODE 0x17, 0x02, 1
2207+#define SR_AACK_ACK_TIME 0x17, 0x04, 2
2208+#define SR_RESERVED_17_5 0x17, 0x08, 3
2209+#define SR_AACK_UPLD_RES_FT 0x17, 0x10, 4
2210+#define SR_AACK_FLTR_RES_FT 0x17, 0x20, 5
2211+#define SR_RESERVED_17_2 0x17, 0x40, 6
2212+#define SR_RESERVED_17_1 0x17, 0x80, 7
2213+#define RG_FTN_CTRL (0x18)
2214+#define SR_RESERVED_18_2 0x18, 0x7f, 0
2215+#define SR_FTN_START 0x18, 0x80, 7
2216+#define RG_PLL_CF (0x1a)
2217+#define SR_RESERVED_1a_2 0x1a, 0x7f, 0
2218+#define SR_PLL_CF_START 0x1a, 0x80, 7
2219+#define RG_PLL_DCU (0x1b)
2220+#define SR_RESERVED_1b_3 0x1b, 0x3f, 0
2221+#define SR_RESERVED_1b_2 0x1b, 0x40, 6
2222+#define SR_PLL_DCU_START 0x1b, 0x80, 7
2223+#define RG_PART_NUM (0x1c)
2224+#define SR_PART_NUM 0x1c, 0xff, 0
2225+#define RG_VERSION_NUM (0x1d)
2226+#define SR_VERSION_NUM 0x1d, 0xff, 0
2227+#define RG_MAN_ID_0 (0x1e)
2228+#define SR_MAN_ID_0 0x1e, 0xff, 0
2229+#define RG_MAN_ID_1 (0x1f)
2230+#define SR_MAN_ID_1 0x1f, 0xff, 0
2231+#define RG_SHORT_ADDR_0 (0x20)
2232+#define SR_SHORT_ADDR_0 0x20, 0xff, 0
2233+#define RG_SHORT_ADDR_1 (0x21)
2234+#define SR_SHORT_ADDR_1 0x21, 0xff, 0
2235+#define RG_PAN_ID_0 (0x22)
2236+#define SR_PAN_ID_0 0x22, 0xff, 0
2237+#define RG_PAN_ID_1 (0x23)
2238+#define SR_PAN_ID_1 0x23, 0xff, 0
2239+#define RG_IEEE_ADDR_0 (0x24)
2240+#define SR_IEEE_ADDR_0 0x24, 0xff, 0
2241+#define RG_IEEE_ADDR_1 (0x25)
2242+#define SR_IEEE_ADDR_1 0x25, 0xff, 0
2243+#define RG_IEEE_ADDR_2 (0x26)
2244+#define SR_IEEE_ADDR_2 0x26, 0xff, 0
2245+#define RG_IEEE_ADDR_3 (0x27)
2246+#define SR_IEEE_ADDR_3 0x27, 0xff, 0
2247+#define RG_IEEE_ADDR_4 (0x28)
2248+#define SR_IEEE_ADDR_4 0x28, 0xff, 0
2249+#define RG_IEEE_ADDR_5 (0x29)
2250+#define SR_IEEE_ADDR_5 0x29, 0xff, 0
2251+#define RG_IEEE_ADDR_6 (0x2a)
2252+#define SR_IEEE_ADDR_6 0x2a, 0xff, 0
2253+#define RG_IEEE_ADDR_7 (0x2b)
2254+#define SR_IEEE_ADDR_7 0x2b, 0xff, 0
2255+#define RG_XAH_CTRL_0 (0x2c)
2256+#define SR_SLOTTED_OPERATION 0x2c, 0x01, 0
2257+#define SR_MAX_CSMA_RETRIES 0x2c, 0x0e, 1
2258+#define SR_MAX_FRAME_RETRIES 0x2c, 0xf0, 4
2259+#define RG_CSMA_SEED_0 (0x2d)
2260+#define SR_CSMA_SEED_0 0x2d, 0xff, 0
2261+#define RG_CSMA_SEED_1 (0x2e)
2262+#define SR_CSMA_SEED_1 0x2e, 0x07, 0
2263+#define SR_AACK_I_AM_COORD 0x2e, 0x08, 3
2264+#define SR_AACK_DIS_ACK 0x2e, 0x10, 4
2265+#define SR_AACK_SET_PD 0x2e, 0x20, 5
2266+#define SR_AACK_FVN_MODE 0x2e, 0xc0, 6
2267+#define RG_CSMA_BE (0x2f)
2268+#define SR_MIN_BE 0x2f, 0x0f, 0
2269+#define SR_MAX_BE 0x2f, 0xf0, 4
2270+
2271+#define CMD_REG 0x80
2272+#define CMD_REG_MASK 0x3f
2273+#define CMD_WRITE 0x40
2274+#define CMD_FB 0x20
2275+
2276+#define IRQ_BAT_LOW (1 << 7)
2277+#define IRQ_TRX_UR (1 << 6)
2278+#define IRQ_AMI (1 << 5)
2279+#define IRQ_CCA_ED (1 << 4)
2280+#define IRQ_TRX_END (1 << 3)
2281+#define IRQ_RX_START (1 << 2)
2282+#define IRQ_PLL_UNL (1 << 1)
2283+#define IRQ_PLL_LOCK (1 << 0)
2284+
2285+#define STATE_P_ON 0x00 /* BUSY */
2286+#define STATE_BUSY_RX 0x01
2287+#define STATE_BUSY_TX 0x02
2288+#define STATE_FORCE_TRX_OFF 0x03
2289+#define STATE_FORCE_TX_ON 0x04 /* IDLE */
2290+/* 0x05 */ /* INVALID_PARAMETER */
2291+#define STATE_RX_ON 0x06
2292+/* 0x07 */ /* SUCCESS */
2293+#define STATE_TRX_OFF 0x08
2294+#define STATE_TX_ON 0x09
2295+/* 0x0a - 0x0e */ /* 0x0a - UNSUPPORTED_ATTRIBUTE */
2296+#define STATE_SLEEP 0x0F
2297+#define STATE_BUSY_RX_AACK 0x11
2298+#define STATE_BUSY_TX_ARET 0x12
2299+#define STATE_BUSY_RX_AACK_ON 0x16
2300+#define STATE_BUSY_TX_ARET_ON 0x19
2301+#define STATE_RX_ON_NOCLK 0x1C
2302+#define STATE_RX_AACK_ON_NOCLK 0x1D
2303+#define STATE_BUSY_RX_AACK_NOCLK 0x1E
2304+#define STATE_TRANSITION_IN_PROGRESS 0x1F
2305+
2306+#endif /* !ATR86F230_H */
2307diff --git a/drivers/ieee802154/cc2420.c b/drivers/ieee802154/cc2420.c
2308new file mode 100644
2309index 0000000..50761de
2310--- /dev/null
2311@@ -0,0 +1,859 @@
2312+/*
2313+ * This program is free software; you can redistribute it and/or modify
2314+ * it under the terms of the GNU General Public License version 2
2315+ * as published by the Free Software Foundation.
2316+ *
2317+ * This program is distributed in the hope that it will be useful,
2318+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2319+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2320+ * GNU General Public License for more details.
2321+ *
2322+ * You should have received a copy of the GNU General Public License along
2323+ * with this program; if not, write to the Free Software Foundation, Inc.,
2324+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2325+ *
2326+ * Author: Jonathan Cameron <jic23@cam.ac.uk>
2327+ *
2328+ * Modified 2010: xue liu <liuxuenetmail@gmail.com>
2329+ */
2330+
2331+#include <linux/kernel.h>
2332+#include <linux/module.h>
2333+#include <linux/mutex.h>
2334+#include <linux/spinlock.h>
2335+#include <linux/gpio.h>
2336+#include <linux/delay.h>
2337+#include <linux/interrupt.h>
2338+#include <linux/workqueue.h>
2339+#include <linux/spi/spi.h>
2340+#include <linux/spi/cc2420.h>
2341+#include <linux/skbuff.h>
2342+#include <linux/irq.h>
2343+#include <net/mac802154.h>
2344+#include <net/wpan-phy.h>
2345+
2346+#define CC2420_WRITEREG(x) (x)
2347+#define CC2420_READREG(x) (0x40 | x)
2348+#define CC2420_RAMADDR(x) ((x & 0x7F) | 0x80)
2349+#define CC2420_RAMBANK(x) ((x >> 1) & 0xc0)
2350+#define CC2420_WRITERAM(x) (x)
2351+#define CC2420_READRAM(x) (0x20 | x)
2352+
2353+#define CC2420_FREQ_MASK 0x3FF
2354+#define CC2420_ADR_DECODE_MASK 0x0B00
2355+#define CC2420_FIFOP_THR_MASK 0x003F
2356+#define CC2420_CRC_MASK 0x80
2357+#define CC2420_RSSI_MASK 0x7F
2358+#define CC2420_FSMSTATE_MASK 0x2F
2359+
2360+#define CC2420_MANFIDLOW 0x233D
2361+#define CC2420_MANFIDHIGH 0x3000 /* my chip appears to version 3 - broaden this with testing */
2362+
2363+#define RSSI_OFFSET 45
2364+
2365+#define STATE_PDOWN 0
2366+#define STATE_IDLE 1
2367+#define STATE_RX_CALIBRATE 2
2368+#define STATE_RX_CALIBRATE2 40
2369+
2370+#define STATE_RX_SFD_SEARCH_MIN 3
2371+#define STATE_RX_SFD_SEARCH_MAX 6
2372+#define STATE_RX_FRAME 16
2373+#define STATE_RX_FRAME2 40
2374+#define STATE_RX_WAIT 14
2375+#define STATE_RX_OVERFLOW 17
2376+#define STATE_TX_ACK_CALIBRATE 48
2377+#define STATE_TX_ACK_PREAMBLE_MIN 49
2378+#define STATE_TX_ACK_PREAMBLE_MAX 51
2379+#define STATE_TX_ACK_MIN 52
2380+#define STATE_TX_ACK_MAX 54
2381+#define STATE_TX_CALIBRATE 32
2382+#define STATE_TX_PREAMBLE_MIN 34
2383+#define STATE_TX_PREAMBLE_MAX 36
2384+#define STATE_TX_FRAME_MIN 37
2385+#define STATE_TX_FRAME_MAX 39
2386+#define STATE_TX_UNDERFLOW 56
2387+
2388+struct cc2420_local {
2389+ struct cc2420_platform_data *pdata;
2390+ struct spi_device *spi;
2391+ struct ieee802154_dev *dev;
2392+ u8 *buf;
2393+ struct mutex bmux;
2394+ int fifop_irq;
2395+ int sfd_irq;
2396+ struct work_struct fifop_irqwork;
2397+ struct work_struct sfd_irqwork;
2398+ spinlock_t lock;
2399+ unsigned irq_disabled:1;/* P:lock */
2400+ unsigned is_tx:1; /* P:lock */
2401+
2402+ struct completion tx_complete;
2403+};
2404+static int cc2420_get_status(struct cc2420_local *lp, u8 *status)
2405+{
2406+ int ret;
2407+ struct spi_message msg;
2408+ struct spi_transfer xfer = {
2409+ .len = 1,
2410+ .tx_buf = lp->buf,
2411+ .rx_buf = lp->buf,
2412+ };
2413+ spi_message_init(&msg);
2414+ spi_message_add_tail(&xfer, &msg);
2415+ mutex_lock(&lp->bmux);
2416+ lp->buf[0] = CC2420_WRITEREG(CC2420_SNOP);
2417+ dev_vdbg(&lp->spi->dev, "get status command buf[0] = %02x\n", lp->buf[0]);
2418+ ret = spi_sync(lp->spi, &msg);
2419+ if (!ret)
2420+ *status = lp->buf[0];
2421+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", lp->buf[0]);
2422+ mutex_unlock(&lp->bmux);
2423+ return ret;
2424+
2425+}
2426+static int cc2420_cmd_strobe(struct cc2420_local *lp,
2427+ u8 addr)
2428+{
2429+ int ret;
2430+ u8 status = 0xf;
2431+ struct spi_message msg;
2432+ struct spi_transfer xfer = {
2433+ .len = 1,
2434+ .tx_buf = lp->buf,
2435+ .rx_buf = lp->buf,
2436+ };
2437+ spi_message_init(&msg);
2438+ spi_message_add_tail(&xfer, &msg);
2439+ mutex_lock(&lp->bmux);
2440+ lp->buf[0] = CC2420_WRITEREG(addr);
2441+ dev_vdbg(&lp->spi->dev, "cmd strobe buf[0] = %02x\n", lp->buf[0]);
2442+ ret = spi_sync(lp->spi, &msg);
2443+ if (!ret)
2444+ status = lp->buf[0];
2445+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", lp->buf[0]);
2446+
2447+ mutex_unlock(&lp->bmux);
2448+
2449+ return ret;
2450+}
2451+
2452+static int cc2420_read_16_bit_reg(struct cc2420_local *lp,
2453+ u8 addr, u16 *data)
2454+{
2455+ int ret;
2456+ struct spi_message msg;
2457+ struct spi_transfer xfer = {
2458+ .len = 3,
2459+ .tx_buf = lp->buf,
2460+ .rx_buf = lp->buf,
2461+ };
2462+
2463+ spi_message_init(&msg);
2464+ spi_message_add_tail(&xfer, &msg);
2465+ mutex_lock(&lp->bmux);
2466+ lp->buf[0] = CC2420_READREG(addr);
2467+ dev_vdbg(&lp->spi->dev, "readreg addr buf[0] = %02x\n", lp->buf[0]);
2468+ ret = spi_sync(lp->spi, &msg);
2469+ dev_dbg(&lp->spi->dev, "status = %d\n", ret);
2470+ mutex_unlock(&lp->bmux);
2471+ dev_dbg(&lp->spi->dev, "buf[0] = %02x\n", lp->buf[0]);
2472+ dev_dbg(&lp->spi->dev, "buf[1] = %02x\n", lp->buf[1]);
2473+ dev_dbg(&lp->spi->dev, "buf[2] = %02x\n", lp->buf[2]);
2474+ if (!ret)
2475+ *data = ((u16) (lp->buf[1]) << 8) | lp->buf[2];
2476+ return ret;
2477+}
2478+
2479+static int cc2420_write_16_bit_reg_partial(struct cc2420_local *lp,
2480+ u8 addr, u16 data, u16 mask)
2481+{
2482+ int ret;
2483+ struct spi_message msg;
2484+ struct spi_transfer xfer = {
2485+ .len = 3,
2486+ .tx_buf = lp->buf,
2487+ .rx_buf = lp->buf,
2488+ };
2489+ dev_dbg(&lp->spi->dev, "data = %x\n", data);
2490+ dev_dbg(&lp->spi->dev, "mask = %x\n", mask);
2491+ spi_message_init(&msg);
2492+ spi_message_add_tail(&xfer, &msg);
2493+ mutex_lock(&lp->bmux);
2494+ lp->buf[0] = CC2420_READREG(addr);
2495+ dev_vdbg(&lp->spi->dev, "read addr buf[0] = %02x\n", lp->buf[0]);
2496+ ret = spi_sync(lp->spi, &msg);
2497+ if (ret)
2498+ goto err_ret;
2499+ dev_dbg(&lp->spi->dev, "read buf[0] = %02x\n", lp->buf[0]);
2500+ dev_dbg(&lp->spi->dev, "buf[1] = %02x\n", lp->buf[1]);
2501+ dev_dbg(&lp->spi->dev, "buf[2] = %02x\n", lp->buf[2]);
2502+
2503+ lp->buf[0] = CC2420_WRITEREG(addr);
2504+
2505+ lp->buf[1] &= ~(mask >> 8);
2506+ lp->buf[2] &= ~(mask & 0xFF);
2507+ lp->buf[1] |= (mask >> 8) & (data >> 8);
2508+ lp->buf[2] |= (mask & 0xFF) & (data & 0xFF);
2509+ dev_vdbg(&lp->spi->dev, "writereg addr buf[0] = %02x\n", lp->buf[0]);
2510+ dev_dbg(&lp->spi->dev, "buf[1] = %02x\n", lp->buf[1]);
2511+ dev_dbg(&lp->spi->dev, "buf[2] = %02x\n", lp->buf[2]);
2512+ ret = spi_sync(lp->spi, &msg);
2513+ if (ret)
2514+ goto err_ret;
2515+ dev_dbg(&lp->spi->dev, "return status buf[0] = %02x\n", lp->buf[0]);
2516+ dev_dbg(&lp->spi->dev, "buf[1] = %02x\n", lp->buf[1]);
2517+ dev_dbg(&lp->spi->dev, "buf[2] = %02x\n", lp->buf[2]);
2518+
2519+err_ret:
2520+ mutex_unlock(&lp->bmux);
2521+ return ret;
2522+}
2523+
2524+static int cc2420_channel(struct ieee802154_dev *dev, int page, int channel)
2525+{
2526+ struct cc2420_local *lp = dev->priv;
2527+ int ret;
2528+
2529+ might_sleep();
2530+ dev_dbg(&lp->spi->dev, "trying to set channel\n");
2531+
2532+ BUG_ON(page != 0);
2533+ BUG_ON(channel < CC2420_MIN_CHANNEL);
2534+ BUG_ON(channel > CC2420_MAX_CHANNEL);
2535+
2536+ ret = cc2420_write_16_bit_reg_partial(lp, CC2420_FSCTRL, 357 + 5*(channel - 11), CC2420_FREQ_MASK);
2537+
2538+ dev->phy->current_channel = channel;
2539+ return ret;
2540+}
2541+
2542+static int cc2420_write_ram(struct cc2420_local *lp, u16 addr, u8 len, u8 *data)
2543+{
2544+ int status;
2545+ struct spi_message msg;
2546+ struct spi_transfer xfer_head = {
2547+ .len = 2,
2548+ .tx_buf = lp->buf,
2549+ .rx_buf = lp->buf,
2550+ };
2551+ struct spi_transfer xfer_buf = {
2552+ .len = len,
2553+ .tx_buf = data,
2554+ };
2555+
2556+ mutex_lock(&lp->bmux);
2557+ lp->buf[0] = CC2420_RAMADDR(addr);
2558+ lp->buf[1] = CC2420_WRITERAM(CC2420_RAMBANK(addr));
2559+ dev_dbg(&lp->spi->dev, "write ram addr buf[0] = %02x\n", lp->buf[0]);
2560+ dev_dbg(&lp->spi->dev, "ram bank buf[1] = %02x\n", lp->buf[1]);
2561+
2562+ spi_message_init(&msg);
2563+ spi_message_add_tail(&xfer_head, &msg);
2564+ spi_message_add_tail(&xfer_buf, &msg);
2565+
2566+ status = spi_sync(lp->spi, &msg);
2567+ dev_dbg(&lp->spi->dev, "spi status = %d\n", status);
2568+ if (msg.status)
2569+ status = msg.status;
2570+ dev_dbg(&lp->spi->dev, "cc2420 status = %02x\n", lp->buf[0]);
2571+ dev_dbg(&lp->spi->dev, "buf[1] = %02x\n", lp->buf[1]);
2572+
2573+ mutex_unlock(&lp->bmux);
2574+ return status;
2575+}
2576+
2577+static int cc2420_write_txfifo(struct cc2420_local *lp, u8 *data, u8 len)
2578+{
2579+ int status;
2580+ /* Length byte must include FCS even if calculated in hardware */
2581+ int len_byte = len + 2;
2582+ struct spi_message msg;
2583+ struct spi_transfer xfer_head = {
2584+ .len = 1,
2585+ .tx_buf = lp->buf,
2586+ .rx_buf = lp->buf,
2587+ };
2588+ struct spi_transfer xfer_len = {
2589+ .len = 1,
2590+ .tx_buf = &len_byte,
2591+ };
2592+ struct spi_transfer xfer_buf = {
2593+ .len = len,
2594+ .tx_buf = data,
2595+ };
2596+
2597+ mutex_lock(&lp->bmux);
2598+ lp->buf[0] = CC2420_WRITEREG(CC2420_TXFIFO);
2599+ dev_vdbg(&lp->spi->dev, "TX_FIFO addr buf[0] = %02x\n", lp->buf[0]);
2600+
2601+ spi_message_init(&msg);
2602+ spi_message_add_tail(&xfer_head, &msg);
2603+ spi_message_add_tail(&xfer_len, &msg);
2604+ spi_message_add_tail(&xfer_buf, &msg);
2605+
2606+ status = spi_sync(lp->spi, &msg);
2607+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
2608+ if (msg.status)
2609+ status = msg.status;
2610+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
2611+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", lp->buf[0]);
2612+
2613+ mutex_unlock(&lp->bmux);
2614+ return status;
2615+}
2616+
2617+static int
2618+cc2420_read_rxfifo(struct cc2420_local *lp, u8 *data, u8 *len, u8 *lqi)
2619+{
2620+ int status;
2621+ struct spi_message msg;
2622+ struct spi_transfer xfer_head = {
2623+ .len = 2,
2624+ .tx_buf = lp->buf,
2625+ .rx_buf = lp->buf,
2626+ };
2627+ struct spi_transfer xfer_buf = {
2628+ .len = *len,
2629+ .rx_buf = data,
2630+ };
2631+
2632+ mutex_lock(&lp->bmux);
2633+ lp->buf[0] = CC2420_READREG(CC2420_RXFIFO);
2634+ lp->buf[1] = 0x00;
2635+ dev_vdbg(&lp->spi->dev, "read rxfifo buf[0] = %02x\n", lp->buf[0]);
2636+ dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", lp->buf[1]);
2637+ spi_message_init(&msg);
2638+ spi_message_add_tail(&xfer_head, &msg);
2639+ spi_message_add_tail(&xfer_buf, &msg);
2640+
2641+ status = spi_sync(lp->spi, &msg);
2642+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
2643+ if (msg.status)
2644+ status = msg.status;
2645+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
2646+ dev_vdbg(&lp->spi->dev, "return status buf[0] = %02x\n", lp->buf[0]);
2647+ dev_vdbg(&lp->spi->dev, "length buf[1] = %02x\n", lp->buf[1]);
2648+
2649+ *lqi = data[lp->buf[1] - 1] & 0x7f;
2650+ *len = lp->buf[1]; /* it should be less than 130 */
2651+
2652+ mutex_unlock(&lp->bmux);
2653+
2654+ return status;
2655+}
2656+
2657+
2658+static int cc2420_tx(struct ieee802154_dev *dev, struct sk_buff *skb)
2659+{
2660+ struct cc2420_local *lp = dev->priv;
2661+ int rc;
2662+ unsigned long flags;
2663+ u8 status = 0;
2664+
2665+ pr_debug("%s\n", __func__);
2666+
2667+ might_sleep();
2668+
2669+ rc = cc2420_cmd_strobe(lp, CC2420_SFLUSHTX);
2670+ if (rc)
2671+ goto err_rx;
2672+ rc = cc2420_write_txfifo(lp, skb->data, skb->len);
2673+ if (rc)
2674+ goto err_rx;
2675+
2676+ /* TODO: test CCA pin */
2677+
2678+ rc = cc2420_get_status(lp, &status);
2679+ if (rc)
2680+ goto err_rx;
2681+
2682+ if (status & CC2420_STATUS_TX_UNDERFLOW) {
2683+ dev_err(&lp->spi->dev, "cc2420 tx underflow!\n");
2684+ goto err_rx;
2685+ }
2686+
2687+ spin_lock_irqsave(&lp->lock, flags);
2688+ BUG_ON(lp->is_tx);
2689+ lp->is_tx = 1;
2690+ INIT_COMPLETION(lp->tx_complete);
2691+ spin_unlock_irqrestore(&lp->lock, flags);
2692+
2693+ rc = cc2420_cmd_strobe(lp, CC2420_STXONCCA);
2694+ if (rc)
2695+ goto err;
2696+
2697+ rc = wait_for_completion_interruptible(&lp->tx_complete);
2698+ if (rc < 0)
2699+ goto err;
2700+
2701+ cc2420_cmd_strobe(lp, CC2420_SFLUSHTX);
2702+ cc2420_cmd_strobe(lp, CC2420_SRXON);
2703+
2704+ return rc;
2705+
2706+err:
2707+ spin_lock_irqsave(&lp->lock, flags);
2708+ lp->is_tx = 0;
2709+ spin_unlock_irqrestore(&lp->lock, flags);
2710+err_rx:
2711+ cc2420_cmd_strobe(lp, CC2420_SFLUSHTX);
2712+ cc2420_cmd_strobe(lp, CC2420_SRXON);
2713+ return rc;
2714+}
2715+
2716+static int cc2420_rx(struct cc2420_local *lp)
2717+{
2718+ u8 len = 128;
2719+ u8 lqi = 0; /* link quality */
2720+ int rc;
2721+ struct sk_buff *skb;
2722+
2723+ skb = alloc_skb(len, GFP_KERNEL);
2724+ if (!skb)
2725+ return -ENOMEM;
2726+
2727+ rc = cc2420_read_rxfifo(lp, skb_put(skb, len), &len, &lqi);
2728+ if (len < 2) {
2729+ kfree_skb(skb);
2730+ return -EINVAL;
2731+ }
2732+
2733+ /* Clip last two bytes. When using hardware FCS they get replaced with
2734+ * correlation value, FCS flag and RSSI value */
2735+ skb_trim(skb, len-2);
2736+
2737+ ieee802154_rx_irqsafe(lp->dev, skb, lqi);
2738+
2739+ dev_dbg(&lp->spi->dev, "RXFIFO: %d %d %x\n", rc, len, lqi);
2740+
2741+ return 0;
2742+}
2743+
2744+static int
2745+cc2420_set_hw_addr_filt(struct ieee802154_dev *dev,
2746+ struct ieee802154_hw_addr_filt *filt,
2747+ unsigned long changed)
2748+{
2749+ struct cc2420_local *lp = dev->priv;
2750+ u16 reg;
2751+
2752+ might_sleep();
2753+
2754+ if (changed & IEEE802515_IEEEADDR_CHANGED)
2755+ cc2420_write_ram(lp, CC2420_RAM_IEEEADR,
2756+ IEEE802154_ALEN,
2757+ filt->ieee_addr);
2758+
2759+ if (changed & IEEE802515_SADDR_CHANGED) {
2760+ u8 short_addr[2];
2761+ short_addr[0] = filt->short_addr & 0xff;/* LSB */
2762+ short_addr[1] = filt->short_addr >> 8; /* MSB */
2763+ cc2420_write_ram(lp, CC2420_RAM_SHORTADR,
2764+ sizeof(short_addr),
2765+ short_addr);
2766+ }
2767+
2768+ if (changed & IEEE802515_PANID_CHANGED) {
2769+ u8 panid[2];
2770+ panid[0] = filt->pan_id & 0xff; /* LSB */
2771+ panid[1] = filt->pan_id >> 8; /* MSB */
2772+ cc2420_write_ram(lp, CC2420_RAM_PANID,
2773+ sizeof(panid),
2774+ panid);
2775+ }
2776+
2777+ if (changed & IEEE802515_PANC_CHANGED) {
2778+ cc2420_read_16_bit_reg(lp, CC2420_MDMCTRL0, &reg);
2779+ if (filt->pan_coord)
2780+ reg |= 1 << CC2420_MDMCTRL0_PANCRD;
2781+ else
2782+ reg &= ~(1 << CC2420_MDMCTRL0_PANCRD);
2783+ cc2420_write_16_bit_reg_partial(lp, CC2420_MDMCTRL0,
2784+ reg, 1 << CC2420_MDMCTRL0_PANCRD);
2785+ }
2786+
2787+ return 0;
2788+}
2789+
2790+static int cc2420_ed(struct ieee802154_dev *dev, u8 *level)
2791+{
2792+ struct cc2420_local *lp = dev->priv;
2793+ u16 rssi;
2794+ int ret;
2795+ dev_dbg(&lp->spi->dev, "ed called\n");
2796+
2797+ ret = cc2420_read_16_bit_reg(lp, CC2420_RSSI, &rssi);
2798+ if (ret)
2799+ return ret;
2800+
2801+ /* P = RSSI_VAL + RSSI_OFFSET[dBm] */
2802+ *level = (rssi & CC2420_RSSI_MASK) + RSSI_OFFSET;
2803+ return ret;
2804+}
2805+
2806+static int cc2420_start(struct ieee802154_dev *dev)
2807+{
2808+ return cc2420_cmd_strobe(dev->priv, CC2420_SRXON);
2809+}
2810+
2811+static void cc2420_stop(struct ieee802154_dev *dev)
2812+{
2813+ cc2420_cmd_strobe(dev->priv, CC2420_SRFOFF);
2814+}
2815+
2816+static struct ieee802154_ops cc2420_ops = {
2817+ .owner = THIS_MODULE,
2818+ .xmit = cc2420_tx,
2819+ .ed = cc2420_ed,
2820+ .start = cc2420_start,
2821+ .stop = cc2420_stop,
2822+ .set_channel = cc2420_channel,
2823+ .set_hw_addr_filt = cc2420_set_hw_addr_filt,
2824+};
2825+
2826+static int cc2420_register(struct cc2420_local *lp)
2827+{
2828+ int ret = -ENOMEM;
2829+ lp->dev = ieee802154_alloc_device(sizeof(*lp), &cc2420_ops);
2830+ if (!lp->dev)
2831+ goto err_ret;
2832+
2833+ lp->dev->priv = lp;
2834+ lp->dev->parent = &lp->spi->dev;
2835+ //look this up.
2836+ lp->dev->extra_tx_headroom = 0;
2837+ //and this
2838+ //lp->dev->channel_mask = 0x7ff;
2839+ //and more.
2840+
2841+ /* We do support only 2.4 Ghz */
2842+ lp->dev->phy->channels_supported[0] = 0x7FFF800;
2843+ lp->dev->flags = IEEE802154_HW_OMIT_CKSUM;
2844+
2845+ dev_dbg(&lp->spi->dev, "registered cc2420\n");
2846+ ret = ieee802154_register_device(lp->dev);
2847+ if (ret)
2848+ goto err_free_device;
2849+
2850+ return 0;
2851+err_free_device:
2852+ ieee802154_free_device(lp->dev);
2853+err_ret:
2854+ return ret;
2855+}
2856+
2857+static void cc2420_unregister(struct cc2420_local *lp)
2858+{
2859+ ieee802154_unregister_device(lp->dev);
2860+ //check this is needed
2861+ ieee802154_free_device(lp->dev);
2862+}
2863+
2864+static irqreturn_t cc2420_isr(int irq, void *data)
2865+{
2866+ struct cc2420_local *lp = data;
2867+
2868+ spin_lock(&lp->lock);
2869+ if (!lp->irq_disabled) {
2870+ disable_irq_nosync(irq);
2871+ lp->irq_disabled = 1;
2872+ }
2873+ spin_unlock(&lp->lock);
2874+
2875+ if (irq == lp->sfd_irq)
2876+ schedule_work(&lp->sfd_irqwork);
2877+
2878+ if (irq == lp->fifop_irq)
2879+ schedule_work(&lp->fifop_irqwork);
2880+
2881+ return IRQ_HANDLED;
2882+}
2883+
2884+static void cc2420_fifop_irqwork(struct work_struct *work)
2885+{
2886+ struct cc2420_local *lp
2887+ = container_of(work, struct cc2420_local, fifop_irqwork);
2888+ unsigned long flags;
2889+
2890+ dev_dbg(&lp->spi->dev, "fifop interrupt received\n");
2891+
2892+ if (gpio_get_value(lp->pdata->fifo))
2893+ cc2420_rx(lp);
2894+ else
2895+ dev_err(&lp->spi->dev, "rxfifo overflow\n");
2896+
2897+ cc2420_cmd_strobe(lp, CC2420_SFLUSHRX);
2898+ cc2420_cmd_strobe(lp, CC2420_SFLUSHRX);
2899+
2900+ spin_lock_irqsave(&lp->lock, flags);
2901+ if (lp->irq_disabled) {
2902+ lp->irq_disabled = 0;
2903+ enable_irq(lp->fifop_irq);
2904+ }
2905+ spin_unlock_irqrestore(&lp->lock, flags);
2906+}
2907+
2908+static void cc2420_sfd_irqwork(struct work_struct *work)
2909+{
2910+ struct cc2420_local *lp
2911+ = container_of(work, struct cc2420_local, sfd_irqwork);
2912+ unsigned long flags;
2913+
2914+ dev_dbg(&lp->spi->dev, "sfd interrupt received\n");
2915+
2916+ spin_lock_irqsave(&lp->lock, flags);
2917+ if (lp->is_tx) {
2918+ lp->is_tx = 0;
2919+ spin_unlock_irqrestore(&lp->lock, flags);
2920+ complete(&lp->tx_complete);
2921+ } else {
2922+ spin_unlock_irqrestore(&lp->lock, flags);
2923+ }
2924+
2925+ spin_lock_irqsave(&lp->lock, flags);
2926+ if (lp->irq_disabled) {
2927+ lp->irq_disabled = 0;
2928+ enable_irq(lp->sfd_irq);
2929+ }
2930+ spin_unlock_irqrestore(&lp->lock, flags);
2931+}
2932+
2933+static int cc2420_hw_init(struct cc2420_local *lp)
2934+{
2935+ int ret;
2936+ u16 state;
2937+ u8 status = 0xff;
2938+ int timeout = 500; /* 500us delay */
2939+ ret = cc2420_read_16_bit_reg(lp, CC2420_FSMSTATE, &state);
2940+ if (ret)
2941+ goto error_ret;
2942+ /* reset has occured prior to this, so there should be no other option */
2943+ if (state != STATE_PDOWN) {
2944+ ret = -EINVAL;
2945+ goto error_ret;
2946+ }
2947+ ret = cc2420_cmd_strobe(lp, CC2420_SXOSCON);
2948+ if (ret)
2949+ goto error_ret;
2950+
2951+ do {
2952+ ret = cc2420_get_status(lp, &status);
2953+ if (ret)
2954+ goto error_ret;
2955+ if (timeout-- <= 0) {
2956+ dev_err(&lp->spi->dev, "oscillator start failed!\n");
2957+ return ret;
2958+ }
2959+ udelay(1);
2960+ } while (!(status & CC2420_STATUS_XOSC16M_STABLE));
2961+
2962+ dev_info(&lp->spi->dev, "oscillator succesfully brought up\n");
2963+
2964+ return 0;
2965+error_ret:
2966+ return ret;
2967+}
2968+
2969+static int __devinit cc2420_probe(struct spi_device *spi)
2970+{
2971+ int ret;
2972+ u16 manidl, manidh;
2973+ struct cc2420_local *lp = kzalloc(sizeof *lp, GFP_KERNEL);
2974+ if (!lp) {
2975+ ret = -ENOMEM;
2976+ goto error_ret;
2977+ }
2978+
2979+ lp->pdata = spi->dev.platform_data;
2980+ if (!lp->pdata) {
2981+ dev_err(&spi->dev, "no platform data\n");
2982+ ret = -EINVAL;
2983+ goto err_free_local;
2984+ }
2985+ spi_set_drvdata(spi, lp);
2986+ mutex_init(&lp->bmux);
2987+ INIT_WORK(&lp->fifop_irqwork, cc2420_fifop_irqwork);
2988+ INIT_WORK(&lp->sfd_irqwork, cc2420_sfd_irqwork);
2989+ spin_lock_init(&lp->lock);
2990+ init_completion(&lp->tx_complete);
2991+
2992+ lp->spi = spi;
2993+ lp->buf = kmalloc(3*sizeof *lp->buf, GFP_KERNEL);
2994+ if (!lp->buf) {
2995+ ret = -ENOMEM;
2996+ goto err_free_local;
2997+ }
2998+
2999+ /* Request all the gpio's */
3000+ ret = gpio_request(lp->pdata->fifo, "fifo");
3001+ if (ret)
3002+ goto err_free_buf;
3003+ ret = gpio_request(lp->pdata->cca, "cca");
3004+ if (ret)
3005+ goto err_free_gpio_fifo;
3006+#if 0
3007+ /* This is causing problems as fifop is gpio 0 ? */
3008+ ret = gpio_request(lp->pdata->fifop, "fifop");
3009+ if (ret)
3010+ goto err_free_gpio_cca;
3011+#endif
3012+ ret = gpio_request(lp->pdata->sfd, "sfd");
3013+ if (ret)
3014+ goto err_free_gpio_fifop;
3015+ ret = gpio_request(lp->pdata->reset, "reset");
3016+ if (ret)
3017+ goto err_free_gpio_sfd;
3018+ ret = gpio_request(lp->pdata->vreg, "vreg");
3019+ if (ret)
3020+ goto err_free_gpio_reset;
3021+ /* Configure the gpios appropriately */
3022+
3023+ /* Enable the voltage regulator */
3024+ ret = gpio_direction_output(lp->pdata->vreg, 1);
3025+ if (ret)
3026+ goto err_free_gpio_reset;
3027+ udelay(600); /* Time for regulator to power up */
3028+ /* Toggle the reset */
3029+ ret = gpio_direction_output(lp->pdata->reset, 0);
3030+ if (ret)
3031+ goto err_disable_vreg;
3032+ udelay(10); /* no idea how long this should be? */
3033+ ret = gpio_direction_output(lp->pdata->reset, 1);
3034+ if (ret)
3035+ goto err_disable_vreg;
3036+ udelay(10);
3037+
3038+ ret = gpio_direction_input(lp->pdata->cca);
3039+ if (ret)
3040+ goto err_disable_vreg;
3041+ ret = gpio_direction_input(lp->pdata->fifo);
3042+ if (ret)
3043+ goto err_disable_vreg;
3044+ ret = gpio_direction_input(lp->pdata->fifop);
3045+ if (ret)
3046+ goto err_disable_vreg;
3047+ ret = gpio_direction_input(lp->pdata->sfd);
3048+ if (ret)
3049+ goto err_disable_vreg;
3050+
3051+
3052+ /* Check this is actually a cc2420 */
3053+ ret = cc2420_read_16_bit_reg(lp, CC2420_MANFIDL, &manidl);
3054+ if (ret)
3055+ goto err_free_gpio_vreg;
3056+ ret = cc2420_read_16_bit_reg(lp, CC2420_MANFIDH, &manidh);
3057+ if (ret)
3058+ goto err_free_gpio_vreg;
3059+ if (manidh != CC2420_MANFIDHIGH || manidl != CC2420_MANFIDLOW) {
3060+ dev_err(&spi->dev, "Incorrect manufacturer id %x%x\n", manidh, manidl);
3061+ ret = -ENODEV;
3062+ goto err_free_gpio_vreg;
3063+ }
3064+ /* TODO: make it more readable */
3065+ dev_info(&lp->spi->dev, "Found Chipcon CC2420\n");
3066+ dev_info(&lp->spi->dev, "Manufacturer ID:%x Version:%x Partnum:%x\n",
3067+ manidl & 0x0FFF, manidh >> 12, manidl >> 12);
3068+
3069+ ret = cc2420_hw_init(lp);
3070+ if (ret)
3071+ goto err_disable_vreg;
3072+
3073+ lp->fifop_irq = gpio_to_irq(lp->pdata->fifop);
3074+ lp->sfd_irq = gpio_to_irq(lp->pdata->sfd);
3075+
3076+ ret = request_irq(lp->fifop_irq,
3077+ cc2420_isr,
3078+ IRQF_TRIGGER_RISING | IRQF_SHARED,
3079+ dev_name(&spi->dev),
3080+ lp);
3081+ if (ret) {
3082+ dev_err(&spi->dev, "could not get fifop irq?\n");
3083+ goto err_free_fifop_irq;
3084+ }
3085+
3086+ ret = request_irq(lp->sfd_irq,
3087+ cc2420_isr,
3088+ IRQF_TRIGGER_FALLING,
3089+ dev_name(&spi->dev),
3090+ lp);
3091+ if (ret) {
3092+ dev_err(&spi->dev, "could not get sfd irq?\n");
3093+ goto err_free_sfd_irq;
3094+ }
3095+
3096+ dev_info(&lp->spi->dev, "Set fifo threshold to 127\n");
3097+ cc2420_write_16_bit_reg_partial(lp, CC2420_IOCFG0, 127, CC2420_FIFOP_THR_MASK);
3098+ ret = cc2420_register(lp);
3099+ if (ret)
3100+ goto err_free_sfd_irq;
3101+
3102+ return 0;
3103+err_free_sfd_irq:
3104+ free_irq(lp->sfd_irq, lp);
3105+err_free_fifop_irq:
3106+ free_irq(lp->fifop_irq, lp);
3107+err_disable_vreg:
3108+ gpio_set_value(lp->pdata->vreg, 0);
3109+err_free_gpio_vreg:
3110+ gpio_free(lp->pdata->vreg);
3111+err_free_gpio_reset:
3112+ gpio_free(lp->pdata->reset);
3113+err_free_gpio_sfd:
3114+ gpio_free(lp->pdata->sfd);
3115+err_free_gpio_fifop:
3116+ gpio_free(lp->pdata->fifop);
3117+//err_free_gpio_cca:
3118+// gpio_free(lp->pdata->cca);
3119+err_free_gpio_fifo:
3120+ gpio_free(lp->pdata->fifo);
3121+err_free_buf:
3122+ kfree(lp->buf);
3123+err_free_local:
3124+ kfree(lp);
3125+error_ret:
3126+ return ret;
3127+}
3128+
3129+static int __devexit cc2420_remove(struct spi_device *spi)
3130+{
3131+ struct cc2420_local *lp = spi_get_drvdata(spi);
3132+
3133+ cc2420_unregister(lp);
3134+ free_irq(lp->fifop_irq, lp);
3135+ free_irq(lp->sfd_irq, lp);
3136+ flush_work(&lp->fifop_irqwork);
3137+ flush_work(&lp->sfd_irqwork);
3138+ gpio_free(lp->pdata->vreg);
3139+ gpio_free(lp->pdata->reset);
3140+ gpio_free(lp->pdata->sfd);
3141+ gpio_free(lp->pdata->fifop);
3142+ gpio_free(lp->pdata->cca);
3143+ gpio_free(lp->pdata->fifo);
3144+ kfree(lp->buf);
3145+ kfree(lp);
3146+
3147+ return 0;
3148+}
3149+
3150+static struct spi_driver cc2420_driver = {
3151+ .driver = {
3152+ .name = "cc2420",
3153+ .owner = THIS_MODULE,
3154+ },
3155+ .probe = cc2420_probe,
3156+ .remove = __devexit_p(cc2420_remove),
3157+};
3158+
3159+static int __init cc2420_init(void)
3160+{
3161+ return spi_register_driver(&cc2420_driver);
3162+}
3163+module_init(cc2420_init);
3164+
3165+static void __exit cc2420_exit(void)
3166+{
3167+ spi_unregister_driver(&cc2420_driver);
3168+}
3169+module_exit(cc2420_exit);
3170+MODULE_LICENSE("GPL v2");
3171diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
3172index a5a49a1..1170074 100644
3173--- a/drivers/ieee802154/fakehard.c
3174@@ -259,7 +259,7 @@ static struct ieee802154_mlme_ops fake_mlme = {
3175     .start_req = fake_start_req,
3176     .scan_req = fake_scan_req,
3177
3178- .get_phy = fake_get_phy,
3179+ .wpan_ops.get_phy = fake_get_phy,
3180
3181     .get_pan_id = fake_get_pan_id,
3182     .get_short_addr = fake_get_short_addr,
3183@@ -370,8 +370,6 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
3184         return -ENOMEM;
3185     }
3186
3187- phy->dev.platform_data = dev;
3188-
3189     memcpy(dev->dev_addr, "\xba\xbe\xca\xfe\xde\xad\xbe\xef",
3190             dev->addr_len);
3191     memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
3192@@ -393,6 +391,16 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
3193     priv = netdev_priv(dev);
3194     priv->phy = phy;
3195
3196+ /*
3197+ * If the name is a format string the caller wants us to do a
3198+ * name allocation.
3199+ */
3200+ if (strchr(dev->name, '%')) {
3201+ err = dev_alloc_name(dev, dev->name);
3202+ if (err < 0)
3203+ goto out;
3204+ }
3205+
3206     wpan_phy_set_dev(phy, &pdev->dev);
3207     SET_NETDEV_DEV(dev, &phy->dev);
3208
3209diff --git a/drivers/ieee802154/fakelb.c b/drivers/ieee802154/fakelb.c
3210new file mode 100644
3211index 0000000..ae6e53f
3212--- /dev/null
3213@@ -0,0 +1,311 @@
3214+/*
3215+ * Loopback IEEE 802.15.4 interface
3216+ *
3217+ * Copyright 2007, 2008 Siemens AG
3218+ *
3219+ * This program is free software; you can redistribute it and/or modify
3220+ * it under the terms of the GNU General Public License version 2
3221+ * as published by the Free Software Foundation.
3222+ *
3223+ * This program is distributed in the hope that it will be useful,
3224+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3225+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3226+ * GNU General Public License for more details.
3227+ *
3228+ * You should have received a copy of the GNU General Public License along
3229+ * with this program; if not, write to the Free Software Foundation, Inc.,
3230+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3231+ *
3232+ * Written by:
3233+ * Sergey Lapin <slapin@ossfans.org>
3234+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
3235+ */
3236+
3237+#include <linux/module.h>
3238+#include <linux/timer.h>
3239+#include <linux/platform_device.h>
3240+#include <linux/netdevice.h>
3241+#include <linux/spinlock.h>
3242+#include <net/mac802154.h>
3243+#include <net/wpan-phy.h>
3244+
3245+struct fake_dev_priv {
3246+ struct ieee802154_dev *dev;
3247+
3248+ struct list_head list;
3249+ struct fake_priv *fake;
3250+
3251+ unsigned int working:1;
3252+};
3253+
3254+struct fake_priv {
3255+ struct list_head list;
3256+ rwlock_t lock;
3257+};
3258+
3259+static int
3260+hw_ed(struct ieee802154_dev *dev, u8 *level)
3261+{
3262+ pr_debug("%s\n", __func__);
3263+ might_sleep();
3264+ BUG_ON(!level);
3265+ *level = 0xbe;
3266+ return 0;
3267+}
3268+
3269+static int
3270+hw_channel(struct ieee802154_dev *dev, int page, int channel)
3271+{
3272+ pr_debug("%s %d\n", __func__, channel);
3273+ might_sleep();
3274+ dev->phy->current_page = page;
3275+ dev->phy->current_channel = channel;
3276+ return 0;
3277+}
3278+
3279+static void
3280+hw_deliver(struct fake_dev_priv *priv, struct sk_buff *skb)
3281+{
3282+ struct sk_buff *newskb;
3283+
3284+ if (!priv->working)
3285+ return;
3286+
3287+ newskb = pskb_copy(skb, GFP_ATOMIC);
3288+
3289+ ieee802154_rx_irqsafe(priv->dev, newskb, 0xcc);
3290+}
3291+
3292+static int
3293+hw_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
3294+{
3295+ struct fake_dev_priv *priv = dev->priv;
3296+ struct fake_priv *fake = priv->fake;
3297+
3298+ might_sleep();
3299+
3300+ read_lock_bh(&fake->lock);
3301+ if (priv->list.next == priv->list.prev) {
3302+ /* we are the only one device */
3303+ hw_deliver(priv, skb);
3304+ } else {
3305+ struct fake_dev_priv *dp;
3306+ list_for_each_entry(dp, &priv->fake->list, list)
3307+ if (dp != priv &&
3308+ dp->dev->phy->current_channel ==
3309+ priv->dev->phy->current_channel)
3310+ hw_deliver(dp, skb);
3311+ }
3312+ read_unlock_bh(&fake->lock);
3313+
3314+ return 0;
3315+}
3316+
3317+static int
3318+hw_start(struct ieee802154_dev *dev) {
3319+ struct fake_dev_priv *priv = dev->priv;
3320+
3321+ if (priv->working)
3322+ return -EBUSY;
3323+
3324+ priv->working = 1;
3325+
3326+ return 0;
3327+}
3328+
3329+static void
3330+hw_stop(struct ieee802154_dev *dev) {
3331+ struct fake_dev_priv *priv = dev->priv;
3332+
3333+ priv->working = 0;
3334+}
3335+
3336+static struct ieee802154_ops fake_ops = {
3337+ .owner = THIS_MODULE,
3338+ .xmit = hw_xmit,
3339+ .ed = hw_ed,
3340+ .set_channel = hw_channel,
3341+ .start = hw_start,
3342+ .stop = hw_stop,
3343+};
3344+
3345+static int ieee802154fake_add_priv(struct device *dev, struct fake_priv *fake)
3346+{
3347+ struct fake_dev_priv *priv;
3348+ int err = -ENOMEM;
3349+ struct ieee802154_dev *ieee;
3350+
3351+ ieee = ieee802154_alloc_device(sizeof(*priv), &fake_ops);
3352+ if (!dev)
3353+ goto err_alloc_dev;
3354+
3355+ priv = ieee->priv;
3356+ priv->dev = ieee;
3357+
3358+ /* 868 MHz BPSK 802.15.4-2003 */
3359+ ieee->phy->channels_supported[0] |= 1;
3360+ /* 915 MHz BPSK 802.15.4-2003 */
3361+ ieee->phy->channels_supported[0] |= 0x7fe;
3362+ /* 2.4 GHz O-QPSK 802.15.4-2003 */
3363+ ieee->phy->channels_supported[0] |= 0x7FFF800;
3364+ /* 868 MHz ASK 802.15.4-2006 */
3365+ ieee->phy->channels_supported[1] |= 1;
3366+ /* 915 MHz ASK 802.15.4-2006 */
3367+ ieee->phy->channels_supported[1] |= 0x7fe;
3368+ /* 868 MHz O-QPSK 802.15.4-2006 */
3369+ ieee->phy->channels_supported[2] |= 1;
3370+ /* 915 MHz O-QPSK 802.15.4-2006 */
3371+ ieee->phy->channels_supported[2] |= 0x7fe;
3372+ /* 2.4 GHz CSS 802.15.4a-2007 */
3373+ ieee->phy->channels_supported[3] |= 0x3fff;
3374+ /* UWB Sub-gigahertz 802.15.4a-2007 */
3375+ ieee->phy->channels_supported[4] |= 1;
3376+ /* UWB Low band 802.15.4a-2007 */
3377+ ieee->phy->channels_supported[4] |= 0x1e;
3378+ /* UWB High band 802.15.4a-2007 */
3379+ ieee->phy->channels_supported[4] |= 0xffe0;
3380+ /* 750 MHz O-QPSK 802.15.4c-2009 */
3381+ ieee->phy->channels_supported[5] |= 0xf;
3382+ /* 750 MHz MPSK 802.15.4c-2009 */
3383+ ieee->phy->channels_supported[5] |= 0xf0;
3384+ /* 950 MHz BPSK 802.15.4d-2009 */
3385+ ieee->phy->channels_supported[6] |= 0x3ff;
3386+ /* 950 MHz GFSK 802.15.4d-2009 */
3387+ ieee->phy->channels_supported[6] |= 0x3ffc00;
3388+
3389+
3390+ INIT_LIST_HEAD(&priv->list);
3391+ priv->fake = fake;
3392+
3393+ ieee->parent = dev;
3394+
3395+ err = ieee802154_register_device(ieee);
3396+ if (err)
3397+ goto err_reg;
3398+
3399+ write_lock_bh(&fake->lock);
3400+ list_add_tail(&priv->list, &fake->list);
3401+ write_unlock_bh(&fake->lock);
3402+
3403+ return 0;
3404+
3405+err_reg:
3406+ ieee802154_free_device(priv->dev);
3407+err_alloc_dev:
3408+ return err;
3409+}
3410+
3411+static void ieee802154fake_del_priv(struct fake_dev_priv *priv)
3412+{
3413+ write_lock_bh(&priv->fake->lock);
3414+ list_del(&priv->list);
3415+ write_unlock_bh(&priv->fake->lock);
3416+
3417+ ieee802154_unregister_device(priv->dev);
3418+ ieee802154_free_device(priv->dev);
3419+}
3420+
3421+static ssize_t
3422+adddev_store(struct device *dev, struct device_attribute *attr,
3423+ const char *buf, size_t n)
3424+{
3425+ struct platform_device *pdev = to_platform_device(dev);
3426+ struct fake_priv *priv = platform_get_drvdata(pdev);
3427+ int err;
3428+
3429+ err = ieee802154fake_add_priv(dev, priv);
3430+ if (err)
3431+ return err;
3432+ return n;
3433+}
3434+
3435+static DEVICE_ATTR(adddev, 0200, NULL, adddev_store);
3436+
3437+static struct attribute *fake_attrs[] = {
3438+ &dev_attr_adddev.attr,
3439+ NULL,
3440+};
3441+
3442+static struct attribute_group fake_group = {
3443+ .name = NULL /* fake */,
3444+ .attrs = fake_attrs,
3445+};
3446+
3447+
3448+static int __devinit ieee802154fake_probe(struct platform_device *pdev)
3449+{
3450+ struct fake_priv *priv;
3451+ struct fake_dev_priv *dp;
3452+
3453+ int err = -ENOMEM;
3454+ priv = kzalloc(sizeof(struct fake_priv), GFP_KERNEL);
3455+ if (!priv)
3456+ goto err_alloc;
3457+
3458+ INIT_LIST_HEAD(&priv->list);
3459+ rwlock_init(&priv->lock);
3460+
3461+ err = sysfs_create_group(&pdev->dev.kobj, &fake_group);
3462+ if (err)
3463+ goto err_grp;
3464+
3465+ err = ieee802154fake_add_priv(&pdev->dev, priv);
3466+ if (err < 0)
3467+ goto err_slave;
3468+
3469+ platform_set_drvdata(pdev, priv);
3470+ dev_info(&pdev->dev, "Added ieee802154 hardware\n");
3471+ return 0;
3472+
3473+err_slave:
3474+ list_for_each_entry(dp, &priv->list, list)
3475+ ieee802154fake_del_priv(dp);
3476+ sysfs_remove_group(&pdev->dev.kobj, &fake_group);
3477+err_grp:
3478+ kfree(priv);
3479+err_alloc:
3480+ return err;
3481+}
3482+
3483+static int __devexit ieee802154fake_remove(struct platform_device *pdev)
3484+{
3485+ struct fake_priv *priv = platform_get_drvdata(pdev);
3486+ struct fake_dev_priv *dp, *temp;
3487+
3488+ list_for_each_entry_safe(dp, temp, &priv->list, list)
3489+ ieee802154fake_del_priv(dp);
3490+ sysfs_remove_group(&pdev->dev.kobj, &fake_group);
3491+ kfree(priv);
3492+ return 0;
3493+}
3494+
3495+static struct platform_device *ieee802154fake_dev;
3496+
3497+static struct platform_driver ieee802154fake_driver = {
3498+ .probe = ieee802154fake_probe,
3499+ .remove = __devexit_p(ieee802154fake_remove),
3500+ .driver = {
3501+ .name = "ieee802154fakelb",
3502+ .owner = THIS_MODULE,
3503+ },
3504+};
3505+
3506+static __init int fake_init(void)
3507+{
3508+ ieee802154fake_dev = platform_device_register_simple(
3509+ "ieee802154fakelb", -1, NULL, 0);
3510+ return platform_driver_register(&ieee802154fake_driver);
3511+}
3512+
3513+static __exit void fake_exit(void)
3514+{
3515+ platform_driver_unregister(&ieee802154fake_driver);
3516+ platform_device_unregister(ieee802154fake_dev);
3517+}
3518+
3519+module_init(fake_init);
3520+module_exit(fake_exit);
3521+MODULE_LICENSE("GPL");
3522+MODULE_AUTHOR("Dmitry Eremin-Solenikov, Sergey Lapin");
3523+
3524+
3525diff --git a/drivers/ieee802154/serial.c b/drivers/ieee802154/serial.c
3526new file mode 100644
3527index 0000000..6981d0e
3528--- /dev/null
3529@@ -0,0 +1,1047 @@
3530+/*
3531+ * ZigBee TTY line discipline.
3532+ *
3533+ * Provides interface between ZigBee stack and IEEE 802.15.4 compatible
3534+ * firmware over serial line. Communication protocol is described below.
3535+ *
3536+ * Copyright (C) 2007, 2008, 2009 Siemens AG
3537+ *
3538+ * This program is free software; you can redistribute it and/or modify
3539+ * it under the terms of the GNU General Public License version 2
3540+ * as published by the Free Software Foundation.
3541+ *
3542+ * This program is distributed in the hope that it will be useful,
3543+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3544+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3545+ * GNU General Public License for more details.
3546+ *
3547+ * You should have received a copy of the GNU General Public License along
3548+ * with this program; if not, write to the Free Software Foundation, Inc.,
3549+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3550+ *
3551+ * Written by:
3552+ * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
3553+ * Maxim Osipov <maxim.osipov@siemens.com>
3554+ * Sergey Lapin <slapin@ossfans.org>
3555+ */
3556+
3557+#include <linux/module.h>
3558+#include <linux/kernel.h>
3559+#include <linux/completion.h>
3560+#include <linux/tty.h>
3561+#include <linux/skbuff.h>
3562+#include <linux/sched.h>
3563+#include <net/mac802154.h>
3564+#include <net/wpan-phy.h>
3565+
3566+
3567+/* NOTE: be sure to use here the same values as in the firmware */
3568+#define START_BYTE1 'z'
3569+#define START_BYTE2 'b'
3570+#define MAX_DATA_SIZE 127
3571+
3572+#define IDLE_MODE 0x00
3573+#define RX_MODE 0x02
3574+#define TX_MODE 0x03
3575+#define FORCE_TRX_OFF 0xF0
3576+
3577+#define STATUS_SUCCESS 0
3578+#define STATUS_RX_ON 1
3579+#define STATUS_TX_ON 2
3580+#define STATUS_TRX_OFF 3
3581+#define STATUS_IDLE 4
3582+#define STATUS_BUSY 5
3583+#define STATUS_BUSY_RX 6
3584+#define STATUS_BUSY_TX 7
3585+#define STATUS_ERR 8
3586+
3587+#define STATUS_WAIT ((u8) -1) /* waiting for the answer */
3588+
3589+/* We re-use PPP ioctl for our purposes */
3590+#define PPPIOCGUNIT _IOR('t', 86, int) /* get ppp unit number */
3591+
3592+/*
3593+ * The following messages are used to control ZigBee firmware.
3594+ * All communication has request/response format,
3595+ * except of asynchronous incoming data stream (DATA_RECV_* messages).
3596+ */
3597+enum {
3598+ NO_ID = 0, /* means no pending id */
3599+
3600+ /* Driver to Firmware */
3601+ CMD_OPEN = 0x01, /* u8 id */
3602+ CMD_CLOSE = 0x02, /* u8 id */
3603+ CMD_SET_CHANNEL = 0x04, /* u8 id, u8 channel */
3604+ CMD_ED = 0x05, /* u8 id */
3605+ CMD_CCA = 0x06, /* u8 id */
3606+ CMD_SET_STATE = 0x07, /* u8 id, u8 flag */
3607+ DATA_XMIT_BLOCK = 0x09, /* u8 id, u8 len, u8 data[len] */
3608+ RESP_RECV_BLOCK = 0x0b, /* u8 id, u8 status */
3609+ CMD_ADDRESS = 0x0d, /* u8 id */
3610+
3611+ /* Firmware to Driver */
3612+ RESP_OPEN = 0x81, /* u8 id, u8 status */
3613+ RESP_CLOSE = 0x82, /* u8 id, u8 status */
3614+ RESP_SET_CHANNEL = 0x84, /* u8 id, u8 status */
3615+ RESP_ED = 0x85, /* u8 id, u8 status, u8 level */
3616+ RESP_CCA = 0x86, /* u8 id, u8 status */
3617+ RESP_SET_STATE = 0x87, /* u8 id, u8 status */
3618+ RESP_XMIT_BLOCK = 0x89, /* u8 id, u8 status */
3619+ DATA_RECV_BLOCK = 0x8b, /* u8 id, u8 lq, u8 len, u8 data[len] */
3620+ RESP_ADDRESS = 0x8d, /* u8 id, u8 status, u8 u8 u8 u8 u8 u8 u8 u8 address */
3621+};
3622+
3623+enum {
3624+ STATE_WAIT_START1,
3625+ STATE_WAIT_START2,
3626+ STATE_WAIT_COMMAND,
3627+ STATE_WAIT_PARAM1,
3628+ STATE_WAIT_PARAM2,
3629+ STATE_WAIT_DATA
3630+};
3631+
3632+struct zb_device {
3633+ /* Relative devices */
3634+ struct tty_struct *tty;
3635+ struct ieee802154_dev *dev;
3636+
3637+ /* locks the ldisc for the command */
3638+ struct mutex mutex;
3639+
3640+ /* command completition */
3641+ wait_queue_head_t wq;
3642+ u8 status;
3643+ u8 ed;
3644+
3645+ /* Internal state */
3646+ struct completion open_done;
3647+ unsigned char opened;
3648+ u8 pending_id;
3649+ unsigned int pending_size;
3650+ u8 *pending_data;
3651+ /* FIXME: WE NEED LOCKING!!! */
3652+
3653+ /* Command (rx) processing */
3654+ int state;
3655+ unsigned char id;
3656+ unsigned char param1;
3657+ unsigned char param2;
3658+ unsigned char index;
3659+ unsigned char data[MAX_DATA_SIZE];
3660+};
3661+
3662+/*****************************************************************************
3663+ * ZigBee serial device protocol handling
3664+ *****************************************************************************/
3665+static int _open_dev(struct zb_device *zbdev);
3666+
3667+static int
3668+_send_pending_data(struct zb_device *zbdev)
3669+{
3670+ struct tty_struct *tty;
3671+
3672+ BUG_ON(!zbdev);
3673+ tty = zbdev->tty;
3674+ if (!tty)
3675+ return -ENODEV;
3676+
3677+ zbdev->status = STATUS_WAIT;
3678+
3679+ /* Debug info */
3680+ printk(KERN_INFO "%s, %d bytes\n", __func__,
3681+ zbdev->pending_size);
3682+#ifdef DEBUG
3683+ print_hex_dump_bytes("send_pending_data ", DUMP_PREFIX_NONE,
3684+ zbdev->pending_data, zbdev->pending_size);
3685+#endif
3686+
3687+ if (tty->driver->ops->write(tty, zbdev->pending_data,
3688+ zbdev->pending_size) != zbdev->pending_size) {
3689+ printk(KERN_ERR "%s: device write failed\n", __func__);
3690+ return -1;
3691+ }
3692+
3693+ return 0;
3694+}
3695+
3696+static int
3697+send_cmd(struct zb_device *zbdev, u8 id)
3698+{
3699+ u8 len = 0;
3700+ /* 4 because of 2 start bytes, id and optional extra */
3701+ u8 buf[4];
3702+
3703+ /* Check arguments */
3704+ BUG_ON(!zbdev);
3705+
3706+ if (!zbdev->opened) {
3707+ if (!_open_dev(zbdev))
3708+ return -EAGAIN;
3709+ }
3710+
3711+ pr_debug("%s(): id = %u\n", __func__, id);
3712+ if (zbdev->pending_size) {
3713+ printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
3714+ __func__, zbdev->pending_id);
3715+ BUG();
3716+ }
3717+
3718+ /* Prepare a message */
3719+ buf[len++] = START_BYTE1;
3720+ buf[len++] = START_BYTE2;
3721+ buf[len++] = id;
3722+
3723+ zbdev->pending_id = id;
3724+ zbdev->pending_size = len;
3725+ zbdev->pending_data = kzalloc(zbdev->pending_size, GFP_KERNEL);
3726+ if (!zbdev->pending_data) {
3727+ printk(KERN_ERR "%s(): unable to allocate memory\n", __func__);
3728+ zbdev->pending_id = 0;
3729+ zbdev->pending_size = 0;
3730+ return -ENOMEM;
3731+ }
3732+ memcpy(zbdev->pending_data, buf, len);
3733+
3734+ return _send_pending_data(zbdev);
3735+}
3736+
3737+static int
3738+send_cmd2(struct zb_device *zbdev, u8 id, u8 extra)
3739+{
3740+ u8 len = 0;
3741+ /* 4 because of 2 start bytes, id and optional extra */
3742+ u8 buf[4];
3743+
3744+ /* Check arguments */
3745+ BUG_ON(!zbdev);
3746+
3747+ if (!zbdev->opened) {
3748+ if (!_open_dev(zbdev))
3749+ return -EAGAIN;
3750+ }
3751+
3752+ pr_debug("%s(): id = %u\n", __func__, id);
3753+ if (zbdev->pending_size) {
3754+ printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
3755+ __func__, zbdev->pending_id);
3756+ BUG();
3757+ }
3758+
3759+ /* Prepare a message */
3760+ buf[len++] = START_BYTE1;
3761+ buf[len++] = START_BYTE2;
3762+ buf[len++] = id;
3763+ buf[len++] = extra;
3764+
3765+ zbdev->pending_id = id;
3766+ zbdev->pending_size = len;
3767+ zbdev->pending_data = kzalloc(zbdev->pending_size, GFP_KERNEL);
3768+ if (!zbdev->pending_data) {
3769+ printk(KERN_ERR "%s(): unable to allocate memory\n", __func__);
3770+ zbdev->pending_id = 0;
3771+ zbdev->pending_size = 0;
3772+ return -ENOMEM;
3773+ }
3774+ memcpy(zbdev->pending_data, buf, len);
3775+
3776+ return _send_pending_data(zbdev);
3777+}
3778+
3779+static int
3780+send_block(struct zb_device *zbdev, u8 len, u8 *data)
3781+{
3782+ u8 i = 0, buf[4]; /* 4 because of 2 start bytes, id and len */
3783+
3784+ /* Check arguments */
3785+ BUG_ON(!zbdev);
3786+
3787+ if (!zbdev->opened) {
3788+ if (!_open_dev(zbdev))
3789+ return -EAGAIN;
3790+ }
3791+
3792+ pr_debug("%s(): id = %u\n", __func__, DATA_XMIT_BLOCK);
3793+ if (zbdev->pending_size) {
3794+ printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
3795+ __func__, zbdev->pending_id);
3796+ BUG();
3797+ }
3798+
3799+ /* Prepare a message */
3800+ buf[i++] = START_BYTE1;
3801+ buf[i++] = START_BYTE2;
3802+ buf[i++] = DATA_XMIT_BLOCK;
3803+ buf[i++] = len;
3804+
3805+ zbdev->pending_id = DATA_XMIT_BLOCK;
3806+ zbdev->pending_size = i + len;
3807+ zbdev->pending_data = kzalloc(zbdev->pending_size, GFP_KERNEL);
3808+ if (!zbdev->pending_data) {
3809+ printk(KERN_ERR "%s(): unable to allocate memory\n", __func__);
3810+ zbdev->pending_id = 0;
3811+ zbdev->pending_size = 0;
3812+ return -ENOMEM;
3813+ }
3814+ memcpy(zbdev->pending_data, buf, i);
3815+ memcpy(zbdev->pending_data + i, data, len);
3816+
3817+ return _send_pending_data(zbdev);
3818+}
3819+
3820+static void
3821+cleanup(struct zb_device *zbdev)
3822+{
3823+ zbdev->state = STATE_WAIT_START1;
3824+ zbdev->id = 0;
3825+ zbdev->param1 = 0;
3826+ zbdev->param2 = 0;
3827+ zbdev->index = 0;
3828+}
3829+
3830+static int
3831+is_command(unsigned char c)
3832+{
3833+ switch (c) {
3834+ /* ids we can get here: */
3835+ case RESP_OPEN:
3836+ case RESP_CLOSE:
3837+ case RESP_SET_CHANNEL:
3838+ case RESP_ED:
3839+ case RESP_CCA:
3840+ case RESP_SET_STATE:
3841+ case RESP_XMIT_BLOCK:
3842+ case DATA_RECV_BLOCK:
3843+ case RESP_ADDRESS:
3844+ return 1;
3845+ }
3846+ return 0;
3847+}
3848+
3849+static int
3850+_match_pending_id(struct zb_device *zbdev)
3851+{
3852+ return ((CMD_OPEN == zbdev->pending_id &&
3853+ RESP_OPEN == zbdev->id) ||
3854+ (CMD_CLOSE == zbdev->pending_id &&
3855+ RESP_CLOSE == zbdev->id) ||
3856+ (CMD_SET_CHANNEL == zbdev->pending_id &&
3857+ RESP_SET_CHANNEL == zbdev->id) ||
3858+ (CMD_ED == zbdev->pending_id &&
3859+ RESP_ED == zbdev->id) ||
3860+ (CMD_CCA == zbdev->pending_id &&
3861+ RESP_CCA == zbdev->id) ||
3862+ (CMD_SET_STATE == zbdev->pending_id &&
3863+ RESP_SET_STATE == zbdev->id) ||
3864+ (DATA_XMIT_BLOCK == zbdev->pending_id &&
3865+ RESP_XMIT_BLOCK == zbdev->id) ||
3866+ (DATA_RECV_BLOCK == zbdev->id) ||
3867+ (CMD_ADDRESS == zbdev->pending_id &&
3868+ RESP_ADDRESS == zbdev->id));
3869+}
3870+
3871+static void serial_net_rx(struct zb_device *zbdev)
3872+{
3873+ /* zbdev->param1 is LQI
3874+ * zbdev->param2 is length of data
3875+ * zbdev->data is data itself
3876+ */
3877+ struct sk_buff *skb;
3878+ skb = alloc_skb(zbdev->param2, GFP_ATOMIC);
3879+ skb_put(skb, zbdev->param2);
3880+ skb_copy_to_linear_data(skb, zbdev->data, zbdev->param2);
3881+ ieee802154_rx_irqsafe(zbdev->dev, skb, zbdev->param1);
3882+}
3883+
3884+static void
3885+process_command(struct zb_device *zbdev)
3886+{
3887+ /* Command processing */
3888+ if (!_match_pending_id(zbdev))
3889+ return;
3890+
3891+ if (RESP_OPEN == zbdev->id && STATUS_SUCCESS == zbdev->param1) {
3892+ zbdev->opened = 1;
3893+ pr_debug("Opened device\n");
3894+ complete(&zbdev->open_done);
3895+ /* Input is not processed during output, so
3896+ * using completion is not possible during output.
3897+ * so we need to handle open as any other command
3898+ * and hope for best
3899+ */
3900+ return;
3901+ }
3902+
3903+ if (!zbdev->opened)
3904+ return;
3905+
3906+ zbdev->pending_id = 0;
3907+ kfree(zbdev->pending_data);
3908+ zbdev->pending_data = NULL;
3909+ zbdev->pending_size = 0;
3910+ if (zbdev->id != DATA_RECV_BLOCK) {
3911+ /* XXX: w/around for old FW, REMOVE */
3912+ if (zbdev->param1 == STATUS_IDLE)
3913+ zbdev->status = STATUS_SUCCESS;
3914+ else
3915+ zbdev->status = zbdev->param1;
3916+ }
3917+
3918+ switch (zbdev->id) {
3919+ case RESP_ED:
3920+ zbdev->ed = zbdev->param2;
3921+ break;
3922+ case DATA_RECV_BLOCK:
3923+ pr_debug("Received block, lqi %02x, len %02x\n",
3924+ zbdev->param1, zbdev->param2);
3925+ /* zbdev->param1 is LQ, zbdev->param2 is length */
3926+ serial_net_rx(zbdev);
3927+ break;
3928+ case RESP_ADDRESS:
3929+ pr_debug("Received address, %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
3930+ zbdev->data[0], zbdev->data[1], zbdev->data[2], zbdev->data[3],
3931+ zbdev->data[4], zbdev->data[5], zbdev->data[6], zbdev->data[7]);
3932+ break;
3933+ }
3934+
3935+ wake_up(&zbdev->wq);
3936+}
3937+
3938+static void
3939+process_char(struct zb_device *zbdev, unsigned char c)
3940+{
3941+ /* Data processing */
3942+ switch (zbdev->state) {
3943+ case STATE_WAIT_START1:
3944+ if (START_BYTE1 == c)
3945+ zbdev->state = STATE_WAIT_START2;
3946+ break;
3947+
3948+ case STATE_WAIT_START2:
3949+ if (START_BYTE2 == c)
3950+ zbdev->state = STATE_WAIT_COMMAND;
3951+ else
3952+ cleanup(zbdev);
3953+ break;
3954+
3955+ case STATE_WAIT_COMMAND:
3956+ if (is_command(c)) {
3957+ zbdev->id = c;
3958+ zbdev->state = STATE_WAIT_PARAM1;
3959+ } else {
3960+ cleanup(zbdev);
3961+ printk(KERN_ERR "%s, unexpected command id: %x\n",
3962+ __func__, c);
3963+ }
3964+ break;
3965+
3966+ case STATE_WAIT_PARAM1:
3967+ zbdev->param1 = c;
3968+ if ((RESP_ED == zbdev->id) || (DATA_RECV_BLOCK == zbdev->id))
3969+ zbdev->state = STATE_WAIT_PARAM2;
3970+ else if (RESP_ADDRESS == zbdev->id) {
3971+ zbdev->param2 = 8;
3972+ zbdev->state = STATE_WAIT_DATA;
3973+ } else {
3974+ process_command(zbdev);
3975+ cleanup(zbdev);
3976+ }
3977+ break;
3978+
3979+ case STATE_WAIT_PARAM2:
3980+ zbdev->param2 = c;
3981+ if (RESP_ED == zbdev->id) {
3982+ process_command(zbdev);
3983+ cleanup(zbdev);
3984+ } else if (DATA_RECV_BLOCK == zbdev->id)
3985+ zbdev->state = STATE_WAIT_DATA;
3986+ else
3987+ cleanup(zbdev);
3988+ break;
3989+
3990+ case STATE_WAIT_DATA:
3991+ if (zbdev->index < sizeof(zbdev->data)) {
3992+ zbdev->data[zbdev->index] = c;
3993+ zbdev->index++;
3994+ /*
3995+ * Pending data is received,
3996+ * param2 is length for DATA_RECV_BLOCK
3997+ */
3998+ if (zbdev->index == zbdev->param2) {
3999+ process_command(zbdev);
4000+ cleanup(zbdev);
4001+ }
4002+ } else {
4003+ printk(KERN_ERR "%s(): data size is greater "
4004+ "than buffer available\n", __func__);
4005+ cleanup(zbdev);
4006+ }
4007+ break;
4008+
4009+ default:
4010+ cleanup(zbdev);
4011+ }
4012+}
4013+
4014+/*****************************************************************************
4015+ * Device operations for IEEE 802.15.4 PHY side interface ZigBee stack
4016+ *****************************************************************************/
4017+
4018+static int _open_dev(struct zb_device *zbdev)
4019+{
4020+ int retries;
4021+ u8 len = 0;
4022+ /* 4 because of 2 start bytes, id and optional extra */
4023+ u8 buf[4];
4024+
4025+ /* Check arguments */
4026+ BUG_ON(!zbdev);
4027+ if (zbdev->opened)
4028+ return 1;
4029+
4030+ pr_debug("%s()\n", __func__);
4031+ if (zbdev->pending_size) {
4032+ printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
4033+ __func__, zbdev->pending_id);
4034+ BUG();
4035+ }
4036+
4037+ /* Prepare a message */
4038+ buf[len++] = START_BYTE1;
4039+ buf[len++] = START_BYTE2;
4040+ buf[len++] = CMD_OPEN;
4041+
4042+ zbdev->pending_id = CMD_OPEN;
4043+ zbdev->pending_size = len;
4044+ zbdev->pending_data = kzalloc(zbdev->pending_size, GFP_KERNEL);
4045+ if (!zbdev->pending_data) {
4046+ printk(KERN_ERR "%s(): unable to allocate memory\n", __func__);
4047+ zbdev->pending_id = 0;
4048+ zbdev->pending_size = 0;
4049+ return -ENOMEM;
4050+ }
4051+ memcpy(zbdev->pending_data, buf, len);
4052+
4053+ retries = 5;
4054+ while (!zbdev->opened && retries) {
4055+ if (_send_pending_data(zbdev) != 0)
4056+ return 0;
4057+
4058+ /* 3 second before retransmission */
4059+ wait_for_completion_interruptible_timeout(
4060+ &zbdev->open_done, msecs_to_jiffies(1000));
4061+ --retries;
4062+ }
4063+
4064+ zbdev->pending_id = 0;
4065+ kfree(zbdev->pending_data);
4066+ zbdev->pending_data = NULL;
4067+ zbdev->pending_size = 0;
4068+
4069+ if (zbdev->opened) {
4070+ printk(KERN_INFO "Opened connection to device\n");
4071+ return 1;
4072+ }
4073+
4074+ return 0;
4075+}
4076+
4077+/* Valid channels: 1-16 */
4078+static int
4079+ieee802154_serial_set_channel(struct ieee802154_dev *dev, int page, int channel)
4080+{
4081+ struct zb_device *zbdev;
4082+ int ret = 0;
4083+
4084+ pr_debug("%s %d\n", __func__, channel);
4085+
4086+ zbdev = dev->priv;
4087+ if (NULL == zbdev) {
4088+ printk(KERN_ERR "%s: wrong phy\n", __func__);
4089+ return -EINVAL;
4090+ }
4091+
4092+ BUG_ON(page != 0);
4093+ /* Our channels are actually from 11 to 26
4094+ * We have IEEE802.15.4 channel no from 0 to 26.
4095+ * channels 0-10 are not valid for us */
4096+ BUG_ON(channel < 11 || channel > 26);
4097+ /* ... but our crappy firmware numbers channels from 1 to 16
4098+ * which is a mystery. We suould enforce that using PIB API
4099+ * but additional checking here won't kill, and gcc will
4100+ * optimize this stuff anyway. */
4101+ BUG_ON((channel - 10) < 1 && (channel - 10) > 16);
4102+ if (mutex_lock_interruptible(&zbdev->mutex))
4103+ return -EINTR;
4104+ ret = send_cmd2(zbdev, CMD_SET_CHANNEL, channel - 10);
4105+ if (ret)
4106+ goto out;
4107+
4108+ if (wait_event_interruptible_timeout(zbdev->wq,
4109+ zbdev->status != STATUS_WAIT,
4110+ msecs_to_jiffies(1000)) > 0) {
4111+ if (zbdev->status != STATUS_SUCCESS)
4112+ ret = -EBUSY;
4113+ } else
4114+ ret = -EINTR;
4115+
4116+ if (!ret)
4117+ zbdev->dev->phy->current_channel = channel;
4118+out:
4119+ mutex_unlock(&zbdev->mutex);
4120+ pr_debug("%s end\n", __func__);
4121+ return ret;
4122+}
4123+
4124+static int
4125+ieee802154_serial_ed(struct ieee802154_dev *dev, u8 *level)
4126+{
4127+ struct zb_device *zbdev;
4128+ int ret = 0;
4129+
4130+ pr_debug("%s\n", __func__);
4131+
4132+ zbdev = dev->priv;
4133+ if (NULL == zbdev) {
4134+ printk(KERN_ERR "%s: wrong phy\n", __func__);
4135+ return -EINVAL;
4136+ }
4137+
4138+ if (mutex_lock_interruptible(&zbdev->mutex))
4139+ return -EINTR;
4140+
4141+ ret = send_cmd(zbdev, CMD_ED);
4142+ if (ret)
4143+ goto out;
4144+
4145+ if (wait_event_interruptible_timeout(zbdev->wq,
4146+ zbdev->status != STATUS_WAIT,
4147+ msecs_to_jiffies(1000)) > 0) {
4148+ *level = zbdev->ed;
4149+ if (zbdev->status != STATUS_SUCCESS)
4150+ ret = -EBUSY;
4151+ } else
4152+ ret = -ETIMEDOUT;
4153+out:
4154+
4155+ mutex_unlock(&zbdev->mutex);
4156+ pr_debug("%s end\n", __func__);
4157+ return ret;
4158+}
4159+
4160+static int
4161+ieee802154_serial_address(struct ieee802154_dev *dev, u8 addr[IEEE802154_ALEN])
4162+{
4163+ struct zb_device *zbdev;
4164+ int ret = 0;
4165+
4166+ pr_debug("%s\n", __func__);
4167+
4168+ zbdev = dev->priv;
4169+ if (NULL == zbdev) {
4170+ printk(KERN_ERR "%s: wrong phy\n", __func__);
4171+ return -EINVAL;
4172+ }
4173+
4174+ if (mutex_lock_interruptible(&zbdev->mutex))
4175+ return -EINTR;
4176+
4177+ ret = send_cmd(zbdev, CMD_ADDRESS);
4178+ if (ret)
4179+ goto out;
4180+
4181+ if (wait_event_interruptible_timeout(zbdev->wq,
4182+ zbdev->status != STATUS_WAIT,
4183+ msecs_to_jiffies(1000)) > 0) {
4184+ memcpy(addr, zbdev->data, sizeof addr);
4185+ if (zbdev->status != STATUS_SUCCESS)
4186+ ret = -EBUSY;
4187+ } else
4188+ ret = -ETIMEDOUT;
4189+out:
4190+
4191+ mutex_unlock(&zbdev->mutex);
4192+ pr_debug("%s end\n", __func__);
4193+ return ret;
4194+}
4195+
4196+static int
4197+ieee802154_serial_start(struct ieee802154_dev *dev)
4198+{
4199+ struct zb_device *zbdev;
4200+ int ret = 0;
4201+
4202+ pr_debug("%s\n", __func__);
4203+
4204+ zbdev = dev->priv;
4205+ if (NULL == zbdev) {
4206+ printk(KERN_ERR "%s: wrong phy\n", __func__);
4207+ return -EINVAL;
4208+ }
4209+
4210+ if (mutex_lock_interruptible(&zbdev->mutex))
4211+ return -EINTR;
4212+
4213+ ret = send_cmd2(zbdev, CMD_SET_STATE, RX_MODE);
4214+ if (ret)
4215+ goto out;
4216+
4217+ if (wait_event_interruptible_timeout(zbdev->wq,
4218+ zbdev->status != STATUS_WAIT,
4219+ msecs_to_jiffies(1000)) > 0) {
4220+ if (zbdev->status != STATUS_SUCCESS)
4221+ ret = -EBUSY;
4222+ } else
4223+ ret = -ETIMEDOUT;
4224+out:
4225+ mutex_unlock(&zbdev->mutex);
4226+ pr_debug("%s end\n", __func__);
4227+ return ret;
4228+}
4229+
4230+static void
4231+ieee802154_serial_stop(struct ieee802154_dev *dev)
4232+{
4233+ struct zb_device *zbdev;
4234+ pr_debug("%s\n", __func__);
4235+
4236+ zbdev = dev->priv;
4237+ if (NULL == zbdev) {
4238+ printk(KERN_ERR "%s: wrong phy\n", __func__);
4239+ return;
4240+ }
4241+
4242+ if (mutex_lock_interruptible(&zbdev->mutex))
4243+ return;
4244+
4245+
4246+ if (send_cmd2(zbdev, CMD_SET_STATE, FORCE_TRX_OFF) != 0)
4247+ goto out;
4248+
4249+ wait_event_interruptible_timeout(zbdev->wq,
4250+ zbdev->status != STATUS_WAIT,
4251+ msecs_to_jiffies(1000));
4252+out:
4253+ mutex_unlock(&zbdev->mutex);
4254+ pr_debug("%s end\n", __func__);
4255+}
4256+
4257+static int
4258+ieee802154_serial_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
4259+{
4260+ struct zb_device *zbdev;
4261+ int ret;
4262+
4263+ pr_debug("%s\n", __func__);
4264+
4265+ zbdev = dev->priv;
4266+ if (NULL == zbdev) {
4267+ printk(KERN_ERR "%s: wrong phy\n", __func__);
4268+ return -EINVAL;
4269+ }
4270+
4271+ if (mutex_lock_interruptible(&zbdev->mutex))
4272+ return -EINTR;
4273+
4274+ ret = send_cmd(zbdev, CMD_CCA);
4275+ if (ret)
4276+ goto out;
4277+
4278+ if (wait_event_interruptible_timeout(zbdev->wq,
4279+ zbdev->status != STATUS_WAIT,
4280+ msecs_to_jiffies(1000)) > 0) {
4281+ if (zbdev->status != STATUS_SUCCESS) {
4282+ ret = -EBUSY;
4283+ goto out;
4284+ }
4285+ } else {
4286+ ret = -ETIMEDOUT;
4287+ goto out;
4288+ }
4289+
4290+ ret = send_cmd2(zbdev, CMD_SET_STATE, TX_MODE);
4291+ if (ret)
4292+ goto out;
4293+
4294+ if (wait_event_interruptible_timeout(zbdev->wq,
4295+ zbdev->status != STATUS_WAIT,
4296+ msecs_to_jiffies(1000)) > 0) {
4297+ if (zbdev->status != STATUS_SUCCESS) {
4298+ ret = -EBUSY;
4299+ goto out;
4300+ }
4301+ } else {
4302+ ret = -ETIMEDOUT;
4303+ goto out;
4304+ }
4305+
4306+ ret = send_block(zbdev, skb->len, skb->data);
4307+ if (ret)
4308+ goto out;
4309+
4310+ if (wait_event_interruptible_timeout(zbdev->wq,
4311+ zbdev->status != STATUS_WAIT,
4312+ msecs_to_jiffies(1000)) > 0) {
4313+ if (zbdev->status != STATUS_SUCCESS) {
4314+ ret = -EBUSY;
4315+ goto out;
4316+ }
4317+ } else {
4318+ ret = -ETIMEDOUT;
4319+ goto out;
4320+ }
4321+
4322+ ret = send_cmd2(zbdev, CMD_SET_STATE, RX_MODE);
4323+ if (ret)
4324+ goto out;
4325+
4326+ if (wait_event_interruptible_timeout(zbdev->wq,
4327+ zbdev->status != STATUS_WAIT,
4328+ msecs_to_jiffies(1000)) > 0) {
4329+ if (zbdev->status != STATUS_SUCCESS) {
4330+ ret = -EBUSY;
4331+ goto out;
4332+ }
4333+ } else {
4334+ ret = -ETIMEDOUT;
4335+ goto out;
4336+ }
4337+
4338+out:
4339+
4340+ mutex_unlock(&zbdev->mutex);
4341+ pr_debug("%s end\n", __func__);
4342+ return ret;
4343+}
4344+
4345+/*****************************************************************************
4346+ * Line discipline interface for IEEE 802.15.4 serial device
4347+ *****************************************************************************/
4348+
4349+static struct ieee802154_ops serial_ops = {
4350+ .owner = THIS_MODULE,
4351+ .xmit = ieee802154_serial_xmit,
4352+ .ed = ieee802154_serial_ed,
4353+ .set_channel = ieee802154_serial_set_channel,
4354+ .start = ieee802154_serial_start,
4355+ .stop = ieee802154_serial_stop,
4356+ .ieee_addr = ieee802154_serial_address,
4357+};
4358+
4359+/*
4360+ * Called when a tty is put into ZB line discipline. Called in process context.
4361+ * Returns 0 on success.
4362+ */
4363+static int
4364+ieee802154_tty_open(struct tty_struct *tty)
4365+{
4366+ struct zb_device *zbdev = tty->disc_data;
4367+ struct ieee802154_dev *dev;
4368+ int err;
4369+
4370+ pr_debug("Openning ldisc\n");
4371+ if (!capable(CAP_NET_ADMIN))
4372+ return -EPERM;
4373+
4374+ if (tty->disc_data)
4375+ return -EBUSY;
4376+
4377+ dev = ieee802154_alloc_device(sizeof(*zbdev), &serial_ops);
4378+ if (!dev)
4379+ return -ENOMEM;
4380+
4381+ zbdev = dev->priv;
4382+ zbdev->dev = dev;
4383+
4384+ mutex_init(&zbdev->mutex);
4385+ init_completion(&zbdev->open_done);
4386+ init_waitqueue_head(&zbdev->wq);
4387+
4388+ dev->extra_tx_headroom = 0;
4389+ /* only 2.4 GHz band */
4390+ dev->phy->channels_supported[0] = 0x7fff800;
4391+
4392+ dev->flags = IEEE802154_HW_OMIT_CKSUM;
4393+
4394+ dev->parent = tty->dev;
4395+
4396+ zbdev->tty = tty_kref_get(tty);
4397+
4398+ cleanup(zbdev);
4399+
4400+ tty->disc_data = zbdev;
4401+ tty->receive_room = MAX_DATA_SIZE;
4402+
4403+ /* FIXME: why is this needed. Note don't use ldisc_ref here as the
4404+ open path is before the ldisc is referencable */
4405+
4406+ if (tty->ldisc->ops->flush_buffer)
4407+ tty->ldisc->ops->flush_buffer(tty);
4408+ tty_driver_flush_buffer(tty);
4409+
4410+ err = ieee802154_register_device(dev);
4411+ if (err) {
4412+ printk(KERN_ERR "%s: device register failed\n", __func__);
4413+ goto out_free;
4414+ }
4415+
4416+ return 0;
4417+
4418+ ieee802154_unregister_device(zbdev->dev);
4419+
4420+out_free:
4421+ tty->disc_data = NULL;
4422+ tty_kref_put(tty);
4423+ zbdev->tty = NULL;
4424+
4425+ ieee802154_free_device(zbdev->dev);
4426+
4427+ return err;
4428+}
4429+
4430+/*
4431+ * Called when the tty is put into another line discipline or it hangs up. We
4432+ * have to wait for any cpu currently executing in any of the other zb_tty_*
4433+ * routines to finish before we can call zb_tty_close and free the
4434+ * zb_serial_dev struct. This routine must be called from process context, not
4435+ * interrupt or softirq context.
4436+ */
4437+static void
4438+ieee802154_tty_close(struct tty_struct *tty)
4439+{
4440+ struct zb_device *zbdev;
4441+
4442+ zbdev = tty->disc_data;
4443+ if (NULL == zbdev) {
4444+ printk(KERN_WARNING "%s: match is not found\n", __func__);
4445+ return;
4446+ }
4447+
4448+ tty->disc_data = NULL;
4449+ tty_kref_put(tty);
4450+ zbdev->tty = NULL;
4451+
4452+ ieee802154_unregister_device(zbdev->dev);
4453+
4454+ tty_ldisc_flush(tty);
4455+ tty_driver_flush_buffer(tty);
4456+
4457+ ieee802154_free_device(zbdev->dev);
4458+}
4459+
4460+/*
4461+ * Called on tty hangup in process context.
4462+ */
4463+static int
4464+ieee802154_tty_hangup(struct tty_struct *tty)
4465+{
4466+ ieee802154_tty_close(tty);
4467+ return 0;
4468+}
4469+
4470+/*
4471+ * Called in process context only. May be re-entered
4472+ * by multiple ioctl calling threads.
4473+ */
4474+static int
4475+ieee802154_tty_ioctl(struct tty_struct *tty, struct file *file,
4476+ unsigned int cmd, unsigned long arg)
4477+{
4478+ struct zb_device *zbdev;
4479+
4480+ pr_debug("cmd = 0x%x\n", cmd);
4481+
4482+ zbdev = tty->disc_data;
4483+ if (NULL == zbdev) {
4484+ pr_debug("match is not found\n");
4485+ return -EINVAL;
4486+ }
4487+
4488+ switch (cmd) {
4489+ case TCFLSH:
4490+ return tty_perform_flush(tty, arg);
4491+ default:
4492+ /* Try the mode commands */
4493+ return tty_mode_ioctl(tty, file, cmd, arg);
4494+ }
4495+}
4496+
4497+
4498+/*
4499+ * This can now be called from hard interrupt level as well
4500+ * as soft interrupt level or mainline.
4501+ */
4502+static void
4503+ieee802154_tty_receive(struct tty_struct *tty, const unsigned char *buf,
4504+ char *cflags, int count)
4505+{
4506+ struct zb_device *zbdev;
4507+ int i;
4508+
4509+ /* Debug info */
4510+ printk(KERN_INFO "%s, received %d bytes\n", __func__,
4511+ count);
4512+#ifdef DEBUG
4513+ print_hex_dump_bytes("ieee802154_tty_receive ", DUMP_PREFIX_NONE,
4514+ buf, count);
4515+#endif
4516+
4517+ /* Actual processing */
4518+ zbdev = tty->disc_data;
4519+ if (NULL == zbdev) {
4520+ printk(KERN_ERR "%s(): record for tty is not found\n",
4521+ __func__);
4522+ return;
4523+ }
4524+ for (i = 0; i < count; ++i)
4525+ process_char(zbdev, buf[i]);
4526+#if 0
4527+ if (tty->driver->flush_chars)
4528+ tty->driver->flush_chars(tty);
4529+#endif
4530+ tty_unthrottle(tty);
4531+}
4532+
4533+/*
4534+ * Line discipline device structure
4535+ */
4536+static struct tty_ldisc_ops ieee802154_ldisc = {
4537+ .owner = THIS_MODULE,
4538+ .magic = TTY_LDISC_MAGIC,
4539+ .name = "ieee802154-ldisc",
4540+ .open = ieee802154_tty_open,
4541+ .close = ieee802154_tty_close,
4542+ .hangup = ieee802154_tty_hangup,
4543+ .receive_buf = ieee802154_tty_receive,
4544+ .ioctl = ieee802154_tty_ioctl,
4545+};
4546+
4547+/*****************************************************************************
4548+ * Module service routinues
4549+ *****************************************************************************/
4550+
4551+static int __init ieee802154_serial_init(void)
4552+{
4553+ printk(KERN_INFO "Initializing ZigBee TTY interface\n");
4554+
4555+ if (tty_register_ldisc(N_IEEE802154, &ieee802154_ldisc) != 0) {
4556+ printk(KERN_ERR "%s: line discipline register failed\n",
4557+ __func__);
4558+ return -EINVAL;
4559+ }
4560+
4561+ return 0;
4562+}
4563+
4564+static void __exit ieee802154_serial_cleanup(void)
4565+{
4566+ if (tty_unregister_ldisc(N_IEEE802154) != 0)
4567+ printk(KERN_CRIT
4568+ "failed to unregister ZigBee line discipline.\n");
4569+}
4570+
4571+module_init(ieee802154_serial_init);
4572+module_exit(ieee802154_serial_cleanup);
4573+
4574+MODULE_LICENSE("GPL");
4575+MODULE_ALIAS_LDISC(N_IEEE802154);
4576+
4577diff --git a/drivers/ieee802154/spi_atben.c b/drivers/ieee802154/spi_atben.c
4578new file mode 100644
4579index 0000000..431bfe0
4580--- /dev/null
4581@@ -0,0 +1,421 @@
4582+/*
4583+ * spi_atben.c - SPI host look-alike for ATBEN
4584+ *
4585+ * Written 2011 by Werner Almesberger
4586+ *
4587+ * This program is free software; you can redistribute it and/or modify
4588+ * it under the terms of the GNU General Public License version 2
4589+ * as published by the Free Software Foundation.
4590+ */
4591+
4592+#include <linux/kernel.h>
4593+#include <linux/module.h>
4594+#include <linux/platform_device.h>
4595+#include <linux/gpio.h>
4596+#include <linux/delay.h>
4597+#include <linux/spi/spi.h>
4598+#include <linux/spi/at86rf230.h>
4599+#include <asm/mach-jz4740/base.h>
4600+
4601+#include "at86rf230.h"
4602+
4603+
4604+enum {
4605+ VDD_OFF = 1 << 2, /* VDD disable, PD02 */
4606+ MOSI = 1 << 8, /* CMD, PD08 */
4607+ SLP_TR = 1 << 9, /* CLK, PD09 */
4608+ MISO = 1 << 10, /* DAT0, PD10 */
4609+ SCLK = 1 << 11, /* DAT1, PD11 */
4610+ IRQ = 1 << 12, /* DAT2, PD12 */
4611+ nSEL = 1 << 13, /* DAT3/CD, PD13 */
4612+};
4613+
4614+#define PDPIN (prv->regs)
4615+#define PDDATS (prv->regs+0x14)
4616+#define PDDATC (prv->regs+0x18)
4617+
4618+
4619+struct atben_prv {
4620+ struct device *dev;
4621+ void __iomem *regs;
4622+ struct resource *ioarea;
4623+ struct at86rf230_platform_data
4624+ platform_data;
4625+ /* copy platform_data so that we can adapt .reset_data */
4626+};
4627+
4628+
4629+/* ----- ATBEN reset ------------------------------------------------------- */
4630+
4631+
4632+static void atben_reset(void *reset_data)
4633+{
4634+ struct atben_prv *prv = reset_data;
4635+ const int charge = nSEL | MOSI | SLP_TR | SCLK;
4636+ const int discharge = charge | IRQ | MISO;
4637+
4638+ dev_info(prv->dev, "atben_reset\n");
4639+ jz_gpio_port_set_value(JZ_GPIO_PORTD(0), 1 << 2, 1 << 2);
4640+ jz_gpio_port_direction_output(JZ_GPIO_PORTD(0), discharge);
4641+ jz_gpio_port_set_value(JZ_GPIO_PORTD(0), 0, discharge);
4642+ msleep(100); /* let power drop */
4643+
4644+ /*
4645+ * Hack: PD12/DAT2/IRQ is an active-high interrupt input, which is
4646+ * indicated by setting its direction bit to 1. We thus must not
4647+ * configure it as an "input".
4648+ */
4649+ jz_gpio_port_direction_input(JZ_GPIO_PORTD(0), MISO);
4650+ jz_gpio_port_set_value(JZ_GPIO_PORTD(0), charge, charge);
4651+ msleep(10); /* precharge caps */
4652+
4653+ jz_gpio_port_set_value(JZ_GPIO_PORTD(0), 0, VDD_OFF | SLP_TR | SCLK);
4654+ msleep(10);
4655+}
4656+
4657+
4658+/* ----- SPI transfers ----------------------------------------------------- */
4659+
4660+
4661+static void rx_only(const struct atben_prv *prv, uint8_t *buf, int len)
4662+{
4663+ uint8_t v;
4664+
4665+ while (len--) {
4666+ writel(SCLK, PDDATS);
4667+ v = readl(PDPIN) & MISO ? 0x80 : 0;
4668+ writel(SCLK, PDDATC);
4669+
4670+ #define DO_BIT(m) \
4671+ writel(SCLK, PDDATS); \
4672+ if (readl(PDPIN) & MISO) \
4673+ v |= (m); \
4674+ writel(SCLK, PDDATC)
4675+
4676+ DO_BIT(0x40);
4677+ DO_BIT(0x20);
4678+ DO_BIT(0x10);
4679+ DO_BIT(0x08);
4680+ DO_BIT(0x04);
4681+ DO_BIT(0x02);
4682+ DO_BIT(0x01);
4683+
4684+ #undef DO_BIT
4685+
4686+ *buf++ = v;
4687+ }
4688+}
4689+
4690+
4691+static void tx_only(const struct atben_prv *prv, const uint8_t *buf, int len)
4692+{
4693+ uint8_t tv;
4694+
4695+ while (len--) {
4696+ tv = *buf++;
4697+
4698+ if (tv & 0x80) {
4699+ writel(MOSI, PDDATS);
4700+ goto b6_1;
4701+ } else {
4702+ writel(MOSI, PDDATC);
4703+ goto b6_0;
4704+ }
4705+
4706+ #define DO_BIT(m, this, next) \
4707+ this##_1: \
4708+ writel(SCLK, PDDATS); \
4709+ if (tv & (m)) { \
4710+ writel(SCLK, PDDATC); \
4711+ goto next##_1; \
4712+ } else { \
4713+ writel(MOSI | SCLK, PDDATC); \
4714+ goto next##_0; \
4715+ } \
4716+ this##_0: \
4717+ writel(SCLK, PDDATS); \
4718+ writel(SCLK, PDDATC); \
4719+ if (tv & (m)) { \
4720+ writel(MOSI, PDDATS); \
4721+ goto next##_1; \
4722+ } else { \
4723+ goto next##_0; \
4724+ }
4725+
4726+ DO_BIT(0x40, b6, b5);
4727+ DO_BIT(0x20, b5, b4);
4728+ DO_BIT(0x10, b4, b3);
4729+ DO_BIT(0x08, b3, b2);
4730+ DO_BIT(0x04, b2, b1);
4731+ DO_BIT(0x02, b1, b0);
4732+ DO_BIT(0x01, b0, done);
4733+
4734+ #undef DO_BIT
4735+
4736+done_1:
4737+done_0:
4738+ writel(SCLK, PDDATS);
4739+ writel(SCLK, PDDATC);
4740+ writel(SCLK, PDDATC); /* delay to meet t5 timing */
4741+ }
4742+}
4743+
4744+
4745+static void bidir(const struct atben_prv *prv, const uint8_t *tx, uint8_t *rx,
4746+ int len)
4747+{
4748+ uint8_t mask, tv, rv;
4749+
4750+ while (len--) {
4751+ tv = *tx++;
4752+ for (mask = 0x80; mask; mask >>= 1) {
4753+ if (tv & mask)
4754+ writel(MOSI, PDDATS);
4755+ else
4756+ writel(MOSI, PDDATC);
4757+ writel(SCLK, PDDATS);
4758+ if (readl(PDPIN) & MISO)
4759+ rv |= mask;
4760+ writel(SCLK, PDDATC);
4761+ }
4762+ *rx++ = rv;
4763+ }
4764+}
4765+
4766+
4767+static int atben_transfer(struct spi_device *spi, struct spi_message *msg)
4768+{
4769+ struct atben_prv *prv = spi_master_get_devdata(spi->master);
4770+ struct spi_transfer *xfer;
4771+ const uint8_t *tx;
4772+ uint8_t *rx;
4773+
4774+ if (unlikely(list_empty(&msg->transfers))) {
4775+ dev_err(prv->dev, "transfer is empty\n");
4776+ return -EINVAL;
4777+ }
4778+
4779+ msg->actual_length = 0;
4780+
4781+ writel(nSEL, PDDATC);
4782+ list_for_each_entry(xfer, &msg->transfers, transfer_list) {
4783+ tx = xfer->tx_buf;
4784+ rx = xfer->rx_buf;
4785+ msg->actual_length += xfer->len;
4786+
4787+ if (!tx)
4788+ rx_only(prv, rx, xfer->len);
4789+ else if (!rx)
4790+ tx_only(prv, tx, xfer->len);
4791+ else
4792+ bidir(prv, tx, rx, xfer->len);
4793+ }
4794+ writel(nSEL, PDDATS);
4795+
4796+ msg->status = 0;
4797+ msg->complete(msg->context);
4798+
4799+ return 0;
4800+}
4801+
4802+static int atben_setup(struct spi_device *spi)
4803+{
4804+ return 0;
4805+}
4806+
4807+
4808+/* ----- SPI master creation/removal --------------------------------------- */
4809+
4810+
4811+const static struct at86rf230_platform_data at86rf230_platform_data = {
4812+ .rstn = -1,
4813+ .slp_tr = JZ_GPIO_PORTD(9),
4814+ .dig2 = -1,
4815+ .reset = atben_reset,
4816+ /* set .reset_data later */
4817+};
4818+
4819+static int __devinit atben_probe(struct platform_device *pdev)
4820+{
4821+ struct spi_board_info board_info = {
4822+ .modalias = "at86rf230",
4823+ /* set .irq later */
4824+ .chip_select = 0,
4825+ .bus_num = -1,
4826+ .max_speed_hz = 8 * 1000 * 1000,
4827+ };
4828+
4829+ struct spi_master *master;
4830+ struct atben_prv *prv;
4831+ struct resource *regs;
4832+ struct spi_device *spi;
4833+ int err = -ENXIO;
4834+
4835+ master = spi_alloc_master(&pdev->dev, sizeof(*prv));
4836+ if (!master)
4837+ return -ENOMEM;
4838+
4839+ prv = spi_master_get_devdata(master);
4840+ prv->dev = &pdev->dev;
4841+ platform_set_drvdata(pdev, spi_master_get(master));
4842+
4843+ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
4844+ master->bus_num = pdev->id;
4845+ master->num_chipselect = 1;
4846+ master->setup = atben_setup;
4847+ master->transfer = atben_transfer;
4848+
4849+ dev_dbg(prv->dev, "Setting up ATBEN SPI\n");
4850+
4851+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
4852+ if (!regs) {
4853+ dev_err(prv->dev, "no IORESOURCE_MEM\n");
4854+ err = -ENOENT;
4855+ goto out_master;
4856+ }
4857+ prv->ioarea = request_mem_region(regs->start, resource_size(regs),
4858+ pdev->name);
4859+ if (!prv->ioarea) {
4860+ dev_err(prv->dev, "can't request ioarea\n");
4861+ goto out_master;
4862+ }
4863+
4864+ prv->regs = ioremap(regs->start, resource_size(regs));
4865+ if (!prv->regs) {
4866+ dev_err(prv->dev, "can't ioremap\n");
4867+ goto out_ioarea;
4868+ }
4869+
4870+ board_info.irq = platform_get_irq(pdev, 0);
4871+ if (board_info.irq < 0) {
4872+ dev_err(prv->dev, "can't get GPIO irq\n");
4873+ err = -ENOENT;
4874+ goto out_regs;
4875+ }
4876+
4877+ err = spi_register_master(master);
4878+ if (err) {
4879+ dev_err(prv->dev, "can't register master\n");
4880+ goto out_regs;
4881+ }
4882+
4883+ prv->platform_data = at86rf230_platform_data;
4884+ prv->platform_data.reset_data = prv;
4885+ board_info.platform_data = &prv->platform_data;
4886+
4887+ spi = spi_new_device(master, &board_info);
4888+ if (!spi) {
4889+ dev_err(&pdev->dev, "can't create new device for %s\n",
4890+ board_info.modalias);
4891+ err = -ENXIO;
4892+ goto out_registered;
4893+ }
4894+
4895+ dev_info(&spi->dev, "ATBEN ready for mischief (IRQ %d)\n",
4896+ board_info.irq);
4897+
4898+ return 0;
4899+
4900+out_registered:
4901+ spi_unregister_master(master);
4902+
4903+out_regs:
4904+ iounmap(prv->regs);
4905+
4906+out_ioarea:
4907+ release_resource(prv->ioarea);
4908+ kfree(prv->ioarea);
4909+
4910+out_master:
4911+ platform_set_drvdata(pdev, NULL);
4912+ spi_master_put(master);
4913+
4914+ return err;
4915+}
4916+
4917+static int __devexit atben_remove(struct platform_device *pdev)
4918+{
4919+ struct spi_master *master = platform_get_drvdata(pdev);
4920+ struct atben_prv *prv = spi_master_get_devdata(master);
4921+
4922+// restore GPIOs
4923+
4924+ spi_unregister_master(master);
4925+
4926+ iounmap(prv->regs);
4927+
4928+ release_resource(prv->ioarea);
4929+ kfree(prv->ioarea);
4930+
4931+ platform_set_drvdata(pdev, NULL);
4932+ spi_master_put(master);
4933+
4934+ return 0;
4935+}
4936+
4937+static struct platform_driver atben_driver = {
4938+ .driver = {
4939+ .name = "spi_atben",
4940+ .owner = THIS_MODULE,
4941+ },
4942+ .remove = __devexit_p(atben_remove),
4943+};
4944+
4945+static struct resource atben_resources[] = {
4946+ {
4947+ .start = JZ4740_GPIO_BASE_ADDR+0x300,
4948+ .end = JZ4740_GPIO_BASE_ADDR+0x3ff,
4949+ .flags = IORESOURCE_MEM,
4950+ },
4951+ {
4952+ /* set start and end later */
4953+ .flags = IORESOURCE_IRQ,
4954+ },
4955+};
4956+
4957+static struct platform_device atben_device = {
4958+ .name = "spi_atben",
4959+ .id = -1,
4960+ .num_resources = ARRAY_SIZE(atben_resources),
4961+ .resource = atben_resources,
4962+};
4963+
4964+/*
4965+ * Registering the platform device just to probe it immediately afterwards
4966+ * seems a little circuitous. Need to see if there's a better way.
4967+ *
4968+ * What we actually should do is this:
4969+ * - in module init, register the device
4970+ * - maybe probe as well, but keep the device also if the probe fails
4971+ * (due to a conflicting driver already occupying the 8:10 slot)
4972+ * - have a means for user space to kick off driver probing, e.g., when
4973+ * anything about the 8:10 slot changes
4974+ */
4975+
4976+static int __init atben_init(void)
4977+{
4978+ int err;
4979+
4980+ err = platform_device_register(&atben_device);
4981+ if (err)
4982+ return err;
4983+
4984+ atben_resources[1].start = atben_resources[1].end =
4985+ gpio_to_irq(JZ_GPIO_PORTD(12));
4986+
4987+ return platform_driver_probe(&atben_driver, atben_probe);
4988+}
4989+
4990+static void __exit atben_exit(void)
4991+{
4992+ platform_driver_unregister(&atben_driver);
4993+ platform_device_unregister(&atben_device);
4994+}
4995+
4996+module_init(atben_init);
4997+module_exit(atben_exit);
4998+
4999+
5000+MODULE_DESCRIPTION("ATBEN SPI Controller Driver");
5001+MODULE_AUTHOR("Werner Almesberger <werner@almesberger.net>");
5002+MODULE_LICENSE("GPL");
5003diff --git a/drivers/ieee802154/spi_atusb.c b/drivers/ieee802154/spi_atusb.c
5004new file mode 100644
5005index 0000000..04d9fb3
5006--- /dev/null
5007@@ -0,0 +1,750 @@
5008+/*
5009+ * spi_atusb - SPI host look-alike for ATUSB
5010+ *
5011+ * Copyright (c) 2011 Richard Sharpe <realrichardsharpe@gmail.com>
5012+ * Copyright (c) 2011 Stefan Schmidt <stefan@datenfreihafen.org>
5013+ * Copyright (c) 2011 Werner Almesberger <werner@almesberger.net>
5014+ *
5015+ * This program is free software; you can redistribute it and/or
5016+ * modify it under the terms of the GNU General Public License as
5017+ * published by the Free Software Foundation, version 2
5018+ *
5019+ */
5020+
5021+/*
5022+ * - implement more robust interrupt synchronization
5023+ * - check URB killing in atusb_disconnect for races
5024+ * - switch from bulk to interrupt endpoint
5025+ * - implement buffer read without extra copy
5026+ * - harmonize indentation style
5027+ * - mv atusb.c ../ieee802.15.4/spi_atusb.c, or maybe atrf_atusb.c or such
5028+ * - check module load/unload
5029+ * - review dev_* severity levels
5030+ */
5031+
5032+#include <linux/kernel.h>
5033+#include <linux/module.h>
5034+#include <linux/platform_device.h>
5035+#include <linux/jiffies.h>
5036+#include <linux/timer.h>
5037+#include <linux/interrupt.h>
5038+#include <linux/usb.h>
5039+#include <linux/spi/spi.h>
5040+#include <linux/spi/at86rf230.h>
5041+
5042+#include "at86rf230.h"
5043+
5044+
5045+#define SYNC_TIMEOUT_MS 50 /* assume interrupt has been synced after
5046+ waiting this long */
5047+
5048+#define VENDOR_ID 0x20b7
5049+#define PRODUCT_ID 0x1540
5050+
5051+/* The devices we work with */
5052+static const struct usb_device_id atusb_device_table[] = {
5053+ { USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
5054+ { },
5055+};
5056+MODULE_DEVICE_TABLE(usb, atusb_device_table);
5057+
5058+#define ATUSB_BUILD_SIZE 256
5059+struct atusb_local {
5060+ struct usb_device * udev;
5061+ /* The interface to the RF part info, if applicable */
5062+ uint8_t ep0_atusb_major;
5063+ uint8_t ep0_atusb_minor;
5064+ uint8_t atusb_hw_type;
5065+ struct spi_master *master;
5066+ int slave_irq;
5067+ struct urb *irq_urb;
5068+ uint8_t irq_buf; /* receive irq serial here*/
5069+ uint8_t irq_seen; /* last irq serial from bulk */
5070+ uint8_t irq_sync; /* last irq serial from WRITE2_SYNC */
5071+ struct tasklet_struct task; /* interrupt delivery tasklet */
5072+ struct timer_list timer; /* delay, for interrupt synch */
5073+ struct at86rf230_platform_data platform_data;
5074+ /* copy platform_data so that we can adapt .reset_data */
5075+ struct spi_device *spi;
5076+// unsigned char buffer[3];
5077+ unsigned char buffer[260]; /* XXL, just in case */
5078+ struct spi_message *msg;
5079+};
5080+
5081+/* Commands to our device. Make sure this is synced with the firmware */
5082+enum atspi_requests {
5083+ ATUSB_ID = 0x00, /* system status/control grp */
5084+ ATUSB_BUILD,
5085+ ATUSB_RESET,
5086+ ATUSB_RF_RESET = 0x10, /* debug/test group */
5087+ ATUSB_POLL_INT,
5088+ ATUSB_TEST, /* atusb-sil only */
5089+ ATUSB_TIMER,
5090+ ATUSB_GPIO,
5091+ ATUSB_SLP_TR,
5092+ ATUSB_GPIO_CLEANUP,
5093+ ATUSB_REG_WRITE = 0x20, /* transceiver group */
5094+ ATUSB_REG_READ,
5095+ ATUSB_BUF_WRITE,
5096+ ATUSB_BUF_READ,
5097+ ATUSB_SRAM_WRITE,
5098+ ATUSB_SRAM_READ,
5099+ ATUSB_SPI_WRITE = 0x30, /* SPI group */
5100+ ATUSB_SPI_READ1,
5101+ ATUSB_SPI_READ2,
5102+ ATUSB_SPI_WRITE2_SYNC,
5103+};
5104+
5105+/*
5106+ * Direction bRequest wValue wIndex wLength
5107+ *
5108+ * ->host ATUSB_ID - - 3
5109+ * ->host ATUSB_BUILD - - #bytes
5110+ * host-> ATUSB_RESET - - 0
5111+ *
5112+ * host-> ATUSB_RF_RESET - - 0
5113+ * ->host ATUSB_POLL_INT - - 1
5114+ * host-> ATUSB_TEST - - 0
5115+ * ->host ATUSB_TIMER - - #bytes (6)
5116+ * ->host ATUSB_GPIO dir+data mask+p# 3
5117+ * host-> ATUSB_SLP_TR - - 0
5118+ * host-> ATUSB_GPIO_CLEANUP - - 0
5119+ *
5120+ * host-> ATUSB_REG_WRITE value addr 0
5121+ * ->host ATUSB_REG_READ - addr 1
5122+ * host-> ATUSB_BUF_WRITE - - #bytes
5123+ * ->host ATUSB_BUF_READ - - #bytes
5124+ * host-> ATUSB_SRAM_WRITE - addr #bytes
5125+ * ->host ATUSB_SRAM_READ - addr #bytes
5126+ *
5127+ * host-> ATUSB_SPI_WRITE byte0 byte1 #bytes
5128+ * ->host ATUSB_SPI_READ1 byte0 - #bytes
5129+ * ->host ATUSB_SPI_READ2 byte0 byte1 #bytes
5130+ * ->host ATUSB_SPI_WRITE2_SYNC byte0 byte1 0/1
5131+ */
5132+
5133+#define ATUSB_FROM_DEV (USB_TYPE_VENDOR | USB_DIR_IN)
5134+#define ATUSB_TO_DEV (USB_TYPE_VENDOR | USB_DIR_OUT)
5135+
5136+
5137+/* ----- Control transfers ------------------------------------------------- */
5138+
5139+
5140+static int atusb_async_errchk(struct urb *urb)
5141+{
5142+ struct atusb_local *atusb = urb->context;
5143+ struct spi_message *msg = atusb->msg;
5144+ struct usb_device *dev = atusb->udev;
5145+
5146+ if (!urb->status) {
5147+ dev_dbg(&dev->dev, "atusb_async_errchk OK len %d\n",
5148+ urb->actual_length);
5149+ return 0;
5150+ }
5151+
5152+ if (urb->status != -ENOENT && urb->status != -ECONNRESET &&
5153+ urb->status != -ESHUTDOWN)
5154+ dev_info(&dev->dev, "atusb_async_errchk FAIL error %d\n",
5155+ urb->status);
5156+
5157+ msg->actual_length = 0;
5158+
5159+ return urb->status;
5160+}
5161+
5162+static void atusb_async_finish(struct urb *urb)
5163+{
5164+ struct atusb_local *atusb = urb->context;
5165+ struct spi_message *msg = atusb->msg;
5166+
5167+ msg->status = urb->status;
5168+ msg->complete(msg->context);
5169+
5170+ kfree(urb->setup_packet);
5171+ usb_free_urb(urb);
5172+}
5173+
5174+static void atusb_ctrl_cb(struct urb *urb)
5175+{
5176+ atusb_async_errchk(urb);
5177+ atusb_async_finish(urb);
5178+}
5179+
5180+static void atusb_timer(unsigned long data)
5181+{
5182+ struct urb *urb = (void *) data;
5183+
5184+ dev_warn(&urb->dev->dev, "atusb_timer\n");
5185+ atusb_async_finish(urb);
5186+}
5187+
5188+static void atusb_ctrl_cb_sync(struct urb *urb)
5189+{
5190+ struct atusb_local *atusb = urb->context;
5191+
5192+ /* @@@ needs locking/atomic */
5193+ if (atusb_async_errchk(urb) || atusb->irq_sync == atusb->irq_seen) {
5194+ atusb_async_finish(urb);
5195+ return;
5196+ }
5197+
5198+ BUG_ON(timer_pending(&atusb->timer));
5199+ atusb->timer.expires = jiffies+msecs_to_jiffies(SYNC_TIMEOUT_MS);
5200+ atusb->timer.data = (unsigned long) urb;
5201+ add_timer(&atusb->timer);
5202+}
5203+
5204+static void atusb_read_fb_cb(struct urb *urb)
5205+{
5206+ struct atusb_local *atusb = urb->context;
5207+ struct spi_message *msg = atusb->msg;
5208+ const struct spi_transfer *xfer;
5209+ uint8_t *rx;
5210+
5211+ if (!atusb_async_errchk(urb)) {
5212+ BUG_ON(!urb->actual_length);
5213+
5214+ xfer = list_first_entry(&msg->transfers, struct spi_transfer,
5215+ transfer_list);
5216+ rx = xfer->rx_buf;
5217+ rx[1] = atusb->buffer[0];
5218+
5219+ xfer = list_entry(xfer->transfer_list.next,
5220+ struct spi_transfer, transfer_list);
5221+ memcpy(xfer->rx_buf, atusb->buffer+1, urb->actual_length-1);
5222+ }
5223+
5224+ atusb_async_finish(urb);
5225+}
5226+
5227+static int submit_control_msg(struct atusb_local *atusb,
5228+ __u8 request, __u8 requesttype, __u16 value, __u16 index,
5229+ void *data, __u16 size, usb_complete_t complete_fn, void *context)
5230+{
5231+ struct usb_device *dev = atusb->udev;
5232+ struct usb_ctrlrequest *req;
5233+ struct urb *urb;
5234+ int retval = -ENOMEM;
5235+
5236+ req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
5237+ if (!req)
5238+ return -ENOMEM;
5239+
5240+ req->bRequest = request;
5241+ req->bRequestType = requesttype;
5242+ req->wValue = cpu_to_le16(value);
5243+ req->wIndex = cpu_to_le16(index);
5244+ req->wLength = cpu_to_le16(size);
5245+
5246+ urb = usb_alloc_urb(0, GFP_KERNEL);
5247+ if (!urb)
5248+ goto out_nourb;
5249+
5250+ usb_fill_control_urb(urb, dev,
5251+ requesttype == ATUSB_FROM_DEV ?
5252+ usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0),
5253+ (unsigned char *) req, data, size, complete_fn, context);
5254+
5255+ retval = usb_submit_urb(urb, GFP_KERNEL);
5256+ if (!retval)
5257+ return 0;
5258+ dev_warn(&dev->dev, "failed submitting read urb, error %d",
5259+ retval);
5260+ retval = retval == -ENOMEM ? retval : -EIO;
5261+
5262+ usb_free_urb(urb);
5263+out_nourb:
5264+ kfree(req);
5265+
5266+ return retval;
5267+}
5268+
5269+
5270+/* ----- SPI transfers ----------------------------------------------------- */
5271+
5272+
5273+static int atusb_read1(struct atusb_local *atusb,
5274+ uint8_t tx, uint8_t *rx, int len)
5275+{
5276+ dev_dbg(&atusb->udev->dev, "atusb_read1: tx = 0x%x\n", tx);
5277+ return submit_control_msg(atusb,
5278+ ATUSB_SPI_READ1, ATUSB_FROM_DEV, tx, 0,
5279+ rx, 1, atusb_ctrl_cb, atusb);
5280+}
5281+
5282+static int atusb_read_fb(struct atusb_local *atusb,
5283+ uint8_t tx, uint8_t *rx0, uint8_t *rx, int len)
5284+{
5285+ dev_dbg(&atusb->udev->dev, "atusb_read_fb: tx = 0x%x\n", tx);
5286+ return submit_control_msg(atusb,
5287+ ATUSB_SPI_READ1, ATUSB_FROM_DEV, tx, 0,
5288+ atusb->buffer, len+1, atusb_read_fb_cb, atusb);
5289+}
5290+
5291+static int atusb_write(struct atusb_local *atusb,
5292+ uint8_t tx0, uint8_t tx1, const uint8_t *tx, int len)
5293+{
5294+ dev_dbg(&atusb->udev->dev,
5295+ "atusb_write: tx0 = 0x%x tx1 = 0x%x\n", tx0, tx1);
5296+
5297+ /*
5298+ * The AT86RF230 driver sometimes requires a transceiver state
5299+ * transition to be an interrupt barrier. This is the case after
5300+ * writing FORCE_TX_ON to the TRX_CMD field in the TRX_STATE register.
5301+ *
5302+ * Since there is no other means of notification, we just decode the
5303+ * transfer and do a bit of pattern matching.
5304+ */
5305+ if (tx0 == (CMD_REG | CMD_WRITE | RG_TRX_STATE) &&
5306+ (tx1 & 0x1f) == STATE_FORCE_TX_ON)
5307+ return submit_control_msg(atusb,
5308+ ATUSB_SPI_WRITE2_SYNC, ATUSB_FROM_DEV, tx0, tx1,
5309+ &atusb->irq_sync, 1, atusb_ctrl_cb_sync, atusb);
5310+ else
5311+ return submit_control_msg(atusb,
5312+ ATUSB_SPI_WRITE, ATUSB_TO_DEV, tx0, tx1,
5313+ (uint8_t *) tx, len, atusb_ctrl_cb, atusb);
5314+}
5315+
5316+static int atusb_transfer(struct spi_device *spi, struct spi_message *msg)
5317+{
5318+ struct atusb_local *atusb = spi_master_get_devdata(spi->master);
5319+ struct spi_transfer *xfer;
5320+ struct spi_transfer *x[2];
5321+ int n;
5322+ const uint8_t *tx;
5323+ uint8_t *rx;
5324+ int len;
5325+ int retval = 0;
5326+
5327+ if (unlikely(list_empty(&msg->transfers))) {
5328+ dev_err(&atusb->udev->dev, "transfer is empty\n");
5329+ return -EINVAL;
5330+ }
5331+
5332+ atusb->msg = msg;
5333+
5334+ /* Classify the request */
5335+ n = 0;
5336+ list_for_each_entry(xfer, &msg->transfers, transfer_list) {
5337+ if (n == ARRAY_SIZE(x)) {
5338+ dev_err(&atusb->udev->dev, "too many transfers\n");
5339+ return -EINVAL;
5340+ }
5341+ x[n] = xfer;
5342+ n++;
5343+ }
5344+
5345+ tx = x[0]->tx_buf;
5346+ rx = x[0]->rx_buf;
5347+ len = x[0]->len;
5348+
5349+ msg->actual_length = len;
5350+
5351+ if (!tx || len != 2)
5352+ goto bad_req;
5353+ if (n == 1) {
5354+ if (rx) {
5355+ dev_dbg(&atusb->udev->dev, "read 1\n");
5356+ retval = atusb_read1(atusb, tx[0], rx+1, len-1);
5357+ } else {
5358+ dev_dbg(&atusb->udev->dev, "write 2\n");
5359+ /*
5360+ * Don't take our clock away !! ;-)
5361+ */
5362+ if (tx[0] == (CMD_REG | CMD_WRITE | RG_TRX_CTRL_0)) {
5363+ msg->status = 0;
5364+ msg->complete(msg->context);
5365+ } else {
5366+ retval = atusb_write(atusb,
5367+ tx[0], tx[1], NULL, 0);
5368+ }
5369+ }
5370+ } else {
5371+ if (x[0]->rx_buf) {
5372+ if (x[1]->tx_buf || !x[1]->rx_buf)
5373+ goto bad_req;
5374+ dev_dbg(&atusb->udev->dev, "read 1+\n");
5375+ retval = atusb_read_fb(atusb, tx[0], rx+1,
5376+ x[1]->rx_buf, x[1]->len);
5377+ } else {
5378+ if (!x[1]->tx_buf ||x[1]->rx_buf)
5379+ goto bad_req;
5380+ dev_dbg(&atusb->udev->dev, "write 2+n\n");
5381+ retval = atusb_write(atusb, tx[0], tx[1],
5382+ x[1]->tx_buf, x[1]->len);
5383+ }
5384+ }
5385+ return retval;
5386+
5387+bad_req:
5388+ dev_err(&atusb->udev->dev, "unrecognized request:\n");
5389+ list_for_each_entry(xfer, &msg->transfers, transfer_list)
5390+ dev_err(&atusb->udev->dev, "%stx %srx len %u\n",
5391+ xfer->tx_buf ? "" : "!", xfer->rx_buf ? " " : "!",
5392+ xfer->len);
5393+ return -EINVAL;
5394+}
5395+
5396+static int atusb_setup(struct spi_device *spi)
5397+{
5398+ return 0;
5399+}
5400+
5401+
5402+/* ----- Interrupt handling ------------------------------------------------ */
5403+
5404+
5405+static void atusb_tasklet(unsigned long data)
5406+{
5407+ struct atusb_local *atusb = (void *) data;
5408+
5409+ generic_handle_irq(atusb->slave_irq);
5410+}
5411+
5412+static void atusb_irq(struct urb *urb)
5413+{
5414+ struct atusb_local *atusb = urb->context;
5415+
5416+ dev_dbg(&urb->dev->dev, "atusb_irq (%d), seen %d sync %d\n",
5417+ urb->status, atusb->irq_buf, atusb->irq_sync);
5418+ if (!urb->status) {
5419+ atusb->irq_seen = atusb->irq_buf;
5420+ if (atusb->irq_sync == atusb->irq_seen &&
5421+ try_to_del_timer_sync(&atusb->timer) == 1)
5422+ atusb_async_finish((struct urb *) atusb->timer.data);
5423+ }
5424+ usb_free_urb(urb);
5425+ atusb->irq_urb = NULL;
5426+ tasklet_schedule(&atusb->task);
5427+}
5428+
5429+static int atusb_arm_interrupt(struct atusb_local *atusb)
5430+{
5431+ struct usb_device *dev = atusb->udev;
5432+ struct urb *urb;
5433+ int retval = -ENOMEM;
5434+
5435+ BUG_ON(atusb->irq_urb);
5436+
5437+ dev_vdbg(&dev->dev, "atusb_arm_interrupt\n");
5438+ urb = usb_alloc_urb(0, GFP_KERNEL);
5439+ if (!urb) {
5440+ dev_err(&dev->dev,
5441+ "atusb_arm_interrupt: usb_alloc_urb failed\n");
5442+ return -ENOMEM;
5443+ }
5444+
5445+ usb_fill_bulk_urb(urb, dev, usb_rcvbulkpipe(dev, 1),
5446+ &atusb->irq_buf, 1, atusb_irq, atusb);
5447+ atusb->irq_urb = urb;
5448+ retval = usb_submit_urb(urb, GFP_KERNEL);
5449+ if (!retval)
5450+ return 0;
5451+
5452+ dev_err(&dev->dev, "failed submitting bulk urb, error %d\n", retval);
5453+ retval = retval == -ENOMEM ? retval : -EIO;
5454+
5455+ usb_free_urb(urb);
5456+
5457+ return retval;
5458+}
5459+
5460+static void atusb_irq_mask(struct irq_data *data)
5461+{
5462+ struct atusb_local *atusb = irq_data_get_irq_chip_data(data);
5463+
5464+ dev_vdbg(&atusb->udev->dev, "atusb_irq_mask\n");
5465+ tasklet_disable_nosync(&atusb->task);
5466+}
5467+
5468+static void atusb_irq_unmask(struct irq_data *data)
5469+{
5470+ struct atusb_local *atusb = irq_data_get_irq_chip_data(data);
5471+
5472+ dev_vdbg(&atusb->udev->dev, "atusb_irq_unmask\n");
5473+ tasklet_enable(&atusb->task);
5474+}
5475+
5476+static void atusb_irq_ack(struct irq_data *data)
5477+{
5478+ struct atusb_local *atusb = irq_data_get_irq_chip_data(data);
5479+
5480+ dev_vdbg(&atusb->udev->dev, "atusb_irq_ack\n");
5481+ atusb_arm_interrupt(atusb);
5482+}
5483+
5484+static struct irq_chip atusb_irq_chip = {
5485+ .name = "atusb-slave",
5486+ .irq_mask = atusb_irq_mask,
5487+ .irq_unmask = atusb_irq_unmask,
5488+ .irq_ack = atusb_irq_ack,
5489+};
5490+
5491+
5492+/* ----- Transceiver reset ------------------------------------------------- */
5493+
5494+
5495+static void atusb_reset(void *reset_data)
5496+{
5497+ int retval;
5498+ struct atusb_local *atusb = reset_data;
5499+
5500+ retval = usb_control_msg(atusb->udev,
5501+ usb_rcvctrlpipe(atusb->udev, 0),
5502+ ATUSB_RF_RESET, ATUSB_TO_DEV, 0, 0,
5503+ NULL, 0, 1000);
5504+ if (retval < 0) {
5505+ dev_err(&atusb->udev->dev,
5506+ "%s: error doing reset retval = %d\n",
5507+ __func__, retval);
5508+ }
5509+}
5510+
5511+
5512+/* ----- Firmware version information -------------------------------------- */
5513+
5514+
5515+static int atusb_get_and_show_revision(struct atusb_local *atusb)
5516+{
5517+ struct usb_device *dev = atusb->udev;
5518+ int retval;
5519+
5520+ /* Get a couple of the ATMega Firmware values */
5521+ retval = usb_control_msg(dev,
5522+ usb_rcvctrlpipe(dev, 0),
5523+ ATUSB_ID, ATUSB_FROM_DEV, 0, 0,
5524+ atusb->buffer, 3, 1000);
5525+ if (retval < 0) {
5526+ dev_info(&dev->dev,
5527+ "failed submitting urb for ATUSB_ID, error %d\n", retval);
5528+ return retval == -ENOMEM ? retval : -EIO;
5529+ }
5530+
5531+ atusb->ep0_atusb_major = atusb->buffer[0];
5532+ atusb->ep0_atusb_minor = atusb->buffer[1];
5533+ atusb->atusb_hw_type = atusb->buffer[2];
5534+ dev_info(&dev->dev,
5535+ "Firmware: major: %u, minor: %u, hardware type: %u\n",
5536+ atusb->ep0_atusb_major, atusb->ep0_atusb_minor,
5537+ atusb->atusb_hw_type);
5538+
5539+ return 0;
5540+}
5541+
5542+static int atusb_get_and_show_build(struct atusb_local *atusb)
5543+{
5544+ struct usb_device *dev = atusb->udev;
5545+ char build[ATUSB_BUILD_SIZE+1];
5546+ int retval;
5547+
5548+ retval = usb_control_msg(dev,
5549+ usb_rcvctrlpipe(atusb->udev, 0),
5550+ ATUSB_BUILD, ATUSB_FROM_DEV, 0, 0,
5551+ build, ATUSB_BUILD_SIZE, 1000);
5552+ if (retval < 0) {
5553+ dev_err(&dev->dev,
5554+ "failed submitting urb for ATUSB_BUILD, error %d\n",
5555+ retval);
5556+ return retval == -ENOMEM ? retval : -EIO;
5557+ }
5558+
5559+ build[retval] = 0;
5560+ dev_info(&dev->dev, "Firmware: build %s\n", build);
5561+
5562+ return 0;
5563+}
5564+
5565+
5566+/* ----- Setup ------------------------------------------------------------- */
5567+
5568+
5569+struct at86rf230_platform_data at86rf230_platform_data = {
5570+ .rstn = -1,
5571+ .slp_tr = -1,
5572+ .dig2 = -1,
5573+ .reset = atusb_reset,
5574+ /* set .reset_data later */
5575+};
5576+
5577+static int atusb_probe(struct usb_interface *interface,
5578+ const struct usb_device_id *id)
5579+{
5580+ struct spi_board_info board_info = {
5581+ .modalias = "at86rf230",
5582+ /* set .irq later */
5583+ .chip_select = 0,
5584+ .bus_num = -1,
5585+ .max_speed_hz = 8 * 1000 * 1000,
5586+ };
5587+
5588+ struct usb_device *udev = interface_to_usbdev(interface);
5589+ struct atusb_local *atusb = NULL;
5590+ struct spi_master *master;
5591+ int retval;
5592+
5593+ /*
5594+ * Ignore all interfaces used for DFU, i.e., everything while in the
5595+ * boot loader, and interface #1 when in the application.
5596+ */
5597+ if (interface->cur_altsetting->desc.bInterfaceClass !=
5598+ USB_CLASS_VENDOR_SPEC) {
5599+ dev_dbg(&udev->dev,
5600+ "Ignoring interface with class 0x%02x\n",
5601+ interface->cur_altsetting->desc.bInterfaceClass);
5602+ return -ENODEV;
5603+ }
5604+
5605+ master = spi_alloc_master(&udev->dev, sizeof(*atusb));
5606+ if (!master)
5607+ return -ENOMEM;
5608+
5609+ atusb = spi_master_get_devdata(master);
5610+
5611+ atusb->udev = usb_get_dev(udev);
5612+ usb_set_intfdata(interface, atusb);
5613+
5614+ atusb->master = spi_master_get(master);
5615+
5616+ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
5617+ master->bus_num = -1;
5618+ master->num_chipselect = 1;
5619+ master->setup = atusb_setup;
5620+ master->transfer = atusb_transfer;
5621+
5622+ atusb->slave_irq = irq_alloc_desc(numa_node_id());
5623+ if (atusb->slave_irq < 0) {
5624+ dev_err(&udev->dev, "can't allocate slave irq\n");
5625+ retval = -ENXIO;
5626+ goto err_free;
5627+ }
5628+
5629+ set_irq_chip_data(atusb->slave_irq, atusb);
5630+ set_irq_chip_and_handler(atusb->slave_irq, &atusb_irq_chip,
5631+ handle_level_irq);
5632+
5633+ /* FIXME prepare USB IRQ */
5634+
5635+ retval = spi_register_master(master);
5636+ if (retval < 0) {
5637+ dev_err(&udev->dev, "can't register spi master\n");
5638+ goto err_slave_irq;
5639+ }
5640+
5641+ atusb->platform_data = at86rf230_platform_data;
5642+ atusb->platform_data.reset_data = atusb;
5643+ board_info.platform_data = &atusb->platform_data;
5644+ board_info.irq = atusb->slave_irq;
5645+
5646+ init_timer(&atusb->timer);
5647+ atusb->timer.function = atusb_timer;
5648+
5649+ tasklet_init(&atusb->task, atusb_tasklet, (unsigned long) atusb);
5650+ tasklet_disable(&atusb->task);
5651+ atusb_arm_interrupt(atusb);
5652+
5653+ if (atusb_get_and_show_revision(atusb) < 0)
5654+ goto err_master;
5655+ if (atusb_get_and_show_build(atusb) < 0)
5656+ goto err_master;
5657+
5658+ atusb->spi = spi_new_device(master, &board_info);
5659+ if (!atusb->spi) {
5660+ dev_err(&udev->dev, "can't create new device for %s\n",
5661+ board_info.modalias);
5662+ goto err_master;
5663+ }
5664+
5665+ dev_info(&atusb->spi->dev,
5666+ "ATUSB ready for mischief (IRQ %d)\n", board_info.irq);
5667+
5668+ return 0;
5669+
5670+err_master:
5671+ /*
5672+ * If we come here from a partially successful driver initialization,
5673+ * we don't really know how much it has done. In particular, it may
5674+ * have triggered an interrupt and thus removed the interrupt URB and
5675+ * maybe scheduled the tasklet.
5676+ */
5677+ tasklet_disable(&atusb->task);
5678+ if (atusb->irq_urb)
5679+ usb_kill_urb(atusb->irq_urb);
5680+ spi_master_put(atusb->master);
5681+err_slave_irq:
5682+ set_irq_chained_handler(atusb->slave_irq, NULL);
5683+ set_irq_chip_data(atusb->slave_irq, NULL);
5684+ irq_free_desc(atusb->slave_irq);
5685+err_free:
5686+ return retval;
5687+}
5688+
5689+static void atusb_disconnect(struct usb_interface *interface)
5690+{
5691+ struct atusb_local *atusb = usb_get_intfdata(interface);
5692+ struct spi_master *master = atusb->master;
5693+
5694+ tasklet_disable(&atusb->task);
5695+ /* @@@ this needs some extra protecion - wa */
5696+ if (atusb->irq_urb)
5697+ usb_kill_urb(atusb->irq_urb);
5698+
5699+ BUG_ON(timer_pending(&atusb->timer));
5700+
5701+ usb_set_intfdata(interface, NULL);
5702+ usb_put_dev(atusb->udev);
5703+
5704+ spi_dev_put(atusb->spi);
5705+
5706+ spi_unregister_master(master);
5707+
5708+ set_irq_chained_handler(atusb->slave_irq, NULL);
5709+ set_irq_chip_data(atusb->slave_irq, NULL);
5710+ irq_free_desc(atusb->slave_irq);
5711+
5712+ spi_master_put(master);
5713+}
5714+
5715+void atusb_release(struct device *dev)
5716+{
5717+ return;
5718+}
5719+
5720+static struct usb_driver atusb_driver = {
5721+ .name = "atusb_ben-wpan",
5722+ .probe = atusb_probe,
5723+ .disconnect = atusb_disconnect,
5724+ .id_table = atusb_device_table,
5725+};
5726+
5727+static struct platform_device atusb_device = {
5728+ .name = "spi_atusb",
5729+ .id = -1,
5730+ .dev.release = atusb_release,
5731+};
5732+
5733+static int __init atusb_init(void)
5734+{
5735+ int retval;
5736+
5737+ retval = platform_device_register(&atusb_device);
5738+ if (retval)
5739+ return retval;
5740+
5741+ return usb_register(&atusb_driver);
5742+}
5743+
5744+static void __exit atusb_exit(void)
5745+{
5746+ usb_deregister(&atusb_driver);
5747+ platform_device_unregister(&atusb_device);
5748+}
5749+
5750+module_init (atusb_init);
5751+module_exit (atusb_exit);
5752+
5753+MODULE_AUTHOR("Richard Sharpe <realrichardsharpe@gmail.com>");
5754+MODULE_AUTHOR("Stefan Schmidt <stefan@datenfreihafen.org>");
5755+MODULE_AUTHOR("Werner Almesberger <werner@almesberger.net>");
5756+MODULE_DESCRIPTION("ATUSB ben-wpan Driver");
5757+MODULE_LICENSE("GPL");
5758diff --git a/include/linux/if.h b/include/linux/if.h
5759index 3bc63e6..4fc7448 100644
5760--- a/include/linux/if.h
5761@@ -77,6 +77,8 @@
5762 #define IFF_OVS_DATAPATH 0x8000 /* device used as Open vSwitch
5763                      * datapath port */
5764
5765+#define IFF_IEEE802154_COORD 0x400 /* IEEE802.15.4 PAN coordinator */
5766+
5767 #define IF_GET_IFACE 0x0001 /* for querying only */
5768 #define IF_GET_PROTO 0x0002
5769
5770diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h
5771index 6d722f4..47a57d8 100644
5772--- a/include/linux/if_arp.h
5773@@ -87,6 +87,8 @@
5774 #define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */
5775 #define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */
5776 #define ARPHRD_IEEE802154 804
5777+#define ARPHRD_IEEE802154_MONITOR 805
5778+#define ARPHRD_SMAC 806 /* Freescale Simple MAC */
5779
5780 #define ARPHRD_PHONET 820 /* PhoNet media type */
5781 #define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */
5782diff --git a/include/linux/if_ieee802154.h b/include/linux/if_ieee802154.h
5783new file mode 100644
5784index 0000000..cce32bb
5785--- /dev/null
5786@@ -0,0 +1,6 @@
5787+#ifndef __LINUX_IF_IEEE802154_H
5788+#define __LINUX_IF_IEEE802154_H
5789+
5790+#define IEEE802154_ALEN 8 /* size of 64-bit hardware address */
5791+
5792+#endif
5793diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h
5794index 33d9f51..a379fc7 100644
5795--- a/include/linux/nl802154.h
5796@@ -68,14 +68,13 @@ enum {
5797     IEEE802154_ATTR_CHANNEL_PAGE_LIST,
5798
5799     IEEE802154_ATTR_PHY_NAME,
5800+ IEEE802154_ATTR_DEV_TYPE,
5801
5802     __IEEE802154_ATTR_MAX,
5803 };
5804
5805 #define IEEE802154_ATTR_MAX (__IEEE802154_ATTR_MAX - 1)
5806
5807-extern const struct nla_policy ieee802154_policy[];
5808-
5809 /* commands */
5810 /* REQ should be responded with CONF
5811  * and INDIC with RESP
5812@@ -126,4 +125,11 @@ enum {
5813
5814 #define IEEE802154_CMD_MAX (__IEEE802154_CMD_MAX - 1)
5815
5816+enum {
5817+ IEEE802154_DEV_WPAN,
5818+ IEEE802154_DEV_MONITOR,
5819+ IEEE802154_DEV_SMAC,
5820+ __IEEE802154_DEV_MAX,
5821+};
5822+
5823 #endif
5824diff --git a/include/linux/spi/at86rf230.h b/include/linux/spi/at86rf230.h
5825new file mode 100644
5826index 0000000..dff0225
5827--- /dev/null
5828@@ -0,0 +1,34 @@
5829+/*
5830+ * AT86RF230/RF231 driver
5831+ *
5832+ * Copyright (C) 2009 Siemens AG
5833+ *
5834+ * This program is free software; you can redistribute it and/or modify
5835+ * it under the terms of the GNU General Public License version 2
5836+ * as published by the Free Software Foundation.
5837+ *
5838+ * This program is distributed in the hope that it will be useful,
5839+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5840+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5841+ * GNU General Public License for more details.
5842+ *
5843+ * You should have received a copy of the GNU General Public License along
5844+ * with this program; if not, write to the Free Software Foundation, Inc.,
5845+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
5846+ *
5847+ * Written by:
5848+ * Dmitry Eremin-Solenikov <dmitry.baryshkov@siemens.com>
5849+ */
5850+#ifndef LINUX_SPI_AT86RF230_H
5851+#define LINUX_SPI_AT86RF230_H
5852+
5853+struct at86rf230_platform_data {
5854+ int rstn;
5855+ int slp_tr;
5856+ int dig2;
5857+ void (*reset)(void *reset_data);
5858+ void *reset_data;
5859+};
5860+
5861+#endif
5862+
5863diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
5864index 5743055..e12ce9a 100644
5865--- a/include/net/ieee802154_netdev.h
5866@@ -26,6 +26,8 @@
5867 #ifndef IEEE802154_NETDEVICE_H
5868 #define IEEE802154_NETDEVICE_H
5869
5870+#include <net/af_ieee802154.h>
5871+
5872 /*
5873  * A control block of skb passed between the ARPHRD_IEEE802154 device
5874  * and other stack parts.
5875@@ -81,7 +83,12 @@ struct wpan_phy;
5876  * get_phy should increment the reference counting on returned phy.
5877  * Use wpan_wpy_put to put that reference.
5878  */
5879+struct simple_mlme_ops {
5880+ struct wpan_phy *(*get_phy)(const struct net_device *dev);
5881+};
5882 struct ieee802154_mlme_ops {
5883+ struct simple_mlme_ops wpan_ops;
5884+
5885     int (*assoc_req)(struct net_device *dev,
5886             struct ieee802154_addr *addr,
5887             u8 channel, u8 page, u8 cap);
5888@@ -98,8 +105,6 @@ struct ieee802154_mlme_ops {
5889     int (*scan_req)(struct net_device *dev,
5890             u8 type, u32 channels, u8 page, u8 duration);
5891
5892- struct wpan_phy *(*get_phy)(const struct net_device *dev);
5893-
5894     /*
5895      * FIXME: these should become the part of PIB/MIB interface.
5896      * However we still don't have IB interface of any kind
5897@@ -110,12 +115,18 @@ struct ieee802154_mlme_ops {
5898     u8 (*get_bsn)(const struct net_device *dev);
5899 };
5900
5901-static inline struct ieee802154_mlme_ops *ieee802154_mlme_ops(
5902+static inline struct simple_mlme_ops *simple_mlme_ops(
5903         const struct net_device *dev)
5904 {
5905     return dev->ml_priv;
5906 }
5907
5908+static inline struct ieee802154_mlme_ops *ieee802154_mlme_ops(
5909+ const struct net_device *dev)
5910+{
5911+ return container_of(dev->ml_priv, struct ieee802154_mlme_ops, wpan_ops);
5912+}
5913+
5914 #endif
5915
5916
5917diff --git a/include/net/mac802154.h b/include/net/mac802154.h
5918new file mode 100644
5919index 0000000..df46f6a
5920--- /dev/null
5921@@ -0,0 +1,156 @@
5922+/*
5923+ * IEEE802.15.4-2003 specification
5924+ *
5925+ * Copyright (C) 2007, 2008 Siemens AG
5926+ *
5927+ * This program is free software; you can redistribute it and/or modify
5928+ * it under the terms of the GNU General Public License version 2
5929+ * as published by the Free Software Foundation.
5930+ *
5931+ * This program is distributed in the hope that it will be useful,
5932+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5933+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5934+ * GNU General Public License for more details.
5935+ *
5936+ * You should have received a copy of the GNU General Public License along
5937+ * with this program; if not, write to the Free Software Foundation, Inc.,
5938+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
5939+ *
5940+ * Written by:
5941+ */
5942+#ifndef NET_MAC802154_H
5943+#define NET_MAC802154_H
5944+
5945+#include <linux/if_ieee802154.h>
5946+
5947+/**
5948+ * enum ieee802154_hw_addr_filt_flags - hardware flags
5949+ *
5950+ * These flags are used to indicate changed address settings from
5951+ * the stack to the hardware.
5952+ *
5953+ * @IEEE802515_SADDR_CHANGED:
5954+ * Indicates that the Short Address changed
5955+ *
5956+ * @IEEE802515_IEEEADDR_CHANGED:
5957+ * Indicates that the IEEE Address changed
5958+ *
5959+ * @IEEE802515_PANID_CHANGED:
5960+ * Indicates that the PAN ID changed
5961+ *
5962+ * @IEEE802515_PANC_CHANGED:
5963+ * Indicates that PAN Coordinator status changed
5964+ */
5965+enum ieee802154_hw_addr_filt_flags {
5966+ IEEE802515_SADDR_CHANGED = 1 << 0,
5967+ IEEE802515_IEEEADDR_CHANGED = 1 << 1,
5968+ IEEE802515_PANID_CHANGED = 1 << 2,
5969+ IEEE802515_PANC_CHANGED = 1 << 3,
5970+};
5971+
5972+struct ieee802154_hw_addr_filt {
5973+ u16 pan_id;
5974+ u16 short_addr;
5975+ u8 ieee_addr[IEEE802154_ALEN];
5976+ u8 pan_coord;
5977+};
5978+
5979+struct ieee802154_dev {
5980+ /* filled by the driver */
5981+ int extra_tx_headroom; /* headroom to reserve for tx skb */
5982+ u32 flags; /* Flags for device to set */
5983+ struct device *parent;
5984+
5985+ /* filled by mac802154 core */
5986+ struct ieee802154_hw_addr_filt hw_filt;
5987+ void *priv; /* driver-specific data */
5988+ struct wpan_phy *phy;
5989+};
5990+
5991+/* Checksum is in hardware and is omitted from packet */
5992+/**
5993+ * enum ieee802154_hw_flags - hardware flags
5994+ *
5995+ * These flags are used to indicate hardware capabilities to
5996+ * the stack. Generally, flags here should have their meaning
5997+ * done in a way that the simplest hardware doesn't need setting
5998+ * any particular flags. There are some exceptions to this rule,
5999+ * however, so you are advised to review these flags carefully.
6000+ *
6001+ * @IEEE802154_HW_OMIT_CKSUM:
6002+ * Indicates that receiver omits FCS and transmitter will add
6003+ * FCS on it's own.
6004+ *
6005+ * @IEEE802154_HW_AACK:
6006+ * Indicates that receiver will autorespond with ACK frames.
6007+ */
6008+enum ieee802154_hw_flags {
6009+ IEEE802154_HW_OMIT_CKSUM = 1 << 0,
6010+ IEEE802154_HW_AACK = 1 << 1,
6011+};
6012+
6013+struct sk_buff;
6014+
6015+/**
6016+ * struct ieee802154_ops - callbacks from mac802154 to the driver
6017+ *
6018+ * This structure contains various callbacks that the driver may
6019+ * handle or, in some cases, must handle, for example to transmit
6020+ * a frame.
6021+ *
6022+ * @start: Handler that 802.15.4 module calls for device initialisation.
6023+ * This function is called before the first interface is attached.
6024+ *
6025+ * @stop: Handler that 802.15.4 module calls for device cleanup
6026+ * This function is called after the last interface is removed.
6027+ *
6028+ * @xmit: Handler that 802.15.4 module calls for each transmitted frame.
6029+ * skb cntains the buffer starting from the IEEE 802.15.4 header.
6030+ * The low-level driver should send the frame based on available
6031+ * configuration.
6032+ * This function should return zero or negative errno.
6033+ * Called with pib_lock held.
6034+ *
6035+ * @ed: Handler that 802.15.4 module calls for Energy Detection.
6036+ * This function should place the value for detected energy
6037+ * (usually device-dependant) in the level pointer and return
6038+ * either zero or negative errno.
6039+ * Called with pib_lock held.
6040+ *
6041+ * @set_channel: Set radio for listening on specific channel.
6042+ * Set the device for listening on specified channel.
6043+ * Returns either zero, or negative errno.
6044+ * Called with pib_lock held.
6045+ *
6046+ * @set_hw_addr_filt: Set radio for listening on specific address.
6047+ * Set the device for listening on specified address.
6048+ * Returns either zero, or negative errno.
6049+ */
6050+struct ieee802154_ops {
6051+ struct module *owner;
6052+ int (*start)(struct ieee802154_dev *dev);
6053+ void (*stop)(struct ieee802154_dev *dev);
6054+ int (*xmit)(struct ieee802154_dev *dev,
6055+ struct sk_buff *skb);
6056+ int (*ed)(struct ieee802154_dev *dev, u8 *level);
6057+ int (*set_channel)(struct ieee802154_dev *dev,
6058+ int page,
6059+ int channel);
6060+ int (*set_hw_addr_filt)(struct ieee802154_dev *dev,
6061+ struct ieee802154_hw_addr_filt *filt,
6062+ unsigned long changed);
6063+ int (*ieee_addr)(struct ieee802154_dev *dev,
6064+ u8 addr[IEEE802154_ALEN]);
6065+};
6066+
6067+struct ieee802154_dev *ieee802154_alloc_device(size_t priv_size,
6068+ struct ieee802154_ops *ops);
6069+int ieee802154_register_device(struct ieee802154_dev *dev);
6070+void ieee802154_unregister_device(struct ieee802154_dev *dev);
6071+void ieee802154_free_device(struct ieee802154_dev *dev);
6072+
6073+void ieee802154_rx(struct ieee802154_dev *dev, struct sk_buff *skb, u8 lqi);
6074+void ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb,
6075+ u8 lqi);
6076+#endif
6077+
6078diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h
6079index d86fffd..9e119c5 100644
6080--- a/include/net/wpan-phy.h
6081@@ -24,17 +24,19 @@
6082 #include <linux/netdevice.h>
6083 #include <linux/mutex.h>
6084
6085+#define WPAN_NUM_PAGES 32
6086+
6087 struct wpan_phy {
6088     struct mutex pib_lock;
6089
6090     /*
6091- * This is a PIB according to 802.15.4-2006.
6092+ * This is a PIB acording to 802.15.4-2006.
6093      * We do not provide timing-related variables, as they
6094      * aren't used outside of driver
6095      */
6096     u8 current_channel;
6097     u8 current_page;
6098- u32 channels_supported[32];
6099+ u32 channels_supported[WPAN_NUM_PAGES];
6100     u8 transmit_power;
6101     u8 cca_mode;
6102
6103@@ -42,7 +44,7 @@ struct wpan_phy {
6104     int idx;
6105
6106     struct net_device *(*add_iface)(struct wpan_phy *phy,
6107- const char *name);
6108+ const char *name, int type);
6109     void (*del_iface)(struct wpan_phy *phy, struct net_device *dev);
6110
6111     char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
6112diff --git a/net/Kconfig b/net/Kconfig
6113index 878151c..66271cc 100644
6114--- a/net/Kconfig
6115@@ -211,6 +211,8 @@ source "net/econet/Kconfig"
6116 source "net/wanrouter/Kconfig"
6117 source "net/phonet/Kconfig"
6118 source "net/ieee802154/Kconfig"
6119+source "net/mac802154/Kconfig"
6120+source "net/zigbee/Kconfig"
6121 source "net/sched/Kconfig"
6122 source "net/dcb/Kconfig"
6123 source "net/dns_resolver/Kconfig"
6124diff --git a/net/Makefile b/net/Makefile
6125index a51d946..b7a6585 100644
6126--- a/net/Makefile
6127@@ -60,6 +60,7 @@ ifneq ($(CONFIG_DCB),)
6128 obj-y += dcb/
6129 endif
6130 obj-$(CONFIG_IEEE802154) += ieee802154/
6131+obj-$(CONFIG_MAC802154) += mac802154/
6132
6133 ifeq ($(CONFIG_NET),y)
6134 obj-$(CONFIG_SYSCTL) += sysctl_net.o
6135diff --git a/net/ieee802154/Kconfig b/net/ieee802154/Kconfig
6136index 1c1de97..5f1a5af 100644
6137--- a/net/ieee802154/Kconfig
6138@@ -10,3 +10,12 @@ config IEEE802154
6139
6140       Say Y here to compile LR-WPAN support into the kernel or say M to
6141       compile it as modules.
6142+
6143+config IEEE802154_PROTO_DEBUG
6144+ bool "IEEE 802.15.4 protocol stack debugging messages"
6145+ depends on IEEE802154
6146+ default y
6147+ help
6148+ Say Y here to make the IEEE 802.15.4 protocol stack generate
6149+ extensive debugging messages.
6150+
6151diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile
6152index 5761185..53f1ec3 100644
6153--- a/net/ieee802154/Makefile
6154@@ -1,3 +1,6 @@
6155 obj-$(CONFIG_IEEE802154) += ieee802154.o af_802154.o
6156 ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o wpan-class.o
6157 af_802154-y := af_ieee802154.o raw.o dgram.o
6158+
6159+ccflags-$(CONFIG_IEEE802154_PROTO_DEBUG) += -DDEBUG
6160+ccflags-y += -Wall
6161diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c
6162index 1a3334c..5c69833 100644
6163--- a/net/ieee802154/dgram.c
6164@@ -130,8 +130,7 @@ static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg)
6165     switch (cmd) {
6166     case SIOCOUTQ:
6167     {
6168- int amount = sk_wmem_alloc_get(sk);
6169-
6170+ int amount = atomic_read(&sk->sk_wmem_alloc);
6171         return put_user(amount, (int __user *)arg);
6172     }
6173
6174diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
6175index aadec42..e78d6c6 100644
6176--- a/net/ieee802154/ieee802154.h
6177@@ -21,6 +21,10 @@
6178 int __init ieee802154_nl_init(void);
6179 void __exit ieee802154_nl_exit(void);
6180
6181+#include <net/netlink.h>
6182+
6183+extern const struct nla_policy ieee802154_policy[];
6184+
6185 #define IEEE802154_OP(_cmd, _func) \
6186     { \
6187         .cmd = _cmd, \
6188diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
6189index 71ee110..51e375e 100644
6190--- a/net/ieee802154/nl-mac.c
6191@@ -262,7 +262,7 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 pid,
6192     if (!hdr)
6193         goto out;
6194
6195- phy = ieee802154_mlme_ops(dev)->get_phy(dev);
6196+ phy = simple_mlme_ops(dev)->get_phy(dev);
6197     BUG_ON(!phy);
6198
6199     NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
6200diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
6201index 02548b2..49a29d7 100644
6202--- a/net/ieee802154/nl-phy.c
6203@@ -24,6 +24,7 @@
6204
6205 #include <linux/kernel.h>
6206 #include <linux/slab.h>
6207+#include <linux/if_arp.h>
6208 #include <net/netlink.h>
6209 #include <net/genetlink.h>
6210 #include <net/wpan-phy.h>
6211@@ -44,7 +45,7 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 pid,
6212     pr_debug("%s\n", __func__);
6213
6214     if (!buf)
6215- return -EMSGSIZE;
6216+ goto out;
6217
6218     hdr = genlmsg_put(msg, 0, seq, &nl802154_family, flags,
6219         IEEE802154_LIST_PHY);
6220@@ -56,7 +57,7 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 pid,
6221
6222     NLA_PUT_U8(msg, IEEE802154_ATTR_PAGE, phy->current_page);
6223     NLA_PUT_U8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel);
6224- for (i = 0; i < 32; i++) {
6225+ for (i = 0; i < WPAN_NUM_PAGES; i++) {
6226         if (phy->channels_supported[i])
6227             buf[pages++] = phy->channels_supported[i] | (i << 27);
6228     }
6229@@ -65,7 +66,6 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 pid,
6230                 pages * sizeof(uint32_t), buf);
6231
6232     mutex_unlock(&phy->pib_lock);
6233- kfree(buf);
6234     return genlmsg_end(msg, hdr);
6235
6236 nla_put_failure:
6237@@ -178,6 +178,7 @@ static int ieee802154_add_iface(struct sk_buff *skb,
6238     const char *devname;
6239     int rc = -ENOBUFS;
6240     struct net_device *dev;
6241+ int type = IEEE802154_DEV_WPAN;
6242
6243     pr_debug("%s\n", __func__);
6244
6245@@ -192,7 +193,7 @@ static int ieee802154_add_iface(struct sk_buff *skb,
6246         devname = nla_data(info->attrs[IEEE802154_ATTR_DEV_NAME]);
6247         if (devname[nla_len(info->attrs[IEEE802154_ATTR_DEV_NAME]) - 1]
6248                 != '\0')
6249- return -EINVAL; /* phy name should be null-terminated */
6250+ return -EINVAL; /* dev name should be null-terminated */
6251     } else {
6252         devname = "wpan%d";
6253     }
6254@@ -200,6 +201,19 @@ static int ieee802154_add_iface(struct sk_buff *skb,
6255     if (strlen(devname) >= IFNAMSIZ)
6256         return -ENAMETOOLONG;
6257
6258+ if (info->attrs[IEEE802154_ATTR_HW_ADDR] &&
6259+ nla_len(info->attrs[IEEE802154_ATTR_HW_ADDR]) !=
6260+ IEEE802154_ADDR_LEN) {
6261+ return -EINVAL;
6262+ }
6263+
6264+ if (info->attrs[IEEE802154_ATTR_DEV_TYPE]) {
6265+ type = nla_get_u8(info->attrs[IEEE802154_ATTR_DEV_TYPE]);
6266+ if (type > __IEEE802154_DEV_MAX) {
6267+ return -EINVAL;
6268+ }
6269+ }
6270+
6271     phy = wpan_phy_find(name);
6272     if (!phy)
6273         return -ENODEV;
6274@@ -213,12 +227,29 @@ static int ieee802154_add_iface(struct sk_buff *skb,
6275         goto nla_put_failure;
6276     }
6277
6278- dev = phy->add_iface(phy, devname);
6279+ dev = phy->add_iface(phy, devname, type);
6280     if (IS_ERR(dev)) {
6281         rc = PTR_ERR(dev);
6282         goto nla_put_failure;
6283     }
6284
6285+ if (info->attrs[IEEE802154_ATTR_HW_ADDR]) {
6286+ struct sockaddr addr;
6287+
6288+ addr.sa_family = ARPHRD_IEEE802154;
6289+ nla_memcpy(&addr.sa_data, info->attrs[IEEE802154_ATTR_HW_ADDR], IEEE802154_ADDR_LEN);
6290+
6291+ /*
6292+ * strangely enough, some callbacks (inetdev_event) from
6293+ * dev_set_mac_address require RTNL_LOCK
6294+ */
6295+ rtnl_lock();
6296+ rc = dev_set_mac_address(dev, &addr);
6297+ rtnl_unlock();
6298+ if (rc)
6299+ goto dev_unregister;
6300+ }
6301+
6302     NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy));
6303     NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
6304
6305@@ -228,6 +259,11 @@ static int ieee802154_add_iface(struct sk_buff *skb,
6306
6307     return ieee802154_nl_reply(msg, info);
6308
6309+dev_unregister:
6310+ rtnl_lock(); /* del_iface must be called with RTNL lock */
6311+ phy->del_iface(phy, dev);
6312+ dev_put(dev);
6313+ rtnl_unlock();
6314 nla_put_failure:
6315     nlmsg_free(msg);
6316 out_dev:
6317@@ -257,7 +293,7 @@ static int ieee802154_del_iface(struct sk_buff *skb,
6318     if (!dev)
6319         return -ENODEV;
6320
6321- phy = ieee802154_mlme_ops(dev)->get_phy(dev);
6322+ phy = simple_mlme_ops(dev)->get_phy(dev);
6323     BUG_ON(!phy);
6324
6325     rc = -EINVAL;
6326diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c
6327index 6adda4d..235cd65 100644
6328--- a/net/ieee802154/nl_policy.c
6329@@ -28,6 +28,7 @@ const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = {
6330     [IEEE802154_ATTR_DEV_NAME] = { .type = NLA_STRING, },
6331     [IEEE802154_ATTR_DEV_INDEX] = { .type = NLA_U32, },
6332     [IEEE802154_ATTR_PHY_NAME] = { .type = NLA_STRING, },
6333+ [IEEE802154_ATTR_DEV_TYPE] = { .type = NLA_U8, },
6334
6335     [IEEE802154_ATTR_STATUS] = { .type = NLA_U8, },
6336     [IEEE802154_ATTR_SHORT_ADDR] = { .type = NLA_U16, },
6337diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
6338index 1627ef2..380fe1a 100644
6339--- a/net/ieee802154/wpan-class.c
6340@@ -56,7 +56,7 @@ static ssize_t channels_supported_show(struct device *dev,
6341     int i, len = 0;
6342
6343     mutex_lock(&phy->pib_lock);
6344- for (i = 0; i < 32; i++) {
6345+ for (i = 0; i < WPAN_NUM_PAGES; i++) {
6346         ret = snprintf(buf + len, PAGE_SIZE - len,
6347                 "%#09x\n", phy->channels_supported[i]);
6348         if (ret < 0)
6349diff --git a/net/mac802154/Kconfig b/net/mac802154/Kconfig
6350new file mode 100644
6351index 0000000..32e63bc
6352--- /dev/null
6353@@ -0,0 +1,24 @@
6354+config MAC802154
6355+ tristate "Generic IEEE 802.15.4 Soft Networking Stack (mac802154)"
6356+ depends on IEEE802154 && EXPERIMENTAL
6357+ select CRC_CCITT
6358+ ---help---
6359+ This option enables the hardware independent IEEE 802.15.4
6360+ networking stack for SoftMAC devices (the ones implementing
6361+ only PHY level of IEEE 802.15.4 standard).
6362+
6363+ Note: this implementation is neither certified, nor feature
6364+ complete! We do not guarantee that it is compatible w/ other
6365+ implementations, etc.
6366+
6367+ If you plan to use HardMAC IEEE 802.15.4 devices, you can
6368+ say N here. Alternatievly you can say M to compile it as
6369+ module.
6370+
6371+config MAC802154_DEBUG
6372+ bool "IEEE 802.15.4 SoftMAC debugging messages"
6373+ depends on MAC802154
6374+ default y
6375+ help
6376+ Say Y here to make the IEEE 802.15.4 SoftMAC generate extensive
6377+ debugging messages.
6378diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile
6379new file mode 100644
6380index 0000000..d76fabb
6381--- /dev/null
6382@@ -0,0 +1,6 @@
6383+obj-$(CONFIG_MAC802154) += mac802154.o
6384+mac802154-objs := rx.o tx.o main.o monitor.o wpan.o mac_cmd.o scan.o mib.o \
6385+ beacon.o beacon_hash.o smac.o
6386+
6387+ccflags-$(CONFIG_MAC802154_DEBUG) += -DDEBUG
6388+ccflags-y += -Wall
6389diff --git a/net/mac802154/beacon.c b/net/mac802154/beacon.c
6390new file mode 100644
6391index 0000000..6b0d327
6392--- /dev/null
6393@@ -0,0 +1,282 @@
6394+/*
6395+ * MAC beacon interface
6396+ *
6397+ * Copyright 2007, 2008 Siemens AG
6398+ *
6399+ * This program is free software; you can redistribute it and/or modify
6400+ * it under the terms of the GNU General Public License version 2
6401+ * as published by the Free Software Foundation.
6402+ *
6403+ * This program is distributed in the hope that it will be useful,
6404+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6405+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6406+ * GNU General Public License for more details.
6407+ *
6408+ * You should have received a copy of the GNU General Public License along
6409+ * with this program; if not, write to the Free Software Foundation, Inc.,
6410+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
6411+ *
6412+ * Written by:
6413+ * Sergey Lapin <slapin@ossfans.org>
6414+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
6415+ */
6416+
6417+#include <linux/kernel.h>
6418+#include <linux/slab.h>
6419+#include <linux/if_arp.h>
6420+#include <linux/list.h>
6421+
6422+#include <net/af_ieee802154.h>
6423+#include <net/nl802154.h>
6424+#include <net/mac802154.h>
6425+#include <net/ieee802154.h>
6426+#include <net/ieee802154_netdev.h>
6427+
6428+#include "mac802154.h"
6429+#include "beacon_hash.h"
6430+
6431+/* Beacon frame format per specification is the followinf:
6432+ * Standard MAC frame header:
6433+ * FC (2) SEQ (1)
6434+ * Addressing (4-20)
6435+ * Beacon fields:
6436+ * <Superframe specification> (2)
6437+ * <GTS> (?)
6438+ * <Pending address> (?)
6439+ * <Beacon payload> (?)
6440+ * FCS (2)
6441+ *
6442+ * Superframe specification:
6443+ * bit Value
6444+ * 15 Association permit
6445+ * 14 PAN coordinator
6446+ * 13 Reserved
6447+ * 12 Battery life extension
6448+ * 8-11 Final CAP slot
6449+ * 4-7 Superframe order
6450+ * 0-3 Beacon order
6451+ *
6452+ * GTS:
6453+ * <GTS specification> (1)
6454+ * <GTS directions> (0-1)
6455+ * <GTS list> (?)
6456+ *
6457+ * Pending address:
6458+ * <Pending address specification> (1)
6459+ * <Pending address list (?)
6460+ *
6461+ * GTS specification:
6462+ * bit Value
6463+ * 7 GTS permit
6464+ * 3-6 Reserved
6465+ * 0-2 GTS descriptor count
6466+ *
6467+ * Pending address specification:
6468+ * bit Value
6469+ * 7 Reserved
6470+ * 4-6 Number of extended addresses pendinf
6471+ * 3 Reserved
6472+ * 0-2 Number of short addresses pending
6473+ * */
6474+
6475+#define IEEE802154_BEACON_SF_BO_BEACONLESS (15 << 0)
6476+#define IEEE802154_BEACON_SF_SO(x) ((x & 0xf) << 4)
6477+#define IEEE802154_BEACON_SF_SO_INACTIVE IEEE802154_BEACON_SF_SO(15)
6478+#define IEEE802154_BEACON_SF_PANCOORD (1 << 14)
6479+#define IEEE802154_BEACON_SF_CANASSOC (1 << 15)
6480+#define IEEE802154_BEACON_GTS_COUNT(x) (x << 0)
6481+#define IEEE802154_BEACON_GTS_PERMIT (1 << 7)
6482+#define IEEE802154_BEACON_PA_SHORT(x) ((x & 7) << 0)
6483+#define IEEE802154_BEACON_PA_LONG(x) ((x & 7) << 4)
6484+
6485+/* Flags parameter */
6486+#define IEEE802154_BEACON_FLAG_PANCOORD (1 << 0)
6487+#define IEEE802154_BEACON_FLAG_CANASSOC (1 << 1)
6488+#define IEEE802154_BEACON_FLAG_GTSPERMIT (1 << 2)
6489+
6490+struct mac802154_address_list {
6491+ struct list_head list;
6492+ struct ieee802154_addr addr;
6493+};
6494+
6495+/* Per spec; optimizations are needed */
6496+struct mac802154_pandsc {
6497+ struct list_head list;
6498+ struct ieee802154_addr addr; /* Contains panid */
6499+ int channel;
6500+ u16 sf;
6501+ bool gts_permit;
6502+ u8 lqi;
6503+/* FIXME: Aging of stored PAN descriptors is not decided yet,
6504+ * because no PAN descriptor storage is implemented yet */
6505+ u32 timestamp;
6506+};
6507+
6508+/*
6509+ * @dev device
6510+ * @addr destination address
6511+ * @saddr source address
6512+ * @buf beacon payload
6513+ * @len beacon payload size
6514+ * @pan_coord - if we're PAN coordinator while sending this frame
6515+ * @gts_permit - wheather we allow GTS requests
6516+ * @al address list to be provided in beacon
6517+ *
6518+ * TODO:
6519+ * For a beacon frame, the sequence number field shall specify a BSN.
6520+ * Each coordinator shall store its current
6521+ * BSN value in the MAC PIB attribute macBSN and initialize it to
6522+ * a random value.
6523+ * The algorithm for choosing a random number is out of the scope
6524+ * of this standard. The coordinator shall copy the value of the macBSN
6525+ * attribute into the sequence number field of a beacon frame,
6526+ * each time one is generated, and shall then increment macBSN by one.
6527+ *
6528+*/
6529+
6530+
6531+int mac802154_send_beacon(struct net_device *dev,
6532+ struct ieee802154_addr *saddr,
6533+ u16 pan_id, const u8 *buf, int len,
6534+ int flags, struct list_head *al)
6535+{
6536+ struct sk_buff *skb;
6537+ int err;
6538+ u16 sf;
6539+ u8 gts;
6540+ u8 pa_spec;
6541+ int addr16_cnt;
6542+ int addr64_cnt;
6543+ struct ieee802154_addr addr;
6544+
6545+ BUG_ON(dev->type != ARPHRD_IEEE802154);
6546+
6547+ skb = alloc_skb(LL_ALLOCATED_SPACE(dev) + len, GFP_ATOMIC);
6548+ if (!skb)
6549+ return -ENOMEM;
6550+
6551+ skb_reserve(skb, LL_RESERVED_SPACE(dev));
6552+
6553+ skb_reset_network_header(skb);
6554+
6555+ mac_cb(skb)->flags = IEEE802154_FC_TYPE_BEACON;
6556+ mac_cb(skb)->seq = ieee802154_mlme_ops(dev)->get_bsn(dev);
6557+
6558+ addr.addr_type = IEEE802154_ADDR_NONE;
6559+ err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &addr, saddr, len);
6560+ if (err < 0) {
6561+ kfree_skb(skb);
6562+ return err;
6563+ }
6564+ skb_reset_mac_header(skb);
6565+
6566+ /* Superframe */
6567+ sf = IEEE802154_BEACON_SF_BO_BEACONLESS;
6568+ sf |= IEEE802154_BEACON_SF_SO_INACTIVE;
6569+ if (flags & IEEE802154_BEACON_FLAG_PANCOORD)
6570+ sf |= IEEE802154_BEACON_SF_PANCOORD;
6571+
6572+ if (flags & IEEE802154_BEACON_FLAG_CANASSOC)
6573+ sf |= IEEE802154_BEACON_SF_CANASSOC;
6574+ memcpy(skb_put(skb, sizeof(sf)), &sf, sizeof(sf));
6575+
6576+ /* TODO GTS */
6577+ gts = 0;
6578+
6579+ if (flags & IEEE802154_BEACON_FLAG_GTSPERMIT)
6580+ gts |= IEEE802154_BEACON_GTS_PERMIT;
6581+ memcpy(skb_put(skb, sizeof(gts)), &gts, sizeof(gts));
6582+
6583+ /* FIXME pending address */
6584+ addr16_cnt = 0;
6585+ addr64_cnt = 0;
6586+
6587+ pa_spec = IEEE802154_BEACON_PA_LONG(addr64_cnt) |
6588+ IEEE802154_BEACON_PA_SHORT(addr16_cnt);
6589+ memcpy(skb_put(skb, sizeof(pa_spec)), &pa_spec, sizeof(pa_spec));
6590+
6591+ memcpy(skb_put(skb, len), buf, len);
6592+
6593+ skb->dev = dev;
6594+ skb->protocol = htons(ETH_P_IEEE802154);
6595+
6596+ return dev_queue_xmit(skb);
6597+}
6598+
6599+/* at entry to this function we need skb->data to point to start
6600+ * of beacon field and MAC frame already parsed into MAC_CB */
6601+
6602+static int parse_beacon_frame(struct sk_buff *skb, u8 *buf,
6603+ int *flags, struct list_head *al)
6604+{
6605+ int offt = 0;
6606+ u8 gts_spec;
6607+ u8 pa_spec;
6608+ struct mac802154_pandsc *pd;
6609+ u16 sf = skb->data[0] + (skb->data[1] << 8);
6610+
6611+ pd = kzalloc(sizeof(struct mac802154_pandsc), GFP_KERNEL);
6612+
6613+ /* Filling-up pre-parsed values */
6614+ pd->lqi = mac_cb(skb)->lqi;
6615+ pd->sf = sf;
6616+ /* FIXME: make sure we do it right */
6617+ memcpy(&pd->addr, &mac_cb(skb)->da, sizeof(struct ieee802154_addr));
6618+
6619+ /* Supplying our nitifiers with data */
6620+ ieee802154_nl_beacon_indic(skb->dev, pd->addr.pan_id,
6621+ pd->addr.short_addr);
6622+ /* FIXME: We don't cache PAN descriptors yet */
6623+ kfree(pd);
6624+
6625+ offt += 2;
6626+ gts_spec = skb->data[offt++];
6627+ /* FIXME !!! */
6628+ if ((gts_spec & 7) != 0) {
6629+ pr_debug("We still don't parse GTS part properly");
6630+ return -ENOTSUPP;
6631+ }
6632+ pa_spec = skb->data[offt++];
6633+ /* FIXME !!! */
6634+ if (pa_spec != 0) {
6635+ pr_debug("We still don't parse PA part properly");
6636+ return -ENOTSUPP;
6637+ }
6638+
6639+ *flags = 0;
6640+
6641+ if (sf & IEEE802154_BEACON_SF_PANCOORD)
6642+ *flags |= IEEE802154_BEACON_FLAG_PANCOORD;
6643+
6644+ if (sf & IEEE802154_BEACON_SF_CANASSOC)
6645+ *flags |= IEEE802154_BEACON_FLAG_CANASSOC;
6646+ BUG_ON(skb->len - offt < 0);
6647+ /* FIXME */
6648+ if (buf && (skb->len - offt > 0))
6649+ memcpy(buf, skb->data + offt, skb->len - offt);
6650+ return 0;
6651+}
6652+
6653+int mac802154_process_beacon(struct net_device *dev,
6654+ struct sk_buff *skb)
6655+{
6656+ int flags;
6657+ int ret;
6658+ ret = parse_beacon_frame(skb, NULL, &flags, NULL);
6659+
6660+ /* Here we have cb->sa = coordinator address, and PAN address */
6661+
6662+ if (ret < 0) {
6663+ ret = NET_RX_DROP;
6664+ goto fail;
6665+ }
6666+ dev_dbg(&dev->dev, "got beacon from pan %04x\n",
6667+ mac_cb(skb)->sa.pan_id);
6668+ mac802154_beacon_hash_add(&mac_cb(skb)->sa);
6669+ mac802154_beacon_hash_dump();
6670+ ret = NET_RX_SUCCESS;
6671+fail:
6672+ kfree_skb(skb);
6673+ return ret;
6674+}
6675+
6676diff --git a/net/mac802154/beacon_hash.c b/net/mac802154/beacon_hash.c
6677new file mode 100644
6678index 0000000..97fb987
6679--- /dev/null
6680@@ -0,0 +1,106 @@
6681+/*
6682+ * MAC beacon hash storage
6683+ *
6684+ * Copyright 2007, 2008 Siemens AG
6685+ *
6686+ * This program is free software; you can redistribute it and/or modify
6687+ * it under the terms of the GNU General Public License version 2
6688+ * as published by the Free Software Foundation.
6689+ *
6690+ * This program is distributed in the hope that it will be useful,
6691+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6692+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6693+ * GNU General Public License for more details.
6694+ *
6695+ * You should have received a copy of the GNU General Public License along
6696+ * with this program; if not, write to the Free Software Foundation, Inc.,
6697+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
6698+ *
6699+ * Written by:
6700+ * Sergey Lapin <slapin@ossfans.org>
6701+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
6702+ */
6703+
6704+#include <linux/slab.h>
6705+#include <linux/list.h>
6706+#include <linux/spinlock.h>
6707+
6708+#include <net/af_ieee802154.h>
6709+
6710+#include "beacon_hash.h"
6711+
6712+static struct hlist_head beacon_hash[IEEE802154_BEACON_HTABLE_SIZE];
6713+static DEFINE_SPINLOCK(beacon_hash_lock);
6714+
6715+static int beacon_hashfn(struct ieee802154_addr *coord_addr, u16 pan_addr)
6716+{
6717+ return pan_addr % IEEE802154_BEACON_HTABLE_SIZE;
6718+}
6719+
6720+static void __beacon_add_node(struct ieee802154_addr *coord_addr, u16 pan_addr)
6721+{
6722+ struct beacon_node *node =
6723+ kzalloc(sizeof(struct beacon_node), GFP_KERNEL);
6724+ struct hlist_head *list =
6725+ &beacon_hash[beacon_hashfn(coord_addr, pan_addr)];
6726+ memcpy(&node->coord_addr, coord_addr, sizeof(struct ieee802154_addr));
6727+ node->pan_addr = pan_addr;
6728+ INIT_HLIST_NODE(&node->list);
6729+ hlist_add_head(&node->list, list);
6730+}
6731+
6732+struct beacon_node *mac802154_beacon_find_pan(
6733+ struct ieee802154_addr *coord_addr, u16 pan_addr)
6734+{
6735+ struct hlist_head *list;
6736+ struct hlist_node *tmp;
6737+ list = &beacon_hash[beacon_hashfn(coord_addr, pan_addr)];
6738+ if (hlist_empty(list))
6739+ return NULL;
6740+ hlist_for_each(tmp, list) {
6741+ struct beacon_node *entry =
6742+ hlist_entry(tmp, struct beacon_node, list);
6743+ if (entry->pan_addr == pan_addr)
6744+ return entry;
6745+ }
6746+ return NULL;
6747+}
6748+
6749+void mac802154_beacon_hash_add(struct ieee802154_addr *coord_addr)
6750+{
6751+ if (!mac802154_beacon_find_pan(coord_addr, coord_addr->pan_id)) {
6752+ spin_lock(&beacon_hash_lock);
6753+ __beacon_add_node(coord_addr, coord_addr->pan_id);
6754+ spin_unlock(&beacon_hash_lock);
6755+ }
6756+}
6757+
6758+void mac802154_beacon_hash_del(struct ieee802154_addr *coord_addr)
6759+{
6760+ struct beacon_node *entry = mac802154_beacon_find_pan(coord_addr,
6761+ coord_addr->pan_id);
6762+ if (!entry)
6763+ return;
6764+ spin_lock(&beacon_hash_lock);
6765+ hlist_del(&entry->list);
6766+ spin_unlock(&beacon_hash_lock);
6767+ kfree(entry);
6768+}
6769+
6770+void mac802154_beacon_hash_dump(void)
6771+{
6772+ int i;
6773+ struct hlist_node *tmp;
6774+ pr_debug("beacon hash dump begin\n");
6775+ spin_lock(&beacon_hash_lock);
6776+ for (i = 0; i < IEEE802154_BEACON_HTABLE_SIZE; i++) {
6777+ struct beacon_node *entry;
6778+ hlist_for_each(tmp, &beacon_hash[i]) {
6779+ entry = hlist_entry(tmp, struct beacon_node, list);
6780+ pr_debug("PAN: %04x\n", entry->pan_addr);
6781+ }
6782+ }
6783+ spin_unlock(&beacon_hash_lock);
6784+ pr_debug("beacon hash dump end\n");
6785+}
6786+
6787diff --git a/net/mac802154/beacon_hash.h b/net/mac802154/beacon_hash.h
6788new file mode 100644
6789index 0000000..a732aa5
6790--- /dev/null
6791@@ -0,0 +1,41 @@
6792+/*
6793+ * MAC beacon hash storage
6794+ *
6795+ * Copyright 2007, 2008 Siemens AG
6796+ *
6797+ * This program is free software; you can redistribute it and/or modify
6798+ * it under the terms of the GNU General Public License version 2
6799+ * as published by the Free Software Foundation.
6800+ *
6801+ * This program is distributed in the hope that it will be useful,
6802+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6803+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6804+ * GNU General Public License for more details.
6805+ *
6806+ * You should have received a copy of the GNU General Public License along
6807+ * with this program; if not, write to the Free Software Foundation, Inc.,
6808+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
6809+ *
6810+ * Written by:
6811+ * Sergey Lapin <slapin@ossfans.org>
6812+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
6813+ */
6814+
6815+#ifndef IEEE802154_BEACON_HASH_H
6816+#define IEEE802154_BEACON_HASH_H
6817+
6818+#define IEEE802154_BEACON_HTABLE_SIZE 256
6819+
6820+struct beacon_node {
6821+ struct hlist_node list;
6822+ struct ieee802154_addr coord_addr;
6823+ u16 pan_addr;
6824+};
6825+struct beacon_node *mac802154_beacon_find_pan(
6826+ struct ieee802154_addr *coord_addr,
6827+ u16 pan_addr);
6828+void mac802154_beacon_hash_add(struct ieee802154_addr *coord_addr);
6829+void mac802154_beacon_hash_del(struct ieee802154_addr *coord_addr);
6830+void mac802154_beacon_hash_dump(void);
6831+#endif
6832+
6833diff --git a/net/mac802154/mac802154.h b/net/mac802154/mac802154.h
6834new file mode 100644
6835index 0000000..f35245d
6836--- /dev/null
6837@@ -0,0 +1,126 @@
6838+/*
6839+ * Copyright (C) 2007, 2008, 2009 Siemens AG
6840+ *
6841+ * This program is free software; you can redistribute it and/or modify
6842+ * it under the terms of the GNU General Public License version 2
6843+ * as published by the Free Software Foundation.
6844+ *
6845+ * This program is distributed in the hope that it will be useful,
6846+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6847+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6848+ * GNU General Public License for more details.
6849+ *
6850+ * You should have received a copy of the GNU General Public License along
6851+ * with this program; if not, write to the Free Software Foundation, Inc.,
6852+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
6853+ *
6854+ * Written by:
6855+ * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
6856+ * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
6857+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
6858+ */
6859+#ifndef MAC802154_H
6860+#define MAC802154_H
6861+
6862+#include <linux/spinlock.h>
6863+
6864+struct mac802154_priv {
6865+ struct ieee802154_dev hw;
6866