Creation of Cybook 2416 (actually Gen4) repository

This commit is contained in:
mlt
2009-12-18 17:10:00 +00:00
committed by godzil
commit 76f20f4d40
13791 changed files with 6812321 additions and 0 deletions

35
drivers/net/ixgb/Makefile Normal file
View File

@@ -0,0 +1,35 @@
################################################################################
#
# Intel PRO/10GbE Linux driver
# Copyright(c) 1999 - 2006 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
#
################################################################################
#
# Makefile for the Intel(R) PRO/10GbE ethernet driver
#
obj-$(CONFIG_IXGB) += ixgb.o
ixgb-objs := ixgb_main.o ixgb_hw.o ixgb_ee.o ixgb_ethtool.o ixgb_param.o

203
drivers/net/ixgb/ixgb.h Normal file
View File

@@ -0,0 +1,203 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
Copyright(c) 1999 - 2006 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
*******************************************************************************/
#ifndef _IXGB_H_
#define _IXGB_H_
#include <linux/stddef.h>
#include <linux/module.h>
#include <linux/types.h>
#include <asm/byteorder.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#include <linux/pagemap.h>
#include <linux/dma-mapping.h>
#include <linux/bitops.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <linux/capability.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <net/pkt_sched.h>
#include <linux/list.h>
#include <linux/reboot.h>
#include <net/checksum.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#define BAR_0 0
#define BAR_1 1
#define BAR_5 5
struct ixgb_adapter;
#include "ixgb_hw.h"
#include "ixgb_ee.h"
#include "ixgb_ids.h"
#ifdef _DEBUG_DRIVER_
#define IXGB_DBG(args...) printk(KERN_DEBUG "ixgb: " args)
#else
#define IXGB_DBG(args...)
#endif
#define PFX "ixgb: "
#define DPRINTK(nlevel, klevel, fmt, args...) \
(void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \
__FUNCTION__ , ## args))
/* TX/RX descriptor defines */
#define DEFAULT_TXD 256
#define MAX_TXD 4096
#define MIN_TXD 64
/* hardware cannot reliably support more than 512 descriptors owned by
* hardware descrioptor cache otherwise an unreliable ring under heavy
* recieve load may result */
/* #define DEFAULT_RXD 1024 */
/* #define MAX_RXD 4096 */
#define DEFAULT_RXD 512
#define MAX_RXD 512
#define MIN_RXD 64
/* Supported Rx Buffer Sizes */
#define IXGB_RXBUFFER_2048 2048
#define IXGB_RXBUFFER_4096 4096
#define IXGB_RXBUFFER_8192 8192
#define IXGB_RXBUFFER_16384 16384
/* How many Rx Buffers do we bundle into one write to the hardware ? */
#define IXGB_RX_BUFFER_WRITE 8 /* Must be power of 2 */
/* only works for sizes that are powers of 2 */
#define IXGB_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
/* wrapper around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer */
struct ixgb_buffer {
struct sk_buff *skb;
dma_addr_t dma;
unsigned long time_stamp;
uint16_t length;
uint16_t next_to_watch;
};
struct ixgb_desc_ring {
/* pointer to the descriptor ring memory */
void *desc;
/* physical address of the descriptor ring */
dma_addr_t dma;
/* length of descriptor ring in bytes */
unsigned int size;
/* number of descriptors in the ring */
unsigned int count;
/* next descriptor to associate a buffer with */
unsigned int next_to_use;
/* next descriptor to check for DD status bit */
unsigned int next_to_clean;
/* array of buffer information structs */
struct ixgb_buffer *buffer_info;
};
#define IXGB_DESC_UNUSED(R) \
((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
(R)->next_to_clean - (R)->next_to_use - 1)
#define IXGB_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))
#define IXGB_RX_DESC(R, i) IXGB_GET_DESC(R, i, ixgb_rx_desc)
#define IXGB_TX_DESC(R, i) IXGB_GET_DESC(R, i, ixgb_tx_desc)
#define IXGB_CONTEXT_DESC(R, i) IXGB_GET_DESC(R, i, ixgb_context_desc)
/* board specific private data structure */
struct ixgb_adapter {
struct timer_list watchdog_timer;
struct vlan_group *vlgrp;
uint32_t bd_number;
uint32_t rx_buffer_len;
uint32_t part_num;
uint16_t link_speed;
uint16_t link_duplex;
spinlock_t tx_lock;
atomic_t irq_sem;
struct work_struct tx_timeout_task;
struct timer_list blink_timer;
unsigned long led_status;
/* TX */
struct ixgb_desc_ring tx_ring ____cacheline_aligned_in_smp;
unsigned int restart_queue;
unsigned long timeo_start;
uint32_t tx_cmd_type;
uint64_t hw_csum_tx_good;
uint64_t hw_csum_tx_error;
uint32_t tx_int_delay;
uint32_t tx_timeout_count;
boolean_t tx_int_delay_enable;
boolean_t detect_tx_hung;
/* RX */
struct ixgb_desc_ring rx_ring;
uint64_t hw_csum_rx_error;
uint64_t hw_csum_rx_good;
uint32_t rx_int_delay;
boolean_t rx_csum;
/* OS defined structs */
struct net_device *netdev;
struct pci_dev *pdev;
struct net_device_stats net_stats;
/* structs defined in ixgb_hw.h */
struct ixgb_hw hw;
u16 msg_enable;
struct ixgb_hw_stats stats;
uint32_t alloc_rx_buff_failed;
#ifdef CONFIG_PCI_MSI
boolean_t have_msi;
#endif
};
#endif /* _IXGB_H_ */

606
drivers/net/ixgb/ixgb_ee.c Normal file
View File

@@ -0,0 +1,606 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
Copyright(c) 1999 - 2006 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
*******************************************************************************/
#include "ixgb_hw.h"
#include "ixgb_ee.h"
/* Local prototypes */
static uint16_t ixgb_shift_in_bits(struct ixgb_hw *hw);
static void ixgb_shift_out_bits(struct ixgb_hw *hw,
uint16_t data,
uint16_t count);
static void ixgb_standby_eeprom(struct ixgb_hw *hw);
static boolean_t ixgb_wait_eeprom_command(struct ixgb_hw *hw);
static void ixgb_cleanup_eeprom(struct ixgb_hw *hw);
/******************************************************************************
* Raises the EEPROM's clock input.
*
* hw - Struct containing variables accessed by shared code
* eecd_reg - EECD's current value
*****************************************************************************/
static void
ixgb_raise_clock(struct ixgb_hw *hw,
uint32_t *eecd_reg)
{
/* Raise the clock input to the EEPROM (by setting the SK bit), and then
* wait 50 microseconds.
*/
*eecd_reg = *eecd_reg | IXGB_EECD_SK;
IXGB_WRITE_REG(hw, EECD, *eecd_reg);
udelay(50);
return;
}
/******************************************************************************
* Lowers the EEPROM's clock input.
*
* hw - Struct containing variables accessed by shared code
* eecd_reg - EECD's current value
*****************************************************************************/
static void
ixgb_lower_clock(struct ixgb_hw *hw,
uint32_t *eecd_reg)
{
/* Lower the clock input to the EEPROM (by clearing the SK bit), and then
* wait 50 microseconds.
*/
*eecd_reg = *eecd_reg & ~IXGB_EECD_SK;
IXGB_WRITE_REG(hw, EECD, *eecd_reg);
udelay(50);
return;
}
/******************************************************************************
* Shift data bits out to the EEPROM.
*
* hw - Struct containing variables accessed by shared code
* data - data to send to the EEPROM
* count - number of bits to shift out
*****************************************************************************/
static void
ixgb_shift_out_bits(struct ixgb_hw *hw,
uint16_t data,
uint16_t count)
{
uint32_t eecd_reg;
uint32_t mask;
/* We need to shift "count" bits out to the EEPROM. So, value in the
* "data" parameter will be shifted out to the EEPROM one bit at a time.
* In order to do this, "data" must be broken down into bits.
*/
mask = 0x01 << (count - 1);
eecd_reg = IXGB_READ_REG(hw, EECD);
eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI);
do {
/* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
* and then raising and then lowering the clock (the SK bit controls
* the clock input to the EEPROM). A "0" is shifted out to the EEPROM
* by setting "DI" to "0" and then raising and then lowering the clock.
*/
eecd_reg &= ~IXGB_EECD_DI;
if(data & mask)
eecd_reg |= IXGB_EECD_DI;
IXGB_WRITE_REG(hw, EECD, eecd_reg);
udelay(50);
ixgb_raise_clock(hw, &eecd_reg);
ixgb_lower_clock(hw, &eecd_reg);
mask = mask >> 1;
} while(mask);
/* We leave the "DI" bit set to "0" when we leave this routine. */
eecd_reg &= ~IXGB_EECD_DI;
IXGB_WRITE_REG(hw, EECD, eecd_reg);
return;
}
/******************************************************************************
* Shift data bits in from the EEPROM
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static uint16_t
ixgb_shift_in_bits(struct ixgb_hw *hw)
{
uint32_t eecd_reg;
uint32_t i;
uint16_t data;
/* In order to read a register from the EEPROM, we need to shift 16 bits
* in from the EEPROM. Bits are "shifted in" by raising the clock input to
* the EEPROM (setting the SK bit), and then reading the value of the "DO"
* bit. During this "shifting in" process the "DI" bit should always be
* clear..
*/
eecd_reg = IXGB_READ_REG(hw, EECD);
eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI);
data = 0;
for(i = 0; i < 16; i++) {
data = data << 1;
ixgb_raise_clock(hw, &eecd_reg);
eecd_reg = IXGB_READ_REG(hw, EECD);
eecd_reg &= ~(IXGB_EECD_DI);
if(eecd_reg & IXGB_EECD_DO)
data |= 1;
ixgb_lower_clock(hw, &eecd_reg);
}
return data;
}
/******************************************************************************
* Prepares EEPROM for access
*
* hw - Struct containing variables accessed by shared code
*
* Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
* function should be called before issuing a command to the EEPROM.
*****************************************************************************/
static void
ixgb_setup_eeprom(struct ixgb_hw *hw)
{
uint32_t eecd_reg;
eecd_reg = IXGB_READ_REG(hw, EECD);
/* Clear SK and DI */
eecd_reg &= ~(IXGB_EECD_SK | IXGB_EECD_DI);
IXGB_WRITE_REG(hw, EECD, eecd_reg);
/* Set CS */
eecd_reg |= IXGB_EECD_CS;
IXGB_WRITE_REG(hw, EECD, eecd_reg);
return;
}
/******************************************************************************
* Returns EEPROM to a "standby" state
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static void
ixgb_standby_eeprom(struct ixgb_hw *hw)
{
uint32_t eecd_reg;
eecd_reg = IXGB_READ_REG(hw, EECD);
/* Deselct EEPROM */
eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_SK);
IXGB_WRITE_REG(hw, EECD, eecd_reg);
udelay(50);
/* Clock high */
eecd_reg |= IXGB_EECD_SK;
IXGB_WRITE_REG(hw, EECD, eecd_reg);
udelay(50);
/* Select EEPROM */
eecd_reg |= IXGB_EECD_CS;
IXGB_WRITE_REG(hw, EECD, eecd_reg);
udelay(50);
/* Clock low */
eecd_reg &= ~IXGB_EECD_SK;
IXGB_WRITE_REG(hw, EECD, eecd_reg);
udelay(50);
return;
}
/******************************************************************************
* Raises then lowers the EEPROM's clock pin
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static void
ixgb_clock_eeprom(struct ixgb_hw *hw)
{
uint32_t eecd_reg;
eecd_reg = IXGB_READ_REG(hw, EECD);
/* Rising edge of clock */
eecd_reg |= IXGB_EECD_SK;
IXGB_WRITE_REG(hw, EECD, eecd_reg);
udelay(50);
/* Falling edge of clock */
eecd_reg &= ~IXGB_EECD_SK;
IXGB_WRITE_REG(hw, EECD, eecd_reg);
udelay(50);
return;
}
/******************************************************************************
* Terminates a command by lowering the EEPROM's chip select pin
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static void
ixgb_cleanup_eeprom(struct ixgb_hw *hw)
{
uint32_t eecd_reg;
eecd_reg = IXGB_READ_REG(hw, EECD);
eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_DI);
IXGB_WRITE_REG(hw, EECD, eecd_reg);
ixgb_clock_eeprom(hw);
return;
}
/******************************************************************************
* Waits for the EEPROM to finish the current command.
*
* hw - Struct containing variables accessed by shared code
*
* The command is done when the EEPROM's data out pin goes high.
*
* Returns:
* TRUE: EEPROM data pin is high before timeout.
* FALSE: Time expired.
*****************************************************************************/
static boolean_t
ixgb_wait_eeprom_command(struct ixgb_hw *hw)
{
uint32_t eecd_reg;
uint32_t i;
/* Toggle the CS line. This in effect tells to EEPROM to actually execute
* the command in question.
*/
ixgb_standby_eeprom(hw);
/* Now read DO repeatedly until is high (equal to '1'). The EEEPROM will
* signal that the command has been completed by raising the DO signal.
* If DO does not go high in 10 milliseconds, then error out.
*/
for(i = 0; i < 200; i++) {
eecd_reg = IXGB_READ_REG(hw, EECD);
if(eecd_reg & IXGB_EECD_DO)
return (TRUE);
udelay(50);
}
ASSERT(0);
return (FALSE);
}
/******************************************************************************
* Verifies that the EEPROM has a valid checksum
*
* hw - Struct containing variables accessed by shared code
*
* Reads the first 64 16 bit words of the EEPROM and sums the values read.
* If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
* valid.
*
* Returns:
* TRUE: Checksum is valid
* FALSE: Checksum is not valid.
*****************************************************************************/
boolean_t
ixgb_validate_eeprom_checksum(struct ixgb_hw *hw)
{
uint16_t checksum = 0;
uint16_t i;
for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++)
checksum += ixgb_read_eeprom(hw, i);
if(checksum == (uint16_t) EEPROM_SUM)
return (TRUE);
else
return (FALSE);
}
/******************************************************************************
* Calculates the EEPROM checksum and writes it to the EEPROM
*
* hw - Struct containing variables accessed by shared code
*
* Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
* Writes the difference to word offset 63 of the EEPROM.
*****************************************************************************/
void
ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
{
uint16_t checksum = 0;
uint16_t i;
for(i = 0; i < EEPROM_CHECKSUM_REG; i++)
checksum += ixgb_read_eeprom(hw, i);
checksum = (uint16_t) EEPROM_SUM - checksum;
ixgb_write_eeprom(hw, EEPROM_CHECKSUM_REG, checksum);
return;
}
/******************************************************************************
* Writes a 16 bit word to a given offset in the EEPROM.
*
* hw - Struct containing variables accessed by shared code
* reg - offset within the EEPROM to be written to
* data - 16 bit word to be writen to the EEPROM
*
* If ixgb_update_eeprom_checksum is not called after this function, the
* EEPROM will most likely contain an invalid checksum.
*
*****************************************************************************/
void
ixgb_write_eeprom(struct ixgb_hw *hw, uint16_t offset, uint16_t data)
{
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
/* Prepare the EEPROM for writing */
ixgb_setup_eeprom(hw);
/* Send the 9-bit EWEN (write enable) command to the EEPROM (5-bit opcode
* plus 4-bit dummy). This puts the EEPROM into write/erase mode.
*/
ixgb_shift_out_bits(hw, EEPROM_EWEN_OPCODE, 5);
ixgb_shift_out_bits(hw, 0, 4);
/* Prepare the EEPROM */
ixgb_standby_eeprom(hw);
/* Send the Write command (3-bit opcode + 6-bit addr) */
ixgb_shift_out_bits(hw, EEPROM_WRITE_OPCODE, 3);
ixgb_shift_out_bits(hw, offset, 6);
/* Send the data */
ixgb_shift_out_bits(hw, data, 16);
ixgb_wait_eeprom_command(hw);
/* Recover from write */
ixgb_standby_eeprom(hw);
/* Send the 9-bit EWDS (write disable) command to the EEPROM (5-bit
* opcode plus 4-bit dummy). This takes the EEPROM out of write/erase
* mode.
*/
ixgb_shift_out_bits(hw, EEPROM_EWDS_OPCODE, 5);
ixgb_shift_out_bits(hw, 0, 4);
/* Done with writing */
ixgb_cleanup_eeprom(hw);
/* clear the init_ctrl_reg_1 to signify that the cache is invalidated */
ee_map->init_ctrl_reg_1 = le16_to_cpu(EEPROM_ICW1_SIGNATURE_CLEAR);
return;
}
/******************************************************************************
* Reads a 16 bit word from the EEPROM.
*
* hw - Struct containing variables accessed by shared code
* offset - offset of 16 bit word in the EEPROM to read
*
* Returns:
* The 16-bit value read from the eeprom
*****************************************************************************/
uint16_t
ixgb_read_eeprom(struct ixgb_hw *hw,
uint16_t offset)
{
uint16_t data;
/* Prepare the EEPROM for reading */
ixgb_setup_eeprom(hw);
/* Send the READ command (opcode + addr) */
ixgb_shift_out_bits(hw, EEPROM_READ_OPCODE, 3);
/*
* We have a 64 word EEPROM, there are 6 address bits
*/
ixgb_shift_out_bits(hw, offset, 6);
/* Read the data */
data = ixgb_shift_in_bits(hw);
/* End this read operation */
ixgb_standby_eeprom(hw);
return (data);
}
/******************************************************************************
* Reads eeprom and stores data in shared structure.
* Validates eeprom checksum and eeprom signature.
*
* hw - Struct containing variables accessed by shared code
*
* Returns:
* TRUE: if eeprom read is successful
* FALSE: otherwise.
*****************************************************************************/
boolean_t
ixgb_get_eeprom_data(struct ixgb_hw *hw)
{
uint16_t i;
uint16_t checksum = 0;
struct ixgb_ee_map_type *ee_map;
DEBUGFUNC("ixgb_get_eeprom_data");
ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
DEBUGOUT("ixgb_ee: Reading eeprom data\n");
for(i = 0; i < IXGB_EEPROM_SIZE ; i++) {
uint16_t ee_data;
ee_data = ixgb_read_eeprom(hw, i);
checksum += ee_data;
hw->eeprom[i] = le16_to_cpu(ee_data);
}
if (checksum != (uint16_t) EEPROM_SUM) {
DEBUGOUT("ixgb_ee: Checksum invalid.\n");
/* clear the init_ctrl_reg_1 to signify that the cache is
* invalidated */
ee_map->init_ctrl_reg_1 = le16_to_cpu(EEPROM_ICW1_SIGNATURE_CLEAR);
return (FALSE);
}
if ((ee_map->init_ctrl_reg_1 & le16_to_cpu(EEPROM_ICW1_SIGNATURE_MASK))
!= le16_to_cpu(EEPROM_ICW1_SIGNATURE_VALID)) {
DEBUGOUT("ixgb_ee: Signature invalid.\n");
return(FALSE);
}
return(TRUE);
}
/******************************************************************************
* Local function to check if the eeprom signature is good
* If the eeprom signature is good, calls ixgb)get_eeprom_data.
*
* hw - Struct containing variables accessed by shared code
*
* Returns:
* TRUE: eeprom signature was good and the eeprom read was successful
* FALSE: otherwise.
******************************************************************************/
static boolean_t
ixgb_check_and_get_eeprom_data (struct ixgb_hw* hw)
{
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
if ((ee_map->init_ctrl_reg_1 & le16_to_cpu(EEPROM_ICW1_SIGNATURE_MASK))
== le16_to_cpu(EEPROM_ICW1_SIGNATURE_VALID)) {
return (TRUE);
} else {
return ixgb_get_eeprom_data(hw);
}
}
/******************************************************************************
* return a word from the eeprom
*
* hw - Struct containing variables accessed by shared code
* index - Offset of eeprom word
*
* Returns:
* Word at indexed offset in eeprom, if valid, 0 otherwise.
******************************************************************************/
uint16_t
ixgb_get_eeprom_word(struct ixgb_hw *hw, uint16_t index)
{
if ((index < IXGB_EEPROM_SIZE) &&
(ixgb_check_and_get_eeprom_data(hw) == TRUE)) {
return(hw->eeprom[index]);
}
return(0);
}
/******************************************************************************
* return the mac address from EEPROM
*
* hw - Struct containing variables accessed by shared code
* mac_addr - Ethernet Address if EEPROM contents are valid, 0 otherwise
*
* Returns: None.
******************************************************************************/
void
ixgb_get_ee_mac_addr(struct ixgb_hw *hw,
uint8_t *mac_addr)
{
int i;
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
DEBUGFUNC("ixgb_get_ee_mac_addr");
if (ixgb_check_and_get_eeprom_data(hw) == TRUE) {
for (i = 0; i < IXGB_ETH_LENGTH_OF_ADDRESS; i++) {
mac_addr[i] = ee_map->mac_addr[i];
DEBUGOUT2("mac(%d) = %.2X\n", i, mac_addr[i]);
}
}
}
/******************************************************************************
* return the Printed Board Assembly number from EEPROM
*
* hw - Struct containing variables accessed by shared code
*
* Returns:
* PBA number if EEPROM contents are valid, 0 otherwise
******************************************************************************/
uint32_t
ixgb_get_ee_pba_number(struct ixgb_hw *hw)
{
if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG])
| (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG])<<16));
return(0);
}
/******************************************************************************
* return the Device Id from EEPROM
*
* hw - Struct containing variables accessed by shared code
*
* Returns:
* Device Id if EEPROM contents are valid, 0 otherwise
******************************************************************************/
uint16_t
ixgb_get_ee_device_id(struct ixgb_hw *hw)
{
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (le16_to_cpu(ee_map->device_id));
return (0);
}

