1fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan/******************************************************************************* 2fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 3fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan Intel PRO/1000 Linux driver 4f5e261e626eb3fe07adf484aaad2ecfc757feba3Bruce Allan Copyright(c) 1999 - 2012 Intel Corporation. 5fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 6fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan This program is free software; you can redistribute it and/or modify it 7fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan under the terms and conditions of the GNU General Public License, 8fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan version 2, as published by the Free Software Foundation. 9fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 10fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan This program is distributed in the hope it will be useful, but WITHOUT 11fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan more details. 14fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 15fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan You should have received a copy of the GNU General Public License along with 16fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan this program; if not, write to the Free Software Foundation, Inc., 17fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 18fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 19fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan The full GNU General Public License is included in this distribution in 20fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan the file called "COPYING". 21fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 22fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan Contact Information: 23fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan Linux NICS <linux.nics@intel.com> 24fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> 25fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 26fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 27fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan*******************************************************************************/ 28fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 29fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan#include "e1000.h" 30fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 31fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allanenum e1000_mng_mode { 32fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan e1000_mng_mode_none = 0, 33fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan e1000_mng_mode_asf, 34fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan e1000_mng_mode_pt, 35fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan e1000_mng_mode_ipmi, 36fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan e1000_mng_mode_host_if_only 37fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan}; 38fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 39fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan#define E1000_FACTPS_MNGCG 0x20000000 40fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 41fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan/* Intel(R) Active Management Technology signature */ 42fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan#define E1000_IAMT_SIGNATURE 0x544D4149 43fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 44fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan/** 45fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * e1000_calculate_checksum - Calculate checksum for buffer 46fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @buffer: pointer to EEPROM 47fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @length: size of EEPROM to calculate a checksum for 48fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * 49fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * Calculates the checksum for some buffer on a specified length. The 50fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * checksum calculated is returned. 51fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan **/ 52fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allanstatic u8 e1000_calculate_checksum(u8 *buffer, u32 length) 53fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan{ 54fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u32 i; 55fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u8 sum = 0; 56fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 57fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (!buffer) 58fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return 0; 59fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 60fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan for (i = 0; i < length; i++) 61fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan sum += buffer[i]; 62fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 63fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return (u8)(0 - sum); 64fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan} 65fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 66fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan/** 67fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * e1000_mng_enable_host_if - Checks host interface is enabled 68fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @hw: pointer to the HW structure 69fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * 70fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND 71fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * 72fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * This function checks whether the HOST IF is enabled for command operation 73fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * and also checks whether the previous command is completed. It busy waits 74fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * in case of previous command is not completed. 75fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan **/ 76fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allanstatic s32 e1000_mng_enable_host_if(struct e1000_hw *hw) 77fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan{ 78fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u32 hicr; 79fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u8 i; 80fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 81668018d74762741c3fe5a54f0eea1bd65dcabd7eBruce Allan if (!hw->mac.arc_subsystem_valid) { 82fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan e_dbg("ARC subsystem not valid.\n"); 83fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return -E1000_ERR_HOST_INTERFACE_COMMAND; 84fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 85fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 86fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Check that the host interface is enabled. */ 87fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hicr = er32(HICR); 88fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if ((hicr & E1000_HICR_EN) == 0) { 89fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan e_dbg("E1000_HOST_EN bit disabled.\n"); 90fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return -E1000_ERR_HOST_INTERFACE_COMMAND; 91fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 92fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* check the previous command is completed */ 93fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) { 94fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hicr = er32(HICR); 95fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (!(hicr & E1000_HICR_C)) 96fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan break; 97fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan mdelay(1); 98fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 99fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 100fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) { 101fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan e_dbg("Previous command timeout failed .\n"); 102fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return -E1000_ERR_HOST_INTERFACE_COMMAND; 103fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 104fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 105fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return 0; 106fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan} 107fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 108fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan/** 10948768329efcf5e3970f54f6d15046f3e549101d8Bruce Allan * e1000e_check_mng_mode_generic - Generic check management mode 110fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @hw: pointer to the HW structure 111fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * 112fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * Reads the firmware semaphore register and returns true (>0) if 113fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * manageability is enabled, else false (0). 114fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan **/ 115fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allanbool e1000e_check_mng_mode_generic(struct e1000_hw *hw) 116fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan{ 117fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u32 fwsm = er32(FWSM); 118fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 119fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return (fwsm & E1000_FWSM_MODE_MASK) == 120fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT); 121fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan} 122fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 123fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan/** 124fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * e1000e_enable_tx_pkt_filtering - Enable packet filtering on Tx 125fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @hw: pointer to the HW structure 126fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * 127fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * Enables packet filtering on transmit packets if manageability is enabled 128fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * and host interface is enabled. 129fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan **/ 130fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allanbool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) 131fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan{ 132fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie; 133fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u32 *buffer = (u32 *)&hw->mng_cookie; 134fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u32 offset; 135fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan s32 ret_val, hdr_csum, csum; 136fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u8 i, len; 137fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 138fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hw->mac.tx_pkt_filtering = true; 139fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 140fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* No manageability, no filtering */ 14148768329efcf5e3970f54f6d15046f3e549101d8Bruce Allan if (!hw->mac.ops.check_mng_mode(hw)) { 142fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hw->mac.tx_pkt_filtering = false; 1435015e53a4cf0c88977120faede7eb02b0459d90eBruce Allan return hw->mac.tx_pkt_filtering; 144fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 145fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 146fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* 147fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * If we can't read from the host interface for whatever 148fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * reason, disable filtering. 149fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan */ 150fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ret_val = e1000_mng_enable_host_if(hw); 151fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (ret_val) { 152fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hw->mac.tx_pkt_filtering = false; 1535015e53a4cf0c88977120faede7eb02b0459d90eBruce Allan return hw->mac.tx_pkt_filtering; 154fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 155fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 156fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Read in the header. Length and offset are in dwords. */ 157fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2; 158fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2; 159fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan for (i = 0; i < len; i++) 160fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan *(buffer + i) = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, 161fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan offset + i); 162fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hdr_csum = hdr->checksum; 163fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hdr->checksum = 0; 164fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan csum = e1000_calculate_checksum((u8 *)hdr, 165fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan E1000_MNG_DHCP_COOKIE_LENGTH); 166fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* 167fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * If either the checksums or signature don't match, then 168fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * the cookie area isn't considered valid, in which case we 169fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * take the safe route of assuming Tx filtering is enabled. 170fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan */ 171fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) { 172fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hw->mac.tx_pkt_filtering = true; 1735015e53a4cf0c88977120faede7eb02b0459d90eBruce Allan return hw->mac.tx_pkt_filtering; 174fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 175fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 176fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Cookie area is valid, make the final check for filtering. */ 1775015e53a4cf0c88977120faede7eb02b0459d90eBruce Allan if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) 178fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hw->mac.tx_pkt_filtering = false; 179fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 180fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return hw->mac.tx_pkt_filtering; 181fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan} 182fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 183fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan/** 184fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * e1000_mng_write_cmd_header - Writes manageability command header 185fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @hw: pointer to the HW structure 186fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @hdr: pointer to the host interface command header 187fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * 188fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * Writes the command header after does the checksum calculation. 189fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan **/ 190fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allanstatic s32 e1000_mng_write_cmd_header(struct e1000_hw *hw, 191fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan struct e1000_host_mng_command_header *hdr) 192fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan{ 193fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u16 i, length = sizeof(struct e1000_host_mng_command_header); 194fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 195fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Write the whole command header structure with new checksum. */ 196fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 197fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length); 198fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 199fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan length >>= 2; 200fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Write the relevant command block into the ram area. */ 201fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan for (i = 0; i < length; i++) { 202fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, i, *((u32 *)hdr + i)); 203fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan e1e_flush(); 204fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 205fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 206fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return 0; 207fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan} 208fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 209fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan/** 210fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * e1000_mng_host_if_write - Write to the manageability host interface 211fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @hw: pointer to the HW structure 212fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @buffer: pointer to the host interface buffer 213fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @length: size of the buffer 214fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @offset: location in the buffer to write to 215fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @sum: sum of the data (not checksum) 216fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * 217fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * This function writes the buffer content at the offset given on the host if. 218fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * It also does alignment considerations to do the writes in most efficient 219fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * way. Also fills up the sum of the buffer in *buffer parameter. 220fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan **/ 221fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allanstatic s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, 222fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u16 length, u16 offset, u8 *sum) 223fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan{ 224fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u8 *tmp; 225fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u8 *bufptr = buffer; 226fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u32 data = 0; 227fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u16 remaining, i, j, prev_bytes; 228fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 229fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* sum = only sum of the data and it is not checksum */ 230fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 231fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) 232fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return -E1000_ERR_PARAM; 233fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 234fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan tmp = (u8 *)&data; 235fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan prev_bytes = offset & 0x3; 236fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan offset >>= 2; 237fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 238fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (prev_bytes) { 239fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan data = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset); 240fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan for (j = prev_bytes; j < sizeof(u32); j++) { 241fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan *(tmp + j) = *bufptr++; 242fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan *sum += *(tmp + j); 243fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 244fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset, data); 245fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan length -= j - prev_bytes; 246fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan offset++; 247fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 248fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 249fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan remaining = length & 0x3; 250fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan length -= remaining; 251fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 252fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Calculate length in DWORDs */ 253fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan length >>= 2; 254fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 255fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* 256fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * The device driver writes the relevant command block into the 257fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * ram area. 258fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan */ 259fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan for (i = 0; i < length; i++) { 260fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan for (j = 0; j < sizeof(u32); j++) { 261fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan *(tmp + j) = *bufptr++; 262fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan *sum += *(tmp + j); 263fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 264fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 265fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data); 266fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 267fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (remaining) { 268fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan for (j = 0; j < sizeof(u32); j++) { 269fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (j < remaining) 270fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan *(tmp + j) = *bufptr++; 271fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan else 272fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan *(tmp + j) = 0; 273fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 274fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan *sum += *(tmp + j); 275fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 276fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data); 277fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 278fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 279fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return 0; 280fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan} 281fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 282fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan/** 283fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * e1000e_mng_write_dhcp_info - Writes DHCP info to host interface 284fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @hw: pointer to the HW structure 285fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @buffer: pointer to the host interface 286fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @length: size of the buffer 287fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * 288fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * Writes the DHCP information to the host interface. 289fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan **/ 290fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allans32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length) 291fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan{ 292fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan struct e1000_host_mng_command_header hdr; 293fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan s32 ret_val; 294fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u32 hicr; 295fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 296fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD; 297fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hdr.command_length = length; 298fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hdr.reserved1 = 0; 299fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hdr.reserved2 = 0; 300fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hdr.checksum = 0; 301fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 302fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Enable the host interface */ 303fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ret_val = e1000_mng_enable_host_if(hw); 304fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (ret_val) 305fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return ret_val; 306fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 307fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Populate the host interface with the contents of "buffer". */ 308fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ret_val = e1000_mng_host_if_write(hw, buffer, length, 309fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan sizeof(hdr), &(hdr.checksum)); 310fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (ret_val) 311fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return ret_val; 312fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 313fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Write the manageability command header */ 314fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ret_val = e1000_mng_write_cmd_header(hw, &hdr); 315fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (ret_val) 316fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return ret_val; 317fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 318fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Tell the ARC a new command is pending. */ 319fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hicr = er32(HICR); 320fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ew32(HICR, hicr | E1000_HICR_C); 321fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 322fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return 0; 323fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan} 324fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 325fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan/** 326fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * e1000e_enable_mng_pass_thru - Check if management passthrough is needed 327fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @hw: pointer to the HW structure 328fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * 329fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * Verifies the hardware needs to leave interface enabled so that frames can 330fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * be directed to and from the management interface. 331fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan **/ 332fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allanbool e1000e_enable_mng_pass_thru(struct e1000_hw *hw) 333fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan{ 334fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u32 manc; 335fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u32 fwsm, factps; 336fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 337fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan manc = er32(MANC); 338fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 339fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (!(manc & E1000_MANC_RCV_TCO_EN)) 3405015e53a4cf0c88977120faede7eb02b0459d90eBruce Allan return false; 341fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 342fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (hw->mac.has_fwsm) { 343fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan fwsm = er32(FWSM); 344fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan factps = er32(FACTPS); 345fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 346fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (!(factps & E1000_FACTPS_MNGCG) && 347fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ((fwsm & E1000_FWSM_MODE_MASK) == 3485015e53a4cf0c88977120faede7eb02b0459d90eBruce Allan (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) 3495015e53a4cf0c88977120faede7eb02b0459d90eBruce Allan return true; 350fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } else if ((hw->mac.type == e1000_82574) || 351fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan (hw->mac.type == e1000_82583)) { 352fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u16 data; 353fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 354fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan factps = er32(FACTPS); 355fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); 356fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 357fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (!(factps & E1000_FACTPS_MNGCG) && 358fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ((data & E1000_NVM_INIT_CTRL2_MNGM) == 3595015e53a4cf0c88977120faede7eb02b0459d90eBruce Allan (e1000_mng_mode_pt << 13))) 3605015e53a4cf0c88977120faede7eb02b0459d90eBruce Allan return true; 361fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } else if ((manc & E1000_MANC_SMBUS_EN) && 362fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan !(manc & E1000_MANC_ASF_EN)) { 3635015e53a4cf0c88977120faede7eb02b0459d90eBruce Allan return true; 364fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 365fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 3665015e53a4cf0c88977120faede7eb02b0459d90eBruce Allan return false; 367fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan} 368