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
under the terms of the GNU General Public License as published by the Free
......@@ -23,6 +23,7 @@
Contact Information:
Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#ifndef _IXGB_H_
......@@ -34,39 +35,44 @@
#include <linux/types.h>
#include <asm/byteorder.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#include <linux/pagemap.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/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <net/pkt_sched.h>
#include <linux/list.h>
#include <linux/workqueue.h>
#include <linux/reboot.h>
#ifdef NETIF_F_TSO
#include <net/checksum.h>
#endif
/* ethtool support */
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
struct ixgb_adapter;
#define BAR_0 0
#define BAR_1 1
#define BAR_5 5
struct ixgb_adapter;
#include "ixgb_hw.h"
#include "ixgb_ee.h"
#include "ixgb_ids.h"
......@@ -89,7 +95,7 @@ struct ixgb_adapter;
#define IXGB_TX_QUEUE_WAKE 16
/* 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 */
#define IXGB_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
......@@ -101,6 +107,7 @@ struct ixgb_buffer {
uint64_t dma;
unsigned long length;
unsigned long time_stamp;
unsigned int next_to_watch;
};
struct ixgb_desc_ring {
......@@ -121,7 +128,8 @@ struct ixgb_desc_ring {
};
#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_RX_DESC(R, i) IXGB_GET_DESC(R, i, ixgb_rx_desc)
......@@ -133,39 +141,32 @@ struct ixgb_desc_ring {
struct ixgb_adapter {
struct timer_list watchdog_timer;
struct vlan_group *vlgrp;
char *id_string;
u32 bd_number;
u32 rx_buffer_len;
u32 part_num;
u16 link_speed;
u16 link_duplex;
uint32_t bd_number;
uint32_t rx_buffer_len;
uint32_t part_num;
uint16_t link_speed;
uint16_t link_duplex;
spinlock_t tx_lock;
atomic_t irq_sem;
struct work_struct tx_timeout_task;
#ifdef ETHTOOL_PHYS_ID
struct timer_list blink_timer;
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 */
struct ixgb_desc_ring tx_ring;
unsigned long timeo_start;
u32 tx_cmd_type;
int max_data_per_txd;
uint32_t tx_cmd_type;
uint64_t hw_csum_tx_good;
uint64_t hw_csum_tx_error;
boolean_t tx_csum;
u32 tx_int_delay;
uint32_t tx_int_delay;
boolean_t tx_int_delay_enable;
/* RX */
struct ixgb_desc_ring rx_ring;
uint64_t hw_csum_rx_error;
uint64_t hw_csum_rx_good;
u32 rx_int_delay;
uint32_t rx_int_delay;
boolean_t raidc;
boolean_t rx_csum;
......@@ -177,8 +178,6 @@ struct ixgb_adapter {
/* structs defined in ixgb_hw.h */
struct ixgb_hw hw;
struct ixgb_hw_stats stats;
u32 pci_state[16];
char ifname[IFNAMSIZ];
uint32_t pci_state[16];
};
#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
under the terms of the GNU General Public License as published by the Free
......@@ -23,15 +23,16 @@
Contact Information:
Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#include "ixgb_hw.h"
#include "ixgb_ee.h"
/* 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,
u16 data, u16 count);
uint16_t data, uint16_t count);
static void ixgb_standby_eeprom(struct ixgb_hw *hw);
static boolean_t ixgb_wait_eeprom_command(struct ixgb_hw *hw);
......@@ -44,8 +45,7 @@ static void ixgb_cleanup_eeprom(struct ixgb_hw *hw);
* hw - Struct containing variables accessed by shared code
* eecd_reg - EECD's current value
*****************************************************************************/
static void
ixgb_raise_clock(struct ixgb_hw *hw, u32 * eecd_reg)
static void ixgb_raise_clock(struct ixgb_hw *hw, uint32_t * eecd_reg)
{
/* Raise the clock input to the EEPROM (by setting the SK bit), and then
* wait 50 microseconds.
......@@ -62,8 +62,7 @@ ixgb_raise_clock(struct ixgb_hw *hw, u32 * eecd_reg)
* hw - Struct containing variables accessed by shared code
* eecd_reg - EECD's current value
*****************************************************************************/
static void
ixgb_lower_clock(struct ixgb_hw *hw, u32 * eecd_reg)
static void ixgb_lower_clock(struct ixgb_hw *hw, uint32_t * eecd_reg)
{
/* Lower the clock input to the EEPROM (by clearing the SK bit), and then
* wait 50 microseconds.
......@@ -82,10 +81,10 @@ ixgb_lower_clock(struct ixgb_hw *hw, u32 * eecd_reg)
* count - number of bits to shift out
*****************************************************************************/
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;
u32 mask;
uint32_t eecd_reg;
uint32_t mask;
/* We need to shift "count" bits out to the EEPROM. So, value in the
* "data" parameter will be shifted out to the EEPROM one bit at a time.
......@@ -127,12 +126,11 @@ ixgb_shift_out_bits(struct ixgb_hw *hw, u16 data, u16 count)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static u16
ixgb_shift_in_bits(struct ixgb_hw *hw)
static uint16_t ixgb_shift_in_bits(struct ixgb_hw *hw)
{
u32 eecd_reg;
u32 i;
u16 data;
uint32_t eecd_reg;
uint32_t i;
uint16_t data;
/* In order to read a register from the EEPROM, we need to shift 16 bits
* in from the EEPROM. Bits are "shifted in" by raising the clock input to
......@@ -170,10 +168,9 @@ ixgb_shift_in_bits(struct ixgb_hw *hw)
* Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
* function should be called before issuing a command to the EEPROM.
*****************************************************************************/
static void
ixgb_setup_eeprom(struct ixgb_hw *hw)
static void ixgb_setup_eeprom(struct ixgb_hw *hw)
{
u32 eecd_reg;
uint32_t eecd_reg;
eecd_reg = IXGB_READ_REG(hw, EECD);
......@@ -192,10 +189,9 @@ ixgb_setup_eeprom(struct ixgb_hw *hw)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static void
ixgb_standby_eeprom(struct ixgb_hw *hw)
static void ixgb_standby_eeprom(struct ixgb_hw *hw)
{
u32 eecd_reg;
uint32_t eecd_reg;
eecd_reg = IXGB_READ_REG(hw, EECD);
......@@ -226,10 +222,9 @@ ixgb_standby_eeprom(struct ixgb_hw *hw)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static void
ixgb_clock_eeprom(struct ixgb_hw *hw)
static void ixgb_clock_eeprom(struct ixgb_hw *hw)
{
u32 eecd_reg;
uint32_t eecd_reg;
eecd_reg = IXGB_READ_REG(hw, EECD);
......@@ -250,10 +245,9 @@ ixgb_clock_eeprom(struct ixgb_hw *hw)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static void
ixgb_cleanup_eeprom(struct ixgb_hw *hw)
static void ixgb_cleanup_eeprom(struct ixgb_hw *hw)
{
u32 eecd_reg;
uint32_t eecd_reg;
eecd_reg = IXGB_READ_REG(hw, EECD);
......@@ -276,11 +270,10 @@ ixgb_cleanup_eeprom(struct ixgb_hw *hw)
* TRUE: EEPROM data pin is high before timeout.
* FALSE: Time expired.
*****************************************************************************/
static boolean_t
ixgb_wait_eeprom_command(struct ixgb_hw *hw)
static boolean_t ixgb_wait_eeprom_command(struct ixgb_hw *hw)
{
u32 eecd_reg;
u32 i;
uint32_t eecd_reg;
uint32_t i;
/* Toggle the CS line. This in effect tells to EEPROM to actually execute
* the command in question.
......@@ -316,16 +309,15 @@ ixgb_wait_eeprom_command(struct ixgb_hw *hw)
* TRUE: Checksum is valid
* FALSE: Checksum is not valid.
*****************************************************************************/
boolean_t
ixgb_validate_eeprom_checksum(struct ixgb_hw * hw)
boolean_t ixgb_validate_eeprom_checksum(struct ixgb_hw * hw)
{
u16 checksum = 0;
u16 i;
uint16_t checksum = 0;
uint16_t i;
for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++)
checksum += ixgb_read_eeprom(hw, i);
if (checksum == (u16) EEPROM_SUM)
if (checksum == (uint16_t) EEPROM_SUM)
return (TRUE);
else
return (FALSE);
......@@ -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.
* Writes the difference to word offset 63 of the EEPROM.
*****************************************************************************/
void
ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
void ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
{
u16 checksum = 0;
u16 i;
uint16_t checksum = 0;
uint16_t i;
for (i = 0; i < EEPROM_CHECKSUM_REG; 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);
return;
......@@ -365,8 +356,7 @@ ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
* EEPROM will most likely contain an invalid checksum.
*
*****************************************************************************/
void
ixgb_write_eeprom(struct ixgb_hw *hw, u16 offset, u16 data)
void ixgb_write_eeprom(struct ixgb_hw *hw, uint16_t offset, uint16_t data)
{
/* Prepare the EEPROM for writing */
ixgb_setup_eeprom(hw);
......@@ -414,10 +404,9 @@ ixgb_write_eeprom(struct ixgb_hw *hw, u16 offset, u16 data)
* Returns:
* The 16-bit value read from the eeprom
*****************************************************************************/
u16
ixgb_read_eeprom(struct ixgb_hw * hw, u16 offset)
uint16_t ixgb_read_eeprom(struct ixgb_hw * hw, uint16_t offset)
{
u16 data;
uint16_t data;
/* Prepare the EEPROM for reading */
ixgb_setup_eeprom(hw);
......@@ -448,26 +437,25 @@ ixgb_read_eeprom(struct ixgb_hw * hw, u16 offset)
* TRUE: if eeprom read is successful
* FALSE: otherwise.
*****************************************************************************/
boolean_t
ixgb_get_eeprom_data(struct ixgb_hw * hw)
boolean_t ixgb_get_eeprom_data(struct ixgb_hw * hw)
{
u16 i;
u16 checksum = 0;
uint16_t i;
uint16_t checksum = 0;
struct ixgb_ee_map_type *ee_map;
DEBUGFUNC("ixgb_get_eeprom_data");
ee_map = (struct ixgb_ee_map_type *) hw->eeprom;
ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
DEBUGOUT("ixgb_ee: Reading eeprom data\n");
for (i = 0; i < IXGB_EEPROM_SIZE; i++) {
u16 ee_data;
uint16_t ee_data;
ee_data = ixgb_read_eeprom(hw, i);
checksum += 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");
return (FALSE);
}
......@@ -491,11 +479,9 @@ ixgb_get_eeprom_data(struct ixgb_hw * hw)
* TRUE: eeprom signature was good and the eeprom read was successful
* FALSE: otherwise.
******************************************************************************/
static boolean_t
ixgb_check_and_get_eeprom_data(struct ixgb_hw *hw)
static boolean_t ixgb_check_and_get_eeprom_data(struct ixgb_hw *hw)
{
struct ixgb_ee_map_type *ee_map =
(struct ixgb_ee_map_type *) hw->eeprom;
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
if ((ee_map->init_ctrl_reg_1 & le16_to_cpu(EEPROM_ICW1_SIGNATURE_MASK))
== le16_to_cpu(EEPROM_ICW1_SIGNATURE_VALID)) {
......@@ -505,6 +491,26 @@ 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
*
......@@ -513,12 +519,10 @@ ixgb_check_and_get_eeprom_data(struct ixgb_hw *hw)
*
* Returns: None.
******************************************************************************/
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)
{
int i;
struct ixgb_ee_map_type *ee_map =
(struct ixgb_ee_map_type *) hw->eeprom;
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
DEBUGFUNC("ixgb_get_ee_mac_addr");
......@@ -538,11 +542,9 @@ ixgb_get_ee_mac_addr(struct ixgb_hw *hw, u8 * mac_addr)
* Returns:
* compatibility flags if EEPROM contents are valid, 0 otherwise
******************************************************************************/
u16
ixgb_get_ee_compatibility(struct ixgb_hw *hw)
uint16_t ixgb_get_ee_compatibility(struct ixgb_hw *hw)
{
struct ixgb_ee_map_type *ee_map =
(struct ixgb_ee_map_type *) hw->eeprom;
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->compatibility);
......@@ -558,8 +560,7 @@ ixgb_get_ee_compatibility(struct ixgb_hw *hw)
* Returns:
* PBA number if EEPROM contents are valid, 0 otherwise
******************************************************************************/
u32
ixgb_get_ee_pba_number(struct ixgb_hw * hw)
uint32_t ixgb_get_ee_pba_number(struct ixgb_hw * hw)
{
if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG])
......@@ -576,11 +577,9 @@ ixgb_get_ee_pba_number(struct ixgb_hw * hw)
* Returns:
* Initialization Control Word 1 if EEPROM contents are valid, 0 otherwise
******************************************************************************/
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)
{
struct ixgb_ee_map_type *ee_map =
(struct ixgb_ee_map_type *) hw->eeprom;
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->init_ctrl_reg_1);
......@@ -596,11 +595,9 @@ ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw * hw)
* Returns:
* Initialization Control Word 2 if EEPROM contents are valid, 0 otherwise
******************************************************************************/
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)
{
struct ixgb_ee_map_type *ee_map =
(struct ixgb_ee_map_type *) hw->eeprom;
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->init_ctrl_reg_2);
......@@ -616,11 +613,9 @@ ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw * hw)
* Returns:
* Subsystem Id if EEPROM contents are valid, 0 otherwise
******************************************************************************/
u16
ixgb_get_ee_subsystem_id(struct ixgb_hw * hw)
uint16_t ixgb_get_ee_subsystem_id(struct ixgb_hw * hw)
{
struct ixgb_ee_map_type *ee_map =
(struct ixgb_ee_map_type *) hw->eeprom;
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->subsystem_id);
......@@ -636,11 +631,9 @@ ixgb_get_ee_subsystem_id(struct ixgb_hw * hw)
* Returns:
* Sub Vendor Id if EEPROM contents are valid, 0 otherwise
******************************************************************************/
u16
ixgb_get_ee_subvendor_id(struct ixgb_hw * hw)
uint16_t ixgb_get_ee_subvendor_id(struct ixgb_hw * hw)
{
struct ixgb_ee_map_type *ee_map =
(struct ixgb_ee_map_type *) hw->eeprom;
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->subvendor_id);
......@@ -656,11 +649,9 @@ ixgb_get_ee_subvendor_id(struct ixgb_hw * hw)
* Returns:
* Device Id if EEPROM contents are valid, 0 otherwise
******************************************************************************/
u16
ixgb_get_ee_device_id(struct ixgb_hw * hw)
uint16_t ixgb_get_ee_device_id(struct ixgb_hw * hw)
{
struct ixgb_ee_map_type *ee_map =
(struct ixgb_ee_map_type *) hw->eeprom;
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->device_id);
......@@ -676,11 +667,9 @@ ixgb_get_ee_device_id(struct ixgb_hw * hw)
* Returns:
* Device Id if EEPROM contents are valid, 0 otherwise
******************************************************************************/
u16
ixgb_get_ee_vendor_id(struct ixgb_hw * hw)
uint16_t ixgb_get_ee_vendor_id(struct ixgb_hw * hw)
{
struct ixgb_ee_map_type *ee_map =
(struct ixgb_ee_map_type *) hw->eeprom;
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->vendor_id);
......@@ -696,11 +685,9 @@ ixgb_get_ee_vendor_id(struct ixgb_hw * hw)
* Returns:
* SDP Register if EEPROM contents are valid, 0 otherwise
******************************************************************************/
u16
ixgb_get_ee_swdpins_reg(struct ixgb_hw * hw)
uint16_t ixgb_get_ee_swdpins_reg(struct ixgb_hw * hw)
{
struct ixgb_ee_map_type *ee_map =
(struct ixgb_ee_map_type *) hw->eeprom;
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->swdpins_reg);
......@@ -716,11 +703,9 @@ ixgb_get_ee_swdpins_reg(struct ixgb_hw * hw)
* Returns:
* D3 Power Management Bits if EEPROM contents are valid, 0 otherwise
******************************************************************************/
u8
ixgb_get_ee_d3_power(struct ixgb_hw * hw)
uint8_t ixgb_get_ee_d3_power(struct ixgb_hw * hw)
{
struct ixgb_ee_map_type *ee_map =
(struct ixgb_ee_map_type *) hw->eeprom;
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
return (ee_map->d3_power);
......@@ -736,11 +721,9 @@ ixgb_get_ee_d3_power(struct ixgb_hw * hw)
* Returns:
* D0 Power Management Bits if EEPROM contents are valid, 0 otherwise
******************************************************************************/
u8
ixgb_get_ee_d0_power(struct ixgb_hw * hw)
uint8_t ixgb_get_ee_d0_power(struct ixgb_hw * hw)
{
struct ixgb_ee_map_type *ee_map =
(struct ixgb_ee_map_type *) hw->eeprom;
struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
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
under the terms of the GNU General Public License as published by the Free
......@@ -23,6 +23,7 @@
Contact Information:
Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#ifndef _IXGB_EE_H_
......@@ -73,32 +74,32 @@
/* EEPROM structure */
struct ixgb_ee_map_type {
u8 mac_addr[IXGB_ETH_LENGTH_OF_ADDRESS];
u16 compatibility;
u16 reserved1[4];
u32 pba_number;
u16 init_ctrl_reg_1;
u16 subsystem_id;
u16 subvendor_id;
u16 device_id;
u16 vendor_id;
u16 init_ctrl_reg_2;
u16 oem_reserved[16];
u16 swdpins_reg;
u16 circuit_ctrl_reg;
u8 d3_power;
u8 d0_power;
u16 reserved2[28];
u16 checksum;
uint8_t mac_addr[IXGB_ETH_LENGTH_OF_ADDRESS];
uint16_t compatibility;
uint16_t reserved1[4];
uint32_t pba_number;
uint16_t init_ctrl_reg_1;
uint16_t subsystem_id;
uint16_t subvendor_id;
uint16_t device_id;
uint16_t vendor_id;
uint16_t init_ctrl_reg_2;
uint16_t oem_reserved[16];
uint16_t swdpins_reg;
uint16_t circuit_ctrl_reg;
uint8_t d3_power;
uint8_t d0_power;
uint16_t reserved2[28];
uint16_t checksum;
};
/* EEPROM Functions */
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);
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 */
/*******************************************************************************
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
under the terms of the GNU General Public License as published by the Free
......@@ -23,6 +23,7 @@
Contact Information:
Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
/* ethtool support for ixgb */
......@@ -35,22 +36,63 @@ extern char ixgb_driver_name[];
extern char ixgb_driver_version[];
extern int ixgb_up(struct ixgb_adapter *adapter);
extern int ixgb_down(struct ixgb_adapter *adapter);
/**
* ixgb_ethtool_ioctl - Ethtool Ioctl Support
* @netdev: net device structure
* @ifr: interface request structure
**/
extern void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog);
static inline int
ixgb_eeprom_size(struct ixgb_hw *hw)
static inline int ixgb_eeprom_size(struct ixgb_hw *hw)
{
/* return size in bytes */
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
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;
if (netif_carrier_ok(adapter->netdev)) {
ecmd->speed = 10000;
ecmd->speed = SPEED_10000;
ecmd->duplex = DUPLEX_FULL;
} else {
ecmd->speed = -1;
......@@ -78,64 +120,80 @@ ixgb_ethtool_sset(struct ixgb_adapter *adapter, struct ethtool_cmd *ecmd)
ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)
return -EINVAL;
else {
ixgb_down(adapter);
ixgb_down(adapter, TRUE);
ixgb_up(adapter);
}
return 0;
}
#if 0
static int
ixgb_ethtool_promiscuous(struct ixgb_adapter *adapter,
struct ethtool_pmode *pmode)
ixgb_ethtool_gpause(struct ixgb_adapter *adapter,
struct ethtool_pauseparam *epause)
{
u32 rctl = IXGB_READ_REG(&adapter->hw, RCTL);
struct ixgb_hw *hw = &adapter->hw;
pmode->rctl_old = rctl;
if (pmode->upe)
rctl |= IXGB_RCTL_UPE;
else
rctl &= ~IXGB_RCTL_UPE;
epause->autoneg = AUTONEG_DISABLE;
if (pmode->mpe)
rctl |= IXGB_RCTL_MPE;
else
rctl &= ~IXGB_RCTL_MPE;
if (hw->fc.type == ixgb_fc_rx_pause)
epause->rx_pause = 1;
else if (hw->fc.type == ixgb_fc_tx_pause)
epause->tx_pause = 1;
else if (hw->fc.type == ixgb_fc_full) {
epause->rx_pause = 1;
epause->tx_pause = 1;
}
IXGB_WRITE_REG(&adapter->hw, RCTL, rctl);
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;
pmode->rctl_new = IXGB_READ_REG(&adapter->hw, 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;
ixgb_down(adapter, TRUE);
ixgb_up(adapter);
return 0;
}
#endif
#define IXGB_REG_DUMP_LEN 136*sizeof(u32)
static void
ixgb_ethtool_gdrvinfo(struct ixgb_adapter *adapter,
struct ethtool_drvinfo *drvinfo)
{
strncpy(drvinfo->driver, ixgb_driver_name, 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);
#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;
#endif /* ETHTOOL_GREGS */
drvinfo->eedump_len = ixgb_eeprom_size(&adapter->hw);
}
#ifdef ETHTOOL_GREGS
#define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_
static void
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;
u32 *reg = (u32 *) regs_buff;
u32 *reg_start = reg;
u8 i;
uint32_t *reg = regs_buff;
uint32_t *reg_start = reg;
uint8_t i;
regs->version =
(adapter->hw.device_id << 16) | adapter->hw.subsystem_id;
......@@ -199,15 +257,6 @@ ixgb_ethtool_gregs(struct ixgb_adapter *adapter,
*reg++ = IXGB_READ_REG(hw, MSCA); /* 74 */
*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 */
*reg++ = IXGB_GET_STAT(adapter, tprl); /* 76 */
*reg++ = IXGB_GET_STAT(adapter, tprh); /* 77 */
......@@ -270,22 +319,21 @@ ixgb_ethtool_gregs(struct ixgb_adapter *adapter,
*reg++ = IXGB_GET_STAT(adapter, xofftxc); /* 134 */
*reg++ = IXGB_GET_STAT(adapter, rjc); /* 135 */
#if 0
#endif
regs->len = (reg - reg_start) * sizeof (u32);
regs->len = (reg - reg_start) * sizeof(uint32_t);
}
#endif /* ETHTOOL_GREGS */
static int
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;
int i, max_len, first_word, last_word;
IXGB_DBG("ixgb_ethtool_geeprom\n");
int ret_val = 0;
if (eeprom->len == 0)
return -EINVAL;
if (eeprom->len == 0) {
ret_val = -EINVAL;
goto geeprom_error;
}
eeprom->magic = hw->vendor_id | (hw->device_id << 16);
......@@ -294,8 +342,10 @@ ixgb_ethtool_geeprom(struct ixgb_adapter *adapter,
/* use our function to read the eeprom and update our cache */
ixgb_get_eeprom_data(hw);
if (eeprom->offset > eeprom->offset + eeprom->len)
return -EINVAL;
if (eeprom->offset > eeprom->offset + eeprom->len) {
ret_val = -EINVAL;
goto geeprom_error;
}
if ((eeprom->offset + eeprom->len) > max_len)
eeprom->len = (max_len - eeprom->offset);
......@@ -306,15 +356,16 @@ ixgb_ethtool_geeprom(struct ixgb_adapter *adapter,
for (i = 0; i <= (last_word - first_word); i++) {
eeprom_buff[i] = hw->eeprom[first_word + i];
}
return 0;
geeprom_error:
return ret_val;
}
static int
ixgb_ethtool_seeprom(struct ixgb_adapter *adapter,
struct ethtool_eeprom *eeprom, void *user_data)
{
struct ixgb_hw *hw = &adapter->hw;
u16 eeprom_buff[256];
uint16_t eeprom_buff[256];
int i, max_len, first_word, last_word;
void *ptr;
......@@ -334,7 +385,7 @@ ixgb_ethtool_seeprom(struct ixgb_adapter *adapter,
first_word = eeprom->offset >> 1;
last_word = (eeprom->offset + eeprom->len - 1) >> 1;
ptr = (void *) eeprom_buff;
ptr = (void *)eeprom_buff;
if (eeprom->offset & 1) {
/* need read/modify/write of first changed EEPROM word */
......@@ -361,18 +412,15 @@ ixgb_ethtool_seeprom(struct ixgb_adapter *adapter,
return 0;
}
#ifdef ETHTOOL_PHYS_ID
/* toggle LED 4 times per second = 2 "blinks" per second */
#define IXGB_ID_INTERVAL (HZ/4)
/* bit defines for adapter->led_status */
#define IXGB_LED_ON 0
static void
ixgb_led_blink_callback(unsigned long data)
static void 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))
ixgb_led_off(&adapter->hw);
......@@ -388,7 +436,7 @@ ixgb_ethtool_led_blink(struct ixgb_adapter *adapter, struct ethtool_value *id)
if (!adapter->blink_timer.function) {
init_timer(&adapter->blink_timer);
adapter->blink_timer.function = ixgb_led_blink_callback;
adapter->blink_timer.data = (unsigned long) adapter;
adapter->blink_timer.data = (unsigned long)adapter;
}
mod_timer(&adapter->blink_timer, jiffies);
......@@ -405,114 +453,121 @@ ixgb_ethtool_led_blink(struct ixgb_adapter *adapter, struct ethtool_value *id)
return 0;
}
#endif /* ETHTOOL_PHYS_ID */
int
ixgb_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
int ixgb_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
{
struct ixgb_adapter *adapter = netdev->priv;
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;
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:{
struct ethtool_cmd ecmd = { ETHTOOL_GSET };
ixgb_ethtool_gset(adapter, &ecmd);
if (copy_to_user(addr, &ecmd, sizeof (ecmd)))
if (copy_to_user(addr, &ecmd, sizeof(ecmd)))
return -EFAULT;
return 0;
}
case ETHTOOL_SSET:{
struct ethtool_cmd ecmd;
if (copy_from_user(&ecmd, addr, sizeof (ecmd)))
if (copy_from_user(&ecmd, addr, sizeof(ecmd)))
return -EFAULT;
return ixgb_ethtool_sset(adapter, &ecmd);
}
case ETHTOOL_GDRVINFO:
{
case ETHTOOL_GDRVINFO:{
struct ethtool_drvinfo drvinfo = { ETHTOOL_GDRVINFO };
ixgb_ethtool_gdrvinfo(adapter, &drvinfo);
if (copy_to_user(addr, &drvinfo, sizeof (drvinfo)))
if (copy_to_user(addr, &drvinfo, sizeof(drvinfo)))
return -EFAULT;
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:{
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);
if (copy_to_user(addr, &regs, sizeof (regs)))
if (copy_to_user(addr, &regs, sizeof(regs)))
return -EFAULT;
addr += offsetof(struct ethtool_regs, data);
if (copy_to_user(addr, regs_buff, regs.len))
return -EFAULT;
return 0;
}
#endif /* ETHTOOL_GREGS */
case ETHTOOL_NWAY_RST:{
IXGB_DBG("ETHTOOL_NWAY_RST\n");
ixgb_down(adapter);
if (netif_running(netdev)) {
ixgb_down(adapter, TRUE);
ixgb_up(adapter);
}
return 0;
}
#ifdef ETHTOOL_PHYS_ID
case ETHTOOL_PHYS_ID:{
struct ethtool_value id;
IXGB_DBG("ETHTOOL_PHYS_ID\n");
if (copy_from_user(&id, addr, sizeof (id)))
if (copy_from_user(&id, addr, sizeof(id)))
return -EFAULT;
return ixgb_ethtool_led_blink(adapter, &id);
}
#endif /* ETHTOOL_PHYS_ID */
case ETHTOOL_GLINK:{
struct ethtool_value link = { ETHTOOL_GLINK };
IXGB_DBG("ETHTOOL_GLINK\n");
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 0;
}
case ETHTOOL_GEEPROM:{
struct ethtool_eeprom eeprom = { ETHTOOL_GEEPROM };
u16 eeprom_buff[IXGB_EEPROM_SIZE];
uint16_t eeprom_buff[IXGB_EEPROM_SIZE];
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;
if ((err =
......@@ -520,12 +575,12 @@ ixgb_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
eeprom_buff)) < 0)
return err;
if (copy_to_user(addr, &eeprom, sizeof (eeprom)))
if (copy_to_user(addr, &eeprom, sizeof(eeprom)))
return -EFAULT;
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))
return -EFAULT;
return 0;
......@@ -533,13 +588,133 @@ ixgb_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
case ETHTOOL_SEEPROM:{
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;
addr += offsetof(struct ethtool_eeprom, data);
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:
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
under the terms of the GNU General Public License as published by the Free
......@@ -23,6 +23,7 @@
Contact Information:
Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
/* ixgb_hw.c
......@@ -34,32 +35,31 @@
/* 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);
boolean_t mac_addr_valid(u8 * mac_addr);
static boolean_t ixgb_link_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
ixgb_mac_reset(struct ixgb_hw *hw)
uint32_t 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 */
IXGB_CTRL0_SDP2_DIR | IXGB_CTRL0_SDP1_DIR | IXGB_CTRL0_SDP0_DIR | IXGB_CTRL0_SDP3 | /* Initial value 1101 */
IXGB_CTRL0_SDP2 | IXGB_CTRL0_SDP0;
#ifdef HP_ZX1
outl(IXGB_CTRL0, hw->io_base);
outl(ctrl_reg, hw->io_base + 4);
/* Workaround for 82597EX reset errata */
IXGB_WRITE_REG_IO(hw, CTRL0, ctrl_reg);
#else
IXGB_WRITE_REG(hw, CTRL0, ctrl_reg);
#endif
......@@ -72,7 +72,10 @@ ixgb_mac_reset(struct ixgb_hw *hw)
ASSERT(!(ctrl_reg & IXGB_CTRL0_RST));
#endif
if (hw->phy_type == ixgb_phy_type_txn17401) {
ixgb_optics_reset(hw);
}
return ctrl_reg;
}
......@@ -81,11 +84,10 @@ ixgb_mac_reset(struct ixgb_hw *hw)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
boolean_t
ixgb_adapter_stop(struct ixgb_hw * hw)
boolean_t ixgb_adapter_stop(struct ixgb_hw * hw)
{
u32 ctrl_reg;
u32 icr_reg;
uint32_t ctrl_reg;
uint32_t icr_reg;
DEBUGFUNC("ixgb_adapter_stop");
......@@ -133,6 +135,91 @@ ixgb_adapter_stop(struct ixgb_hw * hw)
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.
*
......@@ -150,11 +237,10 @@ ixgb_adapter_stop(struct ixgb_hw * hw)
* TRUE if successful,
* FALSE if unrecoverable problems were encountered.
*****************************************************************************/
boolean_t
ixgb_init_hw(struct ixgb_hw * hw)
boolean_t ixgb_init_hw(struct ixgb_hw * hw)
{
u32 i;
u32 ctrl_reg;
uint32_t i;
uint32_t ctrl_reg;
boolean_t status;
DEBUGFUNC("ixgb_init_hw");
......@@ -170,8 +256,8 @@ ixgb_init_hw(struct ixgb_hw * hw)
DEBUGOUT("Issuing an EE reset to MAC\n");
#ifdef HP_ZX1
outl(IXGB_CTRL1, hw->io_base);
outl(IXGB_CTRL1_EE_RST, hw->io_base + 4);
/* Workaround for 82597EX reset errata */
IXGB_WRITE_REG_IO(hw, CTRL1, IXGB_CTRL1_EE_RST);
#else
IXGB_WRITE_REG(hw, CTRL1, IXGB_CTRL1_EE_RST);
#endif
......@@ -183,6 +269,10 @@ ixgb_init_hw(struct ixgb_hw * hw)
return (FALSE);
}
/* 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).
*/
......@@ -217,7 +307,7 @@ ixgb_init_hw(struct ixgb_hw * hw)
/* Call a subroutine to setup flow control. */
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);
return (status);
......@@ -232,10 +322,9 @@ ixgb_init_hw(struct ixgb_hw * hw)
* of the receive addresss registers. Clears the multicast table. Assumes
* the receiver is in reset when the routine is called.
*****************************************************************************/
void
ixgb_init_rx_addrs(struct ixgb_hw *hw)
void ixgb_init_rx_addrs(struct ixgb_hw *hw)
{
u32 i;
uint32_t i;
DEBUGFUNC("ixgb_init_rx_addrs");
......@@ -294,12 +383,12 @@ ixgb_init_rx_addrs(struct ixgb_hw *hw)
*****************************************************************************/
void
ixgb_mc_addr_list_update(struct ixgb_hw *hw,
u8 * mc_addr_list,
u32 mc_addr_count, u32 pad)
uint8_t * mc_addr_list,
uint32_t mc_addr_count, uint32_t pad)
{
u32 hash_value;
u32 i;
u32 rar_used_count = 1; /* RAR[0] is used for our MAC address */
uint32_t hash_value;
uint32_t i;
uint32_t rar_used_count = 1; /* RAR[0] is used for our MAC address */
DEBUGFUNC("ixgb_mc_addr_list_update");
......@@ -371,10 +460,9 @@ ixgb_mc_addr_list_update(struct ixgb_hw *hw,
* Returns:
* The hash value
*****************************************************************************/
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)
{
u32 hash_value = 0;
uint32_t hash_value = 0;
DEBUGFUNC("ixgb_hash_mc_addr");
......@@ -388,18 +476,18 @@ ixgb_hash_mc_addr(struct ixgb_hw *hw, u8 * mc_addr)
case 0:
/* [47:36] i.e. 0x563 for above example address */
hash_value =
((mc_addr[4] >> 4) | (((u16) mc_addr[5]) << 4));
((mc_addr[4] >> 4) | (((uint16_t) mc_addr[5]) << 4));
break;
case 1: /* [46:35] i.e. 0xAC6 for above example address */
hash_value =
((mc_addr[4] >> 3) | (((u16) mc_addr[5]) << 5));
((mc_addr[4] >> 3) | (((uint16_t) mc_addr[5]) << 5));
break;
case 2: /* [45:34] i.e. 0x5D8 for above example address */
hash_value =
((mc_addr[4] >> 2) | (((u16) mc_addr[5]) << 6));
((mc_addr[4] >> 2) | (((uint16_t) mc_addr[5]) << 6));
break;
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;
default:
/* Invalid mc_filter_type, what should we do? */
......@@ -418,11 +506,10 @@ ixgb_hash_mc_addr(struct ixgb_hw *hw, u8 * mc_addr)
* hw - Struct containing variables accessed by shared code
* hash_value - Multicast address hash value
*****************************************************************************/
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)
{
u32 hash_bit, hash_reg;
u32 mta_reg;
uint32_t hash_bit, hash_reg;
uint32_t mta_reg;
/* The MTA is a register array of 128 32-bit registers.
* It is treated like an array of 4096 bits. We want to set
......@@ -451,22 +538,21 @@ ixgb_mta_set(struct ixgb_hw *hw, u32 hash_value)
* addr - Address to put into receive address register
* index - Receive address register to write
*****************************************************************************/
void
ixgb_rar_set(struct ixgb_hw *hw, u8 * addr, u32 index)
void ixgb_rar_set(struct ixgb_hw *hw, uint8_t * addr, uint32_t index)
{
u32 rar_low, rar_high;
uint32_t rar_low, rar_high;
DEBUGFUNC("ixgb_rar_set");
/* HW expects these in little endian so we reverse the byte order
* from network order (big endian) to little endian
*/
rar_low = ((u32) addr[0] |
((u32) addr[1] << 8) |
((u32) addr[2] << 16) | ((u32) addr[3] << 24));
rar_low = ((uint32_t) addr[0] |
((uint32_t) addr[1] << 8) |
((uint32_t) addr[2] << 16) | ((uint32_t) addr[3] << 24));
rar_high = ((u32) addr[4] |
((u32) addr[5] << 8) | IXGB_RAH_AV);
rar_high = ((uint32_t) addr[4] |
((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) + 1), rar_high);
......@@ -480,8 +566,7 @@ ixgb_rar_set(struct ixgb_hw *hw, u8 * addr, u32 index)
* offset - Offset in VLAN filer table to write
* value - Value to write into VLAN filter table
*****************************************************************************/
void
ixgb_write_vfta(struct ixgb_hw *hw, u32 offset, u32 value)
void ixgb_write_vfta(struct ixgb_hw *hw, uint32_t offset, uint32_t value)
{
IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, value);
return;
......@@ -492,10 +577,9 @@ ixgb_write_vfta(struct ixgb_hw *hw, u32 offset, u32 value)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
void
ixgb_clear_vfta(struct ixgb_hw *hw)
void ixgb_clear_vfta(struct ixgb_hw *hw)
{
u32 offset;
uint32_t offset;
for (offset = 0; offset < IXGB_VLAN_FILTER_TBL_SIZE; offset++)
IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
......@@ -508,11 +592,10 @@ ixgb_clear_vfta(struct ixgb_hw *hw)
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
boolean_t
ixgb_setup_fc(struct ixgb_hw * hw)
boolean_t ixgb_setup_fc(struct ixgb_hw * hw)
{
u32 ctrl_reg;
u32 pap_reg = 0; /* by default, assume no pause time */
uint32_t ctrl_reg;
uint32_t pap_reg = 0; /* by default, assume no pause time */
boolean_t status = TRUE;
DEBUGFUNC("ixgb_setup_fc");
......@@ -534,6 +617,8 @@ ixgb_setup_fc(struct ixgb_hw * hw)
*/
switch (hw->fc.type) {
case ixgb_fc_none: /* 0 */
/* Set CMDC bit to disable Rx Flow control */
ctrl_reg |= (IXGB_CTRL0_CMDC);
break;
case ixgb_fc_rx_pause: /* 1 */
/* RX Flow control is enabled, and TX Flow control is
......@@ -603,18 +688,19 @@ ixgb_setup_fc(struct ixgb_hw * hw)
*
* 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
* read command.
*****************************************************************************/
u16
uint16_t
ixgb_read_phy_reg(struct ixgb_hw * hw,
u32 reg_address,
u32 phy_address, u32 device_type)
uint32_t reg_address,
uint32_t phy_address, uint32_t device_type)
{
u32 i;
u32 data;
u32 command = 0;
uint32_t i;
uint32_t data;
uint32_t command = 0;
ASSERT(reg_address <= IXGB_MAX_PHY_REG_ADDRESS);
ASSERT(phy_address <= IXGB_MAX_PHY_ADDRESS);
......@@ -677,7 +763,7 @@ ixgb_read_phy_reg(struct ixgb_hw * hw,
*/
data = IXGB_READ_REG(hw, MSRWD);
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,
*
* 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
* write command.
*****************************************************************************/
void
ixgb_write_phy_reg(struct ixgb_hw *hw,
u32 reg_address,
u32 phy_address, u32 device_type, u16 data)
uint32_t reg_address,
uint32_t phy_address, uint32_t device_type, uint16_t data)
{
u32 i;
u32 command = 0;
uint32_t i;
uint32_t command = 0;
ASSERT(reg_address <= IXGB_MAX_PHY_REG_ADDRESS);
ASSERT(phy_address <= IXGB_MAX_PHY_ADDRESS);
ASSERT(device_type <= IXGB_MAX_PHY_DEV_TYPE);
/* 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 */
command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) |
......@@ -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.
*****************************************************************************/
void
ixgb_check_for_link(struct ixgb_hw *hw)
void ixgb_check_for_link(struct ixgb_hw *hw)
{
u32 status_reg;
u32 xpcss_reg;
uint32_t status_reg;
uint32_t xpcss_reg;
DEBUGFUNC("ixgb_check_for_link");
......@@ -792,30 +878,42 @@ ixgb_check_for_link(struct ixgb_hw *hw)
DEBUGOUT("XPCSS Not Aligned while Status:LU is set.\n");
hw->link_up = ixgb_link_reset(hw);
} 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);
}
/* 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;
/* check for a bad reset that may have occured
* the indication is that the RFC / LFC registers may be incrementing
* continually. Do a full adapter reset to recover
*/
if (hw->phy_type == ixgb_phy_type_txn17401) {
newLFC = IXGB_READ_REG(hw, LFC);
newRFC = IXGB_READ_REG(hw, RFC);
if ((hw->lastLFC + 250 < newLFC) || (hw->lastRFC + 250 < newRFC)) {
DEBUGOUT("BAD LINK! too many LFC/RFC since last check\n");
if ((hw->lastLFC + 250 < newLFC)
|| (hw->lastRFC + 250 < newRFC)) {
DEBUGOUT
("BAD LINK! too many LFC/RFC since last check\n");
bad_link_returncode = TRUE;
}
hw->lastLFC = newLFC;
hw->lastRFC = newRFC;
}
return bad_link_returncode;
}
......@@ -824,10 +922,9 @@ ixgb_check_for_bad_link(struct ixgb_hw *hw)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
void
ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
void ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
{
volatile u32 temp_reg;
volatile uint32_t temp_reg;
DEBUGFUNC("ixgb_clear_hw_cntrs");
......@@ -905,10 +1002,9 @@ ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
void
ixgb_led_on(struct ixgb_hw *hw)
void 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). */
ctrl0_reg &= ~IXGB_CTRL0_SDP0;
......@@ -921,10 +1017,9 @@ ixgb_led_on(struct ixgb_hw *hw)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
void
ixgb_led_off(struct ixgb_hw *hw)
void 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). */
ctrl0_reg |= IXGB_CTRL0_SDP0;
......@@ -937,10 +1032,9 @@ ixgb_led_off(struct ixgb_hw *hw)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static void
ixgb_get_bus_info(struct ixgb_hw *hw)
static void ixgb_get_bus_info(struct ixgb_hw *hw)
{
u32 status_reg;
uint32_t status_reg;
status_reg = IXGB_READ_REG(hw, STATUS);
......@@ -979,8 +1073,7 @@ ixgb_get_bus_info(struct ixgb_hw *hw)
* mac_addr - pointer to MAC address.
*
*****************************************************************************/
boolean_t
mac_addr_valid(u8 * mac_addr)
boolean_t mac_addr_valid(uint8_t * mac_addr)
{
boolean_t is_valid = TRUE;
DEBUGFUNC("mac_addr_valid");
......@@ -1012,17 +1105,18 @@ mac_addr_valid(u8 * mac_addr)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
boolean_t
ixgb_link_reset(struct ixgb_hw * hw)
boolean_t ixgb_link_reset(struct ixgb_hw * hw)
{
boolean_t link_status = FALSE;
u8 wait_retries = MAX_RESET_ITERATIONS;
u8 lrst_retries = MAX_RESET_ITERATIONS;
uint8_t wait_retries = MAX_RESET_ITERATIONS;
uint8_t lrst_retries = MAX_RESET_ITERATIONS;
do {
/* Reset the link */
IXGB_WRITE_REG(hw, CTRL0,
IXGB_READ_REG(hw, CTRL0) | IXGB_CTRL0_LRST);
/* Wait for link-up and lane re-alignment */
do {
udelay(IXGB_DELAY_USECS_AFTER_LINK_RESET);
link_status =
......@@ -1030,6 +1124,7 @@ ixgb_link_reset(struct ixgb_hw * hw)
&& (IXGB_READ_REG(hw, XPCSS) &
IXGB_XPCSS_ALIGN_STATUS)) ? TRUE : FALSE;
} while (!link_status && --wait_retries);
} while (!link_status && --lrst_retries);
return link_status;
......@@ -1040,16 +1135,21 @@ ixgb_link_reset(struct ixgb_hw * hw)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
void
ixgb_optics_reset(struct ixgb_hw *hw)
void 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,
MDIO_PMA_PMD_CR1,
IXGB_PHY_ADDRESS,
TXN17401_PMA_PMD_DID, TXN17401_PMA_PMD_CR1_RESET);
MDIO_PMA_PMD_DID, MDIO_PMA_PMD_CR1_RESET);
mdio_reg = ixgb_read_phy_reg(hw,
TXN17401_PMA_PMD_CR1,
IXGB_PHY_ADDRESS, TXN17401_PMA_PMD_DID);
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
under the terms of the GNU General Public License as published by the Free
......@@ -23,6 +23,7 @@
Contact Information:
Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#ifndef _IXGB_HW_H_
......@@ -37,6 +38,21 @@ typedef enum {
ixgb_num_macs
} ixgb_mac_type;
/* Types of physical layer modules */
typedef enum {
ixgb_phy_type_unknown = 0,
ixgb_phy_type_g6005, /* 850nm, MM fiber, XPAK transceiver */
ixgb_phy_type_g6104, /* 1310nm, SM fiber, XPAK transceiver */
ixgb_phy_type_txn17201, /* 850nm, MM fiber, XPAK transceiver */
ixgb_phy_type_txn17401 /* 1310nm, SM fiber, XENPAK transceiver */
} ixgb_phy_type;
/* XPAK transceiver vendors, for the SR adapters */
typedef enum {
ixgb_xpak_vendor_intel,
ixgb_xpak_vendor_infineon
} ixgb_xpak_vendor;
/* Media Types */
typedef enum {
ixgb_media_type_unknown = 0,
......@@ -84,6 +100,9 @@ typedef enum {
#define SPEED_10000 10000
#define FULL_DUPLEX 2
#define MIN_NUMBER_OF_DESCRIPTORS 8
#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8 /* 13 bits in RDLEN/TDLEN, 128B aligned */
#define IXGB_DELAY_BEFORE_RESET 10 /* allow 10ms after idling rx/tx units */
#define IXGB_DELAY_AFTER_RESET 1 /* allow 1ms after the reset */
#define IXGB_DELAY_AFTER_EE_RESET 10 /* allow 10ms after the EEPROM reset */
......@@ -225,6 +244,9 @@ typedef enum {
/* CTRL0 Bit Masks */
#define IXGB_CTRL0_LRST 0x00000008
#define IXGB_CTRL0_JFE 0x00000010
#define IXGB_CTRL0_XLE 0x00000020
#define IXGB_CTRL0_MDCS 0x00000040
#define IXGB_CTRL0_CMDC 0x00000080
#define IXGB_CTRL0_SDP0 0x00040000
#define IXGB_CTRL0_SDP1 0x00080000
#define IXGB_CTRL0_SDP2 0x00100000
......@@ -239,14 +261,36 @@ typedef enum {
#define IXGB_CTRL0_VME 0x40000000
/* CTRL1 Bit Masks */
#define IXGB_CTRL1_GPI0_EN 0x00000001
#define IXGB_CTRL1_GPI1_EN 0x00000002
#define IXGB_CTRL1_GPI2_EN 0x00000004
#define IXGB_CTRL1_GPI3_EN 0x00000008
#define IXGB_CTRL1_SDP4 0x00000010
#define IXGB_CTRL1_SDP5 0x00000020
#define IXGB_CTRL1_SDP6 0x00000040
#define IXGB_CTRL1_SDP7 0x00000080
#define IXGB_CTRL1_SDP4_DIR 0x00000100
#define IXGB_CTRL1_SDP5_DIR 0x00000200
#define IXGB_CTRL1_SDP6_DIR 0x00000400
#define IXGB_CTRL1_SDP7_DIR 0x00000800
#define IXGB_CTRL1_EE_RST 0x00002000
#define IXGB_CTRL1_RO_DIS 0x00020000
#define IXGB_CTRL1_PCIXHM_MASK 0x00C00000
#define IXGB_CTRL1_PCIXHM_1_2 0x00000000
#define IXGB_CTRL1_PCIXHM_5_8 0x00400000
#define IXGB_CTRL1_PCIXHM_3_4 0x00800000
#define IXGB_CTRL1_PCIXHM_7_8 0x00C00000
/* STATUS Bit Masks */
#define IXGB_STATUS_LU 0x00000002
#define IXGB_STATUS_AIP 0x00000004
#define IXGB_STATUS_TXOFF 0x00000010
#define IXGB_STATUS_XAUIME 0x00000020
#define IXGB_STATUS_RES 0x00000040
#define IXGB_STATUS_RIS 0x00000080
#define IXGB_STATUS_RIE 0x00000100
#define IXGB_STATUS_RLF 0x00000200
#define IXGB_STATUS_RRF 0x00000400
#define IXGB_STATUS_PCI_SPD 0x00000800
#define IXGB_STATUS_BUS64 0x00001000
#define IXGB_STATUS_PCIX_MODE 0x00002000
......@@ -254,31 +298,52 @@ typedef enum {
#define IXGB_STATUS_PCIX_SPD_66 0x00000000
#define IXGB_STATUS_PCIX_SPD_100 0x00004000
#define IXGB_STATUS_PCIX_SPD_133 0x00008000
#define IXGB_STATUS_REV_ID_MASK 0x000F0000
#define IXGB_STATUS_REV_ID_SHIFT 16
/* EECD Bit Masks */
#define IXGB_EECD_SK 0x00000001
#define IXGB_EECD_CS 0x00000002
#define IXGB_EECD_DI 0x00000004
#define IXGB_EECD_DO 0x00000008
#define IXGB_EECD_FWE_MASK 0x00000030
#define IXGB_EECD_FWE_DIS 0x00000010
#define IXGB_EECD_FWE_EN 0x00000020
/* MFS */
#define IXGB_MFS_SHIFT 16
/* Interrupt Register Bit Masks (used for ICR, ICS, IMS, and IMC) */
#define IXGB_INT_TXDW 0x00000001
#define IXGB_INT_TXQE 0x00000002
#define IXGB_INT_LSC 0x00000004
#define IXGB_INT_RXSEQ 0x00000008
#define IXGB_INT_RXDMT0 0x00000010
#define IXGB_INT_RXO 0x00000040
#define IXGB_INT_RXT0 0x00000080
#define IXGB_INT_AUTOSCAN 0x00000200
#define IXGB_INT_GPI0 0x00000800
#define IXGB_INT_GPI1 0x00001000
#define IXGB_INT_GPI2 0x00002000
#define IXGB_INT_GPI3 0x00004000
/* RCTL Bit Masks */
#define IXGB_RCTL_RXEN 0x00000002
#define IXGB_RCTL_SBP 0x00000004
#define IXGB_RCTL_UPE 0x00000008
#define IXGB_RCTL_MPE 0x00000010
#define IXGB_RCTL_RDMTS_MASK 0x00000300
#define IXGB_RCTL_RDMTS_1_2 0x00000000
#define IXGB_RCTL_RDMTS_1_4 0x00000100
#define IXGB_RCTL_RDMTS_1_8 0x00000200
#define IXGB_RCTL_MO_MASK 0x00003000
#define IXGB_RCTL_MO_47_36 0x00000000
#define IXGB_RCTL_MO_46_35 0x00001000
#define IXGB_RCTL_MO_45_34 0x00002000
#define IXGB_RCTL_MO_43_32 0x00003000
#define IXGB_RCTL_MO_SHIFT 12
#define IXGB_RCTL_BAM 0x00008000
#define IXGB_RCTL_BSIZE_MASK 0x00030000
#define IXGB_RCTL_BSIZE_2048 0x00000000
#define IXGB_RCTL_BSIZE_4096 0x00010000
#define IXGB_RCTL_BSIZE_8192 0x00020000
......@@ -286,27 +351,48 @@ typedef enum {
#define IXGB_RCTL_VFE 0x00040000
#define IXGB_RCTL_CFIEN 0x00080000
#define IXGB_RCTL_CFI 0x00100000
#define IXGB_RCTL_RPDA_MASK 0x00600000
#define IXGB_RCTL_RPDA_MC_MAC 0x00000000
#define IXGB_RCTL_MC_ONLY 0x00400000
#define IXGB_RCTL_CFF 0x00800000
#define IXGB_RCTL_SECRC 0x04000000
#define IXGB_RDT_FPDB 0x80000000
#define IXGB_RCTL_IDLE_RX_UNIT 0
/* FCRTL Bit Masks */
#define IXGB_FCRTL_XONE 0x80000000
/* RXDCTL Bit Masks */
#define IXGB_RXDCTL_PTHRESH_MASK 0x000001FF
#define IXGB_RXDCTL_PTHRESH_SHIFT 0
#define IXGB_RXDCTL_HTHRESH_MASK 0x0003FE00
#define IXGB_RXDCTL_HTHRESH_SHIFT 9
#define IXGB_RXDCTL_WTHRESH_MASK 0x07FC0000
#define IXGB_RXDCTL_WTHRESH_SHIFT 18
/* RAIDC Bit Masks */
#define IXGB_RAIDC_HIGHTHRS_MASK 0x0000003F
#define IXGB_RAIDC_DELAY_MASK 0x000FF800
#define IXGB_RAIDC_DELAY_SHIFT 11
#define IXGB_RAIDC_POLL_MASK 0x1FF00000
#define IXGB_RAIDC_POLL_SHIFT 20
#define IXGB_RAIDC_RXT_GATE 0x40000000
#define IXGB_RAIDC_EN 0x80000000
#define IXGB_RAIDC_POLL_1000_INTERRUPTS_PER_SECOND 1220
#define IXGB_RAIDC_POLL_5000_INTERRUPTS_PER_SECOND 244
#define IXGB_RAIDC_POLL_10000_INTERRUPTS_PER_SECOND 122
#define IXGB_RAIDC_POLL_20000_INTERRUPTS_PER_SECOND 61
/* RXCSUM Bit Masks */
#define IXGB_RXCSUM_IPOFL 0x00000100
#define IXGB_RXCSUM_TUOFL 0x00000200
/* RAH Bit Masks */
#define IXGB_RAH_ASEL_MASK 0x00030000
#define IXGB_RAH_ASEL_DEST 0x00000000
#define IXGB_RAH_ASEL_SRC 0x00010000
#define IXGB_RAH_AV 0x80000000
/* TCTL Bit Masks */
......@@ -314,64 +400,145 @@ typedef enum {
#define IXGB_TCTL_TXEN 0x00000002
#define IXGB_TCTL_TPDE 0x00000004
#define IXGB_TCTL_IDLE_TX_UNIT 0
/* TXDCTL Bit Masks */
#define IXGB_TXDCTL_PTHRESH_MASK 0x0000007F
#define IXGB_TXDCTL_HTHRESH_MASK 0x00007F00
#define IXGB_TXDCTL_HTHRESH_SHIFT 8
#define IXGB_TXDCTL_WTHRESH_MASK 0x007F0000
#define IXGB_TXDCTL_WTHRESH_SHIFT 16
/* TSPMT Bit Masks */
#define IXGB_TSPMT_TSMT_MASK 0x0000FFFF
#define IXGB_TSPMT_TSPBP_MASK 0xFFFF0000
#define IXGB_TSPMT_TSPBP_SHIFT 16
/* PAP Bit Masks */
#define IXGB_PAP_TXPC_MASK 0x0000FFFF
#define IXGB_PAP_TXPV_MASK 0x000F0000
#define IXGB_PAP_TXPV_10G 0x00000000
#define IXGB_PAP_TXPV_1G 0x00010000
#define IXGB_PAP_TXPV_2G 0x00020000
#define IXGB_PAP_TXPV_3G 0x00030000
#define IXGB_PAP_TXPV_4G 0x00040000
#define IXGB_PAP_TXPV_5G 0x00050000
#define IXGB_PAP_TXPV_6G 0x00060000
#define IXGB_PAP_TXPV_7G 0x00070000
#define IXGB_PAP_TXPV_8G 0x00080000
#define IXGB_PAP_TXPV_9G 0x00090000
#define IXGB_PAP_TXPV_WAN 0x000F0000
/* PCSC1 Bit Masks */
#define IXGB_PCSC1_LOOPBACK 0x00004000
/* PCSC2 Bit Masks */
#define IXGB_PCSC2_PCS_TYPE_MASK 0x00000003
#define IXGB_PCSC2_PCS_TYPE_10GBX 0x00000001
/* PCSS1 Bit Masks */
#define IXGB_PCSS1_LOCAL_FAULT 0x00000080
#define IXGB_PCSS1_RX_LINK_STATUS 0x00000004
/* PCSS2 Bit Masks */
#define IXGB_PCSS2_DEV_PRES_MASK 0x0000C000
#define IXGB_PCSS2_DEV_PRES 0x00004000
#define IXGB_PCSS2_TX_LF 0x00000800
#define IXGB_PCSS2_RX_LF 0x00000400
#define IXGB_PCSS2_10GBW 0x00000004
#define IXGB_PCSS2_10GBX 0x00000002
#define IXGB_PCSS2_10GBR 0x00000001
/* XPCSS Bit Masks */
#define IXGB_XPCSS_ALIGN_STATUS 0x00001000
#define IXGB_XPCSS_PATTERN_TEST 0x00000800
#define IXGB_XPCSS_LANE_3_SYNC 0x00000008
#define IXGB_XPCSS_LANE_2_SYNC 0x00000004
#define IXGB_XPCSS_LANE_1_SYNC 0x00000002
#define IXGB_XPCSS_LANE_0_SYNC 0x00000001
/* XPCSTC Bit Masks */
#define IXGB_XPCSTC_BERT_TRIG 0x00200000
#define IXGB_XPCSTC_BERT_SST 0x00100000
#define IXGB_XPCSTC_BERT_PSZ_MASK 0x000C0000
#define IXGB_XPCSTC_BERT_PSZ_SHIFT 17
#define IXGB_XPCSTC_BERT_PSZ_INF 0x00000003
#define IXGB_XPCSTC_BERT_PSZ_68 0x00000001
#define IXGB_XPCSTC_BERT_PSZ_1028 0x00000000
/* MSCA bit Masks */
/* New Protocol Address */
#define IXGB_MSCA_NP_ADDR_MASK 0x0000FFFF
#define IXGB_MSCA_NP_ADDR_SHIFT 0
/* Either Device Type or Register Address,depending on ST_CODE */
#define IXGB_MSCA_DEV_TYPE_MASK 0x001F0000
#define IXGB_MSCA_DEV_TYPE_SHIFT 16
#define IXGB_MSCA_PHY_ADDR_MASK 0x03E00000
#define IXGB_MSCA_PHY_ADDR_SHIFT 21
#define IXGB_MSCA_OP_CODE_MASK 0x0C000000
/* OP_CODE == 00, Address cycle, New Protocol */
/* OP_CODE == 01, Write operation */
/* OP_CODE == 10, Read operation */
/* OP_CODE == 11, Read, auto increment, New Protocol */
#define IXGB_MSCA_ADDR_CYCLE 0x00000000
#define IXGB_MSCA_WRITE 0x04000000
#define IXGB_MSCA_READ 0x08000000
#define IXGB_MSCA_READ_AUTOINC 0x0C000000
#define IXGB_MSCA_OP_CODE_SHIFT 26
#define IXGB_MSCA_ST_CODE_MASK 0x30000000
/* ST_CODE == 00, New Protocol */
/* ST_CODE == 01, Old Protocol */
#define IXGB_MSCA_NEW_PROTOCOL 0x00000000
#define IXGB_MSCA_OLD_PROTOCOL 0x10000000
#define IXGB_MSCA_ST_CODE_SHIFT 28
/* Initiate command, self-clearing when command completes */
#define IXGB_MSCA_MDI_COMMAND 0x40000000
/*MDI In Progress Enable. */
#define IXGB_MSCA_MDI_IN_PROG_EN 0x80000000
/* MSRWD bit masks */
#define IXGB_MSRWD_WRITE_DATA_MASK 0x0000FFFF
#define IXGB_MSRWD_WRITE_DATA_SHIFT 0
#define IXGB_MSRWD_READ_DATA_MASK 0xFFFF0000
#define IXGB_MSRWD_READ_DATA_SHIFT 16
/* Definitions for the TXN17401 devices on the MDIO bus. */
/* Definitions for the optics devices on the MDIO bus. */
#define IXGB_PHY_ADDRESS 0x0 /* Single PHY, multiple "Devices" */
/* Five bit Device IDs */
#define TXN17401_PMA_PMD_DID 0x01
#define TXN17401_PCS_DID 0x03
#define TXN17401_XGXS_DID 0x04
/* Standard five-bit Device IDs. See IEEE 802.3ae, clause 45 */
#define MDIO_PMA_PMD_DID 0x01
#define MDIO_WIS_DID 0x02
#define MDIO_PCS_DID 0x03
#define MDIO_XGXS_DID 0x04
/* PMA/PMD registers and bit definitions. */
/* Standard PMA/PMD registers and bit definitions. */
/* Note: This is a very limited set of definitions, */
/* 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 {
uint64_t buff_addr;
u16 length;
u16 reserved;
u8 status;
u8 errors;
u16 special;
uint16_t length;
uint16_t reserved;
uint8_t status;
uint8_t errors;
uint16_t special;
};
#define IXGB_RX_DESC_STATUS_DD 0x01
......@@ -379,23 +546,38 @@ struct ixgb_rx_desc {
#define IXGB_RX_DESC_STATUS_IXSM 0x04
#define IXGB_RX_DESC_STATUS_VP 0x08
#define IXGB_RX_DESC_STATUS_TCPCS 0x20
#define IXGB_RX_DESC_STATUS_IPCS 0x40
#define IXGB_RX_DESC_STATUS_PIF 0x80
#define IXGB_RX_DESC_ERRORS_CE 0x01
#define IXGB_RX_DESC_ERRORS_SE 0x02
#define IXGB_RX_DESC_ERRORS_P 0x08
#define IXGB_RX_DESC_ERRORS_TCPE 0x20
#define IXGB_RX_DESC_ERRORS_IPE 0x40
#define IXGB_RX_DESC_ERRORS_RXE 0x80
#define IXGB_RX_DESC_SPECIAL_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
#define IXGB_RX_DESC_SPECIAL_PRI_MASK 0xE000 /* Priority is in upper 3 bits */
#define IXGB_RX_DESC_SPECIAL_PRI_SHIFT 0x000D /* Priority is in upper 3 of 16 */
/* Layout of a single transmit descriptor. The controller assumes that this
* structure is packed into 16 bytes, which is a safe assumption with most
* compilers. However, some compilers may insert padding between the fields,
* in which case the structure must be packed in some compiler-specific
* manner. */
struct ixgb_tx_desc {
uint64_t buff_addr;
u32 cmd_type_len;
u8 status;
u8 popts;
u16 vlan;
uint32_t cmd_type_len;
uint8_t status;
uint8_t popts;
uint16_t vlan;
};
#define IXGB_TX_DESC_LENGTH_MASK 0x000FFFFF
#define IXGB_TX_DESC_TYPE_MASK 0x00F00000
#define IXGB_TX_DESC_TYPE_SHIFT 20
#define IXGB_TX_DESC_CMD_MASK 0xFF000000
#define IXGB_TX_DESC_CMD_SHIFT 24
#define IXGB_TX_DESC_CMD_EOP 0x01000000
#define IXGB_TX_DESC_CMD_TSE 0x04000000
#define IXGB_TX_DESC_CMD_RS 0x08000000
......@@ -408,18 +590,19 @@ struct ixgb_tx_desc {
#define IXGB_TX_DESC_POPTS_IXSM 0x01
#define IXGB_TX_DESC_POPTS_TXSM 0x02
#define IXGB_TX_DESC_SPECIAL_PRI_SHIFT IXGB_RX_DESC_SPECIAL_PRI_SHIFT /* Priority is in upper 3 of 16 */
struct ixgb_context_desc {
u8 ipcss;
u8 ipcso;
u16 ipcse;
u8 tucss;
u8 tucso;
u16 tucse;
u32 cmd_type_len;
u8 status;
u8 hdr_len;
u16 mss;
uint8_t ipcss;
uint8_t ipcso;
uint16_t ipcse;
uint8_t tucss;
uint8_t tucso;
uint16_t tucse;
uint32_t cmd_type_len;
uint8_t status;
uint8_t hdr_len;
uint16_t mss;
};
#define IXGB_CONTEXT_DESC_CMD_TCP 0x01000000
......@@ -430,11 +613,14 @@ struct ixgb_context_desc {
#define IXGB_CONTEXT_DESC_TYPE 0x00000000
#define IXGB_CONTEXT_DESC_STATUS_DD 0x01
/* Filters */
#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_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
#define IXGB_MEMORY_REGISTER_BASE_ADDRESS 0
#define ENET_HEADER_SIZE 14
#define ENET_FCS_LENGTH 4
#define IXGB_MAX_NUM_MULTICAST_ADDRESSES 128
......@@ -443,29 +629,46 @@ struct ixgb_context_desc {
#define IXGB_MAX_JUMBO_FRAME_SIZE 0x3F00
/* Phy Addresses */
#define IXGB_OPTICAL_PHY_ADDR 0x0 /* Optical Module phy address */
#define IXGB_XAUII_PHY_ADDR 0x1 /* Xauii transceiver phy address */
#define IXGB_DIAG_PHY_ADDR 0x1F /* Diagnostic Device phy address */
/* This structure takes a 64k flash and maps it for identification commands */
struct ixgb_flash_buffer {
uint8_t manufacturer_id;
uint8_t device_id;
uint8_t filler1[0x2AA8];
uint8_t cmd2;
uint8_t filler2[0x2AAA];
uint8_t cmd1;
uint8_t filler3[0xAAAA];
};
/*
* This is a little-endian specific check.
*/
#define IS_MULTICAST(Address) \
(boolean_t)(((u8 *)(Address))[0] & ((u8)0x01))
(boolean_t)(((uint8_t *)(Address))[0] & ((uint8_t)0x01))
/*
* Check whether an address is broadcast.
*/
#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 */
struct ixgb_fc {
u32 high_water; /* Flow Control High-water */
u32 low_water; /* Flow Control Low-water */
u16 pause_time; /* Flow Control Pause timer */
uint32_t high_water; /* Flow Control High-water */
uint32_t low_water; /* Flow Control Low-water */
uint16_t pause_time; /* Flow Control Pause timer */
boolean_t send_xon; /* Flow control send XON */
ixgb_fc_type type; /* Type of flow control */
};
/* The historical defaults for the flow control values are given below. */
#define FC_DEFAULT_HI_THRESH (0x8000) /* 32KB */
#define FC_DEFAULT_LO_THRESH (0x4000) /* 16KB */
#define FC_DEFAULT_TX_TIMER (0x100) /* ~130 us */
/* Phy definitions */
#define IXGB_MAX_PHY_REG_ADDRESS 0xFFFF
......@@ -480,32 +683,40 @@ struct ixgb_bus {
};
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 */
struct ixgb_fc fc; /* Flow control parameters */
struct ixgb_bus bus; /* Bus parameters */
u32 phy_id; /* Phy Identifier */
u32 phy_addr; /* XGMII address of Phy */
uint32_t phy_id; /* Phy Identifier */
uint32_t phy_addr; /* XGMII address of Phy */
ixgb_mac_type mac_type; /* Identifier for MAC controller */
u32 max_frame_size; /* Maximum frame size supported */
u32 mc_filter_type; /* Multicast filter hash type */
u32 num_mc_addrs; /* Number of current Multicast addrs */
u8 curr_mac_addr[IXGB_ETH_LENGTH_OF_ADDRESS]; /* Individual address currently programmed in MAC */
u32 num_tx_desc; /* Number of Transmit descriptors */
u32 num_rx_desc; /* Number of Receive descriptors */
u32 rx_buffer_size; /* Size of Receive buffer */
ixgb_phy_type phy_type; /* Transceiver/phy identifier */
uint32_t max_frame_size; /* Maximum frame size supported */
uint32_t mc_filter_type; /* Multicast filter hash type */
uint32_t num_mc_addrs; /* Number of current Multicast addrs */
uint8_t curr_mac_addr[IXGB_ETH_LENGTH_OF_ADDRESS]; /* Individual address currently programmed in MAC */
uint32_t num_tx_desc; /* Number of Transmit descriptors */
uint32_t num_rx_desc; /* Number of Receive descriptors */
uint32_t rx_buffer_size; /* Size of Receive buffer */
boolean_t link_up; /* TRUE if link is valid */
boolean_t adapter_stopped; /* State of adapter */
u16 device_id; /* device id from PCI configuration space */
u16 vendor_id; /* vendor id from PCI configuration space */
u16 subsystem_vendor_id; /* subsystem vendor id from PCI configuration space */
u16 subsystem_id; /* subsystem id from PCI configuration space */
u16 eeprom[IXGB_EEPROM_SIZE]; /* EEPROM contents read at init time */
uint64_t io_base; /* Our I/O mapped location */
u32 lastLFC;
u32 lastRFC;
uint16_t device_id; /* device id from PCI configuration space */
uint16_t vendor_id; /* vendor id from PCI configuration space */
uint8_t revision_id; /* revision id from PCI configuration space */
uint16_t subsystem_vendor_id; /* subsystem vendor id from PCI configuration space */
uint16_t subsystem_id; /* subsystem id from PCI configuration space */
uint32_t bar0; /* Base Address registers */
uint32_t bar1;
uint32_t bar2;
uint32_t bar3;
uint16_t pci_cmd_word; /* PCI command register id from PCI configuration space */
uint16_t eeprom[IXGB_EEPROM_SIZE]; /* EEPROM contents read at init time */
unsigned long io_base; /* Our I/O mapped location */
uint32_t lastLFC;
uint32_t lastRFC;
};
/* Statistics reported by the hardware */
struct ixgb_hw_stats {
uint64_t tprl;
uint64_t tprh;
......@@ -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_setup_fc(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,
u32 reg_addr,
u32 phy_addr, u32 device_type);
extern uint16_t ixgb_read_phy_reg(struct ixgb_hw *hw,
uint32_t reg_addr,
uint32_t phy_addr, uint32_t device_type);
extern void ixgb_write_phy_reg(struct ixgb_hw *hw,
u32 reg_addr,
u32 phy_addr,
u32 device_type, u16 data);
uint32_t reg_addr,
uint32_t phy_addr,
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) */
extern void ixgb_mc_addr_list_update(struct ixgb_hw *hw,
u8 * mc_addr_list,
u32 mc_addr_count, u32 pad);
uint8_t * mc_addr_list,
uint32_t mc_addr_count, uint32_t pad);
/* Vfta functions */
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);
/* Access functions to eeprom data */
void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, u8 * mac_addr);
u16 ixgb_get_ee_compatibility(struct ixgb_hw *hw);
u32 ixgb_get_ee_pba_number(struct ixgb_hw *hw);
u16 ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw);
u16 ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw *hw);
u16 ixgb_get_ee_subsystem_id(struct ixgb_hw *hw);
u16 ixgb_get_ee_subvendor_id(struct ixgb_hw *hw);
u16 ixgb_get_ee_device_id(struct ixgb_hw *hw);
u16 ixgb_get_ee_vendor_id(struct ixgb_hw *hw);
u16 ixgb_get_ee_swdpins_reg(struct ixgb_hw *hw);
u8 ixgb_get_ee_d3_power(struct ixgb_hw *hw);
u8 ixgb_get_ee_d0_power(struct ixgb_hw *hw);
void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t * mac_addr);
uint16_t ixgb_get_ee_compatibility(struct ixgb_hw *hw);
uint32_t ixgb_get_ee_pba_number(struct ixgb_hw *hw);
uint16_t ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw);
uint16_t ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw *hw);
uint16_t ixgb_get_ee_subsystem_id(struct ixgb_hw *hw);
uint16_t ixgb_get_ee_subvendor_id(struct ixgb_hw *hw);
uint16_t ixgb_get_ee_device_id(struct ixgb_hw *hw);
uint16_t ixgb_get_ee_vendor_id(struct ixgb_hw *hw);
uint16_t ixgb_get_ee_swdpins_reg(struct ixgb_hw *hw);
uint8_t ixgb_get_ee_d3_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);
uint16_t ixgb_get_eeprom_word(struct ixgb_hw *hw, uint16_t index);
/* Everything else */
void ixgb_led_on(struct ixgb_hw *hw);
void ixgb_led_off(struct ixgb_hw *hw);
void ixgb_write_pci_cfg(struct ixgb_hw *hw, u32 reg, u16 * value);
void ixgb_write_pci_cfg(struct ixgb_hw *hw, uint32_t reg, uint16_t * value);
#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
under the terms of the GNU General Public License as published by the Free
......@@ -23,6 +23,7 @@
Contact Information:
Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#ifndef _IXGB_IDS_H_
......@@ -36,8 +37,16 @@
#define INTEL_SUBVENDOR_ID 0x8086
#define IXGB_DEVICE_ID_82597EX 0x1048
#define IXGB_SUBDEVICE_ID_A11F 0xA11F /* Adapter-OEM-1310nm-Fiber */
#define IXGB_SUBDEVICE_ID_A01F 0xA01F /* Adapter-Retail-1310nm-Fiber */
#define IXGB_DEVICE_ID_82597EX_SR 0x1A48
#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_ */
......
/*******************************************************************************
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
under the terms of the GNU General Public License as published by the Free
......@@ -23,36 +23,29 @@
Contact Information:
Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#define __IXGB_MAIN__
*******************************************************************************/
#include "ixgb.h"
char ixgb_driver_name[] = "ixgb";
char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
char ixgb_driver_version[] = "1.0.47-k1jg";
char ixgb_copyright[] = "Copyright (c) 2001-2003 Intel Corporation.";
char ixgb_driver_version[] = "1.0.66";
char ixgb_copyright[] = "Copyright (c) 2001-2004 Intel Corporation.";
/* 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
* Last entry must be all 0s
*
* { 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[] = {
/* 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,
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 */
{0,}
......@@ -60,10 +53,6 @@ static struct pci_device_id ixgb_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, ixgb_pci_tbl);
static char *ixgb_strings[] = {
"Intel(R) PRO/10GbE Network Connection"
};
/* Local Function Prototypes */
int ixgb_up(struct ixgb_adapter *adapter);
......@@ -73,8 +62,8 @@ void ixgb_reset(struct ixgb_adapter *adapter);
static int ixgb_init_module(void);
static void ixgb_exit_module(void);
static int ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
static void ixgb_remove(struct pci_dev *pdev);
static void ixgb_sw_init(struct ixgb_adapter *adapter);
static void __devexit ixgb_remove(struct pci_dev *pdev);
static int ixgb_sw_init(struct ixgb_adapter *adapter);
static int ixgb_open(struct net_device *netdev);
static int ixgb_close(struct net_device *netdev);
static int ixgb_setup_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_set_multi(struct net_device *netdev);
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 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 int ixgb_change_mtu(struct net_device *netdev, int new_mtu);
static int ixgb_set_mac(struct net_device *netdev, void *p);
......@@ -105,20 +85,35 @@ static void ixgb_update_stats(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 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
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
static void ixgb_clean_rx_irq(struct ixgb_adapter *adapter);
static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter);
#endif
static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter);
static int ixgb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
static inline void ixgb_rx_checksum(struct ixgb_adapter *adapter,
struct ixgb_rx_desc *rx_desc,
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,
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 = {
.notifier_call = ixgb_notify_reboot,
......@@ -152,24 +147,20 @@ MODULE_LICENSE("GPL");
#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
* loaded. All it does is register with the PCI subsystem.
**/
static int __init
ixgb_init_module(void)
static int __init ixgb_init_module(void)
{
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);
#ifdef CONFIG_IXGB_NAPI
printk(KERN_INFO "NAPI Enabled\n");
#endif
ret = pci_module_init(&ixgb_driver);
if (ret >= 0) {
register_reboot_notifier(&ixgb_notifier_reboot);
......@@ -180,47 +171,31 @@ ixgb_init_module(void)
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
* from memory.
**/
static void __exit
ixgb_exit_module(void)
static void __exit ixgb_exit_module(void)
{
IXGB_DBG("ixgb_exit_module\n");
unregister_reboot_notifier(&ixgb_notifier_reboot);
pci_unregister_driver(&ixgb_driver);
}
module_exit(ixgb_exit_module);
/**
* 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)
int ixgb_up(struct ixgb_adapter *adapter)
{
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");
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 has been reset, we need to reload some things */
/* hardware was reset in probe/down, we need to reload some things */
ixgb_set_multi(netdev);
ixgb_restore_vlan(adapter);
ixgb_configure_tx(adapter);
......@@ -228,31 +203,45 @@ ixgb_up(struct ixgb_adapter *adapter)
ixgb_configure_rx(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);
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;
}
/**
* 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)
void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog)
{
struct net_device *netdev = adapter->netdev;
IXGB_DBG("ixgb_down\n");
ixgb_irq_disable(adapter);
free_irq(netdev->irq, netdev);
free_irq(adapter->pdev->irq, netdev);
if (kill_watchdog)
del_timer_sync(&adapter->watchdog_timer);
adapter->link_speed = 0;
......@@ -261,21 +250,12 @@ ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog)
netif_stop_queue(netdev);
ixgb_reset(adapter);
ixgb_clean_tx_ring(adapter);
ixgb_clean_rx_ring(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)
void ixgb_reset(struct ixgb_adapter *adapter)
{
IXGB_DBG("ixgb_reset\n");
ixgb_adapter_stop(&adapter->hw);
if (!ixgb_init_hw(&adapter->hw))
......@@ -283,11 +263,15 @@ ixgb_reset(struct ixgb_adapter *adapter)
}
/**
* ixgb_probe - Device Initialization Routine.
* @param pdev PCI device information struct
* @param ent entry in ixgb_pci_table
* ixgb_probe - Device Initialization Routine
* @pdev: PCI device information struct
* @ent: entry in ixgb_pci_tbl
*
* 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
......@@ -300,35 +284,29 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int mmio_len;
int pci_using_dac;
int i;
int err;
IXGB_DBG("ixgb_probe\n");
if ((i = pci_enable_device(pdev))) {
IXGB_ERR("pci_enable_device failed\n");
return i;
}
if ((err = pci_enable_device(pdev)))
return err;
if (!(i = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
pci_using_dac = 1;
} 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");
return i;
return err;
}
pci_using_dac = 0;
}
if ((i = pci_request_regions(pdev, ixgb_driver_name))) {
IXGB_ERR("Failed to reserve PCI I/O and Memory resources.\n");
return i;
}
if ((err = pci_request_regions(pdev, ixgb_driver_name)))
return err;
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) {
IXGB_ERR("Unable to allocate net_device struct\n");
err = -ENOMEM;
goto err_alloc_etherdev;
}
......@@ -345,8 +323,10 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
mmio_len = pci_resource_len(pdev, BAR_0);
adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
if (!adapter->hw.hw_addr)
if (!adapter->hw.hw_addr) {
err = -EIO;
goto err_ioremap;
}
for (i = BAR_1; i <= BAR_5; i++) {
if (pci_resource_len(pdev, i) == 0)
......@@ -356,8 +336,6 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
}
IXGB_DBG("mmio_start<%lx> hw_addr<%p>\n", mmio_start,
adapter->hw.hw_addr);
netdev->open = &ixgb_open;
netdev->stop = &ixgb_close;
......@@ -370,25 +348,28 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->tx_timeout = &ixgb_tx_timeout;
netdev->watchdog_timeo = HZ;
#ifdef CONFIG_IXGB_NAPI
netdev->poll = &ixgb_poll;
netdev->poll = &ixgb_clean;
netdev->weight = 64;
#endif
netdev->vlan_rx_register = ixgb_vlan_rx_register;
netdev->vlan_rx_add_vid = ixgb_vlan_rx_add_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_end = mmio_start + mmio_len;
netdev->base_addr = adapter->hw.io_base;
adapter->bd_number = cards_found;
adapter->id_string = ixgb_strings[ent->driver_data];
adapter->link_speed = 0;
adapter->link_duplex = 0;
/* setup the private structure */
ixgb_sw_init(adapter);
if ((err = ixgb_sw_init(adapter)))
goto err_sw_init;
netdev->features = NETIF_F_SG |
NETIF_F_HW_CSUM |
......@@ -403,57 +384,59 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* make sure the EEPROM is good */
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;
}
ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr);
if (!is_valid_ether_addr(netdev->dev_addr)) {
IXGB_DBG("Invalid MAC address in EEPROM.\n");
err = -EIO;
goto err_eeprom;
}
adapter->max_data_per_txd = IXGB_MAX_JUMBO_FRAME_SIZE;
adapter->part_num = ixgb_get_ee_pba_number(&adapter->hw);
init_timer(&adapter->watchdog_timer);
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,
(void (*)(void *)) ixgb_tx_timeout_task, netdev);
(void (*)(void *))ixgb_tx_timeout_task, netdev);
register_netdev(netdev);
memcpy(adapter->ifname, netdev->name, IFNAMSIZ);
adapter->ifname[IFNAMSIZ - 1] = 0;
if ((err = register_netdev(netdev)))
goto err_register;
/* we're going to reset, so assume we have no link for now */
netif_carrier_off(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);
/* reset the hardware with the new settings */
ixgb_reset(adapter);
cards_found++;
return 0;
err_register:
err_sw_init:
err_eeprom:
iounmap(adapter->hw.hw_addr);
err_ioremap:
pci_release_regions(pdev);
free_netdev(netdev);
err_alloc_etherdev:
return -ENOMEM;
pci_release_regions(pdev);
return err;
}
/**
* ixgb_remove - Device Removal Routine.
* @param pdev PCI device information struct
* ixgb_remove - Device Removal Routine
* @pdev: PCI device information struct
*
* 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
......@@ -461,49 +444,36 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* memory.
**/
static void __devexit
ixgb_remove(struct pci_dev *pdev)
static void __devexit ixgb_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgb_adapter *adapter = netdev->priv;
IXGB_DBG("ixgb_remove\n");
unregister_netdev(netdev);
#ifdef ETHTOOL_IDENTIFY
ixgb_identify_stop(adapter);
#endif
iounmap((void *) adapter->hw.hw_addr);
iounmap(adapter->hw.hw_addr);
pci_release_regions(pdev);
free_netdev(netdev);
}
/**
* ixgb_sw_init - Initialize general software structures (struct ixgb_adapter).
* @param adapter board private structure to initialize
* ixgb_sw_init - Initialize general software structures (struct ixgb_adapter)
* @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
* OS network device settings (MTU size).
**/
static void __devinit
ixgb_sw_init(struct ixgb_adapter *adapter)
static int __devinit ixgb_sw_init(struct ixgb_adapter *adapter)
{
struct ixgb_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
IXGB_DBG("ixgb_sw_init\n");
/* PCI config space info */
/* FIXME: do not store, instead directly use struct pci_dev
* where needed
*/
hw->vendor_id = pdev->vendor;
hw->device_id = pdev->device;
hw->subsystem_vendor_id = pdev->subsystem_vendor;
......@@ -513,7 +483,8 @@ ixgb_sw_init(struct ixgb_adapter *adapter)
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;
else {
/* should never have loaded on this device */
......@@ -524,11 +495,14 @@ ixgb_sw_init(struct ixgb_adapter *adapter)
hw->fc.send_xon = 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.
* @param netdev network interface device structure
* ixgb_open - Called when a network interface is made active
* @netdev: network interface device structure
*
* Returns 0 on success, negative value on failure
*
......@@ -539,27 +513,22 @@ ixgb_sw_init(struct ixgb_adapter *adapter)
* and the stack is notified that the interface is ready.
**/
static int
ixgb_open(struct net_device *netdev)
static int ixgb_open(struct net_device *netdev)
{
struct ixgb_adapter *adapter = netdev->priv;
IXGB_DBG("ixgb_open\n");
int err;
/* allocate transmit descriptors */
if (ixgb_setup_tx_resources(adapter)) {
IXGB_DBG("ixgb_open: failed ixgb_setup_tx_resources.\n");
if ((err = ixgb_setup_tx_resources(adapter)))
goto err_setup_tx;
}
/* allocate receive descriptors and buffers */
/* allocate receive descriptors */
if (ixgb_setup_rx_resources(adapter)) {
IXGB_DBG("ixgb_open: failed ixgb_setup_rx_resources.\n");
if ((err = ixgb_setup_rx_resources(adapter)))
goto err_setup_rx;
}
if (ixgb_up(adapter))
if ((err = ixgb_up(adapter)))
goto err_up;
return 0;
......@@ -570,12 +539,13 @@ ixgb_open(struct net_device *netdev)
ixgb_free_tx_resources(adapter);
err_setup_tx:
ixgb_reset(adapter);
return -EBUSY;
return err;
}
/**
* ixgb_close - Disables a network interface.
* @param netdev network interface device structure
* ixgb_close - Disables a network interface
* @netdev: network interface device structure
*
* Returns 0, this is not allowed to fail
*
......@@ -585,13 +555,10 @@ ixgb_open(struct net_device *netdev)
* hardware, and all transmit and receive resources are freed.
**/
static int
ixgb_close(struct net_device *netdev)
static int ixgb_close(struct net_device *netdev)
{
struct ixgb_adapter *adapter = netdev->priv;
IXGB_DBG("ixgb_close\n");
ixgb_down(adapter, TRUE);
ixgb_free_tx_resources(adapter);
......@@ -601,22 +568,19 @@ ixgb_close(struct net_device *netdev)
}
/**
* ixgb_setup_tx_resources - allocate Tx resources (Descriptors).
* @param adapter board private structure
* ixgb_setup_tx_resources - allocate Tx resources (Descriptors)
* @adapter: board private structure
*
* Return 0 on success, negative on failure
**/
static int
ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
static int ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
struct ixgb_desc_ring *txdr = &adapter->tx_ring;
struct pci_dev *pdev = adapter->pdev;
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);
if (!txdr->buffer_info) {
return -ENOMEM;
......@@ -624,7 +588,8 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
memset(txdr->buffer_info, 0, size);
/* 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);
txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
......@@ -634,10 +599,6 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
}
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_clean = 0;
......@@ -646,21 +607,18 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
/**
* 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.
**/
static void
ixgb_configure_tx(struct ixgb_adapter *adapter)
static void 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;
uint32_t tdlen = adapter->tx_ring.count * sizeof(struct ixgb_tx_desc);
uint32_t tctl;
struct ixgb_hw *hw = &adapter->hw;
IXGB_DBG("ixgb_configure_tx\n");
/* Setup the Base and Length of the Tx Descriptor Ring
* tx_ring.dma can be either a 32 or 64 bit value
*/
......@@ -694,27 +652,24 @@ ixgb_configure_tx(struct ixgb_adapter *adapter)
/* Setup Transmit Descriptor Settings for this adapter */
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);
}
/**
* ixgb_setup_rx_resources - allocate Rx resources (Descriptors).
* @param adapter board private structure
* ixgb_setup_rx_resources - allocate Rx resources (Descriptors)
* @adapter: board private structure
*
* Returns 0 on success, negative on failure
**/
static int
ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
static int ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
struct pci_dev *pdev = adapter->pdev;
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);
if (!rxdr->buffer_info) {
return -ENOMEM;
......@@ -722,42 +677,35 @@ ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
memset(rxdr->buffer_info, 0, size);
/* 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);
rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
if (!rxdr->desc) {
IXGB_DBG("pci_alloc_consistent failed.\n");
kfree(rxdr->buffer_info);
return -ENOMEM;
}
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_use = 0;
return 0;
}
/**
* ixgb_setup_rctl - configure the receive control register.
* @param adapter Board private structure
* ixgb_setup_rctl - configure the receive control register
* @adapter: Board private structure
**/
static void
ixgb_setup_rctl(struct ixgb_adapter *adapter)
static void ixgb_setup_rctl(struct ixgb_adapter *adapter)
{
u32 rctl;
uint32_t rctl;
rctl = IXGB_READ_REG(&adapter->hw, RCTL);
IXGB_DBG("ixgb_setup_rctl\n");
rctl &= ~(3 << IXGB_RCTL_MO_SHIFT);
rctl |=
......@@ -782,35 +730,37 @@ ixgb_setup_rctl(struct ixgb_adapter *adapter)
rctl |= IXGB_RCTL_BSIZE_16384;
break;
}
IXGB_WRITE_REG(&adapter->hw, RCTL, rctl);
}
/**
* 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.
**/
static void
ixgb_configure_rx(struct ixgb_adapter *adapter)
static void ixgb_configure_rx(struct ixgb_adapter *adapter)
{
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;
u32 rctl;
u32 rxcsum;
IXGB_DBG("ixgb_configure_rx\n");
uint32_t rctl;
uint32_t rxcsum;
uint32_t rxdctl;
/* make sure receives are disabled while setting up the descriptors */
rctl = IXGB_READ_REG(hw, RCTL);
IXGB_WRITE_REG(hw, RCTL, rctl & ~IXGB_RCTL_RXEN);
/* set the Receive Delay Timer Register */
IXGB_WRITE_REG(hw, RDTR, adapter->rx_int_delay);
/* Setup the Base and Length of the Rx Descriptor Ring */
IXGB_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL));
IXGB_WRITE_REG(hw, RDBAH, (rdba >> 32));
......@@ -820,18 +770,15 @@ ixgb_configure_rx(struct ixgb_adapter *adapter)
IXGB_WRITE_REG(hw, RDH, 0);
IXGB_WRITE_REG(hw, RDT, 0);
{
u32 rxdctl;
/* burst 16 or burst when RXT0 */
rxdctl = RXDCTL_WTHRESH_DEFAULT << IXGB_RXDCTL_WTHRESH_SHIFT
| RXDCTL_HTHRESH_DEFAULT << IXGB_RXDCTL_HTHRESH_SHIFT
| RXDCTL_PTHRESH_DEFAULT << IXGB_RXDCTL_PTHRESH_SHIFT;
IXGB_WRITE_REG(hw, RXDCTL, rxdctl);
}
if (adapter->raidc) {
u32 raidc;
u8 poll_threshold;
uint32_t raidc;
uint8_t poll_threshold;
/* Poll every rx_int_delay period, if RBD exists
* Receive Backlog Detection is set to <threshold>
......@@ -879,167 +826,180 @@ ixgb_configure_rx(struct ixgb_adapter *adapter)
}
/**
* ixgb_free_tx_resources - Free Tx Resources.
* @param adapter board private structure
* ixgb_free_tx_resources - Free Tx Resources
* @adapter: board private structure
*
* Free all transmit software resources
**/
static void
ixgb_free_tx_resources(struct ixgb_adapter *adapter)
static void ixgb_free_tx_resources(struct ixgb_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
IXGB_DBG("ixgb_free_tx_resources\n");
ixgb_clean_tx_ring(adapter);
kfree(adapter->tx_ring.buffer_info);
adapter->tx_ring.buffer_info = NULL;
pci_free_consistent(pdev, adapter->tx_ring.size, adapter->tx_ring.desc,
adapter->tx_ring.dma);
pci_free_consistent(pdev, adapter->tx_ring.size,
adapter->tx_ring.desc, adapter->tx_ring.dma);
adapter->tx_ring.desc = NULL;
}
/**
* ixgb_clean_tx_ring - Free Tx Buffers.
* @param adapter board private structure
* ixgb_clean_tx_ring - Free Tx Buffers
* @adapter: board private structure
**/
static void
ixgb_clean_tx_ring(struct ixgb_adapter *adapter)
static void 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;
unsigned long size;
int i;
IXGB_DBG("ixgb_clean_tx_ring\n");
unsigned int i;
/* Free all the Tx ring sk_buffs */
for (i = 0; i < adapter->tx_ring.count; i++) {
if (adapter->tx_ring.buffer_info[i].skb) {
for (i = 0; i < tx_ring->count; i++) {
buffer_info = &tx_ring->buffer_info[i];
if (buffer_info->skb) {
pci_unmap_page(pdev,
adapter->tx_ring.buffer_info[i].dma,
adapter->tx_ring.buffer_info[i].length,
PCI_DMA_TODEVICE);
buffer_info->dma,
buffer_info->length, 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;
memset(adapter->tx_ring.buffer_info, 0, size);
size = sizeof(struct ixgb_buffer) * tx_ring->count;
memset(tx_ring->buffer_info, 0, size);
/* 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;
adapter->tx_ring.next_to_clean = 0;
tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0;
IXGB_WRITE_REG(&adapter->hw, TDH, 0);
IXGB_WRITE_REG(&adapter->hw, TDT, 0);
}
/**
* ixgb_free_rx_resources - Free Rx Resources.
* @param adapter board private structure
* ixgb_free_rx_resources - Free Rx Resources
* @adapter: board private structure
*
* Free all receive software resources
**/
static void
ixgb_free_rx_resources(struct ixgb_adapter *adapter)
static void ixgb_free_rx_resources(struct ixgb_adapter *adapter)
{
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
struct pci_dev *pdev = adapter->pdev;
IXGB_DBG("ixgb_free_rx_resources\n");
ixgb_clean_rx_ring(adapter);
kfree(adapter->rx_ring.buffer_info);
adapter->rx_ring.buffer_info = NULL;
kfree(rx_ring->buffer_info);
rx_ring->buffer_info = NULL;
pci_free_consistent(pdev, adapter->rx_ring.size,
adapter->rx_ring.desc, adapter->rx_ring.dma);
pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
adapter->rx_ring.desc = NULL;
rx_ring->desc = NULL;
}
/**
* ixgb_clean_rx_ring - Free Rx Buffers.
* @param adapter board private structure
* ixgb_clean_rx_ring - Free Rx Buffers
* @adapter: board private structure
**/
static void
ixgb_clean_rx_ring(struct ixgb_adapter *adapter)
static void 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;
unsigned long size;
int i;
IXGB_DBG("ixgb_free_rx_ring\n");
unsigned int i;
/* Free all the Rx ring sk_buffs */
for (i = 0; i < adapter->rx_ring.count; i++) {
if (adapter->rx_ring.buffer_info[i].skb) {
for (i = 0; i < rx_ring->count; i++) {
buffer_info = &rx_ring->buffer_info[i];
if (buffer_info->skb) {
pci_unmap_single(pdev,
adapter->rx_ring.buffer_info[i].dma,
adapter->rx_ring.buffer_info[i].length,
buffer_info->dma,
buffer_info->length,
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;
memset(adapter->rx_ring.buffer_info, 0, size);
size = sizeof(struct ixgb_buffer) * rx_ring->count;
memset(rx_ring->buffer_info, 0, size);
/* 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;
adapter->rx_ring.next_to_use = 0;
rx_ring->next_to_clean = 0;
rx_ring->next_to_use = 0;
IXGB_WRITE_REG(&adapter->hw, RDH, 0);
IXGB_WRITE_REG(&adapter->hw, RDT, 0);
}
/**
* ixgb_set_multi - Multicast and Promiscuous mode set.
* @param netdev network interface device structure
* ixgb_set_mac - Change the Ethernet Address of the NIC
* @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
* 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.
**/
void
ixgb_set_multi(struct net_device *netdev)
static void ixgb_set_multi(struct net_device *netdev)
{
struct ixgb_adapter *adapter = netdev->priv;
struct ixgb_hw *hw = &adapter->hw;
u32 rctl;
int i;
struct dev_mc_list *mc_ptr;
IXGB_DBG("ixgb_set_multi <%x>\n", netdev->flags);
uint32_t rctl;
int i;
/* 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) {
rctl |= (IXGB_RCTL_UPE | IXGB_RCTL_MPE);
......@@ -1054,7 +1014,7 @@ ixgb_set_multi(struct net_device *netdev)
rctl |= IXGB_RCTL_MPE;
IXGB_WRITE_REG(hw, RCTL, rctl);
} 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);
......@@ -1068,15 +1028,16 @@ ixgb_set_multi(struct net_device *netdev)
}
/**
* ixgb_watchdog - Timer Call-back.
* @param data pointer to adapter cast into an unsigned long
* ixgb_watchdog - Timer Call-back
* @data: pointer to netdev cast into an unsigned long
**/
void
ixgb_watchdog(unsigned long data)
static void 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 ixgb_desc_ring *txdr = &adapter->tx_ring;
unsigned int i;
ixgb_check_for_link(&adapter->hw);
......@@ -1096,35 +1057,34 @@ ixgb_watchdog(unsigned long data)
}
} else {
if (netif_carrier_ok(netdev)) {
printk(KERN_INFO "ixgb: %s NIC Link is Down\n",
netdev->name);
adapter->link_speed = 0;
adapter->link_duplex = 0;
printk(KERN_INFO
"ixgb: %s NIC Link is Down\n", netdev->name);
netif_carrier_off(netdev);
netif_stop_queue(netdev);
ixgb_down(adapter, FALSE);
ixgb_up(adapter);
}
}
ixgb_update_stats(adapter);
/* Early detection of hung controller */
{
struct ixgb_desc_ring *txdr = &adapter->tx_ring;
int i = txdr->next_to_clean;
if (!netif_carrier_ok(netdev)) {
if (IXGB_DESC_UNUSED(txdr) + 1 < txdr->count) {
/* We've lost link, so the controller stops DMA,
* but we've got queued Tx work that's never going
* to get done, so reset controller to flush Tx.
* (Do the reset outside of interrupt context). */
schedule_work(&adapter->tx_timeout_task);
}
}
/* 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))
{
IXGB_DBG
("ixgb: %s Hung controller? Watchdog stopping queue\n",
netdev->name);
netif_stop_queue(netdev);
}
}
/* generate an interrupt to force clean up of any stragglers */
IXGB_WRITE_REG(&adapter->hw, ICS, IXGB_INT_TXDW);
......@@ -1137,20 +1097,14 @@ ixgb_watchdog(unsigned long data)
#define IXGB_TX_FLAGS_VLAN 0x00000002
#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
ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb)
{
#ifdef NETIF_F_TSO
struct ixgb_context_desc *context_desc;
int i;
u8 ipcss, ipcso, tucss, tucso, hdr_len;
u16 ipcse, tucse, mss;
unsigned int i;
uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
uint16_t ipcse, tucse, mss;
if (likely(skb_shinfo(skb)->tso_size)) {
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)
skb->nh.iph->daddr,
0, IPPROTO_TCP, 0);
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;
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;
i = adapter->tx_ring.next_to_use;
......@@ -1193,32 +1147,28 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb)
| (skb->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;
return TRUE;
}
#endif
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
ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb)
{
struct ixgb_context_desc *context_desc;
int i;
u8 css, cso;
unsigned int i;
uint8_t css, cso;
if (likely(skb->ip_summed == CHECKSUM_HW)) {
css = skb->h.raw - skb->data;
cso = (skb->h.raw + skb->csum) - skb->data;
i = adapter->tx_ring.next_to_use;
context_desc = IXGB_CONTEXT_DESC(adapter->tx_ring, i);
......@@ -1226,7 +1176,7 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb)
context_desc->tucso = cso;
context_desc->tucse = 0;
/* 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->hdr_len = 0;
context_desc->mss = 0;
......@@ -1234,7 +1184,8 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb)
cpu_to_le32(IXGB_CONTEXT_DESC_TYPE
| 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;
return TRUE;
......@@ -1243,43 +1194,41 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb)
return FALSE;
}
/**
* ixgb_tx_map - private function for mapping send data to hardware addresses.
*
* @param adapter board private structure
* @param skb structure containing data to send
**/
#define IXGB_MAX_TXD_PWR 14
#define IXGB_MAX_DATA_PER_TXD (1<<IXGB_MAX_TXD_PWR)
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;
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;
len = skb->len - skb->data_len;
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
unsigned int f;
len -= skb->data_len;
i = (tx_ring->next_to_use + tx_ring->count - 1) % tx_ring->count;
count = 0;
offset = 0;
i = tx_ring->next_to_use;
while (len) {
i = (i + 1) % tx_ring->count;
size = min(len, adapter->max_data_per_txd);
tx_ring->buffer_info[i].length = size;
tx_ring->buffer_info[i].dma =
pci_map_single(adapter->pdev, skb->data + offset, size,
PCI_DMA_TODEVICE);
tx_ring->buffer_info[i].time_stamp = jiffies;
buffer_info = &tx_ring->buffer_info[i];
size = min(len, IXGB_MAX_JUMBO_FRAME_SIZE);
buffer_info->length = size;
buffer_info->dma =
pci_map_single(adapter->pdev,
skb->data + offset, size, PCI_DMA_TODEVICE);
buffer_info->time_stamp = jiffies;
len -= size;
offset += size;
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;
frag = &skb_shinfo(skb)->frags[f];
......@@ -1287,44 +1236,41 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb)
offset = 0;
while (len) {
i = (i + 1) % tx_ring->count;
size = min(len, adapter->max_data_per_txd);
tx_ring->buffer_info[i].length = size;
tx_ring->buffer_info[i].dma =
pci_map_page(adapter->pdev, frag->page,
frag->page_offset + offset, size,
PCI_DMA_TODEVICE);
buffer_info = &tx_ring->buffer_info[i];
size = min(len, IXGB_MAX_JUMBO_FRAME_SIZE);
buffer_info->length = size;
buffer_info->dma =
pci_map_page(adapter->pdev,
frag->page,
frag->page_offset + offset,
size, PCI_DMA_TODEVICE);
buffer_info->time_stamp = jiffies;
tx_ring->buffer_info[i].time_stamp = jiffies;
len -= size;
offset += size;
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[first].next_to_watch = i;
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
ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,
int tx_flags)
{
struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
struct ixgb_tx_desc *tx_desc = NULL;
u32 cmd_type_len = adapter->tx_cmd_type;
u8 status = 0;
u8 popts = 0;
int i;
struct ixgb_buffer *buffer_info;
uint32_t cmd_type_len = adapter->tx_cmd_type;
uint8_t status = 0;
uint8_t popts = 0;
unsigned int i;
if (tx_flags & IXGB_TX_FLAGS_TSO) {
cmd_type_len |= IXGB_TX_DESC_CMD_TSE;
......@@ -1341,18 +1287,21 @@ ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,
i = tx_ring->next_to_use;
while (count--) {
buffer_info = &tx_ring->buffer_info[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 =
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->popts = popts;
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
* know there are new descriptors to fetch. (Only
......@@ -1364,95 +1313,70 @@ ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,
IXGB_WRITE_REG(&adapter->hw, TDT, i);
}
#define TXD_USE_COUNT(S, X) (((S) / (X)) + (((S) % (X)) ? 1 : 0))
/**
* 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
**/
/* 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)
static int ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct ixgb_adapter *adapter = netdev->priv;
unsigned int first;
unsigned int tx_flags = 0;
unsigned long flags;
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);
return 0;
}
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
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)) {
spin_lock_irqsave(&adapter->tx_lock, flags);
if (unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED)) {
netif_stop_queue(netdev);
spin_unlock_irqrestore(&adapter->tx_lock, flags);
return 1;
}
spin_unlock_irqrestore(&adapter->tx_lock, flags);
if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
tx_flags |= IXGB_TX_FLAGS_VLAN;
vlan_id = vlan_tx_tag_get(skb);
}
first = adapter->tx_ring.next_to_use;
if (ixgb_tso(adapter, skb))
tx_flags |= IXGB_TX_FLAGS_TSO;
else if (ixgb_tx_csum(adapter, skb))
tx_flags |= IXGB_TX_FLAGS_CSUM;
count = ixgb_tx_map(adapter, skb);
ixgb_tx_queue(adapter, count, vlan_id, tx_flags);
ixgb_tx_queue(adapter, ixgb_tx_map(adapter, skb, first), vlan_id,
tx_flags);
netdev->trans_start = jiffies;
return 0;
}
/**
* ixgb_tx_timeout - Respond to a Tx Hang by resetting the adapter.
* @param netdev network interface device structure
* ixgb_tx_timeout - Respond to a Tx Hang
* @netdev: network interface device structure
**/
static void
ixgb_tx_timeout(struct net_device *netdev)
static void ixgb_tx_timeout(struct net_device *netdev)
{
struct ixgb_adapter *adapter = netdev->priv;
IXGB_DBG("ixgb_tx_timeout\n");
/* Do the reset outside of interrupt context */
schedule_work(&adapter->tx_timeout_task);
}
/**
* 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)
static void ixgb_tx_timeout_task(struct net_device *netdev)
{
struct ixgb_adapter *adapter = netdev->priv;
IXGB_DBG("ixgb_tx_timeout_task\n");
netif_device_detach(netdev);
ixgb_down(adapter, TRUE);
ixgb_up(adapter);
......@@ -1460,15 +1384,14 @@ ixgb_tx_timeout_task(struct net_device *netdev)
}
/**
* ixgb_get_stats - Get System Network Statistics.
* @param netdev network interface device structure
* ixgb_get_stats - Get System Network Statistics
* @netdev: network interface device structure
*
* Returns the address of the device statistics structure.
* The statistics are actually updated from the timer callback.
**/
static struct net_device_stats *
ixgb_get_stats(struct net_device *netdev)
static struct net_device_stats *ixgb_get_stats(struct net_device *netdev)
{
struct ixgb_adapter *adapter = netdev->priv;
......@@ -1476,22 +1399,19 @@ ixgb_get_stats(struct net_device *netdev)
}
/**
* ixgb_change_mtu - Change the Maximum Transfer Unit.
* @param netdev network interface device structure
* @param new_mtu new value for maximum frame size
* ixgb_change_mtu - Change the Maximum Transfer Unit
* @netdev: network interface device structure
* @new_mtu: new value for maximum frame size
*
* Returns 0 on success, negative on failure
**/
static int
ixgb_change_mtu(struct net_device *netdev, int new_mtu)
static int ixgb_change_mtu(struct net_device *netdev, int new_mtu)
{
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;
IXGB_DBG("ixgb_change_mtu\n");
if ((max_frame < IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH)
|| (max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) {
IXGB_ERR("Invalid MTU setting\n");
......@@ -1513,69 +1433,23 @@ ixgb_change_mtu(struct net_device *netdev, int new_mtu)
adapter->rx_buffer_len = IXGB_RXBUFFER_16384;
}
netdev->mtu = new_mtu;
if (old_mtu != adapter->rx_buffer_len && netif_running(netdev)) {
ixgb_down(adapter, TRUE);
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;
}
/**
* ixgb_update_stats - Update the board statistics counters.
* @param adapter board private structure
* @adapter: board private structure
**/
static void
ixgb_update_stats(struct ixgb_adapter *adapter)
static void ixgb_update_stats(struct ixgb_adapter *adapter)
{
adapter->stats.tprl += IXGB_READ_REG(&adapter->hw, TPRL);
adapter->stats.tprh += IXGB_READ_REG(&adapter->hw, TPRH);
......@@ -1678,309 +1552,241 @@ ixgb_update_stats(struct ixgb_adapter *adapter)
/**
* ixgb_irq_disable - Mask off interrupt generation on the NIC
* @param adapter board private structure
* @adapter: board private structure
**/
static inline void
ixgb_irq_disable(struct ixgb_adapter *adapter)
static inline void ixgb_irq_disable(struct ixgb_adapter *adapter)
{
IXGB_DBG("ixgb_irq_disable\n");
atomic_inc(&adapter->irq_sem);
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.
* @param adapter board private structure
* ixgb_irq_enable - Enable default interrupt generation settings
* @adapter: board private structure
**/
static inline void
ixgb_irq_enable(struct ixgb_adapter *adapter)
static inline void ixgb_irq_enable(struct ixgb_adapter *adapter)
{
IXGB_DBG("ixgb_irq_enable\n");
if (atomic_dec_and_test(&adapter->irq_sem)) {
IXGB_WRITE_REG(&adapter->hw, IMS,
IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | IXGB_INT_TXDW |
IXGB_INT_RXO | IXGB_INT_LSC);
IXGB_WRITE_FLUSH(&adapter->hw);
}
}
#define IXGB_MAX_INTR 10
/**
* ixgb_intr - Interrupt Handler.
* @param irq interrupt number
* @param data pointer to a network interface device structure
* @param regs CPU registers structure
* ixgb_intr - Interrupt Handler
* @irq: interrupt number
* @data: pointer to a network interface device structure
* @pt_regs: CPU registers structure
**/
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)
{
struct net_device *netdev = (struct net_device *) data;
struct net_device *netdev = data;
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;
u32 icr;
uint i = IXGB_MAX_INTR;
boolean_t rxdmt0 = FALSE;
int handled = 0;
while (i && (icr = IXGB_READ_REG(hw, ICR))) {
handled = 1;
uint32_t icr = IXGB_READ_REG(&adapter->hw, ICR);
#ifndef CONFIG_IXGB_NAPI
unsigned int i;
#endif
if (icr & IXGB_INT_RXDMT0)
rxdmt0 = TRUE;
if (unlikely(!icr))
return IRQ_NONE; /* Not our interrupt */
if (unlikely(icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC))) {
mod_timer(&adapter->watchdog_timer, jiffies);
}
#ifdef CONFIG_IXGB_NAPI
if (netif_rx_schedule_prep(netdev)) {
/* adapter->generate_int = 0; */
ixgb_clean_rx_irq(adapter);
ixgb_clean_tx_irq(adapter);
/* Disable interrupts and register for poll. The flush
of the posted write is intentionally left out.
*/
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
* 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 */
IXGB_WRITE_REG(hw, IMC, IXGB_INT_RXDMT0);
/* now restart it, h/w will decide if its necessary */
IXGB_WRITE_REG(hw, IMS, IXGB_INT_RXDMT0);
}
return IRQ_RETVAL(handled);
#endif // NAPI else
#endif
return IRQ_HANDLED;
}
#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;
u32 icr;
int i = IXGB_MAX_INTR;
int hasReceived = 0;
while (i && (icr = IXGB_READ_REG(&adapter->hw, ICR))) {
if (icr & IXGB_INT_RXT0)
hasReceived = 1;
int work_to_do = min(*budget, netdev->quota);
int work_done = 0;
if (!(icr & ~(IXGB_INT_RXT0)))
break;
ixgb_clean_tx_irq(adapter);
ixgb_clean_rx_irq(adapter, &work_done, work_to_do);
if (icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC)) {
mod_timer(&adapter->watchdog_timer, jiffies);
}
*budget -= work_done;
netdev->quota -= work_done;
ixgb_clean_tx_irq(adapter);
i--;
if (work_done < work_to_do || !netif_running(netdev)) {
netif_rx_complete(netdev);
/* RAIDC will be automatically restarted by irq_enable */
ixgb_irq_enable(adapter);
}
return hasReceived;
return (work_done >= work_to_do);
}
#endif
/**
* ixgb_clean_tx_irq - Reclaim resources after transmit completes.
* @param adapter board private structure
* ixgb_clean_tx_irq - Reclaim resources after transmit completes
* @adapter: board private structure
**/
static void
ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
static boolean_t ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
{
struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
int i = adapter->tx_ring.next_to_clean;
struct ixgb_tx_desc *tx_desc = IXGB_TX_DESC(*tx_ring, i);
while ((tx_desc->status & IXGB_TX_DESC_STATUS_DD)) {
if (tx_desc->popts
& (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;
}
struct ixgb_tx_desc *tx_desc, *eop_desc;
struct ixgb_buffer *buffer_info;
unsigned int i, eop;
boolean_t cleaned = FALSE;
if (tx_ring->buffer_info[i].skb) {
dev_kfree_skb_any(tx_ring->buffer_info[i].skb);
tx_ring->buffer_info[i].skb = NULL;
}
i = tx_ring->next_to_clean;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = IXGB_TX_DESC(*tx_ring, eop);
*(u32 *) & (tx_desc->status) = 0;
while (eop_desc->status & cpu_to_le32(IXGB_TX_DESC_STATUS_DD)) {
i = (i + 1) % tx_ring->count;
for (cleaned = FALSE; !cleaned;) {
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;
buffer_info = &tx_ring->buffer_info[i];
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;
length = le16_to_cpu(rx_desc->length);
if (!(rx_desc->status & IXGB_RX_DESC_STATUS_EOP)) {
/* All receives must fit into a single buffer */
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);
rx_desc->status = 0;
rx_ring->buffer_info[i].skb = NULL;
if (buffer_info->dma) {
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);
continue;
buffer_info->dma = 0;
}
if (rx_desc->
errors & (IXGB_RX_DESC_ERRORS_CE | IXGB_RX_DESC_ERRORS_SE |
IXGB_RX_DESC_ERRORS_P | IXGB_RX_DESC_ERRORS_RXE))
{
if (buffer_info->skb) {
IXGB_DBG("Receive Errors Reported by Hardware-%x.\n",
rx_desc->errors);
dev_kfree_skb_any(buffer_info->skb);
dev_kfree_skb_irq(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;
buffer_info->skb = NULL;
}
/* Good Receive */
skb_put(skb, length);
/* Receive Checksum Offload */
ixgb_rx_checksum(adapter, rx_desc, skb);
*(uint32_t *) & (tx_desc->status) = 0;
skb->protocol = eth_type_trans(skb, netdev);
if (adapter->vlgrp
&& (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
(rx_desc-> special & IXGB_RX_DESC_SPECIAL_VLAN_MASK));
} else {
netif_receive_skb(skb);
cleaned = (i == eop);
if (++i == tx_ring->count)
i = 0;
}
netdev->last_rx = jiffies;
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);
received++;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = IXGB_TX_DESC(*tx_ring, eop);
}
if (!received)
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:
tx_ring->next_to_clean = i;
ixgb_alloc_rx_buffers(adapter);
spin_lock(&adapter->tx_lock);
if (cleaned && netif_queue_stopped(netdev) && netif_carrier_ok(netdev)
&& (IXGB_DESC_UNUSED(tx_ring) > IXGB_TX_QUEUE_WAKE)) {
rx_ring->next_to_clean = i;
netdev->quota -= received;
*budget -= received;
netif_wake_queue(netdev);
}
spin_unlock(&adapter->tx_lock);
return 1;
return cleaned;
}
#else
/**
* ixgb_clean_rx_irq - Send received data up the network stack.
* @param adapter board private structure
* ixgb_clean_rx_irq - Send received data up the network stack,
* @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)
#endif
{
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
struct ixgb_rx_desc *rx_desc;
struct sk_buff *skb;
u32 length;
int i;
struct ixgb_rx_desc *rx_desc, *next_rxd;
struct ixgb_buffer *buffer_info, *next_buffer, *next2_buffer;
struct sk_buff *skb, *next_skb;
uint32_t length;
unsigned int i, j;
boolean_t cleaned = FALSE;
i = rx_ring->next_to_clean;
rx_desc = IXGB_RX_DESC(*rx_ring, i);
buffer_info = &rx_ring->buffer_info[i];
while ((rx_desc->status & IXGB_RX_DESC_STATUS_DD)) {
pci_unmap_single(pdev, rx_ring->buffer_info[i].dma,
rx_ring->buffer_info[i].length,
PCI_DMA_FROMDEVICE);
while (rx_desc->status & IXGB_RX_DESC_STATUS_DD) {
skb = buffer_info->skb;
prefetch(skb->data);
if (++i == rx_ring->count)
i = 0;
next_rxd = IXGB_RX_DESC(*rx_ring, i);
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);
if (unlikely(!(rx_desc->status & IXGB_RX_DESC_STATUS_EOP))) {
......@@ -1992,9 +1798,10 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
dev_kfree_skb_irq(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);
buffer_info->skb = NULL;
rx_desc = next_rxd;
buffer_info = next_buffer;
continue;
}
......@@ -2003,14 +1810,12 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
| IXGB_RX_DESC_ERRORS_P |
IXGB_RX_DESC_ERRORS_RXE))) {
IXGB_DBG("Receive Errors Reported by Hardware-%x.\n",
rx_desc->errors);
dev_kfree_skb_irq(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);
buffer_info->skb = NULL;
rx_desc = next_rxd;
buffer_info = next_buffer;
continue;
}
......@@ -2021,53 +1826,63 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
ixgb_rx_checksum(adapter, rx_desc, skb);
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
&& (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
vlan_hwaccel_rx(skb, adapter->vlgrp,
(rx_desc->
le16_to_cpu(rx_desc->
special &
IXGB_RX_DESC_SPECIAL_VLAN_MASK));
} else {
netif_rx(skb);
}
#endif /* CONFIG_IXGB_NAPI */
netdev->last_rx = jiffies;
rx_desc->status = 0;
buffer_info->skb = NULL;
rx_ring->buffer_info[i].skb = NULL;
i = (i + 1) % rx_ring->count;
rx_desc = IXGB_RX_DESC(*rx_ring, i);
} /* while */
rx_desc = next_rxd;
buffer_info = next_buffer;
}
rx_ring->next_to_clean = i;
ixgb_alloc_rx_buffers(adapter);
return cleaned;
}
#endif
/**
* ixgb_alloc_rx_buffers - Replace used receive buffers.
* @param adapter address of board private structure
* ixgb_alloc_rx_buffers - Replace used receive buffers
* @adapter: address of board private structure
**/
static void
ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
{
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
struct ixgb_rx_desc *rx_desc;
struct ixgb_buffer *buffer_info;
struct sk_buff *skb;
int reserve_len;
int i;
int reserve_len = 2;
unsigned int i;
int num_group_tail_writes;
long cleancount;
reserve_len = 2;
i = rx_ring->next_to_use;
buffer_info = &rx_ring->buffer_info[i];
cleancount = IXGB_DESC_UNUSED(rx_ring);
/* lessen this to 4 if we're
......@@ -2080,14 +1895,13 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
while (--cleancount > 0) {
rx_desc = IXGB_RX_DESC(*rx_ring, i);
/* allocate a new one */
skb = dev_alloc_skb(adapter->rx_buffer_len + reserve_len);
if (unlikely(!skb)) {
/* better luck next time around */
IXGB_DBG("Could not allocate SKB\n");
/* Better luck next round */
break;
}
/* Make buffer alignment 2 beyond a 16 byte boundary
* this will result in a 16 byte aligned IP header after
* the 14 byte MAC header is removed
......@@ -2096,24 +1910,28 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
skb->dev = netdev;
rx_ring->buffer_info[i].skb = skb;
rx_ring->buffer_info[i].length = adapter->rx_buffer_len;
rx_ring->buffer_info[i].dma =
pci_map_single(pdev, skb->data, adapter->rx_buffer_len,
PCI_DMA_FROMDEVICE);
buffer_info->skb = skb;
buffer_info->length = adapter->rx_buffer_len;
buffer_info->dma =
pci_map_single(pdev,
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
* know there are new descriptors to fetch. (Only
* applicable for weak-ordered memory model archs,
* such as IA-64). */
wmb();
/* move tail */
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;
......@@ -2126,14 +1944,11 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
* @param cmd ioctl command to execute
**/
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)
{
switch (cmd) {
case SIOCETHTOOL:
return ixgb_ethtool_ioctl(netdev, ifr);
default:
return -EOPNOTSUPP;
}
......@@ -2141,18 +1956,50 @@ ixgb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
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.
*
* @param netdev network interface device structure
* @param grp indicates to enable or disable tagging/stripping
**/
static void
ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
{
struct ixgb_adapter *adapter = netdev->priv;
u32 ctrl, rctl;
uint32_t ctrl, rctl;
ixgb_irq_disable(adapter);
adapter->vlgrp = grp;
......@@ -2164,17 +2011,20 @@ ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl);
/* enable VLAN receive filtering */
rctl = IXGB_READ_REG(&adapter->hw, RCTL);
rctl |= IXGB_RCTL_VFE;
rctl &= ~IXGB_RCTL_CFIEN;
IXGB_WRITE_REG(&adapter->hw, RCTL, rctl);
} else {
/* disable VLAN tag insert/strip */
ctrl = IXGB_READ_REG(&adapter->hw, CTRL0);
ctrl &= ~IXGB_CTRL0_VME;
IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl);
/* disable VLAN filtering */
rctl = IXGB_READ_REG(&adapter->hw, RCTL);
rctl &= ~IXGB_RCTL_VFE;
IXGB_WRITE_REG(&adapter->hw, RCTL, rctl);
......@@ -2183,17 +2033,10 @@ ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
ixgb_irq_enable(adapter);
}
/**
* 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)
static void ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
{
struct ixgb_adapter *adapter = netdev->priv;
u32 vfta, index;
uint32_t vfta, index;
/* add VID to filter table */
......@@ -2203,17 +2046,10 @@ ixgb_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
ixgb_write_vfta(&adapter->hw, index, vfta);
}
/**
* 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)
static void ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
{
struct ixgb_adapter *adapter = netdev->priv;
u32 vfta, index;
uint32_t vfta, index;
ixgb_irq_disable(adapter);
......@@ -2230,17 +2066,12 @@ ixgb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
ixgb_write_vfta(&adapter->hw, index, vfta);
}
/**
* 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)
static void ixgb_restore_vlan(struct ixgb_adapter *adapter)
{
ixgb_vlan_rx_register(adapter->netdev, adapter->vlgrp);
if (adapter->vlgrp) {
u16 vid;
uint16_t vid;
for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
if (!adapter->vlgrp->vlan_devices[vid])
continue;
......@@ -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.
* @param nb notifier block, unused
......@@ -2313,7 +2095,7 @@ ixgb_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
case SYS_DOWN:
case SYS_HALT:
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)
ixgb_suspend(pdev, 3);
}
......@@ -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 state power state to enter
**/
static int
ixgb_suspend(struct pci_dev *pdev, u32 state)
static int ixgb_suspend(struct pci_dev *pdev, uint32_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgb_adapter *adapter = netdev->priv;
......@@ -2346,4 +2127,20 @@ ixgb_suspend(struct pci_dev *pdev, u32 state)
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 */
/*******************************************************************************
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
under the terms of the GNU General Public License as published by the Free
......@@ -23,14 +23,15 @@
Contact Information:
Linux NICS <linux.nics@intel.com>
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
*/
#ifndef IXGB_OSDEP_H
#define IXGB_OSDEP_H
#ifndef _IXGB_OSDEP_H_
#define _IXGB_OSDEP_H_
#include <linux/types.h>
#include <linux/pci.h>
......@@ -39,35 +40,42 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
/* FIXME: eliminate me */
#ifndef msec_delay
#define msec_delay(x) do { if(in_interrupt()) { \
mdelay(x); \
/* Don't mdelay in interrupt context! */ \
BUG(); \
} else { \
set_current_state(TASK_UNINTERRUPTIBLE); \
schedule_timeout((x * HZ)/1000); \
schedule_timeout((x * HZ)/1000 + 2); \
} } while(0)
#endif
#define PCI_COMMAND_REGISTER PCI_COMMAND
#define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE
typedef enum {
#undef FALSE
FALSE = 0,
#undef TRUE
TRUE = 1
} boolean_t;
#undef ASSERT
#define ASSERT(x) if(!(x)) BUG()
#define MSGOUT(S, A, B) printk(KERN_DEBUG S "\n", A, B)
#if DBG
#define ASSERT(x) if(!(x)) BUG()
#define DEBUGOUT(S) printk(KERN_ERR S "\n")
#define DEBUGOUT1(S, A...) printk(KERN_ERR S "\n", A)
#define DEBUGOUT(S) printk(KERN_DEBUG S "\n")
#define DEBUGOUT1(S, A...) printk(KERN_DEBUG S "\n", A)
#else
#define ASSERT(x)
#define DEBUGOUT(S)
#define DEBUGOUT1(S, A...)
#endif
#define DEBUGOUT2 DEBUGOUT1
#define DEBUGOUT3 DEBUGOUT1
#define DEBUGOUT7 DEBUGOUT1
#define DEBUGFUNC(F) DEBUGOUT(F)
#define DEBUGOUT2 DEBUGOUT1
#define DEBUGOUT3 DEBUGOUT2
#define DEBUGOUT7 DEBUGOUT3
#define IXGB_WRITE_REG(a, reg, value) ( \
writel((value), ((a)->hw_addr + IXGB_##reg)))
......@@ -81,4 +89,8 @@ typedef enum {
#define IXGB_READ_REG_ARRAY(a, reg, offset) ( \
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
under the terms of the GNU General Public License as published by the Free
......@@ -23,6 +23,7 @@
Contact Information:
Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#include "ixgb.h"
......@@ -102,17 +103,14 @@ IXGB_PARAM(FlowControl, "Flow Control setting");
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
* - 0 - disables all checksum offload
* - 1 - enables transmmit IP/TCP/UDP checksum offload
* on 82597 based NICs
* Valid Range: 0-65535
*
* 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
*
......@@ -163,15 +161,6 @@ IXGB_PARAM(RxFCLowThresh, "Receive Flow Control Low Threshold");
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
*
* Valid Range: 0, 1
......@@ -187,16 +176,21 @@ IXGB_PARAM(IntDelayEnable, "Transmit Interrupt Delay Enable");
#define DEFAULT_TXD 256
#define MAX_TXD 4096
#define MIN_TXD 64
#define DEFAULT_RXD 1024
#define MAX_RXD 4096
#define MIN_RXD 64
#define DEFAULT_TIDV 32
#define MAX_TIDV 0xFFFF
#define MIN_TIDV 0
#define DEFAULT_RDTR 72
#define MAX_RDTR 0xFFFF
#define MIN_RDTR 0
#define XSUMRX_DEFAULT OPTION_ENABLED
#define FLOW_CONTROL_FULL ixgb_fc_full
#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
#define DEFAULT_FCRTL 0x28000
......@@ -205,7 +199,8 @@ IXGB_PARAM(IntDelayEnable, "Transmit Interrupt Delay Enable");
#define MAX_FCRTL 0x3FFE8
#define MIN_FCRTH 8
#define MAX_FCRTH 0x3FFF0
#define DEFAULT_FCPAUSE 0x100
#define DEFAULT_FCPAUSE 0x100 /* this may be too long */
#define MIN_FCPAUSE 1
#define MAX_FCPAUSE 0xffff
......@@ -215,11 +210,11 @@ struct ixgb_option {
char *err;
int def;
union {
struct { /* range option information */
struct { /* range_option info */
int min;
int max;
} r;
struct { /* list option information */
struct { /* list_option info */
int nr;
struct ixgb_opt_list {
int i;
......@@ -229,8 +224,7 @@ struct ixgb_option {
} arg;
};
static int __devinit
ixgb_validate_option(int *value, struct ixgb_option *opt)
static int __devinit ixgb_validate_option(int *value, struct ixgb_option *opt)
{
if (*value == OPTION_UNSET) {
*value = opt->def;
......@@ -254,8 +248,7 @@ ixgb_validate_option(int *value, struct ixgb_option *opt)
return 0;
}
break;
case list_option:
{
case list_option:{
int i;
struct ixgb_opt_list *ent;
......@@ -263,7 +256,7 @@ ixgb_validate_option(int *value, struct ixgb_option *opt)
ent = &opt->arg.l.p[i];
if (*value == ent->i) {
if (ent->str[0] != '\0')
printk(KERN_INFO "%s",
printk(KERN_INFO "%s\n",
ent->str);
return 0;
}
......@@ -274,8 +267,8 @@ ixgb_validate_option(int *value, struct ixgb_option *opt)
BUG();
}
printk(KERN_INFO "Invalid %s specified (%i) %s\n", opt->name, *value,
opt->err);
printk(KERN_INFO "Invalid %s specified (%i) %s\n",
opt->name, *value, opt->err);
*value = opt->def;
return -1;
}
......@@ -286,24 +279,20 @@ ixgb_validate_option(int *value, struct ixgb_option *opt)
* ixgb_check_options - Range Checking for Command Line Parameters
* @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
* value exists, a default value is used. The final value is stored
* in a variable in the adapter structure.
**/
void __devinit
ixgb_check_options(struct ixgb_adapter *adapter)
void __devinit ixgb_check_options(struct ixgb_adapter *adapter)
{
int board = adapter->bd_number;
IXGB_DBG("ixgb_check_options\n");
if (board >= IXGB_MAX_NIC) {
printk(KERN_NOTICE "Warning: no configuration for board #%i\n",
board);
int bd = adapter->bd_number;
if (bd >= IXGB_MAX_NIC) {
printk(KERN_NOTICE
"Warning: no configuration for board #%i\n", bd);
printk(KERN_NOTICE "Using defaults for all values\n");
board = IXGB_MAX_NIC;
bd = IXGB_MAX_NIC;
}
{ /* Transmit Descriptor Count */
......@@ -312,63 +301,50 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.name = "Transmit Descriptors",
.err = "using default of " __MODULE_STRING(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;
tx_ring->count = TxDescriptors[board];
tx_ring->count = TxDescriptors[bd];
ixgb_validate_option(&tx_ring->count, &opt);
IXGB_ROUNDUP(tx_ring->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
}
{ /* Receive Descriptor Count */
struct ixgb_option opt = {
.type = range_option,
.name = "Receive Descriptors",
.err = "using default of " __MODULE_STRING(DEFAULT_RXD),
.def = DEFAULT_RXD,
.arg = {.r = {.min = MIN_RXD,.max = MAX_RXD}}
.arg = {.r = {.min = MIN_RXD,
.max = MAX_RXD}}
};
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_ROUNDUP(rx_ring->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
}
{ /* Receive Checksum Offload Enable */
struct ixgb_option opt = {
.type = enable_option,
.name = "Receive Checksum Offload",
.err = "defaulting to Enabled",
.def = OPTION_ENABLED,
.def = OPTION_ENABLED
};
int rx_csum = XsumRX[board];
int rx_csum = XsumRX[bd];
ixgb_validate_option(&rx_csum, &opt);
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 */
struct ixgb_opt_list fc_list[] = {
{ixgb_fc_none, "Flow Control Disabled\n"},
{ixgb_fc_rx_pause, "Flow Control Receive Only\n"},
{ixgb_fc_tx_pause, "Flow Control Transmit Only\n"},
{ixgb_fc_full, "Flow Control Enabled\n"},
{ixgb_fc_default, "Flow Control Hardware Default\n"}
struct ixgb_opt_list fc_list[] =
{ {ixgb_fc_none, "Flow Control Disabled"},
{ixgb_fc_rx_pause, "Flow Control Receive Only"},
{ixgb_fc_tx_pause, "Flow Control Transmit Only"},
{ixgb_fc_full, "Flow Control Enabled"},
{ixgb_fc_default, "Flow Control Hardware Default"}
};
struct ixgb_option opt = {
......@@ -376,60 +352,63 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.name = "Flow Control",
.err = "reading default settings from EEPROM",
.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);
adapter->hw.fc.type = fc;
}
{ /* Receive Flow Control High Threshold */
struct ixgb_option fcrth = {
struct ixgb_option opt = {
.type = range_option,
.name = "Rx Flow Control High Threshold",
.err =
"using default of " __MODULE_STRING(DEFAULT_FCRTH),
.def = DEFAULT_FCRTH,
.arg = {.r = {.min = MIN_FCRTH,.max = MAX_FCRTH}}
.arg = {.r = {.min = MIN_FCRTH,
.max = MAX_FCRTH}}
};
adapter->hw.fc.high_water = RxFCHighThresh[board];
ixgb_validate_option(&adapter->hw.fc.high_water, &fcrth);
adapter->hw.fc.high_water = RxFCHighThresh[bd];
ixgb_validate_option(&adapter->hw.fc.high_water, &opt);
if (!(adapter->hw.fc.type & ixgb_fc_rx_pause))
printk(KERN_INFO
"Ignoring RxFCHighThresh when no RxFC\n");
}
{ /* Receive Flow Control Low Threshold */
struct ixgb_option fcrtl = {
struct ixgb_option opt = {
.type = range_option,
.name = "Rx Flow Control Low Threshold",
.err =
"using default of " __MODULE_STRING(DEFAULT_FCRTL),
.def = DEFAULT_FCRTL,
.arg = {.r = {.min = MIN_FCRTL,.max = MAX_FCRTL}}
.arg = {.r = {.min = MIN_FCRTL,
.max = MAX_FCRTL}}
};
adapter->hw.fc.low_water = RxFCLowThresh[board];
ixgb_validate_option(&adapter->hw.fc.low_water, &fcrtl);
adapter->hw.fc.low_water = RxFCLowThresh[bd];
ixgb_validate_option(&adapter->hw.fc.low_water, &opt);
if (!(adapter->hw.fc.type & ixgb_fc_rx_pause))
printk(KERN_INFO
"Ignoring RxFCLowThresh when no RxFC\n");
}
{ /* Flow Control Pause Time Request */
struct ixgb_option fcpap = {
struct ixgb_option opt = {
.type = range_option,
.name = "Flow Control Pause Time Request",
.err =
"using default of "
__MODULE_STRING(DEFAULT_FCPAUSE),
.def = DEFAULT_FCPAUSE,
.arg = {.r = {.min = MIN_FCPAUSE,.max = MAX_FCPAUSE}}
.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))
printk(KERN_INFO
"Ignoring FCReqTimeout when no RxFC\n");
......@@ -454,10 +433,11 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.err =
"using default of " __MODULE_STRING(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);
}
{ /* Receive Interrupt Moderation */
......@@ -465,14 +445,13 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.type = enable_option,
.name = "Advanced Receive Interrupt Moderation",
.err = "defaulting to Enabled",
.def = OPTION_ENABLED,
.def = OPTION_ENABLED
};
int raidc = RAIDC[board];
int raidc = RAIDC[bd];
ixgb_validate_option(&raidc, &opt);
adapter->raidc = raidc;
}
{ /* Transmit Interrupt Delay */
struct ixgb_option opt = {
.type = range_option,
......@@ -480,10 +459,11 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.err =
"using default of " __MODULE_STRING(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);
}
......@@ -492,9 +472,9 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.type = enable_option,
.name = "Tx Interrupt Delay Enable",
.err = "defaulting to Enabled",
.def = OPTION_ENABLED,
.def = OPTION_ENABLED
};
int ide = IntDelayEnable[board];
int ide = IntDelayEnable[bd];
ixgb_validate_option(&ide, &opt);
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