mrf24j40.c (4ca24aca55fe1e2a61f3ffaac9015d9c45204729) mrf24j40.c (5a50439775853a8d565115edb63a5ab4bb780479)
1/*
2 * Driver for Microchip MRF24J40 802.15.4 Wireless-PAN Networking controller
3 *
4 * Copyright (C) 2012 Alan Ott <alan@signal11.us>
5 * Signal 11 Software
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

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

74#define RX_FIFO_SIZE 144 /* From datasheet */
75#define SET_CHANNEL_DELAY_US 192 /* From datasheet */
76
77enum mrf24j40_modules { MRF24J40, MRF24J40MA, MRF24J40MC };
78
79/* Device Private Data */
80struct mrf24j40 {
81 struct spi_device *spi;
1/*
2 * Driver for Microchip MRF24J40 802.15.4 Wireless-PAN Networking controller
3 *
4 * Copyright (C) 2012 Alan Ott <alan@signal11.us>
5 * Signal 11 Software
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

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

74#define RX_FIFO_SIZE 144 /* From datasheet */
75#define SET_CHANNEL_DELAY_US 192 /* From datasheet */
76
77enum mrf24j40_modules { MRF24J40, MRF24J40MA, MRF24J40MC };
78
79/* Device Private Data */
80struct mrf24j40 {
81 struct spi_device *spi;
82 struct ieee802154_dev *dev;
82 struct ieee802154_hw *hw;
83
84 struct mutex buffer_mutex; /* only used to protect buf */
85 struct completion tx_complete;
86 u8 *buf; /* 3 bytes. Used for SPI single-register transfers. */
87};
88
89/* Read/Write SPI Commands for Short and Long Address registers. */
90#define MRF24J40_READSHORT(reg) ((reg) << 1)

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

327 pr_debug("mrf24j40 rx: lqi: %02hhx rssi: %02hhx\n",
328 lqi_rssi[0], lqi_rssi[1]);
329#endif
330
331out:
332 return ret;
333}
334
83
84 struct mutex buffer_mutex; /* only used to protect buf */
85 struct completion tx_complete;
86 u8 *buf; /* 3 bytes. Used for SPI single-register transfers. */
87};
88
89/* Read/Write SPI Commands for Short and Long Address registers. */
90#define MRF24J40_READSHORT(reg) ((reg) << 1)

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

327 pr_debug("mrf24j40 rx: lqi: %02hhx rssi: %02hhx\n",
328 lqi_rssi[0], lqi_rssi[1]);
329#endif
330
331out:
332 return ret;
333}
334
335static int mrf24j40_tx(struct ieee802154_dev *dev, struct sk_buff *skb)
335static int mrf24j40_tx(struct ieee802154_hw *hw, struct sk_buff *skb)
336{
336{
337 struct mrf24j40 *devrec = dev->priv;
337 struct mrf24j40 *devrec = hw->priv;
338 u8 val;
339 int ret = 0;
340
341 dev_dbg(printdev(devrec), "tx packet of %d bytes\n", skb->len);
342
343 ret = write_tx_buf(devrec, 0x000, skb->data, skb->len);
344 if (ret)
345 goto err;

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

378 } else
379 dev_dbg(printdev(devrec), "Packet Sent\n");
380
381err:
382
383 return ret;
384}
385
338 u8 val;
339 int ret = 0;
340
341 dev_dbg(printdev(devrec), "tx packet of %d bytes\n", skb->len);
342
343 ret = write_tx_buf(devrec, 0x000, skb->data, skb->len);
344 if (ret)
345 goto err;

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

