e1000e_manage.c

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003   Intel PRO/1000 Linux driver
00004   Copyright(c) 1999 - 2009 Intel Corporation.
00005 
00006   This program is free software; you can redistribute it and/or modify it
00007   under the terms and conditions of the GNU General Public License,
00008   version 2, as published by the Free Software Foundation.
00009 
00010   This program is distributed in the hope it will be useful, but WITHOUT
00011   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
00013   more details.
00014 
00015   You should have received a copy of the GNU General Public License along with
00016   this program; if not, write to the Free Software Foundation, Inc.,
00017   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
00018 
00019   The full GNU General Public License is included in this distribution in
00020   the file called "COPYING".
00021 
00022   Contact Information:
00023   Linux NICS <linux.nics@intel.com>
00024   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
00025   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
00026 
00027 *******************************************************************************/
00028 
00029 FILE_LICENCE ( GPL2_OR_LATER );
00030 
00031 #if 0
00032 
00033 #include "e1000e.h"
00034 
00035 static u8 e1000e_calculate_checksum(u8 *buffer, u32 length);
00036 
00037 /**
00038  *  e1000e_calculate_checksum - Calculate checksum for buffer
00039  *  @buffer: pointer to EEPROM
00040  *  @length: size of EEPROM to calculate a checksum for
00041  *
00042  *  Calculates the checksum for some buffer on a specified length.  The
00043  *  checksum calculated is returned.
00044  **/
00045 static u8 e1000e_calculate_checksum(u8 *buffer, u32 length)
00046 {
00047         u32 i;
00048         u8  sum = 0;
00049 
00050         if (!buffer)
00051                 return 0;
00052         for (i = 0; i < length; i++)
00053                 sum += buffer[i];
00054 
00055         return (u8) (0 - sum);
00056 }
00057 
00058 /**
00059  *  e1000e_mng_enable_host_if_generic - Checks host interface is enabled
00060  *  @hw: pointer to the HW structure
00061  *
00062  *  Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
00063  *
00064  *  This function checks whether the HOST IF is enabled for command operation
00065  *  and also checks whether the previous command is completed.  It busy waits
00066  *  in case of previous command is not completed.
00067  **/
00068 s32 e1000e_mng_enable_host_if_generic(struct e1000_hw *hw)
00069 {
00070         u32 hicr;
00071         s32 ret_val = E1000_SUCCESS;
00072         u8  i;
00073 
00074         /* Check that the host interface is enabled. */
00075         hicr = er32(HICR);
00076         if ((hicr & E1000_HICR_EN) == 0) {
00077                 e_dbg("E1000_HOST_EN bit disabled.\n");
00078                 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
00079                 goto out;
00080         }
00081         /* check the previous command is completed */
00082         for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
00083                 hicr = er32(HICR);
00084                 if (!(hicr & E1000_HICR_C))
00085                         break;
00086                 mdelay(1);
00087         }
00088 
00089         if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
00090                 e_dbg("Previous command timeout failed .\n");
00091                 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
00092                 goto out;
00093         }
00094 
00095 out:
00096         return ret_val;
00097 }
00098 
00099 /**
00100  *  e1000e_check_mng_mode_generic - Generic check management mode
00101  *  @hw: pointer to the HW structure
00102  *
00103  *  Reads the firmware semaphore register and returns true (>0) if
00104  *  manageability is enabled, else false (0).
00105  **/
00106 bool e1000e_check_mng_mode_generic(struct e1000_hw *hw)
00107 {
00108         u32 fwsm;
00109 
00110         fwsm = er32(FWSM);
00111         return (fwsm & E1000_FWSM_MODE_MASK) ==
00112                 (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
00113 }
00114 
00115 /**
00116  *  e1000e_enable_tx_pkt_filtering - Enable packet filtering on TX
00117  *  @hw: pointer to the HW structure
00118  *
00119  *  Enables packet filtering on transmit packets if manageability is enabled
00120  *  and host interface is enabled.
00121  **/
00122 bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw)
00123 {
00124         struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
00125         u32 *buffer = (u32 *)&hw->mng_cookie;
00126         u32 offset;
00127         s32 ret_val, hdr_csum, csum;
00128         u8 i, len;
00129         bool tx_filter = true;
00130 
00131         /* No manageability, no filtering */
00132         if (!hw->mac.ops.check_mng_mode(hw)) {
00133                 tx_filter = false;
00134                 goto out;
00135         }
00136 
00137         /*
00138          * If we can't read from the host interface for whatever
00139          * reason, disable filtering.
00140          */
00141         ret_val = hw->mac.ops.mng_enable_host_if(hw);
00142         if (ret_val != E1000_SUCCESS) {
00143                 tx_filter = false;
00144                 goto out;
00145         }
00146 
00147         /* Read in the header.  Length and offset are in dwords. */
00148         len    = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
00149         offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
00150         for (i = 0; i < len; i++) {
00151                 *(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw,
00152                                                            E1000_HOST_IF,
00153                                                            offset + i);
00154         }
00155         hdr_csum = hdr->checksum;
00156         hdr->checksum = 0;
00157         csum = e1000e_calculate_checksum((u8 *)hdr,
00158                                         E1000_MNG_DHCP_COOKIE_LENGTH);
00159         /*
00160          * If either the checksums or signature don't match, then
00161          * the cookie area isn't considered valid, in which case we
00162          * take the safe route of assuming Tx filtering is enabled.
00163          */
00164         if (hdr_csum != csum)
00165                 goto out;
00166         if (hdr->signature != E1000_IAMT_SIGNATURE)
00167                 goto out;
00168 
00169         /* Cookie area is valid, make the final check for filtering. */
00170         if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
00171                 tx_filter = false;
00172 
00173 out:
00174         hw->mac.tx_pkt_filtering = tx_filter;
00175         return tx_filter;
00176 }
00177 
00178 /**
00179  *  e1000e_mng_write_dhcp_info - Writes DHCP info to host interface
00180  *  @hw: pointer to the HW structure
00181  *  @buffer: pointer to the host interface
00182  *  @length: size of the buffer
00183  *
00184  *  Writes the DHCP information to the host interface.
00185  **/
00186 s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer,
00187                                       u16 length)
00188 {
00189         struct e1000_host_mng_command_header hdr;
00190         s32 ret_val;
00191         u32 hicr;
00192 
00193         hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
00194         hdr.command_length = length;
00195         hdr.reserved1 = 0;
00196         hdr.reserved2 = 0;
00197         hdr.checksum = 0;
00198 
00199         /* Enable the host interface */
00200         ret_val = hw->mac.ops.mng_enable_host_if(hw);
00201         if (ret_val)
00202                 goto out;
00203 
00204         /* Populate the host interface with the contents of "buffer". */
00205         ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length,
00206                                           sizeof(hdr), &(hdr.checksum));
00207         if (ret_val)
00208                 goto out;
00209 
00210         /* Write the manageability command header */
00211         ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr);
00212         if (ret_val)
00213                 goto out;
00214 
00215         /* Tell the ARC a new command is pending. */
00216         hicr = er32(HICR);
00217         ew32(HICR, hicr | E1000_HICR_C);
00218 
00219 out:
00220         return ret_val;
00221 }
00222 
00223 /**
00224  *  e1000e_mng_write_cmd_header_generic - Writes manageability command header
00225  *  @hw: pointer to the HW structure
00226  *  @hdr: pointer to the host interface command header
00227  *
00228  *  Writes the command header after does the checksum calculation.
00229  **/
00230 s32 e1000e_mng_write_cmd_header_generic(struct e1000_hw *hw,
00231                                     struct e1000_host_mng_command_header *hdr)
00232 {
00233         u16 i, length = sizeof(struct e1000_host_mng_command_header);
00234 
00235         /* Write the whole command header structure with new checksum. */
00236 
00237         hdr->checksum = e1000e_calculate_checksum((u8 *)hdr, length);
00238 
00239         length >>= 2;
00240         /* Write the relevant command block into the ram area. */
00241         for (i = 0; i < length; i++) {
00242                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
00243                                             *((u32 *) hdr + i));
00244                 e1e_flush();
00245         }
00246 
00247         return E1000_SUCCESS;
00248 }
00249 
00250 /**
00251  *  e1000e_mng_host_if_write_generic - Write to the manageability host interface
00252  *  @hw: pointer to the HW structure
00253  *  @buffer: pointer to the host interface buffer
00254  *  @length: size of the buffer
00255  *  @offset: location in the buffer to write to
00256  *  @sum: sum of the data (not checksum)
00257  *
00258  *  This function writes the buffer content at the offset given on the host if.
00259  *  It also does alignment considerations to do the writes in most efficient
00260  *  way.  Also fills up the sum of the buffer in *buffer parameter.
00261  **/
00262 s32 e1000e_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
00263                                     u16 length, u16 offset, u8 *sum)
00264 {
00265         u8 *tmp;
00266         u8 *bufptr = buffer;
00267         u32 data = 0;
00268         s32 ret_val = E1000_SUCCESS;
00269         u16 remaining, i, j, prev_bytes;
00270 
00271         /* sum = only sum of the data and it is not checksum */
00272 
00273         if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
00274                 ret_val = -E1000_ERR_PARAM;
00275                 goto out;
00276         }
00277 
00278         tmp = (u8 *)&data;
00279         prev_bytes = offset & 0x3;
00280         offset >>= 2;
00281 
00282         if (prev_bytes) {
00283                 data = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset);
00284                 for (j = prev_bytes; j < sizeof(u32); j++) {
00285                         *(tmp + j) = *bufptr++;
00286                         *sum += *(tmp + j);
00287                 }
00288                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset, data);
00289                 length -= j - prev_bytes;
00290                 offset++;
00291         }
00292 
00293         remaining = length & 0x3;
00294         length -= remaining;
00295 
00296         /* Calculate length in DWORDs */
00297         length >>= 2;
00298 
00299         /*
00300          * The device driver writes the relevant command block into the
00301          * ram area.
00302          */
00303         for (i = 0; i < length; i++) {
00304                 for (j = 0; j < sizeof(u32); j++) {
00305                         *(tmp + j) = *bufptr++;
00306                         *sum += *(tmp + j);
00307                 }
00308 
00309                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
00310                                             data);
00311         }
00312         if (remaining) {
00313                 for (j = 0; j < sizeof(u32); j++) {
00314                         if (j < remaining)
00315                                 *(tmp + j) = *bufptr++;
00316                         else
00317                                 *(tmp + j) = 0;
00318 
00319                         *sum += *(tmp + j);
00320                 }
00321                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data);
00322         }
00323 
00324 out:
00325         return ret_val;
00326 }
00327 
00328 /**
00329  *  e1000e_enable_mng_pass_thru - Enable processing of ARP's
00330  *  @hw: pointer to the HW structure
00331  *
00332  *  Verifies the hardware needs to allow ARPs to be processed by the host.
00333  **/
00334 bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw)
00335 {
00336         u32 manc;
00337         u32 fwsm, factps;
00338         bool ret_val = false;
00339 
00340         if (!hw->mac.asf_firmware_present)
00341                 goto out;
00342 
00343         manc = er32(MANC);
00344 
00345         if (!(manc & E1000_MANC_RCV_TCO_EN) ||
00346             !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
00347                 goto out;
00348 
00349         if (hw->mac.arc_subsystem_valid) {
00350                 fwsm = er32(FWSM);
00351                 factps = er32(FACTPS);
00352 
00353                 if (!(factps & E1000_FACTPS_MNGCG) &&
00354                     ((fwsm & E1000_FWSM_MODE_MASK) ==
00355                      (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
00356                         ret_val = true;
00357                         goto out;
00358                 }
00359         } else {
00360                 if ((manc & E1000_MANC_SMBUS_EN) &&
00361                     !(manc & E1000_MANC_ASF_EN)) {
00362                         ret_val = true;
00363                         goto out;
00364                 }
00365         }
00366 
00367 out:
00368         return ret_val;
00369 }
00370 
00371 #endif
00372 

Generated on Tue Apr 6 20:00:59 2010 for gPXE by  doxygen 1.5.7.1