iwlwifi: Traffic type and counter for debugFs
[linux-2.6.git] / drivers / net / wireless / iwlwifi / iwl-core.c
index 1ae2ce3..202bc39 100644 (file)
@@ -3051,6 +3051,164 @@ void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv,
        }
 }
 EXPORT_SYMBOL(iwl_dbg_log_rx_data_frame);
+
+const char *get_mgmt_string(int cmd)
+{
+       switch (cmd) {
+               IWL_CMD(MANAGEMENT_ASSOC_REQ);
+               IWL_CMD(MANAGEMENT_ASSOC_RESP);
+               IWL_CMD(MANAGEMENT_REASSOC_REQ);
+               IWL_CMD(MANAGEMENT_REASSOC_RESP);
+               IWL_CMD(MANAGEMENT_PROBE_REQ);
+               IWL_CMD(MANAGEMENT_PROBE_RESP);
+               IWL_CMD(MANAGEMENT_BEACON);
+               IWL_CMD(MANAGEMENT_ATIM);
+               IWL_CMD(MANAGEMENT_DISASSOC);
+               IWL_CMD(MANAGEMENT_AUTH);
+               IWL_CMD(MANAGEMENT_DEAUTH);
+               IWL_CMD(MANAGEMENT_ACTION);
+       default:
+               return "UNKNOWN";
+
+       }
+}
+
+const char *get_ctrl_string(int cmd)
+{
+       switch (cmd) {
+               IWL_CMD(CONTROL_BACK_REQ);
+               IWL_CMD(CONTROL_BACK);
+               IWL_CMD(CONTROL_PSPOLL);
+               IWL_CMD(CONTROL_RTS);
+               IWL_CMD(CONTROL_CTS);
+               IWL_CMD(CONTROL_ACK);
+               IWL_CMD(CONTROL_CFEND);
+               IWL_CMD(CONTROL_CFENDACK);
+       default:
+               return "UNKNOWN";
+
+       }
+}
+
+void iwl_clear_tx_stats(struct iwl_priv *priv)
+{
+       memset(&priv->tx_stats, 0, sizeof(struct traffic_stats));
+
+}
+
+void iwl_clear_rx_stats(struct iwl_priv *priv)
+{
+       memset(&priv->rx_stats, 0, sizeof(struct traffic_stats));
+}
+
+/*
+ * if CONFIG_IWLWIFI_DEBUGFS defined, iwl_update_stats function will
+ * record all the MGMT, CTRL and DATA pkt for both TX and Rx pass.
+ * Use debugFs to display the rx/rx_statistics
+ * if CONFIG_IWLWIFI_DEBUGFS not being defined, then no MGMT and CTRL
+ * information will be recorded, but DATA pkt still will be recorded
+ * for the reason of iwl_led.c need to control the led blinking based on
+ * number of tx and rx data.
+ *
+ */
+void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
+{
+       struct traffic_stats    *stats;
+
+       if (is_tx)
+               stats = &priv->tx_stats;
+       else
+               stats = &priv->rx_stats;
+
+       if (ieee80211_is_mgmt(fc)) {
+               switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
+               case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
+                       stats->mgmt[MANAGEMENT_ASSOC_REQ]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
+                       stats->mgmt[MANAGEMENT_ASSOC_RESP]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
+                       stats->mgmt[MANAGEMENT_REASSOC_REQ]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
+                       stats->mgmt[MANAGEMENT_REASSOC_RESP]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):
+                       stats->mgmt[MANAGEMENT_PROBE_REQ]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
+                       stats->mgmt[MANAGEMENT_PROBE_RESP]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_BEACON):
+                       stats->mgmt[MANAGEMENT_BEACON]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_ATIM):
+                       stats->mgmt[MANAGEMENT_ATIM]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
+                       stats->mgmt[MANAGEMENT_DISASSOC]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_AUTH):
+                       stats->mgmt[MANAGEMENT_AUTH]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
+                       stats->mgmt[MANAGEMENT_DEAUTH]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_ACTION):
+                       stats->mgmt[MANAGEMENT_ACTION]++;
+                       break;
+               }
+       } else if (ieee80211_is_ctl(fc)) {
+               switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
+               case cpu_to_le16(IEEE80211_STYPE_BACK_REQ):
+                       stats->ctrl[CONTROL_BACK_REQ]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_BACK):
+                       stats->ctrl[CONTROL_BACK]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_PSPOLL):
+                       stats->ctrl[CONTROL_PSPOLL]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_RTS):
+                       stats->ctrl[CONTROL_RTS]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_CTS):
+                       stats->ctrl[CONTROL_CTS]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_ACK):
+                       stats->ctrl[CONTROL_ACK]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_CFEND):
+                       stats->ctrl[CONTROL_CFEND]++;
+                       break;
+               case cpu_to_le16(IEEE80211_STYPE_CFENDACK):
+                       stats->ctrl[CONTROL_CFENDACK]++;
+                       break;
+               }
+       } else {
+               /* data */
+               stats->data_cnt++;
+               stats->data_bytes += len;
+       }
+}
+EXPORT_SYMBOL(iwl_update_stats);
+
+#else
+void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
+{
+       struct traffic_stats    *stats;
+
+       if (is_tx)
+               stats = &priv->tx_stats;
+       else
+               stats = &priv->rx_stats;
+
+       if (ieee80211_is_data(fc)) {
+               /* data */
+               stats->data_bytes += len;
+       }
+}
 #endif
 
 #ifdef CONFIG_PM