378 } else
379 dev_dbg(printdev(devrec), "Packet Sent\n");
380
381err:
382
383 return ret;
384}
385
386static int mrf24j40_ed(struct ieee802154_dev *dev, u8 *level)
386static int mrf24j40_ed(struct ieee802154_hw *hw, u8 *level)
387{
388 /* TODO: */
389 pr_warn("mrf24j40: ed not implemented\n");
390 *level = 0;
391 return 0;
392}
393
387{
388 /* TODO: */
389 pr_warn("mrf24j40: ed not implemented\n");
390 *level = 0;
391 return 0;
392}
393
394static int mrf24j40_start(struct ieee802154_dev *dev)
394static int mrf24j40_start(struct ieee802154_hw *hw)
395{
395{
396 struct mrf24j40 *devrec = dev->priv;
396 struct mrf24j40 *devrec = hw->priv;
397 u8 val;
398 int ret;
399
400 dev_dbg(printdev(devrec), "start\n");
401
402 ret = read_short_reg(devrec, REG_INTCON, &val);
403 if (ret)
404 return ret;
405 val &= ~(0x1|0x8); /* Clear TXNIE and RXIE. Enable interrupts */
406 write_short_reg(devrec, REG_INTCON, val);
407
408 return 0;
409}
410
397 u8 val;
398 int ret;
399
400 dev_dbg(printdev(devrec), "start\n");
401
402 ret = read_short_reg(devrec, REG_INTCON, &val);
403 if (ret)
404 return ret;
405 val &= ~(0x1|0x8); /* Clear TXNIE and RXIE. Enable interrupts */
406 write_short_reg(devrec, REG_INTCON, val);
407
408 return 0;
409}
410
411static void mrf24j40_stop(struct ieee802154_dev *dev)
411static void mrf24j40_stop(struct ieee802154_hw *hw)
412{
412{
413 struct mrf24j40 *devrec = dev->priv;
413 struct mrf24j40 *devrec = hw->priv;
414 u8 val;
415 int ret;
416
417 dev_dbg(printdev(devrec), "stop\n");
418
419 ret = read_short_reg(devrec, REG_INTCON, &val);
420 if (ret)
421 return;
422 val |= 0x1|0x8; /* Set TXNIE and RXIE. Disable Interrupts */
423 write_short_reg(devrec, REG_INTCON, val);
424}
425
414 u8 val;
415 int ret;
416
417 dev_dbg(printdev(devrec), "stop\n");
418
419 ret = read_short_reg(devrec, REG_INTCON, &val);
420 if (ret)
421 return;
422 val |= 0x1|0x8; /* Set TXNIE and RXIE. Disable Interrupts */
423 write_short_reg(devrec, REG_INTCON, val);
424}
425
426static int mrf24j40_set_channel(struct ieee802154_dev *dev,
426static int mrf24j40_set_channel(struct ieee802154_hw *hw,
427 int page, int channel)
428{
427 int page, int channel)
428{
429 struct mrf24j40 *devrec = dev->priv;
429 struct mrf24j40 *devrec = hw->priv;
430 u8 val;
431 int ret;
432
433 dev_dbg(printdev(devrec), "Set Channel %d\n", channel);
434
435 WARN_ON(page != 0);
436 WARN_ON(channel < MRF24J40_CHAN_MIN);
437 WARN_ON(channel > MRF24J40_CHAN_MAX);

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

449 val &= ~0x04;
450 write_short_reg(devrec, REG_RFCTL, val);
451
452 udelay(SET_CHANNEL_DELAY_US); /* per datasheet */
453
454 return 0;
455}
456
430 u8 val;
431 int ret;
432
433 dev_dbg(printdev(devrec), "Set Channel %d\n", channel);
434
435 WARN_ON(page != 0);
436 WARN_ON(channel < MRF24J40_CHAN_MIN);
437 WARN_ON(channel > MRF24J40_CHAN_MAX);

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

449 val &= ~0x04;
450 write_short_reg(devrec, REG_RFCTL, val);
451
452 udelay(SET_CHANNEL_DELAY_US); /* per datasheet */
453
454 return 0;
455}
456
457static int mrf24j40_filter(struct ieee802154_dev *dev,
457static int mrf24j40_filter(struct ieee802154_hw *hw,
458 struct ieee802154_hw_addr_filt *filt,
459 unsigned long changed)
460{
458 struct ieee802154_hw_addr_filt *filt,
459 unsigned long changed)
460{
461 struct mrf24j40 *devrec = dev->priv;
461 struct mrf24j40 *devrec = hw->priv;
462
463 dev_dbg(printdev(devrec), "filter\n");
464
465 if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
466 /* Short Addr */
467 u8 addrh, addrl;
468
469 addrh = le16_to_cpu(filt->short_addr) >> 8 & 0xff;

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

559 }
560
561 /* Cut off the checksum */
562 skb_trim(skb, len-2);
563
564 /* TODO: Other drivers call ieee20154_rx_irqsafe() here (eg: cc2040,
565 * also from a workqueue). I think irqsafe is not necessary here.
566 * Can someone confirm? */
462
463 dev_dbg(printdev(devrec), "filter\n");
464
465 if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
466 /* Short Addr */
467 u8 addrh, addrl;
468
469 addrh = le16_to_cpu(filt->short_addr) >> 8 & 0xff;

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

559 }
560
561 /* Cut off the checksum */
562 skb_trim(skb, len-2);
563
564 /* TODO: Other drivers call ieee20154_rx_irqsafe() here (eg: cc2040,
565 * also from a workqueue). I think irqsafe is not necessary here.
566 * Can someone confirm? */
567 ieee802154_rx_irqsafe(devrec->dev, skb, lqi);
567 ieee802154_rx_irqsafe(devrec->hw, skb, lqi);
568
569 dev_dbg(printdev(devrec), "RX Handled\n");
570
571out:
572 /* Turn back on reception of packets off the air. */
573 ret = read_short_reg(devrec, REG_BBREG1, &val);
574 if (ret)
575 return ret;

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

