1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2011 Realtek Corporation. */
3 
4 #include "../include/rtw_iol.h"
5 
rtw_IOL_accquire_xmit_frame(struct adapter * adapter)6 struct xmit_frame	*rtw_IOL_accquire_xmit_frame(struct adapter  *adapter)
7 {
8 	struct xmit_frame	*xmit_frame;
9 	struct xmit_buf	*xmitbuf;
10 	struct pkt_attrib	*pattrib;
11 	struct xmit_priv	*pxmitpriv = &adapter->xmitpriv;
12 
13 	xmit_frame = rtw_alloc_xmitframe(pxmitpriv);
14 	if (!xmit_frame)
15 		return NULL;
16 
17 	xmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
18 	if (!xmitbuf) {
19 		rtw_free_xmitframe(pxmitpriv, xmit_frame);
20 		return NULL;
21 	}
22 
23 	xmit_frame->frame_tag = MGNT_FRAMETAG;
24 	xmit_frame->pxmitbuf = xmitbuf;
25 	xmit_frame->buf_addr = xmitbuf->pbuf;
26 	xmitbuf->priv_data = xmit_frame;
27 
28 	pattrib = &xmit_frame->attrib;
29 	update_mgntframe_attrib(adapter, pattrib);
30 	pattrib->qsel = 0x10;/* Beacon */
31 	pattrib->subtype = WIFI_BEACON;
32 	pattrib->pktlen = 0;
33 	pattrib->last_txcmdsz = 0;
34 
35 	return xmit_frame;
36 }
37 
rtw_IOL_append_cmds(struct xmit_frame * xmit_frame,u8 * IOL_cmds,u32 cmd_len)38 int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len)
39 {
40 	struct pkt_attrib	*pattrib = &xmit_frame->attrib;
41 	u16 buf_offset;
42 	u32 ori_len;
43 
44 	buf_offset = TXDESC_OFFSET;
45 	ori_len = buf_offset + pattrib->pktlen;
46 
47 	/* check if the io_buf can accommodate new cmds */
48 	if (ori_len + cmd_len + 8 > MAX_XMITBUF_SZ)
49 		return _FAIL;
50 
51 	memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len);
52 	pattrib->pktlen += cmd_len;
53 	pattrib->last_txcmdsz += cmd_len;
54 
55 	return _SUCCESS;
56 }
57 
rtw_IOL_applied(struct adapter * adapter)58 bool rtw_IOL_applied(struct adapter  *adapter)
59 {
60 	if (adapter->registrypriv.fw_iol == 1)
61 		return true;
62 
63 	if ((adapter->registrypriv.fw_iol == 2) &&
64 	    (adapter_to_dvobj(adapter)->pusbdev->speed != USB_SPEED_HIGH))
65 		return true;
66 
67 	return false;
68 }
69 
rtw_IOL_append_WB_cmd(struct xmit_frame * xmit_frame,u16 addr,u8 value,u8 mask)70 int rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask)
71 {
72 	struct ioreg_cfg cmd = {8, IOREG_CMD_WB_REG, 0x0, 0x0, 0x0};
73 
74 	cmd.address = cpu_to_le16(addr);
75 	cmd.data = cpu_to_le32(value);
76 
77 	if (mask != 0xFF) {
78 		cmd.length = 12;
79 		cmd.mask = cpu_to_le32(mask);
80 	}
81 	return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
82 }
83 
rtw_IOL_append_WW_cmd(struct xmit_frame * xmit_frame,u16 addr,u16 value,u16 mask)84 int rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask)
85 {
86 	struct ioreg_cfg cmd = {8, IOREG_CMD_WW_REG, 0x0, 0x0, 0x0};
87 
88 	cmd.address = cpu_to_le16(addr);
89 	cmd.data = cpu_to_le32(value);
90 
91 	if (mask != 0xFFFF) {
92 		cmd.length = 12;
93 		cmd.mask =  cpu_to_le32(mask);
94 	}
95 	return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
96 }
97 
rtw_IOL_append_WD_cmd(struct xmit_frame * xmit_frame,u16 addr,u32 value,u32 mask)98 int rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask)
99 {
100 	struct ioreg_cfg cmd = {8, IOREG_CMD_WD_REG, 0x0, 0x0, 0x0};
101 
102 	cmd.address = cpu_to_le16(addr);
103 	cmd.data = cpu_to_le32(value);
104 
105 	if (mask != 0xFFFFFFFF) {
106 		cmd.length = 12;
107 		cmd.mask =  cpu_to_le32(mask);
108 	}
109 	return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
110 }
111 
rtw_IOL_append_WRF_cmd(struct xmit_frame * xmit_frame,u8 rf_path,u16 addr,u32 value,u32 mask)112 int rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask)
113 {
114 	struct ioreg_cfg cmd = {8, IOREG_CMD_W_RF, 0x0, 0x0, 0x0};
115 
116 	cmd.address = cpu_to_le16((rf_path << 8) | ((addr) & 0xFF));
117 	cmd.data = cpu_to_le32(value);
118 
119 	if (mask != 0x000FFFFF) {
120 		cmd.length = 12;
121 		cmd.mask =  cpu_to_le32(mask);
122 	}
123 	return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
124 }
125 
rtw_IOL_append_DELAY_US_cmd(struct xmit_frame * xmit_frame,u16 us)126 int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
127 {
128 	struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
129 	cmd.address = cpu_to_le16(us);
130 
131 	return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
132 }
133 
rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame * xmit_frame,u16 ms)134 int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
135 {
136 	struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
137 
138 	cmd.address = cpu_to_le16(ms);
139 	return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
140 }
141 
rtw_IOL_append_END_cmd(struct xmit_frame * xmit_frame)142 int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
143 {
144 	struct ioreg_cfg cmd = {4, IOREG_CMD_END, cpu_to_le16(0xFFFF), cpu_to_le32(0xFF), 0x0};
145 
146 	return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
147 }
148 
rtw_IOL_cmd_boundary_handle(struct xmit_frame * pxmit_frame)149 u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame)
150 {
151 	u8 is_cmd_bndy = false;
152 	if (((pxmit_frame->attrib.pktlen + 32) % 256) + 8 >= 256) {
153 		rtw_IOL_append_END_cmd(pxmit_frame);
154 		pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen + 32) / 256) + 1) * 256);
155 
156 		pxmit_frame->attrib.last_txcmdsz = pxmit_frame->attrib.pktlen;
157 		is_cmd_bndy = true;
158 	}
159 	return is_cmd_bndy;
160 }
161