Commit 3c7fd9ca authored by Jeff Garzik's avatar Jeff Garzik

[netdrvr ixgb] massive update

Since Intel agreed to submit further updates via broken-up patches
like they do currently (and admirably) for e1000 and e100, I agreed
to merge this update to bring the driver up to speed.

Contributed by: Ayyappan.Veeraiyan@intel.com

Changes:

Features implemented

*	Support for new 850nm adapters.
*	Copyright notice updated to include year 2004.
*	Fix for "ixgb does not maintain non-default MTU setting across a
link loss" issue - When link loss happens in non-default MTU
environment, driver will incorrectly operate with default 1500 MTU
setting.
*	Netpoll support added
*	Ethtool support - status functionality, FlowControl interface,
Checksum interface, TSO and Scatter Gather interfaces
*	Race condition fix - Race condition (TX path) exists between
ixgb_xmit_frame and clean_tx_irq routines in handling the queue.
* 	Removed dead code segments (#if 0)


Performance improvement features 
*	Mod operator usage is removed - used to cause performance
problems in non-IA architecture based machines
*	Multiple ICR register read in ISR is avoided
*	RS bit set on only 'end of packet' TX descriptors - to avoid
multiple writebacks by controller for packets with multiple descriptors.
*	RX descriptors prefetch is done - improved 1500 MTU TX
performance


All relevant e1000 driver cleanups ported to ixgb
*	Valid error propagation in functions ixgb_up, ixgb_probe,
ixgb_open. 
* 	NAPI code cleanups
* 	u8, u16 and u32 data types are changed to uint8_t, uint16_t and
uint32_t respectively. We use these types on our shared code for
multiple OSes and also to make it uniform with e1000 driver.
*	Some functions in ixgb_main.c are moved to different location -
This enables easy porting of e1000 bug fixes to ixgb 
parent 207ebf51
/******************************************************************************* /*******************************************************************************
Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
Contact Information: Contact Information:
Linux NICS <linux.nics@intel.com> Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/ *******************************************************************************/
#ifndef _IXGB_H_ #ifndef _IXGB_H_
...@@ -34,39 +35,44 @@ ...@@ -34,39 +35,44 @@
#include <linux/types.h> #include <linux/types.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/bitops.h> #include <asm/bitops.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <linux/capability.h>
#include <linux/in.h> #include <linux/in.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/tcp.h> #include <linux/tcp.h>
#include <linux/udp.h> #include <linux/udp.h>
#include <net/pkt_sched.h> #include <net/pkt_sched.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/workqueue.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#ifdef NETIF_F_TSO #ifdef NETIF_F_TSO
#include <net/checksum.h> #include <net/checksum.h>
#endif #endif
/* ethtool support */
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
struct ixgb_adapter; #define BAR_0 0
#define BAR_1 1
#define BAR_0 0 #define BAR_5 5
#define BAR_1 1
#define BAR_5 5
struct ixgb_adapter;
#include "ixgb_hw.h" #include "ixgb_hw.h"
#include "ixgb_ee.h" #include "ixgb_ee.h"
#include "ixgb_ids.h" #include "ixgb_ids.h"
...@@ -89,7 +95,7 @@ struct ixgb_adapter; ...@@ -89,7 +95,7 @@ struct ixgb_adapter;
#define IXGB_TX_QUEUE_WAKE 16 #define IXGB_TX_QUEUE_WAKE 16
/* How many Rx Buffers do we bundle into one write to the hardware ? */ /* How many Rx Buffers do we bundle into one write to the hardware ? */
#define IXGB_RX_BUFFER_WRITE 16 #define IXGB_RX_BUFFER_WRITE 16 /* Must be power of 2 */
/* only works for sizes that are powers of 2 */ /* only works for sizes that are powers of 2 */
#define IXGB_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1))) #define IXGB_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
...@@ -101,71 +107,66 @@ struct ixgb_buffer { ...@@ -101,71 +107,66 @@ struct ixgb_buffer {
uint64_t dma; uint64_t dma;
unsigned long length; unsigned long length;
unsigned long time_stamp; unsigned long time_stamp;
unsigned int next_to_watch;
}; };
struct ixgb_desc_ring { struct ixgb_desc_ring {
/* pointer to the descriptor ring memory */ /* pointer to the descriptor ring memory */
void *desc; void *desc;
/* physical address of the descriptor ring */ /* physical address of the descriptor ring */
dma_addr_t dma; dma_addr_t dma;
/* length of descriptor ring in bytes */ /* length of descriptor ring in bytes */
unsigned int size; unsigned int size;
/* number of descriptors in the ring */ /* number of descriptors in the ring */
unsigned int count; unsigned int count;
/* next descriptor to associate a buffer with */ /* next descriptor to associate a buffer with */
unsigned int next_to_use; unsigned int next_to_use;
/* next descriptor to check for DD status bit */ /* next descriptor to check for DD status bit */
unsigned int next_to_clean; unsigned int next_to_clean;
/* array of buffer information structs */ /* array of buffer information structs */
struct ixgb_buffer *buffer_info; struct ixgb_buffer *buffer_info;
}; };
#define IXGB_DESC_UNUSED(R) \ #define IXGB_DESC_UNUSED(R) \
((((R)->next_to_clean + (R)->count) - ((R)->next_to_use + 1)) % ((R)->count)) ((((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_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_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_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) #define IXGB_CONTEXT_DESC(R, i) IXGB_GET_DESC(R, i, ixgb_context_desc)
/* board specific private data structure */ /* board specific private data structure */
struct ixgb_adapter { struct ixgb_adapter {
struct timer_list watchdog_timer; struct timer_list watchdog_timer;
struct vlan_group *vlgrp; struct vlan_group *vlgrp;
char *id_string; uint32_t bd_number;
u32 bd_number; uint32_t rx_buffer_len;
u32 rx_buffer_len; uint32_t part_num;
u32 part_num; uint16_t link_speed;
u16 link_speed; uint16_t link_duplex;
u16 link_duplex; spinlock_t tx_lock;
atomic_t irq_sem; atomic_t irq_sem;
struct work_struct tx_timeout_task; struct work_struct tx_timeout_task;
#ifdef ETHTOOL_PHYS_ID
struct timer_list blink_timer; struct timer_list blink_timer;
unsigned long led_status; unsigned long led_status;
#endif
#ifdef _INTERNAL_LOOPBACK_DRIVER_
struct ixgb_desc_ring diag_tx_ring;
struct ixgb_desc_ring diag_rx_ring;
#endif
/* TX */ /* TX */
struct ixgb_desc_ring tx_ring; struct ixgb_desc_ring tx_ring;
unsigned long timeo_start; unsigned long timeo_start;
u32 tx_cmd_type; uint32_t tx_cmd_type;
int max_data_per_txd;
uint64_t hw_csum_tx_good; uint64_t hw_csum_tx_good;
uint64_t hw_csum_tx_error; uint64_t hw_csum_tx_error;
boolean_t tx_csum; uint32_t tx_int_delay;
u32 tx_int_delay;
boolean_t tx_int_delay_enable; boolean_t tx_int_delay_enable;
/* RX */ /* RX */
struct ixgb_desc_ring rx_ring; struct ixgb_desc_ring rx_ring;
uint64_t hw_csum_rx_error; uint64_t hw_csum_rx_error;
uint64_t hw_csum_rx_good; uint64_t hw_csum_rx_good;
u32 rx_int_delay; uint32_t rx_int_delay;
boolean_t raidc; boolean_t raidc;
boolean_t rx_csum; boolean_t rx_csum;
...@@ -177,8 +178,6 @@ struct ixgb_adapter { ...@@ -177,8 +178,6 @@ struct ixgb_adapter {
/* structs defined in ixgb_hw.h */ /* structs defined in ixgb_hw.h */
struct ixgb_hw hw; struct ixgb_hw hw;
struct ixgb_hw_stats stats; struct ixgb_hw_stats stats;
u32 pci_state[16]; uint32_t pci_state[16];
char ifname[IFNAMSIZ];
}; };
#endif /* _IXGB_H_ */ #endif /* _IXGB_H_ */
/******************************************************************************* /*******************************************************************************
Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
...@@ -23,15 +23,16 @@ ...@@ -23,15 +23,16 @@
Contact Information: Contact Information:
Linux NICS <linux.nics@intel.com> Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/ *******************************************************************************/
#include "ixgb_hw.h" #include "ixgb_hw.h"
#include "ixgb_ee.h" #include "ixgb_ee.h"
/* Local prototypes */ /* Local prototypes */
static u16 ixgb_shift_in_bits(struct ixgb_hw *hw); static uint16_t ixgb_shift_in_bits(struct ixgb_hw *hw);
static void ixgb_shift_out_bits(struct ixgb_hw *hw, static void ixgb_shift_out_bits(struct ixgb_hw *hw,
u16 data, u16 count); uint16_t data, uint16_t count);
static void ixgb_standby_eeprom(struct ixgb_hw *hw); static void ixgb_standby_eeprom(struct ixgb_hw *hw);
static boolean_t ixgb_wait_eeprom_command(struct ixgb_hw *hw); static boolean_t ixgb_wait_eeprom_command(struct ixgb_hw *hw);
...@@ -44,8 +45,7 @@ static void ixgb_cleanup_eeprom(struct ixgb_hw *hw); ...@@ -44,8 +45,7 @@ static void ixgb_cleanup_eeprom(struct ixgb_hw *hw);
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* eecd_reg - EECD's current value * eecd_reg - EECD's current value
*****************************************************************************/ *****************************************************************************/
static void static void ixgb_raise_clock(struct ixgb_hw *hw, uint32_t * eecd_reg)
ixgb_raise_clock(struct ixgb_hw *hw, u32 * eecd_reg)
{ {
/* Raise the clock input to the EEPROM (by setting the SK bit), and then /* Raise the clock input to the EEPROM (by setting the SK bit), and then
* wait 50 microseconds. * wait 50 microseconds.
...@@ -59,14 +59,13 @@ ixgb_raise_clock(struct ixgb_hw *hw, u32 * eecd_reg) ...@@ -59,14 +59,13 @@ ixgb_raise_clock(struct ixgb_hw *hw, u32 * eecd_reg)
/****************************************************************************** /******************************************************************************
* Lowers the EEPROM's clock input. * Lowers the EEPROM's clock input.
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* eecd_reg - EECD's current value * eecd_reg - EECD's current value
*****************************************************************************/ *****************************************************************************/
static void static void ixgb_lower_clock(struct ixgb_hw *hw, uint32_t * eecd_reg)
ixgb_lower_clock(struct ixgb_hw *hw, u32 * eecd_reg)
{ {
/* Lower the clock input to the EEPROM (by clearing the SK bit), and then /* Lower the clock input to the EEPROM (by clearing the SK bit), and then
* wait 50 microseconds. * wait 50 microseconds.
*/ */
*eecd_reg = *eecd_reg & ~IXGB_EECD_SK; *eecd_reg = *eecd_reg & ~IXGB_EECD_SK;
IXGB_WRITE_REG(hw, EECD, *eecd_reg); IXGB_WRITE_REG(hw, EECD, *eecd_reg);
...@@ -82,14 +81,14 @@ ixgb_lower_clock(struct ixgb_hw *hw, u32 * eecd_reg) ...@@ -82,14 +81,14 @@ ixgb_lower_clock(struct ixgb_hw *hw, u32 * eecd_reg)
* count - number of bits to shift out * count - number of bits to shift out
*****************************************************************************/ *****************************************************************************/
static void static void
ixgb_shift_out_bits(struct ixgb_hw *hw, u16 data, u16 count) ixgb_shift_out_bits(struct ixgb_hw *hw, uint16_t data, uint16_t count)
{ {
u32 eecd_reg; uint32_t eecd_reg;
u32 mask; uint32_t mask;
/* We need to shift "count" bits out to the EEPROM. So, value in the /* 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. * "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. * In order to do this, "data" must be broken down into bits.
*/ */
mask = 0x01 << (count - 1); mask = 0x01 << (count - 1);
eecd_reg = IXGB_READ_REG(hw, EECD); eecd_reg = IXGB_READ_REG(hw, EECD);
...@@ -127,17 +126,16 @@ ixgb_shift_out_bits(struct ixgb_hw *hw, u16 data, u16 count) ...@@ -127,17 +126,16 @@ ixgb_shift_out_bits(struct ixgb_hw *hw, u16 data, u16 count)
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
static u16 static uint16_t ixgb_shift_in_bits(struct ixgb_hw *hw)
ixgb_shift_in_bits(struct ixgb_hw *hw)
{ {
u32 eecd_reg; uint32_t eecd_reg;
u32 i; uint32_t i;
u16 data; uint16_t data;
/* In order to read a register from the EEPROM, we need to shift 16 bits /* 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 * 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" * 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 * bit. During this "shifting in" process the "DI" bit should always be
* clear.. * clear..
*/ */
...@@ -167,13 +165,12 @@ ixgb_shift_in_bits(struct ixgb_hw *hw) ...@@ -167,13 +165,12 @@ ixgb_shift_in_bits(struct ixgb_hw *hw)
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
* function should be called before issuing a command to the EEPROM. * function should be called before issuing a command to the EEPROM.
*****************************************************************************/ *****************************************************************************/
static void static void ixgb_setup_eeprom(struct ixgb_hw *hw)
ixgb_setup_eeprom(struct ixgb_hw *hw)
{ {
u32 eecd_reg; uint32_t eecd_reg;
eecd_reg = IXGB_READ_REG(hw, EECD); eecd_reg = IXGB_READ_REG(hw, EECD);
...@@ -189,13 +186,12 @@ ixgb_setup_eeprom(struct ixgb_hw *hw) ...@@ -189,13 +186,12 @@ ixgb_setup_eeprom(struct ixgb_hw *hw)
/****************************************************************************** /******************************************************************************
* Returns EEPROM to a "standby" state * Returns EEPROM to a "standby" state
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
static void static void ixgb_standby_eeprom(struct ixgb_hw *hw)
ixgb_standby_eeprom(struct ixgb_hw *hw)
{ {
u32 eecd_reg; uint32_t eecd_reg;
eecd_reg = IXGB_READ_REG(hw, EECD); eecd_reg = IXGB_READ_REG(hw, EECD);
...@@ -226,10 +222,9 @@ ixgb_standby_eeprom(struct ixgb_hw *hw) ...@@ -226,10 +222,9 @@ ixgb_standby_eeprom(struct ixgb_hw *hw)
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
static void static void ixgb_clock_eeprom(struct ixgb_hw *hw)
ixgb_clock_eeprom(struct ixgb_hw *hw)
{ {
u32 eecd_reg; uint32_t eecd_reg;
eecd_reg = IXGB_READ_REG(hw, EECD); eecd_reg = IXGB_READ_REG(hw, EECD);
...@@ -250,10 +245,9 @@ ixgb_clock_eeprom(struct ixgb_hw *hw) ...@@ -250,10 +245,9 @@ ixgb_clock_eeprom(struct ixgb_hw *hw)
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
static void static void ixgb_cleanup_eeprom(struct ixgb_hw *hw)
ixgb_cleanup_eeprom(struct ixgb_hw *hw)
{ {
u32 eecd_reg; uint32_t eecd_reg;
eecd_reg = IXGB_READ_REG(hw, EECD); eecd_reg = IXGB_READ_REG(hw, EECD);
...@@ -271,18 +265,17 @@ ixgb_cleanup_eeprom(struct ixgb_hw *hw) ...@@ -271,18 +265,17 @@ ixgb_cleanup_eeprom(struct ixgb_hw *hw)
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* The command is done when the EEPROM's data out pin goes high. * The command is done when the EEPROM's data out pin goes high.
* *
* Returns: * Returns:
* TRUE: EEPROM data pin is high before timeout. * TRUE: EEPROM data pin is high before timeout.
* FALSE: Time expired. * FALSE: Time expired.
*****************************************************************************/ *****************************************************************************/
static boolean_t static boolean_t ixgb_wait_eeprom_command(struct ixgb_hw *hw)
ixgb_wait_eeprom_command(struct ixgb_hw *hw)
{ {
u32 eecd_reg; uint32_t eecd_reg;
u32 i; uint32_t i;
/* Toggle the CS line. This in effect tells to EEPROM to actually execute /* Toggle the CS line. This in effect tells to EEPROM to actually execute
* the command in question. * the command in question.
*/ */
ixgb_standby_eeprom(hw); ixgb_standby_eeprom(hw);
...@@ -305,7 +298,7 @@ ixgb_wait_eeprom_command(struct ixgb_hw *hw) ...@@ -305,7 +298,7 @@ ixgb_wait_eeprom_command(struct ixgb_hw *hw)
/****************************************************************************** /******************************************************************************
* Verifies that the EEPROM has a valid checksum * Verifies that the EEPROM has a valid checksum
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Reads the first 64 16 bit words of the EEPROM and sums the values read. * Reads the first 64 16 bit words of the EEPROM and sums the values read.
...@@ -316,16 +309,15 @@ ixgb_wait_eeprom_command(struct ixgb_hw *hw) ...@@ -316,16 +309,15 @@ ixgb_wait_eeprom_command(struct ixgb_hw *hw)
* TRUE: Checksum is valid * TRUE: Checksum is valid
* FALSE: Checksum is not valid. * FALSE: Checksum is not valid.
*****************************************************************************/ *****************************************************************************/
boolean_t boolean_t ixgb_validate_eeprom_checksum(struct ixgb_hw * hw)
ixgb_validate_eeprom_checksum(struct ixgb_hw * hw)
{ {
u16 checksum = 0; uint16_t checksum = 0;
u16 i; uint16_t i;
for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++)
checksum += ixgb_read_eeprom(hw, i); checksum += ixgb_read_eeprom(hw, i);
if (checksum == (u16) EEPROM_SUM) if (checksum == (uint16_t) EEPROM_SUM)
return (TRUE); return (TRUE);
else else
return (FALSE); return (FALSE);
...@@ -339,16 +331,15 @@ ixgb_validate_eeprom_checksum(struct ixgb_hw * hw) ...@@ -339,16 +331,15 @@ ixgb_validate_eeprom_checksum(struct ixgb_hw * hw)
* Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA. * 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. * Writes the difference to word offset 63 of the EEPROM.
*****************************************************************************/ *****************************************************************************/
void void ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
{ {
u16 checksum = 0; uint16_t checksum = 0;
u16 i; uint16_t i;
for (i = 0; i < EEPROM_CHECKSUM_REG; i++) for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
checksum += ixgb_read_eeprom(hw, i); checksum += ixgb_read_eeprom(hw, i);
checksum = (u16) EEPROM_SUM - checksum; checksum = (uint16_t) EEPROM_SUM - checksum;
ixgb_write_eeprom(hw, EEPROM_CHECKSUM_REG, checksum); ixgb_write_eeprom(hw, EEPROM_CHECKSUM_REG, checksum);
return; return;
...@@ -361,18 +352,17 @@ ixgb_update_eeprom_checksum(struct ixgb_hw *hw) ...@@ -361,18 +352,17 @@ ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
* reg - offset within the EEPROM to be written to * reg - offset within the EEPROM to be written to
* data - 16 bit word to be writen to the EEPROM * data - 16 bit word to be writen to the EEPROM
* *
* If ixgb_update_eeprom_checksum is not called after this function, the * If ixgb_update_eeprom_checksum is not called after this function, the
* EEPROM will most likely contain an invalid checksum. * EEPROM will most likely contain an invalid checksum.
* *
*****************************************************************************/ *****************************************************************************/
void void ixgb_write_eeprom(struct ixgb_hw *hw, uint16_t offset, uint16_t data)
ixgb_write_eeprom(struct ixgb_hw *hw, u16 offset, u16 data)
{ {
/* Prepare the EEPROM for writing */ /* Prepare the EEPROM for writing */
ixgb_setup_eeprom(hw); ixgb_setup_eeprom(hw);
/* Send the 9-bit EWEN (write enable) command to the EEPROM (5-bit opcode /* 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. * 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, EEPROM_EWEN_OPCODE, 5);
ixgb_shift_out_bits(hw, 0, 4); ixgb_shift_out_bits(hw, 0, 4);
...@@ -414,17 +404,16 @@ ixgb_write_eeprom(struct ixgb_hw *hw, u16 offset, u16 data) ...@@ -414,17 +404,16 @@ ixgb_write_eeprom(struct ixgb_hw *hw, u16 offset, u16 data)
* Returns: * Returns:
* The 16-bit value read from the eeprom * The 16-bit value read from the eeprom
*****************************************************************************/ *****************************************************************************/
u16 uint16_t ixgb_read_eeprom(struct ixgb_hw * hw, uint16_t offset)
ixgb_read_eeprom(struct ixgb_hw * hw, u16 offset)
{ {
u16 data; uint16_t data;
/* Prepare the EEPROM for reading */ /* Prepare the EEPROM for reading */
ixgb_setup_eeprom(hw); ixgb_setup_eeprom(hw);
/* Send the READ command (opcode + addr) */ /* Send the READ command (opcode + addr) */
ixgb_shift_out_bits(hw, EEPROM_READ_OPCODE, 3); ixgb_shift_out_bits(hw, EEPROM_READ_OPCODE, 3);
/* /*
* We have a 64 word EEPROM, there are 6 address bits * We have a 64 word EEPROM, there are 6 address bits
*/ */
ixgb_shift_out_bits(hw, offset, 6); ixgb_shift_out_bits(hw, offset, 6);
...@@ -442,32 +431,31 @@ ixgb_read_eeprom(struct ixgb_hw * hw, u16 offset) ...@@ -442,32 +431,31 @@ ixgb_read_eeprom(struct ixgb_hw * hw, u16 offset)
* Reads eeprom and stores data in shared structure. * Reads eeprom and stores data in shared structure.
* Validates eeprom checksum and eeprom signature. * Validates eeprom checksum and eeprom signature.
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Returns: * Returns:
* TRUE: if eeprom read is successful * TRUE: if eeprom read is successful
* FALSE: otherwise. * FALSE: otherwise.
*****************************************************************************/ *****************************************************************************/
boolean_t boolean_t ixgb_get_eeprom_data(struct ixgb_hw * hw)
ixgb_get_eeprom_data(struct ixgb_hw * hw)
{ {
u16 i; uint16_t i;
u16 checksum = 0; uint16_t checksum = 0;
struct ixgb_ee_map_type *ee_map; struct ixgb_ee_map_type *ee_map;
DEBUGFUNC("ixgb_get_eeprom_data"); DEBUGFUNC("ixgb_get_eeprom_data");
ee_map = (struct ixgb_ee_map_type *) hw->eeprom; ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
DEBUGOUT("ixgb_ee: Reading eeprom data\n"); DEBUGOUT("ixgb_ee: Reading eeprom data\n");
for (i = 0; i < IXGB_EEPROM_SIZE; i++) { for (i = 0; i < IXGB_EEPROM_SIZE; i++) {
u16 ee_data; uint16_t ee_data;
ee_data = ixgb_read_eeprom(hw, i); ee_data = ixgb_read_eeprom(hw, i);
checksum += ee_data; checksum += ee_data;
hw->eeprom[i] = le16_to_cpu(ee_data); hw->eeprom[i] = le16_to_cpu(ee_data);
} }
if (checksum != (u16) EEPROM_SUM) { if (checksum != (uint16_t) EEPROM_SUM) {
DEBUGOUT("ixgb_ee: Checksum invalid.\n"); DEBUGOUT("ixgb_ee: Checksum invalid.\n");
return (FALSE); return (FALSE);
} }
...@@ -485,17 +473,15 @@ ixgb_get_eeprom_data(struct ixgb_hw * hw) ...@@ -485,17 +473,15 @@ ixgb_get_eeprom_data(struct ixgb_hw * hw)
* Local function to check if the eeprom signature is good * Local function to check if the eeprom signature is good
* If the eeprom signature is good, calls ixgb)get_eeprom_data. * If the eeprom signature is good, calls ixgb)get_eeprom_data.
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Returns: * Returns:
* TRUE: eeprom signature was good and the eeprom read was successful * TRUE: eeprom signature was good and the eeprom read was successful
* FALSE: otherwise. * FALSE: otherwise.
******************************************************************************/ ******************************************************************************/
static boolean_t static boolean_t ixgb_check_and_get_eeprom_data(struct ixgb_hw *hw)
ixgb_check_and_get_eeprom_data(struct ixgb_hw *hw)
{ {
struct ixgb_ee_map_type *ee_map = struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
(struct ixgb_ee_map_type *) hw->eeprom;
if ((ee_map->init_ctrl_reg_1 & le16_to_cpu(EEPROM_ICW1_SIGNATURE_MASK)) if ((ee_map->init_ctrl_reg_1 & le16_to_cpu(EEPROM_ICW1_SIGNATURE_MASK))
== le16_to_cpu(EEPROM_ICW1_SIGNATURE_VALID)) { == le16_to_cpu(EEPROM_ICW1_SIGNATURE_VALID)) {
...@@ -505,20 +491,38 @@ ixgb_check_and_get_eeprom_data(struct ixgb_hw *hw) ...@@ -505,20 +491,38 @@ ixgb_check_and_get_eeprom_data(struct ixgb_hw *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 * return the mac address from EEPROM
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* mac_addr - Ethernet Address if EEPROM contents are valid, 0 otherwise * mac_addr - Ethernet Address if EEPROM contents are valid, 0 otherwise
* *
* Returns: None. * Returns: None.
******************************************************************************/ ******************************************************************************/
void void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t * mac_addr)
ixgb_get_ee_mac_addr(struct ixgb_hw *hw, u8 * mac_addr)
{ {
int i; int i;
struct ixgb_ee_map_type *ee_map = struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
(struct ixgb_ee_map_type *) hw->eeprom;
DEBUGFUNC("ixgb_get_ee_mac_addr"); DEBUGFUNC("ixgb_get_ee_mac_addr");
...@@ -533,16 +537,14 @@ ixgb_get_ee_mac_addr(struct ixgb_hw *hw, u8 * mac_addr) ...@@ -533,16 +537,14 @@ ixgb_get_ee_mac_addr(struct ixgb_hw *hw, u8 * mac_addr)
/****************************************************************************** /******************************************************************************
* return the compatibility flags from EEPROM * return the compatibility flags from EEPROM
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Returns: * Returns:
* compatibility flags if EEPROM contents are valid, 0 otherwise * compatibility flags if EEPROM contents are valid, 0 otherwise
******************************************************************************/ ******************************************************************************/
u16 uint16_t ixgb_get_ee_compatibility(struct ixgb_hw *hw)
ixgb_get_ee_compatibility(struct ixgb_hw *hw)
{ {
struct ixgb_ee_map_type *ee_map = struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
(struct ixgb_ee_map_type *) hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE) if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->compatibility); return (ee_map->compatibility);
...@@ -553,13 +555,12 @@ ixgb_get_ee_compatibility(struct ixgb_hw *hw) ...@@ -553,13 +555,12 @@ ixgb_get_ee_compatibility(struct ixgb_hw *hw)
/****************************************************************************** /******************************************************************************
* return the Printed Board Assembly number from EEPROM * return the Printed Board Assembly number from EEPROM
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Returns: * Returns:
* PBA number if EEPROM contents are valid, 0 otherwise * PBA number if EEPROM contents are valid, 0 otherwise
******************************************************************************/ ******************************************************************************/
u32 uint32_t ixgb_get_ee_pba_number(struct ixgb_hw * hw)
ixgb_get_ee_pba_number(struct ixgb_hw * hw)
{ {
if (ixgb_check_and_get_eeprom_data(hw) == TRUE) if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG]) return (le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG])
...@@ -576,11 +577,9 @@ ixgb_get_ee_pba_number(struct ixgb_hw * hw) ...@@ -576,11 +577,9 @@ ixgb_get_ee_pba_number(struct ixgb_hw * hw)
* Returns: * Returns:
* Initialization Control Word 1 if EEPROM contents are valid, 0 otherwise * Initialization Control Word 1 if EEPROM contents are valid, 0 otherwise
******************************************************************************/ ******************************************************************************/
u16 uint16_t ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw * hw)
ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw * hw)
{ {
struct ixgb_ee_map_type *ee_map = struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
(struct ixgb_ee_map_type *) hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE) if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->init_ctrl_reg_1); return (ee_map->init_ctrl_reg_1);
...@@ -591,16 +590,14 @@ ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw * hw) ...@@ -591,16 +590,14 @@ ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw * hw)
/****************************************************************************** /******************************************************************************
* return the Initialization Control Word 2 from EEPROM * return the Initialization Control Word 2 from EEPROM
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Returns: * Returns:
* Initialization Control Word 2 if EEPROM contents are valid, 0 otherwise * Initialization Control Word 2 if EEPROM contents are valid, 0 otherwise
******************************************************************************/ ******************************************************************************/
u16 uint16_t ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw * hw)
ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw * hw)
{ {
struct ixgb_ee_map_type *ee_map = struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
(struct ixgb_ee_map_type *) hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE) if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->init_ctrl_reg_2); return (ee_map->init_ctrl_reg_2);
...@@ -611,16 +608,14 @@ ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw * hw) ...@@ -611,16 +608,14 @@ ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw * hw)
/****************************************************************************** /******************************************************************************
* return the Subsystem Id from EEPROM * return the Subsystem Id from EEPROM
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Returns: * Returns:
* Subsystem Id if EEPROM contents are valid, 0 otherwise * Subsystem Id if EEPROM contents are valid, 0 otherwise
******************************************************************************/ ******************************************************************************/
u16 uint16_t ixgb_get_ee_subsystem_id(struct ixgb_hw * hw)
ixgb_get_ee_subsystem_id(struct ixgb_hw * hw)
{ {
struct ixgb_ee_map_type *ee_map = struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
(struct ixgb_ee_map_type *) hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE) if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->subsystem_id); return (ee_map->subsystem_id);
...@@ -631,16 +626,14 @@ ixgb_get_ee_subsystem_id(struct ixgb_hw * hw) ...@@ -631,16 +626,14 @@ ixgb_get_ee_subsystem_id(struct ixgb_hw * hw)
/****************************************************************************** /******************************************************************************
* return the Sub Vendor Id from EEPROM * return the Sub Vendor Id from EEPROM
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Returns: * Returns:
* Sub Vendor Id if EEPROM contents are valid, 0 otherwise * Sub Vendor Id if EEPROM contents are valid, 0 otherwise
******************************************************************************/ ******************************************************************************/
u16 uint16_t ixgb_get_ee_subvendor_id(struct ixgb_hw * hw)
ixgb_get_ee_subvendor_id(struct ixgb_hw * hw)
{ {
struct ixgb_ee_map_type *ee_map = struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
(struct ixgb_ee_map_type *) hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE) if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->subvendor_id); return (ee_map->subvendor_id);
...@@ -651,16 +644,14 @@ ixgb_get_ee_subvendor_id(struct ixgb_hw * hw) ...@@ -651,16 +644,14 @@ ixgb_get_ee_subvendor_id(struct ixgb_hw * hw)
/****************************************************************************** /******************************************************************************
* return the Device Id from EEPROM * return the Device Id from EEPROM
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Returns: * Returns:
* Device Id if EEPROM contents are valid, 0 otherwise * Device Id if EEPROM contents are valid, 0 otherwise
******************************************************************************/ ******************************************************************************/
u16 uint16_t ixgb_get_ee_device_id(struct ixgb_hw * hw)
ixgb_get_ee_device_id(struct ixgb_hw * hw)
{ {
struct ixgb_ee_map_type *ee_map = struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
(struct ixgb_ee_map_type *) hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE) if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->device_id); return (ee_map->device_id);
...@@ -671,16 +662,14 @@ ixgb_get_ee_device_id(struct ixgb_hw * hw) ...@@ -671,16 +662,14 @@ ixgb_get_ee_device_id(struct ixgb_hw * hw)
/****************************************************************************** /******************************************************************************
* return the Vendor Id from EEPROM * return the Vendor Id from EEPROM
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Returns: * Returns:
* Device Id if EEPROM contents are valid, 0 otherwise * Device Id if EEPROM contents are valid, 0 otherwise
******************************************************************************/ ******************************************************************************/
u16 uint16_t ixgb_get_ee_vendor_id(struct ixgb_hw * hw)
ixgb_get_ee_vendor_id(struct ixgb_hw * hw)
{ {
struct ixgb_ee_map_type *ee_map = struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
(struct ixgb_ee_map_type *) hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE) if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->vendor_id); return (ee_map->vendor_id);
...@@ -691,16 +680,14 @@ ixgb_get_ee_vendor_id(struct ixgb_hw * hw) ...@@ -691,16 +680,14 @@ ixgb_get_ee_vendor_id(struct ixgb_hw * hw)
/****************************************************************************** /******************************************************************************
* return the Software Defined Pins Register from EEPROM * return the Software Defined Pins Register from EEPROM
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Returns: * Returns:
* SDP Register if EEPROM contents are valid, 0 otherwise * SDP Register if EEPROM contents are valid, 0 otherwise
******************************************************************************/ ******************************************************************************/
u16 uint16_t ixgb_get_ee_swdpins_reg(struct ixgb_hw * hw)
ixgb_get_ee_swdpins_reg(struct ixgb_hw * hw)
{ {
struct ixgb_ee_map_type *ee_map = struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
(struct ixgb_ee_map_type *) hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE) if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->swdpins_reg); return (ee_map->swdpins_reg);
...@@ -711,16 +698,14 @@ ixgb_get_ee_swdpins_reg(struct ixgb_hw * hw) ...@@ -711,16 +698,14 @@ ixgb_get_ee_swdpins_reg(struct ixgb_hw * hw)
/****************************************************************************** /******************************************************************************
* return the D3 Power Management Bits from EEPROM * return the D3 Power Management Bits from EEPROM
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Returns: * Returns:
* D3 Power Management Bits if EEPROM contents are valid, 0 otherwise * D3 Power Management Bits if EEPROM contents are valid, 0 otherwise
******************************************************************************/ ******************************************************************************/
u8 uint8_t ixgb_get_ee_d3_power(struct ixgb_hw * hw)
ixgb_get_ee_d3_power(struct ixgb_hw * hw)
{ {
struct ixgb_ee_map_type *ee_map = struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
(struct ixgb_ee_map_type *) hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE) if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->d3_power); return (ee_map->d3_power);
...@@ -731,16 +716,14 @@ ixgb_get_ee_d3_power(struct ixgb_hw * hw) ...@@ -731,16 +716,14 @@ ixgb_get_ee_d3_power(struct ixgb_hw * hw)
/****************************************************************************** /******************************************************************************
* return the D0 Power Management Bits from EEPROM * return the D0 Power Management Bits from EEPROM
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Returns: * Returns:
* D0 Power Management Bits if EEPROM contents are valid, 0 otherwise * D0 Power Management Bits if EEPROM contents are valid, 0 otherwise
******************************************************************************/ ******************************************************************************/
u8 uint8_t ixgb_get_ee_d0_power(struct ixgb_hw * hw)
ixgb_get_ee_d0_power(struct ixgb_hw * hw)
{ {
struct ixgb_ee_map_type *ee_map = struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
(struct ixgb_ee_map_type *) hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE) if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->d0_power); return (ee_map->d0_power);
......
/******************************************************************************* /*******************************************************************************
Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
Contact Information: Contact Information:
Linux NICS <linux.nics@intel.com> Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/ *******************************************************************************/
#ifndef _IXGB_EE_H_ #ifndef _IXGB_EE_H_
...@@ -33,9 +34,9 @@ ...@@ -33,9 +34,9 @@
#define IXGB_ETH_LENGTH_OF_ADDRESS 6 #define IXGB_ETH_LENGTH_OF_ADDRESS 6
/* EEPROM Commands */ /* EEPROM Commands */
#define EEPROM_READ_OPCODE 0x6 /* EERPOM read opcode */ #define EEPROM_READ_OPCODE 0x6 /* EERPOM read opcode */
#define EEPROM_WRITE_OPCODE 0x5 /* EERPOM write opcode */ #define EEPROM_WRITE_OPCODE 0x5 /* EERPOM write opcode */
#define EEPROM_ERASE_OPCODE 0x7 /* EERPOM erase opcode */ #define EEPROM_ERASE_OPCODE 0x7 /* EERPOM erase opcode */
#define EEPROM_EWEN_OPCODE 0x13 /* EERPOM erase/write enable */ #define EEPROM_EWEN_OPCODE 0x13 /* EERPOM erase/write enable */
#define EEPROM_EWDS_OPCODE 0x10 /* EERPOM erast/write disable */ #define EEPROM_EWDS_OPCODE 0x10 /* EERPOM erast/write disable */
...@@ -73,32 +74,32 @@ ...@@ -73,32 +74,32 @@
/* EEPROM structure */ /* EEPROM structure */
struct ixgb_ee_map_type { struct ixgb_ee_map_type {
u8 mac_addr[IXGB_ETH_LENGTH_OF_ADDRESS]; uint8_t mac_addr[IXGB_ETH_LENGTH_OF_ADDRESS];
u16 compatibility; uint16_t compatibility;
u16 reserved1[4]; uint16_t reserved1[4];
u32 pba_number; uint32_t pba_number;
u16 init_ctrl_reg_1; uint16_t init_ctrl_reg_1;
u16 subsystem_id; uint16_t subsystem_id;
u16 subvendor_id; uint16_t subvendor_id;
u16 device_id; uint16_t device_id;
u16 vendor_id; uint16_t vendor_id;
u16 init_ctrl_reg_2; uint16_t init_ctrl_reg_2;
u16 oem_reserved[16]; uint16_t oem_reserved[16];
u16 swdpins_reg; uint16_t swdpins_reg;
u16 circuit_ctrl_reg; uint16_t circuit_ctrl_reg;
u8 d3_power; uint8_t d3_power;
u8 d0_power; uint8_t d0_power;
u16 reserved2[28]; uint16_t reserved2[28];
u16 checksum; uint16_t checksum;
}; };
/* EEPROM Functions */ /* EEPROM Functions */
u16 ixgb_read_eeprom(struct ixgb_hw *hw, u16 reg); uint16_t ixgb_read_eeprom(struct ixgb_hw *hw, uint16_t reg);
boolean_t ixgb_validate_eeprom_checksum(struct ixgb_hw *hw); boolean_t ixgb_validate_eeprom_checksum(struct ixgb_hw *hw);
void ixgb_update_eeprom_checksum(struct ixgb_hw *hw); void ixgb_update_eeprom_checksum(struct ixgb_hw *hw);
void ixgb_write_eeprom(struct ixgb_hw *hw, u16 reg, u16 data); void ixgb_write_eeprom(struct ixgb_hw *hw, uint16_t reg, uint16_t data);
#endif /* IXGB_EE_H */ #endif /* IXGB_EE_H */
/******************************************************************************* /*******************************************************************************
Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
Contact Information: Contact Information:
Linux NICS <linux.nics@intel.com> Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/ *******************************************************************************/
/* ethtool support for ixgb */ /* ethtool support for ixgb */
...@@ -35,22 +36,63 @@ extern char ixgb_driver_name[]; ...@@ -35,22 +36,63 @@ extern char ixgb_driver_name[];
extern char ixgb_driver_version[]; extern char ixgb_driver_version[];
extern int ixgb_up(struct ixgb_adapter *adapter); extern int ixgb_up(struct ixgb_adapter *adapter);
extern int ixgb_down(struct ixgb_adapter *adapter); extern void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog);
/**
* ixgb_ethtool_ioctl - Ethtool Ioctl Support
* @netdev: net device structure
* @ifr: interface request structure
**/
static inline int static inline int ixgb_eeprom_size(struct ixgb_hw *hw)
ixgb_eeprom_size(struct ixgb_hw *hw)
{ {
/* return size in bytes */ /* return size in bytes */
return (IXGB_EEPROM_SIZE << 1); return (IXGB_EEPROM_SIZE << 1);
} }
#define SPEED_10000 10000 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)},
{"rx_long_length_errors", IXGB_STAT(stats.roc)},
{"rx_short_length_errors", IXGB_STAT(stats.ruc)},
#ifdef NETIF_F_TSO
{"tx_tcp_seg_good", IXGB_STAT(stats.tsctc)},
{"tx_tcp_seg_failed", IXGB_STAT(stats.tsctfc)},
#endif
{"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 void static void
ixgb_ethtool_gset(struct ixgb_adapter *adapter, struct ethtool_cmd *ecmd) ixgb_ethtool_gset(struct ixgb_adapter *adapter, struct ethtool_cmd *ecmd)
...@@ -61,7 +103,7 @@ ixgb_ethtool_gset(struct ixgb_adapter *adapter, struct ethtool_cmd *ecmd) ...@@ -61,7 +103,7 @@ ixgb_ethtool_gset(struct ixgb_adapter *adapter, struct ethtool_cmd *ecmd)
ecmd->transceiver = XCVR_EXTERNAL; ecmd->transceiver = XCVR_EXTERNAL;
if (netif_carrier_ok(adapter->netdev)) { if (netif_carrier_ok(adapter->netdev)) {
ecmd->speed = 10000; ecmd->speed = SPEED_10000;
ecmd->duplex = DUPLEX_FULL; ecmd->duplex = DUPLEX_FULL;
} else { } else {
ecmd->speed = -1; ecmd->speed = -1;
...@@ -78,64 +120,80 @@ ixgb_ethtool_sset(struct ixgb_adapter *adapter, struct ethtool_cmd *ecmd) ...@@ -78,64 +120,80 @@ ixgb_ethtool_sset(struct ixgb_adapter *adapter, struct ethtool_cmd *ecmd)
ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL) ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)
return -EINVAL; return -EINVAL;
else { else {
ixgb_down(adapter); ixgb_down(adapter, TRUE);
ixgb_up(adapter); ixgb_up(adapter);
} }
return 0; return 0;
} }
#if 0
static int static int
ixgb_ethtool_promiscuous(struct ixgb_adapter *adapter, ixgb_ethtool_gpause(struct ixgb_adapter *adapter,
struct ethtool_pmode *pmode) struct ethtool_pauseparam *epause)
{ {
u32 rctl = IXGB_READ_REG(&adapter->hw, RCTL); struct ixgb_hw *hw = &adapter->hw;
pmode->rctl_old = rctl; epause->autoneg = AUTONEG_DISABLE;
if (pmode->upe)
rctl |= IXGB_RCTL_UPE;
else
rctl &= ~IXGB_RCTL_UPE;
if (pmode->mpe) if (hw->fc.type == ixgb_fc_rx_pause)
rctl |= IXGB_RCTL_MPE; epause->rx_pause = 1;
else else if (hw->fc.type == ixgb_fc_tx_pause)
rctl &= ~IXGB_RCTL_MPE; epause->tx_pause = 1;
else if (hw->fc.type == ixgb_fc_full) {
epause->rx_pause = 1;
epause->tx_pause = 1;
}
return 0;
}
static int
ixgb_ethtool_spause(struct ixgb_adapter *adapter,
struct ethtool_pauseparam *epause)
{
struct ixgb_hw *hw = &adapter->hw;
if (epause->autoneg == AUTONEG_ENABLE)
return -EINVAL;
IXGB_WRITE_REG(&adapter->hw, RCTL, rctl); if (epause->rx_pause && epause->tx_pause)
hw->fc.type = ixgb_fc_full;
else if (epause->rx_pause && !epause->tx_pause)
hw->fc.type = ixgb_fc_rx_pause;
else if (!epause->rx_pause && epause->tx_pause)
hw->fc.type = ixgb_fc_tx_pause;
else if (!epause->rx_pause && !epause->tx_pause)
hw->fc.type = ixgb_fc_none;
pmode->rctl_new = IXGB_READ_REG(&adapter->hw, RCTL); ixgb_down(adapter, TRUE);
ixgb_up(adapter);
return 0; return 0;
} }
#endif
#define IXGB_REG_DUMP_LEN 136*sizeof(u32)
static void static void
ixgb_ethtool_gdrvinfo(struct ixgb_adapter *adapter, ixgb_ethtool_gdrvinfo(struct ixgb_adapter *adapter,
struct ethtool_drvinfo *drvinfo) struct ethtool_drvinfo *drvinfo)
{ {
strncpy(drvinfo->driver, ixgb_driver_name, 32); strncpy(drvinfo->driver, ixgb_driver_name, 32);
strncpy(drvinfo->version, ixgb_driver_version, 32); strncpy(drvinfo->version, ixgb_driver_version, 32);
strncpy(drvinfo->fw_version, "", 32); strncpy(drvinfo->fw_version, "N/A", 32);
strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
#ifdef ETHTOOL_GREGS drvinfo->n_stats = IXGB_STATS_LEN;
#define IXGB_REG_DUMP_LEN 136*sizeof(uint32_t)
drvinfo->regdump_len = IXGB_REG_DUMP_LEN; drvinfo->regdump_len = IXGB_REG_DUMP_LEN;
#endif /* ETHTOOL_GREGS */
drvinfo->eedump_len = ixgb_eeprom_size(&adapter->hw); drvinfo->eedump_len = ixgb_eeprom_size(&adapter->hw);
} }
#ifdef ETHTOOL_GREGS
#define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_ #define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_
static void static void
ixgb_ethtool_gregs(struct ixgb_adapter *adapter, ixgb_ethtool_gregs(struct ixgb_adapter *adapter,
struct ethtool_regs *regs, u8 * regs_buff) struct ethtool_regs *regs, uint32_t * regs_buff)
{ {
struct ixgb_hw *hw = &adapter->hw; struct ixgb_hw *hw = &adapter->hw;
u32 *reg = (u32 *) regs_buff; uint32_t *reg = regs_buff;
u32 *reg_start = reg; uint32_t *reg_start = reg;
u8 i; uint8_t i;
regs->version = regs->version =
(adapter->hw.device_id << 16) | adapter->hw.subsystem_id; (adapter->hw.device_id << 16) | adapter->hw.subsystem_id;
...@@ -199,15 +257,6 @@ ixgb_ethtool_gregs(struct ixgb_adapter *adapter, ...@@ -199,15 +257,6 @@ ixgb_ethtool_gregs(struct ixgb_adapter *adapter,
*reg++ = IXGB_READ_REG(hw, MSCA); /* 74 */ *reg++ = IXGB_READ_REG(hw, MSCA); /* 74 */
*reg++ = IXGB_READ_REG(hw, MSRWD); /* 75 */ *reg++ = IXGB_READ_REG(hw, MSRWD); /* 75 */
#if 0
/* Wake-up */
reg[IXGB_WUFC] = IXGB_READ_REG(hw, WUFC);
reg[IXGB_WUS] = IXGB_READ_REG(hw, WUS);
reg[IXGB_FFLT] = IXGB_READ_REG(hw, FFLT);
reg[IXGB_FFMT] = IXGB_READ_REG(hw, FFMT);
reg[IXGB_FTVT] = IXGB_READ_REG(hw, FTVT);
#endif
/* Statistics */ /* Statistics */
*reg++ = IXGB_GET_STAT(adapter, tprl); /* 76 */ *reg++ = IXGB_GET_STAT(adapter, tprl); /* 76 */
*reg++ = IXGB_GET_STAT(adapter, tprh); /* 77 */ *reg++ = IXGB_GET_STAT(adapter, tprh); /* 77 */
...@@ -270,22 +319,21 @@ ixgb_ethtool_gregs(struct ixgb_adapter *adapter, ...@@ -270,22 +319,21 @@ ixgb_ethtool_gregs(struct ixgb_adapter *adapter,
*reg++ = IXGB_GET_STAT(adapter, xofftxc); /* 134 */ *reg++ = IXGB_GET_STAT(adapter, xofftxc); /* 134 */
*reg++ = IXGB_GET_STAT(adapter, rjc); /* 135 */ *reg++ = IXGB_GET_STAT(adapter, rjc); /* 135 */
#if 0 regs->len = (reg - reg_start) * sizeof(uint32_t);
#endif
regs->len = (reg - reg_start) * sizeof (u32);
} }
#endif /* ETHTOOL_GREGS */
static int static int
ixgb_ethtool_geeprom(struct ixgb_adapter *adapter, ixgb_ethtool_geeprom(struct ixgb_adapter *adapter,
struct ethtool_eeprom *eeprom, u16 * eeprom_buff) struct ethtool_eeprom *eeprom, uint16_t * eeprom_buff)
{ {
struct ixgb_hw *hw = &adapter->hw; struct ixgb_hw *hw = &adapter->hw;
int i, max_len, first_word, last_word; int i, max_len, first_word, last_word;
IXGB_DBG("ixgb_ethtool_geeprom\n"); int ret_val = 0;
if (eeprom->len == 0) if (eeprom->len == 0) {
return -EINVAL; ret_val = -EINVAL;
goto geeprom_error;
}
eeprom->magic = hw->vendor_id | (hw->device_id << 16); eeprom->magic = hw->vendor_id | (hw->device_id << 16);
...@@ -294,8 +342,10 @@ ixgb_ethtool_geeprom(struct ixgb_adapter *adapter, ...@@ -294,8 +342,10 @@ ixgb_ethtool_geeprom(struct ixgb_adapter *adapter,
/* use our function to read the eeprom and update our cache */ /* use our function to read the eeprom and update our cache */
ixgb_get_eeprom_data(hw); ixgb_get_eeprom_data(hw);
if (eeprom->offset > eeprom->offset + eeprom->len) if (eeprom->offset > eeprom->offset + eeprom->len) {
return -EINVAL; ret_val = -EINVAL;
goto geeprom_error;
}
if ((eeprom->offset + eeprom->len) > max_len) if ((eeprom->offset + eeprom->len) > max_len)
eeprom->len = (max_len - eeprom->offset); eeprom->len = (max_len - eeprom->offset);
...@@ -306,15 +356,16 @@ ixgb_ethtool_geeprom(struct ixgb_adapter *adapter, ...@@ -306,15 +356,16 @@ ixgb_ethtool_geeprom(struct ixgb_adapter *adapter,
for (i = 0; i <= (last_word - first_word); i++) { for (i = 0; i <= (last_word - first_word); i++) {
eeprom_buff[i] = hw->eeprom[first_word + i]; eeprom_buff[i] = hw->eeprom[first_word + i];
} }
geeprom_error:
return 0; return ret_val;
} }
static int static int
ixgb_ethtool_seeprom(struct ixgb_adapter *adapter, ixgb_ethtool_seeprom(struct ixgb_adapter *adapter,
struct ethtool_eeprom *eeprom, void *user_data) struct ethtool_eeprom *eeprom, void *user_data)
{ {
struct ixgb_hw *hw = &adapter->hw; struct ixgb_hw *hw = &adapter->hw;
u16 eeprom_buff[256]; uint16_t eeprom_buff[256];
int i, max_len, first_word, last_word; int i, max_len, first_word, last_word;
void *ptr; void *ptr;
...@@ -334,7 +385,7 @@ ixgb_ethtool_seeprom(struct ixgb_adapter *adapter, ...@@ -334,7 +385,7 @@ ixgb_ethtool_seeprom(struct ixgb_adapter *adapter,
first_word = eeprom->offset >> 1; first_word = eeprom->offset >> 1;
last_word = (eeprom->offset + eeprom->len - 1) >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1;
ptr = (void *) eeprom_buff; ptr = (void *)eeprom_buff;
if (eeprom->offset & 1) { if (eeprom->offset & 1) {
/* need read/modify/write of first changed EEPROM word */ /* need read/modify/write of first changed EEPROM word */
...@@ -361,18 +412,15 @@ ixgb_ethtool_seeprom(struct ixgb_adapter *adapter, ...@@ -361,18 +412,15 @@ ixgb_ethtool_seeprom(struct ixgb_adapter *adapter,
return 0; return 0;
} }
#ifdef ETHTOOL_PHYS_ID
/* toggle LED 4 times per second = 2 "blinks" per second */ /* toggle LED 4 times per second = 2 "blinks" per second */
#define IXGB_ID_INTERVAL (HZ/4) #define IXGB_ID_INTERVAL (HZ/4)
/* bit defines for adapter->led_status */ /* bit defines for adapter->led_status */
#define IXGB_LED_ON 0 #define IXGB_LED_ON 0
static void static void ixgb_led_blink_callback(unsigned long data)
ixgb_led_blink_callback(unsigned long data)
{ {
struct ixgb_adapter *adapter = (struct ixgb_adapter *) data; struct ixgb_adapter *adapter = (struct ixgb_adapter *)data;
if (test_and_change_bit(IXGB_LED_ON, &adapter->led_status)) if (test_and_change_bit(IXGB_LED_ON, &adapter->led_status))
ixgb_led_off(&adapter->hw); ixgb_led_off(&adapter->hw);
...@@ -388,7 +436,7 @@ ixgb_ethtool_led_blink(struct ixgb_adapter *adapter, struct ethtool_value *id) ...@@ -388,7 +436,7 @@ ixgb_ethtool_led_blink(struct ixgb_adapter *adapter, struct ethtool_value *id)
if (!adapter->blink_timer.function) { if (!adapter->blink_timer.function) {
init_timer(&adapter->blink_timer); init_timer(&adapter->blink_timer);
adapter->blink_timer.function = ixgb_led_blink_callback; adapter->blink_timer.function = ixgb_led_blink_callback;
adapter->blink_timer.data = (unsigned long) adapter; adapter->blink_timer.data = (unsigned long)adapter;
} }
mod_timer(&adapter->blink_timer, jiffies); mod_timer(&adapter->blink_timer, jiffies);
...@@ -405,114 +453,121 @@ ixgb_ethtool_led_blink(struct ixgb_adapter *adapter, struct ethtool_value *id) ...@@ -405,114 +453,121 @@ ixgb_ethtool_led_blink(struct ixgb_adapter *adapter, struct ethtool_value *id)
return 0; return 0;
} }
#endif /* ETHTOOL_PHYS_ID */
int int ixgb_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
ixgb_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
{ {
struct ixgb_adapter *adapter = netdev->priv; struct ixgb_adapter *adapter = netdev->priv;
void *addr = ifr->ifr_data; void *addr = ifr->ifr_data;
u32 cmd; uint32_t cmd;
if (get_user(cmd, (u32 *) addr)) if (get_user(cmd, (uint32_t *) addr))
return -EFAULT; return -EFAULT;
switch (cmd) { switch (cmd) {
#if 0
case ETHTOOL_PROMISCUOUS:{
struct ethtool_pmode pmode;
if (copy_from_user(&pmode, addr, sizeof (pmode)))
return -EFAULT;
ixgb_ethtool_promiscuous(adapter, &pmode);
if (copy_to_user(addr, &pmode, sizeof (pmode)))
return -EFAULT;
return 0;
}
case ETHTOOL_DOWN_UP:
ixgb_down(netdev->priv);
ixgb_up(netdev->priv);
return 0;
#endif
case ETHTOOL_GSET:{ case ETHTOOL_GSET:{
struct ethtool_cmd ecmd = { ETHTOOL_GSET }; struct ethtool_cmd ecmd = { ETHTOOL_GSET };
ixgb_ethtool_gset(adapter, &ecmd); ixgb_ethtool_gset(adapter, &ecmd);
if (copy_to_user(addr, &ecmd, sizeof (ecmd))) if (copy_to_user(addr, &ecmd, sizeof(ecmd)))
return -EFAULT; return -EFAULT;
return 0; return 0;
} }
case ETHTOOL_SSET:{ case ETHTOOL_SSET:{
struct ethtool_cmd ecmd; struct ethtool_cmd ecmd;
if (copy_from_user(&ecmd, addr, sizeof(ecmd)))
if (copy_from_user(&ecmd, addr, sizeof (ecmd)))
return -EFAULT; return -EFAULT;
return ixgb_ethtool_sset(adapter, &ecmd); return ixgb_ethtool_sset(adapter, &ecmd);
} }
case ETHTOOL_GDRVINFO: case ETHTOOL_GDRVINFO:{
{
struct ethtool_drvinfo drvinfo = { ETHTOOL_GDRVINFO }; struct ethtool_drvinfo drvinfo = { ETHTOOL_GDRVINFO };
ixgb_ethtool_gdrvinfo(adapter, &drvinfo); ixgb_ethtool_gdrvinfo(adapter, &drvinfo);
if (copy_to_user(addr, &drvinfo, sizeof (drvinfo))) if (copy_to_user(addr, &drvinfo, sizeof(drvinfo)))
return -EFAULT; return -EFAULT;
return 0; return 0;
} }
#if defined(ETHTOOL_GREGS) && defined(ETHTOOL_GEEPROM) case ETHTOOL_GSTRINGS:{
struct ethtool_gstrings gstrings = { ETHTOOL_GSTRINGS };
char *strings = NULL;
int err = 0;
if (copy_from_user(&gstrings, addr, sizeof(gstrings)))
return -EFAULT;
switch (gstrings.string_set) {
case ETH_SS_STATS:{
int i;
gstrings.len = IXGB_STATS_LEN;
strings =
kmalloc(IXGB_STATS_LEN *
ETH_GSTRING_LEN,
GFP_KERNEL);
if (!strings)
return -ENOMEM;
for (i = 0; i < IXGB_STATS_LEN; i++) {
memcpy(&strings
[i * ETH_GSTRING_LEN],
ixgb_gstrings_stats[i].
stat_string,
ETH_GSTRING_LEN);
}
break;
}
default:
return -EOPNOTSUPP;
}
if (copy_to_user(addr, &gstrings, sizeof(gstrings)))
err = -EFAULT;
addr += offsetof(struct ethtool_gstrings, data);
if (!err && copy_to_user(addr, strings,
gstrings.len *
ETH_GSTRING_LEN))
err = -EFAULT;
kfree(strings);
return err;
}
case ETHTOOL_GREGS:{ case ETHTOOL_GREGS:{
struct ethtool_regs regs = { ETHTOOL_GREGS }; struct ethtool_regs regs = { ETHTOOL_GREGS };
u8 regs_buff[IXGB_REG_DUMP_LEN]; uint32_t regs_buff[IXGB_REG_DUMP_LEN];
if (copy_from_user(&regs, addr, sizeof(regs)))
return -EFAULT;
ixgb_ethtool_gregs(adapter, &regs, regs_buff); ixgb_ethtool_gregs(adapter, &regs, regs_buff);
if (copy_to_user(addr, &regs, sizeof(regs)))
if (copy_to_user(addr, &regs, sizeof (regs)))
return -EFAULT; return -EFAULT;
addr += offsetof(struct ethtool_regs, data); addr += offsetof(struct ethtool_regs, data);
if (copy_to_user(addr, regs_buff, regs.len)) if (copy_to_user(addr, regs_buff, regs.len))
return -EFAULT; return -EFAULT;
return 0; return 0;
} }
#endif /* ETHTOOL_GREGS */
case ETHTOOL_NWAY_RST:{ case ETHTOOL_NWAY_RST:{
IXGB_DBG("ETHTOOL_NWAY_RST\n"); if (netif_running(netdev)) {
ixgb_down(adapter); ixgb_down(adapter, TRUE);
ixgb_up(adapter); ixgb_up(adapter);
}
return 0; return 0;
} }
#ifdef ETHTOOL_PHYS_ID
case ETHTOOL_PHYS_ID:{ case ETHTOOL_PHYS_ID:{
struct ethtool_value id; struct ethtool_value id;
if (copy_from_user(&id, addr, sizeof(id)))
IXGB_DBG("ETHTOOL_PHYS_ID\n");
if (copy_from_user(&id, addr, sizeof (id)))
return -EFAULT; return -EFAULT;
return ixgb_ethtool_led_blink(adapter, &id); return ixgb_ethtool_led_blink(adapter, &id);
} }
#endif /* ETHTOOL_PHYS_ID */
case ETHTOOL_GLINK:{ case ETHTOOL_GLINK:{
struct ethtool_value link = { ETHTOOL_GLINK }; struct ethtool_value link = { ETHTOOL_GLINK };
IXGB_DBG("ETHTOOL_GLINK\n");
link.data = netif_carrier_ok(netdev); link.data = netif_carrier_ok(netdev);
if (copy_to_user(addr, &link, sizeof (link))) if (copy_to_user(addr, &link, sizeof(link)))
return -EFAULT; return -EFAULT;
return 0; return 0;
} }
case ETHTOOL_GEEPROM:{ case ETHTOOL_GEEPROM:{
struct ethtool_eeprom eeprom = { ETHTOOL_GEEPROM }; struct ethtool_eeprom eeprom = { ETHTOOL_GEEPROM };
u16 eeprom_buff[IXGB_EEPROM_SIZE]; uint16_t eeprom_buff[IXGB_EEPROM_SIZE];
void *ptr; void *ptr;
int err; int err = 0;
IXGB_DBG("ETHTOOL_GEEPROM\n"); if (copy_from_user(&eeprom, addr, sizeof(eeprom)))
if (copy_from_user(&eeprom, addr, sizeof (eeprom)))
return -EFAULT; return -EFAULT;
if ((err = if ((err =
...@@ -520,12 +575,12 @@ ixgb_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr) ...@@ -520,12 +575,12 @@ ixgb_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
eeprom_buff)) < 0) eeprom_buff)) < 0)
return err; return err;
if (copy_to_user(addr, &eeprom, sizeof (eeprom))) if (copy_to_user(addr, &eeprom, sizeof(eeprom)))
return -EFAULT; return -EFAULT;
addr += offsetof(struct ethtool_eeprom, data); addr += offsetof(struct ethtool_eeprom, data);
ptr = ((void *)eeprom_buff) + (eeprom.offset & 1);
ptr = ((void *) eeprom_buff) + (eeprom.offset & 1);
if (copy_to_user(addr, ptr, eeprom.len)) if (copy_to_user(addr, ptr, eeprom.len))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -533,13 +588,133 @@ ixgb_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr) ...@@ -533,13 +588,133 @@ ixgb_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
case ETHTOOL_SEEPROM:{ case ETHTOOL_SEEPROM:{
struct ethtool_eeprom eeprom; struct ethtool_eeprom eeprom;
IXGB_DBG("ETHTOOL_SEEPROM\n"); if (copy_from_user(&eeprom, addr, sizeof(eeprom)))
if (copy_from_user(&eeprom, addr, sizeof (eeprom)))
return -EFAULT; return -EFAULT;
addr += offsetof(struct ethtool_eeprom, data); addr += offsetof(struct ethtool_eeprom, data);
return ixgb_ethtool_seeprom(adapter, &eeprom, addr); return ixgb_ethtool_seeprom(adapter, &eeprom, addr);
} }
case ETHTOOL_GPAUSEPARAM:{
struct ethtool_pauseparam epause =
{ ETHTOOL_GPAUSEPARAM };
ixgb_ethtool_gpause(adapter, &epause);
if (copy_to_user(addr, &epause, sizeof(epause)))
return -EFAULT;
return 0;
}
case ETHTOOL_SPAUSEPARAM:{
struct ethtool_pauseparam epause;
if (copy_from_user(&epause, addr, sizeof(epause)))
return -EFAULT;
return ixgb_ethtool_spause(adapter, &epause);
}
case ETHTOOL_GSTATS:{
struct {
struct ethtool_stats eth_stats;
uint64_t data[IXGB_STATS_LEN];
} stats = { {
ETHTOOL_GSTATS, IXGB_STATS_LEN}};
int i;
for (i = 0; i < IXGB_STATS_LEN; i++)
stats.data[i] =
(ixgb_gstrings_stats[i].sizeof_stat ==
sizeof(uint64_t)) ? *(uint64_t *) ((char *)
adapter
+
ixgb_gstrings_stats
[i].
stat_offset)
: *(uint32_t *) ((char *)adapter +
ixgb_gstrings_stats[i].
stat_offset);
if (copy_to_user(addr, &stats, sizeof(stats)))
return -EFAULT;
return 0;
}
case ETHTOOL_GRXCSUM:{
struct ethtool_value edata = { ETHTOOL_GRXCSUM };
edata.data = adapter->rx_csum;
if (copy_to_user(addr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
case ETHTOOL_SRXCSUM:{
struct ethtool_value edata;
if (copy_from_user(&edata, addr, sizeof(edata)))
return -EFAULT;
adapter->rx_csum = edata.data;
ixgb_down(adapter, TRUE);
ixgb_up(adapter);
return 0;
}
case ETHTOOL_GTXCSUM:{
struct ethtool_value edata = { ETHTOOL_GTXCSUM };
edata.data = (netdev->features & NETIF_F_HW_CSUM) != 0;
if (copy_to_user(addr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
case ETHTOOL_STXCSUM:{
struct ethtool_value edata;
if (copy_from_user(&edata, addr, sizeof(edata)))
return -EFAULT;
if (edata.data)
netdev->features |= NETIF_F_HW_CSUM;
else
netdev->features &= ~NETIF_F_HW_CSUM;
return 0;
}
case ETHTOOL_GSG:{
struct ethtool_value edata = { ETHTOOL_GSG };
edata.data = (netdev->features & NETIF_F_SG) != 0;
if (copy_to_user(addr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
case ETHTOOL_SSG:{
struct ethtool_value edata;
if (copy_from_user(&edata, addr, sizeof(edata)))
return -EFAULT;
if (edata.data)
netdev->features |= NETIF_F_SG;
else
netdev->features &= ~NETIF_F_SG;
return 0;
}
#ifdef NETIF_F_TSO
case ETHTOOL_GTSO:{
struct ethtool_value edata = { ETHTOOL_GTSO };
edata.data = (netdev->features & NETIF_F_TSO) != 0;
if (copy_to_user(addr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
case ETHTOOL_STSO:{
struct ethtool_value edata;
if (copy_from_user(&edata, addr, sizeof(edata)))
return -EFAULT;
if (edata.data)
netdev->features |= NETIF_F_TSO;
else
netdev->features &= ~NETIF_F_TSO;
return 0;
}
#endif
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
......
/******************************************************************************* /*******************************************************************************
Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
Contact Information: Contact Information:
Linux NICS <linux.nics@intel.com> Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/ *******************************************************************************/
/* ixgb_hw.c /* ixgb_hw.c
...@@ -34,32 +35,31 @@ ...@@ -34,32 +35,31 @@
/* Local function prototypes */ /* Local function prototypes */
static u32 ixgb_hash_mc_addr(struct ixgb_hw *hw, u8 * mc_addr); static uint32_t ixgb_hash_mc_addr(struct ixgb_hw *hw, uint8_t * mc_addr);
static void ixgb_mta_set(struct ixgb_hw *hw, u32 hash_value); static void ixgb_mta_set(struct ixgb_hw *hw, uint32_t hash_value);
static void ixgb_get_bus_info(struct ixgb_hw *hw); static void ixgb_get_bus_info(struct ixgb_hw *hw);
boolean_t mac_addr_valid(u8 * mac_addr);
static boolean_t ixgb_link_reset(struct ixgb_hw *hw); static boolean_t ixgb_link_reset(struct ixgb_hw *hw);
static void ixgb_optics_reset(struct ixgb_hw *hw); static void ixgb_optics_reset(struct ixgb_hw *hw);
u32 ixgb_mac_reset(struct ixgb_hw *hw); static ixgb_phy_type ixgb_identify_phy(struct ixgb_hw *hw);
uint32_t ixgb_mac_reset(struct ixgb_hw *hw);
u32 uint32_t ixgb_mac_reset(struct ixgb_hw *hw)
ixgb_mac_reset(struct ixgb_hw *hw)
{ {
u32 ctrl_reg; uint32_t ctrl_reg;
/* Setup up hardware to known state with RESET. */
ctrl_reg = IXGB_CTRL0_RST | IXGB_CTRL0_SDP3_DIR | /* All pins are Output=1 */ ctrl_reg = IXGB_CTRL0_RST | IXGB_CTRL0_SDP3_DIR | /* All pins are Output=1 */
IXGB_CTRL0_SDP2_DIR | IXGB_CTRL0_SDP1_DIR | IXGB_CTRL0_SDP0_DIR | IXGB_CTRL0_SDP3 | /* Initial value 1101 */ IXGB_CTRL0_SDP2_DIR | IXGB_CTRL0_SDP1_DIR | IXGB_CTRL0_SDP0_DIR | IXGB_CTRL0_SDP3 | /* Initial value 1101 */
IXGB_CTRL0_SDP2 | IXGB_CTRL0_SDP0; IXGB_CTRL0_SDP2 | IXGB_CTRL0_SDP0;
#ifdef HP_ZX1 #ifdef HP_ZX1
outl(IXGB_CTRL0, hw->io_base); /* Workaround for 82597EX reset errata */
outl(ctrl_reg, hw->io_base + 4); IXGB_WRITE_REG_IO(hw, CTRL0, ctrl_reg);
#else #else
IXGB_WRITE_REG(hw, CTRL0, ctrl_reg); IXGB_WRITE_REG(hw, CTRL0, ctrl_reg);
#endif #endif
...@@ -72,7 +72,10 @@ ixgb_mac_reset(struct ixgb_hw *hw) ...@@ -72,7 +72,10 @@ ixgb_mac_reset(struct ixgb_hw *hw)
ASSERT(!(ctrl_reg & IXGB_CTRL0_RST)); ASSERT(!(ctrl_reg & IXGB_CTRL0_RST));
#endif #endif
ixgb_optics_reset(hw); if (hw->phy_type == ixgb_phy_type_txn17401) {
ixgb_optics_reset(hw);
}
return ctrl_reg; return ctrl_reg;
} }
...@@ -81,11 +84,10 @@ ixgb_mac_reset(struct ixgb_hw *hw) ...@@ -81,11 +84,10 @@ ixgb_mac_reset(struct ixgb_hw *hw)
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
boolean_t boolean_t ixgb_adapter_stop(struct ixgb_hw * hw)
ixgb_adapter_stop(struct ixgb_hw * hw)
{ {
u32 ctrl_reg; uint32_t ctrl_reg;
u32 icr_reg; uint32_t icr_reg;
DEBUGFUNC("ixgb_adapter_stop"); DEBUGFUNC("ixgb_adapter_stop");
...@@ -133,28 +135,112 @@ ixgb_adapter_stop(struct ixgb_hw * hw) ...@@ -133,28 +135,112 @@ ixgb_adapter_stop(struct ixgb_hw * hw)
return (ctrl_reg & IXGB_CTRL0_RST); return (ctrl_reg & IXGB_CTRL0_RST);
} }
/******************************************************************************
* Identifies the vendor of the optics module on the adapter. The SR adapters
* support two different types of XPAK optics, so it is necessary to determine
* which optics are present before applying any optics-specific workarounds.
*
* hw - Struct containing variables accessed by shared code.
*
* Returns: the vendor of the XPAK optics module.
*****************************************************************************/
static ixgb_xpak_vendor ixgb_identify_xpak_vendor(struct ixgb_hw *hw)
{
uint32_t i;
uint16_t vendor_name[5];
ixgb_xpak_vendor xpak_vendor;
DEBUGFUNC("ixgb_identify_xpak_vendor");
/* Read the first few bytes of the vendor string from the XPAK NVR
* registers. These are standard XENPAK/XPAK registers, so all XPAK
* devices should implement them. */
for (i = 0; i < 5; i++) {
vendor_name[i] = ixgb_read_phy_reg(hw,
MDIO_PMA_PMD_XPAK_VENDOR_NAME
+ i, IXGB_PHY_ADDRESS,
MDIO_PMA_PMD_DID);
}
/* Determine the actual vendor */
if (vendor_name[0] == 'I' &&
vendor_name[1] == 'N' &&
vendor_name[2] == 'T' &&
vendor_name[3] == 'E' && vendor_name[4] == 'L') {
xpak_vendor = ixgb_xpak_vendor_intel;
} else {
xpak_vendor = ixgb_xpak_vendor_infineon;
}
return (xpak_vendor);
}
/******************************************************************************
* Determine the physical layer module on the adapter.
*
* hw - Struct containing variables accessed by shared code. The device_id
* field must be (correctly) populated before calling this routine.
*
* Returns: the phy type of the adapter.
*****************************************************************************/
static ixgb_phy_type ixgb_identify_phy(struct ixgb_hw *hw)
{
ixgb_phy_type phy_type;
ixgb_xpak_vendor xpak_vendor;
DEBUGFUNC("ixgb_identify_phy");
/* Infer the transceiver/phy type from the device id */
switch (hw->device_id) {
case IXGB_DEVICE_ID_82597EX:
DEBUGOUT("Identified TXN17401 optics\n");
phy_type = ixgb_phy_type_txn17401;
break;
case IXGB_DEVICE_ID_82597EX_SR:
/* The SR adapters carry two different types of XPAK optics
* modules; read the vendor identifier to determine the exact
* type of optics. */
xpak_vendor = ixgb_identify_xpak_vendor(hw);
if (xpak_vendor == ixgb_xpak_vendor_intel) {
DEBUGOUT("Identified TXN17201 optics\n");
phy_type = ixgb_phy_type_txn17201;
} else {
DEBUGOUT("Identified G6005 optics\n");
phy_type = ixgb_phy_type_g6005;
}
break;
default:
DEBUGOUT("Unknown physical layer module\n");
phy_type = ixgb_phy_type_unknown;
break;
}
return (phy_type);
}
/****************************************************************************** /******************************************************************************
* Performs basic configuration of the adapter. * Performs basic configuration of the adapter.
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Resets the controller. * Resets the controller.
* Reads and validates the EEPROM. * Reads and validates the EEPROM.
* Initializes the receive address registers. * Initializes the receive address registers.
* Initializes the multicast table. * Initializes the multicast table.
* Clears all on-chip counters. * Clears all on-chip counters.
* Calls routine to setup flow control settings. * Calls routine to setup flow control settings.
* Leaves the transmit and receive units disabled and uninitialized. * Leaves the transmit and receive units disabled and uninitialized.
* *
* Returns: * Returns:
* TRUE if successful, * TRUE if successful,
* FALSE if unrecoverable problems were encountered. * FALSE if unrecoverable problems were encountered.
*****************************************************************************/ *****************************************************************************/
boolean_t boolean_t ixgb_init_hw(struct ixgb_hw * hw)
ixgb_init_hw(struct ixgb_hw * hw)
{ {
u32 i; uint32_t i;
u32 ctrl_reg; uint32_t ctrl_reg;
boolean_t status; boolean_t status;
DEBUGFUNC("ixgb_init_hw"); DEBUGFUNC("ixgb_init_hw");
...@@ -170,8 +256,8 @@ ixgb_init_hw(struct ixgb_hw * hw) ...@@ -170,8 +256,8 @@ ixgb_init_hw(struct ixgb_hw * hw)
DEBUGOUT("Issuing an EE reset to MAC\n"); DEBUGOUT("Issuing an EE reset to MAC\n");
#ifdef HP_ZX1 #ifdef HP_ZX1
outl(IXGB_CTRL1, hw->io_base); /* Workaround for 82597EX reset errata */
outl(IXGB_CTRL1_EE_RST, hw->io_base + 4); IXGB_WRITE_REG_IO(hw, CTRL1, IXGB_CTRL1_EE_RST);
#else #else
IXGB_WRITE_REG(hw, CTRL1, IXGB_CTRL1_EE_RST); IXGB_WRITE_REG(hw, CTRL1, IXGB_CTRL1_EE_RST);
#endif #endif
...@@ -183,12 +269,16 @@ ixgb_init_hw(struct ixgb_hw * hw) ...@@ -183,12 +269,16 @@ ixgb_init_hw(struct ixgb_hw * hw)
return (FALSE); return (FALSE);
} }
/* Setup the receive addresses. /* Use the device id to determine the type of phy/transceiver. */
hw->device_id = ixgb_get_ee_device_id(hw);
hw->phy_type = ixgb_identify_phy(hw);
/* Setup the receive addresses.
* Receive Address Registers (RARs 0 - 15). * Receive Address Registers (RARs 0 - 15).
*/ */
ixgb_init_rx_addrs(hw); ixgb_init_rx_addrs(hw);
/* /*
* Check that a valid MAC address has been set. * Check that a valid MAC address has been set.
* If it is not valid, we fail hardware init. * If it is not valid, we fail hardware init.
*/ */
...@@ -217,7 +307,7 @@ ixgb_init_hw(struct ixgb_hw * hw) ...@@ -217,7 +307,7 @@ ixgb_init_hw(struct ixgb_hw * hw)
/* Call a subroutine to setup flow control. */ /* Call a subroutine to setup flow control. */
status = ixgb_setup_fc(hw); status = ixgb_setup_fc(hw);
/* check-for-link in case lane deskew is locked */ /* 82597EX errata: Call check-for-link in case lane deskew is locked */
ixgb_check_for_link(hw); ixgb_check_for_link(hw);
return (status); return (status);
...@@ -226,20 +316,19 @@ ixgb_init_hw(struct ixgb_hw * hw) ...@@ -226,20 +316,19 @@ ixgb_init_hw(struct ixgb_hw * hw)
/****************************************************************************** /******************************************************************************
* Initializes receive address filters. * Initializes receive address filters.
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* *
* Places the MAC address in receive address register 0 and clears the rest * Places the MAC address in receive address register 0 and clears the rest
* of the receive addresss registers. Clears the multicast table. Assumes * of the receive addresss registers. Clears the multicast table. Assumes
* the receiver is in reset when the routine is called. * the receiver is in reset when the routine is called.
*****************************************************************************/ *****************************************************************************/
void void ixgb_init_rx_addrs(struct ixgb_hw *hw)
ixgb_init_rx_addrs(struct ixgb_hw *hw)
{ {
u32 i; uint32_t i;
DEBUGFUNC("ixgb_init_rx_addrs"); DEBUGFUNC("ixgb_init_rx_addrs");
/* /*
* If the current mac address is valid, assume it is a software override * If the current mac address is valid, assume it is a software override
* to the permanent address. * to the permanent address.
* Otherwise, use the permanent address from the eeprom. * Otherwise, use the permanent address from the eeprom.
...@@ -289,17 +378,17 @@ ixgb_init_rx_addrs(struct ixgb_hw *hw) ...@@ -289,17 +378,17 @@ ixgb_init_rx_addrs(struct ixgb_hw *hw)
* *
* The given list replaces any existing list. Clears the last 15 receive * The given list replaces any existing list. Clears the last 15 receive
* address registers and the multicast table. Uses receive address registers * address registers and the multicast table. Uses receive address registers
* for the first 15 multicast addresses, and hashes the rest into the * for the first 15 multicast addresses, and hashes the rest into the
* multicast table. * multicast table.
*****************************************************************************/ *****************************************************************************/
void void
ixgb_mc_addr_list_update(struct ixgb_hw *hw, ixgb_mc_addr_list_update(struct ixgb_hw *hw,
u8 * mc_addr_list, uint8_t * mc_addr_list,
u32 mc_addr_count, u32 pad) uint32_t mc_addr_count, uint32_t pad)
{ {
u32 hash_value; uint32_t hash_value;
u32 i; uint32_t i;
u32 rar_used_count = 1; /* RAR[0] is used for our MAC address */ uint32_t rar_used_count = 1; /* RAR[0] is used for our MAC address */
DEBUGFUNC("ixgb_mc_addr_list_update"); DEBUGFUNC("ixgb_mc_addr_list_update");
...@@ -336,7 +425,7 @@ ixgb_mc_addr_list_update(struct ixgb_hw *hw, ...@@ -336,7 +425,7 @@ ixgb_mc_addr_list_update(struct ixgb_hw *hw,
5]); 5]);
/* Place this multicast address in the RAR if there is room, * /* Place this multicast address in the RAR if there is room, *
* else put it in the MTA * else put it in the MTA
*/ */
if (rar_used_count < IXGB_RAR_ENTRIES) { if (rar_used_count < IXGB_RAR_ENTRIES) {
ixgb_rar_set(hw, ixgb_rar_set(hw,
...@@ -366,20 +455,19 @@ ixgb_mc_addr_list_update(struct ixgb_hw *hw, ...@@ -366,20 +455,19 @@ ixgb_mc_addr_list_update(struct ixgb_hw *hw,
* Hashes an address to determine its location in the multicast table * Hashes an address to determine its location in the multicast table
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* mc_addr - the multicast address to hash * mc_addr - the multicast address to hash
* *
* Returns: * Returns:
* The hash value * The hash value
*****************************************************************************/ *****************************************************************************/
static u32 static uint32_t ixgb_hash_mc_addr(struct ixgb_hw *hw, uint8_t * mc_addr)
ixgb_hash_mc_addr(struct ixgb_hw *hw, u8 * mc_addr)
{ {
u32 hash_value = 0; uint32_t hash_value = 0;
DEBUGFUNC("ixgb_hash_mc_addr"); DEBUGFUNC("ixgb_hash_mc_addr");
/* The portion of the address that is used for the hash table is /* The portion of the address that is used for the hash table is
* determined by the mc_filter_type setting. * determined by the mc_filter_type setting.
*/ */
switch (hw->mc_filter_type) { switch (hw->mc_filter_type) {
/* [0] [1] [2] [3] [4] [5] /* [0] [1] [2] [3] [4] [5]
...@@ -388,18 +476,18 @@ ixgb_hash_mc_addr(struct ixgb_hw *hw, u8 * mc_addr) ...@@ -388,18 +476,18 @@ ixgb_hash_mc_addr(struct ixgb_hw *hw, u8 * mc_addr)
case 0: case 0:
/* [47:36] i.e. 0x563 for above example address */ /* [47:36] i.e. 0x563 for above example address */
hash_value = hash_value =
((mc_addr[4] >> 4) | (((u16) mc_addr[5]) << 4)); ((mc_addr[4] >> 4) | (((uint16_t) mc_addr[5]) << 4));
break; break;
case 1: /* [46:35] i.e. 0xAC6 for above example address */ case 1: /* [46:35] i.e. 0xAC6 for above example address */
hash_value = hash_value =
((mc_addr[4] >> 3) | (((u16) mc_addr[5]) << 5)); ((mc_addr[4] >> 3) | (((uint16_t) mc_addr[5]) << 5));
break; break;
case 2: /* [45:34] i.e. 0x5D8 for above example address */ case 2: /* [45:34] i.e. 0x5D8 for above example address */
hash_value = hash_value =
((mc_addr[4] >> 2) | (((u16) mc_addr[5]) << 6)); ((mc_addr[4] >> 2) | (((uint16_t) mc_addr[5]) << 6));
break; break;
case 3: /* [43:32] i.e. 0x634 for above example address */ case 3: /* [43:32] i.e. 0x634 for above example address */
hash_value = ((mc_addr[4]) | (((u16) mc_addr[5]) << 8)); hash_value = ((mc_addr[4]) | (((uint16_t) mc_addr[5]) << 8));
break; break;
default: default:
/* Invalid mc_filter_type, what should we do? */ /* Invalid mc_filter_type, what should we do? */
...@@ -418,18 +506,17 @@ ixgb_hash_mc_addr(struct ixgb_hw *hw, u8 * mc_addr) ...@@ -418,18 +506,17 @@ ixgb_hash_mc_addr(struct ixgb_hw *hw, u8 * mc_addr)
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
* hash_value - Multicast address hash value * hash_value - Multicast address hash value
*****************************************************************************/ *****************************************************************************/
static void static void ixgb_mta_set(struct ixgb_hw *hw, uint32_t hash_value)
ixgb_mta_set(struct ixgb_hw *hw, u32 hash_value)
{ {
u32 hash_bit, hash_reg; uint32_t hash_bit, hash_reg;
u32 mta_reg; uint32_t mta_reg;
/* The MTA is a register array of 128 32-bit registers. /* The MTA is a register array of 128 32-bit registers.
* It is treated like an array of 4096 bits. We want to set * It is treated like an array of 4096 bits. We want to set
* bit BitArray[hash_value]. So we figure out what register * bit BitArray[hash_value]. So we figure out what register
* the bit is in, read it, OR in the new bit, then write * the bit is in, read it, OR in the new bit, then write
* back the new value. The register is determined by the * back the new value. The register is determined by the
* upper 7 bits of the hash value and the bit within that * upper 7 bits of the hash value and the bit within that
* register are determined by the lower 5 bits of the value. * register are determined by the lower 5 bits of the value.
*/ */
hash_reg = (hash_value >> 5) & 0x7F; hash_reg = (hash_value >> 5) & 0x7F;
...@@ -451,22 +538,21 @@ ixgb_mta_set(struct ixgb_hw *hw, u32 hash_value) ...@@ -451,22 +538,21 @@ ixgb_mta_set(struct ixgb_hw *hw, u32 hash_value)
* addr - Address to put into receive address register * addr - Address to put into receive address register
* index - Receive address register to write * index - Receive address register to write
*****************************************************************************/ *****************************************************************************/
void void ixgb_rar_set(struct ixgb_hw *hw, uint8_t * addr, uint32_t index)
ixgb_rar_set(struct ixgb_hw *hw, u8 * addr, u32 index)
{ {
u32 rar_low, rar_high; uint32_t rar_low, rar_high;
DEBUGFUNC("ixgb_rar_set"); DEBUGFUNC("ixgb_rar_set");
/* HW expects these in little endian so we reverse the byte order /* HW expects these in little endian so we reverse the byte order
* from network order (big endian) to little endian * from network order (big endian) to little endian
*/ */
rar_low = ((u32) addr[0] | rar_low = ((uint32_t) addr[0] |
((u32) addr[1] << 8) | ((uint32_t) addr[1] << 8) |
((u32) addr[2] << 16) | ((u32) addr[3] << 24)); ((uint32_t) addr[2] << 16) | ((uint32_t) addr[3] << 24));
rar_high = ((u32) addr[4] | rar_high = ((uint32_t) addr[4] |
((u32) addr[5] << 8) | IXGB_RAH_AV); ((uint32_t) addr[5] << 8) | IXGB_RAH_AV);
IXGB_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low); IXGB_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low);
IXGB_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high); IXGB_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high);
...@@ -480,8 +566,7 @@ ixgb_rar_set(struct ixgb_hw *hw, u8 * addr, u32 index) ...@@ -480,8 +566,7 @@ ixgb_rar_set(struct ixgb_hw *hw, u8 * addr, u32 index)
* offset - Offset in VLAN filer table to write * offset - Offset in VLAN filer table to write
* value - Value to write into VLAN filter table * value - Value to write into VLAN filter table
*****************************************************************************/ *****************************************************************************/
void void ixgb_write_vfta(struct ixgb_hw *hw, uint32_t offset, uint32_t value)
ixgb_write_vfta(struct ixgb_hw *hw, u32 offset, u32 value)
{ {
IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, value); IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, value);
return; return;
...@@ -492,10 +577,9 @@ ixgb_write_vfta(struct ixgb_hw *hw, u32 offset, u32 value) ...@@ -492,10 +577,9 @@ ixgb_write_vfta(struct ixgb_hw *hw, u32 offset, u32 value)
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
void void ixgb_clear_vfta(struct ixgb_hw *hw)
ixgb_clear_vfta(struct ixgb_hw *hw)
{ {
u32 offset; uint32_t offset;
for (offset = 0; offset < IXGB_VLAN_FILTER_TBL_SIZE; offset++) for (offset = 0; offset < IXGB_VLAN_FILTER_TBL_SIZE; offset++)
IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, 0); IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
...@@ -508,11 +592,10 @@ ixgb_clear_vfta(struct ixgb_hw *hw) ...@@ -508,11 +592,10 @@ ixgb_clear_vfta(struct ixgb_hw *hw)
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
boolean_t boolean_t ixgb_setup_fc(struct ixgb_hw * hw)
ixgb_setup_fc(struct ixgb_hw * hw)
{ {
u32 ctrl_reg; uint32_t ctrl_reg;
u32 pap_reg = 0; /* by default, assume no pause time */ uint32_t pap_reg = 0; /* by default, assume no pause time */
boolean_t status = TRUE; boolean_t status = TRUE;
DEBUGFUNC("ixgb_setup_fc"); DEBUGFUNC("ixgb_setup_fc");
...@@ -534,6 +617,8 @@ ixgb_setup_fc(struct ixgb_hw * hw) ...@@ -534,6 +617,8 @@ ixgb_setup_fc(struct ixgb_hw * hw)
*/ */
switch (hw->fc.type) { switch (hw->fc.type) {
case ixgb_fc_none: /* 0 */ case ixgb_fc_none: /* 0 */
/* Set CMDC bit to disable Rx Flow control */
ctrl_reg |= (IXGB_CTRL0_CMDC);
break; break;
case ixgb_fc_rx_pause: /* 1 */ case ixgb_fc_rx_pause: /* 1 */
/* RX Flow control is enabled, and TX Flow control is /* RX Flow control is enabled, and TX Flow control is
...@@ -573,7 +658,7 @@ ixgb_setup_fc(struct ixgb_hw * hw) ...@@ -573,7 +658,7 @@ ixgb_setup_fc(struct ixgb_hw * hw)
* these registers will be set to a default threshold that may be * these registers will be set to a default threshold that may be
* adjusted later by the driver's runtime code. However, if the * adjusted later by the driver's runtime code. However, if the
* ability to transmit pause frames in not enabled, then these * ability to transmit pause frames in not enabled, then these
* registers will be set to 0. * registers will be set to 0.
*/ */
if (!(hw->fc.type & ixgb_fc_tx_pause)) { if (!(hw->fc.type & ixgb_fc_tx_pause)) {
IXGB_WRITE_REG(hw, FCRTL, 0); IXGB_WRITE_REG(hw, FCRTL, 0);
...@@ -603,18 +688,19 @@ ixgb_setup_fc(struct ixgb_hw * hw) ...@@ -603,18 +688,19 @@ ixgb_setup_fc(struct ixgb_hw * hw)
* *
* Returns: Data word (16 bits) from MDI device. * Returns: Data word (16 bits) from MDI device.
* *
* This routine uses the new protocol MDI Single Command and Address Operation. * The 82597EX has support for several MDI access methods. This routine
* uses the new protocol MDI Single Command and Address Operation.
* This requires that first an address cycle command is sent, followed by a * This requires that first an address cycle command is sent, followed by a
* read command. * read command.
*****************************************************************************/ *****************************************************************************/
u16 uint16_t
ixgb_read_phy_reg(struct ixgb_hw * hw, ixgb_read_phy_reg(struct ixgb_hw * hw,
u32 reg_address, uint32_t reg_address,
u32 phy_address, u32 device_type) uint32_t phy_address, uint32_t device_type)
{ {
u32 i; uint32_t i;
u32 data; uint32_t data;
u32 command = 0; uint32_t command = 0;
ASSERT(reg_address <= IXGB_MAX_PHY_REG_ADDRESS); ASSERT(reg_address <= IXGB_MAX_PHY_REG_ADDRESS);
ASSERT(phy_address <= IXGB_MAX_PHY_ADDRESS); ASSERT(phy_address <= IXGB_MAX_PHY_ADDRESS);
...@@ -673,11 +759,11 @@ ixgb_read_phy_reg(struct ixgb_hw * hw, ...@@ -673,11 +759,11 @@ ixgb_read_phy_reg(struct ixgb_hw * hw,
ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0); ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0);
/* Operation is complete, get the data from the MDIO Read/Write Data /* Operation is complete, get the data from the MDIO Read/Write Data
* register and return. * register and return.
*/ */
data = IXGB_READ_REG(hw, MSRWD); data = IXGB_READ_REG(hw, MSRWD);
data >>= IXGB_MSRWD_READ_DATA_SHIFT; data >>= IXGB_MSRWD_READ_DATA_SHIFT;
return ((u16) data); return ((uint16_t) data);
} }
/****************************************************************************** /******************************************************************************
...@@ -692,24 +778,25 @@ ixgb_read_phy_reg(struct ixgb_hw * hw, ...@@ -692,24 +778,25 @@ ixgb_read_phy_reg(struct ixgb_hw * hw,
* *
* Returns: void. * Returns: void.
* *
* This routine uses the new protocol MDI Single Command and Address Operation. * The 82597EX has support for several MDI access methods. This routine
* uses the new protocol MDI Single Command and Address Operation.
* This requires that first an address cycle command is sent, followed by a * This requires that first an address cycle command is sent, followed by a
* write command. * write command.
*****************************************************************************/ *****************************************************************************/
void void
ixgb_write_phy_reg(struct ixgb_hw *hw, ixgb_write_phy_reg(struct ixgb_hw *hw,
u32 reg_address, uint32_t reg_address,
u32 phy_address, u32 device_type, u16 data) uint32_t phy_address, uint32_t device_type, uint16_t data)
{ {
u32 i; uint32_t i;
u32 command = 0; uint32_t command = 0;
ASSERT(reg_address <= IXGB_MAX_PHY_REG_ADDRESS); ASSERT(reg_address <= IXGB_MAX_PHY_REG_ADDRESS);
ASSERT(phy_address <= IXGB_MAX_PHY_ADDRESS); ASSERT(phy_address <= IXGB_MAX_PHY_ADDRESS);
ASSERT(device_type <= IXGB_MAX_PHY_DEV_TYPE); ASSERT(device_type <= IXGB_MAX_PHY_DEV_TYPE);
/* Put the data in the MDIO Read/Write Data register */ /* Put the data in the MDIO Read/Write Data register */
IXGB_WRITE_REG(hw, MSRWD, (u32) data); IXGB_WRITE_REG(hw, MSRWD, (uint32_t) data);
/* Setup and write the address cycle command */ /* Setup and write the address cycle command */
command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) | command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) |
...@@ -773,11 +860,10 @@ ixgb_write_phy_reg(struct ixgb_hw *hw, ...@@ -773,11 +860,10 @@ ixgb_write_phy_reg(struct ixgb_hw *hw,
* *
* Called by any function that needs to check the link status of the adapter. * Called by any function that needs to check the link status of the adapter.
*****************************************************************************/ *****************************************************************************/
void void ixgb_check_for_link(struct ixgb_hw *hw)
ixgb_check_for_link(struct ixgb_hw *hw)
{ {
u32 status_reg; uint32_t status_reg;
u32 xpcss_reg; uint32_t xpcss_reg;
DEBUGFUNC("ixgb_check_for_link"); DEBUGFUNC("ixgb_check_for_link");
...@@ -792,42 +878,53 @@ ixgb_check_for_link(struct ixgb_hw *hw) ...@@ -792,42 +878,53 @@ ixgb_check_for_link(struct ixgb_hw *hw)
DEBUGOUT("XPCSS Not Aligned while Status:LU is set.\n"); DEBUGOUT("XPCSS Not Aligned while Status:LU is set.\n");
hw->link_up = ixgb_link_reset(hw); hw->link_up = ixgb_link_reset(hw);
} else { } else {
/*
* 82597EX errata. Since the lane deskew problem may prevent
* link, reset the link before reporting link down.
*/
hw->link_up = ixgb_link_reset(hw); hw->link_up = ixgb_link_reset(hw);
} }
/* Anything else for 10 Gig?? */ /* Anything else for 10 Gig?? */
} }
boolean_t /******************************************************************************
ixgb_check_for_bad_link(struct ixgb_hw *hw) * Check for a bad link condition that may have occured.
* The indication is that the RFC / LFC registers may be incrementing
* continually. A full adapter reset is required to recover.
*
* hw - Struct containing variables accessed by hw code
*
* Called by any function that needs to check the link status of the adapter.
*****************************************************************************/
boolean_t ixgb_check_for_bad_link(struct ixgb_hw *hw)
{ {
u32 newLFC, newRFC; uint32_t newLFC, newRFC;
boolean_t bad_link_returncode = FALSE; boolean_t bad_link_returncode = FALSE;
/* check for a bad reset that may have occured if (hw->phy_type == ixgb_phy_type_txn17401) {
* the indication is that the RFC / LFC registers may be incrementing newLFC = IXGB_READ_REG(hw, LFC);
* continually. Do a full adapter reset to recover newRFC = IXGB_READ_REG(hw, RFC);
*/ if ((hw->lastLFC + 250 < newLFC)
newLFC = IXGB_READ_REG(hw, LFC); || (hw->lastRFC + 250 < newRFC)) {
newRFC = IXGB_READ_REG(hw, RFC); DEBUGOUT
if ((hw->lastLFC + 250 < newLFC) || (hw->lastRFC + 250 < newRFC)) { ("BAD LINK! too many LFC/RFC since last check\n");
DEBUGOUT("BAD LINK! too many LFC/RFC since last check\n"); bad_link_returncode = TRUE;
bad_link_returncode = TRUE; }
hw->lastLFC = newLFC;
hw->lastRFC = newRFC;
} }
hw->lastLFC = newLFC;
hw->lastRFC = newRFC;
return bad_link_returncode; return bad_link_returncode;
} }
/****************************************************************************** /******************************************************************************
* Clears all hardware statistics counters. * Clears all hardware statistics counters.
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
void void ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
{ {
volatile u32 temp_reg; volatile uint32_t temp_reg;
DEBUGFUNC("ixgb_clear_hw_cntrs"); DEBUGFUNC("ixgb_clear_hw_cntrs");
...@@ -905,10 +1002,9 @@ ixgb_clear_hw_cntrs(struct ixgb_hw *hw) ...@@ -905,10 +1002,9 @@ ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
void void ixgb_led_on(struct ixgb_hw *hw)
ixgb_led_on(struct ixgb_hw *hw)
{ {
u32 ctrl0_reg = IXGB_READ_REG(hw, CTRL0); uint32_t ctrl0_reg = IXGB_READ_REG(hw, CTRL0);
/* To turn on the LED, clear software-definable pin 0 (SDP0). */ /* To turn on the LED, clear software-definable pin 0 (SDP0). */
ctrl0_reg &= ~IXGB_CTRL0_SDP0; ctrl0_reg &= ~IXGB_CTRL0_SDP0;
...@@ -921,10 +1017,9 @@ ixgb_led_on(struct ixgb_hw *hw) ...@@ -921,10 +1017,9 @@ ixgb_led_on(struct ixgb_hw *hw)
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
void void ixgb_led_off(struct ixgb_hw *hw)
ixgb_led_off(struct ixgb_hw *hw)
{ {
u32 ctrl0_reg = IXGB_READ_REG(hw, CTRL0); uint32_t ctrl0_reg = IXGB_READ_REG(hw, CTRL0);
/* To turn off the LED, set software-definable pin 0 (SDP0). */ /* To turn off the LED, set software-definable pin 0 (SDP0). */
ctrl0_reg |= IXGB_CTRL0_SDP0; ctrl0_reg |= IXGB_CTRL0_SDP0;
...@@ -937,10 +1032,9 @@ ixgb_led_off(struct ixgb_hw *hw) ...@@ -937,10 +1032,9 @@ ixgb_led_off(struct ixgb_hw *hw)
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
static void static void ixgb_get_bus_info(struct ixgb_hw *hw)
ixgb_get_bus_info(struct ixgb_hw *hw)
{ {
u32 status_reg; uint32_t status_reg;
status_reg = IXGB_READ_REG(hw, STATUS); status_reg = IXGB_READ_REG(hw, STATUS);
...@@ -976,11 +1070,10 @@ ixgb_get_bus_info(struct ixgb_hw *hw) ...@@ -976,11 +1070,10 @@ ixgb_get_bus_info(struct ixgb_hw *hw)
/****************************************************************************** /******************************************************************************
* Tests a MAC address to ensure it is a valid Individual Address * Tests a MAC address to ensure it is a valid Individual Address
* *
* mac_addr - pointer to MAC address. * mac_addr - pointer to MAC address.
* *
*****************************************************************************/ *****************************************************************************/
boolean_t boolean_t mac_addr_valid(uint8_t * mac_addr)
mac_addr_valid(u8 * mac_addr)
{ {
boolean_t is_valid = TRUE; boolean_t is_valid = TRUE;
DEBUGFUNC("mac_addr_valid"); DEBUGFUNC("mac_addr_valid");
...@@ -1007,22 +1100,23 @@ mac_addr_valid(u8 * mac_addr) ...@@ -1007,22 +1100,23 @@ mac_addr_valid(u8 * mac_addr)
} }
/****************************************************************************** /******************************************************************************
* Resets the 10GbE link. Waits the settle time and returns the state of * Resets the 10GbE link. Waits the settle time and returns the state of
* the link. * the link.
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
boolean_t boolean_t ixgb_link_reset(struct ixgb_hw * hw)
ixgb_link_reset(struct ixgb_hw * hw)
{ {
boolean_t link_status = FALSE; boolean_t link_status = FALSE;
u8 wait_retries = MAX_RESET_ITERATIONS; uint8_t wait_retries = MAX_RESET_ITERATIONS;
u8 lrst_retries = MAX_RESET_ITERATIONS; uint8_t lrst_retries = MAX_RESET_ITERATIONS;
do { do {
/* Reset the link */
IXGB_WRITE_REG(hw, CTRL0, IXGB_WRITE_REG(hw, CTRL0,
IXGB_READ_REG(hw, CTRL0) | IXGB_CTRL0_LRST); IXGB_READ_REG(hw, CTRL0) | IXGB_CTRL0_LRST);
/* Wait for link-up and lane re-alignment */
do { do {
udelay(IXGB_DELAY_USECS_AFTER_LINK_RESET); udelay(IXGB_DELAY_USECS_AFTER_LINK_RESET);
link_status = link_status =
...@@ -1030,6 +1124,7 @@ ixgb_link_reset(struct ixgb_hw * hw) ...@@ -1030,6 +1124,7 @@ ixgb_link_reset(struct ixgb_hw * hw)
&& (IXGB_READ_REG(hw, XPCSS) & && (IXGB_READ_REG(hw, XPCSS) &
IXGB_XPCSS_ALIGN_STATUS)) ? TRUE : FALSE; IXGB_XPCSS_ALIGN_STATUS)) ? TRUE : FALSE;
} while (!link_status && --wait_retries); } while (!link_status && --wait_retries);
} while (!link_status && --lrst_retries); } while (!link_status && --lrst_retries);
return link_status; return link_status;
...@@ -1040,16 +1135,21 @@ ixgb_link_reset(struct ixgb_hw * hw) ...@@ -1040,16 +1135,21 @@ ixgb_link_reset(struct ixgb_hw * hw)
* *
* hw - Struct containing variables accessed by shared code * hw - Struct containing variables accessed by shared code
*****************************************************************************/ *****************************************************************************/
void void ixgb_optics_reset(struct ixgb_hw *hw)
ixgb_optics_reset(struct ixgb_hw *hw)
{ {
u16 mdio_reg; if (hw->phy_type == ixgb_phy_type_txn17401) {
uint16_t mdio_reg;
ixgb_write_phy_reg(hw,
TXN17401_PMA_PMD_CR1, ixgb_write_phy_reg(hw,
IXGB_PHY_ADDRESS, MDIO_PMA_PMD_CR1,
TXN17401_PMA_PMD_DID, TXN17401_PMA_PMD_CR1_RESET); IXGB_PHY_ADDRESS,
mdio_reg = ixgb_read_phy_reg(hw, MDIO_PMA_PMD_DID, MDIO_PMA_PMD_CR1_RESET);
TXN17401_PMA_PMD_CR1,
IXGB_PHY_ADDRESS, TXN17401_PMA_PMD_DID); mdio_reg = ixgb_read_phy_reg(hw,
MDIO_PMA_PMD_CR1,
IXGB_PHY_ADDRESS,
MDIO_PMA_PMD_DID);
}
return;
} }
/******************************************************************************* /*******************************************************************************
Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
Contact Information: Contact Information:
Linux NICS <linux.nics@intel.com> Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/ *******************************************************************************/
#ifndef _IXGB_HW_H_ #ifndef _IXGB_HW_H_
...@@ -37,6 +38,21 @@ typedef enum { ...@@ -37,6 +38,21 @@ typedef enum {
ixgb_num_macs ixgb_num_macs
} ixgb_mac_type; } 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 */ /* Media Types */
typedef enum { typedef enum {
ixgb_media_type_unknown = 0, ixgb_media_type_unknown = 0,
...@@ -84,6 +100,9 @@ typedef enum { ...@@ -84,6 +100,9 @@ typedef enum {
#define SPEED_10000 10000 #define SPEED_10000 10000
#define FULL_DUPLEX 2 #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_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_RESET 1 /* allow 1ms after the reset */
#define IXGB_DELAY_AFTER_EE_RESET 10 /* allow 10ms after the EEPROM reset */ #define IXGB_DELAY_AFTER_EE_RESET 10 /* allow 10ms after the EEPROM reset */
...@@ -225,6 +244,9 @@ typedef enum { ...@@ -225,6 +244,9 @@ typedef enum {
/* CTRL0 Bit Masks */ /* CTRL0 Bit Masks */
#define IXGB_CTRL0_LRST 0x00000008 #define IXGB_CTRL0_LRST 0x00000008
#define IXGB_CTRL0_JFE 0x00000010 #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_SDP0 0x00040000
#define IXGB_CTRL0_SDP1 0x00080000 #define IXGB_CTRL0_SDP1 0x00080000
#define IXGB_CTRL0_SDP2 0x00100000 #define IXGB_CTRL0_SDP2 0x00100000
...@@ -239,14 +261,36 @@ typedef enum { ...@@ -239,14 +261,36 @@ typedef enum {
#define IXGB_CTRL0_VME 0x40000000 #define IXGB_CTRL0_VME 0x40000000
/* CTRL1 Bit Masks */ /* 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_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 */ /* STATUS Bit Masks */
#define IXGB_STATUS_LU 0x00000002 #define IXGB_STATUS_LU 0x00000002
#define IXGB_STATUS_AIP 0x00000004
#define IXGB_STATUS_TXOFF 0x00000010 #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_PCI_SPD 0x00000800
#define IXGB_STATUS_BUS64 0x00001000 #define IXGB_STATUS_BUS64 0x00001000
#define IXGB_STATUS_PCIX_MODE 0x00002000 #define IXGB_STATUS_PCIX_MODE 0x00002000
...@@ -254,31 +298,52 @@ typedef enum { ...@@ -254,31 +298,52 @@ typedef enum {
#define IXGB_STATUS_PCIX_SPD_66 0x00000000 #define IXGB_STATUS_PCIX_SPD_66 0x00000000
#define IXGB_STATUS_PCIX_SPD_100 0x00004000 #define IXGB_STATUS_PCIX_SPD_100 0x00004000
#define IXGB_STATUS_PCIX_SPD_133 0x00008000 #define IXGB_STATUS_PCIX_SPD_133 0x00008000
#define IXGB_STATUS_REV_ID_MASK 0x000F0000
#define IXGB_STATUS_REV_ID_SHIFT 16
/* EECD Bit Masks */ /* EECD Bit Masks */
#define IXGB_EECD_SK 0x00000001 #define IXGB_EECD_SK 0x00000001
#define IXGB_EECD_CS 0x00000002 #define IXGB_EECD_CS 0x00000002
#define IXGB_EECD_DI 0x00000004 #define IXGB_EECD_DI 0x00000004
#define IXGB_EECD_DO 0x00000008 #define IXGB_EECD_DO 0x00000008
#define IXGB_EECD_FWE_MASK 0x00000030
#define IXGB_EECD_FWE_DIS 0x00000010
#define IXGB_EECD_FWE_EN 0x00000020
/* MFS */ /* MFS */
#define IXGB_MFS_SHIFT 16 #define IXGB_MFS_SHIFT 16
/* Interrupt Register Bit Masks (used for ICR, ICS, IMS, and IMC) */ /* Interrupt Register Bit Masks (used for ICR, ICS, IMS, and IMC) */
#define IXGB_INT_TXDW 0x00000001 #define IXGB_INT_TXDW 0x00000001
#define IXGB_INT_TXQE 0x00000002
#define IXGB_INT_LSC 0x00000004 #define IXGB_INT_LSC 0x00000004
#define IXGB_INT_RXSEQ 0x00000008 #define IXGB_INT_RXSEQ 0x00000008
#define IXGB_INT_RXDMT0 0x00000010 #define IXGB_INT_RXDMT0 0x00000010
#define IXGB_INT_RXO 0x00000040 #define IXGB_INT_RXO 0x00000040
#define IXGB_INT_RXT0 0x00000080 #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 */ /* RCTL Bit Masks */
#define IXGB_RCTL_RXEN 0x00000002 #define IXGB_RCTL_RXEN 0x00000002
#define IXGB_RCTL_SBP 0x00000004
#define IXGB_RCTL_UPE 0x00000008 #define IXGB_RCTL_UPE 0x00000008
#define IXGB_RCTL_MPE 0x00000010 #define IXGB_RCTL_MPE 0x00000010
#define IXGB_RCTL_RDMTS_MASK 0x00000300
#define IXGB_RCTL_RDMTS_1_2 0x00000000 #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_MO_SHIFT 12
#define IXGB_RCTL_BAM 0x00008000 #define IXGB_RCTL_BAM 0x00008000
#define IXGB_RCTL_BSIZE_MASK 0x00030000
#define IXGB_RCTL_BSIZE_2048 0x00000000 #define IXGB_RCTL_BSIZE_2048 0x00000000
#define IXGB_RCTL_BSIZE_4096 0x00010000 #define IXGB_RCTL_BSIZE_4096 0x00010000
#define IXGB_RCTL_BSIZE_8192 0x00020000 #define IXGB_RCTL_BSIZE_8192 0x00020000
...@@ -286,27 +351,48 @@ typedef enum { ...@@ -286,27 +351,48 @@ typedef enum {
#define IXGB_RCTL_VFE 0x00040000 #define IXGB_RCTL_VFE 0x00040000
#define IXGB_RCTL_CFIEN 0x00080000 #define IXGB_RCTL_CFIEN 0x00080000
#define IXGB_RCTL_CFI 0x00100000 #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_CFF 0x00800000
#define IXGB_RCTL_SECRC 0x04000000 #define IXGB_RCTL_SECRC 0x04000000
#define IXGB_RDT_FPDB 0x80000000
#define IXGB_RCTL_IDLE_RX_UNIT 0
/* FCRTL Bit Masks */ /* FCRTL Bit Masks */
#define IXGB_FCRTL_XONE 0x80000000 #define IXGB_FCRTL_XONE 0x80000000
/* RXDCTL Bit Masks */ /* RXDCTL Bit Masks */
#define IXGB_RXDCTL_PTHRESH_MASK 0x000001FF
#define IXGB_RXDCTL_PTHRESH_SHIFT 0 #define IXGB_RXDCTL_PTHRESH_SHIFT 0
#define IXGB_RXDCTL_HTHRESH_MASK 0x0003FE00
#define IXGB_RXDCTL_HTHRESH_SHIFT 9 #define IXGB_RXDCTL_HTHRESH_SHIFT 9
#define IXGB_RXDCTL_WTHRESH_MASK 0x07FC0000
#define IXGB_RXDCTL_WTHRESH_SHIFT 18 #define IXGB_RXDCTL_WTHRESH_SHIFT 18
/* RAIDC Bit Masks */ /* RAIDC Bit Masks */
#define IXGB_RAIDC_HIGHTHRS_MASK 0x0000003F
#define IXGB_RAIDC_DELAY_MASK 0x000FF800
#define IXGB_RAIDC_DELAY_SHIFT 11 #define IXGB_RAIDC_DELAY_SHIFT 11
#define IXGB_RAIDC_POLL_MASK 0x1FF00000
#define IXGB_RAIDC_POLL_SHIFT 20 #define IXGB_RAIDC_POLL_SHIFT 20
#define IXGB_RAIDC_RXT_GATE 0x40000000 #define IXGB_RAIDC_RXT_GATE 0x40000000
#define IXGB_RAIDC_EN 0x80000000 #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 */ /* RXCSUM Bit Masks */
#define IXGB_RXCSUM_IPOFL 0x00000100
#define IXGB_RXCSUM_TUOFL 0x00000200 #define IXGB_RXCSUM_TUOFL 0x00000200
/* RAH Bit Masks */ /* 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 #define IXGB_RAH_AV 0x80000000
/* TCTL Bit Masks */ /* TCTL Bit Masks */
...@@ -314,64 +400,145 @@ typedef enum { ...@@ -314,64 +400,145 @@ typedef enum {
#define IXGB_TCTL_TXEN 0x00000002 #define IXGB_TCTL_TXEN 0x00000002
#define IXGB_TCTL_TPDE 0x00000004 #define IXGB_TCTL_TPDE 0x00000004
#define IXGB_TCTL_IDLE_TX_UNIT 0
/* TXDCTL Bit Masks */ /* TXDCTL Bit Masks */
#define IXGB_TXDCTL_PTHRESH_MASK 0x0000007F
#define IXGB_TXDCTL_HTHRESH_MASK 0x00007F00
#define IXGB_TXDCTL_HTHRESH_SHIFT 8 #define IXGB_TXDCTL_HTHRESH_SHIFT 8
#define IXGB_TXDCTL_WTHRESH_MASK 0x007F0000
#define IXGB_TXDCTL_WTHRESH_SHIFT 16
/* TSPMT Bit Masks */ /* TSPMT Bit Masks */
#define IXGB_TSPMT_TSMT_MASK 0x0000FFFF
#define IXGB_TSPMT_TSPBP_MASK 0xFFFF0000
#define IXGB_TSPMT_TSPBP_SHIFT 16
/* PAP Bit Masks */ /* 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 */ /* PCSC1 Bit Masks */
#define IXGB_PCSC1_LOOPBACK 0x00004000
/* PCSC2 Bit Masks */ /* PCSC2 Bit Masks */
#define IXGB_PCSC2_PCS_TYPE_MASK 0x00000003
#define IXGB_PCSC2_PCS_TYPE_10GBX 0x00000001
/* PCSS1 Bit Masks */ /* PCSS1 Bit Masks */
#define IXGB_PCSS1_LOCAL_FAULT 0x00000080
#define IXGB_PCSS1_RX_LINK_STATUS 0x00000004
/* PCSS2 Bit Masks */ /* 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 */ /* XPCSS Bit Masks */
#define IXGB_XPCSS_ALIGN_STATUS 0x00001000 #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 */ /* 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 */ /* MSCA bit Masks */
/* New Protocol Address */ /* New Protocol Address */
#define IXGB_MSCA_NP_ADDR_MASK 0x0000FFFF
#define IXGB_MSCA_NP_ADDR_SHIFT 0 #define IXGB_MSCA_NP_ADDR_SHIFT 0
/* Either Device Type or Register Address,depending on ST_CODE */ /* 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_DEV_TYPE_SHIFT 16
#define IXGB_MSCA_PHY_ADDR_MASK 0x03E00000
#define IXGB_MSCA_PHY_ADDR_SHIFT 21 #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_ADDR_CYCLE 0x00000000
#define IXGB_MSCA_WRITE 0x04000000 #define IXGB_MSCA_WRITE 0x04000000
#define IXGB_MSCA_READ 0x08000000 #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 */ /* Initiate command, self-clearing when command completes */
#define IXGB_MSCA_MDI_COMMAND 0x40000000 #define IXGB_MSCA_MDI_COMMAND 0x40000000
/*MDI In Progress Enable. */ /*MDI In Progress Enable. */
#define IXGB_MSCA_MDI_IN_PROG_EN 0x80000000
/* MSRWD bit masks */ /* 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 #define IXGB_MSRWD_READ_DATA_SHIFT 16
/* Definitions for the TXN17401 devices on the MDIO bus. */ /* Definitions for the optics devices on the MDIO bus. */
#define IXGB_PHY_ADDRESS 0x0 /* Single PHY, multiple "Devices" */ #define IXGB_PHY_ADDRESS 0x0 /* Single PHY, multiple "Devices" */
/* Five bit Device IDs */ /* Standard five-bit Device IDs. See IEEE 802.3ae, clause 45 */
#define TXN17401_PMA_PMD_DID 0x01 #define MDIO_PMA_PMD_DID 0x01
#define TXN17401_PCS_DID 0x03 #define MDIO_WIS_DID 0x02
#define TXN17401_XGXS_DID 0x04 #define MDIO_PCS_DID 0x03
#define MDIO_XGXS_DID 0x04
/* PMA/PMD registers and bit definitions. */ /* Standard PMA/PMD registers and bit definitions. */
/* Note: This is a very limited set of definitions, */ /* Note: This is a very limited set of definitions, */
/* only implemented features are defined. */ /* only implemented features are defined. */
#define TXN17401_PMA_PMD_CR1 0x0000 #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 */
#define TXN17401_PMA_PMD_CR1_RESET 0x8000 /* 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 { struct ixgb_rx_desc {
uint64_t buff_addr; uint64_t buff_addr;
u16 length; uint16_t length;
u16 reserved; uint16_t reserved;
u8 status; uint8_t status;
u8 errors; uint8_t errors;
u16 special; uint16_t special;
}; };
#define IXGB_RX_DESC_STATUS_DD 0x01 #define IXGB_RX_DESC_STATUS_DD 0x01
...@@ -379,23 +546,38 @@ struct ixgb_rx_desc { ...@@ -379,23 +546,38 @@ struct ixgb_rx_desc {
#define IXGB_RX_DESC_STATUS_IXSM 0x04 #define IXGB_RX_DESC_STATUS_IXSM 0x04
#define IXGB_RX_DESC_STATUS_VP 0x08 #define IXGB_RX_DESC_STATUS_VP 0x08
#define IXGB_RX_DESC_STATUS_TCPCS 0x20 #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_CE 0x01
#define IXGB_RX_DESC_ERRORS_SE 0x02 #define IXGB_RX_DESC_ERRORS_SE 0x02
#define IXGB_RX_DESC_ERRORS_P 0x08 #define IXGB_RX_DESC_ERRORS_P 0x08
#define IXGB_RX_DESC_ERRORS_TCPE 0x20 #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_ERRORS_RXE 0x80
#define IXGB_RX_DESC_SPECIAL_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ #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 { struct ixgb_tx_desc {
uint64_t buff_addr; uint64_t buff_addr;
u32 cmd_type_len; uint32_t cmd_type_len;
u8 status; uint8_t status;
u8 popts; uint8_t popts;
u16 vlan; 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_EOP 0x01000000
#define IXGB_TX_DESC_CMD_TSE 0x04000000 #define IXGB_TX_DESC_CMD_TSE 0x04000000
#define IXGB_TX_DESC_CMD_RS 0x08000000 #define IXGB_TX_DESC_CMD_RS 0x08000000
...@@ -408,18 +590,19 @@ struct ixgb_tx_desc { ...@@ -408,18 +590,19 @@ struct ixgb_tx_desc {
#define IXGB_TX_DESC_POPTS_IXSM 0x01 #define IXGB_TX_DESC_POPTS_IXSM 0x01
#define IXGB_TX_DESC_POPTS_TXSM 0x02 #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 { struct ixgb_context_desc {
u8 ipcss; uint8_t ipcss;
u8 ipcso; uint8_t ipcso;
u16 ipcse; uint16_t ipcse;
u8 tucss; uint8_t tucss;
u8 tucso; uint8_t tucso;
u16 tucse; uint16_t tucse;
u32 cmd_type_len; uint32_t cmd_type_len;
u8 status; uint8_t status;
u8 hdr_len; uint8_t hdr_len;
u16 mss; uint16_t mss;
}; };
#define IXGB_CONTEXT_DESC_CMD_TCP 0x01000000 #define IXGB_CONTEXT_DESC_CMD_TCP 0x01000000
...@@ -430,11 +613,14 @@ struct ixgb_context_desc { ...@@ -430,11 +613,14 @@ struct ixgb_context_desc {
#define IXGB_CONTEXT_DESC_TYPE 0x00000000 #define IXGB_CONTEXT_DESC_TYPE 0x00000000
#define IXGB_CONTEXT_DESC_STATUS_DD 0x01
/* Filters */ /* Filters */
#define IXGB_RAR_ENTRIES 16 /* Number of entries in Rx Address array */ #define IXGB_RAR_ENTRIES 16 /* Number of entries in Rx Address array */
#define IXGB_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bits) */ #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_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
#define IXGB_MEMORY_REGISTER_BASE_ADDRESS 0
#define ENET_HEADER_SIZE 14 #define ENET_HEADER_SIZE 14
#define ENET_FCS_LENGTH 4 #define ENET_FCS_LENGTH 4
#define IXGB_MAX_NUM_MULTICAST_ADDRESSES 128 #define IXGB_MAX_NUM_MULTICAST_ADDRESSES 128
...@@ -443,29 +629,46 @@ struct ixgb_context_desc { ...@@ -443,29 +629,46 @@ struct ixgb_context_desc {
#define IXGB_MAX_JUMBO_FRAME_SIZE 0x3F00 #define IXGB_MAX_JUMBO_FRAME_SIZE 0x3F00
/* Phy Addresses */ /* 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. * This is a little-endian specific check.
*/ */
#define IS_MULTICAST(Address) \ #define IS_MULTICAST(Address) \
(boolean_t)(((u8 *)(Address))[0] & ((u8)0x01)) (boolean_t)(((uint8_t *)(Address))[0] & ((uint8_t)0x01))
/* /*
* Check whether an address is broadcast. * Check whether an address is broadcast.
*/ */
#define IS_BROADCAST(Address) \ #define IS_BROADCAST(Address) \
((((u8 *)(Address))[0] == ((u8)0xff)) && (((u8 *)(Address))[1] == ((u8)0xff))) ((((uint8_t *)(Address))[0] == ((uint8_t)0xff)) && (((uint8_t *)(Address))[1] == ((uint8_t)0xff)))
/* Flow control parameters */ /* Flow control parameters */
struct ixgb_fc { struct ixgb_fc {
u32 high_water; /* Flow Control High-water */ uint32_t high_water; /* Flow Control High-water */
u32 low_water; /* Flow Control Low-water */ uint32_t low_water; /* Flow Control Low-water */
u16 pause_time; /* Flow Control Pause timer */ uint16_t pause_time; /* Flow Control Pause timer */
boolean_t send_xon; /* Flow control send XON */ boolean_t send_xon; /* Flow control send XON */
ixgb_fc_type type; /* Type of flow control */ ixgb_fc_type type; /* Type of flow control */
}; };
/* The historical defaults for the flow control values are given below. */ /* 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 */ /* Phy definitions */
#define IXGB_MAX_PHY_REG_ADDRESS 0xFFFF #define IXGB_MAX_PHY_REG_ADDRESS 0xFFFF
...@@ -480,32 +683,40 @@ struct ixgb_bus { ...@@ -480,32 +683,40 @@ struct ixgb_bus {
}; };
struct ixgb_hw { struct ixgb_hw {
u8 *hw_addr; /* Base Address of the hardware */ uint8_t *hw_addr; /* Base Address of the hardware */
void *back; /* Pointer to OS-dependent struct */ void *back; /* Pointer to OS-dependent struct */
struct ixgb_fc fc; /* Flow control parameters */ struct ixgb_fc fc; /* Flow control parameters */
struct ixgb_bus bus; /* Bus parameters */ struct ixgb_bus bus; /* Bus parameters */
u32 phy_id; /* Phy Identifier */ uint32_t phy_id; /* Phy Identifier */
u32 phy_addr; /* XGMII address of Phy */ uint32_t phy_addr; /* XGMII address of Phy */
ixgb_mac_type mac_type; /* Identifier for MAC controller */ ixgb_mac_type mac_type; /* Identifier for MAC controller */
u32 max_frame_size; /* Maximum frame size supported */ ixgb_phy_type phy_type; /* Transceiver/phy identifier */
u32 mc_filter_type; /* Multicast filter hash type */ uint32_t max_frame_size; /* Maximum frame size supported */
u32 num_mc_addrs; /* Number of current Multicast addrs */ uint32_t mc_filter_type; /* Multicast filter hash type */
u8 curr_mac_addr[IXGB_ETH_LENGTH_OF_ADDRESS]; /* Individual address currently programmed in MAC */ uint32_t num_mc_addrs; /* Number of current Multicast addrs */
u32 num_tx_desc; /* Number of Transmit descriptors */ uint8_t curr_mac_addr[IXGB_ETH_LENGTH_OF_ADDRESS]; /* Individual address currently programmed in MAC */
u32 num_rx_desc; /* Number of Receive descriptors */ uint32_t num_tx_desc; /* Number of Transmit descriptors */
u32 rx_buffer_size; /* Size of Receive buffer */ 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 link_up; /* TRUE if link is valid */
boolean_t adapter_stopped; /* State of adapter */ boolean_t adapter_stopped; /* State of adapter */
u16 device_id; /* device id from PCI configuration space */ uint16_t device_id; /* device id from PCI configuration space */
u16 vendor_id; /* vendor id from PCI configuration space */ uint16_t vendor_id; /* vendor id from PCI configuration space */
u16 subsystem_vendor_id; /* subsystem vendor id from PCI configuration space */ uint8_t revision_id; /* revision id from PCI configuration space */
u16 subsystem_id; /* subsystem id from PCI configuration space */ uint16_t subsystem_vendor_id; /* subsystem vendor id from PCI configuration space */
u16 eeprom[IXGB_EEPROM_SIZE]; /* EEPROM contents read at init time */ uint16_t subsystem_id; /* subsystem id from PCI configuration space */
uint64_t io_base; /* Our I/O mapped location */ uint32_t bar0; /* Base Address registers */
u32 lastLFC; uint32_t bar1;
u32 lastRFC; 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 { struct ixgb_hw_stats {
uint64_t tprl; uint64_t tprl;
uint64_t tprh; uint64_t tprh;
...@@ -578,48 +789,49 @@ extern void ixgb_check_for_link(struct ixgb_hw *hw); ...@@ -578,48 +789,49 @@ extern void ixgb_check_for_link(struct ixgb_hw *hw);
extern boolean_t ixgb_check_for_bad_link(struct ixgb_hw *hw); extern boolean_t ixgb_check_for_bad_link(struct ixgb_hw *hw);
extern boolean_t ixgb_setup_fc(struct ixgb_hw *hw); extern boolean_t ixgb_setup_fc(struct ixgb_hw *hw);
extern void ixgb_clear_hw_cntrs(struct ixgb_hw *hw); extern void ixgb_clear_hw_cntrs(struct ixgb_hw *hw);
extern boolean_t mac_addr_valid(u8 * mac_addr); extern boolean_t mac_addr_valid(uint8_t * mac_addr);
extern u16 ixgb_read_phy_reg(struct ixgb_hw *hw, extern uint16_t ixgb_read_phy_reg(struct ixgb_hw *hw,
u32 reg_addr, uint32_t reg_addr,
u32 phy_addr, u32 device_type); uint32_t phy_addr, uint32_t device_type);
extern void ixgb_write_phy_reg(struct ixgb_hw *hw, extern void ixgb_write_phy_reg(struct ixgb_hw *hw,
u32 reg_addr, uint32_t reg_addr,
u32 phy_addr, uint32_t phy_addr,
u32 device_type, u16 data); uint32_t device_type, uint16_t data);
extern void ixgb_rar_set(struct ixgb_hw *hw, u8 * addr, u32 index); extern void ixgb_rar_set(struct ixgb_hw *hw, uint8_t * addr, uint32_t index);
/* Filters (multicast, vlan, receive) */ /* Filters (multicast, vlan, receive) */
extern void ixgb_mc_addr_list_update(struct ixgb_hw *hw, extern void ixgb_mc_addr_list_update(struct ixgb_hw *hw,
u8 * mc_addr_list, uint8_t * mc_addr_list,
u32 mc_addr_count, u32 pad); uint32_t mc_addr_count, uint32_t pad);
/* Vfta functions */ /* Vfta functions */
extern void ixgb_write_vfta(struct ixgb_hw *hw, extern void ixgb_write_vfta(struct ixgb_hw *hw,
u32 offset, u32 value); uint32_t offset, uint32_t value);
extern void ixgb_clear_vfta(struct ixgb_hw *hw); extern void ixgb_clear_vfta(struct ixgb_hw *hw);
/* Access functions to eeprom data */ /* Access functions to eeprom data */
void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, u8 * mac_addr); void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t * mac_addr);
u16 ixgb_get_ee_compatibility(struct ixgb_hw *hw); uint16_t ixgb_get_ee_compatibility(struct ixgb_hw *hw);
u32 ixgb_get_ee_pba_number(struct ixgb_hw *hw); uint32_t ixgb_get_ee_pba_number(struct ixgb_hw *hw);
u16 ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw); uint16_t ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw);
u16 ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw *hw); uint16_t ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw *hw);
u16 ixgb_get_ee_subsystem_id(struct ixgb_hw *hw); uint16_t ixgb_get_ee_subsystem_id(struct ixgb_hw *hw);
u16 ixgb_get_ee_subvendor_id(struct ixgb_hw *hw); uint16_t ixgb_get_ee_subvendor_id(struct ixgb_hw *hw);
u16 ixgb_get_ee_device_id(struct ixgb_hw *hw); uint16_t ixgb_get_ee_device_id(struct ixgb_hw *hw);
u16 ixgb_get_ee_vendor_id(struct ixgb_hw *hw); uint16_t ixgb_get_ee_vendor_id(struct ixgb_hw *hw);
u16 ixgb_get_ee_swdpins_reg(struct ixgb_hw *hw); uint16_t ixgb_get_ee_swdpins_reg(struct ixgb_hw *hw);
u8 ixgb_get_ee_d3_power(struct ixgb_hw *hw); uint8_t ixgb_get_ee_d3_power(struct ixgb_hw *hw);
u8 ixgb_get_ee_d0_power(struct ixgb_hw *hw); uint8_t ixgb_get_ee_d0_power(struct ixgb_hw *hw);
boolean_t ixgb_get_eeprom_data(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 */ /* Everything else */
void ixgb_led_on(struct ixgb_hw *hw); void ixgb_led_on(struct ixgb_hw *hw);
void ixgb_led_off(struct ixgb_hw *hw); void ixgb_led_off(struct ixgb_hw *hw);
void ixgb_write_pci_cfg(struct ixgb_hw *hw, u32 reg, u16 * value); void ixgb_write_pci_cfg(struct ixgb_hw *hw, uint32_t reg, uint16_t * value);
#endif /* _IXGB_HW_H_ */ #endif /* _IXGB_HW_H_ */
/******************************************************************************* /*******************************************************************************
Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
Contact Information: Contact Information:
Linux NICS <linux.nics@intel.com> Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/ *******************************************************************************/
#ifndef _IXGB_IDS_H_ #ifndef _IXGB_IDS_H_
...@@ -35,9 +36,17 @@ ...@@ -35,9 +36,17 @@
#define INTEL_VENDOR_ID 0x8086 #define INTEL_VENDOR_ID 0x8086
#define INTEL_SUBVENDOR_ID 0x8086 #define INTEL_SUBVENDOR_ID 0x8086
#define IXGB_DEVICE_ID_82597EX 0x1048 #define IXGB_DEVICE_ID_82597EX 0x1048
#define IXGB_SUBDEVICE_ID_A11F 0xA11F /* Adapter-OEM-1310nm-Fiber */ #define IXGB_DEVICE_ID_82597EX_SR 0x1A48
#define IXGB_SUBDEVICE_ID_A01F 0xA01F /* Adapter-Retail-1310nm-Fiber */
#define IXGB_SUBDEVICE_ID_A11F 0xA11F
#define IXGB_SUBDEVICE_ID_A01F 0xA01F
#define IXGB_SUBDEVICE_ID_A15F 0xA15F
#define IXGB_SUBDEVICE_ID_A05F 0xA05F
#define IXGB_SUBDEVICE_ID_A12F 0xA12F
#define IXGB_SUBDEVICE_ID_A02F 0xA02F
#endif /* #ifndef _IXGB_IDS_H_ */ #endif /* #ifndef _IXGB_IDS_H_ */
......
/******************************************************************************* /*******************************************************************************
Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
...@@ -23,36 +23,29 @@ ...@@ -23,36 +23,29 @@
Contact Information: Contact Information:
Linux NICS <linux.nics@intel.com> Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#define __IXGB_MAIN__ *******************************************************************************/
#include "ixgb.h" #include "ixgb.h"
char ixgb_driver_name[] = "ixgb"; char ixgb_driver_name[] = "ixgb";
char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver"; char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
char ixgb_driver_version[] = "1.0.47-k1jg"; char ixgb_driver_version[] = "1.0.66";
char ixgb_copyright[] = "Copyright (c) 2001-2003 Intel Corporation."; char ixgb_copyright[] = "Copyright (c) 2001-2004 Intel Corporation.";
/* ixgb_pci_tbl - PCI Device ID Table /* ixgb_pci_tbl - PCI Device ID Table
* *
* For selecting devices to load on private driver_data field (last one)
* stores an index into ixgb_strings.
* Wildcard entries (PCI_ANY_ID) should come last * Wildcard entries (PCI_ANY_ID) should come last
* Last entry must be all 0s * Last entry must be all 0s
* *
* { Vendor ID, Device ID, SubVendor ID, SubDevice ID, * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
* Class, Class Mask, String Index } * Class, Class Mask, private data (not used) }
*/ */
static struct pci_device_id ixgb_pci_tbl[] = { static struct pci_device_id ixgb_pci_tbl[] = {
/* Intel(R) PRO/10GbE Network Connection */
{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX,
INTEL_SUBVENDOR_ID, IXGB_SUBDEVICE_ID_A11F, 0, 0, 0},
{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX,
INTEL_SUBVENDOR_ID, IXGB_SUBDEVICE_ID_A01F, 0, 0, 0},
/* Generic */
{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX, {INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_SR,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
/* required last entry */ /* required last entry */
{0,} {0,}
...@@ -60,10 +53,6 @@ static struct pci_device_id ixgb_pci_tbl[] = { ...@@ -60,10 +53,6 @@ static struct pci_device_id ixgb_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, ixgb_pci_tbl); MODULE_DEVICE_TABLE(pci, ixgb_pci_tbl);
static char *ixgb_strings[] = {
"Intel(R) PRO/10GbE Network Connection"
};
/* Local Function Prototypes */ /* Local Function Prototypes */
int ixgb_up(struct ixgb_adapter *adapter); int ixgb_up(struct ixgb_adapter *adapter);
...@@ -73,8 +62,8 @@ void ixgb_reset(struct ixgb_adapter *adapter); ...@@ -73,8 +62,8 @@ void ixgb_reset(struct ixgb_adapter *adapter);
static int ixgb_init_module(void); static int ixgb_init_module(void);
static void ixgb_exit_module(void); static void ixgb_exit_module(void);
static int ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent); static int ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
static void ixgb_remove(struct pci_dev *pdev); static void __devexit ixgb_remove(struct pci_dev *pdev);
static void ixgb_sw_init(struct ixgb_adapter *adapter); static int ixgb_sw_init(struct ixgb_adapter *adapter);
static int ixgb_open(struct net_device *netdev); static int ixgb_open(struct net_device *netdev);
static int ixgb_close(struct net_device *netdev); static int ixgb_close(struct net_device *netdev);
static int ixgb_setup_tx_resources(struct ixgb_adapter *adapter); static int ixgb_setup_tx_resources(struct ixgb_adapter *adapter);
...@@ -88,16 +77,7 @@ static void ixgb_free_tx_resources(struct ixgb_adapter *adapter); ...@@ -88,16 +77,7 @@ static void ixgb_free_tx_resources(struct ixgb_adapter *adapter);
static void ixgb_free_rx_resources(struct ixgb_adapter *adapter); static void ixgb_free_rx_resources(struct ixgb_adapter *adapter);
static void ixgb_set_multi(struct net_device *netdev); static void ixgb_set_multi(struct net_device *netdev);
static void ixgb_watchdog(unsigned long data); static void ixgb_watchdog(unsigned long data);
static inline boolean_t ixgb_tso(struct ixgb_adapter *adapter,
struct sk_buff *skb);
static int ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev); static int ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
static void ixgb_tx_timeout(struct net_device *netdev);
static void ixgb_tx_timeout_task(struct net_device *netdev);
static void ixgb_vlan_rx_register(struct net_device *netdev,
struct vlan_group *grp);
static void ixgb_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
static void ixgb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
static void ixgb_restore_vlan(struct ixgb_adapter *adapter);
static struct net_device_stats *ixgb_get_stats(struct net_device *netdev); static struct net_device_stats *ixgb_get_stats(struct net_device *netdev);
static int ixgb_change_mtu(struct net_device *netdev, int new_mtu); static int ixgb_change_mtu(struct net_device *netdev, int new_mtu);
static int ixgb_set_mac(struct net_device *netdev, void *p); static int ixgb_set_mac(struct net_device *netdev, void *p);
...@@ -105,25 +85,40 @@ static void ixgb_update_stats(struct ixgb_adapter *adapter); ...@@ -105,25 +85,40 @@ static void ixgb_update_stats(struct ixgb_adapter *adapter);
static inline void ixgb_irq_disable(struct ixgb_adapter *adapter); static inline void ixgb_irq_disable(struct ixgb_adapter *adapter);
static inline void ixgb_irq_enable(struct ixgb_adapter *adapter); static inline void ixgb_irq_enable(struct ixgb_adapter *adapter);
static irqreturn_t ixgb_intr(int irq, void *data, struct pt_regs *regs); static irqreturn_t ixgb_intr(int irq, void *data, struct pt_regs *regs);
static void ixgb_clean_tx_irq(struct ixgb_adapter *adapter); static boolean_t ixgb_clean_tx_irq(struct ixgb_adapter *adapter);
#ifdef CONFIG_IXGB_NAPI #ifdef CONFIG_IXGB_NAPI
static int ixgb_poll(struct net_device *netdev, int *budget); static int ixgb_clean(struct net_device *netdev, int *budget);
static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter,
int *work_done, int work_to_do);
#else #else
static void ixgb_clean_rx_irq(struct ixgb_adapter *adapter); static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter);
#endif #endif
static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter); static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter);
static int ixgb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); static int ixgb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
static inline void ixgb_rx_checksum(struct ixgb_adapter *adapter, static inline void ixgb_rx_checksum(struct ixgb_adapter *adapter,
struct ixgb_rx_desc *rx_desc, struct ixgb_rx_desc *rx_desc,
struct sk_buff *skb); struct sk_buff *skb);
static void ixgb_tx_timeout(struct net_device *dev);
static void ixgb_tx_timeout_task(struct net_device *dev);
static void ixgb_vlan_rx_register(struct net_device *netdev,
struct vlan_group *grp);
static void ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
static void ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
static void ixgb_restore_vlan(struct ixgb_adapter *adapter);
static int ixgb_notify_reboot(struct notifier_block *, unsigned long event, static int ixgb_notify_reboot(struct notifier_block *, unsigned long event,
void *ptr); void *ptr);
static int ixgb_suspend(struct pci_dev *pdev, u32 state); static int ixgb_suspend(struct pci_dev *pdev, uint32_t state);
#ifdef CONFIG_NET_POLL_CONTROLLER
/* for netdump / net console */
static void ixgb_netpoll(struct net_device *dev);
#endif
struct notifier_block ixgb_notifier_reboot = { struct notifier_block ixgb_notifier_reboot = {
.notifier_call = ixgb_notify_reboot, .notifier_call = ixgb_notify_reboot,
.next = NULL, .next = NULL,
.priority = 0 .priority = 0
}; };
/* Exported from other modules */ /* Exported from other modules */
...@@ -132,13 +127,13 @@ extern void ixgb_check_options(struct ixgb_adapter *adapter); ...@@ -132,13 +127,13 @@ extern void ixgb_check_options(struct ixgb_adapter *adapter);
extern int ixgb_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr); extern int ixgb_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr);
static struct pci_driver ixgb_driver = { static struct pci_driver ixgb_driver = {
.name = ixgb_driver_name, .name = ixgb_driver_name,
.id_table = ixgb_pci_tbl, .id_table = ixgb_pci_tbl,
.probe = ixgb_probe, .probe = ixgb_probe,
.remove = __devexit_p(ixgb_remove), .remove = __devexit_p(ixgb_remove),
/* Power Managment Hooks */ /* Power Managment Hooks */
.suspend = NULL, .suspend = NULL,
.resume = NULL .resume = NULL
}; };
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>"); MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
...@@ -152,24 +147,20 @@ MODULE_LICENSE("GPL"); ...@@ -152,24 +147,20 @@ MODULE_LICENSE("GPL");
#define RXDCTL_WTHRESH_DEFAULT 16 /* chip writes back at this many or RXT0 */ #define RXDCTL_WTHRESH_DEFAULT 16 /* chip writes back at this many or RXT0 */
/** /**
* ixgb_init_module - Driver Registration Routine. * ixgb_init_module - Driver Registration Routine
* *
* ixgb_init_module is the first routine called when the driver is * ixgb_init_module is the first routine called when the driver is
* loaded. All it does is register with the PCI subsystem. * loaded. All it does is register with the PCI subsystem.
**/ **/
static int __init static int __init ixgb_init_module(void)
ixgb_init_module(void)
{ {
int ret; int ret;
IXGB_DBG("ixgb_init_module\n"); printk(KERN_INFO "%s - version %s\n",
ixgb_driver_string, ixgb_driver_version);
printk(KERN_INFO "%s - version %s\n", ixgb_driver_string,
ixgb_driver_version);
printk(KERN_INFO "%s\n", ixgb_copyright); printk(KERN_INFO "%s\n", ixgb_copyright);
#ifdef CONFIG_IXGB_NAPI
printk(KERN_INFO "NAPI Enabled\n");
#endif
ret = pci_module_init(&ixgb_driver); ret = pci_module_init(&ixgb_driver);
if (ret >= 0) { if (ret >= 0) {
register_reboot_notifier(&ixgb_notifier_reboot); register_reboot_notifier(&ixgb_notifier_reboot);
...@@ -180,47 +171,31 @@ ixgb_init_module(void) ...@@ -180,47 +171,31 @@ ixgb_init_module(void)
module_init(ixgb_init_module); module_init(ixgb_init_module);
/** /**
* ixgb_exit_module - Driver Exit Cleanup Routine. * ixgb_exit_module - Driver Exit Cleanup Routine
* *
* ixgb_exit_module is called just before the driver is removed * ixgb_exit_module is called just before the driver is removed
* from memory. * from memory.
**/ **/
static void __exit static void __exit ixgb_exit_module(void)
ixgb_exit_module(void)
{ {
IXGB_DBG("ixgb_exit_module\n");
unregister_reboot_notifier(&ixgb_notifier_reboot); unregister_reboot_notifier(&ixgb_notifier_reboot);
pci_unregister_driver(&ixgb_driver); pci_unregister_driver(&ixgb_driver);
} }
module_exit(ixgb_exit_module); module_exit(ixgb_exit_module);
/** int ixgb_up(struct ixgb_adapter *adapter)
* ixgb_up - Driver ifconfig UP routine.
*
* ixgb_up is called to initialize and bring online an interface.
* @param adapter board private structure
**/
int
ixgb_up(struct ixgb_adapter *adapter)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
int err;
int max_frame = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
struct ixgb_hw *hw = &adapter->hw;
IXGB_DBG("ixgb_up\n"); /* hardware has been reset, we need to reload some things */
if (request_irq(netdev->irq, &ixgb_intr, SA_SHIRQ | SA_SAMPLE_RANDOM,
netdev->name, netdev)) {
IXGB_DBG("%s: request_irq failed\n", netdev->name);
return -1;
}
/* disable interrupts and get the hardware into a known state */
IXGB_WRITE_REG(&adapter->hw, IMC, 0xffffffff);
/* hardware was reset in probe/down, we need to reload some things */
ixgb_set_multi(netdev); ixgb_set_multi(netdev);
ixgb_restore_vlan(adapter); ixgb_restore_vlan(adapter);
ixgb_configure_tx(adapter); ixgb_configure_tx(adapter);
...@@ -228,31 +203,45 @@ ixgb_up(struct ixgb_adapter *adapter) ...@@ -228,31 +203,45 @@ ixgb_up(struct ixgb_adapter *adapter)
ixgb_configure_rx(adapter); ixgb_configure_rx(adapter);
ixgb_alloc_rx_buffers(adapter); ixgb_alloc_rx_buffers(adapter);
if ((err = request_irq(adapter->pdev->irq, &ixgb_intr,
SA_SHIRQ | SA_SAMPLE_RANDOM,
netdev->name, netdev)))
return err;
/* disable interrupts and get the hardware into a known state */
IXGB_WRITE_REG(&adapter->hw, IMC, 0xffffffff);
if ((hw->max_frame_size != max_frame) ||
(hw->max_frame_size !=
(IXGB_READ_REG(hw, MFS) >> IXGB_MFS_SHIFT))) {
hw->max_frame_size = max_frame;
IXGB_WRITE_REG(hw, MFS, hw->max_frame_size << IXGB_MFS_SHIFT);
if (hw->max_frame_size >
IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH) {
uint32_t ctrl0 = IXGB_READ_REG(hw, CTRL0);
if (!(ctrl0 & IXGB_CTRL0_JFE)) {
ctrl0 |= IXGB_CTRL0_JFE;
IXGB_WRITE_REG(hw, CTRL0, ctrl0);
}
}
}
mod_timer(&adapter->watchdog_timer, jiffies); mod_timer(&adapter->watchdog_timer, jiffies);
ixgb_irq_enable(adapter); ixgb_irq_enable(adapter);
IXGB_DBG("ixgb_up: RAH_0 is <%x>\n", IXGB_READ_REG(&adapter->hw, RAH));
IXGB_DBG("ixgb_up: RDBAL is <%x>\n",
IXGB_READ_REG(&adapter->hw, RDBAL));
return 0; return 0;
} }
/** void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog)
* ixgb_down - Driver ifconfig DOWN routine.
*
* ixgb_down is called to uninitialize and take offline an interface.
* @param adapter board private structure
* @param kill_watchdog
**/
void
ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
IXGB_DBG("ixgb_down\n");
ixgb_irq_disable(adapter); ixgb_irq_disable(adapter);
free_irq(netdev->irq, netdev); free_irq(adapter->pdev->irq, netdev);
if (kill_watchdog) if (kill_watchdog)
del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->watchdog_timer);
adapter->link_speed = 0; adapter->link_speed = 0;
...@@ -261,21 +250,12 @@ ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog) ...@@ -261,21 +250,12 @@ ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog)
netif_stop_queue(netdev); netif_stop_queue(netdev);
ixgb_reset(adapter); ixgb_reset(adapter);
ixgb_clean_tx_ring(adapter); ixgb_clean_tx_ring(adapter);
ixgb_clean_rx_ring(adapter); ixgb_clean_rx_ring(adapter);
} }
/** void ixgb_reset(struct ixgb_adapter *adapter)
* ixgb_reset - hardware reset.
*
* ixgb_reset is called to initialize hardware to a known state.
* @param adapter board private structure
**/
void
ixgb_reset(struct ixgb_adapter *adapter)
{ {
IXGB_DBG("ixgb_reset\n");
ixgb_adapter_stop(&adapter->hw); ixgb_adapter_stop(&adapter->hw);
if (!ixgb_init_hw(&adapter->hw)) if (!ixgb_init_hw(&adapter->hw))
...@@ -283,11 +263,15 @@ ixgb_reset(struct ixgb_adapter *adapter) ...@@ -283,11 +263,15 @@ ixgb_reset(struct ixgb_adapter *adapter)
} }
/** /**
* ixgb_probe - Device Initialization Routine. * ixgb_probe - Device Initialization Routine
* @param pdev PCI device information struct * @pdev: PCI device information struct
* @param ent entry in ixgb_pci_table * @ent: entry in ixgb_pci_tbl
* *
* Returns 0 on success, negative on failure * Returns 0 on success, negative on failure
*
* ixgb_probe initializes an adapter identified by a pci_dev structure.
* The OS initialization, configuring of the adapter private structure,
* and a hardware reset occur.
**/ **/
static int __devinit static int __devinit
...@@ -300,35 +284,29 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -300,35 +284,29 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int mmio_len; int mmio_len;
int pci_using_dac; int pci_using_dac;
int i; int i;
int err;
IXGB_DBG("ixgb_probe\n"); if ((err = pci_enable_device(pdev)))
return err;
if ((i = pci_enable_device(pdev))) { if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
IXGB_ERR("pci_enable_device failed\n");
return i;
}
if (!(i = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
pci_using_dac = 1; pci_using_dac = 1;
} else { } else {
if ((i = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) { if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
IXGB_ERR("No usable DMA configuration, aborting\n"); IXGB_ERR("No usable DMA configuration, aborting\n");
return i; return err;
} }
pci_using_dac = 0; pci_using_dac = 0;
} }
if ((i = pci_request_regions(pdev, ixgb_driver_name))) { if ((err = pci_request_regions(pdev, ixgb_driver_name)))
IXGB_ERR("Failed to reserve PCI I/O and Memory resources.\n"); return err;
return i;
}
pci_set_master(pdev); pci_set_master(pdev);
/* alloc_etherdev clears the memory for us */ netdev = alloc_etherdev(sizeof(struct ixgb_adapter));
netdev = alloc_etherdev(sizeof (struct ixgb_adapter));
if (!netdev) { if (!netdev) {
IXGB_ERR("Unable to allocate net_device struct\n"); err = -ENOMEM;
goto err_alloc_etherdev; goto err_alloc_etherdev;
} }
...@@ -345,8 +323,10 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -345,8 +323,10 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
mmio_len = pci_resource_len(pdev, BAR_0); mmio_len = pci_resource_len(pdev, BAR_0);
adapter->hw.hw_addr = ioremap(mmio_start, mmio_len); adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
if (!adapter->hw.hw_addr) if (!adapter->hw.hw_addr) {
err = -EIO;
goto err_ioremap; goto err_ioremap;
}
for (i = BAR_1; i <= BAR_5; i++) { for (i = BAR_1; i <= BAR_5; i++) {
if (pci_resource_len(pdev, i) == 0) if (pci_resource_len(pdev, i) == 0)
...@@ -356,8 +336,6 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -356,8 +336,6 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
break; break;
} }
} }
IXGB_DBG("mmio_start<%lx> hw_addr<%p>\n", mmio_start,
adapter->hw.hw_addr);
netdev->open = &ixgb_open; netdev->open = &ixgb_open;
netdev->stop = &ixgb_close; netdev->stop = &ixgb_close;
...@@ -370,25 +348,28 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -370,25 +348,28 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->tx_timeout = &ixgb_tx_timeout; netdev->tx_timeout = &ixgb_tx_timeout;
netdev->watchdog_timeo = HZ; netdev->watchdog_timeo = HZ;
#ifdef CONFIG_IXGB_NAPI #ifdef CONFIG_IXGB_NAPI
netdev->poll = &ixgb_poll; netdev->poll = &ixgb_clean;
netdev->weight = 64; netdev->weight = 64;
#endif #endif
netdev->vlan_rx_register = ixgb_vlan_rx_register; netdev->vlan_rx_register = ixgb_vlan_rx_register;
netdev->vlan_rx_add_vid = ixgb_vlan_rx_add_vid; netdev->vlan_rx_add_vid = ixgb_vlan_rx_add_vid;
netdev->vlan_rx_kill_vid = ixgb_vlan_rx_kill_vid; netdev->vlan_rx_kill_vid = ixgb_vlan_rx_kill_vid;
#ifdef CONFIG_NET_POLL_CONTROLLER
netdev->poll_controller = ixgb_netpoll;
#endif
netdev->irq = pdev->irq;
netdev->mem_start = mmio_start; netdev->mem_start = mmio_start;
netdev->mem_end = mmio_start + mmio_len; netdev->mem_end = mmio_start + mmio_len;
netdev->base_addr = adapter->hw.io_base; netdev->base_addr = adapter->hw.io_base;
adapter->bd_number = cards_found; adapter->bd_number = cards_found;
adapter->id_string = ixgb_strings[ent->driver_data];
adapter->link_speed = 0; adapter->link_speed = 0;
adapter->link_duplex = 0; adapter->link_duplex = 0;
/* setup the private structure */ /* setup the private structure */
ixgb_sw_init(adapter);
if ((err = ixgb_sw_init(adapter)))
goto err_sw_init;
netdev->features = NETIF_F_SG | netdev->features = NETIF_F_SG |
NETIF_F_HW_CSUM | NETIF_F_HW_CSUM |
...@@ -403,57 +384,59 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -403,57 +384,59 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* make sure the EEPROM is good */ /* make sure the EEPROM is good */
if (!ixgb_validate_eeprom_checksum(&adapter->hw)) { if (!ixgb_validate_eeprom_checksum(&adapter->hw)) {
IXGB_DBG("Invalid EEPROM checksum.\n"); printk(KERN_ERR "The EEPROM Checksum Is Not Valid\n");
err = -EIO;
goto err_eeprom; goto err_eeprom;
} }
ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr); ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr);
if (!is_valid_ether_addr(netdev->dev_addr)) { if (!is_valid_ether_addr(netdev->dev_addr)) {
IXGB_DBG("Invalid MAC address in EEPROM.\n"); err = -EIO;
goto err_eeprom; goto err_eeprom;
} }
adapter->max_data_per_txd = IXGB_MAX_JUMBO_FRAME_SIZE;
adapter->part_num = ixgb_get_ee_pba_number(&adapter->hw); adapter->part_num = ixgb_get_ee_pba_number(&adapter->hw);
init_timer(&adapter->watchdog_timer); init_timer(&adapter->watchdog_timer);
adapter->watchdog_timer.function = &ixgb_watchdog; adapter->watchdog_timer.function = &ixgb_watchdog;
adapter->watchdog_timer.data = (unsigned long) adapter; adapter->watchdog_timer.data = (unsigned long)adapter;
INIT_WORK(&adapter->tx_timeout_task, INIT_WORK(&adapter->tx_timeout_task,
(void (*)(void *)) ixgb_tx_timeout_task, netdev); (void (*)(void *))ixgb_tx_timeout_task, netdev);
register_netdev(netdev); if ((err = register_netdev(netdev)))
memcpy(adapter->ifname, netdev->name, IFNAMSIZ); goto err_register;
adapter->ifname[IFNAMSIZ - 1] = 0;
/* we're going to reset, so assume we have no link for now */ /* we're going to reset, so assume we have no link for now */
netif_carrier_off(netdev); netif_carrier_off(netdev);
netif_stop_queue(netdev); netif_stop_queue(netdev);
printk(KERN_INFO "%s: %s\n", netdev->name, adapter->id_string); printk(KERN_INFO "%s: Intel(R) PRO/10GbE Network Connection\n",
netdev->name);
ixgb_check_options(adapter); ixgb_check_options(adapter);
/* reset the hardware with the new settings */ /* reset the hardware with the new settings */
ixgb_reset(adapter); ixgb_reset(adapter);
cards_found++; cards_found++;
return 0; return 0;
err_register:
err_sw_init:
err_eeprom: err_eeprom:
iounmap(adapter->hw.hw_addr); iounmap(adapter->hw.hw_addr);
err_ioremap: err_ioremap:
pci_release_regions(pdev);
free_netdev(netdev); free_netdev(netdev);
err_alloc_etherdev: err_alloc_etherdev:
return -ENOMEM; pci_release_regions(pdev);
return err;
} }
/** /**
* ixgb_remove - Device Removal Routine. * ixgb_remove - Device Removal Routine
* @param pdev PCI device information struct * @pdev: PCI device information struct
* *
* ixgb_remove is called by the PCI subsystem to alert the driver * ixgb_remove is called by the PCI subsystem to alert the driver
* that it should release a PCI device. The could be caused by a * that it should release a PCI device. The could be caused by a
...@@ -461,49 +444,36 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -461,49 +444,36 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* memory. * memory.
**/ **/
static void __devexit static void __devexit ixgb_remove(struct pci_dev *pdev)
ixgb_remove(struct pci_dev *pdev)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgb_adapter *adapter = netdev->priv; struct ixgb_adapter *adapter = netdev->priv;
IXGB_DBG("ixgb_remove\n");
unregister_netdev(netdev); unregister_netdev(netdev);
#ifdef ETHTOOL_IDENTIFY iounmap(adapter->hw.hw_addr);
ixgb_identify_stop(adapter);
#endif
iounmap((void *) adapter->hw.hw_addr);
pci_release_regions(pdev); pci_release_regions(pdev);
free_netdev(netdev); free_netdev(netdev);
} }
/** /**
* ixgb_sw_init - Initialize general software structures (struct ixgb_adapter). * ixgb_sw_init - Initialize general software structures (struct ixgb_adapter)
* @param adapter board private structure to initialize * @adapter: board private structure to initialize
* *
* ixgb_sw_init initializes the adapter private data structure. * ixgb_sw_init initializes the Adapter private data structure.
* Fields are initialized based on PCI device information and * Fields are initialized based on PCI device information and
* OS network device settings (MTU size). * OS network device settings (MTU size).
**/ **/
static void __devinit static int __devinit ixgb_sw_init(struct ixgb_adapter *adapter)
ixgb_sw_init(struct ixgb_adapter *adapter)
{ {
struct ixgb_hw *hw = &adapter->hw; struct ixgb_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
IXGB_DBG("ixgb_sw_init\n");
/* PCI config space info */ /* PCI config space info */
/* FIXME: do not store, instead directly use struct pci_dev
* where needed
*/
hw->vendor_id = pdev->vendor; hw->vendor_id = pdev->vendor;
hw->device_id = pdev->device; hw->device_id = pdev->device;
hw->subsystem_vendor_id = pdev->subsystem_vendor; hw->subsystem_vendor_id = pdev->subsystem_vendor;
...@@ -513,7 +483,8 @@ ixgb_sw_init(struct ixgb_adapter *adapter) ...@@ -513,7 +483,8 @@ ixgb_sw_init(struct ixgb_adapter *adapter)
hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
if (hw->device_id == IXGB_DEVICE_ID_82597EX) if ((hw->device_id == IXGB_DEVICE_ID_82597EX)
|| (hw->device_id == IXGB_DEVICE_ID_82597EX_SR))
hw->mac_type = ixgb_82597; hw->mac_type = ixgb_82597;
else { else {
/* should never have loaded on this device */ /* should never have loaded on this device */
...@@ -524,11 +495,14 @@ ixgb_sw_init(struct ixgb_adapter *adapter) ...@@ -524,11 +495,14 @@ ixgb_sw_init(struct ixgb_adapter *adapter)
hw->fc.send_xon = 1; hw->fc.send_xon = 1;
atomic_set(&adapter->irq_sem, 1); atomic_set(&adapter->irq_sem, 1);
spin_lock_init(&adapter->tx_lock);
return 0;
} }
/** /**
* ixgb_open - Called when a network interface is made active. * ixgb_open - Called when a network interface is made active
* @param netdev network interface device structure * @netdev: network interface device structure
* *
* Returns 0 on success, negative value on failure * Returns 0 on success, negative value on failure
* *
...@@ -539,27 +513,22 @@ ixgb_sw_init(struct ixgb_adapter *adapter) ...@@ -539,27 +513,22 @@ ixgb_sw_init(struct ixgb_adapter *adapter)
* and the stack is notified that the interface is ready. * and the stack is notified that the interface is ready.
**/ **/
static int static int ixgb_open(struct net_device *netdev)
ixgb_open(struct net_device *netdev)
{ {
struct ixgb_adapter *adapter = netdev->priv; struct ixgb_adapter *adapter = netdev->priv;
int err;
IXGB_DBG("ixgb_open\n");
/* allocate transmit descriptors */ /* allocate transmit descriptors */
if (ixgb_setup_tx_resources(adapter)) { if ((err = ixgb_setup_tx_resources(adapter)))
IXGB_DBG("ixgb_open: failed ixgb_setup_tx_resources.\n");
goto err_setup_tx; goto err_setup_tx;
}
/* allocate receive descriptors and buffers */ /* allocate receive descriptors */
if (ixgb_setup_rx_resources(adapter)) { if ((err = ixgb_setup_rx_resources(adapter)))
IXGB_DBG("ixgb_open: failed ixgb_setup_rx_resources.\n");
goto err_setup_rx; goto err_setup_rx;
}
if (ixgb_up(adapter)) if ((err = ixgb_up(adapter)))
goto err_up; goto err_up;
return 0; return 0;
...@@ -570,12 +539,13 @@ ixgb_open(struct net_device *netdev) ...@@ -570,12 +539,13 @@ ixgb_open(struct net_device *netdev)
ixgb_free_tx_resources(adapter); ixgb_free_tx_resources(adapter);
err_setup_tx: err_setup_tx:
ixgb_reset(adapter); ixgb_reset(adapter);
return -EBUSY;
return err;
} }
/** /**
* ixgb_close - Disables a network interface. * ixgb_close - Disables a network interface
* @param netdev network interface device structure * @netdev: network interface device structure
* *
* Returns 0, this is not allowed to fail * Returns 0, this is not allowed to fail
* *
...@@ -585,13 +555,10 @@ ixgb_open(struct net_device *netdev) ...@@ -585,13 +555,10 @@ ixgb_open(struct net_device *netdev)
* hardware, and all transmit and receive resources are freed. * hardware, and all transmit and receive resources are freed.
**/ **/
static int static int ixgb_close(struct net_device *netdev)
ixgb_close(struct net_device *netdev)
{ {
struct ixgb_adapter *adapter = netdev->priv; struct ixgb_adapter *adapter = netdev->priv;
IXGB_DBG("ixgb_close\n");
ixgb_down(adapter, TRUE); ixgb_down(adapter, TRUE);
ixgb_free_tx_resources(adapter); ixgb_free_tx_resources(adapter);
...@@ -601,22 +568,19 @@ ixgb_close(struct net_device *netdev) ...@@ -601,22 +568,19 @@ ixgb_close(struct net_device *netdev)
} }
/** /**
* ixgb_setup_tx_resources - allocate Tx resources (Descriptors). * ixgb_setup_tx_resources - allocate Tx resources (Descriptors)
* @param adapter board private structure * @adapter: board private structure
* *
* Return 0 on success, negative on failure * Return 0 on success, negative on failure
**/ **/
static int static int ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
{ {
struct pci_dev *pdev = adapter->pdev;
struct ixgb_desc_ring *txdr = &adapter->tx_ring; struct ixgb_desc_ring *txdr = &adapter->tx_ring;
struct pci_dev *pdev = adapter->pdev;
int size; int size;
IXGB_DBG("ixgb_setup_tx_resources\n"); size = sizeof(struct ixgb_buffer) * txdr->count;
size = sizeof (struct ixgb_buffer) * txdr->count;
txdr->buffer_info = kmalloc(size, GFP_KERNEL); txdr->buffer_info = kmalloc(size, GFP_KERNEL);
if (!txdr->buffer_info) { if (!txdr->buffer_info) {
return -ENOMEM; return -ENOMEM;
...@@ -624,7 +588,8 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter) ...@@ -624,7 +588,8 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
memset(txdr->buffer_info, 0, size); memset(txdr->buffer_info, 0, size);
/* round up to nearest 4K */ /* round up to nearest 4K */
txdr->size = txdr->count * sizeof (struct ixgb_tx_desc);
txdr->size = txdr->count * sizeof(struct ixgb_tx_desc);
IXGB_ROUNDUP(txdr->size, 4096); IXGB_ROUNDUP(txdr->size, 4096);
txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma); txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
...@@ -634,10 +599,6 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter) ...@@ -634,10 +599,6 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
} }
memset(txdr->desc, 0, txdr->size); memset(txdr->desc, 0, txdr->size);
IXGB_DBG("txdr->desc <%p>\n", txdr->desc);
IXGB_DBG("txdr->next_to_use = <%p>\n", &txdr->next_to_use);
IXGB_DBG("txdr->next_to_clean = <%p>\n", &txdr->next_to_clean);
txdr->next_to_use = 0; txdr->next_to_use = 0;
txdr->next_to_clean = 0; txdr->next_to_clean = 0;
...@@ -646,21 +607,18 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter) ...@@ -646,21 +607,18 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
/** /**
* ixgb_configure_tx - Configure 82597 Transmit Unit after Reset. * ixgb_configure_tx - Configure 82597 Transmit Unit after Reset.
* @adapter board private structure * @adapter: board private structure
* *
* Configure the Tx unit of the MAC after a reset. * Configure the Tx unit of the MAC after a reset.
**/ **/
static void static void ixgb_configure_tx(struct ixgb_adapter *adapter)
ixgb_configure_tx(struct ixgb_adapter *adapter)
{ {
u32 tctl;
u32 tdlen = adapter->tx_ring.count * sizeof (struct ixgb_tx_desc);
uint64_t tdba = adapter->tx_ring.dma; uint64_t tdba = adapter->tx_ring.dma;
uint32_t tdlen = adapter->tx_ring.count * sizeof(struct ixgb_tx_desc);
uint32_t tctl;
struct ixgb_hw *hw = &adapter->hw; struct ixgb_hw *hw = &adapter->hw;
IXGB_DBG("ixgb_configure_tx\n");
/* Setup the Base and Length of the Tx Descriptor Ring /* Setup the Base and Length of the Tx Descriptor Ring
* tx_ring.dma can be either a 32 or 64 bit value * tx_ring.dma can be either a 32 or 64 bit value
*/ */
...@@ -694,27 +652,24 @@ ixgb_configure_tx(struct ixgb_adapter *adapter) ...@@ -694,27 +652,24 @@ ixgb_configure_tx(struct ixgb_adapter *adapter)
/* Setup Transmit Descriptor Settings for this adapter */ /* Setup Transmit Descriptor Settings for this adapter */
adapter->tx_cmd_type = adapter->tx_cmd_type =
IXGB_TX_DESC_TYPE | IXGB_TX_DESC_CMD_RS IXGB_TX_DESC_TYPE
| (adapter->tx_int_delay_enable ? IXGB_TX_DESC_CMD_IDE : 0); | (adapter->tx_int_delay_enable ? IXGB_TX_DESC_CMD_IDE : 0);
} }
/** /**
* ixgb_setup_rx_resources - allocate Rx resources (Descriptors). * ixgb_setup_rx_resources - allocate Rx resources (Descriptors)
* @param adapter board private structure * @adapter: board private structure
* *
* Returns 0 on success, negative on failure * Returns 0 on success, negative on failure
**/ **/
static int static int ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
{ {
struct pci_dev *pdev = adapter->pdev;
struct ixgb_desc_ring *rxdr = &adapter->rx_ring; struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
struct pci_dev *pdev = adapter->pdev;
int size; int size;
IXGB_DBG("ixgb_setup_rx_resources.\n"); size = sizeof(struct ixgb_buffer) * rxdr->count;
size = sizeof (struct ixgb_buffer) * rxdr->count;
rxdr->buffer_info = kmalloc(size, GFP_KERNEL); rxdr->buffer_info = kmalloc(size, GFP_KERNEL);
if (!rxdr->buffer_info) { if (!rxdr->buffer_info) {
return -ENOMEM; return -ENOMEM;
...@@ -722,42 +677,35 @@ ixgb_setup_rx_resources(struct ixgb_adapter *adapter) ...@@ -722,42 +677,35 @@ ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
memset(rxdr->buffer_info, 0, size); memset(rxdr->buffer_info, 0, size);
/* Round up to nearest 4K */ /* Round up to nearest 4K */
rxdr->size = rxdr->count * sizeof (struct ixgb_rx_desc);
rxdr->size = rxdr->count * sizeof(struct ixgb_rx_desc);
IXGB_ROUNDUP(rxdr->size, 4096); IXGB_ROUNDUP(rxdr->size, 4096);
rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma); rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
if (!rxdr->desc) { if (!rxdr->desc) {
IXGB_DBG("pci_alloc_consistent failed.\n");
kfree(rxdr->buffer_info); kfree(rxdr->buffer_info);
return -ENOMEM; return -ENOMEM;
} }
memset(rxdr->desc, 0, rxdr->size); memset(rxdr->desc, 0, rxdr->size);
IXGB_DBG("rxdr->desc <%p>\n", rxdr->desc);
IXGB_DBG("rxdr->next_to_use = <%p>\n", &rxdr->next_to_use);
IXGB_DBG("rxdr->next_to_clean = <%p>\n", &rxdr->next_to_clean);
rxdr->next_to_use = 0;
rxdr->next_to_clean = 0; rxdr->next_to_clean = 0;
rxdr->next_to_use = 0;
return 0; return 0;
} }
/** /**
* ixgb_setup_rctl - configure the receive control register. * ixgb_setup_rctl - configure the receive control register
* @param adapter Board private structure * @adapter: Board private structure
**/ **/
static void static void ixgb_setup_rctl(struct ixgb_adapter *adapter)
ixgb_setup_rctl(struct ixgb_adapter *adapter)
{ {
u32 rctl; uint32_t rctl;
rctl = IXGB_READ_REG(&adapter->hw, RCTL); rctl = IXGB_READ_REG(&adapter->hw, RCTL);
IXGB_DBG("ixgb_setup_rctl\n");
rctl &= ~(3 << IXGB_RCTL_MO_SHIFT); rctl &= ~(3 << IXGB_RCTL_MO_SHIFT);
rctl |= rctl |=
...@@ -782,35 +730,37 @@ ixgb_setup_rctl(struct ixgb_adapter *adapter) ...@@ -782,35 +730,37 @@ ixgb_setup_rctl(struct ixgb_adapter *adapter)
rctl |= IXGB_RCTL_BSIZE_16384; rctl |= IXGB_RCTL_BSIZE_16384;
break; break;
} }
IXGB_WRITE_REG(&adapter->hw, RCTL, rctl); IXGB_WRITE_REG(&adapter->hw, RCTL, rctl);
} }
/** /**
* ixgb_configure_rx - Configure 82597 Receive Unit after Reset. * ixgb_configure_rx - Configure 82597 Receive Unit after Reset.
* @param adapter board private structure * @adapter: board private structure
* *
* Configure the Rx unit of the MAC after a reset. * Configure the Rx unit of the MAC after a reset.
**/ **/
static void static void ixgb_configure_rx(struct ixgb_adapter *adapter)
ixgb_configure_rx(struct ixgb_adapter *adapter)
{ {
uint64_t rdba = adapter->rx_ring.dma; uint64_t rdba = adapter->rx_ring.dma;
u32 rdlen = adapter->rx_ring.count * sizeof (struct ixgb_rx_desc); uint32_t rdlen = adapter->rx_ring.count * sizeof(struct ixgb_rx_desc);
struct ixgb_hw *hw = &adapter->hw; struct ixgb_hw *hw = &adapter->hw;
u32 rctl; uint32_t rctl;
u32 rxcsum; uint32_t rxcsum;
uint32_t rxdctl;
IXGB_DBG("ixgb_configure_rx\n");
/* make sure receives are disabled while setting up the descriptors */ /* make sure receives are disabled while setting up the descriptors */
rctl = IXGB_READ_REG(hw, RCTL); rctl = IXGB_READ_REG(hw, RCTL);
IXGB_WRITE_REG(hw, RCTL, rctl & ~IXGB_RCTL_RXEN); IXGB_WRITE_REG(hw, RCTL, rctl & ~IXGB_RCTL_RXEN);
/* set the Receive Delay Timer Register */ /* set the Receive Delay Timer Register */
IXGB_WRITE_REG(hw, RDTR, adapter->rx_int_delay); IXGB_WRITE_REG(hw, RDTR, adapter->rx_int_delay);
/* Setup the Base and Length of the Rx Descriptor Ring */ /* Setup the Base and Length of the Rx Descriptor Ring */
IXGB_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL)); IXGB_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL));
IXGB_WRITE_REG(hw, RDBAH, (rdba >> 32)); IXGB_WRITE_REG(hw, RDBAH, (rdba >> 32));
...@@ -820,18 +770,15 @@ ixgb_configure_rx(struct ixgb_adapter *adapter) ...@@ -820,18 +770,15 @@ ixgb_configure_rx(struct ixgb_adapter *adapter)
IXGB_WRITE_REG(hw, RDH, 0); IXGB_WRITE_REG(hw, RDH, 0);
IXGB_WRITE_REG(hw, RDT, 0); IXGB_WRITE_REG(hw, RDT, 0);
{ /* burst 16 or burst when RXT0 */
u32 rxdctl; rxdctl = RXDCTL_WTHRESH_DEFAULT << IXGB_RXDCTL_WTHRESH_SHIFT
/* burst 16 or burst when RXT0 */ | RXDCTL_HTHRESH_DEFAULT << IXGB_RXDCTL_HTHRESH_SHIFT
rxdctl = RXDCTL_WTHRESH_DEFAULT << IXGB_RXDCTL_WTHRESH_SHIFT | RXDCTL_PTHRESH_DEFAULT << IXGB_RXDCTL_PTHRESH_SHIFT;
| RXDCTL_HTHRESH_DEFAULT << IXGB_RXDCTL_HTHRESH_SHIFT IXGB_WRITE_REG(hw, RXDCTL, rxdctl);
| RXDCTL_PTHRESH_DEFAULT << IXGB_RXDCTL_PTHRESH_SHIFT;
IXGB_WRITE_REG(hw, RXDCTL, rxdctl);
}
if (adapter->raidc) { if (adapter->raidc) {
u32 raidc; uint32_t raidc;
u8 poll_threshold; uint8_t poll_threshold;
/* Poll every rx_int_delay period, if RBD exists /* Poll every rx_int_delay period, if RBD exists
* Receive Backlog Detection is set to <threshold> * Receive Backlog Detection is set to <threshold>
...@@ -879,167 +826,180 @@ ixgb_configure_rx(struct ixgb_adapter *adapter) ...@@ -879,167 +826,180 @@ ixgb_configure_rx(struct ixgb_adapter *adapter)
} }
/** /**
* ixgb_free_tx_resources - Free Tx Resources. * ixgb_free_tx_resources - Free Tx Resources
* @param adapter board private structure * @adapter: board private structure
* *
* Free all transmit software resources * Free all transmit software resources
**/ **/
static void static void ixgb_free_tx_resources(struct ixgb_adapter *adapter)
ixgb_free_tx_resources(struct ixgb_adapter *adapter)
{ {
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
IXGB_DBG("ixgb_free_tx_resources\n");
ixgb_clean_tx_ring(adapter); ixgb_clean_tx_ring(adapter);
kfree(adapter->tx_ring.buffer_info); kfree(adapter->tx_ring.buffer_info);
adapter->tx_ring.buffer_info = NULL; adapter->tx_ring.buffer_info = NULL;
pci_free_consistent(pdev, adapter->tx_ring.size, adapter->tx_ring.desc, pci_free_consistent(pdev, adapter->tx_ring.size,
adapter->tx_ring.dma); adapter->tx_ring.desc, adapter->tx_ring.dma);
adapter->tx_ring.desc = NULL; adapter->tx_ring.desc = NULL;
} }
/** /**
* ixgb_clean_tx_ring - Free Tx Buffers. * ixgb_clean_tx_ring - Free Tx Buffers
* @param adapter board private structure * @adapter: board private structure
**/ **/
static void static void ixgb_clean_tx_ring(struct ixgb_adapter *adapter)
ixgb_clean_tx_ring(struct ixgb_adapter *adapter)
{ {
struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
struct ixgb_buffer *buffer_info;
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
unsigned long size; unsigned long size;
int i; unsigned int i;
IXGB_DBG("ixgb_clean_tx_ring\n");
/* Free all the Tx ring sk_buffs */ /* Free all the Tx ring sk_buffs */
for (i = 0; i < adapter->tx_ring.count; i++) { for (i = 0; i < tx_ring->count; i++) {
if (adapter->tx_ring.buffer_info[i].skb) { buffer_info = &tx_ring->buffer_info[i];
if (buffer_info->skb) {
pci_unmap_page(pdev, pci_unmap_page(pdev,
adapter->tx_ring.buffer_info[i].dma, buffer_info->dma,
adapter->tx_ring.buffer_info[i].length, buffer_info->length, PCI_DMA_TODEVICE);
PCI_DMA_TODEVICE);
dev_kfree_skb(adapter->tx_ring.buffer_info[i].skb); dev_kfree_skb(buffer_info->skb);
adapter->tx_ring.buffer_info[i].skb = NULL; buffer_info->skb = NULL;
} }
} }
size = sizeof (struct ixgb_buffer) * adapter->tx_ring.count; size = sizeof(struct ixgb_buffer) * tx_ring->count;
memset(adapter->tx_ring.buffer_info, 0, size); memset(tx_ring->buffer_info, 0, size);
/* Zero out the descriptor ring */ /* Zero out the descriptor ring */
memset(adapter->tx_ring.desc, 0, adapter->tx_ring.size); memset(tx_ring->desc, 0, tx_ring->size);
adapter->tx_ring.next_to_use = 0; tx_ring->next_to_use = 0;
adapter->tx_ring.next_to_clean = 0; tx_ring->next_to_clean = 0;
IXGB_WRITE_REG(&adapter->hw, TDH, 0); IXGB_WRITE_REG(&adapter->hw, TDH, 0);
IXGB_WRITE_REG(&adapter->hw, TDT, 0); IXGB_WRITE_REG(&adapter->hw, TDT, 0);
} }
/** /**
* ixgb_free_rx_resources - Free Rx Resources. * ixgb_free_rx_resources - Free Rx Resources
* @param adapter board private structure * @adapter: board private structure
* *
* Free all receive software resources * Free all receive software resources
**/ **/
static void static void ixgb_free_rx_resources(struct ixgb_adapter *adapter)
ixgb_free_rx_resources(struct ixgb_adapter *adapter)
{ {
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
IXGB_DBG("ixgb_free_rx_resources\n");
ixgb_clean_rx_ring(adapter); ixgb_clean_rx_ring(adapter);
kfree(adapter->rx_ring.buffer_info); kfree(rx_ring->buffer_info);
adapter->rx_ring.buffer_info = NULL; rx_ring->buffer_info = NULL;
pci_free_consistent(pdev, adapter->rx_ring.size, pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
adapter->rx_ring.desc, adapter->rx_ring.dma);
adapter->rx_ring.desc = NULL; rx_ring->desc = NULL;
} }
/** /**
* ixgb_clean_rx_ring - Free Rx Buffers. * ixgb_clean_rx_ring - Free Rx Buffers
* @param adapter board private structure * @adapter: board private structure
**/ **/
static void static void ixgb_clean_rx_ring(struct ixgb_adapter *adapter)
ixgb_clean_rx_ring(struct ixgb_adapter *adapter)
{ {
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
struct ixgb_buffer *buffer_info;
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
unsigned long size; unsigned long size;
int i; unsigned int i;
IXGB_DBG("ixgb_free_rx_ring\n");
/* Free all the Rx ring sk_buffs */ /* Free all the Rx ring sk_buffs */
for (i = 0; i < adapter->rx_ring.count; i++) { for (i = 0; i < rx_ring->count; i++) {
if (adapter->rx_ring.buffer_info[i].skb) { buffer_info = &rx_ring->buffer_info[i];
if (buffer_info->skb) {
pci_unmap_single(pdev, pci_unmap_single(pdev,
adapter->rx_ring.buffer_info[i].dma, buffer_info->dma,
adapter->rx_ring.buffer_info[i].length, buffer_info->length,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
dev_kfree_skb(adapter->rx_ring.buffer_info[i].skb); dev_kfree_skb(buffer_info->skb);
adapter->rx_ring.buffer_info[i].skb = NULL; buffer_info->skb = NULL;
} }
} }
size = sizeof (struct ixgb_buffer) * adapter->rx_ring.count; size = sizeof(struct ixgb_buffer) * rx_ring->count;
memset(adapter->rx_ring.buffer_info, 0, size); memset(rx_ring->buffer_info, 0, size);
/* Zero out the descriptor ring */ /* Zero out the descriptor ring */
memset(adapter->rx_ring.desc, 0, adapter->rx_ring.size); memset(rx_ring->desc, 0, rx_ring->size);
adapter->rx_ring.next_to_clean = 0; rx_ring->next_to_clean = 0;
adapter->rx_ring.next_to_use = 0; rx_ring->next_to_use = 0;
IXGB_WRITE_REG(&adapter->hw, RDH, 0); IXGB_WRITE_REG(&adapter->hw, RDH, 0);
IXGB_WRITE_REG(&adapter->hw, RDT, 0); IXGB_WRITE_REG(&adapter->hw, RDT, 0);
} }
/** /**
* ixgb_set_multi - Multicast and Promiscuous mode set. * ixgb_set_mac - Change the Ethernet Address of the NIC
* @param netdev network interface device structure * @netdev: network interface device structure
* @p: pointer to an address structure
*
* Returns 0 on success, negative on failure
**/
static int ixgb_set_mac(struct net_device *netdev, void *p)
{
struct ixgb_adapter *adapter = netdev->priv;
struct sockaddr *addr = p;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
ixgb_rar_set(&adapter->hw, addr->sa_data, 0);
return 0;
}
/**
* ixgb_set_multi - Multicast and Promiscuous mode set
* @netdev: network interface device structure
* *
* The set_multi entry point is called whenever the multicast address * The set_multi entry point is called whenever the multicast address
* list or the network interface flags are updated. This routine is * list or the network interface flags are updated. This routine is
* resposible for configuring the hardware for proper multicast, * responsible for configuring the hardware for proper multicast,
* promiscuous mode, and all-multi behavior. * promiscuous mode, and all-multi behavior.
**/ **/
void static void ixgb_set_multi(struct net_device *netdev)
ixgb_set_multi(struct net_device *netdev)
{ {
struct ixgb_adapter *adapter = netdev->priv; struct ixgb_adapter *adapter = netdev->priv;
struct ixgb_hw *hw = &adapter->hw; struct ixgb_hw *hw = &adapter->hw;
u32 rctl;
int i;
struct dev_mc_list *mc_ptr; struct dev_mc_list *mc_ptr;
uint32_t rctl;
IXGB_DBG("ixgb_set_multi <%x>\n", netdev->flags); int i;
/* Check for Promiscuous and All Multicast modes */ /* Check for Promiscuous and All Multicast modes */
rctl = IXGB_READ_REG(&adapter->hw, RCTL); rctl = IXGB_READ_REG(hw, RCTL);
if (netdev->flags & IFF_PROMISC) { if (netdev->flags & IFF_PROMISC) {
rctl |= (IXGB_RCTL_UPE | IXGB_RCTL_MPE); rctl |= (IXGB_RCTL_UPE | IXGB_RCTL_MPE);
...@@ -1054,7 +1014,7 @@ ixgb_set_multi(struct net_device *netdev) ...@@ -1054,7 +1014,7 @@ ixgb_set_multi(struct net_device *netdev)
rctl |= IXGB_RCTL_MPE; rctl |= IXGB_RCTL_MPE;
IXGB_WRITE_REG(hw, RCTL, rctl); IXGB_WRITE_REG(hw, RCTL, rctl);
} else { } else {
u8 mta[netdev->mc_count * IXGB_ETH_LENGTH_OF_ADDRESS]; uint8_t mta[netdev->mc_count * IXGB_ETH_LENGTH_OF_ADDRESS];
IXGB_WRITE_REG(hw, RCTL, rctl); IXGB_WRITE_REG(hw, RCTL, rctl);
...@@ -1068,15 +1028,16 @@ ixgb_set_multi(struct net_device *netdev) ...@@ -1068,15 +1028,16 @@ ixgb_set_multi(struct net_device *netdev)
} }
/** /**
* ixgb_watchdog - Timer Call-back. * ixgb_watchdog - Timer Call-back
* @param data pointer to adapter cast into an unsigned long * @data: pointer to netdev cast into an unsigned long
**/ **/
void static void ixgb_watchdog(unsigned long data)
ixgb_watchdog(unsigned long data)
{ {
struct ixgb_adapter *adapter = (struct ixgb_adapter *) data; struct ixgb_adapter *adapter = (struct ixgb_adapter *)data;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct ixgb_desc_ring *txdr = &adapter->tx_ring;
unsigned int i;
ixgb_check_for_link(&adapter->hw); ixgb_check_for_link(&adapter->hw);
...@@ -1096,36 +1057,35 @@ ixgb_watchdog(unsigned long data) ...@@ -1096,36 +1057,35 @@ ixgb_watchdog(unsigned long data)
} }
} else { } else {
if (netif_carrier_ok(netdev)) { if (netif_carrier_ok(netdev)) {
printk(KERN_INFO "ixgb: %s NIC Link is Down\n",
netdev->name);
adapter->link_speed = 0; adapter->link_speed = 0;
adapter->link_duplex = 0; adapter->link_duplex = 0;
printk(KERN_INFO
"ixgb: %s NIC Link is Down\n", netdev->name);
netif_carrier_off(netdev); netif_carrier_off(netdev);
netif_stop_queue(netdev); netif_stop_queue(netdev);
ixgb_down(adapter, FALSE);
ixgb_up(adapter);
} }
} }
ixgb_update_stats(adapter); ixgb_update_stats(adapter);
/* Early detection of hung controller */ if (!netif_carrier_ok(netdev)) {
{ if (IXGB_DESC_UNUSED(txdr) + 1 < txdr->count) {
struct ixgb_desc_ring *txdr = &adapter->tx_ring; /* We've lost link, so the controller stops DMA,
int i = txdr->next_to_clean; * but we've got queued Tx work that's never going
* to get done, so reset controller to flush Tx.
if (txdr->buffer_info[i].dma && * (Do the reset outside of interrupt context). */
time_after(jiffies, txdr->buffer_info[i].time_stamp + HZ) && schedule_work(&adapter->tx_timeout_task);
!(IXGB_READ_REG(&adapter->hw, STATUS) & IXGB_STATUS_TXOFF))
{
IXGB_DBG
("ixgb: %s Hung controller? Watchdog stopping queue\n",
netdev->name);
netif_stop_queue(netdev);
} }
} }
/* Early detection of hung controller */
i = txdr->next_to_clean;
if (txdr->buffer_info[i].dma &&
time_after(jiffies, txdr->buffer_info[i].time_stamp + HZ) &&
!(IXGB_READ_REG(&adapter->hw, STATUS) & IXGB_STATUS_TXOFF))
netif_stop_queue(netdev);
/* generate an interrupt to force clean up of any stragglers */ /* generate an interrupt to force clean up of any stragglers */
IXGB_WRITE_REG(&adapter->hw, ICS, IXGB_INT_TXDW); IXGB_WRITE_REG(&adapter->hw, ICS, IXGB_INT_TXDW);
...@@ -1133,24 +1093,18 @@ ixgb_watchdog(unsigned long data) ...@@ -1133,24 +1093,18 @@ ixgb_watchdog(unsigned long data)
mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
} }
#define IXGB_TX_FLAGS_CSUM 0x00000001 #define IXGB_TX_FLAGS_CSUM 0x00000001
#define IXGB_TX_FLAGS_VLAN 0x00000002 #define IXGB_TX_FLAGS_VLAN 0x00000002
#define IXGB_TX_FLAGS_TSO 0x00000004 #define IXGB_TX_FLAGS_TSO 0x00000004
/** Transmit Segmentation offload setup.
* ixgb_tso - (Large Send) setup where the initial descriptor is prepared
* @param adapter adapter specific information
* @param skb the skb we are trying to set up for segmentation
**/
static inline boolean_t static inline boolean_t
ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb)
{ {
#ifdef NETIF_F_TSO #ifdef NETIF_F_TSO
struct ixgb_context_desc *context_desc; struct ixgb_context_desc *context_desc;
int i; unsigned int i;
u8 ipcss, ipcso, tucss, tucso, hdr_len; uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
u16 ipcse, tucse, mss; uint16_t ipcse, tucse, mss;
if (likely(skb_shinfo(skb)->tso_size)) { if (likely(skb_shinfo(skb)->tso_size)) {
hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
...@@ -1161,10 +1115,10 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) ...@@ -1161,10 +1115,10 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb)
skb->nh.iph->daddr, skb->nh.iph->daddr,
0, IPPROTO_TCP, 0); 0, IPPROTO_TCP, 0);
ipcss = skb->nh.raw - skb->data; ipcss = skb->nh.raw - skb->data;
ipcso = (void *) &(skb->nh.iph->check) - (void *) skb->data; ipcso = (void *)&(skb->nh.iph->check) - (void *)skb->data;
ipcse = skb->h.raw - skb->data - 1; ipcse = skb->h.raw - skb->data - 1;
tucss = skb->h.raw - skb->data; tucss = skb->h.raw - skb->data;
tucso = (void *) &(skb->h.th->check) - (void *) skb->data; tucso = (void *)&(skb->h.th->check) - (void *)skb->data;
tucse = 0; tucse = 0;
i = adapter->tx_ring.next_to_use; i = adapter->tx_ring.next_to_use;
...@@ -1193,32 +1147,28 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) ...@@ -1193,32 +1147,28 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb)
| (skb->len - | (skb->len -
(hdr_len))); (hdr_len)));
i = (i + 1) % adapter->tx_ring.count; if (++i == adapter->tx_ring.count)
i = 0;
adapter->tx_ring.next_to_use = i; adapter->tx_ring.next_to_use = i;
return TRUE; return TRUE;
} }
#endif #endif
return FALSE; return FALSE;
} }
/**
* ixgb_tx_csum - prepare context descriptor for checksum offload.
*
* ixgb_tx_csum is called to prepare for checksumming a packet in hw.
* @param adapter board private structure
* @param skb structure containing data to send
**/
static inline boolean_t static inline boolean_t
ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb) ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb)
{ {
struct ixgb_context_desc *context_desc; struct ixgb_context_desc *context_desc;
int i; unsigned int i;
u8 css, cso; uint8_t css, cso;
if (likely(skb->ip_summed == CHECKSUM_HW)) { if (likely(skb->ip_summed == CHECKSUM_HW)) {
css = skb->h.raw - skb->data; css = skb->h.raw - skb->data;
cso = (skb->h.raw + skb->csum) - skb->data; cso = (skb->h.raw + skb->csum) - skb->data;
i = adapter->tx_ring.next_to_use; i = adapter->tx_ring.next_to_use;
context_desc = IXGB_CONTEXT_DESC(adapter->tx_ring, i); context_desc = IXGB_CONTEXT_DESC(adapter->tx_ring, i);
...@@ -1226,7 +1176,7 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb) ...@@ -1226,7 +1176,7 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb)
context_desc->tucso = cso; context_desc->tucso = cso;
context_desc->tucse = 0; context_desc->tucse = 0;
/* zero out any previously existing data in one instruction */ /* zero out any previously existing data in one instruction */
*(u32 *) & (context_desc->ipcss) = 0; *(uint32_t *) & (context_desc->ipcss) = 0;
context_desc->status = 0; context_desc->status = 0;
context_desc->hdr_len = 0; context_desc->hdr_len = 0;
context_desc->mss = 0; context_desc->mss = 0;
...@@ -1234,7 +1184,8 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb) ...@@ -1234,7 +1184,8 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb)
cpu_to_le32(IXGB_CONTEXT_DESC_TYPE cpu_to_le32(IXGB_CONTEXT_DESC_TYPE
| IXGB_TX_DESC_CMD_RS | IXGB_TX_DESC_CMD_IDE); | IXGB_TX_DESC_CMD_RS | IXGB_TX_DESC_CMD_IDE);
i = (i + 1) % adapter->tx_ring.count; if (++i == adapter->tx_ring.count)
i = 0;
adapter->tx_ring.next_to_use = i; adapter->tx_ring.next_to_use = i;
return TRUE; return TRUE;
...@@ -1243,43 +1194,41 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb) ...@@ -1243,43 +1194,41 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb)
return FALSE; return FALSE;
} }
/** #define IXGB_MAX_TXD_PWR 14
* ixgb_tx_map - private function for mapping send data to hardware addresses. #define IXGB_MAX_DATA_PER_TXD (1<<IXGB_MAX_TXD_PWR)
*
* @param adapter board private structure
* @param skb structure containing data to send
**/
static inline int static inline int
ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb) ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
unsigned int first)
{ {
struct ixgb_desc_ring *tx_ring = &adapter->tx_ring; struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
int len, offset, count, size, i; struct ixgb_buffer *buffer_info;
int len = skb->len;
unsigned int offset = 0, size, count = 0, i;
int f; unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
len = skb->len - skb->data_len; unsigned int f;
len -= skb->data_len;
i = (tx_ring->next_to_use + tx_ring->count - 1) % tx_ring->count; i = tx_ring->next_to_use;
count = 0;
offset = 0;
while (len) { while (len) {
i = (i + 1) % tx_ring->count; buffer_info = &tx_ring->buffer_info[i];
size = min(len, adapter->max_data_per_txd); size = min(len, IXGB_MAX_JUMBO_FRAME_SIZE);
tx_ring->buffer_info[i].length = size; buffer_info->length = size;
tx_ring->buffer_info[i].dma = buffer_info->dma =
pci_map_single(adapter->pdev, skb->data + offset, size, pci_map_single(adapter->pdev,
PCI_DMA_TODEVICE); skb->data + offset, size, PCI_DMA_TODEVICE);
buffer_info->time_stamp = jiffies;
tx_ring->buffer_info[i].time_stamp = jiffies;
len -= size; len -= size;
offset += size; offset += size;
count++; count++;
if (++i == tx_ring->count)
i = 0;
} }
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { for (f = 0; f < nr_frags; f++) {
struct skb_frag_struct *frag; struct skb_frag_struct *frag;
frag = &skb_shinfo(skb)->frags[f]; frag = &skb_shinfo(skb)->frags[f];
...@@ -1287,44 +1236,41 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb) ...@@ -1287,44 +1236,41 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb)
offset = 0; offset = 0;
while (len) { while (len) {
i = (i + 1) % tx_ring->count; buffer_info = &tx_ring->buffer_info[i];
size = min(len, adapter->max_data_per_txd); size = min(len, IXGB_MAX_JUMBO_FRAME_SIZE);
tx_ring->buffer_info[i].length = size; buffer_info->length = size;
tx_ring->buffer_info[i].dma = buffer_info->dma =
pci_map_page(adapter->pdev, frag->page, pci_map_page(adapter->pdev,
frag->page_offset + offset, size, frag->page,
PCI_DMA_TODEVICE); frag->page_offset + offset,
size, PCI_DMA_TODEVICE);
tx_ring->buffer_info[i].time_stamp = jiffies; buffer_info->time_stamp = jiffies;
len -= size; len -= size;
offset += size; offset += size;
count++; count++;
if (++i == tx_ring->count)
i = 0;
} }
} }
i = (i == 0) ? tx_ring->count - 1 : i - 1;
tx_ring->buffer_info[i].skb = skb; tx_ring->buffer_info[i].skb = skb;
tx_ring->buffer_info[first].next_to_watch = i;
return count; return count;
} }
/**
* ixgb_tx_queue - private function to start transmit on hardware.
*
* @param adapter board private structure
* @param count number of tx_descriptors to initialize (consume)
* @param vlan_id the vlan tag to insert (if necessary)
* @param tx_flags special handling for this transmit, if any
**/
static inline void static inline void
ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id, ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,
int tx_flags) int tx_flags)
{ {
struct ixgb_desc_ring *tx_ring = &adapter->tx_ring; struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
struct ixgb_tx_desc *tx_desc = NULL; struct ixgb_tx_desc *tx_desc = NULL;
u32 cmd_type_len = adapter->tx_cmd_type; struct ixgb_buffer *buffer_info;
u8 status = 0; uint32_t cmd_type_len = adapter->tx_cmd_type;
u8 popts = 0; uint8_t status = 0;
int i; uint8_t popts = 0;
unsigned int i;
if (tx_flags & IXGB_TX_FLAGS_TSO) { if (tx_flags & IXGB_TX_FLAGS_TSO) {
cmd_type_len |= IXGB_TX_DESC_CMD_TSE; cmd_type_len |= IXGB_TX_DESC_CMD_TSE;
...@@ -1341,18 +1287,21 @@ ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id, ...@@ -1341,18 +1287,21 @@ ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,
i = tx_ring->next_to_use; i = tx_ring->next_to_use;
while (count--) { while (count--) {
buffer_info = &tx_ring->buffer_info[i];
tx_desc = IXGB_TX_DESC(*tx_ring, i); tx_desc = IXGB_TX_DESC(*tx_ring, i);
tx_desc->buff_addr = cpu_to_le64(tx_ring->buffer_info[i].dma); tx_desc->buff_addr = cpu_to_le64(buffer_info->dma);
tx_desc->cmd_type_len = tx_desc->cmd_type_len =
cpu_to_le32(cmd_type_len | tx_ring->buffer_info[i].length); cpu_to_le32(cmd_type_len | buffer_info->length);
tx_desc->status = status; tx_desc->status = status;
tx_desc->popts = popts; tx_desc->popts = popts;
tx_desc->vlan = cpu_to_le16(vlan_id); tx_desc->vlan = cpu_to_le16(vlan_id);
i = (i + 1) % tx_ring->count; if (++i == tx_ring->count)
i = 0;
} }
tx_desc->cmd_type_len |= cpu_to_le32(IXGB_TX_DESC_CMD_EOP); tx_desc->cmd_type_len |= cpu_to_le32(IXGB_TX_DESC_CMD_EOP
| IXGB_TX_DESC_CMD_RS);
/* Force memory writes to complete before letting h/w /* Force memory writes to complete before letting h/w
* know there are new descriptors to fetch. (Only * know there are new descriptors to fetch. (Only
...@@ -1364,95 +1313,70 @@ ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id, ...@@ -1364,95 +1313,70 @@ ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,
IXGB_WRITE_REG(&adapter->hw, TDT, i); IXGB_WRITE_REG(&adapter->hw, TDT, i);
} }
#define TXD_USE_COUNT(S, X) (((S) / (X)) + (((S) % (X)) ? 1 : 0)) /* Tx Descriptors needed, worst case */
#define TXD_USE_COUNT(S) (((S) >> IXGB_MAX_TXD_PWR) + \
(((S) & (IXGB_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
#define DESC_NEEDED TXD_USE_COUNT(IXGB_MAX_DATA_PER_TXD) + \
MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1
/** static int ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
* ixgb_xmit_frame - hard_start_xmit linked function, transmit entry point.
*
* ixgb_xmit_frame is called to send an skb on the wire.
* @param skb contains data to send
* @param netdev network interface device structure
**/
static int
ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{ {
struct ixgb_adapter *adapter = netdev->priv; struct ixgb_adapter *adapter = netdev->priv;
unsigned int first;
unsigned int tx_flags = 0;
unsigned long flags;
int vlan_id = 0; int vlan_id = 0;
int tx_flags = 0, count;
int f;
count =
TXD_USE_COUNT(skb->len - skb->data_len, adapter->max_data_per_txd);
if (count == 0) { if (skb->len <= 0) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return 0; return 0;
} }
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) spin_lock_irqsave(&adapter->tx_lock, flags);
count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size, if (unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED)) {
adapter->max_data_per_txd);
#ifdef NETIF_F_TSO
if ((skb_shinfo(skb)->tso_size) || (skb->ip_summed == CHECKSUM_HW))
count++;
#else
if (skb->ip_summed == CHECKSUM_HW)
count++;
#endif
if (unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < count)) {
netif_stop_queue(netdev); netif_stop_queue(netdev);
spin_unlock_irqrestore(&adapter->tx_lock, flags);
return 1; return 1;
} }
spin_unlock_irqrestore(&adapter->tx_lock, flags);
if (adapter->vlgrp && vlan_tx_tag_present(skb)) { if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
tx_flags |= IXGB_TX_FLAGS_VLAN; tx_flags |= IXGB_TX_FLAGS_VLAN;
vlan_id = vlan_tx_tag_get(skb); vlan_id = vlan_tx_tag_get(skb);
} }
first = adapter->tx_ring.next_to_use;
if (ixgb_tso(adapter, skb)) if (ixgb_tso(adapter, skb))
tx_flags |= IXGB_TX_FLAGS_TSO; tx_flags |= IXGB_TX_FLAGS_TSO;
else if (ixgb_tx_csum(adapter, skb)) else if (ixgb_tx_csum(adapter, skb))
tx_flags |= IXGB_TX_FLAGS_CSUM; tx_flags |= IXGB_TX_FLAGS_CSUM;
count = ixgb_tx_map(adapter, skb); ixgb_tx_queue(adapter, ixgb_tx_map(adapter, skb, first), vlan_id,
ixgb_tx_queue(adapter, count, vlan_id, tx_flags); tx_flags);
netdev->trans_start = jiffies; netdev->trans_start = jiffies;
return 0; return 0;
} }
/** /**
* ixgb_tx_timeout - Respond to a Tx Hang by resetting the adapter. * ixgb_tx_timeout - Respond to a Tx Hang
* @param netdev network interface device structure * @netdev: network interface device structure
**/ **/
static void static void ixgb_tx_timeout(struct net_device *netdev)
ixgb_tx_timeout(struct net_device *netdev)
{ {
struct ixgb_adapter *adapter = netdev->priv; struct ixgb_adapter *adapter = netdev->priv;
IXGB_DBG("ixgb_tx_timeout\n");
/* Do the reset outside of interrupt context */ /* Do the reset outside of interrupt context */
schedule_work(&adapter->tx_timeout_task); schedule_work(&adapter->tx_timeout_task);
} }
/** static void ixgb_tx_timeout_task(struct net_device *netdev)
* ixgb_tx_timeout_task - worker function to reset hardware and dump queues.
* This function is pointed to by adapter->tx_timeout_task
*
* @param netdev network interface device structure
**/
static void
ixgb_tx_timeout_task(struct net_device *netdev)
{ {
struct ixgb_adapter *adapter = netdev->priv; struct ixgb_adapter *adapter = netdev->priv;
IXGB_DBG("ixgb_tx_timeout_task\n");
netif_device_detach(netdev); netif_device_detach(netdev);
ixgb_down(adapter, TRUE); ixgb_down(adapter, TRUE);
ixgb_up(adapter); ixgb_up(adapter);
...@@ -1460,15 +1384,14 @@ ixgb_tx_timeout_task(struct net_device *netdev) ...@@ -1460,15 +1384,14 @@ ixgb_tx_timeout_task(struct net_device *netdev)
} }
/** /**
* ixgb_get_stats - Get System Network Statistics. * ixgb_get_stats - Get System Network Statistics
* @param netdev network interface device structure * @netdev: network interface device structure
* *
* Returns the address of the device statistics structure. * Returns the address of the device statistics structure.
* The statistics are actually updated from the timer callback. * The statistics are actually updated from the timer callback.
**/ **/
static struct net_device_stats * static struct net_device_stats *ixgb_get_stats(struct net_device *netdev)
ixgb_get_stats(struct net_device *netdev)
{ {
struct ixgb_adapter *adapter = netdev->priv; struct ixgb_adapter *adapter = netdev->priv;
...@@ -1476,22 +1399,19 @@ ixgb_get_stats(struct net_device *netdev) ...@@ -1476,22 +1399,19 @@ ixgb_get_stats(struct net_device *netdev)
} }
/** /**
* ixgb_change_mtu - Change the Maximum Transfer Unit. * ixgb_change_mtu - Change the Maximum Transfer Unit
* @param netdev network interface device structure * @netdev: network interface device structure
* @param new_mtu new value for maximum frame size * @new_mtu: new value for maximum frame size
* *
* Returns 0 on success, negative on failure * Returns 0 on success, negative on failure
**/ **/
static int static int ixgb_change_mtu(struct net_device *netdev, int new_mtu)
ixgb_change_mtu(struct net_device *netdev, int new_mtu)
{ {
struct ixgb_adapter *adapter = netdev->priv; struct ixgb_adapter *adapter = netdev->priv;
u32 old_mtu = adapter->rx_buffer_len; uint32_t old_mtu = adapter->rx_buffer_len;
int max_frame = new_mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; int max_frame = new_mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
IXGB_DBG("ixgb_change_mtu\n");
if ((max_frame < IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH) if ((max_frame < IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH)
|| (max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) { || (max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) {
IXGB_ERR("Invalid MTU setting\n"); IXGB_ERR("Invalid MTU setting\n");
...@@ -1513,69 +1433,23 @@ ixgb_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -1513,69 +1433,23 @@ ixgb_change_mtu(struct net_device *netdev, int new_mtu)
adapter->rx_buffer_len = IXGB_RXBUFFER_16384; adapter->rx_buffer_len = IXGB_RXBUFFER_16384;
} }
netdev->mtu = new_mtu;
if (old_mtu != adapter->rx_buffer_len && netif_running(netdev)) { if (old_mtu != adapter->rx_buffer_len && netif_running(netdev)) {
ixgb_down(adapter, TRUE); ixgb_down(adapter, TRUE);
ixgb_up(adapter); ixgb_up(adapter);
} }
if (adapter->hw.max_frame_size != max_frame) {
struct ixgb_hw *hw = &adapter->hw;
adapter->hw.max_frame_size = max_frame;
IXGB_WRITE_REG(hw, MFS, hw->max_frame_size << IXGB_MFS_SHIFT);
if (hw->max_frame_size >
IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH) {
u32 ctrl0 = IXGB_READ_REG(hw, CTRL0);
if (!(ctrl0 & IXGB_CTRL0_JFE)) {
ctrl0 |= IXGB_CTRL0_JFE;
IXGB_WRITE_REG(hw, CTRL0, ctrl0);
}
}
printk(KERN_ERR "%s: ixgb_change_mtu MFS is set to <%x>\n",
adapter->netdev->name,
(IXGB_READ_REG(hw, MFS) >> IXGB_MFS_SHIFT));
}
netdev->mtu = new_mtu;
return 0;
}
/**
* ixgb_set_mac - Change the Ethernet Address of the NIC.
* @param netdev network interface device structure
* @param p pointer to an address structure
*
* Returns 0 on success, negative on failure
**/
static int
ixgb_set_mac(struct net_device *netdev, void *p)
{
struct ixgb_adapter *adapter = netdev->priv;
struct sockaddr *addr = (struct sockaddr *) p;
IXGB_DBG("ixgb_set_mac\n");
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
ixgb_rar_set(&adapter->hw, addr->sa_data, 0);
return 0; return 0;
} }
/** /**
* ixgb_update_stats - Update the board statistics counters. * ixgb_update_stats - Update the board statistics counters.
* @param adapter board private structure * @adapter: board private structure
**/ **/
static void static void ixgb_update_stats(struct ixgb_adapter *adapter)
ixgb_update_stats(struct ixgb_adapter *adapter)
{ {
adapter->stats.tprl += IXGB_READ_REG(&adapter->hw, TPRL); adapter->stats.tprl += IXGB_READ_REG(&adapter->hw, TPRL);
adapter->stats.tprh += IXGB_READ_REG(&adapter->hw, TPRH); adapter->stats.tprh += IXGB_READ_REG(&adapter->hw, TPRH);
...@@ -1678,309 +1552,241 @@ ixgb_update_stats(struct ixgb_adapter *adapter) ...@@ -1678,309 +1552,241 @@ ixgb_update_stats(struct ixgb_adapter *adapter)
/** /**
* ixgb_irq_disable - Mask off interrupt generation on the NIC * ixgb_irq_disable - Mask off interrupt generation on the NIC
* @param adapter board private structure * @adapter: board private structure
**/ **/
static inline void static inline void ixgb_irq_disable(struct ixgb_adapter *adapter)
ixgb_irq_disable(struct ixgb_adapter *adapter)
{ {
IXGB_DBG("ixgb_irq_disable\n");
atomic_inc(&adapter->irq_sem); atomic_inc(&adapter->irq_sem);
IXGB_WRITE_REG(&adapter->hw, IMC, ~0); IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
synchronize_irq(adapter->netdev->irq); IXGB_WRITE_FLUSH(&adapter->hw);
synchronize_irq(adapter->pdev->irq);
} }
/** /**
* ixgb_irq_enable - Enable default interrupt generation settings. * ixgb_irq_enable - Enable default interrupt generation settings
* @param adapter board private structure * @adapter: board private structure
**/ **/
static inline void static inline void ixgb_irq_enable(struct ixgb_adapter *adapter)
ixgb_irq_enable(struct ixgb_adapter *adapter)
{ {
IXGB_DBG("ixgb_irq_enable\n");
if (atomic_dec_and_test(&adapter->irq_sem)) { if (atomic_dec_and_test(&adapter->irq_sem)) {
IXGB_WRITE_REG(&adapter->hw, IMS, IXGB_WRITE_REG(&adapter->hw, IMS,
IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | IXGB_INT_TXDW | IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | IXGB_INT_TXDW |
IXGB_INT_RXO | IXGB_INT_LSC); IXGB_INT_RXO | IXGB_INT_LSC);
IXGB_WRITE_FLUSH(&adapter->hw);
} }
} }
#define IXGB_MAX_INTR 10 #define IXGB_MAX_INTR 10
/** /**
* ixgb_intr - Interrupt Handler. * ixgb_intr - Interrupt Handler
* @param irq interrupt number * @irq: interrupt number
* @param data pointer to a network interface device structure * @data: pointer to a network interface device structure
* @param regs CPU registers structure * @pt_regs: CPU registers structure
**/ **/
static irqreturn_t static irqreturn_t ixgb_intr(int irq, void *data, struct pt_regs *regs)
ixgb_intr(int irq, void *data, struct pt_regs *regs)
{ {
struct net_device *netdev = (struct net_device *) data; struct net_device *netdev = data;
struct ixgb_adapter *adapter = netdev->priv; struct ixgb_adapter *adapter = netdev->priv;
#ifdef CONFIG_IXGB_NAPI
if (netif_rx_schedule_prep(netdev)) {
ixgb_irq_disable(adapter);
__netif_rx_schedule(netdev);
}
return IRQ_HANDLED; /* FIXME: check for shared interrupts */
#else
struct ixgb_hw *hw = &adapter->hw; struct ixgb_hw *hw = &adapter->hw;
u32 icr; uint32_t icr = IXGB_READ_REG(&adapter->hw, ICR);
uint i = IXGB_MAX_INTR; #ifndef CONFIG_IXGB_NAPI
boolean_t rxdmt0 = FALSE; unsigned int i;
int handled = 0; #endif
while (i && (icr = IXGB_READ_REG(hw, ICR))) {
handled = 1;
if (icr & IXGB_INT_RXDMT0) if (unlikely(!icr))
rxdmt0 = TRUE; return IRQ_NONE; /* Not our interrupt */
if (unlikely(icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC))) { if (unlikely(icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC))) {
mod_timer(&adapter->watchdog_timer, jiffies); mod_timer(&adapter->watchdog_timer, jiffies);
} }
#ifdef CONFIG_IXGB_NAPI
if (netif_rx_schedule_prep(netdev)) {
/* adapter->generate_int = 0; */ /* Disable interrupts and register for poll. The flush
ixgb_clean_rx_irq(adapter); of the posted write is intentionally left out.
ixgb_clean_tx_irq(adapter); */
i--; atomic_inc(&adapter->irq_sem);
IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
__netif_rx_schedule(netdev);
} }
#else
for (i = 0; i < IXGB_MAX_INTR; i++)
if (!ixgb_clean_rx_irq(adapter) & !ixgb_clean_tx_irq(adapter))
break;
/* if RAIDC:EN == 1 and ICR:RXDMT0 == 1, we need to /* if RAIDC:EN == 1 and ICR:RXDMT0 == 1, we need to
* set IMS:RXDMT0 to 1 to restart the RBD timer (POLL) * set IMS:RXDMT0 to 1 to restart the RBD timer (POLL)
*/ */
if (rxdmt0 && adapter->raidc) { if ((icr & IXGB_INT_RXDMT0) && adapter->raidc) {
/* ready the timer by writing the clear reg */ /* ready the timer by writing the clear reg */
IXGB_WRITE_REG(hw, IMC, IXGB_INT_RXDMT0); IXGB_WRITE_REG(hw, IMC, IXGB_INT_RXDMT0);
/* now restart it, h/w will decide if its necessary */ /* now restart it, h/w will decide if its necessary */
IXGB_WRITE_REG(hw, IMS, IXGB_INT_RXDMT0); IXGB_WRITE_REG(hw, IMS, IXGB_INT_RXDMT0);
} }
#endif
return IRQ_RETVAL(handled); return IRQ_HANDLED;
#endif // NAPI else
} }
#ifdef CONFIG_IXGB_NAPI #ifdef CONFIG_IXGB_NAPI
static int /**
ixgb_process_intr(struct net_device *netdev) * ixgb_clean - NAPI Rx polling callback
* @adapter: board private structure
**/
static int ixgb_clean(struct net_device *netdev, int *budget)
{ {
struct ixgb_adapter *adapter = netdev->priv; struct ixgb_adapter *adapter = netdev->priv;
u32 icr; int work_to_do = min(*budget, netdev->quota);
int i = IXGB_MAX_INTR; int work_done = 0;
int hasReceived = 0;
while (i && (icr = IXGB_READ_REG(&adapter->hw, ICR))) { ixgb_clean_tx_irq(adapter);
if (icr & IXGB_INT_RXT0) ixgb_clean_rx_irq(adapter, &work_done, work_to_do);
hasReceived = 1;
if (!(icr & ~(IXGB_INT_RXT0))) *budget -= work_done;
break; netdev->quota -= work_done;
if (icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC)) { if (work_done < work_to_do || !netif_running(netdev)) {
mod_timer(&adapter->watchdog_timer, jiffies); netif_rx_complete(netdev);
} /* RAIDC will be automatically restarted by irq_enable */
ixgb_irq_enable(adapter);
ixgb_clean_tx_irq(adapter);
i--;
} }
return hasReceived; return (work_done >= work_to_do);
} }
#endif #endif
/** /**
* ixgb_clean_tx_irq - Reclaim resources after transmit completes. * ixgb_clean_tx_irq - Reclaim resources after transmit completes
* @param adapter board private structure * @adapter: board private structure
**/ **/
static void static boolean_t ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
{ {
struct ixgb_desc_ring *tx_ring = &adapter->tx_ring; struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
int i = adapter->tx_ring.next_to_clean; struct ixgb_tx_desc *tx_desc, *eop_desc;
struct ixgb_tx_desc *tx_desc = IXGB_TX_DESC(*tx_ring, i); struct ixgb_buffer *buffer_info;
while ((tx_desc->status & IXGB_TX_DESC_STATUS_DD)) { unsigned int i, eop;
if (tx_desc->popts boolean_t cleaned = FALSE;
& (IXGB_TX_DESC_POPTS_TXSM | IXGB_TX_DESC_POPTS_IXSM))
adapter->hw_csum_tx_good++;
if (tx_ring->buffer_info[i].dma) {
pci_unmap_page(pdev, tx_ring->buffer_info[i].dma,
tx_ring->buffer_info[i].length,
PCI_DMA_TODEVICE);
tx_ring->buffer_info[i].dma = 0;
}
if (tx_ring->buffer_info[i].skb) {
dev_kfree_skb_any(tx_ring->buffer_info[i].skb);
tx_ring->buffer_info[i].skb = NULL;
}
*(u32 *) & (tx_desc->status) = 0;
i = (i + 1) % tx_ring->count;
tx_desc = IXGB_TX_DESC(*tx_ring, i);
}
tx_ring->next_to_clean = i;
if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev) &&
(IXGB_DESC_UNUSED(tx_ring) > IXGB_TX_QUEUE_WAKE)) {
netif_wake_queue(netdev);
}
}
#ifdef CONFIG_IXGB_NAPI
static int
ixgb_poll(struct net_device *netdev, int *budget)
{
struct ixgb_adapter *adapter = netdev->priv;
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
struct pci_dev *pdev = adapter->pdev;
struct ixgb_rx_desc *rx_desc;
struct sk_buff *skb;
u32 length;
int i;
int received = 0;
int rx_work_limit = *budget;
if (rx_work_limit > netdev->quota)
rx_work_limit = netdev->quota;
ixgb_process_intr(netdev);
i = rx_ring->next_to_clean;
rx_desc = IXGB_RX_DESC(*rx_ring, i);
while ((rx_desc->status & IXGB_RX_DESC_STATUS_DD)) {
if (--rx_work_limit < 0)
goto not_done;
pci_unmap_single(pdev,
rx_ring->buffer_info[i].dma,
rx_ring->buffer_info[i].length,
PCI_DMA_FROMDEVICE);
skb = rx_ring->buffer_info[i].skb; i = tx_ring->next_to_clean;
length = le16_to_cpu(rx_desc->length); eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = IXGB_TX_DESC(*tx_ring, eop);
if (!(rx_desc->status & IXGB_RX_DESC_STATUS_EOP)) { while (eop_desc->status & cpu_to_le32(IXGB_TX_DESC_STATUS_DD)) {
/* All receives must fit into a single buffer */ for (cleaned = FALSE; !cleaned;) {
tx_desc = IXGB_TX_DESC(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
IXGB_DBG("Receive packet consumed multiple buffers\n"); if (tx_desc->popts
& (IXGB_TX_DESC_POPTS_TXSM |
IXGB_TX_DESC_POPTS_IXSM))
adapter->hw_csum_tx_good++;
dev_kfree_skb_irq(skb); if (buffer_info->dma) {
rx_desc->status = 0;
rx_ring->buffer_info[i].skb = NULL;
i = (i + 1) % rx_ring->count; pci_unmap_page(pdev,
buffer_info->dma,
buffer_info->length,
PCI_DMA_TODEVICE);
rx_desc = IXGB_RX_DESC(*rx_ring, i); buffer_info->dma = 0;
continue; }
}
if (rx_desc->
errors & (IXGB_RX_DESC_ERRORS_CE | IXGB_RX_DESC_ERRORS_SE |
IXGB_RX_DESC_ERRORS_P | IXGB_RX_DESC_ERRORS_RXE))
{
IXGB_DBG("Receive Errors Reported by Hardware-%x.\n", if (buffer_info->skb) {
rx_desc->errors);
dev_kfree_skb_irq(skb); dev_kfree_skb_any(buffer_info->skb);
rx_desc->status = 0;
rx_ring->buffer_info[i].skb = NULL;
i = (i + 1) % rx_ring->count;
rx_desc = IXGB_RX_DESC(*rx_ring, i);
continue;
}
/* Good Receive */ buffer_info->skb = NULL;
skb_put(skb, length); }
/* Receive Checksum Offload */ *(uint32_t *) & (tx_desc->status) = 0;
ixgb_rx_checksum(adapter, rx_desc, skb);
skb->protocol = eth_type_trans(skb, netdev); cleaned = (i == eop);
if (adapter->vlgrp if (++i == tx_ring->count)
&& (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) { i = 0;
vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
(rx_desc-> special & IXGB_RX_DESC_SPECIAL_VLAN_MASK));
} else {
netif_receive_skb(skb);
} }
netdev->last_rx = jiffies;
rx_desc->status = 0;
rx_ring->buffer_info[i].skb = NULL;
i = (i + 1) % rx_ring->count; eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = IXGB_TX_DESC(*tx_ring, eop);
rx_desc = IXGB_RX_DESC(*rx_ring, i);
received++;
} }
if (!received) tx_ring->next_to_clean = i;
received = 1;
ixgb_alloc_rx_buffers(adapter);
rx_ring->next_to_clean = i;
netdev->quota -= received;
*budget -= received;
netif_rx_complete(netdev);
/* NOTE: RAIDC will be automatically restarted by this enable */
ixgb_irq_enable(adapter);
return 0;
not_done: spin_lock(&adapter->tx_lock);
if (cleaned && netif_queue_stopped(netdev) && netif_carrier_ok(netdev)
&& (IXGB_DESC_UNUSED(tx_ring) > IXGB_TX_QUEUE_WAKE)) {
ixgb_alloc_rx_buffers(adapter); netif_wake_queue(netdev);
}
rx_ring->next_to_clean = i; spin_unlock(&adapter->tx_lock);
netdev->quota -= received;
*budget -= received;
return 1; return cleaned;
} }
#else
/** /**
* ixgb_clean_rx_irq - Send received data up the network stack. * ixgb_clean_rx_irq - Send received data up the network stack,
* @param adapter board private structure * @adapter: board private structure
**/ **/
static void static boolean_t
#ifdef CONFIG_IXGB_NAPI
ixgb_clean_rx_irq(struct ixgb_adapter *adapter, int *work_done, int work_to_do)
#else
ixgb_clean_rx_irq(struct ixgb_adapter *adapter) ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
#endif
{ {
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring; struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
struct ixgb_rx_desc *rx_desc; struct ixgb_rx_desc *rx_desc, *next_rxd;
struct sk_buff *skb; struct ixgb_buffer *buffer_info, *next_buffer, *next2_buffer;
u32 length; struct sk_buff *skb, *next_skb;
int i; uint32_t length;
unsigned int i, j;
boolean_t cleaned = FALSE;
i = rx_ring->next_to_clean; i = rx_ring->next_to_clean;
rx_desc = IXGB_RX_DESC(*rx_ring, i); rx_desc = IXGB_RX_DESC(*rx_ring, i);
buffer_info = &rx_ring->buffer_info[i];
while (rx_desc->status & IXGB_RX_DESC_STATUS_DD) {
skb = buffer_info->skb;
prefetch(skb->data);
while ((rx_desc->status & IXGB_RX_DESC_STATUS_DD)) { if (++i == rx_ring->count)
pci_unmap_single(pdev, rx_ring->buffer_info[i].dma, i = 0;
rx_ring->buffer_info[i].length, next_rxd = IXGB_RX_DESC(*rx_ring, i);
PCI_DMA_FROMDEVICE); prefetch(next_rxd);
if ((j = i + 1) == rx_ring->count)
j = 0;
next2_buffer = &rx_ring->buffer_info[j];
prefetch(next2_buffer);
next_buffer = &rx_ring->buffer_info[i];
next_skb = next_buffer->skb;
prefetch(next_skb);
#ifdef CONFIG_IXGB_NAPI
if (*work_done >= work_to_do)
break;
(*work_done)++;
#endif
cleaned = TRUE;
pci_unmap_single(pdev,
buffer_info->dma,
buffer_info->length, PCI_DMA_FROMDEVICE);
skb = rx_ring->buffer_info[i].skb;
length = le16_to_cpu(rx_desc->length); length = le16_to_cpu(rx_desc->length);
if (unlikely(!(rx_desc->status & IXGB_RX_DESC_STATUS_EOP))) { if (unlikely(!(rx_desc->status & IXGB_RX_DESC_STATUS_EOP))) {
...@@ -1992,9 +1798,10 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) ...@@ -1992,9 +1798,10 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
dev_kfree_skb_irq(skb); dev_kfree_skb_irq(skb);
rx_desc->status = 0; rx_desc->status = 0;
rx_ring->buffer_info[i].skb = NULL; buffer_info->skb = NULL;
i = (i + 1) % rx_ring->count;
rx_desc = IXGB_RX_DESC(*rx_ring, i); rx_desc = next_rxd;
buffer_info = next_buffer;
continue; continue;
} }
...@@ -2003,14 +1810,12 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) ...@@ -2003,14 +1810,12 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
| IXGB_RX_DESC_ERRORS_P | | IXGB_RX_DESC_ERRORS_P |
IXGB_RX_DESC_ERRORS_RXE))) { IXGB_RX_DESC_ERRORS_RXE))) {
IXGB_DBG("Receive Errors Reported by Hardware-%x.\n",
rx_desc->errors);
dev_kfree_skb_irq(skb); dev_kfree_skb_irq(skb);
rx_desc->status = 0; rx_desc->status = 0;
rx_ring->buffer_info[i].skb = NULL; buffer_info->skb = NULL;
i = (i + 1) % rx_ring->count;
rx_desc = IXGB_RX_DESC(*rx_ring, i); rx_desc = next_rxd;
buffer_info = next_buffer;
continue; continue;
} }
...@@ -2021,53 +1826,63 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) ...@@ -2021,53 +1826,63 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
ixgb_rx_checksum(adapter, rx_desc, skb); ixgb_rx_checksum(adapter, rx_desc, skb);
skb->protocol = eth_type_trans(skb, netdev); skb->protocol = eth_type_trans(skb, netdev);
#ifdef CONFIG_IXGB_NAPI
if (adapter->vlgrp
&& (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
le16_to_cpu(rx_desc->
special &
IXGB_RX_DESC_SPECIAL_VLAN_MASK));
} else {
netif_receive_skb(skb);
}
#else /* CONFIG_IXGB_NAPI */
if (adapter->vlgrp if (adapter->vlgrp
&& (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) { && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
vlan_hwaccel_rx(skb, adapter->vlgrp, vlan_hwaccel_rx(skb, adapter->vlgrp,
(rx_desc-> le16_to_cpu(rx_desc->
special & special &
IXGB_RX_DESC_SPECIAL_VLAN_MASK)); IXGB_RX_DESC_SPECIAL_VLAN_MASK));
} else { } else {
netif_rx(skb); netif_rx(skb);
} }
#endif /* CONFIG_IXGB_NAPI */
netdev->last_rx = jiffies; netdev->last_rx = jiffies;
rx_desc->status = 0; rx_desc->status = 0;
buffer_info->skb = NULL;
rx_ring->buffer_info[i].skb = NULL; rx_desc = next_rxd;
i = (i + 1) % rx_ring->count; buffer_info = next_buffer;
}
rx_desc = IXGB_RX_DESC(*rx_ring, i);
} /* while */
rx_ring->next_to_clean = i; rx_ring->next_to_clean = i;
ixgb_alloc_rx_buffers(adapter); ixgb_alloc_rx_buffers(adapter);
return cleaned;
} }
#endif
/** /**
* ixgb_alloc_rx_buffers - Replace used receive buffers. * ixgb_alloc_rx_buffers - Replace used receive buffers
* @param adapter address of board private structure * @adapter: address of board private structure
**/ **/
static void static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
{ {
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring; struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
struct ixgb_rx_desc *rx_desc; struct ixgb_rx_desc *rx_desc;
struct ixgb_buffer *buffer_info;
struct sk_buff *skb; struct sk_buff *skb;
int reserve_len; int reserve_len = 2;
int i; unsigned int i;
int num_group_tail_writes; int num_group_tail_writes;
long cleancount; long cleancount;
reserve_len = 2;
i = rx_ring->next_to_use; i = rx_ring->next_to_use;
buffer_info = &rx_ring->buffer_info[i];
cleancount = IXGB_DESC_UNUSED(rx_ring); cleancount = IXGB_DESC_UNUSED(rx_ring);
/* lessen this to 4 if we're /* lessen this to 4 if we're
...@@ -2080,14 +1895,13 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter) ...@@ -2080,14 +1895,13 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
while (--cleancount > 0) { while (--cleancount > 0) {
rx_desc = IXGB_RX_DESC(*rx_ring, i); rx_desc = IXGB_RX_DESC(*rx_ring, i);
/* allocate a new one */
skb = dev_alloc_skb(adapter->rx_buffer_len + reserve_len); skb = dev_alloc_skb(adapter->rx_buffer_len + reserve_len);
if (unlikely(!skb)) { if (unlikely(!skb)) {
/* better luck next time around */ /* Better luck next round */
IXGB_DBG("Could not allocate SKB\n");
break; break;
} }
/* Make buffer alignment 2 beyond a 16 byte boundary /* Make buffer alignment 2 beyond a 16 byte boundary
* this will result in a 16 byte aligned IP header after * this will result in a 16 byte aligned IP header after
* the 14 byte MAC header is removed * the 14 byte MAC header is removed
...@@ -2096,24 +1910,28 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter) ...@@ -2096,24 +1910,28 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
skb->dev = netdev; skb->dev = netdev;
rx_ring->buffer_info[i].skb = skb; buffer_info->skb = skb;
rx_ring->buffer_info[i].length = adapter->rx_buffer_len; buffer_info->length = adapter->rx_buffer_len;
rx_ring->buffer_info[i].dma = buffer_info->dma =
pci_map_single(pdev, skb->data, adapter->rx_buffer_len, pci_map_single(pdev,
PCI_DMA_FROMDEVICE); skb->data,
adapter->rx_buffer_len, PCI_DMA_FROMDEVICE);
rx_desc->buff_addr = cpu_to_le64(rx_ring->buffer_info[i].dma); rx_desc->buff_addr = cpu_to_le64(buffer_info->dma);
if (!(i % num_group_tail_writes)) { if ((i & ~(num_group_tail_writes - 1)) == i) {
/* Force memory writes to complete before letting h/w /* Force memory writes to complete before letting h/w
* know there are new descriptors to fetch. (Only * know there are new descriptors to fetch. (Only
* applicable for weak-ordered memory model archs, * applicable for weak-ordered memory model archs,
* such as IA-64). */ * such as IA-64). */
wmb(); wmb();
/* move tail */
IXGB_WRITE_REG(&adapter->hw, RDT, i); IXGB_WRITE_REG(&adapter->hw, RDT, i);
} }
i = (i + 1) % rx_ring->count;
if (++i == rx_ring->count)
i = 0;
buffer_info = &rx_ring->buffer_info[i];
} }
rx_ring->next_to_use = i; rx_ring->next_to_use = i;
...@@ -2126,14 +1944,11 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter) ...@@ -2126,14 +1944,11 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
* @param cmd ioctl command to execute * @param cmd ioctl command to execute
**/ **/
int static int ixgb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
ixgb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{ {
switch (cmd) { switch (cmd) {
case SIOCETHTOOL: case SIOCETHTOOL:
return ixgb_ethtool_ioctl(netdev, ifr); return ixgb_ethtool_ioctl(netdev, ifr);
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -2141,18 +1956,50 @@ ixgb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) ...@@ -2141,18 +1956,50 @@ ixgb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
return 0; return 0;
} }
/**
* ixgb_rx_checksum - Receive Checksum Offload for 82597.
* @adapter: board private structure
* @rx_desc: receive descriptor
* @sk_buff: socket buffer with received data
**/
static inline void
ixgb_rx_checksum(struct ixgb_adapter *adapter,
struct ixgb_rx_desc *rx_desc, struct sk_buff *skb)
{
/* Ignore Checksum bit is set OR
* TCP Checksum has not been calculated
*/
if ((rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) ||
(!(rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS))) {
skb->ip_summed = CHECKSUM_NONE;
return;
}
/* At this point we know the hardware did the TCP checksum */
/* now look at the TCP checksum error bit */
if (rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE) {
/* let the stack verify checksum errors */
skb->ip_summed = CHECKSUM_NONE;
adapter->hw_csum_rx_error++;
} else {
/* TCP checksum is good */
skb->ip_summed = CHECKSUM_UNNECESSARY;
adapter->hw_csum_rx_good++;
}
}
/** /**
* ixgb_vlan_rx_register - enables or disables vlan tagging/stripping. * ixgb_vlan_rx_register - enables or disables vlan tagging/stripping.
* *
* @param netdev network interface device structure * @param netdev network interface device structure
* @param grp indicates to enable or disable tagging/stripping * @param grp indicates to enable or disable tagging/stripping
**/ **/
static void static void
ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
{ {
struct ixgb_adapter *adapter = netdev->priv; struct ixgb_adapter *adapter = netdev->priv;
u32 ctrl, rctl; uint32_t ctrl, rctl;
ixgb_irq_disable(adapter); ixgb_irq_disable(adapter);
adapter->vlgrp = grp; adapter->vlgrp = grp;
...@@ -2164,17 +2011,20 @@ ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) ...@@ -2164,17 +2011,20 @@ ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl); IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl);
/* enable VLAN receive filtering */ /* enable VLAN receive filtering */
rctl = IXGB_READ_REG(&adapter->hw, RCTL); rctl = IXGB_READ_REG(&adapter->hw, RCTL);
rctl |= IXGB_RCTL_VFE; rctl |= IXGB_RCTL_VFE;
rctl &= ~IXGB_RCTL_CFIEN; rctl &= ~IXGB_RCTL_CFIEN;
IXGB_WRITE_REG(&adapter->hw, RCTL, rctl); IXGB_WRITE_REG(&adapter->hw, RCTL, rctl);
} else { } else {
/* disable VLAN tag insert/strip */ /* disable VLAN tag insert/strip */
ctrl = IXGB_READ_REG(&adapter->hw, CTRL0); ctrl = IXGB_READ_REG(&adapter->hw, CTRL0);
ctrl &= ~IXGB_CTRL0_VME; ctrl &= ~IXGB_CTRL0_VME;
IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl); IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl);
/* disable VLAN filtering */ /* disable VLAN filtering */
rctl = IXGB_READ_REG(&adapter->hw, RCTL); rctl = IXGB_READ_REG(&adapter->hw, RCTL);
rctl &= ~IXGB_RCTL_VFE; rctl &= ~IXGB_RCTL_VFE;
IXGB_WRITE_REG(&adapter->hw, RCTL, rctl); IXGB_WRITE_REG(&adapter->hw, RCTL, rctl);
...@@ -2183,17 +2033,10 @@ ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) ...@@ -2183,17 +2033,10 @@ ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
ixgb_irq_enable(adapter); ixgb_irq_enable(adapter);
} }
/** static void ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
* ixgb_vlan_rx_add_vid - adds a vlan id to be tagged/stripped in packet data.
* @param netdev network interface device structure
* @param vid the vlan to be added
**/
static void
ixgb_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
{ {
struct ixgb_adapter *adapter = netdev->priv; struct ixgb_adapter *adapter = netdev->priv;
u32 vfta, index; uint32_t vfta, index;
/* add VID to filter table */ /* add VID to filter table */
...@@ -2203,17 +2046,10 @@ ixgb_vlan_rx_add_vid(struct net_device *netdev, u16 vid) ...@@ -2203,17 +2046,10 @@ ixgb_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
ixgb_write_vfta(&adapter->hw, index, vfta); ixgb_write_vfta(&adapter->hw, index, vfta);
} }
/** static void ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
* ixgb_vlan_rx_kill_vid - removes a vlan id from tag/strip tables.
* @param netdev network interface device structure
* @param vid the vlan to be deleted
**/
static void
ixgb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
{ {
struct ixgb_adapter *adapter = netdev->priv; struct ixgb_adapter *adapter = netdev->priv;
u32 vfta, index; uint32_t vfta, index;
ixgb_irq_disable(adapter); ixgb_irq_disable(adapter);
...@@ -2230,17 +2066,12 @@ ixgb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) ...@@ -2230,17 +2066,12 @@ ixgb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
ixgb_write_vfta(&adapter->hw, index, vfta); ixgb_write_vfta(&adapter->hw, index, vfta);
} }
/** static void ixgb_restore_vlan(struct ixgb_adapter *adapter)
* ixgb_restore_vlan - restores vlan settings after adapter reset.
* @param adapter the address of the board private structure
**/
static void
ixgb_restore_vlan(struct ixgb_adapter *adapter)
{ {
ixgb_vlan_rx_register(adapter->netdev, adapter->vlgrp); ixgb_vlan_rx_register(adapter->netdev, adapter->vlgrp);
if (adapter->vlgrp) { if (adapter->vlgrp) {
u16 vid; uint16_t vid;
for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
if (!adapter->vlgrp->vlan_devices[vid]) if (!adapter->vlgrp->vlan_devices[vid])
continue; continue;
...@@ -2249,55 +2080,6 @@ ixgb_restore_vlan(struct ixgb_adapter *adapter) ...@@ -2249,55 +2080,6 @@ ixgb_restore_vlan(struct ixgb_adapter *adapter)
} }
} }
/**
* ixgb_rx_checksum - Receive Checksum Offload for 82597.
* @param adapter board private structure
* @param rx_desc receive descriptor
* @param skb socket buffer with received data
**/
static inline void
ixgb_rx_checksum(struct ixgb_adapter *adapter,
struct ixgb_rx_desc *rx_desc, struct sk_buff *skb)
{
/* Ignore Checksum bit is set OR
* TCP Checksum has not been calculated
*/
if ((rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) ||
(!(rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS))) {
skb->ip_summed = CHECKSUM_NONE;
return;
}
/* At this point we know the hardware did the TCP checksum
* now look at the TCP checksum error bit
*/
if (rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE) {
/* let the stack verify checksum errors */
skb->ip_summed = CHECKSUM_NONE;
adapter->hw_csum_rx_error++;
} else {
/* TCP checksum is good */
skb->ip_summed = CHECKSUM_UNNECESSARY;
adapter->hw_csum_rx_good++;
}
}
/**
* ixgb_write_pci_cfg - write PCI configuration space.
* @param hw board specific data structure
* @param reg PCI configuration space register to write to
* @param value Value to be written to reg
**/
void
ixgb_write_pci_cfg(struct ixgb_hw *hw, u32 reg, u16 * value)
{
struct ixgb_adapter *adapter = (struct ixgb_adapter *) hw->back;
pci_write_config_word(adapter->pdev, reg, *value);
}
/** /**
* ixgb_notify_reboot - handles OS notification of reboot event. * ixgb_notify_reboot - handles OS notification of reboot event.
* @param nb notifier block, unused * @param nb notifier block, unused
...@@ -2313,7 +2095,7 @@ ixgb_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) ...@@ -2313,7 +2095,7 @@ ixgb_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
case SYS_DOWN: case SYS_DOWN:
case SYS_HALT: case SYS_HALT:
case SYS_POWER_OFF: case SYS_POWER_OFF:
while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) {
if (pci_dev_driver(pdev) == &ixgb_driver) if (pci_dev_driver(pdev) == &ixgb_driver)
ixgb_suspend(pdev, 3); ixgb_suspend(pdev, 3);
} }
...@@ -2326,8 +2108,7 @@ ixgb_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) ...@@ -2326,8 +2108,7 @@ ixgb_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
* @param pdev pci driver structure used for passing to * @param pdev pci driver structure used for passing to
* @param state power state to enter * @param state power state to enter
**/ **/
static int static int ixgb_suspend(struct pci_dev *pdev, uint32_t state)
ixgb_suspend(struct pci_dev *pdev, u32 state)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgb_adapter *adapter = netdev->priv; struct ixgb_adapter *adapter = netdev->priv;
...@@ -2346,4 +2127,20 @@ ixgb_suspend(struct pci_dev *pdev, u32 state) ...@@ -2346,4 +2127,20 @@ ixgb_suspend(struct pci_dev *pdev, u32 state)
return 0; return 0;
} }
#ifdef CONFIG_NET_POLL_CONTROLLER
/*
* Polling 'interrupt' - used by things like netconsole to send skbs
* without having to re-enable interrupts. It's not called while
* the interrupt routine is executing.
*/
static void ixgb_netpoll(struct net_device *dev)
{
struct ixgb_adapter *adapter = dev->priv;
disable_irq(adapter->pdev->irq);
ixgb_intr(adapter->pdev->irq, dev, NULL);
enable_irq(adapter->pdev->irq);
}
#endif
/* ixgb_main.c */ /* ixgb_main.c */
/******************************************************************************* /*******************************************************************************
Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
...@@ -23,14 +23,15 @@ ...@@ -23,14 +23,15 @@
Contact Information: Contact Information:
Linux NICS <linux.nics@intel.com> Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/ *******************************************************************************/
/* glue for the OS independant part of ixgb /* glue for the OS independent part of ixgb
* includes register access macros * includes register access macros
*/ */
#ifndef IXGB_OSDEP_H #ifndef _IXGB_OSDEP_H_
#define IXGB_OSDEP_H #define _IXGB_OSDEP_H_
#include <linux/types.h> #include <linux/types.h>
#include <linux/pci.h> #include <linux/pci.h>
...@@ -39,35 +40,42 @@ ...@@ -39,35 +40,42 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/sched.h> #include <linux/sched.h>
/* FIXME: eliminate me */ #ifndef msec_delay
#define msec_delay(x) do { if(in_interrupt()) { \ #define msec_delay(x) do { if(in_interrupt()) { \
mdelay(x); \ /* Don't mdelay in interrupt context! */ \
BUG(); \
} else { \ } else { \
set_current_state(TASK_UNINTERRUPTIBLE); \ set_current_state(TASK_UNINTERRUPTIBLE); \
schedule_timeout((x * HZ)/1000); \ schedule_timeout((x * HZ)/1000 + 2); \
} } while(0) } } while(0)
#endif
#define PCI_COMMAND_REGISTER PCI_COMMAND
#define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE
typedef enum { typedef enum {
#undef FALSE
FALSE = 0, FALSE = 0,
#undef TRUE
TRUE = 1 TRUE = 1
} boolean_t; } boolean_t;
#undef ASSERT
#define ASSERT(x) if(!(x)) BUG()
#define MSGOUT(S, A, B) printk(KERN_DEBUG S "\n", A, B) #define MSGOUT(S, A, B) printk(KERN_DEBUG S "\n", A, B)
#if DBG #if DBG
#define ASSERT(x) if(!(x)) BUG() #define DEBUGOUT(S) printk(KERN_DEBUG S "\n")
#define DEBUGOUT(S) printk(KERN_ERR S "\n") #define DEBUGOUT1(S, A...) printk(KERN_DEBUG S "\n", A)
#define DEBUGOUT1(S, A...) printk(KERN_ERR S "\n", A)
#else #else
#define ASSERT(x)
#define DEBUGOUT(S) #define DEBUGOUT(S)
#define DEBUGOUT1(S, A...) #define DEBUGOUT1(S, A...)
#endif #endif
#define DEBUGFUNC(F) DEBUGOUT(F)
#define DEBUGOUT2 DEBUGOUT1 #define DEBUGOUT2 DEBUGOUT1
#define DEBUGOUT3 DEBUGOUT1 #define DEBUGOUT3 DEBUGOUT2
#define DEBUGOUT7 DEBUGOUT1 #define DEBUGOUT7 DEBUGOUT3
#define DEBUGFUNC(F) DEBUGOUT(F)
#define IXGB_WRITE_REG(a, reg, value) ( \ #define IXGB_WRITE_REG(a, reg, value) ( \
writel((value), ((a)->hw_addr + IXGB_##reg))) writel((value), ((a)->hw_addr + IXGB_##reg)))
...@@ -81,4 +89,8 @@ typedef enum { ...@@ -81,4 +89,8 @@ typedef enum {
#define IXGB_READ_REG_ARRAY(a, reg, offset) ( \ #define IXGB_READ_REG_ARRAY(a, reg, offset) ( \
readl((a)->hw_addr + IXGB_##reg + ((offset) << 2))) readl((a)->hw_addr + IXGB_##reg + ((offset) << 2)))
#endif /* IXGB_OSDEP_H */ #define IXGB_WRITE_FLUSH(a) IXGB_READ_REG(a, STATUS)
#define IXGB_MEMCPY memcpy
#endif /* _IXGB_OSDEP_H_ */
/******************************************************************************* /*******************************************************************************
Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
Contact Information: Contact Information:
Linux NICS <linux.nics@intel.com> Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/ *******************************************************************************/
#include "ixgb.h" #include "ixgb.h"
...@@ -31,11 +32,11 @@ ...@@ -31,11 +32,11 @@
* maximum number of ports that the driver can manage. * maximum number of ports that the driver can manage.
*/ */
#define IXGB_MAX_NIC 8 #define IXGB_MAX_NIC 8
#define OPTION_UNSET -1 #define OPTION_UNSET -1
#define OPTION_DISABLED 0 #define OPTION_DISABLED 0
#define OPTION_ENABLED 1 #define OPTION_ENABLED 1
/* Module Parameters are always initialized to -1, so that the driver /* Module Parameters are always initialized to -1, so that the driver
* can tell the difference between no user specified value or the * can tell the difference between no user specified value or the
...@@ -102,17 +103,14 @@ IXGB_PARAM(FlowControl, "Flow Control setting"); ...@@ -102,17 +103,14 @@ IXGB_PARAM(FlowControl, "Flow Control setting");
IXGB_PARAM(XsumRX, "Disable or enable Receive Checksum offload"); IXGB_PARAM(XsumRX, "Disable or enable Receive Checksum offload");
/* XsumTX - Transmit Checksum Offload Enable/Disable /* Transmit Interrupt Delay in units of 0.8192 microseconds
* *
* Valid Range: 0, 1 * Valid Range: 0-65535
* - 0 - disables all checksum offload
* - 1 - enables transmmit IP/TCP/UDP checksum offload
* on 82597 based NICs
* *
* Default Value: 1 * Default Value: 32
*/ */
IXGB_PARAM(XsumTX, "Disable or enable Transmit Checksum offload"); IXGB_PARAM(TxIntDelay, "Transmit Interrupt Delay");
/* Receive Interrupt Delay in units of 0.8192 microseconds /* Receive Interrupt Delay in units of 0.8192 microseconds
* *
...@@ -163,15 +161,6 @@ IXGB_PARAM(RxFCLowThresh, "Receive Flow Control Low Threshold"); ...@@ -163,15 +161,6 @@ IXGB_PARAM(RxFCLowThresh, "Receive Flow Control Low Threshold");
IXGB_PARAM(FCReqTimeout, "Flow Control Request Timeout"); IXGB_PARAM(FCReqTimeout, "Flow Control Request Timeout");
/* Transmit Interrupt Delay in units of 0.8192 microseconds
*
* Valid Range: 0-65535
*
* Default Value: 32
*/
IXGB_PARAM(TxIntDelay, "Transmit Interrupt Delay");
/* Interrupt Delay Enable /* Interrupt Delay Enable
* *
* Valid Range: 0, 1 * Valid Range: 0, 1
...@@ -187,25 +176,31 @@ IXGB_PARAM(IntDelayEnable, "Transmit Interrupt Delay Enable"); ...@@ -187,25 +176,31 @@ IXGB_PARAM(IntDelayEnable, "Transmit Interrupt Delay Enable");
#define DEFAULT_TXD 256 #define DEFAULT_TXD 256
#define MAX_TXD 4096 #define MAX_TXD 4096
#define MIN_TXD 64 #define MIN_TXD 64
#define DEFAULT_RXD 1024 #define DEFAULT_RXD 1024
#define MAX_RXD 4096 #define MAX_RXD 4096
#define MIN_RXD 64 #define MIN_RXD 64
#define DEFAULT_TIDV 32
#define MAX_TIDV 0xFFFF #define DEFAULT_TIDV 32
#define MAX_TIDV 0xFFFF
#define MIN_TIDV 0 #define MIN_TIDV 0
#define DEFAULT_RDTR 72
#define DEFAULT_RDTR 72
#define MAX_RDTR 0xFFFF #define MAX_RDTR 0xFFFF
#define MIN_RDTR 0 #define MIN_RDTR 0
#define XSUMRX_DEFAULT OPTION_ENABLED #define XSUMRX_DEFAULT OPTION_ENABLED
#define FLOW_CONTROL_FULL ixgb_fc_full #define FLOW_CONTROL_FULL ixgb_fc_full
#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL #define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
#define DEFAULT_FCRTL 0x28000 #define DEFAULT_FCRTL 0x28000
#define DEFAULT_FCRTH 0x30000 #define DEFAULT_FCRTH 0x30000
#define MIN_FCRTL 0 #define MIN_FCRTL 0
#define MAX_FCRTL 0x3FFE8 #define MAX_FCRTL 0x3FFE8
#define MIN_FCRTH 8 #define MIN_FCRTH 8
#define MAX_FCRTH 0x3FFF0 #define MAX_FCRTH 0x3FFF0
#define DEFAULT_FCPAUSE 0x100
#define DEFAULT_FCPAUSE 0x100 /* this may be too long */
#define MIN_FCPAUSE 1 #define MIN_FCPAUSE 1
#define MAX_FCPAUSE 0xffff #define MAX_FCPAUSE 0xffff
...@@ -215,11 +210,11 @@ struct ixgb_option { ...@@ -215,11 +210,11 @@ struct ixgb_option {
char *err; char *err;
int def; int def;
union { union {
struct { /* range option information */ struct { /* range_option info */
int min; int min;
int max; int max;
} r; } r;
struct { /* list option information */ struct { /* list_option info */
int nr; int nr;
struct ixgb_opt_list { struct ixgb_opt_list {
int i; int i;
...@@ -229,8 +224,7 @@ struct ixgb_option { ...@@ -229,8 +224,7 @@ struct ixgb_option {
} arg; } arg;
}; };
static int __devinit static int __devinit ixgb_validate_option(int *value, struct ixgb_option *opt)
ixgb_validate_option(int *value, struct ixgb_option *opt)
{ {
if (*value == OPTION_UNSET) { if (*value == OPTION_UNSET) {
*value = opt->def; *value = opt->def;
...@@ -254,8 +248,7 @@ ixgb_validate_option(int *value, struct ixgb_option *opt) ...@@ -254,8 +248,7 @@ ixgb_validate_option(int *value, struct ixgb_option *opt)
return 0; return 0;
} }
break; break;
case list_option: case list_option:{
{
int i; int i;
struct ixgb_opt_list *ent; struct ixgb_opt_list *ent;
...@@ -263,7 +256,7 @@ ixgb_validate_option(int *value, struct ixgb_option *opt) ...@@ -263,7 +256,7 @@ ixgb_validate_option(int *value, struct ixgb_option *opt)
ent = &opt->arg.l.p[i]; ent = &opt->arg.l.p[i];
if (*value == ent->i) { if (*value == ent->i) {
if (ent->str[0] != '\0') if (ent->str[0] != '\0')
printk(KERN_INFO "%s", printk(KERN_INFO "%s\n",
ent->str); ent->str);
return 0; return 0;
} }
...@@ -274,8 +267,8 @@ ixgb_validate_option(int *value, struct ixgb_option *opt) ...@@ -274,8 +267,8 @@ ixgb_validate_option(int *value, struct ixgb_option *opt)
BUG(); BUG();
} }
printk(KERN_INFO "Invalid %s specified (%i) %s\n", opt->name, *value, printk(KERN_INFO "Invalid %s specified (%i) %s\n",
opt->err); opt->name, *value, opt->err);
*value = opt->def; *value = opt->def;
return -1; return -1;
} }
...@@ -286,24 +279,20 @@ ixgb_validate_option(int *value, struct ixgb_option *opt) ...@@ -286,24 +279,20 @@ ixgb_validate_option(int *value, struct ixgb_option *opt)
* ixgb_check_options - Range Checking for Command Line Parameters * ixgb_check_options - Range Checking for Command Line Parameters
* @adapter: board private structure * @adapter: board private structure
* *
* This routine checks all command line paramters for valid user * This routine checks all command line parameters for valid user
* input. If an invalid value is given, or if no user specified * input. If an invalid value is given, or if no user specified
* value exists, a default value is used. The final value is stored * value exists, a default value is used. The final value is stored
* in a variable in the adapter structure. * in a variable in the adapter structure.
**/ **/
void __devinit void __devinit ixgb_check_options(struct ixgb_adapter *adapter)
ixgb_check_options(struct ixgb_adapter *adapter)
{ {
int board = adapter->bd_number; int bd = adapter->bd_number;
if (bd >= IXGB_MAX_NIC) {
IXGB_DBG("ixgb_check_options\n"); printk(KERN_NOTICE
"Warning: no configuration for board #%i\n", bd);
if (board >= IXGB_MAX_NIC) {
printk(KERN_NOTICE "Warning: no configuration for board #%i\n",
board);
printk(KERN_NOTICE "Using defaults for all values\n"); printk(KERN_NOTICE "Using defaults for all values\n");
board = IXGB_MAX_NIC; bd = IXGB_MAX_NIC;
} }
{ /* Transmit Descriptor Count */ { /* Transmit Descriptor Count */
...@@ -312,63 +301,50 @@ ixgb_check_options(struct ixgb_adapter *adapter) ...@@ -312,63 +301,50 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.name = "Transmit Descriptors", .name = "Transmit Descriptors",
.err = "using default of " __MODULE_STRING(DEFAULT_TXD), .err = "using default of " __MODULE_STRING(DEFAULT_TXD),
.def = DEFAULT_TXD, .def = DEFAULT_TXD,
.arg = {.r = {.min = MIN_TXD,.max = MAX_TXD}} .arg = {.r = {.min = MIN_TXD,
.max = MAX_TXD}}
}; };
struct ixgb_desc_ring *tx_ring = &adapter->tx_ring; struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
tx_ring->count = TxDescriptors[board]; tx_ring->count = TxDescriptors[bd];
ixgb_validate_option(&tx_ring->count, &opt); ixgb_validate_option(&tx_ring->count, &opt);
IXGB_ROUNDUP(tx_ring->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE); IXGB_ROUNDUP(tx_ring->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
} }
{ /* Receive Descriptor Count */ { /* Receive Descriptor Count */
struct ixgb_option opt = { struct ixgb_option opt = {
.type = range_option, .type = range_option,
.name = "Receive Descriptors", .name = "Receive Descriptors",
.err = "using default of " __MODULE_STRING(DEFAULT_RXD), .err = "using default of " __MODULE_STRING(DEFAULT_RXD),
.def = DEFAULT_RXD, .def = DEFAULT_RXD,
.arg = {.r = {.min = MIN_RXD,.max = MAX_RXD}} .arg = {.r = {.min = MIN_RXD,
.max = MAX_RXD}}
}; };
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring; struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
rx_ring->count = RxDescriptors[board]; rx_ring->count = RxDescriptors[bd];
ixgb_validate_option(&rx_ring->count, &opt); ixgb_validate_option(&rx_ring->count, &opt);
IXGB_ROUNDUP(rx_ring->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE); IXGB_ROUNDUP(rx_ring->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
} }
{ /* Receive Checksum Offload Enable */ { /* Receive Checksum Offload Enable */
struct ixgb_option opt = { struct ixgb_option opt = {
.type = enable_option, .type = enable_option,
.name = "Receive Checksum Offload", .name = "Receive Checksum Offload",
.err = "defaulting to Enabled", .err = "defaulting to Enabled",
.def = OPTION_ENABLED, .def = OPTION_ENABLED
}; };
int rx_csum = XsumRX[board];
int rx_csum = XsumRX[bd];
ixgb_validate_option(&rx_csum, &opt); ixgb_validate_option(&rx_csum, &opt);
adapter->rx_csum = rx_csum; adapter->rx_csum = rx_csum;
} }
{ /* Transmit Checksum Offload Enable */
struct ixgb_option opt = {
.type = enable_option,
.name = "Transmit Checksum Offload",
.err = "defaulting to Enabled",
.def = OPTION_ENABLED,
};
int tx_csum = XsumTX[board];
ixgb_validate_option(&tx_csum, &opt);
adapter->tx_csum = tx_csum;
}
{ /* Flow Control */ { /* Flow Control */
struct ixgb_opt_list fc_list[] = {
{ixgb_fc_none, "Flow Control Disabled\n"}, struct ixgb_opt_list fc_list[] =
{ixgb_fc_rx_pause, "Flow Control Receive Only\n"}, { {ixgb_fc_none, "Flow Control Disabled"},
{ixgb_fc_tx_pause, "Flow Control Transmit Only\n"}, {ixgb_fc_rx_pause, "Flow Control Receive Only"},
{ixgb_fc_full, "Flow Control Enabled\n"}, {ixgb_fc_tx_pause, "Flow Control Transmit Only"},
{ixgb_fc_default, "Flow Control Hardware Default\n"} {ixgb_fc_full, "Flow Control Enabled"},
{ixgb_fc_default, "Flow Control Hardware Default"}
}; };
struct ixgb_option opt = { struct ixgb_option opt = {
...@@ -376,60 +352,63 @@ ixgb_check_options(struct ixgb_adapter *adapter) ...@@ -376,60 +352,63 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.name = "Flow Control", .name = "Flow Control",
.err = "reading default settings from EEPROM", .err = "reading default settings from EEPROM",
.def = ixgb_fc_full, .def = ixgb_fc_full,
.arg = {.l = {.nr = LIST_LEN(fc_list),.p = fc_list}} .arg = {.l = {.nr = LIST_LEN(fc_list),
.p = fc_list}}
}; };
int fc = FlowControl[board]; int fc = FlowControl[bd];
ixgb_validate_option(&fc, &opt); ixgb_validate_option(&fc, &opt);
adapter->hw.fc.type = fc; adapter->hw.fc.type = fc;
} }
{ /* Receive Flow Control High Threshold */ { /* Receive Flow Control High Threshold */
struct ixgb_option fcrth = { struct ixgb_option opt = {
.type = range_option, .type = range_option,
.name = "Rx Flow Control High Threshold", .name = "Rx Flow Control High Threshold",
.err = .err =
"using default of " __MODULE_STRING(DEFAULT_FCRTH), "using default of " __MODULE_STRING(DEFAULT_FCRTH),
.def = DEFAULT_FCRTH, .def = DEFAULT_FCRTH,
.arg = {.r = {.min = MIN_FCRTH,.max = MAX_FCRTH}} .arg = {.r = {.min = MIN_FCRTH,
.max = MAX_FCRTH}}
}; };
adapter->hw.fc.high_water = RxFCHighThresh[board]; adapter->hw.fc.high_water = RxFCHighThresh[bd];
ixgb_validate_option(&adapter->hw.fc.high_water, &fcrth); ixgb_validate_option(&adapter->hw.fc.high_water, &opt);
if (!(adapter->hw.fc.type & ixgb_fc_rx_pause)) if (!(adapter->hw.fc.type & ixgb_fc_rx_pause))
printk(KERN_INFO printk(KERN_INFO
"Ignoring RxFCHighThresh when no RxFC\n"); "Ignoring RxFCHighThresh when no RxFC\n");
} }
{ /* Receive Flow Control Low Threshold */ { /* Receive Flow Control Low Threshold */
struct ixgb_option fcrtl = { struct ixgb_option opt = {
.type = range_option, .type = range_option,
.name = "Rx Flow Control Low Threshold", .name = "Rx Flow Control Low Threshold",
.err = .err =
"using default of " __MODULE_STRING(DEFAULT_FCRTL), "using default of " __MODULE_STRING(DEFAULT_FCRTL),
.def = DEFAULT_FCRTL, .def = DEFAULT_FCRTL,
.arg = {.r = {.min = MIN_FCRTL,.max = MAX_FCRTL}} .arg = {.r = {.min = MIN_FCRTL,
.max = MAX_FCRTL}}
}; };
adapter->hw.fc.low_water = RxFCLowThresh[board]; adapter->hw.fc.low_water = RxFCLowThresh[bd];
ixgb_validate_option(&adapter->hw.fc.low_water, &fcrtl); ixgb_validate_option(&adapter->hw.fc.low_water, &opt);
if (!(adapter->hw.fc.type & ixgb_fc_rx_pause)) if (!(adapter->hw.fc.type & ixgb_fc_rx_pause))
printk(KERN_INFO printk(KERN_INFO
"Ignoring RxFCLowThresh when no RxFC\n"); "Ignoring RxFCLowThresh when no RxFC\n");
} }
{ /* Flow Control Pause Time Request */ { /* Flow Control Pause Time Request */
struct ixgb_option fcpap = { struct ixgb_option opt = {
.type = range_option, .type = range_option,
.name = "Flow Control Pause Time Request", .name = "Flow Control Pause Time Request",
.err = .err =
"using default of " "using default of "
__MODULE_STRING(DEFAULT_FCPAUSE), __MODULE_STRING(DEFAULT_FCPAUSE),
.def = DEFAULT_FCPAUSE, .def = DEFAULT_FCPAUSE,
.arg = {.r = {.min = MIN_FCPAUSE,.max = MAX_FCPAUSE}} .arg = {.r = {.min = MIN_FCPAUSE,
.max = MAX_FCPAUSE}}
}; };
int pause_time = FCReqTimeout[board]; int pause_time = FCReqTimeout[bd];
ixgb_validate_option(&pause_time, &fcpap); ixgb_validate_option(&pause_time, &opt);
if (!(adapter->hw.fc.type & ixgb_fc_rx_pause)) if (!(adapter->hw.fc.type & ixgb_fc_rx_pause))
printk(KERN_INFO printk(KERN_INFO
"Ignoring FCReqTimeout when no RxFC\n"); "Ignoring FCReqTimeout when no RxFC\n");
...@@ -454,10 +433,11 @@ ixgb_check_options(struct ixgb_adapter *adapter) ...@@ -454,10 +433,11 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.err = .err =
"using default of " __MODULE_STRING(DEFAULT_RDTR), "using default of " __MODULE_STRING(DEFAULT_RDTR),
.def = DEFAULT_RDTR, .def = DEFAULT_RDTR,
.arg = {.r = {.min = MIN_RDTR,.max = MAX_RDTR}} .arg = {.r = {.min = MIN_RDTR,
.max = MAX_RDTR}}
}; };
adapter->rx_int_delay = RxIntDelay[board]; adapter->rx_int_delay = RxIntDelay[bd];
ixgb_validate_option(&adapter->rx_int_delay, &opt); ixgb_validate_option(&adapter->rx_int_delay, &opt);
} }
{ /* Receive Interrupt Moderation */ { /* Receive Interrupt Moderation */
...@@ -465,14 +445,13 @@ ixgb_check_options(struct ixgb_adapter *adapter) ...@@ -465,14 +445,13 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.type = enable_option, .type = enable_option,
.name = "Advanced Receive Interrupt Moderation", .name = "Advanced Receive Interrupt Moderation",
.err = "defaulting to Enabled", .err = "defaulting to Enabled",
.def = OPTION_ENABLED, .def = OPTION_ENABLED
}; };
int raidc = RAIDC[board]; int raidc = RAIDC[bd];
ixgb_validate_option(&raidc, &opt); ixgb_validate_option(&raidc, &opt);
adapter->raidc = raidc; adapter->raidc = raidc;
} }
{ /* Transmit Interrupt Delay */ { /* Transmit Interrupt Delay */
struct ixgb_option opt = { struct ixgb_option opt = {
.type = range_option, .type = range_option,
...@@ -480,10 +459,11 @@ ixgb_check_options(struct ixgb_adapter *adapter) ...@@ -480,10 +459,11 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.err = .err =
"using default of " __MODULE_STRING(DEFAULT_TIDV), "using default of " __MODULE_STRING(DEFAULT_TIDV),
.def = DEFAULT_TIDV, .def = DEFAULT_TIDV,
.arg = {.r = {.min = MIN_TIDV,.max = MAX_TIDV}} .arg = {.r = {.min = MIN_TIDV,
.max = MAX_TIDV}}
}; };
adapter->tx_int_delay = TxIntDelay[board]; adapter->tx_int_delay = TxIntDelay[bd];
ixgb_validate_option(&adapter->tx_int_delay, &opt); ixgb_validate_option(&adapter->tx_int_delay, &opt);
} }
...@@ -492,9 +472,9 @@ ixgb_check_options(struct ixgb_adapter *adapter) ...@@ -492,9 +472,9 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.type = enable_option, .type = enable_option,
.name = "Tx Interrupt Delay Enable", .name = "Tx Interrupt Delay Enable",
.err = "defaulting to Enabled", .err = "defaulting to Enabled",
.def = OPTION_ENABLED, .def = OPTION_ENABLED
}; };
int ide = IntDelayEnable[board]; int ide = IntDelayEnable[bd];
ixgb_validate_option(&ide, &opt); ixgb_validate_option(&ide, &opt);
adapter->tx_int_delay_enable = ide; adapter->tx_int_delay_enable = ide;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment