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