0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 #include <linux/cdev.h>
0051 #include <linux/clk-provider.h>
0052 #include <linux/debugfs.h>
0053 #include <linux/delay.h>
0054 #include <linux/gpio.h>
0055 #include <linux/ieee802154.h>
0056 #include <linux/io.h>
0057 #include <linux/kfifo.h>
0058 #include <linux/of.h>
0059 #include <linux/of_device.h>
0060 #include <linux/of_gpio.h>
0061 #include <linux/module.h>
0062 #include <linux/mutex.h>
0063 #include <linux/poll.h>
0064 #include <linux/skbuff.h>
0065 #include <linux/slab.h>
0066 #include <linux/spi/spi.h>
0067 #include <linux/spinlock.h>
0068 #include <linux/string.h>
0069 #include <linux/workqueue.h>
0070 #include <linux/interrupt.h>
0071
0072 #include <net/ieee802154_netdev.h>
0073 #include <net/mac802154.h>
0074
0075 #define DRIVER_NAME "ca8210"
0076
0077
0078 #define ONE_MHZ 1000000
0079 #define TWO_MHZ (2 * ONE_MHZ)
0080 #define FOUR_MHZ (4 * ONE_MHZ)
0081 #define EIGHT_MHZ (8 * ONE_MHZ)
0082 #define SIXTEEN_MHZ (16 * ONE_MHZ)
0083
0084
0085 #define CA8210_SPI_BUF_SIZE 256
0086 #define CA8210_SYNC_TIMEOUT 1000
0087
0088
0089 #define CA8210_TEST_INT_FILE_NAME "ca8210_test"
0090 #define CA8210_TEST_INT_FIFO_SIZE 256
0091
0092
0093 #define HWME_EDTHRESHOLD (0x04)
0094 #define HWME_EDVALUE (0x06)
0095 #define HWME_SYSCLKOUT (0x0F)
0096 #define HWME_LQILIMIT (0x11)
0097
0098
0099 #define TDME_CHANNEL (0x00)
0100 #define TDME_ATM_CONFIG (0x06)
0101
0102 #define MAX_HWME_ATTRIBUTE_SIZE 16
0103 #define MAX_TDME_ATTRIBUTE_SIZE 2
0104
0105
0106 #define PHY_CURRENT_CHANNEL (0x00)
0107 #define PHY_TRANSMIT_POWER (0x02)
0108 #define PHY_CCA_MODE (0x03)
0109 #define MAC_ASSOCIATION_PERMIT (0x41)
0110 #define MAC_AUTO_REQUEST (0x42)
0111 #define MAC_BATT_LIFE_EXT (0x43)
0112 #define MAC_BATT_LIFE_EXT_PERIODS (0x44)
0113 #define MAC_BEACON_PAYLOAD (0x45)
0114 #define MAC_BEACON_PAYLOAD_LENGTH (0x46)
0115 #define MAC_BEACON_ORDER (0x47)
0116 #define MAC_GTS_PERMIT (0x4d)
0117 #define MAC_MAX_CSMA_BACKOFFS (0x4e)
0118 #define MAC_MIN_BE (0x4f)
0119 #define MAC_PAN_ID (0x50)
0120 #define MAC_PROMISCUOUS_MODE (0x51)
0121 #define MAC_RX_ON_WHEN_IDLE (0x52)
0122 #define MAC_SHORT_ADDRESS (0x53)
0123 #define MAC_SUPERFRAME_ORDER (0x54)
0124 #define MAC_ASSOCIATED_PAN_COORD (0x56)
0125 #define MAC_MAX_BE (0x57)
0126 #define MAC_MAX_FRAME_RETRIES (0x59)
0127 #define MAC_RESPONSE_WAIT_TIME (0x5A)
0128 #define MAC_SECURITY_ENABLED (0x5D)
0129
0130 #define MAC_AUTO_REQUEST_SECURITY_LEVEL (0x78)
0131 #define MAC_AUTO_REQUEST_KEY_ID_MODE (0x79)
0132
0133 #define NS_IEEE_ADDRESS (0xFF)
0134
0135
0136 #define MAC_MODE_NO_ADDR (0x00)
0137 #define MAC_MODE_SHORT_ADDR (0x02)
0138 #define MAC_MODE_LONG_ADDR (0x03)
0139
0140
0141 #define MAX_BEACON_OVERHEAD (75)
0142 #define MAX_BEACON_PAYLOAD_LENGTH (IEEE802154_MTU - MAX_BEACON_OVERHEAD)
0143
0144 #define MAX_ATTRIBUTE_SIZE (122)
0145 #define MAX_DATA_SIZE (114)
0146
0147 #define CA8210_VALID_CHANNELS (0x07FFF800)
0148
0149
0150 #define CA8210_MAC_WORKAROUNDS (0)
0151 #define CA8210_MAC_MPW (0)
0152
0153
0154 #define LS_BYTE(x) ((u8)((x) & 0xFF))
0155 #define MS_BYTE(x) ((u8)(((x) >> 8) & 0xFF))
0156
0157
0158
0159 #define MCPS_DATA_REQUEST (0x00)
0160 #define MLME_ASSOCIATE_REQUEST (0x02)
0161 #define MLME_ASSOCIATE_RESPONSE (0x03)
0162 #define MLME_DISASSOCIATE_REQUEST (0x04)
0163 #define MLME_GET_REQUEST (0x05)
0164 #define MLME_ORPHAN_RESPONSE (0x06)
0165 #define MLME_RESET_REQUEST (0x07)
0166 #define MLME_RX_ENABLE_REQUEST (0x08)
0167 #define MLME_SCAN_REQUEST (0x09)
0168 #define MLME_SET_REQUEST (0x0A)
0169 #define MLME_START_REQUEST (0x0B)
0170 #define MLME_POLL_REQUEST (0x0D)
0171 #define HWME_SET_REQUEST (0x0E)
0172 #define HWME_GET_REQUEST (0x0F)
0173 #define TDME_SETSFR_REQUEST (0x11)
0174 #define TDME_GETSFR_REQUEST (0x12)
0175 #define TDME_SET_REQUEST (0x14)
0176
0177 #define MCPS_DATA_INDICATION (0x00)
0178 #define MCPS_DATA_CONFIRM (0x01)
0179 #define MLME_RESET_CONFIRM (0x0A)
0180 #define MLME_SET_CONFIRM (0x0E)
0181 #define MLME_START_CONFIRM (0x0F)
0182 #define HWME_SET_CONFIRM (0x12)
0183 #define HWME_GET_CONFIRM (0x13)
0184 #define HWME_WAKEUP_INDICATION (0x15)
0185 #define TDME_SETSFR_CONFIRM (0x17)
0186
0187
0188
0189 #define SPI_S2M (0x20)
0190
0191 #define SPI_SYN (0x40)
0192
0193
0194 #define SPI_IDLE (0xFF)
0195 #define SPI_NACK (0xF0)
0196
0197 #define SPI_MCPS_DATA_REQUEST (MCPS_DATA_REQUEST)
0198 #define SPI_MCPS_DATA_INDICATION (MCPS_DATA_INDICATION + SPI_S2M)
0199 #define SPI_MCPS_DATA_CONFIRM (MCPS_DATA_CONFIRM + SPI_S2M)
0200
0201 #define SPI_MLME_ASSOCIATE_REQUEST (MLME_ASSOCIATE_REQUEST)
0202 #define SPI_MLME_RESET_REQUEST (MLME_RESET_REQUEST + SPI_SYN)
0203 #define SPI_MLME_SET_REQUEST (MLME_SET_REQUEST + SPI_SYN)
0204 #define SPI_MLME_START_REQUEST (MLME_START_REQUEST + SPI_SYN)
0205 #define SPI_MLME_RESET_CONFIRM (MLME_RESET_CONFIRM + SPI_S2M + SPI_SYN)
0206 #define SPI_MLME_SET_CONFIRM (MLME_SET_CONFIRM + SPI_S2M + SPI_SYN)
0207 #define SPI_MLME_START_CONFIRM (MLME_START_CONFIRM + SPI_S2M + SPI_SYN)
0208
0209 #define SPI_HWME_SET_REQUEST (HWME_SET_REQUEST + SPI_SYN)
0210 #define SPI_HWME_GET_REQUEST (HWME_GET_REQUEST + SPI_SYN)
0211 #define SPI_HWME_SET_CONFIRM (HWME_SET_CONFIRM + SPI_S2M + SPI_SYN)
0212 #define SPI_HWME_GET_CONFIRM (HWME_GET_CONFIRM + SPI_S2M + SPI_SYN)
0213 #define SPI_HWME_WAKEUP_INDICATION (HWME_WAKEUP_INDICATION + SPI_S2M)
0214
0215 #define SPI_TDME_SETSFR_REQUEST (TDME_SETSFR_REQUEST + SPI_SYN)
0216 #define SPI_TDME_SET_REQUEST (TDME_SET_REQUEST + SPI_SYN)
0217 #define SPI_TDME_SETSFR_CONFIRM (TDME_SETSFR_CONFIRM + SPI_S2M + SPI_SYN)
0218
0219
0220
0221 #define CA8210_SFR_PACFG (0xB1)
0222 #define CA8210_SFR_MACCON (0xD8)
0223 #define CA8210_SFR_PACFGIB (0xFE)
0224
0225 #define CA8210_SFR_LOTXCAL (0xBF)
0226 #define CA8210_SFR_PTHRH (0xD1)
0227 #define CA8210_SFR_PRECFG (0xD3)
0228 #define CA8210_SFR_LNAGX40 (0xE1)
0229 #define CA8210_SFR_LNAGX41 (0xE2)
0230 #define CA8210_SFR_LNAGX42 (0xE3)
0231 #define CA8210_SFR_LNAGX43 (0xE4)
0232 #define CA8210_SFR_LNAGX44 (0xE5)
0233 #define CA8210_SFR_LNAGX45 (0xE6)
0234 #define CA8210_SFR_LNAGX46 (0xE7)
0235 #define CA8210_SFR_LNAGX47 (0xE9)
0236
0237 #define PACFGIB_DEFAULT_CURRENT (0x3F)
0238 #define PTHRH_DEFAULT_THRESHOLD (0x5A)
0239 #define LNAGX40_DEFAULT_GAIN (0x29)
0240 #define LNAGX41_DEFAULT_GAIN (0x54)
0241 #define LNAGX42_DEFAULT_GAIN (0x6C)
0242 #define LNAGX43_DEFAULT_GAIN (0x7A)
0243 #define LNAGX44_DEFAULT_GAIN (0x84)
0244 #define LNAGX45_DEFAULT_GAIN (0x8B)
0245 #define LNAGX46_DEFAULT_GAIN (0x92)
0246 #define LNAGX47_DEFAULT_GAIN (0x96)
0247
0248 #define CA8210_IOCTL_HARD_RESET (0x00)
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263 struct cas_control {
0264 struct spi_message msg;
0265 struct spi_transfer transfer;
0266
0267 u8 tx_buf[CA8210_SPI_BUF_SIZE];
0268 u8 tx_in_buf[CA8210_SPI_BUF_SIZE];
0269
0270 struct ca8210_priv *priv;
0271 };
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281 struct ca8210_test {
0282 struct dentry *ca8210_dfs_spi_int;
0283 struct kfifo up_fifo;
0284 wait_queue_head_t readq;
0285 };
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315 struct ca8210_priv {
0316 struct spi_device *spi;
0317 struct ieee802154_hw *hw;
0318 bool hw_registered;
0319 spinlock_t lock;
0320 struct workqueue_struct *mlme_workqueue;
0321 struct workqueue_struct *irq_workqueue;
0322 struct sk_buff *tx_skb;
0323 u8 nextmsduhandle;
0324 struct clk *clk;
0325 int last_dsn;
0326 struct ca8210_test test;
0327 bool async_tx_pending;
0328 u8 *sync_command_response;
0329 struct completion ca8210_is_awake;
0330 int sync_down, sync_up;
0331 struct completion spi_transfer_complete, sync_exchange_complete;
0332 bool promiscuous;
0333 int retries;
0334 };
0335
0336
0337
0338
0339
0340
0341
0342
0343 struct work_priv_container {
0344 struct work_struct work;
0345 struct ca8210_priv *priv;
0346 };
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358 struct ca8210_platform_data {
0359 bool extclockenable;
0360 unsigned int extclockfreq;
0361 unsigned int extclockgpio;
0362 int gpio_reset;
0363 int gpio_irq;
0364 int irq_id;
0365 };
0366
0367
0368
0369
0370
0371
0372
0373
0374 struct fulladdr {
0375 u8 mode;
0376 u8 pan_id[2];
0377 u8 address[8];
0378 };
0379
0380
0381
0382
0383
0384
0385
0386 union macaddr {
0387 u16 short_address;
0388 u8 ieee_address[8];
0389 };
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399 struct secspec {
0400 u8 security_level;
0401 u8 key_id_mode;
0402 u8 key_source[8];
0403 u8 key_index;
0404 };
0405
0406
0407 struct mcps_data_request_pset {
0408 u8 src_addr_mode;
0409 struct fulladdr dst;
0410 u8 msdu_length;
0411 u8 msdu_handle;
0412 u8 tx_options;
0413 u8 msdu[MAX_DATA_SIZE];
0414 };
0415
0416 struct mlme_set_request_pset {
0417 u8 pib_attribute;
0418 u8 pib_attribute_index;
0419 u8 pib_attribute_length;
0420 u8 pib_attribute_value[MAX_ATTRIBUTE_SIZE];
0421 };
0422
0423 struct hwme_set_request_pset {
0424 u8 hw_attribute;
0425 u8 hw_attribute_length;
0426 u8 hw_attribute_value[MAX_HWME_ATTRIBUTE_SIZE];
0427 };
0428
0429 struct hwme_get_request_pset {
0430 u8 hw_attribute;
0431 };
0432
0433 struct tdme_setsfr_request_pset {
0434 u8 sfr_page;
0435 u8 sfr_address;
0436 u8 sfr_value;
0437 };
0438
0439
0440 struct hwme_set_confirm_pset {
0441 u8 status;
0442 u8 hw_attribute;
0443 };
0444
0445 struct hwme_get_confirm_pset {
0446 u8 status;
0447 u8 hw_attribute;
0448 u8 hw_attribute_length;
0449 u8 hw_attribute_value[MAX_HWME_ATTRIBUTE_SIZE];
0450 };
0451
0452 struct tdme_setsfr_confirm_pset {
0453 u8 status;
0454 u8 sfr_page;
0455 u8 sfr_address;
0456 };
0457
0458 struct mac_message {
0459 u8 command_id;
0460 u8 length;
0461 union {
0462 struct mcps_data_request_pset data_req;
0463 struct mlme_set_request_pset set_req;
0464 struct hwme_set_request_pset hwme_set_req;
0465 struct hwme_get_request_pset hwme_get_req;
0466 struct tdme_setsfr_request_pset tdme_set_sfr_req;
0467 struct hwme_set_confirm_pset hwme_set_cnf;
0468 struct hwme_get_confirm_pset hwme_get_cnf;
0469 struct tdme_setsfr_confirm_pset tdme_set_sfr_cnf;
0470 u8 u8param;
0471 u8 status;
0472 u8 payload[148];
0473 } pdata;
0474 };
0475
0476 union pa_cfg_sfr {
0477 struct {
0478 u8 bias_current_trim : 3;
0479 u8 : 1;
0480 u8 buffer_capacitor_trim : 3;
0481 u8 boost : 1;
0482 };
0483 u8 paib;
0484 };
0485
0486 struct preamble_cfg_sfr {
0487 u8 timeout_symbols : 3;
0488 u8 acquisition_symbols : 3;
0489 u8 search_symbols : 2;
0490 };
0491
0492 static int (*cascoda_api_upstream)(
0493 const u8 *buf,
0494 size_t len,
0495 void *device_ref
0496 );
0497
0498
0499
0500
0501
0502
0503
0504
0505 static int link_to_linux_err(int link_status)
0506 {
0507 if (link_status < 0) {
0508
0509 return link_status;
0510 }
0511 switch (link_status) {
0512 case IEEE802154_SUCCESS:
0513 case IEEE802154_REALIGNMENT:
0514 return 0;
0515 case IEEE802154_IMPROPER_KEY_TYPE:
0516 return -EKEYREJECTED;
0517 case IEEE802154_IMPROPER_SECURITY_LEVEL:
0518 case IEEE802154_UNSUPPORTED_LEGACY:
0519 case IEEE802154_DENIED:
0520 return -EACCES;
0521 case IEEE802154_BEACON_LOST:
0522 case IEEE802154_NO_ACK:
0523 case IEEE802154_NO_BEACON:
0524 return -ENETUNREACH;
0525 case IEEE802154_CHANNEL_ACCESS_FAILURE:
0526 case IEEE802154_TX_ACTIVE:
0527 case IEEE802154_SCAN_IN_PROGRESS:
0528 return -EBUSY;
0529 case IEEE802154_DISABLE_TRX_FAILURE:
0530 case IEEE802154_OUT_OF_CAP:
0531 return -EAGAIN;
0532 case IEEE802154_FRAME_TOO_LONG:
0533 return -EMSGSIZE;
0534 case IEEE802154_INVALID_GTS:
0535 case IEEE802154_PAST_TIME:
0536 return -EBADSLT;
0537 case IEEE802154_INVALID_HANDLE:
0538 return -EBADMSG;
0539 case IEEE802154_INVALID_PARAMETER:
0540 case IEEE802154_UNSUPPORTED_ATTRIBUTE:
0541 case IEEE802154_ON_TIME_TOO_LONG:
0542 case IEEE802154_INVALID_INDEX:
0543 return -EINVAL;
0544 case IEEE802154_NO_DATA:
0545 return -ENODATA;
0546 case IEEE802154_NO_SHORT_ADDRESS:
0547 return -EFAULT;
0548 case IEEE802154_PAN_ID_CONFLICT:
0549 return -EADDRINUSE;
0550 case IEEE802154_TRANSACTION_EXPIRED:
0551 return -ETIME;
0552 case IEEE802154_TRANSACTION_OVERFLOW:
0553 return -ENOBUFS;
0554 case IEEE802154_UNAVAILABLE_KEY:
0555 return -ENOKEY;
0556 case IEEE802154_INVALID_ADDRESS:
0557 return -ENXIO;
0558 case IEEE802154_TRACKING_OFF:
0559 case IEEE802154_SUPERFRAME_OVERLAP:
0560 return -EREMOTEIO;
0561 case IEEE802154_LIMIT_REACHED:
0562 return -EDQUOT;
0563 case IEEE802154_READ_ONLY:
0564 return -EROFS;
0565 default:
0566 return -EPROTO;
0567 }
0568 }
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579 static int ca8210_test_int_driver_write(
0580 const u8 *buf,
0581 size_t len,
0582 void *spi
0583 )
0584 {
0585 struct ca8210_priv *priv = spi_get_drvdata(spi);
0586 struct ca8210_test *test = &priv->test;
0587 char *fifo_buffer;
0588 int i;
0589
0590 dev_dbg(
0591 &priv->spi->dev,
0592 "test_interface: Buffering upstream message:\n"
0593 );
0594 for (i = 0; i < len; i++)
0595 dev_dbg(&priv->spi->dev, "%#03x\n", buf[i]);
0596
0597 fifo_buffer = kmemdup(buf, len, GFP_KERNEL);
0598 if (!fifo_buffer)
0599 return -ENOMEM;
0600 kfifo_in(&test->up_fifo, &fifo_buffer, 4);
0601 wake_up_interruptible(&priv->test.readq);
0602
0603 return 0;
0604 }
0605
0606
0607
0608 static int ca8210_net_rx(
0609 struct ieee802154_hw *hw,
0610 u8 *command,
0611 size_t len
0612 );
0613 static u8 mlme_reset_request_sync(
0614 u8 set_default_pib,
0615 void *device_ref
0616 );
0617 static int ca8210_spi_transfer(
0618 struct spi_device *spi,
0619 const u8 *buf,
0620 size_t len
0621 );
0622
0623
0624
0625
0626
0627
0628 static void ca8210_reset_send(struct spi_device *spi, unsigned int ms)
0629 {
0630 struct ca8210_platform_data *pdata = spi->dev.platform_data;
0631 struct ca8210_priv *priv = spi_get_drvdata(spi);
0632 long status;
0633
0634 gpio_set_value(pdata->gpio_reset, 0);
0635 reinit_completion(&priv->ca8210_is_awake);
0636 msleep(ms);
0637 gpio_set_value(pdata->gpio_reset, 1);
0638 priv->promiscuous = false;
0639
0640
0641 status = wait_for_completion_interruptible_timeout(
0642 &priv->ca8210_is_awake,
0643 msecs_to_jiffies(CA8210_SYNC_TIMEOUT)
0644 );
0645 if (status == 0) {
0646 dev_crit(
0647 &spi->dev,
0648 "Fatal: No wakeup from ca8210 after reset!\n"
0649 );
0650 }
0651
0652 dev_dbg(&spi->dev, "Reset the device\n");
0653 }
0654
0655
0656
0657
0658
0659
0660 static void ca8210_mlme_reset_worker(struct work_struct *work)
0661 {
0662 struct work_priv_container *wpc = container_of(
0663 work,
0664 struct work_priv_container,
0665 work
0666 );
0667 struct ca8210_priv *priv = wpc->priv;
0668
0669 mlme_reset_request_sync(0, priv->spi);
0670 kfree(wpc);
0671 }
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681 static void ca8210_rx_done(struct cas_control *cas_ctl)
0682 {
0683 u8 *buf;
0684 unsigned int len;
0685 struct work_priv_container *mlme_reset_wpc;
0686 struct ca8210_priv *priv = cas_ctl->priv;
0687
0688 buf = cas_ctl->tx_in_buf;
0689 len = buf[1] + 2;
0690 if (len > CA8210_SPI_BUF_SIZE) {
0691 dev_crit(
0692 &priv->spi->dev,
0693 "Received packet len (%u) erroneously long\n",
0694 len
0695 );
0696 goto finish;
0697 }
0698
0699 if (buf[0] & SPI_SYN) {
0700 if (priv->sync_command_response) {
0701 memcpy(priv->sync_command_response, buf, len);
0702 complete(&priv->sync_exchange_complete);
0703 } else {
0704 if (cascoda_api_upstream)
0705 cascoda_api_upstream(buf, len, priv->spi);
0706 priv->sync_up++;
0707 }
0708 } else {
0709 if (cascoda_api_upstream)
0710 cascoda_api_upstream(buf, len, priv->spi);
0711 }
0712
0713 ca8210_net_rx(priv->hw, buf, len);
0714 if (buf[0] == SPI_MCPS_DATA_CONFIRM) {
0715 if (buf[3] == IEEE802154_TRANSACTION_OVERFLOW) {
0716 dev_info(
0717 &priv->spi->dev,
0718 "Waiting for transaction overflow to stabilise...\n");
0719 msleep(2000);
0720 dev_info(
0721 &priv->spi->dev,
0722 "Resetting MAC...\n");
0723
0724 mlme_reset_wpc = kmalloc(sizeof(*mlme_reset_wpc),
0725 GFP_KERNEL);
0726 if (!mlme_reset_wpc)
0727 goto finish;
0728 INIT_WORK(
0729 &mlme_reset_wpc->work,
0730 ca8210_mlme_reset_worker
0731 );
0732 mlme_reset_wpc->priv = priv;
0733 queue_work(priv->mlme_workqueue, &mlme_reset_wpc->work);
0734 }
0735 } else if (buf[0] == SPI_HWME_WAKEUP_INDICATION) {
0736 dev_notice(
0737 &priv->spi->dev,
0738 "Wakeup indication received, reason:\n"
0739 );
0740 switch (buf[2]) {
0741 case 0:
0742 dev_notice(
0743 &priv->spi->dev,
0744 "Transceiver woken up from Power Up / System Reset\n"
0745 );
0746 break;
0747 case 1:
0748 dev_notice(
0749 &priv->spi->dev,
0750 "Watchdog Timer Time-Out\n"
0751 );
0752 break;
0753 case 2:
0754 dev_notice(
0755 &priv->spi->dev,
0756 "Transceiver woken up from Power-Off by Sleep Timer Time-Out\n");
0757 break;
0758 case 3:
0759 dev_notice(
0760 &priv->spi->dev,
0761 "Transceiver woken up from Power-Off by GPIO Activity\n"
0762 );
0763 break;
0764 case 4:
0765 dev_notice(
0766 &priv->spi->dev,
0767 "Transceiver woken up from Standby by Sleep Timer Time-Out\n"
0768 );
0769 break;
0770 case 5:
0771 dev_notice(
0772 &priv->spi->dev,
0773 "Transceiver woken up from Standby by GPIO Activity\n"
0774 );
0775 break;
0776 case 6:
0777 dev_notice(
0778 &priv->spi->dev,
0779 "Sleep-Timer Time-Out in Active Mode\n"
0780 );
0781 break;
0782 default:
0783 dev_warn(&priv->spi->dev, "Wakeup reason unknown\n");
0784 break;
0785 }
0786 complete(&priv->ca8210_is_awake);
0787 }
0788
0789 finish:;
0790 }
0791
0792 static void ca8210_remove(struct spi_device *spi_device);
0793
0794
0795
0796
0797
0798
0799 static void ca8210_spi_transfer_complete(void *context)
0800 {
0801 struct cas_control *cas_ctl = context;
0802 struct ca8210_priv *priv = cas_ctl->priv;
0803 bool duplex_rx = false;
0804 int i;
0805 u8 retry_buffer[CA8210_SPI_BUF_SIZE];
0806
0807 if (
0808 cas_ctl->tx_in_buf[0] == SPI_NACK ||
0809 (cas_ctl->tx_in_buf[0] == SPI_IDLE &&
0810 cas_ctl->tx_in_buf[1] == SPI_NACK)
0811 ) {
0812
0813 dev_info(&priv->spi->dev, "ca8210 was busy during attempted write\n");
0814 if (cas_ctl->tx_buf[0] == SPI_IDLE) {
0815 dev_warn(
0816 &priv->spi->dev,
0817 "IRQ servicing NACKd, dropping transfer\n"
0818 );
0819 kfree(cas_ctl);
0820 return;
0821 }
0822 if (priv->retries > 3) {
0823 dev_err(&priv->spi->dev, "too many retries!\n");
0824 kfree(cas_ctl);
0825 ca8210_remove(priv->spi);
0826 return;
0827 }
0828 memcpy(retry_buffer, cas_ctl->tx_buf, CA8210_SPI_BUF_SIZE);
0829 kfree(cas_ctl);
0830 ca8210_spi_transfer(
0831 priv->spi,
0832 retry_buffer,
0833 CA8210_SPI_BUF_SIZE
0834 );
0835 priv->retries++;
0836 dev_info(&priv->spi->dev, "retried spi write\n");
0837 return;
0838 } else if (
0839 cas_ctl->tx_in_buf[0] != SPI_IDLE &&
0840 cas_ctl->tx_in_buf[0] != SPI_NACK
0841 ) {
0842 duplex_rx = true;
0843 }
0844
0845 if (duplex_rx) {
0846 dev_dbg(&priv->spi->dev, "READ CMD DURING TX\n");
0847 for (i = 0; i < cas_ctl->tx_in_buf[1] + 2; i++)
0848 dev_dbg(
0849 &priv->spi->dev,
0850 "%#03x\n",
0851 cas_ctl->tx_in_buf[i]
0852 );
0853 ca8210_rx_done(cas_ctl);
0854 }
0855 complete(&priv->spi_transfer_complete);
0856 kfree(cas_ctl);
0857 priv->retries = 0;
0858 }
0859
0860
0861
0862
0863
0864
0865
0866
0867
0868 static int ca8210_spi_transfer(
0869 struct spi_device *spi,
0870 const u8 *buf,
0871 size_t len
0872 )
0873 {
0874 int i, status = 0;
0875 struct ca8210_priv *priv;
0876 struct cas_control *cas_ctl;
0877
0878 if (!spi) {
0879 pr_crit("NULL spi device passed to %s\n", __func__);
0880 return -ENODEV;
0881 }
0882
0883 priv = spi_get_drvdata(spi);
0884 reinit_completion(&priv->spi_transfer_complete);
0885
0886 dev_dbg(&spi->dev, "%s called\n", __func__);
0887
0888 cas_ctl = kmalloc(sizeof(*cas_ctl), GFP_ATOMIC);
0889 if (!cas_ctl)
0890 return -ENOMEM;
0891
0892 cas_ctl->priv = priv;
0893 memset(cas_ctl->tx_buf, SPI_IDLE, CA8210_SPI_BUF_SIZE);
0894 memset(cas_ctl->tx_in_buf, SPI_IDLE, CA8210_SPI_BUF_SIZE);
0895 memcpy(cas_ctl->tx_buf, buf, len);
0896
0897 for (i = 0; i < len; i++)
0898 dev_dbg(&spi->dev, "%#03x\n", cas_ctl->tx_buf[i]);
0899
0900 spi_message_init(&cas_ctl->msg);
0901
0902 cas_ctl->transfer.tx_nbits = 1;
0903 cas_ctl->transfer.rx_nbits = 1;
0904 cas_ctl->transfer.speed_hz = 0;
0905 cas_ctl->transfer.bits_per_word = 0;
0906 cas_ctl->transfer.tx_buf = cas_ctl->tx_buf;
0907 cas_ctl->transfer.rx_buf = cas_ctl->tx_in_buf;
0908 cas_ctl->transfer.delay.value = 0;
0909 cas_ctl->transfer.delay.unit = SPI_DELAY_UNIT_USECS;
0910 cas_ctl->transfer.cs_change = 0;
0911 cas_ctl->transfer.len = sizeof(struct mac_message);
0912 cas_ctl->msg.complete = ca8210_spi_transfer_complete;
0913 cas_ctl->msg.context = cas_ctl;
0914
0915 spi_message_add_tail(
0916 &cas_ctl->transfer,
0917 &cas_ctl->msg
0918 );
0919
0920 status = spi_async(spi, &cas_ctl->msg);
0921 if (status < 0) {
0922 dev_crit(
0923 &spi->dev,
0924 "status %d from spi_sync in write\n",
0925 status
0926 );
0927 }
0928
0929 return status;
0930 }
0931
0932
0933
0934
0935
0936
0937
0938
0939
0940
0941
0942
0943
0944
0945 static int ca8210_spi_exchange(
0946 const u8 *buf,
0947 size_t len,
0948 u8 *response,
0949 void *device_ref
0950 )
0951 {
0952 int status = 0;
0953 struct spi_device *spi = device_ref;
0954 struct ca8210_priv *priv = spi->dev.driver_data;
0955 long wait_remaining;
0956
0957 if ((buf[0] & SPI_SYN) && response) {
0958 reinit_completion(&priv->sync_exchange_complete);
0959 priv->sync_command_response = response;
0960 }
0961
0962 do {
0963 reinit_completion(&priv->spi_transfer_complete);
0964 status = ca8210_spi_transfer(priv->spi, buf, len);
0965 if (status) {
0966 dev_warn(
0967 &spi->dev,
0968 "spi write failed, returned %d\n",
0969 status
0970 );
0971 if (status == -EBUSY)
0972 continue;
0973 if (((buf[0] & SPI_SYN) && response))
0974 complete(&priv->sync_exchange_complete);
0975 goto cleanup;
0976 }
0977
0978 wait_remaining = wait_for_completion_interruptible_timeout(
0979 &priv->spi_transfer_complete,
0980 msecs_to_jiffies(1000)
0981 );
0982 if (wait_remaining == -ERESTARTSYS) {
0983 status = -ERESTARTSYS;
0984 } else if (wait_remaining == 0) {
0985 dev_err(
0986 &spi->dev,
0987 "SPI downstream transfer timed out!\n"
0988 );
0989 status = -ETIME;
0990 goto cleanup;
0991 }
0992 } while (status < 0);
0993
0994 if (!((buf[0] & SPI_SYN) && response))
0995 goto cleanup;
0996
0997 wait_remaining = wait_for_completion_interruptible_timeout(
0998 &priv->sync_exchange_complete,
0999 msecs_to_jiffies(CA8210_SYNC_TIMEOUT)
1000 );
1001 if (wait_remaining == -ERESTARTSYS) {
1002 status = -ERESTARTSYS;
1003 } else if (wait_remaining == 0) {
1004 dev_err(
1005 &spi->dev,
1006 "Synchronous confirm timeout\n"
1007 );
1008 status = -ETIME;
1009 }
1010
1011 cleanup:
1012 priv->sync_command_response = NULL;
1013 return status;
1014 }
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027 static irqreturn_t ca8210_interrupt_handler(int irq, void *dev_id)
1028 {
1029 struct ca8210_priv *priv = dev_id;
1030 int status;
1031
1032 dev_dbg(&priv->spi->dev, "irq: Interrupt occurred\n");
1033 do {
1034 status = ca8210_spi_transfer(priv->spi, NULL, 0);
1035 if (status && (status != -EBUSY)) {
1036 dev_warn(
1037 &priv->spi->dev,
1038 "spi read failed, returned %d\n",
1039 status
1040 );
1041 }
1042 } while (status == -EBUSY);
1043 return IRQ_HANDLED;
1044 }
1045
1046 static int (*cascoda_api_downstream)(
1047 const u8 *buf,
1048 size_t len,
1049 u8 *response,
1050 void *device_ref
1051 ) = ca8210_spi_exchange;
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064 static u8 tdme_setsfr_request_sync(
1065 u8 sfr_page,
1066 u8 sfr_address,
1067 u8 sfr_value,
1068 void *device_ref
1069 )
1070 {
1071 int ret;
1072 struct mac_message command, response;
1073 struct spi_device *spi = device_ref;
1074
1075 command.command_id = SPI_TDME_SETSFR_REQUEST;
1076 command.length = 3;
1077 command.pdata.tdme_set_sfr_req.sfr_page = sfr_page;
1078 command.pdata.tdme_set_sfr_req.sfr_address = sfr_address;
1079 command.pdata.tdme_set_sfr_req.sfr_value = sfr_value;
1080 response.command_id = SPI_IDLE;
1081 ret = cascoda_api_downstream(
1082 &command.command_id,
1083 command.length + 2,
1084 &response.command_id,
1085 device_ref
1086 );
1087 if (ret) {
1088 dev_crit(&spi->dev, "cascoda_api_downstream returned %d", ret);
1089 return IEEE802154_SYSTEM_ERROR;
1090 }
1091
1092 if (response.command_id != SPI_TDME_SETSFR_CONFIRM) {
1093 dev_crit(
1094 &spi->dev,
1095 "sync response to SPI_TDME_SETSFR_REQUEST was not SPI_TDME_SETSFR_CONFIRM, it was %d\n",
1096 response.command_id
1097 );
1098 return IEEE802154_SYSTEM_ERROR;
1099 }
1100
1101 return response.pdata.tdme_set_sfr_cnf.status;
1102 }
1103
1104
1105
1106
1107
1108
1109
1110 static u8 tdme_chipinit(void *device_ref)
1111 {
1112 u8 status = IEEE802154_SUCCESS;
1113 u8 sfr_address;
1114 struct spi_device *spi = device_ref;
1115 struct preamble_cfg_sfr pre_cfg_value = {
1116 .timeout_symbols = 3,
1117 .acquisition_symbols = 3,
1118 .search_symbols = 1,
1119 };
1120
1121 status = tdme_setsfr_request_sync(
1122 1, (sfr_address = CA8210_SFR_LNAGX40),
1123 LNAGX40_DEFAULT_GAIN, device_ref);
1124 if (status)
1125 goto finish;
1126 status = tdme_setsfr_request_sync(
1127 1, (sfr_address = CA8210_SFR_LNAGX41),
1128 LNAGX41_DEFAULT_GAIN, device_ref);
1129 if (status)
1130 goto finish;
1131 status = tdme_setsfr_request_sync(
1132 1, (sfr_address = CA8210_SFR_LNAGX42),
1133 LNAGX42_DEFAULT_GAIN, device_ref);
1134 if (status)
1135 goto finish;
1136 status = tdme_setsfr_request_sync(
1137 1, (sfr_address = CA8210_SFR_LNAGX43),
1138 LNAGX43_DEFAULT_GAIN, device_ref);
1139 if (status)
1140 goto finish;
1141 status = tdme_setsfr_request_sync(
1142 1, (sfr_address = CA8210_SFR_LNAGX44),
1143 LNAGX44_DEFAULT_GAIN, device_ref);
1144 if (status)
1145 goto finish;
1146 status = tdme_setsfr_request_sync(
1147 1, (sfr_address = CA8210_SFR_LNAGX45),
1148 LNAGX45_DEFAULT_GAIN, device_ref);
1149 if (status)
1150 goto finish;
1151 status = tdme_setsfr_request_sync(
1152 1, (sfr_address = CA8210_SFR_LNAGX46),
1153 LNAGX46_DEFAULT_GAIN, device_ref);
1154 if (status)
1155 goto finish;
1156 status = tdme_setsfr_request_sync(
1157 1, (sfr_address = CA8210_SFR_LNAGX47),
1158 LNAGX47_DEFAULT_GAIN, device_ref);
1159 if (status)
1160 goto finish;
1161
1162 status = tdme_setsfr_request_sync(
1163 1, (sfr_address = CA8210_SFR_PRECFG),
1164 *((u8 *)&pre_cfg_value), device_ref);
1165 if (status)
1166 goto finish;
1167
1168 status = tdme_setsfr_request_sync(
1169 1, (sfr_address = CA8210_SFR_PTHRH),
1170 PTHRH_DEFAULT_THRESHOLD, device_ref);
1171 if (status)
1172 goto finish;
1173
1174 status = tdme_setsfr_request_sync(
1175 0, (sfr_address = CA8210_SFR_PACFGIB),
1176 PACFGIB_DEFAULT_CURRENT, device_ref);
1177 if (status)
1178 goto finish;
1179
1180 finish:
1181 if (status != IEEE802154_SUCCESS) {
1182 dev_err(
1183 &spi->dev,
1184 "failed to set sfr at %#03x, status = %#03x\n",
1185 sfr_address,
1186 status
1187 );
1188 }
1189 return status;
1190 }
1191
1192
1193
1194
1195
1196
1197
1198
1199 static u8 tdme_channelinit(u8 channel, void *device_ref)
1200 {
1201
1202
1203
1204 u8 txcalval;
1205
1206 if (channel >= 25)
1207 txcalval = 0xA7;
1208 else if (channel >= 23)
1209 txcalval = 0xA8;
1210 else if (channel >= 22)
1211 txcalval = 0xA9;
1212 else if (channel >= 20)
1213 txcalval = 0xAA;
1214 else if (channel >= 17)
1215 txcalval = 0xAB;
1216 else if (channel >= 16)
1217 txcalval = 0xAC;
1218 else if (channel >= 14)
1219 txcalval = 0xAD;
1220 else if (channel >= 12)
1221 txcalval = 0xAE;
1222 else
1223 txcalval = 0xAF;
1224
1225 return tdme_setsfr_request_sync(
1226 1,
1227 CA8210_SFR_LOTXCAL,
1228 txcalval,
1229 device_ref
1230 );
1231 }
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242 static u8 tdme_checkpibattribute(
1243 u8 pib_attribute,
1244 u8 pib_attribute_length,
1245 const void *pib_attribute_value
1246 )
1247 {
1248 u8 status = IEEE802154_SUCCESS;
1249 u8 value;
1250
1251 value = *((u8 *)pib_attribute_value);
1252
1253 switch (pib_attribute) {
1254
1255 case PHY_TRANSMIT_POWER:
1256 if (value > 0x3F)
1257 status = IEEE802154_INVALID_PARAMETER;
1258 break;
1259 case PHY_CCA_MODE:
1260 if (value > 0x03)
1261 status = IEEE802154_INVALID_PARAMETER;
1262 break;
1263
1264 case MAC_BATT_LIFE_EXT_PERIODS:
1265 if (value < 6 || value > 41)
1266 status = IEEE802154_INVALID_PARAMETER;
1267 break;
1268 case MAC_BEACON_PAYLOAD:
1269 if (pib_attribute_length > MAX_BEACON_PAYLOAD_LENGTH)
1270 status = IEEE802154_INVALID_PARAMETER;
1271 break;
1272 case MAC_BEACON_PAYLOAD_LENGTH:
1273 if (value > MAX_BEACON_PAYLOAD_LENGTH)
1274 status = IEEE802154_INVALID_PARAMETER;
1275 break;
1276 case MAC_BEACON_ORDER:
1277 if (value > 15)
1278 status = IEEE802154_INVALID_PARAMETER;
1279 break;
1280 case MAC_MAX_BE:
1281 if (value < 3 || value > 8)
1282 status = IEEE802154_INVALID_PARAMETER;
1283 break;
1284 case MAC_MAX_CSMA_BACKOFFS:
1285 if (value > 5)
1286 status = IEEE802154_INVALID_PARAMETER;
1287 break;
1288 case MAC_MAX_FRAME_RETRIES:
1289 if (value > 7)
1290 status = IEEE802154_INVALID_PARAMETER;
1291 break;
1292 case MAC_MIN_BE:
1293 if (value > 8)
1294 status = IEEE802154_INVALID_PARAMETER;
1295 break;
1296 case MAC_RESPONSE_WAIT_TIME:
1297 if (value < 2 || value > 64)
1298 status = IEEE802154_INVALID_PARAMETER;
1299 break;
1300 case MAC_SUPERFRAME_ORDER:
1301 if (value > 15)
1302 status = IEEE802154_INVALID_PARAMETER;
1303 break;
1304
1305 case MAC_ASSOCIATED_PAN_COORD:
1306 case MAC_ASSOCIATION_PERMIT:
1307 case MAC_AUTO_REQUEST:
1308 case MAC_BATT_LIFE_EXT:
1309 case MAC_GTS_PERMIT:
1310 case MAC_PROMISCUOUS_MODE:
1311 case MAC_RX_ON_WHEN_IDLE:
1312 case MAC_SECURITY_ENABLED:
1313 if (value > 1)
1314 status = IEEE802154_INVALID_PARAMETER;
1315 break;
1316
1317 case MAC_AUTO_REQUEST_SECURITY_LEVEL:
1318 if (value > 7)
1319 status = IEEE802154_INVALID_PARAMETER;
1320 break;
1321 case MAC_AUTO_REQUEST_KEY_ID_MODE:
1322 if (value > 3)
1323 status = IEEE802154_INVALID_PARAMETER;
1324 break;
1325 default:
1326 break;
1327 }
1328
1329 return status;
1330 }
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343 static u8 tdme_settxpower(u8 txp, void *device_ref)
1344 {
1345 u8 status;
1346 s8 txp_val;
1347 u8 txp_ext;
1348 union pa_cfg_sfr pa_cfg_val;
1349
1350
1351 txp_ext = 0x3F & txp;
1352 if (txp_ext & 0x20)
1353 txp_ext += 0xC0;
1354 txp_val = (s8)txp_ext;
1355
1356 if (CA8210_MAC_MPW) {
1357 if (txp_val > 0) {
1358
1359 pa_cfg_val.bias_current_trim = 3;
1360 pa_cfg_val.buffer_capacitor_trim = 5;
1361 pa_cfg_val.boost = 1;
1362 } else {
1363
1364 pa_cfg_val.bias_current_trim = 3;
1365 pa_cfg_val.buffer_capacitor_trim = 7;
1366 pa_cfg_val.boost = 0;
1367 }
1368
1369 status = tdme_setsfr_request_sync(
1370 0,
1371 CA8210_SFR_PACFG,
1372 pa_cfg_val.paib,
1373 device_ref
1374 );
1375 } else {
1376
1377
1378
1379 if (txp_val > 8) {
1380 pa_cfg_val.paib = 0x3F;
1381 } else if (txp_val == 8) {
1382 pa_cfg_val.paib = 0x32;
1383 } else if (txp_val == 7) {
1384 pa_cfg_val.paib = 0x22;
1385 } else if (txp_val == 6) {
1386 pa_cfg_val.paib = 0x18;
1387 } else if (txp_val == 5) {
1388 pa_cfg_val.paib = 0x10;
1389 } else if (txp_val == 4) {
1390 pa_cfg_val.paib = 0x0C;
1391 } else if (txp_val == 3) {
1392 pa_cfg_val.paib = 0x08;
1393 } else if (txp_val == 2) {
1394 pa_cfg_val.paib = 0x05;
1395 } else if (txp_val == 1) {
1396 pa_cfg_val.paib = 0x03;
1397 } else if (txp_val == 0) {
1398 pa_cfg_val.paib = 0x01;
1399 } else {
1400 pa_cfg_val.paib = 0x00;
1401 }
1402
1403 status = tdme_setsfr_request_sync(
1404 0,
1405 CA8210_SFR_PACFGIB,
1406 pa_cfg_val.paib,
1407 device_ref
1408 );
1409 }
1410
1411 return status;
1412 }
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429 static u8 mcps_data_request(
1430 u8 src_addr_mode,
1431 u8 dst_address_mode,
1432 u16 dst_pan_id,
1433 union macaddr *dst_addr,
1434 u8 msdu_length,
1435 u8 *msdu,
1436 u8 msdu_handle,
1437 u8 tx_options,
1438 struct secspec *security,
1439 void *device_ref
1440 )
1441 {
1442 struct secspec *psec;
1443 struct mac_message command;
1444
1445 command.command_id = SPI_MCPS_DATA_REQUEST;
1446 command.pdata.data_req.src_addr_mode = src_addr_mode;
1447 command.pdata.data_req.dst.mode = dst_address_mode;
1448 if (dst_address_mode != MAC_MODE_NO_ADDR) {
1449 command.pdata.data_req.dst.pan_id[0] = LS_BYTE(dst_pan_id);
1450 command.pdata.data_req.dst.pan_id[1] = MS_BYTE(dst_pan_id);
1451 if (dst_address_mode == MAC_MODE_SHORT_ADDR) {
1452 command.pdata.data_req.dst.address[0] = LS_BYTE(
1453 dst_addr->short_address
1454 );
1455 command.pdata.data_req.dst.address[1] = MS_BYTE(
1456 dst_addr->short_address
1457 );
1458 } else {
1459 memcpy(
1460 command.pdata.data_req.dst.address,
1461 dst_addr->ieee_address,
1462 8
1463 );
1464 }
1465 }
1466 command.pdata.data_req.msdu_length = msdu_length;
1467 command.pdata.data_req.msdu_handle = msdu_handle;
1468 command.pdata.data_req.tx_options = tx_options;
1469 memcpy(command.pdata.data_req.msdu, msdu, msdu_length);
1470 psec = (struct secspec *)(command.pdata.data_req.msdu + msdu_length);
1471 command.length = sizeof(struct mcps_data_request_pset) -
1472 MAX_DATA_SIZE + msdu_length;
1473 if (!security || security->security_level == 0) {
1474 psec->security_level = 0;
1475 command.length += 1;
1476 } else {
1477 *psec = *security;
1478 command.length += sizeof(struct secspec);
1479 }
1480
1481 if (ca8210_spi_transfer(device_ref, &command.command_id,
1482 command.length + 2))
1483 return IEEE802154_SYSTEM_ERROR;
1484
1485 return IEEE802154_SUCCESS;
1486 }
1487
1488
1489
1490
1491
1492
1493
1494
1495 static u8 mlme_reset_request_sync(
1496 u8 set_default_pib,
1497 void *device_ref
1498 )
1499 {
1500 u8 status;
1501 struct mac_message command, response;
1502 struct spi_device *spi = device_ref;
1503
1504 command.command_id = SPI_MLME_RESET_REQUEST;
1505 command.length = 1;
1506 command.pdata.u8param = set_default_pib;
1507
1508 if (cascoda_api_downstream(
1509 &command.command_id,
1510 command.length + 2,
1511 &response.command_id,
1512 device_ref)) {
1513 dev_err(&spi->dev, "cascoda_api_downstream failed\n");
1514 return IEEE802154_SYSTEM_ERROR;
1515 }
1516
1517 if (response.command_id != SPI_MLME_RESET_CONFIRM)
1518 return IEEE802154_SYSTEM_ERROR;
1519
1520 status = response.pdata.status;
1521
1522
1523 if (CA8210_MAC_WORKAROUNDS && set_default_pib && !status) {
1524 status = tdme_setsfr_request_sync(
1525 0,
1526 CA8210_SFR_MACCON,
1527 0,
1528 device_ref
1529 );
1530 }
1531
1532 return status;
1533 }
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545 static u8 mlme_set_request_sync(
1546 u8 pib_attribute,
1547 u8 pib_attribute_index,
1548 u8 pib_attribute_length,
1549 const void *pib_attribute_value,
1550 void *device_ref
1551 )
1552 {
1553 u8 status;
1554 struct mac_message command, response;
1555
1556
1557
1558
1559 if (tdme_checkpibattribute(
1560 pib_attribute, pib_attribute_length, pib_attribute_value)) {
1561 return IEEE802154_INVALID_PARAMETER;
1562 }
1563
1564 if (pib_attribute == PHY_CURRENT_CHANNEL) {
1565 status = tdme_channelinit(
1566 *((u8 *)pib_attribute_value),
1567 device_ref
1568 );
1569 if (status)
1570 return status;
1571 }
1572
1573 if (pib_attribute == PHY_TRANSMIT_POWER) {
1574 return tdme_settxpower(
1575 *((u8 *)pib_attribute_value),
1576 device_ref
1577 );
1578 }
1579
1580 command.command_id = SPI_MLME_SET_REQUEST;
1581 command.length = sizeof(struct mlme_set_request_pset) -
1582 MAX_ATTRIBUTE_SIZE + pib_attribute_length;
1583 command.pdata.set_req.pib_attribute = pib_attribute;
1584 command.pdata.set_req.pib_attribute_index = pib_attribute_index;
1585 command.pdata.set_req.pib_attribute_length = pib_attribute_length;
1586 memcpy(
1587 command.pdata.set_req.pib_attribute_value,
1588 pib_attribute_value,
1589 pib_attribute_length
1590 );
1591
1592 if (cascoda_api_downstream(
1593 &command.command_id,
1594 command.length + 2,
1595 &response.command_id,
1596 device_ref)) {
1597 return IEEE802154_SYSTEM_ERROR;
1598 }
1599
1600 if (response.command_id != SPI_MLME_SET_CONFIRM)
1601 return IEEE802154_SYSTEM_ERROR;
1602
1603 return response.pdata.status;
1604 }
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615 static u8 hwme_set_request_sync(
1616 u8 hw_attribute,
1617 u8 hw_attribute_length,
1618 u8 *hw_attribute_value,
1619 void *device_ref
1620 )
1621 {
1622 struct mac_message command, response;
1623
1624 command.command_id = SPI_HWME_SET_REQUEST;
1625 command.length = 2 + hw_attribute_length;
1626 command.pdata.hwme_set_req.hw_attribute = hw_attribute;
1627 command.pdata.hwme_set_req.hw_attribute_length = hw_attribute_length;
1628 memcpy(
1629 command.pdata.hwme_set_req.hw_attribute_value,
1630 hw_attribute_value,
1631 hw_attribute_length
1632 );
1633
1634 if (cascoda_api_downstream(
1635 &command.command_id,
1636 command.length + 2,
1637 &response.command_id,
1638 device_ref)) {
1639 return IEEE802154_SYSTEM_ERROR;
1640 }
1641
1642 if (response.command_id != SPI_HWME_SET_CONFIRM)
1643 return IEEE802154_SYSTEM_ERROR;
1644
1645 return response.pdata.hwme_set_cnf.status;
1646 }
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657 static u8 hwme_get_request_sync(
1658 u8 hw_attribute,
1659 u8 *hw_attribute_length,
1660 u8 *hw_attribute_value,
1661 void *device_ref
1662 )
1663 {
1664 struct mac_message command, response;
1665
1666 command.command_id = SPI_HWME_GET_REQUEST;
1667 command.length = 1;
1668 command.pdata.hwme_get_req.hw_attribute = hw_attribute;
1669
1670 if (cascoda_api_downstream(
1671 &command.command_id,
1672 command.length + 2,
1673 &response.command_id,
1674 device_ref)) {
1675 return IEEE802154_SYSTEM_ERROR;
1676 }
1677
1678 if (response.command_id != SPI_HWME_GET_CONFIRM)
1679 return IEEE802154_SYSTEM_ERROR;
1680
1681 if (response.pdata.hwme_get_cnf.status == IEEE802154_SUCCESS) {
1682 *hw_attribute_length =
1683 response.pdata.hwme_get_cnf.hw_attribute_length;
1684 memcpy(
1685 hw_attribute_value,
1686 response.pdata.hwme_get_cnf.hw_attribute_value,
1687 *hw_attribute_length
1688 );
1689 }
1690
1691 return response.pdata.hwme_get_cnf.status;
1692 }
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705 static int ca8210_async_xmit_complete(
1706 struct ieee802154_hw *hw,
1707 u8 msduhandle,
1708 u8 status)
1709 {
1710 struct ca8210_priv *priv = hw->priv;
1711
1712 if (priv->nextmsduhandle != msduhandle) {
1713 dev_err(
1714 &priv->spi->dev,
1715 "Unexpected msdu_handle on data confirm, Expected %d, got %d\n",
1716 priv->nextmsduhandle,
1717 msduhandle
1718 );
1719 return -EIO;
1720 }
1721
1722 priv->async_tx_pending = false;
1723 priv->nextmsduhandle++;
1724
1725 if (status) {
1726 dev_err(
1727 &priv->spi->dev,
1728 "Link transmission unsuccessful, status = %d\n",
1729 status
1730 );
1731 if (status != IEEE802154_TRANSACTION_OVERFLOW) {
1732 ieee802154_xmit_error(priv->hw, priv->tx_skb, status);
1733 return 0;
1734 }
1735 }
1736 ieee802154_xmit_complete(priv->hw, priv->tx_skb, true);
1737
1738 return 0;
1739 }
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754 static int ca8210_skb_rx(
1755 struct ieee802154_hw *hw,
1756 size_t len,
1757 u8 *data_ind
1758 )
1759 {
1760 struct ieee802154_hdr hdr;
1761 int msdulen;
1762 int hlen;
1763 u8 mpdulinkquality = data_ind[23];
1764 struct sk_buff *skb;
1765 struct ca8210_priv *priv = hw->priv;
1766
1767
1768 skb = dev_alloc_skb(IEEE802154_MTU + sizeof(hdr));
1769 if (!skb)
1770 return -ENOMEM;
1771
1772 skb_reserve(skb, sizeof(hdr));
1773
1774 msdulen = data_ind[22];
1775 if (msdulen > IEEE802154_MTU) {
1776 dev_err(
1777 &priv->spi->dev,
1778 "received erroneously large msdu length!\n"
1779 );
1780 kfree_skb(skb);
1781 return -EMSGSIZE;
1782 }
1783 dev_dbg(&priv->spi->dev, "skb buffer length = %d\n", msdulen);
1784
1785 if (priv->promiscuous)
1786 goto copy_payload;
1787
1788
1789 hdr.sec.level = data_ind[29 + msdulen];
1790 dev_dbg(&priv->spi->dev, "security level: %#03x\n", hdr.sec.level);
1791 if (hdr.sec.level > 0) {
1792 hdr.sec.key_id_mode = data_ind[30 + msdulen];
1793 memcpy(&hdr.sec.extended_src, &data_ind[31 + msdulen], 8);
1794 hdr.sec.key_id = data_ind[39 + msdulen];
1795 }
1796 hdr.source.mode = data_ind[0];
1797 dev_dbg(&priv->spi->dev, "srcAddrMode: %#03x\n", hdr.source.mode);
1798 hdr.source.pan_id = *(u16 *)&data_ind[1];
1799 dev_dbg(&priv->spi->dev, "srcPanId: %#06x\n", hdr.source.pan_id);
1800 memcpy(&hdr.source.extended_addr, &data_ind[3], 8);
1801 hdr.dest.mode = data_ind[11];
1802 dev_dbg(&priv->spi->dev, "dstAddrMode: %#03x\n", hdr.dest.mode);
1803 hdr.dest.pan_id = *(u16 *)&data_ind[12];
1804 dev_dbg(&priv->spi->dev, "dstPanId: %#06x\n", hdr.dest.pan_id);
1805 memcpy(&hdr.dest.extended_addr, &data_ind[14], 8);
1806
1807
1808 hdr.fc.type = 1;
1809 if (hdr.sec.level)
1810 hdr.fc.security_enabled = 1;
1811 else
1812 hdr.fc.security_enabled = 0;
1813 if (data_ind[1] != data_ind[12] || data_ind[2] != data_ind[13])
1814 hdr.fc.intra_pan = 1;
1815 else
1816 hdr.fc.intra_pan = 0;
1817 hdr.fc.dest_addr_mode = hdr.dest.mode;
1818 hdr.fc.source_addr_mode = hdr.source.mode;
1819
1820
1821 hlen = ieee802154_hdr_push(skb, &hdr);
1822
1823 if (hlen < 0) {
1824 dev_crit(&priv->spi->dev, "failed to push mac hdr onto skb!\n");
1825 kfree_skb(skb);
1826 return hlen;
1827 }
1828
1829 skb_reset_mac_header(skb);
1830 skb->mac_len = hlen;
1831
1832 copy_payload:
1833
1834
1835 skb_put_data(skb, &data_ind[29], msdulen);
1836
1837 ieee802154_rx_irqsafe(hw, skb, mpdulinkquality);
1838 return 0;
1839 }
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854 static int ca8210_net_rx(struct ieee802154_hw *hw, u8 *command, size_t len)
1855 {
1856 struct ca8210_priv *priv = hw->priv;
1857 unsigned long flags;
1858 u8 status;
1859
1860 dev_dbg(&priv->spi->dev, "%s: CmdID = %d\n", __func__, command[0]);
1861
1862 if (command[0] == SPI_MCPS_DATA_INDICATION) {
1863
1864 spin_lock_irqsave(&priv->lock, flags);
1865 if (command[26] == priv->last_dsn) {
1866 dev_dbg(
1867 &priv->spi->dev,
1868 "DSN %d resend received, ignoring...\n",
1869 command[26]
1870 );
1871 spin_unlock_irqrestore(&priv->lock, flags);
1872 return 0;
1873 }
1874 priv->last_dsn = command[26];
1875 spin_unlock_irqrestore(&priv->lock, flags);
1876 return ca8210_skb_rx(hw, len - 2, command + 2);
1877 } else if (command[0] == SPI_MCPS_DATA_CONFIRM) {
1878 status = command[3];
1879 if (priv->async_tx_pending) {
1880 return ca8210_async_xmit_complete(
1881 hw,
1882 command[2],
1883 status
1884 );
1885 }
1886 }
1887
1888 return 0;
1889 }
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899 static int ca8210_skb_tx(
1900 struct sk_buff *skb,
1901 u8 msduhandle,
1902 struct ca8210_priv *priv
1903 )
1904 {
1905 int status;
1906 struct ieee802154_hdr header = { };
1907 struct secspec secspec;
1908 unsigned int mac_len;
1909
1910 dev_dbg(&priv->spi->dev, "%s called\n", __func__);
1911
1912
1913
1914
1915 mac_len = ieee802154_hdr_peek_addrs(skb, &header);
1916
1917 secspec.security_level = header.sec.level;
1918 secspec.key_id_mode = header.sec.key_id_mode;
1919 if (secspec.key_id_mode == 2)
1920 memcpy(secspec.key_source, &header.sec.short_src, 4);
1921 else if (secspec.key_id_mode == 3)
1922 memcpy(secspec.key_source, &header.sec.extended_src, 8);
1923 secspec.key_index = header.sec.key_id;
1924
1925
1926 status = mcps_data_request(
1927 header.source.mode,
1928 header.dest.mode,
1929 header.dest.pan_id,
1930 (union macaddr *)&header.dest.extended_addr,
1931 skb->len - mac_len,
1932 &skb->data[mac_len],
1933 msduhandle,
1934 header.fc.ack_request,
1935 &secspec,
1936 priv->spi
1937 );
1938 return link_to_linux_err(status);
1939 }
1940
1941
1942
1943
1944
1945
1946
1947 static int ca8210_start(struct ieee802154_hw *hw)
1948 {
1949 int status;
1950 u8 rx_on_when_idle;
1951 u8 lqi_threshold = 0;
1952 struct ca8210_priv *priv = hw->priv;
1953
1954 priv->last_dsn = -1;
1955
1956 rx_on_when_idle = 1;
1957 status = mlme_set_request_sync(
1958 MAC_RX_ON_WHEN_IDLE,
1959 0,
1960 1,
1961 &rx_on_when_idle,
1962 priv->spi
1963 );
1964 if (status) {
1965 dev_crit(
1966 &priv->spi->dev,
1967 "Setting rx_on_when_idle failed, status = %d\n",
1968 status
1969 );
1970 return link_to_linux_err(status);
1971 }
1972 status = hwme_set_request_sync(
1973 HWME_LQILIMIT,
1974 1,
1975 &lqi_threshold,
1976 priv->spi
1977 );
1978 if (status) {
1979 dev_crit(
1980 &priv->spi->dev,
1981 "Setting lqilimit failed, status = %d\n",
1982 status
1983 );
1984 return link_to_linux_err(status);
1985 }
1986
1987 return 0;
1988 }
1989
1990
1991
1992
1993
1994
1995
1996 static void ca8210_stop(struct ieee802154_hw *hw)
1997 {
1998 }
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008 static int ca8210_xmit_async(struct ieee802154_hw *hw, struct sk_buff *skb)
2009 {
2010 struct ca8210_priv *priv = hw->priv;
2011 int status;
2012
2013 dev_dbg(&priv->spi->dev, "calling %s\n", __func__);
2014
2015 priv->tx_skb = skb;
2016 priv->async_tx_pending = true;
2017 status = ca8210_skb_tx(skb, priv->nextmsduhandle, priv);
2018 return status;
2019 }
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029 static int ca8210_get_ed(struct ieee802154_hw *hw, u8 *level)
2030 {
2031 u8 lenvar;
2032 struct ca8210_priv *priv = hw->priv;
2033
2034 return link_to_linux_err(
2035 hwme_get_request_sync(HWME_EDVALUE, &lenvar, level, priv->spi)
2036 );
2037 }
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048 static int ca8210_set_channel(
2049 struct ieee802154_hw *hw,
2050 u8 page,
2051 u8 channel
2052 )
2053 {
2054 u8 status;
2055 struct ca8210_priv *priv = hw->priv;
2056
2057 status = mlme_set_request_sync(
2058 PHY_CURRENT_CHANNEL,
2059 0,
2060 1,
2061 &channel,
2062 priv->spi
2063 );
2064 if (status) {
2065 dev_err(
2066 &priv->spi->dev,
2067 "error setting channel, MLME-SET.confirm status = %d\n",
2068 status
2069 );
2070 }
2071 return link_to_linux_err(status);
2072 }
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087 static int ca8210_set_hw_addr_filt(
2088 struct ieee802154_hw *hw,
2089 struct ieee802154_hw_addr_filt *filt,
2090 unsigned long changed
2091 )
2092 {
2093 u8 status = 0;
2094 struct ca8210_priv *priv = hw->priv;
2095
2096 if (changed & IEEE802154_AFILT_PANID_CHANGED) {
2097 status = mlme_set_request_sync(
2098 MAC_PAN_ID,
2099 0,
2100 2,
2101 &filt->pan_id, priv->spi
2102 );
2103 if (status) {
2104 dev_err(
2105 &priv->spi->dev,
2106 "error setting pan id, MLME-SET.confirm status = %d",
2107 status
2108 );
2109 return link_to_linux_err(status);
2110 }
2111 }
2112 if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
2113 status = mlme_set_request_sync(
2114 MAC_SHORT_ADDRESS,
2115 0,
2116 2,
2117 &filt->short_addr, priv->spi
2118 );
2119 if (status) {
2120 dev_err(
2121 &priv->spi->dev,
2122 "error setting short address, MLME-SET.confirm status = %d",
2123 status
2124 );
2125 return link_to_linux_err(status);
2126 }
2127 }
2128 if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
2129 status = mlme_set_request_sync(
2130 NS_IEEE_ADDRESS,
2131 0,
2132 8,
2133 &filt->ieee_addr,
2134 priv->spi
2135 );
2136 if (status) {
2137 dev_err(
2138 &priv->spi->dev,
2139 "error setting ieee address, MLME-SET.confirm status = %d",
2140 status
2141 );
2142 return link_to_linux_err(status);
2143 }
2144 }
2145
2146 return 0;
2147 }
2148
2149
2150
2151
2152
2153
2154
2155
2156 static int ca8210_set_tx_power(struct ieee802154_hw *hw, s32 mbm)
2157 {
2158 struct ca8210_priv *priv = hw->priv;
2159
2160 mbm /= 100;
2161 return link_to_linux_err(
2162 mlme_set_request_sync(PHY_TRANSMIT_POWER, 0, 1, &mbm, priv->spi)
2163 );
2164 }
2165
2166
2167
2168
2169
2170
2171
2172
2173 static int ca8210_set_cca_mode(
2174 struct ieee802154_hw *hw,
2175 const struct wpan_phy_cca *cca
2176 )
2177 {
2178 u8 status;
2179 u8 cca_mode;
2180 struct ca8210_priv *priv = hw->priv;
2181
2182 cca_mode = cca->mode & 3;
2183 if (cca_mode == 3 && cca->opt == NL802154_CCA_OPT_ENERGY_CARRIER_OR) {
2184
2185 cca_mode = 0;
2186 }
2187 status = mlme_set_request_sync(
2188 PHY_CCA_MODE,
2189 0,
2190 1,
2191 &cca_mode,
2192 priv->spi
2193 );
2194 if (status) {
2195 dev_err(
2196 &priv->spi->dev,
2197 "error setting cca mode, MLME-SET.confirm status = %d",
2198 status
2199 );
2200 }
2201 return link_to_linux_err(status);
2202 }
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214 static int ca8210_set_cca_ed_level(struct ieee802154_hw *hw, s32 level)
2215 {
2216 u8 status;
2217 u8 ed_threshold = (level / 100) * 2 + 256;
2218 struct ca8210_priv *priv = hw->priv;
2219
2220 status = hwme_set_request_sync(
2221 HWME_EDTHRESHOLD,
2222 1,
2223 &ed_threshold,
2224 priv->spi
2225 );
2226 if (status) {
2227 dev_err(
2228 &priv->spi->dev,
2229 "error setting ed threshold, HWME-SET.confirm status = %d",
2230 status
2231 );
2232 }
2233 return link_to_linux_err(status);
2234 }
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245 static int ca8210_set_csma_params(
2246 struct ieee802154_hw *hw,
2247 u8 min_be,
2248 u8 max_be,
2249 u8 retries
2250 )
2251 {
2252 u8 status;
2253 struct ca8210_priv *priv = hw->priv;
2254
2255 status = mlme_set_request_sync(MAC_MIN_BE, 0, 1, &min_be, priv->spi);
2256 if (status) {
2257 dev_err(
2258 &priv->spi->dev,
2259 "error setting min be, MLME-SET.confirm status = %d",
2260 status
2261 );
2262 return link_to_linux_err(status);
2263 }
2264 status = mlme_set_request_sync(MAC_MAX_BE, 0, 1, &max_be, priv->spi);
2265 if (status) {
2266 dev_err(
2267 &priv->spi->dev,
2268 "error setting max be, MLME-SET.confirm status = %d",
2269 status
2270 );
2271 return link_to_linux_err(status);
2272 }
2273 status = mlme_set_request_sync(
2274 MAC_MAX_CSMA_BACKOFFS,
2275 0,
2276 1,
2277 &retries,
2278 priv->spi
2279 );
2280 if (status) {
2281 dev_err(
2282 &priv->spi->dev,
2283 "error setting max csma backoffs, MLME-SET.confirm status = %d",
2284 status
2285 );
2286 }
2287 return link_to_linux_err(status);
2288 }
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300 static int ca8210_set_frame_retries(struct ieee802154_hw *hw, s8 retries)
2301 {
2302 u8 status;
2303 struct ca8210_priv *priv = hw->priv;
2304
2305 status = mlme_set_request_sync(
2306 MAC_MAX_FRAME_RETRIES,
2307 0,
2308 1,
2309 &retries,
2310 priv->spi
2311 );
2312 if (status) {
2313 dev_err(
2314 &priv->spi->dev,
2315 "error setting frame retries, MLME-SET.confirm status = %d",
2316 status
2317 );
2318 }
2319 return link_to_linux_err(status);
2320 }
2321
2322 static int ca8210_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on)
2323 {
2324 u8 status;
2325 struct ca8210_priv *priv = hw->priv;
2326
2327 status = mlme_set_request_sync(
2328 MAC_PROMISCUOUS_MODE,
2329 0,
2330 1,
2331 (const void *)&on,
2332 priv->spi
2333 );
2334 if (status) {
2335 dev_err(
2336 &priv->spi->dev,
2337 "error setting promiscuous mode, MLME-SET.confirm status = %d",
2338 status
2339 );
2340 } else {
2341 priv->promiscuous = on;
2342 }
2343 return link_to_linux_err(status);
2344 }
2345
2346 static const struct ieee802154_ops ca8210_phy_ops = {
2347 .start = ca8210_start,
2348 .stop = ca8210_stop,
2349 .xmit_async = ca8210_xmit_async,
2350 .ed = ca8210_get_ed,
2351 .set_channel = ca8210_set_channel,
2352 .set_hw_addr_filt = ca8210_set_hw_addr_filt,
2353 .set_txpower = ca8210_set_tx_power,
2354 .set_cca_mode = ca8210_set_cca_mode,
2355 .set_cca_ed_level = ca8210_set_cca_ed_level,
2356 .set_csma_params = ca8210_set_csma_params,
2357 .set_frame_retries = ca8210_set_frame_retries,
2358 .set_promiscuous_mode = ca8210_set_promiscuous_mode
2359 };
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370 static int ca8210_test_int_open(struct inode *inodp, struct file *filp)
2371 {
2372 struct ca8210_priv *priv = inodp->i_private;
2373
2374 filp->private_data = priv;
2375 return 0;
2376 }
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386 static int ca8210_test_check_upstream(u8 *buf, void *device_ref)
2387 {
2388 int ret;
2389 u8 response[CA8210_SPI_BUF_SIZE];
2390
2391 if (buf[0] == SPI_MLME_SET_REQUEST) {
2392 ret = tdme_checkpibattribute(buf[2], buf[4], buf + 5);
2393 if (ret) {
2394 response[0] = SPI_MLME_SET_CONFIRM;
2395 response[1] = 3;
2396 response[2] = IEEE802154_INVALID_PARAMETER;
2397 response[3] = buf[2];
2398 response[4] = buf[3];
2399 if (cascoda_api_upstream)
2400 cascoda_api_upstream(response, 5, device_ref);
2401 return ret;
2402 }
2403 }
2404 if (buf[0] == SPI_MLME_ASSOCIATE_REQUEST) {
2405 return tdme_channelinit(buf[2], device_ref);
2406 } else if (buf[0] == SPI_MLME_START_REQUEST) {
2407 return tdme_channelinit(buf[4], device_ref);
2408 } else if (
2409 (buf[0] == SPI_MLME_SET_REQUEST) &&
2410 (buf[2] == PHY_CURRENT_CHANNEL)
2411 ) {
2412 return tdme_channelinit(buf[5], device_ref);
2413 } else if (
2414 (buf[0] == SPI_TDME_SET_REQUEST) &&
2415 (buf[2] == TDME_CHANNEL)
2416 ) {
2417 return tdme_channelinit(buf[4], device_ref);
2418 } else if (
2419 (CA8210_MAC_WORKAROUNDS) &&
2420 (buf[0] == SPI_MLME_RESET_REQUEST) &&
2421 (buf[2] == 1)
2422 ) {
2423
2424 return tdme_setsfr_request_sync(
2425 0,
2426 CA8210_SFR_MACCON,
2427 0,
2428 device_ref
2429 );
2430 }
2431 return 0;
2432 }
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444 static ssize_t ca8210_test_int_user_write(
2445 struct file *filp,
2446 const char __user *in_buf,
2447 size_t len,
2448 loff_t *off
2449 )
2450 {
2451 int ret;
2452 struct ca8210_priv *priv = filp->private_data;
2453 u8 command[CA8210_SPI_BUF_SIZE];
2454
2455 memset(command, SPI_IDLE, 6);
2456 if (len > CA8210_SPI_BUF_SIZE || len < 2) {
2457 dev_warn(
2458 &priv->spi->dev,
2459 "userspace requested erroneous write length (%zu)\n",
2460 len
2461 );
2462 return -EBADE;
2463 }
2464
2465 ret = copy_from_user(command, in_buf, len);
2466 if (ret) {
2467 dev_err(
2468 &priv->spi->dev,
2469 "%d bytes could not be copied from userspace\n",
2470 ret
2471 );
2472 return -EIO;
2473 }
2474 if (len != command[1] + 2) {
2475 dev_err(
2476 &priv->spi->dev,
2477 "write len does not match packet length field\n"
2478 );
2479 return -EBADE;
2480 }
2481
2482 ret = ca8210_test_check_upstream(command, priv->spi);
2483 if (ret == 0) {
2484 ret = ca8210_spi_exchange(
2485 command,
2486 command[1] + 2,
2487 NULL,
2488 priv->spi
2489 );
2490 if (ret < 0) {
2491
2492 dev_err(
2493 &priv->spi->dev,
2494 "spi exchange failed\n"
2495 );
2496 return ret;
2497 }
2498 if (command[0] & SPI_SYN)
2499 priv->sync_down++;
2500 }
2501
2502 return len;
2503 }
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519 static ssize_t ca8210_test_int_user_read(
2520 struct file *filp,
2521 char __user *buf,
2522 size_t len,
2523 loff_t *offp
2524 )
2525 {
2526 int i, cmdlen;
2527 struct ca8210_priv *priv = filp->private_data;
2528 unsigned char *fifo_buffer;
2529 unsigned long bytes_not_copied;
2530
2531 if (filp->f_flags & O_NONBLOCK) {
2532
2533 if (kfifo_is_empty(&priv->test.up_fifo))
2534 return 0;
2535 } else {
2536
2537 wait_event_interruptible(
2538 priv->test.readq,
2539 !kfifo_is_empty(&priv->test.up_fifo)
2540 );
2541 }
2542
2543 if (kfifo_out(&priv->test.up_fifo, &fifo_buffer, 4) != 4) {
2544 dev_err(
2545 &priv->spi->dev,
2546 "test_interface: Wrong number of elements popped from upstream fifo\n"
2547 );
2548 return 0;
2549 }
2550 cmdlen = fifo_buffer[1];
2551 bytes_not_copied = cmdlen + 2;
2552
2553 bytes_not_copied = copy_to_user(buf, fifo_buffer, bytes_not_copied);
2554 if (bytes_not_copied > 0) {
2555 dev_err(
2556 &priv->spi->dev,
2557 "%lu bytes could not be copied to user space!\n",
2558 bytes_not_copied
2559 );
2560 }
2561
2562 dev_dbg(&priv->spi->dev, "test_interface: Cmd len = %d\n", cmdlen);
2563
2564 dev_dbg(&priv->spi->dev, "test_interface: Read\n");
2565 for (i = 0; i < cmdlen + 2; i++)
2566 dev_dbg(&priv->spi->dev, "%#03x\n", fifo_buffer[i]);
2567
2568 kfree(fifo_buffer);
2569
2570 return cmdlen + 2;
2571 }
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582 static long ca8210_test_int_ioctl(
2583 struct file *filp,
2584 unsigned int ioctl_num,
2585 unsigned long ioctl_param
2586 )
2587 {
2588 struct ca8210_priv *priv = filp->private_data;
2589
2590 switch (ioctl_num) {
2591 case CA8210_IOCTL_HARD_RESET:
2592 ca8210_reset_send(priv->spi, ioctl_param);
2593 break;
2594 default:
2595 break;
2596 }
2597 return 0;
2598 }
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608 static __poll_t ca8210_test_int_poll(
2609 struct file *filp,
2610 struct poll_table_struct *ptable
2611 )
2612 {
2613 __poll_t return_flags = 0;
2614 struct ca8210_priv *priv = filp->private_data;
2615
2616 poll_wait(filp, &priv->test.readq, ptable);
2617 if (!kfifo_is_empty(&priv->test.up_fifo))
2618 return_flags |= (EPOLLIN | EPOLLRDNORM);
2619 if (wait_event_interruptible(
2620 priv->test.readq,
2621 !kfifo_is_empty(&priv->test.up_fifo))) {
2622 return EPOLLERR;
2623 }
2624 return return_flags;
2625 }
2626
2627 static const struct file_operations test_int_fops = {
2628 .read = ca8210_test_int_user_read,
2629 .write = ca8210_test_int_user_write,
2630 .open = ca8210_test_int_open,
2631 .release = NULL,
2632 .unlocked_ioctl = ca8210_test_int_ioctl,
2633 .poll = ca8210_test_int_poll
2634 };
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645 static int ca8210_get_platform_data(
2646 struct spi_device *spi_device,
2647 struct ca8210_platform_data *pdata
2648 )
2649 {
2650 int ret = 0;
2651
2652 if (!spi_device->dev.of_node)
2653 return -EINVAL;
2654
2655 pdata->extclockenable = of_property_read_bool(
2656 spi_device->dev.of_node,
2657 "extclock-enable"
2658 );
2659 if (pdata->extclockenable) {
2660 ret = of_property_read_u32(
2661 spi_device->dev.of_node,
2662 "extclock-freq",
2663 &pdata->extclockfreq
2664 );
2665 if (ret < 0)
2666 return ret;
2667
2668 ret = of_property_read_u32(
2669 spi_device->dev.of_node,
2670 "extclock-gpio",
2671 &pdata->extclockgpio
2672 );
2673 }
2674
2675 return ret;
2676 }
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690 static int ca8210_config_extern_clk(
2691 struct ca8210_platform_data *pdata,
2692 struct spi_device *spi,
2693 bool on
2694 )
2695 {
2696 u8 clkparam[2];
2697
2698 if (on) {
2699 dev_info(&spi->dev, "Switching external clock on\n");
2700 switch (pdata->extclockfreq) {
2701 case SIXTEEN_MHZ:
2702 clkparam[0] = 1;
2703 break;
2704 case EIGHT_MHZ:
2705 clkparam[0] = 2;
2706 break;
2707 case FOUR_MHZ:
2708 clkparam[0] = 3;
2709 break;
2710 case TWO_MHZ:
2711 clkparam[0] = 4;
2712 break;
2713 case ONE_MHZ:
2714 clkparam[0] = 5;
2715 break;
2716 default:
2717 dev_crit(&spi->dev, "Invalid extclock-freq\n");
2718 return -EINVAL;
2719 }
2720 clkparam[1] = pdata->extclockgpio;
2721 } else {
2722 dev_info(&spi->dev, "Switching external clock off\n");
2723 clkparam[0] = 0;
2724 clkparam[1] = 0;
2725 }
2726 return link_to_linux_err(
2727 hwme_set_request_sync(HWME_SYSCLKOUT, 2, clkparam, spi)
2728 );
2729 }
2730
2731
2732
2733
2734
2735
2736
2737 static int ca8210_register_ext_clock(struct spi_device *spi)
2738 {
2739 struct device_node *np = spi->dev.of_node;
2740 struct ca8210_priv *priv = spi_get_drvdata(spi);
2741 struct ca8210_platform_data *pdata = spi->dev.platform_data;
2742 int ret = 0;
2743
2744 if (!np)
2745 return -EFAULT;
2746
2747 priv->clk = clk_register_fixed_rate(
2748 &spi->dev,
2749 np->name,
2750 NULL,
2751 0,
2752 pdata->extclockfreq
2753 );
2754
2755 if (IS_ERR(priv->clk)) {
2756 dev_crit(&spi->dev, "Failed to register external clk\n");
2757 return PTR_ERR(priv->clk);
2758 }
2759 ret = of_clk_add_provider(np, of_clk_src_simple_get, priv->clk);
2760 if (ret) {
2761 clk_unregister(priv->clk);
2762 dev_crit(
2763 &spi->dev,
2764 "Failed to register external clock as clock provider\n"
2765 );
2766 } else {
2767 dev_info(&spi->dev, "External clock set as clock provider\n");
2768 }
2769
2770 return ret;
2771 }
2772
2773
2774
2775
2776
2777
2778 static void ca8210_unregister_ext_clock(struct spi_device *spi)
2779 {
2780 struct ca8210_priv *priv = spi_get_drvdata(spi);
2781
2782 if (!priv->clk)
2783 return
2784
2785 of_clk_del_provider(spi->dev.of_node);
2786 clk_unregister(priv->clk);
2787 dev_info(&spi->dev, "External clock unregistered\n");
2788 }
2789
2790
2791
2792
2793
2794
2795
2796 static int ca8210_reset_init(struct spi_device *spi)
2797 {
2798 int ret;
2799 struct ca8210_platform_data *pdata = spi->dev.platform_data;
2800
2801 pdata->gpio_reset = of_get_named_gpio(
2802 spi->dev.of_node,
2803 "reset-gpio",
2804 0
2805 );
2806
2807 ret = gpio_direction_output(pdata->gpio_reset, 1);
2808 if (ret < 0) {
2809 dev_crit(
2810 &spi->dev,
2811 "Reset GPIO %d did not set to output mode\n",
2812 pdata->gpio_reset
2813 );
2814 }
2815
2816 return ret;
2817 }
2818
2819
2820
2821
2822
2823
2824
2825 static int ca8210_interrupt_init(struct spi_device *spi)
2826 {
2827 int ret;
2828 struct ca8210_platform_data *pdata = spi->dev.platform_data;
2829
2830 pdata->gpio_irq = of_get_named_gpio(
2831 spi->dev.of_node,
2832 "irq-gpio",
2833 0
2834 );
2835
2836 pdata->irq_id = gpio_to_irq(pdata->gpio_irq);
2837 if (pdata->irq_id < 0) {
2838 dev_crit(
2839 &spi->dev,
2840 "Could not get irq for gpio pin %d\n",
2841 pdata->gpio_irq
2842 );
2843 gpio_free(pdata->gpio_irq);
2844 return pdata->irq_id;
2845 }
2846
2847 ret = request_irq(
2848 pdata->irq_id,
2849 ca8210_interrupt_handler,
2850 IRQF_TRIGGER_FALLING,
2851 "ca8210-irq",
2852 spi_get_drvdata(spi)
2853 );
2854 if (ret) {
2855 dev_crit(&spi->dev, "request_irq %d failed\n", pdata->irq_id);
2856 gpio_unexport(pdata->gpio_irq);
2857 gpio_free(pdata->gpio_irq);
2858 }
2859
2860 return ret;
2861 }
2862
2863
2864
2865
2866
2867
2868
2869 static int ca8210_dev_com_init(struct ca8210_priv *priv)
2870 {
2871 priv->mlme_workqueue = alloc_ordered_workqueue(
2872 "MLME work queue",
2873 WQ_UNBOUND
2874 );
2875 if (!priv->mlme_workqueue) {
2876 dev_crit(&priv->spi->dev, "alloc of mlme_workqueue failed!\n");
2877 return -ENOMEM;
2878 }
2879
2880 priv->irq_workqueue = alloc_ordered_workqueue(
2881 "ca8210 irq worker",
2882 WQ_UNBOUND
2883 );
2884 if (!priv->irq_workqueue) {
2885 dev_crit(&priv->spi->dev, "alloc of irq_workqueue failed!\n");
2886 destroy_workqueue(priv->mlme_workqueue);
2887 return -ENOMEM;
2888 }
2889
2890 return 0;
2891 }
2892
2893
2894
2895
2896
2897 static void ca8210_dev_com_clear(struct ca8210_priv *priv)
2898 {
2899 destroy_workqueue(priv->mlme_workqueue);
2900 destroy_workqueue(priv->irq_workqueue);
2901 }
2902
2903 #define CA8210_MAX_TX_POWERS (9)
2904 static const s32 ca8210_tx_powers[CA8210_MAX_TX_POWERS] = {
2905 800, 700, 600, 500, 400, 300, 200, 100, 0
2906 };
2907
2908 #define CA8210_MAX_ED_LEVELS (21)
2909 static const s32 ca8210_ed_levels[CA8210_MAX_ED_LEVELS] = {
2910 -10300, -10250, -10200, -10150, -10100, -10050, -10000, -9950, -9900,
2911 -9850, -9800, -9750, -9700, -9650, -9600, -9550, -9500, -9450, -9400,
2912 -9350, -9300
2913 };
2914
2915
2916
2917
2918
2919
2920 static void ca8210_hw_setup(struct ieee802154_hw *ca8210_hw)
2921 {
2922
2923 ca8210_hw->phy->supported.channels[0] = CA8210_VALID_CHANNELS;
2924 ca8210_hw->phy->supported.tx_powers_size = CA8210_MAX_TX_POWERS;
2925 ca8210_hw->phy->supported.tx_powers = ca8210_tx_powers;
2926 ca8210_hw->phy->supported.cca_ed_levels_size = CA8210_MAX_ED_LEVELS;
2927 ca8210_hw->phy->supported.cca_ed_levels = ca8210_ed_levels;
2928 ca8210_hw->phy->current_channel = 18;
2929 ca8210_hw->phy->current_page = 0;
2930 ca8210_hw->phy->transmit_power = 800;
2931 ca8210_hw->phy->cca.mode = NL802154_CCA_ENERGY_CARRIER;
2932 ca8210_hw->phy->cca.opt = NL802154_CCA_OPT_ENERGY_CARRIER_AND;
2933 ca8210_hw->phy->cca_ed_level = -9800;
2934 ca8210_hw->phy->symbol_duration = 16;
2935 ca8210_hw->phy->lifs_period = 40 * ca8210_hw->phy->symbol_duration;
2936 ca8210_hw->phy->sifs_period = 12 * ca8210_hw->phy->symbol_duration;
2937 ca8210_hw->flags =
2938 IEEE802154_HW_AFILT |
2939 IEEE802154_HW_OMIT_CKSUM |
2940 IEEE802154_HW_FRAME_RETRIES |
2941 IEEE802154_HW_PROMISCUOUS |
2942 IEEE802154_HW_CSMA_PARAMS;
2943 ca8210_hw->phy->flags =
2944 WPAN_PHY_FLAG_TXPOWER |
2945 WPAN_PHY_FLAG_CCA_ED_LEVEL |
2946 WPAN_PHY_FLAG_CCA_MODE;
2947 }
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960 static int ca8210_test_interface_init(struct ca8210_priv *priv)
2961 {
2962 struct ca8210_test *test = &priv->test;
2963 char node_name[32];
2964
2965 snprintf(
2966 node_name,
2967 sizeof(node_name),
2968 "ca8210@%d_%d",
2969 priv->spi->master->bus_num,
2970 priv->spi->chip_select
2971 );
2972
2973 test->ca8210_dfs_spi_int = debugfs_create_file(
2974 node_name,
2975 0600,
2976 NULL,
2977 priv,
2978 &test_int_fops
2979 );
2980
2981 debugfs_create_symlink("ca8210", NULL, node_name);
2982 init_waitqueue_head(&test->readq);
2983 return kfifo_alloc(
2984 &test->up_fifo,
2985 CA8210_TEST_INT_FIFO_SIZE,
2986 GFP_KERNEL
2987 );
2988 }
2989
2990
2991
2992
2993
2994 static void ca8210_test_interface_clear(struct ca8210_priv *priv)
2995 {
2996 struct ca8210_test *test = &priv->test;
2997
2998 debugfs_remove(test->ca8210_dfs_spi_int);
2999 kfifo_free(&test->up_fifo);
3000 dev_info(&priv->spi->dev, "Test interface removed\n");
3001 }
3002
3003
3004
3005
3006
3007
3008
3009 static void ca8210_remove(struct spi_device *spi_device)
3010 {
3011 struct ca8210_priv *priv;
3012 struct ca8210_platform_data *pdata;
3013
3014 dev_info(&spi_device->dev, "Removing ca8210\n");
3015
3016 pdata = spi_device->dev.platform_data;
3017 if (pdata) {
3018 if (pdata->extclockenable) {
3019 ca8210_unregister_ext_clock(spi_device);
3020 ca8210_config_extern_clk(pdata, spi_device, 0);
3021 }
3022 free_irq(pdata->irq_id, spi_device->dev.driver_data);
3023 kfree(pdata);
3024 spi_device->dev.platform_data = NULL;
3025 }
3026
3027 priv = spi_get_drvdata(spi_device);
3028 if (priv) {
3029 dev_info(
3030 &spi_device->dev,
3031 "sync_down = %d, sync_up = %d\n",
3032 priv->sync_down,
3033 priv->sync_up
3034 );
3035 ca8210_dev_com_clear(spi_device->dev.driver_data);
3036 if (priv->hw) {
3037 if (priv->hw_registered)
3038 ieee802154_unregister_hw(priv->hw);
3039 ieee802154_free_hw(priv->hw);
3040 priv->hw = NULL;
3041 dev_info(
3042 &spi_device->dev,
3043 "Unregistered & freed ieee802154_hw.\n"
3044 );
3045 }
3046 if (IS_ENABLED(CONFIG_IEEE802154_CA8210_DEBUGFS))
3047 ca8210_test_interface_clear(priv);
3048 }
3049 }
3050
3051
3052
3053
3054
3055
3056
3057 static int ca8210_probe(struct spi_device *spi_device)
3058 {
3059 struct ca8210_priv *priv;
3060 struct ieee802154_hw *hw;
3061 struct ca8210_platform_data *pdata;
3062 int ret;
3063
3064 dev_info(&spi_device->dev, "Inserting ca8210\n");
3065
3066
3067 hw = ieee802154_alloc_hw(sizeof(struct ca8210_priv), &ca8210_phy_ops);
3068 if (!hw) {
3069 dev_crit(&spi_device->dev, "ieee802154_alloc_hw failed\n");
3070 ret = -ENOMEM;
3071 goto error;
3072 }
3073
3074 priv = hw->priv;
3075 priv->hw = hw;
3076 priv->spi = spi_device;
3077 hw->parent = &spi_device->dev;
3078 spin_lock_init(&priv->lock);
3079 priv->async_tx_pending = false;
3080 priv->hw_registered = false;
3081 priv->sync_up = 0;
3082 priv->sync_down = 0;
3083 priv->promiscuous = false;
3084 priv->retries = 0;
3085 init_completion(&priv->ca8210_is_awake);
3086 init_completion(&priv->spi_transfer_complete);
3087 init_completion(&priv->sync_exchange_complete);
3088 spi_set_drvdata(priv->spi, priv);
3089 if (IS_ENABLED(CONFIG_IEEE802154_CA8210_DEBUGFS)) {
3090 cascoda_api_upstream = ca8210_test_int_driver_write;
3091 ca8210_test_interface_init(priv);
3092 } else {
3093 cascoda_api_upstream = NULL;
3094 }
3095 ca8210_hw_setup(hw);
3096 ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
3097
3098 pdata = kmalloc(sizeof(*pdata), GFP_KERNEL);
3099 if (!pdata) {
3100 ret = -ENOMEM;
3101 goto error;
3102 }
3103
3104 priv->spi->dev.platform_data = pdata;
3105 ret = ca8210_get_platform_data(priv->spi, pdata);
3106 if (ret) {
3107 dev_crit(&spi_device->dev, "ca8210_get_platform_data failed\n");
3108 goto error;
3109 }
3110
3111 ret = ca8210_dev_com_init(priv);
3112 if (ret) {
3113 dev_crit(&spi_device->dev, "ca8210_dev_com_init failed\n");
3114 goto error;
3115 }
3116 ret = ca8210_reset_init(priv->spi);
3117 if (ret) {
3118 dev_crit(&spi_device->dev, "ca8210_reset_init failed\n");
3119 goto error;
3120 }
3121
3122 ret = ca8210_interrupt_init(priv->spi);
3123 if (ret) {
3124 dev_crit(&spi_device->dev, "ca8210_interrupt_init failed\n");
3125 goto error;
3126 }
3127
3128 msleep(100);
3129
3130 ca8210_reset_send(priv->spi, 1);
3131
3132 ret = tdme_chipinit(priv->spi);
3133 if (ret) {
3134 dev_crit(&spi_device->dev, "tdme_chipinit failed\n");
3135 goto error;
3136 }
3137
3138 if (pdata->extclockenable) {
3139 ret = ca8210_config_extern_clk(pdata, priv->spi, 1);
3140 if (ret) {
3141 dev_crit(
3142 &spi_device->dev,
3143 "ca8210_config_extern_clk failed\n"
3144 );
3145 goto error;
3146 }
3147 ret = ca8210_register_ext_clock(priv->spi);
3148 if (ret) {
3149 dev_crit(
3150 &spi_device->dev,
3151 "ca8210_register_ext_clock failed\n"
3152 );
3153 goto error;
3154 }
3155 }
3156
3157 ret = ieee802154_register_hw(hw);
3158 if (ret) {
3159 dev_crit(&spi_device->dev, "ieee802154_register_hw failed\n");
3160 goto error;
3161 }
3162 priv->hw_registered = true;
3163
3164 return 0;
3165 error:
3166 msleep(100);
3167 ca8210_remove(spi_device);
3168 return link_to_linux_err(ret);
3169 }
3170
3171 static const struct of_device_id ca8210_of_ids[] = {
3172 {.compatible = "cascoda,ca8210", },
3173 {},
3174 };
3175 MODULE_DEVICE_TABLE(of, ca8210_of_ids);
3176
3177 static struct spi_driver ca8210_spi_driver = {
3178 .driver = {
3179 .name = DRIVER_NAME,
3180 .owner = THIS_MODULE,
3181 .of_match_table = of_match_ptr(ca8210_of_ids),
3182 },
3183 .probe = ca8210_probe,
3184 .remove = ca8210_remove
3185 };
3186
3187 module_spi_driver(ca8210_spi_driver);
3188
3189 MODULE_AUTHOR("Harry Morris <h.morris@cascoda.com>");
3190 MODULE_DESCRIPTION("CA-8210 SoftMAC driver");
3191 MODULE_LICENSE("Dual BSD/GPL");
3192 MODULE_VERSION("1.0");