mac80211: debugfs support for TSM and DLS
PATCH 3/3 mac80211: debugfs support for TSM and DLS
This adds the debugfs support for the TSM and DLS features. All the stuff will be in the new directory /sys/kernel/debug/ieee80211/phy0/netdev:wlan0/qos/ in STA mode.
--- net/mac80211/debugfs_netdev.c | 332 +++++++++++++++++++++++++++++++++++++++++ net/mac80211/ieee80211_i.h | 33 ++++ 2 files changed, 365 insertions(+), 0 deletions(-)
net/mac80211/debugfs_netdev.c +332 -0
@@ -87,6 +87,264 @@ static const struct file_operations name##_ops = { \ IEEE80211_IF_FMT_##format(name, field) \ __IEEE80211_IF_FILE(name) +static struct ieee80211_elem_tspec _tspec = { + .nominal_msdu_size =200 , + .inactivity_interval =40 , + .mean_data_rate =40000 , + .min_phy_rate =6000000 , + .surplus_band_allow =8192 , + .medium_time =30 , +}; +static u8 _dls_mac[ETH_ALEN ]; + +#define DEBUGFS_QOS_FILE (name, f) \ +static ssize_t qos_ ##name## _write(struct file *file, \ + const char __user *userbuf, \ + size_t count, loff_t *ppos) \ +{ \ + struct ieee80211_sub_if_data *sdata = file->private_data; \ + \ + f(sdata->dev, &sdata->u.sta, &_tspec); \ + \ + return count; \ +} \ + \ +static const struct file_operations qos_ ##name## _ops = { \ + .write = qos_ ##name## _write, \ + .open = mac80211_open_file_generic, \ +}; + +#define DEBUGFS_QOS_ADD (name) \ + sdata->debugfs.sta.qos.name = debugfs_create_file(#name, 0444, qosd,\ + sdata, &qos_ ##name## _ops); + +#define DEBUGFS_QOS_DEL (name) \ + debugfs_remove(sdata->debugfs.sta.qos.name); \ + sdata->debugfs.sta.qos.name = NULL; + +DEBUGFS_QOS_FILE (addts_11e, ieee80211_send_addts); +DEBUGFS_QOS_FILE (addts_wmm, wmm_send_addts); +DEBUGFS_QOS_FILE (delts_11e, ieee80211_send_delts); +DEBUGFS_QOS_FILE (delts_wmm, wmm_send_delts); + +static ssize_t qos_if_dls_mac (const struct ieee80211_sub_if_data *sdata, +char *buf,int buflen) +{ +return scnprintf (buf, buflen,MAC_FMT "\n" ,MAC_ARG (_dls_mac)); +} + +static ssize_t qos_dls_mac_read (struct file *file, +char __user *userbuf, +size_t count,loff_t *ppos) +{ +return ieee80211_if_read (file->private_data, + userbuf, count, ppos, + qos_if_dls_mac); +} + +static ssize_t qos_dls_mac_write (struct file *file,const char __user *userbuf, +size_t count,loff_t *ppos) +{ +struct ieee80211_sub_if_data *sdata = file->private_data; +char buf[20 ]; +size_t size; +u8 m[ETH_ALEN ]; + + size =min (sizeof (buf) -1 , count); + buf[size] ='\0' ; +if (copy_from_user (buf, userbuf, size)) +return -EFAULT ; + +if (sscanf (buf,"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx" , + &((u8 *)(m))[0 ], &((u8 *)(m))[1 ], &((u8 *)(m))[2 ], + &((u8 *)(m))[3 ], &((u8 *)(m))[4 ], &((u8 *)(m))[5 ]) !=ETH_ALEN ){ +printk (KERN_ERR "%s: sscanf input error\n" , sdata->dev->name); +return -EINVAL ; + } +memcpy (_dls_mac, m,ETH_ALEN ); +return count; +} + +static const struct file_operations qos_dls_mac_ops = { + .read = qos_dls_mac_read, + .write = qos_dls_mac_write, + .open = mac80211_open_file_generic, +}; + +static ssize_t qos_if_dls_op (const struct ieee80211_sub_if_data *sdata, +char *buf,int buflen) +{ +return scnprintf (buf, buflen, +"DLS Operation: Setup = 1; Teardown = 2\n" ); +} + +static ssize_t qos_dls_op_read (struct file *file,char __user *userbuf, +size_t count,loff_t *ppos) +{ +return ieee80211_if_read (file->private_data, + userbuf, count, ppos, + qos_if_dls_op); +} + +static ssize_t qos_dls_op_write (struct file *file,const char __user *userbuf, +size_t count,loff_t *ppos) +{ +struct ieee80211_sub_if_data *sdata = file->private_data; +char buf[20 ]; +size_t size; +unsigned int opt; + + size =min (sizeof (buf) -1 , count); + buf[size] ='\0' ; +if (copy_from_user (buf, userbuf, size)) +return -EFAULT ; + +if (sscanf (buf,"%u" , &opt) !=1 ) { +printk (KERN_ERR "%s: sscanf input error\n" , sdata->dev->name); +return -EINVAL ; + } +switch (opt) { +case 1 : +ieee80211_send_dls_req (sdata->dev, &sdata->u.sta, _dls_mac,0 ); +break ; +case 2 : +ieee80211_send_dls_teardown (sdata->dev, &sdata->u.sta, _dls_mac, +WLAN_REASON_QSTA_NOT_USE ); +break ; +default : +printk (KERN_ERR "Unknown DLS Operation: %d\n" , opt); +break ; + } +return count; +} + +static const struct file_operations qos_dls_op_ops = { + .read = qos_dls_op_read, + .write = qos_dls_op_write, + .open = mac80211_open_file_generic, +}; + +#define DEBUGFS_TSINFO_FILE (_name, min_val, max_val) \ +static ssize_t tsinfo_ ##_name## _read(struct file *file, \ + char __user *userbuf, \ + size_t count, loff_t *ppos) \ +{ \ + char buf[20]; \ + int res = scnprintf(buf, count, "%u\n", \ + IEEE80211_TSINFO_## _name (_tspec.ts_info)); \ + return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ +} \ + \ +static ssize_t tsinfo_ ##_name## _write(struct file *file, \ + const char __user *userbuf, \ + size_t count, loff_t *ppos) \ +{ \ + char buf[20]; \ + size_t size; \ + int val; \ + \ + size = min(sizeof(buf) - 1, count); \ + buf[size] = '\0'; \ + if (copy_from_user(buf, userbuf, size)) \ + return -EFAULT; \ + \ + val = simple_strtoul(buf, NULL, 0); \ + if ((val < min_val) || (val > max_val)) { \ + struct ieee80211_sub_if_data *sdata = file->private_data;\ + printk(KERN_ERR "%s: set value (%u) out of range " \ + "[%u, %u]\n",sdata->dev->name,val,min_val,max_val);\ + return -EINVAL; \ + } \ + SET_TSINFO_ ##_name (_tspec.ts_info, val); \ + return count; \ +} \ + \ +static const struct file_operations tsinfo_ ##_name## _ops = { \ + .read = tsinfo_ ##_name## _read, \ + .write = tsinfo_ ##_name## _write, \ + .open = mac80211_open_file_generic, \ +}; + +#define DEBUGFS_TSINFO_ADD_TSID \ + sdata->debugfs.sta.tsinfo.tsid = \ + debugfs_create_file("tsid", 0444, tsinfod, \ + sdata, &tsinfo_TSID_ops); + +#define DEBUGFS_TSINFO_ADD_DIR \ + sdata->debugfs.sta.tsinfo.direction = \ + debugfs_create_file("direction", 0444, tsinfod, \ + sdata, &tsinfo_DIR_ops); + +#define DEBUGFS_TSINFO_ADD_UP \ + sdata->debugfs.sta.tsinfo.up = \ + debugfs_create_file("up", 0444, tsinfod, \ + sdata, &tsinfo_UP_ops); + +#define DEBUGFS_TSINFO_DEL (name) \ + debugfs_remove(sdata->debugfs.sta.tsinfo.name); \ + sdata->debugfs.sta.tsinfo.name = NULL; + +DEBUGFS_TSINFO_FILE (TSID ,8 ,15 ); +DEBUGFS_TSINFO_FILE (DIR ,0 ,3 ); +DEBUGFS_TSINFO_FILE (UP ,0 ,7 ); + +#define DEBUGFS_TSPEC_FILE (name) \ +static ssize_t tspec_ ##name## _read(struct file *file, \ + char __user *userbuf, \ + size_t count, loff_t *ppos) \ +{ \ + char buf[20]; \ + int res = scnprintf(buf, count, "%u\n", _tspec.name); \ + return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ +} \ + \ +static ssize_t tspec_ ##name## _write(struct file *file, \ + const char __user *userbuf, \ + size_t count, loff_t *ppos) \ +{ \ + char buf[20]; \ + size_t size; \ + \ + size = min(sizeof(buf) - 1, count); \ + buf[size] = '\0'; \ + if (copy_from_user(buf, userbuf, size)) \ + return -EFAULT; \ + \ + _tspec.name = simple_strtoul(buf, NULL, 0); \ + return count; \ +} \ + \ +static const struct file_operations tspec_ ##name## _ops = { \ + .read = tspec_ ##name## _read, \ + .write = tspec_ ##name## _write, \ + .open = mac80211_open_file_generic, \ +}; + +#define DEBUGFS_TSPEC_ADD (name) \ + sdata->debugfs.sta.tspec.name = debugfs_create_file(#name, \ + 0444, tspecd, sdata, &tspec_ ##name## _ops); + +#define DEBUGFS_TSPEC_DEL (name) \ + debugfs_remove(sdata->debugfs.sta.tspec.name); \ + sdata->debugfs.sta.tspec.name = NULL; + +DEBUGFS_TSPEC_FILE (nominal_msdu_size); +DEBUGFS_TSPEC_FILE (max_msdu_size); +DEBUGFS_TSPEC_FILE (min_service_interval); +DEBUGFS_TSPEC_FILE (max_service_interval); +DEBUGFS_TSPEC_FILE (inactivity_interval); +DEBUGFS_TSPEC_FILE (suspension_interval); +DEBUGFS_TSPEC_FILE (service_start_time); +DEBUGFS_TSPEC_FILE (min_data_rate); +DEBUGFS_TSPEC_FILE (mean_data_rate); +DEBUGFS_TSPEC_FILE (peak_data_rate); +DEBUGFS_TSPEC_FILE (burst_size); +DEBUGFS_TSPEC_FILE (delay_bound); +DEBUGFS_TSPEC_FILE (min_phy_rate); +DEBUGFS_TSPEC_FILE (surplus_band_allow); +DEBUGFS_TSPEC_FILE (medium_time); + +/* common attributes */ IEEE80211_IF_FILE (channel_use, channel_use,DEC );IEEE80211_IF_FILE (drop_unencrypted, drop_unencrypted,DEC );
@@ -184,6 +442,10 @@ __IEEE80211_IF_FILE(mode);static void add_sta_files (struct ieee80211_sub_if_data *sdata) { +struct dentry *qosd; +struct dentry *tsinfod; +struct dentry *tspecd; +DEBUGFS_ADD (channel_use, sta);DEBUGFS_ADD (drop_unencrypted, sta);DEBUGFS_ADD (eapol, sta);
@@ -202,6 +464,42 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)DEBUGFS_ADD (auth_alg, sta);DEBUGFS_ADD (auth_transaction, sta);DEBUGFS_ADD (flags, sta); + + qosd =debugfs_create_dir ("qos" , sdata->debugfsdir); + sdata->debugfs.sta.qos_dir = qosd; + +DEBUGFS_QOS_ADD (addts_11e); +DEBUGFS_QOS_ADD (addts_wmm); +DEBUGFS_QOS_ADD (delts_11e); +DEBUGFS_QOS_ADD (delts_wmm); +DEBUGFS_QOS_ADD (dls_mac); +DEBUGFS_QOS_ADD (dls_op); + + tsinfod =debugfs_create_dir ("ts_info" , qosd); + sdata->debugfs.sta.tsinfo_dir = tsinfod; + +DEBUGFS_TSINFO_ADD_TSID ; +DEBUGFS_TSINFO_ADD_DIR ; +DEBUGFS_TSINFO_ADD_UP ; + + tspecd =debugfs_create_dir ("tspec" , qosd); + sdata->debugfs.sta.tspec_dir = tspecd; + +DEBUGFS_TSPEC_ADD (nominal_msdu_size); +DEBUGFS_TSPEC_ADD (max_msdu_size); +DEBUGFS_TSPEC_ADD (min_service_interval); +DEBUGFS_TSPEC_ADD (max_service_interval); +DEBUGFS_TSPEC_ADD (inactivity_interval); +DEBUGFS_TSPEC_ADD (suspension_interval); +DEBUGFS_TSPEC_ADD (service_start_time); +DEBUGFS_TSPEC_ADD (min_data_rate); +DEBUGFS_TSPEC_ADD (mean_data_rate); +DEBUGFS_TSPEC_ADD (peak_data_rate); +DEBUGFS_TSPEC_ADD (burst_size); +DEBUGFS_TSPEC_ADD (delay_bound); +DEBUGFS_TSPEC_ADD (min_phy_rate); +DEBUGFS_TSPEC_ADD (surplus_band_allow); +DEBUGFS_TSPEC_ADD (medium_time); }static void add_ap_files (struct ieee80211_sub_if_data *sdata)
@@ -295,6 +593,40 @@ static void del_sta_files(struct ieee80211_sub_if_data *sdata)DEBUGFS_DEL (auth_alg, sta);DEBUGFS_DEL (auth_transaction, sta);DEBUGFS_DEL (flags, sta); + +DEBUGFS_TSINFO_DEL (tsid); +DEBUGFS_TSINFO_DEL (direction); +DEBUGFS_TSINFO_DEL (up); + +DEBUGFS_TSPEC_DEL (nominal_msdu_size); +DEBUGFS_TSPEC_DEL (max_msdu_size); +DEBUGFS_TSPEC_DEL (min_service_interval); +DEBUGFS_TSPEC_DEL (max_service_interval); +DEBUGFS_TSPEC_DEL (inactivity_interval); +DEBUGFS_TSPEC_DEL (suspension_interval); +DEBUGFS_TSPEC_DEL (service_start_time); +DEBUGFS_TSPEC_DEL (min_data_rate); +DEBUGFS_TSPEC_DEL (mean_data_rate); +DEBUGFS_TSPEC_DEL (peak_data_rate); +DEBUGFS_TSPEC_DEL (burst_size); +DEBUGFS_TSPEC_DEL (delay_bound); +DEBUGFS_TSPEC_DEL (min_phy_rate); +DEBUGFS_TSPEC_DEL (surplus_band_allow); +DEBUGFS_TSPEC_DEL (medium_time); + +DEBUGFS_QOS_DEL (addts_11e); +DEBUGFS_QOS_DEL (addts_wmm); +DEBUGFS_QOS_DEL (delts_11e); +DEBUGFS_QOS_DEL (delts_wmm); +DEBUGFS_QOS_DEL (dls_mac); +DEBUGFS_QOS_DEL (dls_op); + +debugfs_remove (sdata->debugfs.sta.tspec_dir); + sdata->debugfs.sta.tspec_dir =NULL ; +debugfs_remove (sdata->debugfs.sta.tsinfo_dir); + sdata->debugfs.sta.tsinfo_dir =NULL ; +debugfs_remove (sdata->debugfs.sta.qos_dir); + sdata->debugfs.sta.qos_dir =NULL ; }static void del_ap_files (struct ieee80211_sub_if_data *sdata)
net/mac80211/ieee80211_i.h +33 -0
@@ -363,6 +363,39 @@ struct ieee80211_sub_if_data {struct dentry *auth_alg;struct dentry *auth_transaction;struct dentry *flags; +struct dentry *qos_dir; +struct { +struct dentry *addts_11e; +struct dentry *addts_wmm; +struct dentry *delts_11e; +struct dentry *delts_wmm; +struct dentry *dls_mac; +struct dentry *dls_op; + } qos; +struct dentry *tsinfo_dir; +struct { +struct dentry *tsid; +struct dentry *direction; +struct dentry *up; + } tsinfo; +struct dentry *tspec_dir; +struct { +struct dentry *nominal_msdu_size; +struct dentry *max_msdu_size; +struct dentry *min_service_interval; +struct dentry *max_service_interval; +struct dentry *inactivity_interval; +struct dentry *suspension_interval; +struct dentry *service_start_time; +struct dentry *min_data_rate; +struct dentry *mean_data_rate; +struct dentry *peak_data_rate; +struct dentry *burst_size; +struct dentry *delay_bound; +struct dentry *min_phy_rate; +struct dentry *surplus_band_allow; +struct dentry *medium_time; + } tspec; } sta;struct {struct dentry *channel_use;
Signature · 1 line
1.5.0.rc2.g73a2
net/mac80211/debugfs_netdev.c static const struct file_operations name##_ops = { \ · line 123
Quoted 12 lines · On Fri, 25 May 2007 19:52:44 +0800 Zhu Yi wrote:
net/mac80211/debugfs_netdev.c | 332 +++++++++++++++++++++++++++++++++++++++++ net/mac80211/ieee80211_i.h | 33 ++++ 2 files changed, 365 insertions(+), 0 deletions(-)net/mac80211/debugfs_netdev.c +3
-0+#define DEBUGFS_QOS_DEL (name) \ + debugfs_remove(sdata->debugfs.sta.qos.name); \ + sdata->debugfs.sta.qos.name = NULL;
Enclose multi-line macros inside braces, or even better, inside
do {
/* multi-lines */
} while (0);net/mac80211/debugfs_netdev.c static const struct file_operations name##_ops = { \ · line 285
Quoted 3 lines
net/mac80211/debugfs_netdev.c +3
-0+#define DEBUGFS_TSINFO_DEL (name) \ + debugfs_remove(sdata->debugfs.sta.tsinfo.name); \ + sdata->debugfs.sta.tsinfo.name = NULL;
ditto.
net/mac80211/debugfs_netdev.c static const struct file_operations name##_ops = { \ · line 329
Quoted 3 lines
net/mac80211/debugfs_netdev.c +3
-0+#define DEBUGFS_TSPEC_DEL (name) \ + debugfs_remove(sdata->debugfs.sta.tspec.name); \ + sdata->debugfs.sta.tspec.name = NULL;
ditto.
---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
Quoted 17 lines · On Friday 25 May 2007 18:20:08 Randy Dunlap wrote:
net/mac80211/debugfs_netdev.c static const struct file_operations name##_ops = { \ · line 123
Quoted 12 lines · On Fri, 25 May 2007 19:52:44 +0800 Zhu Yi wrote:
net/mac80211/debugfs_netdev.c | 332 +++++++++++++++++++++++++++++++++++++++++ net/mac80211/ieee80211_i.h | 33 ++++ 2 files changed, 365 insertions(+), 0 deletions(-)net/mac80211/debugfs_netdev.c +3
-0+#define DEBUGFS_QOS_DEL (name) \ + debugfs_remove(sdata->debugfs.sta.qos.name); \ + sdata->debugfs.sta.qos.name = NULL;Enclose multi-line macros inside braces, or even better, inside
Quoted 3 lines
do {
/* multi-lines */
} while (0);Remove the semicolon.
Signature · 1 line
Greetings Michael.
Quoted 18 lines · Michael Buesch
Quoted 17 lines · On Friday 25 May 2007 18:20:08 Randy Dunlap wrote:
net/mac80211/debugfs_netdev.c
Quoted 12 lines · On Fri, 25 May 2007 19:52:44 +0800 Zhu Yi wrote:
net/mac80211/debugfs_netdev.c | 332 +++++++++++++++++++++++++++++++++++++++++ net/mac80211/ieee80211_i.h | 33 ++++ 2 files changed, 365 insertions(+), 0 deletions(-)net/mac80211/debugfs_netdev.c +3
-0+#define DEBUGFS_QOS_DEL (name) \ + debugfs_remove(sdata->debugfs.sta.qos.name); \ + sdata->debugfs.sta.qos.name = NULL;Enclose multi-line macros inside braces, or even better, inside
Quoted 5 lines
Quoted 3 lines
do { /* multi-lines */ } while (0);Remove the semicolon.
I'd agree. But the existed DEBUGFS_DEL one also needs to be changed. Here is the patch against the "[PATCH 3/3] mac80211: debugfs support for TSM and DLS"
Thanks,
-yi
Quoted 1 line
From
7886ec6ddcc25af5ba3d0284ea3ac7c99bb99da0Mon Sep 17 00:00:00 2001
From: Zhu Yi <[email protected]>
Date: Mon, 28 May 2007 09:41:19 +0800
Subject: [PATCH 4/4] mac80211: use do { } while (0) for multi-line macros
Use do { } while (0) for multi-line macros
--- net/mac80211/debugfs_netdev.c | 26 +++++++++++++++++--------- 1 files changed, 17 insertions(+), 9 deletions(-)
net/mac80211/debugfs_netdev.c +17 -9
@@ -119,8 +119,10 @@ static const struct file_operations qos_ ##name## _ops = { \ sdata, &qos_ ##name## _ops);#define DEBUGFS_QOS_DEL (name) \ - debugfs_remove(sdata->debugfs.sta.qos.name); \ - sdata->debugfs.sta.qos.name = NULL; + do { \ + debugfs_remove(sdata->debugfs.sta.qos.name); \ + sdata->debugfs.sta.qos.name = NULL; \ + } while (0)DEBUGFS_QOS_FILE (addts_11e, ieee80211_send_addts);DEBUGFS_QOS_FILE (addts_wmm, wmm_send_addts);
@@ -281,8 +283,10 @@ static const struct file_operations tsinfo_ ##_name## _ops = { \ sdata, &tsinfo_UP_ops);#define DEBUGFS_TSINFO_DEL (name) \ - debugfs_remove(sdata->debugfs.sta.tsinfo.name); \ - sdata->debugfs.sta.tsinfo.name = NULL; + do { \ + debugfs_remove(sdata->debugfs.sta.tsinfo.name); \ + sdata->debugfs.sta.tsinfo.name = NULL; \ + } while (0)DEBUGFS_TSINFO_FILE (TSID ,8 ,15 );DEBUGFS_TSINFO_FILE (DIR ,0 ,3 );
@@ -325,8 +329,10 @@ static const struct file_operations tspec_ ##name## _ops = { \ 0444, tspecd, sdata, &tspec_ ##name## _ops);#define DEBUGFS_TSPEC_DEL (name) \ - debugfs_remove(sdata->debugfs.sta.tspec.name); \ - sdata->debugfs.sta.tspec.name = NULL; + do { \ + debugfs_remove(sdata->debugfs.sta.tspec.name); \ + sdata->debugfs.sta.tspec.name = NULL; \ + } while (0)DEBUGFS_TSPEC_FILE (nominal_msdu_size);DEBUGFS_TSPEC_FILE (max_msdu_size);
@@ -569,9 +575,11 @@ static void add_files(struct ieee80211_sub_if_data *sdata) } } -#define DEBUGFS_DEL (name, type)\ - debugfs_remove(sdata->debugfs.type.name);\ - sdata->debugfs.type.name = NULL; +#define DEBUGFS_DEL (name, type) \ + do { \ + debugfs_remove(sdata->debugfs.type.name); \ + sdata->debugfs.type.name = NULL; \ + } while (0)static void del_sta_files (struct ieee80211_sub_if_data *sdata) {
Signature · 1 line
1.5.0.rc2.g73a2