Implement the new frame_number API to report the isochronous interval frame number. This patch checks and reports the interval in which the isoc transfer was transmitted or received via the Isoc-First TRB SOF number field. Signed-off-by: Thinh Nguyen <thinhn@xxxxxxxxxxxx> --- Change in v3: - Implement the change with the redefined frame_number meaning Change in v2: - Capture frame number at request cleanup drivers/usb/dwc3/core.h | 1 + drivers/usb/dwc3/gadget.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index ed0359d1216d..2c9f7a93147a 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -777,6 +777,7 @@ enum dwc3_link_state { #define DWC3_TRB_CTRL_ISP_IMI BIT(10) #define DWC3_TRB_CTRL_IOC BIT(11) #define DWC3_TRB_CTRL_SID_SOFN(n) (((n) & 0xffff) << 14) +#define DWC3_TRB_CTRL_GET_SID_SOFN(n) (((n) & (0xffff << 14)) >> 14) #define DWC3_TRBCTL_TYPE(n) ((n) & (0x3f << 4)) #define DWC3_TRBCTL_NORMAL DWC3_TRB_CTRL_TRBCTL(1) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 679c12e14522..2de563124fc1 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2254,6 +2254,19 @@ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep, if (chain && (trb->ctrl & DWC3_TRB_CTRL_HWO)) trb->ctrl &= ~DWC3_TRB_CTRL_HWO; + /* + * For isochronous transfers, the first TRB in a service interval must + * have the Isoc-First type. Track and report its interval frame number. + */ + if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && + (trb->ctrl & DWC3_TRBCTL_ISOCHRONOUS_FIRST)) { + unsigned int frame_number; + + frame_number = DWC3_TRB_CTRL_GET_SID_SOFN(trb->ctrl); + frame_number &= ~(dep->interval - 1); + req->request.frame_number = frame_number; + } + /* * If we're dealing with unaligned size OUT transfer, we will be left * with one TRB pending in the ring. We need to manually clear HWO bit -- 2.11.0