+/*
+ * Convert bInterval expressed in microframes (in 1-255 range) to exponent of
+ * microframes, rounded down to nearest power of 2.
+ */
+static unsigned int xhci_microframes_to_exponent(unsigned int desc_interval,
+ unsigned int min_exponent,
+ unsigned int max_exponent)
+{
+ unsigned int interval;
+
+ interval = fls(desc_interval) - 1;
+ interval = clamp_val(interval, min_exponent, max_exponent);
+ if ((1 << interval) != desc_interval)
+ debug("rounding interval to %d microframes, "\
+ "ep desc says %d microframes\n",
+ 1 << interval, desc_interval);
+
+ return interval;
+}
+
+static unsigned int xhci_parse_microframe_interval(struct usb_device *udev,
+ struct usb_endpoint_descriptor *endpt_desc)
+{
+ if (endpt_desc->bInterval == 0)
+ return 0;
+
+ return xhci_microframes_to_exponent(endpt_desc->bInterval, 0, 15);
+}
+
+static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
+ struct usb_endpoint_descriptor *endpt_desc)
+{
+ return xhci_microframes_to_exponent(endpt_desc->bInterval * 8, 3, 10);
+}
+
+/*
+ * Convert interval expressed as 2^(bInterval - 1) == interval into
+ * straight exponent value 2^n == interval.
+ */
+static unsigned int xhci_parse_exponent_interval(struct usb_device *udev,
+ struct usb_endpoint_descriptor *endpt_desc)
+{
+ unsigned int interval;
+
+ interval = clamp_val(endpt_desc->bInterval, 1, 16) - 1;
+ if (interval != endpt_desc->bInterval - 1)
+ debug("ep %#x - rounding interval to %d %sframes\n",
+ endpt_desc->bEndpointAddress, 1 << interval,
+ udev->speed == USB_SPEED_FULL ? "" : "micro");
+
+ if (udev->speed == USB_SPEED_FULL) {
+ /*
+ * Full speed isoc endpoints specify interval in frames,
+ * not microframes. We are using microframes everywhere,
+ * so adjust accordingly.
+ */
+ interval += 3; /* 1 frame = 2^3 uframes */
+ }
+
+ return interval;
+}
+
+/*
+ * Return the polling or NAK interval.
+ *
+ * The polling interval is expressed in "microframes". If xHCI's Interval field
+ * is set to N, it will service the endpoint every 2^(Interval)*125us.
+ *
+ * The NAK interval is one NAK per 1 to 255 microframes, or no NAKs if interval
+ * is set to 0.
+ */
+static unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
+ struct usb_endpoint_descriptor *endpt_desc)
+{
+ unsigned int interval = 0;
+
+ switch (udev->speed) {
+ case USB_SPEED_HIGH:
+ /* Max NAK rate */
+ if (usb_endpoint_xfer_control(endpt_desc) ||
+ usb_endpoint_xfer_bulk(endpt_desc)) {
+ interval = xhci_parse_microframe_interval(udev,
+ endpt_desc);
+ break;
+ }
+ /* Fall through - SS and HS isoc/int have same decoding */
+
+ case USB_SPEED_SUPER:
+ if (usb_endpoint_xfer_int(endpt_desc) ||
+ usb_endpoint_xfer_isoc(endpt_desc)) {
+ interval = xhci_parse_exponent_interval(udev,
+ endpt_desc);
+ }
+ break;
+
+ case USB_SPEED_FULL:
+ if (usb_endpoint_xfer_isoc(endpt_desc)) {
+ interval = xhci_parse_exponent_interval(udev,
+ endpt_desc);
+ break;
+ }
+ /*
+ * Fall through for interrupt endpoint interval decoding
+ * since it uses the same rules as low speed interrupt
+ * endpoints.
+ */
+
+ case USB_SPEED_LOW:
+ if (usb_endpoint_xfer_int(endpt_desc) ||
+ usb_endpoint_xfer_isoc(endpt_desc)) {
+ interval = xhci_parse_frame_interval(udev, endpt_desc);
+ }
+ break;
+
+ default:
+ BUG();
+ }
+
+ return interval;
+}
+
+/*
+ * The "Mult" field in the endpoint context is only set for SuperSpeed isoc eps.
+ * High speed endpoint descriptors can define "the number of additional
+ * transaction opportunities per microframe", but that goes in the Max Burst
+ * endpoint context field.
+ */
+static u32 xhci_get_endpoint_mult(struct usb_device *udev,
+ struct usb_endpoint_descriptor *endpt_desc,
+ struct usb_ss_ep_comp_descriptor *ss_ep_comp_desc)
+{
+ if (udev->speed < USB_SPEED_SUPER ||
+ !usb_endpoint_xfer_isoc(endpt_desc))
+ return 0;
+
+ return ss_ep_comp_desc->bmAttributes;
+}
+
+static u32 xhci_get_endpoint_max_burst(struct usb_device *udev,
+ struct usb_endpoint_descriptor *endpt_desc,
+ struct usb_ss_ep_comp_descriptor *ss_ep_comp_desc)
+{
+ /* Super speed and Plus have max burst in ep companion desc */
+ if (udev->speed >= USB_SPEED_SUPER)
+ return ss_ep_comp_desc->bMaxBurst;
+
+ if (udev->speed == USB_SPEED_HIGH &&
+ (usb_endpoint_xfer_isoc(endpt_desc) ||
+ usb_endpoint_xfer_int(endpt_desc)))
+ return usb_endpoint_maxp_mult(endpt_desc) - 1;
+
+ return 0;
+}
+
+/*
+ * Return the maximum endpoint service interval time (ESIT) payload.
+ * Basically, this is the maxpacket size, multiplied by the burst size
+ * and mult size.
+ */
+static u32 xhci_get_max_esit_payload(struct usb_device *udev,
+ struct usb_endpoint_descriptor *endpt_desc,
+ struct usb_ss_ep_comp_descriptor *ss_ep_comp_desc)
+{
+ int max_burst;
+ int max_packet;
+
+ /* Only applies for interrupt or isochronous endpoints */
+ if (usb_endpoint_xfer_control(endpt_desc) ||
+ usb_endpoint_xfer_bulk(endpt_desc))
+ return 0;
+
+ /* SuperSpeed Isoc ep with less than 48k per esit */
+ if (udev->speed >= USB_SPEED_SUPER)
+ return le16_to_cpu(ss_ep_comp_desc->wBytesPerInterval);
+
+ max_packet = usb_endpoint_maxp(endpt_desc);
+ max_burst = usb_endpoint_maxp_mult(endpt_desc);
+
+ /* A 0 in max burst means 1 transfer per ESIT */
+ return max_packet * max_burst;
+}
+