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
305struct 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
322struct 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
356struct 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
384struct 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
399struct 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
415struct fulladdr {
416 u8 mode;
417 u8 pan_id[2];
418 u8 address[8];
419};
420
421
422
423
424
425
426
427union macaddr {
428 u16 short_address;
429 u8 ieee_address[8];
430};
431
432
433
434
435
436
437
438
439
440struct secspec {
441 u8 security_level;
442 u8 key_id_mode;
443 u8 key_source[8];
444 u8 key_index;
445};
446
447
448struct 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
457struct 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
464struct hwme_set_request_pset {
465 u8 hw_attribute;
466 u8 hw_attribute_length;
467 u8 hw_attribute_value[MAX_HWME_ATTRIBUTE_SIZE];
468};
469
470struct hwme_get_request_pset {
471 u8 hw_attribute;
472};
473
474struct tdme_setsfr_request_pset {
475 u8 sfr_page;
476 u8 sfr_address;
477 u8 sfr_value;
478};
479
480
481struct hwme_set_confirm_pset {
482 u8 status;
483 u8 hw_attribute;
484};
485
486struct 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
493struct tdme_setsfr_confirm_pset {
494 u8 status;
495 u8 sfr_page;
496 u8 sfr_address;
497};
498
499struct 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
517union 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
527struct preamble_cfg_sfr {
528 u8 timeout_symbols : 3;
529 u8 acquisition_symbols : 3;
530 u8 search_symbols : 2;
531};
532
533static 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
546static 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
620static 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
649static int ca8210_net_rx(
650 struct ieee802154_hw *hw,
651 u8 *command,
652 size_t len
653);
654static u8 mlme_reset_request_sync(
655 u8 set_default_pib,
656 void *device_ref
657);
658static int ca8210_spi_transfer(
659 struct spi_device *spi,
660 const u8 *buf,
661 size_t len
662);
663
664
665
666
667
668
669static 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
701static 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
722static 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
830finish:;
831}
832
833static int ca8210_remove(struct spi_device *spi_device);
834
835
836
837
838
839
840static 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
909static 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.value = 0;
950 cas_ctl->transfer.delay.unit = SPI_DELAY_UNIT_USECS;
951 cas_ctl->transfer.cs_change = 0;
952 cas_ctl->transfer.len = sizeof(struct mac_message);
953 cas_ctl->msg.complete = ca8210_spi_transfer_complete;
954 cas_ctl->msg.context = cas_ctl;
955
956 spi_message_add_tail(
957 &cas_ctl->transfer,
958 &cas_ctl->msg
959 );
960
961 status = spi_async(spi, &cas_ctl->msg);
962 if (status < 0) {
963 dev_crit(
964 &spi->dev,
965 "status %d from spi_sync in write\n",
966 status
967 );
968 }
969
970 return status;
971}
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986static int ca8210_spi_exchange(
987 const u8 *buf,
988 size_t len,
989 u8 *response,
990 void *device_ref
991)
992{
993 int status = 0;
994 struct spi_device *spi = device_ref;
995 struct ca8210_priv *priv = spi->dev.driver_data;
996 long wait_remaining;
997
998 if ((buf[0] & SPI_SYN) && response) {
999 reinit_completion(&priv->sync_exchange_complete);
1000 priv->sync_command_response = response;
1001 }
1002
1003 do {
1004 reinit_completion(&priv->spi_transfer_complete);
1005 status = ca8210_spi_transfer(priv->spi, buf, len);
1006 if (status) {
1007 dev_warn(
1008 &spi->dev,
1009 "spi write failed, returned %d\n",
1010 status
1011 );
1012 if (status == -EBUSY)
1013 continue;
1014 if (((buf[0] & SPI_SYN) && response))
1015 complete(&priv->sync_exchange_complete);
1016 goto cleanup;
1017 }
1018
1019 wait_remaining = wait_for_completion_interruptible_timeout(
1020 &priv->spi_transfer_complete,
1021 msecs_to_jiffies(1000)
1022 );
1023 if (wait_remaining == -ERESTARTSYS) {
1024 status = -ERESTARTSYS;
1025 } else if (wait_remaining == 0) {
1026 dev_err(
1027 &spi->dev,
1028 "SPI downstream transfer timed out!\n"
1029 );
1030 status = -ETIME;
1031 goto cleanup;
1032 }
1033 } while (status < 0);
1034
1035 if (!((buf[0] & SPI_SYN) && response))
1036 goto cleanup;
1037
1038 wait_remaining = wait_for_completion_interruptible_timeout(
1039 &priv->sync_exchange_complete,
1040 msecs_to_jiffies(CA8210_SYNC_TIMEOUT)
1041 );
1042 if (wait_remaining == -ERESTARTSYS) {
1043 status = -ERESTARTSYS;
1044 } else if (wait_remaining == 0) {
1045 dev_err(
1046 &spi->dev,
1047 "Synchronous confirm timeout\n"
1048 );
1049 status = -ETIME;
1050 }
1051
1052cleanup:
1053 priv->sync_command_response = NULL;
1054 return status;
1055}
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068static irqreturn_t ca8210_interrupt_handler(int irq, void *dev_id)
1069{
1070 struct ca8210_priv *priv = dev_id;
1071 int status;
1072
1073 dev_dbg(&priv->spi->dev, "irq: Interrupt occurred\n");
1074 do {
1075 status = ca8210_spi_transfer(priv->spi, NULL, 0);
1076 if (status && (status != -EBUSY)) {
1077 dev_warn(
1078 &priv->spi->dev,
1079 "spi read failed, returned %d\n",
1080 status
1081 );
1082 }
1083 } while (status == -EBUSY);
1084 return IRQ_HANDLED;
1085}
1086
1087static int (*cascoda_api_downstream)(
1088 const u8 *buf,
1089 size_t len,
1090 u8 *response,
1091 void *device_ref
1092) = ca8210_spi_exchange;
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105static u8 tdme_setsfr_request_sync(
1106 u8 sfr_page,
1107 u8 sfr_address,
1108 u8 sfr_value,
1109 void *device_ref
1110)
1111{
1112 int ret;
1113 struct mac_message command, response;
1114 struct spi_device *spi = device_ref;
1115
1116 command.command_id = SPI_TDME_SETSFR_REQUEST;
1117 command.length = 3;
1118 command.pdata.tdme_set_sfr_req.sfr_page = sfr_page;
1119 command.pdata.tdme_set_sfr_req.sfr_address = sfr_address;
1120 command.pdata.tdme_set_sfr_req.sfr_value = sfr_value;
1121 response.command_id = SPI_IDLE;
1122 ret = cascoda_api_downstream(
1123 &command.command_id,
1124 command.length + 2,
1125 &response.command_id,
1126 device_ref
1127 );
1128 if (ret) {
1129 dev_crit(&spi->dev, "cascoda_api_downstream returned %d", ret);
1130 return MAC_SYSTEM_ERROR;
1131 }
1132
1133 if (response.command_id != SPI_TDME_SETSFR_CONFIRM) {
1134 dev_crit(
1135 &spi->dev,
1136 "sync response to SPI_TDME_SETSFR_REQUEST was not SPI_TDME_SETSFR_CONFIRM, it was %d\n",
1137 response.command_id
1138 );
1139 return MAC_SYSTEM_ERROR;
1140 }
1141
1142 return response.pdata.tdme_set_sfr_cnf.status;
1143}
1144
1145
1146
1147
1148
1149
1150
1151static u8 tdme_chipinit(void *device_ref)
1152{
1153 u8 status = MAC_SUCCESS;
1154 u8 sfr_address;
1155 struct spi_device *spi = device_ref;
1156 struct preamble_cfg_sfr pre_cfg_value = {
1157 .timeout_symbols = 3,
1158 .acquisition_symbols = 3,
1159 .search_symbols = 1,
1160 };
1161
1162 status = tdme_setsfr_request_sync(
1163 1, (sfr_address = CA8210_SFR_LNAGX40),
1164 LNAGX40_DEFAULT_GAIN, device_ref);
1165 if (status)
1166 goto finish;
1167 status = tdme_setsfr_request_sync(
1168 1, (sfr_address = CA8210_SFR_LNAGX41),
1169 LNAGX41_DEFAULT_GAIN, device_ref);
1170 if (status)
1171 goto finish;
1172 status = tdme_setsfr_request_sync(
1173 1, (sfr_address = CA8210_SFR_LNAGX42),
1174 LNAGX42_DEFAULT_GAIN, device_ref);
1175 if (status)
1176 goto finish;
1177 status = tdme_setsfr_request_sync(
1178 1, (sfr_address = CA8210_SFR_LNAGX43),
1179 LNAGX43_DEFAULT_GAIN, device_ref);
1180 if (status)
1181 goto finish;
1182 status = tdme_setsfr_request_sync(
1183 1, (sfr_address = CA8210_SFR_LNAGX44),
1184 LNAGX44_DEFAULT_GAIN, device_ref);
1185 if (status)
1186 goto finish;
1187 status = tdme_setsfr_request_sync(
1188 1, (sfr_address = CA8210_SFR_LNAGX45),
1189 LNAGX45_DEFAULT_GAIN, device_ref);
1190 if (status)
1191 goto finish;
1192 status = tdme_setsfr_request_sync(
1193 1, (sfr_address = CA8210_SFR_LNAGX46),
1194 LNAGX46_DEFAULT_GAIN, device_ref);
1195 if (status)
1196 goto finish;
1197 status = tdme_setsfr_request_sync(
1198 1, (sfr_address = CA8210_SFR_LNAGX47),
1199 LNAGX47_DEFAULT_GAIN, device_ref);
1200 if (status)
1201 goto finish;
1202
1203 status = tdme_setsfr_request_sync(
1204 1, (sfr_address = CA8210_SFR_PRECFG),
1205 *((u8 *)&pre_cfg_value), device_ref);
1206 if (status)
1207 goto finish;
1208
1209 status = tdme_setsfr_request_sync(
1210 1, (sfr_address = CA8210_SFR_PTHRH),
1211 PTHRH_DEFAULT_THRESHOLD, device_ref);
1212 if (status)
1213 goto finish;
1214
1215 status = tdme_setsfr_request_sync(
1216 0, (sfr_address = CA8210_SFR_PACFGIB),
1217 PACFGIB_DEFAULT_CURRENT, device_ref);
1218 if (status)
1219 goto finish;
1220
1221finish:
1222 if (status != MAC_SUCCESS) {
1223 dev_err(
1224 &spi->dev,
1225 "failed to set sfr at %#03x, status = %#03x\n",
1226 sfr_address,
1227 status
1228 );
1229 }
1230 return status;
1231}
1232
1233
1234
1235
1236
1237
1238
1239
1240static u8 tdme_channelinit(u8 channel, void *device_ref)
1241{
1242
1243
1244
1245 u8 txcalval;
1246
1247 if (channel >= 25)
1248 txcalval = 0xA7;
1249 else if (channel >= 23)
1250 txcalval = 0xA8;
1251 else if (channel >= 22)
1252 txcalval = 0xA9;
1253 else if (channel >= 20)
1254 txcalval = 0xAA;
1255 else if (channel >= 17)
1256 txcalval = 0xAB;
1257 else if (channel >= 16)
1258 txcalval = 0xAC;
1259 else if (channel >= 14)
1260 txcalval = 0xAD;
1261 else if (channel >= 12)
1262 txcalval = 0xAE;
1263 else
1264 txcalval = 0xAF;
1265
1266 return tdme_setsfr_request_sync(
1267 1,
1268 CA8210_SFR_LOTXCAL,
1269 txcalval,
1270 device_ref
1271 );
1272}
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284static u8 tdme_checkpibattribute(
1285 u8 pib_attribute,
1286 u8 pib_attribute_length,
1287 const void *pib_attribute_value
1288)
1289{
1290 u8 status = MAC_SUCCESS;
1291 u8 value;
1292
1293 value = *((u8 *)pib_attribute_value);
1294
1295 switch (pib_attribute) {
1296
1297 case PHY_TRANSMIT_POWER:
1298 if (value > 0x3F)
1299 status = MAC_INVALID_PARAMETER;
1300 break;
1301 case PHY_CCA_MODE:
1302 if (value > 0x03)
1303 status = MAC_INVALID_PARAMETER;
1304 break;
1305
1306 case MAC_BATT_LIFE_EXT_PERIODS:
1307 if (value < 6 || value > 41)
1308 status = MAC_INVALID_PARAMETER;
1309 break;
1310 case MAC_BEACON_PAYLOAD:
1311 if (pib_attribute_length > MAX_BEACON_PAYLOAD_LENGTH)
1312 status = MAC_INVALID_PARAMETER;
1313 break;
1314 case MAC_BEACON_PAYLOAD_LENGTH:
1315 if (value > MAX_BEACON_PAYLOAD_LENGTH)
1316 status = MAC_INVALID_PARAMETER;
1317 break;
1318 case MAC_BEACON_ORDER:
1319 if (value > 15)
1320 status = MAC_INVALID_PARAMETER;
1321 break;
1322 case MAC_MAX_BE:
1323 if (value < 3 || value > 8)
1324 status = MAC_INVALID_PARAMETER;
1325 break;
1326 case MAC_MAX_CSMA_BACKOFFS:
1327 if (value > 5)
1328 status = MAC_INVALID_PARAMETER;
1329 break;
1330 case MAC_MAX_FRAME_RETRIES:
1331 if (value > 7)
1332 status = MAC_INVALID_PARAMETER;
1333 break;
1334 case MAC_MIN_BE:
1335 if (value > 8)
1336 status = MAC_INVALID_PARAMETER;
1337 break;
1338 case MAC_RESPONSE_WAIT_TIME:
1339 if (value < 2 || value > 64)
1340 status = MAC_INVALID_PARAMETER;
1341 break;
1342 case MAC_SUPERFRAME_ORDER:
1343 if (value > 15)
1344 status = MAC_INVALID_PARAMETER;
1345 break;
1346
1347 case MAC_ASSOCIATED_PAN_COORD:
1348 case MAC_ASSOCIATION_PERMIT:
1349 case MAC_AUTO_REQUEST:
1350 case MAC_BATT_LIFE_EXT:
1351 case MAC_GTS_PERMIT:
1352 case MAC_PROMISCUOUS_MODE:
1353 case MAC_RX_ON_WHEN_IDLE:
1354 case MAC_SECURITY_ENABLED:
1355 if (value > 1)
1356 status = MAC_INVALID_PARAMETER;
1357 break;
1358
1359 case MAC_AUTO_REQUEST_SECURITY_LEVEL:
1360 if (value > 7)
1361 status = MAC_INVALID_PARAMETER;
1362 break;
1363 case MAC_AUTO_REQUEST_KEY_ID_MODE:
1364 if (value > 3)
1365 status = MAC_INVALID_PARAMETER;
1366 break;
1367 default:
1368 break;
1369 }
1370
1371 return status;
1372}
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385static u8 tdme_settxpower(u8 txp, void *device_ref)
1386{
1387 u8 status;
1388 s8 txp_val;
1389 u8 txp_ext;
1390 union pa_cfg_sfr pa_cfg_val;
1391
1392
1393 txp_ext = 0x3F & txp;
1394 if (txp_ext & 0x20)
1395 txp_ext += 0xC0;
1396 txp_val = (s8)txp_ext;
1397
1398 if (CA8210_MAC_MPW) {
1399 if (txp_val > 0) {
1400
1401 pa_cfg_val.bias_current_trim = 3;
1402 pa_cfg_val.buffer_capacitor_trim = 5;
1403 pa_cfg_val.boost = 1;
1404 } else {
1405
1406 pa_cfg_val.bias_current_trim = 3;
1407 pa_cfg_val.buffer_capacitor_trim = 7;
1408 pa_cfg_val.boost = 0;
1409 }
1410
1411 status = tdme_setsfr_request_sync(
1412 0,
1413 CA8210_SFR_PACFG,
1414 pa_cfg_val.paib,
1415 device_ref
1416 );
1417 } else {
1418
1419
1420
1421 if (txp_val > 8) {
1422 pa_cfg_val.paib = 0x3F;
1423 } else if (txp_val == 8) {
1424 pa_cfg_val.paib = 0x32;
1425 } else if (txp_val == 7) {
1426 pa_cfg_val.paib = 0x22;
1427 } else if (txp_val == 6) {
1428 pa_cfg_val.paib = 0x18;
1429 } else if (txp_val == 5) {
1430 pa_cfg_val.paib = 0x10;
1431 } else if (txp_val == 4) {
1432 pa_cfg_val.paib = 0x0C;
1433 } else if (txp_val == 3) {
1434 pa_cfg_val.paib = 0x08;
1435 } else if (txp_val == 2) {
1436 pa_cfg_val.paib = 0x05;
1437 } else if (txp_val == 1) {
1438 pa_cfg_val.paib = 0x03;
1439 } else if (txp_val == 0) {
1440 pa_cfg_val.paib = 0x01;
1441 } else {
1442 pa_cfg_val.paib = 0x00;
1443 }
1444
1445 status = tdme_setsfr_request_sync(
1446 0,
1447 CA8210_SFR_PACFGIB,
1448 pa_cfg_val.paib,
1449 device_ref
1450 );
1451 }
1452
1453 return status;
1454}
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471static u8 mcps_data_request(
1472 u8 src_addr_mode,
1473 u8 dst_address_mode,
1474 u16 dst_pan_id,
1475 union macaddr *dst_addr,
1476 u8 msdu_length,
1477 u8 *msdu,
1478 u8 msdu_handle,
1479 u8 tx_options,
1480 struct secspec *security,
1481 void *device_ref
1482)
1483{
1484 struct secspec *psec;
1485 struct mac_message command;
1486
1487 command.command_id = SPI_MCPS_DATA_REQUEST;
1488 command.pdata.data_req.src_addr_mode = src_addr_mode;
1489 command.pdata.data_req.dst.mode = dst_address_mode;
1490 if (dst_address_mode != MAC_MODE_NO_ADDR) {
1491 command.pdata.data_req.dst.pan_id[0] = LS_BYTE(dst_pan_id);
1492 command.pdata.data_req.dst.pan_id[1] = MS_BYTE(dst_pan_id);
1493 if (dst_address_mode == MAC_MODE_SHORT_ADDR) {
1494 command.pdata.data_req.dst.address[0] = LS_BYTE(
1495 dst_addr->short_address
1496 );
1497 command.pdata.data_req.dst.address[1] = MS_BYTE(
1498 dst_addr->short_address
1499 );
1500 } else {
1501 memcpy(
1502 command.pdata.data_req.dst.address,
1503 dst_addr->ieee_address,
1504 8
1505 );
1506 }
1507 }
1508 command.pdata.data_req.msdu_length = msdu_length;
1509 command.pdata.data_req.msdu_handle = msdu_handle;
1510 command.pdata.data_req.tx_options = tx_options;
1511 memcpy(command.pdata.data_req.msdu, msdu, msdu_length);
1512 psec = (struct secspec *)(command.pdata.data_req.msdu + msdu_length);
1513 command.length = sizeof(struct mcps_data_request_pset) -
1514 MAX_DATA_SIZE + msdu_length;
1515 if (!security || security->security_level == 0) {
1516 psec->security_level = 0;
1517 command.length += 1;
1518 } else {
1519 *psec = *security;
1520 command.length += sizeof(struct secspec);
1521 }
1522
1523 if (ca8210_spi_transfer(device_ref, &command.command_id,
1524 command.length + 2))
1525 return MAC_SYSTEM_ERROR;
1526
1527 return MAC_SUCCESS;
1528}
1529
1530
1531
1532
1533
1534
1535
1536
1537static u8 mlme_reset_request_sync(
1538 u8 set_default_pib,
1539 void *device_ref
1540)
1541{
1542 u8 status;
1543 struct mac_message command, response;
1544 struct spi_device *spi = device_ref;
1545
1546 command.command_id = SPI_MLME_RESET_REQUEST;
1547 command.length = 1;
1548 command.pdata.u8param = set_default_pib;
1549
1550 if (cascoda_api_downstream(
1551 &command.command_id,
1552 command.length + 2,
1553 &response.command_id,
1554 device_ref)) {
1555 dev_err(&spi->dev, "cascoda_api_downstream failed\n");
1556 return MAC_SYSTEM_ERROR;
1557 }
1558
1559 if (response.command_id != SPI_MLME_RESET_CONFIRM)
1560 return MAC_SYSTEM_ERROR;
1561
1562 status = response.pdata.status;
1563
1564
1565 if (CA8210_MAC_WORKAROUNDS && set_default_pib && !status) {
1566 status = tdme_setsfr_request_sync(
1567 0,
1568 CA8210_SFR_MACCON,
1569 0,
1570 device_ref
1571 );
1572 }
1573
1574 return status;
1575}
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587static u8 mlme_set_request_sync(
1588 u8 pib_attribute,
1589 u8 pib_attribute_index,
1590 u8 pib_attribute_length,
1591 const void *pib_attribute_value,
1592 void *device_ref
1593)
1594{
1595 u8 status;
1596 struct mac_message command, response;
1597
1598
1599
1600
1601 if (tdme_checkpibattribute(
1602 pib_attribute, pib_attribute_length, pib_attribute_value)) {
1603 return MAC_INVALID_PARAMETER;
1604 }
1605
1606 if (pib_attribute == PHY_CURRENT_CHANNEL) {
1607 status = tdme_channelinit(
1608 *((u8 *)pib_attribute_value),
1609 device_ref
1610 );
1611 if (status)
1612 return status;
1613 }
1614
1615 if (pib_attribute == PHY_TRANSMIT_POWER) {
1616 return tdme_settxpower(
1617 *((u8 *)pib_attribute_value),
1618 device_ref
1619 );
1620 }
1621
1622 command.command_id = SPI_MLME_SET_REQUEST;
1623 command.length = sizeof(struct mlme_set_request_pset) -
1624 MAX_ATTRIBUTE_SIZE + pib_attribute_length;
1625 command.pdata.set_req.pib_attribute = pib_attribute;
1626 command.pdata.set_req.pib_attribute_index = pib_attribute_index;
1627 command.pdata.set_req.pib_attribute_length = pib_attribute_length;
1628 memcpy(
1629 command.pdata.set_req.pib_attribute_value,
1630 pib_attribute_value,
1631 pib_attribute_length
1632 );
1633
1634 if (cascoda_api_downstream(
1635 &command.command_id,
1636 command.length + 2,
1637 &response.command_id,
1638 device_ref)) {
1639 return MAC_SYSTEM_ERROR;
1640 }
1641
1642 if (response.command_id != SPI_MLME_SET_CONFIRM)
1643 return MAC_SYSTEM_ERROR;
1644
1645 return response.pdata.status;
1646}
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657static u8 hwme_set_request_sync(
1658 u8 hw_attribute,
1659 u8 hw_attribute_length,
1660 u8 *hw_attribute_value,
1661 void *device_ref
1662)
1663{
1664 struct mac_message command, response;
1665
1666 command.command_id = SPI_HWME_SET_REQUEST;
1667 command.length = 2 + hw_attribute_length;
1668 command.pdata.hwme_set_req.hw_attribute = hw_attribute;
1669 command.pdata.hwme_set_req.hw_attribute_length = hw_attribute_length;
1670 memcpy(
1671 command.pdata.hwme_set_req.hw_attribute_value,
1672 hw_attribute_value,
1673 hw_attribute_length
1674 );
1675
1676 if (cascoda_api_downstream(
1677 &command.command_id,
1678 command.length + 2,
1679 &response.command_id,
1680 device_ref)) {
1681 return MAC_SYSTEM_ERROR;
1682 }
1683
1684 if (response.command_id != SPI_HWME_SET_CONFIRM)
1685 return MAC_SYSTEM_ERROR;
1686
1687 return response.pdata.hwme_set_cnf.status;
1688}
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699static u8 hwme_get_request_sync(
1700 u8 hw_attribute,
1701 u8 *hw_attribute_length,
1702 u8 *hw_attribute_value,
1703 void *device_ref
1704)
1705{
1706 struct mac_message command, response;
1707
1708 command.command_id = SPI_HWME_GET_REQUEST;
1709 command.length = 1;
1710 command.pdata.hwme_get_req.hw_attribute = hw_attribute;
1711
1712 if (cascoda_api_downstream(
1713 &command.command_id,
1714 command.length + 2,
1715 &response.command_id,
1716 device_ref)) {
1717 return MAC_SYSTEM_ERROR;
1718 }
1719
1720 if (response.command_id != SPI_HWME_GET_CONFIRM)
1721 return MAC_SYSTEM_ERROR;
1722
1723 if (response.pdata.hwme_get_cnf.status == MAC_SUCCESS) {
1724 *hw_attribute_length =
1725 response.pdata.hwme_get_cnf.hw_attribute_length;
1726 memcpy(
1727 hw_attribute_value,
1728 response.pdata.hwme_get_cnf.hw_attribute_value,
1729 *hw_attribute_length
1730 );
1731 }
1732
1733 return response.pdata.hwme_get_cnf.status;
1734}
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747static int ca8210_async_xmit_complete(
1748 struct ieee802154_hw *hw,
1749 u8 msduhandle,
1750 u8 status)
1751{
1752 struct ca8210_priv *priv = hw->priv;
1753
1754 if (priv->nextmsduhandle != msduhandle) {
1755 dev_err(
1756 &priv->spi->dev,
1757 "Unexpected msdu_handle on data confirm, Expected %d, got %d\n",
1758 priv->nextmsduhandle,
1759 msduhandle
1760 );
1761 return -EIO;
1762 }
1763
1764 priv->async_tx_pending = false;
1765 priv->nextmsduhandle++;
1766
1767 if (status) {
1768 dev_err(
1769 &priv->spi->dev,
1770 "Link transmission unsuccessful, status = %d\n",
1771 status
1772 );
1773 if (status != MAC_TRANSACTION_OVERFLOW) {
1774 ieee802154_wake_queue(priv->hw);
1775 return 0;
1776 }
1777 }
1778 ieee802154_xmit_complete(priv->hw, priv->tx_skb, true);
1779
1780 return 0;
1781}
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796static int ca8210_skb_rx(
1797 struct ieee802154_hw *hw,
1798 size_t len,
1799 u8 *data_ind
1800)
1801{
1802 struct ieee802154_hdr hdr;
1803 int msdulen;
1804 int hlen;
1805 u8 mpdulinkquality = data_ind[23];
1806 struct sk_buff *skb;
1807 struct ca8210_priv *priv = hw->priv;
1808
1809
1810 skb = dev_alloc_skb(IEEE802154_MTU + sizeof(hdr));
1811 if (!skb)
1812 return -ENOMEM;
1813
1814 skb_reserve(skb, sizeof(hdr));
1815
1816 msdulen = data_ind[22];
1817 if (msdulen > IEEE802154_MTU) {
1818 dev_err(
1819 &priv->spi->dev,
1820 "received erroneously large msdu length!\n"
1821 );
1822 kfree_skb(skb);
1823 return -EMSGSIZE;
1824 }
1825 dev_dbg(&priv->spi->dev, "skb buffer length = %d\n", msdulen);
1826
1827 if (priv->promiscuous)
1828 goto copy_payload;
1829
1830
1831 hdr.sec.level = data_ind[29 + msdulen];
1832 dev_dbg(&priv->spi->dev, "security level: %#03x\n", hdr.sec.level);
1833 if (hdr.sec.level > 0) {
1834 hdr.sec.key_id_mode = data_ind[30 + msdulen];
1835 memcpy(&hdr.sec.extended_src, &data_ind[31 + msdulen], 8);
1836 hdr.sec.key_id = data_ind[39 + msdulen];
1837 }
1838 hdr.source.mode = data_ind[0];
1839 dev_dbg(&priv->spi->dev, "srcAddrMode: %#03x\n", hdr.source.mode);
1840 hdr.source.pan_id = *(u16 *)&data_ind[1];
1841 dev_dbg(&priv->spi->dev, "srcPanId: %#06x\n", hdr.source.pan_id);
1842 memcpy(&hdr.source.extended_addr, &data_ind[3], 8);
1843 hdr.dest.mode = data_ind[11];
1844 dev_dbg(&priv->spi->dev, "dstAddrMode: %#03x\n", hdr.dest.mode);
1845 hdr.dest.pan_id = *(u16 *)&data_ind[12];
1846 dev_dbg(&priv->spi->dev, "dstPanId: %#06x\n", hdr.dest.pan_id);
1847 memcpy(&hdr.dest.extended_addr, &data_ind[14], 8);
1848
1849
1850 hdr.fc.type = 1;
1851 if (hdr.sec.level)
1852 hdr.fc.security_enabled = 1;
1853 else
1854 hdr.fc.security_enabled = 0;
1855 if (data_ind[1] != data_ind[12] || data_ind[2] != data_ind[13])
1856 hdr.fc.intra_pan = 1;
1857 else
1858 hdr.fc.intra_pan = 0;
1859 hdr.fc.dest_addr_mode = hdr.dest.mode;
1860 hdr.fc.source_addr_mode = hdr.source.mode;
1861
1862
1863 hlen = ieee802154_hdr_push(skb, &hdr);
1864
1865 if (hlen < 0) {
1866 dev_crit(&priv->spi->dev, "failed to push mac hdr onto skb!\n");
1867 kfree_skb(skb);
1868 return hlen;
1869 }
1870
1871 skb_reset_mac_header(skb);
1872 skb->mac_len = hlen;
1873
1874copy_payload:
1875
1876
1877 skb_put_data(skb, &data_ind[29], msdulen);
1878
1879 ieee802154_rx_irqsafe(hw, skb, mpdulinkquality);
1880 return 0;
1881}
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896static int ca8210_net_rx(struct ieee802154_hw *hw, u8 *command, size_t len)
1897{
1898 struct ca8210_priv *priv = hw->priv;
1899 unsigned long flags;
1900 u8 status;
1901
1902 dev_dbg(&priv->spi->dev, "%s: CmdID = %d\n", __func__, command[0]);
1903
1904 if (command[0] == SPI_MCPS_DATA_INDICATION) {
1905
1906 spin_lock_irqsave(&priv->lock, flags);
1907 if (command[26] == priv->last_dsn) {
1908 dev_dbg(
1909 &priv->spi->dev,
1910 "DSN %d resend received, ignoring...\n",
1911 command[26]
1912 );
1913 spin_unlock_irqrestore(&priv->lock, flags);
1914 return 0;
1915 }
1916 priv->last_dsn = command[26];
1917 spin_unlock_irqrestore(&priv->lock, flags);
1918 return ca8210_skb_rx(hw, len - 2, command + 2);
1919 } else if (command[0] == SPI_MCPS_DATA_CONFIRM) {
1920 status = command[3];
1921 if (priv->async_tx_pending) {
1922 return ca8210_async_xmit_complete(
1923 hw,
1924 command[2],
1925 status
1926 );
1927 }
1928 }
1929
1930 return 0;
1931}
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941static int ca8210_skb_tx(
1942 struct sk_buff *skb,
1943 u8 msduhandle,
1944 struct ca8210_priv *priv
1945)
1946{
1947 int status;
1948 struct ieee802154_hdr header = { };
1949 struct secspec secspec;
1950 unsigned int mac_len;
1951
1952 dev_dbg(&priv->spi->dev, "%s called\n", __func__);
1953
1954
1955
1956
1957 mac_len = ieee802154_hdr_peek_addrs(skb, &header);
1958
1959 secspec.security_level = header.sec.level;
1960 secspec.key_id_mode = header.sec.key_id_mode;
1961 if (secspec.key_id_mode == 2)
1962 memcpy(secspec.key_source, &header.sec.short_src, 4);
1963 else if (secspec.key_id_mode == 3)
1964 memcpy(secspec.key_source, &header.sec.extended_src, 8);
1965 secspec.key_index = header.sec.key_id;
1966
1967
1968 status = mcps_data_request(
1969 header.source.mode,
1970 header.dest.mode,
1971 header.dest.pan_id,
1972 (union macaddr *)&header.dest.extended_addr,
1973 skb->len - mac_len,
1974 &skb->data[mac_len],
1975 msduhandle,
1976 header.fc.ack_request,
1977 &secspec,
1978 priv->spi
1979 );
1980 return link_to_linux_err(status);
1981}
1982
1983
1984
1985
1986
1987
1988
1989static int ca8210_start(struct ieee802154_hw *hw)
1990{
1991 int status;
1992 u8 rx_on_when_idle;
1993 u8 lqi_threshold = 0;
1994 struct ca8210_priv *priv = hw->priv;
1995
1996 priv->last_dsn = -1;
1997
1998 rx_on_when_idle = 1;
1999 status = mlme_set_request_sync(
2000 MAC_RX_ON_WHEN_IDLE,
2001 0,
2002 1,
2003 &rx_on_when_idle,
2004 priv->spi
2005 );
2006 if (status) {
2007 dev_crit(
2008 &priv->spi->dev,
2009 "Setting rx_on_when_idle failed, status = %d\n",
2010 status
2011 );
2012 return link_to_linux_err(status);
2013 }
2014 status = hwme_set_request_sync(
2015 HWME_LQILIMIT,
2016 1,
2017 &lqi_threshold,
2018 priv->spi
2019 );
2020 if (status) {
2021 dev_crit(
2022 &priv->spi->dev,
2023 "Setting lqilimit failed, status = %d\n",
2024 status
2025 );
2026 return link_to_linux_err(status);
2027 }
2028
2029 return 0;
2030}
2031
2032
2033
2034
2035
2036
2037
2038static void ca8210_stop(struct ieee802154_hw *hw)
2039{
2040}
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050static int ca8210_xmit_async(struct ieee802154_hw *hw, struct sk_buff *skb)
2051{
2052 struct ca8210_priv *priv = hw->priv;
2053 int status;
2054
2055 dev_dbg(&priv->spi->dev, "calling %s\n", __func__);
2056
2057 priv->tx_skb = skb;
2058 priv->async_tx_pending = true;
2059 status = ca8210_skb_tx(skb, priv->nextmsduhandle, priv);
2060 return status;
2061}
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071static int ca8210_get_ed(struct ieee802154_hw *hw, u8 *level)
2072{
2073 u8 lenvar;
2074 struct ca8210_priv *priv = hw->priv;
2075
2076 return link_to_linux_err(
2077 hwme_get_request_sync(HWME_EDVALUE, &lenvar, level, priv->spi)
2078 );
2079}
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090static int ca8210_set_channel(
2091 struct ieee802154_hw *hw,
2092 u8 page,
2093 u8 channel
2094)
2095{
2096 u8 status;
2097 struct ca8210_priv *priv = hw->priv;
2098
2099 status = mlme_set_request_sync(
2100 PHY_CURRENT_CHANNEL,
2101 0,
2102 1,
2103 &channel,
2104 priv->spi
2105 );
2106 if (status) {
2107 dev_err(
2108 &priv->spi->dev,
2109 "error setting channel, MLME-SET.confirm status = %d\n",
2110 status
2111 );
2112 }
2113 return link_to_linux_err(status);
2114}
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129static int ca8210_set_hw_addr_filt(
2130 struct ieee802154_hw *hw,
2131 struct ieee802154_hw_addr_filt *filt,
2132 unsigned long changed
2133)
2134{
2135 u8 status = 0;
2136 struct ca8210_priv *priv = hw->priv;
2137
2138 if (changed & IEEE802154_AFILT_PANID_CHANGED) {
2139 status = mlme_set_request_sync(
2140 MAC_PAN_ID,
2141 0,
2142 2,
2143 &filt->pan_id, priv->spi
2144 );
2145 if (status) {
2146 dev_err(
2147 &priv->spi->dev,
2148 "error setting pan id, MLME-SET.confirm status = %d",
2149 status
2150 );
2151 return link_to_linux_err(status);
2152 }
2153 }
2154 if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
2155 status = mlme_set_request_sync(
2156 MAC_SHORT_ADDRESS,
2157 0,
2158 2,
2159 &filt->short_addr, priv->spi
2160 );
2161 if (status) {
2162 dev_err(
2163 &priv->spi->dev,
2164 "error setting short address, MLME-SET.confirm status = %d",
2165 status
2166 );
2167 return link_to_linux_err(status);
2168 }
2169 }
2170 if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
2171 status = mlme_set_request_sync(
2172 NS_IEEE_ADDRESS,
2173 0,
2174 8,
2175 &filt->ieee_addr,
2176 priv->spi
2177 );
2178 if (status) {
2179 dev_err(
2180 &priv->spi->dev,
2181 "error setting ieee address, MLME-SET.confirm status = %d",
2182 status
2183 );
2184 return link_to_linux_err(status);
2185 }
2186 }
2187
2188 return 0;
2189}
2190
2191
2192
2193
2194
2195
2196
2197
2198static int ca8210_set_tx_power(struct ieee802154_hw *hw, s32 mbm)
2199{
2200 struct ca8210_priv *priv = hw->priv;
2201
2202 mbm /= 100;
2203 return link_to_linux_err(
2204 mlme_set_request_sync(PHY_TRANSMIT_POWER, 0, 1, &mbm, priv->spi)
2205 );
2206}
2207
2208
2209
2210
2211
2212
2213
2214
2215static int ca8210_set_cca_mode(
2216 struct ieee802154_hw *hw,
2217 const struct wpan_phy_cca *cca
2218)
2219{
2220 u8 status;
2221 u8 cca_mode;
2222 struct ca8210_priv *priv = hw->priv;
2223
2224 cca_mode = cca->mode & 3;
2225 if (cca_mode == 3 && cca->opt == NL802154_CCA_OPT_ENERGY_CARRIER_OR) {
2226
2227 cca_mode = 0;
2228 }
2229 status = mlme_set_request_sync(
2230 PHY_CCA_MODE,
2231 0,
2232 1,
2233 &cca_mode,
2234 priv->spi
2235 );
2236 if (status) {
2237 dev_err(
2238 &priv->spi->dev,
2239 "error setting cca mode, MLME-SET.confirm status = %d",
2240 status
2241 );
2242 }
2243 return link_to_linux_err(status);
2244}
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256static int ca8210_set_cca_ed_level(struct ieee802154_hw *hw, s32 level)
2257{
2258 u8 status;
2259 u8 ed_threshold = (level / 100) * 2 + 256;
2260 struct ca8210_priv *priv = hw->priv;
2261
2262 status = hwme_set_request_sync(
2263 HWME_EDTHRESHOLD,
2264 1,
2265 &ed_threshold,
2266 priv->spi
2267 );
2268 if (status) {
2269 dev_err(
2270 &priv->spi->dev,
2271 "error setting ed threshold, HWME-SET.confirm status = %d",
2272 status
2273 );
2274 }
2275 return link_to_linux_err(status);
2276}
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287static int ca8210_set_csma_params(
2288 struct ieee802154_hw *hw,
2289 u8 min_be,
2290 u8 max_be,
2291 u8 retries
2292)
2293{
2294 u8 status;
2295 struct ca8210_priv *priv = hw->priv;
2296
2297 status = mlme_set_request_sync(MAC_MIN_BE, 0, 1, &min_be, priv->spi);
2298 if (status) {
2299 dev_err(
2300 &priv->spi->dev,
2301 "error setting min be, MLME-SET.confirm status = %d",
2302 status
2303 );
2304 return link_to_linux_err(status);
2305 }
2306 status = mlme_set_request_sync(MAC_MAX_BE, 0, 1, &max_be, priv->spi);
2307 if (status) {
2308 dev_err(
2309 &priv->spi->dev,
2310 "error setting max be, MLME-SET.confirm status = %d",
2311 status
2312 );
2313 return link_to_linux_err(status);
2314 }
2315 status = mlme_set_request_sync(
2316 MAC_MAX_CSMA_BACKOFFS,
2317 0,
2318 1,
2319 &retries,
2320 priv->spi
2321 );
2322 if (status) {
2323 dev_err(
2324 &priv->spi->dev,
2325 "error setting max csma backoffs, MLME-SET.confirm status = %d",
2326 status
2327 );
2328 }
2329 return link_to_linux_err(status);
2330}
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342static int ca8210_set_frame_retries(struct ieee802154_hw *hw, s8 retries)
2343{
2344 u8 status;
2345 struct ca8210_priv *priv = hw->priv;
2346
2347 status = mlme_set_request_sync(
2348 MAC_MAX_FRAME_RETRIES,
2349 0,
2350 1,
2351 &retries,
2352 priv->spi
2353 );
2354 if (status) {
2355 dev_err(
2356 &priv->spi->dev,
2357 "error setting frame retries, MLME-SET.confirm status = %d",
2358 status
2359 );
2360 }
2361 return link_to_linux_err(status);
2362}
2363
2364static int ca8210_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on)
2365{
2366 u8 status;
2367 struct ca8210_priv *priv = hw->priv;
2368
2369 status = mlme_set_request_sync(
2370 MAC_PROMISCUOUS_MODE,
2371 0,
2372 1,
2373 (const void *)&on,
2374 priv->spi
2375 );
2376 if (status) {
2377 dev_err(
2378 &priv->spi->dev,
2379 "error setting promiscuous mode, MLME-SET.confirm status = %d",
2380 status
2381 );
2382 } else {
2383 priv->promiscuous = on;
2384 }
2385 return link_to_linux_err(status);
2386}
2387
2388static const struct ieee802154_ops ca8210_phy_ops = {
2389 .start = ca8210_start,
2390 .stop = ca8210_stop,
2391 .xmit_async = ca8210_xmit_async,
2392 .ed = ca8210_get_ed,
2393 .set_channel = ca8210_set_channel,
2394 .set_hw_addr_filt = ca8210_set_hw_addr_filt,
2395 .set_txpower = ca8210_set_tx_power,
2396 .set_cca_mode = ca8210_set_cca_mode,
2397 .set_cca_ed_level = ca8210_set_cca_ed_level,
2398 .set_csma_params = ca8210_set_csma_params,
2399 .set_frame_retries = ca8210_set_frame_retries,
2400 .set_promiscuous_mode = ca8210_set_promiscuous_mode
2401};
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412static int ca8210_test_int_open(struct inode *inodp, struct file *filp)
2413{
2414 struct ca8210_priv *priv = inodp->i_private;
2415
2416 filp->private_data = priv;
2417 return 0;
2418}
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428static int ca8210_test_check_upstream(u8 *buf, void *device_ref)
2429{
2430 int ret;
2431 u8 response[CA8210_SPI_BUF_SIZE];
2432
2433 if (buf[0] == SPI_MLME_SET_REQUEST) {
2434 ret = tdme_checkpibattribute(buf[2], buf[4], buf + 5);
2435 if (ret) {
2436 response[0] = SPI_MLME_SET_CONFIRM;
2437 response[1] = 3;
2438 response[2] = MAC_INVALID_PARAMETER;
2439 response[3] = buf[2];
2440 response[4] = buf[3];
2441 if (cascoda_api_upstream)
2442 cascoda_api_upstream(response, 5, device_ref);
2443 return ret;
2444 }
2445 }
2446 if (buf[0] == SPI_MLME_ASSOCIATE_REQUEST) {
2447 return tdme_channelinit(buf[2], device_ref);
2448 } else if (buf[0] == SPI_MLME_START_REQUEST) {
2449 return tdme_channelinit(buf[4], device_ref);
2450 } else if (
2451 (buf[0] == SPI_MLME_SET_REQUEST) &&
2452 (buf[2] == PHY_CURRENT_CHANNEL)
2453 ) {
2454 return tdme_channelinit(buf[5], device_ref);
2455 } else if (
2456 (buf[0] == SPI_TDME_SET_REQUEST) &&
2457 (buf[2] == TDME_CHANNEL)
2458 ) {
2459 return tdme_channelinit(buf[4], device_ref);
2460 } else if (
2461 (CA8210_MAC_WORKAROUNDS) &&
2462 (buf[0] == SPI_MLME_RESET_REQUEST) &&
2463 (buf[2] == 1)
2464 ) {
2465
2466 return tdme_setsfr_request_sync(
2467 0,
2468 CA8210_SFR_MACCON,
2469 0,
2470 device_ref
2471 );
2472 }
2473 return 0;
2474}
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486static ssize_t ca8210_test_int_user_write(
2487 struct file *filp,
2488 const char __user *in_buf,
2489 size_t len,
2490 loff_t *off
2491)
2492{
2493 int ret;
2494 struct ca8210_priv *priv = filp->private_data;
2495 u8 command[CA8210_SPI_BUF_SIZE];
2496
2497 memset(command, SPI_IDLE, 6);
2498 if (len > CA8210_SPI_BUF_SIZE || len < 2) {
2499 dev_warn(
2500 &priv->spi->dev,
2501 "userspace requested erroneous write length (%zu)\n",
2502 len
2503 );
2504 return -EBADE;
2505 }
2506
2507 ret = copy_from_user(command, in_buf, len);
2508 if (ret) {
2509 dev_err(
2510 &priv->spi->dev,
2511 "%d bytes could not be copied from userspace\n",
2512 ret
2513 );
2514 return -EIO;
2515 }
2516 if (len != command[1] + 2) {
2517 dev_err(
2518 &priv->spi->dev,
2519 "write len does not match packet length field\n"
2520 );
2521 return -EBADE;
2522 }
2523
2524 ret = ca8210_test_check_upstream(command, priv->spi);
2525 if (ret == 0) {
2526 ret = ca8210_spi_exchange(
2527 command,
2528 command[1] + 2,
2529 NULL,
2530 priv->spi
2531 );
2532 if (ret < 0) {
2533
2534 dev_err(
2535 &priv->spi->dev,
2536 "spi exchange failed\n"
2537 );
2538 return ret;
2539 }
2540 if (command[0] & SPI_SYN)
2541 priv->sync_down++;
2542 }
2543
2544 return len;
2545}
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561static ssize_t ca8210_test_int_user_read(
2562 struct file *filp,
2563 char __user *buf,
2564 size_t len,
2565 loff_t *offp
2566)
2567{
2568 int i, cmdlen;
2569 struct ca8210_priv *priv = filp->private_data;
2570 unsigned char *fifo_buffer;
2571 unsigned long bytes_not_copied;
2572
2573 if (filp->f_flags & O_NONBLOCK) {
2574
2575 if (kfifo_is_empty(&priv->test.up_fifo))
2576 return 0;
2577 } else {
2578
2579 wait_event_interruptible(
2580 priv->test.readq,
2581 !kfifo_is_empty(&priv->test.up_fifo)
2582 );
2583 }
2584
2585 if (kfifo_out(&priv->test.up_fifo, &fifo_buffer, 4) != 4) {
2586 dev_err(
2587 &priv->spi->dev,
2588 "test_interface: Wrong number of elements popped from upstream fifo\n"
2589 );
2590 return 0;
2591 }
2592 cmdlen = fifo_buffer[1];
2593 bytes_not_copied = cmdlen + 2;
2594
2595 bytes_not_copied = copy_to_user(buf, fifo_buffer, bytes_not_copied);
2596 if (bytes_not_copied > 0) {
2597 dev_err(
2598 &priv->spi->dev,
2599 "%lu bytes could not be copied to user space!\n",
2600 bytes_not_copied
2601 );
2602 }
2603
2604 dev_dbg(&priv->spi->dev, "test_interface: Cmd len = %d\n", cmdlen);
2605
2606 dev_dbg(&priv->spi->dev, "test_interface: Read\n");
2607 for (i = 0; i < cmdlen + 2; i++)
2608 dev_dbg(&priv->spi->dev, "%#03x\n", fifo_buffer[i]);
2609
2610 kfree(fifo_buffer);
2611
2612 return cmdlen + 2;
2613}
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624static long ca8210_test_int_ioctl(
2625 struct file *filp,
2626 unsigned int ioctl_num,
2627 unsigned long ioctl_param
2628)
2629{
2630 struct ca8210_priv *priv = filp->private_data;
2631
2632 switch (ioctl_num) {
2633 case CA8210_IOCTL_HARD_RESET:
2634 ca8210_reset_send(priv->spi, ioctl_param);
2635 break;
2636 default:
2637 break;
2638 }
2639 return 0;
2640}
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650static __poll_t ca8210_test_int_poll(
2651 struct file *filp,
2652 struct poll_table_struct *ptable
2653)
2654{
2655 __poll_t return_flags = 0;
2656 struct ca8210_priv *priv = filp->private_data;
2657
2658 poll_wait(filp, &priv->test.readq, ptable);
2659 if (!kfifo_is_empty(&priv->test.up_fifo))
2660 return_flags |= (EPOLLIN | EPOLLRDNORM);
2661 if (wait_event_interruptible(
2662 priv->test.readq,
2663 !kfifo_is_empty(&priv->test.up_fifo))) {
2664 return EPOLLERR;
2665 }
2666 return return_flags;
2667}
2668
2669static const struct file_operations test_int_fops = {
2670 .read = ca8210_test_int_user_read,
2671 .write = ca8210_test_int_user_write,
2672 .open = ca8210_test_int_open,
2673 .release = NULL,
2674 .unlocked_ioctl = ca8210_test_int_ioctl,
2675 .poll = ca8210_test_int_poll
2676};
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687static int ca8210_get_platform_data(
2688 struct spi_device *spi_device,
2689 struct ca8210_platform_data *pdata
2690)
2691{
2692 int ret = 0;
2693
2694 if (!spi_device->dev.of_node)
2695 return -EINVAL;
2696
2697 pdata->extclockenable = of_property_read_bool(
2698 spi_device->dev.of_node,
2699 "extclock-enable"
2700 );
2701 if (pdata->extclockenable) {
2702 ret = of_property_read_u32(
2703 spi_device->dev.of_node,
2704 "extclock-freq",
2705 &pdata->extclockfreq
2706 );
2707 if (ret < 0)
2708 return ret;
2709
2710 ret = of_property_read_u32(
2711 spi_device->dev.of_node,
2712 "extclock-gpio",
2713 &pdata->extclockgpio
2714 );
2715 }
2716
2717 return ret;
2718}
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732static int ca8210_config_extern_clk(
2733 struct ca8210_platform_data *pdata,
2734 struct spi_device *spi,
2735 bool on
2736)
2737{
2738 u8 clkparam[2];
2739
2740 if (on) {
2741 dev_info(&spi->dev, "Switching external clock on\n");
2742 switch (pdata->extclockfreq) {
2743 case SIXTEEN_MHZ:
2744 clkparam[0] = 1;
2745 break;
2746 case EIGHT_MHZ:
2747 clkparam[0] = 2;
2748 break;
2749 case FOUR_MHZ:
2750 clkparam[0] = 3;
2751 break;
2752 case TWO_MHZ:
2753 clkparam[0] = 4;
2754 break;
2755 case ONE_MHZ:
2756 clkparam[0] = 5;
2757 break;
2758 default:
2759 dev_crit(&spi->dev, "Invalid extclock-freq\n");
2760 return -EINVAL;
2761 }
2762 clkparam[1] = pdata->extclockgpio;
2763 } else {
2764 dev_info(&spi->dev, "Switching external clock off\n");
2765 clkparam[0] = 0;
2766 clkparam[1] = 0;
2767 }
2768 return link_to_linux_err(
2769 hwme_set_request_sync(HWME_SYSCLKOUT, 2, clkparam, spi)
2770 );
2771}
2772
2773
2774
2775
2776
2777
2778
2779static int ca8210_register_ext_clock(struct spi_device *spi)
2780{
2781 struct device_node *np = spi->dev.of_node;
2782 struct ca8210_priv *priv = spi_get_drvdata(spi);
2783 struct ca8210_platform_data *pdata = spi->dev.platform_data;
2784 int ret = 0;
2785
2786 if (!np)
2787 return -EFAULT;
2788
2789 priv->clk = clk_register_fixed_rate(
2790 &spi->dev,
2791 np->name,
2792 NULL,
2793 0,
2794 pdata->extclockfreq
2795 );
2796
2797 if (IS_ERR(priv->clk)) {
2798 dev_crit(&spi->dev, "Failed to register external clk\n");
2799 return PTR_ERR(priv->clk);
2800 }
2801 ret = of_clk_add_provider(np, of_clk_src_simple_get, priv->clk);
2802 if (ret) {
2803 clk_unregister(priv->clk);
2804 dev_crit(
2805 &spi->dev,
2806 "Failed to register external clock as clock provider\n"
2807 );
2808 } else {
2809 dev_info(&spi->dev, "External clock set as clock provider\n");
2810 }
2811
2812 return ret;
2813}
2814
2815
2816
2817
2818
2819
2820static void ca8210_unregister_ext_clock(struct spi_device *spi)
2821{
2822 struct ca8210_priv *priv = spi_get_drvdata(spi);
2823
2824 if (!priv->clk)
2825 return
2826
2827 of_clk_del_provider(spi->dev.of_node);
2828 clk_unregister(priv->clk);
2829 dev_info(&spi->dev, "External clock unregistered\n");
2830}
2831
2832
2833
2834
2835
2836
2837
2838static int ca8210_reset_init(struct spi_device *spi)
2839{
2840 int ret;
2841 struct ca8210_platform_data *pdata = spi->dev.platform_data;
2842
2843 pdata->gpio_reset = of_get_named_gpio(
2844 spi->dev.of_node,
2845 "reset-gpio",
2846 0
2847 );
2848
2849 ret = gpio_direction_output(pdata->gpio_reset, 1);
2850 if (ret < 0) {
2851 dev_crit(
2852 &spi->dev,
2853 "Reset GPIO %d did not set to output mode\n",
2854 pdata->gpio_reset
2855 );
2856 }
2857
2858 return ret;
2859}
2860
2861
2862
2863
2864
2865
2866
2867static int ca8210_interrupt_init(struct spi_device *spi)
2868{
2869 int ret;
2870 struct ca8210_platform_data *pdata = spi->dev.platform_data;
2871
2872 pdata->gpio_irq = of_get_named_gpio(
2873 spi->dev.of_node,
2874 "irq-gpio",
2875 0
2876 );
2877
2878 pdata->irq_id = gpio_to_irq(pdata->gpio_irq);
2879 if (pdata->irq_id < 0) {
2880 dev_crit(
2881 &spi->dev,
2882 "Could not get irq for gpio pin %d\n",
2883 pdata->gpio_irq
2884 );
2885 gpio_free(pdata->gpio_irq);
2886 return pdata->irq_id;
2887 }
2888
2889 ret = request_irq(
2890 pdata->irq_id,
2891 ca8210_interrupt_handler,
2892 IRQF_TRIGGER_FALLING,
2893 "ca8210-irq",
2894 spi_get_drvdata(spi)
2895 );
2896 if (ret) {
2897 dev_crit(&spi->dev, "request_irq %d failed\n", pdata->irq_id);
2898 gpio_unexport(pdata->gpio_irq);
2899 gpio_free(pdata->gpio_irq);
2900 }
2901
2902 return ret;
2903}
2904
2905
2906
2907
2908
2909
2910
2911static int ca8210_dev_com_init(struct ca8210_priv *priv)
2912{
2913 priv->mlme_workqueue = alloc_ordered_workqueue(
2914 "MLME work queue",
2915 WQ_UNBOUND
2916 );
2917 if (!priv->mlme_workqueue) {
2918 dev_crit(&priv->spi->dev, "alloc of mlme_workqueue failed!\n");
2919 return -ENOMEM;
2920 }
2921
2922 priv->irq_workqueue = alloc_ordered_workqueue(
2923 "ca8210 irq worker",
2924 WQ_UNBOUND
2925 );
2926 if (!priv->irq_workqueue) {
2927 dev_crit(&priv->spi->dev, "alloc of irq_workqueue failed!\n");
2928 destroy_workqueue(priv->mlme_workqueue);
2929 return -ENOMEM;
2930 }
2931
2932 return 0;
2933}
2934
2935
2936
2937
2938
2939static void ca8210_dev_com_clear(struct ca8210_priv *priv)
2940{
2941 flush_workqueue(priv->mlme_workqueue);
2942 destroy_workqueue(priv->mlme_workqueue);
2943 flush_workqueue(priv->irq_workqueue);
2944 destroy_workqueue(priv->irq_workqueue);
2945}
2946
2947#define CA8210_MAX_TX_POWERS (9)
2948static const s32 ca8210_tx_powers[CA8210_MAX_TX_POWERS] = {
2949 800, 700, 600, 500, 400, 300, 200, 100, 0
2950};
2951
2952#define CA8210_MAX_ED_LEVELS (21)
2953static const s32 ca8210_ed_levels[CA8210_MAX_ED_LEVELS] = {
2954 -10300, -10250, -10200, -10150, -10100, -10050, -10000, -9950, -9900,
2955 -9850, -9800, -9750, -9700, -9650, -9600, -9550, -9500, -9450, -9400,
2956 -9350, -9300
2957};
2958
2959
2960
2961
2962
2963
2964static void ca8210_hw_setup(struct ieee802154_hw *ca8210_hw)
2965{
2966
2967 ca8210_hw->phy->supported.channels[0] = CA8210_VALID_CHANNELS;
2968 ca8210_hw->phy->supported.tx_powers_size = CA8210_MAX_TX_POWERS;
2969 ca8210_hw->phy->supported.tx_powers = ca8210_tx_powers;
2970 ca8210_hw->phy->supported.cca_ed_levels_size = CA8210_MAX_ED_LEVELS;
2971 ca8210_hw->phy->supported.cca_ed_levels = ca8210_ed_levels;
2972 ca8210_hw->phy->current_channel = 18;
2973 ca8210_hw->phy->current_page = 0;
2974 ca8210_hw->phy->transmit_power = 800;
2975 ca8210_hw->phy->cca.mode = NL802154_CCA_ENERGY_CARRIER;
2976 ca8210_hw->phy->cca.opt = NL802154_CCA_OPT_ENERGY_CARRIER_AND;
2977 ca8210_hw->phy->cca_ed_level = -9800;
2978 ca8210_hw->phy->symbol_duration = 16;
2979 ca8210_hw->phy->lifs_period = 40;
2980 ca8210_hw->phy->sifs_period = 12;
2981 ca8210_hw->flags =
2982 IEEE802154_HW_AFILT |
2983 IEEE802154_HW_OMIT_CKSUM |
2984 IEEE802154_HW_FRAME_RETRIES |
2985 IEEE802154_HW_PROMISCUOUS |
2986 IEEE802154_HW_CSMA_PARAMS;
2987 ca8210_hw->phy->flags =
2988 WPAN_PHY_FLAG_TXPOWER |
2989 WPAN_PHY_FLAG_CCA_ED_LEVEL |
2990 WPAN_PHY_FLAG_CCA_MODE;
2991}
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004static int ca8210_test_interface_init(struct ca8210_priv *priv)
3005{
3006 struct ca8210_test *test = &priv->test;
3007 char node_name[32];
3008
3009 snprintf(
3010 node_name,
3011 sizeof(node_name),
3012 "ca8210@%d_%d",
3013 priv->spi->master->bus_num,
3014 priv->spi->chip_select
3015 );
3016
3017 test->ca8210_dfs_spi_int = debugfs_create_file(
3018 node_name,
3019 0600,
3020 NULL,
3021 priv,
3022 &test_int_fops
3023 );
3024
3025 debugfs_create_symlink("ca8210", NULL, node_name);
3026 init_waitqueue_head(&test->readq);
3027 return kfifo_alloc(
3028 &test->up_fifo,
3029 CA8210_TEST_INT_FIFO_SIZE,
3030 GFP_KERNEL
3031 );
3032}
3033
3034
3035
3036
3037
3038static void ca8210_test_interface_clear(struct ca8210_priv *priv)
3039{
3040 struct ca8210_test *test = &priv->test;
3041
3042 debugfs_remove(test->ca8210_dfs_spi_int);
3043 kfifo_free(&test->up_fifo);
3044 dev_info(&priv->spi->dev, "Test interface removed\n");
3045}
3046
3047
3048
3049
3050
3051
3052
3053static int ca8210_remove(struct spi_device *spi_device)
3054{
3055 struct ca8210_priv *priv;
3056 struct ca8210_platform_data *pdata;
3057
3058 dev_info(&spi_device->dev, "Removing ca8210\n");
3059
3060 pdata = spi_device->dev.platform_data;
3061 if (pdata) {
3062 if (pdata->extclockenable) {
3063 ca8210_unregister_ext_clock(spi_device);
3064 ca8210_config_extern_clk(pdata, spi_device, 0);
3065 }
3066 free_irq(pdata->irq_id, spi_device->dev.driver_data);
3067 kfree(pdata);
3068 spi_device->dev.platform_data = NULL;
3069 }
3070
3071 priv = spi_get_drvdata(spi_device);
3072 if (priv) {
3073 dev_info(
3074 &spi_device->dev,
3075 "sync_down = %d, sync_up = %d\n",
3076 priv->sync_down,
3077 priv->sync_up
3078 );
3079 ca8210_dev_com_clear(spi_device->dev.driver_data);
3080 if (priv->hw) {
3081 if (priv->hw_registered)
3082 ieee802154_unregister_hw(priv->hw);
3083 ieee802154_free_hw(priv->hw);
3084 priv->hw = NULL;
3085 dev_info(
3086 &spi_device->dev,
3087 "Unregistered & freed ieee802154_hw.\n"
3088 );
3089 }
3090 if (IS_ENABLED(CONFIG_IEEE802154_CA8210_DEBUGFS))
3091 ca8210_test_interface_clear(priv);
3092 }
3093
3094 return 0;
3095}
3096
3097
3098
3099
3100
3101
3102
3103static int ca8210_probe(struct spi_device *spi_device)
3104{
3105 struct ca8210_priv *priv;
3106 struct ieee802154_hw *hw;
3107 struct ca8210_platform_data *pdata;
3108 int ret;
3109
3110 dev_info(&spi_device->dev, "Inserting ca8210\n");
3111
3112
3113 hw = ieee802154_alloc_hw(sizeof(struct ca8210_priv), &ca8210_phy_ops);
3114 if (!hw) {
3115 dev_crit(&spi_device->dev, "ieee802154_alloc_hw failed\n");
3116 ret = -ENOMEM;
3117 goto error;
3118 }
3119
3120 priv = hw->priv;
3121 priv->hw = hw;
3122 priv->spi = spi_device;
3123 hw->parent = &spi_device->dev;
3124 spin_lock_init(&priv->lock);
3125 priv->async_tx_pending = false;
3126 priv->hw_registered = false;
3127 priv->sync_up = 0;
3128 priv->sync_down = 0;
3129 priv->promiscuous = false;
3130 priv->retries = 0;
3131 init_completion(&priv->ca8210_is_awake);
3132 init_completion(&priv->spi_transfer_complete);
3133 init_completion(&priv->sync_exchange_complete);
3134 spi_set_drvdata(priv->spi, priv);
3135 if (IS_ENABLED(CONFIG_IEEE802154_CA8210_DEBUGFS)) {
3136 cascoda_api_upstream = ca8210_test_int_driver_write;
3137 ca8210_test_interface_init(priv);
3138 } else {
3139 cascoda_api_upstream = NULL;
3140 }
3141 ca8210_hw_setup(hw);
3142 ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
3143
3144 pdata = kmalloc(sizeof(*pdata), GFP_KERNEL);
3145 if (!pdata) {
3146 ret = -ENOMEM;
3147 goto error;
3148 }
3149
3150 priv->spi->dev.platform_data = pdata;
3151 ret = ca8210_get_platform_data(priv->spi, pdata);
3152 if (ret) {
3153 dev_crit(&spi_device->dev, "ca8210_get_platform_data failed\n");
3154 goto error;
3155 }
3156
3157 ret = ca8210_dev_com_init(priv);
3158 if (ret) {
3159 dev_crit(&spi_device->dev, "ca8210_dev_com_init failed\n");
3160 goto error;
3161 }
3162 ret = ca8210_reset_init(priv->spi);
3163 if (ret) {
3164 dev_crit(&spi_device->dev, "ca8210_reset_init failed\n");
3165 goto error;
3166 }
3167
3168 ret = ca8210_interrupt_init(priv->spi);
3169 if (ret) {
3170 dev_crit(&spi_device->dev, "ca8210_interrupt_init failed\n");
3171 goto error;
3172 }
3173
3174 msleep(100);
3175
3176 ca8210_reset_send(priv->spi, 1);
3177
3178 ret = tdme_chipinit(priv->spi);
3179 if (ret) {
3180 dev_crit(&spi_device->dev, "tdme_chipinit failed\n");
3181 goto error;
3182 }
3183
3184 if (pdata->extclockenable) {
3185 ret = ca8210_config_extern_clk(pdata, priv->spi, 1);
3186 if (ret) {
3187 dev_crit(
3188 &spi_device->dev,
3189 "ca8210_config_extern_clk failed\n"
3190 );
3191 goto error;
3192 }
3193 ret = ca8210_register_ext_clock(priv->spi);
3194 if (ret) {
3195 dev_crit(
3196 &spi_device->dev,
3197 "ca8210_register_ext_clock failed\n"
3198 );
3199 goto error;
3200 }
3201 }
3202
3203 ret = ieee802154_register_hw(hw);
3204 if (ret) {
3205 dev_crit(&spi_device->dev, "ieee802154_register_hw failed\n");
3206 goto error;
3207 }
3208 priv->hw_registered = true;
3209
3210 return 0;
3211error:
3212 msleep(100);
3213 ca8210_remove(spi_device);
3214 return link_to_linux_err(ret);
3215}
3216
3217static const struct of_device_id ca8210_of_ids[] = {
3218 {.compatible = "cascoda,ca8210", },
3219 {},
3220};
3221MODULE_DEVICE_TABLE(of, ca8210_of_ids);
3222
3223static struct spi_driver ca8210_spi_driver = {
3224 .driver = {
3225 .name = DRIVER_NAME,
3226 .owner = THIS_MODULE,
3227 .of_match_table = of_match_ptr(ca8210_of_ids),
3228 },
3229 .probe = ca8210_probe,
3230 .remove = ca8210_remove
3231};
3232
3233module_spi_driver(ca8210_spi_driver);
3234
3235MODULE_AUTHOR("Harry Morris <h.morris@cascoda.com>");
3236MODULE_DESCRIPTION("CA-8210 SoftMAC driver");
3237MODULE_LICENSE("Dual BSD/GPL");
3238MODULE_VERSION("1.0");
3239