106
drivers/net/ixgb/ixgb_ee.h Normal file
View File

@@ -0,0 +1,106 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
Copyright(c) 1999 - 2006 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
*******************************************************************************/
#ifndef _IXGB_EE_H_
#define _IXGB_EE_H_
#define IXGB_EEPROM_SIZE 64 /* Size in words */
#define IXGB_ETH_LENGTH_OF_ADDRESS 6
/* EEPROM Commands */
#define EEPROM_READ_OPCODE 0x6 /* EERPOM read opcode */
#define EEPROM_WRITE_OPCODE 0x5 /* EERPOM write opcode */
#define EEPROM_ERASE_OPCODE 0x7 /* EERPOM erase opcode */
#define EEPROM_EWEN_OPCODE 0x13 /* EERPOM erase/write enable */
#define EEPROM_EWDS_OPCODE 0x10 /* EERPOM erast/write disable */
/* EEPROM MAP (Word Offsets) */
#define EEPROM_IA_1_2_REG 0x0000
#define EEPROM_IA_3_4_REG 0x0001
#define EEPROM_IA_5_6_REG 0x0002
#define EEPROM_COMPATIBILITY_REG 0x0003
#define EEPROM_PBA_1_2_REG 0x0008
#define EEPROM_PBA_3_4_REG 0x0009
#define EEPROM_INIT_CONTROL1_REG 0x000A
#define EEPROM_SUBSYS_ID_REG 0x000B
#define EEPROM_SUBVEND_ID_REG 0x000C
#define EEPROM_DEVICE_ID_REG 0x000D
#define EEPROM_VENDOR_ID_REG 0x000E
#define EEPROM_INIT_CONTROL2_REG 0x000F
#define EEPROM_SWDPINS_REG 0x0020
#define EEPROM_CIRCUIT_CTRL_REG 0x0021
#define EEPROM_D0_D3_POWER_REG 0x0022
#define EEPROM_FLASH_VERSION 0x0032
#define EEPROM_CHECKSUM_REG 0x003F
/* Mask bits for fields in Word 0x0a of the EEPROM */
#define EEPROM_ICW1_SIGNATURE_MASK 0xC000
#define EEPROM_ICW1_SIGNATURE_VALID 0x4000
#define EEPROM_ICW1_SIGNATURE_CLEAR 0x0000
/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
#define EEPROM_SUM 0xBABA
/* EEPROM Map Sizes (Byte Counts) */
#define PBA_SIZE 4
/* EEPROM Map defines (WORD OFFSETS)*/
/* EEPROM structure */
struct ixgb_ee_map_type {
uint8_t mac_addr[IXGB_ETH_LENGTH_OF_ADDRESS];
uint16_t compatibility;
uint16_t reserved1[4];
uint32_t pba_number;
uint16_t init_ctrl_reg_1;
uint16_t subsystem_id;
uint16_t subvendor_id;
uint16_t device_id;
uint16_t vendor_id;
uint16_t init_ctrl_reg_2;
uint16_t oem_reserved[16];
uint16_t swdpins_reg;
uint16_t circuit_ctrl_reg;
uint8_t d3_power;
uint8_t d0_power;
uint16_t reserved2[28];
uint16_t checksum;
};
/* EEPROM Functions */
uint16_t ixgb_read_eeprom(struct ixgb_hw *hw, uint16_t reg);
boolean_t ixgb_validate_eeprom_checksum(struct ixgb_hw *hw);
void ixgb_update_eeprom_checksum(struct ixgb_hw *hw);
void ixgb_write_eeprom(struct ixgb_hw *hw, uint16_t reg, uint16_t data);
#endif /* IXGB_EE_H */

View File

