• Home
  • Raw
  • Download

Lines Matching +full:filt +full:- +full:disable

1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Driver for TI CC2520 802.15.4 Wireless-PAN Networking controller
19 #include <linux/crc-ccitt.h>
48 /* IEEE-802.15.4 defined constants (2.4 GHz logical channels) */
204 struct ieee802154_hw *hw; /* IEEE-802.15.4 device */
224 .tx_buf = priv->buf, in cc2520_cmd_strobe()
225 .rx_buf = priv->buf, in cc2520_cmd_strobe()
231 mutex_lock(&priv->buffer_mutex); in cc2520_cmd_strobe()
232 priv->buf[xfer.len++] = cmd; in cc2520_cmd_strobe()
233 dev_vdbg(&priv->spi->dev, in cc2520_cmd_strobe()
235 priv->buf[0]); in cc2520_cmd_strobe()
237 ret = spi_sync(priv->spi, &msg); in cc2520_cmd_strobe()
238 dev_vdbg(&priv->spi->dev, in cc2520_cmd_strobe()
239 "buf[0] = %02x\n", priv->buf[0]); in cc2520_cmd_strobe()
240 mutex_unlock(&priv->buffer_mutex); in cc2520_cmd_strobe()
252 .tx_buf = priv->buf, in cc2520_get_status()
253 .rx_buf = priv->buf, in cc2520_get_status()
259 mutex_lock(&priv->buffer_mutex); in cc2520_get_status()
260 priv->buf[xfer.len++] = CC2520_CMD_SNOP; in cc2520_get_status()
261 dev_vdbg(&priv->spi->dev, in cc2520_get_status()
262 "get status command buf[0] = %02x\n", priv->buf[0]); in cc2520_get_status()
264 ret = spi_sync(priv->spi, &msg); in cc2520_get_status()
266 *status = priv->buf[0]; in cc2520_get_status()
267 dev_vdbg(&priv->spi->dev, in cc2520_get_status()
268 "buf[0] = %02x\n", priv->buf[0]); in cc2520_get_status()
269 mutex_unlock(&priv->buffer_mutex); in cc2520_get_status()
281 .tx_buf = priv->buf, in cc2520_write_register()
282 .rx_buf = priv->buf, in cc2520_write_register()
288 mutex_lock(&priv->buffer_mutex); in cc2520_write_register()
291 priv->buf[xfer.len++] = CC2520_CMD_REGISTER_WRITE | reg; in cc2520_write_register()
292 priv->buf[xfer.len++] = value; in cc2520_write_register()
294 priv->buf[xfer.len++] = CC2520_CMD_MEMORY_WRITE; in cc2520_write_register()
295 priv->buf[xfer.len++] = reg; in cc2520_write_register()
296 priv->buf[xfer.len++] = value; in cc2520_write_register()
298 status = spi_sync(priv->spi, &msg); in cc2520_write_register()
302 mutex_unlock(&priv->buffer_mutex); in cc2520_write_register()
314 .tx_buf = priv->buf, in cc2520_write_ram()
315 .rx_buf = priv->buf, in cc2520_write_ram()
323 mutex_lock(&priv->buffer_mutex); in cc2520_write_ram()
324 priv->buf[xfer_head.len++] = (CC2520_CMD_MEMORY_WRITE | in cc2520_write_ram()
326 priv->buf[xfer_head.len++] = reg & 0xff; in cc2520_write_ram()
332 status = spi_sync(priv->spi, &msg); in cc2520_write_ram()
333 dev_dbg(&priv->spi->dev, "spi status = %d\n", status); in cc2520_write_ram()
337 mutex_unlock(&priv->buffer_mutex); in cc2520_write_ram()
348 .tx_buf = priv->buf, in cc2520_read_register()
349 .rx_buf = priv->buf, in cc2520_read_register()
361 mutex_lock(&priv->buffer_mutex); in cc2520_read_register()
362 priv->buf[xfer1.len++] = CC2520_CMD_MEMORY_READ; in cc2520_read_register()
363 priv->buf[xfer1.len++] = reg; in cc2520_read_register()
365 status = spi_sync(priv->spi, &msg); in cc2520_read_register()
366 dev_dbg(&priv->spi->dev, in cc2520_read_register()
371 mutex_unlock(&priv->buffer_mutex); in cc2520_read_register()
390 .tx_buf = priv->buf, in cc2520_write_txfifo()
391 .rx_buf = priv->buf, in cc2520_write_txfifo()
407 mutex_lock(&priv->buffer_mutex); in cc2520_write_txfifo()
408 priv->buf[xfer_head.len++] = CC2520_CMD_TXBUF; in cc2520_write_txfifo()
409 dev_vdbg(&priv->spi->dev, in cc2520_write_txfifo()
410 "TX_FIFO cmd buf[0] = %02x\n", priv->buf[0]); in cc2520_write_txfifo()
412 status = spi_sync(priv->spi, &msg); in cc2520_write_txfifo()
413 dev_vdbg(&priv->spi->dev, "status = %d\n", status); in cc2520_write_txfifo()
416 dev_vdbg(&priv->spi->dev, "status = %d\n", status); in cc2520_write_txfifo()
417 dev_vdbg(&priv->spi->dev, "buf[0] = %02x\n", priv->buf[0]); in cc2520_write_txfifo()
418 mutex_unlock(&priv->buffer_mutex); in cc2520_write_txfifo()
431 .tx_buf = priv->buf, in cc2520_read_rxfifo()
432 .rx_buf = priv->buf, in cc2520_read_rxfifo()
443 mutex_lock(&priv->buffer_mutex); in cc2520_read_rxfifo()
444 priv->buf[xfer_head.len++] = CC2520_CMD_RXBUF; in cc2520_read_rxfifo()
446 dev_vdbg(&priv->spi->dev, "read rxfifo buf[0] = %02x\n", priv->buf[0]); in cc2520_read_rxfifo()
447 dev_vdbg(&priv->spi->dev, "buf[1] = %02x\n", priv->buf[1]); in cc2520_read_rxfifo()
449 status = spi_sync(priv->spi, &msg); in cc2520_read_rxfifo()
450 dev_vdbg(&priv->spi->dev, "status = %d\n", status); in cc2520_read_rxfifo()
453 dev_vdbg(&priv->spi->dev, "status = %d\n", status); in cc2520_read_rxfifo()
454 dev_vdbg(&priv->spi->dev, in cc2520_read_rxfifo()
455 "return status buf[0] = %02x\n", priv->buf[0]); in cc2520_read_rxfifo()
456 dev_vdbg(&priv->spi->dev, "length buf[1] = %02x\n", priv->buf[1]); in cc2520_read_rxfifo()
458 mutex_unlock(&priv->buffer_mutex); in cc2520_read_rxfifo()
465 return cc2520_cmd_strobe(hw->priv, CC2520_CMD_SRXON); in cc2520_start()
470 cc2520_cmd_strobe(hw->priv, CC2520_CMD_SRFOFF); in cc2520_stop()
476 struct cc2520_private *priv = hw->priv; in cc2520_tx()
482 /* In promiscuous mode we disable AUTOCRC so we can get the raw CRC in cc2520_tx()
485 if (priv->promiscuous) { in cc2520_tx()
486 u16 crc = crc_ccitt(0, skb->data, skb->len); in cc2520_tx()
489 pkt_len = skb->len; in cc2520_tx()
491 pkt_len = skb->len + 2; in cc2520_tx()
498 rc = cc2520_write_txfifo(priv, pkt_len, skb->data, skb->len); in cc2520_tx()
507 rc = -EINVAL; in cc2520_tx()
508 dev_err(&priv->spi->dev, "cc2520 tx underflow exception\n"); in cc2520_tx()
512 spin_lock_irqsave(&priv->lock, flags); in cc2520_tx()
513 WARN_ON(priv->is_tx); in cc2520_tx()
514 priv->is_tx = 1; in cc2520_tx()
515 spin_unlock_irqrestore(&priv->lock, flags); in cc2520_tx()
521 rc = wait_for_completion_interruptible(&priv->tx_complete); in cc2520_tx()
530 spin_lock_irqsave(&priv->lock, flags); in cc2520_tx()
531 priv->is_tx = 0; in cc2520_tx()
532 spin_unlock_irqrestore(&priv->lock, flags); in cc2520_tx()
549 dev_dbg(&priv->spi->dev, "corrupted frame received\n"); in cc2520_rx()
555 return -ENOMEM; in cc2520_rx()
558 dev_dbg(&priv->spi->dev, "frame reception failed\n"); in cc2520_rx()
560 return -EINVAL; in cc2520_rx()
568 if (!priv->promiscuous) { in cc2520_rx()
575 crc_ok = skb->data[len - 1] & BIT(7); in cc2520_rx()
579 dev_dbg(&priv->spi->dev, "CRC check failed\n"); in cc2520_rx()
581 return -EINVAL; in cc2520_rx()
586 * the range 0-255. According to section 20.6, the correlation in cc2520_rx()
587 * value ranges from 50-110. Ideally this would be calibrated in cc2520_rx()
591 lqi = skb->data[len - 1] & 0x7f; in cc2520_rx()
596 lqi = (lqi - 50) * 4; in cc2520_rx()
599 ieee802154_rx_irqsafe(priv->hw, skb, lqi); in cc2520_rx()
601 dev_vdbg(&priv->spi->dev, "RXFIFO: %x %x\n", len, lqi); in cc2520_rx()
609 struct cc2520_private *priv = hw->priv; in cc2520_ed()
619 return -EINVAL; in cc2520_ed()
625 /* level = RSSI(rssi) - OFFSET [dBm] : offset is 76dBm */ in cc2520_ed()
626 *level = rssi - RSSI_OFFSET; in cc2520_ed()
634 struct cc2520_private *priv = hw->priv; in cc2520_set_channel()
637 dev_dbg(&priv->spi->dev, "trying to set channel\n"); in cc2520_set_channel()
644 11 + 5 * (channel - 11)); in cc2520_set_channel()
651 struct ieee802154_hw_addr_filt *filt, unsigned long changed) in cc2520_filter() argument
653 struct cc2520_private *priv = hw->priv; in cc2520_filter()
657 u16 panid = le16_to_cpu(filt->pan_id); in cc2520_filter()
659 dev_vdbg(&priv->spi->dev, "%s called for pan id\n", __func__); in cc2520_filter()
665 dev_vdbg(&priv->spi->dev, in cc2520_filter()
668 sizeof(filt->ieee_addr), in cc2520_filter()
669 (u8 *)&filt->ieee_addr); in cc2520_filter()
673 u16 addr = le16_to_cpu(filt->short_addr); in cc2520_filter()
675 dev_vdbg(&priv->spi->dev, "%s called for saddr\n", __func__); in cc2520_filter()
683 dev_vdbg(&priv->spi->dev, in cc2520_filter()
688 if (filt->pan_coord) in cc2520_filter()
719 case -200: in cc2520_set_tx_power()
722 case -400: in cc2520_set_tx_power()
725 case -700: in cc2520_set_tx_power()
728 case -1800: in cc2520_set_tx_power()
732 return -EINVAL; in cc2520_set_tx_power()
756 case -100: in cc2520_cc2591_set_tx_power()
759 case -800: in cc2520_cc2591_set_tx_power()
763 return -EINVAL; in cc2520_cc2591_set_tx_power()
771 500, 300, 200, 100, 0, -200, -400, -700, -1800,
776 1700, 1600, 1400, 1100, -100, -800,
782 struct cc2520_private *priv = hw->priv; in cc2520_set_txpower()
784 if (!priv->amplified) in cc2520_set_txpower()
793 struct cc2520_private *priv = hw->priv; in cc2520_set_promiscuous_mode()
796 dev_dbg(&priv->spi->dev, "%s : mode %d\n", __func__, on); in cc2520_set_promiscuous_mode()
798 priv->promiscuous = on; in cc2520_set_promiscuous_mode()
803 /* Disable automatic ACK, automatic CRC, and frame filtering. */ in cc2520_set_promiscuous_mode()
828 int ret = -ENOMEM; in cc2520_register()
830 priv->hw = ieee802154_alloc_hw(sizeof(*priv), &cc2520_ops); in cc2520_register()
831 if (!priv->hw) in cc2520_register()
834 priv->hw->priv = priv; in cc2520_register()
835 priv->hw->parent = &priv->spi->dev; in cc2520_register()
836 priv->hw->extra_tx_headroom = 0; in cc2520_register()
837 ieee802154_random_extended_addr(&priv->hw->phy->perm_extended_addr); in cc2520_register()
840 priv->hw->phy->supported.channels[0] = 0x7FFF800; in cc2520_register()
841 priv->hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT | in cc2520_register()
844 priv->hw->phy->flags = WPAN_PHY_FLAG_TXPOWER; in cc2520_register()
846 if (!priv->amplified) { in cc2520_register()
847 priv->hw->phy->supported.tx_powers = cc2520_powers; in cc2520_register()
848 priv->hw->phy->supported.tx_powers_size = ARRAY_SIZE(cc2520_powers); in cc2520_register()
849 priv->hw->phy->transmit_power = priv->hw->phy->supported.tx_powers[4]; in cc2520_register()
851 priv->hw->phy->supported.tx_powers = cc2520_cc2591_powers; in cc2520_register()
852 priv->hw->phy->supported.tx_powers_size = ARRAY_SIZE(cc2520_cc2591_powers); in cc2520_register()
853 priv->hw->phy->transmit_power = priv->hw->phy->supported.tx_powers[0]; in cc2520_register()
856 priv->hw->phy->current_channel = 11; in cc2520_register()
858 dev_vdbg(&priv->spi->dev, "registered cc2520\n"); in cc2520_register()
859 ret = ieee802154_register_hw(priv->hw); in cc2520_register()
866 ieee802154_free_hw(priv->hw); in cc2520_register()
876 dev_dbg(&priv->spi->dev, "fifop interrupt received\n"); in cc2520_fifop_irqwork()
878 if (gpio_get_value(priv->fifo_pin)) in cc2520_fifop_irqwork()
881 dev_dbg(&priv->spi->dev, "rxfifo overflow\n"); in cc2520_fifop_irqwork()
891 schedule_work(&priv->fifop_irqwork); in cc2520_fifop_isr()
901 spin_lock_irqsave(&priv->lock, flags); in cc2520_sfd_isr()
902 if (priv->is_tx) { in cc2520_sfd_isr()
903 priv->is_tx = 0; in cc2520_sfd_isr()
904 spin_unlock_irqrestore(&priv->lock, flags); in cc2520_sfd_isr()
905 dev_dbg(&priv->spi->dev, "SFD for TX\n"); in cc2520_sfd_isr()
906 complete(&priv->tx_complete); in cc2520_sfd_isr()
908 spin_unlock_irqrestore(&priv->lock, flags); in cc2520_sfd_isr()
909 dev_dbg(&priv->spi->dev, "SFD for RX\n"); in cc2520_sfd_isr()
918 struct device_node *np = spi->dev.of_node; in cc2520_get_platform_data()
922 struct cc2520_platform_data *spi_pdata = spi->dev.platform_data; in cc2520_get_platform_data()
925 return -ENOENT; in cc2520_get_platform_data()
927 priv->fifo_pin = pdata->fifo; in cc2520_get_platform_data()
931 pdata->fifo = of_get_named_gpio(np, "fifo-gpio", 0); in cc2520_get_platform_data()
932 priv->fifo_pin = pdata->fifo; in cc2520_get_platform_data()
934 pdata->fifop = of_get_named_gpio(np, "fifop-gpio", 0); in cc2520_get_platform_data()
936 pdata->sfd = of_get_named_gpio(np, "sfd-gpio", 0); in cc2520_get_platform_data()
937 pdata->cca = of_get_named_gpio(np, "cca-gpio", 0); in cc2520_get_platform_data()
938 pdata->vreg = of_get_named_gpio(np, "vreg-gpio", 0); in cc2520_get_platform_data()
939 pdata->reset = of_get_named_gpio(np, "reset-gpio", 0); in cc2520_get_platform_data()
943 priv->amplified = true; in cc2520_get_platform_data()
955 ret = cc2520_get_platform_data(priv->spi, &pdata); in cc2520_hw_init()
964 return -EINVAL; in cc2520_hw_init()
971 if (timeout-- <= 0) { in cc2520_hw_init()
972 dev_err(&priv->spi->dev, "oscillator start failed!\n"); in cc2520_hw_init()
973 return -ETIMEDOUT; in cc2520_hw_init()
978 dev_vdbg(&priv->spi->dev, "oscillator brought up\n"); in cc2520_hw_init()
986 if (priv->amplified) { in cc2520_hw_init()
1014 /* Set the CCA threshold to -50 dBm. This seems to have been copied in cc2520_hw_init()
1015 * from the TinyOS CC2520 driver and is much higher than the -84 dBm in cc2520_hw_init()
1077 priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL); in cc2520_probe()
1079 return -ENOMEM; in cc2520_probe()
1085 dev_err(&spi->dev, "no platform data\n"); in cc2520_probe()
1086 return -EINVAL; in cc2520_probe()
1089 priv->spi = spi; in cc2520_probe()
1091 priv->buf = devm_kzalloc(&spi->dev, in cc2520_probe()
1093 if (!priv->buf) in cc2520_probe()
1094 return -ENOMEM; in cc2520_probe()
1096 mutex_init(&priv->buffer_mutex); in cc2520_probe()
1097 INIT_WORK(&priv->fifop_irqwork, cc2520_fifop_irqwork); in cc2520_probe()
1098 spin_lock_init(&priv->lock); in cc2520_probe()
1099 init_completion(&priv->tx_complete); in cc2520_probe()
1102 priv->amplified = false; in cc2520_probe()
1106 dev_err(&spi->dev, "fifo gpio is not valid\n"); in cc2520_probe()
1107 ret = -EINVAL; in cc2520_probe()
1111 ret = devm_gpio_request_one(&spi->dev, pdata.fifo, in cc2520_probe()
1117 dev_err(&spi->dev, "cca gpio is not valid\n"); in cc2520_probe()
1118 ret = -EINVAL; in cc2520_probe()
1122 ret = devm_gpio_request_one(&spi->dev, pdata.cca, in cc2520_probe()
1128 dev_err(&spi->dev, "fifop gpio is not valid\n"); in cc2520_probe()
1129 ret = -EINVAL; in cc2520_probe()
1133 ret = devm_gpio_request_one(&spi->dev, pdata.fifop, in cc2520_probe()
1139 dev_err(&spi->dev, "sfd gpio is not valid\n"); in cc2520_probe()
1140 ret = -EINVAL; in cc2520_probe()
1144 ret = devm_gpio_request_one(&spi->dev, pdata.sfd, in cc2520_probe()
1150 dev_err(&spi->dev, "reset gpio is not valid\n"); in cc2520_probe()
1151 ret = -EINVAL; in cc2520_probe()
1155 ret = devm_gpio_request_one(&spi->dev, pdata.reset, in cc2520_probe()
1161 dev_err(&spi->dev, "vreg gpio is not valid\n"); in cc2520_probe()
1162 ret = -EINVAL; in cc2520_probe()
1166 ret = devm_gpio_request_one(&spi->dev, pdata.vreg, in cc2520_probe()
1182 ret = devm_request_irq(&spi->dev, in cc2520_probe()
1186 dev_name(&spi->dev), in cc2520_probe()
1189 dev_err(&spi->dev, "could not get fifop irq\n"); in cc2520_probe()
1194 ret = devm_request_irq(&spi->dev, in cc2520_probe()
1198 dev_name(&spi->dev), in cc2520_probe()
1201 dev_err(&spi->dev, "could not get sfd irq\n"); in cc2520_probe()
1212 mutex_destroy(&priv->buffer_mutex); in cc2520_probe()
1213 flush_work(&priv->fifop_irqwork); in cc2520_probe()
1221 mutex_destroy(&priv->buffer_mutex); in cc2520_remove()
1222 flush_work(&priv->fifop_irqwork); in cc2520_remove()
1224 ieee802154_unregister_hw(priv->hw); in cc2520_remove()
1225 ieee802154_free_hw(priv->hw); in cc2520_remove()