GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / uwb / wlp / sysfs.c
blob5fad6975a9134027f4920d62e90b524c8954e8be
2 #include <linux/wlp.h>
4 #include "wlp-internal.h"
6 static
7 size_t wlp_wss_wssid_e_print(char *buf, size_t bufsize,
8 struct wlp_wssid_e *wssid_e)
10 size_t used = 0;
11 used += scnprintf(buf, bufsize, " WSS: ");
12 used += wlp_wss_uuid_print(buf + used, bufsize - used,
13 &wssid_e->wssid);
15 if (wssid_e->info != NULL) {
16 used += scnprintf(buf + used, bufsize - used, " ");
17 used += uwb_mac_addr_print(buf + used, bufsize - used,
18 &wssid_e->info->bcast);
19 used += scnprintf(buf + used, bufsize - used, " %u %u %s\n",
20 wssid_e->info->accept_enroll,
21 wssid_e->info->sec_status,
22 wssid_e->info->name);
24 return used;
27 /**
28 * Print out information learned from neighbor discovery
30 * Some fields being printed may not be included in the device discovery
31 * information (it is not mandatory). We are thus careful how the
32 * information is printed to ensure it is clear to the user what field is
33 * being referenced.
34 * The information being printed is for one time use - temporary storage is
35 * cleaned after it is printed.
37 * Ideally sysfs output should be on one line. The information printed here
38 * contain a few strings so it will be hard to parse if they are all
39 * printed on the same line - without agreeing on a standard field
40 * separator.
42 static
43 ssize_t wlp_wss_neighborhood_print_remove(struct wlp *wlp, char *buf,
44 size_t bufsize)
46 size_t used = 0;
47 struct wlp_neighbor_e *neighb;
48 struct wlp_wssid_e *wssid_e;
50 mutex_lock(&wlp->nbmutex);
51 used = scnprintf(buf, bufsize, "#Neighbor information\n"
52 "#uuid dev_addr\n"
53 "# Device Name:\n# Model Name:\n# Manufacturer:\n"
54 "# Model Nr:\n# Serial:\n"
55 "# Pri Dev type: CategoryID OUI OUISubdiv "
56 "SubcategoryID\n"
57 "# WSS: WSSID WSS_name accept_enroll sec_status "
58 "bcast\n"
59 "# WSS: WSSID WSS_name accept_enroll sec_status "
60 "bcast\n\n");
61 list_for_each_entry(neighb, &wlp->neighbors, node) {
62 if (bufsize - used <= 0)
63 goto out;
64 used += wlp_wss_uuid_print(buf + used, bufsize - used,
65 &neighb->uuid);
66 buf[used++] = ' ';
67 used += uwb_dev_addr_print(buf + used, bufsize - used,
68 &neighb->uwb_dev->dev_addr);
69 if (neighb->info != NULL)
70 used += scnprintf(buf + used, bufsize - used,
71 "\n Device Name: %s\n"
72 " Model Name: %s\n"
73 " Manufacturer:%s \n"
74 " Model Nr: %s\n"
75 " Serial: %s\n"
76 " Pri Dev type: "
77 "%u %02x:%02x:%02x %u %u\n",
78 neighb->info->name,
79 neighb->info->model_name,
80 neighb->info->manufacturer,
81 neighb->info->model_nr,
82 neighb->info->serial,
83 neighb->info->prim_dev_type.category,
84 neighb->info->prim_dev_type.OUI[0],
85 neighb->info->prim_dev_type.OUI[1],
86 neighb->info->prim_dev_type.OUI[2],
87 neighb->info->prim_dev_type.OUIsubdiv,
88 neighb->info->prim_dev_type.subID);
89 list_for_each_entry(wssid_e, &neighb->wssid, node) {
90 used += wlp_wss_wssid_e_print(buf + used,
91 bufsize - used,
92 wssid_e);
94 buf[used++] = '\n';
95 wlp_remove_neighbor_tmp_info(neighb);
99 out:
100 mutex_unlock(&wlp->nbmutex);
101 return used;
106 * Show properties of all WSS in neighborhood.
108 * Will trigger a complete discovery of WSS activated by this device and
109 * its neighbors.
111 ssize_t wlp_neighborhood_show(struct wlp *wlp, char *buf)
113 wlp_discover(wlp);
114 return wlp_wss_neighborhood_print_remove(wlp, buf, PAGE_SIZE);
116 EXPORT_SYMBOL_GPL(wlp_neighborhood_show);
118 static
119 ssize_t __wlp_wss_properties_show(struct wlp_wss *wss, char *buf,
120 size_t bufsize)
122 ssize_t result;
124 result = wlp_wss_uuid_print(buf, bufsize, &wss->wssid);
125 result += scnprintf(buf + result, bufsize - result, " ");
126 result += uwb_mac_addr_print(buf + result, bufsize - result,
127 &wss->bcast);
128 result += scnprintf(buf + result, bufsize - result,
129 " 0x%02x %u ", wss->hash, wss->secure_status);
130 result += wlp_wss_key_print(buf + result, bufsize - result,
131 wss->master_key);
132 result += scnprintf(buf + result, bufsize - result, " 0x%02x ",
133 wss->tag);
134 result += uwb_mac_addr_print(buf + result, bufsize - result,
135 &wss->virtual_addr);
136 result += scnprintf(buf + result, bufsize - result, " %s", wss->name);
137 result += scnprintf(buf + result, bufsize - result,
138 "\n\n#WSSID\n#WSS broadcast address\n"
139 "#WSS hash\n#WSS secure status\n"
140 "#WSS master key\n#WSS local tag\n"
141 "#WSS local virtual EUI-48\n#WSS name\n");
142 return result;
146 * Show which WSS is activated.
148 ssize_t wlp_wss_activate_show(struct wlp_wss *wss, char *buf)
150 int result = 0;
152 if (mutex_lock_interruptible(&wss->mutex))
153 goto out;
154 if (wss->state >= WLP_WSS_STATE_ACTIVE)
155 result = __wlp_wss_properties_show(wss, buf, PAGE_SIZE);
156 else
157 result = scnprintf(buf, PAGE_SIZE, "No local WSS active.\n");
158 result += scnprintf(buf + result, PAGE_SIZE - result,
159 "\n\n"
160 "# echo WSSID SECURE_STATUS ACCEPT_ENROLLMENT "
161 "NAME #create new WSS\n"
162 "# echo WSSID [DEV ADDR] #enroll in and activate "
163 "existing WSS, can request registrar\n"
164 "#\n"
165 "# WSSID is a 16 byte hex array. Eg. 12 A3 3B ... \n"
166 "# SECURE_STATUS 0 - unsecure, 1 - secure (default)\n"
167 "# ACCEPT_ENROLLMENT 0 - no, 1 - yes (default)\n"
168 "# NAME is the text string identifying the WSS\n"
169 "# DEV ADDR is the device address of neighbor "
170 "that should be registrar. Eg. 32:AB\n");
172 mutex_unlock(&wss->mutex);
173 out:
174 return result;
177 EXPORT_SYMBOL_GPL(wlp_wss_activate_show);
180 * Create/activate a new WSS or enroll/activate in neighboring WSS
182 * The user can provide the WSSID of a WSS in which it wants to enroll.
183 * Only the WSSID is necessary if the WSS have been discovered before. If
184 * the WSS has not been discovered before, or the user wants to use a
185 * particular neighbor as its registrar, then the user can also provide a
186 * device address or the neighbor that will be used as registrar.
188 * A new WSS is created when the user provides a WSSID, secure status, and
189 * WSS name.
191 ssize_t wlp_wss_activate_store(struct wlp_wss *wss,
192 const char *buf, size_t size)
194 ssize_t result = -EINVAL;
195 struct wlp_uuid wssid;
196 struct uwb_dev_addr dev;
197 struct uwb_dev_addr bcast = {.data = {0xff, 0xff} };
198 char name[65];
199 unsigned sec_status, accept;
200 memset(name, 0, sizeof(name));
201 result = sscanf(buf, "%02hhx %02hhx %02hhx %02hhx "
202 "%02hhx %02hhx %02hhx %02hhx "
203 "%02hhx %02hhx %02hhx %02hhx "
204 "%02hhx %02hhx %02hhx %02hhx "
205 "%02hhx:%02hhx",
206 &wssid.data[0] , &wssid.data[1],
207 &wssid.data[2] , &wssid.data[3],
208 &wssid.data[4] , &wssid.data[5],
209 &wssid.data[6] , &wssid.data[7],
210 &wssid.data[8] , &wssid.data[9],
211 &wssid.data[10], &wssid.data[11],
212 &wssid.data[12], &wssid.data[13],
213 &wssid.data[14], &wssid.data[15],
214 &dev.data[1], &dev.data[0]);
215 if (result == 16 || result == 17) {
216 result = sscanf(buf, "%02hhx %02hhx %02hhx %02hhx "
217 "%02hhx %02hhx %02hhx %02hhx "
218 "%02hhx %02hhx %02hhx %02hhx "
219 "%02hhx %02hhx %02hhx %02hhx "
220 "%u %u %64c",
221 &wssid.data[0] , &wssid.data[1],
222 &wssid.data[2] , &wssid.data[3],
223 &wssid.data[4] , &wssid.data[5],
224 &wssid.data[6] , &wssid.data[7],
225 &wssid.data[8] , &wssid.data[9],
226 &wssid.data[10], &wssid.data[11],
227 &wssid.data[12], &wssid.data[13],
228 &wssid.data[14], &wssid.data[15],
229 &sec_status, &accept, name);
230 if (result == 16)
231 result = wlp_wss_enroll_activate(wss, &wssid, &bcast);
232 else if (result == 19) {
233 sec_status = sec_status == 0 ? 0 : 1;
234 accept = accept == 0 ? 0 : 1;
235 /* We read name using %c, so the newline needs to be
236 * removed */
237 if (strlen(name) != sizeof(name) - 1)
238 name[strlen(name) - 1] = '\0';
239 result = wlp_wss_create_activate(wss, &wssid, name,
240 sec_status, accept);
241 } else
242 result = -EINVAL;
243 } else if (result == 18)
244 result = wlp_wss_enroll_activate(wss, &wssid, &dev);
245 else
246 result = -EINVAL;
247 return result < 0 ? result : size;
249 EXPORT_SYMBOL_GPL(wlp_wss_activate_store);
252 * Show the UUID of this host
254 ssize_t wlp_uuid_show(struct wlp *wlp, char *buf)
256 ssize_t result = 0;
258 mutex_lock(&wlp->mutex);
259 result = wlp_wss_uuid_print(buf, PAGE_SIZE, &wlp->uuid);
260 buf[result++] = '\n';
261 mutex_unlock(&wlp->mutex);
262 return result;
264 EXPORT_SYMBOL_GPL(wlp_uuid_show);
267 * Store a new UUID for this host
269 * According to the spec this should be encoded as an octet string in the
270 * order the octets are shown in string representation in RFC 4122 (WLP
271 * 0.99 [Table 6])
273 * We do not check value provided by user.
275 ssize_t wlp_uuid_store(struct wlp *wlp, const char *buf, size_t size)
277 ssize_t result;
278 struct wlp_uuid uuid;
280 mutex_lock(&wlp->mutex);
281 result = sscanf(buf, "%02hhx %02hhx %02hhx %02hhx "
282 "%02hhx %02hhx %02hhx %02hhx "
283 "%02hhx %02hhx %02hhx %02hhx "
284 "%02hhx %02hhx %02hhx %02hhx ",
285 &uuid.data[0] , &uuid.data[1],
286 &uuid.data[2] , &uuid.data[3],
287 &uuid.data[4] , &uuid.data[5],
288 &uuid.data[6] , &uuid.data[7],
289 &uuid.data[8] , &uuid.data[9],
290 &uuid.data[10], &uuid.data[11],
291 &uuid.data[12], &uuid.data[13],
292 &uuid.data[14], &uuid.data[15]);
293 if (result != 16) {
294 result = -EINVAL;
295 goto error;
297 wlp->uuid = uuid;
298 error:
299 mutex_unlock(&wlp->mutex);
300 return result < 0 ? result : size;
302 EXPORT_SYMBOL_GPL(wlp_uuid_store);
305 * Show contents of members of device information structure
307 #define wlp_dev_info_show(type) \
308 ssize_t wlp_dev_##type##_show(struct wlp *wlp, char *buf) \
310 ssize_t result = 0; \
311 mutex_lock(&wlp->mutex); \
312 if (wlp->dev_info == NULL) { \
313 result = __wlp_setup_device_info(wlp); \
314 if (result < 0) \
315 goto out; \
317 result = scnprintf(buf, PAGE_SIZE, "%s\n", wlp->dev_info->type);\
318 out: \
319 mutex_unlock(&wlp->mutex); \
320 return result; \
322 EXPORT_SYMBOL_GPL(wlp_dev_##type##_show);
324 wlp_dev_info_show(name)
325 wlp_dev_info_show(model_name)
326 wlp_dev_info_show(model_nr)
327 wlp_dev_info_show(manufacturer)
328 wlp_dev_info_show(serial)
331 * Store contents of members of device information structure
333 #define wlp_dev_info_store(type, len) \
334 ssize_t wlp_dev_##type##_store(struct wlp *wlp, const char *buf, size_t size)\
336 ssize_t result; \
337 char format[10]; \
338 mutex_lock(&wlp->mutex); \
339 if (wlp->dev_info == NULL) { \
340 result = __wlp_alloc_device_info(wlp); \
341 if (result < 0) \
342 goto out; \
344 memset(wlp->dev_info->type, 0, sizeof(wlp->dev_info->type)); \
345 sprintf(format, "%%%uc", len); \
346 result = sscanf(buf, format, wlp->dev_info->type); \
347 out: \
348 mutex_unlock(&wlp->mutex); \
349 return result < 0 ? result : size; \
351 EXPORT_SYMBOL_GPL(wlp_dev_##type##_store);
353 wlp_dev_info_store(name, 32)
354 wlp_dev_info_store(manufacturer, 64)
355 wlp_dev_info_store(model_name, 32)
356 wlp_dev_info_store(model_nr, 32)
357 wlp_dev_info_store(serial, 32)
359 static
360 const char *__wlp_dev_category[] = {
361 [WLP_DEV_CAT_COMPUTER] = "Computer",
362 [WLP_DEV_CAT_INPUT] = "Input device",
363 [WLP_DEV_CAT_PRINT_SCAN_FAX_COPIER] = "Printer, scanner, FAX, or "
364 "Copier",
365 [WLP_DEV_CAT_CAMERA] = "Camera",
366 [WLP_DEV_CAT_STORAGE] = "Storage Network",
367 [WLP_DEV_CAT_INFRASTRUCTURE] = "Infrastructure",
368 [WLP_DEV_CAT_DISPLAY] = "Display",
369 [WLP_DEV_CAT_MULTIM] = "Multimedia device",
370 [WLP_DEV_CAT_GAMING] = "Gaming device",
371 [WLP_DEV_CAT_TELEPHONE] = "Telephone",
372 [WLP_DEV_CAT_OTHER] = "Other",
375 static
376 const char *wlp_dev_category_str(unsigned cat)
378 if ((cat >= WLP_DEV_CAT_COMPUTER && cat <= WLP_DEV_CAT_TELEPHONE)
379 || cat == WLP_DEV_CAT_OTHER)
380 return __wlp_dev_category[cat];
381 return "unknown category";
384 ssize_t wlp_dev_prim_category_show(struct wlp *wlp, char *buf)
386 ssize_t result = 0;
387 mutex_lock(&wlp->mutex);
388 if (wlp->dev_info == NULL) {
389 result = __wlp_setup_device_info(wlp);
390 if (result < 0)
391 goto out;
393 result = scnprintf(buf, PAGE_SIZE, "%s\n",
394 wlp_dev_category_str(wlp->dev_info->prim_dev_type.category));
395 out:
396 mutex_unlock(&wlp->mutex);
397 return result;
399 EXPORT_SYMBOL_GPL(wlp_dev_prim_category_show);
401 ssize_t wlp_dev_prim_category_store(struct wlp *wlp, const char *buf,
402 size_t size)
404 ssize_t result;
405 u16 cat;
406 mutex_lock(&wlp->mutex);
407 if (wlp->dev_info == NULL) {
408 result = __wlp_alloc_device_info(wlp);
409 if (result < 0)
410 goto out;
412 result = sscanf(buf, "%hu", &cat);
413 if ((cat >= WLP_DEV_CAT_COMPUTER && cat <= WLP_DEV_CAT_TELEPHONE)
414 || cat == WLP_DEV_CAT_OTHER)
415 wlp->dev_info->prim_dev_type.category = cat;
416 else
417 result = -EINVAL;
418 out:
419 mutex_unlock(&wlp->mutex);
420 return result < 0 ? result : size;
422 EXPORT_SYMBOL_GPL(wlp_dev_prim_category_store);
424 ssize_t wlp_dev_prim_OUI_show(struct wlp *wlp, char *buf)
426 ssize_t result = 0;
427 mutex_lock(&wlp->mutex);
428 if (wlp->dev_info == NULL) {
429 result = __wlp_setup_device_info(wlp);
430 if (result < 0)
431 goto out;
433 result = scnprintf(buf, PAGE_SIZE, "%02x:%02x:%02x\n",
434 wlp->dev_info->prim_dev_type.OUI[0],
435 wlp->dev_info->prim_dev_type.OUI[1],
436 wlp->dev_info->prim_dev_type.OUI[2]);
437 out:
438 mutex_unlock(&wlp->mutex);
439 return result;
441 EXPORT_SYMBOL_GPL(wlp_dev_prim_OUI_show);
443 ssize_t wlp_dev_prim_OUI_store(struct wlp *wlp, const char *buf, size_t size)
445 ssize_t result;
446 u8 OUI[3];
447 mutex_lock(&wlp->mutex);
448 if (wlp->dev_info == NULL) {
449 result = __wlp_alloc_device_info(wlp);
450 if (result < 0)
451 goto out;
453 result = sscanf(buf, "%hhx:%hhx:%hhx",
454 &OUI[0], &OUI[1], &OUI[2]);
455 if (result != 3) {
456 result = -EINVAL;
457 goto out;
458 } else
459 memcpy(wlp->dev_info->prim_dev_type.OUI, OUI, sizeof(OUI));
460 out:
461 mutex_unlock(&wlp->mutex);
462 return result < 0 ? result : size;
464 EXPORT_SYMBOL_GPL(wlp_dev_prim_OUI_store);
467 ssize_t wlp_dev_prim_OUI_sub_show(struct wlp *wlp, char *buf)
469 ssize_t result = 0;
470 mutex_lock(&wlp->mutex);
471 if (wlp->dev_info == NULL) {
472 result = __wlp_setup_device_info(wlp);
473 if (result < 0)
474 goto out;
476 result = scnprintf(buf, PAGE_SIZE, "%u\n",
477 wlp->dev_info->prim_dev_type.OUIsubdiv);
478 out:
479 mutex_unlock(&wlp->mutex);
480 return result;
482 EXPORT_SYMBOL_GPL(wlp_dev_prim_OUI_sub_show);
484 ssize_t wlp_dev_prim_OUI_sub_store(struct wlp *wlp, const char *buf,
485 size_t size)
487 ssize_t result;
488 unsigned sub;
489 u8 max_sub = ~0;
490 mutex_lock(&wlp->mutex);
491 if (wlp->dev_info == NULL) {
492 result = __wlp_alloc_device_info(wlp);
493 if (result < 0)
494 goto out;
496 result = sscanf(buf, "%u", &sub);
497 if (sub <= max_sub)
498 wlp->dev_info->prim_dev_type.OUIsubdiv = sub;
499 else
500 result = -EINVAL;
501 out:
502 mutex_unlock(&wlp->mutex);
503 return result < 0 ? result : size;
505 EXPORT_SYMBOL_GPL(wlp_dev_prim_OUI_sub_store);
507 ssize_t wlp_dev_prim_subcat_show(struct wlp *wlp, char *buf)
509 ssize_t result = 0;
510 mutex_lock(&wlp->mutex);
511 if (wlp->dev_info == NULL) {
512 result = __wlp_setup_device_info(wlp);
513 if (result < 0)
514 goto out;
516 result = scnprintf(buf, PAGE_SIZE, "%u\n",
517 wlp->dev_info->prim_dev_type.subID);
518 out:
519 mutex_unlock(&wlp->mutex);
520 return result;
522 EXPORT_SYMBOL_GPL(wlp_dev_prim_subcat_show);
524 ssize_t wlp_dev_prim_subcat_store(struct wlp *wlp, const char *buf,
525 size_t size)
527 ssize_t result;
528 unsigned sub;
529 __le16 max_sub = ~0;
530 mutex_lock(&wlp->mutex);
531 if (wlp->dev_info == NULL) {
532 result = __wlp_alloc_device_info(wlp);
533 if (result < 0)
534 goto out;
536 result = sscanf(buf, "%u", &sub);
537 if (sub <= max_sub)
538 wlp->dev_info->prim_dev_type.subID = sub;
539 else
540 result = -EINVAL;
541 out:
542 mutex_unlock(&wlp->mutex);
543 return result < 0 ? result : size;
545 EXPORT_SYMBOL_GPL(wlp_dev_prim_subcat_store);
548 * Subsystem implementation for interaction with individual WSS via sysfs
550 * Followed instructions for subsystem in Documentation/filesystems/sysfs.txt
553 #define kobj_to_wlp_wss(obj) container_of(obj, struct wlp_wss, kobj)
554 #define attr_to_wlp_wss_attr(_attr) \
555 container_of(_attr, struct wlp_wss_attribute, attr)
558 * Sysfs subsystem: forward read calls
560 * Sysfs operation for forwarding read call to the show method of the
561 * attribute owner
563 static
564 ssize_t wlp_wss_attr_show(struct kobject *kobj, struct attribute *attr,
565 char *buf)
567 struct wlp_wss_attribute *wss_attr = attr_to_wlp_wss_attr(attr);
568 struct wlp_wss *wss = kobj_to_wlp_wss(kobj);
569 ssize_t ret = -EIO;
571 if (wss_attr->show)
572 ret = wss_attr->show(wss, buf);
573 return ret;
576 * Sysfs subsystem: forward write calls
578 * Sysfs operation for forwarding write call to the store method of the
579 * attribute owner
581 static
582 ssize_t wlp_wss_attr_store(struct kobject *kobj, struct attribute *attr,
583 const char *buf, size_t count)
585 struct wlp_wss_attribute *wss_attr = attr_to_wlp_wss_attr(attr);
586 struct wlp_wss *wss = kobj_to_wlp_wss(kobj);
587 ssize_t ret = -EIO;
589 if (wss_attr->store)
590 ret = wss_attr->store(wss, buf, count);
591 return ret;
594 static const struct sysfs_ops wss_sysfs_ops = {
595 .show = wlp_wss_attr_show,
596 .store = wlp_wss_attr_store,
599 struct kobj_type wss_ktype = {
600 .release = wlp_wss_release,
601 .sysfs_ops = &wss_sysfs_ops,
606 * Sysfs files for individual WSS
610 * Print static properties of this WSS
612 * The name of a WSS may not be null teminated. It's max size is 64 bytes
613 * so we copy it to a larger array just to make sure we print sane data.
615 static ssize_t wlp_wss_properties_show(struct wlp_wss *wss, char *buf)
617 int result = 0;
619 if (mutex_lock_interruptible(&wss->mutex))
620 goto out;
621 result = __wlp_wss_properties_show(wss, buf, PAGE_SIZE);
622 mutex_unlock(&wss->mutex);
623 out:
624 return result;
626 WSS_ATTR(properties, S_IRUGO, wlp_wss_properties_show, NULL);
629 * Print all connected members of this WSS
630 * The EDA cache contains all members of WSS neighborhood.
632 static ssize_t wlp_wss_members_show(struct wlp_wss *wss, char *buf)
634 struct wlp *wlp = container_of(wss, struct wlp, wss);
635 return wlp_eda_show(wlp, buf);
637 WSS_ATTR(members, S_IRUGO, wlp_wss_members_show, NULL);
639 static
640 const char *__wlp_strstate[] = {
641 "none",
642 "partially enrolled",
643 "enrolled",
644 "active",
645 "connected",
648 static const char *wlp_wss_strstate(unsigned state)
650 if (state >= ARRAY_SIZE(__wlp_strstate))
651 return "unknown state";
652 return __wlp_strstate[state];
656 * Print current state of this WSS
658 static ssize_t wlp_wss_state_show(struct wlp_wss *wss, char *buf)
660 int result = 0;
662 if (mutex_lock_interruptible(&wss->mutex))
663 goto out;
664 result = scnprintf(buf, PAGE_SIZE, "%s\n",
665 wlp_wss_strstate(wss->state));
666 mutex_unlock(&wss->mutex);
667 out:
668 return result;
670 WSS_ATTR(state, S_IRUGO, wlp_wss_state_show, NULL);
673 static
674 struct attribute *wss_attrs[] = {
675 &wss_attr_properties.attr,
676 &wss_attr_members.attr,
677 &wss_attr_state.attr,
678 NULL,
681 struct attribute_group wss_attr_group = {
682 .name = NULL, /* we want them in the same directory */
683 .attrs = wss_attrs,