1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
4  * All rights reserved.
5  *
6  * Purpose:  MAC routines
7  *
8  * Author: Tevin Chen
9  *
10  * Date: May 21, 1996
11  *
12  * Functions:
13  *
14  * Revision History:
15  */
16 
17 #include <linux/etherdevice.h>
18 
19 #include "desc.h"
20 #include "mac.h"
21 #include "usbpipe.h"
22 
vnt_mac_set_filter(struct vnt_private * priv,u64 mc_filter)23 int vnt_mac_set_filter(struct vnt_private *priv, u64 mc_filter)
24 {
25 	__le64 le_mc = cpu_to_le64(mc_filter);
26 
27 	return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_MAR0,
28 			       MESSAGE_REQUEST_MACREG, sizeof(le_mc),
29 			       (u8 *)&le_mc);
30 }
31 
vnt_mac_shutdown(struct vnt_private * priv)32 int vnt_mac_shutdown(struct vnt_private *priv)
33 {
34 	return vnt_control_out(priv, MESSAGE_TYPE_MACSHUTDOWN, 0, 0, 0, NULL);
35 }
36 
vnt_mac_set_bb_type(struct vnt_private * priv,u8 type)37 int vnt_mac_set_bb_type(struct vnt_private *priv, u8 type)
38 {
39 	u8 data[2];
40 
41 	data[0] = type;
42 	data[1] = EN_CFG_BB_TYPE_MASK;
43 
44 	return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0,
45 			       MESSAGE_REQUEST_MACREG,	ARRAY_SIZE(data),
46 			       data);
47 }
48 
vnt_mac_disable_keyentry(struct vnt_private * priv,u8 entry_idx)49 int vnt_mac_disable_keyentry(struct vnt_private *priv, u8 entry_idx)
50 {
51 	return vnt_control_out(priv, MESSAGE_TYPE_CLRKEYENTRY, 0, 0,
52 			       sizeof(entry_idx), &entry_idx);
53 }
54 
vnt_mac_set_keyentry(struct vnt_private * priv,u16 key_ctl,u32 entry_idx,u32 key_idx,u8 * addr,u8 * key)55 int vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx,
56 			 u32 key_idx, u8 *addr, u8 *key)
57 {
58 	struct vnt_mac_set_key set_key;
59 	u16 offset;
60 
61 	offset = MISCFIFO_KEYETRY0;
62 	offset += entry_idx * MISCFIFO_KEYENTRYSIZE;
63 
64 	set_key.u.write.key_ctl = cpu_to_le16(key_ctl);
65 	ether_addr_copy(set_key.u.write.addr, addr);
66 
67 	/* swap over swap[0] and swap[1] to get correct write order */
68 	swap(set_key.u.swap[0], set_key.u.swap[1]);
69 
70 	memcpy(set_key.key, key, WLAN_KEY_LEN_CCMP);
71 
72 	dev_dbg(&priv->usb->dev, "offset %d key ctl %d set key %24ph\n",
73 		offset, key_ctl, (u8 *)&set_key);
74 
75 	return vnt_control_out(priv, MESSAGE_TYPE_SETKEY, offset,
76 			       (u16)key_idx, sizeof(struct vnt_mac_set_key),
77 			       (u8 *)&set_key);
78 }
79 
vnt_mac_reg_bits_off(struct vnt_private * priv,u8 reg_ofs,u8 bits)80 int vnt_mac_reg_bits_off(struct vnt_private *priv, u8 reg_ofs, u8 bits)
81 {
82 	u8 data[2];
83 
84 	data[0] = 0;
85 	data[1] = bits;
86 
87 	return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, reg_ofs,
88 			       MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
89 }
90 
vnt_mac_reg_bits_on(struct vnt_private * priv,u8 reg_ofs,u8 bits)91 int vnt_mac_reg_bits_on(struct vnt_private *priv, u8 reg_ofs, u8 bits)
92 {
93 	u8 data[2];
94 
95 	data[0] = bits;
96 	data[1] = bits;
97 
98 	return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, reg_ofs,
99 			       MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
100 }
101 
vnt_mac_write_word(struct vnt_private * priv,u8 reg_ofs,u16 word)102 int vnt_mac_write_word(struct vnt_private *priv, u8 reg_ofs, u16 word)
103 {
104 	u8 data[2];
105 
106 	data[0] = (u8)(word & 0xff);
107 	data[1] = (u8)(word >> 8);
108 
109 	return vnt_control_out(priv, MESSAGE_TYPE_WRITE, reg_ofs,
110 			       MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
111 }
112 
vnt_mac_set_bssid_addr(struct vnt_private * priv,u8 * addr)113 int vnt_mac_set_bssid_addr(struct vnt_private *priv, u8 *addr)
114 {
115 	return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_BSSID0,
116 			       MESSAGE_REQUEST_MACREG, ETH_ALEN, addr);
117 }
118 
vnt_mac_enable_protect_mode(struct vnt_private * priv)119 int vnt_mac_enable_protect_mode(struct vnt_private *priv)
120 {
121 	u8 data[2];
122 
123 	data[0] = EN_CFG_PROTECT_MD;
124 	data[1] = EN_CFG_PROTECT_MD;
125 
126 	return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0,
127 			       MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
128 }
129 
vnt_mac_disable_protect_mode(struct vnt_private * priv)130 int vnt_mac_disable_protect_mode(struct vnt_private *priv)
131 {
132 	u8 data[2];
133 
134 	data[0] = 0;
135 	data[1] = EN_CFG_PROTECT_MD;
136 
137 	return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0,
138 			       MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
139 }
140 
vnt_mac_enable_barker_preamble_mode(struct vnt_private * priv)141 int vnt_mac_enable_barker_preamble_mode(struct vnt_private *priv)
142 {
143 	u8 data[2];
144 
145 	data[0] = EN_CFG_BARKER_PREAM;
146 	data[1] = EN_CFG_BARKER_PREAM;
147 
148 	return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG2,
149 			       MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
150 }
151 
vnt_mac_disable_barker_preamble_mode(struct vnt_private * priv)152 int vnt_mac_disable_barker_preamble_mode(struct vnt_private *priv)
153 {
154 	u8 data[2];
155 
156 	data[0] = 0;
157 	data[1] = EN_CFG_BARKER_PREAM;
158 
159 	return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG2,
160 			       MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
161 }
162 
vnt_mac_set_beacon_interval(struct vnt_private * priv,u16 interval)163 int vnt_mac_set_beacon_interval(struct vnt_private *priv, u16 interval)
164 {
165 	u8 data[2];
166 
167 	data[0] = (u8)(interval & 0xff);
168 	data[1] = (u8)(interval >> 8);
169 
170 	return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_BI,
171 			       MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
172 }
173 
vnt_mac_set_led(struct vnt_private * priv,u8 state,u8 led)174 int vnt_mac_set_led(struct vnt_private *priv, u8 state, u8 led)
175 {
176 	u8 data[2];
177 
178 	data[0] = led;
179 	data[1] = state;
180 
181 	return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_PAPEDELAY,
182 			       MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
183 }
184