This source file includes following definitions.
- link_to_linux_err
- ca8210_test_int_driver_write
- ca8210_reset_send
- ca8210_mlme_reset_worker
- ca8210_rx_done
- ca8210_spi_transfer_complete
- ca8210_spi_transfer
- ca8210_spi_exchange
- ca8210_interrupt_handler
- tdme_setsfr_request_sync
- tdme_chipinit
- tdme_channelinit
- tdme_checkpibattribute
- tdme_settxpower
- mcps_data_request
- mlme_reset_request_sync
- mlme_set_request_sync
- hwme_set_request_sync
- hwme_get_request_sync
- ca8210_async_xmit_complete
- ca8210_skb_rx
- ca8210_net_rx
- ca8210_skb_tx
- ca8210_start
- ca8210_stop
- ca8210_xmit_async
- ca8210_get_ed
- ca8210_set_channel
- ca8210_set_hw_addr_filt
- ca8210_set_tx_power
- ca8210_set_cca_mode
- ca8210_set_cca_ed_level
- ca8210_set_csma_params
- ca8210_set_frame_retries
- ca8210_set_promiscuous_mode
- ca8210_test_int_open
- ca8210_test_check_upstream
- ca8210_test_int_user_write
- ca8210_test_int_user_read
- ca8210_test_int_ioctl
- ca8210_test_int_poll
- ca8210_get_platform_data
- ca8210_config_extern_clk
- ca8210_register_ext_clock
- ca8210_unregister_ext_clock
- ca8210_reset_init
- ca8210_interrupt_init
- ca8210_dev_com_init
- ca8210_dev_com_clear
- ca8210_hw_setup
- ca8210_test_interface_init
- ca8210_test_interface_clear
- ca8210_remove
- ca8210_probe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 #include <linux/cdev.h>
51 #include <linux/clk-provider.h>
52 #include <linux/debugfs.h>
53 #include <linux/delay.h>
54 #include <linux/gpio.h>
55 #include <linux/ieee802154.h>
56 #include <linux/io.h>
57 #include <linux/kfifo.h>
58 #include <linux/of.h>
59 #include <linux/of_device.h>
60 #include <linux/of_gpio.h>
61 #include <linux/module.h>
62 #include <linux/mutex.h>
63 #include <linux/poll.h>
64 #include <linux/skbuff.h>
65 #include <linux/slab.h>
66 #include <linux/spi/spi.h>
67 #include <linux/spinlock.h>
68 #include <linux/string.h>
69 #include <linux/workqueue.h>
70 #include <linux/interrupt.h>
71
72 #include <net/ieee802154_netdev.h>
73 #include <net/mac802154.h>
74
75 #define DRIVER_NAME "ca8210"
76
77
78 #define ONE_MHZ 1000000
79 #define TWO_MHZ (2 * ONE_MHZ)
80 #define FOUR_MHZ (4 * ONE_MHZ)
81 #define EIGHT_MHZ (8 * ONE_MHZ)
82 #define SIXTEEN_MHZ (16 * ONE_MHZ)
83
84
85 #define CA8210_SPI_BUF_SIZE 256
86 #define CA8210_SYNC_TIMEOUT 1000
87
88
89 #define CA8210_TEST_INT_FILE_NAME "ca8210_test"
90 #define CA8210_TEST_INT_FIFO_SIZE 256
91
92
93 #define MAC_SUCCESS (0x00)
94 #define MAC_ERROR (0x01)
95 #define MAC_CANCELLED (0x02)
96 #define MAC_READY_FOR_POLL (0x03)
97 #define MAC_COUNTER_ERROR (0xDB)
98 #define MAC_IMPROPER_KEY_TYPE (0xDC)
99 #define MAC_IMPROPER_SECURITY_LEVEL (0xDD)
100 #define MAC_UNSUPPORTED_LEGACY (0xDE)
101 #define MAC_UNSUPPORTED_SECURITY (0xDF)
102 #define MAC_BEACON_LOST (0xE0)
103 #define MAC_CHANNEL_ACCESS_FAILURE (0xE1)
104 #define MAC_DENIED (0xE2)
105 #define MAC_DISABLE_TRX_FAILURE (0xE3)
106 #define MAC_SECURITY_ERROR (0xE4)
107 #define MAC_FRAME_TOO_LONG (0xE5)
108 #define MAC_INVALID_GTS (0xE6)
109 #define MAC_INVALID_HANDLE (0xE7)
110 #define MAC_INVALID_PARAMETER (0xE8)
111 #define MAC_NO_ACK (0xE9)
112 #define MAC_NO_BEACON (0xEA)
113 #define MAC_NO_DATA (0xEB)
114 #define MAC_NO_SHORT_ADDRESS (0xEC)
115 #define MAC_OUT_OF_CAP (0xED)
116 #define MAC_PAN_ID_CONFLICT (0xEE)
117 #define MAC_REALIGNMENT (0xEF)
118 #define MAC_TRANSACTION_EXPIRED (0xF0)
119 #define MAC_TRANSACTION_OVERFLOW (0xF1)
120 #define MAC_TX_ACTIVE (0xF2)
121 #define MAC_UNAVAILABLE_KEY (0xF3)
122 #define MAC_UNSUPPORTED_ATTRIBUTE (0xF4)
123 #define MAC_INVALID_ADDRESS (0xF5)
124 #define MAC_ON_TIME_TOO_LONG (0xF6)
125 #define MAC_PAST_TIME (0xF7)
126 #define MAC_TRACKING_OFF (0xF8)
127 #define MAC_INVALID_INDEX (0xF9)
128 #define MAC_LIMIT_REACHED (0xFA)
129 #define MAC_READ_ONLY (0xFB)
130 #define MAC_SCAN_IN_PROGRESS (0xFC)
131 #define MAC_SUPERFRAME_OVERLAP (0xFD)
132 #define MAC_SYSTEM_ERROR (0xFF)
133
134
135 #define HWME_EDTHRESHOLD (0x04)
136 #define HWME_EDVALUE (0x06)
137 #define HWME_SYSCLKOUT (0x0F)
138 #define HWME_LQILIMIT (0x11)
139
140
141 #define TDME_CHANNEL (0x00)
142 #define TDME_ATM_CONFIG (0x06)
143
144 #define MAX_HWME_ATTRIBUTE_SIZE 16
145 #define MAX_TDME_ATTRIBUTE_SIZE 2
146
147
148 #define PHY_CURRENT_CHANNEL (0x00)
149 #define PHY_TRANSMIT_POWER (0x02)
150 #define PHY_CCA_MODE (0x03)
151 #define MAC_ASSOCIATION_PERMIT (0x41)
152 #define MAC_AUTO_REQUEST (0x42)
153 #define MAC_BATT_LIFE_EXT (0x43)
154 #define MAC_BATT_LIFE_EXT_PERIODS (0x44)
155 #define MAC_BEACON_PAYLOAD (0x45)
156 #define MAC_BEACON_PAYLOAD_LENGTH (0x46)
157 #define MAC_BEACON_ORDER (0x47)
158 #define MAC_GTS_PERMIT (0x4d)
159 #define MAC_MAX_CSMA_BACKOFFS (0x4e)
160 #define MAC_MIN_BE (0x4f)
161 #define MAC_PAN_ID (0x50)
162 #define MAC_PROMISCUOUS_MODE (0x51)
163 #define MAC_RX_ON_WHEN_IDLE (0x52)
164 #define MAC_SHORT_ADDRESS (0x53)
165 #define MAC_SUPERFRAME_ORDER (0x54)
166 #define MAC_ASSOCIATED_PAN_COORD (0x56)
167 #define MAC_MAX_BE (0x57)
168 #define MAC_MAX_FRAME_RETRIES (0x59)
169 #define MAC_RESPONSE_WAIT_TIME (0x5A)
170 #define MAC_SECURITY_ENABLED (0x5D)
171
172 #define MAC_AUTO_REQUEST_SECURITY_LEVEL (0x78)
173 #define MAC_AUTO_REQUEST_KEY_ID_MODE (0x79)
174
175 #define NS_IEEE_ADDRESS (0xFF)
176
177
178 #define MAC_MODE_NO_ADDR (0x00)
179 #define MAC_MODE_SHORT_ADDR (0x02)
180 #define MAC_MODE_LONG_ADDR (0x03)
181
182
183 #define MAX_BEACON_OVERHEAD (75)
184 #define MAX_BEACON_PAYLOAD_LENGTH (IEEE802154_MTU - MAX_BEACON_OVERHEAD)
185
186 #define MAX_ATTRIBUTE_SIZE (122)
187 #define MAX_DATA_SIZE (114)
188
189 #define CA8210_VALID_CHANNELS (0x07FFF800)
190
191
192 #define CA8210_MAC_WORKAROUNDS (0)
193 #define CA8210_MAC_MPW (0)
194
195
196 #define LS_BYTE(x) ((u8)((x) & 0xFF))
197 #define MS_BYTE(x) ((u8)(((x) >> 8) & 0xFF))
198
199
200
201 #define MCPS_DATA_REQUEST (0x00)
202 #define MLME_ASSOCIATE_REQUEST (0x02)
203 #define MLME_ASSOCIATE_RESPONSE (0x03)
204 #define MLME_DISASSOCIATE_REQUEST (0x04)
205 #define MLME_GET_REQUEST (0x05)
206 #define MLME_ORPHAN_RESPONSE (0x06)
207 #define MLME_RESET_REQUEST (0x07)
208 #define MLME_RX_ENABLE_REQUEST (0x08)
209 #define MLME_SCAN_REQUEST (0x09)
210 #define MLME_SET_REQUEST (0x0A)
211 #define MLME_START_REQUEST (0x0B)
212 #define MLME_POLL_REQUEST (0x0D)
213 #define HWME_SET_REQUEST (0x0E)
214 #define HWME_GET_REQUEST (0x0F)
215 #define TDME_SETSFR_REQUEST (0x11)
216 #define TDME_GETSFR_REQUEST (0x12)
217 #define TDME_SET_REQUEST (0x14)
218
219 #define MCPS_DATA_INDICATION (0x00)
220 #define MCPS_DATA_CONFIRM (0x01)
221 #define MLME_RESET_CONFIRM (0x0A)
222 #define MLME_SET_CONFIRM (0x0E)
223 #define MLME_START_CONFIRM (0x0F)
224 #define HWME_SET_CONFIRM (0x12)
225 #define HWME_GET_CONFIRM (0x13)
226 #define HWME_WAKEUP_INDICATION (0x15)
227 #define TDME_SETSFR_CONFIRM (0x17)
228
229
230
231 #define SPI_S2M (0x20)
232
233 #define SPI_SYN (0x40)
234
235
236 #define SPI_IDLE (0xFF)
237 #define SPI_NACK (0xF0)
238
239 #define SPI_MCPS_DATA_REQUEST (MCPS_DATA_REQUEST)
240 #define SPI_MCPS_DATA_INDICATION (MCPS_DATA_INDICATION + SPI_S2M)
241 #define SPI_MCPS_DATA_CONFIRM (MCPS_DATA_CONFIRM + SPI_S2M)
242
243 #define SPI_MLME_ASSOCIATE_REQUEST (MLME_ASSOCIATE_REQUEST)
244 #define SPI_MLME_RESET_REQUEST (MLME_RESET_REQUEST + SPI_SYN)
245 #define SPI_MLME_SET_REQUEST (MLME_SET_REQUEST + SPI_SYN)
246 #define SPI_MLME_START_REQUEST (MLME_START_REQUEST + SPI_SYN)
247 #define SPI_MLME_RESET_CONFIRM (MLME_RESET_CONFIRM + SPI_S2M + SPI_SYN)
248 #define SPI_MLME_SET_CONFIRM (MLME_SET_CONFIRM + SPI_S2M + SPI_SYN)
249 #define SPI_MLME_START_CONFIRM (MLME_START_CONFIRM + SPI_S2M + SPI_SYN)
250
251 #define SPI_HWME_SET_REQUEST (HWME_SET_REQUEST + SPI_SYN)
252 #define SPI_HWME_GET_REQUEST (HWME_GET_REQUEST + SPI_SYN)
253 #define SPI_HWME_SET_CONFIRM (HWME_SET_CONFIRM + SPI_S2M + SPI_SYN)
254 #define SPI_HWME_GET_CONFIRM (HWME_GET_CONFIRM + SPI_S2M + SPI_SYN)
255 #define SPI_HWME_WAKEUP_INDICATION (HWME_WAKEUP_INDICATION + SPI_S2M)
256
257 #define SPI_TDME_SETSFR_REQUEST (TDME_SETSFR_REQUEST + SPI_SYN)
258 #define SPI_TDME_SET_REQUEST (TDME_SET_REQUEST + SPI_SYN)
259 #define SPI_TDME_SETSFR_CONFIRM (TDME_SETSFR_CONFIRM + SPI_S2M + SPI_SYN)
260
261
262
263 #define CA8210_SFR_PACFG (0xB1)
264 #define CA8210_SFR_MACCON (0xD8)
265 #define CA8210_SFR_PACFGIB (0xFE)
266
267 #define CA8210_SFR_LOTXCAL (0xBF)
268 #define CA8210_SFR_PTHRH (0xD1)
269 #define CA8210_SFR_PRECFG (0xD3)
270 #define CA8210_SFR_LNAGX40 (0xE1)
271 #define CA8210_SFR_LNAGX41 (0xE2)
272 #define CA8210_SFR_LNAGX42 (0xE3)
273 #define CA8210_SFR_LNAGX43 (0xE4)
274 #define CA8210_SFR_LNAGX44 (0xE5)
275 #define CA8210_SFR_LNAGX45 (0xE6)
276 #define CA8210_SFR_LNAGX46 (0xE7)
277 #define CA8210_SFR_LNAGX47 (0xE9)
278
279 #define PACFGIB_DEFAULT_CURRENT (0x3F)
280 #define PTHRH_DEFAULT_THRESHOLD (0x5A)
281 #define LNAGX40_DEFAULT_GAIN (0x29)
282 #define LNAGX41_DEFAULT_GAIN (0x54)
283 #define LNAGX42_DEFAULT_GAIN (0x6C)
284 #define LNAGX43_DEFAULT_GAIN (0x7A)
285 #define LNAGX44_DEFAULT_GAIN (0x84)
286 #define LNAGX45_DEFAULT_GAIN (0x8B)
287 #define LNAGX46_DEFAULT_GAIN (0x92)
288 #define LNAGX47_DEFAULT_GAIN (0x96)
289
290 #define CA8210_IOCTL_HARD_RESET (0x00)
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305 struct cas_control {
306 struct spi_message msg;
307 struct spi_transfer transfer;
308
309 u8 tx_buf[CA8210_SPI_BUF_SIZE];
310 u8 tx_in_buf[CA8210_SPI_BUF_SIZE];
311
312 struct ca8210_priv *priv;
313 };
314
315
316
317
318
319
320
321
322 struct ca8210_test {
323 struct dentry *ca8210_dfs_spi_int;
324 struct kfifo up_fifo;
325 wait_queue_head_t readq;
326 };
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356 struct ca8210_priv {
357 struct spi_device *spi;
358 struct ieee802154_hw *hw;
359 bool hw_registered;
360 spinlock_t lock;
361 struct workqueue_struct *mlme_workqueue;
362 struct workqueue_struct *irq_workqueue;
363 struct sk_buff *tx_skb;
364 u8 nextmsduhandle;
365 struct clk *clk;
366 int last_dsn;
367 struct ca8210_test test;
368 bool async_tx_pending;
369 u8 *sync_command_response;
370 struct completion ca8210_is_awake;
371 int sync_down, sync_up;
372 struct completion spi_transfer_complete, sync_exchange_complete;
373 bool promiscuous;
374 int retries;
375 };
376
377
378
379
380
381
382
383
384 struct work_priv_container {
385 struct work_struct work;
386 struct ca8210_priv *priv;
387 };
388
389
390
391
392
393
394
395
396
397
398
399 struct ca8210_platform_data {
400 bool extclockenable;
401 unsigned int extclockfreq;
402 unsigned int extclockgpio;
403 int gpio_reset;
404 int gpio_irq;
405 int irq_id;
406 };
407
408
409
410
411
412
413
414
415 struct fulladdr {
416 u8 mode;
417 u8 pan_id[2];
418 u8 address[8];
419 };
420
421
422
423
424
425
426
427 union macaddr {
428 u16 short_address;
429 u8 ieee_address[8];
430 };
431
432
433
434
435
436
437
438
439
440 struct secspec {
441 u8 security_level;
442 u8 key_id_mode;
443 u8 key_source[8];
444 u8 key_index;
445 };
446
447
448 struct mcps_data_request_pset {
449 u8 src_addr_mode;
450 struct fulladdr dst;
451 u8 msdu_length;
452 u8 msdu_handle;
453 u8 tx_options;
454 u8 msdu[MAX_DATA_SIZE];
455 };
456
457 struct mlme_set_request_pset {
458 u8 pib_attribute;
459 u8 pib_attribute_index;
460 u8 pib_attribute_length;
461 u8 pib_attribute_value[MAX_ATTRIBUTE_SIZE];
462 };
463
464 struct hwme_set_request_pset {
465 u8 hw_attribute;
466 u8 hw_attribute_length;
467 u8 hw_attribute_value[MAX_HWME_ATTRIBUTE_SIZE];
468 };
469
470 struct hwme_get_request_pset {
471 u8 hw_attribute;
472 };
473
474 struct tdme_setsfr_request_pset {
475 u8 sfr_page;
476 u8 sfr_address;
477 u8 sfr_value;
478 };
479
480
481 struct hwme_set_confirm_pset {
482 u8 status;
483 u8 hw_attribute;
484 };
485
486 struct hwme_get_confirm_pset {
487 u8 status;
488 u8 hw_attribute;
489 u8 hw_attribute_length;
490 u8 hw_attribute_value[MAX_HWME_ATTRIBUTE_SIZE];
491 };
492
493 struct tdme_setsfr_confirm_pset {
494 u8 status;
495 u8 sfr_page;
496 u8 sfr_address;
497 };
498
499 struct mac_message {
500 u8 command_id;
501 u8 length;
502 union {
503 struct mcps_data_request_pset data_req;
504 struct mlme_set_request_pset set_req;
505 struct hwme_set_request_pset hwme_set_req;
506 struct hwme_get_request_pset hwme_get_req;
507 struct tdme_setsfr_request_pset tdme_set_sfr_req;
508 struct hwme_set_confirm_pset hwme_set_cnf;
509 struct hwme_get_confirm_pset hwme_get_cnf;
510 struct tdme_setsfr_confirm_pset tdme_set_sfr_cnf;
511 u8 u8param;
512 u8 status;
513 u8 payload[148];
514 } pdata;
515 };
516
517 union pa_cfg_sfr {
518 struct {
519 u8 bias_current_trim : 3;
520 u8 : 1;
521 u8 buffer_capacitor_trim : 3;
522 u8 boost : 1;
523 };
524 u8 paib;
525 };
526
527 struct preamble_cfg_sfr {
528 u8 timeout_symbols : 3;
529 u8 acquisition_symbols : 3;
530 u8 search_symbols : 2;
531 };
532
533 static int (*cascoda_api_upstream)(
534 const u8 *buf,
535 size_t len,
536 void *device_ref
537 );
538
539
540
541
542
543
544
545
546 static int link_to_linux_err(int link_status)
547 {
548 if (link_status < 0) {
549
550 return link_status;
551 }
552 switch (link_status) {
553 case MAC_SUCCESS:
554 case MAC_REALIGNMENT:
555 return 0;
556 case MAC_IMPROPER_KEY_TYPE:
557 return -EKEYREJECTED;
558 case MAC_IMPROPER_SECURITY_LEVEL:
559 case MAC_UNSUPPORTED_LEGACY:
560 case MAC_DENIED:
561 return -EACCES;
562 case MAC_BEACON_LOST:
563 case MAC_NO_ACK:
564 case MAC_NO_BEACON:
565 return -ENETUNREACH;
566 case MAC_CHANNEL_ACCESS_FAILURE:
567 case MAC_TX_ACTIVE:
568 case MAC_SCAN_IN_PROGRESS:
569 return -EBUSY;
570 case MAC_DISABLE_TRX_FAILURE:
571 case MAC_OUT_OF_CAP:
572 return -EAGAIN;
573 case MAC_FRAME_TOO_LONG:
574 return -EMSGSIZE;
575 case MAC_INVALID_GTS:
576 case MAC_PAST_TIME:
577 return -EBADSLT;
578 case MAC_INVALID_HANDLE:
579 return -EBADMSG;
580 case MAC_INVALID_PARAMETER:
581 case MAC_UNSUPPORTED_ATTRIBUTE:
582 case MAC_ON_TIME_TOO_LONG:
583 case MAC_INVALID_INDEX:
584 return -EINVAL;
585 case MAC_NO_DATA:
586 return -ENODATA;
587 case MAC_NO_SHORT_ADDRESS:
588 return -EFAULT;
589 case MAC_PAN_ID_CONFLICT:
590 return -EADDRINUSE;
591 case MAC_TRANSACTION_EXPIRED:
592 return -ETIME;
593 case MAC_TRANSACTION_OVERFLOW:
594 return -ENOBUFS;
595 case MAC_UNAVAILABLE_KEY:
596 return -ENOKEY;
597 case MAC_INVALID_ADDRESS:
598 return -ENXIO;
599 case MAC_TRACKING_OFF:
600 case MAC_SUPERFRAME_OVERLAP:
601 return -EREMOTEIO;
602 case MAC_LIMIT_REACHED:
603 return -EDQUOT;
604 case MAC_READ_ONLY:
605 return -EROFS;
606 default:
607 return -EPROTO;
608 }
609 }
610
611
612
613
614
615
616
617
618
619
620 static int ca8210_test_int_driver_write(
621 const u8 *buf,
622 size_t len,
623 void *spi
624 )
625 {
626 struct ca8210_priv *priv = spi_get_drvdata(spi);
627 struct ca8210_test *test = &priv->test;
628 char *fifo_buffer;
629 int i;
630
631 dev_dbg(
632 &priv->spi->dev,
633 "test_interface: Buffering upstream message:\n"
634 );
635 for (i = 0; i < len; i++)
636 dev_dbg(&priv->spi->dev, "%#03x\n", buf[i]);
637
638 fifo_buffer = kmemdup(buf, len, GFP_KERNEL);
639 if (!fifo_buffer)
640 return -ENOMEM;
641 kfifo_in(&test->up_fifo, &fifo_buffer, 4);
642 wake_up_interruptible(&priv->test.readq);
643
644 return 0;
645 }
646
647
648
649 static int ca8210_net_rx(
650 struct ieee802154_hw *hw,
651 u8 *command,
652 size_t len
653 );
654 static u8 mlme_reset_request_sync(
655 u8 set_default_pib,
656 void *device_ref
657 );
658 static int ca8210_spi_transfer(
659 struct spi_device *spi,
660 const u8 *buf,
661 size_t len
662 );
663
664
665
666
667
668
669 static void ca8210_reset_send(struct spi_device *spi, unsigned int ms)
670 {
671 struct ca8210_platform_data *pdata = spi->dev.platform_data;
672 struct ca8210_priv *priv = spi_get_drvdata(spi);
673 long status;
674
675 gpio_set_value(pdata->gpio_reset, 0);
676 reinit_completion(&priv->ca8210_is_awake);
677 msleep(ms);
678 gpio_set_value(pdata->gpio_reset, 1);
679 priv->promiscuous = false;
680
681
682 status = wait_for_completion_interruptible_timeout(
683 &priv->ca8210_is_awake,
684 msecs_to_jiffies(CA8210_SYNC_TIMEOUT)
685 );
686 if (status == 0) {
687 dev_crit(
688 &spi->dev,
689 "Fatal: No wakeup from ca8210 after reset!\n"
690 );
691 }
692
693 dev_dbg(&spi->dev, "Reset the device\n");
694 }
695
696
697
698
699
700
701 static void ca8210_mlme_reset_worker(struct work_struct *work)
702 {
703 struct work_priv_container *wpc = container_of(
704 work,
705 struct work_priv_container,
706 work
707 );
708 struct ca8210_priv *priv = wpc->priv;
709
710 mlme_reset_request_sync(0, priv->spi);
711 kfree(wpc);
712 }
713
714
715
716
717
718
719
720
721
722 static void ca8210_rx_done(struct cas_control *cas_ctl)
723 {
724 u8 *buf;
725 unsigned int len;
726 struct work_priv_container *mlme_reset_wpc;
727 struct ca8210_priv *priv = cas_ctl->priv;
728
729 buf = cas_ctl->tx_in_buf;
730 len = buf[1] + 2;
731 if (len > CA8210_SPI_BUF_SIZE) {
732 dev_crit(
733 &priv->spi->dev,
734 "Received packet len (%u) erroneously long\n",
735 len
736 );
737 goto finish;
738 }
739
740 if (buf[0] & SPI_SYN) {
741 if (priv->sync_command_response) {
742 memcpy(priv->sync_command_response, buf, len);
743 complete(&priv->sync_exchange_complete);
744 } else {
745 if (cascoda_api_upstream)
746 cascoda_api_upstream(buf, len, priv->spi);
747 priv->sync_up++;
748 }
749 } else {
750 if (cascoda_api_upstream)
751 cascoda_api_upstream(buf, len, priv->spi);
752 }
753
754 ca8210_net_rx(priv->hw, buf, len);
755 if (buf[0] == SPI_MCPS_DATA_CONFIRM) {
756 if (buf[3] == MAC_TRANSACTION_OVERFLOW) {
757 dev_info(
758 &priv->spi->dev,
759 "Waiting for transaction overflow to stabilise...\n");
760 msleep(2000);
761 dev_info(
762 &priv->spi->dev,
763 "Resetting MAC...\n");
764
765 mlme_reset_wpc = kmalloc(sizeof(*mlme_reset_wpc),
766 GFP_KERNEL);
767 if (!mlme_reset_wpc)
768 goto finish;
769 INIT_WORK(
770 &mlme_reset_wpc->work,
771 ca8210_mlme_reset_worker
772 );
773 mlme_reset_wpc->priv = priv;
774 queue_work(priv->mlme_workqueue, &mlme_reset_wpc->work);
775 }
776 } else if (buf[0] == SPI_HWME_WAKEUP_INDICATION) {
777 dev_notice(
778 &priv->spi->dev,
779 "Wakeup indication received, reason:\n"
780 );
781 switch (buf[2]) {
782 case 0:
783 dev_notice(
784 &priv->spi->dev,
785 "Transceiver woken up from Power Up / System Reset\n"
786 );
787 break;
788 case 1:
789 dev_notice(
790 &priv->spi->dev,
791 "Watchdog Timer Time-Out\n"
792 );
793 break;
794 case 2:
795 dev_notice(
796 &priv->spi->dev,
797 "Transceiver woken up from Power-Off by Sleep Timer Time-Out\n");
798 break;
799 case 3:
800 dev_notice(
801 &priv->spi->dev,
802 "Transceiver woken up from Power-Off by GPIO Activity\n"
803 );
804 break;
805 case 4:
806 dev_notice(
807 &priv->spi->dev,
808 "Transceiver woken up from Standby by Sleep Timer Time-Out\n"
809 );
810 break;
811 case 5:
812 dev_notice(
813 &priv->spi->dev,
814 "Transceiver woken up from Standby by GPIO Activity\n"
815 );
816 break;
817 case 6:
818 dev_notice(
819 &priv->spi->dev,
820 "Sleep-Timer Time-Out in Active Mode\n"
821 );
822 break;
823 default:
824 dev_warn(&priv->spi->dev, "Wakeup reason unknown\n");
825 break;
826 }
827 complete(&priv->ca8210_is_awake);
828 }
829
830 finish:;
831 }
832
833 static int ca8210_remove(struct spi_device *spi_device);
834
835
836
837
838
839
840 static void ca8210_spi_transfer_complete(void *context)
841 {
842 struct cas_control *cas_ctl = context;
843 struct ca8210_priv *priv = cas_ctl->priv;
844 bool duplex_rx = false;
845 int i;
846 u8 retry_buffer[CA8210_SPI_BUF_SIZE];
847
848 if (
849 cas_ctl->tx_in_buf[0] == SPI_NACK ||
850 (cas_ctl->tx_in_buf[0] == SPI_IDLE &&
851 cas_ctl->tx_in_buf[1] == SPI_NACK)
852 ) {
853
854 dev_info(&priv->spi->dev, "ca8210 was busy during attempted write\n");
855 if (cas_ctl->tx_buf[0] == SPI_IDLE) {
856 dev_warn(
857 &priv->spi->dev,
858 "IRQ servicing NACKd, dropping transfer\n"
859 );
860 kfree(cas_ctl);
861 return;
862 }
863 if (priv->retries > 3) {
864 dev_err(&priv->spi->dev, "too many retries!\n");
865 kfree(cas_ctl);
866 ca8210_remove(priv->spi);
867 return;
868 }
869 memcpy(retry_buffer, cas_ctl->tx_buf, CA8210_SPI_BUF_SIZE);
870 kfree(cas_ctl);
871 ca8210_spi_transfer(
872 priv->spi,
873 retry_buffer,
874 CA8210_SPI_BUF_SIZE
875 );
876 priv->retries++;
877 dev_info(&priv->spi->dev, "retried spi write\n");
878 return;
879 } else if (
880 cas_ctl->tx_in_buf[0] != SPI_IDLE &&
881 cas_ctl->tx_in_buf[0] != SPI_NACK
882 ) {
883 duplex_rx = true;
884 }
885
886 if (duplex_rx) {
887 dev_dbg(&priv->spi->dev, "READ CMD DURING TX\n");
888 for (i = 0; i < cas_ctl->tx_in_buf[1] + 2; i++)
889 dev_dbg(
890 &priv->spi->dev,
891 "%#03x\n",
892 cas_ctl->tx_in_buf[i]
893 );
894 ca8210_rx_done(cas_ctl);
895 }
896 complete(&priv->spi_transfer_complete);
897 kfree(cas_ctl);
898 priv->retries = 0;
899 }
900
901
902
903
904
905
906
907
908
909 static int ca8210_spi_transfer(
910 struct spi_device *spi,
911 const u8 *buf,
912 size_t len
913 )
914 {
915 int i, status = 0;
916 struct ca8210_priv *priv;
917 struct cas_control *cas_ctl;
918
919 if (!spi) {
920 pr_crit("NULL spi device passed to %s\n", __func__);
921 return -ENODEV;
922 }
923
924 priv = spi_get_drvdata(spi);
925 reinit_completion(&priv->spi_transfer_complete);
926
927 dev_dbg(&spi->dev, "%s called\n", __func__);
928
929 cas_ctl = kmalloc(sizeof(*cas_ctl), GFP_ATOMIC);
930 if (!cas_ctl)
931 return -ENOMEM;
932
933 cas_ctl->priv = priv;
934 memset(cas_ctl->tx_buf, SPI_IDLE, CA8210_SPI_BUF_SIZE);
935 memset(cas_ctl->tx_in_buf, SPI_IDLE, CA8210_SPI_BUF_SIZE);
936 memcpy(cas_ctl->tx_buf, buf, len);
937
938 for (i = 0; i < len; i++)
939 dev_dbg(&spi->dev, "%#03x\n", cas_ctl->tx_buf[i]);
940
941 spi_message_init(&cas_ctl->msg);
942
943 cas_ctl->transfer.tx_nbits = 1;
944 cas_ctl->transfer.rx_nbits = 1;
945 cas_ctl->transfer.speed_hz = 0;
946 cas_ctl->transfer.bits_per_word = 0;
947 cas_ctl->transfer.tx_buf = cas_ctl->tx_buf;
948 cas_ctl->transfer.rx_buf = cas_ctl->tx_in_buf;
949 cas_ctl->transfer.delay_usecs = 0;
950 cas_ctl->transfer.cs_change = 0;
951 cas_ctl->transfer.len = sizeof(struct mac_message);
952 cas_ctl->msg.complete = ca8210_spi_transfer_complete;
953 cas_ctl->msg.context = cas_ctl;
954
955 spi_message_add_tail(
956 &cas_ctl->transfer,
957 &cas_ctl->msg
958 );
959
960 status = spi_async(spi, &cas_ctl->msg);
961 if (status < 0) {
962 dev_crit(
963 &spi->dev,
964 "status %d from spi_sync in write\n",
965 status
966 );
967 }
968
969 return status;
970 }
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985 static int ca8210_spi_exchange(
986 const u8 *buf,
987 size_t len,
988 u8 *response,
989 void *device_ref
990 )
991 {
992 int status = 0;
993 struct spi_device *spi = device_ref;
994 struct ca8210_priv *priv = spi->dev.driver_data;
995 long wait_remaining;
996
997 if ((buf[0] & SPI_SYN) && response) {
998 reinit_completion(&priv->sync_exchange_complete);
999 priv->sync_command_response = response;
1000 }
1001
1002 do {
1003 reinit_completion(&priv->spi_transfer_complete);
1004 status = ca8210_spi_transfer(priv->spi, buf, len);
1005 if (status) {
1006 dev_warn(
1007 &spi->dev,
1008 "spi write failed, returned %d\n",
1009 status
1010 );
1011 if (status == -EBUSY)
1012 continue;
1013 if (((buf[0] & SPI_SYN) && response))
1014 complete(&priv->sync_exchange_complete);
1015 goto cleanup;
1016 }
1017
1018 wait_remaining = wait_for_completion_interruptible_timeout(
1019 &priv->spi_transfer_complete,
1020 msecs_to_jiffies(1000)
1021 );
1022 if (wait_remaining == -ERESTARTSYS) {
1023 status = -ERESTARTSYS;
1024 } else if (wait_remaining == 0) {
1025 dev_err(
1026 &spi->dev,
1027 "SPI downstream transfer timed out!\n"
1028 );
1029 status = -ETIME;
1030 goto cleanup;
1031 }
1032 } while (status < 0);
1033
1034 if (!((buf[0] & SPI_SYN) && response))
1035 goto cleanup;
1036
1037 wait_remaining = wait_for_completion_interruptible_timeout(
1038 &priv->sync_exchange_complete,
1039 msecs_to_jiffies(CA8210_SYNC_TIMEOUT)
1040 );
1041 if (wait_remaining == -ERESTARTSYS) {
1042 status = -ERESTARTSYS;
1043 } else if (wait_remaining == 0) {
1044 dev_err(
1045 &spi->dev,
1046 "Synchronous confirm timeout\n"
1047 );
1048 status = -ETIME;
1049 }
1050
1051 cleanup:
1052 priv->sync_command_response = NULL;
1053 return status;
1054 }
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067 static irqreturn_t ca8210_interrupt_handler(int irq, void *dev_id)
1068 {
1069 struct ca8210_priv *priv = dev_id;
1070 int status;
1071
1072 dev_dbg(&priv->spi->dev, "irq: Interrupt occurred\n");
1073 do {
1074 status = ca8210_spi_transfer(priv->spi, NULL, 0);
1075 if (status && (status != -EBUSY)) {
1076 dev_warn(
1077 &priv->spi->dev,
1078 "spi read failed, returned %d\n",
1079 status
1080 );
1081 }
1082 } while (status == -EBUSY);
1083 return IRQ_HANDLED;
1084 }
1085
1086 static int (*cascoda_api_downstream)(
1087 const u8 *buf,
1088 size_t len,
1089 u8 *response,
1090 void *device_ref
1091 ) = ca8210_spi_exchange;
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104 static u8 tdme_setsfr_request_sync(
1105 u8 sfr_page,
1106 u8 sfr_address,
1107 u8 sfr_value,
1108 void *device_ref
1109 )
1110 {
1111 int ret;
1112 struct mac_message command, response;
1113 struct spi_device *spi = device_ref;
1114
1115 command.command_id = SPI_TDME_SETSFR_REQUEST;
1116 command.length = 3;
1117 command.pdata.tdme_set_sfr_req.sfr_page = sfr_page;
1118 command.pdata.tdme_set_sfr_req.sfr_address = sfr_address;
1119 command.pdata.tdme_set_sfr_req.sfr_value = sfr_value;
1120 response.command_id = SPI_IDLE;
1121 ret = cascoda_api_downstream(
1122 &command.command_id,
1123 command.length + 2,
1124 &response.command_id,
1125 device_ref
1126 );
1127 if (ret) {
1128 dev_crit(&spi->dev, "cascoda_api_downstream returned %d", ret);
1129 return MAC_SYSTEM_ERROR;
1130 }
1131
1132 if (response.command_id != SPI_TDME_SETSFR_CONFIRM) {
1133 dev_crit(
1134 &spi->dev,
1135 "sync response to SPI_TDME_SETSFR_REQUEST was not SPI_TDME_SETSFR_CONFIRM, it was %d\n",
1136 response.command_id
1137 );
1138 return MAC_SYSTEM_ERROR;
1139 }
1140
1141 return response.pdata.tdme_set_sfr_cnf.status;
1142 }
1143
1144
1145
1146
1147
1148
1149
1150 static u8 tdme_chipinit(void *device_ref)
1151 {
1152 u8 status = MAC_SUCCESS;
1153 u8 sfr_address;
1154 struct spi_device *spi = device_ref;
1155 struct preamble_cfg_sfr pre_cfg_value = {
1156 .timeout_symbols = 3,
1157 .acquisition_symbols = 3,
1158 .search_symbols = 1,
1159 };
1160
1161 status = tdme_setsfr_request_sync(
1162 1, (sfr_address = CA8210_SFR_LNAGX40),
1163 LNAGX40_DEFAULT_GAIN, device_ref);
1164 if (status)
1165 goto finish;
1166 status = tdme_setsfr_request_sync(
1167 1, (sfr_address = CA8210_SFR_LNAGX41),
1168 LNAGX41_DEFAULT_GAIN, device_ref);
1169 if (status)
1170 goto finish;
1171 status = tdme_setsfr_request_sync(
1172 1, (sfr_address = CA8210_SFR_LNAGX42),
1173 LNAGX42_DEFAULT_GAIN, device_ref);
1174 if (status)
1175 goto finish;
1176 status = tdme_setsfr_request_sync(
1177 1, (sfr_address = CA8210_SFR_LNAGX43),
1178 LNAGX43_DEFAULT_GAIN, device_ref);
1179 if (status)
1180 goto finish;
1181 status = tdme_setsfr_request_sync(
1182 1, (sfr_address = CA8210_SFR_LNAGX44),
1183 LNAGX44_DEFAULT_GAIN, device_ref);
1184 if (status)
1185 goto finish;
1186 status = tdme_setsfr_request_sync(
1187 1, (sfr_address = CA8210_SFR_LNAGX45),
1188 LNAGX45_DEFAULT_GAIN, device_ref);
1189 if (status)
1190 goto finish;
1191 status = tdme_setsfr_request_sync(
1192 1, (sfr_address = CA8210_SFR_LNAGX46),
1193 LNAGX46_DEFAULT_GAIN, device_ref);
1194 if (status)
1195 goto finish;
1196 status = tdme_setsfr_request_sync(
1197 1, (sfr_address = CA8210_SFR_LNAGX47),
1198 LNAGX47_DEFAULT_GAIN, device_ref);
1199 if (status)
1200 goto finish;
1201
1202 status = tdme_setsfr_request_sync(
1203 1, (sfr_address = CA8210_SFR_PRECFG),
1204 *((u8 *)&pre_cfg_value), device_ref);
1205 if (status)
1206 goto finish;
1207
1208 status = tdme_setsfr_request_sync(
1209 1, (sfr_address = CA8210_SFR_PTHRH),
1210 PTHRH_DEFAULT_THRESHOLD, device_ref);
1211 if (status)
1212 goto finish;
1213
1214 status = tdme_setsfr_request_sync(
1215 0, (sfr_address = CA8210_SFR_PACFGIB),
1216 PACFGIB_DEFAULT_CURRENT, device_ref);
1217 if (status)
1218 goto finish;
1219
1220 finish:
1221 if (status != MAC_SUCCESS) {
1222 dev_err(
1223 &spi->dev,
1224 "failed to set sfr at %#03x, status = %#03x\n",
1225 sfr_address,
1226 status
1227 );
1228 }
1229 return status;
1230 }
1231
1232
1233
1234
1235
1236
1237
1238
1239 static u8 tdme_channelinit(u8 channel, void *device_ref)
1240 {
1241
1242
1243
1244 u8 txcalval;
1245
1246 if (channel >= 25)
1247 txcalval = 0xA7;
1248 else if (channel >= 23)
1249 txcalval = 0xA8;
1250 else if (channel >= 22)
1251 txcalval = 0xA9;
1252 else if (channel >= 20)
1253 txcalval = 0xAA;
1254 else if (channel >= 17)
1255 txcalval = 0xAB;
1256 else if (channel >= 16)
1257 txcalval = 0xAC;
1258 else if (channel >= 14)
1259 txcalval = 0xAD;
1260 else if (channel >= 12)
1261 txcalval = 0xAE;
1262 else
1263 txcalval = 0xAF;
1264
1265 return tdme_setsfr_request_sync(
1266 1,
1267 CA8210_SFR_LOTXCAL,
1268 txcalval,
1269 device_ref
1270 );
1271 }
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283 static u8 tdme_checkpibattribute(
1284 u8 pib_attribute,
1285 u8 pib_attribute_length,
1286 const void *pib_attribute_value
1287 )
1288 {
1289 u8 status = MAC_SUCCESS;
1290 u8 value;
1291
1292 value = *((u8 *)pib_attribute_value);
1293
1294 switch (pib_attribute) {
1295
1296 case PHY_TRANSMIT_POWER:
1297 if (value > 0x3F)
1298 status = MAC_INVALID_PARAMETER;
1299 break;
1300 case PHY_CCA_MODE:
1301 if (value > 0x03)
1302 status = MAC_INVALID_PARAMETER;
1303 break;
1304
1305 case MAC_BATT_LIFE_EXT_PERIODS:
1306 if (value < 6 || value > 41)
1307 status = MAC_INVALID_PARAMETER;
1308 break;
1309 case MAC_BEACON_PAYLOAD:
1310 if (pib_attribute_length > MAX_BEACON_PAYLOAD_LENGTH)
1311 status = MAC_INVALID_PARAMETER;
1312 break;
1313 case MAC_BEACON_PAYLOAD_LENGTH:
1314 if (value > MAX_BEACON_PAYLOAD_LENGTH)
1315 status = MAC_INVALID_PARAMETER;
1316 break;
1317 case MAC_BEACON_ORDER:
1318 if (value > 15)
1319 status = MAC_INVALID_PARAMETER;
1320 break;
1321 case MAC_MAX_BE:
1322 if (value < 3 || value > 8)
1323 status = MAC_INVALID_PARAMETER;
1324 break;
1325 case MAC_MAX_CSMA_BACKOFFS:
1326 if (value > 5)
1327 status = MAC_INVALID_PARAMETER;
1328 break;
1329 case MAC_MAX_FRAME_RETRIES:
1330 if (value > 7)
1331 status = MAC_INVALID_PARAMETER;
1332 break;
1333 case MAC_MIN_BE:
1334 if (value > 8)
1335 status = MAC_INVALID_PARAMETER;
1336 break;
1337 case MAC_RESPONSE_WAIT_TIME:
1338 if (value < 2 || value > 64)
1339 status = MAC_INVALID_PARAMETER;
1340 break;
1341 case MAC_SUPERFRAME_ORDER:
1342 if (value > 15)
1343 status = MAC_INVALID_PARAMETER;
1344 break;
1345
1346 case MAC_ASSOCIATED_PAN_COORD:
1347 case MAC_ASSOCIATION_PERMIT:
1348 case MAC_AUTO_REQUEST:
1349 case MAC_BATT_LIFE_EXT:
1350 case MAC_GTS_PERMIT:
1351 case MAC_PROMISCUOUS_MODE:
1352 case MAC_RX_ON_WHEN_IDLE:
1353 case MAC_SECURITY_ENABLED:
1354 if (value > 1)
1355 status = MAC_INVALID_PARAMETER;
1356 break;
1357
1358 case MAC_AUTO_REQUEST_SECURITY_LEVEL:
1359 if (value > 7)
1360 status = MAC_INVALID_PARAMETER;
1361 break;
1362 case MAC_AUTO_REQUEST_KEY_ID_MODE:
1363 if (value > 3)
1364 status = MAC_INVALID_PARAMETER;
1365 break;
1366 default:
1367 break;
1368 }
1369
1370 return status;
1371 }
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384 static u8 tdme_settxpower(u8 txp, void *device_ref)
1385 {
1386 u8 status;
1387 s8 txp_val;
1388 u8 txp_ext;
1389 union pa_cfg_sfr pa_cfg_val;
1390
1391
1392 txp_ext = 0x3F & txp;
1393 if (txp_ext & 0x20)
1394 txp_ext += 0xC0;
1395 txp_val = (s8)txp_ext;
1396
1397 if (CA8210_MAC_MPW) {
1398 if (txp_val > 0) {
1399
1400 pa_cfg_val.bias_current_trim = 3;
1401 pa_cfg_val.buffer_capacitor_trim = 5;
1402 pa_cfg_val.boost = 1;
1403 } else {
1404
1405 pa_cfg_val.bias_current_trim = 3;
1406 pa_cfg_val.buffer_capacitor_trim = 7;
1407 pa_cfg_val.boost = 0;
1408 }
1409
1410 status = tdme_setsfr_request_sync(
1411 0,
1412 CA8210_SFR_PACFG,
1413 pa_cfg_val.paib,
1414 device_ref
1415 );
1416 } else {
1417
1418
1419
1420 if (txp_val > 8) {
1421 pa_cfg_val.paib = 0x3F;
1422 } else if (txp_val == 8) {
1423 pa_cfg_val.paib = 0x32;
1424 } else if (txp_val == 7) {
1425 pa_cfg_val.paib = 0x22;
1426 } else if (txp_val == 6) {
1427 pa_cfg_val.paib = 0x18;
1428 } else if (txp_val == 5) {
1429 pa_cfg_val.paib = 0x10;
1430 } else if (txp_val == 4) {
1431 pa_cfg_val.paib = 0x0C;
1432 } else if (txp_val == 3) {
1433 pa_cfg_val.paib = 0x08;
1434 } else if (txp_val == 2) {
1435 pa_cfg_val.paib = 0x05;
1436 } else if (txp_val == 1) {
1437 pa_cfg_val.paib = 0x03;
1438 } else if (txp_val == 0) {
1439 pa_cfg_val.paib = 0x01;
1440 } else {
1441 pa_cfg_val.paib = 0x00;
1442 }
1443
1444 status = tdme_setsfr_request_sync(
1445 0,
1446 CA8210_SFR_PACFGIB,
1447 pa_cfg_val.paib,
1448 device_ref
1449 );
1450 }
1451
1452 return status;
1453 }
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470 static u8 mcps_data_request(
1471 u8 src_addr_mode,
1472 u8 dst_address_mode,
1473 u16 dst_pan_id,
1474 union macaddr *dst_addr,
1475 u8 msdu_length,
1476 u8 *msdu,
1477 u8 msdu_handle,
1478 u8 tx_options,
1479 struct secspec *security,
1480 void *device_ref
1481 )
1482 {
1483 struct secspec *psec;
1484 struct mac_message command;
1485
1486 command.command_id = SPI_MCPS_DATA_REQUEST;
1487 command.pdata.data_req.src_addr_mode = src_addr_mode;
1488 command.pdata.data_req.dst.mode = dst_address_mode;
1489 if (dst_address_mode != MAC_MODE_NO_ADDR) {
1490 command.pdata.data_req.dst.pan_id[0] = LS_BYTE(dst_pan_id);
1491 command.pdata.data_req.dst.pan_id[1] = MS_BYTE(dst_pan_id);
1492 if (dst_address_mode == MAC_MODE_SHORT_ADDR) {
1493 command.pdata.data_req.dst.address[0] = LS_BYTE(
1494 dst_addr->short_address
1495 );
1496 command.pdata.data_req.dst.address[1] = MS_BYTE(
1497 dst_addr->short_address
1498 );
1499 } else {
1500 memcpy(
1501 command.pdata.data_req.dst.address,
1502 dst_addr->ieee_address,
1503 8
1504 );
1505 }
1506 }
1507 command.pdata.data_req.msdu_length = msdu_length;
1508 command.pdata.data_req.msdu_handle = msdu_handle;
1509 command.pdata.data_req.tx_options = tx_options;
1510 memcpy(command.pdata.data_req.msdu, msdu, msdu_length);
1511 psec = (struct secspec *)(command.pdata.data_req.msdu + msdu_length);
1512 command.length = sizeof(struct mcps_data_request_pset) -
1513 MAX_DATA_SIZE + msdu_length;
1514 if (!security || security->security_level == 0) {
1515 psec->security_level = 0;
1516 command.length += 1;
1517 } else {
1518 *psec = *security;
1519 command.length += sizeof(struct secspec);
1520 }
1521
1522 if (ca8210_spi_transfer(device_ref, &command.command_id,
1523 command.length + 2))
1524 return MAC_SYSTEM_ERROR;
1525
1526 return MAC_SUCCESS;
1527 }
1528
1529
1530
1531
1532
1533
1534
1535
1536 static u8 mlme_reset_request_sync(
1537 u8 set_default_pib,
1538 void *device_ref
1539 )
1540 {
1541 u8 status;
1542 struct mac_message command, response;
1543 struct spi_device *spi = device_ref;
1544
1545 command.command_id = SPI_MLME_RESET_REQUEST;
1546 command.length = 1;
1547 command.pdata.u8param = set_default_pib;
1548
1549 if (cascoda_api_downstream(
1550 &command.command_id,
1551 command.length + 2,
1552 &response.command_id,
1553 device_ref)) {
1554 dev_err(&spi->dev, "cascoda_api_downstream failed\n");
1555 return MAC_SYSTEM_ERROR;
1556 }
1557
1558 if (response.command_id != SPI_MLME_RESET_CONFIRM)
1559 return MAC_SYSTEM_ERROR;
1560
1561 status = response.pdata.status;
1562
1563
1564 if (CA8210_MAC_WORKAROUNDS && set_default_pib && !status) {
1565 status = tdme_setsfr_request_sync(
1566 0,
1567 CA8210_SFR_MACCON,
1568 0,
1569 device_ref
1570 );
1571 }
1572
1573 return status;
1574 }
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586 static u8 mlme_set_request_sync(
1587 u8 pib_attribute,
1588 u8 pib_attribute_index,
1589 u8 pib_attribute_length,
1590 const void *pib_attribute_value,
1591 void *device_ref
1592 )
1593 {
1594 u8 status;
1595 struct mac_message command, response;
1596
1597
1598
1599
1600 if (tdme_checkpibattribute(
1601 pib_attribute, pib_attribute_length, pib_attribute_value)) {
1602 return MAC_INVALID_PARAMETER;
1603 }
1604
1605 if (pib_attribute == PHY_CURRENT_CHANNEL) {
1606 status = tdme_channelinit(
1607 *((u8 *)pib_attribute_value),
1608 device_ref
1609 );
1610 if (status)
1611 return status;
1612 }
1613
1614 if (pib_attribute == PHY_TRANSMIT_POWER) {
1615 return tdme_settxpower(
1616 *((u8 *)pib_attribute_value),
1617 device_ref
1618 );
1619 }
1620
1621 command.command_id = SPI_MLME_SET_REQUEST;
1622 command.length = sizeof(struct mlme_set_request_pset) -
1623 MAX_ATTRIBUTE_SIZE + pib_attribute_length;
1624 command.pdata.set_req.pib_attribute = pib_attribute;
1625 command.pdata.set_req.pib_attribute_index = pib_attribute_index;
1626 command.pdata.set_req.pib_attribute_length = pib_attribute_length;
1627 memcpy(
1628 command.pdata.set_req.pib_attribute_value,
1629 pib_attribute_value,
1630 pib_attribute_length
1631 );
1632
1633 if (cascoda_api_downstream(
1634 &command.command_id,
1635 command.length + 2,
1636 &response.command_id,
1637 device_ref)) {
1638 return MAC_SYSTEM_ERROR;
1639 }
1640
1641 if (response.command_id != SPI_MLME_SET_CONFIRM)
1642 return MAC_SYSTEM_ERROR;
1643
1644 return response.pdata.status;
1645 }
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656 static u8 hwme_set_request_sync(
1657 u8 hw_attribute,
1658 u8 hw_attribute_length,
1659 u8 *hw_attribute_value,
1660 void *device_ref
1661 )
1662 {
1663 struct mac_message command, response;
1664
1665 command.command_id = SPI_HWME_SET_REQUEST;
1666 command.length = 2 + hw_attribute_length;
1667 command.pdata.hwme_set_req.hw_attribute = hw_attribute;
1668 command.pdata.hwme_set_req.hw_attribute_length = hw_attribute_length;
1669 memcpy(
1670 command.pdata.hwme_set_req.hw_attribute_value,
1671 hw_attribute_value,
1672 hw_attribute_length
1673 );
1674
1675 if (cascoda_api_downstream(
1676 &command.command_id,
1677 command.length + 2,
1678 &response.command_id,
1679 device_ref)) {
1680 return MAC_SYSTEM_ERROR;
1681 }
1682
1683 if (response.command_id != SPI_HWME_SET_CONFIRM)
1684 return MAC_SYSTEM_ERROR;
1685
1686 return response.pdata.hwme_set_cnf.status;
1687 }
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698 static u8 hwme_get_request_sync(
1699 u8 hw_attribute,
1700 u8 *hw_attribute_length,
1701 u8 *hw_attribute_value,
1702 void *device_ref
1703 )
1704 {
1705 struct mac_message command, response;
1706
1707 command.command_id = SPI_HWME_GET_REQUEST;
1708 command.length = 1;
1709 command.pdata.hwme_get_req.hw_attribute = hw_attribute;
1710
1711 if (cascoda_api_downstream(
1712 &command.command_id,
1713 command.length + 2,
1714 &response.command_id,
1715 device_ref)) {
1716 return MAC_SYSTEM_ERROR;
1717 }
1718
1719 if (response.command_id != SPI_HWME_GET_CONFIRM)
1720 return MAC_SYSTEM_ERROR;
1721
1722 if (response.pdata.hwme_get_cnf.status == MAC_SUCCESS) {
1723 *hw_attribute_length =
1724 response.pdata.hwme_get_cnf.hw_attribute_length;
1725 memcpy(
1726 hw_attribute_value,
1727 response.pdata.hwme_get_cnf.hw_attribute_value,
1728 *hw_attribute_length
1729 );
1730 }
1731
1732 return response.pdata.hwme_get_cnf.status;
1733 }
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746 static int ca8210_async_xmit_complete(
1747 struct ieee802154_hw *hw,
1748 u8 msduhandle,
1749 u8 status)
1750 {
1751 struct ca8210_priv *priv = hw->priv;
1752
1753 if (priv->nextmsduhandle != msduhandle) {
1754 dev_err(
1755 &priv->spi->dev,
1756 "Unexpected msdu_handle on data confirm, Expected %d, got %d\n",
1757 priv->nextmsduhandle,
1758 msduhandle
1759 );
1760 return -EIO;
1761 }
1762
1763 priv->async_tx_pending = false;
1764 priv->nextmsduhandle++;
1765
1766 if (status) {
1767 dev_err(
1768 &priv->spi->dev,
1769 "Link transmission unsuccessful, status = %d\n",
1770 status
1771 );
1772 if (status != MAC_TRANSACTION_OVERFLOW) {
1773 ieee802154_wake_queue(priv->hw);
1774 return 0;
1775 }
1776 }
1777 ieee802154_xmit_complete(priv->hw, priv->tx_skb, true);
1778
1779 return 0;
1780 }
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795 static int ca8210_skb_rx(
1796 struct ieee802154_hw *hw,
1797 size_t len,
1798 u8 *data_ind
1799 )
1800 {
1801 struct ieee802154_hdr hdr;
1802 int msdulen;
1803 int hlen;
1804 u8 mpdulinkquality = data_ind[23];
1805 struct sk_buff *skb;
1806 struct ca8210_priv *priv = hw->priv;
1807
1808
1809 skb = dev_alloc_skb(IEEE802154_MTU + sizeof(hdr));
1810 if (!skb)
1811 return -ENOMEM;
1812
1813 skb_reserve(skb, sizeof(hdr));
1814
1815 msdulen = data_ind[22];
1816 if (msdulen > IEEE802154_MTU) {
1817 dev_err(
1818 &priv->spi->dev,
1819 "received erroneously large msdu length!\n"
1820 );
1821 kfree_skb(skb);
1822 return -EMSGSIZE;
1823 }
1824 dev_dbg(&priv->spi->dev, "skb buffer length = %d\n", msdulen);
1825
1826 if (priv->promiscuous)
1827 goto copy_payload;
1828
1829
1830 hdr.sec.level = data_ind[29 + msdulen];
1831 dev_dbg(&priv->spi->dev, "security level: %#03x\n", hdr.sec.level);
1832 if (hdr.sec.level > 0) {
1833 hdr.sec.key_id_mode = data_ind[30 + msdulen];
1834 memcpy(&hdr.sec.extended_src, &data_ind[31 + msdulen], 8);
1835 hdr.sec.key_id = data_ind[39 + msdulen];
1836 }
1837 hdr.source.mode = data_ind[0];
1838 dev_dbg(&priv->spi->dev, "srcAddrMode: %#03x\n", hdr.source.mode);
1839 hdr.source.pan_id = *(u16 *)&data_ind[1];
1840 dev_dbg(&priv->spi->dev, "srcPanId: %#06x\n", hdr.source.pan_id);
1841 memcpy(&hdr.source.extended_addr, &data_ind[3], 8);
1842 hdr.dest.mode = data_ind[11];
1843 dev_dbg(&priv->spi->dev, "dstAddrMode: %#03x\n", hdr.dest.mode);
1844 hdr.dest.pan_id = *(u16 *)&data_ind[12];
1845 dev_dbg(&priv->spi->dev, "dstPanId: %#06x\n", hdr.dest.pan_id);
1846 memcpy(&hdr.dest.extended_addr, &data_ind[14], 8);
1847
1848
1849 hdr.fc.type = 1;
1850 if (hdr.sec.level)
1851 hdr.fc.security_enabled = 1;
1852 else
1853 hdr.fc.security_enabled = 0;
1854 if (data_ind[1] != data_ind[12] || data_ind[2] != data_ind[13])
1855 hdr.fc.intra_pan = 1;
1856 else
1857 hdr.fc.intra_pan = 0;
1858 hdr.fc.dest_addr_mode = hdr.dest.mode;
1859 hdr.fc.source_addr_mode = hdr.source.mode;
1860
1861
1862 hlen = ieee802154_hdr_push(skb, &hdr);
1863
1864 if (hlen < 0) {
1865 dev_crit(&priv->spi->dev, "failed to push mac hdr onto skb!\n");
1866 kfree_skb(skb);
1867 return hlen;
1868 }
1869
1870 skb_reset_mac_header(skb);
1871 skb->mac_len = hlen;
1872
1873 copy_payload:
1874
1875
1876 skb_put_data(skb, &data_ind[29], msdulen);
1877
1878 ieee802154_rx_irqsafe(hw, skb, mpdulinkquality);
1879 return 0;
1880 }
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895 static int ca8210_net_rx(struct ieee802154_hw *hw, u8 *command, size_t len)
1896 {
1897 struct ca8210_priv *priv = hw->priv;
1898 unsigned long flags;
1899 u8 status;
1900
1901 dev_dbg(&priv->spi->dev, "%s: CmdID = %d\n", __func__, command[0]);
1902
1903 if (command[0] == SPI_MCPS_DATA_INDICATION) {
1904
1905 spin_lock_irqsave(&priv->lock, flags);
1906 if (command[26] == priv->last_dsn) {
1907 dev_dbg(
1908 &priv->spi->dev,
1909 "DSN %d resend received, ignoring...\n",
1910 command[26]
1911 );
1912 spin_unlock_irqrestore(&priv->lock, flags);
1913 return 0;
1914 }
1915 priv->last_dsn = command[26];
1916 spin_unlock_irqrestore(&priv->lock, flags);
1917 return ca8210_skb_rx(hw, len - 2, command + 2);
1918 } else if (command[0] == SPI_MCPS_DATA_CONFIRM) {
1919 status = command[3];
1920 if (priv->async_tx_pending) {
1921 return ca8210_async_xmit_complete(
1922 hw,
1923 command[2],
1924 status
1925 );
1926 }
1927 }
1928
1929 return 0;
1930 }
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940 static int ca8210_skb_tx(
1941 struct sk_buff *skb,
1942 u8 msduhandle,
1943 struct ca8210_priv *priv
1944 )
1945 {
1946 int status;
1947 struct ieee802154_hdr header = { };
1948 struct secspec secspec;
1949 unsigned int mac_len;
1950
1951 dev_dbg(&priv->spi->dev, "%s called\n", __func__);
1952
1953
1954
1955
1956 mac_len = ieee802154_hdr_peek_addrs(skb, &header);
1957
1958 secspec.security_level = header.sec.level;
1959 secspec.key_id_mode = header.sec.key_id_mode;
1960 if (secspec.key_id_mode == 2)
1961 memcpy(secspec.key_source, &header.sec.short_src, 4);
1962 else if (secspec.key_id_mode == 3)
1963 memcpy(secspec.key_source, &header.sec.extended_src, 8);
1964 secspec.key_index = header.sec.key_id;
1965
1966
1967 status = mcps_data_request(
1968 header.source.mode,
1969 header.dest.mode,
1970 header.dest.pan_id,
1971 (union macaddr *)&header.dest.extended_addr,
1972 skb->len - mac_len,
1973 &skb->data[mac_len],
1974 msduhandle,
1975 header.fc.ack_request,
1976 &secspec,
1977 priv->spi
1978 );
1979 return link_to_linux_err(status);
1980 }
1981
1982
1983
1984
1985
1986
1987
1988 static int ca8210_start(struct ieee802154_hw *hw)
1989 {
1990 int status;
1991 u8 rx_on_when_idle;
1992 u8 lqi_threshold = 0;
1993 struct ca8210_priv *priv = hw->priv;
1994
1995 priv->last_dsn = -1;
1996
1997 rx_on_when_idle = 1;
1998 status = mlme_set_request_sync(
1999 MAC_RX_ON_WHEN_IDLE,
2000 0,
2001 1,
2002 &rx_on_when_idle,
2003 priv->spi
2004 );
2005 if (status) {
2006 dev_crit(
2007 &priv->spi->dev,
2008 "Setting rx_on_when_idle failed, status = %d\n",
2009 status
2010 );
2011 return link_to_linux_err(status);
2012 }
2013 status = hwme_set_request_sync(
2014 HWME_LQILIMIT,
2015 1,
2016 &lqi_threshold,
2017 priv->spi
2018 );
2019 if (status) {
2020 dev_crit(
2021 &priv->spi->dev,
2022 "Setting lqilimit failed, status = %d\n",
2023 status
2024 );
2025 return link_to_linux_err(status);
2026 }
2027
2028 return 0;
2029 }
2030
2031
2032
2033
2034
2035
2036
2037 static void ca8210_stop(struct ieee802154_hw *hw)
2038 {
2039 }
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049 static int ca8210_xmit_async(struct ieee802154_hw *hw, struct sk_buff *skb)
2050 {
2051 struct ca8210_priv *priv = hw->priv;
2052 int status;
2053
2054 dev_dbg(&priv->spi->dev, "calling %s\n", __func__);
2055
2056 priv->tx_skb = skb;
2057 priv->async_tx_pending = true;
2058 status = ca8210_skb_tx(skb, priv->nextmsduhandle, priv);
2059 return status;
2060 }
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070 static int ca8210_get_ed(struct ieee802154_hw *hw, u8 *level)
2071 {
2072 u8 lenvar;
2073 struct ca8210_priv *priv = hw->priv;
2074
2075 return link_to_linux_err(
2076 hwme_get_request_sync(HWME_EDVALUE, &lenvar, level, priv->spi)
2077 );
2078 }
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089 static int ca8210_set_channel(
2090 struct ieee802154_hw *hw,
2091 u8 page,
2092 u8 channel
2093 )
2094 {
2095 u8 status;
2096 struct ca8210_priv *priv = hw->priv;
2097
2098 status = mlme_set_request_sync(
2099 PHY_CURRENT_CHANNEL,
2100 0,
2101 1,
2102 &channel,
2103 priv->spi
2104 );
2105 if (status) {
2106 dev_err(
2107 &priv->spi->dev,
2108 "error setting channel, MLME-SET.confirm status = %d\n",
2109 status
2110 );
2111 }
2112 return link_to_linux_err(status);
2113 }
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128 static int ca8210_set_hw_addr_filt(
2129 struct ieee802154_hw *hw,
2130 struct ieee802154_hw_addr_filt *filt,
2131 unsigned long changed
2132 )
2133 {
2134 u8 status = 0;
2135 struct ca8210_priv *priv = hw->priv;
2136
2137 if (changed & IEEE802154_AFILT_PANID_CHANGED) {
2138 status = mlme_set_request_sync(
2139 MAC_PAN_ID,
2140 0,
2141 2,
2142 &filt->pan_id, priv->spi
2143 );
2144 if (status) {
2145 dev_err(
2146 &priv->spi->dev,
2147 "error setting pan id, MLME-SET.confirm status = %d",
2148 status
2149 );
2150 return link_to_linux_err(status);
2151 }
2152 }
2153 if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
2154 status = mlme_set_request_sync(
2155 MAC_SHORT_ADDRESS,
2156 0,
2157 2,
2158 &filt->short_addr, priv->spi
2159 );
2160 if (status) {
2161 dev_err(
2162 &priv->spi->dev,
2163 "error setting short address, MLME-SET.confirm status = %d",
2164 status
2165 );
2166 return link_to_linux_err(status);
2167 }
2168 }
2169 if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
2170 status = mlme_set_request_sync(
2171 NS_IEEE_ADDRESS,
2172 0,
2173 8,
2174 &filt->ieee_addr,
2175 priv->spi
2176 );
2177 if (status) {
2178 dev_err(
2179 &priv->spi->dev,
2180 "error setting ieee address, MLME-SET.confirm status = %d",
2181 status
2182 );
2183 return link_to_linux_err(status);
2184 }
2185 }
2186
2187 return 0;
2188 }
2189
2190
2191
2192
2193
2194
2195
2196
2197 static int ca8210_set_tx_power(struct ieee802154_hw *hw, s32 mbm)
2198 {
2199 struct ca8210_priv *priv = hw->priv;
2200
2201 mbm /= 100;
2202 return link_to_linux_err(
2203 mlme_set_request_sync(PHY_TRANSMIT_POWER, 0, 1, &mbm, priv->spi)
2204 );
2205 }
2206
2207
2208
2209
2210
2211
2212
2213
2214 static int ca8210_set_cca_mode(
2215 struct ieee802154_hw *hw,
2216 const struct wpan_phy_cca *cca
2217 )
2218 {
2219 u8 status;
2220 u8 cca_mode;
2221 struct ca8210_priv *priv = hw->priv;
2222
2223 cca_mode = cca->mode & 3;
2224 if (cca_mode == 3 && cca->opt == NL802154_CCA_OPT_ENERGY_CARRIER_OR) {
2225
2226 cca_mode = 0;
2227 }
2228 status = mlme_set_request_sync(
2229 PHY_CCA_MODE,
2230 0,
2231 1,
2232 &cca_mode,
2233 priv->spi
2234 );
2235 if (status) {
2236 dev_err(
2237 &priv->spi->dev,
2238 "error setting cca mode, MLME-SET.confirm status = %d",
2239 status
2240 );
2241 }
2242 return link_to_linux_err(status);
2243 }
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255 static int ca8210_set_cca_ed_level(struct ieee802154_hw *hw, s32 level)
2256 {
2257 u8 status;
2258 u8 ed_threshold = (level / 100) * 2 + 256;
2259 struct ca8210_priv *priv = hw->priv;
2260
2261 status = hwme_set_request_sync(
2262 HWME_EDTHRESHOLD,
2263 1,
2264 &ed_threshold,
2265 priv->spi
2266 );
2267 if (status) {
2268 dev_err(
2269 &priv->spi->dev,
2270 "error setting ed threshold, HWME-SET.confirm status = %d",
2271 status
2272 );
2273 }
2274 return link_to_linux_err(status);
2275 }
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286 static int ca8210_set_csma_params(
2287 struct ieee802154_hw *hw,
2288 u8 min_be,
2289 u8 max_be,
2290 u8 retries
2291 )
2292 {
2293 u8 status;
2294 struct ca8210_priv *priv = hw->priv;
2295
2296 status = mlme_set_request_sync(MAC_MIN_BE, 0, 1, &min_be, priv->spi);
2297 if (status) {
2298 dev_err(
2299 &priv->spi->dev,
2300 "error setting min be, MLME-SET.confirm status = %d",
2301 status
2302 );
2303 return link_to_linux_err(status);
2304 }
2305 status = mlme_set_request_sync(MAC_MAX_BE, 0, 1, &max_be, priv->spi);
2306 if (status) {
2307 dev_err(
2308 &priv->spi->dev,
2309 "error setting max be, MLME-SET.confirm status = %d",
2310 status
2311 );
2312 return link_to_linux_err(status);
2313 }
2314 status = mlme_set_request_sync(
2315 MAC_MAX_CSMA_BACKOFFS,
2316 0,
2317 1,
2318 &retries,
2319 priv->spi
2320 );
2321 if (status) {
2322 dev_err(
2323 &priv->spi->dev,
2324 "error setting max csma backoffs, MLME-SET.confirm status = %d",
2325 status
2326 );
2327 }
2328 return link_to_linux_err(status);
2329 }
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341 static int ca8210_set_frame_retries(struct ieee802154_hw *hw, s8 retries)
2342 {
2343 u8 status;
2344 struct ca8210_priv *priv = hw->priv;
2345
2346 status = mlme_set_request_sync(
2347 MAC_MAX_FRAME_RETRIES,
2348 0,
2349 1,
2350 &retries,
2351 priv->spi
2352 );
2353 if (status) {
2354 dev_err(
2355 &priv->spi->dev,
2356 "error setting frame retries, MLME-SET.confirm status = %d",
2357 status
2358 );
2359 }
2360 return link_to_linux_err(status);
2361 }
2362
2363 static int ca8210_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on)
2364 {
2365 u8 status;
2366 struct ca8210_priv *priv = hw->priv;
2367
2368 status = mlme_set_request_sync(
2369 MAC_PROMISCUOUS_MODE,
2370 0,
2371 1,
2372 (const void *)&on,
2373 priv->spi
2374 );
2375 if (status) {
2376 dev_err(
2377 &priv->spi->dev,
2378 "error setting promiscuous mode, MLME-SET.confirm status = %d",
2379 status
2380 );
2381 } else {
2382 priv->promiscuous = on;
2383 }
2384 return link_to_linux_err(status);
2385 }
2386
2387 static const struct ieee802154_ops ca8210_phy_ops = {
2388 .start = ca8210_start,
2389 .stop = ca8210_stop,
2390 .xmit_async = ca8210_xmit_async,
2391 .ed = ca8210_get_ed,
2392 .set_channel = ca8210_set_channel,
2393 .set_hw_addr_filt = ca8210_set_hw_addr_filt,
2394 .set_txpower = ca8210_set_tx_power,
2395 .set_cca_mode = ca8210_set_cca_mode,
2396 .set_cca_ed_level = ca8210_set_cca_ed_level,
2397 .set_csma_params = ca8210_set_csma_params,
2398 .set_frame_retries = ca8210_set_frame_retries,
2399 .set_promiscuous_mode = ca8210_set_promiscuous_mode
2400 };
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411 static int ca8210_test_int_open(struct inode *inodp, struct file *filp)
2412 {
2413 struct ca8210_priv *priv = inodp->i_private;
2414
2415 filp->private_data = priv;
2416 return 0;
2417 }
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427 static int ca8210_test_check_upstream(u8 *buf, void *device_ref)
2428 {
2429 int ret;
2430 u8 response[CA8210_SPI_BUF_SIZE];
2431
2432 if (buf[0] == SPI_MLME_SET_REQUEST) {
2433 ret = tdme_checkpibattribute(buf[2], buf[4], buf + 5);
2434 if (ret) {
2435 response[0] = SPI_MLME_SET_CONFIRM;
2436 response[1] = 3;
2437 response[2] = MAC_INVALID_PARAMETER;
2438 response[3] = buf[2];
2439 response[4] = buf[3];
2440 if (cascoda_api_upstream)
2441 cascoda_api_upstream(response, 5, device_ref);
2442 return ret;
2443 }
2444 }
2445 if (buf[0] == SPI_MLME_ASSOCIATE_REQUEST) {
2446 return tdme_channelinit(buf[2], device_ref);
2447 } else if (buf[0] == SPI_MLME_START_REQUEST) {
2448 return tdme_channelinit(buf[4], device_ref);
2449 } else if (
2450 (buf[0] == SPI_MLME_SET_REQUEST) &&
2451 (buf[2] == PHY_CURRENT_CHANNEL)
2452 ) {
2453 return tdme_channelinit(buf[5], device_ref);
2454 } else if (
2455 (buf[0] == SPI_TDME_SET_REQUEST) &&
2456 (buf[2] == TDME_CHANNEL)
2457 ) {
2458 return tdme_channelinit(buf[4], device_ref);
2459 } else if (
2460 (CA8210_MAC_WORKAROUNDS) &&
2461 (buf[0] == SPI_MLME_RESET_REQUEST) &&
2462 (buf[2] == 1)
2463 ) {
2464
2465 return tdme_setsfr_request_sync(
2466 0,
2467 CA8210_SFR_MACCON,
2468 0,
2469 device_ref
2470 );
2471 }
2472 return 0;
2473 }
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485 static ssize_t ca8210_test_int_user_write(
2486 struct file *filp,
2487 const char __user *in_buf,
2488 size_t len,
2489 loff_t *off
2490 )
2491 {
2492 int ret;
2493 struct ca8210_priv *priv = filp->private_data;
2494 u8 command[CA8210_SPI_BUF_SIZE];
2495
2496 memset(command, SPI_IDLE, 6);
2497 if (len > CA8210_SPI_BUF_SIZE || len < 2) {
2498 dev_warn(
2499 &priv->spi->dev,
2500 "userspace requested erroneous write length (%zu)\n",
2501 len
2502 );
2503 return -EBADE;
2504 }
2505
2506 ret = copy_from_user(command, in_buf, len);
2507 if (ret) {
2508 dev_err(
2509 &priv->spi->dev,
2510 "%d bytes could not be copied from userspace\n",
2511 ret
2512 );
2513 return -EIO;
2514 }
2515 if (len != command[1] + 2) {
2516 dev_err(
2517 &priv->spi->dev,
2518 "write len does not match packet length field\n"
2519 );
2520 return -EBADE;
2521 }
2522
2523 ret = ca8210_test_check_upstream(command, priv->spi);
2524 if (ret == 0) {
2525 ret = ca8210_spi_exchange(
2526 command,
2527 command[1] + 2,
2528 NULL,
2529 priv->spi
2530 );
2531 if (ret < 0) {
2532
2533 dev_err(
2534 &priv->spi->dev,
2535 "spi exchange failed\n"
2536 );
2537 return ret;
2538 }
2539 if (command[0] & SPI_SYN)
2540 priv->sync_down++;
2541 }
2542
2543 return len;
2544 }
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560 static ssize_t ca8210_test_int_user_read(
2561 struct file *filp,
2562 char __user *buf,
2563 size_t len,
2564 loff_t *offp
2565 )
2566 {
2567 int i, cmdlen;
2568 struct ca8210_priv *priv = filp->private_data;
2569 unsigned char *fifo_buffer;
2570 unsigned long bytes_not_copied;
2571
2572 if (filp->f_flags & O_NONBLOCK) {
2573
2574 if (kfifo_is_empty(&priv->test.up_fifo))
2575 return 0;
2576 } else {
2577
2578 wait_event_interruptible(
2579 priv->test.readq,
2580 !kfifo_is_empty(&priv->test.up_fifo)
2581 );
2582 }
2583
2584 if (kfifo_out(&priv->test.up_fifo, &fifo_buffer, 4) != 4) {
2585 dev_err(
2586 &priv->spi->dev,
2587 "test_interface: Wrong number of elements popped from upstream fifo\n"
2588 );
2589 return 0;
2590 }
2591 cmdlen = fifo_buffer[1];
2592 bytes_not_copied = cmdlen + 2;
2593
2594 bytes_not_copied = copy_to_user(buf, fifo_buffer, bytes_not_copied);
2595 if (bytes_not_copied > 0) {
2596 dev_err(
2597 &priv->spi->dev,
2598 "%lu bytes could not be copied to user space!\n",
2599 bytes_not_copied
2600 );
2601 }
2602
2603 dev_dbg(&priv->spi->dev, "test_interface: Cmd len = %d\n", cmdlen);
2604
2605 dev_dbg(&priv->spi->dev, "test_interface: Read\n");
2606 for (i = 0; i < cmdlen + 2; i++)
2607 dev_dbg(&priv->spi->dev, "%#03x\n", fifo_buffer[i]);
2608
2609 kfree(fifo_buffer);
2610
2611 return cmdlen + 2;
2612 }
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623 static long ca8210_test_int_ioctl(
2624 struct file *filp,
2625 unsigned int ioctl_num,
2626 unsigned long ioctl_param
2627 )
2628 {
2629 struct ca8210_priv *priv = filp->private_data;
2630
2631 switch (ioctl_num) {
2632 case CA8210_IOCTL_HARD_RESET:
2633 ca8210_reset_send(priv->spi, ioctl_param);
2634 break;
2635 default:
2636 break;
2637 }
2638 return 0;
2639 }
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649 static __poll_t ca8210_test_int_poll(
2650 struct file *filp,
2651 struct poll_table_struct *ptable
2652 )
2653 {
2654 __poll_t return_flags = 0;
2655 struct ca8210_priv *priv = filp->private_data;
2656
2657 poll_wait(filp, &priv->test.readq, ptable);
2658 if (!kfifo_is_empty(&priv->test.up_fifo))
2659 return_flags |= (EPOLLIN | EPOLLRDNORM);
2660 if (wait_event_interruptible(
2661 priv->test.readq,
2662 !kfifo_is_empty(&priv->test.up_fifo))) {
2663 return EPOLLERR;
2664 }
2665 return return_flags;
2666 }
2667
2668 static const struct file_operations test_int_fops = {
2669 .read = ca8210_test_int_user_read,
2670 .write = ca8210_test_int_user_write,
2671 .open = ca8210_test_int_open,
2672 .release = NULL,
2673 .unlocked_ioctl = ca8210_test_int_ioctl,
2674 .poll = ca8210_test_int_poll
2675 };
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686 static int ca8210_get_platform_data(
2687 struct spi_device *spi_device,
2688 struct ca8210_platform_data *pdata
2689 )
2690 {
2691 int ret = 0;
2692
2693 if (!spi_device->dev.of_node)
2694 return -EINVAL;
2695
2696 pdata->extclockenable = of_property_read_bool(
2697 spi_device->dev.of_node,
2698 "extclock-enable"
2699 );
2700 if (pdata->extclockenable) {
2701 ret = of_property_read_u32(
2702 spi_device->dev.of_node,
2703 "extclock-freq",
2704 &pdata->extclockfreq
2705 );
2706 if (ret < 0)
2707 return ret;
2708
2709 ret = of_property_read_u32(
2710 spi_device->dev.of_node,
2711 "extclock-gpio",
2712 &pdata->extclockgpio
2713 );
2714 }
2715
2716 return ret;
2717 }
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731 static int ca8210_config_extern_clk(
2732 struct ca8210_platform_data *pdata,
2733 struct spi_device *spi,
2734 bool on
2735 )
2736 {
2737 u8 clkparam[2];
2738
2739 if (on) {
2740 dev_info(&spi->dev, "Switching external clock on\n");
2741 switch (pdata->extclockfreq) {
2742 case SIXTEEN_MHZ:
2743 clkparam[0] = 1;
2744 break;
2745 case EIGHT_MHZ:
2746 clkparam[0] = 2;
2747 break;
2748 case FOUR_MHZ:
2749 clkparam[0] = 3;
2750 break;
2751 case TWO_MHZ:
2752 clkparam[0] = 4;
2753 break;
2754 case ONE_MHZ:
2755 clkparam[0] = 5;
2756 break;
2757 default:
2758 dev_crit(&spi->dev, "Invalid extclock-freq\n");
2759 return -EINVAL;
2760 }
2761 clkparam[1] = pdata->extclockgpio;
2762 } else {
2763 dev_info(&spi->dev, "Switching external clock off\n");
2764 clkparam[0] = 0;
2765 clkparam[1] = 0;
2766 }
2767 return link_to_linux_err(
2768 hwme_set_request_sync(HWME_SYSCLKOUT, 2, clkparam, spi)
2769 );
2770 }
2771
2772
2773
2774
2775
2776
2777
2778 static int ca8210_register_ext_clock(struct spi_device *spi)
2779 {
2780 struct device_node *np = spi->dev.of_node;
2781 struct ca8210_priv *priv = spi_get_drvdata(spi);
2782 struct ca8210_platform_data *pdata = spi->dev.platform_data;
2783 int ret = 0;
2784
2785 if (!np)
2786 return -EFAULT;
2787
2788 priv->clk = clk_register_fixed_rate(
2789 &spi->dev,
2790 np->name,
2791 NULL,
2792 0,
2793 pdata->extclockfreq
2794 );
2795
2796 if (IS_ERR(priv->clk)) {
2797 dev_crit(&spi->dev, "Failed to register external clk\n");
2798 return PTR_ERR(priv->clk);
2799 }
2800 ret = of_clk_add_provider(np, of_clk_src_simple_get, priv->clk);
2801 if (ret) {
2802 clk_unregister(priv->clk);
2803 dev_crit(
2804 &spi->dev,
2805 "Failed to register external clock as clock provider\n"
2806 );
2807 } else {
2808 dev_info(&spi->dev, "External clock set as clock provider\n");
2809 }
2810
2811 return ret;
2812 }
2813
2814
2815
2816
2817
2818
2819 static void ca8210_unregister_ext_clock(struct spi_device *spi)
2820 {
2821 struct ca8210_priv *priv = spi_get_drvdata(spi);
2822
2823 if (!priv->clk)
2824 return
2825
2826 of_clk_del_provider(spi->dev.of_node);
2827 clk_unregister(priv->clk);
2828 dev_info(&spi->dev, "External clock unregistered\n");
2829 }
2830
2831
2832
2833
2834
2835
2836
2837 static int ca8210_reset_init(struct spi_device *spi)
2838 {
2839 int ret;
2840 struct ca8210_platform_data *pdata = spi->dev.platform_data;
2841
2842 pdata->gpio_reset = of_get_named_gpio(
2843 spi->dev.of_node,
2844 "reset-gpio",
2845 0
2846 );
2847
2848 ret = gpio_direction_output(pdata->gpio_reset, 1);
2849 if (ret < 0) {
2850 dev_crit(
2851 &spi->dev,
2852 "Reset GPIO %d did not set to output mode\n",
2853 pdata->gpio_reset
2854 );
2855 }
2856
2857 return ret;
2858 }
2859
2860
2861
2862
2863
2864
2865
2866 static int ca8210_interrupt_init(struct spi_device *spi)
2867 {
2868 int ret;
2869 struct ca8210_platform_data *pdata = spi->dev.platform_data;
2870
2871 pdata->gpio_irq = of_get_named_gpio(
2872 spi->dev.of_node,
2873 "irq-gpio",
2874 0
2875 );
2876
2877 pdata->irq_id = gpio_to_irq(pdata->gpio_irq);
2878 if (pdata->irq_id < 0) {
2879 dev_crit(
2880 &spi->dev,
2881 "Could not get irq for gpio pin %d\n",
2882 pdata->gpio_irq
2883 );
2884 gpio_free(pdata->gpio_irq);
2885 return pdata->irq_id;
2886 }
2887
2888 ret = request_irq(
2889 pdata->irq_id,
2890 ca8210_interrupt_handler,
2891 IRQF_TRIGGER_FALLING,
2892 "ca8210-irq",
2893 spi_get_drvdata(spi)
2894 );
2895 if (ret) {
2896 dev_crit(&spi->dev, "request_irq %d failed\n", pdata->irq_id);
2897 gpio_unexport(pdata->gpio_irq);
2898 gpio_free(pdata->gpio_irq);
2899 }
2900
2901 return ret;
2902 }
2903
2904
2905
2906
2907
2908
2909
2910 static int ca8210_dev_com_init(struct ca8210_priv *priv)
2911 {
2912 priv->mlme_workqueue = alloc_ordered_workqueue(
2913 "MLME work queue",
2914 WQ_UNBOUND
2915 );
2916 if (!priv->mlme_workqueue) {
2917 dev_crit(&priv->spi->dev, "alloc of mlme_workqueue failed!\n");
2918 return -ENOMEM;
2919 }
2920
2921 priv->irq_workqueue = alloc_ordered_workqueue(
2922 "ca8210 irq worker",
2923 WQ_UNBOUND
2924 );
2925 if (!priv->irq_workqueue) {
2926 dev_crit(&priv->spi->dev, "alloc of irq_workqueue failed!\n");
2927 return -ENOMEM;
2928 }
2929
2930 return 0;
2931 }
2932
2933
2934
2935
2936
2937 static void ca8210_dev_com_clear(struct ca8210_priv *priv)
2938 {
2939 flush_workqueue(priv->mlme_workqueue);
2940 destroy_workqueue(priv->mlme_workqueue);
2941 flush_workqueue(priv->irq_workqueue);
2942 destroy_workqueue(priv->irq_workqueue);
2943 }
2944
2945 #define CA8210_MAX_TX_POWERS (9)
2946 static const s32 ca8210_tx_powers[CA8210_MAX_TX_POWERS] = {
2947 800, 700, 600, 500, 400, 300, 200, 100, 0
2948 };
2949
2950 #define CA8210_MAX_ED_LEVELS (21)
2951 static const s32 ca8210_ed_levels[CA8210_MAX_ED_LEVELS] = {
2952 -10300, -10250, -10200, -10150, -10100, -10050, -10000, -9950, -9900,
2953 -9850, -9800, -9750, -9700, -9650, -9600, -9550, -9500, -9450, -9400,
2954 -9350, -9300
2955 };
2956
2957
2958
2959
2960
2961
2962 static void ca8210_hw_setup(struct ieee802154_hw *ca8210_hw)
2963 {
2964
2965 ca8210_hw->phy->supported.channels[0] = CA8210_VALID_CHANNELS;
2966 ca8210_hw->phy->supported.tx_powers_size = CA8210_MAX_TX_POWERS;
2967 ca8210_hw->phy->supported.tx_powers = ca8210_tx_powers;
2968 ca8210_hw->phy->supported.cca_ed_levels_size = CA8210_MAX_ED_LEVELS;
2969 ca8210_hw->phy->supported.cca_ed_levels = ca8210_ed_levels;
2970 ca8210_hw->phy->current_channel = 18;
2971 ca8210_hw->phy->current_page = 0;
2972 ca8210_hw->phy->transmit_power = 800;
2973 ca8210_hw->phy->cca.mode = NL802154_CCA_ENERGY_CARRIER;
2974 ca8210_hw->phy->cca.opt = NL802154_CCA_OPT_ENERGY_CARRIER_AND;
2975 ca8210_hw->phy->cca_ed_level = -9800;
2976 ca8210_hw->phy->symbol_duration = 16;
2977 ca8210_hw->phy->lifs_period = 40;
2978 ca8210_hw->phy->sifs_period = 12;
2979 ca8210_hw->flags =
2980 IEEE802154_HW_AFILT |
2981 IEEE802154_HW_OMIT_CKSUM |
2982 IEEE802154_HW_FRAME_RETRIES |
2983 IEEE802154_HW_PROMISCUOUS |
2984 IEEE802154_HW_CSMA_PARAMS;
2985 ca8210_hw->phy->flags =
2986 WPAN_PHY_FLAG_TXPOWER |
2987 WPAN_PHY_FLAG_CCA_ED_LEVEL |
2988 WPAN_PHY_FLAG_CCA_MODE;
2989 }
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002 static int ca8210_test_interface_init(struct ca8210_priv *priv)
3003 {
3004 struct ca8210_test *test = &priv->test;
3005 char node_name[32];
3006
3007 snprintf(
3008 node_name,
3009 sizeof(node_name),
3010 "ca8210@%d_%d",
3011 priv->spi->master->bus_num,
3012 priv->spi->chip_select
3013 );
3014
3015 test->ca8210_dfs_spi_int = debugfs_create_file(
3016 node_name,
3017 0600,
3018 NULL,
3019 priv,
3020 &test_int_fops
3021 );
3022
3023 debugfs_create_symlink("ca8210", NULL, node_name);
3024 init_waitqueue_head(&test->readq);
3025 return kfifo_alloc(
3026 &test->up_fifo,
3027 CA8210_TEST_INT_FIFO_SIZE,
3028 GFP_KERNEL
3029 );
3030 }
3031
3032
3033
3034
3035
3036 static void ca8210_test_interface_clear(struct ca8210_priv *priv)
3037 {
3038 struct ca8210_test *test = &priv->test;
3039
3040 debugfs_remove(test->ca8210_dfs_spi_int);
3041 kfifo_free(&test->up_fifo);
3042 dev_info(&priv->spi->dev, "Test interface removed\n");
3043 }
3044
3045
3046
3047
3048
3049
3050
3051 static int ca8210_remove(struct spi_device *spi_device)
3052 {
3053 struct ca8210_priv *priv;
3054 struct ca8210_platform_data *pdata;
3055
3056 dev_info(&spi_device->dev, "Removing ca8210\n");
3057
3058 pdata = spi_device->dev.platform_data;
3059 if (pdata) {
3060 if (pdata->extclockenable) {
3061 ca8210_unregister_ext_clock(spi_device);
3062 ca8210_config_extern_clk(pdata, spi_device, 0);
3063 }
3064 free_irq(pdata->irq_id, spi_device->dev.driver_data);
3065 kfree(pdata);
3066 spi_device->dev.platform_data = NULL;
3067 }
3068
3069 priv = spi_get_drvdata(spi_device);
3070 if (priv) {
3071 dev_info(
3072 &spi_device->dev,
3073 "sync_down = %d, sync_up = %d\n",
3074 priv->sync_down,
3075 priv->sync_up
3076 );
3077 ca8210_dev_com_clear(spi_device->dev.driver_data);
3078 if (priv->hw) {
3079 if (priv->hw_registered)
3080 ieee802154_unregister_hw(priv->hw);
3081 ieee802154_free_hw(priv->hw);
3082 priv->hw = NULL;
3083 dev_info(
3084 &spi_device->dev,
3085 "Unregistered & freed ieee802154_hw.\n"
3086 );
3087 }
3088 if (IS_ENABLED(CONFIG_IEEE802154_CA8210_DEBUGFS))
3089 ca8210_test_interface_clear(priv);
3090 }
3091
3092 return 0;
3093 }
3094
3095
3096
3097
3098
3099
3100
3101 static int ca8210_probe(struct spi_device *spi_device)
3102 {
3103 struct ca8210_priv *priv;
3104 struct ieee802154_hw *hw;
3105 struct ca8210_platform_data *pdata;
3106 int ret;
3107
3108 dev_info(&spi_device->dev, "Inserting ca8210\n");
3109
3110
3111 hw = ieee802154_alloc_hw(sizeof(struct ca8210_priv), &ca8210_phy_ops);
3112 if (!hw) {
3113 dev_crit(&spi_device->dev, "ieee802154_alloc_hw failed\n");
3114 ret = -ENOMEM;
3115 goto error;
3116 }
3117
3118 priv = hw->priv;
3119 priv->hw = hw;
3120 priv->spi = spi_device;
3121 hw->parent = &spi_device->dev;
3122 spin_lock_init(&priv->lock);
3123 priv->async_tx_pending = false;
3124 priv->hw_registered = false;
3125 priv->sync_up = 0;
3126 priv->sync_down = 0;
3127 priv->promiscuous = false;
3128 priv->retries = 0;
3129 init_completion(&priv->ca8210_is_awake);
3130 init_completion(&priv->spi_transfer_complete);
3131 init_completion(&priv->sync_exchange_complete);
3132 spi_set_drvdata(priv->spi, priv);
3133 if (IS_ENABLED(CONFIG_IEEE802154_CA8210_DEBUGFS)) {
3134 cascoda_api_upstream = ca8210_test_int_driver_write;
3135 ca8210_test_interface_init(priv);
3136 } else {
3137 cascoda_api_upstream = NULL;
3138 }
3139 ca8210_hw_setup(hw);
3140 ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
3141
3142 pdata = kmalloc(sizeof(*pdata), GFP_KERNEL);
3143 if (!pdata) {
3144 ret = -ENOMEM;
3145 goto error;
3146 }
3147
3148 priv->spi->dev.platform_data = pdata;
3149 ret = ca8210_get_platform_data(priv->spi, pdata);
3150 if (ret) {
3151 dev_crit(&spi_device->dev, "ca8210_get_platform_data failed\n");
3152 goto error;
3153 }
3154
3155 ret = ca8210_dev_com_init(priv);
3156 if (ret) {
3157 dev_crit(&spi_device->dev, "ca8210_dev_com_init failed\n");
3158 goto error;
3159 }
3160 ret = ca8210_reset_init(priv->spi);
3161 if (ret) {
3162 dev_crit(&spi_device->dev, "ca8210_reset_init failed\n");
3163 goto error;
3164 }
3165
3166 ret = ca8210_interrupt_init(priv->spi);
3167 if (ret) {
3168 dev_crit(&spi_device->dev, "ca8210_interrupt_init failed\n");
3169 goto error;
3170 }
3171
3172 msleep(100);
3173
3174 ca8210_reset_send(priv->spi, 1);
3175
3176 ret = tdme_chipinit(priv->spi);
3177 if (ret) {
3178 dev_crit(&spi_device->dev, "tdme_chipinit failed\n");
3179 goto error;
3180 }
3181
3182 if (pdata->extclockenable) {
3183 ret = ca8210_config_extern_clk(pdata, priv->spi, 1);
3184 if (ret) {
3185 dev_crit(
3186 &spi_device->dev,
3187 "ca8210_config_extern_clk failed\n"
3188 );
3189 goto error;
3190 }
3191 ret = ca8210_register_ext_clock(priv->spi);
3192 if (ret) {
3193 dev_crit(
3194 &spi_device->dev,
3195 "ca8210_register_ext_clock failed\n"
3196 );
3197 goto error;
3198 }
3199 }
3200
3201 ret = ieee802154_register_hw(hw);
3202 if (ret) {
3203 dev_crit(&spi_device->dev, "ieee802154_register_hw failed\n");
3204 goto error;
3205 }
3206 priv->hw_registered = true;
3207
3208 return 0;
3209 error:
3210 msleep(100);
3211 ca8210_remove(spi_device);
3212 return link_to_linux_err(ret);
3213 }
3214
3215 static const struct of_device_id ca8210_of_ids[] = {
3216 {.compatible = "cascoda,ca8210", },
3217 {},
3218 };
3219 MODULE_DEVICE_TABLE(of, ca8210_of_ids);
3220
3221 static struct spi_driver ca8210_spi_driver = {
3222 .driver = {
3223 .name = DRIVER_NAME,
3224 .owner = THIS_MODULE,
3225 .of_match_table = of_match_ptr(ca8210_of_ids),
3226 },
3227 .probe = ca8210_probe,
3228 .remove = ca8210_remove
3229 };
3230
3231 module_spi_driver(ca8210_spi_driver);
3232
3233 MODULE_AUTHOR("Harry Morris <h.morris@cascoda.com>");
3234 MODULE_DESCRIPTION("CA-8210 SoftMAC driver");
3235 MODULE_LICENSE("Dual BSD/GPL");
3236 MODULE_VERSION("1.0");