Silicom release 0.26.1.sl.3.2
This commit is contained in:
parent
7cf35a4864
commit
aeca077295
0
scripts/set_irq_affinity
Executable file → Normal file
0
scripts/set_irq_affinity
Executable file → Normal file
|
@ -184,6 +184,10 @@ ifneq (10,$(shell ${CC} -E -dM ${CONFIG_FILE} 2> /dev/null |\
|
|||
endif
|
||||
endif
|
||||
|
||||
#EXTRA_CFLAGS += -DSYS_LINK_PROP_DIS
|
||||
EXTRA_CFLAGS += -DDBI_VF_AUTOLOAD
|
||||
EXTRA_CFLAGS += -DCONFIG_RIVERBED
|
||||
|
||||
EXTRA_CFLAGS += ${CFLAGS_EXTRA}
|
||||
|
||||
# get the kernel version - we use this to find the correct install path
|
||||
|
|
474
src/fm10k.h
474
src/fm10k.h
|
@ -16,6 +16,62 @@
|
|||
#include "fm10k_pf.h"
|
||||
#include "fm10k_vf.h"
|
||||
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
typedef struct _fm10k_dev_mng {
|
||||
char *name;
|
||||
char *desc;
|
||||
struct pci_dev *pdev; /* PCI device */
|
||||
struct net_device *ndev; /* net device */
|
||||
unsigned long mem_map;
|
||||
uint8_t bus;
|
||||
uint8_t slot;
|
||||
uint8_t func;
|
||||
uint8_t bus_p;
|
||||
uint8_t slot_p;
|
||||
uint8_t func_p;
|
||||
u_int32_t device;
|
||||
u_int32_t vendor;
|
||||
u_int32_t subvendor;
|
||||
u_int32_t subdevice;
|
||||
int ifindex;
|
||||
spinlock_t bypass_wr_lock;
|
||||
int port_num;
|
||||
int sw_num;
|
||||
int pep;
|
||||
/* #endif */
|
||||
|
||||
} fm10k_dev_mng_t;
|
||||
|
||||
typedef struct _fm10k_dev {
|
||||
char *name;
|
||||
char *desc;
|
||||
struct pci_dev *pdev; /* PCI device */
|
||||
struct net_device *ndev; /* net device */
|
||||
fm10k_dev_mng_t *pfm10k_dev_c;
|
||||
struct pci_dev *pdev_mng;
|
||||
unsigned long mem_map;
|
||||
uint8_t bus;
|
||||
uint8_t slot;
|
||||
uint8_t func;
|
||||
uint8_t bus_p;
|
||||
uint8_t slot_p;
|
||||
uint8_t func_p;
|
||||
u_int32_t device;
|
||||
u_int32_t vendor;
|
||||
u_int32_t subvendor;
|
||||
u_int32_t subdevice;
|
||||
int ifindex;
|
||||
int port_num;
|
||||
int epl_num;
|
||||
int epl;
|
||||
int lane_num;
|
||||
int sw_num;
|
||||
int pep;
|
||||
|
||||
} fm10k_dev_t;
|
||||
#endif
|
||||
|
||||
|
||||
#define ETH_P_IES ETH_P_XDSA
|
||||
|
||||
#define FM10K_MAX_JUMBO_FRAME_SIZE 15342 /* Maximum supported size 15K */
|
||||
|
@ -391,6 +447,21 @@ struct fm10k_intfc {
|
|||
unsigned long last_reset;
|
||||
unsigned long link_down_event;
|
||||
bool host_ready;
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
bool epl_ready;
|
||||
bool host_up;
|
||||
int epl;
|
||||
int epl_num;
|
||||
int lane_num;
|
||||
int epl_port;
|
||||
int pep_port;
|
||||
int eth_mode;
|
||||
int speed;
|
||||
unsigned long mem_map;
|
||||
fm10k_dev_t *fm10k_dev;
|
||||
fm10k_dev_mng_t *fm10k_dev_mng;
|
||||
struct fm10k_intfc *interface_c;
|
||||
#endif
|
||||
bool lport_map_failed;
|
||||
|
||||
u32 reta[FM10K_RETA_SIZE];
|
||||
|
@ -574,6 +645,7 @@ void fm10k_reset_rx_state(struct fm10k_intfc *);
|
|||
int fm10k_setup_tc(struct net_device *dev, u8 tc);
|
||||
int fm10k_open(struct net_device *netdev);
|
||||
int fm10k_close(struct net_device *netdev);
|
||||
int ies10k_spi_read_flash(struct fm10k_intfc *interface, int addr, u8 *data, int len, int freq_khz);
|
||||
int fm10k_queue_vlan_request(struct fm10k_intfc *interface, u32 vid,
|
||||
u8 vsi, bool set);
|
||||
int fm10k_queue_mac_request(struct fm10k_intfc *interface, u16 glort,
|
||||
|
@ -664,4 +736,406 @@ void fm10k_dcbnl_set_ops(struct net_device *dev);
|
|||
static inline void fm10k_dcbnl_set_ops(struct net_device *dev) {}
|
||||
#endif
|
||||
#endif /* HAVE_DCBNL_IEEE */
|
||||
|
||||
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
|
||||
enum ies_port_state {
|
||||
/* NOTE! Order is important. See the table in ies_port_set_state. */
|
||||
|
||||
/* The port is in working order (symbol lock, alignment done) and
|
||||
* ready to receive a frame.
|
||||
*/
|
||||
IES_PORT_STATE_UP = 0,
|
||||
|
||||
/* Deprecated. Use ''IES_PORT_MODE_ADMIN_DOWN'' instead. */
|
||||
IES_PORT_STATE_ADMIN_DOWN,
|
||||
|
||||
/* Deprecated. Use ''IES_PORT_MODE_ADMIN_PWRDOWN'' instead. */
|
||||
IES_PORT_STATE_ADMIN_PWRDOWN,
|
||||
|
||||
/* Deprecated. Use ''IES_PORT_MODE_BIST'' instead. */
|
||||
IES_PORT_STATE_BIST,
|
||||
|
||||
/* The SERDES transmits remote fault constantly and the receiver is
|
||||
* disabled.
|
||||
*/
|
||||
IES_PORT_STATE_REMOTE_FAULT,
|
||||
|
||||
/* Indicates the absence of any signal on any lane. */
|
||||
IES_PORT_STATE_DOWN,
|
||||
|
||||
/* Some lanes have either signal or partial synchronization. */
|
||||
IES_PORT_STATE_PARTIALLY_UP,
|
||||
|
||||
/* Indicates continuous reception of a local fault condition. A remote
|
||||
* fault is automatically sent continuously.
|
||||
*/
|
||||
IES_PORT_STATE_LOCAL_FAULT,
|
||||
|
||||
/* Indicates that DFE tuning is still in progress. */
|
||||
IES_PORT_STATE_DFE_TUNING
|
||||
};
|
||||
|
||||
enum ies_port_mode {
|
||||
/* NOTE! Order is important. See the table in ies_port_set_state. */
|
||||
|
||||
/* The port is in working order (symbol lock, alignment done) and
|
||||
* ready to receive a frame.
|
||||
*/
|
||||
IES_PORT_MODE_UP = IES_PORT_STATE_UP,
|
||||
|
||||
/* The port is administratively set down with the SERDES
|
||||
* transmitting an idle pattern but the receiver disabled.
|
||||
*/
|
||||
IES_PORT_MODE_ADMIN_DOWN = IES_PORT_STATE_ADMIN_DOWN,
|
||||
|
||||
/* The port is administratively set down with the SERDES
|
||||
* shut down and no signal transmitted.
|
||||
*/
|
||||
IES_PORT_MODE_ADMIN_PWRDOWN = IES_PORT_STATE_ADMIN_PWRDOWN,
|
||||
|
||||
/* The receiver is expecting a Built In Self Test sequence. The subMode
|
||||
* argument to ies_port_set_state or ies_set_port_state_v2 is used to
|
||||
* specify the test pattern.
|
||||
*/
|
||||
IES_PORT_MODE_BIST = IES_PORT_STATE_BIST,
|
||||
|
||||
/* The SERDES transmits remote fault constantly and the receiver is
|
||||
* disabled.
|
||||
*/
|
||||
IES_PORT_MODE_REMOTE_FAULT = IES_PORT_STATE_REMOTE_FAULT,
|
||||
|
||||
/* Indicates continuous reception of a local fault condition. A remote
|
||||
* fault is automatically sent continuously.
|
||||
*/
|
||||
IES_PORT_MODE_LOCAL_FAULT = IES_PORT_STATE_LOCAL_FAULT
|
||||
};
|
||||
|
||||
|
||||
#define IES10K_CM_USAGE_BASE 0xE60000
|
||||
#define IES10K_CM_USAGE_SIZE 0x010000
|
||||
|
||||
|
||||
/* Various per-port pause reception settings */
|
||||
#define IES10K_CM_PAUSE_CFG(index) \
|
||||
(0x000001 * (index) + 0x000800 + IES10K_CM_USAGE_BASE)
|
||||
#define IES10K_CM_PAUSE_CFG_WIDTH 1
|
||||
#define IES10K_CM_PAUSE_CFG_ENTRIES 48
|
||||
|
||||
#define IES10K_CM_PAUSE_CFG_L_PAUSEMASK 0
|
||||
#define IES10K_CM_PAUSE_CFG_H_PAUSEMASK 7
|
||||
|
||||
/* Mapping from Pause Class to SMP */
|
||||
#define IES10K_CM_PC_SMP_MAP(index) \
|
||||
(0x000001 * (index) + 0x0008c0 + IES10K_CM_USAGE_BASE)
|
||||
#define IES10K_EPL_BASE (0x0E0000)
|
||||
|
||||
/* MAC and Reconciliation Sublayer configuration */
|
||||
#define IES10K_MAC_CFG(index1, index0, word) \
|
||||
(0x000400 * (index1) + 0x000080 * (index0) + \
|
||||
(word) + 0x000010 + IES10K_EPL_BASE)
|
||||
#define IES10K_MAC_CFG_WIDTH 7
|
||||
#define IES10K_MAC_CFG_ENTRIES_0 4
|
||||
#define IES10K_MAC_CFG_ENTRIES_1 9
|
||||
|
||||
#define IES10K_MAC_CFG_L_TXANTIBUBBLEWATERMARK 0
|
||||
#define IES10K_MAC_CFG_H_TXANTIBUBBLEWATERMARK 5
|
||||
#define IES10K_MAC_CFG_L_TXRATEFIFOWATERMARK 6
|
||||
#define IES10K_MAC_CFG_H_TXRATEFIFOWATERMARK 9
|
||||
#define IES10K_MAC_CFG_L_TXRATEFIFOFASTINC 10
|
||||
#define IES10K_MAC_CFG_H_TXRATEFIFOFASTINC 17
|
||||
#define IES10K_MAC_CFG_L_TXRATEFIFOSLOWINC 18
|
||||
#define IES10K_MAC_CFG_H_TXRATEFIFOSLOWINC 25
|
||||
#define IES10K_MAC_CFG_L_TXIDLEMINIFGBYTES 26
|
||||
#define IES10K_MAC_CFG_H_TXIDLEMINIFGBYTES 31
|
||||
#define IES10K_MAC_CFG_L_TXCLOCKCOMPENSATIONTIMEOUT 32
|
||||
#define IES10K_MAC_CFG_H_TXCLOCKCOMPENSATIONTIMEOUT 47
|
||||
#define IES10K_MAC_CFG_B_TXCLOCKCOMPENSATIONENABLE 48
|
||||
#define IES10K_MAC_CFG_L_TXFAULTMODE 49
|
||||
#define IES10K_MAC_CFG_H_TXFAULTMODE 51
|
||||
#define IES10K_MAC_CFG_L_TXPCACTTIMESCALE 52
|
||||
#define IES10K_MAC_CFG_H_TXPCACTTIMESCALE 55
|
||||
#define IES10K_MAC_CFG_L_TXPCACTTIMEOUT 56
|
||||
#define IES10K_MAC_CFG_H_TXPCACTTIMEOUT 63
|
||||
#define IES10K_MAC_CFG_L_TXDRAINMODE 64
|
||||
#define IES10K_MAC_CFG_H_TXDRAINMODE 65
|
||||
#define IES10K_MAC_CFG_L_TXMINCOLUMNS 66
|
||||
#define IES10K_MAC_CFG_H_TXMINCOLUMNS 71
|
||||
#define IES10K_MAC_CFG_B_TXLPIDLEREQUEST 108
|
||||
#define IES10K_MAC_CFG_B_TXLPIAUTOMATIC 109
|
||||
#define IES10K_MAC_CFG_L_TXLPITIMEOUT 110
|
||||
#define IES10K_MAC_CFG_H_TXLPITIMEOUT 117
|
||||
#define IES10K_MAC_CFG_L_TXLPITIMESCALE 118
|
||||
#define IES10K_MAC_CFG_H_TXLPITIMESCALE 119
|
||||
#define IES10K_MAC_CFG_L_TXLPIHOLDTIMEOUT 120
|
||||
#define IES10K_MAC_CFG_H_TXLPIHOLDTIMEOUT 127
|
||||
#define IES10K_MAC_CFG_L_TXLPIHOLDTIMESCALE 128
|
||||
#define IES10K_MAC_CFG_H_TXLPIHOLDTIMESCALE 129
|
||||
#define IES10K_MAC_CFG_L_TXFCSMODE 130
|
||||
#define IES10K_MAC_CFG_H_TXFCSMODE 132
|
||||
#define IES10K_MAC_CFG_B_TXIDLEENABLEDIC 134
|
||||
#define IES10K_MAC_CFG_L_RXMINFRAMELENGTH 136
|
||||
#define IES10K_MAC_CFG_H_RXMINFRAMELENGTH 143
|
||||
#define IES10K_MAC_CFG_L_RXMAXFRAMELENGTH 144
|
||||
#define IES10K_MAC_CFG_H_RXMAXFRAMELENGTH 159
|
||||
#define IES10K_MAC_CFG_B_IEEE1588ENABLE 168
|
||||
#define IES10K_MAC_CFG_B_PREAMBLEMODE 170
|
||||
#define IES10K_MAC_CFG_B_RXDRAIN 173
|
||||
#define IES10K_MAC_CFG_B_RXIGNOREIFGERRORS 180
|
||||
|
||||
#define IES10K_MGMT_BASE 0x000000
|
||||
/* SPI_CTRL */
|
||||
#define IES10K_SPI_CTRL() (0x000c29 + IES10K_MGMT_BASE)
|
||||
#define IES10K_SPI_CTRL_WIDTH 1
|
||||
|
||||
#define IES10K_SPI_CTRL_L_FREQ 0
|
||||
#define IES10K_SPI_CTRL_H_FREQ 9
|
||||
#define IES10K_SPI_CTRL_B_BUSY 21
|
||||
|
||||
/* SPI_HEADER */
|
||||
#define IES10K_SPI_HEADER() (0x000c28 + IES10K_MGMT_BASE)
|
||||
#define IES10K_SPI_HEADER_WIDTH 1
|
||||
|
||||
/* SPI_RX_DATA */
|
||||
#define IES10K_SPI_RX_DATA() (0x000c27 + IES10K_MGMT_BASE)
|
||||
#define IES10K_SPI_RX_DATA_WIDTH 1
|
||||
|
||||
#define DBI410T_IF_SERIES(pid) \
|
||||
(pid==0x01B0)
|
||||
|
||||
#define DBI410_IF_SERIES(pid) \
|
||||
((pid==0x01B1)|| \
|
||||
(pid==0x01B2)|| \
|
||||
(pid==0x01B3)|| \
|
||||
(pid==0x01B4))
|
||||
|
||||
|
||||
#define DBI240_IF_SERIES(pid) \
|
||||
((pid==0x01B8)|| \
|
||||
(pid==0x01B9)|| \
|
||||
(pid==0x01BC)|| \
|
||||
(pid==0x01BA))
|
||||
|
||||
#define DBI2100_IF_SERIES(pid) \
|
||||
(pid==0x01BC)
|
||||
|
||||
#define DBI100H_IF_SERIES(pid) \
|
||||
((pid==0x01C0)|| \
|
||||
(pid==0x01C2))
|
||||
|
||||
#define DBI100L_IF_SERIES(pid) \
|
||||
(pid==0x01C1)
|
||||
|
||||
#define DBI25_IF_SERIES(pid) \
|
||||
(pid==0x01C8)
|
||||
|
||||
#define BPCTL_WRITE_REG(a, reg, value) \
|
||||
(writel((value), (void *)(((a)->mem_map) + reg*4)))
|
||||
|
||||
#define BPCTL_READ_REG(a, reg) ( \
|
||||
readl((void *)((a)->mem_map) + reg*4))
|
||||
|
||||
|
||||
inline static void ies_bitfield_set32_multi32(u32 *array, int hi_bit, int lo_bit,
|
||||
u32 value)
|
||||
{
|
||||
int value_pos = 0;
|
||||
int word = lo_bit / 32;
|
||||
int rel_lo_bit = lo_bit % 32;
|
||||
int rel_hi_bit = rel_lo_bit + (hi_bit - lo_bit);
|
||||
|
||||
do {
|
||||
u32 mask;
|
||||
|
||||
mask = (rel_hi_bit < 31 ? (2 << rel_hi_bit) : 0) - 1;
|
||||
mask >>= rel_lo_bit;
|
||||
mask <<= rel_lo_bit;
|
||||
array[word] = ((array[word] & ~mask) |
|
||||
(((value >> value_pos) << rel_lo_bit) & mask));
|
||||
value_pos += (32 - rel_lo_bit);
|
||||
rel_hi_bit -= 32;
|
||||
rel_lo_bit = 0;
|
||||
++word;
|
||||
} while (rel_hi_bit >= 0);
|
||||
}
|
||||
|
||||
/* Get a named field of 1 bit within a 32-bit value. */
|
||||
#define IES_GET_BIT(rvalue, regname, bitname) \
|
||||
((rvalue >> regname ## _B_ ## bitname) & 1)
|
||||
|
||||
/* Set a named field of 1 bit within a 32-bit value. */
|
||||
#define IES_SET_BIT(lvalue, regname, bitname, bitvalue) \
|
||||
(lvalue = (lvalue & ~(1 << regname ## _B_ ## bitname)) | \
|
||||
((bitvalue & 1) << regname ## _B_ ## bitname))
|
||||
|
||||
/* Get the maximum unsigned value a named field (< 33 bits) can hold. */
|
||||
#define IES_FIELD_UNSIGNED_MAX(regname, fieldname) \
|
||||
((2 << (regname ## _H_ ## fieldname \
|
||||
- regname ## _L_ ## fieldname)) - 1)
|
||||
|
||||
/* Get a named field of 2-32 bits within a 32-bit value. */
|
||||
#define IES_GET_FIELD(rvalue, regname, fieldname) \
|
||||
((rvalue >> regname ## _L_ ## fieldname) & \
|
||||
((2 << (regname ## _H_ ## fieldname \
|
||||
- regname ## _L_ ## fieldname)) - 1))
|
||||
|
||||
/* Set a named field of 2-32 bits within a 32-bit value. */
|
||||
#define IES_SET_FIELD(lvalue, regname, fieldname, fieldvalue) \
|
||||
(lvalue ^= (((lvalue >> regname ## _L_ ## fieldname) \
|
||||
^ fieldvalue) & ((2 << (regname ## _H_ ## fieldname \
|
||||
- regname ## _L_ ## fieldname)) - 1)) \
|
||||
<< regname ## _L_ ## fieldname)
|
||||
|
||||
|
||||
/* Get a named field of 2-32 bits within an array of 32-bit values. */
|
||||
#define IES_ARRAY_GET_FIELD(array, regname, fieldname) \
|
||||
ies_bitfield_get32_multi32(array, regname ## _H_ ## fieldname, \
|
||||
regname ## _L_ ## fieldname)
|
||||
|
||||
/* Set a named field of 2-32 bits within an array of 32-bit values. */
|
||||
#define IES_ARRAY_SET_FIELD(array, regname, fieldname, fieldvalue) \
|
||||
ies_bitfield_set32_multi32(array, regname ## _H_ ## fieldname, \
|
||||
regname ## _L_ ## fieldname, fieldvalue)
|
||||
|
||||
|
||||
/* Various per-port pause reception settings */
|
||||
#define IES10K_CM_PAUSE_CFG(index) \
|
||||
(0x000001 * (index) + 0x000800 + IES10K_CM_USAGE_BASE)
|
||||
#define IES10K_CM_PAUSE_CFG_WIDTH 1
|
||||
#define IES10K_CM_PAUSE_CFG_ENTRIES 48
|
||||
|
||||
#define IES10K_CM_PAUSE_CFG_L_PAUSEMASK 0
|
||||
#define IES10K_CM_PAUSE_CFG_H_PAUSEMASK 7
|
||||
|
||||
inline static int convert_adminmode_txlinkfault(int mode)
|
||||
{
|
||||
int link_fault;
|
||||
|
||||
/* Program the output pattern based on the TxFaultMode */
|
||||
switch (mode) {
|
||||
case IES_PORT_MODE_ADMIN_DOWN:
|
||||
link_fault = 1;
|
||||
break;
|
||||
|
||||
case IES_PORT_MODE_LOCAL_FAULT:
|
||||
link_fault = 2;
|
||||
break;
|
||||
|
||||
case IES_PORT_MODE_REMOTE_FAULT:
|
||||
link_fault = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
link_fault = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return link_fault;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* iespl_read_u32 - read a 32-bit register.
|
||||
*
|
||||
* @sw: the switch number.
|
||||
* @addr: the switch register address to read.
|
||||
* @val: pointer to the location where the register value will be stored.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
**/
|
||||
inline static int iespl_read_u32(struct fm10k_intfc *interface, u32 addr, u32 *val)
|
||||
{
|
||||
u32 value = 0;
|
||||
|
||||
if(!interface->mem_map)
|
||||
return -1;
|
||||
|
||||
value = BPCTL_READ_REG(interface, addr);
|
||||
*val = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* iespl_write_u32 - write a 32-bit register.
|
||||
*
|
||||
* @sw: the switch number.
|
||||
* @addr: the switch register address to write.
|
||||
* @val: the register value to write.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
inline static int iespl_write_u32(struct fm10k_intfc *interface, u32 addr, u32 val)
|
||||
{
|
||||
if(!interface->mem_map)
|
||||
return -1;
|
||||
BPCTL_WRITE_REG(interface, addr, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline static int iespl_read_mult_u32(struct fm10k_intfc *interface, u32 addr, int n, u32 *val)
|
||||
{
|
||||
u32 value;
|
||||
int i;
|
||||
|
||||
if(!interface->mem_map)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
value = BPCTL_READ_REG(interface, (addr + i));
|
||||
val[i] = value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
inline static int iespl_write_mult_u32(struct fm10k_intfc *interface, u32 addr, int n, u32 *val)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(!interface->mem_map)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
BPCTL_WRITE_REG(interface, (addr + i), val[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct _bpmod_info_t {
|
||||
unsigned int vendor;
|
||||
unsigned int device;
|
||||
unsigned int subvendor;
|
||||
unsigned int subdevice;
|
||||
unsigned int index;
|
||||
char *bp_name;
|
||||
|
||||
} bpmod_info_t;
|
||||
|
||||
#define SILICOM_SVID 0x1374
|
||||
|
||||
typedef enum {
|
||||
SET_LINK_PROP,
|
||||
|
||||
} CMND_TYPE_FM ;
|
||||
|
||||
#define MAGIC_NUM 'J'
|
||||
|
||||
/* for passing single values */
|
||||
struct fm10k_cmd {
|
||||
int status;
|
||||
int data[8];
|
||||
int in_param[8];
|
||||
int out_param[8];
|
||||
};
|
||||
|
||||
|
||||
#define IOCTL_TX_MSG(cmd) _IOWR(MAGIC_NUM, cmd, struct fm10k_cmd)
|
||||
|
||||
#define FM10K_DEVICE_NODE "/dev/fm10k0"
|
||||
#define FM10K_DEVICE_NAME "fm10k"
|
||||
#endif /* SYS_LINK_PROP_DIS */
|
||||
|
||||
#endif /* _FM10K_H_ */
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
/* Copyright(c) 2013 - 2018 Intel Corporation. */
|
||||
|
||||
#include "fm10k_common.h"
|
||||
#include "fm10k.h"
|
||||
|
||||
/**
|
||||
* fm10k_get_bus_info_generic - Generic set PCI bus info
|
||||
|
@ -520,5 +521,29 @@ s32 fm10k_get_host_state_generic(struct fm10k_hw *hw, bool *host_ready)
|
|||
|
||||
out:
|
||||
*host_ready = !mac->get_host_state;
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
|
||||
if(*host_ready == true) {
|
||||
unsigned int mac_cfg[IES10K_MAC_CFG_WIDTH];
|
||||
struct fm10k_intfc *interface = (struct fm10k_intfc *)hw->back;
|
||||
|
||||
if(!interface)
|
||||
return ret_val;
|
||||
|
||||
if(interface->host_up == false)
|
||||
return ret_val;
|
||||
interface->host_up = false;
|
||||
memset(mac_cfg, 0, IES10K_MAC_CFG_WIDTH*4);
|
||||
|
||||
if(interface->epl_num) {
|
||||
iespl_read_mult_u32(interface, IES10K_MAC_CFG(interface->epl, interface->lane_num, 0 ),
|
||||
IES10K_MAC_CFG_WIDTH, mac_cfg);
|
||||
IES_ARRAY_SET_FIELD(mac_cfg, IES10K_MAC_CFG, TXFAULTMODE,
|
||||
convert_adminmode_txlinkfault(0));
|
||||
iespl_write_mult_u32(interface, IES10K_MAC_CFG(interface->epl, interface->lane_num, 0 ), IES10K_MAC_CFG_WIDTH, mac_cfg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
|
2141
src/fm10k_ethtool.c
2141
src/fm10k_ethtool.c
File diff suppressed because it is too large
Load diff
3389
src/fm10k_main.c
3389
src/fm10k_main.c
File diff suppressed because it is too large
Load diff
|
@ -16,6 +16,183 @@
|
|||
#include <linux/if_macvlan.h>
|
||||
#endif /* NETIF_F_HW_L2FW_DOFFLOAD */
|
||||
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
/**
|
||||
* spi_enable() - Enable Switch SPI interface.
|
||||
*
|
||||
* @sw: the switch number.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
**/
|
||||
static int spi_enable(struct fm10k_intfc *interface)
|
||||
{
|
||||
u32 spi_ctrl = 0;
|
||||
int err;
|
||||
|
||||
err = iespl_read_u32(interface, IES10K_SPI_CTRL(), &spi_ctrl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Keep current freq setting and set SPI Enable. */
|
||||
spi_ctrl &= 0x3ff;
|
||||
spi_ctrl |= 1<<10;
|
||||
err = iespl_write_u32(interface, IES10K_SPI_CTRL(), spi_ctrl);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* spi_disable() - Disable Switch SPI interface.
|
||||
*
|
||||
* @sw: the switch number.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
**/
|
||||
static int spi_disable(struct fm10k_intfc *interface)
|
||||
{
|
||||
u32 spi_ctrl = 0;
|
||||
int err;
|
||||
|
||||
err = iespl_read_u32(interface, IES10K_SPI_CTRL(), &spi_ctrl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Keep current freq setting and set SPI Enable. */
|
||||
spi_ctrl &= 0x3ff;
|
||||
err = iespl_write_u32(interface, IES10K_SPI_CTRL(), spi_ctrl);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* set_spi_ctrl_reg() - Writes SPI_CTRL with value and wait until the operation
|
||||
* is completed, then writes again SPI_CTRL setting command = 0. This is
|
||||
* required because SPI_CTRL is an idempotent register.
|
||||
*
|
||||
* @sw: the switch number.
|
||||
* @value: the value to set.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
**/
|
||||
static int set_spi_ctrl_reg(struct fm10k_intfc *interface, u32 value)
|
||||
{
|
||||
bool is_timeout;
|
||||
u32 start_time;
|
||||
u32 spi_ctrl = 0;
|
||||
int err;
|
||||
|
||||
err = iespl_write_u32(interface, IES10K_SPI_CTRL(), value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
start_time = jiffies_to_msecs(jiffies);
|
||||
|
||||
is_timeout = false;
|
||||
do {
|
||||
if (is_timeout) {
|
||||
pr_err("%s: Timeout waiting for SPI_CTRL.Busy=0. 0x%02x\n",
|
||||
__func__, spi_ctrl);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((jiffies_to_msecs(jiffies) - start_time) > 50)
|
||||
is_timeout = true;
|
||||
|
||||
err = iespl_read_u32(interface, IES10K_SPI_CTRL(), &spi_ctrl);
|
||||
if (err)
|
||||
break;
|
||||
} while (IES_GET_BIT(spi_ctrl, IES10K_SPI_CTRL, BUSY));
|
||||
|
||||
/* The switch seems to need a delay here for RX_DATA to return
|
||||
* correctly on some systems.
|
||||
*/
|
||||
udelay(1);
|
||||
|
||||
/* Write back SPI_CTRL with command = 0. */
|
||||
spi_ctrl &= 0xffff87ff;
|
||||
err = iespl_write_u32(interface, IES10K_SPI_CTRL(), spi_ctrl);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ies10k_spi_read_flash(struct fm10k_intfc *interface, int addr, u8 *data, int len, int freq_khz)
|
||||
{
|
||||
int num_read;
|
||||
u32 spi_ctrl;
|
||||
u32 rx_data;
|
||||
u32 header;
|
||||
int freq;
|
||||
int err;
|
||||
int cnt;
|
||||
|
||||
if (len <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
err = spi_enable(interface);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = iespl_read_u32(interface, IES10K_SPI_CTRL(), &spi_ctrl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (freq_khz > 0) {
|
||||
freq = ((100000 / freq_khz) / 2) - 1;
|
||||
if (freq < 0)
|
||||
freq = 0;
|
||||
IES_SET_FIELD(spi_ctrl, IES10K_SPI_CTRL, FREQ, freq);
|
||||
}
|
||||
|
||||
spi_ctrl &= 0x7ff;
|
||||
|
||||
/* Header: command (1 byte: READ_BYTES) + address (3 bytes). */
|
||||
header = (0x3 << 24) | (addr & 0xffffff);
|
||||
err = iespl_write_u32(interface, IES10K_SPI_HEADER(), header);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* First loop only: set send header flag.
|
||||
* Following loops: shift only data.
|
||||
*/
|
||||
spi_ctrl |= (0x1 << 11);
|
||||
cnt = 0;
|
||||
while (cnt < len) {
|
||||
/* Determine the number of data bytes to read [1..4]. */
|
||||
num_read = (len - cnt) > 3 ? 4 : (len - cnt);
|
||||
/* Set 'shift data' flag and number of data bytes. */
|
||||
spi_ctrl |= ((0x4 << 11) | ((num_read & 0x03) << 17));
|
||||
|
||||
/* Send command to the flash. */
|
||||
err = set_spi_ctrl_reg(interface, spi_ctrl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Get data. */
|
||||
err = iespl_read_u32(interface, IES10K_SPI_RX_DATA(), &rx_data);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Push the read data into the array. */
|
||||
while (num_read) {
|
||||
num_read--;
|
||||
data[cnt++] = (rx_data >> (num_read * 8)) & 0xff;
|
||||
}
|
||||
|
||||
spi_ctrl &= 0x7ff;
|
||||
}
|
||||
|
||||
/* Release CS. */
|
||||
spi_ctrl |= (0x8 << 11);
|
||||
err = set_spi_ctrl_reg(interface, spi_ctrl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = spi_disable(interface);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* fm10k_setup_tx_resources - allocate Tx resources (Descriptors)
|
||||
* @tx_ring: tx descriptor ring (for a specific queue) to setup
|
||||
|
@ -686,6 +863,12 @@ int fm10k_open(struct net_device *netdev)
|
|||
|
||||
fm10k_up(interface);
|
||||
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
if(interface->epl_num) {
|
||||
interface->host_up = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
err_set_queues:
|
||||
|
@ -713,6 +896,21 @@ int fm10k_close(struct net_device *netdev)
|
|||
{
|
||||
struct fm10k_intfc *interface = netdev_priv(netdev);
|
||||
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
unsigned int mac_cfg[IES10K_MAC_CFG_WIDTH];
|
||||
|
||||
interface->host_up = false;
|
||||
memset(mac_cfg, 0, IES10K_MAC_CFG_WIDTH*4);
|
||||
|
||||
if((interface->epl_num)&&(interface->host_ready)) {
|
||||
iespl_read_mult_u32(interface, IES10K_MAC_CFG(interface->epl, interface->lane_num, 0 ),
|
||||
IES10K_MAC_CFG_WIDTH, mac_cfg);
|
||||
IES_ARRAY_SET_FIELD(mac_cfg, IES10K_MAC_CFG, TXFAULTMODE,
|
||||
convert_adminmode_txlinkfault(IES_PORT_MODE_LOCAL_FAULT));
|
||||
iespl_write_mult_u32(interface, IES10K_MAC_CFG(interface->epl, interface->lane_num, 0 ), IES10K_MAC_CFG_WIDTH, mac_cfg);
|
||||
}
|
||||
#endif
|
||||
|
||||
fm10k_down(interface);
|
||||
|
||||
fm10k_qv_free_irq(interface);
|
||||
|
|
|
@ -185,6 +185,13 @@ int fm10k_check_options(struct fm10k_intfc *interface)
|
|||
.max = MAX_SRIOV_VFS} }
|
||||
};
|
||||
unsigned int vfs = opt.def;
|
||||
#ifdef DBI_VF_AUTOLOAD
|
||||
struct fm10k_hw *hw = &interface->hw;
|
||||
|
||||
if (DBI410_IF_SERIES(hw->subsystem_device_id))
|
||||
opt.def = 4;
|
||||
#endif
|
||||
vfs = opt.def;
|
||||
|
||||
/* block enabling SR-IOV if we cannot support it */
|
||||
if (!interface->hw.iov.ops.assign_resources)
|
||||
|
|
434
src/fm10k_pci.c
434
src/fm10k_pci.c
|
@ -2,10 +2,12 @@
|
|||
/* Copyright(c) 2013 - 2018 Intel Corporation. */
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "fm10k.h"
|
||||
|
||||
|
||||
static const struct fm10k_info *fm10k_info_tbl[] = {
|
||||
[fm10k_device_pf] = &fm10k_pf_info,
|
||||
[fm10k_device_vf] = &fm10k_vf_info,
|
||||
|
@ -690,8 +692,11 @@ static void fm10k_watchdog_subtask(struct fm10k_intfc *interface)
|
|||
if (test_bit(__FM10K_DOWN, interface->state) ||
|
||||
test_bit(__FM10K_RESETTING, interface->state))
|
||||
return;
|
||||
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
if ((interface->host_ready) && (interface->epl_ready))
|
||||
#else
|
||||
if (interface->host_ready)
|
||||
#endif
|
||||
fm10k_watchdog_host_is_ready(interface);
|
||||
else
|
||||
fm10k_watchdog_host_not_ready(interface);
|
||||
|
@ -1077,6 +1082,68 @@ static void fm10k_configure_rx_ring(struct fm10k_intfc *interface,
|
|||
*
|
||||
* Configure the drop enable bits for the Rx rings.
|
||||
**/
|
||||
|
||||
/* #ifndef SYS_LINK_PROP_DIS */
|
||||
#ifdef RDIF_FC_EN
|
||||
|
||||
void fm10k_update_rx_drop_en(struct fm10k_intfc *interface)
|
||||
{
|
||||
struct fm10k_hw *hw = &interface->hw;
|
||||
u8 rx_pause = interface->rx_pause;
|
||||
int i;
|
||||
u32 reg1;
|
||||
|
||||
#ifdef HAVE_DCBNL_IEEE
|
||||
#ifdef CONFIG_DCB
|
||||
if (interface->pfc_en)
|
||||
rx_pause = interface->pfc_en;
|
||||
|
||||
#endif
|
||||
#endif /* HAVE_DCBNL_IEEE */
|
||||
|
||||
reg1 = fm10k_read_reg(hw, FM10K_DMA_CTRL);
|
||||
reg1 &=~ (0x1f << 23);
|
||||
|
||||
if(interface->rx_pause) {
|
||||
reg1 |= FM10K_DMA_CTRL_MAX_HOLD;
|
||||
} else {
|
||||
switch (hw->bus.speed) {
|
||||
case fm10k_bus_speed_2500:
|
||||
reg1 |= FM10K_DMA_CTRL_MAX_HOLD_1US_GEN1;
|
||||
break;
|
||||
case fm10k_bus_speed_5000:
|
||||
reg1 |= FM10K_DMA_CTRL_MAX_HOLD_1US_GEN2;
|
||||
break;
|
||||
case fm10k_bus_speed_8000:
|
||||
reg1 |= FM10K_DMA_CTRL_MAX_HOLD_1US_GEN3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fm10k_write_reg(hw, FM10K_DMA_CTRL, reg1);
|
||||
|
||||
|
||||
for (i = 0; i < interface->num_rx_queues; i++) {
|
||||
struct fm10k_ring *ring = interface->rx_ring[i];
|
||||
u32 rxdctl = FM10K_RXDCTL_WRITE_BACK_MIN_DELAY;
|
||||
u32 reg;
|
||||
u8 reg_idx = ring->reg_idx;
|
||||
|
||||
reg = fm10k_read_reg(hw, FM10K_RXDCTL(reg_idx));
|
||||
|
||||
if (!(rx_pause & BIT(ring->qos_pc)))
|
||||
rxdctl |= FM10K_RXDCTL_DROP_ON_EMPTY;
|
||||
|
||||
fm10k_write_reg(hw, FM10K_RXDCTL(reg_idx), rxdctl);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void fm10k_update_rx_drop_en(struct fm10k_intfc *interface)
|
||||
{
|
||||
struct fm10k_hw *hw = &interface->hw;
|
||||
|
@ -1101,6 +1168,7 @@ void fm10k_update_rx_drop_en(struct fm10k_intfc *interface)
|
|||
fm10k_write_reg(hw, FM10K_RXDCTL(reg_idx), rxdctl);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* fm10k_configure_dglort - Configure Receive DGLORT after reset
|
||||
|
@ -2007,6 +2075,76 @@ skip_tx_dma_drain:
|
|||
fm10k_clean_all_rx_rings(interface);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RIVERBED
|
||||
/*
|
||||
* By using PF's mac address, generate the VF's mac by adding up the value
|
||||
* of the least significant byte of the PF's mac with VF's PCI function
|
||||
* number.
|
||||
*/
|
||||
int fm10k_generate_vf_mac(struct pci_dev *vf_pdev, u8 *mac)
|
||||
{
|
||||
struct list_head *tmp;
|
||||
struct fm10k_intfc *pf_interface;
|
||||
struct pci_dev *p, *pf_pdev;
|
||||
struct net_device *pf_netdev = NULL;
|
||||
struct pci_bus *bus = vf_pdev->bus;
|
||||
|
||||
if (!vf_pdev) {
|
||||
pr_err("%s:%d: vf is NULL\n",__FUNCTION__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* don't deal with any interface other than VF */
|
||||
if (vf_pdev->is_physfn) {
|
||||
dev_info(&vf_pdev->dev,
|
||||
"%s:%d: vf_pdev is not virtual function\n",
|
||||
__FUNCTION__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find out the PF's pci_dev struct */
|
||||
p = pf_pdev = NULL;
|
||||
list_for_each(tmp, &bus->devices) {
|
||||
p = list_entry(tmp, struct pci_dev, bus_list);
|
||||
if (p && p->is_physfn) {
|
||||
pf_pdev = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!pf_pdev) {
|
||||
dev_info(&vf_pdev->dev,
|
||||
"%s:%d: not able to find pf\n",
|
||||
__FUNCTION__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find out the PF's mac address */
|
||||
pf_interface = pci_get_drvdata(pf_pdev);
|
||||
if (!pf_interface) {
|
||||
dev_info(&vf_pdev->dev,
|
||||
"%s:%d: pf_interface is null\n",
|
||||
__FUNCTION__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
pf_netdev = pf_interface->netdev;
|
||||
if (!pf_netdev) {
|
||||
dev_info(&vf_pdev->dev,
|
||||
"%s:%d: pf_netdev is null\n",
|
||||
__FUNCTION__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Generate the VF's mac address */
|
||||
ether_addr_copy(mac, pf_netdev->dev_addr);
|
||||
mac[5] += (u8) (PCI_FUNC(vf_pdev->devfn));
|
||||
dev_info(&vf_pdev->dev, "%s:%d mac=%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
__FUNCTION__, __LINE__,
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* fm10k_sw_init - Initialize general software structures
|
||||
* @interface: host interface private structure to initialize
|
||||
|
@ -2099,12 +2237,27 @@ static int fm10k_sw_init(struct fm10k_intfc *interface,
|
|||
/* Initialize MAC address from hardware */
|
||||
err = hw->mac.ops.read_mac_addr(hw);
|
||||
if (err) {
|
||||
#ifdef CONFIG_RIVERBED
|
||||
/* RiOS needs to generate mac address for VF */
|
||||
u8 vf_mac[ETH_ALEN];
|
||||
|
||||
if (!fm10k_generate_vf_mac(pdev, vf_mac)) {
|
||||
ether_addr_copy(hw->mac.perm_addr, vf_mac);
|
||||
ether_addr_copy(hw->mac.addr, vf_mac);
|
||||
} else {
|
||||
dev_warn(&pdev->dev,
|
||||
"MAC address defaulting to random\n");
|
||||
/* tag address assignment as random */
|
||||
netdev->addr_assign_type |= NET_ADDR_RANDOM;
|
||||
}
|
||||
#else /* CONFIG_RIVERBED */
|
||||
dev_warn(&pdev->dev,
|
||||
"Failed to obtain MAC address defaulting to random\n");
|
||||
"MAC address defaulting to random\n");
|
||||
#ifdef NET_ADDR_RANDOM
|
||||
/* tag address assignment as random */
|
||||
netdev->addr_assign_type |= NET_ADDR_RANDOM;
|
||||
#endif
|
||||
#endif /* CONFIG_RIVERBED */
|
||||
}
|
||||
|
||||
ether_addr_copy(netdev->dev_addr, hw->mac.addr);
|
||||
|
@ -2154,6 +2307,271 @@ static int fm10k_sw_init(struct fm10k_intfc *interface,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RIVERBED
|
||||
//#define INTERFACE_RENAME
|
||||
#ifdef INTERFACE_RENAME
|
||||
struct nic_slot_info {
|
||||
int slot;
|
||||
int bus;
|
||||
int dev;
|
||||
int func;
|
||||
};
|
||||
|
||||
#define MAX_SLOTS 7
|
||||
#define SUPPORTED_MB 2
|
||||
|
||||
struct pci_slot_mother_board_entry {
|
||||
const char *product_name;
|
||||
struct nic_slot_info slotinfo[MAX_SLOTS];
|
||||
};
|
||||
|
||||
struct pci_slot_mother_board_entry pomb_table[SUPPORTED_MB] = {
|
||||
{ /* Tarpon: */
|
||||
"S2600GZ",
|
||||
{ /* slot 0 */ { 0, 0x00, 0x01, 0x01 },
|
||||
/* slot 1 */ { 1, 0x80, 0x02, 0x02 },
|
||||
/* slot 2 */ { 2, 0x80, 0x02, 0x00 },
|
||||
/* slot 3 */ { 3, 0x80, 0x03, 0x00 },
|
||||
/* slot 4 */ { 4, 0x00, 0x03, 0x02 },
|
||||
/* slot 5 */ { 5, 0x00, 0x03, 0x00 },
|
||||
/* slot 6 */ { 6, 0x80, 0x01, 0x00 }
|
||||
},
|
||||
},
|
||||
{ /* Pike: */
|
||||
"S2600WTTR",
|
||||
{ /* slot 0 */ { 0, 0x00, 0x02, 0x02 },
|
||||
/* slot 1 */ { 1, 0x80, 0x02, 0x02 },
|
||||
/* slot 2 */ { 2, 0x80, 0x02, 0x00 },
|
||||
/* slot 3 */ { 3, 0x80, 0x01, 0x00 },
|
||||
/* slot 4 */ { 4, 0x00, 0x03, 0x02 },
|
||||
/* slot 5 */ { 5, 0x00, 0x03, 0x00 },
|
||||
/* slot 6 */ { 6, 0x80, 0x03, 0x02 }
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
int fm10k_find_bdf (struct pci_bus *pbus, int *bus, int *dev, int *func)
|
||||
{
|
||||
*bus = *dev = *func = -1;
|
||||
if (pbus == NULL || pbus->self== NULL)
|
||||
return -1;
|
||||
*bus = pbus->self->bus->number;
|
||||
*dev = PCI_SLOT(pbus->self->devfn);
|
||||
*func = PCI_FUNC(pbus->self->devfn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fm10k_find_vpfn (struct pci_bus *bus, int *vcnt, int *pcnt)
|
||||
{
|
||||
struct list_head *tmp;
|
||||
struct pci_dev *child_pdev;
|
||||
|
||||
*vcnt = *pcnt = 0;
|
||||
list_for_each(tmp, &bus->devices) {
|
||||
child_pdev = list_entry(tmp, struct pci_dev, bus_list);
|
||||
if (child_pdev->is_virtfn)
|
||||
*vcnt = *vcnt+1;
|
||||
else if (child_pdev->is_physfn)
|
||||
*pcnt = *pcnt+1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
From lspci -tv, the 2x40g NIC's PCI structure looks like below:
|
||||
|
||||
02.2-[86-8c]----00.0-[87-8c]--+-08.0-[88-89]----00.0 Intel Corporation Device 15a4
|
||||
+-09.0-[8a-8b]----00.0 Intel Corporation Device 15a4
|
||||
\-10.0-[8c]--
|
||||
|
||||
The variables used in this routine has the following mapping.
|
||||
|
||||
parent (86:0.0) ---+- me (87:08.0) --- mykid (88:0.0)
|
||||
+- valid sibbing (87.09.0) -- sibbing's kid (8a:00.0)
|
||||
\- invalid sibbing (87.10.0)
|
||||
|
||||
Input : pointer to me as shown above,
|
||||
Output: if valid sibbing is found, return pointer to sibbing and
|
||||
its kid's bdf via pointers of bus, dev, func.
|
||||
Otherwise, return NULL.
|
||||
|
||||
*/
|
||||
struct pci_bus *
|
||||
fm10k_find_my_only_sibbing (struct pci_bus *me, int *bus, int *dev, int *func)
|
||||
{
|
||||
struct list_head *tmp, *tmp2;
|
||||
struct pci_bus *parent, *sibbing, *candidate;
|
||||
struct pci_dev *child_pdev;
|
||||
int candidate_kid_count = 0;
|
||||
int sibbing_cnt = 0;
|
||||
|
||||
parent = me->parent;
|
||||
if (me == NULL || parent == NULL || pci_is_root_bus(parent))
|
||||
return NULL;
|
||||
|
||||
sibbing = NULL;
|
||||
list_for_each(tmp, &parent->children) {
|
||||
|
||||
candidate = pci_bus_b(tmp);
|
||||
|
||||
/* don't count garbage or me as a sibbing */
|
||||
if (candidate == me || candidate == NULL)
|
||||
continue;
|
||||
|
||||
/* find out how many kid this candidate has */
|
||||
list_for_each(tmp2, &candidate->devices)
|
||||
candidate_kid_count++;
|
||||
|
||||
/* to be eligible, candidate must have only one device kid */
|
||||
if (candidate_kid_count == 1) {
|
||||
sibbing_cnt++;
|
||||
sibbing = candidate;
|
||||
|
||||
child_pdev = NULL;
|
||||
list_for_each(tmp2, &sibbing->devices) {
|
||||
child_pdev = list_entry(tmp2, struct pci_dev, bus_list);
|
||||
if (child_pdev != NULL) {
|
||||
*bus = child_pdev->bus->number;
|
||||
*dev = PCI_SLOT(child_pdev->devfn);
|
||||
*func = PCI_FUNC(child_pdev->devfn);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (sibbing_cnt)
|
||||
return sibbing;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *fm10k_generate_intf_name(struct pci_dev *pdev, int slot, char *buf)
|
||||
{
|
||||
int vcnt, pcnt;
|
||||
int bus, dev, func;
|
||||
|
||||
fm10k_find_vpfn (pdev->bus, &vcnt, &pcnt);
|
||||
|
||||
if (vcnt == 4 && pcnt == 1) { /* 4x10g nic has 1 pf & 4 vfs */
|
||||
struct pci_dev *child_pdev;
|
||||
struct list_head *tmp;
|
||||
int order = 0;
|
||||
|
||||
child_pdev = NULL;
|
||||
list_for_each(tmp, &pdev->bus->devices) {
|
||||
child_pdev = list_entry(tmp, struct pci_dev, bus_list);
|
||||
if (child_pdev != NULL &&
|
||||
child_pdev->bus->number == pdev->bus->number &&
|
||||
PCI_SLOT(child_pdev->devfn) == PCI_SLOT(pdev->devfn) &&
|
||||
PCI_FUNC(child_pdev->devfn) == PCI_FUNC(pdev->devfn))
|
||||
break;
|
||||
order++;
|
||||
}
|
||||
switch (order) {
|
||||
case 1: sprintf(buf, "wan%d_1", slot); return buf;
|
||||
case 2: sprintf(buf, "lan%d_1", slot); return buf;
|
||||
case 3: sprintf(buf, "wan%d_0", slot); return buf;
|
||||
case 4: sprintf(buf, "lan%d_0", slot); return buf;
|
||||
default: return NULL;
|
||||
}
|
||||
} else if (vcnt == 0 && pcnt == 1) { /* 2x40g nic has 1 pf only */
|
||||
struct pci_bus *sibbing;
|
||||
sibbing = fm10k_find_my_only_sibbing (pdev->bus, &bus, &dev, &func);
|
||||
if (sibbing) {
|
||||
int my_pciid, sibbing_pciid;
|
||||
|
||||
my_pciid = (pdev->bus->number << 24) | pdev->devfn;
|
||||
sibbing_pciid = (bus << 24) | PCI_DEVFN(dev, func);
|
||||
if (my_pciid > sibbing_pciid)
|
||||
sprintf(buf, "lan%d_0", slot);
|
||||
else if (my_pciid < sibbing_pciid)
|
||||
sprintf(buf, "wan%d_0", slot);
|
||||
else
|
||||
return NULL;
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
/* We don't care about PF here */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void fm10k_change_interface_name (struct fm10k_intfc *interface)
|
||||
{
|
||||
struct net_device *netdev = interface->netdev;
|
||||
struct pci_dev *pdev = interface->pdev;
|
||||
const char *product_name;
|
||||
struct pci_bus *highest_bridge, *top;
|
||||
int bus, dev, func;
|
||||
int board, slot;
|
||||
char buf[10];
|
||||
|
||||
/* find the matching mother board */
|
||||
product_name = dmi_get_system_info(DMI_PRODUCT_NAME);
|
||||
for (board = 0; board < SUPPORTED_MB; board++)
|
||||
if (!strcmp(pomb_table[board].product_name, product_name))
|
||||
break;
|
||||
if (board == SUPPORTED_MB) {
|
||||
dev_warn(&pdev->dev, "%s:%d name of interface %x:%x.%x not be "
|
||||
" changed due to unsupported motherboard with product "
|
||||
"name %s\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
pdev->bus->number,
|
||||
PCI_SLOT(pdev->devfn),
|
||||
PCI_FUNC(pdev->devfn),
|
||||
product_name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* find the matching slot number */
|
||||
top = pdev->bus;
|
||||
highest_bridge = top;
|
||||
while (!pci_is_root_bus(top)) {
|
||||
highest_bridge = top;
|
||||
top = top->parent;
|
||||
}
|
||||
|
||||
if (fm10k_find_bdf (highest_bridge, &bus, &dev, &func) < 0)
|
||||
return;
|
||||
|
||||
for (slot = 0; slot < MAX_SLOTS; slot++)
|
||||
if (pomb_table[board].slotinfo[slot].bus == bus &&
|
||||
pomb_table[board].slotinfo[slot].dev == dev &&
|
||||
pomb_table[board].slotinfo[slot].func == func)
|
||||
break;
|
||||
if (slot == MAX_SLOTS) {
|
||||
dev_warn(&pdev->dev, "%s:%d name of interface %x:%x.%x not "
|
||||
" changed due to no slot found using highest bridge "
|
||||
" %x:%x.%x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
pdev->bus->number,
|
||||
PCI_SLOT(pdev->devfn),
|
||||
PCI_FUNC(pdev->devfn),
|
||||
bus, dev, func);
|
||||
return;
|
||||
}
|
||||
if (fm10k_generate_intf_name(pdev, slot, buf) == NULL) {
|
||||
dev_warn(&pdev->dev, "%s:%d cannot generate new name for "
|
||||
"%x:%x.%x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
pdev->bus->number,
|
||||
PCI_SLOT(pdev->devfn),
|
||||
PCI_FUNC(pdev->devfn));
|
||||
return;
|
||||
}
|
||||
dev_warn(&pdev->dev, "%s:%d interface name for %x:%x.%x is %s\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
pdev->bus->number,
|
||||
PCI_SLOT(pdev->devfn),
|
||||
PCI_FUNC(pdev->devfn),
|
||||
buf);
|
||||
strcpy(netdev->name, buf);
|
||||
}
|
||||
#endif /* INTERFACE_RENAME */
|
||||
#endif /* CONFIG_RIVERBED */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* fm10k_probe - Device Initialization Routine
|
||||
* @pdev: PCI device information struct
|
||||
|
@ -2228,6 +2646,11 @@ static int fm10k_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
interface->netdev = netdev;
|
||||
interface->pdev = pdev;
|
||||
|
||||
/*#ifndef SYS_LINK_PROP_DIS*/
|
||||
#ifdef RDIF_FC_EN
|
||||
interface->rx_pause = ~0;
|
||||
#endif
|
||||
|
||||
interface->uc_addr = ioremap(pci_resource_start(pdev, 0),
|
||||
FM10K_UC_ADDR_SIZE);
|
||||
if (!interface->uc_addr) {
|
||||
|
@ -2260,7 +2683,12 @@ static int fm10k_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
err = fm10k_hw_ready(interface);
|
||||
if (err)
|
||||
goto err_register;
|
||||
|
||||
#ifdef CONFIG_RIVERBED
|
||||
//#define INTERFACE_RENAME
|
||||
#ifdef INTERFACE_RENAME
|
||||
fm10k_change_interface_name (interface);
|
||||
#endif /* INTERFACE_RENAME */
|
||||
#endif /* CONFIG_RIVERBED */
|
||||
err = register_netdev(netdev);
|
||||
if (err)
|
||||
goto err_register;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "fm10k_pf.h"
|
||||
#include "fm10k_vf.h"
|
||||
#include "fm10k.h"
|
||||
|
||||
/**
|
||||
* fm10k_reset_hw_pf - PF hardware reset
|
||||
|
@ -85,6 +86,9 @@ static s32 fm10k_init_hw_pf(struct fm10k_hw *hw)
|
|||
{
|
||||
u32 dma_ctrl, txqctl;
|
||||
u16 i;
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
u32 interval = FM10K_TC_RATE_INTERVAL_4US_GEN3;
|
||||
#endif
|
||||
|
||||
/* Establish default VSI as valid */
|
||||
fm10k_write_reg(hw, FM10K_DGLORTDEC(fm10k_dglort_default), 0);
|
||||
|
@ -108,7 +112,31 @@ static s32 fm10k_init_hw_pf(struct fm10k_hw *hw)
|
|||
/* Enable interrupt moderator if not already enabled */
|
||||
fm10k_write_reg(hw, FM10K_INT_CTRL, FM10K_INT_CTRL_ENABLEMODERATOR);
|
||||
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
/* set interval to align with 4.096 usec in all modes */
|
||||
switch (hw->bus.speed) {
|
||||
case fm10k_bus_speed_2500:
|
||||
interval = FM10K_TC_RATE_INTERVAL_4US_GEN1;
|
||||
break;
|
||||
case fm10k_bus_speed_5000:
|
||||
interval = FM10K_TC_RATE_INTERVAL_4US_GEN2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* compute the default txqctl configuration */
|
||||
if((DBI240_IF_SERIES(hw->subsystem_device_id)) &&
|
||||
(!(DBI2100_IF_SERIES(hw->subsystem_device_id)))) {
|
||||
fm10k_write_reg(hw, FM10K_TC_RATE(63), 0x4600 | interval);
|
||||
fm10k_write_reg(hw, FM10K_TC_MAXCREDIT(63), FM10K_TC_MAXCREDIT_64K);
|
||||
fm10k_write_reg(hw, FM10K_TC_CREDIT(63), FM10K_TC_MAXCREDIT_64K);
|
||||
txqctl = FM10K_TXQCTL_PF | (63 << FM10K_TXQCTL_TC_SHIFT) |
|
||||
(hw->mac.default_vid << FM10K_TXQCTL_VID_SHIFT);
|
||||
} else
|
||||
#endif
|
||||
/* compute the default txqctl configuration */
|
||||
txqctl = FM10K_TXQCTL_PF | FM10K_TXQCTL_UNLIMITED_BW |
|
||||
(hw->mac.default_vid << FM10K_TXQCTL_VID_SHIFT);
|
||||
|
||||
|
@ -154,6 +182,13 @@ static s32 fm10k_init_hw_pf(struct fm10k_hw *hw)
|
|||
hw->mac.itr_scale = FM10K_TDLEN_ITR_SCALE_GEN3;
|
||||
break;
|
||||
}
|
||||
/*#ifndef SYS_LINK_PROP_DIS*/
|
||||
#ifdef RDIF_FC_EN
|
||||
if(interface->rx_pause) {
|
||||
dma_ctrl = FM10K_DMA_CTRL_MAX_HOLD;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Configure TSO flags */
|
||||
fm10k_write_reg(hw, FM10K_DTXTCPFLGL, FM10K_TSO_FLAGS_LOW);
|
||||
|
@ -622,6 +657,9 @@ static s32 fm10k_iov_assign_resources_pf(struct fm10k_hw *hw, u16 num_vfs,
|
|||
u16 qmap_stride, qpp, vpp, vf_q_idx, vf_q_idx0, qmap_idx;
|
||||
u32 vid = hw->mac.default_vid << FM10K_TXQCTL_VID_SHIFT;
|
||||
int i, j;
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
u32 interval = FM10K_TC_RATE_INTERVAL_4US_GEN3;
|
||||
#endif
|
||||
|
||||
/* hardware only supports up to 64 pools */
|
||||
if (num_pools > 64)
|
||||
|
@ -643,13 +681,35 @@ static s32 fm10k_iov_assign_resources_pf(struct fm10k_hw *hw, u16 num_vfs,
|
|||
/* calculate starting index for queues */
|
||||
vf_q_idx = fm10k_vf_queue_index(hw, 0);
|
||||
qmap_idx = 0;
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
/* set interval to align with 4.096 usec in all modes */
|
||||
switch (hw->bus.speed) {
|
||||
case fm10k_bus_speed_2500:
|
||||
interval = FM10K_TC_RATE_INTERVAL_4US_GEN1;
|
||||
break;
|
||||
case fm10k_bus_speed_5000:
|
||||
interval = FM10K_TC_RATE_INTERVAL_4US_GEN2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* establish TCs with -1 credits and no quanta to prevent transmit */
|
||||
for (i = 0; i < num_vfs; i++) {
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
if (DBI410_IF_SERIES(hw->subsystem_device_id)) {
|
||||
fm10k_write_reg(hw, FM10K_TC_RATE(i), 0x1300 | interval);
|
||||
fm10k_write_reg(hw, FM10K_TC_MAXCREDIT(i), FM10K_TC_MAXCREDIT_64K);
|
||||
fm10k_write_reg(hw, FM10K_TC_CREDIT(i), FM10K_TC_MAXCREDIT_64K);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
fm10k_write_reg(hw, FM10K_TC_MAXCREDIT(i), 0);
|
||||
fm10k_write_reg(hw, FM10K_TC_RATE(i), 0);
|
||||
fm10k_write_reg(hw, FM10K_TC_CREDIT(i),
|
||||
FM10K_TC_CREDIT_CREDIT_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
/* zero out all mbmem registers */
|
||||
|
@ -693,9 +753,15 @@ static s32 fm10k_iov_assign_resources_pf(struct fm10k_hw *hw, u16 num_vfs,
|
|||
fm10k_write_reg(hw, FM10K_TXQCTL(vf_q_idx),
|
||||
(i << FM10K_TXQCTL_TC_SHIFT) | i |
|
||||
FM10K_TXQCTL_VF | vid);
|
||||
/*#ifndef SYS_LINK_PROP_DIS*/
|
||||
#ifdef RDIF_FC_EN
|
||||
fm10k_write_reg(hw, FM10K_RXDCTL(vf_q_idx),
|
||||
FM10K_RXDCTL_WRITE_BACK_MIN_DELAY);
|
||||
#else
|
||||
fm10k_write_reg(hw, FM10K_RXDCTL(vf_q_idx),
|
||||
FM10K_RXDCTL_WRITE_BACK_MIN_DELAY |
|
||||
FM10K_RXDCTL_DROP_ON_EMPTY);
|
||||
#endif
|
||||
fm10k_write_reg(hw, FM10K_RXQCTL(vf_q_idx),
|
||||
(i << FM10K_RXQCTL_VF_SHIFT) |
|
||||
FM10K_RXQCTL_VF);
|
||||
|
@ -736,6 +802,11 @@ static s32 fm10k_iov_configure_tc_pf(struct fm10k_hw *hw, u16 vf_idx, int rate)
|
|||
/* configure defaults */
|
||||
u32 interval = FM10K_TC_RATE_INTERVAL_4US_GEN3;
|
||||
u32 tc_rate = FM10K_TC_RATE_QUANTA_MASK;
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
if (DBI410_IF_SERIES(hw->subsystem_device_id)) {
|
||||
tc_rate = 0x1300;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* verify vf is in range */
|
||||
if (vf_idx >= hw->iov.num_vfs)
|
||||
|
@ -995,9 +1066,16 @@ static s32 fm10k_iov_reset_resources_pf(struct fm10k_hw *hw,
|
|||
for (i = vf_q_idx; i < (queues_per_pool + vf_q_idx); i++) {
|
||||
fm10k_write_reg(hw, FM10K_TXDCTL(i), 0);
|
||||
fm10k_write_reg(hw, FM10K_TXQCTL(i), txqctl);
|
||||
/*#ifndef SYS_LINK_PROP_DIS*/
|
||||
#ifdef RDIF_FC_EN
|
||||
fm10k_write_reg(hw, FM10K_RXDCTL(i),
|
||||
FM10K_RXDCTL_WRITE_BACK_MIN_DELAY);
|
||||
#else
|
||||
fm10k_write_reg(hw, FM10K_RXDCTL(i),
|
||||
FM10K_RXDCTL_WRITE_BACK_MIN_DELAY |
|
||||
FM10K_RXDCTL_DROP_ON_EMPTY);
|
||||
#endif
|
||||
|
||||
fm10k_write_reg(hw, FM10K_RXQCTL(i), rxqctl);
|
||||
}
|
||||
|
||||
|
|
|
@ -166,6 +166,7 @@ struct fm10k_hw;
|
|||
#define FM10K_DMA_CTRL_RX_ACTIVE 0x00000080
|
||||
#define FM10K_DMA_CTRL_RX_DESC_SIZE 0x00000100
|
||||
#define FM10K_DMA_CTRL_MINMSS_64 0x00008000
|
||||
#define FM10K_DMA_CTRL_MAX_HOLD 0x0f800000
|
||||
#define FM10K_DMA_CTRL_MAX_HOLD_1US_GEN3 0x04800000
|
||||
#define FM10K_DMA_CTRL_MAX_HOLD_1US_GEN2 0x04000000
|
||||
#define FM10K_DMA_CTRL_MAX_HOLD_1US_GEN1 0x03800000
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
/* Copyright(c) 2013 - 2018 Intel Corporation. */
|
||||
|
||||
#include "fm10k_vf.h"
|
||||
#include "fm10k.h"
|
||||
|
||||
/**
|
||||
* fm10k_stop_hw_vf - Stop Tx/Rx units
|
||||
|
@ -403,6 +404,9 @@ static s32 fm10k_update_lport_state_vf(struct fm10k_hw *hw, u16 glort,
|
|||
{
|
||||
struct fm10k_mbx_info *mbx = &hw->mbx;
|
||||
u32 msg[2];
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
struct fm10k_intfc *interface = (struct fm10k_intfc *)hw->back;
|
||||
#endif
|
||||
|
||||
UNREFERENCED_2PARAMETER(glort, count);
|
||||
/* reset glort mask 0 as we have to wait to be enabled */
|
||||
|
@ -410,10 +414,22 @@ static s32 fm10k_update_lport_state_vf(struct fm10k_hw *hw, u16 glort,
|
|||
|
||||
/* generate port state request */
|
||||
fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
|
||||
if (!enable)
|
||||
if (!enable) {
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
if((interface) && (interface->interface_c)) {
|
||||
if((interface->interface_c->netdev)&&
|
||||
(interface->interface_c->epl_ready))
|
||||
goto update_lport_exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
fm10k_tlv_attr_put_bool(msg, FM10K_LPORT_STATE_MSG_DISABLE);
|
||||
}
|
||||
|
||||
/* load onto outgoing mailbox */
|
||||
#ifndef SYS_LINK_PROP_DIS
|
||||
update_lport_exit:
|
||||
#endif
|
||||
return mbx->ops.enqueue_tx(hw, mbx, msg);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue