Commit 871489dd authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'ieee802154-for-net-next-2023-02-20' of...

Merge tag 'ieee802154-for-net-next-2023-02-20' of git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan-next

Stefan Schmidt says:

====================
pull-request: ieee802154-next 2023-02-20

Miquel Raynal build upon his earlier work and introduced two new
features into the ieee802154 stack. Beaconing to announce existing
PAN's and passive scanning to discover the beacons and associated
PAN's. The matching changes to the userspace configuration tool
have been posted as well and will be released together with the
kernel release.

Arnd Bergmann and Dmitry Torokhov worked on converting the
at86rf230 and cc2520 drivers away from the unused platform_data
usage and towards the new gpiod API. (I had to add a revert as
Dmitry found a regression on an already pushed tree on my side).

Changes since v1 (pull request 2023-02-02)
- Netlink API extack and NLA_POLICY* usage as suggested by Jakub
- Removed always true condition found by kernel test robot
- Simplify device removal with running background job for scanning
- Fix problems with beacon sending in some cases by using the MLME
  tx path

* tag 'ieee802154-for-net-next-2023-02-20' of git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan-next:
  ieee802154: Drop device trackers
  mac802154: Fix an always true condition
  mac802154: Send beacons using the MLME Tx path
  ieee802154: Change error code on monitor scan netlink request
  ieee802154: Convert scan error messages to extack
  ieee802154: Use netlink policies when relevant on scan parameters
  ieee802154: at86rf230: switch to using gpiod API
  ieee802154: at86rf230: drop support for platform data
  Revert "at86rf230: convert to gpio descriptors"
  cc2520: move to gpio descriptors
  mac802154: Avoid superfluous endianness handling
  at86rf230: convert to gpio descriptors
  mac802154: Handle basic beaconing
  ieee802154: Add support for user beaconing requests
  mac802154: Handle passive scanning
  mac802154: Add MLME Tx locked helpers
  mac802154: Prepare forcing specific symbol duration
  ieee802154: Introduce a helper to validate a channel
  ieee802154: Define a beacon frame header
  ieee802154: Add support for user scanning requests
====================

