1 /****************************************************************************** 2 3 Copyright (c) 2001-2010, Intel Corporation 4 All rights reserved. 5 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions are met: 8 9 1. Redistributions of source code must retain the above copyright notice, 10 this list of conditions and the following disclaimer. 11 12 2. Redistributions in binary form must reproduce the above copyright 13 notice, this list of conditions and the following disclaimer in the 14 documentation and/or other materials provided with the distribution. 15 16 3. Neither the name of the Intel Corporation nor the names of its 17 contributors may be used to endorse or promote products derived from 18 this software without specific prior written permission. 19 20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 POSSIBILITY OF SUCH DAMAGE. 31 32 ******************************************************************************/ 33 /*$FreeBSD$*/ 34 35 #include "e1000_api.h" 36 37 /** 38 * e1000_calculate_checksum - Calculate checksum for buffer 39 * @buffer: pointer to EEPROM 40 * @length: size of EEPROM to calculate a checksum for 41 * 42 * Calculates the checksum for some buffer on a specified length. The 43 * checksum calculated is returned. 44 **/ 45 u8 e1000_calculate_checksum(u8 *buffer, u32 length) 46 { 47 u32 i; 48 u8 sum = 0; 49 50 DEBUGFUNC("e1000_calculate_checksum"); 51 52 if (!buffer) 53 return 0; 54 55 for (i = 0; i < length; i++) 56 sum += buffer[i]; 57 58 return (u8) (0 - sum); 59 } 60 61 /** 62 * e1000_mng_enable_host_if_generic - Checks host interface is enabled 63 * @hw: pointer to the HW structure 64 * 65 * Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND 66 * 67 * This function checks whether the HOST IF is enabled for command operation 68 * and also checks whether the previous command is completed. It busy waits 69 * in case of previous command is not completed. 70 **/ 71 s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw) 72 { 73 u32 hicr; 74 s32 ret_val = E1000_SUCCESS; 75 u8 i; 76 77 DEBUGFUNC("e1000_mng_enable_host_if_generic"); 78 79 if (!(hw->mac.arc_subsystem_valid)) { 80 DEBUGOUT("ARC subsystem not valid.\n"); 81 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND; 82 goto out; 83 } 84 85 /* Check that the host interface is enabled. */ 86 hicr = E1000_READ_REG(hw, E1000_HICR); 87 if ((hicr & E1000_HICR_EN) == 0) { 88 DEBUGOUT("E1000_HOST_EN bit disabled.\n"); 89 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND; 90 goto out; 91 } 92 /* check the previous command is completed */ 93 for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) { 94 hicr = E1000_READ_REG(hw, E1000_HICR); 95 if (!(hicr & E1000_HICR_C)) 96 break; 97 msec_delay_irq(1); 98 } 99 100 if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) { 101 DEBUGOUT("Previous command timeout failed .\n"); 102 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND; 103 goto out; 104 } 105 106 out: 107 return ret_val; 108 } 109 110 /** 111 * e1000_check_mng_mode_generic - Generic check management mode 112 * @hw: pointer to the HW structure 113 * 114 * Reads the firmware semaphore register and returns TRUE (>0) if 115 * manageability is enabled, else FALSE (0). 116 **/ 117 bool e1000_check_mng_mode_generic(struct e1000_hw *hw) 118 { 119 u32 fwsm = E1000_READ_REG(hw, E1000_FWSM); 120 121 DEBUGFUNC("e1000_check_mng_mode_generic"); 122 123 124 return (fwsm & E1000_FWSM_MODE_MASK) == 125 (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT); 126 } 127 128 /** 129 * e1000_enable_tx_pkt_filtering_generic - Enable packet filtering on Tx 130 * @hw: pointer to the HW structure 131 * 132 * Enables packet filtering on transmit packets if manageability is enabled 133 * and host interface is enabled. 134 **/ 135 bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw) 136 { 137 struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie; 138 u32 *buffer = (u32 *)&hw->mng_cookie; 139 u32 offset; 140 s32 ret_val, hdr_csum, csum; 141 u8 i, len; 142 143 DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic"); 144 145 hw->mac.tx_pkt_filtering = TRUE; 146 147 /* No manageability, no filtering */ 148 if (!hw->mac.ops.check_mng_mode(hw)) { 149 hw->mac.tx_pkt_filtering = FALSE; 150 goto out; 151 } 152 153 /* 154 * If we can't read from the host interface for whatever 155 * reason, disable filtering. 156 */ 157 ret_val = hw->mac.ops.mng_enable_host_if(hw); 158 if (ret_val != E1000_SUCCESS) { 159 hw->mac.tx_pkt_filtering = FALSE; 160 goto out; 161 } 162 163 /* Read in the header. Length and offset are in dwords. */ 164 len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2; 165 offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2; 166 for (i = 0; i < len; i++) 167 *(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, 168 offset + i); 169 hdr_csum = hdr->checksum; 170 hdr->checksum = 0; 171 csum = e1000_calculate_checksum((u8 *)hdr, 172 E1000_MNG_DHCP_COOKIE_LENGTH); 173 /* 174 * If either the checksums or signature don't match, then 175 * the cookie area isn't considered valid, in which case we 176 * take the safe route of assuming Tx filtering is enabled. 177 */ 178 if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) { 179 hw->mac.tx_pkt_filtering = TRUE; 180 goto out; 181 } 182 183 /* Cookie area is valid, make the final check for filtering. */ 184 if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) { 185 hw->mac.tx_pkt_filtering = FALSE; 186 goto out; 187 } 188 189 out: 190 return hw->mac.tx_pkt_filtering; 191 } 192 193 /** 194 * e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface 195 * @hw: pointer to the HW structure 196 * @buffer: pointer to the host interface 197 * @length: size of the buffer 198 * 199 * Writes the DHCP information to the host interface. 200 **/ 201 s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer, 202 u16 length) 203 { 204 struct e1000_host_mng_command_header hdr; 205 s32 ret_val; 206 u32 hicr; 207 208 DEBUGFUNC("e1000_mng_write_dhcp_info_generic"); 209 210 hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD; 211 hdr.command_length = length; 212 hdr.reserved1 = 0; 213 hdr.reserved2 = 0; 214 hdr.checksum = 0; 215 216 /* Enable the host interface */ 217 ret_val = hw->mac.ops.mng_enable_host_if(hw); 218 if (ret_val) 219 goto out; 220 221 /* Populate the host interface with the contents of "buffer". */ 222 ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length, 223 sizeof(hdr), &(hdr.checksum)); 224 if (ret_val) 225 goto out; 226 227 /* Write the manageability command header */ 228 ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr); 229 if (ret_val) 230 goto out; 231 232 /* Tell the ARC a new command is pending. */ 233 hicr = E1000_READ_REG(hw, E1000_HICR); 234 E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C); 235 236 out: 237 return ret_val; 238 } 239 240 /** 241 * e1000_mng_write_cmd_header_generic - Writes manageability command header 242 * @hw: pointer to the HW structure 243 * @hdr: pointer to the host interface command header 244 * 245 * Writes the command header after does the checksum calculation. 246 **/ 247 s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw, 248 struct e1000_host_mng_command_header *hdr) 249 { 250 u16 i, length = sizeof(struct e1000_host_mng_command_header); 251 252 DEBUGFUNC("e1000_mng_write_cmd_header_generic"); 253 254 /* Write the whole command header structure with new checksum. */ 255 256 hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length); 257 258 length >>= 2; 259 /* Write the relevant command block into the ram area. */ 260 for (i = 0; i < length; i++) { 261 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i, 262 *((u32 *) hdr + i)); 263 E1000_WRITE_FLUSH(hw); 264 } 265 266 return E1000_SUCCESS; 267 } 268 269 /** 270 * e1000_mng_host_if_write_generic - Write to the manageability host interface 271 * @hw: pointer to the HW structure 272 * @buffer: pointer to the host interface buffer 273 * @length: size of the buffer 274 * @offset: location in the buffer to write to 275 * @sum: sum of the data (not checksum) 276 * 277 * This function writes the buffer content at the offset given on the host if. 278 * It also does alignment considerations to do the writes in most efficient 279 * way. Also fills up the sum of the buffer in *buffer parameter. 280 **/ 281 s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer, 282 u16 length, u16 offset, u8 *sum) 283 { 284 u8 *tmp; 285 u8 *bufptr = buffer; 286 u32 data = 0; 287 s32 ret_val = E1000_SUCCESS; 288 u16 remaining, i, j, prev_bytes; 289 290 DEBUGFUNC("e1000_mng_host_if_write_generic"); 291 292 /* sum = only sum of the data and it is not checksum */ 293 294 if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) { 295 ret_val = -E1000_ERR_PARAM; 296 goto out; 297 } 298 299 tmp = (u8 *)&data; 300 prev_bytes = offset & 0x3; 301 offset >>= 2; 302 303 if (prev_bytes) { 304 data = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset); 305 for (j = prev_bytes; j < sizeof(u32); j++) { 306 *(tmp + j) = *bufptr++; 307 *sum += *(tmp + j); 308 } 309 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset, data); 310 length -= j - prev_bytes; 311 offset++; 312 } 313 314 remaining = length & 0x3; 315 length -= remaining; 316 317 /* Calculate length in DWORDs */ 318 length >>= 2; 319 320 /* 321 * The device driver writes the relevant command block into the 322 * ram area. 323 */ 324 for (i = 0; i < length; i++) { 325 for (j = 0; j < sizeof(u32); j++) { 326 *(tmp + j) = *bufptr++; 327 *sum += *(tmp + j); 328 } 329 330 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, 331 data); 332 } 333 if (remaining) { 334 for (j = 0; j < sizeof(u32); j++) { 335 if (j < remaining) 336 *(tmp + j) = *bufptr++; 337 else 338 *(tmp + j) = 0; 339 340 *sum += *(tmp + j); 341 } 342 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data); 343 } 344 345 out: 346 return ret_val; 347 } 348 349 /** 350 * e1000_enable_mng_pass_thru - Check if management passthrough is needed 351 * @hw: pointer to the HW structure 352 * 353 * Verifies the hardware needs to leave interface enabled so that frames can 354 * be directed to and from the management interface. 355 **/ 356 bool e1000_enable_mng_pass_thru(struct e1000_hw *hw) 357 { 358 u32 manc; 359 u32 fwsm, factps; 360 bool ret_val = FALSE; 361 362 DEBUGFUNC("e1000_enable_mng_pass_thru"); 363 364 if (!hw->mac.asf_firmware_present) 365 goto out; 366 367 manc = E1000_READ_REG(hw, E1000_MANC); 368 369 if (!(manc & E1000_MANC_RCV_TCO_EN)) 370 goto out; 371 372 if (hw->mac.has_fwsm) { 373 fwsm = E1000_READ_REG(hw, E1000_FWSM); 374 factps = E1000_READ_REG(hw, E1000_FACTPS); 375 376 if (!(factps & E1000_FACTPS_MNGCG) && 377 ((fwsm & E1000_FWSM_MODE_MASK) == 378 (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) { 379 ret_val = TRUE; 380 goto out; 381 } 382 } else if ((hw->mac.type == e1000_82574) || 383 (hw->mac.type == e1000_82583)) { 384 u16 data; 385 386 factps = E1000_READ_REG(hw, E1000_FACTPS); 387 e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); 388 389 if (!(factps & E1000_FACTPS_MNGCG) && 390 ((data & E1000_NVM_INIT_CTRL2_MNGM) == 391 (e1000_mng_mode_pt << 13))) { 392 ret_val = TRUE; 393 goto out; 394 } 395 } else if ((manc & E1000_MANC_SMBUS_EN) && 396 !(manc & E1000_MANC_ASF_EN)) { 397 ret_val = TRUE; 398 goto out; 399 } 400 401 out: 402 return ret_val; 403 } 404 405 /** 406 * e1000_host_interface_command - Writes buffer to host interface 407 * @hw: pointer to the HW structure 408 * @buffer: contains a command to write 409 * @length: the byte length of the buffer, must be multiple of 4 bytes 410 * 411 * Writes a buffer to the Host Interface. Upon success, returns E1000_SUCCESS 412 * else returns E1000_ERR_HOST_INTERFACE_COMMAND. 413 **/ 414 s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length) 415 { 416 u32 hicr, i; 417 s32 ret_val = E1000_SUCCESS; 418 419 DEBUGFUNC("e1000_host_interface_command"); 420 421 if (!(hw->mac.arc_subsystem_valid)) { 422 DEBUGOUT("Hardware doesn't support host interface command.\n"); 423 goto out; 424 } 425 426 if (!hw->mac.asf_firmware_present) { 427 DEBUGOUT("Firmware is not present.\n"); 428 goto out; 429 } 430 431 if (length == 0 || length & 0x3 || 432 length > E1000_HI_MAX_BLOCK_BYTE_LENGTH) { 433 DEBUGOUT("Buffer length failure.\n"); 434 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND; 435 goto out; 436 } 437 438 /* Check that the host interface is enabled. */ 439 hicr = E1000_READ_REG(hw, E1000_HICR); 440 if ((hicr & E1000_HICR_EN) == 0) { 441 DEBUGOUT("E1000_HOST_EN bit disabled.\n"); 442 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND; 443 goto out; 444 } 445 446 /* Calculate length in DWORDs */ 447 length >>= 2; 448 449 /* 450 * The device driver writes the relevant command block 451 * into the ram area. 452 */ 453 for (i = 0; i < length; i++) 454 E1000_WRITE_REG_ARRAY_DWORD(hw, 455 E1000_HOST_IF, 456 i, 457 *((u32 *)buffer + i)); 458 459 /* Setting this bit tells the ARC that a new command is pending. */ 460 E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C); 461 462 for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) { 463 hicr = E1000_READ_REG(hw, E1000_HICR); 464 if (!(hicr & E1000_HICR_C)) 465 break; 466 msec_delay(1); 467 } 468 469 /* Check command successful completion. */ 470 if (i == E1000_HI_COMMAND_TIMEOUT || 471 (!(E1000_READ_REG(hw, E1000_HICR) & E1000_HICR_SV))) { 472 DEBUGOUT("Command has failed with no status valid.\n"); 473 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND; 474 goto out; 475 } 476 477 for (i = 0; i < length; i++) 478 *((u32 *)buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw, 479 E1000_HOST_IF, 480 i); 481 482 out: 483 return ret_val; 484 } 485 486