e1000_manage.c

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003   Intel PRO/1000 Linux driver
00004   Copyright(c) 1999 - 2008 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 "e1000_api.h"
00034 
00035 static u8 e1000_calculate_checksum(u8 *buffer, u32 length);
00036 
00037 /**
00038  *  e1000_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 e1000_calculate_checksum(u8 *buffer, u32 length)
00046 {
00047         u32 i;
00048         u8  sum = 0;
00049 
00050         DEBUGFUNC("e1000_calculate_checksum");
00051 
00052         if (!buffer)
00053                 return 0;
00054 
00055         for (i = 0; i < length; i++)
00056                 sum += buffer[i];
00057 
00058         return (u8) (0 - sum);
00059 }
00060 
00061 /**
00062  *  e1000_mng_enable_host_if_generic - Checks host interface is enabled
00063  *  @hw: pointer to the HW structure
00064  *
00065  *  Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
00066  *
00067  *  This function checks whether the HOST IF is enabled for command operation
00068  *  and also checks whether the previous command is completed.  It busy waits
00069  *  in case of previous command is not completed.
00070  **/
00071 s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw)
00072 {
00073         u32 hicr;
00074         s32 ret_val = E1000_SUCCESS;
00075         u8  i;
00076 
00077         DEBUGFUNC("e1000_mng_enable_host_if_generic");
00078 
00079         /* Check that the host interface is enabled. */
00080         hicr = E1000_READ_REG(hw, E1000_HICR);
00081         if ((hicr & E1000_HICR_EN) == 0) {
00082                 DEBUGOUT("E1000_HOST_EN bit disabled.\n");
00083                 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
00084                 goto out;
00085         }
00086         /* check the previous command is completed */
00087         for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
00088                 hicr = E1000_READ_REG(hw, E1000_HICR);
00089                 if (!(hicr & E1000_HICR_C))
00090                         break;
00091                 msec_delay_irq(1);
00092         }
00093 
00094         if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
00095                 DEBUGOUT("Previous command timeout failed .\n");
00096                 ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
00097                 goto out;
00098         }
00099 
00100 out:
00101         return ret_val;
00102 }
00103 
00104 /**
00105  *  e1000_check_mng_mode_generic - Generic check management mode
00106  *  @hw: pointer to the HW structure
00107  *
00108  *  Reads the firmware semaphore register and returns true (>0) if
00109  *  manageability is enabled, else false (0).
00110  **/
00111 bool e1000_check_mng_mode_generic(struct e1000_hw *hw)
00112 {
00113         u32 fwsm;
00114 
00115         DEBUGFUNC("e1000_check_mng_mode_generic");
00116 
00117         fwsm = E1000_READ_REG(hw, E1000_FWSM);
00118 
00119         return (fwsm & E1000_FWSM_MODE_MASK) ==
00120                 (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
00121 }
00122 
00123 /**
00124  *  e1000_enable_tx_pkt_filtering_generic - Enable packet filtering on TX
00125  *  @hw: pointer to the HW structure
00126  *
00127  *  Enables packet filtering on transmit packets if manageability is enabled
00128  *  and host interface is enabled.
00129  **/
00130 bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
00131 {
00132         struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
00133         u32 *buffer = (u32 *)&hw->mng_cookie;
00134         u32 offset;
00135         s32 ret_val, hdr_csum, csum;
00136         u8 i, len;
00137         bool tx_filter = true;
00138 
00139         DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic");
00140 
00141         /* No manageability, no filtering */
00142         if (!hw->mac.ops.check_mng_mode(hw)) {
00143                 tx_filter = false;
00144                 goto out;
00145         }
00146 
00147         /*
00148          * If we can't read from the host interface for whatever
00149          * reason, disable filtering.
00150          */
00151         ret_val = hw->mac.ops.mng_enable_host_if(hw);
00152         if (ret_val != E1000_SUCCESS) {
00153                 tx_filter = false;
00154                 goto out;
00155         }
00156 
00157         /* Read in the header.  Length and offset are in dwords. */
00158         len    = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
00159         offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
00160         for (i = 0; i < len; i++) {
00161                 *(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw,
00162                                                            E1000_HOST_IF,
00163                                                            offset + i);
00164         }
00165         hdr_csum = hdr->checksum;
00166         hdr->checksum = 0;
00167         csum = e1000_calculate_checksum((u8 *)hdr,
00168                                         E1000_MNG_DHCP_COOKIE_LENGTH);
00169         /*
00170          * If either the checksums or signature don't match, then
00171          * the cookie area isn't considered valid, in which case we
00172          * take the safe route of assuming Tx filtering is enabled.
00173          */
00174         if (hdr_csum != csum)
00175                 goto out;
00176         if (hdr->signature != E1000_IAMT_SIGNATURE)
00177                 goto out;
00178 
00179         /* Cookie area is valid, make the final check for filtering. */
00180         if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
00181                 tx_filter = false;
00182 
00183 out:
00184         hw->mac.tx_pkt_filtering = tx_filter;
00185         return tx_filter;
00186 }
00187 
00188 /**
00189  *  e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface
00190  *  @hw: pointer to the HW structure
00191  *  @buffer: pointer to the host interface
00192  *  @length: size of the buffer
00193  *
00194  *  Writes the DHCP information to the host interface.
00195  **/
00196 s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
00197                                       u16 length)
00198 {
00199         struct e1000_host_mng_command_header hdr;
00200         s32 ret_val;
00201         u32 hicr;
00202 
00203         DEBUGFUNC("e1000_mng_write_dhcp_info_generic");
00204 
00205         hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
00206         hdr.command_length = length;
00207         hdr.reserved1 = 0;
00208         hdr.reserved2 = 0;
00209         hdr.checksum = 0;
00210 
00211         /* Enable the host interface */
00212         ret_val = hw->mac.ops.mng_enable_host_if(hw);
00213         if (ret_val)
00214                 goto out;
00215 
00216         /* Populate the host interface with the contents of "buffer". */
00217         ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length,
00218                                           sizeof(hdr), &(hdr.checksum));
00219         if (ret_val)
00220                 goto out;
00221 
00222         /* Write the manageability command header */
00223         ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr);
00224         if (ret_val)
00225                 goto out;
00226 
00227         /* Tell the ARC a new command is pending. */
00228         hicr = E1000_READ_REG(hw, E1000_HICR);
00229         E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
00230 
00231 out:
00232         return ret_val;
00233 }
00234 
00235 /**
00236  *  e1000_mng_write_cmd_header_generic - Writes manageability command header
00237  *  @hw: pointer to the HW structure
00238  *  @hdr: pointer to the host interface command header
00239  *
00240  *  Writes the command header after does the checksum calculation.
00241  **/
00242 s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw,
00243                                     struct e1000_host_mng_command_header *hdr)
00244 {
00245         u16 i, length = sizeof(struct e1000_host_mng_command_header);
00246 
00247         DEBUGFUNC("e1000_mng_write_cmd_header_generic");
00248 
00249         /* Write the whole command header structure with new checksum. */
00250 
00251         hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length);
00252 
00253         length >>= 2;
00254         /* Write the relevant command block into the ram area. */
00255         for (i = 0; i < length; i++) {
00256                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
00257                                             *((u32 *) hdr + i));
00258                 E1000_WRITE_FLUSH(hw);
00259         }
00260 
00261         return E1000_SUCCESS;
00262 }
00263 
00264 /**
00265  *  e1000_mng_host_if_write_generic - Write to the manageability host interface
00266  *  @hw: pointer to the HW structure
00267  *  @buffer: pointer to the host interface buffer
00268  *  @length: size of the buffer
00269  *  @offset: location in the buffer to write to
00270  *  @sum: sum of the data (not checksum)
00271  *
00272  *  This function writes the buffer content at the offset given on the host if.
00273  *  It also does alignment considerations to do the writes in most efficient
00274  *  way.  Also fills up the sum of the buffer in *buffer parameter.
00275  **/
00276 s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
00277                                     u16 length, u16 offset, u8 *sum)
00278 {
00279         u8 *tmp;
00280         u8 *bufptr = buffer;
00281         u32 data = 0;
00282         s32 ret_val = E1000_SUCCESS;
00283         u16 remaining, i, j, prev_bytes;
00284 
00285         DEBUGFUNC("e1000_mng_host_if_write_generic");
00286 
00287         /* sum = only sum of the data and it is not checksum */
00288 
00289         if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
00290                 ret_val = -E1000_ERR_PARAM;
00291                 goto out;
00292         }
00293 
00294         tmp = (u8 *)&data;
00295         prev_bytes = offset & 0x3;
00296         offset >>= 2;
00297 
00298         if (prev_bytes) {
00299                 data = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset);
00300                 for (j = prev_bytes; j < sizeof(u32); j++) {
00301                         *(tmp + j) = *bufptr++;
00302                         *sum += *(tmp + j);
00303                 }
00304                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset, data);
00305                 length -= j - prev_bytes;
00306                 offset++;
00307         }
00308 
00309         remaining = length & 0x3;
00310         length -= remaining;
00311 
00312         /* Calculate length in DWORDs */
00313         length >>= 2;
00314 
00315         /*
00316          * The device driver writes the relevant command block into the
00317          * ram area.
00318          */
00319         for (i = 0; i < length; i++) {
00320                 for (j = 0; j < sizeof(u32); j++) {
00321                         *(tmp + j) = *bufptr++;
00322                         *sum += *(tmp + j);
00323                 }
00324 
00325                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
00326                                             data);
00327         }
00328         if (remaining) {
00329                 for (j = 0; j < sizeof(u32); j++) {
00330                         if (j < remaining)
00331                                 *(tmp + j) = *bufptr++;
00332                         else
00333                                 *(tmp + j) = 0;
00334 
00335                         *sum += *(tmp + j);
00336                 }
00337                 E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data);
00338         }
00339 
00340 out:
00341         return ret_val;
00342 }
00343 
00344 /**
00345  *  e1000_enable_mng_pass_thru - Enable processing of ARP's
00346  *  @hw: pointer to the HW structure
00347  *
00348  *  Verifies the hardware needs to allow ARPs to be processed by the host.
00349  **/
00350 bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
00351 {
00352         u32 manc;
00353         u32 fwsm, factps;
00354         bool ret_val = false;
00355 
00356         DEBUGFUNC("e1000_enable_mng_pass_thru");
00357 
00358         if (!hw->mac.asf_firmware_present)
00359                 goto out;
00360 
00361         manc = E1000_READ_REG(hw, E1000_MANC);
00362 
00363         if (!(manc & E1000_MANC_RCV_TCO_EN) ||
00364             !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
00365                 goto out;
00366 
00367         if (hw->mac.arc_subsystem_valid) {
00368                 fwsm = E1000_READ_REG(hw, E1000_FWSM);
00369                 factps = E1000_READ_REG(hw, E1000_FACTPS);
00370 
00371                 if (!(factps & E1000_FACTPS_MNGCG) &&
00372                     ((fwsm & E1000_FWSM_MODE_MASK) ==
00373                      (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
00374                         ret_val = true;
00375                         goto out;
00376                 }
00377         } else {
00378                 if ((manc & E1000_MANC_SMBUS_EN) &&
00379                     !(manc & E1000_MANC_ASF_EN)) {
00380                         ret_val = true;
00381                         goto out;
00382                 }
00383         }
00384 
00385 out:
00386         return ret_val;
00387 }
00388 
00389 #endif

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