]> Pileus Git - ~andy/linux/commitdiff
USB: wusb: add wusb_phy_rate sysfs file to host controllers
authorDavid Vrabel <david.vrabel@csr.com>
Mon, 12 Oct 2009 15:45:18 +0000 (15:45 +0000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 11 Dec 2009 19:55:16 +0000 (11:55 -0800)
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>
Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc
drivers/usb/host/whci/qset.c
drivers/usb/host/whci/whci-hc.h
drivers/usb/wusbcore/wusbhc.c
drivers/usb/wusbcore/wusbhc.h

index 4e8106f7cfd9a1677ed0e0023dfc1009930fe2b1..25b1e751b77714a5ecbf05f56b3d0f7784cee386 100644 (file)
@@ -23,3 +23,16 @@ Description:
                 Since this relates to security (specifically, the
                 lifetime of PTKs and GTKs) it should not be changed
                 from the default.
                 Since this relates to security (specifically, the
                 lifetime of PTKs and GTKs) it should not be changed
                 from the default.
+
+What:           /sys/class/uwb_rc/uwbN/wusbhc/wusb_phy_rate
+Date:           August 2009
+KernelVersion:  2.6.32
+Contact:        David Vrabel <david.vrabel@csr.com>
+Description:
+                The maximum PHY rate to use for all connected devices.
+                This is only of limited use for testing and
+                development as the hardware's automatic rate
+                adaptation is better then this simple control.
+
+                Refer to [ECMA-368] section 10.3.1.1 for the value to
+                use.
index 08280869ed1c8215b176c0d9340b198043869e73..39e855a55c6384732e30c67b726e3564b98218f2 100644 (file)
@@ -49,11 +49,13 @@ struct whc_qset *qset_alloc(struct whc *whc, gfp_t mem_flags)
  *        state
  * @urb:  an urb for a transfer to this endpoint
  */
  *        state
  * @urb:  an urb for a transfer to this endpoint
  */
-static void qset_fill_qh(struct whc_qset *qset, struct urb *urb)
+static void qset_fill_qh(struct whc *whc, struct whc_qset *qset, struct urb *urb)
 {
        struct usb_device *usb_dev = urb->dev;
 {
        struct usb_device *usb_dev = urb->dev;
+       struct wusb_dev *wusb_dev = usb_dev->wusb_dev;
        struct usb_wireless_ep_comp_descriptor *epcd;
        bool is_out;
        struct usb_wireless_ep_comp_descriptor *epcd;
        bool is_out;
+       uint8_t phy_rate;
 
        is_out = usb_pipeout(urb->pipe);
 
 
        is_out = usb_pipeout(urb->pipe);
 
@@ -68,6 +70,22 @@ static void qset_fill_qh(struct whc_qset *qset, struct urb *urb)
                qset->max_burst = 1;
        }
 
                qset->max_burst = 1;
        }
 
+       /*
+        * Initial PHY rate is 53.3 Mbit/s for control endpoints or
+        * the maximum supported by the device for other endpoints
+        * (unless limited by the user).
+        */
+       if (usb_pipecontrol(urb->pipe))
+               phy_rate = UWB_PHY_RATE_53;
+       else {
+               uint16_t phy_rates;
+
+               phy_rates = le16_to_cpu(wusb_dev->wusb_cap_descr->wPHYRates);
+               phy_rate = fls(phy_rates) - 1;
+               if (phy_rate > whc->wusbhc.phy_rate)
+                       phy_rate = whc->wusbhc.phy_rate;
+       }
+
        qset->qh.info1 = cpu_to_le32(
                QH_INFO1_EP(usb_pipeendpoint(urb->pipe))
                | (is_out ? QH_INFO1_DIR_OUT : QH_INFO1_DIR_IN)
        qset->qh.info1 = cpu_to_le32(
                QH_INFO1_EP(usb_pipeendpoint(urb->pipe))
                | (is_out ? QH_INFO1_DIR_OUT : QH_INFO1_DIR_IN)
@@ -87,7 +105,7 @@ static void qset_fill_qh(struct whc_qset *qset, struct urb *urb)
         * strength and can presumably guess the Tx power required
         * from that? */
        qset->qh.info3 = cpu_to_le32(
         * strength and can presumably guess the Tx power required
         * from that? */
        qset->qh.info3 = cpu_to_le32(
-               QH_INFO3_TX_RATE_53_3
+               QH_INFO3_TX_RATE(phy_rate)
                | QH_INFO3_TX_PWR(0) /* 0 == max power */
                );
 
                | QH_INFO3_TX_PWR(0) /* 0 == max power */
                );
 
@@ -149,7 +167,7 @@ struct whc_qset *get_qset(struct whc *whc, struct urb *urb,
 
                qset->ep = urb->ep;
                urb->ep->hcpriv = qset;
 
                qset->ep = urb->ep;
                urb->ep->hcpriv = qset;
-               qset_fill_qh(qset, urb);
+               qset_fill_qh(whc, qset, urb);
        }
        return qset;
 }
        }
        return qset;
 }
