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
322
323struct ca8210_test {
324 struct dentry *ca8210_dfs_spi_int;
325 struct kfifo up_fifo;
326 wait_queue_head_t readq;
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
357struct ca8210_priv {
358 struct spi_device *spi;
359 struct ieee802154_hw *hw;
360 bool hw_registered;
361 spinlock_t lock;
362 struct workqueue_struct *mlme_workqueue;
363 struct workqueue_struct *irq_workqueue;
364 struct sk_buff *tx_skb;
365 u8 nextmsduhandle;
366 struct clk *clk;
367 int last_dsn;
368 struct ca8210_test test;
369 bool async_tx_pending;
370 u8 *sync_command_response;
371 struct completion ca8210_is_awake;
372 int sync_down, sync_up;
373 struct completion spi_transfer_complete, sync_exchange_complete;
374 bool promiscuous;
375 int retries;
376};
377
378
379
380
381
382
383
384
385struct work_priv_container {
386 struct work_struct work;
387 struct ca8210_priv *priv;
388};
389
390
391
392
393
394
395
396
397
398
399
400struct ca8210_platform_data {
401 bool extclockenable;
402 unsigned int extclockfreq;
403 unsigned int extclockgpio;
404 int gpio_reset;
405 int gpio_irq;
406 int irq_id;
407};
408
409
410
411
412
413
414
415
416struct fulladdr {
417 u8 mode;
418 u8 pan_id[2];
419 u8 address[8];
420};
421
422
423
424
425
426
427
428union macaddr {
429 u16 short_address;
430 u8 ieee_address[8];
431};
432
433
434
435
436
437
438
439
440
441struct secspec {
442 u8 security_level;
443 u8 key_id_mode;
444 u8 key_source[8];
445 u8 key_index;
446};
447
448
449struct mcps_data_request_pset {
450 u8 src_addr_mode;
451 struct fulladdr dst;
452 u8 msdu_length;
453 u8 msdu_handle;
454 u8 tx_options;
455 u8 msdu[MAX_DATA_SIZE];
456};
457
458struct mlme_set_request_pset {
459 u8 pib_attribute;
460 u8 pib_attribute_index;
461 u8 pib_attribute_length;
462 u8 pib_attribute_value[MAX_ATTRIBUTE_SIZE];
463};
464
465struct hwme_set_request_pset {
466 u8 hw_attribute;
467 u8 hw_attribute_length;
468 u8 hw_attribute_value[MAX_HWME_ATTRIBUTE_SIZE];
469};
470
471struct hwme_get_request_pset {
472 u8 hw_attribute;
473};
474
475struct tdme_setsfr_request_pset {
476 u8 sfr_page;
477 u8 sfr_address;
478 u8 sfr_value;
479};
480
481
482struct hwme_set_confirm_pset {
483 u8 status;
484 u8 hw_attribute;
485};
486
487struct hwme_get_confirm_pset {
488 u8 status;
489 u8 hw_attribute;
490 u8 hw_attribute_length;
491 u8 hw_attribute_value[MAX_HWME_ATTRIBUTE_SIZE];
492};
493
494struct tdme_setsfr_confirm_pset {
495 u8 status;
496 u8 sfr_page;
497 u8 sfr_address;
498};
499
500struct mac_message {
501 u8 command_id;
502 u8 length;
503 union {
504 struct mcps_data_request_pset data_req;
505 struct mlme_set_request_pset set_req;
506 struct hwme_set_request_pset hwme_set_req;
507 struct hwme_get_request_pset hwme_get_req;
508 struct tdme_setsfr_request_pset tdme_set_sfr_req;
509 struct hwme_set_confirm_pset hwme_set_cnf;
510 struct hwme_get_confirm_pset hwme_get_cnf;
511 struct tdme_setsfr_confirm_pset tdme_set_sfr_cnf;
512 u8 u8param;
513 u8 status;
514 u8 payload[148];
515 } pdata;
516};
517
518union pa_cfg_sfr {
519 struct {
520 u8 bias_current_trim : 3;
521 u8 : 1;
522 u8 buffer_capacitor_trim : 3;
523 u8 boost : 1;
524 };
525 u8 paib;
526};
527
528struct preamble_cfg_sfr {
529 u8 timeout_symbols : 3;
530 u8 acquisition_symbols : 3;
531 u8 search_symbols : 2;
532};
533
534static int (*cascoda_api_upstream)(
535 const u8 *buf,
536 size_t len,
537 void *device_ref
538);
539
540
541
542
543
544
545
546
547static int link_to_linux_err(int link_status)
548{
549 if (link_status < 0) {
550
551 return link_status;
552 }
553 switch (link_status) {
554 case MAC_SUCCESS:
555 case MAC_REALIGNMENT:
556 return 0;
557 case MAC_IMPROPER_KEY_TYPE:
558 return -EKEYREJECTED;
559 case MAC_IMPROPER_SECURITY_LEVEL:
560 case MAC_UNSUPPORTED_LEGACY:
561 case MAC_DENIED:
562 return -EACCES;
563 case MAC_BEACON_LOST:
564 case MAC_NO_ACK:
565 case MAC_NO_BEACON:
566 return -ENETUNREACH;
567 case MAC_CHANNEL_ACCESS_FAILURE:
568 case MAC_TX_ACTIVE:
569 case MAC_SCAN_IN_PROGRESS:
570 return -EBUSY;
571 case MAC_DISABLE_TRX_FAILURE:
572 case MAC_OUT_OF_CAP:
573 return -EAGAIN;
574 case MAC_FRAME_TOO_LONG:
575 return -EMSGSIZE;
576 case MAC_INVALID_GTS:
577 case MAC_PAST_TIME:
578 return -EBADSLT;
579 case MAC_INVALID_HANDLE:
580 return -EBADMSG;
581 case MAC_INVALID_PARAMETER:
582 case MAC_UNSUPPORTED_ATTRIBUTE:
583 case MAC_ON_TIME_TOO_LONG:
584 case MAC_INVALID_INDEX:
585 return -EINVAL;
586 case MAC_NO_DATA:
587 return -ENODATA;
588 case MAC_NO_SHORT_ADDRESS:
589 return -EFAULT;
590 case MAC_PAN_ID_CONFLICT:
591 return -EADDRINUSE;
592 case MAC_TRANSACTION_EXPIRED:
593 return -ETIME;
594 case MAC_TRANSACTION_OVERFLOW:
595 return -ENOBUFS;
596 case MAC_UNAVAILABLE_KEY:
597 return -ENOKEY;
598 case MAC_INVALID_ADDRESS:
599 return -ENXIO;
600 case MAC_TRACKING_OFF:
601 case MAC_SUPERFRAME_OVERLAP:
602 return -EREMOTEIO;
603 case MAC_LIMIT_REACHED:
604 return -EDQUOT;
605 case MAC_READ_ONLY:
606 return -EROFS;
607 default:
608 return -EPROTO;
609 }
610}
611
612
613
614
615
616
617
618
619
620
621static int ca8210_test_int_driver_write(
622 const u8 *buf,
623 size_t len,
624 void *spi
625)
626{
627 struct ca8210_priv *priv = spi_get_drvdata(spi);
628 struct ca8210_test *test = &priv->test;
629 char *fifo_buffer;
630 int i;
631
632 dev_dbg(
633 &priv->spi->dev,
634 "test_interface: Buffering upstream message:\n"
635 );
636 for (i = 0; i < len; i++)
637 dev_dbg(&priv->spi->dev, "%#03x\n", buf[i]);
638
639 fifo_buffer = kmemdup(buf, len, GFP_KERNEL);
640 if (!fifo_buffer)
641 return -ENOMEM;
642 kfifo_in(&test->up_fifo, &fifo_buffer, 4);
643 wake_up_interruptible(&priv->test.readq);
644
645 return 0;
646}
647
648
649
650static int ca8210_net_rx(
651 struct ieee802154_hw *hw,
652 u8 *command,
653 size_t len
654);
655static u8 mlme_reset_request_sync(
656 u8 set_default_pib,
657 void *device_ref
658);
659static int ca8210_spi_transfer(
660 struct spi_device *spi,
661 const u8 *buf,
662 size_t len
663);
664
665
666
667
668
669
670static void ca8210_reset_send(struct spi_device *spi, unsigned int ms)
671{
672 struct ca8210_platform_data *pdata = spi->dev.platform_data;
673 struct ca8210_priv *priv = spi_get_drvdata(spi);
674 long status;
675
676 gpio_set_value(pdata->gpio_reset, 0);
677 reinit_completion(&priv->ca8210_is_awake);
678 msleep(ms);
679 gpio_set_value(pdata->gpio_reset, 1);
680 priv->promiscuous = false;
681
682
683 status = wait_for_completion_interruptible_timeout(
684 &priv->ca8210_is_awake,
685 msecs_to_jiffies(CA8210_SYNC_TIMEOUT)
686 );
687 if (status == 0) {
688 dev_crit(
689 &spi->dev,
690 "Fatal: No wakeup from ca8210 after reset!\n"
691 );
692 }
693
694 dev_dbg(&spi->dev, "Reset the device\n");
695}
696
697
698
699
700
701
702static void ca8210_mlme_reset_worker(struct work_struct *work)
703{
704 struct work_priv_container *wpc = container_of(
705 work,
706 struct work_priv_container,
707 work
708 );
709 struct ca8210_priv *priv = wpc->priv;
710
711 mlme_reset_request_sync(0, priv->spi);
712 kfree(wpc);
713}
714
715
716
717
718
719
720
721
722
723static void ca8210_rx_done(struct cas_control *cas_ctl)
724{
725 u8 *buf;
726 unsigned int len;
727 struct work_priv_container *mlme_reset_wpc;
728 struct ca8210_priv *priv = cas_ctl->priv;
729
730 buf = cas_ctl->tx_in_buf;
731 len = buf[1] + 2;
732 if (len > CA8210_SPI_BUF_SIZE) {
733 dev_crit(
734 &priv->spi->dev,
735 "Received packet len (%u) erroneously long\n",
736 len
737 );
738 goto finish;
739 }
740
741 if (buf[0] & SPI_SYN) {
742 if (priv->sync_command_response) {
743 memcpy(priv->sync_command_response, buf, len);
744 complete(&priv->sync_exchange_complete);
745 } else {
746 if (cascoda_api_upstream)
747 cascoda_api_upstream(buf, len, priv->spi);
748 priv->sync_up++;
749 }
750 } else {
751 if (cascoda_api_upstream)
752 cascoda_api_upstream(buf, len, priv->spi);
753 }
754
755 ca8210_net_rx(priv->hw, buf, len);
756 if (buf[0] == SPI_MCPS_DATA_CONFIRM) {
757 if (buf[3] == MAC_TRANSACTION_OVERFLOW) {
758 dev_info(
759 &priv->spi->dev,
760 "Waiting for transaction overflow to stabilise...\n");
761 msleep(2000);
762 dev_info(
763 &priv->spi->dev,
764 "Resetting MAC...\n");
765
766 mlme_reset_wpc = kmalloc(sizeof(*mlme_reset_wpc),
767 GFP_KERNEL);
768 if (!mlme_reset_wpc)
769 goto finish;
770 INIT_WORK(
771 &mlme_reset_wpc->work,
772 ca8210_mlme_reset_worker
773 );
774 mlme_reset_wpc->priv = priv;
775 queue_work(priv->mlme_workqueue, &mlme_reset_wpc->work);
776 }
777 } else if (buf[0] == SPI_HWME_WAKEUP_INDICATION) {
778 dev_notice(
779 &priv->spi->dev,
780 "Wakeup indication received, reason:\n"
781 );
782 switch (buf[2]) {
783 case 0:
784 dev_notice(
785 &priv->spi->dev,
786 "Transceiver woken up from Power Up / System Reset\n"
787 );
788 break;
789 case 1:
790 dev_notice(
791 &priv->spi->dev,
792 "Watchdog Timer Time-Out\n"
793 );
794 break;
795 case 2:
796 dev_notice(
797 &priv->spi->dev,
798 "Transceiver woken up from Power-Off by Sleep Timer Time-Out\n");
799 break;
800 case 3:
801 dev_notice(
802 &priv->spi->dev,
803 "Transceiver woken up from Power-Off by GPIO Activity\n"
804 );
805 break;
806 case 4:
807 dev_notice(
808 &priv->spi->dev,
809 "Transceiver woken up from Standby by Sleep Timer Time-Out\n"
810 );
811 break;
812 case 5:
813 dev_notice(
814 &priv->spi->dev,
815 "Transceiver woken up from Standby by GPIO Activity\n"
816 );
817 break;
818 case 6:
819 dev_notice(
820 &priv->spi->dev,
821 "Sleep-Timer Time-Out in Active Mode\n"
822 );
823 break;
824 default:
825 dev_warn(&priv->spi->dev, "Wakeup reason unknown\n");
826 break;
827 }
828 complete(&priv->ca8210_is_awake);
829 }
830
831finish:;
832}
833
834static int ca8210_remove(struct spi_device *spi_device);
835
836
837
838
839
840
841static void ca8210_spi_transfer_complete(void *context)
842{
843 struct cas_control *cas_ctl = context;
844 struct ca8210_priv *priv = cas_ctl->priv;
845 bool duplex_rx = false;
846 int i;
847 u8 retry_buffer[CA8210_SPI_BUF_SIZE];
848
849 if (
850 cas_ctl->tx_in_buf[0] == SPI_NACK ||
851 (cas_ctl->tx_in_buf[0] == SPI_IDLE &&
852 cas_ctl->tx_in_buf[1] == SPI_NACK)
853 ) {
854
855 dev_info(&priv->spi->dev, "ca8210 was busy during attempted write\n");
856 if (cas_ctl->tx_buf[0] == SPI_IDLE) {
857 dev_warn(
858 &priv->spi->dev,
859 "IRQ servicing NACKd, dropping transfer\n"
860 );
861 kfree(cas_ctl);
862 return;
863 }
864 if (priv->retries > 3) {
865 dev_err(&priv->spi->dev, "too many retries!\n");
866 kfree(cas_ctl);
867 ca8210_remove(priv->spi);
868 return;
869 }
870 memcpy(retry_buffer, cas_ctl->tx_buf, CA8210_SPI_BUF_SIZE);
871 kfree(cas_ctl);
872 ca8210_spi_transfer(
873 priv->spi,
874 retry_buffer,
875 CA8210_SPI_BUF_SIZE
876 );
877 priv->retries++;
878 dev_info(&priv->spi->dev, "retried spi write\n");
879 return;
880 } else if (
881 cas_ctl->tx_in_buf[0] != SPI_IDLE &&
882 cas_ctl->tx_in_buf[0] != SPI_NACK
883 ) {
884 duplex_rx = true;
885 }
886
887 if (duplex_rx) {
888 dev_dbg(&priv->spi->dev, "READ CMD DURING TX\n");
889 for (i = 0; i < cas_ctl->tx_in_buf[1] + 2; i++)
890 dev_dbg(
891 &priv->spi->dev,
892 "%#03x\n",
893 cas_ctl->tx_in_buf[i]
894 );
895 ca8210_rx_done(cas_ctl);
896 }
897 complete(&priv->spi_transfer_complete);
898 kfree(cas_ctl);
899 priv->retries = 0;
900}
901
902
903
904
905
906
907
908
909
910static int ca8210_spi_transfer(
911 struct spi_device *spi,
912 const u8 *buf,
913 size_t len
914)
915{
916 int i, status = 0;
917 struct ca8210_priv *priv;
918 struct cas_control *cas_ctl;
919
920 if (!spi) {
921 pr_crit("NULL spi device passed to %s\n", __func__);
922 return -ENODEV;
923 }
924
925 priv = spi_get_drvdata(spi);
926 reinit_completion(&priv->spi_transfer_complete);
927
928 dev_dbg(&spi->dev, "%s called\n", __func__);
929
930 cas_ctl = kmalloc(sizeof(*cas_ctl), GFP_ATOMIC);
931 if (!cas_ctl)
932 return -ENOMEM;
933
934 cas_ctl->priv = priv;
935 memset(cas_ctl->tx_buf, SPI_IDLE, CA8210_SPI_BUF_SIZE);
936 memset(cas_ctl->tx_in_buf, SPI_IDLE, CA8210_SPI_BUF_SIZE);
937 memcpy(cas_ctl->tx_buf, buf, len);
938
939 for (i = 0; i < len; i++)
940 dev_dbg(&spi->dev, "%#03x\n", cas_ctl->tx_buf[i]);
941
942 spi_message_init(&cas_ctl->msg);
943
944 cas_ctl->transfer.tx_nbits = 1;
945 cas_ctl->transfer.rx_nbits = 1;
946 cas_ctl->transfer.speed_hz = 0;
947 cas_ctl->transfer.bits_per_word = 0;
948 cas_ctl->transfer.tx_buf = cas_ctl->tx_buf;
949 cas_ctl->transfer.rx_buf = cas_ctl->tx_in_buf;
950 cas_ctl->transfer.delay.value = 0;
951 cas_ctl->transfer.delay.unit = SPI_DELAY_UNIT_USECS;
952 cas_ctl->transfer.cs_change = 0;
953 cas_ctl->transfer.len = sizeof(struct mac_message);
954 cas_ctl->msg.complete = ca8210_spi_transfer_complete;
955 cas_ctl->msg.context = cas_ctl;
956
957 spi_message_add_tail(
958 &cas_ctl->transfer,
959 &cas_ctl->msg
960 );
961
962 status = spi_async(spi, &cas_ctl->msg);
963 if (status < 0) {
964 dev_crit(
965 &spi->dev,
966 "status %d from spi_sync in write\n",
967 status
968 );
969 }
970
971 return status;
972}
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987static int ca8210_spi_exchange(
988 const u8 *buf,
989 size_t len,
990 u8 *response,
991 void *device_ref
992)
993{
994 int status = 0;
995 struct spi_device *spi = device_ref;
996 struct ca8210_priv *priv = spi->dev.driver_data;
997 long wait_remaining;
998
999 if ((buf[0] & SPI_SYN) && response) {
1000 reinit_completion(&priv->sync_exchange_complete);
1001 priv->sync_command_response = response;
1002 }
1003
1004 do {
1005 reinit_completion(&priv->spi_transfer_complete);
1006 status = ca8210_spi_transfer(priv->spi, buf, len);
1007 if (status) {
1008 dev_warn(
1009 &spi->dev,
1010 "spi write failed, returned %d\n",
1011 status
1012 );
1013 if (status == -EBUSY)
1014 continue;
1015 if (((buf[0] & SPI_SYN) && response))
1016 complete(&priv->sync_exchange_complete);
1017 goto cleanup;
1018 }
1019
1020 wait_remaining = wait_for_completion_interruptible_timeout(
1021 &priv->spi_transfer_complete,
1022 msecs_to_jiffies(1000)
1023 );
1024 if (wait_remaining == -ERESTARTSYS) {
1025 status = -ERESTARTSYS;
1026 } else if (wait_remaining == 0) {
1027 dev_err(
1028 &spi->dev,
1029 "SPI downstream transfer timed out!\n"
1030 );
1031 status = -ETIME;
1032 goto cleanup;
1033 }
1034 } while (status < 0);
1035
1036 if (!((buf[0] & SPI_SYN) && response))
1037 goto cleanup;
1038
1039 wait_remaining = wait_for_completion_interruptible_timeout(
1040 &priv->sync_exchange_complete,
1041 msecs_to_jiffies(CA8210_SYNC_TIMEOUT)
1042 );
1043 if (wait_remaining == -ERESTARTSYS) {
1044 status = -ERESTARTSYS;
1045 } else if (wait_remaining == 0) {
1046 dev_err(
1047 &spi->dev,
1048 "Synchronous confirm timeout\n"
1049 );
1050 status = -ETIME;
1051 }
1052
1053cleanup:
1054 priv->sync_command_response = NULL;
1055 return status;
1056}
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069static irqreturn_t ca8210_interrupt_handler(int irq, void *dev_id)
1070{
1071 struct ca8210_priv *priv = dev_id;
1072 int status;
1073
1074 dev_dbg(&priv->spi->dev, "irq: Interrupt occurred\n");
1075 do {
1076 status = ca8210_spi_transfer(priv->spi, NULL, 0);
1077 if (status && (status != -EBUSY)) {
1078 dev_warn(
1079 &priv->spi->dev,
1080 "spi read failed, returned %d\n",
1081 status
1082 );
1083 }
1084 } while (status == -EBUSY);
1085 return IRQ_HANDLED;
1086}
1087
1088static int (*cascoda_api_downstream)(
1089 const u8 *buf,
1090 size_t len,
1091 u8 *response,
1092 void *device_ref
1093) = ca8210_spi_exchange;
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106static u8 tdme_setsfr_request_sync(
1107 u8 sfr_page,
1108 u8 sfr_address,
1109 u8 sfr_value,
1110 void *device_ref
1111)
1112{
1113 int ret;
1114 struct mac_message command, response;
1115 struct spi_device *spi = device_ref;
1116
1117 command.command_id = SPI_TDME_SETSFR_REQUEST;
1118 command.length = 3;
1119 command.pdata.tdme_set_sfr_req.sfr_page = sfr_page;
1120 command.pdata.tdme_set_sfr_req.sfr_address = sfr_address;
1121 command.pdata.tdme_set_sfr_req.sfr_value = sfr_value;
1122 response.command_id = SPI_IDLE;
1123 ret = cascoda_api_downstream(
1124 &command.command_id,
1125 command.length + 2,
1126 &response.command_id,
1127 device_ref
1128 );
1129 if (ret) {
1130 dev_crit(&spi->dev, "cascoda_api_downstream returned %d", ret);
1131 return MAC_SYSTEM_ERROR;
1132 }
1133
1134 if (response.command_id != SPI_TDME_SETSFR_CONFIRM) {
1135 dev_crit(
1136 &spi->dev,
1137 "sync response to SPI_TDME_SETSFR_REQUEST was not SPI_TDME_SETSFR_CONFIRM, it was %d\n",
1138 response.command_id
1139 );
1140 return MAC_SYSTEM_ERROR;
1141 }
1142
1143 return response.pdata.tdme_set_sfr_cnf.status;
1144}
1145
1146
1147
1148
1149
1150
1151
1152static u8 tdme_chipinit(void *device_ref)
1153{
1154 u8 status = MAC_SUCCESS;
1155 u8 sfr_address;
1156 struct spi_device *spi = device_ref;
1157 struct preamble_cfg_sfr pre_cfg_value = {
1158 .timeout_symbols = 3,
1159 .acquisition_symbols = 3,
1160 .search_symbols = 1,
1161 };
1162
1163 status = tdme_setsfr_request_sync(
1164 1, (sfr_address = CA8210_SFR_LNAGX40),
1165 LNAGX40_DEFAULT_GAIN, device_ref);
1166 if (status)
1167 goto finish;
1168 status = tdme_setsfr_request_sync(
1169 1, (sfr_address = CA8210_SFR_LNAGX41),
1170 LNAGX41_DEFAULT_GAIN, device_ref);
1171 if (status)
1172 goto finish;
1173 status = tdme_setsfr_request_sync(
1174 1, (sfr_address = CA8210_SFR_LNAGX42),
1175 LNAGX42_DEFAULT_GAIN, device_ref);
1176 if (status)
1177 goto finish;
1178 status = tdme_setsfr_request_sync(
1179 1, (sfr_address = CA8210_SFR_LNAGX43),
1180 LNAGX43_DEFAULT_GAIN, device_ref);
1181 if (status)
1182 goto finish;
1183 status = tdme_setsfr_request_sync(
1184 1, (sfr_address = CA8210_SFR_LNAGX44),
1185 LNAGX44_DEFAULT_GAIN, device_ref);
1186 if (status)
1187 goto finish;
1188 status = tdme_setsfr_request_sync(
1189 1, (sfr_address = CA8210_SFR_LNAGX45),
1190 LNAGX45_DEFAULT_GAIN, device_ref);
1191 if (status)
1192 goto finish;
1193 status = tdme_setsfr_request_sync(
1194 1, (sfr_address = CA8210_SFR_LNAGX46),
1195 LNAGX46_DEFAULT_GAIN, device_ref);
1196 if (status)
1197 goto finish;
1198 status = tdme_setsfr_request_sync(
1199 1, (sfr_address = CA8210_SFR_LNAGX47),
1200 LNAGX47_DEFAULT_GAIN, device_ref);
1201 if (status)
1202 goto finish;
1203
1204 status = tdme_setsfr_request_sync(
1205 1, (sfr_address = CA8210_SFR_PRECFG),
1206 *((u8 *)&pre_cfg_value), device_ref);
1207 if (status)
1208 goto finish;
1209
1210 status = tdme_setsfr_request_sync(
1211 1, (sfr_address = CA8210_SFR_PTHRH),
1212 PTHRH_DEFAULT_THRESHOLD, device_ref);
1213 if (status)
1214 goto finish;
1215
1216 status = tdme_setsfr_request_sync(
1217 0, (sfr_address = CA8210_SFR_PACFGIB),
1218 PACFGIB_DEFAULT_CURRENT, device_ref);
1219 if (status)
1220 goto finish;
1221
1222finish:
1223 if (status != MAC_SUCCESS) {
1224 dev_err(
1225 &spi->dev,
1226 "failed to set sfr at %#03x, status = %#03x\n",
1227 sfr_address,
1228 status
1229 );
1230 }
1231 return status;
1232}
1233
1234
1235
1236
1237
1238
1239
1240
1241static u8 tdme_channelinit(u8 channel, void *device_ref)
1242{
1243
1244
1245
1246 u8 txcalval;
1247
1248 if (channel >= 25)
1249 txcalval = 0xA7;
1250 else if (channel >= 23)
1251 txcalval = 0xA8;
1252 else if (channel >= 22)
1253 txcalval = 0xA9;
1254 else if (channel >= 20)
1255 txcalval = 0xAA;
1256 else if (channel >= 17)
1257 txcalval = 0xAB;
1258 else if (channel >= 16)
1259 txcalval = 0xAC;
1260 else if (channel >= 14)
1261 txcalval = 0xAD;
1262 else if (channel >= 12)
1263 txcalval = 0xAE;
1264 else
1265 txcalval = 0xAF;
1266
1267 return tdme_setsfr_request_sync(
1268 1,
1269 CA8210_SFR_LOTXCAL,
1270 txcalval,
1271 device_ref
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