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