Path: blob/master/ALFA-W1F1/RTL8814AU/core/rtw_iol.c
1307 views
/******************************************************************************1*2* Copyright(c) 2007 - 2017 Realtek Corporation.3*4* This program is free software; you can redistribute it and/or modify it5* under the terms of version 2 of the GNU General Public License as6* published by the Free Software Foundation.7*8* This program is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for11* more details.12*13*****************************************************************************/1415#include <drv_types.h>1617#ifdef CONFIG_IOL18struct xmit_frame *rtw_IOL_accquire_xmit_frame(ADAPTER *adapter)19{20struct xmit_frame *xmit_frame;21struct xmit_buf *xmitbuf;22struct pkt_attrib *pattrib;23struct xmit_priv *pxmitpriv = &(adapter->xmitpriv);2425#if 126xmit_frame = rtw_alloc_xmitframe(pxmitpriv);27if (xmit_frame == NULL) {28RTW_INFO("%s rtw_alloc_xmitframe return null\n", __FUNCTION__);29goto exit;30}3132xmitbuf = rtw_alloc_xmitbuf(pxmitpriv);33if (xmitbuf == NULL) {34RTW_INFO("%s rtw_alloc_xmitbuf return null\n", __FUNCTION__);35rtw_free_xmitframe(pxmitpriv, xmit_frame);36xmit_frame = NULL;37goto exit;38}3940xmit_frame->frame_tag = MGNT_FRAMETAG;41xmit_frame->pxmitbuf = xmitbuf;42xmit_frame->buf_addr = xmitbuf->pbuf;43xmitbuf->priv_data = xmit_frame;4445pattrib = &xmit_frame->attrib;46update_mgntframe_attrib(adapter, pattrib);47pattrib->qsel = QSLT_BEACON;/* Beacon */48pattrib->subtype = WIFI_BEACON;49pattrib->pktlen = pattrib->last_txcmdsz = 0;5051#else52xmit_frame = alloc_mgtxmitframe(pxmitpriv);53if (xmit_frame == NULL)54RTW_INFO("%s alloc_mgtxmitframe return null\n", __FUNCTION__);55else {56pattrib = &xmit_frame->attrib;57update_mgntframe_attrib(adapter, pattrib);58pattrib->qsel = QSLT_BEACON;59pattrib->pktlen = pattrib->last_txcmdsz = 0;60}61#endif6263exit:64return xmit_frame;65}666768int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len)69{70struct pkt_attrib *pattrib = &xmit_frame->attrib;71u16 buf_offset;72u32 ori_len;7374buf_offset = TXDESC_OFFSET;75ori_len = buf_offset + pattrib->pktlen;7677/* check if the io_buf can accommodate new cmds */78if (ori_len + cmd_len + 8 > MAX_XMITBUF_SZ) {79RTW_INFO("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n", __FUNCTION__80, ori_len + cmd_len + 8, MAX_XMITBUF_SZ);81return _FAIL;82}8384_rtw_memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len);85pattrib->pktlen += cmd_len;86pattrib->last_txcmdsz += cmd_len;8788/* RTW_INFO("%s ori:%u + cmd_len:%u = %u\n", __FUNCTION__, ori_len, cmd_len, buf_offset+pattrib->pktlen); */8990return _SUCCESS;91}9293bool rtw_IOL_applied(ADAPTER *adapter)94{95if (1 == adapter->registrypriv.fw_iol)96return _TRUE;9798#ifdef CONFIG_USB_HCI99if ((2 == adapter->registrypriv.fw_iol) && (IS_FULL_SPEED_USB(adapter)))100return _TRUE;101#endif102103return _FALSE;104}105106int rtw_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)107{108return rtw_hal_iol_cmd(adapter, xmit_frame, max_wating_ms, bndy_cnt);109}110111#ifdef CONFIG_IOL_NEW_GENERATION112int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)113{114return _SUCCESS;115}116int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask)117{118struct ioreg_cfg cmd = {8, IOREG_CMD_WB_REG, 0x0, 0x0, 0x0};119120/* RTW_PUT_LE16((u8*)&cmd.address, addr); */121/* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */122cmd.address = cpu_to_le16(addr);123cmd.data = cpu_to_le32(value);124125if (mask != 0xFF) {126cmd.length = 12;127/* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */128cmd.mask = cpu_to_le32(mask);129}130131/* RTW_INFO("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FUNCTION__, addr,value,mask); */132133return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);134135}136int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask)137{138struct ioreg_cfg cmd = {8, IOREG_CMD_WW_REG, 0x0, 0x0, 0x0};139140/* RTW_PUT_LE16((u8*)&cmd.address, addr); */141/* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */142cmd.address = cpu_to_le16(addr);143cmd.data = cpu_to_le32(value);144145if (mask != 0xFFFF) {146cmd.length = 12;147/* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */148cmd.mask = cpu_to_le32(mask);149}150151/* RTW_INFO("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FUNCTION__, addr,value,mask); */152153return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);154155}156int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask)157{158struct ioreg_cfg cmd = {8, IOREG_CMD_WD_REG, 0x0, 0x0, 0x0};159160/* RTW_PUT_LE16((u8*)&cmd.address, addr); */161/* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */162cmd.address = cpu_to_le16(addr);163cmd.data = cpu_to_le32(value);164165if (mask != 0xFFFFFFFF) {166cmd.length = 12;167/* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */168cmd.mask = cpu_to_le32(mask);169}170171/* RTW_INFO("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FU2NCTION__, addr,value,mask); */172173return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);174175}176177int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask)178{179struct ioreg_cfg cmd = {8, IOREG_CMD_W_RF, 0x0, 0x0, 0x0};180181/* RTW_PUT_LE16((u8*)&cmd.address, addr); */182/* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */183cmd.address = (rf_path << 8) | ((addr) & 0xFF);184cmd.data = cpu_to_le32(value);185186if (mask != 0x000FFFFF) {187cmd.length = 12;188/* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */189cmd.mask = cpu_to_le32(mask);190}191192/* RTW_INFO("%s rf_path:0x%02x addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FU2NCTION__,rf_path, addr,value,mask); */193194return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);195196}197198199200int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)201{202struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};203/* RTW_PUT_LE16((u8*)&cmd.address, us); */204cmd.address = cpu_to_le16(us);205206/* RTW_INFO("%s %u\n", __FUNCTION__, us); */207return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);208}209210int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)211{212struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};213214/* RTW_PUT_LE16((u8*)&cmd.address, ms); */215cmd.address = cpu_to_le16(ms);216217/* RTW_INFO("%s %u\n", __FUNCTION__, ms); */218return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);219}220int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)221{222struct ioreg_cfg cmd = {4, IOREG_CMD_END, 0xFFFF, 0xFF, 0x0};223return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);224225}226227u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame)228{229u8 is_cmd_bndy = _FALSE;230if (((pxmit_frame->attrib.pktlen + 32) % 256) + 8 >= 256) {231rtw_IOL_append_END_cmd(pxmit_frame);232pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen + 32) / 256) + 1) * 256);233234/* printk("==> %s, pktlen(%d)\n",__FUNCTION__,pxmit_frame->attrib.pktlen); */235pxmit_frame->attrib.last_txcmdsz = pxmit_frame->attrib.pktlen;236is_cmd_bndy = _TRUE;237}238return is_cmd_bndy;239}240241void rtw_IOL_cmd_buf_dump(ADAPTER *Adapter, int buf_len, u8 *pbuf)242{243int i;244int j = 1;245246printk("###### %s ######\n", __FUNCTION__);247for (i = 0; i < buf_len; i++) {248printk("%02x-", *(pbuf + i));249250if (j % 32 == 0)251printk("\n");252j++;253}254printk("\n");255printk("============= ioreg_cmd len = %d ===============\n", buf_len);256}257258259#else /* CONFIG_IOL_NEW_GENERATION */260int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)261{262IOL_CMD cmd = {0x0, IOL_CMD_LLT, 0x0, 0x0};263264RTW_PUT_BE32((u8 *)&cmd.value, (u32)page_boundary);265266return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);267}268269int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value)270{271IOL_CMD cmd = {0x0, IOL_CMD_WB_REG, 0x0, 0x0};272273RTW_PUT_BE16((u8 *)&cmd.address, (u16)addr);274RTW_PUT_BE32((u8 *)&cmd.value, (u32)value);275276return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);277}278279int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value)280{281IOL_CMD cmd = {0x0, IOL_CMD_WW_REG, 0x0, 0x0};282283RTW_PUT_BE16((u8 *)&cmd.address, (u16)addr);284RTW_PUT_BE32((u8 *)&cmd.value, (u32)value);285286return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);287}288289int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value)290{291IOL_CMD cmd = {0x0, IOL_CMD_WD_REG, 0x0, 0x0};292u8 *pos = (u8 *)&cmd;293294RTW_PUT_BE16((u8 *)&cmd.address, (u16)addr);295RTW_PUT_BE32((u8 *)&cmd.value, (u32)value);296297return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);298}299300#ifdef DBG_IO301int dbg_rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, const char *caller, const int line)302{303if (match_write_sniff(xmit_frame->padapter, addr, 1, value)) {304RTW_INFO("DBG_IO %s:%d IOL_WB(0x%04x, 0x%02x)\n"305, caller, line, addr, value);306}307308return _rtw_IOL_append_WB_cmd(xmit_frame, addr, value);309}310311int dbg_rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, const char *caller, const int line)312{313if (match_write_sniff(xmit_frame->padapter, addr, 2, value)) {314RTW_INFO("DBG_IO %s:%d IOL_WW(0x%04x, 0x%04x)\n"315, caller, line, addr, value);316}317318return _rtw_IOL_append_WW_cmd(xmit_frame, addr, value);319}320321int dbg_rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, const char *caller, const int line)322{323if (match_write_sniff(xmit_frame->padapter, addr, 4, value)) {324RTW_INFO("DBG_IO %s:%d IOL_WD(0x%04x, 0x%08x)\n"325, caller, line, addr, value);326}327328return _rtw_IOL_append_WD_cmd(xmit_frame, addr, value);329}330#endif331332int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)333{334IOL_CMD cmd = {0x0, IOL_CMD_DELAY_US, 0x0, 0x0};335336RTW_PUT_BE32((u8 *)&cmd.value, (u32)us);337338/* RTW_INFO("%s %u\n", __FUNCTION__, us); */339340return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);341}342343int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)344{345IOL_CMD cmd = {0x0, IOL_CMD_DELAY_MS, 0x0, 0x0};346347RTW_PUT_BE32((u8 *)&cmd.value, (u32)ms);348349/* RTW_INFO("%s %u\n", __FUNCTION__, ms); */350351return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);352}353354int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)355{356IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0};357358359return rtw_IOL_append_cmds(xmit_frame, (u8 *)&end_cmd, 8);360361}362363int rtw_IOL_exec_cmd_array_sync(PADAPTER adapter, u8 *IOL_cmds, u32 cmd_num, u32 max_wating_ms)364{365struct xmit_frame *xmit_frame;366367xmit_frame = rtw_IOL_accquire_xmit_frame(adapter);368if (xmit_frame == NULL)369return _FAIL;370371if (rtw_IOL_append_cmds(xmit_frame, IOL_cmds, cmd_num << 3) == _FAIL)372return _FAIL;373374return rtw_IOL_exec_cmds_sync(adapter, xmit_frame, max_wating_ms, 0);375}376377int rtw_IOL_exec_empty_cmds_sync(ADAPTER *adapter, u32 max_wating_ms)378{379IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0};380return rtw_IOL_exec_cmd_array_sync(adapter, (u8 *)&end_cmd, 1, max_wating_ms);381}382#endif /* CONFIG_IOL_NEW_GENERATION */383384385386387#endif /* CONFIG_IOL */388389390