diff options
author | Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> | 2014-02-27 09:20:48 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-02-28 14:33:33 -0500 |
commit | ef28afdb1cbb01dd15840eae3786b84ddfa83c6a (patch) | |
tree | f2dc360cf30c1fe3b54f5eb483c30b44a21dc048 | |
parent | 7b05b0ab89e692eb45b011169afb2359d5d92c6c (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.c | 82 |
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 | ||
107 | static int wil_cfg80211_get_station(struct wiphy *wiphy, | 107 | static 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 | |||
142 | static 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 | */ | ||
163 | static 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 | |||
178 | static 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 | ||
148 | static int wil_cfg80211_change_iface(struct wiphy *wiphy, | 197 | static 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, |