2008-04-27 15:55:59 +04:00
/****************************************************************************
* Driver for Solarflare Solarstorm network controllers and boards
* Copyright 2005 - 2006 Fen Systems Ltd .
2009-11-29 18:16:19 +03:00
* Copyright 2006 - 2009 Solarflare Communications Inc .
2008-04-27 15:55:59 +04:00
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation , incorporated herein by reference .
*/
2009-11-29 18:12:08 +03:00
# ifndef EFX_NIC_H
# define EFX_NIC_H
2008-04-27 15:55:59 +04:00
2009-11-23 19:05:28 +03:00
# include <linux/i2c-algo-bit.h>
2008-04-27 15:55:59 +04:00
# include "net_driver.h"
2008-12-13 08:50:08 +03:00
# include "efx.h"
2009-11-29 18:15:41 +03:00
# include "mcdi.h"
2010-12-02 16:47:29 +03:00
# include "spi.h"
2008-04-27 15:55:59 +04:00
/*
* Falcon hardware control
*/
2009-11-28 08:36:04 +03:00
enum {
EFX_REV_FALCON_A0 = 0 ,
EFX_REV_FALCON_A1 = 1 ,
EFX_REV_FALCON_B0 = 2 ,
2009-11-29 18:15:41 +03:00
EFX_REV_SIENA_A0 = 3 ,
2008-04-27 15:55:59 +04:00
} ;
2009-11-28 08:36:04 +03:00
static inline int efx_nic_rev ( struct efx_nic * efx )
2008-05-17 00:16:10 +04:00
{
2009-11-28 08:36:04 +03:00
return efx - > type - > revision ;
2008-05-17 00:16:10 +04:00
}
2008-04-27 15:55:59 +04:00
2009-11-29 06:43:56 +03:00
extern u32 efx_nic_fpga_ver ( struct efx_nic * efx ) ;
2009-11-29 18:15:41 +03:00
static inline bool efx_nic_has_mc ( struct efx_nic * efx )
{
return efx_nic_rev ( efx ) > = EFX_REV_SIENA_A0 ;
}
2009-11-29 06:43:56 +03:00
/* NIC has two interlinked PCI functions for the same port. */
static inline bool efx_nic_is_dual_func ( struct efx_nic * efx )
{
return efx_nic_rev ( efx ) < EFX_REV_FALCON_B0 ;
}
2009-11-29 18:08:55 +03:00
enum {
PHY_TYPE_NONE = 0 ,
PHY_TYPE_TXC43128 = 1 ,
PHY_TYPE_88E1111 = 2 ,
PHY_TYPE_SFX7101 = 3 ,
PHY_TYPE_QT2022C2 = 4 ,
PHY_TYPE_PM8358 = 6 ,
PHY_TYPE_SFT9001A = 8 ,
PHY_TYPE_QT2025C = 9 ,
PHY_TYPE_SFT9001B = 10 ,
} ;
# define FALCON_XMAC_LOOPBACKS \
( ( 1 < < LOOPBACK_XGMII ) | \
( 1 < < LOOPBACK_XGXS ) | \
( 1 < < LOOPBACK_XAUI ) )
# define FALCON_GMAC_LOOPBACKS \
( 1 < < LOOPBACK_GMAC )
2009-11-23 19:05:45 +03:00
/**
2009-11-25 19:09:41 +03:00
* struct falcon_board_type - board operations and type information
* @ id : Board type id , as found in NVRAM
* @ ref_model : Model number of Solarflare reference design
* @ gen_type : Generic board type description
2009-11-23 19:05:45 +03:00
* @ init : Allocate resources and initialise peripheral hardware
* @ init_phy : Do board - specific PHY initialisation
2009-11-25 19:09:41 +03:00
* @ fini : Shut down hardware and free resources
2009-11-23 19:05:45 +03:00
* @ set_id_led : Set state of identifying LED or revert to automatic function
* @ monitor : Board - specific health check function
2009-11-25 19:09:41 +03:00
*/
struct falcon_board_type {
u8 id ;
const char * ref_model ;
const char * gen_type ;
int ( * init ) ( struct efx_nic * nic ) ;
void ( * init_phy ) ( struct efx_nic * efx ) ;
void ( * fini ) ( struct efx_nic * nic ) ;
void ( * set_id_led ) ( struct efx_nic * efx , enum efx_led_mode mode ) ;
int ( * monitor ) ( struct efx_nic * nic ) ;
} ;
/**
* struct falcon_board - board information
* @ type : Type of board
* @ major : Major rev . ( ' A ' , ' B ' . . . )
* @ minor : Minor rev . ( 0 , 1 , . . . )
2009-11-23 19:06:02 +03:00
* @ i2c_adap : I2C adapter for on - board peripherals
* @ i2c_data : Data for bit - banging algorithm
2009-11-23 19:05:45 +03:00
* @ hwmon_client : I2C client for hardware monitor
* @ ioexp_client : I2C client for power / port control
*/
struct falcon_board {
2009-11-25 19:09:41 +03:00
const struct falcon_board_type * type ;
2009-11-23 19:05:45 +03:00
int major ;
int minor ;
2009-11-23 19:06:02 +03:00
struct i2c_adapter i2c_adap ;
struct i2c_algo_bit_data i2c_data ;
2009-11-23 19:05:45 +03:00
struct i2c_client * hwmon_client , * ioexp_client ;
} ;
2009-11-23 19:05:28 +03:00
/**
* struct falcon_nic_data - Falcon NIC state
2009-11-25 19:09:04 +03:00
* @ pci_dev2 : Secondary function of Falcon A
2009-11-23 19:05:45 +03:00
* @ board : Board state and functions
2009-11-25 19:11:35 +03:00
* @ stats_disable_count : Nest count for disabling statistics fetches
* @ stats_pending : Is there a pending DMA of MAC statistics .
* @ stats_timer : A timer for regularly fetching MAC statistics .
* @ stats_dma_done : Pointer to the flag which indicates DMA completion .
2010-12-02 16:47:29 +03:00
* @ spi_flash : SPI flash device
* @ spi_eeprom : SPI EEPROM device
* @ spi_lock : SPI bus lock
2010-12-02 16:47:35 +03:00
* @ mdio_lock : MDIO bus lock
2010-12-02 16:47:51 +03:00
* @ xmac_poll_required : XMAC link state needs polling
2009-11-23 19:05:28 +03:00
*/
struct falcon_nic_data {
struct pci_dev * pci_dev2 ;
2009-11-23 19:05:45 +03:00
struct falcon_board board ;
2009-11-25 19:11:35 +03:00
unsigned int stats_disable_count ;
bool stats_pending ;
struct timer_list stats_timer ;
u32 * stats_dma_done ;
2010-12-02 16:47:29 +03:00
struct efx_spi_device spi_flash ;
struct efx_spi_device spi_eeprom ;
struct mutex spi_lock ;
2010-12-02 16:47:35 +03:00
struct mutex mdio_lock ;
2010-12-02 16:47:51 +03:00
bool xmac_poll_required ;
2009-11-23 19:05:28 +03:00
} ;
2009-11-23 19:05:12 +03:00
static inline struct falcon_board * falcon_board ( struct efx_nic * efx )
{
2009-11-23 19:05:45 +03:00
struct falcon_nic_data * data = efx - > nic_data ;
return & data - > board ;
2009-11-23 19:05:12 +03:00
}
2009-11-29 18:15:41 +03:00
/**
* struct siena_nic_data - Siena NIC state
* @ mcdi : Management - Controller - to - Driver Interface
* @ wol_filter_id : Wake - on - LAN packet filter id
*/
struct siena_nic_data {
struct efx_mcdi_iface mcdi ;
int wol_filter_id ;
} ;
2009-11-28 08:36:04 +03:00
extern struct efx_nic_type falcon_a1_nic_type ;
extern struct efx_nic_type falcon_b0_nic_type ;
2009-11-29 18:15:41 +03:00
extern struct efx_nic_type siena_a0_nic_type ;
2008-04-27 15:55:59 +04:00
/**************************************************************************
*
* Externs
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
2010-04-28 13:01:50 +04:00
extern int falcon_probe_board ( struct efx_nic * efx , u16 revision_info ) ;
2009-10-23 12:29:51 +04:00
2008-04-27 15:55:59 +04:00
/* TX data path */
2009-11-29 06:43:56 +03:00
extern int efx_nic_probe_tx ( struct efx_tx_queue * tx_queue ) ;
extern void efx_nic_init_tx ( struct efx_tx_queue * tx_queue ) ;
extern void efx_nic_fini_tx ( struct efx_tx_queue * tx_queue ) ;
extern void efx_nic_remove_tx ( struct efx_tx_queue * tx_queue ) ;
extern void efx_nic_push_buffers ( struct efx_tx_queue * tx_queue ) ;
2008-04-27 15:55:59 +04:00
/* RX data path */
2009-11-29 06:43:56 +03:00
extern int efx_nic_probe_rx ( struct efx_rx_queue * rx_queue ) ;
extern void efx_nic_init_rx ( struct efx_rx_queue * rx_queue ) ;
extern void efx_nic_fini_rx ( struct efx_rx_queue * rx_queue ) ;
extern void efx_nic_remove_rx ( struct efx_rx_queue * rx_queue ) ;
extern void efx_nic_notify_rx_desc ( struct efx_rx_queue * rx_queue ) ;
2008-04-27 15:55:59 +04:00
/* Event data path */
2009-11-29 06:43:56 +03:00
extern int efx_nic_probe_eventq ( struct efx_channel * channel ) ;
extern void efx_nic_init_eventq ( struct efx_channel * channel ) ;
extern void efx_nic_fini_eventq ( struct efx_channel * channel ) ;
extern void efx_nic_remove_eventq ( struct efx_channel * channel ) ;
extern int efx_nic_process_eventq ( struct efx_channel * channel , int rx_quota ) ;
extern void efx_nic_eventq_read_ack ( struct efx_channel * channel ) ;
2008-04-27 15:55:59 +04:00
/* MAC/PHY */
extern void falcon_drain_tx_fifo ( struct efx_nic * efx ) ;
extern void falcon_reconfigure_mac_wrapper ( struct efx_nic * efx ) ;
2009-11-29 06:43:56 +03:00
extern int efx_nic_rx_xoff_thresh , efx_nic_rx_xon_thresh ;
2008-04-27 15:55:59 +04:00
/* Interrupts and test events */
2009-11-29 06:43:56 +03:00
extern int efx_nic_init_interrupt ( struct efx_nic * efx ) ;
extern void efx_nic_enable_interrupts ( struct efx_nic * efx ) ;
2010-06-01 15:19:09 +04:00
extern void efx_nic_generate_test_event ( struct efx_channel * channel ) ;
2010-06-01 15:19:39 +04:00
extern void efx_nic_generate_fill_event ( struct efx_channel * channel ) ;
2009-11-29 06:43:56 +03:00
extern void efx_nic_generate_interrupt ( struct efx_nic * efx ) ;
extern void efx_nic_disable_interrupts ( struct efx_nic * efx ) ;
extern void efx_nic_fini_interrupt ( struct efx_nic * efx ) ;
extern irqreturn_t efx_nic_fatal_interrupt ( struct efx_nic * efx ) ;
extern irqreturn_t falcon_legacy_interrupt_a1 ( int irq , void * dev_id ) ;
extern void falcon_irq_ack_a1 ( struct efx_nic * efx ) ;
# define EFX_IRQ_MOD_RESOLUTION 5
2009-03-20 16:30:37 +03:00
2008-04-27 15:55:59 +04:00
/* Global Resources */
2009-11-29 06:43:56 +03:00
extern int efx_nic_flush_queues ( struct efx_nic * efx ) ;
2009-11-25 19:11:35 +03:00
extern void falcon_start_nic_stats ( struct efx_nic * efx ) ;
extern void falcon_stop_nic_stats ( struct efx_nic * efx ) ;
2010-04-28 13:28:10 +04:00
extern void falcon_setup_xaui ( struct efx_nic * efx ) ;
2008-04-27 15:55:59 +04:00
extern int falcon_reset_xaui ( struct efx_nic * efx ) ;
2009-11-29 06:43:56 +03:00
extern void efx_nic_init_common ( struct efx_nic * efx ) ;
2010-06-30 09:06:28 +04:00
extern void efx_nic_push_rx_indir_table ( struct efx_nic * efx ) ;
2009-11-29 06:43:56 +03:00
int efx_nic_alloc_buffer ( struct efx_nic * efx , struct efx_buffer * buffer ,
unsigned int len ) ;
void efx_nic_free_buffer ( struct efx_nic * efx , struct efx_buffer * buffer ) ;
2008-04-27 15:55:59 +04:00
2008-09-01 15:49:02 +04:00
/* Tests */
2009-11-29 06:43:56 +03:00
struct efx_nic_register_test {
unsigned address ;
efx_oword_t mask ;
} ;
extern int efx_nic_test_registers ( struct efx_nic * efx ,
const struct efx_nic_register_test * regs ,
size_t n_regs ) ;
2008-09-01 15:49:02 +04:00
2010-06-21 07:06:53 +04:00
extern size_t efx_nic_get_regs_len ( struct efx_nic * efx ) ;
extern void efx_nic_get_regs ( struct efx_nic * efx , void * buf ) ;
2008-04-27 15:55:59 +04:00
/**************************************************************************
*
* Falcon MAC stats
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
# define FALCON_STAT_OFFSET(falcon_stat) EFX_VAL(falcon_stat, offset)
# define FALCON_STAT_WIDTH(falcon_stat) EFX_VAL(falcon_stat, WIDTH)
/* Retrieve statistic from statistics block */
# define FALCON_STAT(efx, falcon_stat, efx_stat) do { \
if ( FALCON_STAT_WIDTH ( falcon_stat ) = = 16 ) \
( efx ) - > mac_stats . efx_stat + = le16_to_cpu ( \
* ( ( __force __le16 * ) \
( efx - > stats_buffer . addr + \
FALCON_STAT_OFFSET ( falcon_stat ) ) ) ) ; \
else if ( FALCON_STAT_WIDTH ( falcon_stat ) = = 32 ) \
( efx ) - > mac_stats . efx_stat + = le32_to_cpu ( \
* ( ( __force __le32 * ) \
( efx - > stats_buffer . addr + \
FALCON_STAT_OFFSET ( falcon_stat ) ) ) ) ; \
else \
( efx ) - > mac_stats . efx_stat + = le64_to_cpu ( \
* ( ( __force __le64 * ) \
( efx - > stats_buffer . addr + \
FALCON_STAT_OFFSET ( falcon_stat ) ) ) ) ; \
} while ( 0 )
# define FALCON_MAC_STATS_SIZE 0x100
# define MAC_DATA_LBN 0
# define MAC_DATA_WIDTH 32
2009-11-29 06:43:56 +03:00
extern void efx_nic_generate_event ( struct efx_channel * channel ,
efx_qword_t * event ) ;
2008-04-27 15:55:59 +04:00
2009-11-25 19:12:01 +03:00
extern void falcon_poll_xmac ( struct efx_nic * efx ) ;
2009-11-29 18:12:08 +03:00
# endif /* EFX_NIC_H */