mirror of
https://github.com/xcat2/xNBA.git
synced 2025-04-15 09:39:26 +00:00
[igbvf] Add igbvf driver
Driver for Intel 82576 based virtual functions, based on Intel source code available at: http://sourceforge.net/projects/e1000 (igbvf-1.0.7) Based on initial port from Eric Keller <ekeller@princeton.edu>. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
parent
708c5060b9
commit
c080de1a60
@ -64,6 +64,7 @@ SRCDIRS += drivers/net
|
||||
SRCDIRS += drivers/net/e1000
|
||||
SRCDIRS += drivers/net/e1000e
|
||||
SRCDIRS += drivers/net/igb
|
||||
SRCDIRS += drivers/net/igbvf
|
||||
SRCDIRS += drivers/net/phantom
|
||||
SRCDIRS += drivers/net/rtl818x
|
||||
SRCDIRS += drivers/net/ath5k
|
||||
|
375
src/drivers/net/igbvf/igbvf.h
Normal file
375
src/drivers/net/igbvf/igbvf.h
Normal file
@ -0,0 +1,375 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel(R) 82576 Virtual Function Linux driver
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
version 2, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
The full GNU General Public License is included in this distribution in
|
||||
the file called "COPYING".
|
||||
|
||||
Contact Information:
|
||||
Linux NICS <linux.nics@intel.com>
|
||||
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
|
||||
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
FILE_LICENCE ( GPL2_ONLY );
|
||||
|
||||
/* Linux PRO/1000 Ethernet Driver main header file */
|
||||
|
||||
#ifndef _IGBVF_H_
|
||||
#define _IGBVF_H_
|
||||
|
||||
#include "igbvf_vf.h"
|
||||
|
||||
/* Forward declarations */
|
||||
struct igbvf_info;
|
||||
struct igbvf_adapter;
|
||||
|
||||
/* Interrupt defines */
|
||||
#define IGBVF_START_ITR 648 /* ~6000 ints/sec */
|
||||
|
||||
/* Tx/Rx descriptor defines */
|
||||
#define IGBVF_DEFAULT_TXD 256
|
||||
#define IGBVF_MAX_TXD 4096
|
||||
#define IGBVF_MIN_TXD 80
|
||||
|
||||
#define IGBVF_DEFAULT_RXD 256
|
||||
#define IGBVF_MAX_RXD 4096
|
||||
#define IGBVF_MIN_RXD 80
|
||||
|
||||
#define IGBVF_MIN_ITR_USECS 10 /* 100000 irq/sec */
|
||||
#define IGBVF_MAX_ITR_USECS 10000 /* 100 irq/sec */
|
||||
|
||||
/* RX descriptor control thresholds.
|
||||
* PTHRESH - MAC will consider prefetch if it has fewer than this number of
|
||||
* descriptors available in its onboard memory.
|
||||
* Setting this to 0 disables RX descriptor prefetch.
|
||||
* HTHRESH - MAC will only prefetch if there are at least this many descriptors
|
||||
* available in host memory.
|
||||
* If PTHRESH is 0, this should also be 0.
|
||||
* WTHRESH - RX descriptor writeback threshold - MAC will delay writing back
|
||||
* descriptors until either it has this many to write back, or the
|
||||
* ITR timer expires.
|
||||
*/
|
||||
#define IGBVF_RX_PTHRESH 16
|
||||
#define IGBVF_RX_HTHRESH 8
|
||||
#define IGBVF_RX_WTHRESH 1
|
||||
|
||||
#define IGBVF_TX_PTHRESH 8
|
||||
#define IGBVF_TX_HTHRESH 1
|
||||
#define IGBVF_TX_WTHRESH 1
|
||||
|
||||
/* this is the size past which hardware will drop packets when setting LPE=0 */
|
||||
#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
|
||||
|
||||
#define IGBVF_FC_PAUSE_TIME 0x0680 /* 858 usec */
|
||||
|
||||
/* How many Tx Descriptors do we need to call netif_wake_queue ? */
|
||||
#define IGBVF_TX_QUEUE_WAKE 32
|
||||
/* How many Rx Buffers do we bundle into one write to the hardware ? */
|
||||
#define IGBVF_RX_BUFFER_WRITE 16 /* Must be power of 2 */
|
||||
|
||||
#define AUTO_ALL_MODES 0
|
||||
#define IGBVF_EEPROM_APME 0x0400
|
||||
|
||||
#define IGBVF_MNG_VLAN_NONE (-1)
|
||||
|
||||
enum igbvf_boards {
|
||||
board_vf,
|
||||
};
|
||||
|
||||
struct igbvf_queue_stats {
|
||||
u64 packets;
|
||||
u64 bytes;
|
||||
};
|
||||
|
||||
/*
|
||||
* wrappers around a pointer to a socket buffer,
|
||||
* so a DMA handle can be stored along with the buffer
|
||||
*/
|
||||
struct igbvf_buffer {
|
||||
dma_addr_t dma;
|
||||
dma_addr_t page_dma;
|
||||
struct sk_buff *skb;
|
||||
union {
|
||||
/* Tx */
|
||||
struct {
|
||||
unsigned long time_stamp;
|
||||
u16 length;
|
||||
u16 next_to_watch;
|
||||
};
|
||||
/* Rx */
|
||||
struct {
|
||||
struct page *page;
|
||||
unsigned int page_offset;
|
||||
};
|
||||
};
|
||||
struct page *page;
|
||||
};
|
||||
|
||||
struct igbvf_ring {
|
||||
struct igbvf_adapter *adapter; /* backlink */
|
||||
void *desc; /* pointer to ring memory */
|
||||
dma_addr_t dma; /* phys address of ring */
|
||||
unsigned int size; /* length of ring in bytes */
|
||||
unsigned int count; /* number of desc. in ring */
|
||||
|
||||
u16 next_to_use;
|
||||
u16 next_to_clean;
|
||||
|
||||
u16 head;
|
||||
u16 tail;
|
||||
|
||||
/* array of buffer information structs */
|
||||
struct igbvf_buffer *buffer_info;
|
||||
#if 0
|
||||
struct napi_struct napi;
|
||||
|
||||
char name[IFNAMSIZ + 5];
|
||||
#endif
|
||||
u32 eims_value;
|
||||
u32 itr_val;
|
||||
u16 itr_register;
|
||||
int set_itr;
|
||||
|
||||
struct sk_buff *rx_skb_top;
|
||||
|
||||
struct igbvf_queue_stats stats;
|
||||
};
|
||||
|
||||
/* board specific private data structure */
|
||||
struct igbvf_adapter {
|
||||
#if 0
|
||||
struct timer_list watchdog_timer;
|
||||
struct timer_list blink_timer;
|
||||
|
||||
struct work_struct reset_task;
|
||||
struct work_struct watchdog_task;
|
||||
|
||||
const struct igbvf_info *ei;
|
||||
|
||||
struct vlan_group *vlgrp;
|
||||
u32 bd_number;
|
||||
u32 rx_buffer_len;
|
||||
u32 polling_interval;
|
||||
u16 mng_vlan_id;
|
||||
u16 link_speed;
|
||||
u16 link_duplex;
|
||||
|
||||
spinlock_t tx_queue_lock; /* prevent concurrent tail updates */
|
||||
|
||||
/* track device up/down/testing state */
|
||||
unsigned long state;
|
||||
|
||||
/* Interrupt Throttle Rate */
|
||||
u32 itr;
|
||||
u32 itr_setting;
|
||||
u16 tx_itr;
|
||||
u16 rx_itr;
|
||||
|
||||
/*
|
||||
* Tx
|
||||
*/
|
||||
struct igbvf_ring *tx_ring /* One per active queue */
|
||||
____cacheline_aligned_in_smp;
|
||||
|
||||
unsigned long tx_queue_len;
|
||||
unsigned int restart_queue;
|
||||
u32 txd_cmd;
|
||||
|
||||
bool detect_tx_hung;
|
||||
u8 tx_timeout_factor;
|
||||
|
||||
unsigned int total_tx_bytes;
|
||||
unsigned int total_tx_packets;
|
||||
unsigned int total_rx_bytes;
|
||||
unsigned int total_rx_packets;
|
||||
|
||||
/* Tx stats */
|
||||
u32 tx_timeout_count;
|
||||
u32 tx_fifo_head;
|
||||
u32 tx_head_addr;
|
||||
u32 tx_fifo_size;
|
||||
u32 tx_dma_failed;
|
||||
|
||||
/*
|
||||
* Rx
|
||||
*/
|
||||
struct igbvf_ring *rx_ring;
|
||||
|
||||
/* Rx stats */
|
||||
u64 hw_csum_err;
|
||||
u64 hw_csum_good;
|
||||
u64 rx_hdr_split;
|
||||
u32 alloc_rx_buff_failed;
|
||||
u32 rx_dma_failed;
|
||||
|
||||
unsigned int rx_ps_hdr_size;
|
||||
u32 max_frame_size;
|
||||
u32 min_frame_size;
|
||||
|
||||
/* OS defined structs */
|
||||
struct net_device *netdev;
|
||||
struct pci_dev *pdev;
|
||||
struct net_device_stats net_stats;
|
||||
spinlock_t stats_lock; /* prevent concurrent stats updates */
|
||||
|
||||
/* structs defined in e1000_hw.h */
|
||||
struct e1000_hw hw;
|
||||
|
||||
/* The VF counters don't clear on read so we have to get a base
|
||||
* count on driver start up and always subtract that base on
|
||||
* on the first update, thus the flag..
|
||||
*/
|
||||
struct e1000_vf_stats stats;
|
||||
u64 zero_base;
|
||||
|
||||
struct igbvf_ring test_tx_ring;
|
||||
struct igbvf_ring test_rx_ring;
|
||||
u32 test_icr;
|
||||
|
||||
u32 msg_enable;
|
||||
struct msix_entry *msix_entries;
|
||||
int int_mode;
|
||||
u32 eims_enable_mask;
|
||||
u32 eims_other;
|
||||
u32 int_counter0;
|
||||
u32 int_counter1;
|
||||
|
||||
u32 eeprom_wol;
|
||||
u32 wol;
|
||||
u32 pba;
|
||||
|
||||
bool fc_autoneg;
|
||||
|
||||
unsigned long led_status;
|
||||
|
||||
unsigned int flags;
|
||||
unsigned long last_reset;
|
||||
u32 *config_space;
|
||||
#endif
|
||||
/* OS defined structs */
|
||||
struct net_device *netdev;
|
||||
struct pci_device *pdev;
|
||||
struct net_device_stats net_stats;
|
||||
|
||||
/* structs defined in e1000_hw.h */
|
||||
struct e1000_hw hw;
|
||||
|
||||
u32 min_frame_size;
|
||||
u32 max_frame_size;
|
||||
|
||||
u32 max_hw_frame_size;
|
||||
|
||||
#define NUM_TX_DESC 8
|
||||
#define NUM_RX_DESC 8
|
||||
|
||||
struct io_buffer *tx_iobuf[NUM_TX_DESC];
|
||||
struct io_buffer *rx_iobuf[NUM_RX_DESC];
|
||||
|
||||
union e1000_adv_tx_desc *tx_base;
|
||||
union e1000_adv_rx_desc *rx_base;
|
||||
|
||||
uint32_t tx_ring_size;
|
||||
uint32_t rx_ring_size;
|
||||
|
||||
uint32_t tx_head;
|
||||
uint32_t tx_tail;
|
||||
uint32_t tx_fill_ctr;
|
||||
|
||||
uint32_t rx_curr;
|
||||
|
||||
uint32_t ioaddr;
|
||||
uint32_t irqno;
|
||||
|
||||
uint32_t tx_int_delay;
|
||||
uint32_t tx_abs_int_delay;
|
||||
uint32_t txd_cmd;
|
||||
};
|
||||
|
||||
struct igbvf_info {
|
||||
enum e1000_mac_type mac;
|
||||
unsigned int flags;
|
||||
u32 pba;
|
||||
void (*init_ops)(struct e1000_hw *);
|
||||
s32 (*get_variants)(struct igbvf_adapter *);
|
||||
};
|
||||
|
||||
/* hardware capability, feature, and workaround flags */
|
||||
#define IGBVF_FLAG_RX_CSUM_DISABLED (1 << 0)
|
||||
|
||||
#define IGBVF_DESC_UNUSED(R) \
|
||||
((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
|
||||
(R)->next_to_clean - (R)->next_to_use - 1)
|
||||
|
||||
#define IGBVF_RX_DESC_ADV(R, i) \
|
||||
(&(((union e1000_adv_rx_desc *)((R).desc))[i]))
|
||||
#define IGBVF_TX_DESC_ADV(R, i) \
|
||||
(&(((union e1000_adv_tx_desc *)((R).desc))[i]))
|
||||
#define IGBVF_TX_CTXTDESC_ADV(R, i) \
|
||||
(&(((struct e1000_adv_tx_context_desc *)((R).desc))[i]))
|
||||
|
||||
enum igbvf_state_t {
|
||||
__IGBVF_TESTING,
|
||||
__IGBVF_RESETTING,
|
||||
__IGBVF_DOWN
|
||||
};
|
||||
|
||||
enum latency_range {
|
||||
lowest_latency = 0,
|
||||
low_latency = 1,
|
||||
bulk_latency = 2,
|
||||
latency_invalid = 255
|
||||
};
|
||||
|
||||
extern char igbvf_driver_name[];
|
||||
extern const char igbvf_driver_version[];
|
||||
|
||||
extern void igbvf_check_options(struct igbvf_adapter *adapter);
|
||||
extern void igbvf_set_ethtool_ops(struct net_device *netdev);
|
||||
#ifdef ETHTOOL_OPS_COMPAT
|
||||
extern int ethtool_ioctl(struct ifreq *ifr);
|
||||
#endif
|
||||
|
||||
extern int igbvf_up(struct igbvf_adapter *adapter);
|
||||
extern void igbvf_down(struct igbvf_adapter *adapter);
|
||||
extern void igbvf_reinit_locked(struct igbvf_adapter *adapter);
|
||||
extern void igbvf_reset(struct igbvf_adapter *adapter);
|
||||
extern int igbvf_setup_rx_resources(struct igbvf_adapter *adapter);
|
||||
extern int igbvf_setup_tx_resources(struct igbvf_adapter *adapter);
|
||||
extern void igbvf_free_rx_resources(struct igbvf_adapter *adapter);
|
||||
extern void igbvf_free_tx_resources(struct igbvf_adapter *adapter);
|
||||
extern void igbvf_update_stats(struct igbvf_adapter *adapter);
|
||||
extern void igbvf_set_interrupt_capability(struct igbvf_adapter *adapter);
|
||||
extern void igbvf_reset_interrupt_capability(struct igbvf_adapter *adapter);
|
||||
|
||||
extern unsigned int copybreak;
|
||||
|
||||
static inline u32 __er32(struct e1000_hw *hw, unsigned long reg)
|
||||
{
|
||||
return readl(hw->hw_addr + reg);
|
||||
}
|
||||
|
||||
static inline void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val)
|
||||
{
|
||||
writel(val, hw->hw_addr + reg);
|
||||
}
|
||||
#define er32(reg) E1000_READ_REG(hw, E1000_##reg)
|
||||
#define ew32(reg,val) E1000_WRITE_REG(hw, E1000_##reg, (val))
|
||||
#define e1e_flush() er32(STATUS)
|
||||
|
||||
#endif /* _IGBVF_H_ */
|
1395
src/drivers/net/igbvf/igbvf_defines.h
Normal file
1395
src/drivers/net/igbvf/igbvf_defines.h
Normal file
File diff suppressed because it is too large
Load Diff
955
src/drivers/net/igbvf/igbvf_main.c
Normal file
955
src/drivers/net/igbvf/igbvf_main.c
Normal file
@ -0,0 +1,955 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel(R) 82576 Virtual Function Linux driver
|
||||
Copyright(c) 2009 Intel Corporation.
|
||||
|
||||
Copyright(c) 2010 Eric Keller <ekeller@princeton.edu>
|
||||
Copyright(c) 2010 Red Hat Inc.
|
||||
Alex Williamson <alex.williamson@redhat.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
version 2, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
The full GNU General Public License is included in this distribution in
|
||||
the file called "COPYING".
|
||||
|
||||
Contact Information:
|
||||
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
|
||||
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
FILE_LICENCE ( GPL2_ONLY );
|
||||
|
||||
#include "igbvf.h"
|
||||
|
||||
/**
|
||||
* igbvf_setup_tx_resources - allocate Tx resources (Descriptors)
|
||||
*
|
||||
* @v adapter e1000 private structure
|
||||
*
|
||||
* @ret rc Returns 0 on success, negative on failure
|
||||
**/
|
||||
int igbvf_setup_tx_resources ( struct igbvf_adapter *adapter )
|
||||
{
|
||||
DBG ( "igbvf_setup_tx_resources\n" );
|
||||
|
||||
/* Allocate transmit descriptor ring memory.
|
||||
It must not cross a 64K boundary because of hardware errata #23
|
||||
so we use malloc_dma() requesting a 128 byte block that is
|
||||
128 byte aligned. This should guarantee that the memory
|
||||
allocated will not cross a 64K boundary, because 128 is an
|
||||
even multiple of 65536 ( 65536 / 128 == 512 ), so all possible
|
||||
allocations of 128 bytes on a 128 byte boundary will not
|
||||
cross 64K bytes.
|
||||
*/
|
||||
|
||||
adapter->tx_base =
|
||||
malloc_dma ( adapter->tx_ring_size, adapter->tx_ring_size );
|
||||
|
||||
if ( ! adapter->tx_base ) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset ( adapter->tx_base, 0, adapter->tx_ring_size );
|
||||
|
||||
DBG ( "adapter->tx_base = %#08lx\n", virt_to_bus ( adapter->tx_base ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_free_tx_resources - Free Tx Resources per Queue
|
||||
* @adapter: board private structure
|
||||
*
|
||||
* Free all transmit software resources
|
||||
**/
|
||||
void igbvf_free_tx_resources ( struct igbvf_adapter *adapter )
|
||||
{
|
||||
DBG ( "igbvf_free_tx_resources\n" );
|
||||
|
||||
free_dma ( adapter->tx_base, adapter->tx_ring_size );
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_free_rx_resources - Free Rx Resources
|
||||
* @adapter: board private structure
|
||||
*
|
||||
* Free all receive software resources
|
||||
**/
|
||||
void igbvf_free_rx_resources ( struct igbvf_adapter *adapter )
|
||||
{
|
||||
int i;
|
||||
|
||||
DBG ( "igbvf_free_rx_resources\n" );
|
||||
|
||||
free_dma ( adapter->rx_base, adapter->rx_ring_size );
|
||||
|
||||
for ( i = 0; i < NUM_RX_DESC; i++ ) {
|
||||
free_iob ( adapter->rx_iobuf[i] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_refill_rx_ring - allocate Rx io_buffers
|
||||
*
|
||||
* @v adapter e1000 private structure
|
||||
*
|
||||
* @ret rc Returns 0 on success, negative on failure
|
||||
**/
|
||||
static int igbvf_refill_rx_ring ( struct igbvf_adapter *adapter )
|
||||
{
|
||||
int i, rx_curr;
|
||||
int rc = 0;
|
||||
union e1000_adv_rx_desc *rx_curr_desc;
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
struct io_buffer *iob;
|
||||
|
||||
DBGP ("igbvf_refill_rx_ring\n");
|
||||
|
||||
for ( i = 0; i < NUM_RX_DESC; i++ ) {
|
||||
rx_curr = ( ( adapter->rx_curr + i ) % NUM_RX_DESC );
|
||||
rx_curr_desc = adapter->rx_base + rx_curr;
|
||||
|
||||
if ( rx_curr_desc->wb.upper.status_error & E1000_RXD_STAT_DD )
|
||||
continue;
|
||||
|
||||
if ( adapter->rx_iobuf[rx_curr] != NULL )
|
||||
continue;
|
||||
|
||||
DBG2 ( "Refilling rx desc %d\n", rx_curr );
|
||||
|
||||
iob = alloc_iob ( MAXIMUM_ETHERNET_VLAN_SIZE );
|
||||
adapter->rx_iobuf[rx_curr] = iob;
|
||||
|
||||
rx_curr_desc->wb.upper.status_error = 0;
|
||||
|
||||
if ( ! iob ) {
|
||||
DBG ( "alloc_iob failed\n" );
|
||||
rc = -ENOMEM;
|
||||
break;
|
||||
} else {
|
||||
rx_curr_desc->read.pkt_addr = virt_to_bus ( iob->data );
|
||||
rx_curr_desc->read.hdr_addr = 0;
|
||||
ew32 ( RDT(0), rx_curr );
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_irq_disable - Mask off interrupt generation on the NIC
|
||||
* @adapter: board private structure
|
||||
**/
|
||||
static void igbvf_irq_disable ( struct igbvf_adapter *adapter )
|
||||
{
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
|
||||
ew32 ( EIMC, ~0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_irq_enable - Enable default interrupt generation settings
|
||||
* @adapter: board private structure
|
||||
**/
|
||||
static void igbvf_irq_enable ( struct igbvf_adapter *adapter )
|
||||
{
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
|
||||
ew32 ( EIAC, IMS_ENABLE_MASK );
|
||||
ew32 ( EIAM, IMS_ENABLE_MASK );
|
||||
ew32 ( EIMS, IMS_ENABLE_MASK );
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_irq - enable or Disable interrupts
|
||||
*
|
||||
* @v adapter e1000 adapter
|
||||
* @v action requested interrupt action
|
||||
**/
|
||||
static void igbvf_irq ( struct net_device *netdev, int enable )
|
||||
{
|
||||
struct igbvf_adapter *adapter = netdev_priv ( netdev );
|
||||
|
||||
DBG ( "igbvf_irq\n" );
|
||||
|
||||
if ( enable ) {
|
||||
igbvf_irq_enable ( adapter );
|
||||
} else {
|
||||
igbvf_irq_disable ( adapter );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_process_tx_packets - process transmitted packets
|
||||
*
|
||||
* @v netdev network interface device structure
|
||||
**/
|
||||
static void igbvf_process_tx_packets ( struct net_device *netdev )
|
||||
{
|
||||
struct igbvf_adapter *adapter = netdev_priv ( netdev );
|
||||
uint32_t i;
|
||||
uint32_t tx_status;
|
||||
union e1000_adv_tx_desc *tx_curr_desc;
|
||||
|
||||
/* Check status of transmitted packets
|
||||
*/
|
||||
DBGP ( "process_tx_packets: tx_head = %d, tx_tail = %d\n", adapter->tx_head,
|
||||
adapter->tx_tail );
|
||||
|
||||
while ( ( i = adapter->tx_head ) != adapter->tx_tail ) {
|
||||
|
||||
tx_curr_desc = ( void * ) ( adapter->tx_base ) +
|
||||
( i * sizeof ( *adapter->tx_base ) );
|
||||
|
||||
tx_status = tx_curr_desc->wb.status;
|
||||
DBG ( " tx_curr_desc = %#08lx\n", virt_to_bus ( tx_curr_desc ) );
|
||||
DBG ( " tx_status = %#08x\n", tx_status );
|
||||
|
||||
/* if the packet at tx_head is not owned by hardware it is for us */
|
||||
if ( ! ( tx_status & E1000_TXD_STAT_DD ) )
|
||||
break;
|
||||
|
||||
DBG ( "Sent packet. tx_head: %d tx_tail: %d tx_status: %#08x\n",
|
||||
adapter->tx_head, adapter->tx_tail, tx_status );
|
||||
|
||||
netdev_tx_complete ( netdev, adapter->tx_iobuf[i] );
|
||||
DBG ( "Success transmitting packet, tx_status: %#08x\n",
|
||||
tx_status );
|
||||
|
||||
/* Decrement count of used descriptors, clear this descriptor
|
||||
*/
|
||||
adapter->tx_fill_ctr--;
|
||||
memset ( tx_curr_desc, 0, sizeof ( *tx_curr_desc ) );
|
||||
|
||||
adapter->tx_head = ( adapter->tx_head + 1 ) % NUM_TX_DESC;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_process_rx_packets - process received packets
|
||||
*
|
||||
* @v netdev network interface device structure
|
||||
**/
|
||||
static void igbvf_process_rx_packets ( struct net_device *netdev )
|
||||
{
|
||||
struct igbvf_adapter *adapter = netdev_priv ( netdev );
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
uint32_t i;
|
||||
uint32_t rx_status;
|
||||
uint32_t rx_len;
|
||||
uint32_t rx_err;
|
||||
union e1000_adv_rx_desc *rx_curr_desc;
|
||||
|
||||
DBGP ( "igbvf_process_rx_packets\n" );
|
||||
|
||||
/* Process received packets
|
||||
*/
|
||||
while ( 1 ) {
|
||||
i = adapter->rx_curr;
|
||||
|
||||
rx_curr_desc = ( void * ) ( adapter->rx_base ) +
|
||||
( i * sizeof ( *adapter->rx_base ) );
|
||||
rx_status = rx_curr_desc->wb.upper.status_error;
|
||||
|
||||
DBG2 ( "Before DD Check RX_status: %#08x, rx_curr: %d\n",
|
||||
rx_status, i );
|
||||
|
||||
if ( ! ( rx_status & E1000_RXD_STAT_DD ) )
|
||||
break;
|
||||
|
||||
if ( adapter->rx_iobuf[i] == NULL )
|
||||
break;
|
||||
|
||||
DBG ( "E1000_RCTL = %#08x\n", er32 (RCTL) );
|
||||
|
||||
rx_len = rx_curr_desc->wb.upper.length;
|
||||
|
||||
DBG ( "Received packet, rx_curr: %d rx_status: %#08x rx_len: %d\n",
|
||||
i, rx_status, rx_len );
|
||||
|
||||
rx_err = rx_status;
|
||||
|
||||
iob_put ( adapter->rx_iobuf[i], rx_len );
|
||||
|
||||
if ( rx_err & E1000_RXDEXT_ERR_FRAME_ERR_MASK ) {
|
||||
|
||||
netdev_rx_err ( netdev, adapter->rx_iobuf[i], -EINVAL );
|
||||
DBG ( "igbvf_process_rx_packets: Corrupted packet received!"
|
||||
" rx_err: %#08x\n", rx_err );
|
||||
} else {
|
||||
/* Add this packet to the receive queue. */
|
||||
netdev_rx ( netdev, adapter->rx_iobuf[i] );
|
||||
}
|
||||
adapter->rx_iobuf[i] = NULL;
|
||||
|
||||
memset ( rx_curr_desc, 0, sizeof ( *rx_curr_desc ) );
|
||||
|
||||
adapter->rx_curr = ( adapter->rx_curr + 1 ) % NUM_RX_DESC;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_poll - Poll for received packets
|
||||
*
|
||||
* @v netdev Network device
|
||||
*/
|
||||
static void igbvf_poll ( struct net_device *netdev )
|
||||
{
|
||||
struct igbvf_adapter *adapter = netdev_priv ( netdev );
|
||||
uint32_t rx_status;
|
||||
union e1000_adv_rx_desc *rx_curr_desc;
|
||||
|
||||
DBGP ( "igbvf_poll\n" );
|
||||
|
||||
rx_curr_desc = ( void * ) ( adapter->rx_base ) +
|
||||
( adapter->rx_curr * sizeof ( *adapter->rx_base ) );
|
||||
rx_status = rx_curr_desc->wb.upper.status_error;
|
||||
|
||||
if ( ! ( rx_status & E1000_RXD_STAT_DD ) )
|
||||
return;
|
||||
|
||||
igbvf_process_tx_packets ( netdev );
|
||||
|
||||
igbvf_process_rx_packets ( netdev );
|
||||
|
||||
igbvf_refill_rx_ring ( adapter );
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_config_collision_dist_generic - Configure collision distance
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Configures the collision distance to the default value and is used
|
||||
* during link setup. Currently no func pointer exists and all
|
||||
* implementations are handled in the generic version of this function.
|
||||
**/
|
||||
void igbvf_config_collision_dist ( struct e1000_hw *hw )
|
||||
{
|
||||
u32 tctl;
|
||||
|
||||
DBG ("igbvf_config_collision_dist");
|
||||
|
||||
tctl = er32 (TCTL);
|
||||
|
||||
tctl &= ~E1000_TCTL_COLD;
|
||||
tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
|
||||
|
||||
ew32 (TCTL, tctl);
|
||||
e1e_flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_configure_tx - Configure Transmit Unit after Reset
|
||||
* @adapter: board private structure
|
||||
*
|
||||
* Configure the Tx unit of the MAC after a reset.
|
||||
**/
|
||||
static void igbvf_configure_tx ( struct igbvf_adapter *adapter )
|
||||
{
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
u32 tctl, txdctl;
|
||||
|
||||
DBG ( "igbvf_configure_tx\n" );
|
||||
|
||||
/* disable transmits while setting up the descriptors */
|
||||
tctl = er32 ( TCTL );
|
||||
ew32 ( TCTL, tctl & ~E1000_TCTL_EN );
|
||||
e1e_flush();
|
||||
mdelay (10);
|
||||
|
||||
ew32 ( TDBAH(0), 0 );
|
||||
ew32 ( TDBAL(0), virt_to_bus ( adapter->tx_base ) );
|
||||
ew32 ( TDLEN(0), adapter->tx_ring_size );
|
||||
|
||||
DBG ( "E1000_TDBAL(0): %#08x\n", er32 ( TDBAL(0) ) );
|
||||
DBG ( "E1000_TDLEN(0): %d\n", er32 ( TDLEN(0) ) );
|
||||
|
||||
/* Setup the HW Tx Head and Tail descriptor pointers */
|
||||
ew32 ( TDH(0), 0 );
|
||||
ew32 ( TDT(0), 0 );
|
||||
|
||||
adapter->tx_head = 0;
|
||||
adapter->tx_tail = 0;
|
||||
adapter->tx_fill_ctr = 0;
|
||||
|
||||
txdctl = er32(TXDCTL(0));
|
||||
txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
|
||||
ew32 ( TXDCTL(0), txdctl );
|
||||
|
||||
txdctl = er32 ( TXDCTL(0) );
|
||||
txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
|
||||
ew32 ( TXDCTL(0), txdctl );
|
||||
|
||||
/* Setup Transmit Descriptor Settings for eop descriptor */
|
||||
adapter->txd_cmd = E1000_ADVTXD_DCMD_EOP | E1000_ADVTXD_DCMD_IFCS;
|
||||
|
||||
/* Advanced descriptor */
|
||||
adapter->txd_cmd |= E1000_ADVTXD_DCMD_DEXT;
|
||||
|
||||
/* (not part of cmd, but in same 32 bit word...) */
|
||||
adapter->txd_cmd |= E1000_ADVTXD_DTYP_DATA;
|
||||
|
||||
/* enable Report Status bit */
|
||||
adapter->txd_cmd |= E1000_ADVTXD_DCMD_RS;
|
||||
|
||||
/* Program the Transmit Control Register */
|
||||
tctl &= ~E1000_TCTL_CT;
|
||||
tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
|
||||
(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
|
||||
|
||||
igbvf_config_collision_dist ( hw );
|
||||
|
||||
/* Enable transmits */
|
||||
tctl |= E1000_TCTL_EN;
|
||||
ew32(TCTL, tctl);
|
||||
e1e_flush();
|
||||
}
|
||||
|
||||
/* igbvf_reset - bring the hardware into a known good state
|
||||
*
|
||||
* This function boots the hardware and enables some settings that
|
||||
* require a configuration cycle of the hardware - those cannot be
|
||||
* set/changed during runtime. After reset the device needs to be
|
||||
* properly configured for Rx, Tx etc.
|
||||
*/
|
||||
void igbvf_reset ( struct igbvf_adapter *adapter )
|
||||
{
|
||||
struct e1000_mac_info *mac = &adapter->hw.mac;
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
|
||||
/* Allow time for pending master requests to run */
|
||||
if ( mac->ops.reset_hw(hw) )
|
||||
DBG ("PF still resetting\n");
|
||||
|
||||
mac->ops.init_hw ( hw );
|
||||
|
||||
if ( is_valid_ether_addr(adapter->hw.mac.addr) ) {
|
||||
memcpy ( netdev->hw_addr, adapter->hw.mac.addr, ETH_ALEN );
|
||||
}
|
||||
}
|
||||
|
||||
extern void igbvf_init_function_pointers_vf(struct e1000_hw *hw);
|
||||
|
||||
/**
|
||||
* igbvf_sw_init - Initialize general software structures (struct igbvf_adapter)
|
||||
* @adapter: board private structure to initialize
|
||||
*
|
||||
* igbvf_sw_init initializes the Adapter private data structure.
|
||||
* Fields are initialized based on PCI device information and
|
||||
* OS network device settings (MTU size).
|
||||
**/
|
||||
static int __devinit igbvf_sw_init ( struct igbvf_adapter *adapter )
|
||||
{
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
struct pci_device *pdev = adapter->pdev;
|
||||
int rc;
|
||||
|
||||
/* PCI config space info */
|
||||
|
||||
hw->vendor_id = pdev->vendor;
|
||||
hw->device_id = pdev->device;
|
||||
|
||||
pci_read_config_byte ( pdev, PCI_REVISION_ID, &hw->revision_id );
|
||||
|
||||
pci_read_config_word ( pdev, PCI_COMMAND, &hw->bus.pci_cmd_word );
|
||||
|
||||
adapter->max_frame_size = MAXIMUM_ETHERNET_VLAN_SIZE + ETH_HLEN + ETH_FCS_LEN;
|
||||
adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
|
||||
|
||||
/* Set various function pointers */
|
||||
igbvf_init_function_pointers_vf ( &adapter->hw );
|
||||
|
||||
rc = adapter->hw.mac.ops.init_params ( &adapter->hw );
|
||||
if (rc) {
|
||||
DBG ("hw.mac.ops.init_params(&adapter->hw) Failure\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = adapter->hw.mbx.ops.init_params ( &adapter->hw );
|
||||
if (rc) {
|
||||
DBG ("hw.mbx.ops.init_params(&adapter->hw) Failure\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Explicitly disable IRQ since the NIC can be in any state. */
|
||||
igbvf_irq_disable ( adapter );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_setup_srrctl - configure the receive control registers
|
||||
* @adapter: Board private structure
|
||||
**/
|
||||
static void igbvf_setup_srrctl ( struct igbvf_adapter *adapter )
|
||||
{
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
u32 srrctl = 0;
|
||||
|
||||
DBG ( "igbvf_setup_srrctl\n" );
|
||||
|
||||
srrctl &= ~(E1000_SRRCTL_DESCTYPE_MASK |
|
||||
E1000_SRRCTL_BSIZEHDR_MASK |
|
||||
E1000_SRRCTL_BSIZEPKT_MASK);
|
||||
|
||||
/* Enable queue drop to avoid head of line blocking */
|
||||
srrctl |= E1000_SRRCTL_DROP_EN;
|
||||
|
||||
/* Setup buffer sizes */
|
||||
srrctl |= 2048 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
|
||||
srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
|
||||
|
||||
ew32 ( SRRCTL(0), srrctl );
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_configure_rx - Configure 8254x Receive Unit after Reset
|
||||
* @adapter: board private structure
|
||||
*
|
||||
* Configure the Rx unit of the MAC after a reset.
|
||||
**/
|
||||
static void igbvf_configure_rx ( struct igbvf_adapter *adapter )
|
||||
{
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
u32 rxdctl;
|
||||
|
||||
DBG ( "igbvf_configure_rx\n" );
|
||||
|
||||
/* disable receives */
|
||||
rxdctl = er32 ( RXDCTL(0) );
|
||||
ew32 ( RXDCTL(0), rxdctl & ~E1000_RXDCTL_QUEUE_ENABLE );
|
||||
msleep ( 10 );
|
||||
|
||||
/*
|
||||
* Setup the HW Rx Head and Tail Descriptor Pointers and
|
||||
* the Base and Length of the Rx Descriptor Ring
|
||||
*/
|
||||
ew32 ( RDBAL(0), virt_to_bus (adapter->rx_base) );
|
||||
ew32 ( RDBAH(0), 0 );
|
||||
ew32 ( RDLEN(0), adapter->rx_ring_size );
|
||||
adapter->rx_curr = 0;
|
||||
ew32 ( RDH(0), 0 );
|
||||
ew32 ( RDT(0), 0 );
|
||||
|
||||
rxdctl |= E1000_RXDCTL_QUEUE_ENABLE;
|
||||
rxdctl &= 0xFFF00000;
|
||||
rxdctl |= IGBVF_RX_PTHRESH;
|
||||
rxdctl |= IGBVF_RX_HTHRESH << 8;
|
||||
rxdctl |= IGBVF_RX_WTHRESH << 16;
|
||||
|
||||
igbvf_rlpml_set_vf ( hw, adapter->max_frame_size );
|
||||
|
||||
/* enable receives */
|
||||
ew32 ( RXDCTL(0), rxdctl );
|
||||
ew32 ( RDT(0), NUM_RX_DESC );
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_setup_rx_resources - allocate Rx resources (Descriptors)
|
||||
*
|
||||
* @v adapter e1000 private structure
|
||||
**/
|
||||
int igbvf_setup_rx_resources ( struct igbvf_adapter *adapter )
|
||||
{
|
||||
int i;
|
||||
union e1000_adv_rx_desc *rx_curr_desc;
|
||||
struct io_buffer *iob;
|
||||
|
||||
DBG ( "igbvf_setup_rx_resources\n" );
|
||||
|
||||
/* Allocate receive descriptor ring memory.
|
||||
It must not cross a 64K boundary because of hardware errata
|
||||
*/
|
||||
|
||||
adapter->rx_base =
|
||||
malloc_dma ( adapter->rx_ring_size, adapter->rx_ring_size );
|
||||
|
||||
if ( ! adapter->rx_base ) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset ( adapter->rx_base, 0, adapter->rx_ring_size );
|
||||
|
||||
for ( i = 0; i < NUM_RX_DESC; i++ ) {
|
||||
rx_curr_desc = adapter->rx_base + i;
|
||||
iob = alloc_iob ( MAXIMUM_ETHERNET_VLAN_SIZE );
|
||||
adapter->rx_iobuf[i] = iob;
|
||||
rx_curr_desc->wb.upper.status_error = 0;
|
||||
if ( ! iob ) {
|
||||
DBG ( "alloc_iob failed\n" );
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
rx_curr_desc->read.pkt_addr = virt_to_bus ( iob->data );
|
||||
rx_curr_desc->read.hdr_addr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_open - Called when a network interface is made active
|
||||
* @netdev: network interface device structure
|
||||
*
|
||||
* Returns 0 on success, negative value on failure
|
||||
*
|
||||
* The open entry point is called when a network interface is made
|
||||
* active by the system (IFF_UP). At this point all resources needed
|
||||
* for transmit and receive operations are allocated, the interrupt
|
||||
* handler is registered with the OS, the watchdog timer is started,
|
||||
* and the stack is notified that the interface is ready.
|
||||
**/
|
||||
static int igbvf_open ( struct net_device *netdev )
|
||||
{
|
||||
struct igbvf_adapter *adapter = netdev_priv ( netdev );
|
||||
int err;
|
||||
|
||||
DBG ("igbvf_open\n");
|
||||
|
||||
/* allocate transmit descriptors */
|
||||
err = igbvf_setup_tx_resources ( adapter );
|
||||
if (err) {
|
||||
DBG ( "Error setting up TX resources!\n" );
|
||||
goto err_setup_tx;
|
||||
}
|
||||
|
||||
igbvf_configure_tx ( adapter );
|
||||
|
||||
igbvf_setup_srrctl( adapter );
|
||||
|
||||
err = igbvf_setup_rx_resources( adapter );
|
||||
if (err) {
|
||||
DBG ( "Error setting up RX resources!\n" );
|
||||
goto err_setup_rx;
|
||||
}
|
||||
|
||||
igbvf_configure_rx ( adapter );
|
||||
|
||||
return 0;
|
||||
|
||||
err_setup_rx:
|
||||
DBG ( "err_setup_rx\n" );
|
||||
igbvf_free_tx_resources ( adapter );
|
||||
return err;
|
||||
|
||||
err_setup_tx:
|
||||
DBG ( "err_setup_tx\n" );
|
||||
igbvf_reset ( adapter );
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_close - Disables a network interface
|
||||
* @netdev: network interface device structure
|
||||
*
|
||||
* Returns 0, this is not allowed to fail
|
||||
*
|
||||
* The close entry point is called when an interface is de-activated
|
||||
* by the OS. The hardware is still under the drivers control, but
|
||||
* needs to be disabled. A global MAC reset is issued to stop the
|
||||
* hardware, and all transmit and receive resources are freed.
|
||||
**/
|
||||
static void igbvf_close ( struct net_device *netdev )
|
||||
{
|
||||
struct igbvf_adapter *adapter = netdev_priv ( netdev );
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
uint32_t rxdctl;
|
||||
uint32_t icr;
|
||||
|
||||
DBG ( "igbvf_close\n" );
|
||||
icr = er32(EICR);
|
||||
|
||||
igbvf_irq_disable ( adapter );
|
||||
|
||||
/* disable receives */
|
||||
rxdctl = er32 ( RXDCTL(0) );
|
||||
ew32 ( RXDCTL(0), rxdctl & ~E1000_RXDCTL_QUEUE_ENABLE );
|
||||
mdelay ( 10 );
|
||||
|
||||
igbvf_reset ( adapter );
|
||||
|
||||
igbvf_free_tx_resources( adapter );
|
||||
igbvf_free_rx_resources( adapter );
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_transmit - Transmit a packet
|
||||
*
|
||||
* @v netdev Network device
|
||||
* @v iobuf I/O buffer
|
||||
*
|
||||
* @ret rc Returns 0 on success, negative on failure
|
||||
*/
|
||||
static int igbvf_transmit ( struct net_device *netdev, struct io_buffer *iobuf )
|
||||
{
|
||||
struct igbvf_adapter *adapter = netdev_priv ( netdev );
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
uint32_t tx_curr = adapter->tx_tail;
|
||||
union e1000_adv_tx_desc *tx_curr_desc;
|
||||
|
||||
DBGP ("igbvf_transmit\n");
|
||||
|
||||
if ( adapter->tx_fill_ctr == NUM_TX_DESC ) {
|
||||
DBG ("TX overflow\n");
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
/* Save pointer to iobuf we have been given to transmit,
|
||||
netdev_tx_complete() will need it later
|
||||
*/
|
||||
adapter->tx_iobuf[tx_curr] = iobuf;
|
||||
|
||||
tx_curr_desc = ( void * ) ( adapter->tx_base ) +
|
||||
( tx_curr * sizeof ( *adapter->tx_base ) );
|
||||
|
||||
DBG ( "tx_curr_desc = %#08lx\n", virt_to_bus ( tx_curr_desc ) );
|
||||
DBG ( "tx_curr_desc + 16 = %#08lx\n", virt_to_bus ( tx_curr_desc ) + 16 );
|
||||
DBG ( "iobuf->data = %#08lx\n", virt_to_bus ( iobuf->data ) );
|
||||
|
||||
/* Add the packet to TX ring
|
||||
*/
|
||||
tx_curr_desc->read.buffer_addr = virt_to_bus ( iobuf->data );
|
||||
tx_curr_desc->read.cmd_type_len = adapter->txd_cmd |(iob_len ( iobuf )) ;
|
||||
// minus hdr_len ????
|
||||
tx_curr_desc->read.olinfo_status = ((iob_len ( iobuf )) << E1000_ADVTXD_PAYLEN_SHIFT);
|
||||
|
||||
DBG ( "TX fill: %d tx_curr: %d addr: %#08lx len: %zd\n", adapter->tx_fill_ctr,
|
||||
tx_curr, virt_to_bus ( iobuf->data ), iob_len ( iobuf ) );
|
||||
|
||||
/* Point to next free descriptor */
|
||||
adapter->tx_tail = ( adapter->tx_tail + 1 ) % NUM_TX_DESC;
|
||||
adapter->tx_fill_ctr++;
|
||||
|
||||
/* Write new tail to NIC, making packet available for transmit
|
||||
*/
|
||||
ew32 ( TDT(0), adapter->tx_tail );
|
||||
e1e_flush ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** igbvf net device operations */
|
||||
static struct net_device_operations igbvf_operations = {
|
||||
.open = igbvf_open,
|
||||
.close = igbvf_close,
|
||||
.transmit = igbvf_transmit,
|
||||
.poll = igbvf_poll,
|
||||
.irq = igbvf_irq,
|
||||
};
|
||||
|
||||
/**
|
||||
* igbvf_get_hw_control - get control of the h/w from f/w
|
||||
* @adapter: address of board private structure
|
||||
*
|
||||
* igb_get_hw_control sets CTRL_EXT:DRV_LOAD bit.
|
||||
* For ASF and Pass Through versions of f/w this means that
|
||||
* the driver is loaded.
|
||||
*
|
||||
**/
|
||||
void igbvf_get_hw_control ( struct igbvf_adapter *adapter )
|
||||
{
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
u32 ctrl_ext;
|
||||
|
||||
/* Let firmware know the driver has taken over */
|
||||
ctrl_ext = er32 ( CTRL_EXT );
|
||||
ew32 ( CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD );
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_probe - Device Initialization Routine
|
||||
* @pdev: PCI device information struct
|
||||
* @ent: entry in igbvf_pci_tbl
|
||||
*
|
||||
* Returns 0 on success, negative on failure
|
||||
*
|
||||
* igbvf_probe initializes an adapter identified by a pci_dev structure.
|
||||
* The OS initialization, configuring of the adapter private structure,
|
||||
* and a hardware reset occur.
|
||||
**/
|
||||
int igbvf_probe ( struct pci_device *pdev,
|
||||
const struct pci_device_id *ent __unused )
|
||||
{
|
||||
int err;
|
||||
struct net_device *netdev;
|
||||
struct igbvf_adapter *adapter;
|
||||
unsigned long mmio_start, mmio_len;
|
||||
struct e1000_hw *hw;
|
||||
|
||||
DBG ( "igbvf_probe\n" );
|
||||
|
||||
err = -ENOMEM;
|
||||
|
||||
/* Allocate net device ( also allocates memory for netdev->priv
|
||||
and makes netdev-priv point to it ) */
|
||||
netdev = alloc_etherdev ( sizeof ( struct igbvf_adapter ) );
|
||||
if ( ! netdev )
|
||||
goto err_alloc_etherdev;
|
||||
|
||||
/* Associate igbvf-specific network operations operations with
|
||||
* generic network device layer */
|
||||
netdev_init ( netdev, &igbvf_operations );
|
||||
|
||||
/* Associate this network device with given PCI device */
|
||||
pci_set_drvdata ( pdev, netdev );
|
||||
netdev->dev = &pdev->dev;
|
||||
|
||||
/* Initialize driver private storage */
|
||||
adapter = netdev_priv ( netdev );
|
||||
memset ( adapter, 0, ( sizeof ( *adapter ) ) );
|
||||
|
||||
adapter->pdev = pdev;
|
||||
|
||||
adapter->ioaddr = pdev->ioaddr;
|
||||
adapter->hw.io_base = pdev->ioaddr;
|
||||
|
||||
hw = &adapter->hw;
|
||||
hw->vendor_id = pdev->vendor;
|
||||
hw->device_id = pdev->device;
|
||||
|
||||
adapter->irqno = pdev->irq;
|
||||
adapter->netdev = netdev;
|
||||
adapter->hw.back = adapter;
|
||||
|
||||
adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
|
||||
adapter->max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN;
|
||||
|
||||
adapter->tx_ring_size = sizeof ( *adapter->tx_base ) * NUM_TX_DESC;
|
||||
adapter->rx_ring_size = sizeof ( *adapter->rx_base ) * NUM_RX_DESC;
|
||||
|
||||
/* Fix up PCI device */
|
||||
adjust_pci_device ( pdev );
|
||||
|
||||
err = -EIO;
|
||||
|
||||
mmio_start = pci_bar_start ( pdev, PCI_BASE_ADDRESS_0 );
|
||||
mmio_len = pci_bar_size ( pdev, PCI_BASE_ADDRESS_0 );
|
||||
|
||||
DBG ( "mmio_start: %#08lx\n", mmio_start );
|
||||
DBG ( "mmio_len: %#08lx\n", mmio_len );
|
||||
|
||||
adapter->hw.hw_addr = ioremap ( mmio_start, mmio_len );
|
||||
DBG ( "adapter->hw.hw_addr: %p\n", adapter->hw.hw_addr );
|
||||
|
||||
if ( ! adapter->hw.hw_addr ) {
|
||||
DBG ( "err_ioremap\n" );
|
||||
goto err_ioremap;
|
||||
}
|
||||
|
||||
/* setup adapter struct */
|
||||
err = igbvf_sw_init ( adapter );
|
||||
if (err) {
|
||||
DBG ( "err_sw_init\n" );
|
||||
goto err_sw_init;
|
||||
}
|
||||
|
||||
/* reset the controller to put the device in a known good state */
|
||||
err = hw->mac.ops.reset_hw ( hw );
|
||||
if ( err ) {
|
||||
DBG ("PF still in reset state, assigning new address\n");
|
||||
netdev->hw_addr[0] = 0x21;
|
||||
netdev->hw_addr[1] = 0x21;
|
||||
netdev->hw_addr[2] = 0x21;
|
||||
netdev->hw_addr[3] = 0x21;
|
||||
netdev->hw_addr[4] = 0x21;
|
||||
netdev->hw_addr[5] = 0x21;
|
||||
netdev->hw_addr[6] = 0x21;
|
||||
} else {
|
||||
err = hw->mac.ops.read_mac_addr(hw);
|
||||
if (err) {
|
||||
DBG ("Error reading MAC address\n");
|
||||
goto err_hw_init;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy ( netdev->hw_addr, adapter->hw.mac.addr, ETH_ALEN );
|
||||
|
||||
if ( ! is_valid_ether_addr( netdev->hw_addr ) ) {
|
||||
DBG ("Invalid MAC Address: "
|
||||
"%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
netdev->hw_addr[0], netdev->hw_addr[1],
|
||||
netdev->hw_addr[2], netdev->hw_addr[3],
|
||||
netdev->hw_addr[4], netdev->hw_addr[5]);
|
||||
err = -EIO;
|
||||
goto err_hw_init;
|
||||
}
|
||||
|
||||
/* reset the hardware with the new settings */
|
||||
igbvf_reset ( adapter );
|
||||
|
||||
/* let the f/w know that the h/w is now under the control of the
|
||||
* driver. */
|
||||
igbvf_get_hw_control ( adapter );
|
||||
|
||||
/* Mark as link up; we don't yet handle link state */
|
||||
netdev_link_up ( netdev );
|
||||
|
||||
if ( ( err = register_netdev ( netdev ) ) != 0) {
|
||||
DBG ( "err_register\n" );
|
||||
goto err_register;
|
||||
}
|
||||
|
||||
DBG ("igbvf_probe_succeeded\n");
|
||||
|
||||
return 0;
|
||||
|
||||
err_register:
|
||||
err_hw_init:
|
||||
err_sw_init:
|
||||
iounmap ( adapter->hw.hw_addr );
|
||||
err_ioremap:
|
||||
netdev_put ( netdev );
|
||||
err_alloc_etherdev:
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_remove - Device Removal Routine
|
||||
* @pdev: PCI device information struct
|
||||
*
|
||||
* igbvf_remove is called by the PCI subsystem to alert the driver
|
||||
* that it should release a PCI device. The could be caused by a
|
||||
* Hot-Plug event, or because the driver is going to be removed from
|
||||
* memory.
|
||||
**/
|
||||
void igbvf_remove ( struct pci_device *pdev )
|
||||
{
|
||||
struct net_device *netdev = pci_get_drvdata ( pdev );
|
||||
struct igbvf_adapter *adapter = netdev_priv ( netdev );
|
||||
|
||||
DBG ( "igbvf_remove\n" );
|
||||
|
||||
if ( adapter->hw.flash_address )
|
||||
iounmap ( adapter->hw.flash_address );
|
||||
if ( adapter->hw.hw_addr )
|
||||
iounmap ( adapter->hw.hw_addr );
|
||||
|
||||
unregister_netdev ( netdev );
|
||||
igbvf_reset ( adapter );
|
||||
netdev_nullify ( netdev );
|
||||
netdev_put ( netdev );
|
||||
}
|
||||
|
||||
static struct pci_device_id igbvf_pci_tbl[] = {
|
||||
PCI_ROM(0x8086, 0x10CA, "igbvf", "E1000_DEV_ID_82576_VF", 0)
|
||||
};
|
||||
|
||||
|
||||
struct pci_driver igbvf_driver __pci_driver = {
|
||||
.ids = igbvf_pci_tbl,
|
||||
.id_count = (sizeof(igbvf_pci_tbl) / sizeof(igbvf_pci_tbl[0])),
|
||||
.probe = igbvf_probe,
|
||||
.remove = igbvf_remove,
|
||||
};
|
404
src/drivers/net/igbvf/igbvf_mbx.c
Normal file
404
src/drivers/net/igbvf/igbvf_mbx.c
Normal file
@ -0,0 +1,404 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel(R) 82576 Virtual Function Linux driver
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
version 2, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
The full GNU General Public License is included in this distribution in
|
||||
the file called "COPYING".
|
||||
|
||||
Contact Information:
|
||||
Linux NICS <linux.nics@intel.com>
|
||||
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
|
||||
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
FILE_LICENCE ( GPL2_ONLY );
|
||||
|
||||
#include "igbvf_mbx.h"
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
int countdown = mbx->timeout;
|
||||
|
||||
DEBUGFUNC("igbvf_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
int countdown = mbx->timeout;
|
||||
|
||||
DEBUGFUNC("igbvf_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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.
|
||||
**/
|
||||
static s32 igbvf_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("igbvf_read_posted_mbx");
|
||||
|
||||
if (!mbx->ops.read)
|
||||
goto out;
|
||||
|
||||
ret_val = igbvf_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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
|
||||
**/
|
||||
static s32 igbvf_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("igbvf_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 = igbvf_poll_for_ack(hw, mbx_id);
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_init_mbx_ops_generic - Initialize NVM function pointers
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Setups up the function pointers to no-op functions
|
||||
**/
|
||||
void igbvf_init_mbx_ops_generic(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_mbx_info *mbx = &hw->mbx;
|
||||
mbx->ops.read_posted = igbvf_read_posted_mbx;
|
||||
mbx->ops.write_posted = igbvf_write_posted_mbx;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_check_for_bit_vf(struct e1000_hw *hw, u32 mask)
|
||||
{
|
||||
u32 v2p_mailbox = igbvf_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_check_for_msg_vf(struct e1000_hw *hw, u16 mbx_id __unused)
|
||||
{
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("igbvf_check_for_msg_vf");
|
||||
|
||||
if (!igbvf_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFSTS)) {
|
||||
ret_val = E1000_SUCCESS;
|
||||
hw->mbx.stats.reqs++;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_check_for_ack_vf(struct e1000_hw *hw, u16 mbx_id __unused)
|
||||
{
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("igbvf_check_for_ack_vf");
|
||||
|
||||
if (!igbvf_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFACK)) {
|
||||
ret_val = E1000_SUCCESS;
|
||||
hw->mbx.stats.acks++;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_check_for_rst_vf(struct e1000_hw *hw, u16 mbx_id __unused)
|
||||
{
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("igbvf_check_for_rst_vf");
|
||||
|
||||
if (!igbvf_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD |
|
||||
E1000_V2PMAILBOX_RSTI))) {
|
||||
ret_val = E1000_SUCCESS;
|
||||
hw->mbx.stats.rsts++;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_obtain_mbx_lock_vf - obtain mailbox lock
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* return SUCCESS if we obtained the mailbox lock
|
||||
**/
|
||||
static s32 igbvf_obtain_mbx_lock_vf(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val = -E1000_ERR_MBX;
|
||||
|
||||
DEBUGFUNC("igbvf_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 (igbvf_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU)
|
||||
ret_val = E1000_SUCCESS;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
|
||||
u16 mbx_id __unused)
|
||||
{
|
||||
s32 ret_val;
|
||||
u16 i;
|
||||
|
||||
|
||||
DEBUGFUNC("igbvf_write_mbx_vf");
|
||||
|
||||
/* lock the mailbox to prevent pf/vf race condition */
|
||||
ret_val = igbvf_obtain_mbx_lock_vf(hw);
|
||||
if (ret_val)
|
||||
goto out_no_write;
|
||||
|
||||
/* flush msg and acks as we are overwriting the message buffer */
|
||||
igbvf_check_for_msg_vf(hw, 0);
|
||||
igbvf_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
|
||||
u16 mbx_id __unused)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u16 i;
|
||||
|
||||
DEBUGFUNC("igbvf_read_mbx_vf");
|
||||
|
||||
/* lock the mailbox to prevent pf/vf race condition */
|
||||
ret_val = igbvf_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_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 = igbvf_read_mbx_vf;
|
||||
mbx->ops.write = igbvf_write_mbx_vf;
|
||||
mbx->ops.read_posted = igbvf_read_posted_mbx;
|
||||
mbx->ops.write_posted = igbvf_write_posted_mbx;
|
||||
mbx->ops.check_for_msg = igbvf_check_for_msg_vf;
|
||||
mbx->ops.check_for_ack = igbvf_check_for_ack_vf;
|
||||
mbx->ops.check_for_rst = igbvf_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;
|
||||
}
|
||||
|
87
src/drivers/net/igbvf/igbvf_mbx.h
Normal file
87
src/drivers/net/igbvf/igbvf_mbx.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel(R) 82576 Virtual Function Linux driver
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
version 2, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
The full GNU General Public License is included in this distribution in
|
||||
the file called "COPYING".
|
||||
|
||||
Contact Information:
|
||||
Linux NICS <linux.nics@intel.com>
|
||||
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
|
||||
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
FILE_LICENCE ( GPL2_ONLY );
|
||||
|
||||
#ifndef _IGBVF_MBX_H_
|
||||
#define _IGBVF_MBX_H_
|
||||
|
||||
#include "igbvf_vf.h"
|
||||
|
||||
/* Define mailbox specific registers */
|
||||
#define E1000_V2PMAILBOX(_n) (0x00C40 + (4 * (_n)))
|
||||
#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n)))
|
||||
|
||||
/* 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_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 */
|
||||
|
||||
void igbvf_init_mbx_ops_generic(struct e1000_hw *hw);
|
||||
s32 igbvf_init_mbx_params_vf(struct e1000_hw *);
|
||||
|
||||
#endif /* _IGBVF_MBX_H_ */
|
121
src/drivers/net/igbvf/igbvf_osdep.h
Normal file
121
src/drivers/net/igbvf/igbvf_osdep.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel(R) 82576 Virtual Function Linux driver
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
version 2, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
The full GNU General Public License is included in this distribution in
|
||||
the file called "COPYING".
|
||||
|
||||
Contact Information:
|
||||
Linux NICS <linux.nics@intel.com>
|
||||
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
|
||||
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
FILE_LICENCE ( GPL2_ONLY );
|
||||
|
||||
/* glue for the OS-dependent part of igbvf
|
||||
* includes register access macros
|
||||
*/
|
||||
|
||||
#ifndef _IGBVF_OSDEP_H_
|
||||
#define _IGBVF_OSDEP_H_
|
||||
|
||||
#define u8 unsigned char
|
||||
#define bool boolean_t
|
||||
#define dma_addr_t unsigned long
|
||||
#define __le16 uint16_t
|
||||
#define __le32 uint32_t
|
||||
#define __le64 uint64_t
|
||||
|
||||
#define __iomem
|
||||
#define __devinit
|
||||
#define ____cacheline_aligned_in_smp
|
||||
|
||||
#define msleep(x) mdelay(x)
|
||||
|
||||
#define ETH_FCS_LEN 4
|
||||
|
||||
typedef int spinlock_t;
|
||||
typedef enum {
|
||||
false = 0,
|
||||
true = 1
|
||||
} boolean_t;
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define usec_delay(x) udelay(x)
|
||||
#define msec_delay(x) mdelay(x)
|
||||
#define msec_delay_irq(x) mdelay(x)
|
||||
|
||||
#define PCI_COMMAND_REGISTER PCI_COMMAND
|
||||
#define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE
|
||||
#define ETH_ADDR_LEN ETH_ALEN
|
||||
|
||||
|
||||
#define DEBUGOUT(S) if (0) { printf(S); }
|
||||
#define DEBUGOUT1(S, A...) if (0) { printf(S, A); }
|
||||
|
||||
#define DEBUGFUNC(F) DEBUGOUT(F "\n")
|
||||
#define DEBUGOUT2 DEBUGOUT1
|
||||
#define DEBUGOUT3 DEBUGOUT2
|
||||
#define DEBUGOUT7 DEBUGOUT3
|
||||
|
||||
#define E1000_WRITE_REG(a, reg, value) do { \
|
||||
writel((value), ((a)->hw_addr + reg)); } while (0)
|
||||
|
||||
#define E1000_READ_REG(a, reg) (readl((a)->hw_addr + reg))
|
||||
|
||||
#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) do { \
|
||||
writel((value), ((a)->hw_addr + reg + ((offset) << 2))); } while (0)
|
||||
|
||||
#define E1000_READ_REG_ARRAY(a, reg, offset) ( \
|
||||
readl((a)->hw_addr + reg + ((offset) << 2)))
|
||||
|
||||
#define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY
|
||||
#define E1000_WRITE_REG_ARRAY_DWORD E1000_WRITE_REG_ARRAY
|
||||
|
||||
#define E1000_WRITE_REG_ARRAY_WORD(a, reg, offset, value) ( \
|
||||
writew((value), ((a)->hw_addr + reg + ((offset) << 1))))
|
||||
|
||||
#define E1000_READ_REG_ARRAY_WORD(a, reg, offset) ( \
|
||||
readw((a)->hw_addr + reg + ((offset) << 1)))
|
||||
|
||||
#define E1000_WRITE_REG_ARRAY_BYTE(a, reg, offset, value) ( \
|
||||
writeb((value), ((a)->hw_addr + reg + (offset))))
|
||||
|
||||
#define E1000_READ_REG_ARRAY_BYTE(a, reg, offset) ( \
|
||||
readb((a)->hw_addr + reg + (offset)))
|
||||
|
||||
#define E1000_WRITE_REG_IO(a, reg, offset) do { \
|
||||
outl(reg, ((a)->io_base)); \
|
||||
outl(offset, ((a)->io_base + 4)); } while(0)
|
||||
|
||||
#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, E1000_STATUS)
|
||||
|
||||
#define E1000_WRITE_FLASH_REG(a, reg, value) ( \
|
||||
writel((value), ((a)->flash_address + reg)))
|
||||
|
||||
#define E1000_WRITE_FLASH_REG16(a, reg, value) ( \
|
||||
writew((value), ((a)->flash_address + reg)))
|
||||
|
||||
#define E1000_READ_FLASH_REG(a, reg) (readl((a)->flash_address + reg))
|
||||
|
||||
#define E1000_READ_FLASH_REG16(a, reg) (readw((a)->flash_address + reg))
|
||||
|
||||
#endif /* _IGBVF_OSDEP_H_ */
|
338
src/drivers/net/igbvf/igbvf_regs.h
Normal file
338
src/drivers/net/igbvf/igbvf_regs.h
Normal file
@ -0,0 +1,338 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel(R) 82576 Virtual Function Linux driver
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
version 2, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
The full GNU General Public License is included in this distribution in
|
||||
the file called "COPYING".
|
||||
|
||||
Contact Information:
|
||||
Linux NICS <linux.nics@intel.com>
|
||||
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
|
||||
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
FILE_LICENCE ( GPL2_ONLY );
|
||||
|
||||
#ifndef _IGBVF_REGS_H_
|
||||
#define _IGBVF_REGS_H_
|
||||
|
||||
#define E1000_CTRL 0x00000 /* Device Control - RW */
|
||||
#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW */
|
||||
#define E1000_STATUS 0x00008 /* Device Status - RO */
|
||||
#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
|
||||
#define E1000_EERD 0x00014 /* EEPROM Read - RW */
|
||||
#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
|
||||
#define E1000_FLA 0x0001C /* Flash Access - RW */
|
||||
#define E1000_MDIC 0x00020 /* MDI Control - RW */
|
||||
#define E1000_SCTL 0x00024 /* SerDes Control - RW */
|
||||
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
|
||||
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
|
||||
#define E1000_FEXT 0x0002C /* Future Extended - RW */
|
||||
#define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */
|
||||
#define E1000_FCT 0x00030 /* Flow Control Type - RW */
|
||||
#define E1000_CONNSW 0x00034 /* Copper/Fiber switch control - RW */
|
||||
#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
|
||||
#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
|
||||
#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
|
||||
#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
|
||||
#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
|
||||
#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
|
||||
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
|
||||
#define E1000_RCTL 0x00100 /* Rx Control - RW */
|
||||
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
|
||||
#define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */
|
||||
#define E1000_RXCW 0x00180 /* Rx Configuration Word - RO */
|
||||
#define E1000_TCTL 0x00400 /* Tx Control - RW */
|
||||
#define E1000_TCTL_EXT 0x00404 /* Extended Tx Control - RW */
|
||||
#define E1000_TIPG 0x00410 /* Tx Inter-packet gap -RW */
|
||||
#define E1000_TBT 0x00448 /* Tx Burst Timer - RW */
|
||||
#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
|
||||
#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
|
||||
#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */
|
||||
#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */
|
||||
#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */
|
||||
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
|
||||
#define E1000_PBS 0x01008 /* Packet Buffer Size */
|
||||
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
|
||||
#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
|
||||
#define E1000_FLASHT 0x01028 /* FLASH Timer Register */
|
||||
#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
|
||||
#define E1000_FLSWCTL 0x01030 /* FLASH control register */
|
||||
#define E1000_FLSWDATA 0x01034 /* FLASH data register */
|
||||
#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */
|
||||
#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
|
||||
#define E1000_I2CCMD 0x01028 /* SFPI2C Command Register - RW */
|
||||
#define E1000_I2CPARAMS 0x0102C /* SFPI2C Parameters Register - RW */
|
||||
#define E1000_WDSTP 0x01040 /* Watchdog Setup - RW */
|
||||
#define E1000_SWDSTS 0x01044 /* SW Device Status - RW */
|
||||
#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */
|
||||
#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
|
||||
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
|
||||
#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
|
||||
#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */
|
||||
#define E1000_RDFPCQ(_n) (0x02430 + (0x4 * (_n)))
|
||||
#define E1000_PBRTH 0x02458 /* PB Rx Arbitration Threshold - RW */
|
||||
#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */
|
||||
/* Split and Replication Rx Control - RW */
|
||||
#define E1000_RDPUMB 0x025CC /* DMA Rx Descriptor uC Mailbox - RW */
|
||||
#define E1000_RDPUAD 0x025D0 /* DMA Rx Descriptor uC Addr Command - RW */
|
||||
#define E1000_RDPUWD 0x025D4 /* DMA Rx Descriptor uC Data Write - RW */
|
||||
#define E1000_RDPURD 0x025D8 /* DMA Rx Descriptor uC Data Read - RW */
|
||||
#define E1000_RDPUCTL 0x025DC /* DMA Rx Descriptor uC Control - RW */
|
||||
#define E1000_RXCTL(_n) (0x0C014 + (0x40 * (_n)))
|
||||
#define E1000_RQDPC(_n) (0x0C030 + (0x40 * (_n)))
|
||||
#define E1000_RDTR 0x02820 /* Rx Delay Timer - RW */
|
||||
#define E1000_RADV 0x0282C /* Rx Interrupt Absolute Delay Timer - RW */
|
||||
/*
|
||||
* Convenience macros
|
||||
*
|
||||
* Note: "_n" is the queue number of the register to be written to.
|
||||
*
|
||||
* Example usage:
|
||||
* E1000_RDBAL_REG(current_rx_queue)
|
||||
*/
|
||||
#define E1000_RDBAL(_n) ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) : \
|
||||
(0x0C000 + ((_n) * 0x40)))
|
||||
#define E1000_RDBAH(_n) ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) : \
|
||||
(0x0C004 + ((_n) * 0x40)))
|
||||
#define E1000_RDLEN(_n) ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) : \
|
||||
(0x0C008 + ((_n) * 0x40)))
|
||||
#define E1000_SRRCTL(_n) ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) : \
|
||||
(0x0C00C + ((_n) * 0x40)))
|
||||
#define E1000_RDH(_n) ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) : \
|
||||
(0x0C010 + ((_n) * 0x40)))
|
||||
#define E1000_RDT(_n) ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) : \
|
||||
(0x0C018 + ((_n) * 0x40)))
|
||||
#define E1000_RXDCTL(_n) ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) : \
|
||||
(0x0C028 + ((_n) * 0x40)))
|
||||
#define E1000_TDBAL(_n) ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) : \
|
||||
(0x0E000 + ((_n) * 0x40)))
|
||||
#define E1000_TDBAH(_n) ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) : \
|
||||
(0x0E004 + ((_n) * 0x40)))
|
||||
#define E1000_TDLEN(_n) ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) : \
|
||||
(0x0E008 + ((_n) * 0x40)))
|
||||
#define E1000_TDH(_n) ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) : \
|
||||
(0x0E010 + ((_n) * 0x40)))
|
||||
#define E1000_TDT(_n) ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) : \
|
||||
(0x0E018 + ((_n) * 0x40)))
|
||||
#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) : \
|
||||
(0x0E028 + ((_n) * 0x40)))
|
||||
#define E1000_TARC(_n) (0x03840 + (_n << 8))
|
||||
#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8))
|
||||
#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8))
|
||||
#define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) : \
|
||||
(0x0E038 + ((_n) * 0x40)))
|
||||
#define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) : \
|
||||
(0x0E03C + ((_n) * 0x40)))
|
||||
#define E1000_RSRPD 0x02C00 /* Rx Small Packet Detect - RW */
|
||||
#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */
|
||||
#define E1000_TXDMAC 0x03000 /* Tx DMA Control - RW */
|
||||
#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */
|
||||
#define E1000_PSRTYPE(_i) (0x05480 + ((_i) * 4))
|
||||
#define E1000_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
|
||||
(0x054E0 + ((_i - 16) * 8)))
|
||||
#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
|
||||
(0x054E4 + ((_i - 16) * 8)))
|
||||
#define E1000_IP4AT_REG(_i) (0x05840 + ((_i) * 8))
|
||||
#define E1000_IP6AT_REG(_i) (0x05880 + ((_i) * 4))
|
||||
#define E1000_WUPM_REG(_i) (0x05A00 + ((_i) * 4))
|
||||
#define E1000_FFMT_REG(_i) (0x09000 + ((_i) * 8))
|
||||
#define E1000_FFVT_REG(_i) (0x09800 + ((_i) * 8))
|
||||
#define E1000_FFLT_REG(_i) (0x05F00 + ((_i) * 8))
|
||||
#define E1000_TDFH 0x03410 /* Tx Data FIFO Head - RW */
|
||||
#define E1000_TDFT 0x03418 /* Tx Data FIFO Tail - RW */
|
||||
#define E1000_TDFHS 0x03420 /* Tx Data FIFO Head Saved - RW */
|
||||
#define E1000_TDFTS 0x03428 /* Tx Data FIFO Tail Saved - RW */
|
||||
#define E1000_TDFPC 0x03430 /* Tx Data FIFO Packet Count - RW */
|
||||
#define E1000_TDPUMB 0x0357C /* DMA Tx Descriptor uC Mail Box - RW */
|
||||
#define E1000_TDPUAD 0x03580 /* DMA Tx Descriptor uC Addr Command - RW */
|
||||
#define E1000_TDPUWD 0x03584 /* DMA Tx Descriptor uC Data Write - RW */
|
||||
#define E1000_TDPURD 0x03588 /* DMA Tx Descriptor uC Data Read - RW */
|
||||
#define E1000_TDPUCTL 0x0358C /* DMA Tx Descriptor uC Control - RW */
|
||||
#define E1000_DTXCTL 0x03590 /* DMA Tx Control - RW */
|
||||
#define E1000_TIDV 0x03820 /* Tx Interrupt Delay Value - RW */
|
||||
#define E1000_TADV 0x0382C /* Tx Interrupt Absolute Delay Val - RW */
|
||||
#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
|
||||
#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
|
||||
#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
|
||||
#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
|
||||
#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */
|
||||
#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */
|
||||
#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */
|
||||
#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */
|
||||
#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */
|
||||
#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */
|
||||
#define E1000_COLC 0x04028 /* Collision Count - R/clr */
|
||||
#define E1000_DC 0x04030 /* Defer Count - R/clr */
|
||||
#define E1000_TNCRS 0x04034 /* Tx-No CRS - R/clr */
|
||||
#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */
|
||||
#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
|
||||
#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
|
||||
#define E1000_XONRXC 0x04048 /* XON Rx Count - R/clr */
|
||||
#define E1000_XONTXC 0x0404C /* XON Tx Count - R/clr */
|
||||
#define E1000_XOFFRXC 0x04050 /* XOFF Rx Count - R/clr */
|
||||
#define E1000_XOFFTXC 0x04054 /* XOFF Tx Count - R/clr */
|
||||
#define E1000_FCRUC 0x04058 /* Flow Control Rx Unsupported Count- R/clr */
|
||||
#define E1000_PRC64 0x0405C /* Packets Rx (64 bytes) - R/clr */
|
||||
#define E1000_PRC127 0x04060 /* Packets Rx (65-127 bytes) - R/clr */
|
||||
#define E1000_PRC255 0x04064 /* Packets Rx (128-255 bytes) - R/clr */
|
||||
#define E1000_PRC511 0x04068 /* Packets Rx (255-511 bytes) - R/clr */
|
||||
#define E1000_PRC1023 0x0406C /* Packets Rx (512-1023 bytes) - R/clr */
|
||||
#define E1000_PRC1522 0x04070 /* Packets Rx (1024-1522 bytes) - R/clr */
|
||||
#define E1000_GPRC 0x04074 /* Good Packets Rx Count - R/clr */
|
||||
#define E1000_BPRC 0x04078 /* Broadcast Packets Rx Count - R/clr */
|
||||
#define E1000_MPRC 0x0407C /* Multicast Packets Rx Count - R/clr */
|
||||
#define E1000_GPTC 0x04080 /* Good Packets Tx Count - R/clr */
|
||||
#define E1000_GORCL 0x04088 /* Good Octets Rx Count Low - R/clr */
|
||||
#define E1000_GORCH 0x0408C /* Good Octets Rx Count High - R/clr */
|
||||
#define E1000_GOTCL 0x04090 /* Good Octets Tx Count Low - R/clr */
|
||||
#define E1000_GOTCH 0x04094 /* Good Octets Tx Count High - R/clr */
|
||||
#define E1000_RNBC 0x040A0 /* Rx No Buffers Count - R/clr */
|
||||
#define E1000_RUC 0x040A4 /* Rx Undersize Count - R/clr */
|
||||
#define E1000_RFC 0x040A8 /* Rx Fragment Count - R/clr */
|
||||
#define E1000_ROC 0x040AC /* Rx Oversize Count - R/clr */
|
||||
#define E1000_RJC 0x040B0 /* Rx Jabber Count - R/clr */
|
||||
#define E1000_MGTPRC 0x040B4 /* Management Packets Rx Count - R/clr */
|
||||
#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
|
||||
#define E1000_MGTPTC 0x040BC /* Management Packets Tx Count - R/clr */
|
||||
#define E1000_TORL 0x040C0 /* Total Octets Rx Low - R/clr */
|
||||
#define E1000_TORH 0x040C4 /* Total Octets Rx High - R/clr */
|
||||
#define E1000_TOTL 0x040C8 /* Total Octets Tx Low - R/clr */
|
||||
#define E1000_TOTH 0x040CC /* Total Octets Tx High - R/clr */
|
||||
#define E1000_TPR 0x040D0 /* Total Packets Rx - R/clr */
|
||||
#define E1000_TPT 0x040D4 /* Total Packets Tx - R/clr */
|
||||
#define E1000_PTC64 0x040D8 /* Packets Tx (64 bytes) - R/clr */
|
||||
#define E1000_PTC127 0x040DC /* Packets Tx (65-127 bytes) - R/clr */
|
||||
#define E1000_PTC255 0x040E0 /* Packets Tx (128-255 bytes) - R/clr */
|
||||
#define E1000_PTC511 0x040E4 /* Packets Tx (256-511 bytes) - R/clr */
|
||||
#define E1000_PTC1023 0x040E8 /* Packets Tx (512-1023 bytes) - R/clr */
|
||||
#define E1000_PTC1522 0x040EC /* Packets Tx (1024-1522 Bytes) - R/clr */
|
||||
#define E1000_MPTC 0x040F0 /* Multicast Packets Tx Count - R/clr */
|
||||
#define E1000_BPTC 0x040F4 /* Broadcast Packets Tx Count - R/clr */
|
||||
#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context Tx - R/clr */
|
||||
#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context Tx Fail - R/clr */
|
||||
#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
|
||||
#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Pkt Timer Expire Count */
|
||||
#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Abs Timer Expire Count */
|
||||
#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Pkt Timer Expire Count */
|
||||
#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Abs Timer Expire Count */
|
||||
#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */
|
||||
#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Min Thresh Count */
|
||||
#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Desc Min Thresh Count */
|
||||
#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
|
||||
|
||||
#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
|
||||
#define E1000_PCS_CFG0 0x04200 /* PCS Configuration 0 - RW */
|
||||
#define E1000_PCS_LCTL 0x04208 /* PCS Link Control - RW */
|
||||
#define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */
|
||||
#define E1000_CBTMPC 0x0402C /* Circuit Breaker Tx Packet Count */
|
||||
#define E1000_HTDPMC 0x0403C /* Host Transmit Discarded Packets */
|
||||
#define E1000_CBRDPC 0x04044 /* Circuit Breaker Rx Dropped Count */
|
||||
#define E1000_CBRMPC 0x040FC /* Circuit Breaker Rx Packet Count */
|
||||
#define E1000_RPTHC 0x04104 /* Rx Packets To Host */
|
||||
#define E1000_HGPTC 0x04118 /* Host Good Packets Tx Count */
|
||||
#define E1000_HTCBDPC 0x04124 /* Host Tx Circuit Breaker Dropped Count */
|
||||
#define E1000_HGORCL 0x04128 /* Host Good Octets Received Count Low */
|
||||
#define E1000_HGORCH 0x0412C /* Host Good Octets Received Count High */
|
||||
#define E1000_HGOTCL 0x04130 /* Host Good Octets Transmit Count Low */
|
||||
#define E1000_HGOTCH 0x04134 /* Host Good Octets Transmit Count High */
|
||||
#define E1000_LENERRS 0x04138 /* Length Errors Count */
|
||||
#define E1000_SCVPC 0x04228 /* SerDes/SGMII Code Violation Pkt Count */
|
||||
#define E1000_HRMPC 0x0A018 /* Header Redirection Missed Packet Count */
|
||||
#define E1000_PCS_ANADV 0x04218 /* AN advertisement - RW */
|
||||
#define E1000_PCS_LPAB 0x0421C /* Link Partner Ability - RW */
|
||||
#define E1000_PCS_NPTX 0x04220 /* AN Next Page Transmit - RW */
|
||||
#define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Page - RW */
|
||||
#define E1000_1GSTAT_RCV 0x04228 /* 1GSTAT Code Violation Packet Count - RW */
|
||||
#define E1000_RXCSUM 0x05000 /* Rx Checksum Control - RW */
|
||||
#define E1000_RLPML 0x05004 /* Rx Long Packet Max Length */
|
||||
#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
|
||||
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
|
||||
#define E1000_RA 0x05400 /* Receive Address - RW Array */
|
||||
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
|
||||
#define E1000_VT_CTL 0x0581C /* VMDq Control - RW */
|
||||
#define E1000_VFQA0 0x0B000 /* VLAN Filter Queue Array 0 - RW Array */
|
||||
#define E1000_VFQA1 0x0B200 /* VLAN Filter Queue Array 1 - RW Array */
|
||||
#define E1000_WUC 0x05800 /* Wakeup Control - RW */
|
||||
#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
|
||||
#define E1000_WUS 0x05810 /* Wakeup Status - RO */
|
||||
#define E1000_MANC 0x05820 /* Management Control - RW */
|
||||
#define E1000_IPAV 0x05838 /* IP Address Valid - RW */
|
||||
#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */
|
||||
#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */
|
||||
#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */
|
||||
#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */
|
||||
#define E1000_PBACL 0x05B68 /* MSIx PBA Clear - Read/Write 1's to clear */
|
||||
#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */
|
||||
#define E1000_HOST_IF 0x08800 /* Host Interface */
|
||||
#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
|
||||
#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */
|
||||
|
||||
#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */
|
||||
#define E1000_MDPHYA 0x0003C /* PHY address - RW */
|
||||
#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
|
||||
#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
|
||||
#define E1000_CCMCTL 0x05B48 /* CCM Control Register */
|
||||
#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */
|
||||
#define E1000_SCCTL 0x05B4C /* PCIc PLL Configuration Register */
|
||||
#define E1000_GCR 0x05B00 /* PCI-Ex Control */
|
||||
#define E1000_GCR2 0x05B64 /* PCI-Ex Control #2 */
|
||||
#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */
|
||||
#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */
|
||||
#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */
|
||||
#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */
|
||||
#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
|
||||
#define E1000_SWSM 0x05B50 /* SW Semaphore */
|
||||
#define E1000_FWSM 0x05B54 /* FW Semaphore */
|
||||
#define E1000_SWSM2 0x05B58 /* Driver-only SW semaphore (not used by BOOT agents) */
|
||||
#define E1000_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */
|
||||
#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */
|
||||
#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
|
||||
#define E1000_HICR 0x08F00 /* Host Interface Control */
|
||||
|
||||
/* RSS registers */
|
||||
#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
|
||||
#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
|
||||
#define E1000_IMIR(_i) (0x05A80 + ((_i) * 4)) /* Immediate Interrupt */
|
||||
#define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate Interrupt Ext*/
|
||||
#define E1000_IMIRVP 0x05AC0 /* Immediate Interrupt Rx VLAN Priority - RW */
|
||||
#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4)) /* MSI-X Allocation Register
|
||||
* (_i) - RW */
|
||||
#define E1000_MSIXTADD(_i) (0x0C000 + ((_i) * 0x10)) /* MSI-X Table entry addr
|
||||
* low reg - RW */
|
||||
#define E1000_MSIXTUADD(_i) (0x0C004 + ((_i) * 0x10)) /* MSI-X Table entry addr
|
||||
* upper reg - RW */
|
||||
#define E1000_MSIXTMSG(_i) (0x0C008 + ((_i) * 0x10)) /* MSI-X Table entry
|
||||
* message reg - RW */
|
||||
#define E1000_MSIXVCTRL(_i) (0x0C00C + ((_i) * 0x10)) /* MSI-X Table entry
|
||||
* vector ctrl reg - RW */
|
||||
#define E1000_MSIXPBA 0x0E000 /* MSI-X Pending bit array */
|
||||
#define E1000_RETA(_i) (0x05C00 + ((_i) * 4)) /* Redirection Table - RW */
|
||||
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW */
|
||||
#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
|
||||
#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */
|
||||
|
||||
#endif /* _IGBVF_REGS_H_ */
|
455
src/drivers/net/igbvf/igbvf_vf.c
Normal file
455
src/drivers/net/igbvf/igbvf_vf.c
Normal file
@ -0,0 +1,455 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel(R) 82576 Virtual Function Linux driver
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
version 2, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
The full GNU General Public License is included in this distribution in
|
||||
the file called "COPYING".
|
||||
|
||||
Contact Information:
|
||||
Linux NICS <linux.nics@intel.com>
|
||||
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
|
||||
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
FILE_LICENCE ( GPL2_ONLY );
|
||||
|
||||
#include "igbvf_vf.h"
|
||||
|
||||
|
||||
static s32 igbvf_init_mac_params_vf(struct e1000_hw *hw);
|
||||
static s32 igbvf_check_for_link_vf(struct e1000_hw *hw);
|
||||
static s32 igbvf_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
|
||||
u16 *duplex);
|
||||
static s32 igbvf_init_hw_vf(struct e1000_hw *hw);
|
||||
static s32 igbvf_reset_hw_vf(struct e1000_hw *hw);
|
||||
static void igbvf_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *, u32);
|
||||
static void igbvf_rar_set_vf(struct e1000_hw *, u8 *, u32);
|
||||
static s32 igbvf_read_mac_addr_vf(struct e1000_hw *);
|
||||
|
||||
/**
|
||||
* igbvf_init_mac_params_vf - Inits MAC params
|
||||
* @hw: pointer to the HW structure
|
||||
**/
|
||||
static s32 igbvf_init_mac_params_vf(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_mac_info *mac = &hw->mac;
|
||||
|
||||
DEBUGFUNC("igbvf_init_mac_params_vf");
|
||||
|
||||
/* 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 */
|
||||
/* reset */
|
||||
mac->ops.reset_hw = igbvf_reset_hw_vf;
|
||||
/* hw initialization */
|
||||
mac->ops.init_hw = igbvf_init_hw_vf;
|
||||
/* check for link */
|
||||
mac->ops.check_for_link = igbvf_check_for_link_vf;
|
||||
/* link info */
|
||||
mac->ops.get_link_up_info = igbvf_get_link_up_info_vf;
|
||||
/* multicast address update */
|
||||
mac->ops.update_mc_addr_list = igbvf_update_mc_addr_list_vf;
|
||||
/* set mac address */
|
||||
mac->ops.rar_set = igbvf_rar_set_vf;
|
||||
/* read mac address */
|
||||
mac->ops.read_mac_addr = igbvf_read_mac_addr_vf;
|
||||
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_init_function_pointers_vf - Inits function pointers
|
||||
* @hw: pointer to the HW structure
|
||||
**/
|
||||
void igbvf_init_function_pointers_vf(struct e1000_hw *hw)
|
||||
{
|
||||
DEBUGFUNC("igbvf_init_function_pointers_vf");
|
||||
|
||||
hw->mac.ops.init_params = igbvf_init_mac_params_vf;
|
||||
hw->mbx.ops.init_params = igbvf_init_mbx_params_vf;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
|
||||
u16 *duplex)
|
||||
{
|
||||
s32 status;
|
||||
|
||||
DEBUGFUNC("igbvf_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_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("igbvf_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_init_hw_vf(struct e1000_hw *hw)
|
||||
{
|
||||
DEBUGFUNC("igbvf_init_hw_vf");
|
||||
|
||||
/* attempt to set and restore our mac address */
|
||||
igbvf_rar_set_vf(hw, hw->mac.addr, 0);
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_rar_set_vf(struct e1000_hw *hw, u8 * addr, u32 index __unused)
|
||||
{
|
||||
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)))
|
||||
igbvf_read_mac_addr_vf(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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. See
|
||||
* igbvf_mta_set_generic()
|
||||
**/
|
||||
static u32 igbvf_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr)
|
||||
{
|
||||
u32 hash_value, hash_mask;
|
||||
u8 bit_shift = 0;
|
||||
|
||||
DEBUGFUNC("igbvf_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_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("igbvf_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);
|
||||
|
||||
msgbuf[0] = E1000_VF_SET_MULTICAST;
|
||||
|
||||
if (mc_addr_count > 30) {
|
||||
msgbuf[0] |= E1000_VF_SET_MULTICAST_OVERFLOW;
|
||||
mc_addr_count = 30;
|
||||
}
|
||||
|
||||
msgbuf[0] |= mc_addr_count << E1000_VT_MSGINFO_SHIFT;
|
||||
|
||||
for (i = 0; i < mc_addr_count; i++) {
|
||||
hash_value = igbvf_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);
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_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);
|
||||
}
|
||||
|
||||
/** igbvf_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 igbvf_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);
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_read_mac_addr_vf - Read device MAC address
|
||||
* @hw: pointer to the HW structure
|
||||
**/
|
||||
static s32 igbvf_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* igbvf_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 igbvf_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("igbvf_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;
|
||||
}
|
||||
|
345
src/drivers/net/igbvf/igbvf_vf.h
Normal file
345
src/drivers/net/igbvf/igbvf_vf.h
Normal file
@ -0,0 +1,345 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel(R) 82576 Virtual Function Linux driver
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
version 2, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
The full GNU General Public License is included in this distribution in
|
||||
the file called "COPYING".
|
||||
|
||||
Contact Information:
|
||||
Linux NICS <linux.nics@intel.com>
|
||||
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
|
||||
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
FILE_LICENCE ( GPL2_ONLY );
|
||||
|
||||
#ifndef _IGBVF_VF_H_
|
||||
#define _IGBVF_VF_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <byteswap.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/pci.h>
|
||||
#include <ipxe/malloc.h>
|
||||
#include <ipxe/if_ether.h>
|
||||
#include <ipxe/io.h>
|
||||
#include <ipxe/ethernet.h>
|
||||
#include <ipxe/iobuf.h>
|
||||
#include <ipxe/netdevice.h>
|
||||
|
||||
#include "igbvf_osdep.h"
|
||||
#include "igbvf_regs.h"
|
||||
#include "igbvf_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 "igbvf_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 (*mta_set)(struct e1000_hw *, 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;
|
||||
};
|
||||
|
||||
enum e1000_bus_type {
|
||||
e1000_bus_type_unknown = 0,
|
||||
e1000_bus_type_pci,
|
||||
e1000_bus_type_pcix,
|
||||
e1000_bus_type_pci_express,
|
||||
e1000_bus_type_reserved
|
||||
};
|
||||
|
||||
enum e1000_bus_speed {
|
||||
e1000_bus_speed_unknown = 0,
|
||||
e1000_bus_speed_33,
|
||||
e1000_bus_speed_66,
|
||||
e1000_bus_speed_100,
|
||||
e1000_bus_speed_120,
|
||||
e1000_bus_speed_133,
|
||||
e1000_bus_speed_2500,
|
||||
e1000_bus_speed_5000,
|
||||
e1000_bus_speed_reserved
|
||||
};
|
||||
|
||||
enum e1000_bus_width {
|
||||
e1000_bus_width_unknown = 0,
|
||||
e1000_bus_width_pcie_x1,
|
||||
e1000_bus_width_pcie_x2,
|
||||
e1000_bus_width_pcie_x4 = 4,
|
||||
e1000_bus_width_pcie_x8 = 8,
|
||||
e1000_bus_width_32,
|
||||
e1000_bus_width_64,
|
||||
e1000_bus_width_reserved
|
||||
};
|
||||
|
||||
struct e1000_bus_info {
|
||||
enum e1000_bus_type type;
|
||||
enum e1000_bus_speed speed;
|
||||
enum e1000_bus_width width;
|
||||
|
||||
u16 func;
|
||||
u16 pci_cmd_word;
|
||||
};
|
||||
|
||||
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 __iomem *hw_addr;
|
||||
u8 __iomem *flash_address;
|
||||
unsigned long io_base;
|
||||
|
||||
struct e1000_mac_info mac;
|
||||
struct e1000_bus_info bus;
|
||||
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 igbvf_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
|
||||
void igbvf_vfta_set_vf(struct e1000_hw *, u16, bool);
|
||||
void igbvf_rlpml_set_vf(struct e1000_hw *, u16);
|
||||
s32 igbvf_promisc_set_vf(struct e1000_hw *, enum e1000_promisc_type);
|
||||
#endif /* _IGBVF_VF_H_ */
|
@ -135,6 +135,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
#define ERRFILE_jme ( ERRFILE_DRIVER | 0x005b0000 )
|
||||
#define ERRFILE_virtio_net ( ERRFILE_DRIVER | 0x005c0000 )
|
||||
#define ERRFILE_tap ( ERRFILE_DRIVER | 0x005d0000 )
|
||||
#define ERRFILE_igbvf_main ( ERRFILE_DRIVER | 0x005e0000 )
|
||||
|
||||
#define ERRFILE_scsi ( ERRFILE_DRIVER | 0x00700000 )
|
||||
#define ERRFILE_arbel ( ERRFILE_DRIVER | 0x00710000 )
|
||||
|
Loading…
x
Reference in New Issue
Block a user