18cfa0ad2SJack F Vogel /****************************************************************************** 28cfa0ad2SJack F Vogel 38cfa0ad2SJack F Vogel Copyright (c) 2001-2008, Intel Corporation 48cfa0ad2SJack F Vogel All rights reserved. 58cfa0ad2SJack F Vogel 68cfa0ad2SJack F Vogel Redistribution and use in source and binary forms, with or without 78cfa0ad2SJack F Vogel modification, are permitted provided that the following conditions are met: 88cfa0ad2SJack F Vogel 98cfa0ad2SJack F Vogel 1. Redistributions of source code must retain the above copyright notice, 108cfa0ad2SJack F Vogel this list of conditions and the following disclaimer. 118cfa0ad2SJack F Vogel 128cfa0ad2SJack F Vogel 2. Redistributions in binary form must reproduce the above copyright 138cfa0ad2SJack F Vogel notice, this list of conditions and the following disclaimer in the 148cfa0ad2SJack F Vogel documentation and/or other materials provided with the distribution. 158cfa0ad2SJack F Vogel 168cfa0ad2SJack F Vogel 3. Neither the name of the Intel Corporation nor the names of its 178cfa0ad2SJack F Vogel contributors may be used to endorse or promote products derived from 188cfa0ad2SJack F Vogel this software without specific prior written permission. 198cfa0ad2SJack F Vogel 208cfa0ad2SJack F Vogel THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 218cfa0ad2SJack F Vogel AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 228cfa0ad2SJack F Vogel IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 238cfa0ad2SJack F Vogel ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 248cfa0ad2SJack F Vogel LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 258cfa0ad2SJack F Vogel CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 268cfa0ad2SJack F Vogel SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 278cfa0ad2SJack F Vogel INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 288cfa0ad2SJack F Vogel CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 298cfa0ad2SJack F Vogel ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 308cfa0ad2SJack F Vogel POSSIBILITY OF SUCH DAMAGE. 318cfa0ad2SJack F Vogel 328cfa0ad2SJack F Vogel ******************************************************************************/ 338cfa0ad2SJack F Vogel /*$FreeBSD$*/ 348cfa0ad2SJack F Vogel 358cfa0ad2SJack F Vogel #include "e1000_api.h" 368cfa0ad2SJack F Vogel 378cfa0ad2SJack F Vogel static u8 e1000_calculate_checksum(u8 *buffer, u32 length); 388cfa0ad2SJack F Vogel 398cfa0ad2SJack F Vogel /** 408cfa0ad2SJack F Vogel * e1000_calculate_checksum - Calculate checksum for buffer 418cfa0ad2SJack F Vogel * @buffer: pointer to EEPROM 428cfa0ad2SJack F Vogel * @length: size of EEPROM to calculate a checksum for 438cfa0ad2SJack F Vogel * 448cfa0ad2SJack F Vogel * Calculates the checksum for some buffer on a specified length. The 458cfa0ad2SJack F Vogel * checksum calculated is returned. 468cfa0ad2SJack F Vogel **/ 478cfa0ad2SJack F Vogel static u8 e1000_calculate_checksum(u8 *buffer, u32 length) 488cfa0ad2SJack F Vogel { 498cfa0ad2SJack F Vogel u32 i; 508cfa0ad2SJack F Vogel u8 sum = 0; 518cfa0ad2SJack F Vogel 528cfa0ad2SJack F Vogel DEBUGFUNC("e1000_calculate_checksum"); 538cfa0ad2SJack F Vogel 548cfa0ad2SJack F Vogel if (!buffer) 558cfa0ad2SJack F Vogel return 0; 568cfa0ad2SJack F Vogel 578cfa0ad2SJack F Vogel for (i = 0; i < length; i++) 588cfa0ad2SJack F Vogel sum += buffer[i]; 598cfa0ad2SJack F Vogel 608cfa0ad2SJack F Vogel return (u8) (0 - sum); 618cfa0ad2SJack F Vogel } 628cfa0ad2SJack F Vogel 638cfa0ad2SJack F Vogel /** 648cfa0ad2SJack F Vogel * e1000_mng_enable_host_if_generic - Checks host interface is enabled 658cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 668cfa0ad2SJack F Vogel * 678cfa0ad2SJack F Vogel * Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND 688cfa0ad2SJack F Vogel * 698cfa0ad2SJack F Vogel * This function checks whether the HOST IF is enabled for command operation 708cfa0ad2SJack F Vogel * and also checks whether the previous command is completed. It busy waits 718cfa0ad2SJack F Vogel * in case of previous command is not completed. 728cfa0ad2SJack F Vogel **/ 738cfa0ad2SJack F Vogel s32 e1000_mng_enable_host_if_generic(struct e1000_hw * hw) 748cfa0ad2SJack F Vogel { 758cfa0ad2SJack F Vogel u32 hicr; 768cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS; 778cfa0ad2SJack F Vogel u8 i; 788cfa0ad2SJack F Vogel 798cfa0ad2SJack F Vogel DEBUGFUNC("e1000_mng_enable_host_if_generic"); 808cfa0ad2SJack F Vogel 818cfa0ad2SJack F Vogel /* Check that the host interface is enabled. */ 828cfa0ad2SJack F Vogel hicr = E1000_READ_REG(hw, E1000_HICR); 838cfa0ad2SJack F Vogel if ((hicr & E1000_HICR_EN) == 0) { 848cfa0ad2SJack F Vogel DEBUGOUT("E1000_HOST_EN bit disabled.\n"); 858cfa0ad2SJack F Vogel ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND; 868cfa0ad2SJack F Vogel goto out; 878cfa0ad2SJack F Vogel } 888cfa0ad2SJack F Vogel /* check the previous command is completed */ 898cfa0ad2SJack F Vogel for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) { 908cfa0ad2SJack F Vogel hicr = E1000_READ_REG(hw, E1000_HICR); 918cfa0ad2SJack F Vogel if (!(hicr & E1000_HICR_C)) 928cfa0ad2SJack F Vogel break; 938cfa0ad2SJack F Vogel msec_delay_irq(1); 948cfa0ad2SJack F Vogel } 958cfa0ad2SJack F Vogel 968cfa0ad2SJack F Vogel if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) { 978cfa0ad2SJack F Vogel DEBUGOUT("Previous command timeout failed .\n"); 988cfa0ad2SJack F Vogel ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND; 998cfa0ad2SJack F Vogel goto out; 1008cfa0ad2SJack F Vogel } 1018cfa0ad2SJack F Vogel 1028cfa0ad2SJack F Vogel out: 1038cfa0ad2SJack F Vogel return ret_val; 1048cfa0ad2SJack F Vogel } 1058cfa0ad2SJack F Vogel 1068cfa0ad2SJack F Vogel /** 1078cfa0ad2SJack F Vogel * e1000_check_mng_mode_generic - Generic check management mode 1088cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 1098cfa0ad2SJack F Vogel * 1108cfa0ad2SJack F Vogel * Reads the firmware semaphore register and returns TRUE (>0) if 1118cfa0ad2SJack F Vogel * manageability is enabled, else FALSE (0). 1128cfa0ad2SJack F Vogel **/ 1138cfa0ad2SJack F Vogel bool e1000_check_mng_mode_generic(struct e1000_hw *hw) 1148cfa0ad2SJack F Vogel { 1158cfa0ad2SJack F Vogel u32 fwsm; 1168cfa0ad2SJack F Vogel 1178cfa0ad2SJack F Vogel DEBUGFUNC("e1000_check_mng_mode_generic"); 1188cfa0ad2SJack F Vogel 1198cfa0ad2SJack F Vogel fwsm = E1000_READ_REG(hw, E1000_FWSM); 1208cfa0ad2SJack F Vogel 1218cfa0ad2SJack F Vogel return ((fwsm & E1000_FWSM_MODE_MASK) == 1228cfa0ad2SJack F Vogel (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT)); 1238cfa0ad2SJack F Vogel } 1248cfa0ad2SJack F Vogel 1258cfa0ad2SJack F Vogel /** 1268cfa0ad2SJack F Vogel * e1000_enable_tx_pkt_filtering_generic - Enable packet filtering on TX 1278cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 1288cfa0ad2SJack F Vogel * 1298cfa0ad2SJack F Vogel * Enables packet filtering on transmit packets if manageability is enabled 1308cfa0ad2SJack F Vogel * and host interface is enabled. 1318cfa0ad2SJack F Vogel **/ 1328cfa0ad2SJack F Vogel bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw) 1338cfa0ad2SJack F Vogel { 1348cfa0ad2SJack F Vogel struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie; 1358cfa0ad2SJack F Vogel u32 *buffer = (u32 *)&hw->mng_cookie; 1368cfa0ad2SJack F Vogel u32 offset; 1378cfa0ad2SJack F Vogel s32 ret_val, hdr_csum, csum; 1388cfa0ad2SJack F Vogel u8 i, len; 1398cfa0ad2SJack F Vogel bool tx_filter = TRUE; 1408cfa0ad2SJack F Vogel 1418cfa0ad2SJack F Vogel DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic"); 1428cfa0ad2SJack F Vogel 1438cfa0ad2SJack F Vogel /* No manageability, no filtering */ 1448cfa0ad2SJack F Vogel if (!hw->mac.ops.check_mng_mode(hw)) { 1458cfa0ad2SJack F Vogel tx_filter = FALSE; 1468cfa0ad2SJack F Vogel goto out; 1478cfa0ad2SJack F Vogel } 1488cfa0ad2SJack F Vogel 1498cfa0ad2SJack F Vogel /* 1508cfa0ad2SJack F Vogel * If we can't read from the host interface for whatever 1518cfa0ad2SJack F Vogel * reason, disable filtering. 1528cfa0ad2SJack F Vogel */ 1538cfa0ad2SJack F Vogel ret_val = hw->mac.ops.mng_enable_host_if(hw); 1548cfa0ad2SJack F Vogel if (ret_val != E1000_SUCCESS) { 1558cfa0ad2SJack F Vogel tx_filter = FALSE; 1568cfa0ad2SJack F Vogel goto out; 1578cfa0ad2SJack F Vogel } 1588cfa0ad2SJack F Vogel 1598cfa0ad2SJack F Vogel /* Read in the header. Length and offset are in dwords. */ 1608cfa0ad2SJack F Vogel len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2; 1618cfa0ad2SJack F Vogel offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2; 1628cfa0ad2SJack F Vogel for (i = 0; i < len; i++) { 1638cfa0ad2SJack F Vogel *(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw, 1648cfa0ad2SJack F Vogel E1000_HOST_IF, 1658cfa0ad2SJack F Vogel offset + i); 1668cfa0ad2SJack F Vogel } 1678cfa0ad2SJack F Vogel hdr_csum = hdr->checksum; 1688cfa0ad2SJack F Vogel hdr->checksum = 0; 1698cfa0ad2SJack F Vogel csum = e1000_calculate_checksum((u8 *)hdr, 1708cfa0ad2SJack F Vogel E1000_MNG_DHCP_COOKIE_LENGTH); 1718cfa0ad2SJack F Vogel /* 1728cfa0ad2SJack F Vogel * If either the checksums or signature don't match, then 1738cfa0ad2SJack F Vogel * the cookie area isn't considered valid, in which case we 1748cfa0ad2SJack F Vogel * take the safe route of assuming Tx filtering is enabled. 1758cfa0ad2SJack F Vogel */ 1768cfa0ad2SJack F Vogel if (hdr_csum != csum) 1778cfa0ad2SJack F Vogel goto out; 1788cfa0ad2SJack F Vogel if (hdr->signature != E1000_IAMT_SIGNATURE) 1798cfa0ad2SJack F Vogel goto out; 1808cfa0ad2SJack F Vogel 1818cfa0ad2SJack F Vogel /* Cookie area is valid, make the final check for filtering. */ 1828cfa0ad2SJack F Vogel if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) 1838cfa0ad2SJack F Vogel tx_filter = FALSE; 1848cfa0ad2SJack F Vogel 1858cfa0ad2SJack F Vogel out: 1868cfa0ad2SJack F Vogel hw->mac.tx_pkt_filtering = tx_filter; 1878cfa0ad2SJack F Vogel return tx_filter; 1888cfa0ad2SJack F Vogel } 1898cfa0ad2SJack F Vogel 1908cfa0ad2SJack F Vogel /** 1918cfa0ad2SJack F Vogel * e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface 1928cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 1938cfa0ad2SJack F Vogel * @buffer: pointer to the host interface 1948cfa0ad2SJack F Vogel * @length: size of the buffer 1958cfa0ad2SJack F Vogel * 1968cfa0ad2SJack F Vogel * Writes the DHCP information to the host interface. 1978cfa0ad2SJack F Vogel **/ 1988cfa0ad2SJack F Vogel s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw * hw, u8 *buffer, 1998cfa0ad2SJack F Vogel u16 length) 2008cfa0ad2SJack F Vogel { 2018cfa0ad2SJack F Vogel struct e1000_host_mng_command_header hdr; 2028cfa0ad2SJack F Vogel s32 ret_val; 2038cfa0ad2SJack F Vogel u32 hicr; 2048cfa0ad2SJack F Vogel 2058cfa0ad2SJack F Vogel DEBUGFUNC("e1000_mng_write_dhcp_info_generic"); 2068cfa0ad2SJack F Vogel 2078cfa0ad2SJack F Vogel hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD; 2088cfa0ad2SJack F Vogel hdr.command_length = length; 2098cfa0ad2SJack F Vogel hdr.reserved1 = 0; 2108cfa0ad2SJack F Vogel hdr.reserved2 = 0; 2118cfa0ad2SJack F Vogel hdr.checksum = 0; 2128cfa0ad2SJack F Vogel 2138cfa0ad2SJack F Vogel /* Enable the host interface */ 2148cfa0ad2SJack F Vogel ret_val = hw->mac.ops.mng_enable_host_if(hw); 2158cfa0ad2SJack F Vogel if (ret_val) 2168cfa0ad2SJack F Vogel goto out; 2178cfa0ad2SJack F Vogel 2188cfa0ad2SJack F Vogel /* Populate the host interface with the contents of "buffer". */ 2198cfa0ad2SJack F Vogel ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length, 2208cfa0ad2SJack F Vogel sizeof(hdr), &(hdr.checksum)); 2218cfa0ad2SJack F Vogel if (ret_val) 2228cfa0ad2SJack F Vogel goto out; 2238cfa0ad2SJack F Vogel 2248cfa0ad2SJack F Vogel /* Write the manageability command header */ 2258cfa0ad2SJack F Vogel ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr); 2268cfa0ad2SJack F Vogel if (ret_val) 2278cfa0ad2SJack F Vogel goto out; 2288cfa0ad2SJack F Vogel 2298cfa0ad2SJack F Vogel /* Tell the ARC a new command is pending. */ 2308cfa0ad2SJack F Vogel hicr = E1000_READ_REG(hw, E1000_HICR); 2318cfa0ad2SJack F Vogel E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C); 2328cfa0ad2SJack F Vogel 2338cfa0ad2SJack F Vogel out: 2348cfa0ad2SJack F Vogel return ret_val; 2358cfa0ad2SJack F Vogel } 2368cfa0ad2SJack F Vogel 2378cfa0ad2SJack F Vogel /** 2388cfa0ad2SJack F Vogel * e1000_mng_write_cmd_header_generic - Writes manageability command header 2398cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 2408cfa0ad2SJack F Vogel * @hdr: pointer to the host interface command header 2418cfa0ad2SJack F Vogel * 2428cfa0ad2SJack F Vogel * Writes the command header after does the checksum calculation. 2438cfa0ad2SJack F Vogel **/ 2448cfa0ad2SJack F Vogel s32 e1000_mng_write_cmd_header_generic(struct e1000_hw * hw, 2458cfa0ad2SJack F Vogel struct e1000_host_mng_command_header * hdr) 2468cfa0ad2SJack F Vogel { 2478cfa0ad2SJack F Vogel u16 i, length = sizeof(struct e1000_host_mng_command_header); 2488cfa0ad2SJack F Vogel 2498cfa0ad2SJack F Vogel DEBUGFUNC("e1000_mng_write_cmd_header_generic"); 2508cfa0ad2SJack F Vogel 2518cfa0ad2SJack F Vogel /* Write the whole command header structure with new checksum. */ 2528cfa0ad2SJack F Vogel 2538cfa0ad2SJack F Vogel hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length); 2548cfa0ad2SJack F Vogel 2558cfa0ad2SJack F Vogel length >>= 2; 2568cfa0ad2SJack F Vogel /* Write the relevant command block into the ram area. */ 2578cfa0ad2SJack F Vogel for (i = 0; i < length; i++) { 2588cfa0ad2SJack F Vogel E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i, 2598cfa0ad2SJack F Vogel *((u32 *) hdr + i)); 2608cfa0ad2SJack F Vogel E1000_WRITE_FLUSH(hw); 2618cfa0ad2SJack F Vogel } 2628cfa0ad2SJack F Vogel 2638cfa0ad2SJack F Vogel return E1000_SUCCESS; 2648cfa0ad2SJack F Vogel } 2658cfa0ad2SJack F Vogel 2668cfa0ad2SJack F Vogel /** 2678cfa0ad2SJack F Vogel * e1000_mng_host_if_write_generic - Write to the manageability host interface 2688cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 2698cfa0ad2SJack F Vogel * @buffer: pointer to the host interface buffer 2708cfa0ad2SJack F Vogel * @length: size of the buffer 2718cfa0ad2SJack F Vogel * @offset: location in the buffer to write to 2728cfa0ad2SJack F Vogel * @sum: sum of the data (not checksum) 2738cfa0ad2SJack F Vogel * 2748cfa0ad2SJack F Vogel * This function writes the buffer content at the offset given on the host if. 2758cfa0ad2SJack F Vogel * It also does alignment considerations to do the writes in most efficient 2768cfa0ad2SJack F Vogel * way. Also fills up the sum of the buffer in *buffer parameter. 2778cfa0ad2SJack F Vogel **/ 2788cfa0ad2SJack F Vogel s32 e1000_mng_host_if_write_generic(struct e1000_hw * hw, u8 *buffer, 2798cfa0ad2SJack F Vogel u16 length, u16 offset, u8 *sum) 2808cfa0ad2SJack F Vogel { 2818cfa0ad2SJack F Vogel u8 *tmp; 2828cfa0ad2SJack F Vogel u8 *bufptr = buffer; 2838cfa0ad2SJack F Vogel u32 data = 0; 2848cfa0ad2SJack F Vogel s32 ret_val = E1000_SUCCESS; 2858cfa0ad2SJack F Vogel u16 remaining, i, j, prev_bytes; 2868cfa0ad2SJack F Vogel 2878cfa0ad2SJack F Vogel DEBUGFUNC("e1000_mng_host_if_write_generic"); 2888cfa0ad2SJack F Vogel 2898cfa0ad2SJack F Vogel /* sum = only sum of the data and it is not checksum */ 2908cfa0ad2SJack F Vogel 2918cfa0ad2SJack F Vogel if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) { 2928cfa0ad2SJack F Vogel ret_val = -E1000_ERR_PARAM; 2938cfa0ad2SJack F Vogel goto out; 2948cfa0ad2SJack F Vogel } 2958cfa0ad2SJack F Vogel 2968cfa0ad2SJack F Vogel tmp = (u8 *)&data; 2978cfa0ad2SJack F Vogel prev_bytes = offset & 0x3; 2988cfa0ad2SJack F Vogel offset >>= 2; 2998cfa0ad2SJack F Vogel 3008cfa0ad2SJack F Vogel if (prev_bytes) { 3018cfa0ad2SJack F Vogel data = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset); 3028cfa0ad2SJack F Vogel for (j = prev_bytes; j < sizeof(u32); j++) { 3038cfa0ad2SJack F Vogel *(tmp + j) = *bufptr++; 3048cfa0ad2SJack F Vogel *sum += *(tmp + j); 3058cfa0ad2SJack F Vogel } 3068cfa0ad2SJack F Vogel E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset, data); 3078cfa0ad2SJack F Vogel length -= j - prev_bytes; 3088cfa0ad2SJack F Vogel offset++; 3098cfa0ad2SJack F Vogel } 3108cfa0ad2SJack F Vogel 3118cfa0ad2SJack F Vogel remaining = length & 0x3; 3128cfa0ad2SJack F Vogel length -= remaining; 3138cfa0ad2SJack F Vogel 3148cfa0ad2SJack F Vogel /* Calculate length in DWORDs */ 3158cfa0ad2SJack F Vogel length >>= 2; 3168cfa0ad2SJack F Vogel 3178cfa0ad2SJack F Vogel /* 3188cfa0ad2SJack F Vogel * The device driver writes the relevant command block into the 3198cfa0ad2SJack F Vogel * ram area. 3208cfa0ad2SJack F Vogel */ 3218cfa0ad2SJack F Vogel for (i = 0; i < length; i++) { 3228cfa0ad2SJack F Vogel for (j = 0; j < sizeof(u32); j++) { 3238cfa0ad2SJack F Vogel *(tmp + j) = *bufptr++; 3248cfa0ad2SJack F Vogel *sum += *(tmp + j); 3258cfa0ad2SJack F Vogel } 3268cfa0ad2SJack F Vogel 3278cfa0ad2SJack F Vogel E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data); 3288cfa0ad2SJack F Vogel } 3298cfa0ad2SJack F Vogel if (remaining) { 3308cfa0ad2SJack F Vogel for (j = 0; j < sizeof(u32); j++) { 3318cfa0ad2SJack F Vogel if (j < remaining) 3328cfa0ad2SJack F Vogel *(tmp + j) = *bufptr++; 3338cfa0ad2SJack F Vogel else 3348cfa0ad2SJack F Vogel *(tmp + j) = 0; 3358cfa0ad2SJack F Vogel 3368cfa0ad2SJack F Vogel *sum += *(tmp + j); 3378cfa0ad2SJack F Vogel } 3388cfa0ad2SJack F Vogel E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data); 3398cfa0ad2SJack F Vogel } 3408cfa0ad2SJack F Vogel 3418cfa0ad2SJack F Vogel out: 3428cfa0ad2SJack F Vogel return ret_val; 3438cfa0ad2SJack F Vogel } 3448cfa0ad2SJack F Vogel 3458cfa0ad2SJack F Vogel /** 3468cfa0ad2SJack F Vogel * e1000_enable_mng_pass_thru - Enable processing of ARP's 3478cfa0ad2SJack F Vogel * @hw: pointer to the HW structure 3488cfa0ad2SJack F Vogel * 3498cfa0ad2SJack F Vogel * Verifies the hardware needs to allow ARPs to be processed by the host. 3508cfa0ad2SJack F Vogel **/ 3518cfa0ad2SJack F Vogel bool e1000_enable_mng_pass_thru(struct e1000_hw *hw) 3528cfa0ad2SJack F Vogel { 3538cfa0ad2SJack F Vogel u32 manc; 3548cfa0ad2SJack F Vogel u32 fwsm, factps; 3558cfa0ad2SJack F Vogel bool ret_val = FALSE; 3568cfa0ad2SJack F Vogel 3578cfa0ad2SJack F Vogel DEBUGFUNC("e1000_enable_mng_pass_thru"); 3588cfa0ad2SJack F Vogel 3598cfa0ad2SJack F Vogel if (!hw->mac.asf_firmware_present) 3608cfa0ad2SJack F Vogel goto out; 3618cfa0ad2SJack F Vogel 3628cfa0ad2SJack F Vogel manc = E1000_READ_REG(hw, E1000_MANC); 3638cfa0ad2SJack F Vogel 3648cfa0ad2SJack F Vogel if (!(manc & E1000_MANC_RCV_TCO_EN) || 3658cfa0ad2SJack F Vogel !(manc & E1000_MANC_EN_MAC_ADDR_FILTER)) 3668cfa0ad2SJack F Vogel goto out; 3678cfa0ad2SJack F Vogel 3688cfa0ad2SJack F Vogel if (hw->mac.arc_subsystem_valid) { 3698cfa0ad2SJack F Vogel fwsm = E1000_READ_REG(hw, E1000_FWSM); 3708cfa0ad2SJack F Vogel factps = E1000_READ_REG(hw, E1000_FACTPS); 3718cfa0ad2SJack F Vogel 3728cfa0ad2SJack F Vogel if (!(factps & E1000_FACTPS_MNGCG) && 3738cfa0ad2SJack F Vogel ((fwsm & E1000_FWSM_MODE_MASK) == 3748cfa0ad2SJack F Vogel (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) { 3758cfa0ad2SJack F Vogel ret_val = TRUE; 3768cfa0ad2SJack F Vogel goto out; 3778cfa0ad2SJack F Vogel } 3788cfa0ad2SJack F Vogel } else { 3798cfa0ad2SJack F Vogel if ((manc & E1000_MANC_SMBUS_EN) && 3808cfa0ad2SJack F Vogel !(manc & E1000_MANC_ASF_EN)) { 3818cfa0ad2SJack F Vogel ret_val = TRUE; 3828cfa0ad2SJack F Vogel goto out; 3838cfa0ad2SJack F Vogel } 3848cfa0ad2SJack F Vogel } 3858cfa0ad2SJack F Vogel 3868cfa0ad2SJack F Vogel out: 3878cfa0ad2SJack F Vogel return ret_val; 3888cfa0ad2SJack F Vogel } 3898cfa0ad2SJack F Vogel 390