cc2520.c (4ca24aca55fe1e2a61f3ffaac9015d9c45204729) cc2520.c (5a50439775853a8d565115edb63a5ab4bb780479)
1/* Driver for TI CC2520 802.15.4 Wireless-PAN Networking controller
2 *
3 * Copyright (C) 2014 Varka Bhadram <varkab@cdac.in>
4 * Md.Jamal Mohiuddin <mjmohiuddin@cdac.in>
5 * P Sowjanya <sowjanyap@cdac.in>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by

--- 179 unchanged lines hidden (view full) ---

188#define CC2520_RSSISTAT 0x39
189#define CC2520_RXFIRST 0x3C
190#define CC2520_RXFIFOCNT 0x3E
191#define CC2520_TXFIFOCNT 0x3F
192
193/* Driver private information */
194struct cc2520_private {
195 struct spi_device *spi; /* SPI device structure */
1/* Driver for TI CC2520 802.15.4 Wireless-PAN Networking controller
2 *
3 * Copyright (C) 2014 Varka Bhadram <varkab@cdac.in>
4 * Md.Jamal Mohiuddin <mjmohiuddin@cdac.in>
5 * P Sowjanya <sowjanyap@cdac.in>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by

--- 179 unchanged lines hidden (view full) ---

188#define CC2520_RSSISTAT 0x39
189#define CC2520_RXFIRST 0x3C
190#define CC2520_RXFIFOCNT 0x3E
191#define CC2520_TXFIFOCNT 0x3F
192
193/* Driver private information */
194struct cc2520_private {
195 struct spi_device *spi; /* SPI device structure */
196 struct ieee802154_dev *dev; /* IEEE-802.15.4 device */
196 struct ieee802154_hw *hw; /* IEEE-802.15.4 device */
197 u8 *buf; /* SPI TX/Rx data buffer */
198 struct mutex buffer_mutex; /* SPI buffer mutex */
199 bool is_tx; /* Flag for sync b/w Tx and Rx */
200 int fifo_pin; /* FIFO GPIO pin number */
201 struct work_struct fifop_irqwork;/* Workqueue for FIFOP */
202 spinlock_t lock; /* Lock for is_tx*/
203 struct completion tx_complete; /* Work completion for Tx */
204};

--- 243 unchanged lines hidden (view full) ---

448 "return status buf[0] = %02x\n", priv->buf[0]);
449 dev_vdbg(&priv->spi->dev, "length buf[1] = %02x\n", priv->buf[1]);
450
451 mutex_unlock(&priv->buffer_mutex);
452
453 return status;
454}
455
197 u8 *buf; /* SPI TX/Rx data buffer */
198 struct mutex buffer_mutex; /* SPI buffer mutex */
199 bool is_tx; /* Flag for sync b/w Tx and Rx */
200 int fifo_pin; /* FIFO GPIO pin number */
201 struct work_struct fifop_irqwork;/* Workqueue for FIFOP */
202 spinlock_t lock; /* Lock for is_tx*/
203 struct completion tx_complete; /* Work completion for Tx */
204};

--- 243 unchanged lines hidden (view full) ---

448 "return status buf[0] = %02x\n", priv->buf[0]);
449 dev_vdbg(&priv->spi->dev, "length buf[1] = %02x\n", priv->buf[1]);
450
451 mutex_unlock(&priv->buffer_mutex);
452
453 return status;
454}
455
456static int cc2520_start(struct ieee802154_dev *dev)
456static int cc2520_start(struct ieee802154_hw *hw)
457{
457{
458 return cc2520_cmd_strobe(dev->priv, CC2520_CMD_SRXON);
458 return cc2520_cmd_strobe(hw->priv, CC2520_CMD_SRXON);
459}
460
459}
460
461static void cc2520_stop(struct ieee802154_dev *dev)
461static void cc2520_stop(struct ieee802154_hw *hw)
462{
462{
463 cc2520_cmd_strobe(dev->priv, CC2520_CMD_SRFOFF);
463 cc2520_cmd_strobe(hw->priv, CC2520_CMD_SRFOFF);
464}
465
466static int
464}
465
466static int
467cc2520_tx(struct ieee802154_dev *dev, struct sk_buff *skb)
467cc2520_tx(struct ieee802154_hw *hw, struct sk_buff *skb)
468{
468{
469 struct cc2520_private *priv = dev->priv;
469 struct cc2520_private *priv = hw->priv;
470 unsigned long flags;
471 int rc;
472 u8 status = 0;
473
474 rc = cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHTX);
475 if (rc)
476 goto err_tx;
477

--- 53 unchanged lines hidden (view full) ---

531 if (cc2520_read_rxfifo(priv, skb_put(skb, len), len, &lqi)) {
532 dev_dbg(&priv->spi->dev, "frame reception failed\n");
533 kfree_skb(skb);
534 return -EINVAL;
535 }
536
537 skb_trim(skb, skb->len - 2);
538
470 unsigned long flags;
471 int rc;
472 u8 status = 0;
473
474 rc = cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHTX);
475 if (rc)
476 goto err_tx;
477

