Merge tag 'pci-v5.18-changes-2' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / drivers / staging / r8188eu / core / rtw_iol.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2011 Realtek Corporation. */
3
4 #include "../include/rtw_iol.h"
5
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
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
58 bool rtw_IOL_applied(struct adapter  *adapter)
59 {
60         if (1 == adapter->registrypriv.fw_iol)
61                 return true;
62
63         if ((2 == adapter->registrypriv.fw_iol) &&
64             (adapter_to_dvobj(adapter)->pusbdev->speed != USB_SPEED_HIGH))
65                 return true;
66
67         return false;
68 }
69
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
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
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
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
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
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
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
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 }