igb_manage.c

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

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