Silicom release 0.26.1.sl.3.2

This commit is contained in:
Silicom Ltd 2018-09-26 08:07:47 +00:00 committed by Shoghi
parent 7cf35a4864
commit aeca077295
12 changed files with 4584 additions and 2185 deletions

0
scripts/set_irq_affinity Executable file → Normal file
View file

View 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

View file

@ -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_ */

View file

@ -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;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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);

View file

@ -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)

View file

@ -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;

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}