index d5e5c3aaccedc4732d38f5a001cd9440942387bf..4d4cbc0730bf032fc32d263b6f46fbb26c2764d7 100644 (file)
@@ -172,14 +172,7 @@ struct whc_qhead {
 #define QH_INFO3_MAX_DELAY(d)    ((d) << 0)  /* maximum stream delay in 125 us units (isoc only) */
 #define QH_INFO3_INTERVAL(i)     ((i) << 16) /* segment interval in 125 us units (isoc only) */
 
 #define QH_INFO3_MAX_DELAY(d)    ((d) << 0)  /* maximum stream delay in 125 us units (isoc only) */
 #define QH_INFO3_INTERVAL(i)     ((i) << 16) /* segment interval in 125 us units (isoc only) */
 
-#define QH_INFO3_TX_RATE_53_3    (0 << 24)
-#define QH_INFO3_TX_RATE_80      (1 << 24)
-#define QH_INFO3_TX_RATE_106_7   (2 << 24)
-#define QH_INFO3_TX_RATE_160     (3 << 24)
-#define QH_INFO3_TX_RATE_200     (4 << 24)
-#define QH_INFO3_TX_RATE_320     (5 << 24)
-#define QH_INFO3_TX_RATE_400     (6 << 24)
-#define QH_INFO3_TX_RATE_480     (7 << 24)
+#define QH_INFO3_TX_RATE(r)      ((r) << 24) /* PHY rate (see [ECMA-368] section 10.3.1.1) */
 #define QH_INFO3_TX_PWR(p)       ((p) << 29) /* transmit power (see [WUSB] section 5.2.1.2) */
 
 #define QH_STATUS_FLOW_CTRL      (1 << 15)
 #define QH_INFO3_TX_PWR(p)       ((p) << 29) /* transmit power (see [WUSB] section 5.2.1.2) */
 
 #define QH_STATUS_FLOW_CTRL      (1 << 15)
index ee6256f236368921a7b0aada69b06ff86c9e5e23..eab86e4bc770ca1dc81fb8a11f7bec1727ddcf82 100644 (file)
@@ -147,10 +147,40 @@ static ssize_t wusb_chid_store(struct device *dev,
 }
 static DEVICE_ATTR(wusb_chid, 0644, wusb_chid_show, wusb_chid_store);
 
 }
 static DEVICE_ATTR(wusb_chid, 0644, wusb_chid_show, wusb_chid_store);
 
+
+static ssize_t wusb_phy_rate_show(struct device *dev,
+                                 struct device_attribute *attr,
+                                 char *buf)
+{
+       struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
+
+       return sprintf(buf, "%d\n", wusbhc->phy_rate);
+}
+
+static ssize_t wusb_phy_rate_store(struct device *dev,
+                                  struct device_attribute *attr,
+                                  const char *buf, size_t size)
+{
+       struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
+       uint8_t phy_rate;
+       ssize_t result;
+
+       result = sscanf(buf, "%hhu", &phy_rate);
+       if (result != 1)
+               return -EINVAL;
+       if (phy_rate >= UWB_PHY_RATE_INVALID)
+               return -EINVAL;
+
+       wusbhc->phy_rate = phy_rate;
+       return size;
+}
+static DEVICE_ATTR(wusb_phy_rate, 0644, wusb_phy_rate_show, wusb_phy_rate_store);
+
 /* Group all the WUSBHC attributes */
 static struct attribute *wusbhc_attrs[] = {
                &dev_attr_wusb_trust_timeout.attr,
                &dev_attr_wusb_chid.attr,
 /* Group all the WUSBHC attributes */
 static struct attribute *wusbhc_attrs[] = {
                &dev_attr_wusb_trust_timeout.attr,
                &dev_attr_wusb_chid.attr,
+               &dev_attr_wusb_phy_rate.attr,
                NULL,
 };
 
                NULL,
 };
 
@@ -177,6 +207,8 @@ int wusbhc_create(struct wusbhc *wusbhc)
        int result = 0;
 
        wusbhc->trust_timeout = WUSB_TRUST_TIMEOUT_MS;
        int result = 0;
 
        wusbhc->trust_timeout = WUSB_TRUST_TIMEOUT_MS;
+       wusbhc->phy_rate = UWB_PHY_RATE_INVALID - 1;
+
        mutex_init(&wusbhc->mutex);
        result = wusbhc_mmcie_create(wusbhc);
        if (result < 0)
        mutex_init(&wusbhc->mutex);
        result = wusbhc_mmcie_create(wusbhc);
        if (result < 0)
index 797c2453a35bf829ec2fef965d5ac42a37cd33af..fd2fd4e277e1914871d530adcea2d08ef3f8abeb 100644 (file)
@@ -253,6 +253,7 @@ struct wusbhc {
 
        unsigned trust_timeout;                 /* in jiffies */
        struct wusb_ckhdid chid;
 
        unsigned trust_timeout;                 /* in jiffies */
        struct wusb_ckhdid chid;
+       uint8_t phy_rate;
        struct wuie_host_info *wuie_host_info;
 
        struct mutex mutex;                     /* locks everything else */
        struct wuie_host_info *wuie_host_info;
 
        struct mutex mutex;                     /* locks everything else */