Commit c3f22d92 authored by David Vrabel's avatar David Vrabel Committed by Greg Kroah-Hartman

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: default avatarDavid Vrabel <david.vrabel@csr.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent d19fc291
......@@ -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.
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.
......@@ -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
*/
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 wusb_dev *wusb_dev = usb_dev->wusb_dev;
struct usb_wireless_ep_comp_descriptor *epcd;
bool is_out;
uint8_t phy_rate;
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;
}
/*
* 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)
......@@ -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(
QH_INFO3_TX_RATE_53_3
QH_INFO3_TX_RATE(phy_rate)
| 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_fill_qh(qset, urb);
qset_fill_qh(whc, qset, urb);
}
return qset;
}
......
......@@ -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_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)
......
......@@ -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 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,
&dev_attr_wusb_phy_rate.attr,
NULL,
};
......@@ -177,6 +207,8 @@ int wusbhc_create(struct wusbhc *wusbhc)
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)
......
......@@ -253,6 +253,7 @@ struct wusbhc {
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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment