mirror of
https://github.com/opnsense/src.git
synced 2026-06-08 16:22:46 -04:00
axgbe: several patches from 22.1 not yet present in FreeBSD
This commit is contained in:
parent
0362a8af23
commit
f45a2d1e5a
9 changed files with 330 additions and 48 deletions
|
|
@ -58,6 +58,14 @@
|
|||
#include "ifdi_if.h"
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
#include "opt_rss.h"
|
||||
|
||||
#ifdef RSS
|
||||
|
||||
#include <net/rss_config.h>
|
||||
#include <netinet/in_rss.h>
|
||||
|
||||
#endif
|
||||
|
||||
MALLOC_DEFINE(M_AXGBE, "axgbe", "axgbe data");
|
||||
|
||||
|
|
@ -105,6 +113,7 @@ static bool axgbe_if_needs_restart(if_ctx_t, enum iflib_restart_event);
|
|||
#endif
|
||||
static void axgbe_set_counts(if_ctx_t);
|
||||
static void axgbe_init_iflib_softc_ctx(struct axgbe_if_softc *);
|
||||
static void axgbe_initialize_rss_mapping(struct xgbe_prv_data *);
|
||||
|
||||
/* MII interface registered functions */
|
||||
static int axgbe_miibus_readreg(device_t, int, int);
|
||||
|
|
@ -279,11 +288,11 @@ axgbe_register(device_t dev)
|
|||
* No tunable found, generate one with default values
|
||||
* Note: only a reboot will reveal the new kenv
|
||||
*/
|
||||
error = kern_setenv("dev.ax.sph_enable", "1");
|
||||
error = kern_setenv("dev.ax.sph_enable", "0");
|
||||
if (error) {
|
||||
printf("Error setting tunable, using default driver values\n");
|
||||
}
|
||||
axgbe_sph_enable = 1;
|
||||
axgbe_sph_enable = 0;
|
||||
}
|
||||
|
||||
if (!axgbe_sph_enable) {
|
||||
|
|
@ -391,6 +400,7 @@ axgbe_if_attach_pre(if_ctx_t ctx)
|
|||
if_softc_ctx_t scctx;
|
||||
if_shared_ctx_t sctx;
|
||||
device_t dev;
|
||||
device_t rdev;
|
||||
unsigned int ma_lo, ma_hi;
|
||||
unsigned int reg;
|
||||
int ret;
|
||||
|
|
@ -433,8 +443,15 @@ axgbe_if_attach_pre(if_ctx_t ctx)
|
|||
sc->pdata.xpcs_res = mac_res[1];
|
||||
|
||||
/* Set the PCS indirect addressing definition registers*/
|
||||
pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF;
|
||||
pdata->xpcs_window_sel_reg = PCS_V2_WINDOW_SELECT;
|
||||
rdev = pci_find_dbsf(0, 0, 0, 0);
|
||||
if (rdev && pci_get_device(rdev) == 0x15d0
|
||||
&& pci_get_vendor(rdev) == 0x1022) {
|
||||
pdata->xpcs_window_def_reg = PCS_V2_RV_WINDOW_DEF;
|
||||
pdata->xpcs_window_sel_reg = PCS_V2_RV_WINDOW_SELECT;
|
||||
} else {
|
||||
pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF;
|
||||
pdata->xpcs_window_sel_reg = PCS_V2_WINDOW_SELECT;
|
||||
}
|
||||
|
||||
/* Configure the PCS indirect addressing support */
|
||||
reg = XPCS32_IOREAD(pdata, pdata->xpcs_window_def_reg);
|
||||
|
|
@ -698,6 +715,47 @@ axgbe_init_iflib_softc_ctx(struct axgbe_if_softc *sc)
|
|||
scctx->isc_txrx = &axgbe_txrx;
|
||||
}
|
||||
|
||||
static void
|
||||
axgbe_initialize_rss_mapping(struct xgbe_prv_data *pdata)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Get RSS key */
|
||||
#ifdef RSS
|
||||
int qid;
|
||||
uint32_t rss_hash_config = 0;
|
||||
|
||||
rss_getkey((uint8_t *)&pdata->rss_key);
|
||||
|
||||
rss_hash_config = rss_gethashconfig();
|
||||
|
||||
if (rss_hash_config & RSS_HASHTYPE_RSS_IPV4)
|
||||
XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, IP2TE, 1);
|
||||
if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV4)
|
||||
XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, TCP4TE, 1);
|
||||
if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4)
|
||||
XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1);
|
||||
#else
|
||||
arc4rand(&pdata->rss_key, ARRAY_SIZE(pdata->rss_key), 0);
|
||||
|
||||
XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, IP2TE, 1);
|
||||
XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, TCP4TE, 1);
|
||||
XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1);
|
||||
#endif
|
||||
|
||||
/* Setup RSS lookup table */
|
||||
for (i = 0; i < XGBE_RSS_MAX_TABLE_SIZE; i++) {
|
||||
#ifdef RSS
|
||||
qid = rss_get_indirection_to_bucket(i) % pdata->rx_ring_count;
|
||||
XGMAC_SET_BITS(pdata->rss_table[i], MAC_RSSDR, DMCH, qid);
|
||||
#else
|
||||
XGMAC_SET_BITS(pdata->rss_table[i], MAC_RSSDR, DMCH,
|
||||
i % pdata->rx_ring_count);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
axgbe_alloc_channels(if_ctx_t ctx)
|
||||
{
|
||||
|
|
@ -1323,11 +1381,8 @@ xgbe_default_config(struct xgbe_prv_data *pdata)
|
|||
pdata->rx_sf_mode = MTL_RSF_DISABLE;
|
||||
pdata->rx_threshold = MTL_RX_THRESHOLD_64;
|
||||
pdata->pause_autoneg = 1;
|
||||
pdata->tx_pause = 1;
|
||||
pdata->rx_pause = 1;
|
||||
pdata->phy_speed = SPEED_UNKNOWN;
|
||||
pdata->power_down = 0;
|
||||
pdata->enable_rss = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -1339,7 +1394,7 @@ axgbe_if_attach_post(if_ctx_t ctx)
|
|||
struct xgbe_phy_if *phy_if = &pdata->phy_if;
|
||||
struct xgbe_hw_if *hw_if = &pdata->hw_if;
|
||||
if_softc_ctx_t scctx = sc->scctx;
|
||||
int i, ret;
|
||||
int ret;
|
||||
|
||||
/* set split header support based on tunable */
|
||||
pdata->sph_enable = axgbe_sph_enable;
|
||||
|
|
@ -1357,6 +1412,8 @@ axgbe_if_attach_post(if_ctx_t ctx)
|
|||
if (ret)
|
||||
axgbe_error("%s: exit error %d\n", __func__, ret);
|
||||
|
||||
axgbe_sysctl_init(pdata);
|
||||
|
||||
/* Configure the defaults */
|
||||
xgbe_default_config(pdata);
|
||||
|
||||
|
|
@ -1392,15 +1449,7 @@ axgbe_if_attach_post(if_ctx_t ctx)
|
|||
scctx->isc_nrxqsets);
|
||||
DBGPR("Channel count set to: %u\n", pdata->channel_count);
|
||||
|
||||
/* Get RSS key */
|
||||
#ifdef RSS
|
||||
rss_getkey((uint8_t *)pdata->rss_key);
|
||||
#else
|
||||
arc4rand(&pdata->rss_key, ARRAY_SIZE(pdata->rss_key), 0);
|
||||
#endif
|
||||
XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, IP2TE, 1);
|
||||
XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, TCP4TE, 1);
|
||||
XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1);
|
||||
axgbe_initialize_rss_mapping(pdata);
|
||||
|
||||
/* Initialize the PHY device */
|
||||
pdata->sysctl_an_cdr_workaround = pdata->vdata->an_cdr_workaround;
|
||||
|
|
@ -1436,11 +1485,6 @@ axgbe_if_attach_post(if_ctx_t ctx)
|
|||
pdata->rx_buf_size = ret;
|
||||
DBGPR("%s: rx_buf_size %d\n", __func__, ret);
|
||||
|
||||
/* Setup RSS lookup table */
|
||||
for (i = 0; i < XGBE_RSS_MAX_TABLE_SIZE; i++)
|
||||
XGMAC_SET_BITS(pdata->rss_table[i], MAC_RSSDR, DMCH,
|
||||
i % pdata->rx_ring_count);
|
||||
|
||||
/*
|
||||
* Mark the device down until it is initialized, which happens
|
||||
* when the device is accessed first (for configuring the iface,
|
||||
|
|
@ -1452,8 +1496,6 @@ axgbe_if_attach_post(if_ctx_t ctx)
|
|||
scctx->isc_max_frame_size = if_getmtu(ifp) + 18;
|
||||
scctx->isc_min_frame_size = XGMAC_MIN_PACKET;
|
||||
|
||||
axgbe_sysctl_init(pdata);
|
||||
|
||||
axgbe_pci_init(pdata);
|
||||
|
||||
return (0);
|
||||
|
|
|
|||
|
|
@ -479,6 +479,8 @@
|
|||
#define MAC_PFR_VTFE_WIDTH 1
|
||||
#define MAC_PFR_VUCC_INDEX 22
|
||||
#define MAC_PFR_VUCC_WIDTH 1
|
||||
#define MAC_PFR_RA_INDEX 31
|
||||
#define MAC_PFR_RA_WIDTH 1
|
||||
#define MAC_PMTCSR_MGKPKTEN_INDEX 1
|
||||
#define MAC_PMTCSR_MGKPKTEN_WIDTH 1
|
||||
#define MAC_PMTCSR_PWRDWN_INDEX 0
|
||||
|
|
@ -1319,10 +1321,18 @@
|
|||
#define MDIO_PMA_10GBR_FECCTRL 0x00ab
|
||||
#endif
|
||||
|
||||
#ifndef MDIO_PMA_RX_CTRL1
|
||||
#define MDIO_PMA_RX_CTRL1 0x8051
|
||||
#endif
|
||||
|
||||
#ifndef MDIO_PCS_DIG_CTRL
|
||||
#define MDIO_PCS_DIG_CTRL 0x8000
|
||||
#endif
|
||||
|
||||
#ifndef MDIO_PCS_DIGITAL_STAT
|
||||
#define MDIO_PCS_DIGITAL_STAT 0x8010
|
||||
#endif
|
||||
|
||||
#ifndef MDIO_AN_XNP
|
||||
#define MDIO_AN_XNP 0x0016
|
||||
#endif
|
||||
|
|
@ -1363,6 +1373,10 @@
|
|||
#define MDIO_VEND2_PMA_CDR_CONTROL 0x8056
|
||||
#endif
|
||||
|
||||
#ifndef MDIO_VEND2_PMA_MISC_CTRL0
|
||||
#define MDIO_VEND2_PMA_MISC_CTRL0 0x8090
|
||||
#endif
|
||||
|
||||
#ifndef MDIO_CTRL1_SPEED1G
|
||||
#define MDIO_CTRL1_SPEED1G (MDIO_CTRL1_SPEED10G & ~BMCR_SPEED100)
|
||||
#endif
|
||||
|
|
@ -1398,6 +1412,8 @@
|
|||
#define XGBE_KR_TRAINING_ENABLE BIT(1)
|
||||
|
||||
#define XGBE_PCS_CL37_BP BIT(12)
|
||||
#define XGBE_PCS_PSEQ_STATE_MASK 0x1c
|
||||
#define XGBE_PCS_PSEQ_STATE_POWER_GOOD 0x10
|
||||
|
||||
#define XGBE_AN_CL37_INT_CMPLT BIT(0)
|
||||
#define XGBE_AN_CL37_INT_MASK 0x01
|
||||
|
|
@ -1415,6 +1431,14 @@
|
|||
#define XGBE_PMA_CDR_TRACK_EN_OFF 0x00
|
||||
#define XGBE_PMA_CDR_TRACK_EN_ON 0x01
|
||||
|
||||
#define XGBE_PMA_RX_RST_0_MASK BIT(4)
|
||||
#define XGBE_PMA_RX_RST_0_RESET_ON 0x10
|
||||
#define XGBE_PMA_RX_RST_0_RESET_OFF 0x00
|
||||
|
||||
#define XGBE_PMA_PLL_CTRL_MASK BIT(15)
|
||||
#define XGBE_PMA_PLL_CTRL_ENABLE BIT(15)
|
||||
#define XGBE_PMA_PLL_CTRL_DISABLE 0x0000
|
||||
|
||||
/* Bit setting and getting macros
|
||||
* The get macro will extract the current bit field value from within
|
||||
* the variable
|
||||
|
|
|
|||
|
|
@ -1451,7 +1451,8 @@ xgbe_dev_read(struct xgbe_channel *channel)
|
|||
|
||||
if (!err || !etlt) {
|
||||
/* No error if err is 0 or etlt is 0 */
|
||||
if (etlt == 0x09) {
|
||||
if (etlt == 0x09 &&
|
||||
(if_getcapenable(pdata->netdev) & IFCAP_VLAN_HWTAGGING)) {
|
||||
XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
|
||||
VLAN_CTAG, 1);
|
||||
packet->vlan_ctag = XGMAC_GET_BITS_LE(rdesc->desc0,
|
||||
|
|
@ -2029,6 +2030,13 @@ xgbe_config_mac_address(struct xgbe_prv_data *pdata)
|
|||
{
|
||||
xgbe_set_mac_address(pdata, if_getlladdr(pdata->netdev));
|
||||
|
||||
/*
|
||||
* Promisc mode does not work as intended. When receiving CARP
|
||||
* packets, the filter still seems to kick in. As a workaround,
|
||||
* enable the "Receive All" mode on the card during init.
|
||||
*/
|
||||
XGMAC_IOWRITE_BITS(pdata, MAC_PFR, RA, 1);
|
||||
|
||||
/* Filtering is done using perfect filtering and hash filtering */
|
||||
if (pdata->hw_feat.hash_table_size) {
|
||||
XGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1);
|
||||
|
|
|
|||
|
|
@ -327,8 +327,6 @@ out:
|
|||
if (state->ret || XI2C_GET_BITS(isr, IC_RAW_INTR_STAT, STOP_DET))
|
||||
pdata->i2c_complete = true;
|
||||
|
||||
return;
|
||||
|
||||
reissue_check:
|
||||
/* Reissue interrupt if status is not clear */
|
||||
if (pdata->vdata->irq_reissue_support)
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ enum xgbe_sfp_base {
|
|||
XGBE_SFP_BASE_1000_SX,
|
||||
XGBE_SFP_BASE_1000_LX,
|
||||
XGBE_SFP_BASE_1000_CX,
|
||||
XGBE_SFP_BASE_1000_BX,
|
||||
XGBE_SFP_BASE_10000_SR,
|
||||
XGBE_SFP_BASE_10000_LR,
|
||||
XGBE_SFP_BASE_10000_LRM,
|
||||
|
|
@ -236,6 +237,14 @@ enum xgbe_sfp_speed {
|
|||
#define XGBE_SFP_BASE_BR_10GBE_MIN 0x64
|
||||
#define XGBE_SFP_BASE_BR_10GBE_MAX 0x68
|
||||
|
||||
/* Single mode, length of fiber in units of km */
|
||||
#define XGBE_SFP_BASE_SM_LEN_KM 14
|
||||
#define XGBE_SFP_BASE_SM_LEN_KM_MIN 0x0A
|
||||
|
||||
/* Single mode, length of fiber in units of 100m */
|
||||
#define XGBE_SFP_BASE_SM_LEN_100M 15
|
||||
#define XGBE_SFP_BASE_SM_LEN_100M_MIN 0x64
|
||||
|
||||
#define XGBE_SFP_BASE_CU_CABLE_LEN 18
|
||||
|
||||
#define XGBE_SFP_BASE_VENDOR_NAME 20
|
||||
|
|
@ -245,6 +254,16 @@ enum xgbe_sfp_speed {
|
|||
#define XGBE_SFP_BASE_VENDOR_REV 56
|
||||
#define XGBE_SFP_BASE_VENDOR_REV_LEN 4
|
||||
|
||||
/*
|
||||
* Optical specification compliance - denotes wavelength
|
||||
* for optical tranceivers
|
||||
*/
|
||||
#define XGBE_SFP_BASE_OSC 60
|
||||
#define XGBE_SFP_BASE_OSC_LEN 2
|
||||
#define XGBE_SFP_BASE_OSC_1310 0x051E
|
||||
#define XGBE_SFP_BASE_OSC_1439 0x05D2
|
||||
#define XGBE_SFP_BASE_OSC_1550 0x060E
|
||||
|
||||
#define XGBE_SFP_BASE_CC 63
|
||||
|
||||
/* SFP Serial ID Extended ID values relative to an offset of 64 */
|
||||
|
|
@ -342,6 +361,9 @@ struct xgbe_phy_data {
|
|||
unsigned int sfp_gpio_address;
|
||||
unsigned int sfp_gpio_mask;
|
||||
unsigned int sfp_gpio_inputs;
|
||||
unsigned int sfp_gpio_outputs;
|
||||
unsigned int sfp_gpio_polarity;
|
||||
unsigned int sfp_gpio_configuration;
|
||||
unsigned int sfp_gpio_rx_los;
|
||||
unsigned int sfp_gpio_tx_fault;
|
||||
unsigned int sfp_gpio_mod_absent;
|
||||
|
|
@ -777,6 +799,13 @@ xgbe_phy_sfp_phy_settings(struct xgbe_prv_data *pdata)
|
|||
XGBE_SET_SUP(&pdata->phy, 1000baseX_Full);
|
||||
}
|
||||
break;
|
||||
case XGBE_SFP_BASE_1000_BX:
|
||||
pdata->phy.speed = SPEED_1000;
|
||||
pdata->phy.duplex = DUPLEX_FULL;
|
||||
pdata->phy.autoneg = AUTONEG_DISABLE;
|
||||
pdata->phy.pause_autoneg = AUTONEG_DISABLE;
|
||||
XGBE_SET_SUP(&pdata->phy, 1000baseBX_Full);
|
||||
break;
|
||||
case XGBE_SFP_BASE_10000_SR:
|
||||
case XGBE_SFP_BASE_10000_LR:
|
||||
case XGBE_SFP_BASE_10000_LRM:
|
||||
|
|
@ -1187,6 +1216,7 @@ xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
|
|||
struct xgbe_phy_data *phy_data = pdata->phy_data;
|
||||
struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom;
|
||||
uint8_t *sfp_base;
|
||||
uint16_t wavelen = 0;
|
||||
|
||||
sfp_base = sfp_eeprom->base;
|
||||
|
||||
|
|
@ -1211,6 +1241,8 @@ xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
|
|||
} else
|
||||
phy_data->sfp_cable = XGBE_SFP_CABLE_ACTIVE;
|
||||
|
||||
wavelen = (sfp_base[XGBE_SFP_BASE_OSC] << 8) | sfp_base[XGBE_SFP_BASE_OSC + 1];
|
||||
|
||||
/*
|
||||
* Determine the type of SFP. Certain 10G SFP+ modules read as
|
||||
* 1000BASE-CX. To prevent 10G DAC cables to be recognized as
|
||||
|
|
@ -1236,7 +1268,12 @@ xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
|
|||
phy_data->sfp_base = XGBE_SFP_BASE_1000_CX;
|
||||
else if (sfp_base[XGBE_SFP_BASE_1GBE_CC] & XGBE_SFP_BASE_1GBE_CC_T)
|
||||
phy_data->sfp_base = XGBE_SFP_BASE_1000_T;
|
||||
|
||||
else if (xgbe_phy_sfp_bit_rate(sfp_eeprom, XGBE_SFP_SPEED_1000)
|
||||
&& (sfp_base[XGBE_SFP_BASE_SM_LEN_KM] >= XGBE_SFP_BASE_SM_LEN_KM_MIN
|
||||
|| sfp_base[XGBE_SFP_BASE_SM_LEN_100M] >= XGBE_SFP_BASE_SM_LEN_100M_MIN)
|
||||
&& wavelen >= XGBE_SFP_BASE_OSC_1310)
|
||||
phy_data->sfp_base = XGBE_SFP_BASE_1000_BX;
|
||||
|
||||
switch (phy_data->sfp_base) {
|
||||
case XGBE_SFP_BASE_1000_T:
|
||||
phy_data->sfp_speed = XGBE_SFP_SPEED_100_1000;
|
||||
|
|
@ -1244,6 +1281,7 @@ xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
|
|||
case XGBE_SFP_BASE_1000_SX:
|
||||
case XGBE_SFP_BASE_1000_LX:
|
||||
case XGBE_SFP_BASE_1000_CX:
|
||||
case XGBE_SFP_BASE_1000_BX:
|
||||
phy_data->sfp_speed = XGBE_SFP_SPEED_1000;
|
||||
break;
|
||||
case XGBE_SFP_BASE_10000_SR:
|
||||
|
|
@ -1269,29 +1307,29 @@ xgbe_phy_sfp_eeprom_info(struct xgbe_prv_data *pdata,
|
|||
struct xgbe_sfp_ascii sfp_ascii;
|
||||
char *sfp_data = (char *)&sfp_ascii;
|
||||
|
||||
axgbe_printf(3, "SFP detected:\n");
|
||||
axgbe_printf(0, "SFP detected:\n");
|
||||
memcpy(sfp_data, &sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_NAME],
|
||||
XGBE_SFP_BASE_VENDOR_NAME_LEN);
|
||||
sfp_data[XGBE_SFP_BASE_VENDOR_NAME_LEN] = '\0';
|
||||
axgbe_printf(3, " vendor: %s\n",
|
||||
axgbe_printf(0, " vendor: %s\n",
|
||||
sfp_data);
|
||||
|
||||
memcpy(sfp_data, &sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_PN],
|
||||
XGBE_SFP_BASE_VENDOR_PN_LEN);
|
||||
sfp_data[XGBE_SFP_BASE_VENDOR_PN_LEN] = '\0';
|
||||
axgbe_printf(3, " part number: %s\n",
|
||||
axgbe_printf(0, " part number: %s\n",
|
||||
sfp_data);
|
||||
|
||||
memcpy(sfp_data, &sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_REV],
|
||||
XGBE_SFP_BASE_VENDOR_REV_LEN);
|
||||
sfp_data[XGBE_SFP_BASE_VENDOR_REV_LEN] = '\0';
|
||||
axgbe_printf(3, " revision level: %s\n",
|
||||
axgbe_printf(0, " revision level: %s\n",
|
||||
sfp_data);
|
||||
|
||||
memcpy(sfp_data, &sfp_eeprom->extd[XGBE_SFP_BASE_VENDOR_SN],
|
||||
XGBE_SFP_BASE_VENDOR_SN_LEN);
|
||||
sfp_data[XGBE_SFP_BASE_VENDOR_SN_LEN] = '\0';
|
||||
axgbe_printf(3, " serial number: %s\n",
|
||||
axgbe_printf(0, " serial number: %s\n",
|
||||
sfp_data);
|
||||
}
|
||||
|
||||
|
|
@ -1390,13 +1428,19 @@ xgbe_phy_sfp_signals(struct xgbe_prv_data *pdata)
|
|||
axgbe_printf(3, "%s: befor sfp_mod:%d sfp_gpio_address:0x%x\n",
|
||||
__func__, phy_data->sfp_mod_absent, phy_data->sfp_gpio_address);
|
||||
|
||||
ret = xgbe_phy_sfp_get_mux(pdata);
|
||||
if (ret) {
|
||||
axgbe_error("I2C error setting SFP MUX\n");
|
||||
return;
|
||||
}
|
||||
|
||||
gpio_reg = 0;
|
||||
ret = xgbe_phy_i2c_read(pdata, phy_data->sfp_gpio_address, &gpio_reg,
|
||||
sizeof(gpio_reg), gpio_ports, sizeof(gpio_ports));
|
||||
if (ret) {
|
||||
axgbe_error("%s: I2C error reading SFP GPIO addr:0x%x\n",
|
||||
__func__, phy_data->sfp_gpio_address);
|
||||
return;
|
||||
goto put_mux;
|
||||
}
|
||||
|
||||
phy_data->sfp_gpio_inputs = (gpio_ports[1] << 8) | gpio_ports[0];
|
||||
|
|
@ -1410,6 +1454,112 @@ xgbe_phy_sfp_signals(struct xgbe_prv_data *pdata)
|
|||
|
||||
axgbe_printf(3, "%s: after sfp_mod:%d sfp_gpio_inputs:0x%x\n",
|
||||
__func__, phy_data->sfp_mod_absent, phy_data->sfp_gpio_inputs);
|
||||
|
||||
put_mux:
|
||||
xgbe_phy_sfp_put_mux(pdata);
|
||||
}
|
||||
|
||||
static int
|
||||
xgbe_read_gpio_expander(struct xgbe_prv_data *pdata)
|
||||
{
|
||||
struct xgbe_phy_data *phy_data = pdata->phy_data;
|
||||
uint8_t gpio_reg, gpio_ports[2];
|
||||
int ret = 0;
|
||||
|
||||
ret = xgbe_phy_sfp_get_mux(pdata);
|
||||
if (ret) {
|
||||
axgbe_error("I2C error setting SFP MUX\n");
|
||||
return (ret);
|
||||
}
|
||||
|
||||
gpio_reg = 2;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
ret = xgbe_phy_i2c_read(pdata, phy_data->sfp_gpio_address, &gpio_reg,
|
||||
sizeof(gpio_reg), gpio_ports, sizeof(gpio_ports));
|
||||
if (ret) {
|
||||
axgbe_error("%s: I2C error reading GPIO expander register: %d\n",
|
||||
__func__, gpio_reg);
|
||||
goto put_mux;
|
||||
}
|
||||
|
||||
if (gpio_reg == 2)
|
||||
phy_data->sfp_gpio_outputs = (gpio_ports[1] << 8) | gpio_ports[0];
|
||||
else if (gpio_reg == 4)
|
||||
phy_data->sfp_gpio_polarity = (gpio_ports[1] << 8) | gpio_ports[0];
|
||||
else if (gpio_reg == 6)
|
||||
phy_data->sfp_gpio_configuration = (gpio_ports[1] << 8) | gpio_ports[0];
|
||||
|
||||
memset(gpio_ports, 0, sizeof(gpio_ports));
|
||||
gpio_reg += 2;
|
||||
}
|
||||
|
||||
put_mux:
|
||||
xgbe_phy_sfp_put_mux(pdata);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
xgbe_log_gpio_expander(struct xgbe_prv_data *pdata)
|
||||
{
|
||||
struct xgbe_phy_data *phy_data = pdata->phy_data;
|
||||
|
||||
axgbe_printf(0, "%s: Input port registers: 0x%x\n", __func__, phy_data->sfp_gpio_inputs);
|
||||
axgbe_printf(0, "%s: Output port registers: 0x%x\n", __func__, phy_data->sfp_gpio_outputs);
|
||||
axgbe_printf(0, "%s: Polarity port registers: 0x%x\n", __func__, phy_data->sfp_gpio_polarity);
|
||||
axgbe_printf(0, "%s: Configuration port registers: 0x%x\n", __func__, phy_data->sfp_gpio_configuration);
|
||||
}
|
||||
|
||||
static int
|
||||
xgbe_phy_validate_gpio_expander(struct xgbe_prv_data *pdata)
|
||||
{
|
||||
struct xgbe_phy_data *phy_data = pdata->phy_data;
|
||||
uint8_t polarity[3];
|
||||
int ret = 0;
|
||||
|
||||
ret = xgbe_phy_get_comm_ownership(pdata);
|
||||
if (ret)
|
||||
return (ret);
|
||||
|
||||
ret = xgbe_read_gpio_expander(pdata);
|
||||
if (ret)
|
||||
goto put;
|
||||
|
||||
if (phy_data->sfp_gpio_polarity) {
|
||||
axgbe_printf(0, "GPIO polarity inverted - resetting\n");
|
||||
|
||||
ret = xgbe_phy_sfp_get_mux(pdata);
|
||||
if (ret) {
|
||||
axgbe_error("I2C error setting SFP MUX\n");
|
||||
goto put;
|
||||
}
|
||||
|
||||
polarity[0] = 4;
|
||||
polarity[1] = 0x0;
|
||||
polarity[2] = 0x0;
|
||||
|
||||
ret = xgbe_phy_i2c_write(pdata, phy_data->sfp_gpio_address,
|
||||
polarity, sizeof(polarity));
|
||||
if (ret) {
|
||||
axgbe_error("%s: I2C error writing address to GPIO polarity register\n",
|
||||
__func__);
|
||||
goto put_mux;
|
||||
}
|
||||
|
||||
ret = xgbe_read_gpio_expander(pdata);
|
||||
if (ret)
|
||||
goto put_mux;
|
||||
|
||||
xgbe_log_gpio_expander(pdata);
|
||||
|
||||
put_mux:
|
||||
xgbe_phy_sfp_put_mux(pdata);
|
||||
}
|
||||
|
||||
put:
|
||||
xgbe_phy_put_comm_ownership(pdata);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1441,9 +1591,6 @@ xgbe_phy_sfp_detect(struct xgbe_prv_data *pdata)
|
|||
struct xgbe_phy_data *phy_data = pdata->phy_data;
|
||||
int ret, prev_sfp_state = phy_data->sfp_mod_absent;
|
||||
|
||||
/* Reset the SFP signals and info */
|
||||
xgbe_phy_sfp_reset(phy_data);
|
||||
|
||||
ret = xgbe_phy_get_comm_ownership(pdata);
|
||||
if (ret)
|
||||
return;
|
||||
|
|
@ -1461,6 +1608,11 @@ xgbe_phy_sfp_detect(struct xgbe_prv_data *pdata)
|
|||
if (ret) {
|
||||
/* Treat any error as if there isn't an SFP plugged in */
|
||||
axgbe_error("%s: eeprom read failed\n", __func__);
|
||||
ret = xgbe_read_gpio_expander(pdata);
|
||||
|
||||
if (!ret)
|
||||
xgbe_log_gpio_expander(pdata);
|
||||
|
||||
xgbe_phy_sfp_reset(phy_data);
|
||||
xgbe_phy_sfp_mod_absent(pdata);
|
||||
goto put;
|
||||
|
|
@ -2022,6 +2174,39 @@ xgbe_phy_set_redrv_mode(struct xgbe_prv_data *pdata)
|
|||
xgbe_phy_put_comm_ownership(pdata);
|
||||
}
|
||||
|
||||
static void
|
||||
xgbe_phy_rx_reset(struct xgbe_prv_data *pdata)
|
||||
{
|
||||
int reg;
|
||||
|
||||
reg = XMDIO_READ_BITS(pdata, MDIO_MMD_PCS, MDIO_PCS_DIGITAL_STAT,
|
||||
XGBE_PCS_PSEQ_STATE_MASK);
|
||||
|
||||
if (reg == XGBE_PCS_PSEQ_STATE_POWER_GOOD) {
|
||||
/* Mailbox command timed out, reset of RX block is required.
|
||||
* This can be done by asserting the reset bit and waiting
|
||||
* for its completion.
|
||||
*/
|
||||
XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_CTRL1,
|
||||
XGBE_PMA_RX_RST_0_MASK, XGBE_PMA_RX_RST_0_RESET_ON);
|
||||
DELAY(20);
|
||||
XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_CTRL1,
|
||||
XGBE_PMA_RX_RST_0_MASK, XGBE_PMA_RX_RST_0_RESET_OFF);
|
||||
DELAY(50);
|
||||
axgbe_printf(0, "%s: firmware mailbox reset performed\n", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xgbe_phy_pll_ctrl(struct xgbe_prv_data *pdata, bool enable)
|
||||
{
|
||||
XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_MISC_CTRL0,
|
||||
XGBE_PMA_PLL_CTRL_MASK,
|
||||
enable ? XGBE_PMA_PLL_CTRL_ENABLE
|
||||
: XGBE_PMA_PLL_CTRL_DISABLE);
|
||||
DELAY(200);
|
||||
}
|
||||
|
||||
static void
|
||||
xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, unsigned int cmd,
|
||||
unsigned int sub_cmd)
|
||||
|
|
@ -2029,9 +2214,13 @@ xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, unsigned int cmd,
|
|||
unsigned int s0 = 0;
|
||||
unsigned int wait;
|
||||
|
||||
xgbe_phy_pll_ctrl(pdata, false);
|
||||
|
||||
/* Log if a previous command did not complete */
|
||||
if (XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS))
|
||||
if (XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) {
|
||||
axgbe_error("firmware mailbox not ready for command\n");
|
||||
xgbe_phy_rx_reset(pdata);
|
||||
}
|
||||
|
||||
/* Construct the command */
|
||||
XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, cmd);
|
||||
|
|
@ -2047,13 +2236,19 @@ xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, unsigned int cmd,
|
|||
while (wait--) {
|
||||
if (!XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) {
|
||||
axgbe_printf(3, "%s: Rate change done\n", __func__);
|
||||
return;
|
||||
goto reenable_pll;
|
||||
}
|
||||
|
||||
DELAY(2000);
|
||||
}
|
||||
|
||||
axgbe_printf(3, "firmware mailbox command did not complete\n");
|
||||
|
||||
/* Reset on error */
|
||||
xgbe_phy_rx_reset(pdata);
|
||||
|
||||
reenable_pll:
|
||||
xgbe_phy_pll_ctrl(pdata, true);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -3354,6 +3549,11 @@ xgbe_phy_start(struct xgbe_prv_data *pdata)
|
|||
switch (phy_data->port_mode) {
|
||||
case XGBE_PORT_MODE_SFP:
|
||||
axgbe_printf(3, "%s: calling phy detect\n", __func__);
|
||||
|
||||
/* Validate the contents of the GPIO expander */
|
||||
axgbe_printf(0, "Checking GPIO expander validity\n");
|
||||
xgbe_phy_validate_gpio_expander(pdata);
|
||||
|
||||
xgbe_phy_sfp_detect(pdata);
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -1608,6 +1608,8 @@ axgbe_sysctl_init(struct xgbe_prv_data *pdata)
|
|||
pdata->sysctl_xgmac_reg = 0;
|
||||
pdata->sysctl_xpcs_mmd = 1;
|
||||
pdata->sysctl_xpcs_reg = 0;
|
||||
pdata->link_workaround = 1;
|
||||
pdata->enable_rss = 1;
|
||||
|
||||
SYSCTL_ADD_UINT(clist, top, OID_AUTO, "axgbe_debug_level", CTLFLAG_RWTUN,
|
||||
&pdata->debug_level, 0, "axgbe log level -- higher is verbose");
|
||||
|
|
@ -1619,6 +1621,18 @@ axgbe_sysctl_init(struct xgbe_prv_data *pdata)
|
|||
SYSCTL_ADD_UINT(clist, top, OID_AUTO, "link_workaround",
|
||||
CTLFLAG_RWTUN, &pdata->link_workaround, 0,
|
||||
"enable the workaround for link issue in coming up");
|
||||
|
||||
SYSCTL_ADD_UINT(clist, top, OID_AUTO, "rss_enabled",
|
||||
CTLFLAG_RDTUN, &pdata->enable_rss, 1,
|
||||
"shows the RSS feature state (1 - enable, 0 - disable)");
|
||||
|
||||
SYSCTL_ADD_UINT(clist, top, OID_AUTO, "tx_pause",
|
||||
CTLFLAG_RDTUN, &pdata->tx_pause, 1,
|
||||
"shows the Flow Control TX pause feature state (1 - enable, 0 - disable)");
|
||||
|
||||
SYSCTL_ADD_UINT(clist, top, OID_AUTO, "rx_pause",
|
||||
CTLFLAG_RDTUN, &pdata->rx_pause, 1,
|
||||
"shows the Flow Control RX pause feature state (1 - enable, 0 - disable)");
|
||||
|
||||
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xgmac_register",
|
||||
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
|
|
|
|||
|
|
@ -702,7 +702,7 @@ axgbe_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri)
|
|||
struct xgbe_packet_data *packet = &ring->packet_data;
|
||||
struct xgbe_ring_data *rdata;
|
||||
unsigned int last, context_next, context;
|
||||
unsigned int buf1_len, buf2_len, max_len, len = 0, prev_cur;
|
||||
unsigned int buf1_len, buf2_len, len = 0, prev_cur;
|
||||
int i = 0;
|
||||
|
||||
axgbe_printf(2, "%s: rxq %d cidx %d cur %d dirty %d\n", __func__,
|
||||
|
|
@ -767,11 +767,9 @@ read_again:
|
|||
axgbe_printf(2, "%s: csum flags 0x%x\n", __func__, ri->iri_csum_flags);
|
||||
}
|
||||
|
||||
max_len = if_getmtu(pdata->netdev) + ETH_HLEN;
|
||||
if (XGMAC_GET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, VLAN_CTAG)) {
|
||||
ri->iri_flags |= M_VLANTAG;
|
||||
ri->iri_vtag = packet->vlan_ctag;
|
||||
max_len += VLAN_HLEN;
|
||||
axgbe_printf(2, "%s: iri_flags 0x%x vtag 0x%x\n", __func__,
|
||||
ri->iri_flags, ri->iri_vtag);
|
||||
}
|
||||
|
|
@ -788,9 +786,6 @@ read_again:
|
|||
if (__predict_false(len == 0))
|
||||
axgbe_printf(1, "%s: Discarding Zero len packet\n", __func__);
|
||||
|
||||
if (__predict_false(len > max_len))
|
||||
axgbe_error("%s: Big packet %d/%d\n", __func__, len, max_len);
|
||||
|
||||
if (__predict_false(packet->errors))
|
||||
axgbe_printf(1, "<-- %s: rxq: %d len: %d frags: %d cidx %d cur: %d "
|
||||
"dirty: %d error 0x%x\n", __func__, ri->iri_qsidx, len, i,
|
||||
|
|
|
|||
|
|
@ -180,9 +180,9 @@
|
|||
#define XGBE_DMA_SYS_AWCR 0x30303030
|
||||
|
||||
/* DMA cache settings - PCI device */
|
||||
#define XGBE_DMA_PCI_ARCR 0x00000003
|
||||
#define XGBE_DMA_PCI_AWCR 0x13131313
|
||||
#define XGBE_DMA_PCI_AWARCR 0x00000313
|
||||
#define XGBE_DMA_PCI_ARCR 0x000f0f0f
|
||||
#define XGBE_DMA_PCI_AWCR 0x0f0f0f0f
|
||||
#define XGBE_DMA_PCI_AWARCR 0x00000f0f
|
||||
|
||||
/* DMA channel interrupt modes */
|
||||
#define XGBE_IRQ_MODE_EDGE 0
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ do { \
|
|||
#define SUPPORTED_10000baseCR_Full (1 << 19)
|
||||
#define SUPPORTED_100baseT_Half (1 << 20)
|
||||
#define SUPPORTED_1000baseT_Half (1 << 21)
|
||||
#define SUPPORTED_1000baseBX_Full (1 << 22)
|
||||
|
||||
#define LPA_PAUSE_ASYM 0x0800
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue