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