manage.c (8635B)
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright(c) 1999 - 2018 Intel Corporation. */ 3 4#include "e1000.h" 5 6/** 7 * e1000_calculate_checksum - Calculate checksum for buffer 8 * @buffer: pointer to EEPROM 9 * @length: size of EEPROM to calculate a checksum for 10 * 11 * Calculates the checksum for some buffer on a specified length. The 12 * checksum calculated is returned. 13 **/ 14static u8 e1000_calculate_checksum(u8 *buffer, u32 length) 15{ 16 u32 i; 17 u8 sum = 0; 18 19 if (!buffer) 20 return 0; 21 22 for (i = 0; i < length; i++) 23 sum += buffer[i]; 24 25 return (u8)(0 - sum); 26} 27 28/** 29 * e1000_mng_enable_host_if - Checks host interface is enabled 30 * @hw: pointer to the HW structure 31 * 32 * Returns 0 upon success, else -E1000_ERR_HOST_INTERFACE_COMMAND 33 * 34 * This function checks whether the HOST IF is enabled for command operation 35 * and also checks whether the previous command is completed. It busy waits 36 * in case of previous command is not completed. 37 **/ 38static s32 e1000_mng_enable_host_if(struct e1000_hw *hw) 39{ 40 u32 hicr; 41 u8 i; 42 43 if (!hw->mac.arc_subsystem_valid) { 44 e_dbg("ARC subsystem not valid.\n"); 45 return -E1000_ERR_HOST_INTERFACE_COMMAND; 46 } 47 48 /* Check that the host interface is enabled. */ 49 hicr = er32(HICR); 50 if (!(hicr & E1000_HICR_EN)) { 51 e_dbg("E1000_HOST_EN bit disabled.\n"); 52 return -E1000_ERR_HOST_INTERFACE_COMMAND; 53 } 54 /* check the previous command is completed */ 55 for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) { 56 hicr = er32(HICR); 57 if (!(hicr & E1000_HICR_C)) 58 break; 59 mdelay(1); 60 } 61 62 if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) { 63 e_dbg("Previous command timeout failed.\n"); 64 return -E1000_ERR_HOST_INTERFACE_COMMAND; 65 } 66 67 return 0; 68} 69 70/** 71 * e1000e_check_mng_mode_generic - Generic check management mode 72 * @hw: pointer to the HW structure 73 * 74 * Reads the firmware semaphore register and returns true (>0) if 75 * manageability is enabled, else false (0). 76 **/ 77bool e1000e_check_mng_mode_generic(struct e1000_hw *hw) 78{ 79 u32 fwsm = er32(FWSM); 80 81 return (fwsm & E1000_FWSM_MODE_MASK) == 82 (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT); 83} 84 85/** 86 * e1000e_enable_tx_pkt_filtering - Enable packet filtering on Tx 87 * @hw: pointer to the HW structure 88 * 89 * Enables packet filtering on transmit packets if manageability is enabled 90 * and host interface is enabled. 91 **/ 92bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) 93{ 94 struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie; 95 u32 *buffer = (u32 *)&hw->mng_cookie; 96 u32 offset; 97 s32 ret_val, hdr_csum, csum; 98 u8 i, len; 99 100 hw->mac.tx_pkt_filtering = true; 101 102 /* No manageability, no filtering */ 103 if (!hw->mac.ops.check_mng_mode(hw)) { 104 hw->mac.tx_pkt_filtering = false; 105 return hw->mac.tx_pkt_filtering; 106 } 107 108 /* If we can't read from the host interface for whatever 109 * reason, disable filtering. 110 */ 111 ret_val = e1000_mng_enable_host_if(hw); 112 if (ret_val) { 113 hw->mac.tx_pkt_filtering = false; 114 return hw->mac.tx_pkt_filtering; 115 } 116 117 /* Read in the header. Length and offset are in dwords. */ 118 len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2; 119 offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2; 120 for (i = 0; i < len; i++) 121 *(buffer + i) = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, 122 offset + i); 123 hdr_csum = hdr->checksum; 124 hdr->checksum = 0; 125 csum = e1000_calculate_checksum((u8 *)hdr, 126 E1000_MNG_DHCP_COOKIE_LENGTH); 127 /* If either the checksums or signature don't match, then 128 * the cookie area isn't considered valid, in which case we 129 * take the safe route of assuming Tx filtering is enabled. 130 */ 131 if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) { 132 hw->mac.tx_pkt_filtering = true; 133 return hw->mac.tx_pkt_filtering; 134 } 135 136 /* Cookie area is valid, make the final check for filtering. */ 137 if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) 138 hw->mac.tx_pkt_filtering = false; 139 140 return hw->mac.tx_pkt_filtering; 141} 142 143/** 144 * e1000_mng_write_cmd_header - Writes manageability command header 145 * @hw: pointer to the HW structure 146 * @hdr: pointer to the host interface command header 147 * 148 * Writes the command header after does the checksum calculation. 149 **/ 150static s32 e1000_mng_write_cmd_header(struct e1000_hw *hw, 151 struct e1000_host_mng_command_header *hdr) 152{ 153 u16 i, length = sizeof(struct e1000_host_mng_command_header); 154 155 /* Write the whole command header structure with new checksum. */ 156 157 hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length); 158 159 length >>= 2; 160 /* Write the relevant command block into the ram area. */ 161 for (i = 0; i < length; i++) { 162 E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, i, *((u32 *)hdr + i)); 163 e1e_flush(); 164 } 165 166 return 0; 167} 168 169/** 170 * e1000_mng_host_if_write - Write to the manageability host interface 171 * @hw: pointer to the HW structure 172 * @buffer: pointer to the host interface buffer 173 * @length: size of the buffer 174 * @offset: location in the buffer to write to 175 * @sum: sum of the data (not checksum) 176 * 177 * This function writes the buffer content at the offset given on the host if. 178 * It also does alignment considerations to do the writes in most efficient 179 * way. Also fills up the sum of the buffer in *buffer parameter. 180 **/ 181static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, 182 u16 length, u16 offset, u8 *sum) 183{ 184 u8 *tmp; 185 u8 *bufptr = buffer; 186 u32 data = 0; 187 u16 remaining, i, j, prev_bytes; 188 189 /* sum = only sum of the data and it is not checksum */ 190 191 if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) 192 return -E1000_ERR_PARAM; 193 194 tmp = (u8 *)&data; 195 prev_bytes = offset & 0x3; 196 offset >>= 2; 197 198 if (prev_bytes) { 199 data = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset); 200 for (j = prev_bytes; j < sizeof(u32); j++) { 201 *(tmp + j) = *bufptr++; 202 *sum += *(tmp + j); 203 } 204 E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset, data); 205 length -= j - prev_bytes; 206 offset++; 207 } 208 209 remaining = length & 0x3; 210 length -= remaining; 211 212 /* Calculate length in DWORDs */ 213 length >>= 2; 214 215 /* The device driver writes the relevant command block into the 216 * ram area. 217 */ 218 for (i = 0; i < length; i++) { 219 for (j = 0; j < sizeof(u32); j++) { 220 *(tmp + j) = *bufptr++; 221 *sum += *(tmp + j); 222 } 223 224 E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data); 225 } 226 if (remaining) { 227 for (j = 0; j < sizeof(u32); j++) { 228 if (j < remaining) 229 *(tmp + j) = *bufptr++; 230 else 231 *(tmp + j) = 0; 232 233 *sum += *(tmp + j); 234 } 235 E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data); 236 } 237 238 return 0; 239} 240 241/** 242 * e1000e_mng_write_dhcp_info - Writes DHCP info to host interface 243 * @hw: pointer to the HW structure 244 * @buffer: pointer to the host interface 245 * @length: size of the buffer 246 * 247 * Writes the DHCP information to the host interface. 248 **/ 249s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length) 250{ 251 struct e1000_host_mng_command_header hdr; 252 s32 ret_val; 253 u32 hicr; 254 255 hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD; 256 hdr.command_length = length; 257 hdr.reserved1 = 0; 258 hdr.reserved2 = 0; 259 hdr.checksum = 0; 260 261 /* Enable the host interface */ 262 ret_val = e1000_mng_enable_host_if(hw); 263 if (ret_val) 264 return ret_val; 265 266 /* Populate the host interface with the contents of "buffer". */ 267 ret_val = e1000_mng_host_if_write(hw, buffer, length, 268 sizeof(hdr), &(hdr.checksum)); 269 if (ret_val) 270 return ret_val; 271 272 /* Write the manageability command header */ 273 ret_val = e1000_mng_write_cmd_header(hw, &hdr); 274 if (ret_val) 275 return ret_val; 276 277 /* Tell the ARC a new command is pending. */ 278 hicr = er32(HICR); 279 ew32(HICR, hicr | E1000_HICR_C); 280 281 return 0; 282} 283 284/** 285 * e1000e_enable_mng_pass_thru - Check if management passthrough is needed 286 * @hw: pointer to the HW structure 287 * 288 * Verifies the hardware needs to leave interface enabled so that frames can 289 * be directed to and from the management interface. 290 **/ 291bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw) 292{ 293 u32 manc; 294 u32 fwsm, factps; 295 296 manc = er32(MANC); 297 298 if (!(manc & E1000_MANC_RCV_TCO_EN)) 299 return false; 300 301 if (hw->mac.has_fwsm) { 302 fwsm = er32(FWSM); 303 factps = er32(FACTPS); 304 305 if (!(factps & E1000_FACTPS_MNGCG) && 306 ((fwsm & E1000_FWSM_MODE_MASK) == 307 (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) 308 return true; 309 } else if ((hw->mac.type == e1000_82574) || 310 (hw->mac.type == e1000_82583)) { 311 u16 data; 312 s32 ret_val; 313 314 factps = er32(FACTPS); 315 ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); 316 if (ret_val) 317 return false; 318 319 if (!(factps & E1000_FACTPS_MNGCG) && 320 ((data & E1000_NVM_INIT_CTRL2_MNGM) == 321 (e1000_mng_mode_pt << 13))) 322 return true; 323 } else if ((manc & E1000_MANC_SMBUS_EN) && 324 !(manc & E1000_MANC_ASF_EN)) { 325 return true; 326 } 327 328 return false; 329}