Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: wusb: add wusb_phy_rate sysfs file to host controllers

Add the wusb_phy_rate sysfs file to Wireless USB host controllers. This
sets the maximum PHY rate that will be used for all connected devices.

Signed-off-by: David Vrabel <david.vrabel@csr.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

David Vrabel and committed by
Greg Kroah-Hartman
c3f22d92 d19fc291

+68 -11
+13
Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc
··· 23 23 Since this relates to security (specifically, the 24 24 lifetime of PTKs and GTKs) it should not be changed 25 25 from the default. 26 + 27 + What: /sys/class/uwb_rc/uwbN/wusbhc/wusb_phy_rate 28 + Date: August 2009 29 + KernelVersion: 2.6.32 30 + Contact: David Vrabel <david.vrabel@csr.com> 31 + Description: 32 + The maximum PHY rate to use for all connected devices. 33 + This is only of limited use for testing and 34 + development as the hardware's automatic rate 35 + adaptation is better then this simple control. 36 + 37 + Refer to [ECMA-368] section 10.3.1.1 for the value to 38 + use.
+21 -3
drivers/usb/host/whci/qset.c
··· 49 49 * state 50 50 * @urb: an urb for a transfer to this endpoint 51 51 */ 52 - static void qset_fill_qh(struct whc_qset *qset, struct urb *urb) 52 + static void qset_fill_qh(struct whc *whc, struct whc_qset *qset, struct urb *urb) 53 53 { 54 54 struct usb_device *usb_dev = urb->dev; 55 + struct wusb_dev *wusb_dev = usb_dev->wusb_dev; 55 56 struct usb_wireless_ep_comp_descriptor *epcd; 56 57 bool is_out; 58 + uint8_t phy_rate; 57 59 58 60 is_out = usb_pipeout(urb->pipe); 59 61 ··· 68 66 } else { 69 67 qset->max_seq = 2; 70 68 qset->max_burst = 1; 69 + } 70 + 71 + /* 72 + * Initial PHY rate is 53.3 Mbit/s for control endpoints or 73 + * the maximum supported by the device for other endpoints 74 + * (unless limited by the user). 75 + */ 76 + if (usb_pipecontrol(urb->pipe)) 77 + phy_rate = UWB_PHY_RATE_53; 78 + else { 79 + uint16_t phy_rates; 80 + 81 + phy_rates = le16_to_cpu(wusb_dev->wusb_cap_descr->wPHYRates); 82 + phy_rate = fls(phy_rates) - 1; 83 + if (phy_rate > whc->wusbhc.phy_rate) 84 + phy_rate = whc->wusbhc.phy_rate; 71 85 } 72 86 73 87 qset->qh.info1 = cpu_to_le32( ··· 105 87 * strength and can presumably guess the Tx power required 106 88 * from that? */ 107 89 qset->qh.info3 = cpu_to_le32( 108 - QH_INFO3_TX_RATE_53_3 90 + QH_INFO3_TX_RATE(phy_rate) 109 91 | QH_INFO3_TX_PWR(0) /* 0 == max power */ 110 92 ); 111 93 ··· 167 149 168 150 qset->ep = urb->ep; 169 151 urb->ep->hcpriv = qset; 170 - qset_fill_qh(qset, urb); 152 + qset_fill_qh(whc, qset, urb); 171 153 } 172 154 return qset; 173 155 }
+1 -8
drivers/usb/host/whci/whci-hc.h
··· 172 172 #define QH_INFO3_MAX_DELAY(d) ((d) << 0) /* maximum stream delay in 125 us units (isoc only) */ 173 173 #define QH_INFO3_INTERVAL(i) ((i) << 16) /* segment interval in 125 us units (isoc only) */ 174 174 175 - #define QH_INFO3_TX_RATE_53_3 (0 << 24) 176 - #define QH_INFO3_TX_RATE_80 (1 << 24) 177 - #define QH_INFO3_TX_RATE_106_7 (2 << 24) 178 - #define QH_INFO3_TX_RATE_160 (3 << 24) 179 - #define QH_INFO3_TX_RATE_200 (4 << 24) 180 - #define QH_INFO3_TX_RATE_320 (5 << 24) 181 - #define QH_INFO3_TX_RATE_400 (6 << 24) 182 - #define QH_INFO3_TX_RATE_480 (7 << 24) 175 + #define QH_INFO3_TX_RATE(r) ((r) << 24) /* PHY rate (see [ECMA-368] section 10.3.1.1) */ 183 176 #define QH_INFO3_TX_PWR(p) ((p) << 29) /* transmit power (see [WUSB] section 5.2.1.2) */ 184 177 185 178 #define QH_STATUS_FLOW_CTRL (1 << 15)
+32
drivers/usb/wusbcore/wusbhc.c
··· 147 147 } 148 148 static DEVICE_ATTR(wusb_chid, 0644, wusb_chid_show, wusb_chid_store); 149 149 150 + 151 + static ssize_t wusb_phy_rate_show(struct device *dev, 152 + struct device_attribute *attr, 153 + char *buf) 154 + { 155 + struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); 156 + 157 + return sprintf(buf, "%d\n", wusbhc->phy_rate); 158 + } 159 + 160 + static ssize_t wusb_phy_rate_store(struct device *dev, 161 + struct device_attribute *attr, 162 + const char *buf, size_t size) 163 + { 164 + struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); 165 + uint8_t phy_rate; 166 + ssize_t result; 167 + 168 + result = sscanf(buf, "%hhu", &phy_rate); 169 + if (result != 1) 170 + return -EINVAL; 171 + if (phy_rate >= UWB_PHY_RATE_INVALID) 172 + return -EINVAL; 173 + 174 + wusbhc->phy_rate = phy_rate; 175 + return size; 176 + } 177 + static DEVICE_ATTR(wusb_phy_rate, 0644, wusb_phy_rate_show, wusb_phy_rate_store); 178 + 150 179 /* Group all the WUSBHC attributes */ 151 180 static struct attribute *wusbhc_attrs[] = { 152 181 &dev_attr_wusb_trust_timeout.attr, 153 182 &dev_attr_wusb_chid.attr, 183 + &dev_attr_wusb_phy_rate.attr, 154 184 NULL, 155 185 }; 156 186 ··· 207 177 int result = 0; 208 178 209 179 wusbhc->trust_timeout = WUSB_TRUST_TIMEOUT_MS; 180 + wusbhc->phy_rate = UWB_PHY_RATE_INVALID - 1; 181 + 210 182 mutex_init(&wusbhc->mutex); 211 183 result = wusbhc_mmcie_create(wusbhc); 212 184 if (result < 0)
+1
drivers/usb/wusbcore/wusbhc.h
··· 253 253 254 254 unsigned trust_timeout; /* in jiffies */ 255 255 struct wusb_ckhdid chid; 256 + uint8_t phy_rate; 256 257 struct wuie_host_info *wuie_host_info; 257 258 258 259 struct mutex mutex; /* locks everything else */