linux/drivers/net/ieee802154/cc2520.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/* Driver for TI CC2520 802.15.4 Wireless-PAN Networking controller
   3 *
   4 * Copyright (C) 2014 Varka Bhadram <varkab@cdac.in>
   5 *                    Md.Jamal Mohiuddin <mjmohiuddin@cdac.in>
   6 *                    P Sowjanya <sowjanyap@cdac.in>
   7 */
   8#include <linux/kernel.h>
   9#include <linux/module.h>
  10#include <linux/gpio.h>
  11#include <linux/delay.h>
  12#include <linux/spi/spi.h>
  13#include <linux/spi/cc2520.h>
  14#include <linux/workqueue.h>
  15#include <linux/interrupt.h>
  16#include <linux/skbuff.h>
  17#include <linux/of_gpio.h>
  18#include <linux/ieee802154.h>
  19#include <linux/crc-ccitt.h>
  20#include <asm/unaligned.h>
  21
  22#include <net/mac802154.h>
  23#include <net/cfg802154.h>
  24
  25#define SPI_COMMAND_BUFFER      3
  26#define HIGH                    1
  27#define LOW                     0
  28#define STATE_IDLE              0
  29#define RSSI_VALID              0
  30#define RSSI_OFFSET             78
  31
  32#define CC2520_RAM_SIZE         640
  33#define CC2520_FIFO_SIZE        128
  34
  35#define CC2520RAM_TXFIFO        0x100
  36#define CC2520RAM_RXFIFO        0x180
  37#define CC2520RAM_IEEEADDR      0x3EA
  38#define CC2520RAM_PANID         0x3F2
  39#define CC2520RAM_SHORTADDR     0x3F4
  40
  41#define CC2520_FREG_MASK        0x3F
  42
  43/* status byte values */
  44#define CC2520_STATUS_XOSC32M_STABLE    BIT(7)
  45#define CC2520_STATUS_RSSI_VALID        BIT(6)
  46#define CC2520_STATUS_TX_UNDERFLOW      BIT(3)
  47
  48/* IEEE-802.15.4 defined constants (2.4 GHz logical channels) */
  49#define CC2520_MINCHANNEL               11
  50#define CC2520_MAXCHANNEL               26
  51#define CC2520_CHANNEL_SPACING          5
  52
  53/* command strobes */
  54#define CC2520_CMD_SNOP                 0x00
  55#define CC2520_CMD_IBUFLD               0x02
  56#define CC2520_CMD_SIBUFEX              0x03
  57#define CC2520_CMD_SSAMPLECCA           0x04
  58#define CC2520_CMD_SRES                 0x0f
  59#define CC2520_CMD_MEMORY_MASK          0x0f
  60#define CC2520_CMD_MEMORY_READ          0x10
  61#define CC2520_CMD_MEMORY_WRITE         0x20
  62#define CC2520_CMD_RXBUF                0x30
  63#define CC2520_CMD_RXBUFCP              0x38
  64#define CC2520_CMD_RXBUFMOV             0x32
  65#define CC2520_CMD_TXBUF                0x3A
  66#define CC2520_CMD_TXBUFCP              0x3E
  67#define CC2520_CMD_RANDOM               0x3C
  68#define CC2520_CMD_SXOSCON              0x40
  69#define CC2520_CMD_STXCAL               0x41
  70#define CC2520_CMD_SRXON                0x42
  71#define CC2520_CMD_STXON                0x43
  72#define CC2520_CMD_STXONCCA             0x44
  73#define CC2520_CMD_SRFOFF               0x45
  74#define CC2520_CMD_SXOSCOFF             0x46
  75#define CC2520_CMD_SFLUSHRX             0x47
  76#define CC2520_CMD_SFLUSHTX             0x48
  77#define CC2520_CMD_SACK                 0x49
  78#define CC2520_CMD_SACKPEND             0x4A
  79#define CC2520_CMD_SNACK                0x4B
  80#define CC2520_CMD_SRXMASKBITSET        0x4C
  81#define CC2520_CMD_SRXMASKBITCLR        0x4D
  82#define CC2520_CMD_RXMASKAND            0x4E
  83#define CC2520_CMD_RXMASKOR             0x4F
  84#define CC2520_CMD_MEMCP                0x50
  85#define CC2520_CMD_MEMCPR               0x52
  86#define CC2520_CMD_MEMXCP               0x54
  87#define CC2520_CMD_MEMXWR               0x56
  88#define CC2520_CMD_BCLR                 0x58
  89#define CC2520_CMD_BSET                 0x59
  90#define CC2520_CMD_CTR_UCTR             0x60
  91#define CC2520_CMD_CBCMAC               0x64
  92#define CC2520_CMD_UCBCMAC              0x66
  93#define CC2520_CMD_CCM                  0x68
  94#define CC2520_CMD_UCCM                 0x6A
  95#define CC2520_CMD_ECB                  0x70
  96#define CC2520_CMD_ECBO                 0x72
  97#define CC2520_CMD_ECBX                 0x74
  98#define CC2520_CMD_INC                  0x78
  99#define CC2520_CMD_ABORT                0x7F
 100#define CC2520_CMD_REGISTER_READ        0x80
 101#define CC2520_CMD_REGISTER_WRITE       0xC0
 102
 103/* status registers */
 104#define CC2520_CHIPID                   0x40
 105#define CC2520_VERSION                  0x42
 106#define CC2520_EXTCLOCK                 0x44
 107#define CC2520_MDMCTRL0                 0x46
 108#define CC2520_MDMCTRL1                 0x47
 109#define CC2520_FREQEST                  0x48
 110#define CC2520_RXCTRL                   0x4A
 111#define CC2520_FSCTRL                   0x4C
 112#define CC2520_FSCAL0                   0x4E
 113#define CC2520_FSCAL1                   0x4F
 114#define CC2520_FSCAL2                   0x50
 115#define CC2520_FSCAL3                   0x51
 116#define CC2520_AGCCTRL0                 0x52
 117#define CC2520_AGCCTRL1                 0x53
 118#define CC2520_AGCCTRL2                 0x54
 119#define CC2520_AGCCTRL3                 0x55
 120#define CC2520_ADCTEST0                 0x56
 121#define CC2520_ADCTEST1                 0x57
 122#define CC2520_ADCTEST2                 0x58
 123#define CC2520_MDMTEST0                 0x5A
 124#define CC2520_MDMTEST1                 0x5B
 125#define CC2520_DACTEST0                 0x5C
 126#define CC2520_DACTEST1                 0x5D
 127#define CC2520_ATEST                    0x5E
 128#define CC2520_DACTEST2                 0x5F
 129#define CC2520_PTEST0                   0x60
 130#define CC2520_PTEST1                   0x61
 131#define CC2520_RESERVED                 0x62
 132#define CC2520_DPUBIST                  0x7A
 133#define CC2520_ACTBIST                  0x7C
 134#define CC2520_RAMBIST                  0x7E
 135
 136/* frame registers */
 137#define CC2520_FRMFILT0                 0x00
 138#define CC2520_FRMFILT1                 0x01
 139#define CC2520_SRCMATCH                 0x02
 140#define CC2520_SRCSHORTEN0              0x04
 141#define CC2520_SRCSHORTEN1              0x05
 142#define CC2520_SRCSHORTEN2              0x06
 143#define CC2520_SRCEXTEN0                0x08
 144#define CC2520_SRCEXTEN1                0x09
 145#define CC2520_SRCEXTEN2                0x0A
 146#define CC2520_FRMCTRL0                 0x0C
 147#define CC2520_FRMCTRL1                 0x0D
 148#define CC2520_RXENABLE0                0x0E
 149#define CC2520_RXENABLE1                0x0F
 150#define CC2520_EXCFLAG0                 0x10
 151#define CC2520_EXCFLAG1                 0x11
 152#define CC2520_EXCFLAG2                 0x12
 153#define CC2520_EXCMASKA0                0x14
 154#define CC2520_EXCMASKA1                0x15
 155#define CC2520_EXCMASKA2                0x16
 156#define CC2520_EXCMASKB0                0x18
 157#define CC2520_EXCMASKB1                0x19
 158#define CC2520_EXCMASKB2                0x1A
 159#define CC2520_EXCBINDX0                0x1C
 160#define CC2520_EXCBINDX1                0x1D
 161#define CC2520_EXCBINDY0                0x1E
 162#define CC2520_EXCBINDY1                0x1F
 163#define CC2520_GPIOCTRL0                0x20
 164#define CC2520_GPIOCTRL1                0x21
 165#define CC2520_GPIOCTRL2                0x22
 166#define CC2520_GPIOCTRL3                0x23
 167#define CC2520_GPIOCTRL4                0x24
 168#define CC2520_GPIOCTRL5                0x25
 169#define CC2520_GPIOPOLARITY             0x26
 170#define CC2520_GPIOCTRL                 0x28
 171#define CC2520_DPUCON                   0x2A
 172#define CC2520_DPUSTAT                  0x2C
 173#define CC2520_FREQCTRL                 0x2E
 174#define CC2520_FREQTUNE                 0x2F
 175#define CC2520_TXPOWER                  0x30
 176#define CC2520_TXCTRL                   0x31
 177#define CC2520_FSMSTAT0                 0x32
 178#define CC2520_FSMSTAT1                 0x33
 179#define CC2520_FIFOPCTRL                0x34
 180#define CC2520_FSMCTRL                  0x35
 181#define CC2520_CCACTRL0                 0x36
 182#define CC2520_CCACTRL1                 0x37
 183#define CC2520_RSSI                     0x38
 184#define CC2520_RSSISTAT                 0x39
 185#define CC2520_RXFIRST                  0x3C
 186#define CC2520_RXFIFOCNT                0x3E
 187#define CC2520_TXFIFOCNT                0x3F
 188
 189/* CC2520_FRMFILT0 */
 190#define FRMFILT0_FRAME_FILTER_EN        BIT(0)
 191#define FRMFILT0_PAN_COORDINATOR        BIT(1)
 192
 193/* CC2520_FRMCTRL0 */
 194#define FRMCTRL0_AUTOACK                BIT(5)
 195#define FRMCTRL0_AUTOCRC                BIT(6)
 196
 197/* CC2520_FRMCTRL1 */
 198#define FRMCTRL1_SET_RXENMASK_ON_TX     BIT(0)
 199#define FRMCTRL1_IGNORE_TX_UNDERF       BIT(1)
 200
 201/* Driver private information */
 202struct cc2520_private {
 203        struct spi_device *spi;         /* SPI device structure */
 204        struct ieee802154_hw *hw;       /* IEEE-802.15.4 device */
 205        u8 *buf;                        /* SPI TX/Rx data buffer */
 206        struct mutex buffer_mutex;      /* SPI buffer mutex */
 207        bool is_tx;                     /* Flag for sync b/w Tx and Rx */
 208        bool amplified;                 /* Flag for CC2591 */
 209        int fifo_pin;                   /* FIFO GPIO pin number */
 210        struct work_struct fifop_irqwork;/* Workqueue for FIFOP */
 211        spinlock_t lock;                /* Lock for is_tx*/
 212        struct completion tx_complete;  /* Work completion for Tx */
 213        bool promiscuous;               /* Flag for promiscuous mode */
 214};
 215
 216/* Generic Functions */
 217static int
 218cc2520_cmd_strobe(struct cc2520_private *priv, u8 cmd)
 219{
 220        int ret;
 221        struct spi_message msg;
 222        struct spi_transfer xfer = {
 223                .len = 0,
 224                .tx_buf = priv->buf,
 225                .rx_buf = priv->buf,
 226        };
 227
 228        spi_message_init(&msg);
 229        spi_message_add_tail(&xfer, &msg);
 230
 231        mutex_lock(&priv->buffer_mutex);
 232        priv->buf[xfer.len++] = cmd;
 233        dev_vdbg(&priv->spi->dev,
 234                 "command strobe buf[0] = %02x\n",
 235                 priv->buf[0]);
 236
 237        ret = spi_sync(priv->spi, &msg);
 238        dev_vdbg(&priv->spi->dev,
 239                 "buf[0] = %02x\n", priv->buf[0]);
 240        mutex_unlock(&priv->buffer_mutex);
 241
 242        return ret;
 243}
 244
 245static int
 246cc2520_get_status(struct cc2520_private *priv, u8 *status)
 247{
 248        int ret;
 249        struct spi_message msg;
 250        struct spi_transfer xfer = {
 251                .len = 0,
 252                .tx_buf = priv->buf,
 253                .rx_buf = priv->buf,
 254        };
 255
 256        spi_message_init(&msg);
 257        spi_message_add_tail(&xfer, &msg);
 258
 259        mutex_lock(&priv->buffer_mutex);
 260        priv->buf[xfer.len++] = CC2520_CMD_SNOP;
 261        dev_vdbg(&priv->spi->dev,
 262                 "get status command buf[0] = %02x\n", priv->buf[0]);
 263
 264        ret = spi_sync(priv->spi, &msg);
 265        if (!ret)
 266                *status = priv->buf[0];
 267        dev_vdbg(&priv->spi->dev,
 268                 "buf[0] = %02x\n", priv->buf[0]);
 269        mutex_unlock(&priv->buffer_mutex);
 270
 271        return ret;
 272}
 273
 274static int
 275cc2520_write_register(struct cc2520_private *priv, u8 reg, u8 value)
 276{
 277        int status;
 278        struct spi_message msg;
 279        struct spi_transfer xfer = {
 280                .len = 0,
 281                .tx_buf = priv->buf,
 282                .rx_buf = priv->buf,
 283        };
 284
 285        spi_message_init(&msg);
 286        spi_message_add_tail(&xfer, &msg);
 287
 288        mutex_lock(&priv->buffer_mutex);
 289
 290        if (reg <= CC2520_FREG_MASK) {
 291                priv->buf[xfer.len++] = CC2520_CMD_REGISTER_WRITE | reg;
 292                priv->buf[xfer.len++] = value;
 293        } else {
 294                priv->buf[xfer.len++] = CC2520_CMD_MEMORY_WRITE;
 295                priv->buf[xfer.len++] = reg;
 296                priv->buf[xfer.len++] = value;
 297        }
 298        status = spi_sync(priv->spi, &msg);
 299        if (msg.status)
 300                status = msg.status;
 301
 302        mutex_unlock(&priv->buffer_mutex);
 303
 304        return status;
 305}
 306
 307static int
 308cc2520_write_ram(struct cc2520_private *priv, u16 reg, u8 len, u8 *data)
 309{
 310        int status;
 311        struct spi_message msg;
 312        struct spi_transfer xfer_head = {
 313                .len        = 0,
 314                .tx_buf        = priv->buf,
 315                .rx_buf        = priv->buf,
 316        };
 317
 318        struct spi_transfer xfer_buf = {
 319                .len = len,
 320                .tx_buf = data,
 321        };
 322
 323        mutex_lock(&priv->buffer_mutex);
 324        priv->buf[xfer_head.len++] = (CC2520_CMD_MEMORY_WRITE |
 325                                                ((reg >> 8) & 0xff));
 326        priv->buf[xfer_head.len++] = reg & 0xff;
 327
 328        spi_message_init(&msg);
 329        spi_message_add_tail(&xfer_head, &msg);
 330        spi_message_add_tail(&xfer_buf, &msg);
 331
 332        status = spi_sync(priv->spi, &msg);
 333        dev_dbg(&priv->spi->dev, "spi status = %d\n", status);
 334        if (msg.status)
 335                status = msg.status;
 336
 337        mutex_unlock(&priv->buffer_mutex);
 338        return status;
 339}
 340
 341static int
 342cc2520_read_register(struct cc2520_private *priv, u8 reg, u8 *data)
 343{
 344        int status;
 345        struct spi_message msg;
 346        struct spi_transfer xfer1 = {
 347                .len = 0,
 348                .tx_buf = priv->buf,
 349                .rx_buf = priv->buf,
 350        };
 351
 352        struct spi_transfer xfer2 = {
 353                .len = 1,
 354                .rx_buf = data,
 355        };
 356
 357        spi_message_init(&msg);
 358        spi_message_add_tail(&xfer1, &msg);
 359        spi_message_add_tail(&xfer2, &msg);
 360
 361        mutex_lock(&priv->buffer_mutex);
 362        priv->buf[xfer1.len++] = CC2520_CMD_MEMORY_READ;
 363        priv->buf[xfer1.len++] = reg;
 364
 365        status = spi_sync(priv->spi, &msg);
 366        dev_dbg(&priv->spi->dev,
 367                "spi status = %d\n", status);
 368        if (msg.status)
 369                status = msg.status;
 370
 371        mutex_unlock(&priv->buffer_mutex);
 372
 373        return status;
 374}
 375
 376static int
 377cc2520_write_txfifo(struct cc2520_private *priv, u8 pkt_len, u8 *data, u8 len)
 378{
 379        int status;
 380
 381        /* length byte must include FCS even
 382         * if it is calculated in the hardware
 383         */
 384        int len_byte = pkt_len;
 385
 386        struct spi_message msg;
 387
 388        struct spi_transfer xfer_head = {
 389                .len = 0,
 390                .tx_buf = priv->buf,
 391                .rx_buf = priv->buf,
 392        };
 393        struct spi_transfer xfer_len = {
 394                .len = 1,
 395                .tx_buf = &len_byte,
 396        };
 397        struct spi_transfer xfer_buf = {
 398                .len = len,
 399                .tx_buf = data,
 400        };
 401
 402        spi_message_init(&msg);
 403        spi_message_add_tail(&xfer_head, &msg);
 404        spi_message_add_tail(&xfer_len, &msg);
 405        spi_message_add_tail(&xfer_buf, &msg);
 406
 407        mutex_lock(&priv->buffer_mutex);
 408        priv->buf[xfer_head.len++] = CC2520_CMD_TXBUF;
 409        dev_vdbg(&priv->spi->dev,
 410                 "TX_FIFO cmd buf[0] = %02x\n", priv->buf[0]);
 411
 412        status = spi_sync(priv->spi, &msg);
 413        dev_vdbg(&priv->spi->dev, "status = %d\n", status);
 414        if (msg.status)
 415                status = msg.status;
 416        dev_vdbg(&priv->spi->dev, "status = %d\n", status);
 417        dev_vdbg(&priv->spi->dev, "buf[0] = %02x\n", priv->buf[0]);
 418        mutex_unlock(&priv->buffer_mutex);
 419
 420        return status;
 421}
 422
 423static int
 424cc2520_read_rxfifo(struct cc2520_private *priv, u8 *data, u8 len)
 425{
 426        int status;
 427        struct spi_message msg;
 428
 429        struct spi_transfer xfer_head = {
 430                .len = 0,
 431                .tx_buf = priv->buf,
 432                .rx_buf = priv->buf,
 433        };
 434        struct spi_transfer xfer_buf = {
 435                .len = len,
 436                .rx_buf = data,
 437        };
 438
 439        spi_message_init(&msg);
 440        spi_message_add_tail(&xfer_head, &msg);
 441        spi_message_add_tail(&xfer_buf, &msg);
 442
 443        mutex_lock(&priv->buffer_mutex);
 444        priv->buf[xfer_head.len++] = CC2520_CMD_RXBUF;
 445
 446        dev_vdbg(&priv->spi->dev, "read rxfifo buf[0] = %02x\n", priv->buf[0]);
 447        dev_vdbg(&priv->spi->dev, "buf[1] = %02x\n", priv->buf[1]);
 448
 449        status = spi_sync(priv->spi, &msg);
 450        dev_vdbg(&priv->spi->dev, "status = %d\n", status);
 451        if (msg.status)
 452                status = msg.status;
 453        dev_vdbg(&priv->spi->dev, "status = %d\n", status);
 454        dev_vdbg(&priv->spi->dev,
 455                 "return status buf[0] = %02x\n", priv->buf[0]);
 456        dev_vdbg(&priv->spi->dev, "length buf[1] = %02x\n", priv->buf[1]);
 457
 458        mutex_unlock(&priv->buffer_mutex);
 459
 460        return status;
 461}
 462
 463static int cc2520_start(struct ieee802154_hw *hw)
 464{
 465        return cc2520_cmd_strobe(hw->priv, CC2520_CMD_SRXON);
 466}
 467
 468static void cc2520_stop(struct ieee802154_hw *hw)
 469{
 470        cc2520_cmd_strobe(hw->priv, CC2520_CMD_SRFOFF);
 471}
 472
 473static int
 474cc2520_tx(struct ieee802154_hw *hw, struct sk_buff *skb)
 475{
 476        struct cc2520_private *priv = hw->priv;
 477        unsigned long flags;
 478        int rc;
 479        u8 status = 0;
 480        u8 pkt_len;
 481
 482        /* In promiscuous mode we disable AUTOCRC so we can get the raw CRC
 483         * values on RX. This means we need to manually add the CRC on TX.
 484         */
 485        if (priv->promiscuous) {
 486                u16 crc = crc_ccitt(0, skb->data, skb->len);
 487
 488                put_unaligned_le16(crc, skb_put(skb, 2));
 489                pkt_len = skb->len;
 490        } else {
 491                pkt_len = skb->len + 2;
 492        }
 493
 494        rc = cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHTX);
 495        if (rc)
 496                goto err_tx;
 497
 498        rc = cc2520_write_txfifo(priv, pkt_len, skb->data, skb->len);
 499        if (rc)
 500                goto err_tx;
 501
 502        rc = cc2520_get_status(priv, &status);
 503        if (rc)
 504                goto err_tx;
 505
 506        if (status & CC2520_STATUS_TX_UNDERFLOW) {
 507                dev_err(&priv->spi->dev, "cc2520 tx underflow exception\n");
 508                goto err_tx;
 509        }
 510
 511        spin_lock_irqsave(&priv->lock, flags);
 512        WARN_ON(priv->is_tx);
 513        priv->is_tx = 1;
 514        spin_unlock_irqrestore(&priv->lock, flags);
 515
 516        rc = cc2520_cmd_strobe(priv, CC2520_CMD_STXONCCA);
 517        if (rc)
 518                goto err;
 519
 520        rc = wait_for_completion_interruptible(&priv->tx_complete);
 521        if (rc < 0)
 522                goto err;
 523
 524        cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHTX);
 525        cc2520_cmd_strobe(priv, CC2520_CMD_SRXON);
 526
 527        return rc;
 528err:
 529        spin_lock_irqsave(&priv->lock, flags);
 530        priv->is_tx = 0;
 531        spin_unlock_irqrestore(&priv->lock, flags);
 532err_tx:
 533        return rc;
 534}
 535
 536static int cc2520_rx(struct cc2520_private *priv)
 537{
 538        u8 len = 0, lqi = 0, bytes = 1;
 539        struct sk_buff *skb;
 540
 541        /* Read single length byte from the radio. */
 542        cc2520_read_rxfifo(priv, &len, bytes);
 543
 544        if (!ieee802154_is_valid_psdu_len(len)) {
 545                /* Corrupted frame received, clear frame buffer by
 546                 * reading entire buffer.
 547                 */
 548                dev_dbg(&priv->spi->dev, "corrupted frame received\n");
 549                len = IEEE802154_MTU;
 550        }
 551
 552        skb = dev_alloc_skb(len);
 553        if (!skb)
 554                return -ENOMEM;
 555
 556        if (cc2520_read_rxfifo(priv, skb_put(skb, len), len)) {
 557                dev_dbg(&priv->spi->dev, "frame reception failed\n");
 558                kfree_skb(skb);
 559                return -EINVAL;
 560        }
 561
 562        /* In promiscuous mode, we configure the radio to include the
 563         * CRC (AUTOCRC==0) and we pass on the packet unconditionally. If not
 564         * in promiscuous mode, we check the CRC here, but leave the
 565         * RSSI/LQI/CRC_OK bytes as they will get removed in the mac layer.
 566         */
 567        if (!priv->promiscuous) {
 568                bool crc_ok;
 569
 570                /* Check if the CRC is valid. With AUTOCRC set, the most
 571                 * significant bit of the last byte returned from the CC2520
 572                 * is CRC_OK flag. See section 20.3.4 of the datasheet.
 573                 */
 574                crc_ok = skb->data[len - 1] & BIT(7);
 575
 576                /* If we failed CRC drop the packet in the driver layer. */
 577                if (!crc_ok) {
 578                        dev_dbg(&priv->spi->dev, "CRC check failed\n");
 579                        kfree_skb(skb);
 580                        return -EINVAL;
 581                }
 582
 583                /* To calculate LQI, the lower 7 bits of the last byte (the
 584                 * correlation value provided by the radio) must be scaled to
 585                 * the range 0-255. According to section 20.6, the correlation
 586                 * value ranges from 50-110. Ideally this would be calibrated
 587                 * per hardware design, but we use roughly the datasheet values
 588                 * to get close enough while avoiding floating point.
 589                 */
 590                lqi = skb->data[len - 1] & 0x7f;
 591                if (lqi < 50)
 592                        lqi = 50;
 593                else if (lqi > 113)
 594                        lqi = 113;
 595                lqi = (lqi - 50) * 4;
 596        }
 597
 598        ieee802154_rx_irqsafe(priv->hw, skb, lqi);
 599
 600        dev_vdbg(&priv->spi->dev, "RXFIFO: %x %x\n", len, lqi);
 601
 602        return 0;
 603}
 604
 605static int
 606cc2520_ed(struct ieee802154_hw *hw, u8 *level)
 607{
 608        struct cc2520_private *priv = hw->priv;
 609        u8 status = 0xff;
 610        u8 rssi;
 611        int ret;
 612
 613        ret = cc2520_read_register(priv, CC2520_RSSISTAT, &status);
 614        if (ret)
 615                return ret;
 616
 617        if (status != RSSI_VALID)
 618                return -EINVAL;
 619
 620        ret = cc2520_read_register(priv, CC2520_RSSI, &rssi);
 621        if (ret)
 622                return ret;
 623
 624        /* level = RSSI(rssi) - OFFSET [dBm] : offset is 76dBm */
 625        *level = rssi - RSSI_OFFSET;
 626
 627        return 0;
 628}
 629
 630static int
 631cc2520_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
 632{
 633        struct cc2520_private *priv = hw->priv;
 634        int ret;
 635
 636        dev_dbg(&priv->spi->dev, "trying to set channel\n");
 637
 638        WARN_ON(page != 0);
 639        WARN_ON(channel < CC2520_MINCHANNEL);
 640        WARN_ON(channel > CC2520_MAXCHANNEL);
 641
 642        ret = cc2520_write_register(priv, CC2520_FREQCTRL,
 643                                    11 + 5 * (channel - 11));
 644
 645        return ret;
 646}
 647
 648static int
 649cc2520_filter(struct ieee802154_hw *hw,
 650              struct ieee802154_hw_addr_filt *filt, unsigned long changed)
 651{
 652        struct cc2520_private *priv = hw->priv;
 653        int ret = 0;
 654
 655        if (changed & IEEE802154_AFILT_PANID_CHANGED) {
 656                u16 panid = le16_to_cpu(filt->pan_id);
 657
 658                dev_vdbg(&priv->spi->dev, "%s called for pan id\n", __func__);
 659                ret = cc2520_write_ram(priv, CC2520RAM_PANID,
 660                                       sizeof(panid), (u8 *)&panid);
 661        }
 662
 663        if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
 664                dev_vdbg(&priv->spi->dev,
 665                         "%s called for IEEE addr\n", __func__);
 666                ret = cc2520_write_ram(priv, CC2520RAM_IEEEADDR,
 667                                       sizeof(filt->ieee_addr),
 668                                       (u8 *)&filt->ieee_addr);
 669        }
 670
 671        if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
 672                u16 addr = le16_to_cpu(filt->short_addr);
 673
 674                dev_vdbg(&priv->spi->dev, "%s called for saddr\n", __func__);
 675                ret = cc2520_write_ram(priv, CC2520RAM_SHORTADDR,
 676                                       sizeof(addr), (u8 *)&addr);
 677        }
 678
 679        if (changed & IEEE802154_AFILT_PANC_CHANGED) {
 680                u8 frmfilt0;
 681
 682                dev_vdbg(&priv->spi->dev,
 683                         "%s called for panc change\n", __func__);
 684
 685                cc2520_read_register(priv, CC2520_FRMFILT0, &frmfilt0);
 686
 687                if (filt->pan_coord)
 688                        frmfilt0 |= FRMFILT0_PAN_COORDINATOR;
 689                else
 690                        frmfilt0 &= ~FRMFILT0_PAN_COORDINATOR;
 691
 692                ret = cc2520_write_register(priv, CC2520_FRMFILT0, frmfilt0);
 693        }
 694
 695        return ret;
 696}
 697
 698static inline int cc2520_set_tx_power(struct cc2520_private *priv, s32 mbm)
 699{
 700        u8 power;
 701
 702        switch (mbm) {
 703        case 500:
 704                power = 0xF7;
 705                break;
 706        case 300:
 707                power = 0xF2;
 708                break;
 709        case 200:
 710                power = 0xAB;
 711                break;
 712        case 100:
 713                power = 0x13;
 714                break;
 715        case 0:
 716                power = 0x32;
 717                break;
 718        case -200:
 719                power = 0x81;
 720                break;
 721        case -400:
 722                power = 0x88;
 723                break;
 724        case -700:
 725                power = 0x2C;
 726                break;
 727        case -1800:
 728                power = 0x03;
 729                break;
 730        default:
 731                return -EINVAL;
 732        }
 733
 734        return cc2520_write_register(priv, CC2520_TXPOWER, power);
 735}
 736
 737static inline int cc2520_cc2591_set_tx_power(struct cc2520_private *priv,
 738                                             s32 mbm)
 739{
 740        u8 power;
 741
 742        switch (mbm) {
 743        case 1700:
 744                power = 0xF9;
 745                break;
 746        case 1600:
 747                power = 0xF0;
 748                break;
 749        case 1400:
 750                power = 0xA0;
 751                break;
 752        case 1100:
 753                power = 0x2C;
 754                break;
 755        case -100:
 756                power = 0x03;
 757                break;
 758        case -800:
 759                power = 0x01;
 760                break;
 761        default:
 762                return -EINVAL;
 763        }
 764
 765        return cc2520_write_register(priv, CC2520_TXPOWER, power);
 766}
 767
 768#define CC2520_MAX_TX_POWERS 0x8
 769static const s32 cc2520_powers[CC2520_MAX_TX_POWERS + 1] = {
 770        500, 300, 200, 100, 0, -200, -400, -700, -1800,
 771};
 772
 773#define CC2520_CC2591_MAX_TX_POWERS 0x5
 774static const s32 cc2520_cc2591_powers[CC2520_CC2591_MAX_TX_POWERS + 1] = {
 775        1700, 1600, 1400, 1100, -100, -800,
 776};
 777
 778static int
 779cc2520_set_txpower(struct ieee802154_hw *hw, s32 mbm)
 780{
 781        struct cc2520_private *priv = hw->priv;
 782
 783        if (!priv->amplified)
 784                return cc2520_set_tx_power(priv, mbm);
 785
 786        return cc2520_cc2591_set_tx_power(priv, mbm);
 787}
 788
 789static int
 790cc2520_set_promiscuous_mode(struct ieee802154_hw *hw, bool on)
 791{
 792        struct cc2520_private *priv = hw->priv;
 793        u8 frmfilt0;
 794
 795        dev_dbg(&priv->spi->dev, "%s : mode %d\n", __func__, on);
 796
 797        priv->promiscuous = on;
 798
 799        cc2520_read_register(priv, CC2520_FRMFILT0, &frmfilt0);
 800
 801        if (on) {
 802                /* Disable automatic ACK, automatic CRC, and frame filtering. */
 803                cc2520_write_register(priv, CC2520_FRMCTRL0, 0);
 804                frmfilt0 &= ~FRMFILT0_FRAME_FILTER_EN;
 805        } else {
 806                cc2520_write_register(priv, CC2520_FRMCTRL0, FRMCTRL0_AUTOACK |
 807                                                             FRMCTRL0_AUTOCRC);
 808                frmfilt0 |= FRMFILT0_FRAME_FILTER_EN;
 809        }
 810        return cc2520_write_register(priv, CC2520_FRMFILT0, frmfilt0);
 811}
 812
 813static const struct ieee802154_ops cc2520_ops = {
 814        .owner = THIS_MODULE,
 815        .start = cc2520_start,
 816        .stop = cc2520_stop,
 817        .xmit_sync = cc2520_tx,
 818        .ed = cc2520_ed,
 819        .set_channel = cc2520_set_channel,
 820        .set_hw_addr_filt = cc2520_filter,
 821        .set_txpower = cc2520_set_txpower,
 822        .set_promiscuous_mode = cc2520_set_promiscuous_mode,
 823};
 824
 825static int cc2520_register(struct cc2520_private *priv)
 826{
 827        int ret = -ENOMEM;
 828
 829        priv->hw = ieee802154_alloc_hw(sizeof(*priv), &cc2520_ops);
 830        if (!priv->hw)
 831                goto err_ret;
 832
 833        priv->hw->priv = priv;
 834        priv->hw->parent = &priv->spi->dev;
 835        priv->hw->extra_tx_headroom = 0;
 836        ieee802154_random_extended_addr(&priv->hw->phy->perm_extended_addr);
 837
 838        /* We do support only 2.4 Ghz */
 839        priv->hw->phy->supported.channels[0] = 0x7FFF800;
 840        priv->hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT |
 841                          IEEE802154_HW_PROMISCUOUS;
 842
 843        priv->hw->phy->flags = WPAN_PHY_FLAG_TXPOWER;
 844
 845        if (!priv->amplified) {
 846                priv->hw->phy->supported.tx_powers = cc2520_powers;
 847                priv->hw->phy->supported.tx_powers_size = ARRAY_SIZE(cc2520_powers);
 848                priv->hw->phy->transmit_power = priv->hw->phy->supported.tx_powers[4];
 849        } else {
 850                priv->hw->phy->supported.tx_powers = cc2520_cc2591_powers;
 851                priv->hw->phy->supported.tx_powers_size = ARRAY_SIZE(cc2520_cc2591_powers);
 852                priv->hw->phy->transmit_power = priv->hw->phy->supported.tx_powers[0];
 853        }
 854
 855        priv->hw->phy->current_channel = 11;
 856
 857        dev_vdbg(&priv->spi->dev, "registered cc2520\n");
 858        ret = ieee802154_register_hw(priv->hw);
 859        if (ret)
 860                goto err_free_device;
 861
 862        return 0;
 863
 864err_free_device:
 865        ieee802154_free_hw(priv->hw);
 866err_ret:
 867        return ret;
 868}
 869
 870static void cc2520_fifop_irqwork(struct work_struct *work)
 871{
 872        struct cc2520_private *priv
 873                = container_of(work, struct cc2520_private, fifop_irqwork);
 874
 875        dev_dbg(&priv->spi->dev, "fifop interrupt received\n");
 876
 877        if (gpio_get_value(priv->fifo_pin))
 878                cc2520_rx(priv);
 879        else
 880                dev_dbg(&priv->spi->dev, "rxfifo overflow\n");
 881
 882        cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHRX);
 883        cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHRX);
 884}
 885
 886static irqreturn_t cc2520_fifop_isr(int irq, void *data)
 887{
 888        struct cc2520_private *priv = data;
 889
 890        schedule_work(&priv->fifop_irqwork);
 891
 892        return IRQ_HANDLED;
 893}
 894
 895static irqreturn_t cc2520_sfd_isr(int irq, void *data)
 896{
 897        struct cc2520_private *priv = data;
 898        unsigned long flags;
 899
 900        spin_lock_irqsave(&priv->lock, flags);
 901        if (priv->is_tx) {
 902                priv->is_tx = 0;
 903                spin_unlock_irqrestore(&priv->lock, flags);
 904                dev_dbg(&priv->spi->dev, "SFD for TX\n");
 905                complete(&priv->tx_complete);
 906        } else {
 907                spin_unlock_irqrestore(&priv->lock, flags);
 908                dev_dbg(&priv->spi->dev, "SFD for RX\n");
 909        }
 910
 911        return IRQ_HANDLED;
 912}
 913
 914static int cc2520_get_platform_data(struct spi_device *spi,
 915                                    struct cc2520_platform_data *pdata)
 916{
 917        struct device_node *np = spi->dev.of_node;
 918        struct cc2520_private *priv = spi_get_drvdata(spi);
 919
 920        if (!np) {
 921                struct cc2520_platform_data *spi_pdata = spi->dev.platform_data;
 922
 923                if (!spi_pdata)
 924                        return -ENOENT;
 925                *pdata = *spi_pdata;
 926                priv->fifo_pin = pdata->fifo;
 927                return 0;
 928        }
 929
 930        pdata->fifo = of_get_named_gpio(np, "fifo-gpio", 0);
 931        priv->fifo_pin = pdata->fifo;
 932
 933        pdata->fifop = of_get_named_gpio(np, "fifop-gpio", 0);
 934
 935        pdata->sfd = of_get_named_gpio(np, "sfd-gpio", 0);
 936        pdata->cca = of_get_named_gpio(np, "cca-gpio", 0);
 937        pdata->vreg = of_get_named_gpio(np, "vreg-gpio", 0);
 938        pdata->reset = of_get_named_gpio(np, "reset-gpio", 0);
 939
 940        /* CC2591 front end for CC2520 */
 941        if (of_property_read_bool(np, "amplified"))
 942                priv->amplified = true;
 943
 944        return 0;
 945}
 946
 947static int cc2520_hw_init(struct cc2520_private *priv)
 948{
 949        u8 status = 0, state = 0xff;
 950        int ret;
 951        int timeout = 100;
 952        struct cc2520_platform_data pdata;
 953
 954        ret = cc2520_get_platform_data(priv->spi, &pdata);
 955        if (ret)
 956                goto err_ret;
 957
 958        ret = cc2520_read_register(priv, CC2520_FSMSTAT1, &state);
 959        if (ret)
 960                goto err_ret;
 961
 962        if (state != STATE_IDLE)
 963                return -EINVAL;
 964
 965        do {
 966                ret = cc2520_get_status(priv, &status);
 967                if (ret)
 968                        goto err_ret;
 969
 970                if (timeout-- <= 0) {
 971                        dev_err(&priv->spi->dev, "oscillator start failed!\n");
 972                        return ret;
 973                }
 974                udelay(1);
 975        } while (!(status & CC2520_STATUS_XOSC32M_STABLE));
 976
 977        dev_vdbg(&priv->spi->dev, "oscillator brought up\n");
 978
 979        /* If the CC2520 is connected to a CC2591 amplifier, we must both
 980         * configure GPIOs on the CC2520 to correctly configure the CC2591
 981         * and change a couple settings of the CC2520 to work with the
 982         * amplifier. See section 8 page 17 of TI application note AN065.
 983         * http://www.ti.com/lit/an/swra229a/swra229a.pdf
 984         */
 985        if (priv->amplified) {
 986                ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x16);
 987                if (ret)
 988                        goto err_ret;
 989
 990                ret = cc2520_write_register(priv, CC2520_GPIOCTRL0, 0x46);
 991                if (ret)
 992                        goto err_ret;
 993
 994                ret = cc2520_write_register(priv, CC2520_GPIOCTRL5, 0x47);
 995                if (ret)
 996                        goto err_ret;
 997
 998                ret = cc2520_write_register(priv, CC2520_GPIOPOLARITY, 0x1e);
 999                if (ret)
1000                        goto err_ret;
1001
1002                ret = cc2520_write_register(priv, CC2520_TXCTRL, 0xc1);
1003                if (ret)
1004                        goto err_ret;
1005        } else {
1006                ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x11);
1007                if (ret)
1008                        goto err_ret;
1009        }
1010
1011        /* Registers default value: section 28.1 in Datasheet */
1012
1013        /* Set the CCA threshold to -50 dBm. This seems to have been copied
1014         * from the TinyOS CC2520 driver and is much higher than the -84 dBm
1015         * threshold suggested in the datasheet.
1016         */
1017        ret = cc2520_write_register(priv, CC2520_CCACTRL0, 0x1A);
1018        if (ret)
1019                goto err_ret;
1020
1021        ret = cc2520_write_register(priv, CC2520_MDMCTRL0, 0x85);
1022        if (ret)
1023                goto err_ret;
1024
1025        ret = cc2520_write_register(priv, CC2520_MDMCTRL1, 0x14);
1026        if (ret)
1027                goto err_ret;
1028
1029        ret = cc2520_write_register(priv, CC2520_RXCTRL, 0x3f);
1030        if (ret)
1031                goto err_ret;
1032
1033        ret = cc2520_write_register(priv, CC2520_FSCTRL, 0x5a);
1034        if (ret)
1035                goto err_ret;
1036
1037        ret = cc2520_write_register(priv, CC2520_FSCAL1, 0x2b);
1038        if (ret)
1039                goto err_ret;
1040
1041        ret = cc2520_write_register(priv, CC2520_ADCTEST0, 0x10);
1042        if (ret)
1043                goto err_ret;
1044
1045        ret = cc2520_write_register(priv, CC2520_ADCTEST1, 0x0e);
1046        if (ret)
1047                goto err_ret;
1048
1049        ret = cc2520_write_register(priv, CC2520_ADCTEST2, 0x03);
1050        if (ret)
1051                goto err_ret;
1052
1053        /* Configure registers correctly for this driver. */
1054        ret = cc2520_write_register(priv, CC2520_FRMCTRL1,
1055                                    FRMCTRL1_SET_RXENMASK_ON_TX |
1056                                    FRMCTRL1_IGNORE_TX_UNDERF);
1057        if (ret)
1058                goto err_ret;
1059
1060        ret = cc2520_write_register(priv, CC2520_FIFOPCTRL, 127);
1061        if (ret)
1062                goto err_ret;
1063
1064        return 0;
1065
1066err_ret:
1067        return ret;
1068}
1069
1070static int cc2520_probe(struct spi_device *spi)
1071{
1072        struct cc2520_private *priv;
1073        struct cc2520_platform_data pdata;
1074        int ret;
1075
1076        priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
1077        if (!priv)
1078                return -ENOMEM;
1079
1080        spi_set_drvdata(spi, priv);
1081
1082        ret = cc2520_get_platform_data(spi, &pdata);
1083        if (ret < 0) {
1084                dev_err(&spi->dev, "no platform data\n");
1085                return -EINVAL;
1086        }
1087
1088        priv->spi = spi;
1089
1090        priv->buf = devm_kzalloc(&spi->dev,
1091                                 SPI_COMMAND_BUFFER, GFP_KERNEL);
1092        if (!priv->buf)
1093                return -ENOMEM;
1094
1095        mutex_init(&priv->buffer_mutex);
1096        INIT_WORK(&priv->fifop_irqwork, cc2520_fifop_irqwork);
1097        spin_lock_init(&priv->lock);
1098        init_completion(&priv->tx_complete);
1099
1100        /* Assumption that CC2591 is not connected */
1101        priv->amplified = false;
1102
1103        /* Request all the gpio's */
1104        if (!gpio_is_valid(pdata.fifo)) {
1105                dev_err(&spi->dev, "fifo gpio is not valid\n");
1106                ret = -EINVAL;
1107                goto err_hw_init;
1108        }
1109
1110        ret = devm_gpio_request_one(&spi->dev, pdata.fifo,
1111                                    GPIOF_IN, "fifo");
1112        if (ret)
1113                goto err_hw_init;
1114
1115        if (!gpio_is_valid(pdata.cca)) {
1116                dev_err(&spi->dev, "cca gpio is not valid\n");
1117                ret = -EINVAL;
1118                goto err_hw_init;
1119        }
1120
1121        ret = devm_gpio_request_one(&spi->dev, pdata.cca,
1122                                    GPIOF_IN, "cca");
1123        if (ret)
1124                goto err_hw_init;
1125
1126        if (!gpio_is_valid(pdata.fifop)) {
1127                dev_err(&spi->dev, "fifop gpio is not valid\n");
1128                ret = -EINVAL;
1129                goto err_hw_init;
1130        }
1131
1132        ret = devm_gpio_request_one(&spi->dev, pdata.fifop,
1133                                    GPIOF_IN, "fifop");
1134        if (ret)
1135                goto err_hw_init;
1136
1137        if (!gpio_is_valid(pdata.sfd)) {
1138                dev_err(&spi->dev, "sfd gpio is not valid\n");
1139                ret = -EINVAL;
1140                goto err_hw_init;
1141        }
1142
1143        ret = devm_gpio_request_one(&spi->dev, pdata.sfd,
1144                                    GPIOF_IN, "sfd");
1145        if (ret)
1146                goto err_hw_init;
1147
1148        if (!gpio_is_valid(pdata.reset)) {
1149                dev_err(&spi->dev, "reset gpio is not valid\n");
1150                ret = -EINVAL;
1151                goto err_hw_init;
1152        }
1153
1154        ret = devm_gpio_request_one(&spi->dev, pdata.reset,
1155                                    GPIOF_OUT_INIT_LOW, "reset");
1156        if (ret)
1157                goto err_hw_init;
1158
1159        if (!gpio_is_valid(pdata.vreg)) {
1160                dev_err(&spi->dev, "vreg gpio is not valid\n");
1161                ret = -EINVAL;
1162                goto err_hw_init;
1163        }
1164
1165        ret = devm_gpio_request_one(&spi->dev, pdata.vreg,
1166                                    GPIOF_OUT_INIT_LOW, "vreg");
1167        if (ret)
1168                goto err_hw_init;
1169
1170        gpio_set_value(pdata.vreg, HIGH);
1171        usleep_range(100, 150);
1172
1173        gpio_set_value(pdata.reset, HIGH);
1174        usleep_range(200, 250);
1175
1176        ret = cc2520_hw_init(priv);
1177        if (ret)
1178                goto err_hw_init;
1179
1180        /* Set up fifop interrupt */
1181        ret = devm_request_irq(&spi->dev,
1182                               gpio_to_irq(pdata.fifop),
1183                               cc2520_fifop_isr,
1184                               IRQF_TRIGGER_RISING,
1185                               dev_name(&spi->dev),
1186                               priv);
1187        if (ret) {
1188                dev_err(&spi->dev, "could not get fifop irq\n");
1189                goto err_hw_init;
1190        }
1191
1192        /* Set up sfd interrupt */
1193        ret = devm_request_irq(&spi->dev,
1194                               gpio_to_irq(pdata.sfd),
1195                               cc2520_sfd_isr,
1196                               IRQF_TRIGGER_FALLING,
1197                               dev_name(&spi->dev),
1198                               priv);
1199        if (ret) {
1200                dev_err(&spi->dev, "could not get sfd irq\n");
1201                goto err_hw_init;
1202        }
1203
1204        ret = cc2520_register(priv);
1205        if (ret)
1206                goto err_hw_init;
1207
1208        return 0;
1209
1210err_hw_init:
1211        mutex_destroy(&priv->buffer_mutex);
1212        flush_work(&priv->fifop_irqwork);
1213        return ret;
1214}
1215
1216static int cc2520_remove(struct spi_device *spi)
1217{
1218        struct cc2520_private *priv = spi_get_drvdata(spi);
1219
1220        mutex_destroy(&priv->buffer_mutex);
1221        flush_work(&priv->fifop_irqwork);
1222
1223        ieee802154_unregister_hw(priv->hw);
1224        ieee802154_free_hw(priv->hw);
1225
1226        return 0;
1227}
1228
1229static const struct spi_device_id cc2520_ids[] = {
1230        {"cc2520", },
1231        {},
1232};
1233MODULE_DEVICE_TABLE(spi, cc2520_ids);
1234
1235static const struct of_device_id cc2520_of_ids[] = {
1236        {.compatible = "ti,cc2520", },
1237        {},
1238};
1239MODULE_DEVICE_TABLE(of, cc2520_of_ids);
1240
1241/* SPI driver structure */
1242static struct spi_driver cc2520_driver = {
1243        .driver = {
1244                .name = "cc2520",
1245                .of_match_table = of_match_ptr(cc2520_of_ids),
1246        },
1247        .id_table = cc2520_ids,
1248        .probe = cc2520_probe,
1249        .remove = cc2520_remove,
1250};
1251module_spi_driver(cc2520_driver);
1252
1253MODULE_AUTHOR("Varka Bhadram <varkab@cdac.in>");
1254MODULE_DESCRIPTION("CC2520 Transceiver Driver");
1255MODULE_LICENSE("GPL v2");
1256