Root/target/linux/xburst/patches-3.2/0025-first-patch-for-atBen.patch

Source at commit a4f94608b1c84c9faf85a3efc10d603e09947c52 created 8 years 4 months ago.
By Xiangfu, xburst: nanonote: fix atusb compile error
1From b4e4f47e778bba5c86a3725cd447e0bfda545ae0 Mon Sep 17 00:00:00 2001
2From: Xiangfu Liu <xiangfu@sharism.cc>
3Date: Tue, 6 Mar 2012 11:40:52 +0800
4Subject: [PATCH 25/28] first-patch-for-atBen
5
6---
7 drivers/ieee802154/Kconfig | 55 ++-
8 drivers/ieee802154/Makefile | 11 +
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 | 12 +-
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 | 8 +
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 | 20 +-
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 | 283 +++++++++++
44 net/mac802154/mib.c | 249 ++++++++++
45 net/mac802154/mib.h | 35 ++
46 net/mac802154/monitor.c | 117 +++++
47 net/mac802154/rx.c | 117 +++++
48 net/mac802154/scan.c | 203 ++++++++
49 net/mac802154/smac.c | 128 +++++
50 net/mac802154/tx.c | 106 ++++
51 net/mac802154/wpan.c | 631 +++++++++++++++++++++++
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, 9360 insertions(+), 18 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 800a389..6374677 100644
162--- a/drivers/ieee802154/Makefile
163+++ b/drivers/ieee802154/Makefile
164@@ -1 +1,12 @@
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 eb0e2cc..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@@ -391,6 +391,16 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
3191     priv = netdev_priv(dev);
3192     priv->phy = phy;
3193 
3194+ /*
3195+ * If the name is a format string the caller wants us to do a
3196+ * name allocation.
3197+ */
3198+ if (strchr(dev->name, '%')) {
3199+ err = dev_alloc_name(dev, dev->name);
3200+ if (err < 0)
3201+ goto out;
3202+ }
3203+
3204     wpan_phy_set_dev(phy, &pdev->dev);
3205     SET_NETDEV_DEV(dev, &phy->dev);
3206 
3207diff --git a/drivers/ieee802154/fakelb.c b/drivers/ieee802154/fakelb.c
3208new file mode 100644
3209index 0000000..ae6e53f
3210--- /dev/null
3211+++ b/drivers/ieee802154/fakelb.c
3212@@ -0,0 +1,311 @@
3213+/*
3214+ * Loopback IEEE 802.15.4 interface
3215+ *
3216+ * Copyright 2007, 2008 Siemens AG
3217+ *
3218+ * This program is free software; you can redistribute it and/or modify
3219+ * it under the terms of the GNU General Public License version 2
3220+ * as published by the Free Software Foundation.
3221+ *
3222+ * This program is distributed in the hope that it will be useful,
3223+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3224+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3225+ * GNU General Public License for more details.
3226+ *
3227+ * You should have received a copy of the GNU General Public License along
3228+ * with this program; if not, write to the Free Software Foundation, Inc.,
3229+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3230+ *
3231+ * Written by:
3232+ * Sergey Lapin <slapin@ossfans.org>
3233+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
3234+ */
3235+
3236+#include <linux/module.h>
3237+#include <linux/timer.h>
3238+#include <linux/platform_device.h>
3239+#include <linux/netdevice.h>
3240+#include <linux/spinlock.h>
3241+#include <net/mac802154.h>
3242+#include <net/wpan-phy.h>
3243+
3244+struct fake_dev_priv {
3245+ struct ieee802154_dev *dev;
3246+
3247+ struct list_head list;
3248+ struct fake_priv *fake;
3249+
3250+ unsigned int working:1;
3251+};
3252+
3253+struct fake_priv {
3254+ struct list_head list;
3255+ rwlock_t lock;
3256+};
3257+
3258+static int
3259+hw_ed(struct ieee802154_dev *dev, u8 *level)
3260+{
3261+ pr_debug("%s\n", __func__);
3262+ might_sleep();
3263+ BUG_ON(!level);
3264+ *level = 0xbe;
3265+ return 0;
3266+}
3267+
3268+static int
3269+hw_channel(struct ieee802154_dev *dev, int page, int channel)
3270+{
3271+ pr_debug("%s %d\n", __func__, channel);
3272+ might_sleep();
3273+ dev->phy->current_page = page;
3274+ dev->phy->current_channel = channel;
3275+ return 0;
3276+}
3277+
3278+static void
3279+hw_deliver(struct fake_dev_priv *priv, struct sk_buff *skb)
3280+{
3281+ struct sk_buff *newskb;
3282+
3283+ if (!priv->working)
3284+ return;
3285+
3286+ newskb = pskb_copy(skb, GFP_ATOMIC);
3287+
3288+ ieee802154_rx_irqsafe(priv->dev, newskb, 0xcc);
3289+}
3290+
3291+static int
3292+hw_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
3293+{
3294+ struct fake_dev_priv *priv = dev->priv;
3295+ struct fake_priv *fake = priv->fake;
3296+
3297+ might_sleep();
3298+
3299+ read_lock_bh(&fake->lock);
3300+ if (priv->list.next == priv->list.prev) {
3301+ /* we are the only one device */
3302+ hw_deliver(priv, skb);
3303+ } else {
3304+ struct fake_dev_priv *dp;
3305+ list_for_each_entry(dp, &priv->fake->list, list)
3306+ if (dp != priv &&
3307+ dp->dev->phy->current_channel ==
3308+ priv->dev->phy->current_channel)
3309+ hw_deliver(dp, skb);
3310+ }
3311+ read_unlock_bh(&fake->lock);
3312+
3313+ return 0;
3314+}
3315+
3316+static int
3317+hw_start(struct ieee802154_dev *dev) {
3318+ struct fake_dev_priv *priv = dev->priv;
3319+
3320+ if (priv->working)
3321+ return -EBUSY;
3322+
3323+ priv->working = 1;
3324+
3325+ return 0;
3326+}
3327+
3328+static void
3329+hw_stop(struct ieee802154_dev *dev) {
3330+ struct fake_dev_priv *priv = dev->priv;
3331+
3332+ priv->working = 0;
3333+}
3334+
3335+static struct ieee802154_ops fake_ops = {
3336+ .owner = THIS_MODULE,
3337+ .xmit = hw_xmit,
3338+ .ed = hw_ed,
3339+ .set_channel = hw_channel,
3340+ .start = hw_start,
3341+ .stop = hw_stop,
3342+};
3343+
3344+static int ieee802154fake_add_priv(struct device *dev, struct fake_priv *fake)
3345+{
3346+ struct fake_dev_priv *priv;
3347+ int err = -ENOMEM;
3348+ struct ieee802154_dev *ieee;
3349+
3350+ ieee = ieee802154_alloc_device(sizeof(*priv), &fake_ops);
3351+ if (!dev)
3352+ goto err_alloc_dev;
3353+
3354+ priv = ieee->priv;
3355+ priv->dev = ieee;
3356+
3357+ /* 868 MHz BPSK 802.15.4-2003 */
3358+ ieee->phy->channels_supported[0] |= 1;
3359+ /* 915 MHz BPSK 802.15.4-2003 */
3360+ ieee->phy->channels_supported[0] |= 0x7fe;
3361+ /* 2.4 GHz O-QPSK 802.15.4-2003 */
3362+ ieee->phy->channels_supported[0] |= 0x7FFF800;
3363+ /* 868 MHz ASK 802.15.4-2006 */
3364+ ieee->phy->channels_supported[1] |= 1;
3365+ /* 915 MHz ASK 802.15.4-2006 */
3366+ ieee->phy->channels_supported[1] |= 0x7fe;
3367+ /* 868 MHz O-QPSK 802.15.4-2006 */
3368+ ieee->phy->channels_supported[2] |= 1;
3369+ /* 915 MHz O-QPSK 802.15.4-2006 */
3370+ ieee->phy->channels_supported[2] |= 0x7fe;
3371+ /* 2.4 GHz CSS 802.15.4a-2007 */
3372+ ieee->phy->channels_supported[3] |= 0x3fff;
3373+ /* UWB Sub-gigahertz 802.15.4a-2007 */
3374+ ieee->phy->channels_supported[4] |= 1;
3375+ /* UWB Low band 802.15.4a-2007 */
3376+ ieee->phy->channels_supported[4] |= 0x1e;
3377+ /* UWB High band 802.15.4a-2007 */
3378+ ieee->phy->channels_supported[4] |= 0xffe0;
3379+ /* 750 MHz O-QPSK 802.15.4c-2009 */
3380+ ieee->phy->channels_supported[5] |= 0xf;
3381+ /* 750 MHz MPSK 802.15.4c-2009 */
3382+ ieee->phy->channels_supported[5] |= 0xf0;
3383+ /* 950 MHz BPSK 802.15.4d-2009 */
3384+ ieee->phy->channels_supported[6] |= 0x3ff;
3385+ /* 950 MHz GFSK 802.15.4d-2009 */
3386+ ieee->phy->channels_supported[6] |= 0x3ffc00;
3387+
3388+
3389+ INIT_LIST_HEAD(&priv->list);
3390+ priv->fake = fake;
3391+
3392+ ieee->parent = dev;
3393+
3394+ err = ieee802154_register_device(ieee);
3395+ if (err)
3396+ goto err_reg;
3397+
3398+ write_lock_bh(&fake->lock);
3399+ list_add_tail(&priv->list, &fake->list);
3400+ write_unlock_bh(&fake->lock);
3401+
3402+ return 0;
3403+
3404+err_reg:
3405+ ieee802154_free_device(priv->dev);
3406+err_alloc_dev:
3407+ return err;
3408+}
3409+
3410+static void ieee802154fake_del_priv(struct fake_dev_priv *priv)
3411+{
3412+ write_lock_bh(&priv->fake->lock);
3413+ list_del(&priv->list);
3414+ write_unlock_bh(&priv->fake->lock);
3415+
3416+ ieee802154_unregister_device(priv->dev);
3417+ ieee802154_free_device(priv->dev);
3418+}
3419+
3420+static ssize_t
3421+adddev_store(struct device *dev, struct device_attribute *attr,
3422+ const char *buf, size_t n)
3423+{
3424+ struct platform_device *pdev = to_platform_device(dev);
3425+ struct fake_priv *priv = platform_get_drvdata(pdev);
3426+ int err;
3427+
3428+ err = ieee802154fake_add_priv(dev, priv);
3429+ if (err)
3430+ return err;
3431+ return n;
3432+}
3433+
3434+static DEVICE_ATTR(adddev, 0200, NULL, adddev_store);
3435+
3436+static struct attribute *fake_attrs[] = {
3437+ &dev_attr_adddev.attr,
3438+ NULL,
3439+};
3440+
3441+static struct attribute_group fake_group = {
3442+ .name = NULL /* fake */,
3443+ .attrs = fake_attrs,
3444+};
3445+
3446+
3447+static int __devinit ieee802154fake_probe(struct platform_device *pdev)
3448+{
3449+ struct fake_priv *priv;
3450+ struct fake_dev_priv *dp;
3451+
3452+ int err = -ENOMEM;
3453+ priv = kzalloc(sizeof(struct fake_priv), GFP_KERNEL);
3454+ if (!priv)
3455+ goto err_alloc;
3456+
3457+ INIT_LIST_HEAD(&priv->list);
3458+ rwlock_init(&priv->lock);
3459+
3460+ err = sysfs_create_group(&pdev->dev.kobj, &fake_group);
3461+ if (err)
3462+ goto err_grp;
3463+
3464+ err = ieee802154fake_add_priv(&pdev->dev, priv);
3465+ if (err < 0)
3466+ goto err_slave;
3467+
3468+ platform_set_drvdata(pdev, priv);
3469+ dev_info(&pdev->dev, "Added ieee802154 hardware\n");
3470+ return 0;
3471+
3472+err_slave:
3473+ list_for_each_entry(dp, &priv->list, list)
3474+ ieee802154fake_del_priv(dp);
3475+ sysfs_remove_group(&pdev->dev.kobj, &fake_group);
3476+err_grp:
3477+ kfree(priv);
3478+err_alloc:
3479+ return err;
3480+}
3481+
3482+static int __devexit ieee802154fake_remove(struct platform_device *pdev)
3483+{
3484+ struct fake_priv *priv = platform_get_drvdata(pdev);
3485+ struct fake_dev_priv *dp, *temp;
3486+
3487+ list_for_each_entry_safe(dp, temp, &priv->list, list)
3488+ ieee802154fake_del_priv(dp);
3489+ sysfs_remove_group(&pdev->dev.kobj, &fake_group);
3490+ kfree(priv);
3491+ return 0;
3492+}
3493+
3494+static struct platform_device *ieee802154fake_dev;
3495+
3496+static struct platform_driver ieee802154fake_driver = {
3497+ .probe = ieee802154fake_probe,
3498+ .remove = __devexit_p(ieee802154fake_remove),
3499+ .driver = {
3500+ .name = "ieee802154fakelb",
3501+ .owner = THIS_MODULE,
3502+ },
3503+};
3504+
3505+static __init int fake_init(void)
3506+{
3507+ ieee802154fake_dev = platform_device_register_simple(
3508+ "ieee802154fakelb", -1, NULL, 0);
3509+ return platform_driver_register(&ieee802154fake_driver);
3510+}
3511+
3512+static __exit void fake_exit(void)
3513+{
3514+ platform_driver_unregister(&ieee802154fake_driver);
3515+ platform_device_unregister(ieee802154fake_dev);
3516+}
3517+
3518+module_init(fake_init);
3519+module_exit(fake_exit);
3520+MODULE_LICENSE("GPL");
3521+MODULE_AUTHOR("Dmitry Eremin-Solenikov, Sergey Lapin");
3522+
3523+
3524diff --git a/drivers/ieee802154/serial.c b/drivers/ieee802154/serial.c
3525new file mode 100644
3526index 0000000..6981d0e
3527--- /dev/null
3528+++ b/drivers/ieee802154/serial.c
3529@@ -0,0 +1,1047 @@
3530+/*
3531+ * ZigBee TTY line discipline.
3532+ *
3533+ * Provides interface between ZigBee stack and IEEE 802.15.4 compatible
3534+ * firmware over serial line. Communication protocol is described below.
3535+ *
3536+ * Copyright (C) 2007, 2008, 2009 Siemens AG
3537+ *
3538+ * This program is free software; you can redistribute it and/or modify
3539+ * it under the terms of the GNU General Public License version 2
3540+ * as published by the Free Software Foundation.
3541+ *
3542+ * This program is distributed in the hope that it will be useful,
3543+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3544+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3545+ * GNU General Public License for more details.
3546+ *
3547+ * You should have received a copy of the GNU General Public License along
3548+ * with this program; if not, write to the Free Software Foundation, Inc.,
3549+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3550+ *
3551+ * Written by:
3552+ * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
3553+ * Maxim Osipov <maxim.osipov@siemens.com>
3554+ * Sergey Lapin <slapin@ossfans.org>
3555+ */
3556+
3557+#include <linux/module.h>
3558+#include <linux/kernel.h>
3559+#include <linux/completion.h>
3560+#include <linux/tty.h>
3561+#include <linux/skbuff.h>
3562+#include <linux/sched.h>
3563+#include <net/mac802154.h>
3564+#include <net/wpan-phy.h>
3565+
3566+
3567+/* NOTE: be sure to use here the same values as in the firmware */
3568+#define START_BYTE1 'z'
3569+#define START_BYTE2 'b'
3570+#define MAX_DATA_SIZE 127
3571+
3572+#define IDLE_MODE 0x00
3573+#define RX_MODE 0x02
3574+#define TX_MODE 0x03
3575+#define FORCE_TRX_OFF 0xF0
3576+
3577+#define STATUS_SUCCESS 0
3578+#define STATUS_RX_ON 1
3579+#define STATUS_TX_ON 2
3580+#define STATUS_TRX_OFF 3
3581+#define STATUS_IDLE 4
3582+#define STATUS_BUSY 5
3583+#define STATUS_BUSY_RX 6
3584+#define STATUS_BUSY_TX 7
3585+#define STATUS_ERR 8
3586+
3587+#define STATUS_WAIT ((u8) -1) /* waiting for the answer */
3588+
3589+/* We re-use PPP ioctl for our purposes */
3590+#define PPPIOCGUNIT _IOR('t', 86, int) /* get ppp unit number */
3591+
3592+/*
3593+ * The following messages are used to control ZigBee firmware.
3594+ * All communication has request/response format,
3595+ * except of asynchronous incoming data stream (DATA_RECV_* messages).
3596+ */
3597+enum {
3598+ NO_ID = 0, /* means no pending id */
3599+
3600+ /* Driver to Firmware */
3601+ CMD_OPEN = 0x01, /* u8 id */
3602+ CMD_CLOSE = 0x02, /* u8 id */
3603+ CMD_SET_CHANNEL = 0x04, /* u8 id, u8 channel */
3604+ CMD_ED = 0x05, /* u8 id */
3605+ CMD_CCA = 0x06, /* u8 id */
3606+ CMD_SET_STATE = 0x07, /* u8 id, u8 flag */
3607+ DATA_XMIT_BLOCK = 0x09, /* u8 id, u8 len, u8 data[len] */
3608+ RESP_RECV_BLOCK = 0x0b, /* u8 id, u8 status */
3609+ CMD_ADDRESS = 0x0d, /* u8 id */
3610+
3611+ /* Firmware to Driver */
3612+ RESP_OPEN = 0x81, /* u8 id, u8 status */
3613+ RESP_CLOSE = 0x82, /* u8 id, u8 status */
3614+ RESP_SET_CHANNEL = 0x84, /* u8 id, u8 status */
3615+ RESP_ED = 0x85, /* u8 id, u8 status, u8 level */
3616+ RESP_CCA = 0x86, /* u8 id, u8 status */
3617+ RESP_SET_STATE = 0x87, /* u8 id, u8 status */
3618+ RESP_XMIT_BLOCK = 0x89, /* u8 id, u8 status */
3619+ DATA_RECV_BLOCK = 0x8b, /* u8 id, u8 lq, u8 len, u8 data[len] */
3620+ RESP_ADDRESS = 0x8d, /* u8 id, u8 status, u8 u8 u8 u8 u8 u8 u8 u8 address */
3621+};
3622+
3623+enum {
3624+ STATE_WAIT_START1,
3625+ STATE_WAIT_START2,
3626+ STATE_WAIT_COMMAND,
3627+ STATE_WAIT_PARAM1,
3628+ STATE_WAIT_PARAM2,
3629+ STATE_WAIT_DATA
3630+};
3631+
3632+struct zb_device {
3633+ /* Relative devices */
3634+ struct tty_struct *tty;
3635+ struct ieee802154_dev *dev;
3636+
3637+ /* locks the ldisc for the command */
3638+ struct mutex mutex;
3639+
3640+ /* command completition */
3641+ wait_queue_head_t wq;
3642+ u8 status;
3643+ u8 ed;
3644+
3645+ /* Internal state */
3646+ struct completion open_done;
3647+ unsigned char opened;
3648+ u8 pending_id;
3649+ unsigned int pending_size;
3650+ u8 *pending_data;
3651+ /* FIXME: WE NEED LOCKING!!! */
3652+
3653+ /* Command (rx) processing */
3654+ int state;
3655+ unsigned char id;
3656+ unsigned char param1;
3657+ unsigned char param2;
3658+ unsigned char index;
3659+ unsigned char data[MAX_DATA_SIZE];
3660+};
3661+
3662+/*****************************************************************************
3663+ * ZigBee serial device protocol handling
3664+ *****************************************************************************/
3665+static int _open_dev(struct zb_device *zbdev);
3666+
3667+static int
3668+_send_pending_data(struct zb_device *zbdev)
3669+{
3670+ struct tty_struct *tty;
3671+
3672+ BUG_ON(!zbdev);
3673+ tty = zbdev->tty;
3674+ if (!tty)
3675+ return -ENODEV;
3676+
3677+ zbdev->status = STATUS_WAIT;
3678+
3679+ /* Debug info */
3680+ printk(KERN_INFO "%s, %d bytes\n", __func__,
3681+ zbdev->pending_size);
3682+#ifdef DEBUG
3683+ print_hex_dump_bytes("send_pending_data ", DUMP_PREFIX_NONE,
3684+ zbdev->pending_data, zbdev->pending_size);
3685+#endif
3686+
3687+ if (tty->driver->ops->write(tty, zbdev->pending_data,
3688+ zbdev->pending_size) != zbdev->pending_size) {
3689+ printk(KERN_ERR "%s: device write failed\n", __func__);
3690+ return -1;
3691+ }
3692+
3693+ return 0;
3694+}
3695+
3696+static int
3697+send_cmd(struct zb_device *zbdev, u8 id)
3698+{
3699+ u8 len = 0;
3700+ /* 4 because of 2 start bytes, id and optional extra */
3701+ u8 buf[4];
3702+
3703+ /* Check arguments */
3704+ BUG_ON(!zbdev);
3705+
3706+ if (!zbdev->opened) {
3707+ if (!_open_dev(zbdev))
3708+ return -EAGAIN;
3709+ }
3710+
3711+ pr_debug("%s(): id = %u\n", __func__, id);
3712+ if (zbdev->pending_size) {
3713+ printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
3714+ __func__, zbdev->pending_id);
3715+ BUG();
3716+ }
3717+
3718+ /* Prepare a message */
3719+ buf[len++] = START_BYTE1;
3720+ buf[len++] = START_BYTE2;
3721+ buf[len++] = id;
3722+
3723+ zbdev->pending_id = id;
3724+ zbdev->pending_size = len;
3725+ zbdev->pending_data = kzalloc(zbdev->pending_size, GFP_KERNEL);
3726+ if (!zbdev->pending_data) {
3727+ printk(KERN_ERR "%s(): unable to allocate memory\n", __func__);
3728+ zbdev->pending_id = 0;
3729+ zbdev->pending_size = 0;
3730+ return -ENOMEM;
3731+ }
3732+ memcpy(zbdev->pending_data, buf, len);
3733+
3734+ return _send_pending_data(zbdev);
3735+}
3736+
3737+static int
3738+send_cmd2(struct zb_device *zbdev, u8 id, u8 extra)
3739+{
3740+ u8 len = 0;
3741+ /* 4 because of 2 start bytes, id and optional extra */
3742+ u8 buf[4];
3743+
3744+ /* Check arguments */
3745+ BUG_ON(!zbdev);
3746+
3747+ if (!zbdev->opened) {
3748+ if (!_open_dev(zbdev))
3749+ return -EAGAIN;
3750+ }
3751+
3752+ pr_debug("%s(): id = %u\n", __func__, id);
3753+ if (zbdev->pending_size) {
3754+ printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
3755+ __func__, zbdev->pending_id);
3756+ BUG();
3757+ }
3758+
3759+ /* Prepare a message */
3760+ buf[len++] = START_BYTE1;
3761+ buf[len++] = START_BYTE2;
3762+ buf[len++] = id;
3763+ buf[len++] = extra;
3764+
3765+ zbdev->pending_id = id;
3766+ zbdev->pending_size = len;
3767+ zbdev->pending_data = kzalloc(zbdev->pending_size, GFP_KERNEL);
3768+ if (!zbdev->pending_data) {
3769+ printk(KERN_ERR "%s(): unable to allocate memory\n", __func__);
3770+ zbdev->pending_id = 0;
3771+ zbdev->pending_size = 0;
3772+ return -ENOMEM;
3773+ }
3774+ memcpy(zbdev->pending_data, buf, len);
3775+
3776+ return _send_pending_data(zbdev);
3777+}
3778+
3779+static int
3780+send_block(struct zb_device *zbdev, u8 len, u8 *data)
3781+{
3782+ u8 i = 0, buf[4]; /* 4 because of 2 start bytes, id and len */
3783+
3784+ /* Check arguments */
3785+ BUG_ON(!zbdev);
3786+
3787+ if (!zbdev->opened) {
3788+ if (!_open_dev(zbdev))
3789+ return -EAGAIN;
3790+ }
3791+
3792+ pr_debug("%s(): id = %u\n", __func__, DATA_XMIT_BLOCK);
3793+ if (zbdev->pending_size) {
3794+ printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
3795+ __func__, zbdev->pending_id);
3796+ BUG();
3797+ }
3798+
3799+ /* Prepare a message */
3800+ buf[i++] = START_BYTE1;
3801+ buf[i++] = START_BYTE2;
3802+ buf[i++] = DATA_XMIT_BLOCK;
3803+ buf[i++] = len;
3804+
3805+ zbdev->pending_id = DATA_XMIT_BLOCK;
3806+ zbdev->pending_size = i + len;
3807+ zbdev->pending_data = kzalloc(zbdev->pending_size, GFP_KERNEL);
3808+ if (!zbdev->pending_data) {
3809+ printk(KERN_ERR "%s(): unable to allocate memory\n", __func__);
3810+ zbdev->pending_id = 0;
3811+ zbdev->pending_size = 0;
3812+ return -ENOMEM;
3813+ }
3814+ memcpy(zbdev->pending_data, buf, i);
3815+ memcpy(zbdev->pending_data + i, data, len);
3816+
3817+ return _send_pending_data(zbdev);
3818+}
3819+
3820+static void
3821+cleanup(struct zb_device *zbdev)
3822+{
3823+ zbdev->state = STATE_WAIT_START1;
3824+ zbdev->id = 0;
3825+ zbdev->param1 = 0;
3826+ zbdev->param2 = 0;
3827+ zbdev->index = 0;
3828+}
3829+
3830+static int
3831+is_command(unsigned char c)
3832+{
3833+ switch (c) {
3834+ /* ids we can get here: */
3835+ case RESP_OPEN:
3836+ case RESP_CLOSE:
3837+ case RESP_SET_CHANNEL:
3838+ case RESP_ED:
3839+ case RESP_CCA:
3840+ case RESP_SET_STATE:
3841+ case RESP_XMIT_BLOCK:
3842+ case DATA_RECV_BLOCK:
3843+ case RESP_ADDRESS:
3844+ return 1;
3845+ }
3846+ return 0;
3847+}
3848+
3849+static int
3850+_match_pending_id(struct zb_device *zbdev)
3851+{
3852+ return ((CMD_OPEN == zbdev->pending_id &&
3853+ RESP_OPEN == zbdev->id) ||
3854+ (CMD_CLOSE == zbdev->pending_id &&
3855+ RESP_CLOSE == zbdev->id) ||
3856+ (CMD_SET_CHANNEL == zbdev->pending_id &&
3857+ RESP_SET_CHANNEL == zbdev->id) ||
3858+ (CMD_ED == zbdev->pending_id &&
3859+ RESP_ED == zbdev->id) ||
3860+ (CMD_CCA == zbdev->pending_id &&
3861+ RESP_CCA == zbdev->id) ||
3862+ (CMD_SET_STATE == zbdev->pending_id &&
3863+ RESP_SET_STATE == zbdev->id) ||
3864+ (DATA_XMIT_BLOCK == zbdev->pending_id &&
3865+ RESP_XMIT_BLOCK == zbdev->id) ||
3866+ (DATA_RECV_BLOCK == zbdev->id) ||
3867+ (CMD_ADDRESS == zbdev->pending_id &&
3868+ RESP_ADDRESS == zbdev->id));
3869+}
3870+
3871+static void serial_net_rx(struct zb_device *zbdev)
3872+{
3873+ /* zbdev->param1 is LQI
3874+ * zbdev->param2 is length of data
3875+ * zbdev->data is data itself
3876+ */
3877+ struct sk_buff *skb;
3878+ skb = alloc_skb(zbdev->param2, GFP_ATOMIC);
3879+ skb_put(skb, zbdev->param2);
3880+ skb_copy_to_linear_data(skb, zbdev->data, zbdev->param2);
3881+ ieee802154_rx_irqsafe(zbdev->dev, skb, zbdev->param1);
3882+}
3883+
3884+static void
3885+process_command(struct zb_device *zbdev)
3886+{
3887+ /* Command processing */
3888+ if (!_match_pending_id(zbdev))
3889+ return;
3890+
3891+ if (RESP_OPEN == zbdev->id && STATUS_SUCCESS == zbdev->param1) {
3892+ zbdev->opened = 1;
3893+ pr_debug("Opened device\n");
3894+ complete(&zbdev->open_done);
3895+ /* Input is not processed during output, so
3896+ * using completion is not possible during output.
3897+ * so we need to handle open as any other command
3898+ * and hope for best
3899+ */
3900+ return;
3901+ }
3902+
3903+ if (!zbdev->opened)
3904+ return;
3905+
3906+ zbdev->pending_id = 0;
3907+ kfree(zbdev->pending_data);
3908+ zbdev->pending_data = NULL;
3909+ zbdev->pending_size = 0;
3910+ if (zbdev->id != DATA_RECV_BLOCK) {
3911+ /* XXX: w/around for old FW, REMOVE */
3912+ if (zbdev->param1 == STATUS_IDLE)
3913+ zbdev->status = STATUS_SUCCESS;
3914+ else
3915+ zbdev->status = zbdev->param1;
3916+ }
3917+
3918+ switch (zbdev->id) {
3919+ case RESP_ED:
3920+ zbdev->ed = zbdev->param2;
3921+ break;
3922+ case DATA_RECV_BLOCK:
3923+ pr_debug("Received block, lqi %02x, len %02x\n",
3924+ zbdev->param1, zbdev->param2);
3925+ /* zbdev->param1 is LQ, zbdev->param2 is length */
3926+ serial_net_rx(zbdev);
3927+ break;
3928+ case RESP_ADDRESS:
3929+ pr_debug("Received address, %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
3930+ zbdev->data[0], zbdev->data[1], zbdev->data[2], zbdev->data[3],
3931+ zbdev->data[4], zbdev->data[5], zbdev->data[6], zbdev->data[7]);
3932+ break;
3933+ }
3934+
3935+ wake_up(&zbdev->wq);
3936+}
3937+
3938+static void
3939+process_char(struct zb_device *zbdev, unsigned char c)
3940+{
3941+ /* Data processing */
3942+ switch (zbdev->state) {
3943+ case STATE_WAIT_START1:
3944+ if (START_BYTE1 == c)
3945+ zbdev->state = STATE_WAIT_START2;
3946+ break;
3947+
3948+ case STATE_WAIT_START2:
3949+ if (START_BYTE2 == c)
3950+ zbdev->state = STATE_WAIT_COMMAND;
3951+ else
3952+ cleanup(zbdev);
3953+ break;
3954+
3955+ case STATE_WAIT_COMMAND:
3956+ if (is_command(c)) {
3957+ zbdev->id = c;
3958+ zbdev->state = STATE_WAIT_PARAM1;
3959+ } else {
3960+ cleanup(zbdev);
3961+ printk(KERN_ERR "%s, unexpected command id: %x\n",
3962+ __func__, c);
3963+ }
3964+ break;
3965+
3966+ case STATE_WAIT_PARAM1:
3967+ zbdev->param1 = c;
3968+ if ((RESP_ED == zbdev->id) || (DATA_RECV_BLOCK == zbdev->id))
3969+ zbdev->state = STATE_WAIT_PARAM2;
3970+ else if (RESP_ADDRESS == zbdev->id) {
3971+ zbdev->param2 = 8;
3972+ zbdev->state = STATE_WAIT_DATA;
3973+ } else {
3974+ process_command(zbdev);
3975+ cleanup(zbdev);
3976+ }
3977+ break;
3978+
3979+ case STATE_WAIT_PARAM2:
3980+ zbdev->param2 = c;
3981+ if (RESP_ED == zbdev->id) {
3982+ process_command(zbdev);
3983+ cleanup(zbdev);
3984+ } else if (DATA_RECV_BLOCK == zbdev->id)
3985+ zbdev->state = STATE_WAIT_DATA;
3986+ else
3987+ cleanup(zbdev);
3988+ break;
3989+
3990+ case STATE_WAIT_DATA:
3991+ if (zbdev->index < sizeof(zbdev->data)) {
3992+ zbdev->data[zbdev->index] = c;
3993+ zbdev->index++;
3994+ /*
3995+ * Pending data is received,
3996+ * param2 is length for DATA_RECV_BLOCK
3997+ */
3998+ if (zbdev->index == zbdev->param2) {
3999+ process_command(zbdev);
4000+ cleanup(zbdev);
4001+ }
4002+ } else {
4003+ printk(KERN_ERR "%s(): data size is greater "
4004+ "than buffer available\n", __func__);
4005+ cleanup(zbdev);
4006+ }
4007+ break;
4008+
4009+ default:
4010+ cleanup(zbdev);
4011+ }
4012+}
4013+
4014+/*****************************************************************************
4015+ * Device operations for IEEE 802.15.4 PHY side interface ZigBee stack
4016+ *****************************************************************************/
4017+
4018+static int _open_dev(struct zb_device *zbdev)
4019+{
4020+ int retries;
4021+ u8 len = 0;
4022+ /* 4 because of 2 start bytes, id and optional extra */
4023+ u8 buf[4];
4024+
4025+ /* Check arguments */
4026+ BUG_ON(!zbdev);
4027+ if (zbdev->opened)
4028+ return 1;
4029+
4030+ pr_debug("%s()\n", __func__);
4031+ if (zbdev->pending_size) {
4032+ printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
4033+ __func__, zbdev->pending_id);
4034+ BUG();
4035+ }
4036+
4037+ /* Prepare a message */
4038+ buf[len++] = START_BYTE1;
4039+ buf[len++] = START_BYTE2;
4040+ buf[len++] = CMD_OPEN;
4041+
4042+ zbdev->pending_id = CMD_OPEN;
4043+ zbdev->pending_size = len;
4044+ zbdev->pending_data = kzalloc(zbdev->pending_size, GFP_KERNEL);
4045+ if (!zbdev->pending_data) {
4046+ printk(KERN_ERR "%s(): unable to allocate memory\n", __func__);
4047+ zbdev->pending_id = 0;
4048+ zbdev->pending_size = 0;
4049+ return -ENOMEM;
4050+ }
4051+ memcpy(zbdev->pending_data, buf, len);
4052+
4053+ retries = 5;
4054+ while (!zbdev->opened && retries) {
4055+ if (_send_pending_data(zbdev) != 0)
4056+ return 0;
4057+
4058+ /* 3 second before retransmission */
4059+ wait_for_completion_interruptible_timeout(
4060+ &zbdev->open_done, msecs_to_jiffies(1000));
4061+ --retries;
4062+ }
4063+
4064+ zbdev->pending_id = 0;
4065+ kfree(zbdev->pending_data);
4066+ zbdev->pending_data = NULL;
4067+ zbdev->pending_size = 0;
4068+
4069+ if (zbdev->opened) {
4070+ printk(KERN_INFO "Opened connection to device\n");
4071+ return 1;
4072+ }
4073+
4074+ return 0;
4075+}
4076+
4077+/* Valid channels: 1-16 */
4078+static int
4079+ieee802154_serial_set_channel(struct ieee802154_dev *dev, int page, int channel)
4080+{
4081+ struct zb_device *zbdev;
4082+ int ret = 0;
4083+
4084+ pr_debug("%s %d\n", __func__, channel);
4085+
4086+ zbdev = dev->priv;
4087+ if (NULL == zbdev) {
4088+ printk(KERN_ERR "%s: wrong phy\n", __func__);
4089+ return -EINVAL;
4090+ }
4091+
4092+ BUG_ON(page != 0);
4093+ /* Our channels are actually from 11 to 26
4094+ * We have IEEE802.15.4 channel no from 0 to 26.
4095+ * channels 0-10 are not valid for us */
4096+ BUG_ON(channel < 11 || channel > 26);
4097+ /* ... but our crappy firmware numbers channels from 1 to 16
4098+ * which is a mystery. We suould enforce that using PIB API
4099+ * but additional checking here won't kill, and gcc will
4100+ * optimize this stuff anyway. */
4101+ BUG_ON((channel - 10) < 1 && (channel - 10) > 16);
4102+ if (mutex_lock_interruptible(&zbdev->mutex))
4103+ return -EINTR;
4104+ ret = send_cmd2(zbdev, CMD_SET_CHANNEL, channel - 10);
4105+ if (ret)
4106+ goto out;
4107+
4108+ if (wait_event_interruptible_timeout(zbdev->wq,
4109+ zbdev->status != STATUS_WAIT,
4110+ msecs_to_jiffies(1000)) > 0) {
4111+ if (zbdev->status != STATUS_SUCCESS)
4112+ ret = -EBUSY;
4113+ } else
4114+ ret = -EINTR;
4115+
4116+ if (!ret)
4117+ zbdev->dev->phy->current_channel = channel;
4118+out:
4119+ mutex_unlock(&zbdev->mutex);
4120+ pr_debug("%s end\n", __func__);
4121+ return ret;
4122+}
4123+
4124+static int
4125+ieee802154_serial_ed(struct ieee802154_dev *dev, u8 *level)
4126+{
4127+ struct zb_device *zbdev;
4128+ int ret = 0;
4129+
4130+ pr_debug("%s\n", __func__);
4131+
4132+ zbdev = dev->priv;
4133+ if (NULL == zbdev) {
4134+ printk(KERN_ERR "%s: wrong phy\n", __func__);
4135+ return -EINVAL;
4136+ }
4137+
4138+ if (mutex_lock_interruptible(&zbdev->mutex))
4139+ return -EINTR;
4140+
4141+ ret = send_cmd(zbdev, CMD_ED);
4142+ if (ret)
4143+ goto out;
4144+
4145+ if (wait_event_interruptible_timeout(zbdev->wq,
4146+ zbdev->status != STATUS_WAIT,
4147+ msecs_to_jiffies(1000)) > 0) {
4148+ *level = zbdev->ed;
4149+ if (zbdev->status != STATUS_SUCCESS)
4150+ ret = -EBUSY;
4151+ } else
4152+ ret = -ETIMEDOUT;
4153+out:
4154+
4155+ mutex_unlock(&zbdev->mutex);
4156+ pr_debug("%s end\n", __func__);
4157+ return ret;
4158+}
4159+
4160+static int
4161+ieee802154_serial_address(struct ieee802154_dev *dev, u8 addr[IEEE802154_ALEN])
4162+{
4163+ struct zb_device *zbdev;
4164+ int ret = 0;
4165+
4166+ pr_debug("%s\n", __func__);
4167+
4168+ zbdev = dev->priv;
4169+ if (NULL == zbdev) {
4170+ printk(KERN_ERR "%s: wrong phy\n", __func__);
4171+ return -EINVAL;
4172+ }
4173+
4174+ if (mutex_lock_interruptible(&zbdev->mutex))
4175+ return -EINTR;
4176+
4177+ ret = send_cmd(zbdev, CMD_ADDRESS);
4178+ if (ret)
4179+ goto out;
4180+
4181+ if (wait_event_interruptible_timeout(zbdev->wq,
4182+ zbdev->status != STATUS_WAIT,
4183+ msecs_to_jiffies(1000)) > 0) {
4184+ memcpy(addr, zbdev->data, sizeof addr);
4185+ if (zbdev->status != STATUS_SUCCESS)
4186+ ret = -EBUSY;
4187+ } else
4188+ ret = -ETIMEDOUT;
4189+out:
4190+
4191+ mutex_unlock(&zbdev->mutex);
4192+ pr_debug("%s end\n", __func__);
4193+ return ret;
4194+}
4195+
4196+static int
4197+ieee802154_serial_start(struct ieee802154_dev *dev)
4198+{
4199+ struct zb_device *zbdev;
4200+ int ret = 0;
4201+
4202+ pr_debug("%s\n", __func__);
4203+
4204+ zbdev = dev->priv;
4205+ if (NULL == zbdev) {
4206+ printk(KERN_ERR "%s: wrong phy\n", __func__);
4207+ return -EINVAL;
4208+ }
4209+
4210+ if (mutex_lock_interruptible(&zbdev->mutex))
4211+ return -EINTR;
4212+
4213+ ret = send_cmd2(zbdev, CMD_SET_STATE, RX_MODE);
4214+ if (ret)
4215+ goto out;
4216+
4217+ if (wait_event_interruptible_timeout(zbdev->wq,
4218+ zbdev->status != STATUS_WAIT,
4219+ msecs_to_jiffies(1000)) > 0) {
4220+ if (zbdev->status != STATUS_SUCCESS)
4221+ ret = -EBUSY;
4222+ } else
4223+ ret = -ETIMEDOUT;
4224+out:
4225+ mutex_unlock(&zbdev->mutex);
4226+ pr_debug("%s end\n", __func__);
4227+ return ret;
4228+}
4229+
4230+static void
4231+ieee802154_serial_stop(struct ieee802154_dev *dev)
4232+{
4233+ struct zb_device *zbdev;
4234+ pr_debug("%s\n", __func__);
4235+
4236+ zbdev = dev->priv;
4237+ if (NULL == zbdev) {
4238+ printk(KERN_ERR "%s: wrong phy\n", __func__);
4239+ return;
4240+ }
4241+
4242+ if (mutex_lock_interruptible(&zbdev->mutex))
4243+ return;
4244+
4245+
4246+ if (send_cmd2(zbdev, CMD_SET_STATE, FORCE_TRX_OFF) != 0)
4247+ goto out;
4248+
4249+ wait_event_interruptible_timeout(zbdev->wq,
4250+ zbdev->status != STATUS_WAIT,
4251+ msecs_to_jiffies(1000));
4252+out:
4253+ mutex_unlock(&zbdev->mutex);
4254+ pr_debug("%s end\n", __func__);
4255+}
4256+
4257+static int
4258+ieee802154_serial_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
4259+{
4260+ struct zb_device *zbdev;
4261+ int ret;
4262+
4263+ pr_debug("%s\n", __func__);
4264+
4265+ zbdev = dev->priv;
4266+ if (NULL == zbdev) {
4267+ printk(KERN_ERR "%s: wrong phy\n", __func__);
4268+ return -EINVAL;
4269+ }
4270+
4271+ if (mutex_lock_interruptible(&zbdev->mutex))
4272+ return -EINTR;
4273+
4274+ ret = send_cmd(zbdev, CMD_CCA);
4275+ if (ret)
4276+ goto out;
4277+
4278+ if (wait_event_interruptible_timeout(zbdev->wq,
4279+ zbdev->status != STATUS_WAIT,
4280+ msecs_to_jiffies(1000)) > 0) {
4281+ if (zbdev->status != STATUS_SUCCESS) {
4282+ ret = -EBUSY;
4283+ goto out;
4284+ }
4285+ } else {
4286+ ret = -ETIMEDOUT;
4287+ goto out;
4288+ }
4289+
4290+ ret = send_cmd2(zbdev, CMD_SET_STATE, TX_MODE);
4291+ if (ret)
4292+ goto out;
4293+
4294+ if (wait_event_interruptible_timeout(zbdev->wq,
4295+ zbdev->status != STATUS_WAIT,
4296+ msecs_to_jiffies(1000)) > 0) {
4297+ if (zbdev->status != STATUS_SUCCESS) {
4298+ ret = -EBUSY;
4299+ goto out;
4300+ }
4301+ } else {
4302+ ret = -ETIMEDOUT;
4303+ goto out;
4304+ }
4305+
4306+ ret = send_block(zbdev, skb->len, skb->data);
4307+ if (ret)
4308+ goto out;
4309+
4310+ if (wait_event_interruptible_timeout(zbdev->wq,
4311+ zbdev->status != STATUS_WAIT,
4312+ msecs_to_jiffies(1000)) > 0) {
4313+ if (zbdev->status != STATUS_SUCCESS) {
4314+ ret = -EBUSY;
4315+ goto out;
4316+ }
4317+ } else {
4318+ ret = -ETIMEDOUT;
4319+ goto out;
4320+ }
4321+
4322+ ret = send_cmd2(zbdev, CMD_SET_STATE, RX_MODE);
4323+ if (ret)
4324+ goto out;
4325+
4326+ if (wait_event_interruptible_timeout(zbdev->wq,
4327+ zbdev->status != STATUS_WAIT,
4328+ msecs_to_jiffies(1000)) > 0) {
4329+ if (zbdev->status != STATUS_SUCCESS) {
4330+ ret = -EBUSY;
4331+ goto out;
4332+ }
4333+ } else {
4334+ ret = -ETIMEDOUT;
4335+ goto out;
4336+ }
4337+
4338+out:
4339+
4340+ mutex_unlock(&zbdev->mutex);
4341+ pr_debug("%s end\n", __func__);
4342+ return ret;
4343+}
4344+
4345+/*****************************************************************************
4346+ * Line discipline interface for IEEE 802.15.4 serial device
4347+ *****************************************************************************/
4348+
4349+static struct ieee802154_ops serial_ops = {
4350+ .owner = THIS_MODULE,
4351+ .xmit = ieee802154_serial_xmit,
4352+ .ed = ieee802154_serial_ed,
4353+ .set_channel = ieee802154_serial_set_channel,
4354+ .start = ieee802154_serial_start,
4355+ .stop = ieee802154_serial_stop,
4356+ .ieee_addr = ieee802154_serial_address,
4357+};
4358+
4359+/*
4360+ * Called when a tty is put into ZB line discipline. Called in process context.
4361+ * Returns 0 on success.
4362+ */
4363+static int
4364+ieee802154_tty_open(struct tty_struct *tty)
4365+{
4366+ struct zb_device *zbdev = tty->disc_data;
4367+ struct ieee802154_dev *dev;
4368+ int err;
4369+
4370+ pr_debug("Openning ldisc\n");
4371+ if (!capable(CAP_NET_ADMIN))
4372+ return -EPERM;
4373+
4374+ if (tty->disc_data)
4375+ return -EBUSY;
4376+
4377+ dev = ieee802154_alloc_device(sizeof(*zbdev), &serial_ops);
4378+ if (!dev)
4379+ return -ENOMEM;
4380+
4381+ zbdev = dev->priv;
4382+ zbdev->dev = dev;
4383+
4384+ mutex_init(&zbdev->mutex);
4385+ init_completion(&zbdev->open_done);
4386+ init_waitqueue_head(&zbdev->wq);
4387+
4388+ dev->extra_tx_headroom = 0;
4389+ /* only 2.4 GHz band */
4390+ dev->phy->channels_supported[0] = 0x7fff800;
4391+
4392+ dev->flags = IEEE802154_HW_OMIT_CKSUM;
4393+
4394+ dev->parent = tty->dev;
4395+
4396+ zbdev->tty = tty_kref_get(tty);
4397+
4398+ cleanup(zbdev);
4399+
4400+ tty->disc_data = zbdev;
4401+ tty->receive_room = MAX_DATA_SIZE;
4402+
4403+ /* FIXME: why is this needed. Note don't use ldisc_ref here as the
4404+ open path is before the ldisc is referencable */
4405+
4406+ if (tty->ldisc->ops->flush_buffer)
4407+ tty->ldisc->ops->flush_buffer(tty);
4408+ tty_driver_flush_buffer(tty);
4409+
4410+ err = ieee802154_register_device(dev);
4411+ if (err) {
4412+ printk(KERN_ERR "%s: device register failed\n", __func__);
4413+ goto out_free;
4414+ }
4415+
4416+ return 0;
4417+
4418+ ieee802154_unregister_device(zbdev->dev);
4419+
4420+out_free:
4421+ tty->disc_data = NULL;
4422+ tty_kref_put(tty);
4423+ zbdev->tty = NULL;
4424+
4425+ ieee802154_free_device(zbdev->dev);
4426+
4427+ return err;
4428+}
4429+
4430+/*
4431+ * Called when the tty is put into another line discipline or it hangs up. We
4432+ * have to wait for any cpu currently executing in any of the other zb_tty_*
4433+ * routines to finish before we can call zb_tty_close and free the
4434+ * zb_serial_dev struct. This routine must be called from process context, not
4435+ * interrupt or softirq context.
4436+ */
4437+static void
4438+ieee802154_tty_close(struct tty_struct *tty)
4439+{
4440+ struct zb_device *zbdev;
4441+
4442+ zbdev = tty->disc_data;
4443+ if (NULL == zbdev) {
4444+ printk(KERN_WARNING "%s: match is not found\n", __func__);
4445+ return;
4446+ }
4447+
4448+ tty->disc_data = NULL;
4449+ tty_kref_put(tty);
4450+ zbdev->tty = NULL;
4451+
4452+ ieee802154_unregister_device(zbdev->dev);
4453+
4454+ tty_ldisc_flush(tty);
4455+ tty_driver_flush_buffer(tty);
4456+
4457+ ieee802154_free_device(zbdev->dev);
4458+}
4459+
4460+/*
4461+ * Called on tty hangup in process context.
4462+ */
4463+static int
4464+ieee802154_tty_hangup(struct tty_struct *tty)
4465+{
4466+ ieee802154_tty_close(tty);
4467+ return 0;
4468+}
4469+
4470+/*
4471+ * Called in process context only. May be re-entered
4472+ * by multiple ioctl calling threads.
4473+ */
4474+static int
4475+ieee802154_tty_ioctl(struct tty_struct *tty, struct file *file,
4476+ unsigned int cmd, unsigned long arg)
4477+{
4478+ struct zb_device *zbdev;
4479+
4480+ pr_debug("cmd = 0x%x\n", cmd);
4481+
4482+ zbdev = tty->disc_data;
4483+ if (NULL == zbdev) {
4484+ pr_debug("match is not found\n");
4485+ return -EINVAL;
4486+ }
4487+
4488+ switch (cmd) {
4489+ case TCFLSH:
4490+ return tty_perform_flush(tty, arg);
4491+ default:
4492+ /* Try the mode commands */
4493+ return tty_mode_ioctl(tty, file, cmd, arg);
4494+ }
4495+}
4496+
4497+
4498+/*
4499+ * This can now be called from hard interrupt level as well
4500+ * as soft interrupt level or mainline.
4501+ */
4502+static void
4503+ieee802154_tty_receive(struct tty_struct *tty, const unsigned char *buf,
4504+ char *cflags, int count)
4505+{
4506+ struct zb_device *zbdev;
4507+ int i;
4508+
4509+ /* Debug info */
4510+ printk(KERN_INFO "%s, received %d bytes\n", __func__,
4511+ count);
4512+#ifdef DEBUG
4513+ print_hex_dump_bytes("ieee802154_tty_receive ", DUMP_PREFIX_NONE,
4514+ buf, count);
4515+#endif
4516+
4517+ /* Actual processing */
4518+ zbdev = tty->disc_data;
4519+ if (NULL == zbdev) {
4520+ printk(KERN_ERR "%s(): record for tty is not found\n",
4521+ __func__);
4522+ return;
4523+ }
4524+ for (i = 0; i < count; ++i)
4525+ process_char(zbdev, buf[i]);
4526+#if 0
4527+ if (tty->driver->flush_chars)
4528+ tty->driver->flush_chars(tty);
4529+#endif
4530+ tty_unthrottle(tty);
4531+}
4532+
4533+/*
4534+ * Line discipline device structure
4535+ */
4536+static struct tty_ldisc_ops ieee802154_ldisc = {
4537+ .owner = THIS_MODULE,
4538+ .magic = TTY_LDISC_MAGIC,
4539+ .name = "ieee802154-ldisc",
4540+ .open = ieee802154_tty_open,
4541+ .close = ieee802154_tty_close,
4542+ .hangup = ieee802154_tty_hangup,
4543+ .receive_buf = ieee802154_tty_receive,
4544+ .ioctl = ieee802154_tty_ioctl,
4545+};
4546+
4547+/*****************************************************************************
4548+ * Module service routinues
4549+ *****************************************************************************/
4550+
4551+static int __init ieee802154_serial_init(void)
4552+{
4553+ printk(KERN_INFO "Initializing ZigBee TTY interface\n");
4554+
4555+ if (tty_register_ldisc(N_IEEE802154, &ieee802154_ldisc) != 0) {
4556+ printk(KERN_ERR "%s: line discipline register failed\n",
4557+ __func__);
4558+ return -EINVAL;
4559+ }
4560+
4561+ return 0;
4562+}
4563+
4564+static void __exit ieee802154_serial_cleanup(void)
4565+{
4566+ if (tty_unregister_ldisc(N_IEEE802154) != 0)
4567+ printk(KERN_CRIT
4568+ "failed to unregister ZigBee line discipline.\n");
4569+}
4570+
4571+module_init(ieee802154_serial_init);
4572+module_exit(ieee802154_serial_cleanup);
4573+
4574+MODULE_LICENSE("GPL");
4575+MODULE_ALIAS_LDISC(N_IEEE802154);
4576+
4577diff --git a/drivers/ieee802154/spi_atben.c b/drivers/ieee802154/spi_atben.c
4578new file mode 100644
4579index 0000000..431bfe0
4580--- /dev/null
4581+++ b/drivers/ieee802154/spi_atben.c
4582@@ -0,0 +1,421 @@
4583+/*
4584+ * spi_atben.c - SPI host look-alike for ATBEN
4585+ *
4586+ * Written 2011 by Werner Almesberger
4587+ *
4588+ * This program is free software; you can redistribute it and/or modify
4589+ * it under the terms of the GNU General Public License version 2
4590+ * as published by the Free Software Foundation.
4591+ */
4592+
4593+#include <linux/kernel.h>
4594+#include <linux/module.h>
4595+#include <linux/platform_device.h>
4596+#include <linux/gpio.h>
4597+#include <linux/delay.h>
4598+#include <linux/spi/spi.h>
4599+#include <linux/spi/at86rf230.h>
4600+#include <asm/mach-jz4740/base.h>
4601+
4602+#include "at86rf230.h"
4603+
4604+
4605+enum {
4606+ VDD_OFF = 1 << 2, /* VDD disable, PD02 */
4607+ MOSI = 1 << 8, /* CMD, PD08 */
4608+ SLP_TR = 1 << 9, /* CLK, PD09 */
4609+ MISO = 1 << 10, /* DAT0, PD10 */
4610+ SCLK = 1 << 11, /* DAT1, PD11 */
4611+ IRQ = 1 << 12, /* DAT2, PD12 */
4612+ nSEL = 1 << 13, /* DAT3/CD, PD13 */
4613+};
4614+
4615+#define PDPIN (prv->regs)
4616+#define PDDATS (prv->regs+0x14)
4617+#define PDDATC (prv->regs+0x18)
4618+
4619+
4620+struct atben_prv {
4621+ struct device *dev;
4622+ void __iomem *regs;
4623+ struct resource *ioarea;
4624+ struct at86rf230_platform_data
4625+ platform_data;
4626+ /* copy platform_data so that we can adapt .reset_data */
4627+};
4628+
4629+
4630+/* ----- ATBEN reset ------------------------------------------------------- */
4631+
4632+
4633+static void atben_reset(void *reset_data)
4634+{
4635+ struct atben_prv *prv = reset_data;
4636+ const int charge = nSEL | MOSI | SLP_TR | SCLK;
4637+ const int discharge = charge | IRQ | MISO;
4638+
4639+ dev_info(prv->dev, "atben_reset\n");
4640+ jz_gpio_port_set_value(JZ_GPIO_PORTD(0), 1 << 2, 1 << 2);
4641+ jz_gpio_port_direction_output(JZ_GPIO_PORTD(0), discharge);
4642+ jz_gpio_port_set_value(JZ_GPIO_PORTD(0), 0, discharge);
4643+ msleep(100); /* let power drop */
4644+
4645+ /*
4646+ * Hack: PD12/DAT2/IRQ is an active-high interrupt input, which is
4647+ * indicated by setting its direction bit to 1. We thus must not
4648+ * configure it as an "input".
4649+ */
4650+ jz_gpio_port_direction_input(JZ_GPIO_PORTD(0), MISO);
4651+ jz_gpio_port_set_value(JZ_GPIO_PORTD(0), charge, charge);
4652+ msleep(10); /* precharge caps */
4653+
4654+ jz_gpio_port_set_value(JZ_GPIO_PORTD(0), 0, VDD_OFF | SLP_TR | SCLK);
4655+ msleep(10);
4656+}
4657+
4658+
4659+/* ----- SPI transfers ----------------------------------------------------- */
4660+
4661+
4662+static void rx_only(const struct atben_prv *prv, uint8_t *buf, int len)
4663+{
4664+ uint8_t v;
4665+
4666+ while (len--) {
4667+ writel(SCLK, PDDATS);
4668+ v = readl(PDPIN) & MISO ? 0x80 : 0;
4669+ writel(SCLK, PDDATC);
4670+
4671+ #define DO_BIT(m) \
4672+ writel(SCLK, PDDATS); \
4673+ if (readl(PDPIN) & MISO) \
4674+ v |= (m); \
4675+ writel(SCLK, PDDATC)
4676+
4677+ DO_BIT(0x40);
4678+ DO_BIT(0x20);
4679+ DO_BIT(0x10);
4680+ DO_BIT(0x08);
4681+ DO_BIT(0x04);
4682+ DO_BIT(0x02);
4683+ DO_BIT(0x01);
4684+
4685+ #undef DO_BIT
4686+
4687+ *buf++ = v;
4688+ }
4689+}
4690+
4691+
4692+static void tx_only(const struct atben_prv *prv, const uint8_t *buf, int len)
4693+{
4694+ uint8_t tv;
4695+
4696+ while (len--) {
4697+ tv = *buf++;
4698+
4699+ if (tv & 0x80) {
4700+ writel(MOSI, PDDATS);
4701+ goto b6_1;
4702+ } else {
4703+ writel(MOSI, PDDATC);
4704+ goto b6_0;
4705+ }
4706+
4707+ #define DO_BIT(m, this, next) \
4708+ this##_1: \
4709+ writel(SCLK, PDDATS); \
4710+ if (tv & (m)) { \
4711+ writel(SCLK, PDDATC); \
4712+ goto next##_1; \
4713+ } else { \
4714+ writel(MOSI | SCLK, PDDATC); \
4715+ goto next##_0; \
4716+ } \
4717+ this##_0: \
4718+ writel(SCLK, PDDATS); \
4719+ writel(SCLK, PDDATC); \
4720+ if (tv & (m)) { \
4721+ writel(MOSI, PDDATS); \
4722+ goto next##_1; \
4723+ } else { \
4724+ goto next##_0; \
4725+ }
4726+
4727+ DO_BIT(0x40, b6, b5);
4728+ DO_BIT(0x20, b5, b4);
4729+ DO_BIT(0x10, b4, b3);
4730+ DO_BIT(0x08, b3, b2);
4731+ DO_BIT(0x04, b2, b1);
4732+ DO_BIT(0x02, b1, b0);
4733+ DO_BIT(0x01, b0, done);
4734+
4735+ #undef DO_BIT
4736+
4737+done_1:
4738+done_0:
4739+ writel(SCLK, PDDATS);
4740+ writel(SCLK, PDDATC);
4741+ writel(SCLK, PDDATC); /* delay to meet t5 timing */
4742+ }
4743+}
4744+
4745+
4746+static void bidir(const struct atben_prv *prv, const uint8_t *tx, uint8_t *rx,
4747+ int len)
4748+{
4749+ uint8_t mask, tv, rv;
4750+
4751+ while (len--) {
4752+ tv = *tx++;
4753+ for (mask = 0x80; mask; mask >>= 1) {
4754+ if (tv & mask)
4755+ writel(MOSI, PDDATS);
4756+ else
4757+ writel(MOSI, PDDATC);
4758+ writel(SCLK, PDDATS);
4759+ if (readl(PDPIN) & MISO)
4760+ rv |= mask;
4761+ writel(SCLK, PDDATC);
4762+ }
4763+ *rx++ = rv;
4764+ }
4765+}
4766+
4767+
4768+static int atben_transfer(struct spi_device *spi, struct spi_message *msg)
4769+{
4770+ struct atben_prv *prv = spi_master_get_devdata(spi->master);
4771+ struct spi_transfer *xfer;
4772+ const uint8_t *tx;
4773+ uint8_t *rx;
4774+
4775+ if (unlikely(list_empty(&msg->transfers))) {
4776+ dev_err(prv->dev, "transfer is empty\n");
4777+ return -EINVAL;
4778+ }
4779+
4780+ msg->actual_length = 0;
4781+
4782+ writel(nSEL, PDDATC);
4783+ list_for_each_entry(xfer, &msg->transfers, transfer_list) {
4784+ tx = xfer->tx_buf;
4785+ rx = xfer->rx_buf;
4786+ msg->actual_length += xfer->len;
4787+
4788+ if (!tx)
4789+ rx_only(prv, rx, xfer->len);
4790+ else if (!rx)
4791+ tx_only(prv, tx, xfer->len);
4792+ else
4793+ bidir(prv, tx, rx, xfer->len);
4794+ }
4795+ writel(nSEL, PDDATS);
4796+
4797+ msg->status = 0;
4798+ msg->complete(msg->context);
4799+
4800+ return 0;
4801+}
4802+
4803+static int atben_setup(struct spi_device *spi)
4804+{
4805+ return 0;
4806+}
4807+
4808+
4809+/* ----- SPI master creation/removal --------------------------------------- */
4810+
4811+
4812+const static struct at86rf230_platform_data at86rf230_platform_data = {
4813+ .rstn = -1,
4814+ .slp_tr = JZ_GPIO_PORTD(9),
4815+ .dig2 = -1,
4816+ .reset = atben_reset,
4817+ /* set .reset_data later */
4818+};
4819+
4820+static int __devinit atben_probe(struct platform_device *pdev)
4821+{
4822+ struct spi_board_info board_info = {
4823+ .modalias = "at86rf230",
4824+ /* set .irq later */
4825+ .chip_select = 0,
4826+ .bus_num = -1,
4827+ .max_speed_hz = 8 * 1000 * 1000,
4828+ };
4829+
4830+ struct spi_master *master;
4831+ struct atben_prv *prv;
4832+ struct resource *regs;
4833+ struct spi_device *spi;
4834+ int err = -ENXIO;
4835+
4836+ master = spi_alloc_master(&pdev->dev, sizeof(*prv));
4837+ if (!master)
4838+ return -ENOMEM;
4839+
4840+ prv = spi_master_get_devdata(master);
4841+ prv->dev = &pdev->dev;
4842+ platform_set_drvdata(pdev, spi_master_get(master));
4843+
4844+ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
4845+ master->bus_num = pdev->id;
4846+ master->num_chipselect = 1;
4847+ master->setup = atben_setup;
4848+ master->transfer = atben_transfer;
4849+
4850+ dev_dbg(prv->dev, "Setting up ATBEN SPI\n");
4851+
4852+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
4853+ if (!regs) {
4854+ dev_err(prv->dev, "no IORESOURCE_MEM\n");
4855+ err = -ENOENT;
4856+ goto out_master;
4857+ }
4858+ prv->ioarea = request_mem_region(regs->start, resource_size(regs),
4859+ pdev->name);
4860+ if (!prv->ioarea) {
4861+ dev_err(prv->dev, "can't request ioarea\n");
4862+ goto out_master;
4863+ }
4864+
4865+ prv->regs = ioremap(regs->start, resource_size(regs));
4866+ if (!prv->regs) {
4867+ dev_err(prv->dev, "can't ioremap\n");
4868+ goto out_ioarea;
4869+ }
4870+
4871+ board_info.irq = platform_get_irq(pdev, 0);
4872+ if (board_info.irq < 0) {
4873+ dev_err(prv->dev, "can't get GPIO irq\n");
4874+ err = -ENOENT;
4875+ goto out_regs;
4876+ }
4877+
4878+ err = spi_register_master(master);
4879+ if (err) {
4880+ dev_err(prv->dev, "can't register master\n");
4881+ goto out_regs;
4882+ }
4883+
4884+ prv->platform_data = at86rf230_platform_data;
4885+ prv->platform_data.reset_data = prv;
4886+ board_info.platform_data = &prv->platform_data;
4887+
4888+ spi = spi_new_device(master, &board_info);
4889+ if (!spi) {
4890+ dev_err(&pdev->dev, "can't create new device for %s\n",
4891+ board_info.modalias);
4892+ err = -ENXIO;
4893+ goto out_registered;
4894+ }
4895+
4896+ dev_info(&spi->dev, "ATBEN ready for mischief (IRQ %d)\n",
4897+ board_info.irq);
4898+
4899+ return 0;
4900+
4901+out_registered:
4902+ spi_unregister_master(master);
4903+
4904+out_regs:
4905+ iounmap(prv->regs);
4906+
4907+out_ioarea:
4908+ release_resource(prv->ioarea);
4909+ kfree(prv->ioarea);
4910+
4911+out_master:
4912+ platform_set_drvdata(pdev, NULL);
4913+ spi_master_put(master);
4914+
4915+ return err;
4916+}
4917+
4918+static int __devexit atben_remove(struct platform_device *pdev)
4919+{
4920+ struct spi_master *master = platform_get_drvdata(pdev);
4921+ struct atben_prv *prv = spi_master_get_devdata(master);
4922+
4923+// restore GPIOs
4924+
4925+ spi_unregister_master(master);
4926+
4927+ iounmap(prv->regs);
4928+
4929+ release_resource(prv->ioarea);
4930+ kfree(prv->ioarea);
4931+
4932+ platform_set_drvdata(pdev, NULL);
4933+ spi_master_put(master);
4934+
4935+ return 0;
4936+}
4937+
4938+static struct platform_driver atben_driver = {
4939+ .driver = {
4940+ .name = "spi_atben",
4941+ .owner = THIS_MODULE,
4942+ },
4943+ .remove = __devexit_p(atben_remove),
4944+};
4945+
4946+static struct resource atben_resources[] = {
4947+ {
4948+ .start = JZ4740_GPIO_BASE_ADDR+0x300,
4949+ .end = JZ4740_GPIO_BASE_ADDR+0x3ff,
4950+ .flags = IORESOURCE_MEM,
4951+ },
4952+ {
4953+ /* set start and end later */
4954+ .flags = IORESOURCE_IRQ,
4955+ },
4956+};
4957+
4958+static struct platform_device atben_device = {
4959+ .name = "spi_atben",
4960+ .id = -1,
4961+ .num_resources = ARRAY_SIZE(atben_resources),
4962+ .resource = atben_resources,
4963+};
4964+
4965+/*
4966+ * Registering the platform device just to probe it immediately afterwards
4967+ * seems a little circuitous. Need to see if there's a better way.
4968+ *
4969+ * What we actually should do is this:
4970+ * - in module init, register the device
4971+ * - maybe probe as well, but keep the device also if the probe fails
4972+ * (due to a conflicting driver already occupying the 8:10 slot)
4973+ * - have a means for user space to kick off driver probing, e.g., when
4974+ * anything about the 8:10 slot changes
4975+ */
4976+
4977+static int __init atben_init(void)
4978+{
4979+ int err;
4980+
4981+ err = platform_device_register(&atben_device);
4982+ if (err)
4983+ return err;
4984+
4985+ atben_resources[1].start = atben_resources[1].end =
4986+ gpio_to_irq(JZ_GPIO_PORTD(12));
4987+
4988+ return platform_driver_probe(&atben_driver, atben_probe);
4989+}
4990+
4991+static void __exit atben_exit(void)
4992+{
4993+ platform_driver_unregister(&atben_driver);
4994+ platform_device_unregister(&atben_device);
4995+}
4996+
4997+module_init(atben_init);
4998+module_exit(atben_exit);
4999+
5000+
5001+MODULE_DESCRIPTION("ATBEN SPI Controller Driver");
5002+MODULE_AUTHOR("Werner Almesberger <werner@almesberger.net>");
5003+MODULE_LICENSE("GPL");
5004diff --git a/drivers/ieee802154/spi_atusb.c b/drivers/ieee802154/spi_atusb.c
5005new file mode 100644
5006index 0000000..44a9d03
5007--- /dev/null
5008+++ b/drivers/ieee802154/spi_atusb.c
5009@@ -0,0 +1,750 @@
5010+/*
5011+ * spi_atusb - SPI host look-alike for ATUSB
5012+ *
5013+ * Copyright (c) 2011 Richard Sharpe <realrichardsharpe@gmail.com>
5014+ * Copyright (c) 2011 Stefan Schmidt <stefan@datenfreihafen.org>
5015+ * Copyright (c) 2011 Werner Almesberger <werner@almesberger.net>
5016+ *
5017+ * This program is free software; you can redistribute it and/or
5018+ * modify it under the terms of the GNU General Public License as
5019+ * published by the Free Software Foundation, version 2
5020+ *
5021+ */
5022+
5023+/*
5024+ * - implement more robust interrupt synchronization
5025+ * - check URB killing in atusb_disconnect for races
5026+ * - switch from bulk to interrupt endpoint
5027+ * - implement buffer read without extra copy
5028+ * - harmonize indentation style
5029+ * - mv atusb.c ../ieee802.15.4/spi_atusb.c, or maybe atrf_atusb.c or such
5030+ * - check module load/unload
5031+ * - review dev_* severity levels
5032+ */
5033+
5034+#include <linux/kernel.h>
5035+#include <linux/module.h>
5036+#include <linux/platform_device.h>
5037+#include <linux/jiffies.h>
5038+#include <linux/timer.h>
5039+#include <linux/interrupt.h>
5040+#include <linux/usb.h>
5041+#include <linux/spi/spi.h>
5042+#include <linux/spi/at86rf230.h>
5043+
5044+#include "at86rf230.h"
5045+
5046+
5047+#define SYNC_TIMEOUT_MS 50 /* assume interrupt has been synced after
5048+ waiting this long */
5049+
5050+#define VENDOR_ID 0x20b7
5051+#define PRODUCT_ID 0x1540
5052+
5053+/* The devices we work with */
5054+static const struct usb_device_id atusb_device_table[] = {
5055+ { USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
5056+ { },
5057+};
5058+MODULE_DEVICE_TABLE(usb, atusb_device_table);
5059+
5060+#define ATUSB_BUILD_SIZE 256
5061+struct atusb_local {
5062+ struct usb_device * udev;
5063+ /* The interface to the RF part info, if applicable */
5064+ uint8_t ep0_atusb_major;
5065+ uint8_t ep0_atusb_minor;
5066+ uint8_t atusb_hw_type;
5067+ struct spi_master *master;
5068+ int slave_irq;
5069+ struct urb *irq_urb;
5070+ uint8_t irq_buf; /* receive irq serial here*/
5071+ uint8_t irq_seen; /* last irq serial from bulk */
5072+ uint8_t irq_sync; /* last irq serial from WRITE2_SYNC */
5073+ struct tasklet_struct task; /* interrupt delivery tasklet */
5074+ struct timer_list timer; /* delay, for interrupt synch */
5075+ struct at86rf230_platform_data platform_data;
5076+ /* copy platform_data so that we can adapt .reset_data */
5077+ struct spi_device *spi;
5078+// unsigned char buffer[3];
5079+ unsigned char buffer[260]; /* XXL, just in case */
5080+ struct spi_message *msg;
5081+};
5082+
5083+/* Commands to our device. Make sure this is synced with the firmware */
5084+enum atspi_requests {
5085+ ATUSB_ID = 0x00, /* system status/control grp */
5086+ ATUSB_BUILD,
5087+ ATUSB_RESET,
5088+ ATUSB_RF_RESET = 0x10, /* debug/test group */
5089+ ATUSB_POLL_INT,
5090+ ATUSB_TEST, /* atusb-sil only */
5091+ ATUSB_TIMER,
5092+ ATUSB_GPIO,
5093+ ATUSB_SLP_TR,
5094+ ATUSB_GPIO_CLEANUP,
5095+ ATUSB_REG_WRITE = 0x20, /* transceiver group */
5096+ ATUSB_REG_READ,
5097+ ATUSB_BUF_WRITE,
5098+ ATUSB_BUF_READ,
5099+ ATUSB_SRAM_WRITE,
5100+ ATUSB_SRAM_READ,
5101+ ATUSB_SPI_WRITE = 0x30, /* SPI group */
5102+ ATUSB_SPI_READ1,
5103+ ATUSB_SPI_READ2,
5104+ ATUSB_SPI_WRITE2_SYNC,
5105+};
5106+
5107+/*
5108+ * Direction bRequest wValue wIndex wLength
5109+ *
5110+ * ->host ATUSB_ID - - 3
5111+ * ->host ATUSB_BUILD - - #bytes
5112+ * host-> ATUSB_RESET - - 0
5113+ *
5114+ * host-> ATUSB_RF_RESET - - 0
5115+ * ->host ATUSB_POLL_INT - - 1
5116+ * host-> ATUSB_TEST - - 0
5117+ * ->host ATUSB_TIMER - - #bytes (6)
5118+ * ->host ATUSB_GPIO dir+data mask+p# 3
5119+ * host-> ATUSB_SLP_TR - - 0
5120+ * host-> ATUSB_GPIO_CLEANUP - - 0
5121+ *
5122+ * host-> ATUSB_REG_WRITE value addr 0
5123+ * ->host ATUSB_REG_READ - addr 1
5124+ * host-> ATUSB_BUF_WRITE - - #bytes
5125+ * ->host ATUSB_BUF_READ - - #bytes
5126+ * host-> ATUSB_SRAM_WRITE - addr #bytes
5127+ * ->host ATUSB_SRAM_READ - addr #bytes
5128+ *
5129+ * host-> ATUSB_SPI_WRITE byte0 byte1 #bytes
5130+ * ->host ATUSB_SPI_READ1 byte0 - #bytes
5131+ * ->host ATUSB_SPI_READ2 byte0 byte1 #bytes
5132+ * ->host ATUSB_SPI_WRITE2_SYNC byte0 byte1 0/1
5133+ */
5134+
5135+#define ATUSB_FROM_DEV (USB_TYPE_VENDOR | USB_DIR_IN)
5136+#define ATUSB_TO_DEV (USB_TYPE_VENDOR | USB_DIR_OUT)
5137+
5138+
5139+/* ----- Control transfers ------------------------------------------------- */
5140+
5141+
5142+static int atusb_async_errchk(struct urb *urb)
5143+{
5144+ struct atusb_local *atusb = urb->context;
5145+ struct spi_message *msg = atusb->msg;
5146+ struct usb_device *dev = atusb->udev;
5147+
5148+ if (!urb->status) {
5149+ dev_dbg(&dev->dev, "atusb_async_errchk OK len %d\n",
5150+ urb->actual_length);
5151+ return 0;
5152+ }
5153+
5154+ if (urb->status != -ENOENT && urb->status != -ECONNRESET &&
5155+ urb->status != -ESHUTDOWN)
5156+ dev_info(&dev->dev, "atusb_async_errchk FAIL error %d\n",
5157+ urb->status);
5158+
5159+ msg->actual_length = 0;
5160+
5161+ return urb->status;
5162+}
5163+
5164+static void atusb_async_finish(struct urb *urb)
5165+{
5166+ struct atusb_local *atusb = urb->context;
5167+ struct spi_message *msg = atusb->msg;
5168+
5169+ msg->status = urb->status;
5170+ msg->complete(msg->context);
5171+
5172+ kfree(urb->setup_packet);
5173+ usb_free_urb(urb);
5174+}
5175+
5176+static void atusb_ctrl_cb(struct urb *urb)
5177+{
5178+ atusb_async_errchk(urb);
5179+ atusb_async_finish(urb);
5180+}
5181+
5182+static void atusb_timer(unsigned long data)
5183+{
5184+ struct urb *urb = (void *) data;
5185+
5186+ dev_warn(&urb->dev->dev, "atusb_timer\n");
5187+ atusb_async_finish(urb);
5188+}
5189+
5190+static void atusb_ctrl_cb_sync(struct urb *urb)
5191+{
5192+ struct atusb_local *atusb = urb->context;
5193+
5194+ /* @@@ needs locking/atomic */
5195+ if (atusb_async_errchk(urb) || atusb->irq_sync == atusb->irq_seen) {
5196+ atusb_async_finish(urb);
5197+ return;
5198+ }
5199+
5200+ BUG_ON(timer_pending(&atusb->timer));
5201+ atusb->timer.expires = jiffies+msecs_to_jiffies(SYNC_TIMEOUT_MS);
5202+ atusb->timer.data = (unsigned long) urb;
5203+ add_timer(&atusb->timer);
5204+}
5205+
5206+static void atusb_read_fb_cb(struct urb *urb)
5207+{
5208+ struct atusb_local *atusb = urb->context;
5209+ struct spi_message *msg = atusb->msg;
5210+ const struct spi_transfer *xfer;
5211+ uint8_t *rx;
5212+
5213+ if (!atusb_async_errchk(urb)) {
5214+ BUG_ON(!urb->actual_length);
5215+
5216+ xfer = list_first_entry(&msg->transfers, struct spi_transfer,
5217+ transfer_list);
5218+ rx = xfer->rx_buf;
5219+ rx[1] = atusb->buffer[0];
5220+
5221+ xfer = list_entry(xfer->transfer_list.next,
5222+ struct spi_transfer, transfer_list);
5223+ memcpy(xfer->rx_buf, atusb->buffer+1, urb->actual_length-1);
5224+ }
5225+
5226+ atusb_async_finish(urb);
5227+}
5228+
5229+static int submit_control_msg(struct atusb_local *atusb,
5230+ __u8 request, __u8 requesttype, __u16 value, __u16 index,
5231+ void *data, __u16 size, usb_complete_t complete_fn, void *context)
5232+{
5233+ struct usb_device *dev = atusb->udev;
5234+ struct usb_ctrlrequest *req;
5235+ struct urb *urb;
5236+ int retval = -ENOMEM;
5237+
5238+ req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
5239+ if (!req)
5240+ return -ENOMEM;
5241+
5242+ req->bRequest = request;
5243+ req->bRequestType = requesttype;
5244+ req->wValue = cpu_to_le16(value);
5245+ req->wIndex = cpu_to_le16(index);
5246+ req->wLength = cpu_to_le16(size);
5247+
5248+ urb = usb_alloc_urb(0, GFP_KERNEL);
5249+ if (!urb)
5250+ goto out_nourb;
5251+
5252+ usb_fill_control_urb(urb, dev,
5253+ requesttype == ATUSB_FROM_DEV ?
5254+ usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0),
5255+ (unsigned char *) req, data, size, complete_fn, context);
5256+
5257+ retval = usb_submit_urb(urb, GFP_KERNEL);
5258+ if (!retval)
5259+ return 0;
5260+ dev_warn(&dev->dev, "failed submitting read urb, error %d",
5261+ retval);
5262+ retval = retval == -ENOMEM ? retval : -EIO;
5263+
5264+ usb_free_urb(urb);
5265+out_nourb:
5266+ kfree(req);
5267+
5268+ return retval;
5269+}
5270+
5271+
5272+/* ----- SPI transfers ----------------------------------------------------- */
5273+
5274+
5275+static int atusb_read1(struct atusb_local *atusb,
5276+ uint8_t tx, uint8_t *rx, int len)
5277+{
5278+ dev_dbg(&atusb->udev->dev, "atusb_read1: tx = 0x%x\n", tx);
5279+ return submit_control_msg(atusb,
5280+ ATUSB_SPI_READ1, ATUSB_FROM_DEV, tx, 0,
5281+ rx, 1, atusb_ctrl_cb, atusb);
5282+}
5283+
5284+static int atusb_read_fb(struct atusb_local *atusb,
5285+ uint8_t tx, uint8_t *rx0, uint8_t *rx, int len)
5286+{
5287+ dev_dbg(&atusb->udev->dev, "atusb_read_fb: tx = 0x%x\n", tx);
5288+ return submit_control_msg(atusb,
5289+ ATUSB_SPI_READ1, ATUSB_FROM_DEV, tx, 0,
5290+ atusb->buffer, len+1, atusb_read_fb_cb, atusb);
5291+}
5292+
5293+static int atusb_write(struct atusb_local *atusb,
5294+ uint8_t tx0, uint8_t tx1, const uint8_t *tx, int len)
5295+{
5296+ dev_dbg(&atusb->udev->dev,
5297+ "atusb_write: tx0 = 0x%x tx1 = 0x%x\n", tx0, tx1);
5298+
5299+ /*
5300+ * The AT86RF230 driver sometimes requires a transceiver state
5301+ * transition to be an interrupt barrier. This is the case after
5302+ * writing FORCE_TX_ON to the TRX_CMD field in the TRX_STATE register.
5303+ *
5304+ * Since there is no other means of notification, we just decode the
5305+ * transfer and do a bit of pattern matching.
5306+ */
5307+ if (tx0 == (CMD_REG | CMD_WRITE | RG_TRX_STATE) &&
5308+ (tx1 & 0x1f) == STATE_FORCE_TX_ON)
5309+ return submit_control_msg(atusb,
5310+ ATUSB_SPI_WRITE2_SYNC, ATUSB_FROM_DEV, tx0, tx1,
5311+ &atusb->irq_sync, 1, atusb_ctrl_cb_sync, atusb);
5312+ else
5313+ return submit_control_msg(atusb,
5314+ ATUSB_SPI_WRITE, ATUSB_TO_DEV, tx0, tx1,
5315+ (uint8_t *) tx, len, atusb_ctrl_cb, atusb);
5316+}
5317+
5318+static int atusb_transfer(struct spi_device *spi, struct spi_message *msg)
5319+{
5320+ struct atusb_local *atusb = spi_master_get_devdata(spi->master);
5321+ struct spi_transfer *xfer;
5322+ struct spi_transfer *x[2];
5323+ int n;
5324+ const uint8_t *tx;
5325+ uint8_t *rx;
5326+ int len;
5327+ int retval = 0;
5328+
5329+ if (unlikely(list_empty(&msg->transfers))) {
5330+ dev_err(&atusb->udev->dev, "transfer is empty\n");
5331+ return -EINVAL;
5332+ }
5333+
5334+ atusb->msg = msg;
5335+
5336+ /* Classify the request */
5337+ n = 0;
5338+ list_for_each_entry(xfer, &msg->transfers, transfer_list) {
5339+ if (n == ARRAY_SIZE(x)) {
5340+ dev_err(&atusb->udev->dev, "too many transfers\n");
5341+ return -EINVAL;
5342+ }
5343+ x[n] = xfer;
5344+ n++;
5345+ }
5346+
5347+ tx = x[0]->tx_buf;
5348+ rx = x[0]->rx_buf;
5349+ len = x[0]->len;
5350+
5351+ msg->actual_length = len;
5352+
5353+ if (!tx || len != 2)
5354+ goto bad_req;
5355+ if (n == 1) {
5356+ if (rx) {
5357+ dev_dbg(&atusb->udev->dev, "read 1\n");
5358+ retval = atusb_read1(atusb, tx[0], rx+1, len-1);
5359+ } else {
5360+ dev_dbg(&atusb->udev->dev, "write 2\n");
5361+ /*
5362+ * Don't take our clock away !! ;-)
5363+ */
5364+ if (tx[0] == (CMD_REG | CMD_WRITE | RG_TRX_CTRL_0)) {
5365+ msg->status = 0;
5366+ msg->complete(msg->context);
5367+ } else {
5368+ retval = atusb_write(atusb,
5369+ tx[0], tx[1], NULL, 0);
5370+ }
5371+ }
5372+ } else {
5373+ if (x[0]->rx_buf) {
5374+ if (x[1]->tx_buf || !x[1]->rx_buf)
5375+ goto bad_req;
5376+ dev_dbg(&atusb->udev->dev, "read 1+\n");
5377+ retval = atusb_read_fb(atusb, tx[0], rx+1,
5378+ x[1]->rx_buf, x[1]->len);
5379+ } else {
5380+ if (!x[1]->tx_buf ||x[1]->rx_buf)
5381+ goto bad_req;
5382+ dev_dbg(&atusb->udev->dev, "write 2+n\n");
5383+ retval = atusb_write(atusb, tx[0], tx[1],
5384+ x[1]->tx_buf, x[1]->len);
5385+ }
5386+ }
5387+ return retval;
5388+
5389+bad_req:
5390+ dev_err(&atusb->udev->dev, "unrecognized request:\n");
5391+ list_for_each_entry(xfer, &msg->transfers, transfer_list)
5392+ dev_err(&atusb->udev->dev, "%stx %srx len %u\n",
5393+ xfer->tx_buf ? "" : "!", xfer->rx_buf ? " " : "!",
5394+ xfer->len);
5395+ return -EINVAL;
5396+}
5397+
5398+static int atusb_setup(struct spi_device *spi)
5399+{
5400+ return 0;
5401+}
5402+
5403+
5404+/* ----- Interrupt handling ------------------------------------------------ */
5405+
5406+
5407+static void atusb_tasklet(unsigned long data)
5408+{
5409+ struct atusb_local *atusb = (void *) data;
5410+
5411+ generic_handle_irq(atusb->slave_irq);
5412+}
5413+
5414+static void atusb_irq(struct urb *urb)
5415+{
5416+ struct atusb_local *atusb = urb->context;
5417+
5418+ dev_dbg(&urb->dev->dev, "atusb_irq (%d), seen %d sync %d\n",
5419+ urb->status, atusb->irq_buf, atusb->irq_sync);
5420+ if (!urb->status) {
5421+ atusb->irq_seen = atusb->irq_buf;
5422+ if (atusb->irq_sync == atusb->irq_seen &&
5423+ try_to_del_timer_sync(&atusb->timer) == 1)
5424+ atusb_async_finish((struct urb *) atusb->timer.data);
5425+ }
5426+ usb_free_urb(urb);
5427+ atusb->irq_urb = NULL;
5428+ tasklet_schedule(&atusb->task);
5429+}
5430+
5431+static int atusb_arm_interrupt(struct atusb_local *atusb)
5432+{
5433+ struct usb_device *dev = atusb->udev;
5434+ struct urb *urb;
5435+ int retval = -ENOMEM;
5436+
5437+ BUG_ON(atusb->irq_urb);
5438+
5439+ dev_vdbg(&dev->dev, "atusb_arm_interrupt\n");
5440+ urb = usb_alloc_urb(0, GFP_KERNEL);
5441+ if (!urb) {
5442+ dev_err(&dev->dev,
5443+ "atusb_arm_interrupt: usb_alloc_urb failed\n");
5444+ return -ENOMEM;
5445+ }
5446+
5447+ usb_fill_bulk_urb(urb, dev, usb_rcvbulkpipe(dev, 1),
5448+ &atusb->irq_buf, 1, atusb_irq, atusb);
5449+ atusb->irq_urb = urb;
5450+ retval = usb_submit_urb(urb, GFP_KERNEL);
5451+ if (!retval)
5452+ return 0;
5453+
5454+ dev_err(&dev->dev, "failed submitting bulk urb, error %d\n", retval);
5455+ retval = retval == -ENOMEM ? retval : -EIO;
5456+
5457+ usb_free_urb(urb);
5458+
5459+ return retval;
5460+}
5461+
5462+static void atusb_irq_mask(struct irq_data *data)
5463+{
5464+ struct atusb_local *atusb = irq_data_get_irq_chip_data(data);
5465+
5466+ dev_vdbg(&atusb->udev->dev, "atusb_irq_mask\n");
5467+ tasklet_disable_nosync(&atusb->task);
5468+}
5469+
5470+static void atusb_irq_unmask(struct irq_data *data)
5471+{
5472+ struct atusb_local *atusb = irq_data_get_irq_chip_data(data);
5473+
5474+ dev_vdbg(&atusb->udev->dev, "atusb_irq_unmask\n");
5475+ tasklet_enable(&atusb->task);
5476+}
5477+
5478+static void atusb_irq_ack(struct irq_data *data)
5479+{
5480+ struct atusb_local *atusb = irq_data_get_irq_chip_data(data);
5481+
5482+ dev_vdbg(&atusb->udev->dev, "atusb_irq_ack\n");
5483+ atusb_arm_interrupt(atusb);
5484+}
5485+
5486+static struct irq_chip atusb_irq_chip = {
5487+ .name = "atusb-slave",
5488+ .irq_mask = atusb_irq_mask,
5489+ .irq_unmask = atusb_irq_unmask,
5490+ .irq_ack = atusb_irq_ack,
5491+};
5492+
5493+
5494+/* ----- Transceiver reset ------------------------------------------------- */
5495+
5496+
5497+static void atusb_reset(void *reset_data)
5498+{
5499+ int retval;
5500+ struct atusb_local *atusb = reset_data;
5501+
5502+ retval = usb_control_msg(atusb->udev,
5503+ usb_rcvctrlpipe(atusb->udev, 0),
5504+ ATUSB_RF_RESET, ATUSB_TO_DEV, 0, 0,
5505+ NULL, 0, 1000);
5506+ if (retval < 0) {
5507+ dev_err(&atusb->udev->dev,
5508+ "%s: error doing reset retval = %d\n",
5509+ __func__, retval);
5510+ }
5511+}
5512+
5513+
5514+/* ----- Firmware version information -------------------------------------- */
5515+
5516+
5517+static int atusb_get_and_show_revision(struct atusb_local *atusb)
5518+{
5519+ struct usb_device *dev = atusb->udev;
5520+ int retval;
5521+
5522+ /* Get a couple of the ATMega Firmware values */
5523+ retval = usb_control_msg(dev,
5524+ usb_rcvctrlpipe(dev, 0),
5525+ ATUSB_ID, ATUSB_FROM_DEV, 0, 0,
5526+ atusb->buffer, 3, 1000);
5527+ if (retval < 0) {
5528+ dev_info(&dev->dev,
5529+ "failed submitting urb for ATUSB_ID, error %d\n", retval);
5530+ return retval == -ENOMEM ? retval : -EIO;
5531+ }
5532+
5533+ atusb->ep0_atusb_major = atusb->buffer[0];
5534+ atusb->ep0_atusb_minor = atusb->buffer[1];
5535+ atusb->atusb_hw_type = atusb->buffer[2];
5536+ dev_info(&dev->dev,
5537+ "Firmware: major: %u, minor: %u, hardware type: %u\n",
5538+ atusb->ep0_atusb_major, atusb->ep0_atusb_minor,
5539+ atusb->atusb_hw_type);
5540+
5541+ return 0;
5542+}
5543+
5544+static int atusb_get_and_show_build(struct atusb_local *atusb)
5545+{
5546+ struct usb_device *dev = atusb->udev;
5547+ char build[ATUSB_BUILD_SIZE+1];
5548+ int retval;
5549+
5550+ retval = usb_control_msg(dev,
5551+ usb_rcvctrlpipe(atusb->udev, 0),
5552+ ATUSB_BUILD, ATUSB_FROM_DEV, 0, 0,
5553+ build, ATUSB_BUILD_SIZE, 1000);
5554+ if (retval < 0) {
5555+ dev_err(&dev->dev,
5556+ "failed submitting urb for ATUSB_BUILD, error %d\n",
5557+ retval);
5558+ return retval == -ENOMEM ? retval : -EIO;
5559+ }
5560+
5561+ build[retval] = 0;
5562+ dev_info(&dev->dev, "Firmware: build %s\n", build);
5563+
5564+ return 0;
5565+}
5566+
5567+
5568+/* ----- Setup ------------------------------------------------------------- */
5569+
5570+
5571+struct at86rf230_platform_data at86rf230_platform_data = {
5572+ .rstn = -1,
5573+ .slp_tr = -1,
5574+ .dig2 = -1,
5575+ .reset = atusb_reset,
5576+ /* set .reset_data later */
5577+};
5578+
5579+static int atusb_probe(struct usb_interface *interface,
5580+ const struct usb_device_id *id)
5581+{
5582+ struct spi_board_info board_info = {
5583+ .modalias = "at86rf230",
5584+ /* set .irq later */
5585+ .chip_select = 0,
5586+ .bus_num = -1,
5587+ .max_speed_hz = 8 * 1000 * 1000,
5588+ };
5589+
5590+ struct usb_device *udev = interface_to_usbdev(interface);
5591+ struct atusb_local *atusb = NULL;
5592+ struct spi_master *master;
5593+ int retval;
5594+
5595+ /*
5596+ * Ignore all interfaces used for DFU, i.e., everything while in the
5597+ * boot loader, and interface #1 when in the application.
5598+ */
5599+ if (interface->cur_altsetting->desc.bInterfaceClass !=
5600+ USB_CLASS_VENDOR_SPEC) {
5601+ dev_dbg(&udev->dev,
5602+ "Ignoring interface with class 0x%02x\n",
5603+ interface->cur_altsetting->desc.bInterfaceClass);
5604+ return -ENODEV;
5605+ }
5606+
5607+ master = spi_alloc_master(&udev->dev, sizeof(*atusb));
5608+ if (!master)
5609+ return -ENOMEM;
5610+
5611+ atusb = spi_master_get_devdata(master);
5612+
5613+ atusb->udev = usb_get_dev(udev);
5614+ usb_set_intfdata(interface, atusb);
5615+
5616+ atusb->master = spi_master_get(master);
5617+
5618+ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
5619+ master->bus_num = -1;
5620+ master->num_chipselect = 1;
5621+ master->setup = atusb_setup;
5622+ master->transfer = atusb_transfer;
5623+
5624+ atusb->slave_irq = irq_alloc_desc(numa_node_id());
5625+ if (atusb->slave_irq < 0) {
5626+ dev_err(&udev->dev, "can't allocate slave irq\n");
5627+ retval = -ENXIO;
5628+ goto err_free;
5629+ }
5630+
5631+ irq_set_chip_data(atusb->slave_irq, atusb);
5632+ irq_set_chip_and_handler(atusb->slave_irq, &atusb_irq_chip,
5633+ handle_level_irq);
5634+
5635+ /* FIXME prepare USB IRQ */
5636+
5637+ retval = spi_register_master(master);
5638+ if (retval < 0) {
5639+ dev_err(&udev->dev, "can't register spi master\n");
5640+ goto err_slave_irq;
5641+ }
5642+
5643+ atusb->platform_data = at86rf230_platform_data;
5644+ atusb->platform_data.reset_data = atusb;
5645+ board_info.platform_data = &atusb->platform_data;
5646+ board_info.irq = atusb->slave_irq;
5647+
5648+ init_timer(&atusb->timer);
5649+ atusb->timer.function = atusb_timer;
5650+
5651+ tasklet_init(&atusb->task, atusb_tasklet, (unsigned long) atusb);
5652+ tasklet_disable(&atusb->task);
5653+ atusb_arm_interrupt(atusb);
5654+
5655+ if (atusb_get_and_show_revision(atusb) < 0)
5656+ goto err_master;
5657+ if (atusb_get_and_show_build(atusb) < 0)
5658+ goto err_master;
5659+
5660+ atusb->spi = spi_new_device(master, &board_info);
5661+ if (!atusb->spi) {
5662+ dev_err(&udev->dev, "can't create new device for %s\n",
5663+ board_info.modalias);
5664+ goto err_master;
5665+ }
5666+
5667+ dev_info(&atusb->spi->dev,
5668+ "ATUSB ready for mischief (IRQ %d)\n", board_info.irq);
5669+
5670+ return 0;
5671+
5672+err_master:
5673+ /*
5674+ * If we come here from a partially successful driver initialization,
5675+ * we don't really know how much it has done. In particular, it may
5676+ * have triggered an interrupt and thus removed the interrupt URB and
5677+ * maybe scheduled the tasklet.
5678+ */
5679+ tasklet_disable(&atusb->task);
5680+ if (atusb->irq_urb)
5681+ usb_kill_urb(atusb->irq_urb);
5682+ spi_master_put(atusb->master);
5683+err_slave_irq:
5684+ irq_set_chained_handler(atusb->slave_irq, NULL);
5685+ irq_set_chip_data(atusb->slave_irq, NULL);
5686+ irq_free_desc(atusb->slave_irq);
5687+err_free:
5688+ return retval;
5689+}
5690+
5691+static void atusb_disconnect(struct usb_interface *interface)
5692+{
5693+ struct atusb_local *atusb = usb_get_intfdata(interface);
5694+ struct spi_master *master = atusb->master;
5695+
5696+ tasklet_disable(&atusb->task);
5697+ /* @@@ this needs some extra protecion - wa */
5698+ if (atusb->irq_urb)
5699+ usb_kill_urb(atusb->irq_urb);
5700+
5701+ BUG_ON(timer_pending(&atusb->timer));
5702+
5703+ usb_set_intfdata(interface, NULL);
5704+ usb_put_dev(atusb->udev);
5705+
5706+ spi_dev_put(atusb->spi);
5707+
5708+ spi_unregister_master(master);
5709+
5710+ irq_set_chained_handler(atusb->slave_irq, NULL);
5711+ irq_set_chip_data(atusb->slave_irq, NULL);
5712+ irq_free_desc(atusb->slave_irq);
5713+
5714+ spi_master_put(master);
5715+}
5716+
5717+void atusb_release(struct device *dev)
5718+{
5719+ return;
5720+}
5721+
5722+static struct usb_driver atusb_driver = {
5723+ .name = "atusb_ben-wpan",
5724+ .probe = atusb_probe,
5725+ .disconnect = atusb_disconnect,
5726+ .id_table = atusb_device_table,
5727+};
5728+
5729+static struct platform_device atusb_device = {
5730+ .name = "spi_atusb",
5731+ .id = -1,
5732+ .dev.release = atusb_release,
5733+};
5734+
5735+static int __init atusb_init(void)
5736+{
5737+ int retval;
5738+
5739+ retval = platform_device_register(&atusb_device);
5740+ if (retval)
5741+ return retval;
5742+
5743+ return usb_register(&atusb_driver);
5744+}
5745+
5746+static void __exit atusb_exit(void)
5747+{
5748+ usb_deregister(&atusb_driver);
5749+ platform_device_unregister(&atusb_device);
5750+}
5751+
5752+module_init (atusb_init);
5753+module_exit (atusb_exit);
5754+
5755+MODULE_AUTHOR("Richard Sharpe <realrichardsharpe@gmail.com>");
5756+MODULE_AUTHOR("Stefan Schmidt <stefan@datenfreihafen.org>");
5757+MODULE_AUTHOR("Werner Almesberger <werner@almesberger.net>");
5758+MODULE_DESCRIPTION("ATUSB ben-wpan Driver");
5759+MODULE_LICENSE("GPL");
5760diff --git a/include/linux/if.h b/include/linux/if.h
5761index db20bd4..cec9280 100644
5762--- a/include/linux/if.h
5763+++ b/include/linux/if.h
5764@@ -80,6 +80,8 @@
5765                      * skbs on transmit */
5766 #define IFF_UNICAST_FLT 0x20000 /* Supports unicast filtering */
5767 
5768+#define IFF_IEEE802154_COORD 0x400 /* IEEE802.15.4 PAN coordinator */
5769+
5770 #define IF_GET_IFACE 0x0001 /* for querying only */
5771 #define IF_GET_PROTO 0x0002
5772 
5773diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h
5774index 6d722f4..47a57d8 100644
5775--- a/include/linux/if_arp.h
5776+++ b/include/linux/if_arp.h
5777@@ -87,6 +87,8 @@
5778 #define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */
5779 #define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */
5780 #define ARPHRD_IEEE802154 804
5781+#define ARPHRD_IEEE802154_MONITOR 805
5782+#define ARPHRD_SMAC 806 /* Freescale Simple MAC */
5783 
5784 #define ARPHRD_PHONET 820 /* PhoNet media type */
5785 #define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */
5786diff --git a/include/linux/if_ieee802154.h b/include/linux/if_ieee802154.h
5787new file mode 100644
5788index 0000000..cce32bb
5789--- /dev/null
5790+++ b/include/linux/if_ieee802154.h
5791@@ -0,0 +1,6 @@
5792+#ifndef __LINUX_IF_IEEE802154_H
5793+#define __LINUX_IF_IEEE802154_H
5794+
5795+#define IEEE802154_ALEN 8 /* size of 64-bit hardware address */
5796+
5797+#endif
5798diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h
5799index 33d9f51..a379fc7 100644
5800--- a/include/linux/nl802154.h
5801+++ b/include/linux/nl802154.h
5802@@ -68,14 +68,13 @@ enum {
5803     IEEE802154_ATTR_CHANNEL_PAGE_LIST,
5804 
5805     IEEE802154_ATTR_PHY_NAME,
5806+ IEEE802154_ATTR_DEV_TYPE,
5807 
5808     __IEEE802154_ATTR_MAX,
5809 };
5810 
5811 #define IEEE802154_ATTR_MAX (__IEEE802154_ATTR_MAX - 1)
5812 
5813-extern const struct nla_policy ieee802154_policy[];
5814-
5815 /* commands */
5816 /* REQ should be responded with CONF
5817  * and INDIC with RESP
5818@@ -126,4 +125,11 @@ enum {
5819 
5820 #define IEEE802154_CMD_MAX (__IEEE802154_CMD_MAX - 1)
5821 
5822+enum {
5823+ IEEE802154_DEV_WPAN,
5824+ IEEE802154_DEV_MONITOR,
5825+ IEEE802154_DEV_SMAC,
5826+ __IEEE802154_DEV_MAX,
5827+};
5828+
5829 #endif
5830diff --git a/include/linux/spi/at86rf230.h b/include/linux/spi/at86rf230.h
5831new file mode 100644
5832index 0000000..dff0225
5833--- /dev/null
5834+++ b/include/linux/spi/at86rf230.h
5835@@ -0,0 +1,34 @@
5836+/*
5837+ * AT86RF230/RF231 driver
5838+ *
5839+ * Copyright (C) 2009 Siemens AG
5840+ *
5841+ * This program is free software; you can redistribute it and/or modify
5842+ * it under the terms of the GNU General Public License version 2
5843+ * as published by the Free Software Foundation.
5844+ *
5845+ * This program is distributed in the hope that it will be useful,
5846+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5847+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5848+ * GNU General Public License for more details.
5849+ *
5850+ * You should have received a copy of the GNU General Public License along
5851+ * with this program; if not, write to the Free Software Foundation, Inc.,
5852+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
5853+ *
5854+ * Written by:
5855+ * Dmitry Eremin-Solenikov <dmitry.baryshkov@siemens.com>
5856+ */
5857+#ifndef LINUX_SPI_AT86RF230_H
5858+#define LINUX_SPI_AT86RF230_H
5859+
5860+struct at86rf230_platform_data {
5861+ int rstn;
5862+ int slp_tr;
5863+ int dig2;
5864+ void (*reset)(void *reset_data);
5865+ void *reset_data;
5866+};
5867+
5868+#endif
5869+
5870diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
5871index 5743055..e12ce9a 100644
5872--- a/include/net/ieee802154_netdev.h
5873+++ b/include/net/ieee802154_netdev.h
5874@@ -26,6 +26,8 @@
5875 #ifndef IEEE802154_NETDEVICE_H
5876 #define IEEE802154_NETDEVICE_H
5877 
5878+#include <net/af_ieee802154.h>
5879+
5880 /*
5881  * A control block of skb passed between the ARPHRD_IEEE802154 device
5882  * and other stack parts.
5883@@ -81,7 +83,12 @@ struct wpan_phy;
5884  * get_phy should increment the reference counting on returned phy.
5885  * Use wpan_wpy_put to put that reference.
5886  */
5887+struct simple_mlme_ops {
5888+ struct wpan_phy *(*get_phy)(const struct net_device *dev);
5889+};
5890 struct ieee802154_mlme_ops {
5891+ struct simple_mlme_ops wpan_ops;
5892+
5893     int (*assoc_req)(struct net_device *dev,
5894             struct ieee802154_addr *addr,
5895             u8 channel, u8 page, u8 cap);
5896@@ -98,8 +105,6 @@ struct ieee802154_mlme_ops {
5897     int (*scan_req)(struct net_device *dev,
5898             u8 type, u32 channels, u8 page, u8 duration);
5899 
5900- struct wpan_phy *(*get_phy)(const struct net_device *dev);
5901-
5902     /*
5903      * FIXME: these should become the part of PIB/MIB interface.
5904      * However we still don't have IB interface of any kind
5905@@ -110,12 +115,18 @@ struct ieee802154_mlme_ops {
5906     u8 (*get_bsn)(const struct net_device *dev);
5907 };
5908 
5909-static inline struct ieee802154_mlme_ops *ieee802154_mlme_ops(
5910+static inline struct simple_mlme_ops *simple_mlme_ops(
5911         const struct net_device *dev)
5912 {
5913     return dev->ml_priv;
5914 }
5915 
5916+static inline struct ieee802154_mlme_ops *ieee802154_mlme_ops(
5917+ const struct net_device *dev)
5918+{
5919+ return container_of(dev->ml_priv, struct ieee802154_mlme_ops, wpan_ops);
5920+}
5921+
5922 #endif
5923 
5924 
5925diff --git a/include/net/mac802154.h b/include/net/mac802154.h
5926new file mode 100644
5927index 0000000..df46f6a
5928--- /dev/null
5929+++ b/include/net/mac802154.h
5930@@ -0,0 +1,156 @@
5931+/*
5932+ * IEEE802.15.4-2003 specification
5933+ *
5934+ * Copyright (C) 2007, 2008 Siemens AG
5935+ *
5936+ * This program is free software; you can redistribute it and/or modify
5937+ * it under the terms of the GNU General Public License version 2
5938+ * as published by the Free Software Foundation.
5939+ *
5940+ * This program is distributed in the hope that it will be useful,
5941+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5942+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5943+ * GNU General Public License for more details.
5944+ *
5945+ * You should have received a copy of the GNU General Public License along
5946+ * with this program; if not, write to the Free Software Foundation, Inc.,
5947+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
5948+ *
5949+ * Written by:
5950+ */
5951+#ifndef NET_MAC802154_H
5952+#define NET_MAC802154_H
5953+
5954+#include <linux/if_ieee802154.h>
5955+
5956+/**
5957+ * enum ieee802154_hw_addr_filt_flags - hardware flags
5958+ *
5959+ * These flags are used to indicate changed address settings from
5960+ * the stack to the hardware.
5961+ *
5962+ * @IEEE802515_SADDR_CHANGED:
5963+ * Indicates that the Short Address changed
5964+ *
5965+ * @IEEE802515_IEEEADDR_CHANGED:
5966+ * Indicates that the IEEE Address changed
5967+ *
5968+ * @IEEE802515_PANID_CHANGED:
5969+ * Indicates that the PAN ID changed
5970+ *
5971+ * @IEEE802515_PANC_CHANGED:
5972+ * Indicates that PAN Coordinator status changed
5973+ */
5974+enum ieee802154_hw_addr_filt_flags {
5975+ IEEE802515_SADDR_CHANGED = 1 << 0,
5976+ IEEE802515_IEEEADDR_CHANGED = 1 << 1,
5977+ IEEE802515_PANID_CHANGED = 1 << 2,
5978+ IEEE802515_PANC_CHANGED = 1 << 3,
5979+};
5980+
5981+struct ieee802154_hw_addr_filt {
5982+ u16 pan_id;
5983+ u16 short_addr;
5984+ u8 ieee_addr[IEEE802154_ALEN];
5985+ u8 pan_coord;
5986+};
5987+
5988+struct ieee802154_dev {
5989+ /* filled by the driver */
5990+ int extra_tx_headroom; /* headroom to reserve for tx skb */
5991+ u32 flags; /* Flags for device to set */
5992+ struct device *parent;
5993+
5994+ /* filled by mac802154 core */
5995+ struct ieee802154_hw_addr_filt hw_filt;
5996+ void *priv; /* driver-specific data */
5997+ struct wpan_phy *phy;
5998+};
5999+
6000+/* Checksum is in hardware and is omitted from packet */
6001+/**
6002+ * enum ieee802154_hw_flags - hardware flags
6003+ *
6004+ * These flags are used to indicate hardware capabilities to
6005+ * the stack. Generally, flags here should have their meaning
6006+ * done in a way that the simplest hardware doesn't need setting
6007+ * any particular flags. There are some exceptions to this rule,
6008+ * however, so you are advised to review these flags carefully.
6009+ *
6010+ * @IEEE802154_HW_OMIT_CKSUM:
6011+ * Indicates that receiver omits FCS and transmitter will add
6012+ * FCS on it's own.
6013+ *
6014+ * @IEEE802154_HW_AACK:
6015+ * Indicates that receiver will autorespond with ACK frames.
6016+ */
6017+enum ieee802154_hw_flags {
6018+ IEEE802154_HW_OMIT_CKSUM = 1 << 0,
6019+ IEEE802154_HW_AACK = 1 << 1,
6020+};
6021+
6022+struct sk_buff;
6023+
6024+/**
6025+ * struct ieee802154_ops - callbacks from mac802154 to the driver
6026+ *
6027+ * This structure contains various callbacks that the driver may
6028+ * handle or, in some cases, must handle, for example to transmit
6029+ * a frame.
6030+ *
6031+ * @start: Handler that 802.15.4 module calls for device initialisation.
6032+ * This function is called before the first interface is attached.
6033+ *
6034+ * @stop: Handler that 802.15.4 module calls for device cleanup
6035+ * This function is called after the last interface is removed.
6036+ *
6037+ * @xmit: Handler that 802.15.4 module calls for each transmitted frame.
6038+ * skb cntains the buffer starting from the IEEE 802.15.4 header.
6039+ * The low-level driver should send the frame based on available
6040+ * configuration.
6041+ * This function should return zero or negative errno.
6042+ * Called with pib_lock held.
6043+ *
6044+ * @ed: Handler that 802.15.4 module calls for Energy Detection.
6045+ * This function should place the value for detected energy
6046+ * (usually device-dependant) in the level pointer and return
6047+ * either zero or negative errno.
6048+ * Called with pib_lock held.
6049+ *
6050+ * @set_channel: Set radio for listening on specific channel.
6051+ * Set the device for listening on specified channel.
6052+ * Returns either zero, or negative errno.
6053+ * Called with pib_lock held.
6054+ *
6055+ * @set_hw_addr_filt: Set radio for listening on specific address.
6056+ * Set the device for listening on specified address.
6057+ * Returns either zero, or negative errno.
6058+ */
6059+struct ieee802154_ops {
6060+ struct module *owner;
6061+ int (*start)(struct ieee802154_dev *dev);
6062+ void (*stop)(struct ieee802154_dev *dev);
6063+ int (*xmit)(struct ieee802154_dev *dev,
6064+ struct sk_buff *skb);
6065+ int (*ed)(struct ieee802154_dev *dev, u8 *level);
6066+ int (*set_channel)(struct ieee802154_dev *dev,
6067+ int page,
6068+ int channel);
6069+ int (*set_hw_addr_filt)(struct ieee802154_dev *dev,
6070+ struct ieee802154_hw_addr_filt *filt,
6071+ unsigned long changed);
6072+ int (*ieee_addr)(struct ieee802154_dev *dev,
6073+ u8 addr[IEEE802154_ALEN]);
6074+};
6075+
6076+struct ieee802154_dev *ieee802154_alloc_device(size_t priv_size,
6077+ struct ieee802154_ops *ops);
6078+int ieee802154_register_device(struct ieee802154_dev *dev);
6079+void ieee802154_unregister_device(struct ieee802154_dev *dev);
6080+void ieee802154_free_device(struct ieee802154_dev *dev);
6081+
6082+void ieee802154_rx(struct ieee802154_dev *dev, struct sk_buff *skb, u8 lqi);
6083+void ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb,
6084+ u8 lqi);
6085+#endif
6086+
6087diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h
6088index d86fffd..9e119c5 100644
6089--- a/include/net/wpan-phy.h
6090+++ b/include/net/wpan-phy.h
6091@@ -24,17 +24,19 @@
6092 #include <linux/netdevice.h>
6093 #include <linux/mutex.h>
6094 
6095+#define WPAN_NUM_PAGES 32
6096+
6097 struct wpan_phy {
6098     struct mutex pib_lock;
6099 
6100     /*
6101- * This is a PIB according to 802.15.4-2006.
6102+ * This is a PIB acording to 802.15.4-2006.
6103      * We do not provide timing-related variables, as they
6104      * aren't used outside of driver
6105      */
6106     u8 current_channel;
6107     u8 current_page;
6108- u32 channels_supported[32];
6109+ u32 channels_supported[WPAN_NUM_PAGES];
6110     u8 transmit_power;
6111     u8 cca_mode;
6112 
6113@@ -42,7 +44,7 @@ struct wpan_phy {
6114     int idx;
6115 
6116     struct net_device *(*add_iface)(struct wpan_phy *phy,
6117- const char *name);
6118+ const char *name, int type);
6119     void (*del_iface)(struct wpan_phy *phy, struct net_device *dev);
6120 
6121     char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
6122diff --git a/net/Kconfig b/net/Kconfig
6123index a073148..4ab1d57 100644
6124--- a/net/Kconfig
6125+++ b/net/Kconfig
6126@@ -211,6 +211,8 @@ source "net/econet/Kconfig"
6127 source "net/wanrouter/Kconfig"
6128 source "net/phonet/Kconfig"
6129 source "net/ieee802154/Kconfig"
6130+source "net/mac802154/Kconfig"
6131+source "net/zigbee/Kconfig"
6132 source "net/sched/Kconfig"
6133 source "net/dcb/Kconfig"
6134 source "net/dns_resolver/Kconfig"
6135diff --git a/net/Makefile b/net/Makefile
6136index acdde49..1969e93 100644
6137--- a/net/Makefile
6138+++ b/net/Makefile
6139@@ -60,6 +60,7 @@ ifneq ($(CONFIG_DCB),)
6140 obj-y += dcb/
6141 endif
6142 obj-$(CONFIG_IEEE802154) += ieee802154/
6143+obj-$(CONFIG_MAC802154) += mac802154/
6144 
6145 ifeq ($(CONFIG_NET),y)
6146 obj-$(CONFIG_SYSCTL) += sysctl_net.o
6147diff --git a/net/ieee802154/Kconfig b/net/ieee802154/Kconfig
6148index 7dee650..3dea3c1 100644
6149--- a/net/ieee802154/Kconfig
6150+++ b/net/ieee802154/Kconfig
6151@@ -16,3 +16,11 @@ config IEEE802154_6LOWPAN
6152     depends on IEEE802154 && IPV6
6153     ---help---
6154     IPv6 compression over IEEE 802.15.4.
6155+
6156+config IEEE802154_PROTO_DEBUG
6157+ bool "IEEE 802.15.4 protocol stack debugging messages"
6158+ depends on IEEE802154
6159+ default y
6160+ help
6161+ Say Y here to make the IEEE 802.15.4 protocol stack generate
6162+ extensive debugging messages.
6163diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile
6164index d7716d6..e2b6735 100644
6165--- a/net/ieee802154/Makefile
6166+++ b/net/ieee802154/Makefile
6167@@ -3,3 +3,6 @@ obj-$(CONFIG_IEEE802154_6LOWPAN) += 6lowpan.o
6168 
6169 ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o wpan-class.o
6170 af_802154-y := af_ieee802154.o raw.o dgram.o
6171+
6172+ccflags-$(CONFIG_IEEE802154_PROTO_DEBUG) += -DDEBUG
6173+ccflags-y += -Wall
6174diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c
6175index faecf64..1f28f3a 100644
6176--- a/net/ieee802154/dgram.c
6177+++ b/net/ieee802154/dgram.c
6178@@ -130,8 +130,7 @@ static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg)
6179     switch (cmd) {
6180     case SIOCOUTQ:
6181     {
6182- int amount = sk_wmem_alloc_get(sk);
6183-
6184+ int amount = atomic_read(&sk->sk_wmem_alloc);
6185         return put_user(amount, (int __user *)arg);
6186     }
6187 
6188diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
6189index aadec42..e78d6c6 100644
6190--- a/net/ieee802154/ieee802154.h
6191+++ b/net/ieee802154/ieee802154.h
6192@@ -21,6 +21,10 @@
6193 int __init ieee802154_nl_init(void);
6194 void __exit ieee802154_nl_exit(void);
6195 
6196+#include <net/netlink.h>
6197+
6198+extern const struct nla_policy ieee802154_policy[];
6199+
6200 #define IEEE802154_OP(_cmd, _func) \
6201     { \
6202         .cmd = _cmd, \
6203diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
6204index adaf462..1d23aa6 100644
6205--- a/net/ieee802154/nl-mac.c
6206+++ b/net/ieee802154/nl-mac.c
6207@@ -263,7 +263,7 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 pid,
6208     if (!hdr)
6209         goto out;
6210 
6211- phy = ieee802154_mlme_ops(dev)->get_phy(dev);
6212+ phy = simple_mlme_ops(dev)->get_phy(dev);
6213     BUG_ON(!phy);
6214 
6215     NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
6216diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
6217index c64a38d..76ef7a3 100644
6218--- a/net/ieee802154/nl-phy.c
6219+++ b/net/ieee802154/nl-phy.c
6220@@ -57,7 +57,7 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 pid,
6221 
6222     NLA_PUT_U8(msg, IEEE802154_ATTR_PAGE, phy->current_page);
6223     NLA_PUT_U8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel);
6224- for (i = 0; i < 32; i++) {
6225+ for (i = 0; i < WPAN_NUM_PAGES; i++) {
6226         if (phy->channels_supported[i])
6227             buf[pages++] = phy->channels_supported[i] | (i << 27);
6228     }
6229@@ -179,6 +179,7 @@ static int ieee802154_add_iface(struct sk_buff *skb,
6230     const char *devname;
6231     int rc = -ENOBUFS;
6232     struct net_device *dev;
6233+ int type = IEEE802154_DEV_WPAN;
6234 
6235     pr_debug("%s\n", __func__);
6236 
6237@@ -201,6 +202,19 @@ static int ieee802154_add_iface(struct sk_buff *skb,
6238     if (strlen(devname) >= IFNAMSIZ)
6239         return -ENAMETOOLONG;
6240 
6241+ if (info->attrs[IEEE802154_ATTR_HW_ADDR] &&
6242+ nla_len(info->attrs[IEEE802154_ATTR_HW_ADDR]) !=
6243+ IEEE802154_ADDR_LEN) {
6244+ return -EINVAL;
6245+ }
6246+
6247+ if (info->attrs[IEEE802154_ATTR_DEV_TYPE]) {
6248+ type = nla_get_u8(info->attrs[IEEE802154_ATTR_DEV_TYPE]);
6249+ if (type > __IEEE802154_DEV_MAX) {
6250+ return -EINVAL;
6251+ }
6252+ }
6253+
6254     phy = wpan_phy_find(name);
6255     if (!phy)
6256         return -ENODEV;
6257@@ -221,7 +235,7 @@ static int ieee802154_add_iface(struct sk_buff *skb,
6258         goto nla_put_failure;
6259     }
6260 
6261- dev = phy->add_iface(phy, devname);
6262+ dev = phy->add_iface(phy, devname, type);
6263     if (IS_ERR(dev)) {
6264         rc = PTR_ERR(dev);
6265         goto nla_put_failure;
6266@@ -288,7 +302,7 @@ static int ieee802154_del_iface(struct sk_buff *skb,
6267     if (!dev)
6268         return -ENODEV;
6269 
6270- phy = ieee802154_mlme_ops(dev)->get_phy(dev);
6271+ phy = simple_mlme_ops(dev)->get_phy(dev);
6272     BUG_ON(!phy);
6273 
6274     rc = -EINVAL;
6275diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c
6276index 6adda4d..235cd65 100644
6277--- a/net/ieee802154/nl_policy.c
6278+++ b/net/ieee802154/nl_policy.c
6279@@ -28,6 +28,7 @@ const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = {
6280     [IEEE802154_ATTR_DEV_NAME] = { .type = NLA_STRING, },
6281     [IEEE802154_ATTR_DEV_INDEX] = { .type = NLA_U32, },
6282     [IEEE802154_ATTR_PHY_NAME] = { .type = NLA_STRING, },
6283+ [IEEE802154_ATTR_DEV_TYPE] = { .type = NLA_U8, },
6284 
6285     [IEEE802154_ATTR_STATUS] = { .type = NLA_U8, },
6286     [IEEE802154_ATTR_SHORT_ADDR] = { .type = NLA_U16, },
6287diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
6288index 1627ef2..380fe1a 100644
6289--- a/net/ieee802154/wpan-class.c
6290+++ b/net/ieee802154/wpan-class.c
6291@@ -56,7 +56,7 @@ static ssize_t channels_supported_show(struct device *dev,
6292     int i, len = 0;
6293 
6294     mutex_lock(&phy->pib_lock);
6295- for (i = 0; i < 32; i++) {
6296+ for (i = 0; i < WPAN_NUM_PAGES; i++) {
6297         ret = snprintf(buf + len, PAGE_SIZE - len,
6298                 "%#09x\n", phy->channels_supported[i]);
6299         if (ret < 0)
6300diff --git a/net/mac802154/Kconfig b/net/mac802154/Kconfig
6301new file mode 100644
6302index 0000000..32e63bc
6303--- /dev/null
6304+++ b/net/mac802154/Kconfig
6305@@ -0,0 +1,24 @@
6306+config MAC802154
6307+ tristate "Generic IEEE 802.15.4 Soft Networking Stack (mac802154)"
6308+ depends on IEEE802154 && EXPERIMENTAL
6309+ select CRC_CCITT
6310+ ---help---
6311+ This option enables the hardware independent IEEE 802.15.4
6312+ networking stack for SoftMAC devices (the ones implementing
6313+ only PHY level of IEEE 802.15.4 standard).
6314+
6315+ Note: this implementation is neither certified, nor feature
6316+ complete! We do not guarantee that it is compatible w/ other
6317+ implementations, etc.
6318+
6319+ If you plan to use HardMAC IEEE 802.15.4 devices, you can
6320+ say N here. Alternatievly you can say M to compile it as
6321+ module.
6322+
6323+config MAC802154_DEBUG
6324+ bool "IEEE 802.15.4 SoftMAC debugging messages"
6325+ depends on MAC802154
6326+ default y
6327+ help
6328+ Say Y here to make the IEEE 802.15.4 SoftMAC generate extensive
6329+ debugging messages.
6330diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile
6331new file mode 100644
6332index 0000000..d76fabb
6333--- /dev/null
6334+++ b/net/mac802154/Makefile
6335@@ -0,0 +1,6 @@
6336+obj-$(CONFIG_MAC802154) += mac802154.o
6337+mac802154-objs := rx.o tx.o main.o monitor.o wpan.o mac_cmd.o scan.o mib.o \
6338+ beacon.o beacon_hash.o smac.o
6339+
6340+ccflags-$(CONFIG_MAC802154_DEBUG) += -DDEBUG
6341+ccflags-y += -Wall
6342diff --git a/net/mac802154/beacon.c b/net/mac802154/beacon.c
6343new file mode 100644
6344index 0000000..6b0d327
6345--- /dev/null
6346+++ b/net/mac802154/beacon.c
6347@@ -0,0 +1,282 @@
6348+/*
6349+ * MAC beacon interface
6350+ *
6351+ * Copyright 2007, 2008 Siemens AG
6352+ *
6353+ * This program is free software; you can redistribute it and/or modify
6354+ * it under the terms of the GNU General Public License version 2
6355+ * as published by the Free Software Foundation.
6356+ *
6357+ * This program is distributed in the hope that it will be useful,
6358+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6359+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6360+ * GNU General Public License for more details.
6361+ *
6362+ * You should have received a copy of the GNU General Public License along
6363+ * with this program; if not, write to the Free Software Foundation, Inc.,
6364+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
6365+ *
6366+ * Written by:
6367+ * Sergey Lapin <slapin@ossfans.org>
6368+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
6369+ */
6370+
6371+#include <linux/kernel.h>
6372+#include <linux/slab.h>
6373+#include <linux/if_arp.h>
6374+#include <linux/list.h>
6375+
6376+#include <net/af_ieee802154.h>
6377+#include <net/nl802154.h>
6378+#include <net/mac802154.h>
6379+#include <net/ieee802154.h>
6380+#include <net/ieee802154_netdev.h>
6381+
6382+#include "mac802154.h"
6383+#include "beacon_hash.h"
6384+
6385+/* Beacon frame format per specification is the followinf:
6386+ * Standard MAC frame header:
6387+ * FC (2) SEQ (1)
6388+ * Addressing (4-20)
6389+ * Beacon fields:
6390+ * <Superframe specification> (2)
6391+ * <GTS> (?)
6392+ * <Pending address> (?)
6393+ * <Beacon payload> (?)
6394+ * FCS (2)
6395+ *
6396+ * Superframe specification:
6397+ * bit Value
6398+ * 15 Association permit
6399+ * 14 PAN coordinator
6400+ * 13 Reserved
6401+ * 12 Battery life extension
6402+ * 8-11 Final CAP slot
6403+ * 4-7 Superframe order
6404+ * 0-3 Beacon order
6405+ *
6406+ * GTS:
6407+ * <GTS specification> (1)
6408+ * <GTS directions> (0-1)
6409+ * <GTS list> (?)
6410+ *
6411+ * Pending address:
6412+ * <Pending address specification> (1)
6413+ * <Pending address list (?)
6414+ *
6415+ * GTS specification:
6416+ * bit Value
6417+ * 7 GTS permit
6418+ * 3-6 Reserved
6419+ * 0-2 GTS descriptor count
6420+ *
6421+ * Pending address specification:
6422+ * bit Value
6423+ * 7 Reserved
6424+ * 4-6 Number of extended addresses pendinf
6425+ * 3 Reserved
6426+ * 0-2 Number of short addresses pending
6427+ * */
6428+
6429+#define IEEE802154_BEACON_SF_BO_BEACONLESS (15 << 0)
6430+#define IEEE802154_BEACON_SF_SO(x) ((x & 0xf) << 4)
6431+#define IEEE802154_BEACON_SF_SO_INACTIVE IEEE802154_BEACON_SF_SO(15)
6432+#define IEEE802154_BEACON_SF_PANCOORD (1 << 14)
6433+#define IEEE802154_BEACON_SF_CANASSOC (1 << 15)
6434+#define IEEE802154_BEACON_GTS_COUNT(x) (x << 0)
6435+#define IEEE802154_BEACON_GTS_PERMIT (1 << 7)
6436+#define IEEE802154_BEACON_PA_SHORT(x) ((x & 7) << 0)
6437+#define IEEE802154_BEACON_PA_LONG(x) ((x & 7) << 4)
6438+
6439+/* Flags parameter */
6440+#define IEEE802154_BEACON_FLAG_PANCOORD (1 << 0)
6441+#define IEEE802154_BEACON_FLAG_CANASSOC (1 << 1)
6442+#define IEEE802154_BEACON_FLAG_GTSPERMIT (1 << 2)
6443+
6444+struct mac802154_address_list {
6445+ struct list_head list;
6446+ struct ieee802154_addr addr;
6447+};
6448+
6449+/* Per spec; optimizations are needed */
6450+struct mac802154_pandsc {
6451+ struct list_head list;
6452+ struct ieee802154_addr addr; /* Contains panid */
6453+ int channel;
6454+ u16 sf;
6455+ bool gts_permit;
6456+ u8 lqi;
6457+/* FIXME: Aging of stored PAN descriptors is not decided yet,
6458+ * because no PAN descriptor storage is implemented yet */
6459+ u32 timestamp;
6460+};
6461+
6462+/*
6463+ * @dev device
6464+ * @addr destination address
6465+ * @saddr source address
6466+ * @buf beacon payload
6467+ * @len beacon payload size
6468+ * @pan_coord - if we're PAN coordinator while sending this frame
6469+ * @gts_permit - wheather we allow GTS requests
6470+ * @al address list to be provided in beacon
6471+ *
6472+ * TODO:
6473+ * For a beacon frame, the sequence number field shall specify a BSN.
6474+ * Each coordinator shall store its current
6475+ * BSN value in the MAC PIB attribute macBSN and initialize it to
6476+ * a random value.
6477+ * The algorithm for choosing a random number is out of the scope
6478+ * of this standard. The coordinator shall copy the value of the macBSN
6479+ * attribute into the sequence number field of a beacon frame,
6480+ * each time one is generated, and shall then increment macBSN by one.
6481+ *
6482+*/
6483+
6484+
6485+int mac802154_send_beacon(struct net_device *dev,
6486+ struct ieee802154_addr *saddr,
6487+ u16 pan_id, const u8 *buf, int len,
6488+ int flags, struct list_head *al)
6489+{
6490+ struct sk_buff *skb;
6491+ int err;
6492+ u16 sf;
6493+ u8 gts;
6494+ u8 pa_spec;
6495+ int addr16_cnt;
6496+ int addr64_cnt;
6497+ struct ieee802154_addr addr;
6498+
6499+ BUG_ON(dev->type != ARPHRD_IEEE802154);
6500+
6501+ skb = alloc_skb(LL_ALLOCATED_SPACE(dev) + len, GFP_ATOMIC);
6502+ if (!skb)
6503+ return -ENOMEM;
6504+
6505+ skb_reserve(skb, LL_RESERVED_SPACE(dev));
6506+
6507+ skb_reset_network_header(skb);
6508+
6509+ mac_cb(skb)->flags = IEEE802154_FC_TYPE_BEACON;
6510+ mac_cb(skb)->seq = ieee802154_mlme_ops(dev)->get_bsn(dev);
6511+
6512+ addr.addr_type = IEEE802154_ADDR_NONE;
6513+ err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &addr, saddr, len);
6514+ if (err < 0) {
6515+ kfree_skb(skb);
6516+ return err;
6517+ }
6518+ skb_reset_mac_header(skb);
6519+
6520+ /* Superframe */
6521+ sf = IEEE802154_BEACON_SF_BO_BEACONLESS;
6522+ sf |= IEEE802154_BEACON_SF_SO_INACTIVE;
6523+ if (flags & IEEE802154_BEACON_FLAG_PANCOORD)
6524+ sf |= IEEE802154_BEACON_SF_PANCOORD;
6525+
6526+ if (flags & IEEE802154_BEACON_FLAG_CANASSOC)
6527+ sf |= IEEE802154_BEACON_SF_CANASSOC;
6528+ memcpy(skb_put(skb, sizeof(sf)), &sf, sizeof(sf));
6529+
6530+ /* TODO GTS */
6531+ gts = 0;
6532+
6533+ if (flags & IEEE802154_BEACON_FLAG_GTSPERMIT)
6534+ gts |= IEEE802154_BEACON_GTS_PERMIT;
6535+ memcpy(skb_put(skb, sizeof(gts)), &gts, sizeof(gts));
6536+
6537+ /* FIXME pending address */
6538+ addr16_cnt = 0;
6539+ addr64_cnt = 0;
6540+
6541+ pa_spec = IEEE802154_BEACON_PA_LONG(addr64_cnt) |
6542+ IEEE802154_BEACON_PA_SHORT(addr16_cnt);
6543+ memcpy(skb_put(skb, sizeof(pa_spec)), &pa_spec, sizeof(pa_spec));
6544+
6545+ memcpy(skb_put(skb, len), buf, len);
6546+
6547+ skb->dev = dev;
6548+ skb->protocol = htons(ETH_P_IEEE802154);
6549+
6550+ return dev_queue_xmit(skb);
6551+}
6552+
6553+/* at entry to this function we need skb->data to point to start
6554+ * of beacon field and MAC frame already parsed into MAC_CB */
6555+
6556+static int parse_beacon_frame(struct sk_buff *skb, u8 *buf,
6557+ int *flags, struct list_head *al)
6558+{
6559+ int offt = 0;
6560+ u8 gts_spec;
6561+ u8 pa_spec;
6562+ struct mac802154_pandsc *pd;
6563+ u16 sf = skb->data[0] + (skb->data[1] << 8);
6564+
6565+ pd = kzalloc(sizeof(struct mac802154_pandsc), GFP_KERNEL);
6566+
6567+ /* Filling-up pre-parsed values */
6568+ pd->lqi = mac_cb(skb)->lqi;
6569+ pd->sf = sf;
6570+ /* FIXME: make sure we do it right */
6571+ memcpy(&pd->addr, &mac_cb(skb)->da, sizeof(struct ieee802154_addr));
6572+
6573+ /* Supplying our nitifiers with data */
6574+ ieee802154_nl_beacon_indic(skb->dev, pd->addr.pan_id,
6575+ pd->addr.short_addr);
6576+ /* FIXME: We don't cache PAN descriptors yet */
6577+ kfree(pd);
6578+
6579+ offt += 2;
6580+ gts_spec = skb->data[offt++];
6581+ /* FIXME !!! */
6582+ if ((gts_spec & 7) != 0) {
6583+ pr_debug("We still don't parse GTS part properly");
6584+ return -ENOTSUPP;
6585+ }
6586+ pa_spec = skb->data[offt++];
6587+ /* FIXME !!! */
6588+ if (pa_spec != 0) {
6589+ pr_debug("We still don't parse PA part properly");
6590+ return -ENOTSUPP;
6591+ }
6592+
6593+ *flags = 0;
6594+
6595+ if (sf & IEEE802154_BEACON_SF_PANCOORD)
6596+ *flags |= IEEE802154_BEACON_FLAG_PANCOORD;
6597+
6598+ if (sf & IEEE802154_BEACON_SF_CANASSOC)
6599+ *flags |= IEEE802154_BEACON_FLAG_CANASSOC;
6600+ BUG_ON(skb->len - offt < 0);
6601+ /* FIXME */
6602+ if (buf && (skb->len - offt > 0))
6603+ memcpy(buf, skb->data + offt, skb->len - offt);
6604+ return 0;
6605+}
6606+
6607+int mac802154_process_beacon(struct net_device *dev,
6608+ struct sk_buff *skb)
6609+{
6610+ int flags;
6611+ int ret;
6612+ ret = parse_beacon_frame(skb, NULL, &flags, NULL);
6613+
6614+ /* Here we have cb->sa = coordinator address, and PAN address */
6615+
6616+ if (ret < 0) {
6617+ ret = NET_RX_DROP;
6618+ goto fail;
6619+ }
6620+ dev_dbg(&dev->dev, "got beacon from pan %04x\n",
6621+ mac_cb(skb)->sa.pan_id);
6622+ mac802154_beacon_hash_add(&mac_cb(skb)->sa);
6623+ mac802154_beacon_hash_dump();
6624+ ret = NET_RX_SUCCESS;
6625+fail:
6626+ kfree_skb(skb);
6627+ return ret;
6628+}
6629+
6630diff --git a/net/mac802154/beacon_hash.c b/net/mac802154/beacon_hash.c
6631new file mode 100644
6632index 0000000..97fb987
6633--- /dev/null
6634+++ b/net/mac802154/beacon_hash.c
6635@@ -0,0 +1,106 @@
6636+/*
6637+ * MAC beacon hash storage
6638+ *
6639+ * Copyright 2007, 2008 Siemens AG
6640+ *
6641+ * This program is free software; you can redistribute it and/or modify
6642+ * it under the terms of the GNU General Public License version 2
6643+ * as published by the Free Software Foundation.
6644+ *
6645+ * This program is distributed in the hope that it will be useful,
6646+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6647+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6648+ * GNU General Public License for more details.
6649+ *
6650+ * You should have received a copy of the GNU General Public License along
6651+ * with this program; if not, write to the Free Software Foundation, Inc.,
6652+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
6653+ *
6654+ * Written by:
6655+ * Sergey Lapin <slapin@ossfans.org>
6656+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
6657+ */
6658+
6659+#include <linux/slab.h>
6660+#include <linux/list.h>
6661+#include <linux/spinlock.h>
6662+
6663+#include <net/af_ieee802154.h>
6664+
6665+#include "beacon_hash.h"
6666+
6667+static struct hlist_head beacon_hash[IEEE802154_BEACON_HTABLE_SIZE];
6668+static DEFINE_SPINLOCK(beacon_hash_lock);
6669+
6670+static int beacon_hashfn(struct ieee802154_addr *coord_addr, u16 pan_addr)
6671+{
6672+ return pan_addr % IEEE802154_BEACON_HTABLE_SIZE;
6673+}
6674+
6675+static void __beacon_add_node(struct ieee802154_addr *coord_addr, u16 pan_addr)
6676+{
6677+ struct beacon_node *node =
6678+ kzalloc(sizeof(struct beacon_node), GFP_KERNEL);
6679+ struct hlist_head *list =
6680+ &beacon_hash[beacon_hashfn(coord_addr, pan_addr)];
6681+ memcpy(&node->coord_addr, coord_addr, sizeof(struct ieee802154_addr));
6682+ node->pan_addr = pan_addr;
6683+ INIT_HLIST_NODE(&node->list);
6684+ hlist_add_head(&node->list, list);
6685+}
6686+
6687+struct beacon_node *mac802154_beacon_find_pan(
6688+ struct ieee802154_addr *coord_addr, u16 pan_addr)
6689+{
6690+ struct hlist_head *list;
6691+ struct hlist_node *tmp;
6692+ list = &beacon_hash[beacon_hashfn(coord_addr, pan_addr)];
6693+ if (hlist_empty(list))
6694+ return NULL;
6695+ hlist_for_each(tmp, list) {
6696+ struct beacon_node *entry =
6697+ hlist_entry(tmp, struct beacon_node, list);
6698+ if (entry->pan_addr == pan_addr)
6699+ return entry;
6700+ }
6701+ return NULL;
6702+}
6703+
6704+void mac802154_beacon_hash_add(struct ieee802154_addr *coord_addr)
6705+{
6706+ if (!mac802154_beacon_find_pan(coord_addr, coord_addr->pan_id)) {
6707+ spin_lock(&beacon_hash_lock);
6708+ __beacon_add_node(coord_addr, coord_addr->pan_id);
6709+ spin_unlock(&beacon_hash_lock);
6710+ }
6711+}
6712+
6713+void mac802154_beacon_hash_del(struct ieee802154_addr *coord_addr)
6714+{
6715+ struct beacon_node *entry = mac802154_beacon_find_pan(coord_addr,
6716+ coord_addr->pan_id);
6717+ if (!entry)
6718+ return;
6719+ spin_lock(&beacon_hash_lock);
6720+ hlist_del(&entry->list);
6721+ spin_unlock(&beacon_hash_lock);
6722+ kfree(entry);
6723+}
6724+
6725+void mac802154_beacon_hash_dump(void)
6726+{
6727+ int i;
6728+ struct hlist_node *tmp;
6729+ pr_debug("beacon hash dump begin\n");
6730+ spin_lock(&beacon_hash_lock);
6731+ for (i = 0; i < IEEE802154_BEACON_HTABLE_SIZE; i++) {
6732+ struct beacon_node *entry;
6733+ hlist_for_each(tmp, &beacon_hash[i]) {
6734+ entry = hlist_entry(tmp, struct beacon_node, list);
6735+ pr_debug("PAN: %04x\n", entry->pan_addr);
6736+ }
6737+ }
6738+ spin_unlock(&beacon_hash_lock);
6739+ pr_debug("beacon hash dump end\n");
6740+}
6741+
6742diff --git a/net/mac802154/beacon_hash.h b/net/mac802154/beacon_hash.h
6743new file mode 100644
6744index 0000000..a732aa5
6745--- /dev/null
6746+++ b/net/mac802154/beacon_hash.h
6747@@ -0,0 +1,41 @@
6748+/*
6749+ * MAC beacon hash storage
6750+ *
6751+ * Copyright 2007, 2008 Siemens AG
6752+ *
6753+ * This program is free software; you can redistribute it and/or modify
6754+ * it under the terms of the GNU General Public License version 2
6755+ * as published by the Free Software Foundation.
6756+ *
6757+ * This program is distributed in the hope that it will be useful,
6758+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6759+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6760+ * GNU General Public License for more details.
6761+ *
6762+ * You should have received a copy of the GNU General Public License along
6763+ * with this program; if not, write to the Free Software Foundation, Inc.,
6764+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
6765+ *
6766+ * Written by:
6767+ * Sergey Lapin <slapin@ossfans.org>
6768+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
6769+ */
6770+
6771+#ifndef IEEE802154_BEACON_HASH_H
6772+#define IEEE802154_BEACON_HASH_H
6773+
6774+#define IEEE802154_BEACON_HTABLE_SIZE 256
6775+
6776+struct beacon_node {
6777+ struct hlist_node list;
6778+ struct ieee802154_addr coord_addr;
6779+ u16 pan_addr;
6780+};
6781+struct beacon_node *mac802154_beacon_find_pan(
6782+ struct ieee802154_addr *coord_addr,
6783+ u16 pan_addr);
6784+void mac802154_beacon_hash_add(struct ieee802154_addr *coord_addr);
6785+void mac802154_beacon_hash_del(struct ieee802154_addr *coord_addr);
6786+void mac802154_beacon_hash_dump(void);
6787+#endif
6788+
6789diff --git a/net/mac802154/mac802154.h b/net/mac802154/mac802154.h
6790new file mode 100644
6791index 0000000..f35245d
6792--- /dev/null
6793+++ b/net/mac802154/mac802154.h
6794@@ -0,0 +1,126 @@
6795+/*
6796+ * Copyright (C) 2007, 2008, 2009 Siemens AG
6797+ *
6798+ * This program is free software; you can redistribute it and/or modify
6799+ * it under the terms of the GNU General Public License version 2
6800+ * as published by the Free Software Foundation.
6801+ *
6802+ * This program is distributed in the hope that it will be useful,
6803+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6804+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6805+ * GNU General Public License for more details.
6806+ *
6807+ * You should have received a copy of the GNU General Public License along
6808+ * with this program; if not, write to the Free Software Foundation, Inc.,
6809+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
6810+ *
6811+ * Written by:
6812+ * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
6813+ * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
6814+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
6815+ */
6816+#ifndef MAC802154_H
6817+#define MAC802154_H
6818+
6819+#include <linux/spinlock.h>
6820+
6821+struct mac802154_priv {
6822+ struct ieee802154_dev hw;
6823+ struct ieee802154_ops *ops;
6824+
6825+ struct wpan_phy *phy;
6826+
6827+ int open_count;
6828+ /* As in mac80211 slaves list is modified:
6829+ * 1) under the RTNL
6830+ * 2) protected by slaves_mtx;
6831+ * 3) in an RCU manner
6832+ *
6833+ * So atomic readers can use any of this protection methods
6834+ */
6835+ struct list_head slaves;
6836+ struct mutex slaves_mtx;
6837+ /* This one is used for scanning and other
6838+ * jobs not to be interfered with serial driver */
6839+ struct workqueue_struct *dev_workqueue;
6840+
6841+ /*
6842+ * These flags are also modified under slaves_mtx and RTNL,
6843+ * so you can read them using any of protection methods.
6844+ */
6845+ /* SoftMAC device is registered and running. One can add subinterfaces. */
6846+ unsigned running: 1;
6847+};
6848+
6849+#define mac802154_to_priv(_hw) container_of(_hw, struct mac802154_priv, hw)
6850+
6851+struct mac802154_wpan_mib {
6852+ spinlock_t mib_lock;
6853+
6854+ u16 pan_id;
6855+ u16 short_addr;
6856+
6857+ u8 chan;
6858+ u8 page;
6859+
6860+ /* MAC BSN field */
6861+ u8 bsn;
6862+ /* MAC BSN field */
6863+ u8 dsn;
6864+};
6865+
6866+struct mac802154_sub_if_data {
6867+ struct list_head list; /* the ieee802154_priv->slaves list */
6868+
6869+ struct mac802154_priv *hw;
6870+ struct net_device *dev;
6871+
6872+ int type;
6873+
6874+ spinlock_t mib_lock;
6875+
6876+ u16 pan_id;
6877+ u16 short_addr;
6878+
6879+ u8 chan;
6880+ u8 page;
6881+
6882+ /* MAC BSN field */
6883+ u8 bsn;
6884+ /* MAC DSN field */
6885+ u8 dsn;
6886+};
6887+
6888+struct ieee802154_addr;
6889+
6890+extern struct ieee802154_mlme_ops mac802154_mlme_wpan;
6891+extern struct simple_mlme_ops mac802154_mlme_simple;
6892+
6893+int mac802154_mlme_scan_req(struct net_device *dev,
6894+ u8 type, u32 channels, u8 page, u8 duration);
6895+
6896+int mac802154_process_cmd(struct net_device *dev, struct sk_buff *skb);
6897+int mac802154_process_beacon(struct net_device *dev, struct sk_buff *skb);
6898+int mac802154_send_beacon(struct net_device *dev,
6899+ struct ieee802154_addr *saddr,
6900+ u16 pan_id, const u8 *buf, int len,
6901+ int flags, struct list_head *al);
6902+int mac802154_send_beacon_req(struct net_device *dev);
6903+
6904+struct mac802154_priv *mac802154_slave_get_priv(struct net_device *dev);
6905+
6906+void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb);
6907+void mac802154_monitor_setup(struct net_device *dev);
6908+
6909+void mac802154_smacs_rx(struct mac802154_priv *priv, struct sk_buff *skb);
6910+void mac802154_smac_setup(struct net_device *dev);
6911+
6912+void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb);
6913+void mac802154_wpan_setup(struct net_device *dev);
6914+
6915+int mac802154_slave_open(struct net_device *dev);
6916+int mac802154_slave_close(struct net_device *dev);
6917+
6918+netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb,
6919+ u8 page, u8 chan);
6920+#endif
6921diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c
6922new file mode 100644
6923index 0000000..c763585
6924--- /dev/null
6925+++ b/net/mac802154/mac_cmd.c
6926@@ -0,0 +1,362 @@
6927+/*
6928+ * MAC commands interface
6929+ *
6930+ * Copyright 2007, 2008 Siemens AG
6931+ *
6932+ * This program is free software; you can redistribute it and/or modify
6933+ * it under the terms of the GNU General Public License version 2
6934+ * as published by the Free Software Foundation.
6935+ *
6936+ * This program is distributed in the hope that it will be useful,
6937+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6938+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6939+ * GNU General Public License for more details.
6940+ *
6941+ * You should have received a copy of the GNU General Public License along
6942+ * with this program; if not, write to the Free Software Foundation, Inc.,
6943+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
6944+ *
6945+ * Written by:
6946+ * Sergey Lapin <slapin@ossfans.org>
6947+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
6948+ */
6949+
6950+#include <linux/kernel.h>
6951+#include <linux/skbuff.h>
6952+#include <linux/if_arp.h>
6953+#include <net/af_ieee802154.h>
6954+#include <net/mac802154.h>
6955+#include <net/ieee802154.h>
6956+#include <net/ieee802154_netdev.h>
6957+#include <net/nl802154.h>
6958+
6959+#include "mac802154.h"
6960+#include "mib.h"
6961+
6962+static int mac802154_cmd_beacon_req(struct sk_buff *skb)
6963+{
6964+ struct ieee802154_addr saddr; /* jeez */
6965+ int flags = 0;
6966+ u16 shortaddr;
6967+
6968+ if (skb->len != 1)
6969+ return -EINVAL;
6970+
6971+ if (skb->pkt_type != PACKET_BROADCAST)
6972+ return 0;
6973+
6974+ /* Checking if we're really PAN coordinator
6975+ * before sending beacons */
6976+ if (!(skb->dev->priv_flags & IFF_IEEE802154_COORD))
6977+ return 0;
6978+
6979+ if (mac_cb(skb)->sa.addr_type != IEEE802154_ADDR_NONE ||
6980+ mac_cb(skb)->da.addr_type != IEEE802154_ADDR_SHORT ||
6981+ mac_cb(skb)->da.pan_id != IEEE802154_PANID_BROADCAST ||
6982+ mac_cb(skb)->da.short_addr != IEEE802154_ADDR_BROADCAST)
6983+ return -EINVAL;
6984+
6985+ shortaddr = mac802154_dev_get_short_addr(skb->dev);
6986+ if (shortaddr != IEEE802154_ADDR_BROADCAST &&
6987+ shortaddr != IEEE802154_ADDR_UNDEF) {
6988+ saddr.addr_type = IEEE802154_ADDR_SHORT;
6989+ saddr.short_addr = shortaddr;
6990+ } else {
6991+ saddr.addr_type = IEEE802154_ADDR_LONG;
6992+ memcpy(saddr.hwaddr, skb->dev->dev_addr, IEEE802154_ADDR_LEN);
6993+ }
6994+ saddr.pan_id = mac802154_dev_get_pan_id(skb->dev);
6995+
6996+
6997+ /* 7 bytes of MHR and 1 byte of command frame identifier
6998+ * We have no information in this command to proceed with.
6999+ * we need to submit beacon as answer to this. */
7000+
7001+ return mac802154_send_beacon(skb->dev, &saddr,
7002+ ieee802154_mlme_ops(skb->dev)->get_pan_id(skb->dev),
7003+ NULL, 0, flags, NULL);
7004+}
7005+
7006+static int mac802154_cmd_assoc_req(struct sk_buff *skb)
7007+{
7008+ u8 cap;
7009+
7010+ if (skb->len != 2)
7011+ return -EINVAL;
7012+
7013+ if (skb->pkt_type != PACKET_HOST)
7014+ return 0;
7015+
7016+ if (mac_cb(skb)->sa.addr_type != IEEE802154_ADDR_LONG ||
7017+ mac_cb(skb)->sa.pan_id != IEEE802154_PANID_BROADCAST)
7018+ return -EINVAL;
7019+
7020+ /*
7021+ * FIXME: check that we allow incoming ASSOC requests
7022+ * by consulting MIB
7023+ */
7024+
7025+ cap = skb->data[1];
7026+
7027+ return ieee802154_nl_assoc_indic(skb->dev, &mac_cb(skb)->sa, cap);
7028+}
7029+
7030+static int mac802154_cmd_assoc_resp(struct sk_buff *skb)
7031+{
7032+ u8 status;
7033+ u16 short_addr;
7034+
7035+ if (skb->len != 4)
7036+ return -EINVAL;
7037+
7038+ if (skb->pkt_type != PACKET_HOST)
7039+ return 0;
7040+
7041+ if (mac_cb(skb)->sa.addr_type != IEEE802154_ADDR_LONG ||
7042+ mac_cb(skb)->sa.addr_type != IEEE802154_ADDR_LONG ||
7043+ !(mac_cb(skb)->flags & MAC_CB_FLAG_INTRAPAN))
7044+ return -EINVAL;
7045+
7046+ /* FIXME: check that we requested association ? */
7047+
7048+ status = skb->data[3];
7049+ short_addr = skb->data[1] | (skb->data[2] << 8);
7050+ pr_info("Received ASSOC-RESP status %x, addr %hx\n", status,
7051+ short_addr);
7052+ if (status) {
7053+ mac802154_dev_set_short_addr(skb->dev,
7054+ IEEE802154_ADDR_BROADCAST);
7055+ mac802154_dev_set_pan_id(skb->dev,
7056+ IEEE802154_PANID_BROADCAST);
7057+ } else
7058+ mac802154_dev_set_short_addr(skb->dev, short_addr);
7059+
7060+ return ieee802154_nl_assoc_confirm(skb->dev, short_addr, status);
7061+}
7062+
7063+static int mac802154_cmd_disassoc_notify(struct sk_buff *skb)
7064+{
7065+ u8 reason;
7066+
7067+ if (skb->len != 2)
7068+ return -EINVAL;
7069+
7070+ if (skb->pkt_type != PACKET_HOST)
7071+ return 0;
7072+
7073+ if (mac_cb(skb)->sa.addr_type != IEEE802154_ADDR_LONG ||
7074+ (mac_cb(skb)->da.addr_type != IEEE802154_ADDR_LONG &&
7075+ mac_cb(skb)->da.addr_type != IEEE802154_ADDR_SHORT) ||
7076+ mac_cb(skb)->sa.pan_id != mac_cb(skb)->da.pan_id)
7077+ return -EINVAL;
7078+
7079+ reason = skb->data[1];
7080+
7081+ /* FIXME: checks if this was our coordinator and the disassoc us */
7082+ /* FIXME: if we device, one should receive ->da and not ->sa */
7083+ /* FIXME: the status should also help */
7084+
7085+ return ieee802154_nl_disassoc_indic(skb->dev, &mac_cb(skb)->sa,
7086+ reason);
7087+}
7088+
7089+int mac802154_process_cmd(struct net_device *dev, struct sk_buff *skb)
7090+{
7091+ u8 cmd;
7092+
7093+ if (skb->len < 1) {
7094+ pr_warning("Uncomplete command frame!\n");
7095+ goto drop;
7096+ }
7097+
7098+ cmd = *(skb->data);
7099+ pr_debug("Command %02x on device %s\n", cmd, dev->name);
7100+
7101+ switch (cmd) {
7102+ case IEEE802154_CMD_ASSOCIATION_REQ:
7103+ mac802154_cmd_assoc_req(skb);
7104+ break;
7105+ case IEEE802154_CMD_ASSOCIATION_RESP:
7106+ mac802154_cmd_assoc_resp(skb);
7107+ break;
7108+ case IEEE802154_CMD_DISASSOCIATION_NOTIFY:
7109+ mac802154_cmd_disassoc_notify(skb);
7110+ break;
7111+ case IEEE802154_CMD_BEACON_REQ:
7112+ mac802154_cmd_beacon_req(skb);
7113+ break;
7114+ default:
7115+ pr_debug("Frame type is not supported yet\n");
7116+ goto drop;
7117+ }
7118+
7119+
7120+ kfree_skb(skb);
7121+ return NET_RX_SUCCESS;
7122+
7123+drop:
7124+ kfree_skb(skb);
7125+ return NET_RX_DROP;
7126+}
7127+
7128+static int mac802154_send_cmd(struct net_device *dev,
7129+ struct ieee802154_addr *addr, struct ieee802154_addr *saddr,
7130+ const u8 *buf, int len)
7131+{
7132+ struct sk_buff *skb;
7133+ int err;
7134+
7135+ BUG_ON(dev->type != ARPHRD_IEEE802154);
7136+
7137+ skb = alloc_skb(LL_ALLOCATED_SPACE(dev) + len, GFP_KERNEL);
7138+ if (!skb)
7139+ return -ENOMEM;
7140+
7141+ skb_reserve(skb, LL_RESERVED_SPACE(dev));
7142+
7143+ skb_reset_network_header(skb);
7144+
7145+ mac_cb(skb)->flags = IEEE802154_FC_TYPE_MAC_CMD | MAC_CB_FLAG_ACKREQ;
7146+ mac_cb(skb)->seq = ieee802154_mlme_ops(dev)->get_dsn(dev);
7147+ err = dev_hard_header(skb, dev, ETH_P_IEEE802154, addr, saddr, len);
7148+ if (err < 0) {
7149+ kfree_skb(skb);
7150+ return err;
7151+ }
7152+
7153+ skb_reset_mac_header(skb);
7154+ memcpy(skb_put(skb, len), buf, len);
7155+
7156+ skb->dev = dev;
7157+ skb->protocol = htons(ETH_P_IEEE802154);
7158+
7159+ return dev_queue_xmit(skb);
7160+}
7161+
7162+int mac802154_send_beacon_req(struct net_device *dev)
7163+{
7164+ struct ieee802154_addr addr;
7165+ struct ieee802154_addr saddr;
7166+ u8 cmd = IEEE802154_CMD_BEACON_REQ;
7167+ addr.addr_type = IEEE802154_ADDR_SHORT;
7168+ addr.short_addr = IEEE802154_ADDR_BROADCAST;
7169+ addr.pan_id = IEEE802154_PANID_BROADCAST;
7170+ saddr.addr_type = IEEE802154_ADDR_NONE;
7171+ return mac802154_send_cmd(dev, &addr, &saddr, &cmd, 1);
7172+}
7173+
7174+
7175+static int mac802154_mlme_assoc_req(struct net_device *dev,
7176+ struct ieee802154_addr *addr, u8 channel, u8 page, u8 cap)
7177+{
7178+ struct ieee802154_addr saddr;
7179+ u8 buf[2];
7180+ int pos = 0;
7181+
7182+ saddr.addr_type = IEEE802154_ADDR_LONG;
7183+ saddr.pan_id = IEEE802154_PANID_BROADCAST;
7184+ memcpy(saddr.hwaddr, dev->dev_addr, IEEE802154_ADDR_LEN);
7185+
7186+
7187+ /* FIXME: set PIB/MIB info */
7188+ mac802154_dev_set_pan_id(dev, addr->pan_id);
7189+ mac802154_dev_set_page_channel(dev, page, channel);
7190+ mac802154_dev_set_ieee_addr(dev);
7191+
7192+ buf[pos++] = IEEE802154_CMD_ASSOCIATION_REQ;
7193+ buf[pos++] = cap;
7194+
7195+ return mac802154_send_cmd(dev, addr, &saddr, buf, pos);
7196+}
7197+
7198+static int mac802154_mlme_assoc_resp(struct net_device *dev,
7199+ struct ieee802154_addr *addr, u16 short_addr, u8 status)
7200+{
7201+ struct ieee802154_addr saddr;
7202+ u8 buf[4];
7203+ int pos = 0;
7204+
7205+ saddr.addr_type = IEEE802154_ADDR_LONG;
7206+ saddr.pan_id = addr->pan_id;
7207+ memcpy(saddr.hwaddr, dev->dev_addr, IEEE802154_ADDR_LEN);
7208+
7209+ buf[pos++] = IEEE802154_CMD_ASSOCIATION_RESP;
7210+ buf[pos++] = short_addr;
7211+ buf[pos++] = short_addr >> 8;
7212+ buf[pos++] = status;
7213+
7214+ return mac802154_send_cmd(dev, addr, &saddr, buf, pos);
7215+}
7216+
7217+static int mac802154_mlme_disassoc_req(struct net_device *dev,
7218+ struct ieee802154_addr *addr, u8 reason)
7219+{
7220+ struct ieee802154_addr saddr;
7221+ u8 buf[2];
7222+ int pos = 0;
7223+ int ret;
7224+
7225+ saddr.addr_type = IEEE802154_ADDR_LONG;
7226+ saddr.pan_id = addr->pan_id;
7227+ memcpy(saddr.hwaddr, dev->dev_addr, IEEE802154_ADDR_LEN);
7228+
7229+ buf[pos++] = IEEE802154_CMD_DISASSOCIATION_NOTIFY;
7230+ buf[pos++] = reason;
7231+
7232+ ret = mac802154_send_cmd(dev, addr, &saddr, buf, pos);
7233+
7234+ /* FIXME: this should be after the ack receved */
7235+ mac802154_dev_set_pan_id(dev, 0xffff);
7236+ mac802154_dev_set_short_addr(dev, 0xffff);
7237+ ieee802154_nl_disassoc_confirm(dev, 0x00);
7238+
7239+ return ret;
7240+}
7241+
7242+static int mac802154_mlme_start_req(struct net_device *dev,
7243+ struct ieee802154_addr *addr,
7244+ u8 channel, u8 page,
7245+ u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx,
7246+ u8 coord_realign)
7247+{
7248+ BUG_ON(addr->addr_type != IEEE802154_ADDR_SHORT);
7249+
7250+ mac802154_dev_set_pan_id(dev, addr->pan_id);
7251+ mac802154_dev_set_short_addr(dev, addr->short_addr);
7252+ mac802154_dev_set_ieee_addr(dev);
7253+ mac802154_dev_set_page_channel(dev, page, channel);
7254+
7255+ /*
7256+ * FIXME: add validation for unused parameters to be sane
7257+ * for SoftMAC
7258+ */
7259+
7260+ if (pan_coord)
7261+ dev->priv_flags |= IFF_IEEE802154_COORD;
7262+ else
7263+ dev->priv_flags &= ~IFF_IEEE802154_COORD;
7264+
7265+ mac802154_dev_set_pan_coord(dev);
7266+ ieee802154_nl_start_confirm(dev, IEEE802154_SUCCESS);
7267+
7268+ return 0;
7269+}
7270+
7271+struct ieee802154_mlme_ops mac802154_mlme_wpan = {
7272+ .assoc_req = mac802154_mlme_assoc_req,
7273+ .assoc_resp = mac802154_mlme_assoc_resp,
7274+ .disassoc_req = mac802154_mlme_disassoc_req,
7275+ .start_req = mac802154_mlme_start_req,
7276+ .scan_req = mac802154_mlme_scan_req,
7277+
7278+ .wpan_ops.get_phy = mac802154_get_phy,
7279+
7280+ .get_pan_id = mac802154_dev_get_pan_id,
7281+ .get_short_addr = mac802154_dev_get_short_addr,
7282