diff options
author | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2009-08-07 18:41:40 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-14 09:13:47 -0400 |
commit | 22fdf3c9e19dce6d66bcfdbed547a5aa52b89933 (patch) | |
tree | d2f0cf8e6f4f133ad08036d6ee01978fc0d51803 /drivers/net/wireless | |
parent | 20594eb0daa67f7a0cc19d74a1bafceb1bb09f4a (diff) |
iwlwifi: Traffic type and counter for debugFs
Break down the traffic type and counter for both Tx and Rx.
Enhance the tx_statistics and rx_statistics debugfs function and move
to /sys/kernel/debug/ieee80211/phy0/iwlagn/debug directory to help
better debugging both driver and uCode related problems.
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 158 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 9 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-debug.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-debugfs.c | 129 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 48 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-hcmd.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-led.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-rx.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 1 |
11 files changed, 324 insertions, 53 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index bfd509f7af24..ae7f1632ccbf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -577,6 +577,8 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
577 | if (ieee80211_is_data(hdr->frame_control)) | 577 | if (ieee80211_is_data(hdr->frame_control)) |
578 | priv->rxtxpackets += len; | 578 | priv->rxtxpackets += len; |
579 | #endif | 579 | #endif |
580 | iwl_update_stats(priv, false, hdr->frame_control, len); | ||
581 | |||
580 | memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats)); | 582 | memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats)); |
581 | ieee80211_rx_irqsafe(priv->hw, rxb->skb); | 583 | ieee80211_rx_irqsafe(priv->hw, rxb->skb); |
582 | rxb->skb = NULL; | 584 | rxb->skb = NULL; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 1ae2ce3512c3..202bc3985a46 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -3051,6 +3051,164 @@ void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, | |||
3051 | } | 3051 | } |
3052 | } | 3052 | } |
3053 | EXPORT_SYMBOL(iwl_dbg_log_rx_data_frame); | 3053 | EXPORT_SYMBOL(iwl_dbg_log_rx_data_frame); |
3054 | |||
3055 | const char *get_mgmt_string(int cmd) | ||
3056 | { | ||
3057 | switch (cmd) { | ||
3058 | IWL_CMD(MANAGEMENT_ASSOC_REQ); | ||
3059 | IWL_CMD(MANAGEMENT_ASSOC_RESP); | ||
3060 | IWL_CMD(MANAGEMENT_REASSOC_REQ); | ||
3061 | IWL_CMD(MANAGEMENT_REASSOC_RESP); | ||
3062 | IWL_CMD(MANAGEMENT_PROBE_REQ); | ||
3063 | IWL_CMD(MANAGEMENT_PROBE_RESP); | ||
3064 | IWL_CMD(MANAGEMENT_BEACON); | ||
3065 | IWL_CMD(MANAGEMENT_ATIM); | ||
3066 | IWL_CMD(MANAGEMENT_DISASSOC); | ||
3067 | IWL_CMD(MANAGEMENT_AUTH); | ||
3068 | IWL_CMD(MANAGEMENT_DEAUTH); | ||
3069 | IWL_CMD(MANAGEMENT_ACTION); | ||
3070 | default: | ||
3071 | return "UNKNOWN"; | ||
3072 | |||
3073 | } | ||
3074 | } | ||
3075 | |||
3076 | const char *get_ctrl_string(int cmd) | ||
3077 | { | ||
3078 | switch (cmd) { | ||
3079 | IWL_CMD(CONTROL_BACK_REQ); | ||
3080 | IWL_CMD(CONTROL_BACK); | ||
3081 | IWL_CMD(CONTROL_PSPOLL); | ||
3082 | IWL_CMD(CONTROL_RTS); | ||
3083 | IWL_CMD(CONTROL_CTS); | ||
3084 | IWL_CMD(CONTROL_ACK); | ||
3085 | IWL_CMD(CONTROL_CFEND); | ||
3086 | IWL_CMD(CONTROL_CFENDACK); | ||
3087 | default: | ||
3088 | return "UNKNOWN"; | ||
3089 | |||
3090 | } | ||
3091 | } | ||
3092 | |||
3093 | void iwl_clear_tx_stats(struct iwl_priv *priv) | ||
3094 | { | ||
3095 | memset(&priv->tx_stats, 0, sizeof(struct traffic_stats)); | ||
3096 | |||
3097 | } | ||
3098 | |||
3099 | void iwl_clear_rx_stats(struct iwl_priv *priv) | ||
3100 | { | ||
3101 | memset(&priv->rx_stats, 0, sizeof(struct traffic_stats)); | ||
3102 | } | ||
3103 | |||
3104 | /* | ||
3105 | * if CONFIG_IWLWIFI_DEBUGFS defined, iwl_update_stats function will | ||
3106 | * record all the MGMT, CTRL and DATA pkt for both TX and Rx pass. | ||
3107 | * Use debugFs to display the rx/rx_statistics | ||
3108 | * if CONFIG_IWLWIFI_DEBUGFS not being defined, then no MGMT and CTRL | ||
3109 | * information will be recorded, but DATA pkt still will be recorded | ||
3110 | * for the reason of iwl_led.c need to control the led blinking based on | ||
3111 | * number of tx and rx data. | ||
3112 | * | ||
3113 | */ | ||
3114 | void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) | ||
3115 | { | ||
3116 | struct traffic_stats *stats; | ||
3117 | |||
3118 | if (is_tx) | ||
3119 | stats = &priv->tx_stats; | ||
3120 | else | ||
3121 | stats = &priv->rx_stats; | ||
3122 | |||
3123 | if (ieee80211_is_mgmt(fc)) { | ||
3124 | switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { | ||
3125 | case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): | ||
3126 | stats->mgmt[MANAGEMENT_ASSOC_REQ]++; | ||
3127 | break; | ||
3128 | case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP): | ||
3129 | stats->mgmt[MANAGEMENT_ASSOC_RESP]++; | ||
3130 | break; | ||
3131 | case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): | ||
3132 | stats->mgmt[MANAGEMENT_REASSOC_REQ]++; | ||
3133 | break; | ||
3134 | case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP): | ||
3135 | stats->mgmt[MANAGEMENT_REASSOC_RESP]++; | ||
3136 | break; | ||
3137 | case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ): | ||
3138 | stats->mgmt[MANAGEMENT_PROBE_REQ]++; | ||
3139 | break; | ||
3140 | case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP): | ||
3141 | stats->mgmt[MANAGEMENT_PROBE_RESP]++; | ||
3142 | break; | ||
3143 | case cpu_to_le16(IEEE80211_STYPE_BEACON): | ||
3144 | stats->mgmt[MANAGEMENT_BEACON]++; | ||
3145 | break; | ||
3146 | case cpu_to_le16(IEEE80211_STYPE_ATIM): | ||
3147 | stats->mgmt[MANAGEMENT_ATIM]++; | ||
3148 | break; | ||
3149 | case cpu_to_le16(IEEE80211_STYPE_DISASSOC): | ||
3150 | stats->mgmt[MANAGEMENT_DISASSOC]++; | ||
3151 | break; | ||
3152 | case cpu_to_le16(IEEE80211_STYPE_AUTH): | ||
3153 | stats->mgmt[MANAGEMENT_AUTH]++; | ||
3154 | break; | ||
3155 | case cpu_to_le16(IEEE80211_STYPE_DEAUTH): | ||
3156 | stats->mgmt[MANAGEMENT_DEAUTH]++; | ||
3157 | break; | ||
3158 | case cpu_to_le16(IEEE80211_STYPE_ACTION): | ||
3159 | stats->mgmt[MANAGEMENT_ACTION]++; | ||
3160 | break; | ||
3161 | } | ||
3162 | } else if (ieee80211_is_ctl(fc)) { | ||
3163 | switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { | ||
3164 | case cpu_to_le16(IEEE80211_STYPE_BACK_REQ): | ||
3165 | stats->ctrl[CONTROL_BACK_REQ]++; | ||
3166 | break; | ||
3167 | case cpu_to_le16(IEEE80211_STYPE_BACK): | ||
3168 | stats->ctrl[CONTROL_BACK]++; | ||
3169 | break; | ||
3170 | case cpu_to_le16(IEEE80211_STYPE_PSPOLL): | ||
3171 | stats->ctrl[CONTROL_PSPOLL]++; | ||
3172 | break; | ||
3173 | case cpu_to_le16(IEEE80211_STYPE_RTS): | ||
3174 | stats->ctrl[CONTROL_RTS]++; | ||
3175 | break; | ||
3176 | case cpu_to_le16(IEEE80211_STYPE_CTS): | ||
3177 | stats->ctrl[CONTROL_CTS]++; | ||
3178 | break; | ||
3179 | case cpu_to_le16(IEEE80211_STYPE_ACK): | ||
3180 | stats->ctrl[CONTROL_ACK]++; | ||
3181 | break; | ||
3182 | case cpu_to_le16(IEEE80211_STYPE_CFEND): | ||
3183 | stats->ctrl[CONTROL_CFEND]++; | ||
3184 | break; | ||
3185 | case cpu_to_le16(IEEE80211_STYPE_CFENDACK): | ||
3186 | stats->ctrl[CONTROL_CFENDACK]++; | ||
3187 | break; | ||
3188 | } | ||
3189 | } else { | ||
3190 | /* data */ | ||
3191 | stats->data_cnt++; | ||
3192 | stats->data_bytes += len; | ||
3193 | } | ||
3194 | } | ||
3195 | EXPORT_SYMBOL(iwl_update_stats); | ||
3196 | |||
3197 | #else | ||
3198 | void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) | ||
3199 | { | ||
3200 | struct traffic_stats *stats; | ||
3201 | |||
3202 | if (is_tx) | ||
3203 | stats = &priv->tx_stats; | ||
3204 | else | ||
3205 | stats = &priv->rx_stats; | ||
3206 | |||
3207 | if (ieee80211_is_data(fc)) { | ||
3208 | /* data */ | ||
3209 | stats->data_bytes += len; | ||
3210 | } | ||
3211 | } | ||
3054 | #endif | 3212 | #endif |
3055 | 3213 | ||
3056 | #ifdef CONFIG_PM | 3214 | #ifdef CONFIG_PM |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 40a9167cacce..fc096b929ee3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -83,6 +83,8 @@ struct iwl_cmd; | |||
83 | #define IWL_SKU_A 0x2 | 83 | #define IWL_SKU_A 0x2 |
84 | #define IWL_SKU_N 0x8 | 84 | #define IWL_SKU_N 0x8 |
85 | 85 | ||
86 | #define IWL_CMD(x) case x: return #x | ||
87 | |||
86 | struct iwl_hcmd_ops { | 88 | struct iwl_hcmd_ops { |
87 | int (*rxon_assoc)(struct iwl_priv *priv); | 89 | int (*rxon_assoc)(struct iwl_priv *priv); |
88 | int (*commit_rxon)(struct iwl_priv *priv); | 90 | int (*commit_rxon)(struct iwl_priv *priv); |
@@ -308,7 +310,10 @@ void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv, | |||
308 | u16 length, struct ieee80211_hdr *header); | 310 | u16 length, struct ieee80211_hdr *header); |
309 | void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, | 311 | void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, |
310 | u16 length, struct ieee80211_hdr *header); | 312 | u16 length, struct ieee80211_hdr *header); |
311 | 313 | const char *get_mgmt_string(int cmd); | |
314 | const char *get_ctrl_string(int cmd); | ||
315 | void iwl_clear_tx_stats(struct iwl_priv *priv); | ||
316 | void iwl_clear_rx_stats(struct iwl_priv *priv); | ||
312 | #else | 317 | #else |
313 | static inline int iwl_alloc_traffic_mem(struct iwl_priv *priv) | 318 | static inline int iwl_alloc_traffic_mem(struct iwl_priv *priv) |
314 | { | 319 | { |
@@ -329,6 +334,8 @@ static inline void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, | |||
329 | { | 334 | { |
330 | } | 335 | } |
331 | #endif | 336 | #endif |
337 | void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, | ||
338 | u16 len); | ||
332 | /***************************************************** | 339 | /***************************************************** |
333 | * RX handlers. | 340 | * RX handlers. |
334 | * **************************************************/ | 341 | * **************************************************/ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 335ff5c43966..4ac06ad69ed3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -78,8 +78,6 @@ struct iwl_debugfs { | |||
78 | struct dentry *file_sram; | 78 | struct dentry *file_sram; |
79 | struct dentry *file_nvm; | 79 | struct dentry *file_nvm; |
80 | struct dentry *file_stations; | 80 | struct dentry *file_stations; |
81 | struct dentry *file_rx_statistics; | ||
82 | struct dentry *file_tx_statistics; | ||
83 | struct dentry *file_log_event; | 81 | struct dentry *file_log_event; |
84 | struct dentry *file_channels; | 82 | struct dentry *file_channels; |
85 | struct dentry *file_status; | 83 | struct dentry *file_status; |
@@ -97,6 +95,8 @@ struct iwl_debugfs { | |||
97 | struct dentry *file_disable_tx_power; | 95 | struct dentry *file_disable_tx_power; |
98 | } dbgfs_rf_files; | 96 | } dbgfs_rf_files; |
99 | struct dir_debug_files { | 97 | struct dir_debug_files { |
98 | struct dentry *file_rx_statistics; | ||
99 | struct dentry *file_tx_statistics; | ||
100 | struct dentry *file_traffic_log; | 100 | struct dentry *file_traffic_log; |
101 | } dbgfs_debug_files; | 101 | } dbgfs_debug_files; |
102 | u32 sram_offset; | 102 | u32 sram_offset; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 031538c42063..a0e5063cd8c9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -126,18 +126,58 @@ static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file, | |||
126 | size_t count, loff_t *ppos) { | 126 | size_t count, loff_t *ppos) { |
127 | 127 | ||
128 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | 128 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; |
129 | char buf[256]; | 129 | char *buf; |
130 | int pos = 0; | 130 | int pos = 0; |
131 | const size_t bufsz = sizeof(buf); | ||
132 | 131 | ||
133 | pos += scnprintf(buf + pos, bufsz - pos, "mgmt: %u\n", | 132 | int cnt; |
134 | priv->tx_stats[0].cnt); | 133 | ssize_t ret; |
135 | pos += scnprintf(buf + pos, bufsz - pos, "ctrl: %u\n", | 134 | const size_t bufsz = 100 + sizeof(char) * 24 * (MANAGEMENT_MAX + CONTROL_MAX); |
136 | priv->tx_stats[1].cnt); | 135 | buf = kzalloc(bufsz, GFP_KERNEL); |
137 | pos += scnprintf(buf + pos, bufsz - pos, "data: %u\n", | 136 | if (!buf) |
138 | priv->tx_stats[2].cnt); | 137 | return -ENOMEM; |
138 | pos += scnprintf(buf + pos, bufsz - pos, "Management:\n"); | ||
139 | for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) { | ||
140 | pos += scnprintf(buf + pos, bufsz - pos, | ||
141 | "\t%s\t\t: %u\n", | ||
142 | get_mgmt_string(cnt), | ||
143 | priv->tx_stats.mgmt[cnt]); | ||
144 | } | ||
145 | pos += scnprintf(buf + pos, bufsz - pos, "Control\n"); | ||
146 | for (cnt = 0; cnt < CONTROL_MAX; cnt++) { | ||
147 | pos += scnprintf(buf + pos, bufsz - pos, | ||
148 | "\t%s\t\t: %u\n", | ||
149 | get_ctrl_string(cnt), | ||
150 | priv->tx_stats.ctrl[cnt]); | ||
151 | } | ||
152 | pos += scnprintf(buf + pos, bufsz - pos, "Data:\n"); | ||
153 | pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n", | ||
154 | priv->tx_stats.data_cnt); | ||
155 | pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n", | ||
156 | priv->tx_stats.data_bytes); | ||
157 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
158 | kfree(buf); | ||
159 | return ret; | ||
160 | } | ||
161 | |||
162 | static ssize_t iwl_dbgfs_tx_statistics_write(struct file *file, | ||
163 | const char __user *user_buf, | ||
164 | size_t count, loff_t *ppos) | ||
165 | { | ||
166 | struct iwl_priv *priv = file->private_data; | ||
167 | u32 clear_flag; | ||
168 | char buf[8]; | ||
169 | int buf_size; | ||
139 | 170 | ||
140 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 171 | memset(buf, 0, sizeof(buf)); |
172 | buf_size = min(count, sizeof(buf) - 1); | ||
173 | if (copy_from_user(buf, user_buf, buf_size)) | ||
174 | return -EFAULT; | ||
175 | if (sscanf(buf, "%x", &clear_flag) != 1) | ||
176 | return -EFAULT; | ||
177 | if (clear_flag == 1) | ||
178 | iwl_clear_tx_stats(priv); | ||
179 | |||
180 | return count; | ||
141 | } | 181 | } |
142 | 182 | ||
143 | static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file, | 183 | static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file, |
@@ -145,18 +185,59 @@ static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file, | |||
145 | size_t count, loff_t *ppos) { | 185 | size_t count, loff_t *ppos) { |
146 | 186 | ||
147 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | 187 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; |
148 | char buf[256]; | 188 | char *buf; |
149 | int pos = 0; | 189 | int pos = 0; |
150 | const size_t bufsz = sizeof(buf); | 190 | int cnt; |
191 | ssize_t ret; | ||
192 | const size_t bufsz = 100 + | ||
193 | sizeof(char) * 24 * (MANAGEMENT_MAX + CONTROL_MAX); | ||
194 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
195 | if (!buf) | ||
196 | return -ENOMEM; | ||
151 | 197 | ||
152 | pos += scnprintf(buf + pos, bufsz - pos, "mgmt: %u\n", | 198 | pos += scnprintf(buf + pos, bufsz - pos, "Management:\n"); |
153 | priv->rx_stats[0].cnt); | 199 | for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) { |
154 | pos += scnprintf(buf + pos, bufsz - pos, "ctrl: %u\n", | 200 | pos += scnprintf(buf + pos, bufsz - pos, |
155 | priv->rx_stats[1].cnt); | 201 | "\t%s\t\t: %u\n", |
156 | pos += scnprintf(buf + pos, bufsz - pos, "data: %u\n", | 202 | get_mgmt_string(cnt), |
157 | priv->rx_stats[2].cnt); | 203 | priv->rx_stats.mgmt[cnt]); |
204 | } | ||
205 | pos += scnprintf(buf + pos, bufsz - pos, "Control:\n"); | ||
206 | for (cnt = 0; cnt < CONTROL_MAX; cnt++) { | ||
207 | pos += scnprintf(buf + pos, bufsz - pos, | ||
208 | "\t%s\t\t: %u\n", | ||
209 | get_ctrl_string(cnt), | ||
210 | priv->rx_stats.ctrl[cnt]); | ||
211 | } | ||
212 | pos += scnprintf(buf + pos, bufsz - pos, "Data:\n"); | ||
213 | pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n", | ||
214 | priv->rx_stats.data_cnt); | ||
215 | pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n", | ||
216 | priv->rx_stats.data_bytes); | ||
158 | 217 | ||
159 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 218 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
219 | kfree(buf); | ||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | static ssize_t iwl_dbgfs_rx_statistics_write(struct file *file, | ||
224 | const char __user *user_buf, | ||
225 | size_t count, loff_t *ppos) | ||
226 | { | ||
227 | struct iwl_priv *priv = file->private_data; | ||
228 | u32 clear_flag; | ||
229 | char buf[8]; | ||
230 | int buf_size; | ||
231 | |||
232 | memset(buf, 0, sizeof(buf)); | ||
233 | buf_size = min(count, sizeof(buf) - 1); | ||
234 | if (copy_from_user(buf, user_buf, buf_size)) | ||
235 | return -EFAULT; | ||
236 | if (sscanf(buf, "%x", &clear_flag) != 1) | ||
237 | return -EFAULT; | ||
238 | if (clear_flag == 1) | ||
239 | iwl_clear_rx_stats(priv); | ||
240 | return count; | ||
160 | } | 241 | } |
161 | 242 | ||
162 | #define BYTE1_MASK 0x000000ff; | 243 | #define BYTE1_MASK 0x000000ff; |
@@ -700,8 +781,6 @@ DEBUGFS_READ_WRITE_FILE_OPS(sram); | |||
700 | DEBUGFS_WRITE_FILE_OPS(log_event); | 781 | DEBUGFS_WRITE_FILE_OPS(log_event); |
701 | DEBUGFS_READ_FILE_OPS(nvm); | 782 | DEBUGFS_READ_FILE_OPS(nvm); |
702 | DEBUGFS_READ_FILE_OPS(stations); | 783 | DEBUGFS_READ_FILE_OPS(stations); |
703 | DEBUGFS_READ_FILE_OPS(rx_statistics); | ||
704 | DEBUGFS_READ_FILE_OPS(tx_statistics); | ||
705 | DEBUGFS_READ_FILE_OPS(channels); | 784 | DEBUGFS_READ_FILE_OPS(channels); |
706 | DEBUGFS_READ_FILE_OPS(status); | 785 | DEBUGFS_READ_FILE_OPS(status); |
707 | DEBUGFS_READ_WRITE_FILE_OPS(interrupt); | 786 | DEBUGFS_READ_WRITE_FILE_OPS(interrupt); |
@@ -808,6 +887,8 @@ static ssize_t iwl_dbgfs_traffic_log_write(struct file *file, | |||
808 | return count; | 887 | return count; |
809 | } | 888 | } |
810 | 889 | ||
890 | DEBUGFS_READ_WRITE_FILE_OPS(rx_statistics); | ||
891 | DEBUGFS_READ_WRITE_FILE_OPS(tx_statistics); | ||
811 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); | 892 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); |
812 | 893 | ||
813 | /* | 894 | /* |
@@ -841,8 +922,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
841 | DEBUGFS_ADD_FILE(sram, data); | 922 | DEBUGFS_ADD_FILE(sram, data); |
842 | DEBUGFS_ADD_FILE(log_event, data); | 923 | DEBUGFS_ADD_FILE(log_event, data); |
843 | DEBUGFS_ADD_FILE(stations, data); | 924 | DEBUGFS_ADD_FILE(stations, data); |
844 | DEBUGFS_ADD_FILE(rx_statistics, data); | ||
845 | DEBUGFS_ADD_FILE(tx_statistics, data); | ||
846 | DEBUGFS_ADD_FILE(channels, data); | 925 | DEBUGFS_ADD_FILE(channels, data); |
847 | DEBUGFS_ADD_FILE(status, data); | 926 | DEBUGFS_ADD_FILE(status, data); |
848 | DEBUGFS_ADD_FILE(interrupt, data); | 927 | DEBUGFS_ADD_FILE(interrupt, data); |
@@ -852,6 +931,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
852 | #endif | 931 | #endif |
853 | DEBUGFS_ADD_FILE(thermal_throttling, data); | 932 | DEBUGFS_ADD_FILE(thermal_throttling, data); |
854 | DEBUGFS_ADD_FILE(disable_ht40, data); | 933 | DEBUGFS_ADD_FILE(disable_ht40, data); |
934 | DEBUGFS_ADD_FILE(rx_statistics, debug); | ||
935 | DEBUGFS_ADD_FILE(tx_statistics, debug); | ||
855 | DEBUGFS_ADD_FILE(traffic_log, debug); | 936 | DEBUGFS_ADD_FILE(traffic_log, debug); |
856 | DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); | 937 | DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); |
857 | DEBUGFS_ADD_BOOL(disable_chain_noise, rf, | 938 | DEBUGFS_ADD_BOOL(disable_chain_noise, rf, |
@@ -879,8 +960,6 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
879 | return; | 960 | return; |
880 | 961 | ||
881 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm); | 962 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm); |
882 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_rx_statistics); | ||
883 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_tx_statistics); | ||
884 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram); | 963 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram); |
885 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event); | 964 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event); |
886 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); | 965 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); |
@@ -894,6 +973,8 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
894 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling); | 973 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling); |
895 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40); | 974 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40); |
896 | DEBUGFS_REMOVE(priv->dbgfs->dir_data); | 975 | DEBUGFS_REMOVE(priv->dbgfs->dir_data); |
976 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_statistics); | ||
977 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_statistics); | ||
897 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_traffic_log); | 978 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_traffic_log); |
898 | DEBUGFS_REMOVE(priv->dbgfs->dir_debug); | 979 | DEBUGFS_REMOVE(priv->dbgfs->dir_debug); |
899 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); | 980 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 899b75f28a23..dcf9d5763237 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -919,6 +919,48 @@ struct isr_statistics { | |||
919 | u32 unhandled; | 919 | u32 unhandled; |
920 | }; | 920 | }; |
921 | 921 | ||
922 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
923 | /* management statistics */ | ||
924 | enum iwl_mgmt_stats { | ||
925 | MANAGEMENT_ASSOC_REQ = 0, | ||
926 | MANAGEMENT_ASSOC_RESP, | ||
927 | MANAGEMENT_REASSOC_REQ, | ||
928 | MANAGEMENT_REASSOC_RESP, | ||
929 | MANAGEMENT_PROBE_REQ, | ||
930 | MANAGEMENT_PROBE_RESP, | ||
931 | MANAGEMENT_BEACON, | ||
932 | MANAGEMENT_ATIM, | ||
933 | MANAGEMENT_DISASSOC, | ||
934 | MANAGEMENT_AUTH, | ||
935 | MANAGEMENT_DEAUTH, | ||
936 | MANAGEMENT_ACTION, | ||
937 | MANAGEMENT_MAX, | ||
938 | }; | ||
939 | /* control statistics */ | ||
940 | enum iwl_ctrl_stats { | ||
941 | CONTROL_BACK_REQ = 0, | ||
942 | CONTROL_BACK, | ||
943 | CONTROL_PSPOLL, | ||
944 | CONTROL_RTS, | ||
945 | CONTROL_CTS, | ||
946 | CONTROL_ACK, | ||
947 | CONTROL_CFEND, | ||
948 | CONTROL_CFENDACK, | ||
949 | CONTROL_MAX, | ||
950 | }; | ||
951 | |||
952 | struct traffic_stats { | ||
953 | u32 mgmt[MANAGEMENT_MAX]; | ||
954 | u32 ctrl[CONTROL_MAX]; | ||
955 | u32 data_cnt; | ||
956 | u64 data_bytes; | ||
957 | }; | ||
958 | #else | ||
959 | struct traffic_stats { | ||
960 | u64 data_bytes; | ||
961 | }; | ||
962 | #endif | ||
963 | |||
922 | #define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */ | 964 | #define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */ |
923 | 965 | ||
924 | struct iwl_priv { | 966 | struct iwl_priv { |
@@ -1064,10 +1106,8 @@ struct iwl_priv { | |||
1064 | int last_rx_noise; /* From beacon statistics */ | 1106 | int last_rx_noise; /* From beacon statistics */ |
1065 | 1107 | ||
1066 | /* counts mgmt, ctl, and data packets */ | 1108 | /* counts mgmt, ctl, and data packets */ |
1067 | struct traffic_stats { | 1109 | struct traffic_stats tx_stats; |
1068 | u32 cnt; | 1110 | struct traffic_stats rx_stats; |
1069 | u64 bytes; | ||
1070 | } tx_stats[3], rx_stats[3]; | ||
1071 | 1111 | ||
1072 | /* counts interrupts */ | 1112 | /* counts interrupts */ |
1073 | struct isr_statistics isr_stats; | 1113 | struct isr_statistics isr_stats; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index b82ad15d5189..532c8d6cd8da 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
@@ -36,8 +36,6 @@ | |||
36 | #include "iwl-core.h" | 36 | #include "iwl-core.h" |
37 | 37 | ||
38 | 38 | ||
39 | #define IWL_CMD(x) case x: return #x | ||
40 | |||
41 | const char *get_cmd_string(u8 cmd) | 39 | const char *get_cmd_string(u8 cmd) |
42 | { | 40 | { |
43 | switch (cmd) { | 41 | switch (cmd) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 3d61cb43151c..f420c99e7240 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c | |||
@@ -272,7 +272,8 @@ static int iwl_get_blink_rate(struct iwl_priv *priv) | |||
272 | /* count both tx and rx traffic to be able to | 272 | /* count both tx and rx traffic to be able to |
273 | * handle traffic in either direction | 273 | * handle traffic in either direction |
274 | */ | 274 | */ |
275 | u64 current_tpt = priv->tx_stats[2].bytes + priv->rx_stats[2].bytes; | 275 | u64 current_tpt = priv->tx_stats.data_bytes + |
276 | priv->rx_stats.data_bytes; | ||
276 | s64 tpt = current_tpt - priv->led_tpt; | 277 | s64 tpt = current_tpt - priv->led_tpt; |
277 | 278 | ||
278 | if (tpt < 0) /* wraparound */ | 279 | if (tpt < 0) /* wraparound */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 55860037f98a..43b2fce4cbf0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -745,14 +745,6 @@ static void iwl_dbg_report_frame(struct iwl_priv *priv, | |||
745 | } | 745 | } |
746 | #endif | 746 | #endif |
747 | 747 | ||
748 | static void iwl_update_rx_stats(struct iwl_priv *priv, u16 fc, u16 len) | ||
749 | { | ||
750 | /* 0 - mgmt, 1 - cnt, 2 - data */ | ||
751 | int idx = (fc & IEEE80211_FCTL_FTYPE) >> 2; | ||
752 | priv->rx_stats[idx].cnt++; | ||
753 | priv->rx_stats[idx].bytes += len; | ||
754 | } | ||
755 | |||
756 | /* | 748 | /* |
757 | * returns non-zero if packet should be dropped | 749 | * returns non-zero if packet should be dropped |
758 | */ | 750 | */ |
@@ -930,7 +922,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
930 | iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) | 922 | iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) |
931 | return; | 923 | return; |
932 | 924 | ||
933 | iwl_update_rx_stats(priv, le16_to_cpu(hdr->frame_control), len); | 925 | iwl_update_stats(priv, false, hdr->frame_control, len); |
934 | memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats)); | 926 | memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats)); |
935 | ieee80211_rx_irqsafe(priv->hw, rxb->skb); | 927 | ieee80211_rx_irqsafe(priv->hw, rxb->skb); |
936 | priv->alloc_rxb_skb--; | 928 | priv->alloc_rxb_skb--; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index c85e54cb31d2..9b76bd41f214 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -668,14 +668,6 @@ static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv, | |||
668 | } | 668 | } |
669 | } | 669 | } |
670 | 670 | ||
671 | static void iwl_update_tx_stats(struct iwl_priv *priv, u16 fc, u16 len) | ||
672 | { | ||
673 | /* 0 - mgmt, 1 - cnt, 2 - data */ | ||
674 | int idx = (fc & IEEE80211_FCTL_FTYPE) >> 2; | ||
675 | priv->tx_stats[idx].cnt++; | ||
676 | priv->tx_stats[idx].bytes += len; | ||
677 | } | ||
678 | |||
679 | /* | 671 | /* |
680 | * start REPLY_TX command process | 672 | * start REPLY_TX command process |
681 | */ | 673 | */ |
@@ -813,8 +805,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
813 | /* set is_hcca to 0; it probably will never be implemented */ | 805 | /* set is_hcca to 0; it probably will never be implemented */ |
814 | iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0); | 806 | iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0); |
815 | 807 | ||
816 | iwl_update_tx_stats(priv, le16_to_cpu(fc), len); | 808 | iwl_update_stats(priv, true, fc, len); |
817 | |||
818 | /* | 809 | /* |
819 | * Use the first empty entry in this queue's command buffer array | 810 | * Use the first empty entry in this queue's command buffer array |
820 | * to contain the Tx command and MAC header concatenated together | 811 | * to contain the Tx command and MAC header concatenated together |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 4f5a3d035b0e..e5fa672e8390 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -599,6 +599,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
599 | tx->len = cpu_to_le16(len); | 599 | tx->len = cpu_to_le16(len); |
600 | 600 | ||
601 | iwl_dbg_log_tx_data_frame(priv, len, hdr); | 601 | iwl_dbg_log_tx_data_frame(priv, len, hdr); |
602 | iwl_update_stats(priv, true, fc, len); | ||
602 | tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; | 603 | tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; |
603 | tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; | 604 | tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; |
604 | 605 | ||