aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>2014-02-27 09:20:48 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-02-28 14:33:33 -0500
commitef28afdb1cbb01dd15840eae3786b84ddfa83c6a (patch)
treef2dc360cf30c1fe3b54f5eb483c30b44a21dc048
parent7b05b0ab89e692eb45b011169afb2359d5d92c6c (diff)
wil6210: dump_station initial support
Rx stats is not calculated per STA - just give some number Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c82
1 files changed, 66 insertions, 16 deletions
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index fa713ef8dc95..495347baf523 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -104,27 +104,21 @@ int wil_iftype_nl2wmi(enum nl80211_iftype type)
104 return -EOPNOTSUPP; 104 return -EOPNOTSUPP;
105} 105}
106 106
107static int wil_cfg80211_get_station(struct wiphy *wiphy, 107static int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid,
108 struct net_device *ndev, 108 struct station_info *sinfo)
109 u8 *mac, struct station_info *sinfo)
110{ 109{
111 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
112 int rc;
113
114 int cid = wil_find_cid(wil, mac);
115 struct wmi_notify_req_cmd cmd = { 110 struct wmi_notify_req_cmd cmd = {
116 .cid = cid, 111 .cid = cid,
117 .interval_usec = 0, 112 .interval_usec = 0,
118 }; 113 };
114 struct {
115 struct wil6210_mbox_hdr_wmi wmi;
116 struct wmi_notify_req_done_event evt;
117 } __packed reply;
118 int rc;
119 119
120 wil_info(wil, "%s(%pM) CID %d\n", __func__, mac, cid);
121 if (cid < 0)
122 return -ENOENT;
123
124 /* WMI_NOTIFY_REQ_DONE_EVENTID handler fills wil->stats.bf_mcs */
125 /* TODO: keep stats per CID */
126 rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd), 120 rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd),
127 WMI_NOTIFY_REQ_DONE_EVENTID, NULL, 0, 20); 121 WMI_NOTIFY_REQ_DONE_EVENTID, &reply, sizeof(reply), 20);
128 if (rc) 122 if (rc)
129 return rc; 123 return rc;
130 124
@@ -132,7 +126,7 @@ static int wil_cfg80211_get_station(struct wiphy *wiphy,
132 126
133 sinfo->filled |= STATION_INFO_TX_BITRATE; 127 sinfo->filled |= STATION_INFO_TX_BITRATE;
134 sinfo->txrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G; 128 sinfo->txrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
135 sinfo->txrate.mcs = wil->stats.bf_mcs; 129 sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs);
136 sinfo->filled |= STATION_INFO_RX_BITRATE; 130 sinfo->filled |= STATION_INFO_RX_BITRATE;
137 sinfo->rxrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G; 131 sinfo->rxrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
138 sinfo->rxrate.mcs = wil->stats.last_mcs_rx; 132 sinfo->rxrate.mcs = wil->stats.last_mcs_rx;
@@ -142,7 +136,62 @@ static int wil_cfg80211_get_station(struct wiphy *wiphy,
142 sinfo->signal = 12; /* TODO: provide real value */ 136 sinfo->signal = 12; /* TODO: provide real value */
143 } 137 }
144 138
145 return 0; 139 return rc;
140}
141
142static int wil_cfg80211_get_station(struct wiphy *wiphy,
143 struct net_device *ndev,
144 u8 *mac, struct station_info *sinfo)
145{
146 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
147 int rc;
148
149 int cid = wil_find_cid(wil, mac);
150
151 wil_info(wil, "%s(%pM) CID %d\n", __func__, mac, cid);
152 if (cid < 0)
153 return -ENOENT;
154
155 rc = wil_cid_fill_sinfo(wil, cid, sinfo);
156
157 return rc;
158}
159
160/*
161 * Find @idx-th active STA for station dump.
162 */
163static int wil_find_cid_by_idx(struct wil6210_priv *wil, int idx)
164{
165 int i;
166
167 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
168 if (wil->sta[i].status == wil_sta_unused)
169 continue;
170 if (idx == 0)
171 return i;
172 idx--;
173 }
174
175 return -ENOENT;
176}
177
178static int wil_cfg80211_dump_station(struct wiphy *wiphy,
179 struct net_device *dev, int idx,
180 u8 *mac, struct station_info *sinfo)
181{
182 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
183 int rc;
184 int cid = wil_find_cid_by_idx(wil, idx);
185
186 if (cid < 0)
187 return -ENOENT;
188
189 memcpy(mac, wil->sta[cid].addr, ETH_ALEN);
190 wil_info(wil, "%s(%pM) CID %d\n", __func__, mac, cid);
191
192 rc = wil_cid_fill_sinfo(wil, cid, sinfo);
193
194 return rc;
146} 195}
147 196
148static int wil_cfg80211_change_iface(struct wiphy *wiphy, 197static int wil_cfg80211_change_iface(struct wiphy *wiphy,
@@ -583,6 +632,7 @@ static struct cfg80211_ops wil_cfg80211_ops = {
583 .disconnect = wil_cfg80211_disconnect, 632 .disconnect = wil_cfg80211_disconnect,
584 .change_virtual_intf = wil_cfg80211_change_iface, 633 .change_virtual_intf = wil_cfg80211_change_iface,
585 .get_station = wil_cfg80211_get_station, 634 .get_station = wil_cfg80211_get_station,
635 .dump_station = wil_cfg80211_dump_station,
586 .remain_on_channel = wil_remain_on_channel, 636 .remain_on_channel = wil_remain_on_channel,
587 .cancel_remain_on_channel = wil_cancel_remain_on_channel, 637 .cancel_remain_on_channel = wil_cancel_remain_on_channel,
588 .mgmt_tx = wil_cfg80211_mgmt_tx, 638 .mgmt_tx = wil_cfg80211_mgmt_tx,