18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright 2015 Intel Deutschland GmbH 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci#include <net/mac80211.h> 68c2ecf20Sopenharmony_ci#include "ieee80211_i.h" 78c2ecf20Sopenharmony_ci#include "trace.h" 88c2ecf20Sopenharmony_ci#include "driver-ops.h" 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ciint drv_start(struct ieee80211_local *local) 118c2ecf20Sopenharmony_ci{ 128c2ecf20Sopenharmony_ci int ret; 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci might_sleep(); 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci if (WARN_ON(local->started)) 178c2ecf20Sopenharmony_ci return -EALREADY; 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci trace_drv_start(local); 208c2ecf20Sopenharmony_ci local->started = true; 218c2ecf20Sopenharmony_ci /* allow rx frames */ 228c2ecf20Sopenharmony_ci smp_mb(); 238c2ecf20Sopenharmony_ci ret = local->ops->start(&local->hw); 248c2ecf20Sopenharmony_ci trace_drv_return_int(local, ret); 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci if (ret) 278c2ecf20Sopenharmony_ci local->started = false; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci return ret; 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_civoid drv_stop(struct ieee80211_local *local) 338c2ecf20Sopenharmony_ci{ 348c2ecf20Sopenharmony_ci might_sleep(); 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci if (WARN_ON(!local->started)) 378c2ecf20Sopenharmony_ci return; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci trace_drv_stop(local); 408c2ecf20Sopenharmony_ci local->ops->stop(&local->hw); 418c2ecf20Sopenharmony_ci trace_drv_return_void(local); 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci /* sync away all work on the tasklet before clearing started */ 448c2ecf20Sopenharmony_ci tasklet_disable(&local->tasklet); 458c2ecf20Sopenharmony_ci tasklet_enable(&local->tasklet); 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci barrier(); 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci local->started = false; 508c2ecf20Sopenharmony_ci} 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ciint drv_add_interface(struct ieee80211_local *local, 538c2ecf20Sopenharmony_ci struct ieee80211_sub_if_data *sdata) 548c2ecf20Sopenharmony_ci{ 558c2ecf20Sopenharmony_ci int ret; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci might_sleep(); 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN || 608c2ecf20Sopenharmony_ci (sdata->vif.type == NL80211_IFTYPE_MONITOR && 618c2ecf20Sopenharmony_ci !ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) && 628c2ecf20Sopenharmony_ci !(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE)))) 638c2ecf20Sopenharmony_ci return -EINVAL; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci trace_drv_add_interface(local, sdata); 668c2ecf20Sopenharmony_ci ret = local->ops->add_interface(&local->hw, &sdata->vif); 678c2ecf20Sopenharmony_ci trace_drv_return_int(local, ret); 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci if (ret == 0) 708c2ecf20Sopenharmony_ci sdata->flags |= IEEE80211_SDATA_IN_DRIVER; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci return ret; 738c2ecf20Sopenharmony_ci} 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ciint drv_change_interface(struct ieee80211_local *local, 768c2ecf20Sopenharmony_ci struct ieee80211_sub_if_data *sdata, 778c2ecf20Sopenharmony_ci enum nl80211_iftype type, bool p2p) 788c2ecf20Sopenharmony_ci{ 798c2ecf20Sopenharmony_ci int ret; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci might_sleep(); 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci if (!check_sdata_in_driver(sdata)) 848c2ecf20Sopenharmony_ci return -EIO; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci trace_drv_change_interface(local, sdata, type, p2p); 878c2ecf20Sopenharmony_ci ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); 888c2ecf20Sopenharmony_ci trace_drv_return_int(local, ret); 898c2ecf20Sopenharmony_ci return ret; 908c2ecf20Sopenharmony_ci} 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_civoid drv_remove_interface(struct ieee80211_local *local, 938c2ecf20Sopenharmony_ci struct ieee80211_sub_if_data *sdata) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci might_sleep(); 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci if (!check_sdata_in_driver(sdata)) 988c2ecf20Sopenharmony_ci return; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci trace_drv_remove_interface(local, sdata); 1018c2ecf20Sopenharmony_ci local->ops->remove_interface(&local->hw, &sdata->vif); 1028c2ecf20Sopenharmony_ci sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER; 1038c2ecf20Sopenharmony_ci trace_drv_return_void(local); 1048c2ecf20Sopenharmony_ci} 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci__must_check 1078c2ecf20Sopenharmony_ciint drv_sta_state(struct ieee80211_local *local, 1088c2ecf20Sopenharmony_ci struct ieee80211_sub_if_data *sdata, 1098c2ecf20Sopenharmony_ci struct sta_info *sta, 1108c2ecf20Sopenharmony_ci enum ieee80211_sta_state old_state, 1118c2ecf20Sopenharmony_ci enum ieee80211_sta_state new_state) 1128c2ecf20Sopenharmony_ci{ 1138c2ecf20Sopenharmony_ci int ret = 0; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci might_sleep(); 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci sdata = get_bss_sdata(sdata); 1188c2ecf20Sopenharmony_ci if (!check_sdata_in_driver(sdata)) 1198c2ecf20Sopenharmony_ci return -EIO; 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state); 1228c2ecf20Sopenharmony_ci if (local->ops->sta_state) { 1238c2ecf20Sopenharmony_ci ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta, 1248c2ecf20Sopenharmony_ci old_state, new_state); 1258c2ecf20Sopenharmony_ci } else if (old_state == IEEE80211_STA_AUTH && 1268c2ecf20Sopenharmony_ci new_state == IEEE80211_STA_ASSOC) { 1278c2ecf20Sopenharmony_ci ret = drv_sta_add(local, sdata, &sta->sta); 1288c2ecf20Sopenharmony_ci if (ret == 0) { 1298c2ecf20Sopenharmony_ci sta->uploaded = true; 1308c2ecf20Sopenharmony_ci if (rcu_access_pointer(sta->sta.rates)) 1318c2ecf20Sopenharmony_ci drv_sta_rate_tbl_update(local, sdata, &sta->sta); 1328c2ecf20Sopenharmony_ci } 1338c2ecf20Sopenharmony_ci } else if (old_state == IEEE80211_STA_ASSOC && 1348c2ecf20Sopenharmony_ci new_state == IEEE80211_STA_AUTH) { 1358c2ecf20Sopenharmony_ci drv_sta_remove(local, sdata, &sta->sta); 1368c2ecf20Sopenharmony_ci } 1378c2ecf20Sopenharmony_ci trace_drv_return_int(local, ret); 1388c2ecf20Sopenharmony_ci return ret; 1398c2ecf20Sopenharmony_ci} 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci__must_check 1428c2ecf20Sopenharmony_ciint drv_sta_set_txpwr(struct ieee80211_local *local, 1438c2ecf20Sopenharmony_ci struct ieee80211_sub_if_data *sdata, 1448c2ecf20Sopenharmony_ci struct sta_info *sta) 1458c2ecf20Sopenharmony_ci{ 1468c2ecf20Sopenharmony_ci int ret = -EOPNOTSUPP; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci might_sleep(); 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci sdata = get_bss_sdata(sdata); 1518c2ecf20Sopenharmony_ci if (!check_sdata_in_driver(sdata)) 1528c2ecf20Sopenharmony_ci return -EIO; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci trace_drv_sta_set_txpwr(local, sdata, &sta->sta); 1558c2ecf20Sopenharmony_ci if (local->ops->sta_set_txpwr) 1568c2ecf20Sopenharmony_ci ret = local->ops->sta_set_txpwr(&local->hw, &sdata->vif, 1578c2ecf20Sopenharmony_ci &sta->sta); 1588c2ecf20Sopenharmony_ci trace_drv_return_int(local, ret); 1598c2ecf20Sopenharmony_ci return ret; 1608c2ecf20Sopenharmony_ci} 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_civoid drv_sta_rc_update(struct ieee80211_local *local, 1638c2ecf20Sopenharmony_ci struct ieee80211_sub_if_data *sdata, 1648c2ecf20Sopenharmony_ci struct ieee80211_sta *sta, u32 changed) 1658c2ecf20Sopenharmony_ci{ 1668c2ecf20Sopenharmony_ci sdata = get_bss_sdata(sdata); 1678c2ecf20Sopenharmony_ci if (!check_sdata_in_driver(sdata)) 1688c2ecf20Sopenharmony_ci return; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED && 1718c2ecf20Sopenharmony_ci (sdata->vif.type != NL80211_IFTYPE_ADHOC && 1728c2ecf20Sopenharmony_ci sdata->vif.type != NL80211_IFTYPE_MESH_POINT)); 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci trace_drv_sta_rc_update(local, sdata, sta, changed); 1758c2ecf20Sopenharmony_ci if (local->ops->sta_rc_update) 1768c2ecf20Sopenharmony_ci local->ops->sta_rc_update(&local->hw, &sdata->vif, 1778c2ecf20Sopenharmony_ci sta, changed); 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci trace_drv_return_void(local); 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ciint drv_conf_tx(struct ieee80211_local *local, 1838c2ecf20Sopenharmony_ci struct ieee80211_sub_if_data *sdata, u16 ac, 1848c2ecf20Sopenharmony_ci const struct ieee80211_tx_queue_params *params) 1858c2ecf20Sopenharmony_ci{ 1868c2ecf20Sopenharmony_ci int ret = -EOPNOTSUPP; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci might_sleep(); 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci if (!check_sdata_in_driver(sdata)) 1918c2ecf20Sopenharmony_ci return -EIO; 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci if (params->cw_min == 0 || params->cw_min > params->cw_max) { 1948c2ecf20Sopenharmony_ci /* 1958c2ecf20Sopenharmony_ci * If we can't configure hardware anyway, don't warn. We may 1968c2ecf20Sopenharmony_ci * never have initialized the CW parameters. 1978c2ecf20Sopenharmony_ci */ 1988c2ecf20Sopenharmony_ci WARN_ONCE(local->ops->conf_tx, 1998c2ecf20Sopenharmony_ci "%s: invalid CW_min/CW_max: %d/%d\n", 2008c2ecf20Sopenharmony_ci sdata->name, params->cw_min, params->cw_max); 2018c2ecf20Sopenharmony_ci return -EINVAL; 2028c2ecf20Sopenharmony_ci } 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci trace_drv_conf_tx(local, sdata, ac, params); 2058c2ecf20Sopenharmony_ci if (local->ops->conf_tx) 2068c2ecf20Sopenharmony_ci ret = local->ops->conf_tx(&local->hw, &sdata->vif, 2078c2ecf20Sopenharmony_ci ac, params); 2088c2ecf20Sopenharmony_ci trace_drv_return_int(local, ret); 2098c2ecf20Sopenharmony_ci return ret; 2108c2ecf20Sopenharmony_ci} 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ciu64 drv_get_tsf(struct ieee80211_local *local, 2138c2ecf20Sopenharmony_ci struct ieee80211_sub_if_data *sdata) 2148c2ecf20Sopenharmony_ci{ 2158c2ecf20Sopenharmony_ci u64 ret = -1ULL; 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci might_sleep(); 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci if (!check_sdata_in_driver(sdata)) 2208c2ecf20Sopenharmony_ci return ret; 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci trace_drv_get_tsf(local, sdata); 2238c2ecf20Sopenharmony_ci if (local->ops->get_tsf) 2248c2ecf20Sopenharmony_ci ret = local->ops->get_tsf(&local->hw, &sdata->vif); 2258c2ecf20Sopenharmony_ci trace_drv_return_u64(local, ret); 2268c2ecf20Sopenharmony_ci return ret; 2278c2ecf20Sopenharmony_ci} 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_civoid drv_set_tsf(struct ieee80211_local *local, 2308c2ecf20Sopenharmony_ci struct ieee80211_sub_if_data *sdata, 2318c2ecf20Sopenharmony_ci u64 tsf) 2328c2ecf20Sopenharmony_ci{ 2338c2ecf20Sopenharmony_ci might_sleep(); 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci if (!check_sdata_in_driver(sdata)) 2368c2ecf20Sopenharmony_ci return; 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci trace_drv_set_tsf(local, sdata, tsf); 2398c2ecf20Sopenharmony_ci if (local->ops->set_tsf) 2408c2ecf20Sopenharmony_ci local->ops->set_tsf(&local->hw, &sdata->vif, tsf); 2418c2ecf20Sopenharmony_ci trace_drv_return_void(local); 2428c2ecf20Sopenharmony_ci} 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_civoid drv_offset_tsf(struct ieee80211_local *local, 2458c2ecf20Sopenharmony_ci struct ieee80211_sub_if_data *sdata, 2468c2ecf20Sopenharmony_ci s64 offset) 2478c2ecf20Sopenharmony_ci{ 2488c2ecf20Sopenharmony_ci might_sleep(); 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci if (!check_sdata_in_driver(sdata)) 2518c2ecf20Sopenharmony_ci return; 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci trace_drv_offset_tsf(local, sdata, offset); 2548c2ecf20Sopenharmony_ci if (local->ops->offset_tsf) 2558c2ecf20Sopenharmony_ci local->ops->offset_tsf(&local->hw, &sdata->vif, offset); 2568c2ecf20Sopenharmony_ci trace_drv_return_void(local); 2578c2ecf20Sopenharmony_ci} 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_civoid drv_reset_tsf(struct ieee80211_local *local, 2608c2ecf20Sopenharmony_ci struct ieee80211_sub_if_data *sdata) 2618c2ecf20Sopenharmony_ci{ 2628c2ecf20Sopenharmony_ci might_sleep(); 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci if (!check_sdata_in_driver(sdata)) 2658c2ecf20Sopenharmony_ci return; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci trace_drv_reset_tsf(local, sdata); 2688c2ecf20Sopenharmony_ci if (local->ops->reset_tsf) 2698c2ecf20Sopenharmony_ci local->ops->reset_tsf(&local->hw, &sdata->vif); 2708c2ecf20Sopenharmony_ci trace_drv_return_void(local); 2718c2ecf20Sopenharmony_ci} 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ciint drv_switch_vif_chanctx(struct ieee80211_local *local, 2748c2ecf20Sopenharmony_ci struct ieee80211_vif_chanctx_switch *vifs, 2758c2ecf20Sopenharmony_ci int n_vifs, enum ieee80211_chanctx_switch_mode mode) 2768c2ecf20Sopenharmony_ci{ 2778c2ecf20Sopenharmony_ci int ret = 0; 2788c2ecf20Sopenharmony_ci int i; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci might_sleep(); 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci if (!local->ops->switch_vif_chanctx) 2838c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci for (i = 0; i < n_vifs; i++) { 2868c2ecf20Sopenharmony_ci struct ieee80211_chanctx *new_ctx = 2878c2ecf20Sopenharmony_ci container_of(vifs[i].new_ctx, 2888c2ecf20Sopenharmony_ci struct ieee80211_chanctx, 2898c2ecf20Sopenharmony_ci conf); 2908c2ecf20Sopenharmony_ci struct ieee80211_chanctx *old_ctx = 2918c2ecf20Sopenharmony_ci container_of(vifs[i].old_ctx, 2928c2ecf20Sopenharmony_ci struct ieee80211_chanctx, 2938c2ecf20Sopenharmony_ci conf); 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci WARN_ON_ONCE(!old_ctx->driver_present); 2968c2ecf20Sopenharmony_ci WARN_ON_ONCE((mode == CHANCTX_SWMODE_SWAP_CONTEXTS && 2978c2ecf20Sopenharmony_ci new_ctx->driver_present) || 2988c2ecf20Sopenharmony_ci (mode == CHANCTX_SWMODE_REASSIGN_VIF && 2998c2ecf20Sopenharmony_ci !new_ctx->driver_present)); 3008c2ecf20Sopenharmony_ci } 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci trace_drv_switch_vif_chanctx(local, vifs, n_vifs, mode); 3038c2ecf20Sopenharmony_ci ret = local->ops->switch_vif_chanctx(&local->hw, 3048c2ecf20Sopenharmony_ci vifs, n_vifs, mode); 3058c2ecf20Sopenharmony_ci trace_drv_return_int(local, ret); 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci if (!ret && mode == CHANCTX_SWMODE_SWAP_CONTEXTS) { 3088c2ecf20Sopenharmony_ci for (i = 0; i < n_vifs; i++) { 3098c2ecf20Sopenharmony_ci struct ieee80211_chanctx *new_ctx = 3108c2ecf20Sopenharmony_ci container_of(vifs[i].new_ctx, 3118c2ecf20Sopenharmony_ci struct ieee80211_chanctx, 3128c2ecf20Sopenharmony_ci conf); 3138c2ecf20Sopenharmony_ci struct ieee80211_chanctx *old_ctx = 3148c2ecf20Sopenharmony_ci container_of(vifs[i].old_ctx, 3158c2ecf20Sopenharmony_ci struct ieee80211_chanctx, 3168c2ecf20Sopenharmony_ci conf); 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci new_ctx->driver_present = true; 3198c2ecf20Sopenharmony_ci old_ctx->driver_present = false; 3208c2ecf20Sopenharmony_ci } 3218c2ecf20Sopenharmony_ci } 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_ci return ret; 3248c2ecf20Sopenharmony_ci} 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ciint drv_ampdu_action(struct ieee80211_local *local, 3278c2ecf20Sopenharmony_ci struct ieee80211_sub_if_data *sdata, 3288c2ecf20Sopenharmony_ci struct ieee80211_ampdu_params *params) 3298c2ecf20Sopenharmony_ci{ 3308c2ecf20Sopenharmony_ci int ret = -EOPNOTSUPP; 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci might_sleep(); 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci if (!sdata) 3358c2ecf20Sopenharmony_ci return -EIO; 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci sdata = get_bss_sdata(sdata); 3388c2ecf20Sopenharmony_ci if (!check_sdata_in_driver(sdata)) 3398c2ecf20Sopenharmony_ci return -EIO; 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci trace_drv_ampdu_action(local, sdata, params); 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci if (local->ops->ampdu_action) 3448c2ecf20Sopenharmony_ci ret = local->ops->ampdu_action(&local->hw, &sdata->vif, params); 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci trace_drv_return_int(local, ret); 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci return ret; 3498c2ecf20Sopenharmony_ci} 350