1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. 4 * All rights reserved. 5 * 6 * File: mac.c 7 * 8 * Purpose: MAC routines 9 * 10 * Author: Tevin Chen 11 * 12 * Date: May 21, 1996 13 * 14 * Functions: 15 * 16 * Revision History: 17 */ 18 19 #include <linux/etherdevice.h> 20 21 #include "desc.h" 22 #include "mac.h" 23 #include "usbpipe.h" 24 25 /* 26 * Description: 27 * Write MAC Multicast Address Mask 28 * 29 * Parameters: 30 * In: 31 * mc_filter (mac filter) 32 * Out: 33 * none 34 * 35 * Return Value: none 36 * 37 */ 38 void vnt_mac_set_filter(struct vnt_private *priv, u64 mc_filter) 39 { 40 __le64 le_mc = cpu_to_le64(mc_filter); 41 42 vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_MAR0, 43 MESSAGE_REQUEST_MACREG, sizeof(le_mc), (u8 *)&le_mc); 44 } 45 46 /* 47 * Description: 48 * Shut Down MAC 49 * 50 * Parameters: 51 * In: 52 * Out: 53 * none 54 * 55 * 56 */ 57 void vnt_mac_shutdown(struct vnt_private *priv) 58 { 59 vnt_control_out(priv, MESSAGE_TYPE_MACSHUTDOWN, 0, 0, 0, NULL); 60 } 61 62 void vnt_mac_set_bb_type(struct vnt_private *priv, u8 type) 63 { 64 u8 data[2]; 65 66 data[0] = type; 67 data[1] = EnCFG_BBType_MASK; 68 69 vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0, 70 MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); 71 } 72 73 /* 74 * Description: 75 * Disable the Key Entry by MISCFIFO 76 * 77 * Parameters: 78 * In: 79 * dwIoBase - Base Address for MAC 80 * 81 * Out: 82 * none 83 * 84 * Return Value: none 85 * 86 */ 87 void vnt_mac_disable_keyentry(struct vnt_private *priv, u8 entry_idx) 88 { 89 vnt_control_out(priv, MESSAGE_TYPE_CLRKEYENTRY, 0, 0, 90 sizeof(entry_idx), &entry_idx); 91 } 92 93 /* 94 * Description: 95 * Set the Key by MISCFIFO 96 * 97 * Parameters: 98 * In: 99 * dwIoBase - Base Address for MAC 100 * 101 * Out: 102 * none 103 * 104 * Return Value: none 105 * 106 */ 107 void vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx, 108 u32 key_idx, u8 *addr, u8 *key) 109 { 110 struct vnt_mac_set_key set_key; 111 u16 offset; 112 113 offset = MISCFIFO_KEYETRY0; 114 offset += entry_idx * MISCFIFO_KEYENTRYSIZE; 115 116 set_key.u.write.key_ctl = cpu_to_le16(key_ctl); 117 ether_addr_copy(set_key.u.write.addr, addr); 118 119 /* swap over swap[0] and swap[1] to get correct write order */ 120 swap(set_key.u.swap[0], set_key.u.swap[1]); 121 122 memcpy(set_key.key, key, WLAN_KEY_LEN_CCMP); 123 124 dev_dbg(&priv->usb->dev, "offset %d key ctl %d set key %24ph\n", 125 offset, key_ctl, (u8 *)&set_key); 126 127 vnt_control_out(priv, MESSAGE_TYPE_SETKEY, offset, 128 (u16)key_idx, sizeof(struct vnt_mac_set_key), 129 (u8 *)&set_key); 130 } 131 132 void vnt_mac_reg_bits_off(struct vnt_private *priv, u8 reg_ofs, u8 bits) 133 { 134 u8 data[2]; 135 136 data[0] = 0; 137 data[1] = bits; 138 139 vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, 140 reg_ofs, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), 141 data); 142 } 143 144 void vnt_mac_reg_bits_on(struct vnt_private *priv, u8 reg_ofs, u8 bits) 145 { 146 u8 data[2]; 147 148 data[0] = bits; 149 data[1] = bits; 150 151 vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, reg_ofs, 152 MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); 153 } 154 155 void vnt_mac_write_word(struct vnt_private *priv, u8 reg_ofs, u16 word) 156 { 157 u8 data[2]; 158 159 data[0] = (u8)(word & 0xff); 160 data[1] = (u8)(word >> 8); 161 162 vnt_control_out(priv, MESSAGE_TYPE_WRITE, reg_ofs, 163 MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); 164 } 165 166 void vnt_mac_set_bssid_addr(struct vnt_private *priv, u8 *addr) 167 { 168 vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_BSSID0, 169 MESSAGE_REQUEST_MACREG, ETH_ALEN, addr); 170 } 171 172 void vnt_mac_enable_protect_mode(struct vnt_private *priv) 173 { 174 u8 data[2]; 175 176 data[0] = EnCFG_ProtectMd; 177 data[1] = EnCFG_ProtectMd; 178 179 vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0, 180 MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); 181 } 182 183 void vnt_mac_disable_protect_mode(struct vnt_private *priv) 184 { 185 u8 data[2]; 186 187 data[0] = 0; 188 data[1] = EnCFG_ProtectMd; 189 190 vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0, 191 MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); 192 } 193 194 void vnt_mac_enable_barker_preamble_mode(struct vnt_private *priv) 195 { 196 u8 data[2]; 197 198 data[0] = EnCFG_BarkerPream; 199 data[1] = EnCFG_BarkerPream; 200 201 vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG2, 202 MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); 203 } 204 205 void vnt_mac_disable_barker_preamble_mode(struct vnt_private *priv) 206 { 207 u8 data[2]; 208 209 data[0] = 0; 210 data[1] = EnCFG_BarkerPream; 211 212 vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG2, 213 MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); 214 } 215 216 void vnt_mac_set_beacon_interval(struct vnt_private *priv, u16 interval) 217 { 218 u8 data[2]; 219 220 data[0] = (u8)(interval & 0xff); 221 data[1] = (u8)(interval >> 8); 222 223 vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_BI, 224 MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); 225 } 226 227 void vnt_mac_set_led(struct vnt_private *priv, u8 state, u8 led) 228 { 229 u8 data[2]; 230 231 data[0] = led; 232 data[1] = state; 233 234 vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_PAPEDELAY, 235 MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); 236 } 237