@@ -0,0 +1,733 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
Copyright(c) 1999 - 2006 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
*******************************************************************************/
/* ethtool support for ixgb */
#include "ixgb.h"
#include <asm/uaccess.h>
extern char ixgb_driver_name[];
extern char ixgb_driver_version[];
extern int ixgb_up(struct ixgb_adapter *adapter);
extern void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog);
extern void ixgb_reset(struct ixgb_adapter *adapter);
extern int ixgb_setup_rx_resources(struct ixgb_adapter *adapter);
extern int ixgb_setup_tx_resources(struct ixgb_adapter *adapter);
extern void ixgb_free_rx_resources(struct ixgb_adapter *adapter);
extern void ixgb_free_tx_resources(struct ixgb_adapter *adapter);
extern void ixgb_update_stats(struct ixgb_adapter *adapter);
#define IXGB_ALL_RAR_ENTRIES 16
struct ixgb_stats {
char stat_string[ETH_GSTRING_LEN];
int sizeof_stat;
int stat_offset;
};
#define IXGB_STAT(m) sizeof(((struct ixgb_adapter *)0)->m), \
offsetof(struct ixgb_adapter, m)
static struct ixgb_stats ixgb_gstrings_stats[] = {
{"rx_packets", IXGB_STAT(net_stats.rx_packets)},
{"tx_packets", IXGB_STAT(net_stats.tx_packets)},
{"rx_bytes", IXGB_STAT(net_stats.rx_bytes)},
{"tx_bytes", IXGB_STAT(net_stats.tx_bytes)},
{"rx_errors", IXGB_STAT(net_stats.rx_errors)},
{"tx_errors", IXGB_STAT(net_stats.tx_errors)},
{"rx_dropped", IXGB_STAT(net_stats.rx_dropped)},
{"tx_dropped", IXGB_STAT(net_stats.tx_dropped)},
{"multicast", IXGB_STAT(net_stats.multicast)},
{"collisions", IXGB_STAT(net_stats.collisions)},
/* { "rx_length_errors", IXGB_STAT(net_stats.rx_length_errors) }, */
{"rx_over_errors", IXGB_STAT(net_stats.rx_over_errors)},
{"rx_crc_errors", IXGB_STAT(net_stats.rx_crc_errors)},
{"rx_frame_errors", IXGB_STAT(net_stats.rx_frame_errors)},
{"rx_fifo_errors", IXGB_STAT(net_stats.rx_fifo_errors)},
{"rx_missed_errors", IXGB_STAT(net_stats.rx_missed_errors)},
{"tx_aborted_errors", IXGB_STAT(net_stats.tx_aborted_errors)},
{"tx_carrier_errors", IXGB_STAT(net_stats.tx_carrier_errors)},
{"tx_fifo_errors", IXGB_STAT(net_stats.tx_fifo_errors)},
{"tx_heartbeat_errors", IXGB_STAT(net_stats.tx_heartbeat_errors)},
{"tx_window_errors", IXGB_STAT(net_stats.tx_window_errors)},
{"tx_deferred_ok", IXGB_STAT(stats.dc)},
{"tx_timeout_count", IXGB_STAT(tx_timeout_count) },
{"tx_restart_queue", IXGB_STAT(restart_queue) },
{"rx_long_length_errors", IXGB_STAT(stats.roc)},
{"rx_short_length_errors", IXGB_STAT(stats.ruc)},
{"tx_tcp_seg_good", IXGB_STAT(stats.tsctc)},
{"tx_tcp_seg_failed", IXGB_STAT(stats.tsctfc)},
{"rx_flow_control_xon", IXGB_STAT(stats.xonrxc)},
{"rx_flow_control_xoff", IXGB_STAT(stats.xoffrxc)},
{"tx_flow_control_xon", IXGB_STAT(stats.xontxc)},
{"tx_flow_control_xoff", IXGB_STAT(stats.xofftxc)},
{"rx_csum_offload_good", IXGB_STAT(hw_csum_rx_good)},
{"rx_csum_offload_errors", IXGB_STAT(hw_csum_rx_error)},
{"tx_csum_offload_good", IXGB_STAT(hw_csum_tx_good)},
{"tx_csum_offload_errors", IXGB_STAT(hw_csum_tx_error)}
};
#define IXGB_STATS_LEN \
sizeof(ixgb_gstrings_stats) / sizeof(struct ixgb_stats)
static int
ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE);
ecmd->port = PORT_FIBRE;
ecmd->transceiver = XCVR_EXTERNAL;
if(netif_carrier_ok(adapter->netdev)) {
ecmd->speed = SPEED_10000;
ecmd->duplex = DUPLEX_FULL;
} else {
ecmd->speed = -1;
ecmd->duplex = -1;
}
ecmd->autoneg = AUTONEG_DISABLE;
return 0;
}
static void ixgb_set_speed_duplex(struct net_device *netdev)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
/* be optimistic about our link, since we were up before */
adapter->link_speed = 10000;
adapter->link_duplex = FULL_DUPLEX;
netif_carrier_on(netdev);
netif_wake_queue(netdev);
}
static int
ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
if(ecmd->autoneg == AUTONEG_ENABLE ||
ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)
return -EINVAL;
if(netif_running(adapter->netdev)) {
ixgb_down(adapter, TRUE);
ixgb_reset(adapter);
ixgb_up(adapter);
ixgb_set_speed_duplex(netdev);
} else
ixgb_reset(adapter);
return 0;
}
static void
ixgb_get_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
struct ixgb_hw *hw = &adapter->hw;
pause->autoneg = AUTONEG_DISABLE;
if(hw->fc.type == ixgb_fc_rx_pause)
pause->rx_pause = 1;
else if(hw->fc.type == ixgb_fc_tx_pause)
pause->tx_pause = 1;
else if(hw->fc.type == ixgb_fc_full) {
pause->rx_pause = 1;
pause->tx_pause = 1;
}
}
static int
ixgb_set_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
struct ixgb_hw *hw = &adapter->hw;
if(pause->autoneg == AUTONEG_ENABLE)
return -EINVAL;
if(pause->rx_pause && pause->tx_pause)
hw->fc.type = ixgb_fc_full;
else if(pause->rx_pause && !pause->tx_pause)
hw->fc.type = ixgb_fc_rx_pause;
else if(!pause->rx_pause && pause->tx_pause)
hw->fc.type = ixgb_fc_tx_pause;
else if(!pause->rx_pause && !pause->tx_pause)
hw->fc.type = ixgb_fc_none;
if(netif_running(adapter->netdev)) {
ixgb_down(adapter, TRUE);
ixgb_up(adapter);
ixgb_set_speed_duplex(netdev);
} else
ixgb_reset(adapter);
return 0;
}
static uint32_t
ixgb_get_rx_csum(struct net_device *netdev)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
return adapter->rx_csum;
}
static int
ixgb_set_rx_csum(struct net_device *netdev, uint32_t data)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
adapter->rx_csum = data;
if(netif_running(netdev)) {
ixgb_down(adapter,TRUE);
ixgb_up(adapter);
ixgb_set_speed_duplex(netdev);
} else
ixgb_reset(adapter);
return 0;
}
static uint32_t
ixgb_get_tx_csum(struct net_device *netdev)
{
return (netdev->features & NETIF_F_HW_CSUM) != 0;
}
static int
ixgb_set_tx_csum(struct net_device *netdev, uint32_t data)
{
if (data)
netdev->features |= NETIF_F_HW_CSUM;
else
netdev->features &= ~NETIF_F_HW_CSUM;
return 0;
}
static int
ixgb_set_tso(struct net_device *netdev, uint32_t data)
{
if(data)
netdev->features |= NETIF_F_TSO;
else
netdev->features &= ~NETIF_F_TSO;
return 0;
}
static uint32_t
ixgb_get_msglevel(struct net_device *netdev)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
return adapter->msg_enable;
}
static void
ixgb_set_msglevel(struct net_device *netdev, uint32_t data)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
adapter->msg_enable = data;
}
#define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_
static int
ixgb_get_regs_len(struct net_device *netdev)
{
#define IXGB_REG_DUMP_LEN 136*sizeof(uint32_t)
return IXGB_REG_DUMP_LEN;
}
static void
ixgb_get_regs(struct net_device *netdev,
struct ethtool_regs *regs, void *p)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
struct ixgb_hw *hw = &adapter->hw;
uint32_t *reg = p;
uint32_t *reg_start = reg;
uint8_t i;
/* the 1 (one) below indicates an attempt at versioning, if the
* interface in ethtool or the driver changes, this 1 should be
* incremented */
regs->version = (1<<24) | hw->revision_id << 16 | hw->device_id;
/* General Registers */
*reg++ = IXGB_READ_REG(hw, CTRL0); /* 0 */
*reg++ = IXGB_READ_REG(hw, CTRL1); /* 1 */
*reg++ = IXGB_READ_REG(hw, STATUS); /* 2 */
*reg++ = IXGB_READ_REG(hw, EECD); /* 3 */
*reg++ = IXGB_READ_REG(hw, MFS); /* 4 */
/* Interrupt */
*reg++ = IXGB_READ_REG(hw, ICR); /* 5 */
*reg++ = IXGB_READ_REG(hw, ICS); /* 6 */
*reg++ = IXGB_READ_REG(hw, IMS); /* 7 */
*reg++ = IXGB_READ_REG(hw, IMC); /* 8 */
/* Receive */
*reg++ = IXGB_READ_REG(hw, RCTL); /* 9 */
*reg++ = IXGB_READ_REG(hw, FCRTL); /* 10 */
*reg++ = IXGB_READ_REG(hw, FCRTH); /* 11 */
*reg++ = IXGB_READ_REG(hw, RDBAL); /* 12 */
*reg++ = IXGB_READ_REG(hw, RDBAH); /* 13 */
*reg++ = IXGB_READ_REG(hw, RDLEN); /* 14 */
*reg++ = IXGB_READ_REG(hw, RDH); /* 15 */
*reg++ = IXGB_READ_REG(hw, RDT); /* 16 */
*reg++ = IXGB_READ_REG(hw, RDTR); /* 17 */
*reg++ = IXGB_READ_REG(hw, RXDCTL); /* 18 */
*reg++ = IXGB_READ_REG(hw, RAIDC); /* 19 */
*reg++ = IXGB_READ_REG(hw, RXCSUM); /* 20 */
/* there are 16 RAR entries in hardware, we only use 3 */
for(i = 0; i < IXGB_ALL_RAR_ENTRIES; i++) {
*reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */
*reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */
}
/* Transmit */
*reg++ = IXGB_READ_REG(hw, TCTL); /* 53 */
*reg++ = IXGB_READ_REG(hw, TDBAL); /* 54 */
*reg++ = IXGB_READ_REG(hw, TDBAH); /* 55 */
*reg++ = IXGB_READ_REG(hw, TDLEN); /* 56 */
*reg++ = IXGB_READ_REG(hw, TDH); /* 57 */
*reg++ = IXGB_READ_REG(hw, TDT); /* 58 */
*reg++ = IXGB_READ_REG(hw, TIDV); /* 59 */
*reg++ = IXGB_READ_REG(hw, TXDCTL); /* 60 */
*reg++ = IXGB_READ_REG(hw, TSPMT); /* 61 */
*reg++ = IXGB_READ_REG(hw, PAP); /* 62 */
/* Physical */
*reg++ = IXGB_READ_REG(hw, PCSC1); /* 63 */
*reg++ = IXGB_READ_REG(hw, PCSC2); /* 64 */
*reg++ = IXGB_READ_REG(hw, PCSS1); /* 65 */
*reg++ = IXGB_READ_REG(hw, PCSS2); /* 66 */
*reg++ = IXGB_READ_REG(hw, XPCSS); /* 67 */
*reg++ = IXGB_READ_REG(hw, UCCR); /* 68 */
*reg++ = IXGB_READ_REG(hw, XPCSTC); /* 69 */
*reg++ = IXGB_READ_REG(hw, MACA); /* 70 */
*reg++ = IXGB_READ_REG(hw, APAE); /* 71 */
*reg++ = IXGB_READ_REG(hw, ARD); /* 72 */
*reg++ = IXGB_READ_REG(hw, AIS); /* 73 */
*reg++ = IXGB_READ_REG(hw, MSCA); /* 74 */
*reg++ = IXGB_READ_REG(hw, MSRWD); /* 75 */
/* Statistics */
*reg++ = IXGB_GET_STAT(adapter, tprl); /* 76 */
*reg++ = IXGB_GET_STAT(adapter, tprh); /* 77 */
*reg++ = IXGB_GET_STAT(adapter, gprcl); /* 78 */
*reg++ = IXGB_GET_STAT(adapter, gprch); /* 79 */
*reg++ = IXGB_GET_STAT(adapter, bprcl); /* 80 */
*reg++ = IXGB_GET_STAT(adapter, bprch); /* 81 */
*reg++ = IXGB_GET_STAT(adapter, mprcl); /* 82 */
*reg++ = IXGB_GET_STAT(adapter, mprch); /* 83 */
*reg++ = IXGB_GET_STAT(adapter, uprcl); /* 84 */
*reg++ = IXGB_GET_STAT(adapter, uprch); /* 85 */
*reg++ = IXGB_GET_STAT(adapter, vprcl); /* 86 */
*reg++ = IXGB_GET_STAT(adapter, vprch); /* 87 */
*reg++ = IXGB_GET_STAT(adapter, jprcl); /* 88 */
*reg++ = IXGB_GET_STAT(adapter, jprch); /* 89 */
*reg++ = IXGB_GET_STAT(adapter, gorcl); /* 90 */
*reg++ = IXGB_GET_STAT(adapter, gorch); /* 91 */
*reg++ = IXGB_GET_STAT(adapter, torl); /* 92 */
*reg++ = IXGB_GET_STAT(adapter, torh); /* 93 */
*reg++ = IXGB_GET_STAT(adapter, rnbc); /* 94 */
*reg++ = IXGB_GET_STAT(adapter, ruc); /* 95 */
*reg++ = IXGB_GET_STAT(adapter, roc); /* 96 */
*reg++ = IXGB_GET_STAT(adapter, rlec); /* 97 */
*reg++ = IXGB_GET_STAT(adapter, crcerrs); /* 98 */
*reg++ = IXGB_GET_STAT(adapter, icbc); /* 99 */
*reg++ = IXGB_GET_STAT(adapter, ecbc); /* 100 */
*reg++ = IXGB_GET_STAT(adapter, mpc); /* 101 */
*reg++ = IXGB_GET_STAT(adapter, tptl); /* 102 */
*reg++ = IXGB_GET_STAT(adapter, tpth); /* 103 */
*reg++ = IXGB_GET_STAT(adapter, gptcl); /* 104 */
*reg++ = IXGB_GET_STAT(adapter, gptch); /* 105 */
*reg++ = IXGB_GET_STAT(adapter, bptcl); /* 106 */
*reg++ = IXGB_GET_STAT(adapter, bptch); /* 107 */
*reg++ = IXGB_GET_STAT(adapter, mptcl); /* 108 */
*reg++ = IXGB_GET_STAT(adapter, mptch); /* 109 */
*reg++ = IXGB_GET_STAT(adapter, uptcl); /* 110 */
*reg++ = IXGB_GET_STAT(adapter, uptch); /* 111 */
*reg++ = IXGB_GET_STAT(adapter, vptcl); /* 112 */
*reg++ = IXGB_GET_STAT(adapter, vptch); /* 113 */
*reg++ = IXGB_GET_STAT(adapter, jptcl); /* 114 */
*reg++ = IXGB_GET_STAT(adapter, jptch); /* 115 */
*reg++ = IXGB_GET_STAT(adapter, gotcl); /* 116 */
*reg++ = IXGB_GET_STAT(adapter, gotch); /* 117 */
*reg++ = IXGB_GET_STAT(adapter, totl); /* 118 */
*reg++ = IXGB_GET_STAT(adapter, toth); /* 119 */
*reg++ = IXGB_GET_STAT(adapter, dc); /* 120 */
*reg++ = IXGB_GET_STAT(adapter, plt64c); /* 121 */
*reg++ = IXGB_GET_STAT(adapter, tsctc); /* 122 */
*reg++ = IXGB_GET_STAT(adapter, tsctfc); /* 123 */
*reg++ = IXGB_GET_STAT(adapter, ibic); /* 124 */
*reg++ = IXGB_GET_STAT(adapter, rfc); /* 125 */
*reg++ = IXGB_GET_STAT(adapter, lfc); /* 126 */
*reg++ = IXGB_GET_STAT(adapter, pfrc); /* 127 */
*reg++ = IXGB_GET_STAT(adapter, pftc); /* 128 */
*reg++ = IXGB_GET_STAT(adapter, mcfrc); /* 129 */
*reg++ = IXGB_GET_STAT(adapter, mcftc); /* 130 */
*reg++ = IXGB_GET_STAT(adapter, xonrxc); /* 131 */
*reg++ = IXGB_GET_STAT(adapter, xontxc); /* 132 */
*reg++ = IXGB_GET_STAT(adapter, xoffrxc); /* 133 */
*reg++ = IXGB_GET_STAT(adapter, xofftxc); /* 134 */
*reg++ = IXGB_GET_STAT(adapter, rjc); /* 135 */
regs->len = (reg - reg_start) * sizeof(uint32_t);
}
static int
ixgb_get_eeprom_len(struct net_device *netdev)
{
/* return size in bytes */
return (IXGB_EEPROM_SIZE << 1);
}
static int
ixgb_get_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, uint8_t *bytes)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
struct ixgb_hw *hw = &adapter->hw;
uint16_t *eeprom_buff;
int i, max_len, first_word, last_word;
int ret_val = 0;
if(eeprom->len == 0) {
ret_val = -EINVAL;
goto geeprom_error;
}
eeprom->magic = hw->vendor_id | (hw->device_id << 16);
max_len = ixgb_get_eeprom_len(netdev);
if(eeprom->offset > eeprom->offset + eeprom->len) {
ret_val = -EINVAL;
goto geeprom_error;
}
if((eeprom->offset + eeprom->len) > max_len)
eeprom->len = (max_len - eeprom->offset);
first_word = eeprom->offset >> 1;
last_word = (eeprom->offset + eeprom->len - 1) >> 1;
eeprom_buff = kmalloc(sizeof(uint16_t) *
(last_word - first_word + 1), GFP_KERNEL);
if(!eeprom_buff)
return -ENOMEM;
/* note the eeprom was good because the driver loaded */
for(i = 0; i <= (last_word - first_word); i++) {
eeprom_buff[i] = ixgb_get_eeprom_word(hw, (first_word + i));
}
memcpy(bytes, (uint8_t *)eeprom_buff + (eeprom->offset & 1),
eeprom->len);
kfree(eeprom_buff);
geeprom_error:
return ret_val;
}
static int
ixgb_set_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, uint8_t *bytes)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
struct ixgb_hw *hw = &adapter->hw;
uint16_t *eeprom_buff;
void *ptr;
int max_len, first_word, last_word;
uint16_t i;
if(eeprom->len == 0)
return -EINVAL;
if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
return -EFAULT;
max_len = ixgb_get_eeprom_len(netdev);
if(eeprom->offset > eeprom->offset + eeprom->len)
return -EINVAL;
if((eeprom->offset + eeprom->len) > max_len)
eeprom->len = (max_len - eeprom->offset);
first_word = eeprom->offset >> 1;
last_word = (eeprom->offset + eeprom->len - 1) >> 1;
eeprom_buff = kmalloc(max_len, GFP_KERNEL);
if(!eeprom_buff)
return -ENOMEM;
ptr = (void *)eeprom_buff;
if(eeprom->offset & 1) {
/* need read/modify/write of first changed EEPROM word */
/* only the second byte of the word is being modified */
eeprom_buff[0] = ixgb_read_eeprom(hw, first_word);
ptr++;
}
if((eeprom->offset + eeprom->len) & 1) {
/* need read/modify/write of last changed EEPROM word */
/* only the first byte of the word is being modified */
eeprom_buff[last_word - first_word]
= ixgb_read_eeprom(hw, last_word);
}
memcpy(ptr, bytes, eeprom->len);
for(i = 0; i <= (last_word - first_word); i++)
ixgb_write_eeprom(hw, first_word + i, eeprom_buff[i]);
/* Update the checksum over the first part of the EEPROM if needed */
if(first_word <= EEPROM_CHECKSUM_REG)
ixgb_update_eeprom_checksum(hw);
kfree(eeprom_buff);
return 0;
}
static void
ixgb_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
strncpy(drvinfo->driver, ixgb_driver_name, 32);
strncpy(drvinfo->version, ixgb_driver_version, 32);
strncpy(drvinfo->fw_version, "N/A", 32);
strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
drvinfo->n_stats = IXGB_STATS_LEN;
drvinfo->regdump_len = ixgb_get_regs_len(netdev);
drvinfo->eedump_len = ixgb_get_eeprom_len(netdev);
}
static void
ixgb_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
struct ixgb_desc_ring *txdr = &adapter->tx_ring;
struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
ring->rx_max_pending = MAX_RXD;
ring->tx_max_pending = MAX_TXD;
ring->rx_mini_max_pending = 0;
ring->rx_jumbo_max_pending = 0;
ring->rx_pending = rxdr->count;
ring->tx_pending = txdr->count;
ring->rx_mini_pending = 0;
ring->rx_jumbo_pending = 0;
}
static int
ixgb_set_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
struct ixgb_desc_ring *txdr = &adapter->tx_ring;
struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new;
int err;
tx_old = adapter->tx_ring;
rx_old = adapter->rx_ring;
if((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
return -EINVAL;
if(netif_running(adapter->netdev))
ixgb_down(adapter,TRUE);
rxdr->count = max(ring->rx_pending,(uint32_t)MIN_RXD);
rxdr->count = min(rxdr->count,(uint32_t)MAX_RXD);
IXGB_ROUNDUP(rxdr->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
txdr->count = max(ring->tx_pending,(uint32_t)MIN_TXD);
txdr->count = min(txdr->count,(uint32_t)MAX_TXD);
IXGB_ROUNDUP(txdr->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
if(netif_running(adapter->netdev)) {
/* Try to get new resources before deleting old */
if((err = ixgb_setup_rx_resources(adapter)))
goto err_setup_rx;
if((err = ixgb_setup_tx_resources(adapter)))
goto err_setup_tx;
/* save the new, restore the old in order to free it,
* then restore the new back again */
rx_new = adapter->rx_ring;
tx_new = adapter->tx_ring;
adapter->rx_ring = rx_old;
adapter->tx_ring = tx_old;
ixgb_free_rx_resources(adapter);
ixgb_free_tx_resources(adapter);
adapter->rx_ring = rx_new;
adapter->tx_ring = tx_new;
if((err = ixgb_up(adapter)))
return err;
ixgb_set_speed_duplex(netdev);
}
return 0;
err_setup_tx:
ixgb_free_rx_resources(adapter);
err_setup_rx:
adapter->rx_ring = rx_old;
adapter->tx_ring = tx_old;
ixgb_up(adapter);
return err;
}
/* toggle LED 4 times per second = 2 "blinks" per second */
#define IXGB_ID_INTERVAL (HZ/4)
/* bit defines for adapter->led_status */
#define IXGB_LED_ON 0
static void
ixgb_led_blink_callback(unsigned long data)
{
struct ixgb_adapter *adapter = (struct ixgb_adapter *)data;
if(test_and_change_bit(IXGB_LED_ON, &adapter->led_status))
ixgb_led_off(&adapter->hw);
else
ixgb_led_on(&adapter->hw);
mod_timer(&adapter->blink_timer, jiffies + IXGB_ID_INTERVAL);
}
static int
ixgb_phys_id(struct net_device *netdev, uint32_t data)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);
if(!adapter->blink_timer.function) {
init_timer(&adapter->blink_timer);
adapter->blink_timer.function = ixgb_led_blink_callback;
adapter->blink_timer.data = (unsigned long)adapter;
}
mod_timer(&adapter->blink_timer, jiffies);
msleep_interruptible(data * 1000);
del_timer_sync(&adapter->blink_timer);
ixgb_led_off(&adapter->hw);
clear_bit(IXGB_LED_ON, &adapter->led_status);
return 0;
}
static int
ixgb_get_stats_count(struct net_device *netdev)
{
return IXGB_STATS_LEN;
}
static void
ixgb_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats *stats, uint64_t *data)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
int i;
ixgb_update_stats(adapter);
for(i = 0; i < IXGB_STATS_LEN; i++) {
char *p = (char *)adapter+ixgb_gstrings_stats[i].stat_offset;
data[i] = (ixgb_gstrings_stats[i].sizeof_stat ==
sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p;
}
}
static void
ixgb_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
{
int i;
switch(stringset) {
case ETH_SS_STATS:
for(i=0; i < IXGB_STATS_LEN; i++) {
memcpy(data + i * ETH_GSTRING_LEN,
ixgb_gstrings_stats[i].stat_string,
ETH_GSTRING_LEN);
}
break;
}
}
static const struct ethtool_ops ixgb_ethtool_ops = {
.get_settings = ixgb_get_settings,
.set_settings = ixgb_set_settings,
.get_drvinfo = ixgb_get_drvinfo,
.get_regs_len = ixgb_get_regs_len,
.get_regs = ixgb_get_regs,
.get_link = ethtool_op_get_link,
.get_eeprom_len = ixgb_get_eeprom_len,
.get_eeprom = ixgb_get_eeprom,
.set_eeprom = ixgb_set_eeprom,
.get_ringparam = ixgb_get_ringparam,
.set_ringparam = ixgb_set_ringparam,
.get_pauseparam = ixgb_get_pauseparam,
.set_pauseparam = ixgb_set_pauseparam,
.get_rx_csum = ixgb_get_rx_csum,
.set_rx_csum = ixgb_set_rx_csum,
.get_tx_csum = ixgb_get_tx_csum,
.set_tx_csum = ixgb_set_tx_csum,
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
.get_msglevel = ixgb_get_msglevel,
.set_msglevel = ixgb_set_msglevel,
.get_tso = ethtool_op_get_tso,
.set_tso = ixgb_set_tso,
.get_strings = ixgb_get_strings,
.phys_id = ixgb_phys_id,
.get_stats_count = ixgb_get_stats_count,
.get_ethtool_stats = ixgb_get_ethtool_stats,
.get_perm_addr = ethtool_op_get_perm_addr,
};
void ixgb_set_ethtool_ops(struct net_device *netdev)
{
SET_ETHTOOL_OPS(netdev, &ixgb_ethtool_ops);
}

