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