.name = (_n), \
}
+static const struct ar8xxx_mib_desc ar8216_mibs[] = {
+ MIB_DESC(1, AR8216_STATS_RXBROAD, "RxBroad"),
+ MIB_DESC(1, AR8216_STATS_RXPAUSE, "RxPause"),
+ MIB_DESC(1, AR8216_STATS_RXMULTI, "RxMulti"),
+ MIB_DESC(1, AR8216_STATS_RXFCSERR, "RxFcsErr"),
+ MIB_DESC(1, AR8216_STATS_RXALIGNERR, "RxAlignErr"),
+ MIB_DESC(1, AR8216_STATS_RXRUNT, "RxRunt"),
+ MIB_DESC(1, AR8216_STATS_RXFRAGMENT, "RxFragment"),
+ MIB_DESC(1, AR8216_STATS_RX64BYTE, "Rx64Byte"),
+ MIB_DESC(1, AR8216_STATS_RX128BYTE, "Rx128Byte"),
+ MIB_DESC(1, AR8216_STATS_RX256BYTE, "Rx256Byte"),
+ MIB_DESC(1, AR8216_STATS_RX512BYTE, "Rx512Byte"),
+ MIB_DESC(1, AR8216_STATS_RX1024BYTE, "Rx1024Byte"),
+ MIB_DESC(1, AR8216_STATS_RXMAXBYTE, "RxMaxByte"),
+ MIB_DESC(1, AR8216_STATS_RXTOOLONG, "RxTooLong"),
+ MIB_DESC(2, AR8216_STATS_RXGOODBYTE, "RxGoodByte"),
+ MIB_DESC(2, AR8216_STATS_RXBADBYTE, "RxBadByte"),
+ MIB_DESC(1, AR8216_STATS_RXOVERFLOW, "RxOverFlow"),
+ MIB_DESC(1, AR8216_STATS_FILTERED, "Filtered"),
+ MIB_DESC(1, AR8216_STATS_TXBROAD, "TxBroad"),
+ MIB_DESC(1, AR8216_STATS_TXPAUSE, "TxPause"),
+ MIB_DESC(1, AR8216_STATS_TXMULTI, "TxMulti"),
+ MIB_DESC(1, AR8216_STATS_TXUNDERRUN, "TxUnderRun"),
+ MIB_DESC(1, AR8216_STATS_TX64BYTE, "Tx64Byte"),
+ MIB_DESC(1, AR8216_STATS_TX128BYTE, "Tx128Byte"),
+ MIB_DESC(1, AR8216_STATS_TX256BYTE, "Tx256Byte"),
+ MIB_DESC(1, AR8216_STATS_TX512BYTE, "Tx512Byte"),
+ MIB_DESC(1, AR8216_STATS_TX1024BYTE, "Tx1024Byte"),
+ MIB_DESC(1, AR8216_STATS_TXMAXBYTE, "TxMaxByte"),
+ MIB_DESC(1, AR8216_STATS_TXOVERSIZE, "TxOverSize"),
+ MIB_DESC(2, AR8216_STATS_TXBYTE, "TxByte"),
+ MIB_DESC(1, AR8216_STATS_TXCOLLISION, "TxCollision"),
+ MIB_DESC(1, AR8216_STATS_TXABORTCOL, "TxAbortCol"),
+ MIB_DESC(1, AR8216_STATS_TXMULTICOL, "TxMultiCol"),
+ MIB_DESC(1, AR8216_STATS_TXSINGLECOL, "TxSingleCol"),
+ MIB_DESC(1, AR8216_STATS_TXEXCDEFER, "TxExcDefer"),
+ MIB_DESC(1, AR8216_STATS_TXDEFER, "TxDefer"),
+ MIB_DESC(1, AR8216_STATS_TXLATECOL, "TxLateCol"),
+};
+
static const struct ar8xxx_mib_desc ar8236_mibs[] = {
MIB_DESC(1, AR8236_STATS_RXBROAD, "RxBroad"),
MIB_DESC(1, AR8236_STATS_RXPAUSE, "RxPause"),
}
static int
-ar8216_mib_capture(struct ar8216_priv *priv)
+ar8216_mib_op(struct ar8216_priv *priv, u32 op)
{
unsigned mib_func;
int ret;
else
mib_func = AR8216_REG_MIB_FUNC;
+ mutex_lock(&priv->reg_mutex);
/* Capture the hardware statistics for all ports */
- ar8216_rmw(priv, mib_func, AR8216_MIB_FUNC,
- (AR8216_MIB_FUNC_CAPTURE << AR8216_MIB_FUNC_S));
+ ar8216_rmw(priv, mib_func, AR8216_MIB_FUNC, (op << AR8216_MIB_FUNC_S));
+ mutex_unlock(&priv->reg_mutex);
/* Wait for the capturing to complete. */
ret = ar8216_reg_wait(priv, mib_func, AR8216_MIB_BUSY, 0, 10);
}
static int
-ar8216_mib_flush(struct ar8216_priv *priv)
+ar8216_mib_capture(struct ar8216_priv *priv)
{
- unsigned mib_func;
- int ret;
-
- lockdep_assert_held(&priv->mib_lock);
-
- if (chip_is_ar8327(priv))
- mib_func = AR8327_REG_MIB_FUNC;
- else
- mib_func = AR8216_REG_MIB_FUNC;
-
- /* Flush hardware statistics for all ports */
- ar8216_rmw(priv, mib_func, AR8216_MIB_FUNC,
- (AR8216_MIB_FUNC_FLUSH << AR8216_MIB_FUNC_S));
-
- /* Wait for the capturing to complete. */
- ret = ar8216_reg_wait(priv, mib_func, AR8216_MIB_BUSY, 0, 10);
- if (ret)
- goto out;
-
- ret = 0;
+ return ar8216_mib_op(priv, AR8216_MIB_FUNC_CAPTURE);
+}
-out:
- return ret;
+static int
+ar8216_mib_flush(struct ar8216_priv *priv)
+{
+ return ar8216_mib_op(priv, AR8216_MIB_FUNC_FLUSH);
}
static void
u64 *mib_stats;
int i;
+ WARN_ON(port >= priv->dev.ports);
+
lockdep_assert_held(&priv->mib_lock);
if (chip_is_ar8327(priv))
base = AR8327_REG_PORT_STATS_BASE(port);
- else
+ else if (chip_is_ar8236(priv) ||
+ chip_is_ar8316(priv))
base = AR8236_REG_PORT_STATS_BASE(port);
+ else
+ base = AR8216_REG_PORT_STATS_BASE(port);
mib_stats = &priv->mib_stats[port * priv->chip->num_mibs];
for (i = 0; i < priv->chip->num_mibs; i++) {
}
static const struct ar8xxx_chip ar8216_chip = {
+ .caps = AR8XXX_CAP_MIB_COUNTERS,
+
.hw_init = ar8216_hw_init,
.init_globals = ar8216_init_globals,
.init_port = ar8216_init_port,
.atu_flush = ar8216_atu_flush,
.vtu_flush = ar8216_vtu_flush,
.vtu_load_vlan = ar8216_vtu_load_vlan,
+
+ .num_mibs = ARRAY_SIZE(ar8216_mibs),
+ .mib_decs = ar8216_mibs,
};
static void
case AR8327_PAD_MAC_SGMII:
t = AR8327_PAD_SGMII_EN;
+
+ /*
+ * WAR for the QUalcomm Atheros AP136 board.
+ * It seems that RGMII TX/RX delay settings needs to be
+ * applied for SGMII mode as well, The ethernet is not
+ * reliable without this.
+ */
+ t |= cfg->txclk_delay_sel << AR8327_PAD_RGMII_TXCLK_DELAY_SEL_S;
+ t |= cfg->rxclk_delay_sel << AR8327_PAD_RGMII_RXCLK_DELAY_SEL_S;
+ if (cfg->rxclk_delay_en)
+ t |= AR8327_PAD_RGMII_RXCLK_DELAY_EN;
+ if (cfg->txclk_delay_en)
+ t |= AR8327_PAD_RGMII_TXCLK_DELAY_EN;
+
+ if (cfg->sgmii_delay_en)
+ t |= AR8327_PAD_SGMII_DELAY_EN;
+
break;
case AR8327_PAD_MAC2PHY_MII:
}
static void
-ar8327_init_cpuport(struct ar8216_priv *priv)
+ar8327_config_port(struct ar8216_priv *priv, unsigned int port,
+ struct ar8327_port_cfg *cfg)
{
- struct ar8327_platform_data *pdata;
- struct ar8327_port_cfg *cfg;
u32 t;
- pdata = priv->phy->dev.platform_data;
- if (!pdata)
- return;
-
- cfg = &pdata->cpuport_cfg;
- if (!cfg->force_link) {
- priv->write(priv, AR8327_REG_PORT_STATUS(AR8216_PORT_CPU),
+ if (!cfg || !cfg->force_link) {
+ priv->write(priv, AR8327_REG_PORT_STATUS(port),
AR8216_PORT_STATUS_LINK_AUTO);
return;
}
t |= cfg->duplex ? AR8216_PORT_STATUS_DUPLEX : 0;
t |= cfg->rxpause ? AR8216_PORT_STATUS_RXFLOW : 0;
t |= cfg->txpause ? AR8216_PORT_STATUS_TXFLOW : 0;
+
switch (cfg->speed) {
case AR8327_PORT_SPEED_10:
t |= AR8216_PORT_SPEED_10M;
break;
}
- priv->write(priv, AR8327_REG_PORT_STATUS(AR8216_PORT_CPU), t);
+ priv->write(priv, AR8327_REG_PORT_STATUS(port), t);
}
static void
ar8327_init_port(struct ar8216_priv *priv, int port)
{
+ struct ar8327_platform_data *pdata;
+ struct ar8327_port_cfg *cfg;
u32 t;
- if (port == AR8216_PORT_CPU) {
- ar8327_init_cpuport(priv);
- } else {
- t = AR8216_PORT_STATUS_LINK_AUTO;
- priv->write(priv, AR8327_REG_PORT_STATUS(port), t);
- }
+ pdata = priv->phy->dev.platform_data;
+ if (pdata && port == AR8216_PORT_CPU)
+ cfg = &pdata->port0_cfg;
+ else if (pdata && port == 6)
+ cfg = &pdata->port6_cfg;
+ else
+ cfg = NULL;
+
+ ar8327_config_port(priv, port, cfg);
+
priv->write(priv, AR8327_REG_PORT_HEADER(port), 0);
- priv->write(priv, AR8327_REG_PORT_VLAN0(port), 0);
+ t = 1 << AR8327_PORT_VLAN0_DEF_SVID_S;
+ t |= 1 << AR8327_PORT_VLAN0_DEF_CVID_S;
+ priv->write(priv, AR8327_REG_PORT_VLAN0(port), t);
t = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH << AR8327_PORT_VLAN1_OUT_MODE_S;
priv->write(priv, AR8327_REG_PORT_VLAN1(port), t);
goto unlock;
ar8216_mib_fetch_port_stat(priv, port, false);
- mutex_unlock(&priv->mib_lock);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"Port %d MIB counters\n",
next_port:
priv->mib_next_port++;
- if (priv->mib_next_port > priv->dev.ports)
+ if (priv->mib_next_port >= priv->dev.ports)
priv->mib_next_port = 0;
mutex_unlock(&priv->mib_lock);