740
741 mutex_init(&devrec->buffer_mutex);
742 init_completion(&devrec->tx_complete);
743 devrec->spi = spi;
744 spi_set_drvdata(spi, devrec);
745
746 /* Register with the 802154 subsystem */
747
568
569 dev_dbg(printdev(devrec), "RX Handled\n");
570
571out:
572 /* Turn back on reception of packets off the air. */
573 ret = read_short_reg(devrec, REG_BBREG1, &val);
574 if (ret)
575 return ret;

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

740
741 mutex_init(&devrec->buffer_mutex);
742 init_completion(&devrec->tx_complete);
743 devrec->spi = spi;
744 spi_set_drvdata(spi, devrec);
745
746 /* Register with the 802154 subsystem */
747
748 devrec->dev = ieee802154_alloc_device(0, &mrf24j40_ops);
749 if (!devrec->dev)
748 devrec->hw = ieee802154_alloc_hw(0, &mrf24j40_ops);
749 if (!devrec->hw)
750 goto err_ret;
751
750 goto err_ret;
751
752 devrec->dev->priv = devrec;
753 devrec->dev->parent = &devrec->spi->dev;
754 devrec->dev->phy->channels_supported[0] = CHANNEL_MASK;
755 devrec->dev->flags = IEEE802154_HW_OMIT_CKSUM|IEEE802154_HW_AACK;
752 devrec->hw->priv = devrec;
753 devrec->hw->parent = &devrec->spi->dev;
754 devrec->hw->phy->channels_supported[0] = CHANNEL_MASK;
755 devrec->hw->flags = IEEE802154_HW_OMIT_CKSUM|IEEE802154_HW_AACK;
756
757 dev_dbg(printdev(devrec), "registered mrf24j40\n");
756
757 dev_dbg(printdev(devrec), "registered mrf24j40\n");
758 ret = ieee802154_register_device(devrec->dev);
758 ret = ieee802154_register_hw(devrec->hw);
759 if (ret)
760 goto err_register_device;
761
762 ret = mrf24j40_hw_init(devrec);
763 if (ret)
764 goto err_hw_init;
765
766 ret = devm_request_threaded_irq(&spi->dev,

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

775 dev_err(printdev(devrec), "Unable to get IRQ");
776 goto err_irq;
777 }
778
779 return 0;
780
781err_irq:
782err_hw_init:
759 if (ret)
760 goto err_register_device;
761
762 ret = mrf24j40_hw_init(devrec);
763 if (ret)
764 goto err_hw_init;
765
766 ret = devm_request_threaded_irq(&spi->dev,

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

775 dev_err(printdev(devrec), "Unable to get IRQ");
776 goto err_irq;
777 }
778
779 return 0;
780
781err_irq:
782err_hw_init:
783 ieee802154_unregister_device(devrec->dev);
783 ieee802154_unregister_hw(devrec->hw);
784err_register_device:
784err_register_device:
785 ieee802154_free_device(devrec->dev);
785 ieee802154_free_hw(devrec->hw);
786err_ret:
787 return ret;
788}
789
790static int mrf24j40_remove(struct spi_device *spi)
791{
792 struct mrf24j40 *devrec = spi_get_drvdata(spi);
793
794 dev_dbg(printdev(devrec), "remove\n");
795
786err_ret:
787 return ret;
788}
789
790static int mrf24j40_remove(struct spi_device *spi)
791{
792 struct mrf24j40 *devrec = spi_get_drvdata(spi);
793
794 dev_dbg(printdev(devrec), "remove\n");
795
796 ieee802154_unregister_device(devrec->dev);
797 ieee802154_free_device(devrec->dev);
796 ieee802154_unregister_hw(devrec->hw);
797 ieee802154_free_hw(devrec->hw);
798 /* TODO: Will ieee802154_free_device() wait until ->xmit() is
799 * complete? */
800
801 return 0;
802}
803
804static const struct spi_device_id mrf24j40_ids[] = {
805 { "mrf24j40", MRF24J40 },

--- 22 unchanged lines hidden ---
798 /* TODO: Will ieee802154_free_device() wait until ->xmit() is
799 * complete? */
800
801 return 0;
802}
803
804static const struct spi_device_id mrf24j40_ids[] = {
805 { "mrf24j40", MRF24J40 },

--- 22 unchanged lines hidden ---