Commit f8be91fb authored by Alexander Aring's avatar Alexander Aring Committed by Stefan Schmidt
Browse files

ieee802154: atusb: add support for trac feature



This patch adds support for reading the trac register if atusb firmware
reports tx done. There is currently a feature to compare a sequence
number, if the payload is 1 it tells the driver only the sequence number
is available if it's two there is additional the trac status register as
payload.

Currently the atusb_in_good() function determines if it's a tx done or
rx done if according the payload length. This patch is doing the same
and assumes this behaviour.

Signed-off-by: default avatarAlexander Aring <aahringo@redhat.com>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20220905203412.1322947-10-miquel.raynal@bootlin.com


Signed-off-by: default avatarStefan Schmidt <stefan@datenfreihafen.org>
parent 3a22550a
Loading
Loading
Loading
Loading
+28 −5
Original line number Diff line number Diff line
@@ -191,7 +191,7 @@ static void atusb_work_urbs(struct work_struct *work)

/* ----- Asynchronous USB -------------------------------------------------- */

static void atusb_tx_done(struct atusb *atusb, u8 seq)
static void atusb_tx_done(struct atusb *atusb, u8 seq, int reason)
{
	struct usb_device *usb_dev = atusb->usb_dev;
	u8 expect = atusb->tx_ack_seq;
@@ -199,7 +199,10 @@ static void atusb_tx_done(struct atusb *atusb, u8 seq)
	dev_dbg(&usb_dev->dev, "%s (0x%02x/0x%02x)\n", __func__, seq, expect);
	if (seq == expect) {
		/* TODO check for ifs handling in firmware */
		if (reason == IEEE802154_SUCCESS)
			ieee802154_xmit_complete(atusb->hw, atusb->tx_skb, false);
		else
			ieee802154_xmit_error(atusb->hw, atusb->tx_skb, reason);
	} else {
		/* TODO I experience this case when atusb has a tx complete
		 * irq before probing, we should fix the firmware it's an
@@ -215,7 +218,8 @@ static void atusb_in_good(struct urb *urb)
	struct usb_device *usb_dev = urb->dev;
	struct sk_buff *skb = urb->context;
	struct atusb *atusb = SKB_ATUSB(skb);
	u8 len, lqi;
	int result = IEEE802154_SUCCESS;
	u8 len, lqi, trac;

	if (!urb->actual_length) {
		dev_dbg(&usb_dev->dev, "atusb_in: zero-sized URB ?\n");
@@ -224,8 +228,27 @@ static void atusb_in_good(struct urb *urb)

	len = *skb->data;

	if (urb->actual_length == 1) {
		atusb_tx_done(atusb, len);
	switch (urb->actual_length) {
	case 2:
		trac = TRAC_MASK(*(skb->data + 1));
		switch (trac) {
		case TRAC_SUCCESS:
		case TRAC_SUCCESS_DATA_PENDING:
			/* already IEEE802154_SUCCESS */
			break;
		case TRAC_CHANNEL_ACCESS_FAILURE:
			result = IEEE802154_CHANNEL_ACCESS_FAILURE;
			break;
		case TRAC_NO_ACK:
			result = IEEE802154_NO_ACK;
			break;
		default:
			result = IEEE802154_SYSTEM_ERROR;
		}

		fallthrough;
	case 1:
		atusb_tx_done(atusb, len, result);
		return;
	}