diff options
author | Thomas Pedersen <c_tpeder@qca.qualcomm.com> | 2012-07-17 22:39:55 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2012-10-24 04:49:33 -0400 |
commit | 279b2862ee6ba9ee950c02044142f8ea137c302e (patch) | |
tree | a220670d2ad97c18cffe49da9262769d932fd976 | |
parent | bf744f11788280bcbd9bb8ec62974274b72a75bf (diff) |
ath6kl: support TX error rate notification
The ath6kl firmware can monitor a connection and report when a certain
TX failure threshold is crossed. Support this configuration and event
reporting on compatible firmwares.
Signed-off-by: Thomas Pedersen <c_tpeder@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/cfg80211.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/core.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/wmi.c | 47 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/wmi.h | 35 |
4 files changed, 108 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index a624a0c5e5f5..0194617ff30e 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -3326,6 +3326,27 @@ static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy, | |||
3326 | mask); | 3326 | mask); |
3327 | } | 3327 | } |
3328 | 3328 | ||
3329 | static int ath6kl_cfg80211_set_txe_config(struct wiphy *wiphy, | ||
3330 | struct net_device *dev, | ||
3331 | u32 rate, u32 pkts, u32 intvl) | ||
3332 | { | ||
3333 | struct ath6kl *ar = ath6kl_priv(dev); | ||
3334 | struct ath6kl_vif *vif = netdev_priv(dev); | ||
3335 | |||
3336 | if (vif->nw_type != INFRA_NETWORK || | ||
3337 | !test_bit(ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, ar->fw_capabilities)) | ||
3338 | return -EOPNOTSUPP; | ||
3339 | |||
3340 | if (vif->sme_state != SME_CONNECTED) | ||
3341 | return -ENOTCONN; | ||
3342 | |||
3343 | /* save this since the firmware won't report the interval */ | ||
3344 | vif->txe_intvl = intvl; | ||
3345 | |||
3346 | return ath6kl_wmi_set_txe_notify(ar->wmi, vif->fw_vif_idx, | ||
3347 | rate, pkts, intvl); | ||
3348 | } | ||
3349 | |||
3329 | static const struct ieee80211_txrx_stypes | 3350 | static const struct ieee80211_txrx_stypes |
3330 | ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = { | 3351 | ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = { |
3331 | [NL80211_IFTYPE_STATION] = { | 3352 | [NL80211_IFTYPE_STATION] = { |
@@ -3392,6 +3413,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = { | |||
3392 | .sched_scan_start = ath6kl_cfg80211_sscan_start, | 3413 | .sched_scan_start = ath6kl_cfg80211_sscan_start, |
3393 | .sched_scan_stop = ath6kl_cfg80211_sscan_stop, | 3414 | .sched_scan_stop = ath6kl_cfg80211_sscan_stop, |
3394 | .set_bitrate_mask = ath6kl_cfg80211_set_bitrate, | 3415 | .set_bitrate_mask = ath6kl_cfg80211_set_bitrate, |
3416 | .set_cqm_txe_config = ath6kl_cfg80211_set_txe_config, | ||
3395 | }; | 3417 | }; |
3396 | 3418 | ||
3397 | void ath6kl_cfg80211_stop(struct ath6kl_vif *vif) | 3419 | void ath6kl_cfg80211_stop(struct ath6kl_vif *vif) |
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index f16f6ba481d5..a754a153cc81 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h | |||
@@ -121,6 +121,9 @@ enum ath6kl_fw_capability { | |||
121 | /* FW sets mac_addr[4] ^= 0x80 for newly created interfaces */ | 121 | /* FW sets mac_addr[4] ^= 0x80 for newly created interfaces */ |
122 | ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR, | 122 | ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR, |
123 | 123 | ||
124 | /* Firmware supports TX error rate notification */ | ||
125 | ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, | ||
126 | |||
124 | /* this needs to be last */ | 127 | /* this needs to be last */ |
125 | ATH6KL_FW_CAPABILITY_MAX, | 128 | ATH6KL_FW_CAPABILITY_MAX, |
126 | }; | 129 | }; |
@@ -593,6 +596,7 @@ struct ath6kl_vif { | |||
593 | u16 assoc_bss_beacon_int; | 596 | u16 assoc_bss_beacon_int; |
594 | u16 listen_intvl_t; | 597 | u16 listen_intvl_t; |
595 | u16 bmiss_time_t; | 598 | u16 bmiss_time_t; |
599 | u32 txe_intvl; | ||
596 | u16 bg_scan_period; | 600 | u16 bg_scan_period; |
597 | u8 assoc_bss_dtim_period; | 601 | u8 assoc_bss_dtim_period; |
598 | struct net_device_stats net_stats; | 602 | struct net_device_stats net_stats; |
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 9673f2778176..4762fa570630 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c | |||
@@ -1531,6 +1531,50 @@ static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
1531 | return 0; | 1531 | return 0; |
1532 | } | 1532 | } |
1533 | 1533 | ||
1534 | static int ath6kl_wmi_txe_notify_event_rx(struct wmi *wmi, u8 *datap, int len, | ||
1535 | struct ath6kl_vif *vif) | ||
1536 | { | ||
1537 | struct wmi_txe_notify_event *ev; | ||
1538 | u32 rate, pkts; | ||
1539 | |||
1540 | if (len < sizeof(*ev)) | ||
1541 | return -EINVAL; | ||
1542 | |||
1543 | if (vif->sme_state != SME_CONNECTED) | ||
1544 | return -ENOTCONN; | ||
1545 | |||
1546 | ev = (struct wmi_txe_notify_event *) datap; | ||
1547 | rate = le32_to_cpu(ev->rate); | ||
1548 | pkts = le32_to_cpu(ev->pkts); | ||
1549 | |||
1550 | ath6kl_dbg(ATH6KL_DBG_WMI, "TXE notify event: peer %pM rate %d% pkts %d intvl %ds\n", | ||
1551 | vif->bssid, rate, pkts, vif->txe_intvl); | ||
1552 | |||
1553 | cfg80211_cqm_txe_notify(vif->ndev, vif->bssid, pkts, | ||
1554 | rate, vif->txe_intvl, GFP_KERNEL); | ||
1555 | |||
1556 | return 0; | ||
1557 | } | ||
1558 | |||
1559 | int ath6kl_wmi_set_txe_notify(struct wmi *wmi, u8 idx, | ||
1560 | u32 rate, u32 pkts, u32 intvl) | ||
1561 | { | ||
1562 | struct sk_buff *skb; | ||
1563 | struct wmi_txe_notify_cmd *cmd; | ||
1564 | |||
1565 | skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); | ||
1566 | if (!skb) | ||
1567 | return -ENOMEM; | ||
1568 | |||
1569 | cmd = (struct wmi_txe_notify_cmd *) skb->data; | ||
1570 | cmd->rate = cpu_to_le32(rate); | ||
1571 | cmd->pkts = cpu_to_le32(pkts); | ||
1572 | cmd->intvl = cpu_to_le32(intvl); | ||
1573 | |||
1574 | return ath6kl_wmi_cmd_send(wmi, idx, skb, WMI_SET_TXE_NOTIFY_CMDID, | ||
1575 | NO_SYNC_WMIFLAG); | ||
1576 | } | ||
1577 | |||
1534 | int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi) | 1578 | int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi) |
1535 | { | 1579 | { |
1536 | struct sk_buff *skb; | 1580 | struct sk_buff *skb; |
@@ -3768,6 +3812,9 @@ static int ath6kl_wmi_proc_events_vif(struct wmi *wmi, u16 if_idx, u16 cmd_id, | |||
3768 | case WMI_RX_ACTION_EVENTID: | 3812 | case WMI_RX_ACTION_EVENTID: |
3769 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n"); | 3813 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n"); |
3770 | return ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif); | 3814 | return ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif); |
3815 | case WMI_TXE_NOTIFY_EVENTID: | ||
3816 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TXE_NOTIFY_EVENTID\n"); | ||
3817 | return ath6kl_wmi_txe_notify_event_rx(wmi, datap, len, vif); | ||
3771 | default: | 3818 | default: |
3772 | ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", cmd_id); | 3819 | ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", cmd_id); |
3773 | return -EINVAL; | 3820 | return -EINVAL; |
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index b5deaffb79e4..8e8846f1b1a5 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h | |||
@@ -632,6 +632,12 @@ enum wmi_cmd_id { | |||
632 | WMI_SET_REGDOMAIN_CMDID, | 632 | WMI_SET_REGDOMAIN_CMDID, |
633 | 633 | ||
634 | WMI_SET_RSSI_FILTER_CMDID, | 634 | WMI_SET_RSSI_FILTER_CMDID, |
635 | |||
636 | WMI_SET_KEEP_ALIVE_EXT, | ||
637 | |||
638 | WMI_VOICE_DETECTION_ENABLE_CMDID, | ||
639 | |||
640 | WMI_SET_TXE_NOTIFY_CMDID, | ||
635 | }; | 641 | }; |
636 | 642 | ||
637 | enum wmi_mgmt_frame_type { | 643 | enum wmi_mgmt_frame_type { |
@@ -1464,6 +1470,20 @@ enum wmi_event_id { | |||
1464 | WMI_P2P_CAPABILITIES_EVENTID, | 1470 | WMI_P2P_CAPABILITIES_EVENTID, |
1465 | WMI_RX_ACTION_EVENTID, | 1471 | WMI_RX_ACTION_EVENTID, |
1466 | WMI_P2P_INFO_EVENTID, | 1472 | WMI_P2P_INFO_EVENTID, |
1473 | |||
1474 | /* WPS Events */ | ||
1475 | WMI_WPS_GET_STATUS_EVENTID, | ||
1476 | WMI_WPS_PROFILE_EVENTID, | ||
1477 | |||
1478 | /* more P2P events */ | ||
1479 | WMI_NOA_INFO_EVENTID, | ||
1480 | WMI_OPPPS_INFO_EVENTID, | ||
1481 | WMI_PORT_STATUS_EVENTID, | ||
1482 | |||
1483 | /* 802.11w */ | ||
1484 | WMI_GET_RSN_CAP_EVENTID, | ||
1485 | |||
1486 | WMI_TXE_NOTIFY_EVENTID, | ||
1467 | }; | 1487 | }; |
1468 | 1488 | ||
1469 | struct wmi_ready_event_2 { | 1489 | struct wmi_ready_event_2 { |
@@ -2096,6 +2116,19 @@ struct wmi_del_wow_pattern_cmd { | |||
2096 | __le16 filter_id; | 2116 | __le16 filter_id; |
2097 | } __packed; | 2117 | } __packed; |
2098 | 2118 | ||
2119 | /* WMI_SET_TXE_NOTIFY_CMDID */ | ||
2120 | struct wmi_txe_notify_cmd { | ||
2121 | __le32 rate; | ||
2122 | __le32 pkts; | ||
2123 | __le32 intvl; | ||
2124 | } __packed; | ||
2125 | |||
2126 | /* WMI_TXE_NOTIFY_EVENTID */ | ||
2127 | struct wmi_txe_notify_event { | ||
2128 | __le32 rate; | ||
2129 | __le32 pkts; | ||
2130 | } __packed; | ||
2131 | |||
2099 | /* WMI_SET_AKMP_PARAMS_CMD */ | 2132 | /* WMI_SET_AKMP_PARAMS_CMD */ |
2100 | 2133 | ||
2101 | struct wmi_pmkid { | 2134 | struct wmi_pmkid { |
@@ -2610,6 +2643,8 @@ int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on); | |||
2610 | int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, | 2643 | int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, |
2611 | u8 *filter, bool add_filter); | 2644 | u8 *filter, bool add_filter); |
2612 | int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable); | 2645 | int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable); |
2646 | int ath6kl_wmi_set_txe_notify(struct wmi *wmi, u8 idx, | ||
2647 | u32 rate, u32 pkts, u32 intvl); | ||
2613 | 2648 | ||
2614 | /* AP mode uAPSD */ | 2649 | /* AP mode uAPSD */ |
2615 | int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable); | 2650 | int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable); |