aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorThomas Pedersen <c_tpeder@qca.qualcomm.com>2012-07-17 22:39:55 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2012-10-24 04:49:33 -0400
commit279b2862ee6ba9ee950c02044142f8ea137c302e (patch)
treea220670d2ad97c18cffe49da9262769d932fd976 /drivers/net
parentbf744f11788280bcbd9bb8ec62974274b72a75bf (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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c22
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h4
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c47
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.h35
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 a624a0c5e5f..0194617ff30 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
3329static 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
3329static const struct ieee80211_txrx_stypes 3350static const struct ieee80211_txrx_stypes
3330ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = { 3351ath6kl_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
3397void ath6kl_cfg80211_stop(struct ath6kl_vif *vif) 3419void 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 f16f6ba481d..a754a153cc8 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 9673f277817..4762fa57063 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
1534static 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
1559int 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
1534int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi) 1578int 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 b5deaffb79e..8e8846f1b1a 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
637enum wmi_mgmt_frame_type { 643enum 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
1469struct wmi_ready_event_2 { 1489struct 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 */
2120struct wmi_txe_notify_cmd {
2121 __le32 rate;
2122 __le32 pkts;
2123 __le32 intvl;
2124} __packed;
2125
2126/* WMI_TXE_NOTIFY_EVENTID */
2127struct 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
2101struct wmi_pmkid { 2134struct wmi_pmkid {
@@ -2610,6 +2643,8 @@ int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on);
2610int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, 2643int 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);
2612int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable); 2645int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable);
2646int 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 */
2615int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable); 2650int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable);