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