1 2 3#include <linux/netdevice.h> 4#include <linux/etherdevice.h> 5#include <linux/device.h> 6 7#include "i1480u-wlp.h" 8 9 10/** 11 * 12 * @dev: Class device from the net_device; assumed refcnted. 13 * 14 * Yes, I don't lock--we assume it is refcounted and I am getting a 15 * single byte value that is kind of atomic to read. 16 */ 17ssize_t uwb_phy_rate_show(const struct wlp_options *options, char *buf) 18{ 19 return sprintf(buf, "%u\n", 20 wlp_tx_hdr_phy_rate(&options->def_tx_hdr)); 21} 22EXPORT_SYMBOL_GPL(uwb_phy_rate_show); 23 24 25ssize_t uwb_phy_rate_store(struct wlp_options *options, 26 const char *buf, size_t size) 27{ 28 ssize_t result; 29 unsigned rate; 30 31 result = sscanf(buf, "%u\n", &rate); 32 if (result != 1) { 33 result = -EINVAL; 34 goto out; 35 } 36 result = -EINVAL; 37 if (rate >= UWB_PHY_RATE_INVALID) 38 goto out; 39 wlp_tx_hdr_set_phy_rate(&options->def_tx_hdr, rate); 40 result = 0; 41out: 42 return result < 0 ? result : size; 43} 44EXPORT_SYMBOL_GPL(uwb_phy_rate_store); 45 46 47ssize_t uwb_rts_cts_show(const struct wlp_options *options, char *buf) 48{ 49 return sprintf(buf, "%u\n", 50 wlp_tx_hdr_rts_cts(&options->def_tx_hdr)); 51} 52EXPORT_SYMBOL_GPL(uwb_rts_cts_show); 53 54 55ssize_t uwb_rts_cts_store(struct wlp_options *options, 56 const char *buf, size_t size) 57{ 58 ssize_t result; 59 unsigned value; 60 61 result = sscanf(buf, "%u\n", &value); 62 if (result != 1) { 63 result = -EINVAL; 64 goto out; 65 } 66 result = -EINVAL; 67 wlp_tx_hdr_set_rts_cts(&options->def_tx_hdr, !!value); 68 result = 0; 69out: 70 return result < 0 ? result : size; 71} 72EXPORT_SYMBOL_GPL(uwb_rts_cts_store); 73 74 75ssize_t uwb_ack_policy_show(const struct wlp_options *options, char *buf) 76{ 77 return sprintf(buf, "%u\n", 78 wlp_tx_hdr_ack_policy(&options->def_tx_hdr)); 79} 80EXPORT_SYMBOL_GPL(uwb_ack_policy_show); 81 82 83ssize_t uwb_ack_policy_store(struct wlp_options *options, 84 const char *buf, size_t size) 85{ 86 ssize_t result; 87 unsigned value; 88 89 result = sscanf(buf, "%u\n", &value); 90 if (result != 1 || value > UWB_ACK_B_REQ) { 91 result = -EINVAL; 92 goto out; 93 } 94 wlp_tx_hdr_set_ack_policy(&options->def_tx_hdr, value); 95 result = 0; 96out: 97 return result < 0 ? result : size; 98} 99EXPORT_SYMBOL_GPL(uwb_ack_policy_store); 100 101 102/** 103 * Show the PCA base priority. 104 * 105 * We can access without locking, as the value is (for now) orthogonal 106 * to other values. 107 */ 108ssize_t uwb_pca_base_priority_show(const struct wlp_options *options, 109 char *buf) 110{ 111 return sprintf(buf, "%u\n", 112 options->pca_base_priority); 113} 114EXPORT_SYMBOL_GPL(uwb_pca_base_priority_show); 115 116 117/** 118 * Set the PCA base priority. 119 * 120 * We can access without locking, as the value is (for now) orthogonal 121 * to other values. 122 */ 123ssize_t uwb_pca_base_priority_store(struct wlp_options *options, 124 const char *buf, size_t size) 125{ 126 ssize_t result = -EINVAL; 127 u8 pca_base_priority; 128 129 result = sscanf(buf, "%hhu\n", &pca_base_priority); 130 if (result != 1) { 131 result = -EINVAL; 132 goto out; 133 } 134 result = -EINVAL; 135 if (pca_base_priority >= 8) 136 goto out; 137 options->pca_base_priority = pca_base_priority; 138 /* Update TX header if we are currently using PCA. */ 139 if (result >= 0 && (wlp_tx_hdr_delivery_id_type(&options->def_tx_hdr) & WLP_DRP) == 0) 140 wlp_tx_hdr_set_delivery_id_type(&options->def_tx_hdr, options->pca_base_priority); 141 result = 0; 142out: 143 return result < 0 ? result : size; 144} 145EXPORT_SYMBOL_GPL(uwb_pca_base_priority_store); 146 147/** 148 * Show current inflight values 149 * 150 * Will print the current MAX and THRESHOLD values for the basic flow 151 * control. In addition it will report how many times the TX queue needed 152 * to be restarted since the last time this query was made. 153 */ 154static ssize_t wlp_tx_inflight_show(struct i1480u_tx_inflight *inflight, 155 char *buf) 156{ 157 ssize_t result; 158 unsigned long sec_elapsed = (jiffies - inflight->restart_ts)/HZ; 159 unsigned long restart_count = atomic_read(&inflight->restart_count); 160 161 result = scnprintf(buf, PAGE_SIZE, "%lu %lu %d %lu %lu %lu\n" 162 "#read: threshold max inflight_count restarts " 163 "seconds restarts/sec\n" 164 "#write: threshold max\n", 165 inflight->threshold, inflight->max, 166 atomic_read(&inflight->count), 167 restart_count, sec_elapsed, 168 sec_elapsed == 0 ? 0 : restart_count/sec_elapsed); 169 inflight->restart_ts = jiffies; 170 atomic_set(&inflight->restart_count, 0); 171 return result; 172} 173 174static 175ssize_t wlp_tx_inflight_store(struct i1480u_tx_inflight *inflight, 176 const char *buf, size_t size) 177{ 178 unsigned long in_threshold, in_max; 179 ssize_t result; 180 result = sscanf(buf, "%lu %lu", &in_threshold, &in_max); 181 if (result != 2) 182 return -EINVAL; 183 if (in_max <= in_threshold) 184 return -EINVAL; 185 inflight->max = in_max; 186 inflight->threshold = in_threshold; 187 return size; 188} 189/* 190 * Glue (or function adaptors) for accesing info on sysfs 191 * 192 * [we need this indirection because the PCI driver does almost the 193 * same] 194 * 195 * Linux 2.6.21 changed how 'struct netdevice' does attributes (from 196 * having a 'struct class_dev' to having a 'struct device'). That is 197 * quite of a pain. 198 * 199 * So we try to abstract that here. i1480u_SHOW() and i1480u_STORE() 200 * create adaptors for extracting the 'struct i1480u' from a 'struct 201 * dev' and calling a function for doing a sysfs operation (as we have 202 * them factorized already). i1480u_ATTR creates the attribute file 203 * (CLASS_DEVICE_ATTR or DEVICE_ATTR) and i1480u_ATTR_NAME produces a 204 * class_device_attr_NAME or device_attr_NAME (for group registration). 205 */ 206 207#define i1480u_SHOW(name, fn, param) \ 208static ssize_t i1480u_show_##name(struct device *dev, \ 209 struct device_attribute *attr,\ 210 char *buf) \ 211{ \ 212 struct i1480u *i1480u = netdev_priv(to_net_dev(dev)); \ 213 return fn(&i1480u->param, buf); \ 214} 215 216#define i1480u_STORE(name, fn, param) \ 217static ssize_t i1480u_store_##name(struct device *dev, \ 218 struct device_attribute *attr,\ 219 const char *buf, size_t size)\ 220{ \ 221 struct i1480u *i1480u = netdev_priv(to_net_dev(dev)); \ 222 return fn(&i1480u->param, buf, size); \ 223} 224 225#define i1480u_ATTR(name, perm) static DEVICE_ATTR(name, perm, \ 226 i1480u_show_##name,\ 227 i1480u_store_##name) 228 229#define i1480u_ATTR_SHOW(name) static DEVICE_ATTR(name, \ 230 S_IRUGO, \ 231 i1480u_show_##name, NULL) 232 233#define i1480u_ATTR_NAME(a) (dev_attr_##a) 234 235 236/* 237 * Sysfs adaptors 238 */ 239i1480u_SHOW(uwb_phy_rate, uwb_phy_rate_show, options); 240i1480u_STORE(uwb_phy_rate, uwb_phy_rate_store, options); 241i1480u_ATTR(uwb_phy_rate, S_IRUGO | S_IWUSR); 242 243i1480u_SHOW(uwb_rts_cts, uwb_rts_cts_show, options); 244i1480u_STORE(uwb_rts_cts, uwb_rts_cts_store, options); 245i1480u_ATTR(uwb_rts_cts, S_IRUGO | S_IWUSR); 246 247i1480u_SHOW(uwb_ack_policy, uwb_ack_policy_show, options); 248i1480u_STORE(uwb_ack_policy, uwb_ack_policy_store, options); 249i1480u_ATTR(uwb_ack_policy, S_IRUGO | S_IWUSR); 250 251i1480u_SHOW(uwb_pca_base_priority, uwb_pca_base_priority_show, options); 252i1480u_STORE(uwb_pca_base_priority, uwb_pca_base_priority_store, options); 253i1480u_ATTR(uwb_pca_base_priority, S_IRUGO | S_IWUSR); 254 255i1480u_SHOW(wlp_eda, wlp_eda_show, wlp); 256i1480u_STORE(wlp_eda, wlp_eda_store, wlp); 257i1480u_ATTR(wlp_eda, S_IRUGO | S_IWUSR); 258 259i1480u_SHOW(wlp_uuid, wlp_uuid_show, wlp); 260i1480u_STORE(wlp_uuid, wlp_uuid_store, wlp); 261i1480u_ATTR(wlp_uuid, S_IRUGO | S_IWUSR); 262 263i1480u_SHOW(wlp_dev_name, wlp_dev_name_show, wlp); 264i1480u_STORE(wlp_dev_name, wlp_dev_name_store, wlp); 265i1480u_ATTR(wlp_dev_name, S_IRUGO | S_IWUSR); 266 267i1480u_SHOW(wlp_dev_manufacturer, wlp_dev_manufacturer_show, wlp); 268i1480u_STORE(wlp_dev_manufacturer, wlp_dev_manufacturer_store, wlp); 269i1480u_ATTR(wlp_dev_manufacturer, S_IRUGO | S_IWUSR); 270 271i1480u_SHOW(wlp_dev_model_name, wlp_dev_model_name_show, wlp); 272i1480u_STORE(wlp_dev_model_name, wlp_dev_model_name_store, wlp); 273i1480u_ATTR(wlp_dev_model_name, S_IRUGO | S_IWUSR); 274 275i1480u_SHOW(wlp_dev_model_nr, wlp_dev_model_nr_show, wlp); 276i1480u_STORE(wlp_dev_model_nr, wlp_dev_model_nr_store, wlp); 277i1480u_ATTR(wlp_dev_model_nr, S_IRUGO | S_IWUSR); 278 279i1480u_SHOW(wlp_dev_serial, wlp_dev_serial_show, wlp); 280i1480u_STORE(wlp_dev_serial, wlp_dev_serial_store, wlp); 281i1480u_ATTR(wlp_dev_serial, S_IRUGO | S_IWUSR); 282 283i1480u_SHOW(wlp_dev_prim_category, wlp_dev_prim_category_show, wlp); 284i1480u_STORE(wlp_dev_prim_category, wlp_dev_prim_category_store, wlp); 285i1480u_ATTR(wlp_dev_prim_category, S_IRUGO | S_IWUSR); 286 287i1480u_SHOW(wlp_dev_prim_OUI, wlp_dev_prim_OUI_show, wlp); 288i1480u_STORE(wlp_dev_prim_OUI, wlp_dev_prim_OUI_store, wlp); 289i1480u_ATTR(wlp_dev_prim_OUI, S_IRUGO | S_IWUSR); 290 291i1480u_SHOW(wlp_dev_prim_OUI_sub, wlp_dev_prim_OUI_sub_show, wlp); 292i1480u_STORE(wlp_dev_prim_OUI_sub, wlp_dev_prim_OUI_sub_store, wlp); 293i1480u_ATTR(wlp_dev_prim_OUI_sub, S_IRUGO | S_IWUSR); 294 295i1480u_SHOW(wlp_dev_prim_subcat, wlp_dev_prim_subcat_show, wlp); 296i1480u_STORE(wlp_dev_prim_subcat, wlp_dev_prim_subcat_store, wlp); 297i1480u_ATTR(wlp_dev_prim_subcat, S_IRUGO | S_IWUSR); 298 299i1480u_SHOW(wlp_neighborhood, wlp_neighborhood_show, wlp); 300i1480u_ATTR_SHOW(wlp_neighborhood); 301 302i1480u_SHOW(wss_activate, wlp_wss_activate_show, wlp.wss); 303i1480u_STORE(wss_activate, wlp_wss_activate_store, wlp.wss); 304i1480u_ATTR(wss_activate, S_IRUGO | S_IWUSR); 305 306/* 307 * Show the (min, max, avg) Line Quality Estimate (LQE, in dB) as over 308 * the last 256 received WLP frames (ECMA-368 13.3). 309 * 310 * [the -7dB that have to be substracted from the LQI to make the LQE 311 * are already taken into account]. 312 */ 313i1480u_SHOW(wlp_lqe, stats_show, lqe_stats); 314i1480u_STORE(wlp_lqe, stats_store, lqe_stats); 315i1480u_ATTR(wlp_lqe, S_IRUGO | S_IWUSR); 316 317/* 318 * Show the Receive Signal Strength Indicator averaged over all the 319 * received WLP frames (ECMA-368 13.3). Still is not clear what 320 * this value is, but is kind of a percentage of the signal strength 321 * at the antenna. 322 */ 323i1480u_SHOW(wlp_rssi, stats_show, rssi_stats); 324i1480u_STORE(wlp_rssi, stats_store, rssi_stats); 325i1480u_ATTR(wlp_rssi, S_IRUGO | S_IWUSR); 326 327/** 328 * We maintain a basic flow control counter. "count" how many TX URBs are 329 * outstanding. Only allow "max" 330 * TX URBs to be outstanding. If this value is reached the queue will be 331 * stopped. The queue will be restarted when there are 332 * "threshold" URBs outstanding. 333 */ 334i1480u_SHOW(wlp_tx_inflight, wlp_tx_inflight_show, tx_inflight); 335i1480u_STORE(wlp_tx_inflight, wlp_tx_inflight_store, tx_inflight); 336i1480u_ATTR(wlp_tx_inflight, S_IRUGO | S_IWUSR); 337 338static struct attribute *i1480u_attrs[] = { 339 &i1480u_ATTR_NAME(uwb_phy_rate).attr, 340 &i1480u_ATTR_NAME(uwb_rts_cts).attr, 341 &i1480u_ATTR_NAME(uwb_ack_policy).attr, 342 &i1480u_ATTR_NAME(uwb_pca_base_priority).attr, 343 &i1480u_ATTR_NAME(wlp_lqe).attr, 344 &i1480u_ATTR_NAME(wlp_rssi).attr, 345 &i1480u_ATTR_NAME(wlp_eda).attr, 346 &i1480u_ATTR_NAME(wlp_uuid).attr, 347 &i1480u_ATTR_NAME(wlp_dev_name).attr, 348 &i1480u_ATTR_NAME(wlp_dev_manufacturer).attr, 349 &i1480u_ATTR_NAME(wlp_dev_model_name).attr, 350 &i1480u_ATTR_NAME(wlp_dev_model_nr).attr, 351 &i1480u_ATTR_NAME(wlp_dev_serial).attr, 352 &i1480u_ATTR_NAME(wlp_dev_prim_category).attr, 353 &i1480u_ATTR_NAME(wlp_dev_prim_OUI).attr, 354 &i1480u_ATTR_NAME(wlp_dev_prim_OUI_sub).attr, 355 &i1480u_ATTR_NAME(wlp_dev_prim_subcat).attr, 356 &i1480u_ATTR_NAME(wlp_neighborhood).attr, 357 &i1480u_ATTR_NAME(wss_activate).attr, 358 &i1480u_ATTR_NAME(wlp_tx_inflight).attr, 359 NULL, 360}; 361 362static struct attribute_group i1480u_attr_group = { 363 .name = NULL, /* we want them in the same directory */ 364 .attrs = i1480u_attrs, 365}; 366 367int i1480u_sysfs_setup(struct i1480u *i1480u) 368{ 369 int result; 370 struct device *dev = &i1480u->usb_iface->dev; 371 result = sysfs_create_group(&i1480u->net_dev->dev.kobj, 372 &i1480u_attr_group); 373 if (result < 0) 374 dev_err(dev, "cannot initialize sysfs attributes: %d\n", 375 result); 376 return result; 377} 378 379 380void i1480u_sysfs_release(struct i1480u *i1480u) 381{ 382 sysfs_remove_group(&i1480u->net_dev->dev.kobj, 383 &i1480u_attr_group); 384} 385