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 --- |