Link: https://lore.kernel.org/r/20230220213749.386451-1-stefan@datenfreihafen.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 5f22c3b6 ed9a8ad7
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -4819,7 +4819,6 @@ L: linux-wpan@vger.kernel.org
S:	Maintained
F:	Documentation/devicetree/bindings/net/ieee802154/cc2520.txt
F:	drivers/net/ieee802154/cc2520.c
F:	include/linux/spi/cc2520.h
CCREE ARM TRUSTZONE CRYPTOCELL REE DRIVER
M:	Gilad Ben-Yossef <gilad@benyossef.com>
+35 −55
Original line number Diff line number Diff line
@@ -17,8 +17,8 @@
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/property.h>
#include <linux/spi/spi.h>
#include <linux/spi/at86rf230.h>
#include <linux/regmap.h>
#include <linux/skbuff.h>
#include <linux/of_gpio.h>
@@ -82,7 +82,7 @@ struct at86rf230_local {
	struct ieee802154_hw *hw;
	struct at86rf2xx_chip_data *data;
	struct regmap *regmap;
	int slp_tr;
	struct gpio_desc *slp_tr;
	bool sleep;

	struct completion state_complete;
@@ -107,8 +107,8 @@ at86rf230_async_state_change(struct at86rf230_local *lp,
static inline void
at86rf230_sleep(struct at86rf230_local *lp)
{
	if (gpio_is_valid(lp->slp_tr)) {
		gpio_set_value(lp->slp_tr, 1);
	if (lp->slp_tr) {
		gpiod_set_value(lp->slp_tr, 1);
		usleep_range(lp->data->t_off_to_sleep,
			     lp->data->t_off_to_sleep + 10);
		lp->sleep = true;
@@ -118,8 +118,8 @@ at86rf230_sleep(struct at86rf230_local *lp)
static inline void
at86rf230_awake(struct at86rf230_local *lp)
{
	if (gpio_is_valid(lp->slp_tr)) {
		gpio_set_value(lp->slp_tr, 0);
	if (lp->slp_tr) {
		gpiod_set_value(lp->slp_tr, 0);
		usleep_range(lp->data->t_sleep_to_off,
			     lp->data->t_sleep_to_off + 100);
		lp->sleep = false;
@@ -204,9 +204,9 @@ at86rf230_write_subreg(struct at86rf230_local *lp,
static inline void
at86rf230_slp_tr_rising_edge(struct at86rf230_local *lp)
{
	gpio_set_value(lp->slp_tr, 1);
	gpiod_set_value(lp->slp_tr, 1);
	udelay(1);
	gpio_set_value(lp->slp_tr, 0);
	gpiod_set_value(lp->slp_tr, 0);
}

static bool
@@ -819,7 +819,7 @@ at86rf230_write_frame_complete(void *context)

	ctx->trx.len = 2;

	if (gpio_is_valid(lp->slp_tr))
	if (lp->slp_tr)
		at86rf230_slp_tr_rising_edge(lp);
	else
		at86rf230_async_write_reg(lp, RG_TRX_STATE, STATE_BUSY_TX, ctx,
@@ -1415,32 +1415,6 @@ static int at86rf230_hw_init(struct at86rf230_local *lp, u8 xtal_trim)
	return at86rf230_write_subreg(lp, SR_SLOTTED_OPERATION, 0);
}

static int
at86rf230_get_pdata(struct spi_device *spi, int *rstn, int *slp_tr,
		    u8 *xtal_trim)
{
	struct at86rf230_platform_data *pdata = spi->dev.platform_data;
	int ret;

	if (!IS_ENABLED(CONFIG_OF) || !spi->dev.of_node) {
		if (!pdata)
			return -ENOENT;

		*rstn = pdata->rstn;
		*slp_tr = pdata->slp_tr;
		*xtal_trim = pdata->xtal_trim;
		return 0;
	}

	*rstn = of_get_named_gpio(spi->dev.of_node, "reset-gpio", 0);
	*slp_tr = of_get_named_gpio(spi->dev.of_node, "sleep-gpio", 0);
	ret = of_property_read_u8(spi->dev.of_node, "xtal-trim", xtal_trim);
	if (ret < 0 && ret != -EINVAL)
		return ret;

	return 0;
}

static int
at86rf230_detect_device(struct at86rf230_local *lp)
{
@@ -1546,41 +1520,47 @@ static int at86rf230_probe(struct spi_device *spi)
{
	struct ieee802154_hw *hw;
	struct at86rf230_local *lp;
	struct gpio_desc *slp_tr;
	struct gpio_desc *rstn;
	unsigned int status;
	int rc, irq_type, rstn, slp_tr;
	u8 xtal_trim = 0;
	int rc, irq_type;
	u8 xtal_trim;

	if (!spi->irq) {
		dev_err(&spi->dev, "no IRQ specified\n");
		return -EINVAL;
	}

	rc = at86rf230_get_pdata(spi, &rstn, &slp_tr, &xtal_trim);
	rc = device_property_read_u8(&spi->dev, "xtal-trim", &xtal_trim);
	if (rc < 0) {
		dev_err(&spi->dev, "failed to parse platform_data: %d\n", rc);
		if (rc != -EINVAL) {
			dev_err(&spi->dev,
				"failed to parse xtal-trim: %d\n", rc);
			return rc;
		}
		xtal_trim = 0;
	}

	if (gpio_is_valid(rstn)) {
		rc = devm_gpio_request_one(&spi->dev, rstn,
					   GPIOF_OUT_INIT_HIGH, "rstn");
	rstn = devm_gpiod_get_optional(&spi->dev, "reset", GPIOD_OUT_LOW);
	rc = PTR_ERR_OR_ZERO(rstn);
	if (rc)
		return rc;
	}

	if (gpio_is_valid(slp_tr)) {
		rc = devm_gpio_request_one(&spi->dev, slp_tr,
					   GPIOF_OUT_INIT_LOW, "slp_tr");
	gpiod_set_consumer_name(rstn, "rstn");

	slp_tr = devm_gpiod_get_optional(&spi->dev, "sleep", GPIOD_OUT_LOW);
	rc = PTR_ERR_OR_ZERO(slp_tr);
	if (rc)
		return rc;
	}

	gpiod_set_consumer_name(slp_tr, "slp_tr");

	/* Reset */
	if (gpio_is_valid(rstn)) {
	if (rstn) {
		udelay(1);
		gpio_set_value_cansleep(rstn, 0);
		gpiod_set_value_cansleep(rstn, 1);
		udelay(1);
		gpio_set_value_cansleep(rstn, 1);
		gpiod_set_value_cansleep(rstn, 0);
		usleep_range(120, 240);
	}

+37 −99
Original line number Diff line number Diff line
@@ -7,14 +7,13 @@
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/delay.h>
#include <linux/spi/spi.h>
#include <linux/spi/cc2520.h>
#include <linux/property.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/skbuff.h>
#include <linux/of_gpio.h>
#include <linux/ieee802154.h>
#include <linux/crc-ccitt.h>
#include <asm/unaligned.h>
@@ -206,7 +205,7 @@ struct cc2520_private {
	struct mutex buffer_mutex;	/* SPI buffer mutex */
	bool is_tx;			/* Flag for sync b/w Tx and Rx */
	bool amplified;			/* Flag for CC2591 */
	int fifo_pin;			/* FIFO GPIO pin number */
	struct gpio_desc *fifo_pin;	/* FIFO GPIO pin number */
	struct work_struct fifop_irqwork;/* Workqueue for FIFOP */
	spinlock_t lock;		/* Lock for is_tx*/
	struct completion tx_complete;	/* Work completion for Tx */
@@ -875,7 +874,7 @@ static void cc2520_fifop_irqwork(struct work_struct *work)

	dev_dbg(&priv->spi->dev, "fifop interrupt received\n");

	if (gpio_get_value(priv->fifo_pin))
	if (gpiod_get_value(priv->fifo_pin))
		cc2520_rx(priv);
	else
		dev_dbg(&priv->spi->dev, "rxfifo overflow\n");
@@ -912,49 +911,11 @@ static irqreturn_t cc2520_sfd_isr(int irq, void *data)
	return IRQ_HANDLED;
}

static int cc2520_get_platform_data(struct spi_device *spi,
				    struct cc2520_platform_data *pdata)
{
	struct device_node *np = spi->dev.of_node;
	struct cc2520_private *priv = spi_get_drvdata(spi);

	if (!np) {
		struct cc2520_platform_data *spi_pdata = spi->dev.platform_data;

		if (!spi_pdata)
			return -ENOENT;
		*pdata = *spi_pdata;
		priv->fifo_pin = pdata->fifo;
		return 0;
	}

	pdata->fifo = of_get_named_gpio(np, "fifo-gpio", 0);
	priv->fifo_pin = pdata->fifo;

	pdata->fifop = of_get_named_gpio(np, "fifop-gpio", 0);

	pdata->sfd = of_get_named_gpio(np, "sfd-gpio", 0);
	pdata->cca = of_get_named_gpio(np, "cca-gpio", 0);
	pdata->vreg = of_get_named_gpio(np, "vreg-gpio", 0);
	pdata->reset = of_get_named_gpio(np, "reset-gpio", 0);

	/* CC2591 front end for CC2520 */
	if (of_property_read_bool(np, "amplified"))
		priv->amplified = true;

	return 0;
}

static int cc2520_hw_init(struct cc2520_private *priv)
{
	u8 status = 0, state = 0xff;
	int ret;
	int timeout = 100;
	struct cc2520_platform_data pdata;

	ret = cc2520_get_platform_data(priv->spi, &pdata);
	if (ret)
		goto err_ret;

	ret = cc2520_read_register(priv, CC2520_FSMSTAT1, &state);
	if (ret)
@@ -1071,7 +1032,11 @@ static int cc2520_hw_init(struct cc2520_private *priv)
static int cc2520_probe(struct spi_device *spi)
{
	struct cc2520_private *priv;
	struct cc2520_platform_data pdata;
	struct gpio_desc *fifop;
	struct gpio_desc *cca;
	struct gpio_desc *sfd;
	struct gpio_desc *reset;
	struct gpio_desc *vreg;
	int ret;

	priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
@@ -1080,11 +1045,11 @@ static int cc2520_probe(struct spi_device *spi)

	spi_set_drvdata(spi, priv);

	ret = cc2520_get_platform_data(spi, &pdata);
	if (ret < 0) {
		dev_err(&spi->dev, "no platform data\n");
		return -EINVAL;
	}
	/* CC2591 front end for CC2520 */
	/* Assumption that CC2591 is not connected */
	priv->amplified = false;
	if (device_property_read_bool(&spi->dev, "amplified"))
		priv->amplified = true;

	priv->spi = spi;

@@ -1098,80 +1063,53 @@ static int cc2520_probe(struct spi_device *spi)
	spin_lock_init(&priv->lock);
	init_completion(&priv->tx_complete);

	/* Assumption that CC2591 is not connected */
	priv->amplified = false;

	/* Request all the gpio's */
	if (!gpio_is_valid(pdata.fifo)) {
	priv->fifo_pin = devm_gpiod_get(&spi->dev, "fifo", GPIOD_IN);
	if (IS_ERR(priv->fifo_pin)) {
		dev_err(&spi->dev, "fifo gpio is not valid\n");
		ret = -EINVAL;
		ret = PTR_ERR(priv->fifo_pin);
		goto err_hw_init;
	}

	ret = devm_gpio_request_one(&spi->dev, pdata.fifo,
				    GPIOF_IN, "fifo");
	if (ret)
		goto err_hw_init;

	if (!gpio_is_valid(pdata.cca)) {
	cca = devm_gpiod_get(&spi->dev, "cca", GPIOD_IN);
	if (IS_ERR(cca)) {
		dev_err(&spi->dev, "cca gpio is not valid\n");
		ret = -EINVAL;
		ret = PTR_ERR(cca);
		goto err_hw_init;
	}

	ret = devm_gpio_request_one(&spi->dev, pdata.cca,
				    GPIOF_IN, "cca");
	if (ret)
		goto err_hw_init;

	if (!gpio_is_valid(pdata.fifop)) {
	fifop = devm_gpiod_get(&spi->dev, "fifop", GPIOD_IN);
	if (IS_ERR(fifop)) {
		dev_err(&spi->dev, "fifop gpio is not valid\n");
		ret = -EINVAL;
		ret = PTR_ERR(fifop);
		goto err_hw_init;
	}

	ret = devm_gpio_request_one(&spi->dev, pdata.fifop,
				    GPIOF_IN, "fifop");
	if (ret)
		goto err_hw_init;

	if (!gpio_is_valid(pdata.sfd)) {
	sfd = devm_gpiod_get(&spi->dev, "sfd", GPIOD_IN);
	if (IS_ERR(sfd)) {
		dev_err(&spi->dev, "sfd gpio is not valid\n");
		ret = -EINVAL;
		ret = PTR_ERR(sfd);
		goto err_hw_init;
	}

	ret = devm_gpio_request_one(&spi->dev, pdata.sfd,
				    GPIOF_IN, "sfd");
	if (ret)
		goto err_hw_init;

	if (!gpio_is_valid(pdata.reset)) {
	reset = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_LOW);
	if (IS_ERR(reset)) {
		dev_err(&spi->dev, "reset gpio is not valid\n");
		ret = -EINVAL;
		ret = PTR_ERR(reset);
		goto err_hw_init;
	}

	ret = devm_gpio_request_one(&spi->dev, pdata.reset,
				    GPIOF_OUT_INIT_LOW, "reset");
	if (ret)
		goto err_hw_init;

	if (!gpio_is_valid(pdata.vreg)) {
	vreg = devm_gpiod_get(&spi->dev, "vreg", GPIOD_OUT_LOW);
	if (IS_ERR(vreg)) {
		dev_err(&spi->dev, "vreg gpio is not valid\n");
		ret = -EINVAL;
		ret = PTR_ERR(vreg);
		goto err_hw_init;
	}

	ret = devm_gpio_request_one(&spi->dev, pdata.vreg,
				    GPIOF_OUT_INIT_LOW, "vreg");
	if (ret)
		goto err_hw_init;

	gpio_set_value(pdata.vreg, HIGH);
	gpiod_set_value(vreg, HIGH);
	usleep_range(100, 150);

	gpio_set_value(pdata.reset, HIGH);
	gpiod_set_value(reset, HIGH);
	usleep_range(200, 250);

	ret = cc2520_hw_init(priv);
@@ -1180,7 +1118,7 @@ static int cc2520_probe(struct spi_device *spi)

	/* Set up fifop interrupt */
	ret = devm_request_irq(&spi->dev,
			       gpio_to_irq(pdata.fifop),
			       gpiod_to_irq(fifop),
			       cc2520_fifop_isr,
			       IRQF_TRIGGER_RISING,
			       dev_name(&spi->dev),
@@ -1192,7 +1130,7 @@ static int cc2520_probe(struct spi_device *spi)

	/* Set up sfd interrupt */
	ret = devm_request_irq(&spi->dev,
			       gpio_to_irq(pdata.sfd),
			       gpiod_to_irq(sfd),
			       cc2520_sfd_isr,
			       IRQF_TRIGGER_FALLING,
			       dev_name(&spi->dev),
@@ -1241,7 +1179,7 @@ MODULE_DEVICE_TABLE(of, cc2520_of_ids);
static struct spi_driver cc2520_driver = {
	.driver = {
		.name = "cc2520",
		.of_match_table = of_match_ptr(cc2520_of_ids),
		.of_match_table = cc2520_of_ids,
	},
	.id_table = cc2520_ids,
	.probe = cc2520_probe,
+7 −0
Original line number Diff line number Diff line
@@ -44,6 +44,13 @@
#define IEEE802154_SHORT_ADDR_LEN	2
#define IEEE802154_PAN_ID_LEN		2

/* Duration in superframe order */
#define IEEE802154_MAX_SCAN_DURATION	14
#define IEEE802154_ACTIVE_SCAN_DURATION	15
/* Superframe duration in slots */
#define IEEE802154_SUPERFRAME_PERIOD	16
/* Various periods expressed in symbols */
#define IEEE802154_SLOT_PERIOD		60
#define IEEE802154_LIFS_PERIOD		40
#define IEEE802154_SIFS_PERIOD		12
#define IEEE802154_MAX_SIFS_FRAME_SIZE	18

include/linux/spi/at86rf230.h

deleted100644 → 0
+0 −20
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * AT86RF230/RF231 driver
 *
 * Copyright (C) 2009-2012 Siemens AG
 *
 * Written by:
 * Dmitry Eremin-Solenikov <dmitry.baryshkov@siemens.com>
 */
#ifndef AT86RF230_H
#define AT86RF230_H

struct at86rf230_platform_data {
	int rstn;
	int slp_tr;
	int dig2;
	u8 xtal_trim;
};

#endif
Loading