Return-path: Received: from styx.suse.cz ([82.119.242.94]:48998 "EHLO silver.suse.cz" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S934311AbXCWUni (ORCPT ); Fri, 23 Mar 2007 16:43:38 -0400 From: Jiri Benc To: "John W. Linville" In-Reply-To: <20070323214400.642621638.midnight@suse.cz> Cc: linux-wireless@vger.kernel.org Subject: [PATCH 11/19] mac80211: move per-netdev and key stuff to debugfs Message-Id: <20070323204453.F419648580@silver.suse.cz> Date: Fri, 23 Mar 2007 21:44:53 +0100 (CET) Sender: linux-wireless-owner@vger.kernel.org List-ID: From: johannes@sipsolutions.net This patch moves the remaining sysfs stuff from mac80211 into debugfs. Signed-off-by: Johannes Berg Signed-off-by: Jiri Benc --- net/mac80211/Makefile | 4 net/mac80211/debugfs.c | 3 net/mac80211/debugfs_key.c | 253 +++++++++++++++++++++++ net/mac80211/debugfs_key.h | 34 +++ net/mac80211/debugfs_netdev.c | 440 ++++++++++++++++++++++++++++++++++++++++ net/mac80211/debugfs_netdev.h | 30 +++ net/mac80211/ieee80211.c | 49 ++-- net/mac80211/ieee80211_i.h | 65 ++++++ net/mac80211/ieee80211_iface.c | 25 +- net/mac80211/ieee80211_ioctl.c | 31 +-- net/mac80211/ieee80211_key.h | 21 ++ net/mac80211/ieee80211_sysfs.c | 344 ------------------------------- net/mac80211/ieee80211_sysfs.h | 10 - net/mac80211/key_sysfs.c | 217 -------------------- net/mac80211/key_sysfs.h | 12 - net/mac80211/sta_info.c | 6 - 16 files changed, 891 insertions(+), 653 deletions(-) create mode 100644 net/mac80211/debugfs_key.c create mode 100644 net/mac80211/debugfs_key.h create mode 100644 net/mac80211/debugfs_netdev.c create mode 100644 net/mac80211/debugfs_netdev.h delete mode 100644 net/mac80211/ieee80211_sysfs.c delete mode 100644 net/mac80211/ieee80211_sysfs.h delete mode 100644 net/mac80211/key_sysfs.c delete mode 100644 net/mac80211/key_sysfs.h a31d8e7a6e4789185ad35851a1f554b7ed29c439 diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 8c00960..15eff76 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile @@ -1,7 +1,7 @@ obj-$(CONFIG_MAC80211) += mac80211.o rc80211_simple.o mac80211-objs-$(CONFIG_MAC80211_LEDS) += ieee80211_led.o -mac80211-objs-$(CONFIG_DEBUG_FS) += debugfs.o debugfs_sta.o +mac80211-objs-$(CONFIG_DEBUG_FS) += debugfs.o debugfs_sta.o debugfs_netdev.o debugfs_key.o mac80211-objs := \ ieee80211.o \ @@ -13,13 +13,11 @@ mac80211-objs := \ ieee80211_sta.o \ ieee80211_iface.o \ ieee80211_rate.o \ - ieee80211_sysfs.o \ michael.o \ tkip.o \ aes_ccm.o \ wme.o \ ieee80211_cfg.o \ - key_sysfs.o \ $(mac80211-objs-y) ifeq ($(CONFIG_NET_SCHED),) diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index d78c8a6..419da6a 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -303,6 +303,7 @@ void debugfs_hw_add(struct ieee80211_loc return; local->debugfs.stations = debugfs_create_dir("stations", phyd); + local->debugfs.keys = debugfs_create_dir("keys", phyd); DEBUGFS_ADD(channel); DEBUGFS_ADD(frequency); @@ -430,4 +431,6 @@ #endif local->debugfs.statistics = NULL; debugfs_remove(local->debugfs.stations); local->debugfs.stations = NULL; + debugfs_remove(local->debugfs.keys); + local->debugfs.keys = NULL; } diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c new file mode 100644 index 0000000..e90d2cf --- /dev/null +++ b/net/mac80211/debugfs_key.c @@ -0,0 +1,253 @@ +/* + * Copyright 2003-2005 Devicescape Software, Inc. + * Copyright (c) 2006 Jiri Benc + * Copyright 2007 Johannes Berg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include "ieee80211_i.h" +#include "ieee80211_key.h" +#include "debugfs.h" +#include "debugfs_key.h" + +#define KEY_READ(name, buflen, format_string) \ +static ssize_t key_##name##_read(struct file *file, \ + char __user *userbuf, \ + size_t count, loff_t *ppos) \ +{ \ + char buf[buflen]; \ + struct ieee80211_key *key = file->private_data; \ + int res = scnprintf(buf, buflen, format_string, key->name); \ + return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ +} +#define KEY_READ_D(name) KEY_READ(name, 20, "%d\n") + +#define KEY_OPS(name) \ +static const struct file_operations key_ ##name## _ops = { \ + .read = key_##name##_read, \ + .open = mac80211_open_file_generic, \ +} + +#define KEY_FILE(name, format) \ + KEY_READ_##format(name) \ + KEY_OPS(name) + +KEY_FILE(keylen, D); +KEY_FILE(force_sw_encrypt, D); +KEY_FILE(keyidx, D); +KEY_FILE(hw_key_idx, D); +KEY_FILE(tx_rx_count, D); + +static ssize_t key_algorithm_read(struct file *file, + char __user *userbuf, + size_t count, loff_t *ppos) +{ + char *alg; + struct ieee80211_key *key = file->private_data; + + switch (key->alg) { + case ALG_WEP: + alg = "WEP\n"; + break; + case ALG_TKIP: + alg = "TKIP\n"; + break; + case ALG_CCMP: + alg = "CCMP\n"; + break; + default: + return 0; + } + return simple_read_from_buffer(userbuf, count, ppos, alg, strlen(alg)); +} +KEY_OPS(algorithm); + +static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + const u8 *tpn; + char buf[20]; + int len; + struct ieee80211_key *key = file->private_data; + + switch (key->alg) { + case ALG_WEP: + len = scnprintf(buf, sizeof(buf), "\n"); + case ALG_TKIP: + len = scnprintf(buf, sizeof(buf), "%08x %04x\n", + key->u.tkip.iv32, + key->u.tkip.iv16); + case ALG_CCMP: + tpn = key->u.ccmp.tx_pn; + len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", + tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]); + default: + return 0; + } + return simple_read_from_buffer(userbuf, count, ppos, buf, len); +} +KEY_OPS(tx_spec); + +static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct ieee80211_key *key = file->private_data; + char buf[14*NUM_RX_DATA_QUEUES+1], *p = buf; + int i, len; + const u8 *rpn; + + switch (key->alg) { + case ALG_WEP: + len = scnprintf(buf, sizeof(buf), "\n"); + case ALG_TKIP: + for (i = 0; i < NUM_RX_DATA_QUEUES; i++) + p += scnprintf(p, sizeof(buf)+buf-p, + "%08x %04x\n", + key->u.tkip.iv32_rx[i], + key->u.tkip.iv16_rx[i]); + len = p - buf; + case ALG_CCMP: + for (i = 0; i < NUM_RX_DATA_QUEUES; i++) { + rpn = key->u.ccmp.rx_pn[i]; + p += scnprintf(p, sizeof(buf)+buf-p, + "%02x%02x%02x%02x%02x%02x\n", + rpn[0], rpn[1], rpn[2], + rpn[3], rpn[4], rpn[5]); + } + len = p - buf; + default: + return 0; + } + return simple_read_from_buffer(userbuf, count, ppos, buf, len); +} +KEY_OPS(rx_spec); + +static ssize_t key_replays_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct ieee80211_key *key = file->private_data; + char buf[20]; + int len; + + if (key->alg != ALG_CCMP) + return 0; + len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays); + return simple_read_from_buffer(userbuf, count, ppos, buf, len); +} +KEY_OPS(replays); + +static ssize_t key_key_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct ieee80211_key *key = file->private_data; + int i, res, bufsize = 2*key->keylen+2; + char *buf = kmalloc(bufsize, GFP_KERNEL); + char *p = buf; + + for (i = 0; i < key->keylen; i++) + p += scnprintf(p, bufsize+buf-p, "%02x", key->key[i]); + p += scnprintf(p, bufsize+buf-p, "\n"); + res = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); + kfree(buf); + return res; +} +KEY_OPS(key); + +#define DEBUGFS_ADD(name) \ + key->debugfs.name = debugfs_create_file(#name, 0400,\ + key->debugfs.dir, key, &key_##name##_ops); + +void ieee80211_debugfs_key_add(struct ieee80211_local *local, + struct ieee80211_key *key) +{ + char buf[20]; + + if (!local->debugfs.keys) + return; + + sprintf(buf, "%d", key->keyidx); + key->debugfs.dir = debugfs_create_dir(buf, + local->debugfs.keys); + + if (!key->debugfs.dir) + return; + + DEBUGFS_ADD(keylen); + DEBUGFS_ADD(force_sw_encrypt); + DEBUGFS_ADD(keyidx); + DEBUGFS_ADD(hw_key_idx); + DEBUGFS_ADD(tx_rx_count); + DEBUGFS_ADD(algorithm); + DEBUGFS_ADD(tx_spec); + DEBUGFS_ADD(rx_spec); + DEBUGFS_ADD(replays); + DEBUGFS_ADD(key); +}; + +#define DEBUGFS_DEL(name) \ + debugfs_remove(key->debugfs.name); key->debugfs.name = NULL; + +void ieee80211_debugfs_key_remove(struct ieee80211_key *key) +{ + if (!key) + return; + + DEBUGFS_DEL(keylen); + DEBUGFS_DEL(force_sw_encrypt); + DEBUGFS_DEL(keyidx); + DEBUGFS_DEL(hw_key_idx); + DEBUGFS_DEL(tx_rx_count); + DEBUGFS_DEL(algorithm); + DEBUGFS_DEL(tx_spec); + DEBUGFS_DEL(rx_spec); + DEBUGFS_DEL(replays); + DEBUGFS_DEL(key); + + debugfs_remove(key->debugfs.stalink); + key->debugfs.stalink = NULL; + debugfs_remove(key->debugfs.dir); + key->debugfs.dir = NULL; +} +void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata) +{ + char buf[50]; + + if (!sdata->debugfsdir) + return; + + sprintf(buf, "../keys/%d", sdata->default_key->keyidx); + sdata->debugfs.default_key = + debugfs_create_symlink("default_key", sdata->debugfsdir, buf); +} +void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata) +{ + if (!sdata) + return; + + debugfs_remove(sdata->debugfs.default_key); + sdata->debugfs.default_key = NULL; +} +void ieee80211_debugfs_key_sta_link(struct ieee80211_key *key, + struct sta_info *sta) +{ + char buf[50]; + + if (!key->debugfs.dir) + return; + + sprintf(buf, "../sta/" MAC_FMT, MAC_ARG(sta->addr)); + key->debugfs.stalink = + debugfs_create_symlink("station", key->debugfs.dir, buf); +} + +void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key, + struct sta_info *sta) +{ + debugfs_remove(key->debugfs.stalink); + key->debugfs.stalink = NULL; +} diff --git a/net/mac80211/debugfs_key.h b/net/mac80211/debugfs_key.h new file mode 100644 index 0000000..5de3546 --- /dev/null +++ b/net/mac80211/debugfs_key.h @@ -0,0 +1,34 @@ +#ifndef __MAC80211_DEBUGFS_KEY_H +#define __MAC80211_DEBUGFS_KEY_H + +#ifdef CONFIG_DEBUG_FS +void ieee80211_debugfs_key_add(struct ieee80211_local *local, + struct ieee80211_key *key); +void ieee80211_debugfs_key_remove(struct ieee80211_key *key); +void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata); +void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata); +void ieee80211_debugfs_key_sta_link(struct ieee80211_key *key, + struct sta_info *sta); +void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key, + struct sta_info *sta); +#else +static inline void ieee80211_debugfs_key_add(struct ieee80211_local *local, + struct ieee80211_key *key) +{} +static inline void ieee80211_debugfs_key_remove(struct ieee80211_key *key) +{} +static inline void ieee80211_debugfs_key_add_default( + struct ieee80211_sub_if_data *sdata) +{} +static inline void ieee80211_debugfs_key_remove_default( + struct ieee80211_sub_if_data *sdata) +{} +static inline void ieee80211_debugfs_key_sta_link( + struct ieee80211_key *key, struct sta_info *sta) +{} +static inline void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key, + struct sta_info *sta) +{} +#endif + +#endif /* __MAC80211_DEBUGFS_KEY_H */ diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c new file mode 100644 index 0000000..7b713fb --- /dev/null +++ b/net/mac80211/debugfs_netdev.c @@ -0,0 +1,440 @@ +/* + * Copyright (c) 2006 Jiri Benc + * Copyright 2007 Johannes Berg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ieee80211_i.h" +#include "ieee80211_rate.h" +#include "debugfs.h" +#include "debugfs_netdev.h" + +static ssize_t ieee80211_if_read( + struct ieee80211_sub_if_data *sdata, + char __user *userbuf, + size_t count, loff_t *ppos, + ssize_t (*format)(const struct ieee80211_sub_if_data *, char *, int)) +{ + char buf[70]; + ssize_t ret = -EINVAL; + + read_lock(&dev_base_lock); + if (sdata->dev->reg_state == NETREG_REGISTERED) { + ret = (*format)(sdata, buf, sizeof(buf)); + ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret); + } + read_unlock(&dev_base_lock); + return ret; +} + +#define IEEE80211_IF_FMT(name, field, format_string) \ +static ssize_t ieee80211_if_fmt_##name( \ + const struct ieee80211_sub_if_data *sdata, char *buf, \ + int buflen) \ +{ \ + return scnprintf(buf, buflen, format_string, sdata->field); \ +} +#define IEEE80211_IF_FMT_DEC(name, field) \ + IEEE80211_IF_FMT(name, field, "%d\n") +#define IEEE80211_IF_FMT_HEX(name, field) \ + IEEE80211_IF_FMT(name, field, "%#x\n") +#define IEEE80211_IF_FMT_SIZE(name, field) \ + IEEE80211_IF_FMT(name, field, "%zd\n") + +#define IEEE80211_IF_FMT_ATOMIC(name, field) \ +static ssize_t ieee80211_if_fmt_##name( \ + const struct ieee80211_sub_if_data *sdata, \ + char *buf, int buflen) \ +{ \ + return scnprintf(buf, buflen, "%d\n", atomic_read(&sdata->field));\ +} + +#define IEEE80211_IF_FMT_MAC(name, field) \ +static ssize_t ieee80211_if_fmt_##name( \ + const struct ieee80211_sub_if_data *sdata, char *buf, \ + int buflen) \ +{ \ + return scnprintf(buf, buflen, MAC_FMT "\n", MAC_ARG(sdata->field));\ +} + +#define __IEEE80211_IF_FILE(name) \ +static ssize_t ieee80211_if_read_##name(struct file *file, \ + char __user *userbuf, \ + size_t count, loff_t *ppos) \ +{ \ + return ieee80211_if_read(file->private_data, \ + userbuf, count, ppos, \ + ieee80211_if_fmt_##name); \ +} \ +static const struct file_operations name##_ops = { \ + .read = ieee80211_if_read_##name, \ + .open = mac80211_open_file_generic, \ +} + +#define IEEE80211_IF_FILE(name, field, format) \ + IEEE80211_IF_FMT_##format(name, field) \ + __IEEE80211_IF_FILE(name) + +/* common attributes */ +IEEE80211_IF_FILE(channel_use, channel_use, DEC); +IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); +IEEE80211_IF_FILE(eapol, eapol, DEC); +IEEE80211_IF_FILE(ieee8021_x, ieee802_1x, DEC); + +/* STA/IBSS attributes */ +IEEE80211_IF_FILE(state, u.sta.state, DEC); +IEEE80211_IF_FILE(bssid, u.sta.bssid, MAC); +IEEE80211_IF_FILE(prev_bssid, u.sta.prev_bssid, MAC); +IEEE80211_IF_FILE(ssid_len, u.sta.ssid_len, SIZE); +IEEE80211_IF_FILE(aid, u.sta.aid, DEC); +IEEE80211_IF_FILE(ap_capab, u.sta.ap_capab, HEX); +IEEE80211_IF_FILE(capab, u.sta.capab, HEX); +IEEE80211_IF_FILE(extra_ie_len, u.sta.extra_ie_len, SIZE); +IEEE80211_IF_FILE(auth_tries, u.sta.auth_tries, DEC); +IEEE80211_IF_FILE(assoc_tries, u.sta.assoc_tries, DEC); +IEEE80211_IF_FILE(auth_algs, u.sta.auth_algs, HEX); +IEEE80211_IF_FILE(auth_alg, u.sta.auth_alg, DEC); +IEEE80211_IF_FILE(auth_transaction, u.sta.auth_transaction, DEC); + +static ssize_t ieee80211_if_fmt_flags( + const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) +{ + return scnprintf(buf, buflen, "%s%s%s%s%s%s%s\n", + sdata->u.sta.ssid_set ? "SSID\n" : "", + sdata->u.sta.bssid_set ? "BSSID\n" : "", + sdata->u.sta.prev_bssid_set ? "prev BSSID\n" : "", + sdata->u.sta.authenticated ? "AUTH\n" : "", + sdata->u.sta.associated ? "ASSOC\n" : "", + sdata->u.sta.probereq_poll ? "PROBEREQ POLL\n" : "", + sdata->u.sta.use_protection ? "CTS prot\n" : ""); +} +__IEEE80211_IF_FILE(flags); + +/* AP attributes */ +IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); +IEEE80211_IF_FILE(dtim_period, u.ap.dtim_period, DEC); +IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC); +IEEE80211_IF_FILE(num_beacons, u.ap.num_beacons, DEC); +IEEE80211_IF_FILE(force_unicast_rateidx, u.ap.force_unicast_rateidx, DEC); +IEEE80211_IF_FILE(max_ratectrl_rateidx, u.ap.max_ratectrl_rateidx, DEC); + +static ssize_t ieee80211_if_fmt_num_buffered_multicast( + const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) +{ + return scnprintf(buf, buflen, "%u\n", + skb_queue_len(&sdata->u.ap.ps_bc_buf)); +} +__IEEE80211_IF_FILE(num_buffered_multicast); + +static ssize_t ieee80211_if_fmt_beacon_head_len( + const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) +{ + if (sdata->u.ap.beacon_head) + return scnprintf(buf, buflen, "%d\n", + sdata->u.ap.beacon_head_len); + return scnprintf(buf, buflen, "\n"); +} +__IEEE80211_IF_FILE(beacon_head_len); + +static ssize_t ieee80211_if_fmt_beacon_tail_len( + const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) +{ + if (sdata->u.ap.beacon_tail) + return scnprintf(buf, buflen, "%d\n", + sdata->u.ap.beacon_tail_len); + return scnprintf(buf, buflen, "\n"); +} +__IEEE80211_IF_FILE(beacon_tail_len); + +/* WDS attributes */ +IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC); + +/* VLAN attributes */ +IEEE80211_IF_FILE(vlan_id, u.vlan.id, DEC); + +/* MONITOR attributes */ +static ssize_t ieee80211_if_fmt_mode( + const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) +{ + struct ieee80211_local *local = sdata->local; + + return scnprintf(buf, buflen, "%s\n", + ((local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER) || + local->open_count == local->monitors) ? + "hard" : "soft"); +} +__IEEE80211_IF_FILE(mode); + + +#define DEBUGFS_ADD(name, type)\ + sdata->debugfs.type.name = debugfs_create_file(#name, 0444,\ + sdata->debugfsdir, sdata, &name##_ops); + +static void add_sta_files(struct ieee80211_sub_if_data *sdata) +{ + DEBUGFS_ADD(channel_use, sta); + DEBUGFS_ADD(drop_unencrypted, sta); + DEBUGFS_ADD(eapol, sta); + DEBUGFS_ADD(ieee8021_x, sta); + DEBUGFS_ADD(state, sta); + DEBUGFS_ADD(bssid, sta); + DEBUGFS_ADD(prev_bssid, sta); + DEBUGFS_ADD(ssid_len, sta); + DEBUGFS_ADD(aid, sta); + DEBUGFS_ADD(ap_capab, sta); + DEBUGFS_ADD(capab, sta); + DEBUGFS_ADD(extra_ie_len, sta); + DEBUGFS_ADD(auth_tries, sta); + DEBUGFS_ADD(assoc_tries, sta); + DEBUGFS_ADD(auth_algs, sta); + DEBUGFS_ADD(auth_alg, sta); + DEBUGFS_ADD(auth_transaction, sta); + DEBUGFS_ADD(flags, sta); +} + +static void add_ap_files(struct ieee80211_sub_if_data *sdata) +{ + DEBUGFS_ADD(channel_use, ap); + DEBUGFS_ADD(drop_unencrypted, ap); + DEBUGFS_ADD(eapol, ap); + DEBUGFS_ADD(ieee8021_x, ap); + DEBUGFS_ADD(num_sta_ps, ap); + DEBUGFS_ADD(dtim_period, ap); + DEBUGFS_ADD(dtim_count, ap); + DEBUGFS_ADD(num_beacons, ap); + DEBUGFS_ADD(force_unicast_rateidx, ap); + DEBUGFS_ADD(max_ratectrl_rateidx, ap); + DEBUGFS_ADD(num_buffered_multicast, ap); + DEBUGFS_ADD(beacon_head_len, ap); + DEBUGFS_ADD(beacon_tail_len, ap); +} + +static void add_wds_files(struct ieee80211_sub_if_data *sdata) +{ + DEBUGFS_ADD(channel_use, wds); + DEBUGFS_ADD(drop_unencrypted, wds); + DEBUGFS_ADD(eapol, wds); + DEBUGFS_ADD(ieee8021_x, wds); + DEBUGFS_ADD(peer, wds); +} + +static void add_vlan_files(struct ieee80211_sub_if_data *sdata) +{ + DEBUGFS_ADD(channel_use, vlan); + DEBUGFS_ADD(drop_unencrypted, vlan); + DEBUGFS_ADD(eapol, vlan); + DEBUGFS_ADD(ieee8021_x, vlan); + DEBUGFS_ADD(vlan_id, vlan); +} + +static void add_monitor_files(struct ieee80211_sub_if_data *sdata) +{ + DEBUGFS_ADD(mode, monitor); +} + +void add_files(struct ieee80211_sub_if_data *sdata) +{ + if (!sdata->debugfsdir) + return; + + switch (sdata->type) { + case IEEE80211_IF_TYPE_STA: + case IEEE80211_IF_TYPE_IBSS: + add_sta_files(sdata); + break; + case IEEE80211_IF_TYPE_AP: + add_ap_files(sdata); + break; + case IEEE80211_IF_TYPE_WDS: + add_wds_files(sdata); + break; + case IEEE80211_IF_TYPE_MNTR: + add_monitor_files(sdata); + break; + case IEEE80211_IF_TYPE_VLAN: + add_vlan_files(sdata); + break; + default: + break; + } +} + +#define DEBUGFS_DEL(name, type)\ + debugfs_remove(sdata->debugfs.type.name);\ + sdata->debugfs.type.name = NULL; + +static void del_sta_files(struct ieee80211_sub_if_data *sdata) +{ + DEBUGFS_DEL(channel_use, sta); + DEBUGFS_DEL(drop_unencrypted, sta); + DEBUGFS_DEL(eapol, sta); + DEBUGFS_DEL(ieee8021_x, sta); + DEBUGFS_DEL(state, sta); + DEBUGFS_DEL(bssid, sta); + DEBUGFS_DEL(prev_bssid, sta); + DEBUGFS_DEL(ssid_len, sta); + DEBUGFS_DEL(aid, sta); + DEBUGFS_DEL(ap_capab, sta); + DEBUGFS_DEL(capab, sta); + DEBUGFS_DEL(extra_ie_len, sta); + DEBUGFS_DEL(auth_tries, sta); + DEBUGFS_DEL(assoc_tries, sta); + DEBUGFS_DEL(auth_algs, sta); + DEBUGFS_DEL(auth_alg, sta); + DEBUGFS_DEL(auth_transaction, sta); + DEBUGFS_DEL(flags, sta); +} + +static void del_ap_files(struct ieee80211_sub_if_data *sdata) +{ + DEBUGFS_DEL(channel_use, ap); + DEBUGFS_DEL(drop_unencrypted, ap); + DEBUGFS_DEL(eapol, ap); + DEBUGFS_DEL(ieee8021_x, ap); + DEBUGFS_DEL(num_sta_ps, ap); + DEBUGFS_DEL(dtim_period, ap); + DEBUGFS_DEL(dtim_count, ap); + DEBUGFS_DEL(num_beacons, ap); + DEBUGFS_DEL(force_unicast_rateidx, ap); + DEBUGFS_DEL(max_ratectrl_rateidx, ap); + DEBUGFS_DEL(num_buffered_multicast, ap); + DEBUGFS_DEL(beacon_head_len, ap); + DEBUGFS_DEL(beacon_tail_len, ap); +} + +static void del_wds_files(struct ieee80211_sub_if_data *sdata) +{ + DEBUGFS_DEL(channel_use, wds); + DEBUGFS_DEL(drop_unencrypted, wds); + DEBUGFS_DEL(eapol, wds); + DEBUGFS_DEL(ieee8021_x, wds); + DEBUGFS_DEL(peer, wds); +} + +static void del_vlan_files(struct ieee80211_sub_if_data *sdata) +{ + DEBUGFS_DEL(channel_use, vlan); + DEBUGFS_DEL(drop_unencrypted, vlan); + DEBUGFS_DEL(eapol, vlan); + DEBUGFS_DEL(ieee8021_x, vlan); + DEBUGFS_DEL(vlan_id, vlan); +} + +static void del_monitor_files(struct ieee80211_sub_if_data *sdata) +{ + DEBUGFS_DEL(mode, monitor); +} + +void del_files(struct ieee80211_sub_if_data *sdata, int type) +{ + if (!sdata->debugfsdir) + return; + + switch (type) { + case IEEE80211_IF_TYPE_STA: + case IEEE80211_IF_TYPE_IBSS: + del_sta_files(sdata); + break; + case IEEE80211_IF_TYPE_AP: + del_ap_files(sdata); + break; + case IEEE80211_IF_TYPE_WDS: + del_wds_files(sdata); + break; + case IEEE80211_IF_TYPE_MNTR: + del_monitor_files(sdata); + break; + case IEEE80211_IF_TYPE_VLAN: + del_vlan_files(sdata); + break; + default: + break; + } +} + +static int notif_registered; + +void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata) +{ + char buf[10+IFNAMSIZ]; + + if (!notif_registered) + return; + + sprintf(buf, "netdev:%s", sdata->dev->name); + sdata->debugfsdir = debugfs_create_dir(buf, + sdata->local->hw.wiphy->debugfsdir); +} + +void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata) +{ + del_files(sdata, sdata->type); + debugfs_remove(sdata->debugfsdir); + sdata->debugfsdir = NULL; +} + +void ieee80211_debugfs_change_if_type(struct ieee80211_sub_if_data *sdata, + int oldtype) +{ + del_files(sdata, oldtype); + add_files(sdata); +} + +static int netdev_notify(struct notifier_block * nb, + unsigned long state, + void *ndev) +{ + struct net_device *dev = ndev; + char buf[10+IFNAMSIZ]; + + if (state != NETDEV_CHANGENAME) + return 0; + + if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy) + return 0; + + if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid) + return 0; + + /* TODO + sprintf(buf, "netdev:%s", dev->name); + debugfs_rename(IEEE80211_DEV_TO_SUB_IF(dev)->debugfsdir, buf); + */ + + return 0; +} + +static struct notifier_block mac80211_debugfs_netdev_notifier = { + .notifier_call = netdev_notify, +}; + +void ieee80211_debugfs_netdev_init(void) +{ + int err; + + err = register_netdevice_notifier(&mac80211_debugfs_netdev_notifier); + if (err) { + printk(KERN_ERR + "mac80211: failed to install netdev notifier," + " disabling per-netdev debugfs!\n"); + } else + notif_registered = 1; +} + +void ieee80211_debugfs_netdev_exit(void) +{ + unregister_netdevice_notifier(&mac80211_debugfs_netdev_notifier); + notif_registered = 0; +} diff --git a/net/mac80211/debugfs_netdev.h b/net/mac80211/debugfs_netdev.h new file mode 100644 index 0000000..308a52a --- /dev/null +++ b/net/mac80211/debugfs_netdev.h @@ -0,0 +1,30 @@ +/* routines exported for sysfs handling */ + +#ifndef __IEEE80211_SYSFS_H +#define __IEEE80211_SYSFS_H + +#ifdef CONFIG_DEBUG_FS +void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata); +void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata); +void ieee80211_debugfs_change_if_type(struct ieee80211_sub_if_data *sdata, + int oldtype); +void ieee80211_debugfs_netdev_init(void); +void ieee80211_debugfs_netdev_exit(void); +#else +static inline void ieee80211_debugfs_add_netdev( + struct ieee80211_sub_if_data *sdata) +{} +static inline void ieee80211_debugfs_remove_netdev( + struct ieee80211_sub_if_data *sdata) +{} +static inline void ieee80211_debugfs_change_if_type( + struct ieee80211_sub_if_data *sdata, int oldtype) +{} +static inline void ieee80211_debugfs_netdev_init(void) +{} + +static inline void ieee80211_debugfs_netdev_exit(void) +{} +#endif + +#endif /* __IEEE80211_SYSFS_H */ diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index c9e4cd0..db04fd8 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c @@ -33,9 +33,12 @@ #include "wme.h" #include "aes_ccm.h" #include "ieee80211_led.h" #include "ieee80211_cfg.h" -#include "ieee80211_sysfs.h" #include "debugfs.h" -#include "key_sysfs.h" +#include "debugfs_netdev.h" +#include "debugfs_key.h" + +/* privid for wiphys to determine whether they belong to us or not */ +void *mac80211_wiphy_privid = &mac80211_wiphy_privid; /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ @@ -86,40 +89,31 @@ struct ieee80211_key *ieee80211_key_allo int idx, size_t key_len, gfp_t flags) { struct ieee80211_key *key; - int res; key = kzalloc(sizeof(struct ieee80211_key) + key_len, flags); if (!key) return NULL; - if (sdata) - res = kobject_set_name(&key->kobj, "%d", idx); - else - res = kobject_set_name(&key->kobj, "key"); - if (res) { - kfree(key); - return NULL; - } - ieee80211_key_sysfs_set_kset(key, sdata ? &sdata->key_kset : NULL); - kobject_init(&key->kobj); + kref_init(&key->kref); return key; } -void ieee80211_key_free(struct ieee80211_key *key) -{ - if (key) - kobject_put(&key->kobj); -} - -void ieee80211_key_release(struct kobject *kobj) +void ieee80211_key_release(struct kref *kref) { struct ieee80211_key *key; - key = container_of(kobj, struct ieee80211_key, kobj); + key = container_of(kref, struct ieee80211_key, kref); if (key->alg == ALG_CCMP) ieee80211_aes_key_free(key->u.ccmp.tfm); + ieee80211_debugfs_key_remove(key); kfree(key); } +void ieee80211_key_free(struct ieee80211_key *key) +{ + if (key) + kref_put(&key->kref, ieee80211_key_release); +} + static int rate_list_match(const int *rate_list, int rate) { int i; @@ -4520,6 +4514,8 @@ struct ieee80211_hw *ieee80211_alloc_hw( if (!wiphy) return NULL; + wiphy->privid = mac80211_wiphy_privid; + local = wiphy_priv(wiphy); local->hw.wiphy = wiphy; @@ -4645,9 +4641,8 @@ int ieee80211_register_hw(struct ieee802 result = register_netdevice(local->mdev); if (result < 0) goto fail_dev; - result = ieee80211_sysfs_add_netdevice(local->mdev); - if (result < 0) - goto fail_if_sysfs; + + ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev)); result = ieee80211_init_rate_ctrl_alg(local, NULL); if (result < 0) { @@ -4682,8 +4677,7 @@ int ieee80211_register_hw(struct ieee802 fail_wep: rate_control_deinitialize(local); fail_rate: - ieee80211_sysfs_remove_netdevice(local->mdev); -fail_if_sysfs: + ieee80211_debugfs_remove_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev)); unregister_netdevice(local->mdev); fail_dev: rtnl_unlock(); @@ -4895,6 +4889,8 @@ static int __init ieee80211_init(void) return ret; } + ieee80211_debugfs_netdev_init(); + return 0; } @@ -4902,6 +4898,7 @@ static int __init ieee80211_init(void) static void __exit ieee80211_exit(void) { ieee80211_wme_unregister(); + ieee80211_debugfs_netdev_exit(); } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 0bb08b0..baf927f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -325,7 +325,6 @@ struct ieee80211_sub_if_data { #define NUM_DEFAULT_KEYS 4 struct ieee80211_key *keys[NUM_DEFAULT_KEYS]; struct ieee80211_key *default_key; - struct kset key_kset; struct ieee80211_if_ap *bss; /* BSS that this device belongs to */ @@ -338,7 +337,64 @@ #define NUM_DEFAULT_KEYS 4 int channel_use; int channel_use_raw; - struct attribute_group *sysfs_group; +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfsdir; + union { + struct { + struct dentry *channel_use; + struct dentry *drop_unencrypted; + struct dentry *eapol; + struct dentry *ieee8021_x; + struct dentry *state; + struct dentry *bssid; + struct dentry *prev_bssid; + struct dentry *ssid_len; + struct dentry *aid; + struct dentry *ap_capab; + struct dentry *capab; + struct dentry *extra_ie_len; + struct dentry *auth_tries; + struct dentry *assoc_tries; + struct dentry *auth_algs; + struct dentry *auth_alg; + struct dentry *auth_transaction; + struct dentry *flags; + } sta; + struct { + struct dentry *channel_use; + struct dentry *drop_unencrypted; + struct dentry *eapol; + struct dentry *ieee8021_x; + struct dentry *num_sta_ps; + struct dentry *dtim_period; + struct dentry *dtim_count; + struct dentry *num_beacons; + struct dentry *force_unicast_rateidx; + struct dentry *max_ratectrl_rateidx; + struct dentry *num_buffered_multicast; + struct dentry *beacon_head_len; + struct dentry *beacon_tail_len; + } ap; + struct { + struct dentry *channel_use; + struct dentry *drop_unencrypted; + struct dentry *eapol; + struct dentry *ieee8021_x; + struct dentry *peer; + } wds; + struct { + struct dentry *channel_use; + struct dentry *drop_unencrypted; + struct dentry *eapol; + struct dentry *ieee8021_x; + struct dentry *vlan_id; + } vlan; + struct { + struct dentry *mode; + } monitor; + struct dentry *default_key; + } debugfs; +#endif }; #define IEEE80211_DEV_TO_SUB_IF(dev) netdev_priv(dev) @@ -600,6 +656,7 @@ #endif struct dentry *wme_rx_queue; } stats; struct dentry *stations; + struct dentry *keys; } debugfs; #endif }; @@ -671,7 +728,6 @@ ieee80211_key_data2conf(struct ieee80211 struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata, int idx, size_t key_len, gfp_t flags); void ieee80211_key_free(struct ieee80211_key *key); -void ieee80211_key_release(struct kobject *kobj); void ieee80211_rx_mgmt(struct ieee80211_local *local, struct sk_buff *skb, struct ieee80211_rx_status *status, u32 msg_type); void ieee80211_prepare_rates(struct ieee80211_local *local, @@ -764,4 +820,7 @@ void ieee80211_if_sdata_init(struct ieee int ieee80211_if_add_mgmt(struct ieee80211_local *local); void ieee80211_if_del_mgmt(struct ieee80211_local *local); +/* for wiphy privid */ +extern void *mac80211_wiphy_privid; + #endif /* IEEE80211_I_H */ diff --git a/net/mac80211/ieee80211_iface.c b/net/mac80211/ieee80211_iface.c index 3e0b4fa..b1b20ba 100644 --- a/net/mac80211/ieee80211_iface.c +++ b/net/mac80211/ieee80211_iface.c @@ -14,7 +14,7 @@ #include #include #include "ieee80211_i.h" #include "sta_info.h" -#include "ieee80211_sysfs.h" +#include "debugfs_netdev.h" void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata) { @@ -81,14 +81,8 @@ int ieee80211_if_add(struct net_device * ret = register_netdevice(ndev); if (ret) goto fail; - ret = ieee80211_sysfs_add_netdevice(ndev); - if (ret) { - /* ndev will be freed by ndev->destructor */ - unregister_netdevice(ndev); - *new_dev = NULL; - return ret; - } + ieee80211_debugfs_add_netdev(sdata); list_add(&sdata->list, &local->sub_if_list); ieee80211_update_default_wep_only(local); @@ -130,16 +124,14 @@ int ieee80211_if_add_mgmt(struct ieee802 ret = register_netdevice(ndev); if (ret) goto fail; - ret = ieee80211_sysfs_add_netdevice(ndev); - if (ret) - goto fail_sysfs; + + ieee80211_debugfs_add_netdev(nsdata); + if (local->open_count > 0) dev_open(ndev); local->apdev = ndev; return 0; -fail_sysfs: - unregister_netdevice(ndev); fail: free_netdev(ndev); return ret; @@ -151,7 +143,7 @@ void ieee80211_if_del_mgmt(struct ieee80 ASSERT_RTNL(); apdev = local->apdev; - ieee80211_sysfs_remove_netdevice(apdev); + ieee80211_debugfs_remove_netdev(IEEE80211_DEV_TO_SUB_IF(apdev)); local->apdev = NULL; unregister_netdevice(apdev); } @@ -160,6 +152,7 @@ void ieee80211_if_set_type(struct net_de { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); + int oldtype = sdata->type; sdata->type = type; switch (type) { @@ -205,7 +198,7 @@ void ieee80211_if_set_type(struct net_de printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x", dev->name, __FUNCTION__, type); } - ieee80211_sysfs_change_if_type(dev); + ieee80211_debugfs_change_if_type(sdata, oldtype); ieee80211_update_default_wep_only(local); } @@ -309,7 +302,7 @@ void __ieee80211_if_del(struct ieee80211 struct net_device *dev = sdata->dev; list_del(&sdata->list); - ieee80211_sysfs_remove_netdevice(dev); + ieee80211_debugfs_remove_netdev(sdata); unregister_netdevice(dev); /* Except master interface, the net_device will be freed by * net_device->destructor (i. e. ieee80211_if_free). */ diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c index 782c1cb..cb75015 100644 --- a/net/mac80211/ieee80211_ioctl.c +++ b/net/mac80211/ieee80211_ioctl.c @@ -25,7 +25,7 @@ #include "hostapd_ioctl.h" #include "ieee80211_rate.h" #include "wpa.h" #include "aes_ccm.h" -#include "key_sysfs.h" +#include "debugfs_key.h" static int ieee80211_regdom = 0x10; /* FCC */ module_param(ieee80211_regdom, int, 0444); @@ -634,10 +634,10 @@ #endif /* CONFIG_MAC80211_VERBOSE_DEBUG kfree(keyconf); if (set_tx_key || sdata->default_key == key) { - ieee80211_key_sysfs_remove_default(sdata); + ieee80211_debugfs_key_remove_default(sdata); sdata->default_key = NULL; } - ieee80211_key_sysfs_remove(key); + ieee80211_debugfs_key_remove(key); if (sta) sta->key = NULL; else @@ -678,18 +678,18 @@ #endif /* CONFIG_MAC80211_VERBOSE_DEBUG } if (set_tx_key || sdata->default_key == old_key) { - ieee80211_key_sysfs_remove_default(sdata); + ieee80211_debugfs_key_remove_default(sdata); sdata->default_key = NULL; } - ieee80211_key_sysfs_remove(old_key); + ieee80211_debugfs_key_remove(old_key); if (sta) sta->key = key; else sdata->keys[idx] = key; ieee80211_key_free(old_key); - ret = ieee80211_key_sysfs_add(key); - if (ret) - goto err_null; + ieee80211_debugfs_key_add(local, key); + if (sta) + ieee80211_debugfs_key_sta_link(key, sta); if (try_hwaccel && (alg == ALG_WEP || alg == ALG_TKIP || alg == ALG_CCMP)) { @@ -702,9 +702,9 @@ #endif /* CONFIG_MAC80211_VERBOSE_DEBUG if (set_tx_key || (!sta && !sdata->default_key && key)) { sdata->default_key = key; - if (key && ieee80211_key_sysfs_add_default(sdata)) - printk(KERN_WARNING "%s: cannot create symlink to " - "default key\n", dev->name); + if (key) + ieee80211_debugfs_key_add_default(sdata); + if (local->ops->set_key_idx && local->ops->set_key_idx(local_to_hw(local), idx)) printk(KERN_DEBUG "%s: failed to set TX key idx for " @@ -716,11 +716,6 @@ #endif /* CONFIG_MAC80211_VERBOSE_DEBUG return 0; -err_null: - if (sta) - sta->key = NULL; - else - sdata->keys[idx] = NULL; err_free: ieee80211_key_free(key); err_out: @@ -2949,10 +2944,10 @@ static int ieee80211_ioctl_siwencode(str else if (erq->length == 0) { /* No key data - just set the default TX key index */ if (sdata->default_key != sdata->keys[idx]) { - ieee80211_key_sysfs_remove_default(sdata); + ieee80211_debugfs_key_remove_default(sdata); sdata->default_key = sdata->keys[idx]; if (sdata->default_key) - ieee80211_key_sysfs_add_default(sdata); + ieee80211_debugfs_key_add_default(sdata); } return 0; } diff --git a/net/mac80211/ieee80211_key.h b/net/mac80211/ieee80211_key.h index 60c4339..cde2974 100644 --- a/net/mac80211/ieee80211_key.h +++ b/net/mac80211/ieee80211_key.h @@ -11,7 +11,7 @@ #ifndef IEEE80211_KEY_H #define IEEE80211_KEY_H #include -#include +#include #include #include @@ -42,7 +42,7 @@ #define CCMP_PN_LEN 6 #define NUM_RX_DATA_QUEUES 17 struct ieee80211_key { - struct kobject kobj; + struct kref kref; int hw_key_idx; /* filled and used by low-level driver */ ieee80211_key_alg alg; @@ -83,6 +83,23 @@ #endif * (used only for broadcast keys). */ s8 keyidx; /* WEP key index */ +#ifdef CONFIG_DEBUG_FS + struct { + struct dentry *stalink; + struct dentry *dir; + struct dentry *keylen; + struct dentry *force_sw_encrypt; + struct dentry *keyidx; + struct dentry *hw_key_idx; + struct dentry *tx_rx_count; + struct dentry *algorithm; + struct dentry *tx_spec; + struct dentry *rx_spec; + struct dentry *replays; + struct dentry *key; + } debugfs; +#endif + u8 key[0]; }; diff --git a/net/mac80211/ieee80211_sysfs.c b/net/mac80211/ieee80211_sysfs.c deleted file mode 100644 index 9fdc398..0000000 --- a/net/mac80211/ieee80211_sysfs.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (c) 2006 Jiri Benc - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "ieee80211_i.h" -#include "ieee80211_rate.h" -#include "ieee80211_sysfs.h" -#include "key_sysfs.h" - -static inline struct ieee80211_local *to_ieee80211_local(struct device *dev) -{ - struct wiphy *wiphy = container_of(dev, struct wiphy, dev); - return wiphy_priv(wiphy); -} - -static inline int rtnl_lock_local(struct ieee80211_local *local) -{ - rtnl_lock(); - if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED)) { - rtnl_unlock(); - return -ENODEV; - } - return 0; -} - -/* attributes in /sys/class/net/X/ */ - -static ssize_t ieee80211_if_show(struct device *d, - struct device_attribute *attr, char *buf, - ssize_t (*format)(const struct ieee80211_sub_if_data *, - char *)) -{ - struct net_device *dev = to_net_dev(d); - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - ssize_t ret = -EINVAL; - - read_lock(&dev_base_lock); - if (dev->reg_state == NETREG_REGISTERED) { - ret = (*format)(sdata, buf); - } - read_unlock(&dev_base_lock); - return ret; -} - -#define IEEE80211_IF_FMT(name, field, format_string) \ -static ssize_t ieee80211_if_fmt_##name(const struct \ - ieee80211_sub_if_data *sdata, char *buf) \ -{ \ - return sprintf(buf, format_string, sdata->field); \ -} -#define IEEE80211_IF_FMT_DEC(name, field) \ - IEEE80211_IF_FMT(name, field, "%d\n") -#define IEEE80211_IF_FMT_HEX(name, field) \ - IEEE80211_IF_FMT(name, field, "%#x\n") -#define IEEE80211_IF_FMT_SIZE(name, field) \ - IEEE80211_IF_FMT(name, field, "%zd\n") - -#define IEEE80211_IF_FMT_ATOMIC(name, field) \ -static ssize_t ieee80211_if_fmt_##name(const struct \ - ieee80211_sub_if_data *sdata, char *buf) \ -{ \ - return sprintf(buf, "%d\n", atomic_read(&sdata->field)); \ -} - -#define IEEE80211_IF_FMT_MAC(name, field) \ -static ssize_t ieee80211_if_fmt_##name(const struct \ - ieee80211_sub_if_data *sdata, char *buf) \ -{ \ - return sprintf(buf, MAC_FMT "\n", MAC_ARG(sdata->field)); \ -} - -#define __IEEE80211_IF_SHOW(name) \ -static ssize_t ieee80211_if_show_##name(struct device *d, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - return ieee80211_if_show(d, attr, buf, ieee80211_if_fmt_##name);\ -} \ -static DEVICE_ATTR(name, S_IRUGO, ieee80211_if_show_##name, NULL); - -#define IEEE80211_IF_SHOW(name, field, format) \ - IEEE80211_IF_FMT_##format(name, field) \ - __IEEE80211_IF_SHOW(name) - -/* common attributes */ -IEEE80211_IF_SHOW(channel_use, channel_use, DEC); -IEEE80211_IF_SHOW(drop_unencrypted, drop_unencrypted, DEC); -IEEE80211_IF_SHOW(eapol, eapol, DEC); -IEEE80211_IF_SHOW(ieee8021_x, ieee802_1x, DEC); - -/* STA/IBSS attributes */ -IEEE80211_IF_SHOW(state, u.sta.state, DEC); -IEEE80211_IF_SHOW(bssid, u.sta.bssid, MAC); -IEEE80211_IF_SHOW(prev_bssid, u.sta.prev_bssid, MAC); -IEEE80211_IF_SHOW(ssid_len, u.sta.ssid_len, SIZE); -IEEE80211_IF_SHOW(aid, u.sta.aid, DEC); -IEEE80211_IF_SHOW(ap_capab, u.sta.ap_capab, HEX); -IEEE80211_IF_SHOW(capab, u.sta.capab, HEX); -IEEE80211_IF_SHOW(extra_ie_len, u.sta.extra_ie_len, SIZE); -IEEE80211_IF_SHOW(auth_tries, u.sta.auth_tries, DEC); -IEEE80211_IF_SHOW(assoc_tries, u.sta.assoc_tries, DEC); -IEEE80211_IF_SHOW(auth_algs, u.sta.auth_algs, HEX); -IEEE80211_IF_SHOW(auth_alg, u.sta.auth_alg, DEC); -IEEE80211_IF_SHOW(auth_transaction, u.sta.auth_transaction, DEC); - -static ssize_t ieee80211_if_fmt_flags(const struct - ieee80211_sub_if_data *sdata, char *buf) -{ - return sprintf(buf, "%s%s%s%s%s%s%s\n", - sdata->u.sta.ssid_set ? "SSID\n" : "", - sdata->u.sta.bssid_set ? "BSSID\n" : "", - sdata->u.sta.prev_bssid_set ? "prev BSSID\n" : "", - sdata->u.sta.authenticated ? "AUTH\n" : "", - sdata->u.sta.associated ? "ASSOC\n" : "", - sdata->u.sta.probereq_poll ? "PROBEREQ POLL\n" : "", - sdata->u.sta.use_protection ? "CTS prot\n" : ""); -} -__IEEE80211_IF_SHOW(flags); - -/* AP attributes */ -IEEE80211_IF_SHOW(num_sta_ps, u.ap.num_sta_ps, ATOMIC); -IEEE80211_IF_SHOW(dtim_period, u.ap.dtim_period, DEC); -IEEE80211_IF_SHOW(dtim_count, u.ap.dtim_count, DEC); -IEEE80211_IF_SHOW(num_beacons, u.ap.num_beacons, DEC); -IEEE80211_IF_SHOW(force_unicast_rateidx, u.ap.force_unicast_rateidx, DEC); -IEEE80211_IF_SHOW(max_ratectrl_rateidx, u.ap.max_ratectrl_rateidx, DEC); - -static ssize_t ieee80211_if_fmt_num_buffered_multicast(const struct - ieee80211_sub_if_data *sdata, char *buf) -{ - return sprintf(buf, "%u\n", skb_queue_len(&sdata->u.ap.ps_bc_buf)); -} -__IEEE80211_IF_SHOW(num_buffered_multicast); - -static ssize_t ieee80211_if_fmt_beacon_head_len(const struct - ieee80211_sub_if_data *sdata, char *buf) -{ - if (sdata->u.ap.beacon_head) - return sprintf(buf, "%d\n", sdata->u.ap.beacon_head_len); - return sprintf(buf, "\n"); -} -__IEEE80211_IF_SHOW(beacon_head_len); - -static ssize_t ieee80211_if_fmt_beacon_tail_len(const struct - ieee80211_sub_if_data *sdata, char *buf) -{ - if (sdata->u.ap.beacon_tail) - return sprintf(buf, "%d\n", sdata->u.ap.beacon_tail_len); - return sprintf(buf, "\n"); -} -__IEEE80211_IF_SHOW(beacon_tail_len); - -/* WDS attributes */ -IEEE80211_IF_SHOW(peer, u.wds.remote_addr, MAC); - -/* VLAN attributes */ -IEEE80211_IF_SHOW(vlan_id, u.vlan.id, DEC); - -/* MONITOR attributes */ -static ssize_t ieee80211_if_fmt_mode(const struct - ieee80211_sub_if_data *sdata, char *buf) -{ - struct ieee80211_local *local = sdata->local; - - return sprintf(buf, "%s\n", - ((local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER) || - local->open_count == local->monitors) ? - "hard" : "soft"); -} -__IEEE80211_IF_SHOW(mode); - -static struct attribute *ieee80211_sta_attrs[] = { - &dev_attr_channel_use.attr, - &dev_attr_drop_unencrypted.attr, - &dev_attr_eapol.attr, - &dev_attr_ieee8021_x.attr, - &dev_attr_state.attr, - &dev_attr_bssid.attr, - &dev_attr_prev_bssid.attr, - &dev_attr_ssid_len.attr, - &dev_attr_aid.attr, - &dev_attr_ap_capab.attr, - &dev_attr_capab.attr, - &dev_attr_extra_ie_len.attr, - &dev_attr_auth_tries.attr, - &dev_attr_assoc_tries.attr, - &dev_attr_auth_algs.attr, - &dev_attr_auth_alg.attr, - &dev_attr_auth_transaction.attr, - &dev_attr_flags.attr, - NULL -}; - -static struct attribute *ieee80211_ap_attrs[] = { - &dev_attr_channel_use.attr, - &dev_attr_drop_unencrypted.attr, - &dev_attr_eapol.attr, - &dev_attr_ieee8021_x.attr, - &dev_attr_num_sta_ps.attr, - &dev_attr_dtim_period.attr, - &dev_attr_dtim_count.attr, - &dev_attr_num_beacons.attr, - &dev_attr_force_unicast_rateidx.attr, - &dev_attr_max_ratectrl_rateidx.attr, - &dev_attr_num_buffered_multicast.attr, - &dev_attr_beacon_head_len.attr, - &dev_attr_beacon_tail_len.attr, - NULL -}; - -static struct attribute *ieee80211_wds_attrs[] = { - &dev_attr_channel_use.attr, - &dev_attr_drop_unencrypted.attr, - &dev_attr_eapol.attr, - &dev_attr_ieee8021_x.attr, - &dev_attr_peer.attr, - NULL -}; - -static struct attribute *ieee80211_vlan_attrs[] = { - &dev_attr_channel_use.attr, - &dev_attr_drop_unencrypted.attr, - &dev_attr_eapol.attr, - &dev_attr_ieee8021_x.attr, - &dev_attr_vlan_id.attr, - NULL -}; - -static struct attribute *ieee80211_monitor_attrs[] = { - &dev_attr_mode.attr, - NULL -}; - -static struct attribute_group ieee80211_sta_group = { - .name = "sta", - .attrs = ieee80211_sta_attrs, -}; - -static struct attribute_group ieee80211_ap_group = { - .name = "ap", - .attrs = ieee80211_ap_attrs, -}; - -static struct attribute_group ieee80211_wds_group = { - .name = "wds", - .attrs = ieee80211_wds_attrs, -}; - -static struct attribute_group ieee80211_vlan_group = { - .name = "vlan", - .attrs = ieee80211_vlan_attrs, -}; - -static struct attribute_group ieee80211_monitor_group = { - .name = "monitor", - .attrs = ieee80211_monitor_attrs, -}; - -/* /sys/class/net/X functions */ - -static void __ieee80211_remove_if_group(struct kobject *kobj, - struct ieee80211_sub_if_data *sdata) -{ - if (sdata->sysfs_group) { - sysfs_remove_group(kobj, sdata->sysfs_group); - sdata->sysfs_group = NULL; - } -} - -static inline void ieee80211_remove_if_group(struct kobject *kobj, - struct net_device *dev) -{ - __ieee80211_remove_if_group(kobj, IEEE80211_DEV_TO_SUB_IF(dev)); -} - -static int ieee80211_add_if_group(struct kobject *kobj, - struct net_device *dev) -{ - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - int res = 0; - - __ieee80211_remove_if_group(kobj, sdata); - switch (sdata->type) { - case IEEE80211_IF_TYPE_STA: - sdata->sysfs_group = &ieee80211_sta_group; - break; - case IEEE80211_IF_TYPE_AP: - sdata->sysfs_group = &ieee80211_ap_group; - break; - case IEEE80211_IF_TYPE_WDS: - sdata->sysfs_group = &ieee80211_wds_group; - break; - case IEEE80211_IF_TYPE_VLAN: - sdata->sysfs_group = &ieee80211_vlan_group; - break; - case IEEE80211_IF_TYPE_MNTR: - sdata->sysfs_group = &ieee80211_monitor_group; - break; - default: - goto out; - } - res = sysfs_create_group(kobj, sdata->sysfs_group); - if (res) - sdata->sysfs_group = NULL; -out: - return res; -} - -int ieee80211_sysfs_change_if_type(struct net_device *dev) -{ - return ieee80211_add_if_group(&dev->dev.kobj, dev); -} - -int ieee80211_sysfs_add_netdevice(struct net_device *dev) -{ - int res; - - res = ieee80211_add_if_group(&dev->dev.kobj, dev); - if (res) - goto err_fail_if_group; - res = ieee80211_key_kset_sysfs_register(IEEE80211_DEV_TO_SUB_IF(dev)); - return res; - -err_fail_if_group: - return res; -} - -void ieee80211_sysfs_remove_netdevice(struct net_device *dev) -{ - ieee80211_key_kset_sysfs_unregister(IEEE80211_DEV_TO_SUB_IF(dev)); - ieee80211_remove_if_group(&dev->dev.kobj, dev); -} diff --git a/net/mac80211/ieee80211_sysfs.h b/net/mac80211/ieee80211_sysfs.h deleted file mode 100644 index 1749cbd..0000000 --- a/net/mac80211/ieee80211_sysfs.h +++ /dev/null @@ -1,10 +0,0 @@ -/* routines exported for sysfs handling */ - -#ifndef __IEEE80211_SYSFS_H -#define __IEEE80211_SYSFS_H - -int ieee80211_sysfs_add_netdevice(struct net_device *dev); -void ieee80211_sysfs_remove_netdevice(struct net_device *dev); -int ieee80211_sysfs_change_if_type(struct net_device *dev); - -#endif /* __IEEE80211_SYSFS_H */ diff --git a/net/mac80211/key_sysfs.c b/net/mac80211/key_sysfs.c deleted file mode 100644 index 6576659..0000000 --- a/net/mac80211/key_sysfs.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright 2003-2005 Devicescape Software, Inc. - * Copyright (c) 2006 Jiri Benc - * Copyright 2007 Johannes Berg - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include "ieee80211_i.h" -#include "ieee80211_key.h" - -/* keys attributtes */ - -struct key_attribute { - struct attribute attr; - ssize_t (*show)(const struct ieee80211_key *, char *buf); - ssize_t (*store)(struct ieee80211_key *, const char *buf, - size_t count); -}; - -#define KEY_SHOW(name, field, format_string) \ -static ssize_t show_key_##name(const struct ieee80211_key *key, char *buf)\ -{ \ - return sprintf(buf, format_string, key->field); \ -} -#define KEY_SHOW_D(name, field) KEY_SHOW(name, field, "%d\n") - -#define __KEY_ATTR(name) \ -static struct key_attribute key_attr_##name = \ - __ATTR(name, S_IRUSR, show_key_##name, NULL) - -#define KEY_ATTR(name, field, format) \ - KEY_SHOW_##format(name, field) \ - __KEY_ATTR(name) - -KEY_ATTR(length, keylen, D); -KEY_ATTR(sw_encrypt, force_sw_encrypt, D); -KEY_ATTR(index, keyidx, D); -KEY_ATTR(hw_index, hw_key_idx, D); -KEY_ATTR(tx_rx_count, tx_rx_count, D); - -static ssize_t show_key_algorithm(const struct ieee80211_key *key, char *buf) -{ - char *alg; - - switch (key->alg) { - case ALG_WEP: - alg = "WEP"; - break; - case ALG_TKIP: - alg = "TKIP"; - break; - case ALG_CCMP: - alg = "CCMP"; - break; - default: - return 0; - } - return sprintf(buf, "%s\n", alg); -} -__KEY_ATTR(algorithm); - -static ssize_t show_key_tx_spec(const struct ieee80211_key *key, char *buf) -{ - const u8 *tpn; - - switch (key->alg) { - case ALG_WEP: - return sprintf(buf, "\n"); - case ALG_TKIP: - return sprintf(buf, "%08x %04x\n", key->u.tkip.iv32, - key->u.tkip.iv16); - case ALG_CCMP: - tpn = key->u.ccmp.tx_pn; - return sprintf(buf, "%02x%02x%02x%02x%02x%02x\n", tpn[0], - tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]); - default: - return 0; - } -} -__KEY_ATTR(tx_spec); - -static ssize_t show_key_rx_spec(const struct ieee80211_key *key, char *buf) -{ - int i; - const u8 *rpn; - char *p = buf; - - switch (key->alg) { - case ALG_WEP: - return sprintf(buf, "\n"); - case ALG_TKIP: - for (i = 0; i < NUM_RX_DATA_QUEUES; i++) - p += sprintf(p, "%08x %04x\n", - key->u.tkip.iv32_rx[i], - key->u.tkip.iv16_rx[i]); - return (p - buf); - case ALG_CCMP: - for (i = 0; i < NUM_RX_DATA_QUEUES; i++) { - rpn = key->u.ccmp.rx_pn[i]; - p += sprintf(p, "%02x%02x%02x%02x%02x%02x\n", rpn[0], - rpn[1], rpn[2], rpn[3], rpn[4], rpn[5]); - } - return (p - buf); - default: - return 0; - } -} -__KEY_ATTR(rx_spec); - -static ssize_t show_key_replays(const struct ieee80211_key *key, char *buf) -{ - if (key->alg != ALG_CCMP) - return 0; - return sprintf(buf, "%u\n", key->u.ccmp.replays); -} -__KEY_ATTR(replays); - -static ssize_t show_key_key(const struct ieee80211_key *key, char *buf) -{ - int i; - char *p = buf; - - for (i = 0; i < key->keylen; i++) - p += sprintf(p, "%02x", key->key[i]); - p += sprintf(p, "\n"); - return (p - buf); -} -__KEY_ATTR(key); - -static struct attribute *key_ktype_attrs[] = { - &key_attr_length.attr, - &key_attr_sw_encrypt.attr, - &key_attr_index.attr, - &key_attr_hw_index.attr, - &key_attr_tx_rx_count.attr, - &key_attr_algorithm.attr, - &key_attr_tx_spec.attr, - &key_attr_rx_spec.attr, - &key_attr_replays.attr, - &key_attr_key.attr, - NULL -}; - -/* structures and functions */ - -static ssize_t key_sysfs_show(struct kobject *kobj, struct attribute *attr, - char *buf) -{ - struct key_attribute *key_attr; - struct ieee80211_key *key; - - key_attr = container_of(attr, struct key_attribute, attr); - key = container_of(kobj, struct ieee80211_key, kobj); - return key_attr->show(key, buf); -} - -static struct sysfs_ops key_ktype_ops = { - .show = key_sysfs_show, -}; - -static struct kobj_type key_ktype = { - .release = ieee80211_key_release, - .sysfs_ops = &key_ktype_ops, - .default_attrs = key_ktype_attrs, -}; - -int ieee80211_key_kset_sysfs_register(struct ieee80211_sub_if_data *sdata) -{ - int res; - - res = kobject_set_name(&sdata->key_kset.kobj, "keys"); - if (res) - return res; - sdata->key_kset.kobj.parent = &sdata->dev->dev.kobj; - sdata->key_kset.ktype = &key_ktype; - return kset_register(&sdata->key_kset); -} - -void ieee80211_key_kset_sysfs_unregister(struct ieee80211_sub_if_data *sdata) -{ - kset_unregister(&sdata->key_kset); -} - -void ieee80211_key_sysfs_set_kset(struct ieee80211_key *key, struct kset *kset) -{ - key->kobj.kset = kset; - if (!kset) - key->kobj.ktype = &key_ktype; -} - -int ieee80211_key_sysfs_add(struct ieee80211_key *key) -{ - return kobject_add(&key->kobj); -} - -void ieee80211_key_sysfs_remove(struct ieee80211_key *key) -{ - if (key) - kobject_del(&key->kobj); -} - -int ieee80211_key_sysfs_add_default(struct ieee80211_sub_if_data *sdata) -{ - return sysfs_create_link(&sdata->key_kset.kobj, - &sdata->default_key->kobj, "default"); -} - -void ieee80211_key_sysfs_remove_default(struct ieee80211_sub_if_data *sdata) -{ - if (sdata->default_key) - sysfs_remove_link(&sdata->key_kset.kobj, "default"); -} diff --git a/net/mac80211/key_sysfs.h b/net/mac80211/key_sysfs.h deleted file mode 100644 index 9ac9f2b..0000000 --- a/net/mac80211/key_sysfs.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __MAC80211_KEY_SYSFS_H -#define __MAC80211_KEY_SYSFS_H - -int ieee80211_key_kset_sysfs_register(struct ieee80211_sub_if_data *sdata); -void ieee80211_key_kset_sysfs_unregister(struct ieee80211_sub_if_data *sdata); -void ieee80211_key_sysfs_set_kset(struct ieee80211_key *key, struct kset *kset); -int ieee80211_key_sysfs_add(struct ieee80211_key *key); -void ieee80211_key_sysfs_remove(struct ieee80211_key *key); -int ieee80211_key_sysfs_add_default(struct ieee80211_sub_if_data *sdata); -void ieee80211_key_sysfs_remove_default(struct ieee80211_sub_if_data *sdata); - -#endif /* __MAC80211_KEY_SYSFS_H */ diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 37d83eb..dfbd369 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -18,7 +18,7 @@ #include #include "ieee80211_i.h" #include "ieee80211_rate.h" #include "sta_info.h" -#include "key_sysfs.h" +#include "debugfs_key.h" #include "debugfs_sta.h" /* Caller must hold local->sta_lock */ @@ -121,6 +121,8 @@ void sta_info_release(struct kref *kref) } rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv); rate_control_put(sta->rate_ctrl); + if (sta->key) + ieee80211_debugfs_key_sta_del(sta->key, sta); kfree(sta); } @@ -197,7 +199,7 @@ #ifdef CONFIG_MAC80211_VERBOSE_DEBUG #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ if (sta->key) { - ieee80211_key_sysfs_remove(sta->key); + ieee80211_debugfs_key_remove(sta->key); ieee80211_key_free(sta->key); sta->key = NULL; } -- 1.3.0