OK, I was a bit sleep this morning and checked in
the core changes but left out the shared code, lol. Well, and a couple fixes to the core... hopefully this will all be complete now. Happy happy joy joy :)
This commit is contained in:
parent
049a97931c
commit
b827058579
@ -963,6 +963,10 @@ dev/e1000/e1000_nvm.c optional em | igb \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_phy.c optional em | igb \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_vf.c optional em | igb \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_mbx.c optional em | igb \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_osdep.c optional em | igb \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/et/if_et.c optional et
|
||||
|
@ -459,5 +459,16 @@ struct e1000_adv_tx_context_desc {
|
||||
#define E1000_RXPBS_SIZE_MASK_82576 0x0000007F
|
||||
void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable);
|
||||
void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable);
|
||||
enum e1000_promisc_type {
|
||||
e1000_promisc_disabled = 0, /* all promisc modes disabled */
|
||||
e1000_promisc_unicast = 1, /* unicast promiscuous enabled */
|
||||
e1000_promisc_multicast = 2, /* multicast promiscuous enabled */
|
||||
e1000_promisc_enabled = 3, /* both uni and multicast promisc */
|
||||
e1000_num_promisc_types
|
||||
};
|
||||
|
||||
void e1000_vfta_set_vf(struct e1000_hw *, u16, bool);
|
||||
void e1000_rlpml_set_vf(struct e1000_hw *, u16);
|
||||
s32 e1000_promisc_set_vf(struct e1000_hw *, enum e1000_promisc_type type);
|
||||
u16 e1000_rxpbs_adjust_82580(u32 data);
|
||||
#endif /* _E1000_82575_H_ */
|
||||
|
@ -112,6 +112,31 @@ out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_init_mbx_params - Initialize mailbox function pointers
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* This function initializes the function pointers for the PHY
|
||||
* set of functions. Called by drivers or by e1000_setup_init_funcs.
|
||||
**/
|
||||
s32 e1000_init_mbx_params(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
|
||||
if (hw->mbx.ops.init_params) {
|
||||
ret_val = hw->mbx.ops.init_params(hw);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("Mailbox Initialization Error\n");
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
DEBUGOUT("mbx.init_mbx_params was NULL\n");
|
||||
ret_val = -E1000_ERR_CONFIG;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_set_mac_type - Sets MAC type
|
||||
@ -281,6 +306,9 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
|
||||
case E1000_DEV_ID_82580_COPPER_DUAL:
|
||||
mac->type = e1000_82580;
|
||||
break;
|
||||
case E1000_DEV_ID_82576_VF:
|
||||
mac->type = e1000_vfadapt;
|
||||
break;
|
||||
default:
|
||||
/* Should never have loaded on this device */
|
||||
ret_val = -E1000_ERR_MAC_INIT;
|
||||
@ -326,6 +354,7 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
|
||||
e1000_init_mac_ops_generic(hw);
|
||||
e1000_init_phy_ops_generic(hw);
|
||||
e1000_init_nvm_ops_generic(hw);
|
||||
e1000_init_mbx_ops_generic(hw);
|
||||
|
||||
/*
|
||||
* Set up the init function pointers. These are functions within the
|
||||
@ -374,6 +403,9 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
|
||||
case e1000_82580:
|
||||
e1000_init_function_pointers_82575(hw);
|
||||
break;
|
||||
case e1000_vfadapt:
|
||||
e1000_init_function_pointers_vf(hw);
|
||||
break;
|
||||
default:
|
||||
DEBUGOUT("Hardware not supported\n");
|
||||
ret_val = -E1000_ERR_CONFIG;
|
||||
@ -396,6 +428,10 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
|
||||
ret_val = e1000_init_phy_params(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
ret_val = e1000_init_mbx_params(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -55,6 +55,7 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device);
|
||||
s32 e1000_init_mac_params(struct e1000_hw *hw);
|
||||
s32 e1000_init_nvm_params(struct e1000_hw *hw);
|
||||
s32 e1000_init_phy_params(struct e1000_hw *hw);
|
||||
s32 e1000_init_mbx_params(struct e1000_hw *hw);
|
||||
s32 e1000_get_bus_info(struct e1000_hw *hw);
|
||||
void e1000_clear_vfta(struct e1000_hw *hw);
|
||||
void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
|
||||
|
@ -134,6 +134,7 @@ struct e1000_hw;
|
||||
#define E1000_DEV_ID_82576_NS 0x150A
|
||||
#define E1000_DEV_ID_82576_NS_SERDES 0x1518
|
||||
#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D
|
||||
#define E1000_DEV_ID_82576_VF 0x10CA
|
||||
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
|
||||
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
|
||||
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
|
||||
@ -186,6 +187,7 @@ enum e1000_mac_type {
|
||||
e1000_82575,
|
||||
e1000_82576,
|
||||
e1000_82580,
|
||||
e1000_vfadapt,
|
||||
e1000_num_macs /* List is 1-based, so subtract 1 for TRUE count. */
|
||||
};
|
||||
|
||||
@ -531,6 +533,37 @@ struct e1000_hw_stats {
|
||||
u64 doosync;
|
||||
};
|
||||
|
||||
struct e1000_vf_stats {
|
||||
u64 base_gprc;
|
||||
u64 base_gptc;
|
||||
u64 base_gorc;
|
||||
u64 base_gotc;
|
||||
u64 base_mprc;
|
||||
u64 base_gotlbc;
|
||||
u64 base_gptlbc;
|
||||
u64 base_gorlbc;
|
||||
u64 base_gprlbc;
|
||||
|
||||
u32 last_gprc;
|
||||
u32 last_gptc;
|
||||
u32 last_gorc;
|
||||
u32 last_gotc;
|
||||
u32 last_mprc;
|
||||
u32 last_gotlbc;
|
||||
u32 last_gptlbc;
|
||||
u32 last_gorlbc;
|
||||
u32 last_gprlbc;
|
||||
|
||||
u64 gprc;
|
||||
u64 gptc;
|
||||
u64 gorc;
|
||||
u64 gotc;
|
||||
u64 mprc;
|
||||
u64 gotlbc;
|
||||
u64 gptlbc;
|
||||
u64 gorlbc;
|
||||
u64 gprlbc;
|
||||
};
|
||||
|
||||
struct e1000_phy_stats {
|
||||
u32 idle_errors;
|
||||
@ -581,6 +614,7 @@ struct e1000_host_mng_command_info {
|
||||
#include "e1000_phy.h"
|
||||
#include "e1000_nvm.h"
|
||||
#include "e1000_manage.h"
|
||||
#include "e1000_mbx.h"
|
||||
|
||||
struct e1000_mac_operations {
|
||||
/* Function pointers for the MAC. */
|
||||
@ -758,6 +792,7 @@ struct e1000_fc_info {
|
||||
u32 high_water; /* Flow control high-water mark */
|
||||
u32 low_water; /* Flow control low-water mark */
|
||||
u16 pause_time; /* Flow control pause timer */
|
||||
u16 refresh_time; /* Flow control refresh timer */
|
||||
bool send_xon; /* Flow control send XON */
|
||||
bool strict_ieee; /* Strict IEEE mode */
|
||||
enum e1000_fc_mode current_mode; /* FC mode in effect */
|
||||
@ -805,6 +840,33 @@ struct e1000_dev_spec_ich8lan {
|
||||
bool nvm_k1_enabled;
|
||||
};
|
||||
|
||||
struct e1000_mbx_operations {
|
||||
s32 (*init_params)(struct e1000_hw *hw);
|
||||
s32 (*read)(struct e1000_hw *, u32 *, u16, u16);
|
||||
s32 (*write)(struct e1000_hw *, u32 *, u16, u16);
|
||||
s32 (*read_posted)(struct e1000_hw *, u32 *, u16, u16);
|
||||
s32 (*write_posted)(struct e1000_hw *, u32 *, u16, u16);
|
||||
s32 (*check_for_msg)(struct e1000_hw *, u16);
|
||||
s32 (*check_for_ack)(struct e1000_hw *, u16);
|
||||
s32 (*check_for_rst)(struct e1000_hw *, u16);
|
||||
};
|
||||
|
||||
struct e1000_mbx_stats {
|
||||
u32 msgs_tx;
|
||||
u32 msgs_rx;
|
||||
u32 acks;
|
||||
u32 reqs;
|
||||
u32 rsts;
|
||||
};
|
||||
|
||||
struct e1000_mbx_info {
|
||||
struct e1000_mbx_operations ops;
|
||||
struct e1000_mbx_stats stats;
|
||||
u32 timeout;
|
||||
u32 usec_delay;
|
||||
u16 size;
|
||||
};
|
||||
|
||||
struct e1000_dev_spec_82575 {
|
||||
bool sgmii_active;
|
||||
bool global_device_reset;
|
||||
@ -828,6 +890,7 @@ struct e1000_hw {
|
||||
struct e1000_phy_info phy;
|
||||
struct e1000_nvm_info nvm;
|
||||
struct e1000_bus_info bus;
|
||||
struct e1000_mbx_info mbx;
|
||||
struct e1000_host_mng_dhcp_cookie mng_cookie;
|
||||
|
||||
union {
|
||||
|
762
sys/dev/e1000/e1000_mbx.c
Normal file
762
sys/dev/e1000/e1000_mbx.c
Normal file
@ -0,0 +1,762 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2010, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the Intel Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
******************************************************************************/
|
||||
/*$FreeBSD$*/
|
||||
|
||||
#include "e1000_mbx.h"
|
||||
|
||||
/**
|
||||
* e1000_null_mbx_check_for_flag - No-op function, return 0
|
||||
* @hw: pointer to the HW structure
|
||||
**/
|
||||
static s32 e1000_null_mbx_check_for_flag(struct e1000_hw *hw, u16 mbx_id)
|
||||
{
|
||||
DEBUGFUNC("e1000_null_mbx_check_flag");
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_null_mbx_transact - No-op function, return 0
|
||||
* @hw: pointer to the HW structure
|
||||
**/
|
||||
static s32 e1000_null_mbx_transact(struct e1000_hw *hw, u32 *msg, u16 size,
|
||||
u16 mbx_id)
|
||||
{
|
||||
DEBUGFUNC("e1000_null_mbx_rw_msg");
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_read_mbx - Reads a message from the mailbox
|
||||
* @hw: pointer to the HW structure
|
||||
* @msg: The message buffer
|
||||
* @size: Length of buffer
|
||||
* @mbx_id: id of mailbox to read
|
||||
*
|
||||
* returns SUCCESS if it successfuly read message from buffer
|
||||
**/
|
||||
s32 e1000_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("e1000_read_mbx");
|
||||
|
||||
/* limit read to size of mailbox */
|
||||
if (size > mbx->size)
|
||||
size = mbx->size;
|
||||
|
||||
if (mbx->ops.read)
|
||||
ret_val = mbx->ops.read(hw, msg, size, mbx_id);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_write_mbx - Write a message to the mailbox
|
||||
* @hw: pointer to the HW structure
|
||||
* @msg: The message buffer
|
||||
* @size: Length of buffer
|
||||
* @mbx_id: id of mailbox to write
|
||||
*
|
||||
* returns SUCCESS if it successfully copied message into the buffer
|
||||
**/
|
||||
s32 e1000_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
|
||||
DEBUGFUNC("e1000_write_mbx");
|
||||
|
||||
if (size > mbx->size)
|
||||
ret_val = -E1000_ERR_MBX;
|
||||
|
||||
else if (mbx->ops.write)
|
||||
ret_val = mbx->ops.write(hw, msg, size, mbx_id);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_check_for_msg - checks to see if someone sent us mail
|
||||
* @hw: pointer to the HW structure
|
||||
* @mbx_id: id of mailbox to check
|
||||
*
|
||||
* returns SUCCESS if the Status bit was found or else ERR_MBX
|
||||
**/
|
||||
s32 e1000_check_for_msg(struct e1000_hw *hw, u16 mbx_id)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("e1000_check_for_msg");
|
||||
|
||||
if (mbx->ops.check_for_msg)
|
||||
ret_val = mbx->ops.check_for_msg(hw, mbx_id);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_check_for_ack - checks to see if someone sent us ACK
|
||||
* @hw: pointer to the HW structure
|
||||
* @mbx_id: id of mailbox to check
|
||||
*
|
||||
* returns SUCCESS if the Status bit was found or else ERR_MBX
|
||||
**/
|
||||
s32 e1000_check_for_ack(struct e1000_hw *hw, u16 mbx_id)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("e1000_check_for_ack");
|
||||
|
||||
if (mbx->ops.check_for_ack)
|
||||
ret_val = mbx->ops.check_for_ack(hw, mbx_id);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_check_for_rst - checks to see if other side has reset
|
||||
* @hw: pointer to the HW structure
|
||||
* @mbx_id: id of mailbox to check
|
||||
*
|
||||
* returns SUCCESS if the Status bit was found or else ERR_MBX
|
||||
**/
|
||||
s32 e1000_check_for_rst(struct e1000_hw *hw, u16 mbx_id)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("e1000_check_for_rst");
|
||||
|
||||
if (mbx->ops.check_for_rst)
|
||||
ret_val = mbx->ops.check_for_rst(hw, mbx_id);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_poll_for_msg - Wait for message notification
|
||||
* @hw: pointer to the HW structure
|
||||
* @mbx_id: id of mailbox to write
|
||||
*
|
||||
* returns SUCCESS if it successfully received a message notification
|
||||
**/
|
||||
static s32 e1000_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
int countdown = mbx->timeout;
|
||||
|
||||
DEBUGFUNC("e1000_poll_for_msg");
|
||||
|
||||
if (!countdown || !mbx->ops.check_for_msg)
|
||||
goto out;
|
||||
|
||||
while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
|
||||
countdown--;
|
||||
if (!countdown)
|
||||
break;
|
||||
usec_delay(mbx->usec_delay);
|
||||
}
|
||||
|
||||
/* if we failed, all future posted messages fail until reset */
|
||||
if (!countdown)
|
||||
mbx->timeout = 0;
|
||||
out:
|
||||
return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_poll_for_ack - Wait for message acknowledgement
|
||||
* @hw: pointer to the HW structure
|
||||
* @mbx_id: id of mailbox to write
|
||||
*
|
||||
* returns SUCCESS if it successfully received a message acknowledgement
|
||||
**/
|
||||
static s32 e1000_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
int countdown = mbx->timeout;
|
||||
|
||||
DEBUGFUNC("e1000_poll_for_ack");
|
||||
|
||||
if (!countdown || !mbx->ops.check_for_ack)
|
||||
goto out;
|
||||
|
||||
while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
|
||||
countdown--;
|
||||
if (!countdown)
|
||||
break;
|
||||
usec_delay(mbx->usec_delay);
|
||||
}
|
||||
|
||||
/* if we failed, all future posted messages fail until reset */
|
||||
if (!countdown)
|
||||
mbx->timeout = 0;
|
||||
out:
|
||||
return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_read_posted_mbx - Wait for message notification and receive message
|
||||
* @hw: pointer to the HW structure
|
||||
* @msg: The message buffer
|
||||
* @size: Length of buffer
|
||||
* @mbx_id: id of mailbox to write
|
||||
*
|
||||
* returns SUCCESS if it successfully received a message notification and
|
||||
* copied it into the receive buffer.
|
||||
**/
|
||||
s32 e1000_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("e1000_read_posted_mbx");
|
||||
|
||||
if (!mbx->ops.read)
|
||||
goto out;
|
||||
|
||||
ret_val = e1000_poll_for_msg(hw, mbx_id);
|
||||
|
||||
/* if ack received read message, otherwise we timed out */
|
||||
if (!ret_val)
|
||||
ret_val = mbx->ops.read(hw, msg, size, mbx_id);
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_write_posted_mbx - Write a message to the mailbox, wait for ack
|
||||
* @hw: pointer to the HW structure
|
||||
* @msg: The message buffer
|
||||
* @size: Length of buffer
|
||||
* @mbx_id: id of mailbox to write
|
||||
*
|
||||
* returns SUCCESS if it successfully copied message into the buffer and
|
||||
* received an ack to that message within delay * timeout period
|
||||
**/
|
||||
s32 e1000_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("e1000_write_posted_mbx");
|
||||
|
||||
/* exit if either we can't write or there isn't a defined timeout */
|
||||
if (!mbx->ops.write || !mbx->timeout)
|
||||
goto out;
|
||||
|
||||
/* send msg */
|
||||
ret_val = mbx->ops.write(hw, msg, size, mbx_id);
|
||||
|
||||
/* if msg sent wait until we receive an ack */
|
||||
if (!ret_val)
|
||||
ret_val = e1000_poll_for_ack(hw, mbx_id);
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_init_mbx_ops_generic - Initialize mbx function pointers
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Sets the function pointers to no-op functions
|
||||
**/
|
||||
void e1000_init_mbx_ops_generic(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
mbx->ops.init_params = e1000_null_ops_generic;
|
||||
mbx->ops.read = e1000_null_mbx_transact;
|
||||
mbx->ops.write = e1000_null_mbx_transact;
|
||||
mbx->ops.check_for_msg = e1000_null_mbx_check_for_flag;
|
||||
mbx->ops.check_for_ack = e1000_null_mbx_check_for_flag;
|
||||
mbx->ops.check_for_rst = e1000_null_mbx_check_for_flag;
|
||||
mbx->ops.read_posted = e1000_read_posted_mbx;
|
||||
mbx->ops.write_posted = e1000_write_posted_mbx;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_read_v2p_mailbox - read v2p mailbox
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* This function is used to read the v2p mailbox without losing the read to
|
||||
* clear status bits.
|
||||
**/
|
||||
static u32 e1000_read_v2p_mailbox(struct e1000_hw *hw)
|
||||
{
|
||||
u32 v2p_mailbox = E1000_READ_REG(hw, E1000_V2PMAILBOX(0));
|
||||
|
||||
v2p_mailbox |= hw->dev_spec.vf.v2p_mailbox;
|
||||
hw->dev_spec.vf.v2p_mailbox |= v2p_mailbox & E1000_V2PMAILBOX_R2C_BITS;
|
||||
|
||||
return v2p_mailbox;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_check_for_bit_vf - Determine if a status bit was set
|
||||
* @hw: pointer to the HW structure
|
||||
* @mask: bitmask for bits to be tested and cleared
|
||||
*
|
||||
* This function is used to check for the read to clear bits within
|
||||
* the V2P mailbox.
|
||||
**/
|
||||
static s32 e1000_check_for_bit_vf(struct e1000_hw *hw, u32 mask)
|
||||
{
|
||||
u32 v2p_mailbox = e1000_read_v2p_mailbox(hw);
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
if (v2p_mailbox & mask)
|
||||
ret_val = E1000_SUCCESS;
|
||||
|
||||
hw->dev_spec.vf.v2p_mailbox &= ~mask;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_check_for_msg_vf - checks to see if the PF has sent mail
|
||||
* @hw: pointer to the HW structure
|
||||
* @mbx_id: id of mailbox to check
|
||||
*
|
||||
* returns SUCCESS if the PF has set the Status bit or else ERR_MBX
|
||||
**/
|
||||
static s32 e1000_check_for_msg_vf(struct e1000_hw *hw, u16 mbx_id)
|
||||
{
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("e1000_check_for_msg_vf");
|
||||
|
||||
if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFSTS)) {
|
||||
ret_val = E1000_SUCCESS;
|
||||
hw->mbx.stats.reqs++;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_check_for_ack_vf - checks to see if the PF has ACK'd
|
||||
* @hw: pointer to the HW structure
|
||||
* @mbx_id: id of mailbox to check
|
||||
*
|
||||
* returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
|
||||
**/
|
||||
static s32 e1000_check_for_ack_vf(struct e1000_hw *hw, u16 mbx_id)
|
||||
{
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("e1000_check_for_ack_vf");
|
||||
|
||||
if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFACK)) {
|
||||
ret_val = E1000_SUCCESS;
|
||||
hw->mbx.stats.acks++;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_check_for_rst_vf - checks to see if the PF has reset
|
||||
* @hw: pointer to the HW structure
|
||||
* @mbx_id: id of mailbox to check
|
||||
*
|
||||
* returns TRUE if the PF has set the reset done bit or else FALSE
|
||||
**/
|
||||
static s32 e1000_check_for_rst_vf(struct e1000_hw *hw, u16 mbx_id)
|
||||
{
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("e1000_check_for_rst_vf");
|
||||
|
||||
if (!e1000_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD |
|
||||
E1000_V2PMAILBOX_RSTI))) {
|
||||
ret_val = E1000_SUCCESS;
|
||||
hw->mbx.stats.rsts++;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_obtain_mbx_lock_vf - obtain mailbox lock
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* return SUCCESS if we obtained the mailbox lock
|
||||
**/
|
||||
static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("e1000_obtain_mbx_lock_vf");
|
||||
|
||||
/* Take ownership of the buffer */
|
||||
E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);
|
||||
|
||||
/* reserve mailbox for vf use */
|
||||
if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU)
|
||||
ret_val = E1000_SUCCESS;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_write_mbx_vf - Write a message to the mailbox
|
||||
* @hw: pointer to the HW structure
|
||||
* @msg: The message buffer
|
||||
* @size: Length of buffer
|
||||
* @mbx_id: id of mailbox to write
|
||||
*
|
||||
* returns SUCCESS if it successfully copied message into the buffer
|
||||
**/
|
||||
static s32 e1000_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
|
||||
u16 mbx_id)
|
||||
{
|
||||
s32 ret_val;
|
||||
u16 i;
|
||||
|
||||
|
||||
DEBUGFUNC("e1000_write_mbx_vf");
|
||||
|
||||
/* lock the mailbox to prevent pf/vf race condition */
|
||||
ret_val = e1000_obtain_mbx_lock_vf(hw);
|
||||
if (ret_val)
|
||||
goto out_no_write;
|
||||
|
||||
/* flush msg and acks as we are overwriting the message buffer */
|
||||
e1000_check_for_msg_vf(hw, 0);
|
||||
e1000_check_for_ack_vf(hw, 0);
|
||||
|
||||
/* copy the caller specified message to the mailbox memory buffer */
|
||||
for (i = 0; i < size; i++)
|
||||
E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(0), i, msg[i]);
|
||||
|
||||
/* update stats */
|
||||
hw->mbx.stats.msgs_tx++;
|
||||
|
||||
/* Drop VFU and interrupt the PF to tell it a message has been sent */
|
||||
E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_REQ);
|
||||
|
||||
out_no_write:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_read_mbx_vf - Reads a message from the inbox intended for vf
|
||||
* @hw: pointer to the HW structure
|
||||
* @msg: The message buffer
|
||||
* @size: Length of buffer
|
||||
* @mbx_id: id of mailbox to read
|
||||
*
|
||||
* returns SUCCESS if it successfuly read message from buffer
|
||||
**/
|
||||
static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
|
||||
u16 mbx_id)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u16 i;
|
||||
|
||||
DEBUGFUNC("e1000_read_mbx_vf");
|
||||
|
||||
/* lock the mailbox to prevent pf/vf race condition */
|
||||
ret_val = e1000_obtain_mbx_lock_vf(hw);
|
||||
if (ret_val)
|
||||
goto out_no_read;
|
||||
|
||||
/* copy the message from the mailbox memory buffer */
|
||||
for (i = 0; i < size; i++)
|
||||
msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(0), i);
|
||||
|
||||
/* Acknowledge receipt and release mailbox, then we're done */
|
||||
E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_ACK);
|
||||
|
||||
/* update stats */
|
||||
hw->mbx.stats.msgs_rx++;
|
||||
|
||||
out_no_read:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_init_mbx_params_vf - set initial values for vf mailbox
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Initializes the hw->mbx struct to correct values for vf mailbox
|
||||
*/
|
||||
s32 e1000_init_mbx_params_vf(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
|
||||
/* start mailbox as timed out and let the reset_hw call set the timeout
|
||||
* value to begin communications */
|
||||
mbx->timeout = 0;
|
||||
mbx->usec_delay = E1000_VF_MBX_INIT_DELAY;
|
||||
|
||||
mbx->size = E1000_VFMAILBOX_SIZE;
|
||||
|
||||
mbx->ops.read = e1000_read_mbx_vf;
|
||||
mbx->ops.write = e1000_write_mbx_vf;
|
||||
mbx->ops.read_posted = e1000_read_posted_mbx;
|
||||
mbx->ops.write_posted = e1000_write_posted_mbx;
|
||||
mbx->ops.check_for_msg = e1000_check_for_msg_vf;
|
||||
mbx->ops.check_for_ack = e1000_check_for_ack_vf;
|
||||
mbx->ops.check_for_rst = e1000_check_for_rst_vf;
|
||||
|
||||
mbx->stats.msgs_tx = 0;
|
||||
mbx->stats.msgs_rx = 0;
|
||||
mbx->stats.reqs = 0;
|
||||
mbx->stats.acks = 0;
|
||||
mbx->stats.rsts = 0;
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
static s32 e1000_check_for_bit_pf(struct e1000_hw *hw, u32 mask)
|
||||
{
|
||||
u32 mbvficr = E1000_READ_REG(hw, E1000_MBVFICR);
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
if (mbvficr & mask) {
|
||||
ret_val = E1000_SUCCESS;
|
||||
E1000_WRITE_REG(hw, E1000_MBVFICR, mask);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_check_for_msg_pf - checks to see if the VF has sent mail
|
||||
* @hw: pointer to the HW structure
|
||||
* @vf_number: the VF index
|
||||
*
|
||||
* returns SUCCESS if the VF has set the Status bit or else ERR_MBX
|
||||
**/
|
||||
static s32 e1000_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number)
|
||||
{
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("e1000_check_for_msg_pf");
|
||||
|
||||
if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) {
|
||||
ret_val = E1000_SUCCESS;
|
||||
hw->mbx.stats.reqs++;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_check_for_ack_pf - checks to see if the VF has ACKed
|
||||
* @hw: pointer to the HW structure
|
||||
* @vf_number: the VF index
|
||||
*
|
||||
* returns SUCCESS if the VF has set the Status bit or else ERR_MBX
|
||||
**/
|
||||
static s32 e1000_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number)
|
||||
{
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("e1000_check_for_ack_pf");
|
||||
|
||||
if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) {
|
||||
ret_val = E1000_SUCCESS;
|
||||
hw->mbx.stats.acks++;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_check_for_rst_pf - checks to see if the VF has reset
|
||||
* @hw: pointer to the HW structure
|
||||
* @vf_number: the VF index
|
||||
*
|
||||
* returns SUCCESS if the VF has set the Status bit or else ERR_MBX
|
||||
**/
|
||||
static s32 e1000_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
|
||||
{
|
||||
u32 vflre = E1000_READ_REG(hw, E1000_VFLRE);
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("e1000_check_for_rst_pf");
|
||||
|
||||
if (vflre & (1 << vf_number)) {
|
||||
ret_val = E1000_SUCCESS;
|
||||
E1000_WRITE_REG(hw, E1000_VFLRE, (1 << vf_number));
|
||||
hw->mbx.stats.rsts++;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_obtain_mbx_lock_pf - obtain mailbox lock
|
||||
* @hw: pointer to the HW structure
|
||||
* @vf_number: the VF index
|
||||
*
|
||||
* return SUCCESS if we obtained the mailbox lock
|
||||
**/
|
||||
static s32 e1000_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
|
||||
{
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
u32 p2v_mailbox;
|
||||
|
||||
DEBUGFUNC("e1000_obtain_mbx_lock_pf");
|
||||
|
||||
/* Take ownership of the buffer */
|
||||
E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
|
||||
|
||||
/* reserve mailbox for vf use */
|
||||
p2v_mailbox = E1000_READ_REG(hw, E1000_P2VMAILBOX(vf_number));
|
||||
if (p2v_mailbox & E1000_P2VMAILBOX_PFU)
|
||||
ret_val = E1000_SUCCESS;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_write_mbx_pf - Places a message in the mailbox
|
||||
* @hw: pointer to the HW structure
|
||||
* @msg: The message buffer
|
||||
* @size: Length of buffer
|
||||
* @vf_number: the VF index
|
||||
*
|
||||
* returns SUCCESS if it successfully copied message into the buffer
|
||||
**/
|
||||
static s32 e1000_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
|
||||
u16 vf_number)
|
||||
{
|
||||
s32 ret_val;
|
||||
u16 i;
|
||||
|
||||
DEBUGFUNC("e1000_write_mbx_pf");
|
||||
|
||||
/* lock the mailbox to prevent pf/vf race condition */
|
||||
ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number);
|
||||
if (ret_val)
|
||||
goto out_no_write;
|
||||
|
||||
/* flush msg and acks as we are overwriting the message buffer */
|
||||
e1000_check_for_msg_pf(hw, vf_number);
|
||||
e1000_check_for_ack_pf(hw, vf_number);
|
||||
|
||||
/* copy the caller specified message to the mailbox memory buffer */
|
||||
for (i = 0; i < size; i++)
|
||||
E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i, msg[i]);
|
||||
|
||||
/* Interrupt VF to tell it a message has been sent and release buffer*/
|
||||
E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS);
|
||||
|
||||
/* update stats */
|
||||
hw->mbx.stats.msgs_tx++;
|
||||
|
||||
out_no_write:
|
||||
return ret_val;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_read_mbx_pf - Read a message from the mailbox
|
||||
* @hw: pointer to the HW structure
|
||||
* @msg: The message buffer
|
||||
* @size: Length of buffer
|
||||
* @vf_number: the VF index
|
||||
*
|
||||
* This function copies a message from the mailbox buffer to the caller's
|
||||
* memory buffer. The presumption is that the caller knows that there was
|
||||
* a message due to a VF request so no polling for message is needed.
|
||||
**/
|
||||
static s32 e1000_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
|
||||
u16 vf_number)
|
||||
{
|
||||
s32 ret_val;
|
||||
u16 i;
|
||||
|
||||
DEBUGFUNC("e1000_read_mbx_pf");
|
||||
|
||||
/* lock the mailbox to prevent pf/vf race condition */
|
||||
ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number);
|
||||
if (ret_val)
|
||||
goto out_no_read;
|
||||
|
||||
/* copy the message to the mailbox memory buffer */
|
||||
for (i = 0; i < size; i++)
|
||||
msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i);
|
||||
|
||||
/* Acknowledge the message and release buffer */
|
||||
E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK);
|
||||
|
||||
/* update stats */
|
||||
hw->mbx.stats.msgs_rx++;
|
||||
|
||||
out_no_read:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_init_mbx_params_pf - set initial values for pf mailbox
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Initializes the hw->mbx struct to correct values for pf mailbox
|
||||
*/
|
||||
s32 e1000_init_mbx_params_pf(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
|
||||
if (hw->mac.type == e1000_82576) {
|
||||
mbx->timeout = 0;
|
||||
mbx->usec_delay = 0;
|
||||
|
||||
mbx->size = E1000_VFMAILBOX_SIZE;
|
||||
|
||||
mbx->ops.read = e1000_read_mbx_pf;
|
||||
mbx->ops.write = e1000_write_mbx_pf;
|
||||
mbx->ops.read_posted = e1000_read_posted_mbx;
|
||||
mbx->ops.write_posted = e1000_write_posted_mbx;
|
||||
mbx->ops.check_for_msg = e1000_check_for_msg_pf;
|
||||
mbx->ops.check_for_ack = e1000_check_for_ack_pf;
|
||||
mbx->ops.check_for_rst = e1000_check_for_rst_pf;
|
||||
|
||||
mbx->stats.msgs_tx = 0;
|
||||
mbx->stats.msgs_rx = 0;
|
||||
mbx->stats.reqs = 0;
|
||||
mbx->stats.acks = 0;
|
||||
mbx->stats.rsts = 0;
|
||||
}
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
106
sys/dev/e1000/e1000_mbx.h
Normal file
106
sys/dev/e1000/e1000_mbx.h
Normal file
@ -0,0 +1,106 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2010, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the Intel Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
******************************************************************************/
|
||||
/*$FreeBSD$*/
|
||||
|
||||
#ifndef _E1000_MBX_H_
|
||||
#define _E1000_MBX_H_
|
||||
|
||||
#include "e1000_api.h"
|
||||
|
||||
/* Define mailbox register bits */
|
||||
#define E1000_V2PMAILBOX_REQ 0x00000001 /* Request for PF Ready bit */
|
||||
#define E1000_V2PMAILBOX_ACK 0x00000002 /* Ack PF message received */
|
||||
#define E1000_V2PMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */
|
||||
#define E1000_V2PMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */
|
||||
#define E1000_V2PMAILBOX_PFSTS 0x00000010 /* PF wrote a message in the MB */
|
||||
#define E1000_V2PMAILBOX_PFACK 0x00000020 /* PF ack the previous VF msg */
|
||||
#define E1000_V2PMAILBOX_RSTI 0x00000040 /* PF has reset indication */
|
||||
#define E1000_V2PMAILBOX_RSTD 0x00000080 /* PF has indicated reset done */
|
||||
#define E1000_V2PMAILBOX_R2C_BITS 0x000000B0 /* All read to clear bits */
|
||||
|
||||
#define E1000_P2VMAILBOX_STS 0x00000001 /* Initiate message send to VF */
|
||||
#define E1000_P2VMAILBOX_ACK 0x00000002 /* Ack message recv'd from VF */
|
||||
#define E1000_P2VMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */
|
||||
#define E1000_P2VMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */
|
||||
#define E1000_P2VMAILBOX_RVFU 0x00000010 /* Reset VFU - used when VF stuck */
|
||||
|
||||
#define E1000_MBVFICR_VFREQ_MASK 0x000000FF /* bits for VF messages */
|
||||
#define E1000_MBVFICR_VFREQ_VF1 0x00000001 /* bit for VF 1 message */
|
||||
#define E1000_MBVFICR_VFACK_MASK 0x00FF0000 /* bits for VF acks */
|
||||
#define E1000_MBVFICR_VFACK_VF1 0x00010000 /* bit for VF 1 ack */
|
||||
|
||||
#define E1000_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */
|
||||
|
||||
/* If it's a E1000_VF_* msg then it originates in the VF and is sent to the
|
||||
* PF. The reverse is TRUE if it is E1000_PF_*.
|
||||
* Message ACK's are the value or'd with 0xF0000000
|
||||
*/
|
||||
#define E1000_VT_MSGTYPE_ACK 0x80000000 /* Messages below or'd with
|
||||
* this are the ACK */
|
||||
#define E1000_VT_MSGTYPE_NACK 0x40000000 /* Messages below or'd with
|
||||
* this are the NACK */
|
||||
#define E1000_VT_MSGTYPE_CTS 0x20000000 /* Indicates that VF is still
|
||||
clear to send requests */
|
||||
#define E1000_VT_MSGINFO_SHIFT 16
|
||||
/* bits 23:16 are used for exra info for certain messages */
|
||||
#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT)
|
||||
|
||||
#define E1000_VF_RESET 0x01 /* VF requests reset */
|
||||
#define E1000_VF_SET_MAC_ADDR 0x02 /* VF requests to set MAC addr */
|
||||
#define E1000_VF_SET_MULTICAST 0x03 /* VF requests to set MC addr */
|
||||
#define E1000_VF_SET_MULTICAST_COUNT_MASK (0x1F << E1000_VT_MSGINFO_SHIFT)
|
||||
#define E1000_VF_SET_MULTICAST_OVERFLOW (0x80 << E1000_VT_MSGINFO_SHIFT)
|
||||
#define E1000_VF_SET_VLAN 0x04 /* VF requests to set VLAN */
|
||||
#define E1000_VF_SET_VLAN_ADD (0x01 << E1000_VT_MSGINFO_SHIFT)
|
||||
#define E1000_VF_SET_LPE 0x05 /* VF requests to set VMOLR.LPE */
|
||||
#define E1000_VF_SET_PROMISC 0x06 /*VF requests to clear VMOLR.ROPE/MPME*/
|
||||
#define E1000_VF_SET_PROMISC_UNICAST (0x01 << E1000_VT_MSGINFO_SHIFT)
|
||||
#define E1000_VF_SET_PROMISC_MULTICAST (0x02 << E1000_VT_MSGINFO_SHIFT)
|
||||
|
||||
#define E1000_PF_CONTROL_MSG 0x0100 /* PF control message */
|
||||
|
||||
#define E1000_VF_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */
|
||||
#define E1000_VF_MBX_INIT_DELAY 500 /* microseconds between retries */
|
||||
|
||||
s32 e1000_read_mbx(struct e1000_hw *, u32 *, u16, u16);
|
||||
s32 e1000_write_mbx(struct e1000_hw *, u32 *, u16, u16);
|
||||
s32 e1000_read_posted_mbx(struct e1000_hw *, u32 *, u16, u16);
|
||||
s32 e1000_write_posted_mbx(struct e1000_hw *, u32 *, u16, u16);
|
||||
s32 e1000_check_for_msg(struct e1000_hw *, u16);
|
||||
s32 e1000_check_for_ack(struct e1000_hw *, u16);
|
||||
s32 e1000_check_for_rst(struct e1000_hw *, u16);
|
||||
void e1000_init_mbx_ops_generic(struct e1000_hw *hw);
|
||||
s32 e1000_init_mbx_params_vf(struct e1000_hw *);
|
||||
s32 e1000_init_mbx_params_pf(struct e1000_hw *);
|
||||
|
||||
#endif /* _E1000_MBX_H_ */
|
@ -282,6 +282,15 @@
|
||||
#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
|
||||
#define E1000_CRC_OFFSET 0x05F50 /* CRC Offset register */
|
||||
|
||||
#define E1000_VFGPRC 0x00F10
|
||||
#define E1000_VFGORC 0x00F18
|
||||
#define E1000_VFMPRC 0x00F3C
|
||||
#define E1000_VFGPTC 0x00F14
|
||||
#define E1000_VFGOTC 0x00F34
|
||||
#define E1000_VFGOTLBC 0x00F50
|
||||
#define E1000_VFGPTLBC 0x00F44
|
||||
#define E1000_VFGORLBC 0x00F48
|
||||
#define E1000_VFGPRLBC 0x00F40
|
||||
/* Virtualization statistical counters */
|
||||
#define E1000_PFVFGPRC(_n) (0x010010 + (0x100 * (_n)))
|
||||
#define E1000_PFVFGPTC(_n) (0x010014 + (0x100 * (_n)))
|
||||
|
574
sys/dev/e1000/e1000_vf.c
Normal file
574
sys/dev/e1000/e1000_vf.c
Normal file
@ -0,0 +1,574 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2010, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the Intel Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
******************************************************************************/
|
||||
/*$FreeBSD$*/
|
||||
|
||||
|
||||
#include "e1000_api.h"
|
||||
|
||||
|
||||
static s32 e1000_init_phy_params_vf(struct e1000_hw *hw);
|
||||
static s32 e1000_init_nvm_params_vf(struct e1000_hw *hw);
|
||||
static void e1000_release_vf(struct e1000_hw *hw);
|
||||
static s32 e1000_acquire_vf(struct e1000_hw *hw);
|
||||
static s32 e1000_setup_link_vf(struct e1000_hw *hw);
|
||||
static s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw);
|
||||
static s32 e1000_init_mac_params_vf(struct e1000_hw *hw);
|
||||
static s32 e1000_check_for_link_vf(struct e1000_hw *hw);
|
||||
static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
|
||||
u16 *duplex);
|
||||
static s32 e1000_init_hw_vf(struct e1000_hw *hw);
|
||||
static s32 e1000_reset_hw_vf(struct e1000_hw *hw);
|
||||
static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *, u32);
|
||||
static void e1000_rar_set_vf(struct e1000_hw *, u8 *, u32);
|
||||
static s32 e1000_read_mac_addr_vf(struct e1000_hw *);
|
||||
|
||||
/**
|
||||
* e1000_init_phy_params_vf - Inits PHY params
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Doesn't do much - there's no PHY available to the VF.
|
||||
**/
|
||||
static s32 e1000_init_phy_params_vf(struct e1000_hw *hw)
|
||||
{
|
||||
DEBUGFUNC("e1000_init_phy_params_vf");
|
||||
hw->phy.type = e1000_phy_vf;
|
||||
hw->phy.ops.acquire = e1000_acquire_vf;
|
||||
hw->phy.ops.release = e1000_release_vf;
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_init_nvm_params_vf - Inits NVM params
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Doesn't do much - there's no NVM available to the VF.
|
||||
**/
|
||||
static s32 e1000_init_nvm_params_vf(struct e1000_hw *hw)
|
||||
{
|
||||
DEBUGFUNC("e1000_init_nvm_params_vf");
|
||||
hw->nvm.type = e1000_nvm_none;
|
||||
hw->nvm.ops.acquire = e1000_acquire_vf;
|
||||
hw->nvm.ops.release = e1000_release_vf;
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_init_mac_params_vf - Inits MAC params
|
||||
* @hw: pointer to the HW structure
|
||||
**/
|
||||
static s32 e1000_init_mac_params_vf(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_mac_info *mac = &hw->mac;
|
||||
|
||||
DEBUGFUNC("e1000_init_mac_params_vf");
|
||||
|
||||
/* Set media type */
|
||||
/*
|
||||
* Virtual functions don't care what they're media type is as they
|
||||
* have no direct access to the PHY, or the media. That is handled
|
||||
* by the physical function driver.
|
||||
*/
|
||||
hw->phy.media_type = e1000_media_type_unknown;
|
||||
|
||||
/* No ASF features for the VF driver */
|
||||
mac->asf_firmware_present = FALSE;
|
||||
/* ARC subsystem not supported */
|
||||
mac->arc_subsystem_valid = FALSE;
|
||||
/* Disable adaptive IFS mode so the generic funcs don't do anything */
|
||||
mac->adaptive_ifs = FALSE;
|
||||
/* VF's have no MTA Registers - PF feature only */
|
||||
mac->mta_reg_count = 128;
|
||||
/* VF's have no access to RAR entries */
|
||||
mac->rar_entry_count = 1;
|
||||
|
||||
/* Function pointers */
|
||||
/* link setup */
|
||||
mac->ops.setup_link = e1000_setup_link_vf;
|
||||
/* bus type/speed/width */
|
||||
mac->ops.get_bus_info = e1000_get_bus_info_pcie_vf;
|
||||
/* reset */
|
||||
mac->ops.reset_hw = e1000_reset_hw_vf;
|
||||
/* hw initialization */
|
||||
mac->ops.init_hw = e1000_init_hw_vf;
|
||||
/* check for link */
|
||||
mac->ops.check_for_link = e1000_check_for_link_vf;
|
||||
/* link info */
|
||||
mac->ops.get_link_up_info = e1000_get_link_up_info_vf;
|
||||
/* multicast address update */
|
||||
mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_vf;
|
||||
/* set mac address */
|
||||
mac->ops.rar_set = e1000_rar_set_vf;
|
||||
/* read mac address */
|
||||
mac->ops.read_mac_addr = e1000_read_mac_addr_vf;
|
||||
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_init_function_pointers_vf - Inits function pointers
|
||||
* @hw: pointer to the HW structure
|
||||
**/
|
||||
void e1000_init_function_pointers_vf(struct e1000_hw *hw)
|
||||
{
|
||||
DEBUGFUNC("e1000_init_function_pointers_vf");
|
||||
|
||||
hw->mac.ops.init_params = e1000_init_mac_params_vf;
|
||||
hw->nvm.ops.init_params = e1000_init_nvm_params_vf;
|
||||
hw->phy.ops.init_params = e1000_init_phy_params_vf;
|
||||
hw->mbx.ops.init_params = e1000_init_mbx_params_vf;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_acquire_vf - Acquire rights to access PHY or NVM.
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* There is no PHY or NVM so we want all attempts to acquire these to fail.
|
||||
* In addition, the MAC registers to access PHY/NVM don't exist so we don't
|
||||
* even want any SW to attempt to use them.
|
||||
**/
|
||||
static s32 e1000_acquire_vf(struct e1000_hw *hw)
|
||||
{
|
||||
return -E1000_ERR_PHY;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_release_vf - Release PHY or NVM
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* There is no PHY or NVM so we want all attempts to acquire these to fail.
|
||||
* In addition, the MAC registers to access PHY/NVM don't exist so we don't
|
||||
* even want any SW to attempt to use them.
|
||||
**/
|
||||
static void e1000_release_vf(struct e1000_hw *hw)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_setup_link_vf - Sets up link.
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Virtual functions cannot change link.
|
||||
**/
|
||||
static s32 e1000_setup_link_vf(struct e1000_hw *hw)
|
||||
{
|
||||
DEBUGFUNC("e1000_setup_link_vf");
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_get_bus_info_pcie_vf - Gets the bus info.
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Virtual functions are not really on their own bus.
|
||||
**/
|
||||
static s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_bus_info *bus = &hw->bus;
|
||||
|
||||
DEBUGFUNC("e1000_get_bus_info_pcie_vf");
|
||||
|
||||
/* Do not set type PCI-E because we don't want disable master to run */
|
||||
bus->type = e1000_bus_type_reserved;
|
||||
bus->speed = e1000_bus_speed_2500;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_get_link_up_info_vf - Gets link info.
|
||||
* @hw: pointer to the HW structure
|
||||
* @speed: pointer to 16 bit value to store link speed.
|
||||
* @duplex: pointer to 16 bit value to store duplex.
|
||||
*
|
||||
* Since we cannot read the PHY and get accurate link info, we must rely upon
|
||||
* the status register's data which is often stale and inaccurate.
|
||||
**/
|
||||
static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
|
||||
u16 *duplex)
|
||||
{
|
||||
s32 status;
|
||||
|
||||
DEBUGFUNC("e1000_get_link_up_info_vf");
|
||||
|
||||
status = E1000_READ_REG(hw, E1000_STATUS);
|
||||
if (status & E1000_STATUS_SPEED_1000) {
|
||||
*speed = SPEED_1000;
|
||||
DEBUGOUT("1000 Mbs, ");
|
||||
} else if (status & E1000_STATUS_SPEED_100) {
|
||||
*speed = SPEED_100;
|
||||
DEBUGOUT("100 Mbs, ");
|
||||
} else {
|
||||
*speed = SPEED_10;
|
||||
DEBUGOUT("10 Mbs, ");
|
||||
}
|
||||
|
||||
if (status & E1000_STATUS_FD) {
|
||||
*duplex = FULL_DUPLEX;
|
||||
DEBUGOUT("Full Duplex\n");
|
||||
} else {
|
||||
*duplex = HALF_DUPLEX;
|
||||
DEBUGOUT("Half Duplex\n");
|
||||
}
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_reset_hw_vf - Resets the HW
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* VF's provide a function level reset. This is done using bit 26 of ctrl_reg.
|
||||
* This is all the reset we can perform on a VF.
|
||||
**/
|
||||
static s32 e1000_reset_hw_vf(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
u32 timeout = E1000_VF_INIT_TIMEOUT;
|
||||
s32 ret_val = -E1000_ERR_MAC_INIT;
|
||||
u32 ctrl, msgbuf[3];
|
||||
u8 *addr = (u8 *)(&msgbuf[1]);
|
||||
|
||||
DEBUGFUNC("e1000_reset_hw_vf");
|
||||
|
||||
DEBUGOUT("Issuing a function level reset to MAC\n");
|
||||
ctrl = E1000_READ_REG(hw, E1000_CTRL);
|
||||
E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
|
||||
|
||||
/* we cannot reset while the RSTI / RSTD bits are asserted */
|
||||
while (!mbx->ops.check_for_rst(hw, 0) && timeout) {
|
||||
timeout--;
|
||||
usec_delay(5);
|
||||
}
|
||||
|
||||
if (timeout) {
|
||||
/* mailbox timeout can now become active */
|
||||
mbx->timeout = E1000_VF_MBX_INIT_TIMEOUT;
|
||||
|
||||
msgbuf[0] = E1000_VF_RESET;
|
||||
mbx->ops.write_posted(hw, msgbuf, 1, 0);
|
||||
|
||||
msec_delay(10);
|
||||
|
||||
/* set our "perm_addr" based on info provided by PF */
|
||||
ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0);
|
||||
if (!ret_val) {
|
||||
if (msgbuf[0] == (E1000_VF_RESET |
|
||||
E1000_VT_MSGTYPE_ACK))
|
||||
memcpy(hw->mac.perm_addr, addr, 6);
|
||||
else
|
||||
ret_val = -E1000_ERR_MAC_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_init_hw_vf - Inits the HW
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Not much to do here except clear the PF Reset indication if there is one.
|
||||
**/
|
||||
static s32 e1000_init_hw_vf(struct e1000_hw *hw)
|
||||
{
|
||||
DEBUGFUNC("e1000_init_hw_vf");
|
||||
|
||||
/* attempt to set and restore our mac address */
|
||||
e1000_rar_set_vf(hw, hw->mac.addr, 0);
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_rar_set_vf - set device MAC address
|
||||
* @hw: pointer to the HW structure
|
||||
* @addr: pointer to the receive address
|
||||
* @index receive address array register
|
||||
**/
|
||||
static void e1000_rar_set_vf(struct e1000_hw *hw, u8 * addr, u32 index)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
u32 msgbuf[3];
|
||||
u8 *msg_addr = (u8 *)(&msgbuf[1]);
|
||||
s32 ret_val;
|
||||
|
||||
memset(msgbuf, 0, 12);
|
||||
msgbuf[0] = E1000_VF_SET_MAC_ADDR;
|
||||
memcpy(msg_addr, addr, 6);
|
||||
ret_val = mbx->ops.write_posted(hw, msgbuf, 3, 0);
|
||||
|
||||
if (!ret_val)
|
||||
ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0);
|
||||
|
||||
msgbuf[0] &= ~E1000_VT_MSGTYPE_CTS;
|
||||
|
||||
/* if nacked the address was rejected, use "perm_addr" */
|
||||
if (!ret_val &&
|
||||
(msgbuf[0] == (E1000_VF_SET_MAC_ADDR | E1000_VT_MSGTYPE_NACK)))
|
||||
e1000_read_mac_addr_vf(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_hash_mc_addr_vf - Generate a multicast hash value
|
||||
* @hw: pointer to the HW structure
|
||||
* @mc_addr: pointer to a multicast address
|
||||
*
|
||||
* Generates a multicast address hash value which is used to determine
|
||||
* the multicast filter table array address and new table value.
|
||||
**/
|
||||
static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr)
|
||||
{
|
||||
u32 hash_value, hash_mask;
|
||||
u8 bit_shift = 0;
|
||||
|
||||
DEBUGFUNC("e1000_hash_mc_addr_generic");
|
||||
|
||||
/* Register count multiplied by bits per register */
|
||||
hash_mask = (hw->mac.mta_reg_count * 32) - 1;
|
||||
|
||||
/*
|
||||
* The bit_shift is the number of left-shifts
|
||||
* where 0xFF would still fall within the hash mask.
|
||||
*/
|
||||
while (hash_mask >> bit_shift != 0xFF)
|
||||
bit_shift++;
|
||||
|
||||
hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) |
|
||||
(((u16) mc_addr[5]) << bit_shift)));
|
||||
|
||||
return hash_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_update_mc_addr_list_vf - Update Multicast addresses
|
||||
* @hw: pointer to the HW structure
|
||||
* @mc_addr_list: array of multicast addresses to program
|
||||
* @mc_addr_count: number of multicast addresses to program
|
||||
*
|
||||
* Updates the Multicast Table Array.
|
||||
* The caller must have a packed mc_addr_list of multicast addresses.
|
||||
**/
|
||||
void e1000_update_mc_addr_list_vf(struct e1000_hw *hw,
|
||||
u8 *mc_addr_list, u32 mc_addr_count)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
u32 msgbuf[E1000_VFMAILBOX_SIZE];
|
||||
u16 *hash_list = (u16 *)&msgbuf[1];
|
||||
u32 hash_value;
|
||||
u32 i;
|
||||
|
||||
DEBUGFUNC("e1000_update_mc_addr_list_vf");
|
||||
|
||||
/* Each entry in the list uses 1 16 bit word. We have 30
|
||||
* 16 bit words available in our HW msg buffer (minus 1 for the
|
||||
* msg type). That's 30 hash values if we pack 'em right. If
|
||||
* there are more than 30 MC addresses to add then punt the
|
||||
* extras for now and then add code to handle more than 30 later.
|
||||
* It would be unusual for a server to request that many multi-cast
|
||||
* addresses except for in large enterprise network environments.
|
||||
*/
|
||||
|
||||
DEBUGOUT1("MC Addr Count = %d\n", mc_addr_count);
|
||||
|
||||
if (mc_addr_count > 30) {
|
||||
msgbuf[0] |= E1000_VF_SET_MULTICAST_OVERFLOW;
|
||||
mc_addr_count = 30;
|
||||
}
|
||||
|
||||
msgbuf[0] = E1000_VF_SET_MULTICAST;
|
||||
msgbuf[0] |= mc_addr_count << E1000_VT_MSGINFO_SHIFT;
|
||||
|
||||
for (i = 0; i < mc_addr_count; i++) {
|
||||
hash_value = e1000_hash_mc_addr_vf(hw, mc_addr_list);
|
||||
DEBUGOUT1("Hash value = 0x%03X\n", hash_value);
|
||||
hash_list[i] = hash_value & 0x0FFF;
|
||||
mc_addr_list += ETH_ADDR_LEN;
|
||||
}
|
||||
|
||||
mbx->ops.write_posted(hw, msgbuf, E1000_VFMAILBOX_SIZE, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_vfta_set_vf - Set/Unset vlan filter table address
|
||||
* @hw: pointer to the HW structure
|
||||
* @vid: determines the vfta register and bit to set/unset
|
||||
* @set: if TRUE then set bit, else clear bit
|
||||
**/
|
||||
void e1000_vfta_set_vf(struct e1000_hw *hw, u16 vid, bool set)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
u32 msgbuf[2];
|
||||
|
||||
msgbuf[0] = E1000_VF_SET_VLAN;
|
||||
msgbuf[1] = vid;
|
||||
/* Setting the 8 bit field MSG INFO to TRUE indicates "add" */
|
||||
if (set)
|
||||
msgbuf[0] |= E1000_VF_SET_VLAN_ADD;
|
||||
|
||||
mbx->ops.write_posted(hw, msgbuf, 2, 0);
|
||||
}
|
||||
|
||||
/** e1000_rlpml_set_vf - Set the maximum receive packet length
|
||||
* @hw: pointer to the HW structure
|
||||
* @max_size: value to assign to max frame size
|
||||
**/
|
||||
void e1000_rlpml_set_vf(struct e1000_hw *hw, u16 max_size)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
u32 msgbuf[2];
|
||||
|
||||
msgbuf[0] = E1000_VF_SET_LPE;
|
||||
msgbuf[1] = max_size;
|
||||
|
||||
mbx->ops.write_posted(hw, msgbuf, 2, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_promisc_set_vf - Set flags for Unicast or Multicast promisc
|
||||
* @hw: pointer to the HW structure
|
||||
* @uni: boolean indicating unicast promisc status
|
||||
* @multi: boolean indicating multicast promisc status
|
||||
**/
|
||||
s32 e1000_promisc_set_vf(struct e1000_hw *hw, enum e1000_promisc_type type)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
u32 msgbuf = E1000_VF_SET_PROMISC;
|
||||
s32 ret_val;
|
||||
|
||||
switch (type) {
|
||||
case e1000_promisc_multicast:
|
||||
msgbuf |= E1000_VF_SET_PROMISC_MULTICAST;
|
||||
break;
|
||||
case e1000_promisc_enabled:
|
||||
msgbuf |= E1000_VF_SET_PROMISC_MULTICAST;
|
||||
case e1000_promisc_unicast:
|
||||
msgbuf |= E1000_VF_SET_PROMISC_UNICAST;
|
||||
case e1000_promisc_disabled:
|
||||
break;
|
||||
default:
|
||||
return -E1000_ERR_MAC_INIT;
|
||||
}
|
||||
|
||||
ret_val = mbx->ops.write_posted(hw, &msgbuf, 1, 0);
|
||||
|
||||
if (!ret_val)
|
||||
ret_val = mbx->ops.read_posted(hw, &msgbuf, 1, 0);
|
||||
|
||||
if (!ret_val && !(msgbuf & E1000_VT_MSGTYPE_ACK))
|
||||
ret_val = -E1000_ERR_MAC_INIT;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_read_mac_addr_vf - Read device MAC address
|
||||
* @hw: pointer to the HW structure
|
||||
**/
|
||||
static s32 e1000_read_mac_addr_vf(struct e1000_hw *hw)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ETH_ADDR_LEN; i++)
|
||||
hw->mac.addr[i] = hw->mac.perm_addr[i];
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_check_for_link_vf - Check for link for a virtual interface
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Checks to see if the underlying PF is still talking to the VF and
|
||||
* if it is then it reports the link state to the hardware, otherwise
|
||||
* it reports link down and returns an error.
|
||||
**/
|
||||
static s32 e1000_check_for_link_vf(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
struct e1000_mac_info *mac = &hw->mac;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u32 in_msg = 0;
|
||||
|
||||
DEBUGFUNC("e1000_check_for_link_vf");
|
||||
|
||||
/*
|
||||
* We only want to run this if there has been a rst asserted.
|
||||
* in this case that could mean a link change, device reset,
|
||||
* or a virtual function reset
|
||||
*/
|
||||
|
||||
/* If we were hit with a reset drop the link */
|
||||
if (!mbx->ops.check_for_rst(hw, 0))
|
||||
mac->get_link_status = TRUE;
|
||||
|
||||
if (!mac->get_link_status)
|
||||
goto out;
|
||||
|
||||
/* if link status is down no point in checking to see if pf is up */
|
||||
if (!(E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU))
|
||||
goto out;
|
||||
|
||||
/* if the read failed it could just be a mailbox collision, best wait
|
||||
* until we are called again and don't report an error */
|
||||
if (mbx->ops.read(hw, &in_msg, 1, 0))
|
||||
goto out;
|
||||
|
||||
/* if incoming message isn't clear to send we are waiting on response */
|
||||
if (!(in_msg & E1000_VT_MSGTYPE_CTS)) {
|
||||
/* message is not CTS and is NACK we have lost CTS status */
|
||||
if (in_msg & E1000_VT_MSGTYPE_NACK)
|
||||
ret_val = -E1000_ERR_MAC_INIT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* at this point we know the PF is talking to us, check and see if
|
||||
* we are still accepting timeout or if we had a timeout failure.
|
||||
* if we failed then we will need to reinit */
|
||||
if (!mbx->timeout) {
|
||||
ret_val = -E1000_ERR_MAC_INIT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* if we passed all the tests above then the link is up and we no
|
||||
* longer need to check for link */
|
||||
mac->get_link_status = FALSE;
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
291
sys/dev/e1000/e1000_vf.h
Normal file
291
sys/dev/e1000/e1000_vf.h
Normal file
@ -0,0 +1,291 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2010, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the Intel Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
******************************************************************************/
|
||||
/*$FreeBSD$*/
|
||||
|
||||
#ifndef _E1000_VF_H_
|
||||
#define _E1000_VF_H_
|
||||
|
||||
#include "e1000_osdep.h"
|
||||
#include "e1000_regs.h"
|
||||
#include "e1000_defines.h"
|
||||
|
||||
struct e1000_hw;
|
||||
|
||||
#define E1000_DEV_ID_82576_VF 0x10CA
|
||||
|
||||
#define E1000_VF_INIT_TIMEOUT 200 /* Number of retries to clear RSTI */
|
||||
|
||||
/* Additional Descriptor Control definitions */
|
||||
#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Tx Queue */
|
||||
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
|
||||
|
||||
/* SRRCTL bit definitions */
|
||||
#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
|
||||
#define E1000_SRRCTL_BSIZEHDRSIZE_MASK 0x00000F00
|
||||
#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
|
||||
#define E1000_SRRCTL_DESCTYPE_LEGACY 0x00000000
|
||||
#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
|
||||
#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT 0x04000000
|
||||
#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
|
||||
#define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION 0x06000000
|
||||
#define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000
|
||||
#define E1000_SRRCTL_DESCTYPE_MASK 0x0E000000
|
||||
#define E1000_SRRCTL_DROP_EN 0x80000000
|
||||
|
||||
#define E1000_SRRCTL_BSIZEPKT_MASK 0x0000007F
|
||||
#define E1000_SRRCTL_BSIZEHDR_MASK 0x00003F00
|
||||
|
||||
/* Interrupt Defines */
|
||||
#define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */
|
||||
#define E1000_EITR(_n) (0x01680 + ((_n) << 2))
|
||||
#define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */
|
||||
#define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */
|
||||
#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */
|
||||
#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */
|
||||
#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */
|
||||
#define E1000_IVAR0 0x01700 /* Interrupt Vector Allocation (array) - RW */
|
||||
#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */
|
||||
#define E1000_IVAR_VALID 0x80
|
||||
|
||||
/* Receive Descriptor - Advanced */
|
||||
union e1000_adv_rx_desc {
|
||||
struct {
|
||||
u64 pkt_addr; /* Packet buffer address */
|
||||
u64 hdr_addr; /* Header buffer address */
|
||||
} read;
|
||||
struct {
|
||||
struct {
|
||||
union {
|
||||
u32 data;
|
||||
struct {
|
||||
u16 pkt_info; /* RSS type, Packet type */
|
||||
u16 hdr_info; /* Split Header,
|
||||
* header buffer length */
|
||||
} hs_rss;
|
||||
} lo_dword;
|
||||
union {
|
||||
u32 rss; /* RSS Hash */
|
||||
struct {
|
||||
u16 ip_id; /* IP id */
|
||||
u16 csum; /* Packet Checksum */
|
||||
} csum_ip;
|
||||
} hi_dword;
|
||||
} lower;
|
||||
struct {
|
||||
u32 status_error; /* ext status/error */
|
||||
u16 length; /* Packet length */
|
||||
u16 vlan; /* VLAN tag */
|
||||
} upper;
|
||||
} wb; /* writeback */
|
||||
};
|
||||
|
||||
#define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0
|
||||
#define E1000_RXDADV_HDRBUFLEN_SHIFT 5
|
||||
|
||||
/* Transmit Descriptor - Advanced */
|
||||
union e1000_adv_tx_desc {
|
||||
struct {
|
||||
u64 buffer_addr; /* Address of descriptor's data buf */
|
||||
u32 cmd_type_len;
|
||||
u32 olinfo_status;
|
||||
} read;
|
||||
struct {
|
||||
u64 rsvd; /* Reserved */
|
||||
u32 nxtseq_seed;
|
||||
u32 status;
|
||||
} wb;
|
||||
};
|
||||
|
||||
/* Adv Transmit Descriptor Config Masks */
|
||||
#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */
|
||||
#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
|
||||
#define E1000_ADVTXD_DCMD_EOP 0x01000000 /* End of Packet */
|
||||
#define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
|
||||
#define E1000_ADVTXD_DCMD_RS 0x08000000 /* Report Status */
|
||||
#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */
|
||||
#define E1000_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */
|
||||
#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
|
||||
#define E1000_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
|
||||
|
||||
/* Context descriptors */
|
||||
struct e1000_adv_tx_context_desc {
|
||||
u32 vlan_macip_lens;
|
||||
u32 seqnum_seed;
|
||||
u32 type_tucmd_mlhl;
|
||||
u32 mss_l4len_idx;
|
||||
};
|
||||
|
||||
#define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
|
||||
#define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
|
||||
#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
|
||||
#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
|
||||
#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
|
||||
|
||||
enum e1000_mac_type {
|
||||
e1000_undefined = 0,
|
||||
e1000_vfadapt,
|
||||
e1000_num_macs /* List is 1-based, so subtract 1 for TRUE count. */
|
||||
};
|
||||
|
||||
struct e1000_vf_stats {
|
||||
u64 base_gprc;
|
||||
u64 base_gptc;
|
||||
u64 base_gorc;
|
||||
u64 base_gotc;
|
||||
u64 base_mprc;
|
||||
u64 base_gotlbc;
|
||||
u64 base_gptlbc;
|
||||
u64 base_gorlbc;
|
||||
u64 base_gprlbc;
|
||||
|
||||
u32 last_gprc;
|
||||
u32 last_gptc;
|
||||
u32 last_gorc;
|
||||
u32 last_gotc;
|
||||
u32 last_mprc;
|
||||
u32 last_gotlbc;
|
||||
u32 last_gptlbc;
|
||||
u32 last_gorlbc;
|
||||
u32 last_gprlbc;
|
||||
|
||||
u64 gprc;
|
||||
u64 gptc;
|
||||
u64 gorc;
|
||||
u64 gotc;
|
||||
u64 mprc;
|
||||
u64 gotlbc;
|
||||
u64 gptlbc;
|
||||
u64 gorlbc;
|
||||
u64 gprlbc;
|
||||
};
|
||||
|
||||
#include "e1000_mbx.h"
|
||||
|
||||
struct e1000_mac_operations {
|
||||
/* Function pointers for the MAC. */
|
||||
s32 (*init_params)(struct e1000_hw *);
|
||||
s32 (*check_for_link)(struct e1000_hw *);
|
||||
void (*clear_vfta)(struct e1000_hw *);
|
||||
s32 (*get_bus_info)(struct e1000_hw *);
|
||||
s32 (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
|
||||
void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);
|
||||
s32 (*reset_hw)(struct e1000_hw *);
|
||||
s32 (*init_hw)(struct e1000_hw *);
|
||||
s32 (*setup_link)(struct e1000_hw *);
|
||||
void (*write_vfta)(struct e1000_hw *, u32, u32);
|
||||
void (*rar_set)(struct e1000_hw *, u8*, u32);
|
||||
s32 (*read_mac_addr)(struct e1000_hw *);
|
||||
};
|
||||
|
||||
struct e1000_mac_info {
|
||||
struct e1000_mac_operations ops;
|
||||
u8 addr[6];
|
||||
u8 perm_addr[6];
|
||||
|
||||
enum e1000_mac_type type;
|
||||
|
||||
u16 mta_reg_count;
|
||||
u16 rar_entry_count;
|
||||
|
||||
bool get_link_status;
|
||||
};
|
||||
|
||||
struct e1000_mbx_operations {
|
||||
s32 (*init_params)(struct e1000_hw *hw);
|
||||
s32 (*read)(struct e1000_hw *, u32 *, u16, u16);
|
||||
s32 (*write)(struct e1000_hw *, u32 *, u16, u16);
|
||||
s32 (*read_posted)(struct e1000_hw *, u32 *, u16, u16);
|
||||
s32 (*write_posted)(struct e1000_hw *, u32 *, u16, u16);
|
||||
s32 (*check_for_msg)(struct e1000_hw *, u16);
|
||||
s32 (*check_for_ack)(struct e1000_hw *, u16);
|
||||
s32 (*check_for_rst)(struct e1000_hw *, u16);
|
||||
};
|
||||
|
||||
struct e1000_mbx_stats {
|
||||
u32 msgs_tx;
|
||||
u32 msgs_rx;
|
||||
|
||||
u32 acks;
|
||||
u32 reqs;
|
||||
u32 rsts;
|
||||
};
|
||||
|
||||
struct e1000_mbx_info {
|
||||
struct e1000_mbx_operations ops;
|
||||
struct e1000_mbx_stats stats;
|
||||
u32 timeout;
|
||||
u32 usec_delay;
|
||||
u16 size;
|
||||
};
|
||||
|
||||
struct e1000_dev_spec_vf {
|
||||
u32 vf_number;
|
||||
u32 v2p_mailbox;
|
||||
};
|
||||
|
||||
struct e1000_hw {
|
||||
void *back;
|
||||
|
||||
u8 *hw_addr;
|
||||
u8 *flash_address;
|
||||
unsigned long io_base;
|
||||
|
||||
struct e1000_mac_info mac;
|
||||
struct e1000_mbx_info mbx;
|
||||
|
||||
union {
|
||||
struct e1000_dev_spec_vf vf;
|
||||
} dev_spec;
|
||||
|
||||
u16 device_id;
|
||||
u16 subsystem_vendor_id;
|
||||
u16 subsystem_device_id;
|
||||
u16 vendor_id;
|
||||
|
||||
u8 revision_id;
|
||||
};
|
||||
|
||||
enum e1000_promisc_type {
|
||||
e1000_promisc_disabled = 0, /* all promisc modes disabled */
|
||||
e1000_promisc_unicast = 1, /* unicast promiscuous enabled */
|
||||
e1000_promisc_multicast = 2, /* multicast promiscuous enabled */
|
||||
e1000_promisc_enabled = 3, /* both uni and multicast promisc */
|
||||
e1000_num_promisc_types
|
||||
};
|
||||
|
||||
/* These functions must be implemented by drivers */
|
||||
s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
|
||||
void e1000_vfta_set_vf(struct e1000_hw *, u16, bool);
|
||||
void e1000_rlpml_set_vf(struct e1000_hw *, u16);
|
||||
s32 e1000_promisc_set_vf(struct e1000_hw *, enum e1000_promisc_type);
|
||||
#endif /* _E1000_VF_H_ */
|
@ -4853,7 +4853,6 @@ igb_update_stats_counters(struct adapter *adapter)
|
||||
stats->cexterr += E1000_READ_REG(hw, E1000_CEXTERR);
|
||||
stats->tsctc += E1000_READ_REG(hw, E1000_TSCTC);
|
||||
stats->tsctfc += E1000_READ_REG(hw, E1000_TSCTFC);
|
||||
ifp = adapter->ifp;
|
||||
|
||||
ifp = adapter->ifp;
|
||||
ifp->if_collisions = stats->colc;
|
||||
@ -4875,7 +4874,7 @@ igb_update_stats_counters(struct adapter *adapter)
|
||||
adapter->packet_buf_alloc_tx =
|
||||
((E1000_READ_REG(hw, E1000_PBA) & 0xffff0000) >> 16);
|
||||
adapter->packet_buf_alloc_rx =
|
||||
((E1000_READ_REG(hw, E1000_PBA) & 0xffff);
|
||||
(E1000_READ_REG(hw, E1000_PBA) & 0xffff);
|
||||
}
|
||||
|
||||
|
||||
@ -4943,7 +4942,7 @@ igb_add_hw_stats(struct adapter *adapter)
|
||||
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
|
||||
struct sysctl_oid *tree = device_get_sysctl_tree(dev);
|
||||
struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
|
||||
struct e1000_hw_stats *stats = &adapter->stats;
|
||||
struct e1000_hw_stats *stats = adapter->stats;
|
||||
|
||||
struct sysctl_oid *stat_node, *queue_node, *int_node, *host_node;
|
||||
struct sysctl_oid_list *stat_list, *queue_list, *int_list, *host_list;
|
||||
@ -4994,14 +4993,10 @@ igb_add_hw_stats(struct adapter *adapter)
|
||||
queue_list = SYSCTL_CHILDREN(queue_node);
|
||||
|
||||
SYSCTL_ADD_UINT(ctx, queue_list, OID_AUTO, "txd_head",
|
||||
CTLFLAG_RD,
|
||||
E1000_READ_REG(&adapter->hw,
|
||||
E1000_TDH(txr->me)), 0,
|
||||
CTLFLAG_RD, &txr->tdh, 0,
|
||||
"Transmit Descriptor Head");
|
||||
SYSCTL_ADD_UINT(ctx, queue_list, OID_AUTO, "txd_tail",
|
||||
CTLFLAG_RD,
|
||||
E1000_READ_REG(&adapter->hw,
|
||||
E1000_TDT(txr->me))), 0,
|
||||
CTLFLAG_RD, &txr->tdt, 0,
|
||||
"Transmit Descriptor Tail");
|
||||
SYSCTL_ADD_QUAD(ctx, queue_list, OID_AUTO, "no_desc_avail",
|
||||
CTLFLAG_RD, &txr->no_desc_avail,
|
||||
@ -5056,19 +5051,19 @@ igb_add_hw_stats(struct adapter *adapter)
|
||||
*/
|
||||
if (adapter->hw.mac.type == e1000_vfadapt) {
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_pkts_recvd",
|
||||
CTLFLAG_RD, &adapter->stats.gprc,
|
||||
CTLFLAG_RD, &stats->gprc,
|
||||
"Good Packets Received");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_pkts_txd",
|
||||
CTLFLAG_RD, &adapter->stats.gptc,
|
||||
CTLFLAG_RD, &stats->gptc,
|
||||
"Good Packets Transmitted");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_octets_recvd",
|
||||
CTLFLAG_RD, &adapter->stats.gorc,
|
||||
CTLFLAG_RD, &stats->gorc,
|
||||
"Good Octets Received");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_octest_txd",
|
||||
CTLFLAG_RD, &adapter->stats.gotc,
|
||||
CTLFLAG_RD, &stats->gotc,
|
||||
"Good Octest Transmitted");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_recvd",
|
||||
CTLFLAG_RD, &adapter->stats.mprc,
|
||||
CTLFLAG_RD, &stats->mprc,
|
||||
"Multicast Packets Received");
|
||||
return;
|
||||
}
|
||||
@ -5089,44 +5084,44 @@ igb_add_hw_stats(struct adapter *adapter)
|
||||
CTLFLAG_RD, &stats->colc,
|
||||
"Collision Count");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "symbol_errors",
|
||||
CTLFLAG_RD, &adapter->stats.symerrs,
|
||||
CTLFLAG_RD, &stats->symerrs,
|
||||
"Symbol Errors");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "sequence_errors",
|
||||
CTLFLAG_RD, &adapter->stats.sec,
|
||||
CTLFLAG_RD, &stats->sec,
|
||||
"Sequence Errors");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "defer_count",
|
||||
CTLFLAG_RD, &adapter->stats.dc,
|
||||
CTLFLAG_RD, &stats->dc,
|
||||
"Defer Count");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "missed_packets",
|
||||
CTLFLAG_RD, &adapter->stats.mpc,
|
||||
CTLFLAG_RD, &stats->mpc,
|
||||
"Missed Packets");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_no_buff",
|
||||
CTLFLAG_RD, &adapter->stats.rnbc,
|
||||
CTLFLAG_RD, &stats->rnbc,
|
||||
"Receive No Buffers");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_undersize",
|
||||
CTLFLAG_RD, &adapter->stats.ruc,
|
||||
CTLFLAG_RD, &stats->ruc,
|
||||
"Receive Undersize");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_fragmented",
|
||||
CTLFLAG_RD, &adapter->stats.rfc,
|
||||
CTLFLAG_RD, &stats->rfc,
|
||||
"Fragmented Packets Received ");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_oversize",
|
||||
CTLFLAG_RD, &adapter->stats.roc,
|
||||
CTLFLAG_RD, &stats->roc,
|
||||
"Oversized Packets Received");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_jabber",
|
||||
CTLFLAG_RD, &adapter->stats.rjc,
|
||||
CTLFLAG_RD, &stats->rjc,
|
||||
"Recevied Jabber");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_errs",
|
||||
CTLFLAG_RD, &adapter->stats.rxerrc,
|
||||
CTLFLAG_RD, &stats->rxerrc,
|
||||
"Receive Errors");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "crc_errs",
|
||||
CTLFLAG_RD, &adapter->stats.crcerrs,
|
||||
CTLFLAG_RD, &stats->crcerrs,
|
||||
"CRC errors");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "alignment_errs",
|
||||
CTLFLAG_RD, &adapter->stats.algnerrc,
|
||||
CTLFLAG_RD, &stats->algnerrc,
|
||||
"Alignment Errors");
|
||||
/* On 82575 these are collision counts */
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "coll_ext_errs",
|
||||
CTLFLAG_RD, &adapter->stats.cexterr,
|
||||
CTLFLAG_RD, &stats->cexterr,
|
||||
"Collision/Carrier extension errors");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_overruns",
|
||||
CTLFLAG_RD, &adapter->rx_overruns,
|
||||
@ -5135,91 +5130,91 @@ igb_add_hw_stats(struct adapter *adapter)
|
||||
CTLFLAG_RD, &adapter->watchdog_events,
|
||||
"Watchdog timeouts");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "xon_recvd",
|
||||
CTLFLAG_RD, &adapter->stats.xonrxc,
|
||||
CTLFLAG_RD, &stats->xonrxc,
|
||||
"XON Received");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "xon_txd",
|
||||
CTLFLAG_RD, &adapter->stats.xontxc,
|
||||
CTLFLAG_RD, &stats->xontxc,
|
||||
"XON Transmitted");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "xoff_recvd",
|
||||
CTLFLAG_RD, &adapter->stats.xoffrxc,
|
||||
CTLFLAG_RD, &stats->xoffrxc,
|
||||
"XOFF Received");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "xoff_txd",
|
||||
CTLFLAG_RD, &adapter->stats.xofftxc,
|
||||
CTLFLAG_RD, &stats->xofftxc,
|
||||
"XOFF Transmitted");
|
||||
/* Packet Reception Stats */
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "total_pkts_recvd",
|
||||
CTLFLAG_RD, &adapter->stats.tpr,
|
||||
CTLFLAG_RD, &stats->tpr,
|
||||
"Total Packets Received ");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_pkts_recvd",
|
||||
CTLFLAG_RD, &adapter->stats.gprc,
|
||||
CTLFLAG_RD, &stats->gprc,
|
||||
"Good Packets Received");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_recvd",
|
||||
CTLFLAG_RD, &adapter->stats.bprc,
|
||||
CTLFLAG_RD, &stats->bprc,
|
||||
"Broadcast Packets Received");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_recvd",
|
||||
CTLFLAG_RD, &adapter->stats.mprc,
|
||||
CTLFLAG_RD, &stats->mprc,
|
||||
"Multicast Packets Received");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_64",
|
||||
CTLFLAG_RD, &adapter->stats.prc64,
|
||||
CTLFLAG_RD, &stats->prc64,
|
||||
"64 byte frames received ");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_65_127",
|
||||
CTLFLAG_RD, &adapter->stats.prc127,
|
||||
CTLFLAG_RD, &stats->prc127,
|
||||
"65-127 byte frames received");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_128_255",
|
||||
CTLFLAG_RD, &adapter->stats.prc255,
|
||||
CTLFLAG_RD, &stats->prc255,
|
||||
"128-255 byte frames received");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_256_511",
|
||||
CTLFLAG_RD, &adapter->stats.prc511,
|
||||
CTLFLAG_RD, &stats->prc511,
|
||||
"256-511 byte frames received");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_512_1023",
|
||||
CTLFLAG_RD, &adapter->stats.prc1023,
|
||||
CTLFLAG_RD, &stats->prc1023,
|
||||
"512-1023 byte frames received");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_1024_1522",
|
||||
CTLFLAG_RD, &adapter->stats.prc1522,
|
||||
CTLFLAG_RD, &stats->prc1522,
|
||||
"1023-1522 byte frames received");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_octets_recvd",
|
||||
CTLFLAG_RD, &adapter->stats.gorc,
|
||||
CTLFLAG_RD, &stats->gorc,
|
||||
"Good Octets Received");
|
||||
|
||||
/* Packet Transmission Stats */
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_octest_txd",
|
||||
CTLFLAG_RD, &adapter->stats.gotc,
|
||||
CTLFLAG_RD, &stats->gotc,
|
||||
"Good Octest Transmitted");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "total_pkts_txd",
|
||||
CTLFLAG_RD, &adapter->stats.tpt,
|
||||
CTLFLAG_RD, &stats->tpt,
|
||||
"Total Packets Transmitted");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_pkts_txd",
|
||||
CTLFLAG_RD, &adapter->stats.gptc,
|
||||
CTLFLAG_RD, &stats->gptc,
|
||||
"Good Packets Transmitted");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_txd",
|
||||
CTLFLAG_RD, &adapter->stats.bptc,
|
||||
CTLFLAG_RD, &stats->bptc,
|
||||
"Broadcast Packets Transmitted");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_txd",
|
||||
CTLFLAG_RD, &adapter->stats.mptc,
|
||||
CTLFLAG_RD, &stats->mptc,
|
||||
"Multicast Packets Transmitted");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_64",
|
||||
CTLFLAG_RD, &adapter->stats.ptc64,
|
||||
CTLFLAG_RD, &stats->ptc64,
|
||||
"64 byte frames transmitted ");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_65_127",
|
||||
CTLFLAG_RD, &adapter->stats.ptc127,
|
||||
CTLFLAG_RD, &stats->ptc127,
|
||||
"65-127 byte frames transmitted");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_128_255",
|
||||
CTLFLAG_RD, &adapter->stats.ptc255,
|
||||
CTLFLAG_RD, &stats->ptc255,
|
||||
"128-255 byte frames transmitted");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_256_511",
|
||||
CTLFLAG_RD, &adapter->stats.ptc511,
|
||||
CTLFLAG_RD, &stats->ptc511,
|
||||
"256-511 byte frames transmitted");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_512_1023",
|
||||
CTLFLAG_RD, &adapter->stats.ptc1023,
|
||||
CTLFLAG_RD, &stats->ptc1023,
|
||||
"512-1023 byte frames transmitted");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_1024_1522",
|
||||
CTLFLAG_RD, &adapter->stats.ptc1522,
|
||||
CTLFLAG_RD, &stats->ptc1522,
|
||||
"1024-1522 byte frames transmitted");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tso_txd",
|
||||
CTLFLAG_RD, &adapter->stats.tsctc,
|
||||
CTLFLAG_RD, &stats->tsctc,
|
||||
"TSO Contexts Transmitted");
|
||||
SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tso_ctx_fail",
|
||||
CTLFLAG_RD, &adapter->stats.tsctfc,
|
||||
CTLFLAG_RD, &stats->tsctfc,
|
||||
"TSO Contexts Failed");
|
||||
|
||||
|
||||
@ -5230,39 +5225,39 @@ igb_add_hw_stats(struct adapter *adapter)
|
||||
int_list = SYSCTL_CHILDREN(int_node);
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "asserts",
|
||||
CTLFLAG_RD, &adapter->stats.iac,
|
||||
CTLFLAG_RD, &stats->iac,
|
||||
"Interrupt Assertion Count");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "rx_pkt_timer",
|
||||
CTLFLAG_RD, &adapter->stats.icrxptc,
|
||||
CTLFLAG_RD, &stats->icrxptc,
|
||||
"Interrupt Cause Rx Pkt Timer Expire Count");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "rx_abs_timer",
|
||||
CTLFLAG_RD, &adapter->stats.icrxatc,
|
||||
CTLFLAG_RD, &stats->icrxatc,
|
||||
"Interrupt Cause Rx Abs Timer Expire Count");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "tx_pkt_timer",
|
||||
CTLFLAG_RD, &adapter->stats.ictxptc,
|
||||
CTLFLAG_RD, &stats->ictxptc,
|
||||
"Interrupt Cause Tx Pkt Timer Expire Count");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "tx_abs_timer",
|
||||
CTLFLAG_RD, &adapter->stats.ictxatc,
|
||||
CTLFLAG_RD, &stats->ictxatc,
|
||||
"Interrupt Cause Tx Abs Timer Expire Count");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "tx_queue_empty",
|
||||
CTLFLAG_RD, &adapter->stats.ictxqec,
|
||||
CTLFLAG_RD, &stats->ictxqec,
|
||||
"Interrupt Cause Tx Queue Empty Count");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "tx_queue_min_thresh",
|
||||
CTLFLAG_RD, &adapter->stats.ictxqmtc,
|
||||
CTLFLAG_RD, &stats->ictxqmtc,
|
||||
"Interrupt Cause Tx Queue Min Thresh Count");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "rx_desc_min_thresh",
|
||||
CTLFLAG_RD, &adapter->stats.icrxdmtc,
|
||||
CTLFLAG_RD, &stats->icrxdmtc,
|
||||
"Interrupt Cause Rx Desc Min Thresh Count");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, int_list, OID_AUTO, "rx_overrun",
|
||||
CTLFLAG_RD, &adapter->stats.icrxoc,
|
||||
CTLFLAG_RD, &stats->icrxoc,
|
||||
"Interrupt Cause Receiver Overrun Count");
|
||||
|
||||
/* Host to Card Stats */
|
||||
@ -5274,51 +5269,51 @@ igb_add_hw_stats(struct adapter *adapter)
|
||||
host_list = SYSCTL_CHILDREN(host_node);
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "breaker_tx_pkt",
|
||||
CTLFLAG_RD, &adapter->stats.cbtmpc,
|
||||
CTLFLAG_RD, &stats->cbtmpc,
|
||||
"Circuit Breaker Tx Packet Count");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "host_tx_pkt_discard",
|
||||
CTLFLAG_RD, &adapter->stats.htdpmc,
|
||||
CTLFLAG_RD, &stats->htdpmc,
|
||||
"Host Transmit Discarded Packets");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "rx_pkt",
|
||||
CTLFLAG_RD, &adapter->stats.rpthc,
|
||||
CTLFLAG_RD, &stats->rpthc,
|
||||
"Rx Packets To Host");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "breaker_rx_pkts",
|
||||
CTLFLAG_RD, &adapter->stats.cbrmpc,
|
||||
CTLFLAG_RD, &stats->cbrmpc,
|
||||
"Circuit Breaker Rx Packet Count");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "breaker_rx_pkt_drop",
|
||||
CTLFLAG_RD, &adapter->stats.cbrdpc,
|
||||
CTLFLAG_RD, &stats->cbrdpc,
|
||||
"Circuit Breaker Rx Dropped Count");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "tx_good_pkt",
|
||||
CTLFLAG_RD, &adapter->stats.hgptc,
|
||||
CTLFLAG_RD, &stats->hgptc,
|
||||
"Host Good Packets Tx Count");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "breaker_tx_pkt_drop",
|
||||
CTLFLAG_RD, &adapter->stats.htcbdpc,
|
||||
CTLFLAG_RD, &stats->htcbdpc,
|
||||
"Host Tx Circuit Breaker Dropped Count");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "rx_good_bytes",
|
||||
CTLFLAG_RD, &adapter->stats.hgorc,
|
||||
CTLFLAG_RD, &stats->hgorc,
|
||||
"Host Good Octets Received Count");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "tx_good_bytes",
|
||||
CTLFLAG_RD, &adapter->stats.hgotc,
|
||||
CTLFLAG_RD, &stats->hgotc,
|
||||
"Host Good Octets Transmit Count");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "length_errors",
|
||||
CTLFLAG_RD, &adapter->stats.lenerrs,
|
||||
CTLFLAG_RD, &stats->lenerrs,
|
||||
"Length Errors");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "serdes_violation_pkt",
|
||||
CTLFLAG_RD, &adapter->stats.scvpc,
|
||||
CTLFLAG_RD, &stats->scvpc,
|
||||
"SerDes/SGMII Code Violation Pkt Count");
|
||||
|
||||
SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "header_redir_missed",
|
||||
CTLFLAG_RD, &adapter->stats.hrmpc,
|
||||
CTLFLAG_RD, &stats->hrmpc,
|
||||
"Header Redirection Missed Packet Count");
|
||||
}
|
||||
|
||||
|
@ -316,6 +316,8 @@ struct tx_ring {
|
||||
|
||||
bool watchdog_check;
|
||||
int watchdog_time;
|
||||
int tdt;
|
||||
int tdh;
|
||||
u64 no_desc_avail;
|
||||
u64 tx_packets;
|
||||
};
|
||||
@ -348,6 +350,8 @@ struct rx_ring {
|
||||
|
||||
u32 bytes;
|
||||
u32 packets;
|
||||
int rdt;
|
||||
int rdh;
|
||||
|
||||
/* Soft stats */
|
||||
u64 rx_split_packets;
|
||||
@ -504,6 +508,18 @@ struct igb_rx_buf {
|
||||
cur |= new; \
|
||||
}
|
||||
|
||||
#if __FreeBSD_version < 800504
|
||||
static __inline int
|
||||
drbr_needs_enqueue(struct ifnet *ifp, struct buf_ring *br)
|
||||
{
|
||||
#ifdef ALTQ
|
||||
if (ALTQ_IS_ENABLED(&ifp->if_snd))
|
||||
return (1);
|
||||
#endif
|
||||
return (!buf_ring_empty(br));
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _IGB_H_DEFINED_ */
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@ SRCS += if_igb.c $(SHARED_SRCS)
|
||||
SHARED_SRCS = e1000_api.c e1000_phy.c e1000_nvm.c e1000_mac.c e1000_manage.c
|
||||
SHARED_SRCS += e1000_80003es2lan.c e1000_82542.c e1000_82541.c e1000_82543.c
|
||||
SHARED_SRCS += e1000_82540.c e1000_ich8lan.c e1000_82571.c e1000_osdep.c
|
||||
SHARED_SRCS += e1000_82575.c
|
||||
SHARED_SRCS += e1000_82575.c e1000_vf.c e1000_mbx.c
|
||||
|
||||
CFLAGS += -I${.CURDIR}/../../dev/e1000 -DSMP
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user