/* * Aim an rpipe to its device & endpoint destination * * Make sure we change the address to unauthenticathed if the device * is WUSB and it is not authenticated. */ static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa, struct usb_host_endpoint *ep, struct urb *urb, gfp_t gfp) { int result = -ENOMSG; /* better code for lack of companion? */ struct device *dev = &wa->usb_iface->dev; struct usb_device *usb_dev = urb->dev; struct usb_wireless_ep_comp_descriptor *epcd; u8 unauth; epcd = rpipe_epc_find(dev, ep); if (epcd == NULL) { dev_err(dev, "ep 0x%02x: can't find companion descriptor\n", ep->desc.bEndpointAddress); goto error; } unauth = usb_dev->wusb && !usb_dev->authenticated ? 0x80 : 0; __rpipe_reset(wa, le16_to_cpu(rpipe->descr.wRPipeIndex)); atomic_set(&rpipe->segs_available, le16_to_cpu(rpipe->descr.wRequests)); /* FIXME: block allocation system; request with queuing and timeout */ /* FIXME: compute so seg_size > ep->maxpktsize */ rpipe->descr.wBlocks = cpu_to_le16(16); /* given */ /* ep0 maxpktsize is 0x200 (WUSB1.0[4.8.1]) */ if (usb_endpoint_xfer_isoc(&ep->desc)) rpipe->descr.wMaxPacketSize = epcd->wOverTheAirPacketSize; else rpipe->descr.wMaxPacketSize = ep->desc.wMaxPacketSize; rpipe->descr.bHSHubAddress = 0; /* reserved: zero */ rpipe->descr.bHSHubPort = wusb_port_no_to_idx(urb->dev->portnum); /* FIXME: use maximum speed as supported or recommended by device */ rpipe->descr.bSpeed = usb_pipeendpoint(urb->pipe) == 0 ? UWB_PHY_RATE_53 : UWB_PHY_RATE_200; dev_dbg(dev, "addr %u (0x%02x) rpipe #%u ep# %u speed %d\n", urb->dev->devnum, urb->dev->devnum | unauth, le16_to_cpu(rpipe->descr.wRPipeIndex), usb_pipeendpoint(urb->pipe), rpipe->descr.bSpeed); /* see security.c:wusb_update_address() */ if (unlikely(urb->dev->devnum == 0x80)) rpipe->descr.bDeviceAddress = 0; else rpipe->descr.bDeviceAddress = urb->dev->devnum | unauth; rpipe->descr.bEndpointAddress = ep->desc.bEndpointAddress; /* FIXME: bDataSequence */ rpipe->descr.bDataSequence = 0; /* FIXME: dwCurrentWindow */ rpipe->descr.dwCurrentWindow = cpu_to_le32(1); /* FIXME: bMaxDataSequence */ rpipe->descr.bMaxDataSequence = epcd->bMaxSequence - 1; rpipe->descr.bInterval = ep->desc.bInterval; /* FIXME: bOverTheAirInterval */ rpipe->descr.bOverTheAirInterval = 0; /* 0 if not isoc */ /* FIXME: xmit power & preamble blah blah */ rpipe->descr.bmAttribute = ep->desc.bmAttributes & 0x03; /* rpipe->descr.bmCharacteristics RO */ /* FIXME: bmRetryOptions */ rpipe->descr.bmRetryOptions = 15; /* FIXME: use for assessing link quality? */ rpipe->descr.wNumTransactionErrors = 0; result = __rpipe_set_descr(wa, &rpipe->descr, le16_to_cpu(rpipe->descr.wRPipeIndex)); if (result < 0) { dev_err(dev, "Cannot aim rpipe: %d\n", result); goto error; } result = 0; error: return result; }
/* * Aim an rpipe to its device & endpoint destination * * Make sure we change the address to unauthenticated if the device * is WUSB and it is not authenticated. */ static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa, struct usb_host_endpoint *ep, struct urb *urb, gfp_t gfp) { int result = -ENOMSG; /* better code for lack of companion? */ struct device *dev = &wa->usb_iface->dev; struct usb_device *usb_dev = urb->dev; struct usb_wireless_ep_comp_descriptor *epcd; u32 ack_window, epcd_max_sequence; u8 unauth; epcd = rpipe_epc_find(dev, ep); if (epcd == NULL) { dev_err(dev, "ep 0x%02x: can't find companion descriptor\n", ep->desc.bEndpointAddress); goto error; } unauth = usb_dev->wusb && !usb_dev->authenticated ? 0x80 : 0; __rpipe_reset(wa, le16_to_cpu(rpipe->descr.wRPipeIndex)); atomic_set(&rpipe->segs_available, le16_to_cpu(rpipe->descr.wRequests)); /* FIXME: block allocation system; request with queuing and timeout */ /* FIXME: compute so seg_size > ep->maxpktsize */ rpipe->descr.wBlocks = cpu_to_le16(16); /* given */ /* ep0 maxpktsize is 0x200 (WUSB1.0[4.8.1]) */ if (usb_endpoint_xfer_isoc(&ep->desc)) rpipe->descr.wMaxPacketSize = epcd->wOverTheAirPacketSize; else rpipe->descr.wMaxPacketSize = ep->desc.wMaxPacketSize; rpipe->descr.hwa_bMaxBurst = max(min_t(unsigned int, epcd->bMaxBurst, 16U), 1U); rpipe->descr.hwa_bDeviceInfoIndex = wusb_port_no_to_idx(urb->dev->portnum); /* FIXME: use maximum speed as supported or recommended by device */ rpipe->descr.bSpeed = usb_pipeendpoint(urb->pipe) == 0 ? UWB_PHY_RATE_53 : UWB_PHY_RATE_200; dev_dbg(dev, "addr %u (0x%02x) rpipe #%u ep# %u speed %d\n", urb->dev->devnum, urb->dev->devnum | unauth, le16_to_cpu(rpipe->descr.wRPipeIndex), usb_pipeendpoint(urb->pipe), rpipe->descr.bSpeed); rpipe->descr.hwa_reserved = 0; rpipe->descr.bEndpointAddress = ep->desc.bEndpointAddress; /* FIXME: bDataSequence */ rpipe->descr.bDataSequence = 0; /* start with base window of hwa_bMaxBurst bits starting at 0. */ ack_window = 0xFFFFFFFF >> (32 - rpipe->descr.hwa_bMaxBurst); rpipe->descr.dwCurrentWindow = cpu_to_le32(ack_window); epcd_max_sequence = max(min_t(unsigned int, epcd->bMaxSequence, 32U), 2U); rpipe->descr.bMaxDataSequence = epcd_max_sequence - 1; rpipe->descr.bInterval = ep->desc.bInterval; if (usb_endpoint_xfer_isoc(&ep->desc)) rpipe->descr.bOverTheAirInterval = epcd->bOverTheAirInterval; else rpipe->descr.bOverTheAirInterval = 0; /* 0 if not isoc */ /* FIXME: xmit power & preamble blah blah */ rpipe->descr.bmAttribute = (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); /* rpipe->descr.bmCharacteristics RO */ rpipe->descr.bmRetryOptions = (wa->wusb->retry_count & 0xF); /* FIXME: use for assessing link quality? */ rpipe->descr.wNumTransactionErrors = 0; result = __rpipe_set_descr(wa, &rpipe->descr, le16_to_cpu(rpipe->descr.wRPipeIndex)); if (result < 0) { dev_err(dev, "Cannot aim rpipe: %d\n", result); goto error; } result = 0; error: return result; }