aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath10k/wmi.c
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2014-09-18 09:21:24 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2014-09-23 05:31:25 -0400
commit5c01aa3de918c0afc1b338df6d7162d461ad3a55 (patch)
tree0a1adde8f83368f7f5a1a3368f97ece6a7bd8445 /drivers/net/wireless/ath/ath10k/wmi.c
parentb79b9baac4f9ecec85353b76a45ae2eda4a1e41d (diff)
ath10k: deduplicate wmi service ready logic
The logic responsible for processing the event is no different across different firmware binaries. The difference that needs to be dealt with is the ABI of data structures. The intermediate structure uses __le32 to avoid extra memory allocations to byteswap variable-length substructures (i.e. host mem chunks). Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/wmi.c')
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c237
1 files changed, 117 insertions, 120 deletions
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index cec0c2839e5b..a7c11b292bf4 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -2205,30 +2205,113 @@ static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id,
2205 return 0; 2205 return 0;
2206} 2206}
2207 2207
2208static int ath10k_wmi_main_pull_svc_rdy_ev(struct sk_buff *skb,
2209 struct wmi_svc_rdy_ev_arg *arg)
2210{
2211 struct wmi_service_ready_event *ev;
2212 size_t i, n;
2213
2214 if (skb->len < sizeof(*ev))
2215 return -EPROTO;
2216
2217 ev = (void *)skb->data;
2218 skb_pull(skb, sizeof(*ev));
2219 arg->min_tx_power = ev->hw_min_tx_power;
2220 arg->max_tx_power = ev->hw_max_tx_power;
2221 arg->ht_cap = ev->ht_cap_info;
2222 arg->vht_cap = ev->vht_cap_info;
2223 arg->sw_ver0 = ev->sw_version;
2224 arg->sw_ver1 = ev->sw_version_1;
2225 arg->phy_capab = ev->phy_capability;
2226 arg->num_rf_chains = ev->num_rf_chains;
2227 arg->eeprom_rd = ev->hal_reg_capabilities.eeprom_rd;
2228 arg->num_mem_reqs = ev->num_mem_reqs;
2229 arg->service_map = ev->wmi_service_bitmap;
2230
2231 n = min_t(size_t, __le32_to_cpu(arg->num_mem_reqs),
2232 ARRAY_SIZE(arg->mem_reqs));
2233 for (i = 0; i < n; i++)
2234 arg->mem_reqs[i] = &ev->mem_reqs[i];
2235
2236 if (skb->len <
2237 __le32_to_cpu(arg->num_mem_reqs) * sizeof(arg->mem_reqs[0]))
2238 return -EPROTO;
2239
2240 return 0;
2241}
2242
2243static int ath10k_wmi_10x_pull_svc_rdy_ev(struct sk_buff *skb,
2244 struct wmi_svc_rdy_ev_arg *arg)
2245{
2246 struct wmi_10x_service_ready_event *ev;
2247 int i, n;
2248
2249 if (skb->len < sizeof(*ev))
2250 return -EPROTO;
2251
2252 ev = (void *)skb->data;
2253 skb_pull(skb, sizeof(*ev));
2254 arg->min_tx_power = ev->hw_min_tx_power;
2255 arg->max_tx_power = ev->hw_max_tx_power;
2256 arg->ht_cap = ev->ht_cap_info;
2257 arg->vht_cap = ev->vht_cap_info;
2258 arg->sw_ver0 = ev->sw_version;
2259 arg->phy_capab = ev->phy_capability;
2260 arg->num_rf_chains = ev->num_rf_chains;
2261 arg->eeprom_rd = ev->hal_reg_capabilities.eeprom_rd;
2262 arg->num_mem_reqs = ev->num_mem_reqs;
2263 arg->service_map = ev->wmi_service_bitmap;
2264
2265 n = min_t(size_t, __le32_to_cpu(arg->num_mem_reqs),
2266 ARRAY_SIZE(arg->mem_reqs));
2267 for (i = 0; i < n; i++)
2268 arg->mem_reqs[i] = &ev->mem_reqs[i];
2269
2270 if (skb->len <
2271 __le32_to_cpu(arg->num_mem_reqs) * sizeof(arg->mem_reqs[0]))
2272 return -EPROTO;
2273
2274 return 0;
2275}
2276
2208static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, 2277static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar,
2209 struct sk_buff *skb) 2278 struct sk_buff *skb)
2210{ 2279{
2211 struct wmi_service_ready_event *ev = (void *)skb->data; 2280 struct wmi_svc_rdy_ev_arg arg = {};
2281 u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i;
2212 DECLARE_BITMAP(svc_bmap, WMI_SERVICE_MAX) = {}; 2282 DECLARE_BITMAP(svc_bmap, WMI_SERVICE_MAX) = {};
2283 int ret;
2213 2284
2214 if (skb->len < sizeof(*ev)) { 2285 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
2215 ath10k_warn(ar, "Service ready event was %d B but expected %zu B. Wrong firmware version?\n", 2286 ret = ath10k_wmi_10x_pull_svc_rdy_ev(skb, &arg);
2216 skb->len, sizeof(*ev)); 2287 wmi_10x_svc_map(arg.service_map, svc_bmap);
2288 } else {
2289 ret = ath10k_wmi_main_pull_svc_rdy_ev(skb, &arg);
2290 wmi_main_svc_map(arg.service_map, svc_bmap);
2291 }
2292
2293 if (ret) {
2294 ath10k_warn(ar, "failed to parse service ready: %d\n", ret);
2217 return; 2295 return;
2218 } 2296 }
2219 2297
2220 ar->hw_min_tx_power = __le32_to_cpu(ev->hw_min_tx_power); 2298 ar->hw_min_tx_power = __le32_to_cpu(arg.min_tx_power);
2221 ar->hw_max_tx_power = __le32_to_cpu(ev->hw_max_tx_power); 2299 ar->hw_max_tx_power = __le32_to_cpu(arg.max_tx_power);
2222 ar->ht_cap_info = __le32_to_cpu(ev->ht_cap_info); 2300 ar->ht_cap_info = __le32_to_cpu(arg.ht_cap);
2223 ar->vht_cap_info = __le32_to_cpu(ev->vht_cap_info); 2301 ar->vht_cap_info = __le32_to_cpu(arg.vht_cap);
2224 ar->fw_version_major = 2302 ar->fw_version_major =
2225 (__le32_to_cpu(ev->sw_version) & 0xff000000) >> 24; 2303 (__le32_to_cpu(arg.sw_ver0) & 0xff000000) >> 24;
2226 ar->fw_version_minor = (__le32_to_cpu(ev->sw_version) & 0x00ffffff); 2304 ar->fw_version_minor = (__le32_to_cpu(arg.sw_ver0) & 0x00ffffff);
2227 ar->fw_version_release = 2305 ar->fw_version_release =
2228 (__le32_to_cpu(ev->sw_version_1) & 0xffff0000) >> 16; 2306 (__le32_to_cpu(arg.sw_ver1) & 0xffff0000) >> 16;
2229 ar->fw_version_build = (__le32_to_cpu(ev->sw_version_1) & 0x0000ffff); 2307 ar->fw_version_build = (__le32_to_cpu(arg.sw_ver1) & 0x0000ffff);
2230 ar->phy_capability = __le32_to_cpu(ev->phy_capability); 2308 ar->phy_capability = __le32_to_cpu(arg.phy_capab);
2231 ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains); 2309 ar->num_rf_chains = __le32_to_cpu(arg.num_rf_chains);
2310 ar->ath_common.regulatory.current_rd = __le32_to_cpu(arg.eeprom_rd);
2311
2312 ath10k_debug_read_service_map(ar, svc_bmap, sizeof(svc_bmap));
2313 ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ",
2314 arg.service_map, sizeof(arg.service_map));
2232 2315
2233 /* only manually set fw features when not using FW IE format */ 2316 /* only manually set fw features when not using FW IE format */
2234 if (ar->fw_api == 1 && ar->fw_version_build > 636) 2317 if (ar->fw_api == 1 && ar->fw_version_build > 636)
@@ -2243,14 +2326,6 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar,
2243 ar->supp_tx_chainmask = (1 << ar->num_rf_chains) - 1; 2326 ar->supp_tx_chainmask = (1 << ar->num_rf_chains) - 1;
2244 ar->supp_rx_chainmask = (1 << ar->num_rf_chains) - 1; 2327 ar->supp_rx_chainmask = (1 << ar->num_rf_chains) - 1;
2245 2328
2246 ar->ath_common.regulatory.current_rd =
2247 __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd);
2248
2249 wmi_main_svc_map(ev->wmi_service_bitmap, svc_bmap);
2250 ath10k_debug_read_service_map(ar, svc_bmap, sizeof(svc_bmap));
2251 ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ",
2252 ev->wmi_service_bitmap, sizeof(ev->wmi_service_bitmap));
2253
2254 if (strlen(ar->hw->wiphy->fw_version) == 0) { 2329 if (strlen(ar->hw->wiphy->fw_version) == 0) {
2255 snprintf(ar->hw->wiphy->fw_version, 2330 snprintf(ar->hw->wiphy->fw_version,
2256 sizeof(ar->hw->wiphy->fw_version), 2331 sizeof(ar->hw->wiphy->fw_version),
@@ -2261,96 +2336,18 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar,
2261 ar->fw_version_build); 2336 ar->fw_version_build);
2262 } 2337 }
2263 2338
2264 /* FIXME: it probably should be better to support this */ 2339 num_mem_reqs = __le32_to_cpu(arg.num_mem_reqs);
2265 if (__le32_to_cpu(ev->num_mem_reqs) > 0) { 2340 if (num_mem_reqs > WMI_MAX_MEM_REQS) {
2266 ath10k_warn(ar, "target requested %d memory chunks; ignoring\n",
2267 __le32_to_cpu(ev->num_mem_reqs));
2268 }
2269
2270 ath10k_dbg(ar, ATH10K_DBG_WMI,
2271 "wmi event service ready sw_ver 0x%08x sw_ver1 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u num_rf_chains %u\n",
2272 __le32_to_cpu(ev->sw_version),
2273 __le32_to_cpu(ev->sw_version_1),
2274 __le32_to_cpu(ev->abi_version),
2275 __le32_to_cpu(ev->phy_capability),
2276 __le32_to_cpu(ev->ht_cap_info),
2277 __le32_to_cpu(ev->vht_cap_info),
2278 __le32_to_cpu(ev->vht_supp_mcs),
2279 __le32_to_cpu(ev->sys_cap_info),
2280 __le32_to_cpu(ev->num_mem_reqs),
2281 __le32_to_cpu(ev->num_rf_chains));
2282
2283 complete(&ar->wmi.service_ready);
2284}
2285
2286static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar,
2287 struct sk_buff *skb)
2288{
2289 u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i;
2290 int ret;
2291 struct wmi_service_ready_event_10x *ev = (void *)skb->data;
2292 DECLARE_BITMAP(svc_bmap, WMI_SERVICE_MAX) = {};
2293
2294 if (skb->len < sizeof(*ev)) {
2295 ath10k_warn(ar, "Service ready event was %d B but expected %zu B. Wrong firmware version?\n",
2296 skb->len, sizeof(*ev));
2297 return;
2298 }
2299
2300 ar->hw_min_tx_power = __le32_to_cpu(ev->hw_min_tx_power);
2301 ar->hw_max_tx_power = __le32_to_cpu(ev->hw_max_tx_power);
2302 ar->ht_cap_info = __le32_to_cpu(ev->ht_cap_info);
2303 ar->vht_cap_info = __le32_to_cpu(ev->vht_cap_info);
2304 ar->fw_version_major =
2305 (__le32_to_cpu(ev->sw_version) & 0xff000000) >> 24;
2306 ar->fw_version_minor = (__le32_to_cpu(ev->sw_version) & 0x00ffffff);
2307 ar->phy_capability = __le32_to_cpu(ev->phy_capability);
2308 ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains);
2309
2310 if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) {
2311 ath10k_warn(ar, "hardware advertises support for more spatial streams than it should (%d > %d)\n",
2312 ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM);
2313 ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM;
2314 }
2315
2316 ar->supp_tx_chainmask = (1 << ar->num_rf_chains) - 1;
2317 ar->supp_rx_chainmask = (1 << ar->num_rf_chains) - 1;
2318
2319 ar->ath_common.regulatory.current_rd =
2320 __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd);
2321
2322 wmi_10x_svc_map(ev->wmi_service_bitmap, svc_bmap);
2323 ath10k_debug_read_service_map(ar, svc_bmap, sizeof(svc_bmap));
2324 ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ",
2325 ev->wmi_service_bitmap, sizeof(ev->wmi_service_bitmap));
2326
2327 if (strlen(ar->hw->wiphy->fw_version) == 0) {
2328 snprintf(ar->hw->wiphy->fw_version,
2329 sizeof(ar->hw->wiphy->fw_version),
2330 "%u.%u",
2331 ar->fw_version_major,
2332 ar->fw_version_minor);
2333 }
2334
2335 num_mem_reqs = __le32_to_cpu(ev->num_mem_reqs);
2336
2337 if (num_mem_reqs > ATH10K_MAX_MEM_REQS) {
2338 ath10k_warn(ar, "requested memory chunks number (%d) exceeds the limit\n", 2341 ath10k_warn(ar, "requested memory chunks number (%d) exceeds the limit\n",
2339 num_mem_reqs); 2342 num_mem_reqs);
2340 return; 2343 return;
2341 } 2344 }
2342 2345
2343 if (!num_mem_reqs)
2344 goto exit;
2345
2346 ath10k_dbg(ar, ATH10K_DBG_WMI, "firmware has requested %d memory chunks\n",
2347 num_mem_reqs);
2348
2349 for (i = 0; i < num_mem_reqs; ++i) { 2346 for (i = 0; i < num_mem_reqs; ++i) {
2350 req_id = __le32_to_cpu(ev->mem_reqs[i].req_id); 2347 req_id = __le32_to_cpu(arg.mem_reqs[i]->req_id);
2351 num_units = __le32_to_cpu(ev->mem_reqs[i].num_units); 2348 num_units = __le32_to_cpu(arg.mem_reqs[i]->num_units);
2352 unit_size = __le32_to_cpu(ev->mem_reqs[i].unit_size); 2349 unit_size = __le32_to_cpu(arg.mem_reqs[i]->unit_size);
2353 num_unit_info = __le32_to_cpu(ev->mem_reqs[i].num_unit_info); 2350 num_unit_info = __le32_to_cpu(arg.mem_reqs[i]->num_unit_info);
2354 2351
2355 if (num_unit_info & NUM_UNITS_IS_NUM_PEERS) 2352 if (num_unit_info & NUM_UNITS_IS_NUM_PEERS)
2356 /* number of units to allocate is number of 2353 /* number of units to allocate is number of
@@ -2364,7 +2361,7 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar,
2364 ath10k_dbg(ar, ATH10K_DBG_WMI, 2361 ath10k_dbg(ar, ATH10K_DBG_WMI,
2365 "wmi mem_req_id %d num_units %d num_unit_info %d unit size %d actual units %d\n", 2362 "wmi mem_req_id %d num_units %d num_unit_info %d unit size %d actual units %d\n",
2366 req_id, 2363 req_id,
2367 __le32_to_cpu(ev->mem_reqs[i].num_units), 2364 __le32_to_cpu(arg.mem_reqs[i]->num_units),
2368 num_unit_info, 2365 num_unit_info,
2369 unit_size, 2366 unit_size,
2370 num_units); 2367 num_units);
@@ -2375,18 +2372,18 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar,
2375 return; 2372 return;
2376 } 2373 }
2377 2374
2378exit:
2379 ath10k_dbg(ar, ATH10K_DBG_WMI, 2375 ath10k_dbg(ar, ATH10K_DBG_WMI,
2380 "wmi event service ready sw_ver 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u num_rf_chains %u\n", 2376 "wmi event service ready min_tx_power 0x%08x max_tx_power 0x%08x ht_cap 0x%08x vht_cap 0x%08x sw_ver0 0x%08x sw_ver1 0x%08x phy_capab 0x%08x num_rf_chains 0x%08x eeprom_rd 0x%08x num_mem_reqs 0x%08x\n",
2381 __le32_to_cpu(ev->sw_version), 2377 __le32_to_cpu(arg.min_tx_power),
2382 __le32_to_cpu(ev->abi_version), 2378 __le32_to_cpu(arg.max_tx_power),
2383 __le32_to_cpu(ev->phy_capability), 2379 __le32_to_cpu(arg.ht_cap),
2384 __le32_to_cpu(ev->ht_cap_info), 2380 __le32_to_cpu(arg.vht_cap),
2385 __le32_to_cpu(ev->vht_cap_info), 2381 __le32_to_cpu(arg.sw_ver0),
2386 __le32_to_cpu(ev->vht_supp_mcs), 2382 __le32_to_cpu(arg.sw_ver1),
2387 __le32_to_cpu(ev->sys_cap_info), 2383 __le32_to_cpu(arg.phy_capab),
2388 __le32_to_cpu(ev->num_mem_reqs), 2384 __le32_to_cpu(arg.num_rf_chains),
2389 __le32_to_cpu(ev->num_rf_chains)); 2385 __le32_to_cpu(arg.eeprom_rd),
2386 __le32_to_cpu(arg.num_mem_reqs));
2390 2387
2391 complete(&ar->wmi.service_ready); 2388 complete(&ar->wmi.service_ready);
2392} 2389}
@@ -2634,7 +2631,7 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb)
2634 ath10k_wmi_event_vdev_resume_req(ar, skb); 2631 ath10k_wmi_event_vdev_resume_req(ar, skb);
2635 break; 2632 break;
2636 case WMI_10X_SERVICE_READY_EVENTID: 2633 case WMI_10X_SERVICE_READY_EVENTID:
2637 ath10k_wmi_10x_service_ready_event_rx(ar, skb); 2634 ath10k_wmi_service_ready_event_rx(ar, skb);
2638 break; 2635 break;
2639 case WMI_10X_READY_EVENTID: 2636 case WMI_10X_READY_EVENTID:
2640 ath10k_wmi_ready_event_rx(ar, skb); 2637 ath10k_wmi_ready_event_rx(ar, skb);
@@ -2745,7 +2742,7 @@ static void ath10k_wmi_10_2_process_rx(struct ath10k *ar, struct sk_buff *skb)
2745 ath10k_wmi_event_vdev_resume_req(ar, skb); 2742 ath10k_wmi_event_vdev_resume_req(ar, skb);
2746 break; 2743 break;
2747 case WMI_10_2_SERVICE_READY_EVENTID: 2744 case WMI_10_2_SERVICE_READY_EVENTID:
2748 ath10k_wmi_10x_service_ready_event_rx(ar, skb); 2745 ath10k_wmi_service_ready_event_rx(ar, skb);
2749 break; 2746 break;
2750 case WMI_10_2_READY_EVENTID: 2747 case WMI_10_2_READY_EVENTID:
2751 ath10k_wmi_ready_event_rx(ar, skb); 2748 ath10k_wmi_ready_event_rx(ar, skb);