/****************************************************************************** * * Copyright(c) 2019 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * ******************************************************************************/ #include "mcc.h" u32 mac_reset_mcc_group(struct mac_ax_adapter *adapter, u8 group) { struct fwcmd_reset_mcc_group *ptr; #if MAC_AX_PHL_H2C struct rtw_h2c_pkt *h2cb; #else struct h2c_buf *h2cb; #endif u8 *buf; u32 ret = 0; if (group > MCC_GROUP_ID_MAX) { PLTFM_MSG_ERR("[ERR]%s: invalid group: %d\n", __func__, group); return MACNOITEM; } adapter->sm.mcc_group[group] = MAC_AX_MCC_EMPTY; adapter->sm.mcc_request[group] = MAC_AX_MCC_REQ_IDLE; h2cb = h2cb_alloc(adapter, H2CB_CLASS_DATA); if (!h2cb) { PLTFM_MSG_ERR("[ERR]%s: H2C alloc fail\n", __func__); return MACNPTR; } buf = h2cb_put(h2cb, sizeof(struct fwcmd_reset_mcc_group)); if (!buf) { PLTFM_MSG_ERR("[ERR]%s: H2C put fail\n", __func__); ret = MACNOBUF; goto fail; } ptr = (struct fwcmd_reset_mcc_group *)buf; ptr->dword0 = cpu_to_le32(SET_WORD(group, FWCMD_H2C_RESET_MCC_GROUP_GROUP)); ret = h2c_pkt_set_hdr(adapter, h2cb, FWCMD_TYPE_H2C, FWCMD_H2C_CAT_MAC, FWCMD_H2C_CL_MCC, FWCMD_H2C_FUNC_RESET_MCC_GROUP, 0, 0); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Set H2C HDR fail\n", __func__); goto fail; } ret = h2c_pkt_build_txd(adapter, h2cb); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Build H2C TXD fail\n", __func__); goto fail; } #if MAC_AX_PHL_H2C ret = PLTFM_TX(h2cb); #else ret = PLTFM_TX(h2cb->data, h2cb->len); #endif if (ret) { PLTFM_MSG_ERR("[ERR]%s: platform tx err: %d\n", __func__, ret); goto fail; } h2cb_free(adapter, h2cb); return MACSUCCESS; fail: h2cb_free(adapter, h2cb); return ret; } u32 mac_reset_mcc_request(struct mac_ax_adapter *adapter, u8 group) { if (adapter->sm.mcc_request[group] != MAC_AX_MCC_REQ_FAIL) { PLTFM_MSG_ERR("[ERR]%s: state != req fail\n", __func__); return MACPROCERR; } if (group > MCC_GROUP_ID_MAX) { PLTFM_MSG_ERR("[ERR]%s: invalid group: %d\n", __func__, group); return MACNOITEM; } adapter->sm.mcc_request[group] = MAC_AX_MCC_REQ_IDLE; return MACSUCCESS; } u32 mac_add_mcc(struct mac_ax_adapter *adapter, struct mac_ax_mcc_role *info) { struct fwcmd_add_mcc *ptr; #if MAC_AX_PHL_H2C struct rtw_h2c_pkt *h2cb; #else struct h2c_buf *h2cb; #endif u8 *buf; u32 ret = 0; if (!(adapter->sm.mcc_group[info->group] == MAC_AX_MCC_EMPTY || adapter->sm.mcc_group[info->group] == MAC_AX_MCC_ADD_DONE)) { PLTFM_MSG_ERR("[ERR]%s: state != empty or add done\n", __func__); return MACPROCERR; } adapter->sm.mcc_group[info->group] = MAC_AX_MCC_STATE_H2C_SENT; h2cb = h2cb_alloc(adapter, H2CB_CLASS_DATA); if (!h2cb) { PLTFM_MSG_ERR("[ERR]%s: H2C alloc fail\n", __func__); return MACNPTR; } buf = h2cb_put(h2cb, sizeof(struct fwcmd_add_mcc)); if (!buf) { PLTFM_MSG_ERR("[ERR]%s: H2C put fail\n", __func__); ret = MACNOBUF; goto fail; } ptr = (struct fwcmd_add_mcc *)buf; ptr->dword0 = cpu_to_le32(SET_WORD(info->macid, FWCMD_H2C_ADD_MCC_MACID) | SET_WORD(info->central_ch_seg0, FWCMD_H2C_ADD_MCC_CENTRAL_CH_SEG0) | SET_WORD(info->central_ch_seg1, FWCMD_H2C_ADD_MCC_CENTRAL_CH_SEG1) | SET_WORD(info->primary_ch, FWCMD_H2C_ADD_MCC_PRIMARY_CH)); ptr->dword1 = cpu_to_le32((info->dis_tx_null ? FWCMD_H2C_ADD_MCC_DIS_TX_NULL : 0) | (info->dis_sw_retry ? FWCMD_H2C_ADD_MCC_DIS_SW_RETRY : 0) | (info->in_curr_ch ? FWCMD_H2C_ADD_MCC_IN_CURR_CH : 0) | SET_WORD(info->bandwidth, FWCMD_H2C_ADD_MCC_BANDWIDTH) | SET_WORD(info->group, FWCMD_H2C_ADD_MCC_GROUP) | SET_WORD(info->c2h_rpt, FWCMD_H2C_ADD_MCC_C2H_RPT) | SET_WORD(info->sw_retry_count, FWCMD_H2C_ADD_MCC_SW_RETRY_COUNT) | SET_WORD(info->tx_null_early, FWCMD_H2C_ADD_MCC_TX_NULL_EARLY) | (info->btc_in_2g ? FWCMD_H2C_ADD_MCC_BTC_IN_2G : 0) | (info->pta_en ? FWCMD_H2C_ADD_MCC_PTA_EN : 0) | (info->rfk_by_pass ? FWCMD_H2C_ADD_MCC_RFK_BY_PASS : 0)); ptr->dword2 = cpu_to_le32(SET_WORD(info->duration, FWCMD_H2C_ADD_MCC_DURATION)); ret = h2c_pkt_set_hdr(adapter, h2cb, FWCMD_TYPE_H2C, FWCMD_H2C_CAT_MAC, FWCMD_H2C_CL_MCC, FWCMD_H2C_FUNC_ADD_MCC, 0, 0); ptr->dword3 = cpu_to_le32((info->courtesy_en ? FWCMD_H2C_ADD_MCC_COURTESY_EN : 0) | SET_WORD(info->courtesy_num, FWCMD_H2C_ADD_MCC_COURTESY_NUM) | SET_WORD(info->courtesy_target, FWCMD_H2C_ADD_MCC_COURTESY_TARGET)); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Set H2C HDR fail\n", __func__); goto fail; } ret = h2c_pkt_build_txd(adapter, h2cb); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Build H2C TXD fail\n", __func__); goto fail; } #if MAC_AX_PHL_H2C ret = PLTFM_TX(h2cb); #else ret = PLTFM_TX(h2cb->data, h2cb->len); #endif if (ret) { PLTFM_MSG_ERR("[ERR]%s: platform tx err: %d\n", __func__, ret); goto fail; } h2cb_free(adapter, h2cb); return MACSUCCESS; fail: h2cb_free(adapter, h2cb); return ret; } u32 mac_start_mcc(struct mac_ax_adapter *adapter, struct mac_ax_mcc_start *info) { struct fwcmd_start_mcc *ptr; #if MAC_AX_PHL_H2C struct rtw_h2c_pkt *h2cb; #else struct h2c_buf *h2cb; #endif u8 *buf; u32 ret = 0; u32 group = info->group; if (group > MCC_GROUP_ID_MAX) { PLTFM_MSG_ERR("[ERR]%s: invalid group: %d\n", __func__, info->group); return MACNOITEM; } if (adapter->sm.mcc_group[info->group] != MAC_AX_MCC_ADD_DONE) { PLTFM_MSG_ERR("[ERR]%s: state != add done\n", __func__); return MACPROCERR; } adapter->sm.mcc_group[info->group] = MAC_AX_MCC_STATE_H2C_SENT; h2cb = h2cb_alloc(adapter, H2CB_CLASS_DATA); if (!h2cb) { PLTFM_MSG_ERR("[ERR]%s: H2C alloc fail\n", __func__); return MACNPTR; } buf = h2cb_put(h2cb, sizeof(struct fwcmd_start_mcc)); if (!buf) { PLTFM_MSG_ERR("[ERR]%s: H2C put fail\n", __func__); ret = MACNOBUF; goto fail; } ptr = (struct fwcmd_start_mcc *)buf; ptr->dword0 = cpu_to_le32(SET_WORD(info->group, FWCMD_H2C_START_MCC_GROUP) | (info->btc_in_group ? FWCMD_H2C_START_MCC_BTC_IN_GROUP : 0) | SET_WORD(info->old_group_action, FWCMD_H2C_START_MCC_OLD_GROUP_ACTION) | SET_WORD(info->old_group, FWCMD_H2C_START_MCC_OLD_GROUP) | SET_WORD(info->macid, FWCMD_H2C_START_MCC_MACID)); ptr->dword1 = cpu_to_le32(SET_WORD(info->tsf_low, FWCMD_H2C_START_MCC_TSF_LOW)); ptr->dword2 = cpu_to_le32(SET_WORD(info->tsf_high, FWCMD_H2C_START_MCC_TSF_HIGH)); ret = h2c_pkt_set_hdr(adapter, h2cb, FWCMD_TYPE_H2C, FWCMD_H2C_CAT_MAC, FWCMD_H2C_CL_MCC, FWCMD_H2C_FUNC_START_MCC, 0, 0); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Set H2C HDR fail\n", __func__); goto fail; } ret = h2c_pkt_build_txd(adapter, h2cb); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Build H2C TXD fail\n", __func__); goto fail; } #if MAC_AX_PHL_H2C ret = PLTFM_TX(h2cb); #else ret = PLTFM_TX(h2cb->data, h2cb->len); #endif if (ret) { PLTFM_MSG_ERR("[ERR]%s: platform tx err: %d\n", __func__, ret); goto fail; } h2cb_free(adapter, h2cb); return MACSUCCESS; fail: h2cb_free(adapter, h2cb); return ret; } u32 mac_stop_mcc(struct mac_ax_adapter *adapter, u8 group, u8 macid, u8 prev_groups) { struct fwcmd_stop_mcc *ptr; #if MAC_AX_PHL_H2C struct rtw_h2c_pkt *h2cb; #else struct h2c_buf *h2cb; #endif u8 *buf; u32 ret = 0; if (group > MCC_GROUP_ID_MAX) { PLTFM_MSG_ERR("[ERR]%s: invalid group: %d\n", __func__, group); return MACNOITEM; } if (adapter->sm.mcc_group[group] != MAC_AX_MCC_START_DONE) { PLTFM_MSG_ERR("[ERR]%s: state != start done\n", __func__); return MACPROCERR; } adapter->sm.mcc_group[group] = MAC_AX_MCC_STATE_H2C_SENT; h2cb = h2cb_alloc(adapter, H2CB_CLASS_DATA); if (!h2cb) { PLTFM_MSG_ERR("[ERR]%s: H2C alloc fail\n", __func__); return MACNPTR; } buf = h2cb_put(h2cb, sizeof(struct fwcmd_stop_mcc)); if (!buf) { PLTFM_MSG_ERR("[ERR]%s: H2C put fail\n", __func__); ret = MACNOBUF; goto fail; } ptr = (struct fwcmd_stop_mcc *)buf; ptr->dword0 = cpu_to_le32(SET_WORD(group, FWCMD_H2C_STOP_MCC_GROUP) | SET_WORD(macid, FWCMD_H2C_STOP_MCC_MACID) | (prev_groups ? FWCMD_H2C_STOP_MCC_PREV_GROUPS : 0)); ret = h2c_pkt_set_hdr(adapter, h2cb, FWCMD_TYPE_H2C, FWCMD_H2C_CAT_MAC, FWCMD_H2C_CL_MCC, FWCMD_H2C_FUNC_STOP_MCC, 0, 0); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Set H2C HDR fail\n", __func__); goto fail; } ret = h2c_pkt_build_txd(adapter, h2cb); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Build H2C TXD fail\n", __func__); goto fail; } #if MAC_AX_PHL_H2C ret = PLTFM_TX(h2cb); #else ret = PLTFM_TX(h2cb->data, h2cb->len); #endif if (ret) { PLTFM_MSG_ERR("[ERR]%s: platform tx err: %d\n", __func__, ret); goto fail; } h2cb_free(adapter, h2cb); return MACSUCCESS; fail: h2cb_free(adapter, h2cb); return ret; } u32 mac_del_mcc_group(struct mac_ax_adapter *adapter, u8 group, u8 prev_groups) { struct fwcmd_del_mcc_group *ptr; #if MAC_AX_PHL_H2C struct rtw_h2c_pkt *h2cb; #else struct h2c_buf *h2cb; #endif u8 *buf; u32 ret = 0; if (group > MCC_GROUP_ID_MAX) { PLTFM_MSG_ERR("[ERR]%s: invalid group: %d\n", __func__, group); return MACNOITEM; } if (!(adapter->sm.mcc_group[group] == MAC_AX_MCC_ADD_DONE || adapter->sm.mcc_group[group] == MAC_AX_MCC_STOP_DONE)) { PLTFM_MSG_ERR("[ERR]%s: state != add or stop done\n", __func__); return MACPROCERR; } adapter->sm.mcc_group[group] = MAC_AX_MCC_STATE_H2C_SENT; h2cb = h2cb_alloc(adapter, H2CB_CLASS_DATA); if (!h2cb) { PLTFM_MSG_ERR("[ERR]%s: H2C alloc fail\n", __func__); return MACNPTR; } buf = h2cb_put(h2cb, sizeof(struct fwcmd_del_mcc_group)); if (!buf) { PLTFM_MSG_ERR("[ERR]%s: H2C put fail\n", __func__); ret = MACNOBUF; goto fail; } ptr = (struct fwcmd_del_mcc_group *)buf; ptr->dword0 = cpu_to_le32(SET_WORD(group, FWCMD_H2C_DEL_MCC_GROUP_GROUP) | (prev_groups ? FWCMD_H2C_DEL_MCC_GROUP_PREV_GROUPS : 0)); ret = h2c_pkt_set_hdr(adapter, h2cb, FWCMD_TYPE_H2C, FWCMD_H2C_CAT_MAC, FWCMD_H2C_CL_MCC, FWCMD_H2C_FUNC_DEL_MCC_GROUP, 0, 0); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Set H2C HDR fail\n", __func__); goto fail; } ret = h2c_pkt_build_txd(adapter, h2cb); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Build H2C TXD fail\n", __func__); goto fail; } #if MAC_AX_PHL_H2C ret = PLTFM_TX(h2cb); #else ret = PLTFM_TX(h2cb->data, h2cb->len); #endif if (ret) { PLTFM_MSG_ERR("[ERR]%s: platform tx err: %d\n", __func__, ret); goto fail; } h2cb_free(adapter, h2cb); return MACSUCCESS; fail: h2cb_free(adapter, h2cb); return ret; } u32 mac_mcc_request_tsf(struct mac_ax_adapter *adapter, u8 group, u8 macid_x, u8 macid_y) { struct fwcmd_mcc_req_tsf *ptr; #if MAC_AX_PHL_H2C struct rtw_h2c_pkt *h2cb; #else struct h2c_buf *h2cb; #endif u8 *buf; u32 ret = 0; if (group > MCC_GROUP_ID_MAX) { PLTFM_MSG_ERR("[ERR]%s: invalid group: %d\n", __func__, group); return MACNOITEM; } if (adapter->sm.mcc_request[group] != MAC_AX_MCC_REQ_IDLE) { PLTFM_MSG_ERR("[ERR]%s: state != req idle\n", __func__); return MACPROCERR; } adapter->sm.mcc_request[group] = MAC_AX_MCC_REQ_H2C_SENT; h2cb = h2cb_alloc(adapter, H2CB_CLASS_DATA); if (!h2cb) { PLTFM_MSG_ERR("[ERR]%s: H2C alloc fail\n", __func__); return MACNPTR; } buf = h2cb_put(h2cb, sizeof(struct fwcmd_mcc_req_tsf)); if (!buf) { PLTFM_MSG_ERR("[ERR]%s: H2C put fail\n", __func__); ret = MACNOBUF; goto fail; } ptr = (struct fwcmd_mcc_req_tsf *)buf; ptr->dword0 = cpu_to_le32(SET_WORD(group, FWCMD_H2C_MCC_REQ_TSF_GROUP) | SET_WORD(macid_x, FWCMD_H2C_MCC_REQ_TSF_MACID_X) | SET_WORD(macid_y, FWCMD_H2C_MCC_REQ_TSF_MACID_Y)); ret = h2c_pkt_set_hdr(adapter, h2cb, FWCMD_TYPE_H2C, FWCMD_H2C_CAT_MAC, FWCMD_H2C_CL_MCC, FWCMD_H2C_FUNC_MCC_REQ_TSF, 0, 0); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Set H2C HDR fail\n", __func__); goto fail; } ret = h2c_pkt_build_txd(adapter, h2cb); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Build H2C TXD fail\n", __func__); goto fail; } #if MAC_AX_PHL_H2C ret = PLTFM_TX(h2cb); #else ret = PLTFM_TX(h2cb->data, h2cb->len); #endif if (ret) { PLTFM_MSG_ERR("[ERR]%s: platform tx err: %d\n", __func__, ret); goto fail; } h2cb_free(adapter, h2cb); return MACSUCCESS; fail: h2cb_free(adapter, h2cb); return ret; } u32 mac_mcc_macid_bitmap(struct mac_ax_adapter *adapter, u8 group, u8 macid, u8 *bitmap, u8 len) { struct fwcmd_mcc_macid_bitmap *ptr; #if MAC_AX_PHL_H2C struct rtw_h2c_pkt *h2cb; #else struct h2c_buf *h2cb; #endif u8 *buf; u32 ret = 0; if (group > MCC_GROUP_ID_MAX) { PLTFM_MSG_ERR("[ERR]%s: invalid group: %d\n", __func__, group); return MACNOITEM; } if (adapter->sm.mcc_request[group] != MAC_AX_MCC_REQ_IDLE) { PLTFM_MSG_ERR("[ERR]%s: state != req idle\n", __func__); return MACPROCERR; } adapter->sm.mcc_request[group] = MAC_AX_MCC_REQ_H2C_SENT; h2cb = h2cb_alloc(adapter, H2CB_CLASS_DATA); if (!h2cb) { PLTFM_MSG_ERR("[ERR]%s: H2C alloc fail\n", __func__); return MACNPTR; } buf = h2cb_put(h2cb, len + 4); if (!buf) { PLTFM_MSG_ERR("[ERR]%s: H2C put fail\n", __func__); ret = MACNOBUF; goto fail; } ptr = (struct fwcmd_mcc_macid_bitmap *)buf; ptr->dword0 = cpu_to_le32(SET_WORD(group, FWCMD_H2C_MCC_MACID_BITMAP_GROUP) | SET_WORD(macid, FWCMD_H2C_MCC_MACID_BITMAP_MACID) | SET_WORD(len, FWCMD_H2C_MCC_MACID_BITMAP_BITMAP_LENGTH)); PLTFM_MEMCPY((u8 *)ptr + sizeof(u32), bitmap, len); ret = h2c_pkt_set_hdr(adapter, h2cb, FWCMD_TYPE_H2C, FWCMD_H2C_CAT_MAC, FWCMD_H2C_CL_MCC, FWCMD_H2C_FUNC_MCC_MACID_BITMAP, 0, 0); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Set H2C HDR fail\n", __func__); goto fail; } ret = h2c_pkt_build_txd(adapter, h2cb); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Build H2C TXD fail\n", __func__); goto fail; } #if MAC_AX_PHL_H2C ret = PLTFM_TX(h2cb); #else ret = PLTFM_TX(h2cb->data, h2cb->len); #endif if (ret) { PLTFM_MSG_ERR("[ERR]%s: platform tx error %d\n", __func__, ret); goto fail; } h2cb_free(adapter, h2cb); return MACSUCCESS; fail: h2cb_free(adapter, h2cb); return ret; } u32 mac_mcc_sync_enable(struct mac_ax_adapter *adapter, u8 group, u8 source, u8 target, u8 offset) { struct fwcmd_mcc_sync *ptr; #if MAC_AX_PHL_H2C struct rtw_h2c_pkt *h2cb; #else struct h2c_buf *h2cb; #endif u8 *buf; u32 ret = 0; if (group > MCC_GROUP_ID_MAX) { PLTFM_MSG_ERR("[ERR]%s: invalid group: %d\n", __func__, group); return MACNOITEM; } if (adapter->sm.mcc_request[group] != MAC_AX_MCC_REQ_IDLE) { PLTFM_MSG_ERR("[ERR]%s: state != req idle\n", __func__); return MACPROCERR; } adapter->sm.mcc_request[group] = MAC_AX_MCC_REQ_H2C_SENT; h2cb = h2cb_alloc(adapter, H2CB_CLASS_DATA); if (!h2cb) { PLTFM_MSG_ERR("[ERR]%s: H2C alloc fail\n", __func__); return MACNPTR; } buf = h2cb_put(h2cb, sizeof(struct fwcmd_mcc_sync)); if (!buf) { PLTFM_MSG_ERR("[ERR]%s: H2C put fail\n", __func__); ret = MACNOBUF; goto fail; } ptr = (struct fwcmd_mcc_sync *)buf; ptr->dword0 = cpu_to_le32(SET_WORD(group, FWCMD_H2C_MCC_SYNC_GROUP) | SET_WORD(source, FWCMD_H2C_MCC_SYNC_MACID_SOURCE) | SET_WORD(target, FWCMD_H2C_MCC_SYNC_MACID_TARGET) | SET_WORD(offset, FWCMD_H2C_MCC_SYNC_SYNC_OFFSET)); ret = h2c_pkt_set_hdr(adapter, h2cb, FWCMD_TYPE_H2C, FWCMD_H2C_CAT_MAC, FWCMD_H2C_CL_MCC, FWCMD_H2C_FUNC_MCC_SYNC, 0, 0); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Set H2C HDR fail\n", __func__); goto fail; } ret = h2c_pkt_build_txd(adapter, h2cb); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Build H2C TXD fail\n", __func__); goto fail; } #if MAC_AX_PHL_H2C ret = PLTFM_TX(h2cb); #else ret = PLTFM_TX(h2cb->data, h2cb->len); #endif if (ret) { PLTFM_MSG_ERR("[ERR]%s: platform tx error %d\n", __func__, ret); goto fail; } h2cb_free(adapter, h2cb); return MACSUCCESS; fail: h2cb_free(adapter, h2cb); return ret; } u32 mac_mcc_set_duration(struct mac_ax_adapter *adapter, struct mac_ax_mcc_duration_info *info) { struct fwcmd_mcc_set_duration *ptr; #if MAC_AX_PHL_H2C struct rtw_h2c_pkt *h2cb; #else struct h2c_buf *h2cb; #endif u8 *buf; u32 ret = 0; if (adapter->sm.mcc_request[info->group] != MAC_AX_MCC_REQ_IDLE) { PLTFM_MSG_ERR("[ERR]%s: state != req idle\n", __func__); return MACPROCERR; } adapter->sm.mcc_request[info->group] = MAC_AX_MCC_REQ_H2C_SENT; h2cb = h2cb_alloc(adapter, H2CB_CLASS_DATA); if (!h2cb) { PLTFM_MSG_ERR("[ERR]%s: H2C alloc fail\n", __func__); return MACNPTR; } buf = h2cb_put(h2cb, sizeof(struct fwcmd_mcc_set_duration)); if (!buf) { PLTFM_MSG_ERR("[ERR]%s: H2C put fail\n", __func__); ret = MACNOBUF; goto fail; } ptr = (struct fwcmd_mcc_set_duration *)buf; ptr->dword0 = cpu_to_le32(SET_WORD(info->group, FWCMD_H2C_MCC_SET_DURATION_GROUP) | (info->btc_in_group ? FWCMD_H2C_MCC_SET_DURATION_BTC_IN_GROUP : 0) | SET_WORD(info->start_macid, FWCMD_H2C_MCC_SET_DURATION_START_MACID) | SET_WORD(info->macid_x, FWCMD_H2C_MCC_SET_DURATION_MACID_X) | SET_WORD(info->macid_y, FWCMD_H2C_MCC_SET_DURATION_MACID_Y)); ptr->dword1 = cpu_to_le32(SET_WORD(info->start_tsf_low, FWCMD_H2C_MCC_SET_DURATION_START_TSF_LOW)); ptr->dword2 = cpu_to_le32(SET_WORD(info->start_tsf_high, FWCMD_H2C_MCC_SET_DURATION_START_TSF_HIGH)); ptr->dword3 = cpu_to_le32(SET_WORD(info->duration_x, FWCMD_H2C_MCC_SET_DURATION_DURATION_X)); ptr->dword4 = cpu_to_le32(SET_WORD(info->duration_y, FWCMD_H2C_MCC_SET_DURATION_DURATION_Y)); ret = h2c_pkt_set_hdr(adapter, h2cb, FWCMD_TYPE_H2C, FWCMD_H2C_CAT_MAC, FWCMD_H2C_CL_MCC, FWCMD_H2C_FUNC_MCC_SET_DURATION, 0, 0); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Set H2C HDR fail\n", __func__); goto fail; } ret = h2c_pkt_build_txd(adapter, h2cb); if (ret) { PLTFM_MSG_ERR("[ERR]%s: Build H2C TXD fail\n", __func__); goto fail; } #if MAC_AX_PHL_H2C ret = PLTFM_TX(h2cb); #else ret = PLTFM_TX(h2cb->data, h2cb->len); #endif if (ret) { PLTFM_MSG_ERR("[ERR]%s: platform tx err %d\n", __func__, ret); goto fail; } h2cb_free(adapter, h2cb); return MACSUCCESS; fail: h2cb_free(adapter, h2cb); return ret; } u32 mac_get_mcc_status_rpt(struct mac_ax_adapter *adapter, u8 group, u8 *status, u32 *tsf_high, u32 *tsf_low) { struct mac_ax_mcc_group_info *mcc_info = &adapter->mcc_group_info; if (adapter->sm.mcc_group[group] == MAC_AX_MCC_EMPTY) { PLTFM_MSG_ERR("[ERR]%s: state = empty\n", __func__); return MACPROCERR; } if (group > MCC_GROUP_ID_MAX) { PLTFM_MSG_ERR("[ERR]%s: invalid group: %d\n", __func__, group); return MACNOITEM; } *status = mcc_info->groups[group].rpt_status; PLTFM_MSG_TRACE("[TRACE]%s: mcc status: %d\n", __func__, *status); *tsf_high = mcc_info->groups[group].rpt_tsf_high; *tsf_low = mcc_info->groups[group].rpt_tsf_low; PLTFM_MSG_TRACE("[TRACE]%s: report tsf_high: 0x%x\n", __func__, *tsf_high); PLTFM_MSG_TRACE("[TRACE]%s: report tsf_low: 0x%x\n", __func__, *tsf_low); return MACSUCCESS; } u32 mac_get_mcc_tsf_rpt(struct mac_ax_adapter *adapter, u8 group, u32 *tsf_x_high, u32 *tsf_x_low, u32 *tsf_y_high, u32 *tsf_y_low) { struct mac_ax_mcc_group_info *mcc_info = &adapter->mcc_group_info; if (group > MCC_GROUP_ID_MAX) { PLTFM_MSG_ERR("[ERR]%s: invalid group: %d\n", __func__, group); return MACNOITEM; } *tsf_x_high = mcc_info->groups[group].tsf_x_high; *tsf_x_low = mcc_info->groups[group].tsf_x_low; PLTFM_MSG_TRACE("[TRACE]%s: tsf_x_high: 0x%x\n", __func__, *tsf_x_high); PLTFM_MSG_TRACE("[TRACE]%s: tsf_x_low: 0x%x\n", __func__, *tsf_x_low); *tsf_y_high = mcc_info->groups[group].tsf_y_high; *tsf_y_low += mcc_info->groups[group].tsf_y_low; PLTFM_MSG_TRACE("[TRACE]%s: tsf_y_high: 0x%x\n", __func__, *tsf_y_high); PLTFM_MSG_TRACE("[TRACE]%s: tsf_y_low: 0x%x\n", __func__, *tsf_y_low); adapter->sm.mcc_request[group] = MAC_AX_MCC_REQ_IDLE; return MACSUCCESS; } u32 mac_get_mcc_group(struct mac_ax_adapter *adapter, u8 *pget_group) { struct mac_ax_state_mach *sm = &adapter->sm; u8 group_idx; for (group_idx = 0; group_idx <= MCC_GROUP_ID_MAX; group_idx++) { if (sm->mcc_group[group_idx] == MAC_AX_MCC_EMPTY) { *pget_group = group_idx; PLTFM_MSG_TRACE("[TRACE]%s: get mcc empty group %u\n", __func__, *pget_group); return MACSUCCESS; } } return MACMCCGPFL; } u32 mac_check_add_mcc_done(struct mac_ax_adapter *adapter, u8 group) { PLTFM_MSG_TRACE("[TRACE]%s: group %d curr state: %d\n", __func__, group, adapter->sm.mcc_group[group]); if (adapter->sm.mcc_group[group] == MAC_AX_MCC_ADD_DONE) return MACSUCCESS; else return MACPROCBUSY; } u32 mac_check_start_mcc_done(struct mac_ax_adapter *adapter, u8 group) { PLTFM_MSG_TRACE("[TRACE]%s: group %d curr state: %d\n", __func__, group, adapter->sm.mcc_group[group]); if (adapter->sm.mcc_group[group] == MAC_AX_MCC_START_DONE) return MACSUCCESS; else return MACPROCBUSY; } u32 mac_check_stop_mcc_done(struct mac_ax_adapter *adapter, u8 group) { PLTFM_MSG_TRACE("[TRACE]%s: group %d curr state: %d\n", __func__, group, adapter->sm.mcc_group[group]); if (adapter->sm.mcc_group[group] == MAC_AX_MCC_STOP_DONE) return MACSUCCESS; else return MACPROCBUSY; } u32 mac_check_del_mcc_group_done(struct mac_ax_adapter *adapter, u8 group) { PLTFM_MSG_TRACE("[TRACE]%s: group %d curr state: %d\n", __func__, group, adapter->sm.mcc_group[group]); if (adapter->sm.mcc_group[group] == MAC_AX_MCC_EMPTY) return MACSUCCESS; else return MACPROCBUSY; } u32 mac_check_mcc_request_tsf_done(struct mac_ax_adapter *adapter, u8 group) { PLTFM_MSG_TRACE("[TRACE]%s: group %d curr req state: %d\n", __func__, group, adapter->sm.mcc_request[group]); if (adapter->sm.mcc_request[group] == MAC_AX_MCC_REQ_DONE) return MACSUCCESS; else return MACPROCBUSY; } u32 mac_check_mcc_macid_bitmap_done(struct mac_ax_adapter *adapter, u8 group) { PLTFM_MSG_TRACE("[TRACE]%s: group %d curr req state: %d\n", __func__, group, adapter->sm.mcc_request[group]); if (adapter->sm.mcc_request[group] == MAC_AX_MCC_REQ_IDLE) return MACSUCCESS; else return MACPROCBUSY; } u32 mac_check_mcc_sync_enable_done(struct mac_ax_adapter *adapter, u8 group) { PLTFM_MSG_TRACE("[TRACE]%s: group %d curr req state: %d\n", __func__, group, adapter->sm.mcc_request[group]); if (adapter->sm.mcc_request[group] == MAC_AX_MCC_REQ_IDLE) return MACSUCCESS; else return MACPROCBUSY; } u32 mac_check_mcc_set_duration_done(struct mac_ax_adapter *adapter, u8 group) { PLTFM_MSG_TRACE("[TRACE]%s: group %d curr req state: %d\n", __func__, group, adapter->sm.mcc_request[group]); if (adapter->sm.mcc_request[group] == MAC_AX_MCC_REQ_IDLE) return MACSUCCESS; else return MACPROCBUSY; }