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: Alexander Aring <aahringo@redhat.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20220905203412.1322947-10-miquel.raynal@bootlin.com
Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
This commit is contained in:
Alexander Aring 2022-09-05 22:34:12 +02:00 committed by Stefan Schmidt
parent 3a22550ab5
commit f8be91fbfc

View File

@ -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 */
ieee802154_xmit_complete(atusb->hw, atusb->tx_skb, false);
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;
}