1227
drivers/net/ixgb/ixgb_hw.c Normal file

File diff suppressed because it is too large Load Diff

822
drivers/net/ixgb/ixgb_hw.h Normal file
View File

@@ -0,0 +1,822 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
Copyright(c) 1999 - 2006 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
*******************************************************************************/
#ifndef _IXGB_HW_H_
#define _IXGB_HW_H_
#include "ixgb_osdep.h"
/* Enums */
typedef enum {
ixgb_mac_unknown = 0,
ixgb_82597,
ixgb_num_macs
} ixgb_mac_type;
/* Types of physical layer modules */
typedef enum {
ixgb_phy_type_unknown = 0,
ixgb_phy_type_g6005, /* 850nm, MM fiber, XPAK transceiver */
ixgb_phy_type_g6104, /* 1310nm, SM fiber, XPAK transceiver */
ixgb_phy_type_txn17201, /* 850nm, MM fiber, XPAK transceiver */
ixgb_phy_type_txn17401 /* 1310nm, SM fiber, XENPAK transceiver */
} ixgb_phy_type;
/* XPAK transceiver vendors, for the SR adapters */
typedef enum {
ixgb_xpak_vendor_intel,
ixgb_xpak_vendor_infineon
} ixgb_xpak_vendor;
/* Media Types */
typedef enum {
ixgb_media_type_unknown = 0,
ixgb_media_type_fiber = 1,
ixgb_media_type_copper = 2,
ixgb_num_media_types
} ixgb_media_type;
/* Flow Control Settings */
typedef enum {
ixgb_fc_none = 0,
ixgb_fc_rx_pause = 1,
ixgb_fc_tx_pause = 2,
ixgb_fc_full = 3,
ixgb_fc_default = 0xFF
} ixgb_fc_type;
/* PCI bus types */
typedef enum {
ixgb_bus_type_unknown = 0,
ixgb_bus_type_pci,
ixgb_bus_type_pcix
} ixgb_bus_type;
/* PCI bus speeds */
typedef enum {
ixgb_bus_speed_unknown = 0,
ixgb_bus_speed_33,
ixgb_bus_speed_66,
ixgb_bus_speed_100,
ixgb_bus_speed_133,
ixgb_bus_speed_reserved
} ixgb_bus_speed;
/* PCI bus widths */
typedef enum {
ixgb_bus_width_unknown = 0,
ixgb_bus_width_32,
ixgb_bus_width_64
} ixgb_bus_width;
#define IXGB_ETH_LENGTH_OF_ADDRESS 6
#define IXGB_EEPROM_SIZE 64 /* Size in words */
#define SPEED_10000 10000
#define FULL_DUPLEX 2
#define MIN_NUMBER_OF_DESCRIPTORS 8
#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8 /* 13 bits in RDLEN/TDLEN, 128B aligned */
#define IXGB_DELAY_BEFORE_RESET 10 /* allow 10ms after idling rx/tx units */
#define IXGB_DELAY_AFTER_RESET 1 /* allow 1ms after the reset */
#define IXGB_DELAY_AFTER_EE_RESET 10 /* allow 10ms after the EEPROM reset */
#define IXGB_DELAY_USECS_AFTER_LINK_RESET 13 /* allow 13 microseconds after the reset */
/* NOTE: this is MICROSECONDS */
#define MAX_RESET_ITERATIONS 8 /* number of iterations to get things right */
/* General Registers */
#define IXGB_CTRL0 0x00000 /* Device Control Register 0 - RW */
#define IXGB_CTRL1 0x00008 /* Device Control Register 1 - RW */
#define IXGB_STATUS 0x00010 /* Device Status Register - RO */
#define IXGB_EECD 0x00018 /* EEPROM/Flash Control/Data Register - RW */
#define IXGB_MFS 0x00020 /* Maximum Frame Size - RW */
/* Interrupt */
#define IXGB_ICR 0x00080 /* Interrupt Cause Read - R/clr */
#define IXGB_ICS 0x00088 /* Interrupt Cause Set - RW */
#define IXGB_IMS 0x00090 /* Interrupt Mask Set/Read - RW */
#define IXGB_IMC 0x00098 /* Interrupt Mask Clear - WO */
/* Receive */
#define IXGB_RCTL 0x00100 /* RX Control - RW */
#define IXGB_FCRTL 0x00108 /* Flow Control Receive Threshold Low - RW */
#define IXGB_FCRTH 0x00110 /* Flow Control Receive Threshold High - RW */
#define IXGB_RDBAL 0x00118 /* RX Descriptor Base Low - RW */
#define IXGB_RDBAH 0x0011C /* RX Descriptor Base High - RW */
#define IXGB_RDLEN 0x00120 /* RX Descriptor Length - RW */
#define IXGB_RDH 0x00128 /* RX Descriptor Head - RW */
#define IXGB_RDT 0x00130 /* RX Descriptor Tail - RW */
#define IXGB_RDTR 0x00138 /* RX Delay Timer Ring - RW */
#define IXGB_RXDCTL 0x00140 /* Receive Descriptor Control - RW */
#define IXGB_RAIDC 0x00148 /* Receive Adaptive Interrupt Delay Control - RW */
#define IXGB_RXCSUM 0x00158 /* Receive Checksum Control - RW */
#define IXGB_RA 0x00180 /* Receive Address Array Base - RW */
#define IXGB_RAL 0x00180 /* Receive Address Low [0:15] - RW */
#define IXGB_RAH 0x00184 /* Receive Address High [0:15] - RW */
#define IXGB_MTA 0x00200 /* Multicast Table Array [0:127] - RW */
#define IXGB_VFTA 0x00400 /* VLAN Filter Table Array [0:127] - RW */
#define IXGB_REQ_RX_DESCRIPTOR_MULTIPLE 8
/* Transmit */
#define IXGB_TCTL 0x00600 /* TX Control - RW */
#define IXGB_TDBAL 0x00608 /* TX Descriptor Base Low - RW */
#define IXGB_TDBAH 0x0060C /* TX Descriptor Base High - RW */
#define IXGB_TDLEN 0x00610 /* TX Descriptor Length - RW */
#define IXGB_TDH 0x00618 /* TX Descriptor Head - RW */
#define IXGB_TDT 0x00620 /* TX Descriptor Tail - RW */
#define IXGB_TIDV 0x00628 /* TX Interrupt Delay Value - RW */
#define IXGB_TXDCTL 0x00630 /* Transmit Descriptor Control - RW */
#define IXGB_TSPMT 0x00638 /* TCP Segmentation PAD & Min Threshold - RW */
#define IXGB_PAP 0x00640 /* Pause and Pace - RW */
#define IXGB_REQ_TX_DESCRIPTOR_MULTIPLE 8
/* Physical */
#define IXGB_PCSC1 0x00700 /* PCS Control 1 - RW */
#define IXGB_PCSC2 0x00708 /* PCS Control 2 - RW */
#define IXGB_PCSS1 0x00710 /* PCS Status 1 - RO */
#define IXGB_PCSS2 0x00718 /* PCS Status 2 - RO */
#define IXGB_XPCSS 0x00720 /* 10GBASE-X PCS Status (or XGXS Lane Status) - RO */
#define IXGB_UCCR 0x00728 /* Unilink Circuit Control Register */
#define IXGB_XPCSTC 0x00730 /* 10GBASE-X PCS Test Control */
#define IXGB_MACA 0x00738 /* MDI Autoscan Command and Address - RW */
#define IXGB_APAE 0x00740 /* Autoscan PHY Address Enable - RW */
#define IXGB_ARD 0x00748 /* Autoscan Read Data - RO */
#define IXGB_AIS 0x00750 /* Autoscan Interrupt Status - RO */
#define IXGB_MSCA 0x00758 /* MDI Single Command and Address - RW */
#define IXGB_MSRWD 0x00760 /* MDI Single Read and Write Data - RW, RO */
/* Wake-up */
#define IXGB_WUFC 0x00808 /* Wake Up Filter Control - RW */
#define IXGB_WUS 0x00810 /* Wake Up Status - RO */
#define IXGB_FFLT 0x01000 /* Flexible Filter Length Table - RW */
#define IXGB_FFMT 0x01020 /* Flexible Filter Mask Table - RW */
#define IXGB_FTVT 0x01420 /* Flexible Filter Value Table - RW */
/* Statistics */
#define IXGB_TPRL 0x02000 /* Total Packets Received (Low) */
#define IXGB_TPRH 0x02004 /* Total Packets Received (High) */
#define IXGB_GPRCL 0x02008 /* Good Packets Received Count (Low) */
#define IXGB_GPRCH 0x0200C /* Good Packets Received Count (High) */
#define IXGB_BPRCL 0x02010 /* Broadcast Packets Received Count (Low) */
#define IXGB_BPRCH 0x02014 /* Broadcast Packets Received Count (High) */
#define IXGB_MPRCL 0x02018 /* Multicast Packets Received Count (Low) */
#define IXGB_MPRCH 0x0201C /* Multicast Packets Received Count (High) */
#define IXGB_UPRCL 0x02020 /* Unicast Packets Received Count (Low) */
#define IXGB_UPRCH 0x02024 /* Unicast Packets Received Count (High) */
#define IXGB_VPRCL 0x02028 /* VLAN Packets Received Count (Low) */
#define IXGB_VPRCH 0x0202C /* VLAN Packets Received Count (High) */
#define IXGB_JPRCL 0x02030 /* Jumbo Packets Received Count (Low) */
#define IXGB_JPRCH 0x02034 /* Jumbo Packets Received Count (High) */
#define IXGB_GORCL 0x02038 /* Good Octets Received Count (Low) */
#define IXGB_GORCH 0x0203C /* Good Octets Received Count (High) */
#define IXGB_TORL 0x02040 /* Total Octets Received (Low) */
#define IXGB_TORH 0x02044 /* Total Octets Received (High) */
#define IXGB_RNBC 0x02048 /* Receive No Buffers Count */
#define IXGB_RUC 0x02050 /* Receive Undersize Count */
#define IXGB_ROC 0x02058 /* Receive Oversize Count */
#define IXGB_RLEC 0x02060 /* Receive Length Error Count */
#define IXGB_CRCERRS 0x02068 /* CRC Error Count */
#define IXGB_ICBC 0x02070 /* Illegal control byte in mid-packet Count */
#define IXGB_ECBC 0x02078 /* Error Control byte in mid-packet Count */
#define IXGB_MPC 0x02080 /* Missed Packets Count */
#define IXGB_TPTL 0x02100 /* Total Packets Transmitted (Low) */
#define IXGB_TPTH 0x02104 /* Total Packets Transmitted (High) */
#define IXGB_GPTCL 0x02108 /* Good Packets Transmitted Count (Low) */
#define IXGB_GPTCH 0x0210C /* Good Packets Transmitted Count (High) */
#define IXGB_BPTCL 0x02110 /* Broadcast Packets Transmitted Count (Low) */
#define IXGB_BPTCH 0x02114 /* Broadcast Packets Transmitted Count (High) */
#define IXGB_MPTCL 0x02118 /* Multicast Packets Transmitted Count (Low) */
#define IXGB_MPTCH 0x0211C /* Multicast Packets Transmitted Count (High) */
#define IXGB_UPTCL 0x02120 /* Unicast Packets Transmitted Count (Low) */
#define IXGB_UPTCH 0x02124 /* Unicast Packets Transmitted Count (High) */
#define IXGB_VPTCL 0x02128 /* VLAN Packets Transmitted Count (Low) */
#define IXGB_VPTCH 0x0212C /* VLAN Packets Transmitted Count (High) */
#define IXGB_JPTCL 0x02130 /* Jumbo Packets Transmitted Count (Low) */
#define IXGB_JPTCH 0x02134 /* Jumbo Packets Transmitted Count (High) */
#define IXGB_GOTCL 0x02138 /* Good Octets Transmitted Count (Low) */
#define IXGB_GOTCH 0x0213C /* Good Octets Transmitted Count (High) */
#define IXGB_TOTL 0x02140 /* Total Octets Transmitted Count (Low) */
#define IXGB_TOTH 0x02144 /* Total Octets Transmitted Count (High) */
#define IXGB_DC 0x02148 /* Defer Count */
#define IXGB_PLT64C 0x02150 /* Packet Transmitted was less than 64 bytes Count */
#define IXGB_TSCTC 0x02170 /* TCP Segmentation Context Transmitted Count */
#define IXGB_TSCTFC 0x02178 /* TCP Segmentation Context Tx Fail Count */
#define IXGB_IBIC 0x02180 /* Illegal byte during Idle stream count */
#define IXGB_RFC 0x02188 /* Remote Fault Count */
#define IXGB_LFC 0x02190 /* Local Fault Count */
#define IXGB_PFRC 0x02198 /* Pause Frame Receive Count */
#define IXGB_PFTC 0x021A0 /* Pause Frame Transmit Count */
#define IXGB_MCFRC 0x021A8 /* MAC Control Frames (non-Pause) Received Count */
#define IXGB_MCFTC 0x021B0 /* MAC Control Frames (non-Pause) Transmitted Count */
#define IXGB_XONRXC 0x021B8 /* XON Received Count */
#define IXGB_XONTXC 0x021C0 /* XON Transmitted Count */
#define IXGB_XOFFRXC 0x021C8 /* XOFF Received Count */
#define IXGB_XOFFTXC 0x021D0 /* XOFF Transmitted Count */
#define IXGB_RJC 0x021D8 /* Receive Jabber Count */
/* CTRL0 Bit Masks */
#define IXGB_CTRL0_LRST 0x00000008
#define IXGB_CTRL0_JFE 0x00000010
#define IXGB_CTRL0_XLE 0x00000020
#define IXGB_CTRL0_MDCS 0x00000040
#define IXGB_CTRL0_CMDC 0x00000080
#define IXGB_CTRL0_SDP0 0x00040000
#define IXGB_CTRL0_SDP1 0x00080000
#define IXGB_CTRL0_SDP2 0x00100000
#define IXGB_CTRL0_SDP3 0x00200000
#define IXGB_CTRL0_SDP0_DIR 0x00400000
#define IXGB_CTRL0_SDP1_DIR 0x00800000
#define IXGB_CTRL0_SDP2_DIR 0x01000000
#define IXGB_CTRL0_SDP3_DIR 0x02000000
#define IXGB_CTRL0_RST 0x04000000
#define IXGB_CTRL0_RPE 0x08000000
#define IXGB_CTRL0_TPE 0x10000000
#define IXGB_CTRL0_VME 0x40000000
/* CTRL1 Bit Masks */
#define IXGB_CTRL1_GPI0_EN 0x00000001
#define IXGB_CTRL1_GPI1_EN 0x00000002
#define IXGB_CTRL1_GPI2_EN 0x00000004
#define IXGB_CTRL1_GPI3_EN 0x00000008
#define IXGB_CTRL1_SDP4 0x00000010
#define IXGB_CTRL1_SDP5 0x00000020
#define IXGB_CTRL1_SDP6 0x00000040
#define IXGB_CTRL1_SDP7 0x00000080
#define IXGB_CTRL1_SDP4_DIR 0x00000100
#define IXGB_CTRL1_SDP5_DIR 0x00000200
#define IXGB_CTRL1_SDP6_DIR 0x00000400
#define IXGB_CTRL1_SDP7_DIR 0x00000800
#define IXGB_CTRL1_EE_RST 0x00002000
#define IXGB_CTRL1_RO_DIS 0x00020000
#define IXGB_CTRL1_PCIXHM_MASK 0x00C00000
#define IXGB_CTRL1_PCIXHM_1_2 0x00000000
#define IXGB_CTRL1_PCIXHM_5_8 0x00400000
#define IXGB_CTRL1_PCIXHM_3_4 0x00800000
#define IXGB_CTRL1_PCIXHM_7_8 0x00C00000
/* STATUS Bit Masks */
#define IXGB_STATUS_LU 0x00000002
#define IXGB_STATUS_AIP 0x00000004
#define IXGB_STATUS_TXOFF 0x00000010
#define IXGB_STATUS_XAUIME 0x00000020
#define IXGB_STATUS_RES 0x00000040
#define IXGB_STATUS_RIS 0x00000080
#define IXGB_STATUS_RIE 0x00000100
#define IXGB_STATUS_RLF 0x00000200
#define IXGB_STATUS_RRF 0x00000400
#define IXGB_STATUS_PCI_SPD 0x00000800
#define IXGB_STATUS_BUS64 0x00001000
#define IXGB_STATUS_PCIX_MODE 0x00002000
#define IXGB_STATUS_PCIX_SPD_MASK 0x0000C000
#define IXGB_STATUS_PCIX_SPD_66 0x00000000
#define IXGB_STATUS_PCIX_SPD_100 0x00004000
#define IXGB_STATUS_PCIX_SPD_133 0x00008000
#define IXGB_STATUS_REV_ID_MASK 0x000F0000
#define IXGB_STATUS_REV_ID_SHIFT 16
/* EECD Bit Masks */
#define IXGB_EECD_SK 0x00000001
#define IXGB_EECD_CS 0x00000002
#define IXGB_EECD_DI 0x00000004
#define IXGB_EECD_DO 0x00000008
#define IXGB_EECD_FWE_MASK 0x00000030
#define IXGB_EECD_FWE_DIS 0x00000010
#define IXGB_EECD_FWE_EN 0x00000020
/* MFS */
#define IXGB_MFS_SHIFT 16
/* Interrupt Register Bit Masks (used for ICR, ICS, IMS, and IMC) */
#define IXGB_INT_TXDW 0x00000001
#define IXGB_INT_TXQE 0x00000002
#define IXGB_INT_LSC 0x00000004
#define IXGB_INT_RXSEQ 0x00000008
#define IXGB_INT_RXDMT0 0x00000010
#define IXGB_INT_RXO 0x00000040
#define IXGB_INT_RXT0 0x00000080
#define IXGB_INT_AUTOSCAN 0x00000200
#define IXGB_INT_GPI0 0x00000800
#define IXGB_INT_GPI1 0x00001000
#define IXGB_INT_GPI2 0x00002000
#define IXGB_INT_GPI3 0x00004000
/* RCTL Bit Masks */
#define IXGB_RCTL_RXEN 0x00000002
#define IXGB_RCTL_SBP 0x00000004
#define IXGB_RCTL_UPE 0x00000008
#define IXGB_RCTL_MPE 0x00000010
#define IXGB_RCTL_RDMTS_MASK 0x00000300
#define IXGB_RCTL_RDMTS_1_2 0x00000000
#define IXGB_RCTL_RDMTS_1_4 0x00000100
#define IXGB_RCTL_RDMTS_1_8 0x00000200
#define IXGB_RCTL_MO_MASK 0x00003000
#define IXGB_RCTL_MO_47_36 0x00000000
#define IXGB_RCTL_MO_46_35 0x00001000
#define IXGB_RCTL_MO_45_34 0x00002000
#define IXGB_RCTL_MO_43_32 0x00003000
#define IXGB_RCTL_MO_SHIFT 12
#define IXGB_RCTL_BAM 0x00008000
#define IXGB_RCTL_BSIZE_MASK 0x00030000
#define IXGB_RCTL_BSIZE_2048 0x00000000
#define IXGB_RCTL_BSIZE_4096 0x00010000
#define IXGB_RCTL_BSIZE_8192 0x00020000
#define IXGB_RCTL_BSIZE_16384 0x00030000
#define IXGB_RCTL_VFE 0x00040000
#define IXGB_RCTL_CFIEN 0x00080000
#define IXGB_RCTL_CFI 0x00100000
#define IXGB_RCTL_RPDA_MASK 0x00600000
#define IXGB_RCTL_RPDA_MC_MAC 0x00000000
#define IXGB_RCTL_MC_ONLY 0x00400000
#define IXGB_RCTL_CFF 0x00800000
#define IXGB_RCTL_SECRC 0x04000000
#define IXGB_RDT_FPDB 0x80000000
#define IXGB_RCTL_IDLE_RX_UNIT 0
/* FCRTL Bit Masks */
#define IXGB_FCRTL_XONE 0x80000000
/* RXDCTL Bit Masks */
#define IXGB_RXDCTL_PTHRESH_MASK 0x000001FF
#define IXGB_RXDCTL_PTHRESH_SHIFT 0
#define IXGB_RXDCTL_HTHRESH_MASK 0x0003FE00
#define IXGB_RXDCTL_HTHRESH_SHIFT 9
#define IXGB_RXDCTL_WTHRESH_MASK 0x07FC0000
#define IXGB_RXDCTL_WTHRESH_SHIFT 18
/* RAIDC Bit Masks */
#define IXGB_RAIDC_HIGHTHRS_MASK 0x0000003F
#define IXGB_RAIDC_DELAY_MASK 0x000FF800
#define IXGB_RAIDC_DELAY_SHIFT 11
#define IXGB_RAIDC_POLL_MASK 0x1FF00000
#define IXGB_RAIDC_POLL_SHIFT 20
#define IXGB_RAIDC_RXT_GATE 0x40000000
#define IXGB_RAIDC_EN 0x80000000
#define IXGB_RAIDC_POLL_1000_INTERRUPTS_PER_SECOND 1220
#define IXGB_RAIDC_POLL_5000_INTERRUPTS_PER_SECOND 244
#define IXGB_RAIDC_POLL_10000_INTERRUPTS_PER_SECOND 122
#define IXGB_RAIDC_POLL_20000_INTERRUPTS_PER_SECOND 61
/* RXCSUM Bit Masks */
#define IXGB_RXCSUM_IPOFL 0x00000100
#define IXGB_RXCSUM_TUOFL 0x00000200
/* RAH Bit Masks */
#define IXGB_RAH_ASEL_MASK 0x00030000
#define IXGB_RAH_ASEL_DEST 0x00000000
#define IXGB_RAH_ASEL_SRC 0x00010000
#define IXGB_RAH_AV 0x80000000
/* TCTL Bit Masks */
#define IXGB_TCTL_TCE 0x00000001
#define IXGB_TCTL_TXEN 0x00000002
#define IXGB_TCTL_TPDE 0x00000004
#define IXGB_TCTL_IDLE_TX_UNIT 0
/* TXDCTL Bit Masks */
#define IXGB_TXDCTL_PTHRESH_MASK 0x0000007F
#define IXGB_TXDCTL_HTHRESH_MASK 0x00007F00
#define IXGB_TXDCTL_HTHRESH_SHIFT 8
#define IXGB_TXDCTL_WTHRESH_MASK 0x007F0000
#define IXGB_TXDCTL_WTHRESH_SHIFT 16
/* TSPMT Bit Masks */
#define IXGB_TSPMT_TSMT_MASK 0x0000FFFF
#define IXGB_TSPMT_TSPBP_MASK 0xFFFF0000
#define IXGB_TSPMT_TSPBP_SHIFT 16
/* PAP Bit Masks */
#define IXGB_PAP_TXPC_MASK 0x0000FFFF
#define IXGB_PAP_TXPV_MASK 0x000F0000
#define IXGB_PAP_TXPV_10G 0x00000000
#define IXGB_PAP_TXPV_1G 0x00010000
#define IXGB_PAP_TXPV_2G 0x00020000
#define IXGB_PAP_TXPV_3G 0x00030000
#define IXGB_PAP_TXPV_4G 0x00040000
#define IXGB_PAP_TXPV_5G 0x00050000
#define IXGB_PAP_TXPV_6G 0x00060000
#define IXGB_PAP_TXPV_7G 0x00070000
#define IXGB_PAP_TXPV_8G 0x00080000
#define IXGB_PAP_TXPV_9G 0x00090000
#define IXGB_PAP_TXPV_WAN 0x000F0000
/* PCSC1 Bit Masks */
#define IXGB_PCSC1_LOOPBACK 0x00004000
/* PCSC2 Bit Masks */
#define IXGB_PCSC2_PCS_TYPE_MASK 0x00000003
#define IXGB_PCSC2_PCS_TYPE_10GBX 0x00000001
/* PCSS1 Bit Masks */
#define IXGB_PCSS1_LOCAL_FAULT 0x00000080
#define IXGB_PCSS1_RX_LINK_STATUS 0x00000004
/* PCSS2 Bit Masks */
#define IXGB_PCSS2_DEV_PRES_MASK 0x0000C000
#define IXGB_PCSS2_DEV_PRES 0x00004000
#define IXGB_PCSS2_TX_LF 0x00000800
#define IXGB_PCSS2_RX_LF 0x00000400
#define IXGB_PCSS2_10GBW 0x00000004
#define IXGB_PCSS2_10GBX 0x00000002
#define IXGB_PCSS2_10GBR 0x00000001
/* XPCSS Bit Masks */
#define IXGB_XPCSS_ALIGN_STATUS 0x00001000
#define IXGB_XPCSS_PATTERN_TEST 0x00000800
#define IXGB_XPCSS_LANE_3_SYNC 0x00000008
#define IXGB_XPCSS_LANE_2_SYNC 0x00000004
#define IXGB_XPCSS_LANE_1_SYNC 0x00000002
#define IXGB_XPCSS_LANE_0_SYNC 0x00000001
/* XPCSTC Bit Masks */
#define IXGB_XPCSTC_BERT_TRIG 0x00200000
#define IXGB_XPCSTC_BERT_SST 0x00100000
#define IXGB_XPCSTC_BERT_PSZ_MASK 0x000C0000
#define IXGB_XPCSTC_BERT_PSZ_SHIFT 17
#define IXGB_XPCSTC_BERT_PSZ_INF 0x00000003
#define IXGB_XPCSTC_BERT_PSZ_68 0x00000001
#define IXGB_XPCSTC_BERT_PSZ_1028 0x00000000
/* MSCA bit Masks */
/* New Protocol Address */
#define IXGB_MSCA_NP_ADDR_MASK 0x0000FFFF
#define IXGB_MSCA_NP_ADDR_SHIFT 0
/* Either Device Type or Register Address,depending on ST_CODE */
#define IXGB_MSCA_DEV_TYPE_MASK 0x001F0000
#define IXGB_MSCA_DEV_TYPE_SHIFT 16
#define IXGB_MSCA_PHY_ADDR_MASK 0x03E00000
#define IXGB_MSCA_PHY_ADDR_SHIFT 21
#define IXGB_MSCA_OP_CODE_MASK 0x0C000000
/* OP_CODE == 00, Address cycle, New Protocol */
/* OP_CODE == 01, Write operation */
/* OP_CODE == 10, Read operation */
/* OP_CODE == 11, Read, auto increment, New Protocol */
#define IXGB_MSCA_ADDR_CYCLE 0x00000000
#define IXGB_MSCA_WRITE 0x04000000
#define IXGB_MSCA_READ 0x08000000
#define IXGB_MSCA_READ_AUTOINC 0x0C000000
#define IXGB_MSCA_OP_CODE_SHIFT 26
#define IXGB_MSCA_ST_CODE_MASK 0x30000000
/* ST_CODE == 00, New Protocol */
/* ST_CODE == 01, Old Protocol */
#define IXGB_MSCA_NEW_PROTOCOL 0x00000000
#define IXGB_MSCA_OLD_PROTOCOL 0x10000000
#define IXGB_MSCA_ST_CODE_SHIFT 28
/* Initiate command, self-clearing when command completes */
#define IXGB_MSCA_MDI_COMMAND 0x40000000
/*MDI In Progress Enable. */
#define IXGB_MSCA_MDI_IN_PROG_EN 0x80000000
/* MSRWD bit masks */
#define IXGB_MSRWD_WRITE_DATA_MASK 0x0000FFFF
#define IXGB_MSRWD_WRITE_DATA_SHIFT 0
#define IXGB_MSRWD_READ_DATA_MASK 0xFFFF0000
#define IXGB_MSRWD_READ_DATA_SHIFT 16
/* Definitions for the optics devices on the MDIO bus. */
#define IXGB_PHY_ADDRESS 0x0 /* Single PHY, multiple "Devices" */
/* Standard five-bit Device IDs. See IEEE 802.3ae, clause 45 */
#define MDIO_PMA_PMD_DID 0x01
#define MDIO_WIS_DID 0x02
#define MDIO_PCS_DID 0x03
#define MDIO_XGXS_DID 0x04
/* Standard PMA/PMD registers and bit definitions. */
/* Note: This is a very limited set of definitions, */
/* only implemented features are defined. */
#define MDIO_PMA_PMD_CR1 0x0000
#define MDIO_PMA_PMD_CR1_RESET 0x8000
#define MDIO_PMA_PMD_XPAK_VENDOR_NAME 0x803A /* XPAK/XENPAK devices only */
/* Vendor-specific MDIO registers */
#define G6XXX_PMA_PMD_VS1 0xC001 /* Vendor-specific register */
#define G6XXX_XGXS_XAUI_VS2 0x18 /* Vendor-specific register */
#define G6XXX_PMA_PMD_VS1_PLL_RESET 0x80
#define G6XXX_PMA_PMD_VS1_REMOVE_PLL_RESET 0x00
#define G6XXX_XGXS_XAUI_VS2_INPUT_MASK 0x0F /* XAUI lanes synchronized */
/* Layout of a single receive descriptor. The controller assumes that this
* structure is packed into 16 bytes, which is a safe assumption with most
* compilers. However, some compilers may insert padding between the fields,
* in which case the structure must be packed in some compiler-specific
* manner. */
struct ixgb_rx_desc {
uint64_t buff_addr;
uint16_t length;
uint16_t reserved;
uint8_t status;
uint8_t errors;
uint16_t special;
};
#define IXGB_RX_DESC_STATUS_DD 0x01
#define IXGB_RX_DESC_STATUS_EOP 0x02
#define IXGB_RX_DESC_STATUS_IXSM 0x04
#define IXGB_RX_DESC_STATUS_VP 0x08
#define IXGB_RX_DESC_STATUS_TCPCS 0x20
#define IXGB_RX_DESC_STATUS_IPCS 0x40
#define IXGB_RX_DESC_STATUS_PIF 0x80
#define IXGB_RX_DESC_ERRORS_CE 0x01
#define IXGB_RX_DESC_ERRORS_SE 0x02
#define IXGB_RX_DESC_ERRORS_P 0x08
#define IXGB_RX_DESC_ERRORS_TCPE 0x20
#define IXGB_RX_DESC_ERRORS_IPE 0x40
#define IXGB_RX_DESC_ERRORS_RXE 0x80
#define IXGB_RX_DESC_SPECIAL_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
#define IXGB_RX_DESC_SPECIAL_PRI_MASK 0xE000 /* Priority is in upper 3 bits */
#define IXGB_RX_DESC_SPECIAL_PRI_SHIFT 0x000D /* Priority is in upper 3 of 16 */
/* Layout of a single transmit descriptor. The controller assumes that this
* structure is packed into 16 bytes, which is a safe assumption with most
* compilers. However, some compilers may insert padding between the fields,
* in which case the structure must be packed in some compiler-specific
* manner. */
struct ixgb_tx_desc {
uint64_t buff_addr;
uint32_t cmd_type_len;
uint8_t status;
uint8_t popts;
uint16_t vlan;
};
#define IXGB_TX_DESC_LENGTH_MASK 0x000FFFFF
#define IXGB_TX_DESC_TYPE_MASK 0x00F00000
#define IXGB_TX_DESC_TYPE_SHIFT 20
#define IXGB_TX_DESC_CMD_MASK 0xFF000000
#define IXGB_TX_DESC_CMD_SHIFT 24
#define IXGB_TX_DESC_CMD_EOP 0x01000000
#define IXGB_TX_DESC_CMD_TSE 0x04000000
#define IXGB_TX_DESC_CMD_RS 0x08000000
#define IXGB_TX_DESC_CMD_VLE 0x40000000
#define IXGB_TX_DESC_CMD_IDE 0x80000000
#define IXGB_TX_DESC_TYPE 0x00100000
#define IXGB_TX_DESC_STATUS_DD 0x01
#define IXGB_TX_DESC_POPTS_IXSM 0x01
#define IXGB_TX_DESC_POPTS_TXSM 0x02
#define IXGB_TX_DESC_SPECIAL_PRI_SHIFT IXGB_RX_DESC_SPECIAL_PRI_SHIFT /* Priority is in upper 3 of 16 */
struct ixgb_context_desc {
uint8_t ipcss;
uint8_t ipcso;
uint16_t ipcse;
uint8_t tucss;
uint8_t tucso;
uint16_t tucse;
uint32_t cmd_type_len;
uint8_t status;
uint8_t hdr_len;
uint16_t mss;
};
#define IXGB_CONTEXT_DESC_CMD_TCP 0x01000000
#define IXGB_CONTEXT_DESC_CMD_IP 0x02000000
#define IXGB_CONTEXT_DESC_CMD_TSE 0x04000000
#define IXGB_CONTEXT_DESC_CMD_RS 0x08000000
#define IXGB_CONTEXT_DESC_CMD_IDE 0x80000000
#define IXGB_CONTEXT_DESC_TYPE 0x00000000
#define IXGB_CONTEXT_DESC_STATUS_DD 0x01
/* Filters */
#define IXGB_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bits) */
#define IXGB_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
#define IXGB_RAR_ENTRIES 3 /* Number of entries in Rx Address array */
#define IXGB_MEMORY_REGISTER_BASE_ADDRESS 0
#define ENET_HEADER_SIZE 14
#define ENET_FCS_LENGTH 4
#define IXGB_MAX_NUM_MULTICAST_ADDRESSES 128
#define IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS 60
#define IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS 1514
#define IXGB_MAX_JUMBO_FRAME_SIZE 0x3F00
/* Phy Addresses */
#define IXGB_OPTICAL_PHY_ADDR 0x0 /* Optical Module phy address */
#define IXGB_XAUII_PHY_ADDR 0x1 /* Xauii transceiver phy address */
#define IXGB_DIAG_PHY_ADDR 0x1F /* Diagnostic Device phy address */
/* This structure takes a 64k flash and maps it for identification commands */
struct ixgb_flash_buffer {
uint8_t manufacturer_id;
uint8_t device_id;
uint8_t filler1[0x2AA8];
uint8_t cmd2;
uint8_t filler2[0x2AAA];
uint8_t cmd1;
uint8_t filler3[0xAAAA];
};
/*
* This is a little-endian specific check.
*/
#define IS_MULTICAST(Address) \
(boolean_t)(((uint8_t *)(Address))[0] & ((uint8_t)0x01))
/*
* Check whether an address is broadcast.
*/
#define IS_BROADCAST(Address) \
((((uint8_t *)(Address))[0] == ((uint8_t)0xff)) && (((uint8_t *)(Address))[1] == ((uint8_t)0xff)))
/* Flow control parameters */
struct ixgb_fc {
uint32_t high_water; /* Flow Control High-water */
uint32_t low_water; /* Flow Control Low-water */
uint16_t pause_time; /* Flow Control Pause timer */
boolean_t send_xon; /* Flow control send XON */
ixgb_fc_type type; /* Type of flow control */
};
/* The historical defaults for the flow control values are given below. */
#define FC_DEFAULT_HI_THRESH (0x8000) /* 32KB */
#define FC_DEFAULT_LO_THRESH (0x4000) /* 16KB */
#define FC_DEFAULT_TX_TIMER (0x100) /* ~130 us */
/* Phy definitions */
#define IXGB_MAX_PHY_REG_ADDRESS 0xFFFF
#define IXGB_MAX_PHY_ADDRESS 31
#define IXGB_MAX_PHY_DEV_TYPE 31
/* Bus parameters */
struct ixgb_bus {
ixgb_bus_speed speed;
ixgb_bus_width width;
ixgb_bus_type type;
};
struct ixgb_hw {
uint8_t __iomem *hw_addr;/* Base Address of the hardware */
void *back; /* Pointer to OS-dependent struct */
struct ixgb_fc fc; /* Flow control parameters */
struct ixgb_bus bus; /* Bus parameters */
uint32_t phy_id; /* Phy Identifier */
uint32_t phy_addr; /* XGMII address of Phy */
ixgb_mac_type mac_type; /* Identifier for MAC controller */
ixgb_phy_type phy_type; /* Transceiver/phy identifier */
uint32_t max_frame_size; /* Maximum frame size supported */
uint32_t mc_filter_type; /* Multicast filter hash type */
uint32_t num_mc_addrs; /* Number of current Multicast addrs */
uint8_t curr_mac_addr[IXGB_ETH_LENGTH_OF_ADDRESS]; /* Individual address currently programmed in MAC */
uint32_t num_tx_desc; /* Number of Transmit descriptors */
uint32_t num_rx_desc; /* Number of Receive descriptors */
uint32_t rx_buffer_size; /* Size of Receive buffer */
boolean_t link_up; /* TRUE if link is valid */
boolean_t adapter_stopped; /* State of adapter */
uint16_t device_id; /* device id from PCI configuration space */
uint16_t vendor_id; /* vendor id from PCI configuration space */
uint8_t revision_id; /* revision id from PCI configuration space */
uint16_t subsystem_vendor_id; /* subsystem vendor id from PCI configuration space */
uint16_t subsystem_id; /* subsystem id from PCI configuration space */
uint32_t bar0; /* Base Address registers */
uint32_t bar1;
uint32_t bar2;
uint32_t bar3;
uint16_t pci_cmd_word; /* PCI command register id from PCI configuration space */
uint16_t eeprom[IXGB_EEPROM_SIZE]; /* EEPROM contents read at init time */
unsigned long io_base; /* Our I/O mapped location */
uint32_t lastLFC;
uint32_t lastRFC;
};
/* Statistics reported by the hardware */
struct ixgb_hw_stats {
uint64_t tprl;
uint64_t tprh;
uint64_t gprcl;
uint64_t gprch;
uint64_t bprcl;
uint64_t bprch;
uint64_t mprcl;
uint64_t mprch;
uint64_t uprcl;
uint64_t uprch;
uint64_t vprcl;
uint64_t vprch;
uint64_t jprcl;
uint64_t jprch;
uint64_t gorcl;
uint64_t gorch;
uint64_t torl;
uint64_t torh;
uint64_t rnbc;
uint64_t ruc;
uint64_t roc;
uint64_t rlec;
uint64_t crcerrs;
uint64_t icbc;
uint64_t ecbc;
uint64_t mpc;
uint64_t tptl;
uint64_t tpth;
uint64_t gptcl;
uint64_t gptch;
uint64_t bptcl;
uint64_t bptch;
uint64_t mptcl;
uint64_t mptch;
uint64_t uptcl;
uint64_t uptch;
uint64_t vptcl;
uint64_t vptch;
uint64_t jptcl;
uint64_t jptch;
uint64_t gotcl;
uint64_t gotch;
uint64_t totl;
uint64_t toth;
uint64_t dc;
uint64_t plt64c;
uint64_t tsctc;
uint64_t tsctfc;
uint64_t ibic;
uint64_t rfc;
uint64_t lfc;
uint64_t pfrc;
uint64_t pftc;
uint64_t mcfrc;
uint64_t mcftc;
uint64_t xonrxc;
uint64_t xontxc;
uint64_t xoffrxc;
uint64_t xofftxc;
uint64_t rjc;
};
/* Function Prototypes */
extern boolean_t ixgb_adapter_stop(struct ixgb_hw *hw);
extern boolean_t ixgb_init_hw(struct ixgb_hw *hw);
extern boolean_t ixgb_adapter_start(struct ixgb_hw *hw);
extern void ixgb_check_for_link(struct ixgb_hw *hw);
extern boolean_t ixgb_check_for_bad_link(struct ixgb_hw *hw);
extern void ixgb_rar_set(struct ixgb_hw *hw,
uint8_t *addr,
uint32_t index);
/* Filters (multicast, vlan, receive) */
extern void ixgb_mc_addr_list_update(struct ixgb_hw *hw,
uint8_t *mc_addr_list,
uint32_t mc_addr_count,
uint32_t pad);
/* Vfta functions */
extern void ixgb_write_vfta(struct ixgb_hw *hw,
uint32_t offset,
uint32_t value);
/* Access functions to eeprom data */
void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t *mac_addr);
uint32_t ixgb_get_ee_pba_number(struct ixgb_hw *hw);
uint16_t ixgb_get_ee_device_id(struct ixgb_hw *hw);
boolean_t ixgb_get_eeprom_data(struct ixgb_hw *hw);
uint16_t ixgb_get_eeprom_word(struct ixgb_hw *hw, uint16_t index);
/* Everything else */
void ixgb_led_on(struct ixgb_hw *hw);
void ixgb_led_off(struct ixgb_hw *hw);
void ixgb_write_pci_cfg(struct ixgb_hw *hw,
uint32_t reg,
uint16_t * value);
#endif /* _IXGB_HW_H_ */

