Root/target/linux/xburst/patches-3.3/800-WPAN-new-files.patch

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