devices/e1000e/manage-3.12-ethercat.c
author Patrick Bruenn <p.bruenn@beckhoff.com>
Tue, 12 Apr 2016 11:17:36 +0200
branchstable-1.5
changeset 2654 b3f6b3e5ef29
parent 2586 5b89b4e38cdc
permissions -rw-r--r--
devices/ccat: revert "limit rx processing to one frame per poll"

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