View File

@@ -0,0 +1,51 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
Copyright(c) 1999 - 2006 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
*******************************************************************************/
#ifndef _IXGB_IDS_H_
#define _IXGB_IDS_H_
/**********************************************************************
** The Device and Vendor IDs for 10 Gigabit MACs
**********************************************************************/
#define INTEL_VENDOR_ID 0x8086
#define INTEL_SUBVENDOR_ID 0x8086
#define IXGB_DEVICE_ID_82597EX 0x1048
#define IXGB_DEVICE_ID_82597EX_SR 0x1A48
#define IXGB_DEVICE_ID_82597EX_LR 0x1B48
#define IXGB_SUBDEVICE_ID_A11F 0xA11F
#define IXGB_SUBDEVICE_ID_A01F 0xA01F
#define IXGB_DEVICE_ID_82597EX_CX4 0x109E
#define IXGB_SUBDEVICE_ID_A00C 0xA00C
#define IXGB_SUBDEVICE_ID_A01C 0xA01C
#endif /* #ifndef _IXGB_IDS_H_ */
/* End of File */

2354
drivers/net/ixgb/ixgb_main.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,83 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
Copyright(c) 1999 - 2006 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
*******************************************************************************/
/* glue for the OS independent part of ixgb
* includes register access macros
*/
#ifndef _IXGB_OSDEP_H_
#define _IXGB_OSDEP_H_
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
typedef enum {
#undef FALSE
FALSE = 0,
#undef TRUE
TRUE = 1
} boolean_t;
#undef ASSERT
#define ASSERT(x) if(!(x)) BUG()
#define MSGOUT(S, A, B) printk(KERN_DEBUG S "\n", A, B)
#ifdef DBG
#define DEBUGOUT(S) printk(KERN_DEBUG S "\n")
#define DEBUGOUT1(S, A...) printk(KERN_DEBUG S "\n", A)
#else
#define DEBUGOUT(S)
#define DEBUGOUT1(S, A...)
#endif
#define DEBUGFUNC(F) DEBUGOUT(F)
#define DEBUGOUT2 DEBUGOUT1
#define DEBUGOUT3 DEBUGOUT2
#define DEBUGOUT7 DEBUGOUT3
#define IXGB_WRITE_REG(a, reg, value) ( \
writel((value), ((a)->hw_addr + IXGB_##reg)))
#define IXGB_READ_REG(a, reg) ( \
readl((a)->hw_addr + IXGB_##reg))
#define IXGB_WRITE_REG_ARRAY(a, reg, offset, value) ( \
writel((value), ((a)->hw_addr + IXGB_##reg + ((offset) << 2))))
#define IXGB_READ_REG_ARRAY(a, reg, offset) ( \
readl((a)->hw_addr + IXGB_##reg + ((offset) << 2)))
#define IXGB_WRITE_FLUSH(a) IXGB_READ_REG(a, STATUS)
#define IXGB_MEMCPY memcpy
#endif /* _IXGB_OSDEP_H_ */

View File

@@ -0,0 +1,474 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
Copyright(c) 1999 - 2006 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
*******************************************************************************/
#include "ixgb.h"
/* This is the only thing that needs to be changed to adjust the
* maximum number of ports that the driver can manage.
*/
#define IXGB_MAX_NIC 8
#define OPTION_UNSET -1
#define OPTION_DISABLED 0
#define OPTION_ENABLED 1
/* All parameters are treated the same, as an integer array of values.
* This macro just reduces the need to repeat the same declaration code
* over and over (plus this helps to avoid typo bugs).
*/
#define IXGB_PARAM_INIT { [0 ... IXGB_MAX_NIC] = OPTION_UNSET }
#define IXGB_PARAM(X, desc) \
static int __devinitdata X[IXGB_MAX_NIC+1] = IXGB_PARAM_INIT; \
static int num_##X = 0; \
module_param_array_named(X, X, int, &num_##X, 0); \
MODULE_PARM_DESC(X, desc);
/* Transmit Descriptor Count
*
* Valid Range: 64-4096
*
* Default Value: 256
*/
IXGB_PARAM(TxDescriptors, "Number of transmit descriptors");
/* Receive Descriptor Count
*
* Valid Range: 64-4096
*
* Default Value: 1024
*/
IXGB_PARAM(RxDescriptors, "Number of receive descriptors");
/* User Specified Flow Control Override
*
* Valid Range: 0-3
* - 0 - No Flow Control
* - 1 - Rx only, respond to PAUSE frames but do not generate them
* - 2 - Tx only, generate PAUSE frames but ignore them on receive
* - 3 - Full Flow Control Support
*
* Default Value: 2 - Tx only (silicon bug avoidance)
*/
IXGB_PARAM(FlowControl, "Flow Control setting");
/* XsumRX - Receive Checksum Offload Enable/Disable
*
* Valid Range: 0, 1
* - 0 - disables all checksum offload
* - 1 - enables receive IP/TCP/UDP checksum offload
* on 82597 based NICs
*
* Default Value: 1
*/
IXGB_PARAM(XsumRX, "Disable or enable Receive Checksum offload");
/* Transmit Interrupt Delay in units of 0.8192 microseconds
*
* Valid Range: 0-65535
*
* Default Value: 32
*/
IXGB_PARAM(TxIntDelay, "Transmit Interrupt Delay");
/* Receive Interrupt Delay in units of 0.8192 microseconds
*
* Valid Range: 0-65535
*
* Default Value: 72
*/
IXGB_PARAM(RxIntDelay, "Receive Interrupt Delay");
/* Receive Flow control high threshold (when we send a pause frame)
* (FCRTH)
*
* Valid Range: 1,536 - 262,136 (0x600 - 0x3FFF8, 8 byte granularity)
*
* Default Value: 196,608 (0x30000)
*/
IXGB_PARAM(RxFCHighThresh, "Receive Flow Control High Threshold");
/* Receive Flow control low threshold (when we send a resume frame)
* (FCRTL)
*
* Valid Range: 64 - 262,136 (0x40 - 0x3FFF8, 8 byte granularity)
* must be less than high threshold by at least 8 bytes
*
* Default Value: 163,840 (0x28000)
*/
IXGB_PARAM(RxFCLowThresh, "Receive Flow Control Low Threshold");
/* Flow control request timeout (how long to pause the link partner's tx)
* (PAP 15:0)
*
* Valid Range: 1 - 65535
*
* Default Value: 65535 (0xffff) (we'll send an xon if we recover)
*/
IXGB_PARAM(FCReqTimeout, "Flow Control Request Timeout");
/* Interrupt Delay Enable
*
* Valid Range: 0, 1
*
* - 0 - disables transmit interrupt delay
* - 1 - enables transmmit interrupt delay
*
* Default Value: 1
*/
IXGB_PARAM(IntDelayEnable, "Transmit Interrupt Delay Enable");
#define DEFAULT_TIDV 32
#define MAX_TIDV 0xFFFF
#define MIN_TIDV 0
#define DEFAULT_RDTR 72
#define MAX_RDTR 0xFFFF
#define MIN_RDTR 0
#define XSUMRX_DEFAULT OPTION_ENABLED
#define DEFAULT_FCRTL 0x28000
#define DEFAULT_FCRTH 0x30000
#define MIN_FCRTL 0
#define MAX_FCRTL 0x3FFE8
#define MIN_FCRTH 8
#define MAX_FCRTH 0x3FFF0
#define MIN_FCPAUSE 1
#define MAX_FCPAUSE 0xffff
#define DEFAULT_FCPAUSE 0xFFFF /* this may be too long */
struct ixgb_option {
enum { enable_option, range_option, list_option } type;
char *name;
char *err;
int def;
union {
struct { /* range_option info */
int min;
int max;
} r;
struct { /* list_option info */
int nr;
struct ixgb_opt_list {
int i;
char *str;
} *p;
} l;
} arg;
};
static int __devinit
ixgb_validate_option(int *value, struct ixgb_option *opt)
{
if(*value == OPTION_UNSET) {
*value = opt->def;
return 0;
}
switch (opt->type) {
case enable_option:
switch (*value) {
case OPTION_ENABLED:
printk(KERN_INFO "%s Enabled\n", opt->name);
return 0;
case OPTION_DISABLED:
printk(KERN_INFO "%s Disabled\n", opt->name);
return 0;
}
break;
case range_option:
if(*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
printk(KERN_INFO "%s set to %i\n", opt->name, *value);
return 0;
}
break;
case list_option: {
int i;
struct ixgb_opt_list *ent;
for(i = 0; i < opt->arg.l.nr; i++) {
ent = &opt->arg.l.p[i];
if(*value == ent->i) {
if(ent->str[0] != '\0')
printk(KERN_INFO "%s\n", ent->str);
return 0;
}
}
}
break;
default:
BUG();
}
printk(KERN_INFO "Invalid %s specified (%i) %s\n",
opt->name, *value, opt->err);
*value = opt->def;
return -1;
}
#define LIST_LEN(l) (sizeof(l) / sizeof(l[0]))
/**
* ixgb_check_options - Range Checking for Command Line Parameters
* @adapter: board private structure
*
* This routine checks all command line parameters for valid user
* input. If an invalid value is given, or if no user specified
* value exists, a default value is used. The final value is stored
* in a variable in the adapter structure.
**/
void __devinit
ixgb_check_options(struct ixgb_adapter *adapter)
{
int bd = adapter->bd_number;
if(bd >= IXGB_MAX_NIC) {
printk(KERN_NOTICE
"Warning: no configuration for board #%i\n", bd);
printk(KERN_NOTICE "Using defaults for all values\n");
}
{ /* Transmit Descriptor Count */
struct ixgb_option opt = {
.type = range_option,
.name = "Transmit Descriptors",
.err = "using default of " __MODULE_STRING(DEFAULT_TXD),
.def = DEFAULT_TXD,
.arg = { .r = { .min = MIN_TXD,
.max = MAX_TXD}}
};
struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
if(num_TxDescriptors > bd) {
tx_ring->count = TxDescriptors[bd];
ixgb_validate_option(&tx_ring->count, &opt);
} else {
tx_ring->count = opt.def;
}
IXGB_ROUNDUP(tx_ring->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
}
{ /* Receive Descriptor Count */
struct ixgb_option opt = {
.type = range_option,
.name = "Receive Descriptors",
.err = "using default of " __MODULE_STRING(DEFAULT_RXD),
.def = DEFAULT_RXD,
.arg = { .r = { .min = MIN_RXD,
.max = MAX_RXD}}
};
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
if(num_RxDescriptors > bd) {
rx_ring->count = RxDescriptors[bd];
ixgb_validate_option(&rx_ring->count, &opt);
} else {
rx_ring->count = opt.def;
}
IXGB_ROUNDUP(rx_ring->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
}
{ /* Receive Checksum Offload Enable */
struct ixgb_option opt = {
.type = enable_option,
.name = "Receive Checksum Offload",
.err = "defaulting to Enabled",
.def = OPTION_ENABLED
};
if(num_XsumRX > bd) {
int rx_csum = XsumRX[bd];
ixgb_validate_option(&rx_csum, &opt);
adapter->rx_csum = rx_csum;
} else {
adapter->rx_csum = opt.def;
}
}
{ /* Flow Control */
struct ixgb_opt_list fc_list[] =
{{ ixgb_fc_none, "Flow Control Disabled" },
{ ixgb_fc_rx_pause,"Flow Control Receive Only" },
{ ixgb_fc_tx_pause,"Flow Control Transmit Only" },
{ ixgb_fc_full, "Flow Control Enabled" },
{ ixgb_fc_default, "Flow Control Hardware Default" }};
struct ixgb_option opt = {
.type = list_option,
.name = "Flow Control",
.err = "reading default settings from EEPROM",
.def = ixgb_fc_tx_pause,
.arg = { .l = { .nr = LIST_LEN(fc_list),
.p = fc_list }}
};
if(num_FlowControl > bd) {
int fc = FlowControl[bd];
ixgb_validate_option(&fc, &opt);
adapter->hw.fc.type = fc;
} else {
adapter->hw.fc.type = opt.def;
}
}
{ /* Receive Flow Control High Threshold */
struct ixgb_option opt = {
.type = range_option,
.name = "Rx Flow Control High Threshold",
.err = "using default of " __MODULE_STRING(DEFAULT_FCRTH),
.def = DEFAULT_FCRTH,
.arg = { .r = { .min = MIN_FCRTH,
.max = MAX_FCRTH}}
};
if(num_RxFCHighThresh > bd) {
adapter->hw.fc.high_water = RxFCHighThresh[bd];
ixgb_validate_option(&adapter->hw.fc.high_water, &opt);
} else {
adapter->hw.fc.high_water = opt.def;
}
if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) )
printk (KERN_INFO
"Ignoring RxFCHighThresh when no RxFC\n");
}
{ /* Receive Flow Control Low Threshold */
struct ixgb_option opt = {
.type = range_option,
.name = "Rx Flow Control Low Threshold",
.err = "using default of " __MODULE_STRING(DEFAULT_FCRTL),
.def = DEFAULT_FCRTL,
.arg = { .r = { .min = MIN_FCRTL,
.max = MAX_FCRTL}}
};
if(num_RxFCLowThresh > bd) {
adapter->hw.fc.low_water = RxFCLowThresh[bd];
ixgb_validate_option(&adapter->hw.fc.low_water, &opt);
} else {
adapter->hw.fc.low_water = opt.def;
}
if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) )
printk (KERN_INFO
"Ignoring RxFCLowThresh when no RxFC\n");
}
{ /* Flow Control Pause Time Request*/
struct ixgb_option opt = {
.type = range_option,
.name = "Flow Control Pause Time Request",
.err = "using default of "__MODULE_STRING(DEFAULT_FCPAUSE),
.def = DEFAULT_FCPAUSE,
.arg = { .r = { .min = MIN_FCPAUSE,
.max = MAX_FCPAUSE}}
};
if(num_FCReqTimeout > bd) {
int pause_time = FCReqTimeout[bd];
ixgb_validate_option(&pause_time, &opt);
adapter->hw.fc.pause_time = pause_time;
} else {
adapter->hw.fc.pause_time = opt.def;
}
if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) )
printk (KERN_INFO
"Ignoring FCReqTimeout when no RxFC\n");
}
/* high low and spacing check for rx flow control thresholds */
if (adapter->hw.fc.type & ixgb_fc_tx_pause) {
/* high must be greater than low */
if (adapter->hw.fc.high_water < (adapter->hw.fc.low_water + 8)) {
/* set defaults */
printk (KERN_INFO
"RxFCHighThresh must be >= (RxFCLowThresh + 8), "
"Using Defaults\n");
adapter->hw.fc.high_water = DEFAULT_FCRTH;
adapter->hw.fc.low_water = DEFAULT_FCRTL;
}
}
{ /* Receive Interrupt Delay */
struct ixgb_option opt = {
.type = range_option,
.name = "Receive Interrupt Delay",
.err = "using default of " __MODULE_STRING(DEFAULT_RDTR),
.def = DEFAULT_RDTR,
.arg = { .r = { .min = MIN_RDTR,
.max = MAX_RDTR}}
};
if(num_RxIntDelay > bd) {
adapter->rx_int_delay = RxIntDelay[bd];
ixgb_validate_option(&adapter->rx_int_delay, &opt);
} else {
adapter->rx_int_delay = opt.def;
}
}
{ /* Transmit Interrupt Delay */
struct ixgb_option opt = {
.type = range_option,
.name = "Transmit Interrupt Delay",
.err = "using default of " __MODULE_STRING(DEFAULT_TIDV),
.def = DEFAULT_TIDV,
.arg = { .r = { .min = MIN_TIDV,
.max = MAX_TIDV}}
};
if(num_TxIntDelay > bd) {
adapter->tx_int_delay = TxIntDelay[bd];
ixgb_validate_option(&adapter->tx_int_delay, &opt);
} else {
adapter->tx_int_delay = opt.def;
}
}
{ /* Transmit Interrupt Delay Enable */
struct ixgb_option opt = {
.type = enable_option,
.name = "Tx Interrupt Delay Enable",
.err = "defaulting to Enabled",
.def = OPTION_ENABLED
};
if(num_IntDelayEnable > bd) {
int ide = IntDelayEnable[bd];
ixgb_validate_option(&ide, &opt);
adapter->tx_int_delay_enable = ide;
} else {
adapter->tx_int_delay_enable = opt.def;
}
}
}