On Sun, May 08, 2022 at 12:29:57AM -0400, Farhan Khan wrote:
> On May 6, 2022 4:37:48 AM EDT, Stefan Sperling <s...@stsp.name> wrote:
> >On Thu, May 05, 2022 at 01:19:08PM -0400, Farhan Khan wrote:
> >> Hi all,
> >>
> >> Summary Question:
> >>
> >> Broadly, I am trying to understand where a interrupt callback is specified
> >> if
> >> not already specified by usbd_open_pipe_intr(9). Specifically, for the
> >> athn(4)
> >> driver, I am trying to understand if/how athn_usb_intr() is executed for
> >> Tx
> >> interrupts. This seems necessary yet I do not see a callback specified by
> >> usbd_setup_xfer(9) or by usbd_open_pipe_intr(9).
> >>
> >> All code is located in sys/dev/usb/if_athn_usb.c.
> >>
> >> Question Walk-through:
> >>
> >> >From reading the code, it seems that the athn_usb_intr() function is
> >> >called
> >> whenever a Tx interrupt is triggered. The reason I think this is because
> >> there
> >> is a tsleep_nsec(9) for a Tx interrupt that awaits for a wakeup(9) that
> >> only
> >> happens in athn_usb_intr().
> >>
> >> The 3 relevant steps are listed below in athn_usb_htc_setup() under the
> >> comment "Set credits for WLAN Tx pipe":
> >>
> >> 1. athn_usb_htc_msg(), which runs usbd_setup_xfer(9) and usbd_transfer(9)
> >> for
> >> a Tx interrupt. The callback is set to NULL.
> >> 2. usc->wait_msg_id is set to AR_HTC_MSG_CONF_PIPE_RSP.
> >> 3. A tsleep_nsec() on &usc->wait_msg_id
> >>
> >> The only place I see a wakeup(9) on &usc->wait_msg_id is within
> >> athn_usb_intr(), on condition that usc->wait_msg_id is set to
> >> AR_HTC_MSG_CONF_PIPE_RSP. Seems like a perfect match. Additionally, I do
> >> not
> >> see an Rx interrupt anywhere else. But even if it does happen somewhere
> >> and I
> >> am just missing it, the only place AR_HTC_MSG_CONF_PIPE_RSP is used is
> >> step 2.
> >>
> >> Rx interrupt callbacks to athn_usb_intr() are specified by the
> >> usbd_open_pipe_intr(9) call in athn_usb_open_pipes(). That seems explicit.
> >> But
> >> for the Tx interrupt, I do not see where the mapping to athn_usb_intr() is.
> >>
> >> Please assist, thank you.
> >
> >Everything related to Tx is happening in athn_usb_tx() and athn_usb_txoef().
> >
> >usbd_setup_xfer() gets a function pointer to call when the USB transfer
> >has completed. This function pointer is athn_usb_txeof():
> >
> > usbd_setup_xfer(data->xfer, usc->tx_data_pipe, data, data->buf,
> > xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, ATHN_USB_TX_TIMEOUT,
> > athn_usb_txeof);
> >
> >athn_usb_txeof() puts the buffer associated with the Tx attempt back onto
> >the list of free buffers, and schedules more Tx attempts if needed by
> >calling if_start().
> >
> >The associated mbuf is freed quite early, before the Tx attempt is even made,
> >because the entire packet gets copied into the Tx command sent to the device:
> >
> > /* Copy payload. */
> > m_copydata(m, 0, m->m_pkthdr.len, frm);
> > frm += m->m_pkthdr.len;
> > m_freem(m);
>
>
> Hi Stefan!
> Reading through athn_usb_txeof, I don't see where it triggers an Rx interrupt
> such that the wakeup(9) is done. Additionally, that seems to be a periodic
> function whereas I suspect thr interrupt I am looking for is only during
> initial of the device, not if-up. But perhaps I am mistaken? I do kot
> understand where or how the wakeup(9) occurs.
>
> Thanks!
athn_usb_intr() is not used for Tx interrupts.
athn_usb_intr() is only used to process HTC message responses, not for
processing packets. The driver sleeps on &ubsc->wait_msg_id when it must
wait for a device command to be processed before the driver can continue.
A wakeup() is required in that case to interrupt the corresponding tsleep().
But when the driver is submitting a packet for Tx there is no need to wait.