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>
This commit is contained in:
parent
d19fc29192
commit
c3f22d92a1
|
@ -23,3 +23,16 @@ Description:
|
||||||
Since this relates to security (specifically, the
|
Since this relates to security (specifically, the
|
||||||
lifetime of PTKs and GTKs) it should not be changed
|
lifetime of PTKs and GTKs) it should not be changed
|
||||||
from the default.
|
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
|
* state
|
||||||
* @urb: an urb for a transfer to this endpoint
|
* @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;
|
struct usb_wireless_ep_comp_descriptor *epcd;
|
||||||
bool is_out;
|
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(
|
qset->qh.info1 = cpu_to_le32(
|
||||||
QH_INFO1_EP(usb_pipeendpoint(urb->pipe))
|
QH_INFO1_EP(usb_pipeendpoint(urb->pipe))
|
||||||
| (is_out ? QH_INFO1_DIR_OUT : QH_INFO1_DIR_IN)
|
| (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
|
* strength and can presumably guess the Tx power required
|
||||||
* from that? */
|
* from that? */
|
||||||
qset->qh.info3 = cpu_to_le32(
|
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;
|
qset->ep = urb->ep;
|
||||||
urb->ep->hcpriv = qset;
|
urb->ep->hcpriv = qset;
|
||||||
qset_fill_qh(qset, urb);
|
qset_fill_qh(whc, qset, urb);
|
||||||
}
|
}
|
||||||
return qset;
|
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_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_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(r) ((r) << 24) /* PHY rate (see [ECMA-368] section 10.3.1.1) */
|
||||||
#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_PWR(p) ((p) << 29) /* transmit power (see [WUSB] section 5.2.1.2) */
|
#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_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 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 */
|
/* Group all the WUSBHC attributes */
|
||||||
static struct attribute *wusbhc_attrs[] = {
|
static struct attribute *wusbhc_attrs[] = {
|
||||||
&dev_attr_wusb_trust_timeout.attr,
|
&dev_attr_wusb_trust_timeout.attr,
|
||||||
&dev_attr_wusb_chid.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;
|
int result = 0;
|
||||||
|
|
||||||
wusbhc->trust_timeout = WUSB_TRUST_TIMEOUT_MS;
|
wusbhc->trust_timeout = WUSB_TRUST_TIMEOUT_MS;
|
||||||
|
wusbhc->phy_rate = UWB_PHY_RATE_INVALID - 1;
|
||||||
|
|
||||||
mutex_init(&wusbhc->mutex);
|
mutex_init(&wusbhc->mutex);
|
||||||
result = wusbhc_mmcie_create(wusbhc);
|
result = wusbhc_mmcie_create(wusbhc);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
|
|
|
@ -253,6 +253,7 @@ struct wusbhc {
|
||||||
|
|
||||||
unsigned trust_timeout; /* in jiffies */
|
unsigned trust_timeout; /* in jiffies */
|
||||||
struct wusb_ckhdid chid;
|
struct wusb_ckhdid chid;
|
||||||
|
uint8_t phy_rate;
|
||||||
struct wuie_host_info *wuie_host_info;
|
struct wuie_host_info *wuie_host_info;
|
||||||
|
|
||||||
struct mutex mutex; /* locks everything else */
|
struct mutex mutex; /* locks everything else */
|
||||||
|
|
Reference in New Issue