wmi.c (bf9b608e63dfd71ab225c9d4211eb6d8dc582a3b) | wmi.c (0c936b3c96337c3fd5ad4951ca7bdc54fa578a02) |
---|---|
1/* 2 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. 3 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * --- 450 unchanged lines hidden (view full) --- 459 case WMI_TX_DESC_RING_ADD_CMDID: 460 return "WMI_TX_DESC_RING_ADD_CMD"; 461 case WMI_RX_DESC_RING_ADD_CMDID: 462 return "WMI_RX_DESC_RING_ADD_CMD"; 463 case WMI_BCAST_DESC_RING_ADD_CMDID: 464 return "WMI_BCAST_DESC_RING_ADD_CMD"; 465 case WMI_CFG_DEF_RX_OFFLOAD_CMDID: 466 return "WMI_CFG_DEF_RX_OFFLOAD_CMD"; | 1/* 2 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. 3 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * --- 450 unchanged lines hidden (view full) --- 459 case WMI_TX_DESC_RING_ADD_CMDID: 460 return "WMI_TX_DESC_RING_ADD_CMD"; 461 case WMI_RX_DESC_RING_ADD_CMDID: 462 return "WMI_RX_DESC_RING_ADD_CMD"; 463 case WMI_BCAST_DESC_RING_ADD_CMDID: 464 return "WMI_BCAST_DESC_RING_ADD_CMD"; 465 case WMI_CFG_DEF_RX_OFFLOAD_CMDID: 466 return "WMI_CFG_DEF_RX_OFFLOAD_CMD"; |
467 case WMI_LINK_STATS_CMDID: 468 return "WMI_LINK_STATS_CMD"; |
|
467 default: 468 return "Untracked CMD"; 469 } 470} 471 472static const char *eventid2name(u16 eventid) 473{ 474 switch (eventid) { --- 118 unchanged lines hidden (view full) --- 593 case WMI_RX_STATUS_RING_CFG_DONE_EVENTID: 594 return "WMI_RX_STATUS_RING_CFG_DONE_EVENT"; 595 case WMI_TX_DESC_RING_CFG_DONE_EVENTID: 596 return "WMI_TX_DESC_RING_CFG_DONE_EVENT"; 597 case WMI_RX_DESC_RING_CFG_DONE_EVENTID: 598 return "WMI_RX_DESC_RING_CFG_DONE_EVENT"; 599 case WMI_CFG_DEF_RX_OFFLOAD_DONE_EVENTID: 600 return "WMI_CFG_DEF_RX_OFFLOAD_DONE_EVENT"; | 469 default: 470 return "Untracked CMD"; 471 } 472} 473 474static const char *eventid2name(u16 eventid) 475{ 476 switch (eventid) { --- 118 unchanged lines hidden (view full) --- 595 case WMI_RX_STATUS_RING_CFG_DONE_EVENTID: 596 return "WMI_RX_STATUS_RING_CFG_DONE_EVENT"; 597 case WMI_TX_DESC_RING_CFG_DONE_EVENTID: 598 return "WMI_TX_DESC_RING_CFG_DONE_EVENT"; 599 case WMI_RX_DESC_RING_CFG_DONE_EVENTID: 600 return "WMI_RX_DESC_RING_CFG_DONE_EVENT"; 601 case WMI_CFG_DEF_RX_OFFLOAD_DONE_EVENTID: 602 return "WMI_CFG_DEF_RX_OFFLOAD_DONE_EVENT"; |
603 case WMI_LINK_STATS_CONFIG_DONE_EVENTID: 604 return "WMI_LINK_STATS_CONFIG_DONE_EVENT"; 605 case WMI_LINK_STATS_EVENTID: 606 return "WMI_LINK_STATS_EVENT"; |
|
601 default: 602 return "Untracked EVENT"; 603 } 604} 605 606static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, u8 mid, 607 void *buf, u16 len) 608{ --- 715 unchanged lines hidden (view full) --- 1324 cfg80211_put_bss(wiphy, bss); 1325 } else { 1326 wil_err(wil, "cfg80211_inform_bss_frame() failed\n"); 1327 } 1328 1329 cfg80211_sched_scan_results(wiphy, 0); 1330} 1331 | 607 default: 608 return "Untracked EVENT"; 609 } 610} 611 612static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, u8 mid, 613 void *buf, u16 len) 614{ --- 715 unchanged lines hidden (view full) --- 1330 cfg80211_put_bss(wiphy, bss); 1331 } else { 1332 wil_err(wil, "cfg80211_inform_bss_frame() failed\n"); 1333 } 1334 1335 cfg80211_sched_scan_results(wiphy, 0); 1336} 1337 |
1338static void wil_link_stats_store_basic(struct wil6210_vif *vif, 1339 struct wmi_link_stats_basic *basic) 1340{ 1341 struct wil6210_priv *wil = vif_to_wil(vif); 1342 u8 cid = basic->cid; 1343 struct wil_sta_info *sta; 1344 1345 if (cid < 0 || cid >= WIL6210_MAX_CID) { 1346 wil_err(wil, "invalid cid %d\n", cid); 1347 return; 1348 } 1349 1350 sta = &wil->sta[cid]; 1351 sta->fw_stats_basic = *basic; 1352} 1353 1354static void wil_link_stats_store_global(struct wil6210_vif *vif, 1355 struct wmi_link_stats_global *global) 1356{ 1357 struct wil6210_priv *wil = vif_to_wil(vif); 1358 1359 wil->fw_stats_global.stats = *global; 1360} 1361 1362static void wmi_link_stats_parse(struct wil6210_vif *vif, u64 tsf, 1363 bool has_next, void *payload, 1364 size_t payload_size) 1365{ 1366 struct wil6210_priv *wil = vif_to_wil(vif); 1367 size_t hdr_size = sizeof(struct wmi_link_stats_record); 1368 size_t stats_size, record_size, expected_size; 1369 struct wmi_link_stats_record *hdr; 1370 1371 if (payload_size < hdr_size) { 1372 wil_err(wil, "link stats wrong event size %zu\n", payload_size); 1373 return; 1374 } 1375 1376 while (payload_size >= hdr_size) { 1377 hdr = payload; 1378 stats_size = le16_to_cpu(hdr->record_size); 1379 record_size = hdr_size + stats_size; 1380 1381 if (payload_size < record_size) { 1382 wil_err(wil, "link stats payload ended unexpectedly, size %zu < %zu\n", 1383 payload_size, record_size); 1384 return; 1385 } 1386 1387 switch (hdr->record_type_id) { 1388 case WMI_LINK_STATS_TYPE_BASIC: 1389 expected_size = sizeof(struct wmi_link_stats_basic); 1390 if (stats_size < expected_size) { 1391 wil_err(wil, "link stats invalid basic record size %zu < %zu\n", 1392 stats_size, expected_size); 1393 return; 1394 } 1395 if (vif->fw_stats_ready) { 1396 /* clean old statistics */ 1397 vif->fw_stats_tsf = 0; 1398 vif->fw_stats_ready = 0; 1399 } 1400 1401 wil_link_stats_store_basic(vif, payload + hdr_size); 1402 1403 if (!has_next) { 1404 vif->fw_stats_tsf = tsf; 1405 vif->fw_stats_ready = 1; 1406 } 1407 1408 break; 1409 case WMI_LINK_STATS_TYPE_GLOBAL: 1410 expected_size = sizeof(struct wmi_link_stats_global); 1411 if (stats_size < sizeof(struct wmi_link_stats_global)) { 1412 wil_err(wil, "link stats invalid global record size %zu < %zu\n", 1413 stats_size, expected_size); 1414 return; 1415 } 1416 1417 if (wil->fw_stats_global.ready) { 1418 /* clean old statistics */ 1419 wil->fw_stats_global.tsf = 0; 1420 wil->fw_stats_global.ready = 0; 1421 } 1422 1423 wil_link_stats_store_global(vif, payload + hdr_size); 1424 1425 if (!has_next) { 1426 wil->fw_stats_global.tsf = tsf; 1427 wil->fw_stats_global.ready = 1; 1428 } 1429 1430 break; 1431 default: 1432 break; 1433 } 1434 1435 /* skip to next record */ 1436 payload += record_size; 1437 payload_size -= record_size; 1438 } 1439} 1440 1441static void 1442wmi_evt_link_stats(struct wil6210_vif *vif, int id, void *d, int len) 1443{ 1444 struct wil6210_priv *wil = vif_to_wil(vif); 1445 struct wmi_link_stats_event *evt = d; 1446 size_t payload_size; 1447 1448 if (len < offsetof(struct wmi_link_stats_event, payload)) { 1449 wil_err(wil, "stats event way too short %d\n", len); 1450 return; 1451 } 1452 payload_size = le16_to_cpu(evt->payload_size); 1453 if (len < sizeof(struct wmi_link_stats_event) + payload_size) { 1454 wil_err(wil, "stats event too short %d\n", len); 1455 return; 1456 } 1457 1458 wmi_link_stats_parse(vif, le64_to_cpu(evt->tsf), evt->has_next, 1459 evt->payload, payload_size); 1460} 1461 |
|
1332/** 1333 * Some events are ignored for purpose; and need not be interpreted as 1334 * "unhandled events" 1335 */ 1336static void wmi_evt_ignore(struct wil6210_vif *vif, int id, void *d, int len) 1337{ 1338 struct wil6210_priv *wil = vif_to_wil(vif); 1339 --- 14 unchanged lines hidden (view full) --- 1354 {WMI_DISCONNECT_EVENTID, wmi_evt_disconnect}, 1355 {WMI_EAPOL_RX_EVENTID, wmi_evt_eapol_rx}, 1356 {WMI_BA_STATUS_EVENTID, wmi_evt_ba_status}, 1357 {WMI_RCP_ADDBA_REQ_EVENTID, wmi_evt_addba_rx_req}, 1358 {WMI_DELBA_EVENTID, wmi_evt_delba}, 1359 {WMI_RING_EN_EVENTID, wmi_evt_ring_en}, 1360 {WMI_DATA_PORT_OPEN_EVENTID, wmi_evt_ignore}, 1361 {WMI_SCHED_SCAN_RESULT_EVENTID, wmi_evt_sched_scan_result}, | 1462/** 1463 * Some events are ignored for purpose; and need not be interpreted as 1464 * "unhandled events" 1465 */ 1466static void wmi_evt_ignore(struct wil6210_vif *vif, int id, void *d, int len) 1467{ 1468 struct wil6210_priv *wil = vif_to_wil(vif); 1469 --- 14 unchanged lines hidden (view full) --- 1484 {WMI_DISCONNECT_EVENTID, wmi_evt_disconnect}, 1485 {WMI_EAPOL_RX_EVENTID, wmi_evt_eapol_rx}, 1486 {WMI_BA_STATUS_EVENTID, wmi_evt_ba_status}, 1487 {WMI_RCP_ADDBA_REQ_EVENTID, wmi_evt_addba_rx_req}, 1488 {WMI_DELBA_EVENTID, wmi_evt_delba}, 1489 {WMI_RING_EN_EVENTID, wmi_evt_ring_en}, 1490 {WMI_DATA_PORT_OPEN_EVENTID, wmi_evt_ignore}, 1491 {WMI_SCHED_SCAN_RESULT_EVENTID, wmi_evt_sched_scan_result}, |
1492 {WMI_LINK_STATS_EVENTID, wmi_evt_link_stats}, |
|
1362}; 1363 1364/* 1365 * Run in IRQ context 1366 * Extract WMI command from mailbox. Queue it to the @wil->pending_wmi_ev 1367 * that will be eventually handled by the @wmi_event_worker in the thread 1368 * context of thread "wil6210_wmi" 1369 */ --- 1867 unchanged lines hidden (view full) --- 3237 spin_lock_bh(&txdata->lock); 3238 ring->hwtail = le32_to_cpu(reply.evt.ring_tail_ptr); 3239 txdata->mid = vif->mid; 3240 txdata->enabled = 1; 3241 spin_unlock_bh(&txdata->lock); 3242 3243 return 0; 3244} | 1493}; 1494 1495/* 1496 * Run in IRQ context 1497 * Extract WMI command from mailbox. Queue it to the @wil->pending_wmi_ev 1498 * that will be eventually handled by the @wmi_event_worker in the thread 1499 * context of thread "wil6210_wmi" 1500 */ --- 1867 unchanged lines hidden (view full) --- 3368 spin_lock_bh(&txdata->lock); 3369 ring->hwtail = le32_to_cpu(reply.evt.ring_tail_ptr); 3370 txdata->mid = vif->mid; 3371 txdata->enabled = 1; 3372 spin_unlock_bh(&txdata->lock); 3373 3374 return 0; 3375} |
3376 3377int wmi_link_stats_cfg(struct wil6210_vif *vif, u32 type, u8 cid, u32 interval) 3378{ 3379 struct wil6210_priv *wil = vif_to_wil(vif); 3380 struct wmi_link_stats_cmd cmd = { 3381 .record_type_mask = cpu_to_le32(type), 3382 .cid = cid, 3383 .action = WMI_LINK_STATS_SNAPSHOT, 3384 .interval_msec = cpu_to_le32(interval), 3385 }; 3386 struct { 3387 struct wmi_cmd_hdr wmi; 3388 struct wmi_link_stats_config_done_event evt; 3389 } __packed reply = { 3390 .evt = {.status = WMI_FW_STATUS_FAILURE}, 3391 }; 3392 int rc; 3393 3394 rc = wmi_call(wil, WMI_LINK_STATS_CMDID, vif->mid, &cmd, sizeof(cmd), 3395 WMI_LINK_STATS_CONFIG_DONE_EVENTID, &reply, 3396 sizeof(reply), WIL_WMI_CALL_GENERAL_TO_MS); 3397 if (rc) { 3398 wil_err(wil, "WMI_LINK_STATS_CMDID failed, rc %d\n", rc); 3399 return rc; 3400 } 3401 3402 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) { 3403 wil_err(wil, "Link statistics config failed, status %d\n", 3404 reply.evt.status); 3405 return -EINVAL; 3406 } 3407 3408 return 0; 3409} |
|