manage.c revision fe2ddfb510f9d305a6654c7538c5c8faf326a16c
1fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan/******************************************************************************* 2fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 3fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan Intel PRO/1000 Linux driver 4fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan Copyright(c) 1999 - 2011 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 81fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce 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/** 109fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * e1000e_check_mng_mode_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 */ 141fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (!e1000e_check_mng_mode(hw)) { 142fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hw->mac.tx_pkt_filtering = false; 143fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan goto out; 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; 153fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan goto out; 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; 173fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan goto out; 174fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 175fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 176fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Cookie area is valid, make the final check for filtering. */ 177fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) { 178fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hw->mac.tx_pkt_filtering = false; 179fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan goto out; 180fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 181fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 182fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allanout: 183fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return hw->mac.tx_pkt_filtering; 184fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan} 185fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 186fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan/** 187fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * e1000_mng_write_cmd_header - Writes manageability command header 188fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @hw: pointer to the HW structure 189fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @hdr: pointer to the host interface command header 190fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * 191fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * Writes the command header after does the checksum calculation. 192fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan **/ 193fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allanstatic s32 e1000_mng_write_cmd_header(struct e1000_hw *hw, 194fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan struct e1000_host_mng_command_header *hdr) 195fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan{ 196fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u16 i, length = sizeof(struct e1000_host_mng_command_header); 197fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 198fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Write the whole command header structure with new checksum. */ 199fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 200fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length); 201fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 202fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan length >>= 2; 203fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Write the relevant command block into the ram area. */ 204fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan for (i = 0; i < length; i++) { 205fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, i, *((u32 *)hdr + i)); 206fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan e1e_flush(); 207fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 208fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 209fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return 0; 210fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan} 211fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 212fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan/** 213fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * e1000_mng_host_if_write - Write to the manageability host interface 214fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @hw: pointer to the HW structure 215fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @buffer: pointer to the host interface buffer 216fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @length: size of the buffer 217fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @offset: location in the buffer to write to 218fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @sum: sum of the data (not checksum) 219fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * 220fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * This function writes the buffer content at the offset given on the host if. 221fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * It also does alignment considerations to do the writes in most efficient 222fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * way. Also fills up the sum of the buffer in *buffer parameter. 223fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan **/ 224fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allanstatic s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, 225fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u16 length, u16 offset, u8 *sum) 226fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan{ 227fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u8 *tmp; 228fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u8 *bufptr = buffer; 229fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u32 data = 0; 230fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u16 remaining, i, j, prev_bytes; 231fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 232fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* sum = only sum of the data and it is not checksum */ 233fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 234fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) 235fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return -E1000_ERR_PARAM; 236fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 237fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan tmp = (u8 *)&data; 238fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan prev_bytes = offset & 0x3; 239fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan offset >>= 2; 240fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 241fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (prev_bytes) { 242fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan data = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset); 243fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan for (j = prev_bytes; j < sizeof(u32); j++) { 244fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan *(tmp + j) = *bufptr++; 245fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan *sum += *(tmp + j); 246fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 247fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset, data); 248fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan length -= j - prev_bytes; 249fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan offset++; 250fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 251fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 252fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan remaining = length & 0x3; 253fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan length -= remaining; 254fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 255fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Calculate length in DWORDs */ 256fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan length >>= 2; 257fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 258fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* 259fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * The device driver writes the relevant command block into the 260fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * ram area. 261fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan */ 262fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan for (i = 0; i < length; i++) { 263fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan for (j = 0; j < sizeof(u32); j++) { 264fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan *(tmp + j) = *bufptr++; 265fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan *sum += *(tmp + j); 266fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 267fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 268fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data); 269fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 270fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (remaining) { 271fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan for (j = 0; j < sizeof(u32); j++) { 272fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (j < remaining) 273fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan *(tmp + j) = *bufptr++; 274fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan else 275fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan *(tmp + j) = 0; 276fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 277fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan *sum += *(tmp + j); 278fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 279fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data); 280fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 281fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 282fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return 0; 283fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan} 284fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 285fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan/** 286fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * e1000e_mng_write_dhcp_info - Writes DHCP info to host interface 287fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @hw: pointer to the HW structure 288fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @buffer: pointer to the host interface 289fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @length: size of the buffer 290fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * 291fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * Writes the DHCP information to the host interface. 292fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan **/ 293fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allans32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length) 294fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan{ 295fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan struct e1000_host_mng_command_header hdr; 296fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan s32 ret_val; 297fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u32 hicr; 298fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 299fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD; 300fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hdr.command_length = length; 301fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hdr.reserved1 = 0; 302fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hdr.reserved2 = 0; 303fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hdr.checksum = 0; 304fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 305fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Enable the host interface */ 306fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ret_val = e1000_mng_enable_host_if(hw); 307fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (ret_val) 308fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return ret_val; 309fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 310fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Populate the host interface with the contents of "buffer". */ 311fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ret_val = e1000_mng_host_if_write(hw, buffer, length, 312fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan sizeof(hdr), &(hdr.checksum)); 313fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (ret_val) 314fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return ret_val; 315fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 316fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Write the manageability command header */ 317fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ret_val = e1000_mng_write_cmd_header(hw, &hdr); 318fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (ret_val) 319fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return ret_val; 320fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 321fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan /* Tell the ARC a new command is pending. */ 322fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan hicr = er32(HICR); 323fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ew32(HICR, hicr | E1000_HICR_C); 324fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 325fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return 0; 326fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan} 327fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 328fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan/** 329fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * e1000e_enable_mng_pass_thru - Check if management passthrough is needed 330fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * @hw: pointer to the HW structure 331fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * 332fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * Verifies the hardware needs to leave interface enabled so that frames can 333fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan * be directed to and from the management interface. 334fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan **/ 335fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allanbool e1000e_enable_mng_pass_thru(struct e1000_hw *hw) 336fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan{ 337fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u32 manc; 338fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u32 fwsm, factps; 339fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan bool ret_val = false; 340fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 341fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan manc = er32(MANC); 342fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 343fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (!(manc & E1000_MANC_RCV_TCO_EN)) 344fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan goto out; 345fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 346fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (hw->mac.has_fwsm) { 347fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan fwsm = er32(FWSM); 348fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan factps = er32(FACTPS); 349fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 350fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (!(factps & E1000_FACTPS_MNGCG) && 351fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ((fwsm & E1000_FWSM_MODE_MASK) == 352fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) { 353fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ret_val = true; 354fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan goto out; 355fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 356fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } else if ((hw->mac.type == e1000_82574) || 357fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan (hw->mac.type == e1000_82583)) { 358fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan u16 data; 359fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 360fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan factps = er32(FACTPS); 361fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); 362fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 363fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan if (!(factps & E1000_FACTPS_MNGCG) && 364fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ((data & E1000_NVM_INIT_CTRL2_MNGM) == 365fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan (e1000_mng_mode_pt << 13))) { 366fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ret_val = true; 367fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan goto out; 368fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 369fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } else if ((manc & E1000_MANC_SMBUS_EN) && 370fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan !(manc & E1000_MANC_ASF_EN)) { 371fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan ret_val = true; 372fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan goto out; 373fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan } 374fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan 375fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allanout: 376fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan return ret_val; 377fe2ddfb510f9d305a6654c7538c5c8faf326a16cBruce Allan} 378