--- 53 unchanged lines hidden (view full) ---

531 if (cc2520_read_rxfifo(priv, skb_put(skb, len), len, &lqi)) {
532 dev_dbg(&priv->spi->dev, "frame reception failed\n");
533 kfree_skb(skb);
534 return -EINVAL;
535 }
536
537 skb_trim(skb, skb->len - 2);
538
539 ieee802154_rx_irqsafe(priv->dev, skb, lqi);
539 ieee802154_rx_irqsafe(priv->hw, skb, lqi);
540
541 dev_vdbg(&priv->spi->dev, "RXFIFO: %x %x\n", len, lqi);
542
543 return 0;
544}
545
546static int
540
541 dev_vdbg(&priv->spi->dev, "RXFIFO: %x %x\n", len, lqi);
542
543 return 0;
544}
545
546static int
547cc2520_ed(struct ieee802154_dev *dev, u8 *level)
547cc2520_ed(struct ieee802154_hw *hw, u8 *level)
548{
548{
549 struct cc2520_private *priv = dev->priv;
549 struct cc2520_private *priv = hw->priv;
550 u8 status = 0xff;
551 u8 rssi;
552 int ret;
553
554 ret = cc2520_read_register(priv , CC2520_RSSISTAT, &status);
555 if (ret)
556 return ret;
557

--- 6 unchanged lines hidden (view full) ---

564
565 /* level = RSSI(rssi) - OFFSET [dBm] : offset is 76dBm */
566 *level = rssi - RSSI_OFFSET;
567
568 return 0;
569}
570
571static int
550 u8 status = 0xff;
551 u8 rssi;
552 int ret;
553
554 ret = cc2520_read_register(priv , CC2520_RSSISTAT, &status);
555 if (ret)
556 return ret;
557

--- 6 unchanged lines hidden (view full) ---

564
565 /* level = RSSI(rssi) - OFFSET [dBm] : offset is 76dBm */
566 *level = rssi - RSSI_OFFSET;
567
568 return 0;
569}
570
571static int
572cc2520_set_channel(struct ieee802154_dev *dev, int page, int channel)
572cc2520_set_channel(struct ieee802154_hw *hw, int page, int channel)
573{
573{
574 struct cc2520_private *priv = dev->priv;
574 struct cc2520_private *priv = hw->priv;
575 int ret;
576
577 might_sleep();
578 dev_dbg(&priv->spi->dev, "trying to set channel\n");
579
580 BUG_ON(page != 0);
581 BUG_ON(channel < CC2520_MINCHANNEL);
582 BUG_ON(channel > CC2520_MAXCHANNEL);
583
584 ret = cc2520_write_register(priv, CC2520_FREQCTRL,
585 11 + 5*(channel - 11));
586
587 return ret;
588}
589
590static int
575 int ret;
576
577 might_sleep();
578 dev_dbg(&priv->spi->dev, "trying to set channel\n");
579
580 BUG_ON(page != 0);
581 BUG_ON(channel < CC2520_MINCHANNEL);
582 BUG_ON(channel > CC2520_MAXCHANNEL);
583
584 ret = cc2520_write_register(priv, CC2520_FREQCTRL,
585 11 + 5*(channel - 11));
586
587 return ret;
588}
589
590static int
591cc2520_filter(struct ieee802154_dev *dev,
591cc2520_filter(struct ieee802154_hw *hw,
592 struct ieee802154_hw_addr_filt *filt, unsigned long changed)
593{
592 struct ieee802154_hw_addr_filt *filt, unsigned long changed)
593{
594 struct cc2520_private *priv = dev->priv;
594 struct cc2520_private *priv = hw->priv;
595
596 if (changed & IEEE802154_AFILT_PANID_CHANGED) {
597 u16 panid = le16_to_cpu(filt->pan_id);
598
599 dev_vdbg(&priv->spi->dev,
600 "cc2520_filter called for pan id\n");
601 cc2520_write_ram(priv, CC2520RAM_PANID,
602 sizeof(panid), (u8 *)&panid);

--- 37 unchanged lines hidden (view full) ---

640 .set_channel = cc2520_set_channel,
641 .set_hw_addr_filt = cc2520_filter,
642};
643
644static int cc2520_register(struct cc2520_private *priv)
645{
646 int ret = -ENOMEM;
647
595
596 if (changed & IEEE802154_AFILT_PANID_CHANGED) {
597 u16 panid = le16_to_cpu(filt->pan_id);
598
599 dev_vdbg(&priv->spi->dev,
600 "cc2520_filter called for pan id\n");
601 cc2520_write_ram(priv, CC2520RAM_PANID,
602 sizeof(panid), (u8 *)&panid);

--- 37 unchanged lines hidden (view full) ---

640 .set_channel = cc2520_set_channel,
641 .set_hw_addr_filt = cc2520_filter,
642};
643
644static int cc2520_register(struct cc2520_private *priv)
645{
646 int ret = -ENOMEM;
647
648 priv->dev = ieee802154_alloc_device(sizeof(*priv), &cc2520_ops);
649 if (!priv->dev)
648 priv->hw = ieee802154_alloc_hw(sizeof(*priv), &cc2520_ops);
649 if (!priv->hw)
650 goto err_ret;
651
650 goto err_ret;
651
652 priv->dev->priv = priv;
653 priv->dev->parent = &priv->spi->dev;
654 priv->dev->extra_tx_headroom = 0;
652 priv->hw->priv = priv;
653 priv->hw->parent = &priv->spi->dev;
654 priv->hw->extra_tx_headroom = 0;
655
656 /* We do support only 2.4 Ghz */
655
656 /* We do support only 2.4 Ghz */
657 priv->dev->phy->channels_supported[0] = 0x7FFF800;
658 priv->dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK;
657 priv->hw->phy->channels_supported[0] = 0x7FFF800;
658 priv->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK;
659
660 dev_vdbg(&priv->spi->dev, "registered cc2520\n");
659
660 dev_vdbg(&priv->spi->dev, "registered cc2520\n");
661 ret = ieee802154_register_device(priv->dev);
661 ret = ieee802154_register_hw(priv->hw);
662 if (ret)
663 goto err_free_device;
664
665 return 0;
666
667err_free_device:
662 if (ret)
663 goto err_free_device;
664
665 return 0;
666
667err_free_device:
668 ieee802154_free_device(priv->dev);
668 ieee802154_free_hw(priv->hw);
669err_ret:
670 return ret;
671}
672
673static void cc2520_fifop_irqwork(struct work_struct *work)
674{
675 struct cc2520_private *priv
676 = container_of(work, struct cc2520_private, fifop_irqwork);

--- 320 unchanged lines hidden (view full) ---

997
998static int cc2520_remove(struct spi_device *spi)
999{
1000 struct cc2520_private *priv = spi_get_drvdata(spi);
1001
1002 mutex_destroy(&priv->buffer_mutex);
1003 flush_work(&priv->fifop_irqwork);
1004
669err_ret:
670 return ret;
671}
672
673static void cc2520_fifop_irqwork(struct work_struct *work)
674{
675 struct cc2520_private *priv
676 = container_of(work, struct cc2520_private, fifop_irqwork);

--- 320 unchanged lines hidden (view full) ---

997
998static int cc2520_remove(struct spi_device *spi)
999{
1000 struct cc2520_private *priv = spi_get_drvdata(spi);
1001
1002 mutex_destroy(&priv->buffer_mutex);
1003 flush_work(&priv->fifop_irqwork);
1004
1005 ieee802154_unregister_device(priv->dev);
1006 ieee802154_free_device(priv->dev);
1005 ieee802154_unregister_hw(priv->hw);
1006 ieee802154_free_hw(priv->hw);
1007
1008 return 0;
1009}
1010
1011static const struct spi_device_id cc2520_ids[] = {
1012 {"cc2520", },
1013 {},
1014};

--- 25 unchanged lines hidden ---
1007
1008 return 0;
1009}
1010
1011static const struct spi_device_id cc2520_ids[] = {
1012 {"cc2520", },
1013 {},
1014};

--- 25 unchanged lines hidden ---