aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.c24
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.h2
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmmii.c6
-rw-r--r--drivers/net/ethernet/cadence/macb.h25
-rw-r--r--drivers/net/ethernet/cadence/macb_main.c140
-rw-r--r--drivers/net/phy/bcm-phy-ptp.c12
-rw-r--r--drivers/net/phy/broadcom.c764
-rw-r--r--drivers/net/phy/microchip.c27
-rw-r--r--drivers/net/usb/lan78xx.c37
-rw-r--r--drivers/net/usb/smsc95xx.c41
10 files changed, 699 insertions, 379 deletions
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 98971ae4f87d..0d89590d0022 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -65,6 +65,12 @@
/* Forward declarations */
static void bcmgenet_set_rx_mode(struct net_device *dev);
+static bool skip_umac_reset = false;
+module_param(skip_umac_reset, bool, 0444);
+MODULE_PARM_DESC(skip_umac_reset, "Skip UMAC reset step");
+static bool eee = true;
+module_param(eee, bool, 0444);
+MODULE_PARM_DESC(eee, "Enable EEE (default Y)");
static inline void bcmgenet_writel(u32 value, void __iomem *offset)
{
@@ -2566,6 +2572,11 @@ static void reset_umac(struct bcmgenet_priv *priv)
bcmgenet_rbuf_ctrl_set(priv, 0);
udelay(10);
+ if (skip_umac_reset) {
+ pr_warn("Skipping UMAC reset\n");
+ return;
+ }
+
/* issue soft reset and disable MAC while updating its registers */
spin_lock_bh(&priv->reg_lock);
bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD);
@@ -2728,7 +2739,7 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,
bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_PROD_INDEX);
bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_CONS_INDEX);
- bcmgenet_tdma_ring_writel(priv, index, 1, DMA_MBUF_DONE_THRESH);
+ bcmgenet_tdma_ring_writel(priv, index, 10, DMA_MBUF_DONE_THRESH);
/* Disable rate control for now */
bcmgenet_tdma_ring_writel(priv, index, flow_period_val,
TDMA_FLOW_PERIOD);
@@ -3363,6 +3374,17 @@ static int bcmgenet_open(struct net_device *dev)
bcmgenet_phy_pause_set(dev, priv->rx_pause, priv->tx_pause);
+ if (!eee) {
+ struct ethtool_keee eee_data;
+
+ ret = bcmgenet_get_eee(dev, &eee_data);
+ if (ret == 0) {
+ eee_data.eee_enabled = 0;
+ bcmgenet_set_eee(dev, &eee_data);
+ netdev_warn(dev, "EEE disabled\n");
+ }
+ }
+
bcmgenet_netif_start(dev);
netif_tx_start_all_queues(dev);
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
index 5ec3979779ec..3527e8e23a66 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -34,7 +34,7 @@
#define ENET_PAD 8
#define ENET_MAX_MTU_SIZE (ETH_DATA_LEN + ETH_HLEN + VLAN_HLEN + \
ENET_BRCM_TAG_LEN + ETH_FCS_LEN + ENET_PAD)
-#define DMA_MAX_BURST_LENGTH 0x10
+#define DMA_MAX_BURST_LENGTH 0x08
/* misc. configuration */
#define MAX_NUM_OF_FS_RULES 16
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
index 573e8b279e52..f2fd1e5a4015 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
@@ -309,14 +309,14 @@ int bcmgenet_mii_probe(struct net_device *dev)
struct device_node *dn = kdev->of_node;
phy_interface_t phy_iface = priv->phy_interface;
struct phy_device *phydev;
- u32 phy_flags = PHY_BRCM_AUTO_PWRDWN_ENABLE |
- PHY_BRCM_DIS_TXCRXC_NOENRGY |
- PHY_BRCM_IDDQ_SUSPEND;
+ u32 phy_flags = 0;
int ret;
/* Communicate the integrated PHY revision */
if (priv->internal_phy)
phy_flags = priv->gphy_rev;
+ else
+ phy_flags = PHY_BRCM_AUTO_PWRDWN_ENABLE;
/* This is an ugly quirk but we have not been correctly interpreting
* the phy_interface values and we have done that across different
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 0830c48973aa..2c814a2d06b7 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -86,6 +86,8 @@
#define GEM_PBUFRXCUT 0x0044 /* RX Partial Store and Forward */
#define GEM_JML 0x0048 /* Jumbo Max Length */
#define GEM_HS_MAC_CONFIG 0x0050 /* GEM high speed config */
+#define GEM_AMP 0x0054 /* AXI Max Pipeline */
+#define GEM_INTMOD 0x005c /* Interrupt moderation */
#define GEM_HRB 0x0080 /* Hash Bottom */
#define GEM_HRT 0x0084 /* Hash Top */
#define GEM_SA1B 0x0088 /* Specific1 Bottom */
@@ -360,6 +362,21 @@
#define GEM_ADDR64_OFFSET 30 /* Address bus width - 64b or 32b */
#define GEM_ADDR64_SIZE 1
+/* Bitfields in AMP */
+#define GEM_AR2R_MAX_PIPE_OFFSET 0 /* Maximum number of outstanding AXI read requests */
+#define GEM_AR2R_MAX_PIPE_SIZE 8
+#define GEM_AW2W_MAX_PIPE_OFFSET 8 /* Maximum number of outstanding AXI write requests */
+#define GEM_AW2W_MAX_PIPE_SIZE 8
+#define GEM_AW2B_FILL_OFFSET 16 /* Select wether the max AW2W transactions operates between: */
+#define GEM_AW2B_FILL_AW2W 0 /* 0: the AW to W AXI channel */
+#define GEM_AW2B_FILL_AW2B 1 /* 1: AW to B channel */
+#define GEM_AW2B_FILL_SIZE 1
+
+/* Bitfields in INTMOD */
+#define GEM_RX_MODERATION_OFFSET 0 /* RX interrupt moderation */
+#define GEM_RX_MODERATION_SIZE 8
+#define GEM_TX_MODERATION_OFFSET 16 /* TX interrupt moderation */
+#define GEM_TX_MODERATION_SIZE 8
/* Bitfields in PBUFRXCUT */
#define GEM_ENCUTTHRU_OFFSET 31 /* Enable RX partial store and forward */
@@ -843,6 +860,7 @@
})
#define MACB_READ_NSR(bp) macb_readl(bp, NSR)
+#define MACB_READ_TSR(bp) macb_readl(bp, TSR)
/* struct macb_dma_desc - Hardware DMA descriptor
* @addr: DMA address of data buffer
@@ -1260,6 +1278,7 @@ struct macb_queue {
dma_addr_t tx_ring_dma;
struct work_struct tx_error_task;
bool txubr_pending;
+ bool tx_pending;
struct napi_struct napi_tx;
dma_addr_t rx_ring_dma;
@@ -1327,9 +1346,15 @@ struct macb {
u32 caps;
unsigned int dma_burst_length;
+ u8 aw2w_max_pipe;
+ u8 ar2r_max_pipe;
+ bool use_aw2b_fill;
phy_interface_t phy_interface;
+ struct gpio_desc *phy_reset_gpio;
+ int phy_reset_ms;
+
/* AT91RM9200 transmit queue (1 on wire + 1 queued) */
struct macb_tx_skb rm9200_txq[2];
unsigned int max_tx_length;
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index ca2386b83473..db4c08e1514a 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -21,6 +21,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/dma-mapping.h>
+#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/phylink.h>
#include <linux/of.h>
@@ -39,6 +40,9 @@
#include <net/pkt_sched.h>
#include "macb.h"
+static unsigned int txdelay = 35;
+module_param(txdelay, uint, 0644);
+
/* This structure is only used for MACB on SiFive FU540 devices */
struct sifive_fu540_macb_mgmt {
void __iomem *reg;
@@ -328,7 +332,7 @@ static int macb_mdio_wait_for_idle(struct macb *bp)
u32 val;
return readx_poll_timeout(MACB_READ_NSR, bp, val, val & MACB_BIT(IDLE),
- 1, MACB_MDIO_TIMEOUT);
+ 100, MACB_MDIO_TIMEOUT);
}
static int macb_mdio_read_c22(struct mii_bus *bus, int mii_id, int regnum)
@@ -487,6 +491,19 @@ mdio_pm_exit:
return status;
}
+static int macb_mdio_reset(struct mii_bus *bus)
+{
+ struct macb *bp = bus->priv;
+
+ if (bp->phy_reset_gpio) {
+ gpiod_set_value_cansleep(bp->phy_reset_gpio, 1);
+ msleep(bp->phy_reset_ms);
+ gpiod_set_value_cansleep(bp->phy_reset_gpio, 0);
+ }
+
+ return 0;
+}
+
static void macb_init_buffers(struct macb *bp)
{
struct macb_queue *queue;
@@ -953,6 +970,7 @@ static int macb_mii_init(struct macb *bp)
bp->mii_bus->write = &macb_mdio_write_c22;
bp->mii_bus->read_c45 = &macb_mdio_read_c45;
bp->mii_bus->write_c45 = &macb_mdio_write_c45;
+ bp->mii_bus->reset = &macb_mdio_reset;
snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
bp->pdev->name, bp->pdev->id);
bp->mii_bus->priv = bp;
@@ -1629,6 +1647,11 @@ static int macb_rx(struct macb_queue *queue, struct napi_struct *napi,
macb_init_rx_ring(queue);
queue_writel(queue, RBQP, queue->rx_ring_dma);
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ if (bp->hw_dma_cap & HW_DMA_CAP_64B)
+ macb_writel(bp, RBQPH,
+ upper_32_bits(queue->rx_ring_dma));
+#endif
macb_writel(bp, NCR, ctrl | MACB_BIT(RE));
@@ -1931,8 +1954,9 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
queue_writel(queue, ISR, MACB_BIT(TCOMP) |
MACB_BIT(TXUBR));
- if (status & MACB_BIT(TXUBR)) {
+ if (status & MACB_BIT(TXUBR) || queue->tx_pending) {
queue->txubr_pending = true;
+ queue->tx_pending = 0;
wmb(); // ensure softirq can see update
}
@@ -2390,6 +2414,11 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb->len);
spin_lock(&bp->lock);
+
+ /* TSTART write might get dropped, so make the IRQ retrigger a buffer read */
+ if (macb_readl(bp, TSR) & MACB_BIT(TGO))
+ queue->tx_pending = 1;
+
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
spin_unlock(&bp->lock);
@@ -2813,6 +2842,37 @@ static void macb_configure_dma(struct macb *bp)
}
}
+static void gem_init_axi(struct macb *bp)
+{
+ u32 amp;
+
+ /* AXI pipeline setup - don't touch values unless specified in device
+ * tree. Some hardware could have reset values > 1.
+ */
+ amp = gem_readl(bp, AMP);
+
+ if (bp->use_aw2b_fill)
+ amp = GEM_BFINS(AW2B_FILL, bp->use_aw2b_fill, amp);
+ if (bp->aw2w_max_pipe)
+ amp = GEM_BFINS(AW2W_MAX_PIPE, bp->aw2w_max_pipe, amp);
+ if (bp->ar2r_max_pipe)
+ amp = GEM_BFINS(AR2R_MAX_PIPE, bp->ar2r_max_pipe, amp);
+
+ gem_writel(bp, AMP, amp);
+}
+
+static void gem_init_intmod(struct macb *bp)
+{
+ unsigned int throttle;
+ u32 intmod = 0;
+
+ /* Use sensible interrupt moderation thresholds (50us rx and tx) */
+ throttle = (1000 * 50) / 800;
+ intmod = GEM_BFINS(TX_MODERATION, throttle, intmod);
+ intmod = GEM_BFINS(RX_MODERATION, throttle, intmod);
+ gem_writel(bp, INTMOD, intmod);
+}
+
static void macb_init_hw(struct macb *bp)
{
u32 config;
@@ -2841,6 +2901,11 @@ static void macb_init_hw(struct macb *bp)
if (bp->caps & MACB_CAPS_JUMBO)
bp->rx_frm_len_mask = MACB_RX_JFRMLEN_MASK;
+ if (macb_is_gem(bp)) {
+ gem_init_axi(bp);
+ gem_init_intmod(bp);
+ }
+
macb_configure_dma(bp);
/* Enable RX partial store and forward and set watermark */
@@ -3201,6 +3266,52 @@ static void gem_get_ethtool_strings(struct net_device *dev, u32 sset, u8 *p)
}
}
+static int gem_set_coalesce(struct net_device *dev,
+ struct ethtool_coalesce *ec,
+ struct kernel_ethtool_coalesce *kernel_coal,
+ struct netlink_ext_ack *extack)
+{
+ struct macb *bp = netdev_priv(dev);
+ unsigned int tx_throttle;
+ unsigned int rx_throttle;
+ u32 intmod = 0;
+
+ /* GEM has simple IRQ throttling support. RX and TX interrupts
+ * are separately moderated on 800ns quantums, with no support
+ * for frame coalescing.
+ */
+
+ /* Max is 255 * 0.8us = 204us. Zero implies no moderation. */
+ if (ec->rx_coalesce_usecs > 204 || ec->tx_coalesce_usecs > 204)
+ return -EINVAL;
+
+ tx_throttle = (1000 * ec->tx_coalesce_usecs) / 800;
+ rx_throttle = (1000 * ec->rx_coalesce_usecs) / 800;
+
+ intmod = GEM_BFINS(TX_MODERATION, tx_throttle, intmod);
+ intmod = GEM_BFINS(RX_MODERATION, rx_throttle, intmod);
+
+ gem_writel(bp, INTMOD, intmod);
+
+ return 0;
+}
+
+static int gem_get_coalesce(struct net_device *dev,
+ struct ethtool_coalesce *ec,
+ struct kernel_ethtool_coalesce *kernel_coal,
+ struct netlink_ext_ack *extack)
+{
+ struct macb *bp = netdev_priv(dev);
+ u32 intmod;
+
+ intmod = gem_readl(bp, INTMOD);
+
+ ec->tx_coalesce_usecs = (GEM_BFEXT(TX_MODERATION, intmod) * 800) / 1000;
+ ec->rx_coalesce_usecs = (GEM_BFEXT(RX_MODERATION, intmod) * 800) / 1000;
+
+ return 0;
+}
+
static void macb_get_stats(struct net_device *dev,
struct rtnl_link_stats64 *nstat)
{
@@ -3954,6 +4065,8 @@ static const struct ethtool_ops macb_ethtool_ops = {
};
static const struct ethtool_ops gem_ethtool_ops = {
+ .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS |
+ ETHTOOL_COALESCE_TX_USECS,
.get_regs_len = macb_get_regs_len,
.get_regs = macb_get_regs,
.get_wol = macb_get_wol,
@@ -3967,6 +4080,8 @@ static const struct ethtool_ops gem_ethtool_ops = {
.get_eth_mac_stats = gem_get_eth_mac_stats,
.get_eth_phy_stats = gem_get_eth_phy_stats,
.get_rmon_stats = gem_get_rmon_stats,
+ .get_coalesce = gem_get_coalesce,
+ .set_coalesce = gem_set_coalesce,
.get_link_ksettings = macb_get_link_ksettings,
.set_link_ksettings = macb_set_link_ksettings,
.get_ringparam = macb_get_ringparam,
@@ -5533,6 +5648,11 @@ static int macb_probe(struct platform_device *pdev)
}
}
}
+
+ device_property_read_u8(&pdev->dev, "cdns,aw2w-max-pipe", &bp->aw2w_max_pipe);
+ device_property_read_u8(&pdev->dev, "cdns,ar2r-max-pipe", &bp->ar2r_max_pipe);
+ bp->use_aw2b_fill = device_property_read_bool(&pdev->dev, "cdns,use-aw2b-fill");
+
spin_lock_init(&bp->lock);
spin_lock_init(&bp->stats_lock);
@@ -5593,6 +5713,21 @@ static int macb_probe(struct platform_device *pdev)
else
bp->phy_interface = interface;
+ /* optional PHY reset-related properties */
+ bp->phy_reset_gpio = devm_gpiod_get_optional(&pdev->dev, "phy-reset",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(bp->phy_reset_gpio)) {
+ dev_err(&pdev->dev, "Failed to obtain phy-reset gpio\n");
+ err = PTR_ERR(bp->phy_reset_gpio);
+ goto err_out_free_netdev;
+ }
+
+ bp->phy_reset_ms = 10;
+ of_property_read_u32(np, "phy-reset-duration", &bp->phy_reset_ms);
+ /* A sane reset duration should not be longer than 1s */
+ if (bp->phy_reset_ms > 1000)
+ bp->phy_reset_ms = 1000;
+
/* IP specific init */
err = init(pdev);
if (err)
@@ -5932,6 +6067,7 @@ static const struct dev_pm_ops macb_pm_ops = {
static struct platform_driver macb_driver = {
.probe = macb_probe,
.remove = macb_remove,
+ .shutdown = macb_shutdown,
.driver = {
.name = "macb",
.of_match_table = of_match_ptr(macb_dt_ids),
diff --git a/drivers/net/phy/bcm-phy-ptp.c b/drivers/net/phy/bcm-phy-ptp.c
index d3501f8487d9..fcb004fcba3d 100644
--- a/drivers/net/phy/bcm-phy-ptp.c
+++ b/drivers/net/phy/bcm-phy-ptp.c
@@ -912,6 +912,18 @@ struct bcm_ptp_private *bcm_ptp_probe(struct phy_device *phydev)
switch (BRCM_PHY_MODEL(phydev)) {
case PHY_ID_BCM54210E:
break;
+#ifdef PHY_ID_BCM54213PE
+ case PHY_ID_BCM54213PE:
+ switch (phydev->mdio.addr) {
+ case 0: // CM4 - this is a BCM54210PE which supports PTP
+ break;
+ case 1: // 4B - this is a BCM54213PE which doesn't
+ return NULL;
+ default: // Unknown - assume it's BCM54210PE
+ break;
+ }
+ break;
+#endif
default:
return NULL;
}
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index cb306f9e80cc..ddd055da6684 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -31,34 +31,30 @@ MODULE_AUTHOR("Maciej W. Rozycki");
MODULE_LICENSE("GPL");
struct bcm54xx_phy_priv {
- u64 *stats;
+ u64 *stats;
struct bcm_ptp_private *ptp;
- int wake_irq;
- bool wake_irq_enabled;
- bool brr_mode;
+ int wake_irq;
+ bool wake_irq_enabled;
+ bool brr_mode;
};
/* Link modes for BCM58411 PHY */
-static const int bcm54811_linkmodes[] = {
- ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
- ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
- ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
- ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
- ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
- ETHTOOL_LINK_MODE_100baseT_Full_BIT,
- ETHTOOL_LINK_MODE_100baseT_Half_BIT,
- ETHTOOL_LINK_MODE_10baseT_Full_BIT,
- ETHTOOL_LINK_MODE_10baseT_Half_BIT
-};
+static const int bcm54811_linkmodes[] = { ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
+ ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
+ ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
+ ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+ ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+ ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_10baseT_Half_BIT };
/* Long-Distance Signaling (BroadR-Reach mode aneg) relevant linkmode bits */
-static const int lds_br_bits[] = {
- ETHTOOL_LINK_MODE_Autoneg_BIT,
- ETHTOOL_LINK_MODE_Pause_BIT,
- ETHTOOL_LINK_MODE_Asym_Pause_BIT,
- ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
- ETHTOOL_LINK_MODE_100baseT1_Full_BIT
-};
+static const int lds_br_bits[] = { ETHTOOL_LINK_MODE_Autoneg_BIT,
+ ETHTOOL_LINK_MODE_Pause_BIT,
+ ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+ ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
+ ETHTOOL_LINK_MODE_100baseT1_Full_BIT };
static bool bcm54xx_phy_can_wakeup(struct phy_device *phydev)
{
@@ -84,8 +80,7 @@ static int bcm54xx_config_clock_delay(struct phy_device *phydev)
/* Enable RGMII RXC-RXD skew */
val |= MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
}
- rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
- val);
+ rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, val);
if (rc < 0)
return rc;
@@ -123,6 +118,11 @@ static int bcm54210e_config_init(struct phy_device *phydev)
return 0;
}
+static int bcm54213pe_config_init(struct phy_device *phydev)
+{
+ return bcm54210e_config_init(phydev);
+}
+
static int bcm54612e_config_init(struct phy_device *phydev)
{
int reg;
@@ -159,8 +159,7 @@ static int bcm54616s_config_init(struct phy_device *phydev)
return val;
val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_EN;
val |= MII_BCM54XX_AUXCTL_MISC_WREN;
- rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
- val);
+ rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, val);
if (rc < 0)
return rc;
@@ -181,8 +180,8 @@ static int bcm54616s_config_init(struct phy_device *phydev)
/* Select proper interface mode */
val &= ~BCM54XX_SHD_INTF_SEL_MASK;
val |= phydev->interface == PHY_INTERFACE_MODE_SGMII ?
- BCM54XX_SHD_INTF_SEL_SGMII :
- BCM54XX_SHD_INTF_SEL_GBIC;
+ BCM54XX_SHD_INTF_SEL_SGMII :
+ BCM54XX_SHD_INTF_SEL_GBIC;
rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val);
if (rc < 0)
return rc;
@@ -209,7 +208,7 @@ static int bcm50610_a0_workaround(struct phy_device *phydev)
err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_AADJ1CH0,
MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN |
- MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF);
+ MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF);
if (err < 0)
return err;
@@ -239,10 +238,9 @@ static int bcm54xx_phydsp_config(struct phy_device *phydev)
int err, err2;
/* Enable the SMDSP clock */
- err = bcm54xx_auxctl_write(phydev,
- MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
+ err = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
- MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
+ MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
if (err < 0)
return err;
@@ -274,8 +272,7 @@ static int bcm54xx_phydsp_config(struct phy_device *phydev)
error:
/* Disable the SMDSP clock */
- err2 = bcm54xx_auxctl_write(phydev,
- MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
+ err2 = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
/* Return the first error reported. */
@@ -293,6 +290,7 @@ static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev)
phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM50610) ||
phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM50610M) ||
phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM54210E) ||
+ phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM54213PE) ||
phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM54810) ||
phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM54811)))
return;
@@ -328,8 +326,10 @@ static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev)
val |= BCM54XX_SHD_SCR3_DLLAPD_DIS;
if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) {
- if (phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM54210E) ||
- phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM54810) ||
+ if (phy_id_compare_model(phydev->drv->phy_id,
+ PHY_ID_BCM54210E) ||
+ phy_id_compare_model(phydev->drv->phy_id,
+ PHY_ID_BCM54810) ||
phy_id_compare_model(phydev->drv->phy_id, PHY_ID_BCM54811))
val |= BCM54XX_SHD_SCR3_RXCTXC_DIS;
else
@@ -386,8 +386,8 @@ static int bcm5481x_set_brrmode(struct phy_device *phydev, bool on)
else
reg &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
- err = bcm_phy_write_exp(phydev,
- BCM54810_EXP_BROADREACH_LRE_MISC_CTL, reg);
+ err = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
+ reg);
if (err)
return err;
@@ -444,11 +444,10 @@ static int bcm54811_config_init(struct phy_device *phydev)
/* Also writing Reserved bits 6:5 because the documentation requires
* them to be written to 0b11
*/
- err = bcm54xx_auxctl_write(phydev,
- MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
- MII_BCM54XX_AUXCTL_MISC_WREN |
- aux_rgmii_en |
- MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RSVD);
+ err = bcm54xx_auxctl_write(
+ phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
+ MII_BCM54XX_AUXCTL_MISC_WREN | aux_rgmii_en |
+ MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RSVD);
if (err < 0)
return err;
@@ -458,6 +457,9 @@ static int bcm54811_config_init(struct phy_device *phydev)
static int bcm54xx_config_init(struct phy_device *phydev)
{
int reg, err, val;
+ u32 led_modes[] = { BCM_LED_MULTICOLOR_LINK_ACT,
+ BCM_LED_MULTICOLOR_LINK };
+ struct device_node *np = phydev->mdio.dev.of_node;
reg = phy_read(phydev, MII_BCM54XX_ECR);
if (reg < 0)
@@ -470,8 +472,7 @@ static int bcm54xx_config_init(struct phy_device *phydev)
return err;
/* Unmask events we are interested in. */
- reg = ~(MII_BCM54XX_INT_DUPLEX |
- MII_BCM54XX_INT_SPEED |
+ reg = ~(MII_BCM54XX_INT_DUPLEX | MII_BCM54XX_INT_SPEED |
MII_BCM54XX_INT_LINK);
err = phy_write(phydev, MII_BCM54XX_IMR, reg);
if (err < 0)
@@ -482,6 +483,9 @@ static int bcm54xx_config_init(struct phy_device *phydev)
(phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE))
bcm_phy_write_shadow(phydev, BCM54XX_SHD_RGMII_MODE, 0);
+ if (of_property_read_bool(np, "brcm,powerdown-enable"))
+ phydev->dev_flags |= PHY_BRCM_AUTO_PWRDWN_ENABLE;
+
bcm54xx_adjust_rxrefclk(phydev);
switch (phydev->drv->phy_id & PHY_ID_MATCH_MODEL_MASK) {
@@ -495,6 +499,9 @@ static int bcm54xx_config_init(struct phy_device *phydev)
case PHY_ID_BCM54612E:
err = bcm54612e_config_init(phydev);
break;
+ case PHY_ID_BCM54213PE:
+ err = bcm54213pe_config_init(phydev);
+ break;
case PHY_ID_BCM54616S:
err = bcm54616s_config_init(phydev);
break;
@@ -503,9 +510,8 @@ static int bcm54xx_config_init(struct phy_device *phydev)
val = bcm_phy_read_exp(phydev,
BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
- err = bcm_phy_write_exp(phydev,
- BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
- val);
+ err = bcm_phy_write_exp(
+ phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL, val);
break;
case PHY_ID_BCM54811:
err = bcm54811_config_init(phydev);
@@ -516,22 +522,27 @@ static int bcm54xx_config_init(struct phy_device *phydev)
bcm54xx_phydsp_config(phydev);
+ of_property_read_u32_array(np, "led-modes", led_modes, 2);
+
/* For non-SFP setups, encode link speed into LED1 and LED3 pair
* (green/amber).
- * Also flash these two LEDs on activity. This means configuring
- * them for MULTICOLOR and encoding link/activity into them.
* Don't do this for devices on an SFP module, since some of these
* use the LED outputs to control the SFP LOS signal, and changing
* these settings will cause LOS to malfunction.
*/
if (!phy_on_sfp(phydev)) {
val = BCM54XX_SHD_LEDS1_LED1(BCM_LED_SRC_MULTICOLOR1) |
- BCM54XX_SHD_LEDS1_LED3(BCM_LED_SRC_MULTICOLOR1);
+ BCM54XX_SHD_LEDS1_LED3(BCM_LED_SRC_MULTICOLOR1);
bcm_phy_write_shadow(phydev, BCM54XX_SHD_LEDS1, val);
+ /* BCM54210PE controls two extra LEDs with the next register.
+ * Make them shadow the first pair of LEDs - useful on CM4 which
+ * uses LED3 for ETH_LEDY instead of LED1.
+ */
+ bcm_phy_write_shadow(phydev, BCM54XX_SHD_LEDS1 + 1, val);
val = BCM_LED_MULTICOLOR_IN_PHASE |
- BCM54XX_SHD_LEDS1_LED1(BCM_LED_MULTICOLOR_LINK_ACT) |
- BCM54XX_SHD_LEDS1_LED3(BCM_LED_MULTICOLOR_LINK_ACT);
+ BCM54XX_SHD_LEDS1_LED1(led_modes[0]) |
+ BCM54XX_SHD_LEDS1_LED3(led_modes[1]);
bcm_phy_write_exp(phydev, BCM_EXP_MULTICOLOR, val);
}
@@ -664,7 +675,6 @@ static int bcm54810_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
return -EOPNOTSUPP;
}
-
/**
* bcm5481x_read_abilities - read PHY abilities from LRESR or Clause 22
* (BMSR) registers, based on whether the PHY is in BroadR-Reach or IEEE mode
@@ -715,14 +725,11 @@ static int bcm5481x_read_abilities(struct phy_device *phydev)
aneg = val & LRESR_LDSABILITY;
linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
- phydev->supported,
- aneg);
+ phydev->supported, aneg);
linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
- phydev->supported,
- val & LRESR_100_1PAIR);
+ phydev->supported, val & LRESR_100_1PAIR);
linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
- phydev->supported,
- val & LRESR_10_1PAIR);
+ phydev->supported, val & LRESR_10_1PAIR);
return 0;
}
@@ -738,9 +745,8 @@ static int bcm5481x_config_delay_swap(struct phy_device *phydev)
if (of_property_read_bool(np, "enet-phy-lane-swap")) {
/* Lane Swap - Undocumented register...magic! */
- int ret = bcm_phy_write_exp(phydev,
- MII_BCM54XX_EXP_SEL_ER + 0x9,
- 0x11B);
+ int ret = bcm_phy_write_exp(
+ phydev, MII_BCM54XX_EXP_SEL_ER + 0x9, 0x11B);
if (ret < 0)
return ret;
}
@@ -905,13 +911,10 @@ static int brcm_fet_config_init(struct phy_device *phydev)
/* Unmask events we are interested in and mask interrupts globally. */
if (phydev->drv->phy_id == PHY_ID_BCM5221)
- reg = MII_BRCM_FET_IR_ENABLE |
- MII_BRCM_FET_IR_MASK;
+ reg = MII_BRCM_FET_IR_ENABLE | MII_BRCM_FET_IR_MASK;
else
- reg = MII_BRCM_FET_IR_DUPLEX_EN |
- MII_BRCM_FET_IR_SPEED_EN |
- MII_BRCM_FET_IR_LINK_EN |
- MII_BRCM_FET_IR_ENABLE |
+ reg = MII_BRCM_FET_IR_DUPLEX_EN | MII_BRCM_FET_IR_SPEED_EN |
+ MII_BRCM_FET_IR_LINK_EN | MII_BRCM_FET_IR_ENABLE |
MII_BRCM_FET_IR_MASK;
err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
@@ -1095,9 +1098,9 @@ static int bcm5221_config_aneg(struct phy_device *phydev)
return 0;
}
- return phy_modify(phydev, BCM5221_AEGSR, BCM5221_AEGSR_MDIX_MAN_SWAP |
- BCM5221_AEGSR_MDIX_DIS,
- val);
+ return phy_modify(phydev, BCM5221_AEGSR,
+ BCM5221_AEGSR_MDIX_MAN_SWAP | BCM5221_AEGSR_MDIX_DIS,
+ val);
}
static int bcm5221_read_status(struct phy_device *phydev)
@@ -1316,8 +1319,7 @@ static int lre_read_lpa(struct phy_device *phydev)
phydev->lp_advertising,
lrelpa & LRELPA_PAUSE_ASYM);
linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT,
- phydev->lp_advertising,
- lrelpa & LRELPA_PAUSE);
+ phydev->lp_advertising, lrelpa & LRELPA_PAUSE);
linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
phydev->lp_advertising,
lrelpa & LRELPA_100_1PAIR);
@@ -1416,8 +1418,7 @@ static int bcm54811_lre_read_status(struct phy_device *phydev)
return err;
/* why bother the PHY if nothing can have changed */
- if (phydev->autoneg ==
- AUTONEG_ENABLE && old_link && phydev->link)
+ if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
return 0;
phydev->speed = SPEED_UNKNOWN;
@@ -1447,304 +1448,339 @@ static int bcm54811_read_status(struct phy_device *phydev)
struct bcm54xx_phy_priv *priv = phydev->priv;
if (priv->brr_mode)
- return bcm54811_lre_read_status(phydev);
+ return bcm54811_lre_read_status(phydev);
return genphy_read_status(phydev);
}
static struct phy_driver broadcom_drivers[] = {
-{
- PHY_ID_MATCH_MODEL(PHY_ID_BCM5411),
- .name = "Broadcom BCM5411",
- /* PHY_GBIT_FEATURES */
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .config_init = bcm54xx_config_init,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .link_change_notify = bcm54xx_link_change_notify,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM5421),
- .name = "Broadcom BCM5421",
- /* PHY_GBIT_FEATURES */
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .config_init = bcm54xx_config_init,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .link_change_notify = bcm54xx_link_change_notify,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM54210E),
- .name = "Broadcom BCM54210E",
- /* PHY_GBIT_FEATURES */
- .flags = PHY_ALWAYS_CALL_SUSPEND,
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .config_init = bcm54xx_config_init,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .link_change_notify = bcm54xx_link_change_notify,
- .suspend = bcm54xx_suspend,
- .resume = bcm54xx_resume,
- .get_wol = bcm54xx_phy_get_wol,
- .set_wol = bcm54xx_phy_set_wol,
- .led_brightness_set = bcm_phy_led_brightness_set,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM5461),
- .name = "Broadcom BCM5461",
- /* PHY_GBIT_FEATURES */
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .config_init = bcm54xx_config_init,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .link_change_notify = bcm54xx_link_change_notify,
- .led_brightness_set = bcm_phy_led_brightness_set,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM54612E),
- .name = "Broadcom BCM54612E",
- /* PHY_GBIT_FEATURES */
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .config_init = bcm54xx_config_init,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .link_change_notify = bcm54xx_link_change_notify,
- .led_brightness_set = bcm_phy_led_brightness_set,
- .suspend = bcm54xx_suspend,
- .resume = bcm54xx_resume,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM54616S),
- .name = "Broadcom BCM54616S",
- /* PHY_GBIT_FEATURES */
- .soft_reset = genphy_soft_reset,
- .config_init = bcm54xx_config_init,
- .config_aneg = bcm54616s_config_aneg,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .read_status = bcm54616s_read_status,
- .probe = bcm54616s_probe,
- .link_change_notify = bcm54xx_link_change_notify,
- .led_brightness_set = bcm_phy_led_brightness_set,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM5464),
- .name = "Broadcom BCM5464",
- /* PHY_GBIT_FEATURES */
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .config_init = bcm54xx_config_init,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- .link_change_notify = bcm54xx_link_change_notify,
- .led_brightness_set = bcm_phy_led_brightness_set,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM5481),
- .name = "Broadcom BCM5481",
- /* PHY_GBIT_FEATURES */
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .config_init = bcm54xx_config_init,
- .config_aneg = bcm5481_config_aneg,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .link_change_notify = bcm54xx_link_change_notify,
- .led_brightness_set = bcm_phy_led_brightness_set,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM54810),
- .name = "Broadcom BCM54810",
- /* PHY_GBIT_FEATURES */
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .read_mmd = bcm54810_read_mmd,
- .write_mmd = bcm54810_write_mmd,
- .config_init = bcm54xx_config_init,
- .config_aneg = bcm5481_config_aneg,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .suspend = bcm54xx_suspend,
- .resume = bcm54xx_resume,
- .link_change_notify = bcm54xx_link_change_notify,
- .led_brightness_set = bcm_phy_led_brightness_set,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM54811),
- .name = "Broadcom BCM54811",
- /* PHY_GBIT_FEATURES */
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .config_init = bcm54xx_config_init,
- .config_aneg = bcm54811_config_aneg,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .read_status = bcm54811_read_status,
- .get_features = bcm5481x_read_abilities,
- .suspend = bcm54xx_suspend,
- .resume = bcm54xx_resume,
- .link_change_notify = bcm54xx_link_change_notify,
- .led_brightness_set = bcm_phy_led_brightness_set,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM5482),
- .name = "Broadcom BCM5482",
- /* PHY_GBIT_FEATURES */
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .config_init = bcm54xx_config_init,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .link_change_notify = bcm54xx_link_change_notify,
- .led_brightness_set = bcm_phy_led_brightness_set,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM50610),
- .name = "Broadcom BCM50610",
- /* PHY_GBIT_FEATURES */
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .config_init = bcm54xx_config_init,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .link_change_notify = bcm54xx_link_change_notify,
- .suspend = bcm54xx_suspend,
- .resume = bcm54xx_resume,
- .led_brightness_set = bcm_phy_led_brightness_set,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM50610M),
- .name = "Broadcom BCM50610M",
- /* PHY_GBIT_FEATURES */
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .config_init = bcm54xx_config_init,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .link_change_notify = bcm54xx_link_change_notify,
- .suspend = bcm54xx_suspend,
- .resume = bcm54xx_resume,
- .led_brightness_set = bcm_phy_led_brightness_set,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM57780),
- .name = "Broadcom BCM57780",
- /* PHY_GBIT_FEATURES */
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .config_init = bcm54xx_config_init,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .link_change_notify = bcm54xx_link_change_notify,
- .led_brightness_set = bcm_phy_led_brightness_set,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCMAC131),
- .name = "Broadcom BCMAC131",
- /* PHY_BASIC_FEATURES */
- .config_init = brcm_fet_config_init,
- .config_intr = brcm_fet_config_intr,
- .handle_interrupt = brcm_fet_handle_interrupt,
- .suspend = brcm_fet_suspend,
- .resume = brcm_fet_config_init,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM5241),
- .name = "Broadcom BCM5241",
- /* PHY_BASIC_FEATURES */
- .config_init = brcm_fet_config_init,
- .config_intr = brcm_fet_config_intr,
- .handle_interrupt = brcm_fet_handle_interrupt,
- .suspend = brcm_fet_suspend,
- .resume = brcm_fet_config_init,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM5221),
- .name = "Broadcom BCM5221",
- /* PHY_BASIC_FEATURES */
- .config_init = brcm_fet_config_init,
- .config_intr = brcm_fet_config_intr,
- .handle_interrupt = brcm_fet_handle_interrupt,
- .suspend = brcm_fet_suspend,
- .resume = brcm_fet_config_init,
- .config_aneg = bcm5221_config_aneg,
- .read_status = bcm5221_read_status,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM5395),
- .name = "Broadcom BCM5395",
- .flags = PHY_IS_INTERNAL,
- /* PHY_GBIT_FEATURES */
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .link_change_notify = bcm54xx_link_change_notify,
- .led_brightness_set = bcm_phy_led_brightness_set,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM53125),
- .name = "Broadcom BCM53125",
- .flags = PHY_IS_INTERNAL,
- /* PHY_GBIT_FEATURES */
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .config_init = bcm54xx_config_init,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .link_change_notify = bcm54xx_link_change_notify,
- .led_brightness_set = bcm_phy_led_brightness_set,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM53128),
- .name = "Broadcom BCM53128",
- .flags = PHY_IS_INTERNAL,
- /* PHY_GBIT_FEATURES */
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .config_init = bcm54xx_config_init,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .link_change_notify = bcm54xx_link_change_notify,
- .led_brightness_set = bcm_phy_led_brightness_set,
-}, {
- PHY_ID_MATCH_MODEL(PHY_ID_BCM89610),
- .name = "Broadcom BCM89610",
- /* PHY_GBIT_FEATURES */
- .get_sset_count = bcm_phy_get_sset_count,
- .get_strings = bcm_phy_get_strings,
- .get_stats = bcm54xx_get_stats,
- .probe = bcm54xx_phy_probe,
- .config_init = bcm54xx_config_init,
- .config_intr = bcm_phy_config_intr,
- .handle_interrupt = bcm_phy_handle_interrupt,
- .link_change_notify = bcm54xx_link_change_notify,
-} };
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM5411),
+ .name = "Broadcom BCM5411",
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .config_init = bcm54xx_config_init,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .link_change_notify = bcm54xx_link_change_notify,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM5421),
+ .name = "Broadcom BCM5421",
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .config_init = bcm54xx_config_init,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .link_change_notify = bcm54xx_link_change_notify,
+ },
+ {
+ PHY_ID_MATCH_EXACT(PHY_ID_BCM54210E),
+ .name = "Broadcom BCM54210E",
+ /* PHY_GBIT_FEATURES */
+ .flags = PHY_ALWAYS_CALL_SUSPEND,
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .config_init = bcm54xx_config_init,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .link_change_notify = bcm54xx_link_change_notify,
+ .suspend = bcm54xx_suspend,
+ .resume = bcm54xx_resume,
+ .get_wol = bcm54xx_phy_get_wol,
+ .set_wol = bcm54xx_phy_set_wol,
+ .led_brightness_set = bcm_phy_led_brightness_set,
+ },
+ {
+ PHY_ID_MATCH_EXACT(PHY_ID_BCM54213PE),
+ .name = "Broadcom BCM54213PE",
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .config_init = bcm54xx_config_init,
+ .config_intr = bcm_phy_config_intr,
+ .suspend = bcm54xx_suspend,
+ .resume = bcm54xx_resume,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM5461),
+ .name = "Broadcom BCM5461",
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .config_init = bcm54xx_config_init,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .link_change_notify = bcm54xx_link_change_notify,
+ .led_brightness_set = bcm_phy_led_brightness_set,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM54612E),
+ .name = "Broadcom BCM54612E",
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .config_init = bcm54xx_config_init,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .link_change_notify = bcm54xx_link_change_notify,
+ .led_brightness_set = bcm_phy_led_brightness_set,
+ .suspend = bcm54xx_suspend,
+ .resume = bcm54xx_resume,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM54616S),
+ .name = "Broadcom BCM54616S",
+ /* PHY_GBIT_FEATURES */
+ .soft_reset = genphy_soft_reset,
+ .config_init = bcm54xx_config_init,
+ .config_aneg = bcm54616s_config_aneg,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .read_status = bcm54616s_read_status,
+ .probe = bcm54616s_probe,
+ .link_change_notify = bcm54xx_link_change_notify,
+ .led_brightness_set = bcm_phy_led_brightness_set,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM5464),
+ .name = "Broadcom BCM5464",
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .config_init = bcm54xx_config_init,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .link_change_notify = bcm54xx_link_change_notify,
+ .led_brightness_set = bcm_phy_led_brightness_set,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM5481),
+ .name = "Broadcom BCM5481",
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .config_init = bcm54xx_config_init,
+ .config_aneg = bcm5481_config_aneg,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .link_change_notify = bcm54xx_link_change_notify,
+ .led_brightness_set = bcm_phy_led_brightness_set,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM54810),
+ .name = "Broadcom BCM54810",
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .read_mmd = bcm54810_read_mmd,
+ .write_mmd = bcm54810_write_mmd,
+ .config_init = bcm54xx_config_init,
+ .config_aneg = bcm5481_config_aneg,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .suspend = bcm54xx_suspend,
+ .resume = bcm54xx_resume,
+ .link_change_notify = bcm54xx_link_change_notify,
+ .led_brightness_set = bcm_phy_led_brightness_set,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM54811),
+ .name = "Broadcom BCM54811",
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .config_init = bcm54xx_config_init,
+ .config_aneg = bcm54811_config_aneg,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .read_status = bcm54811_read_status,
+ .get_features = bcm5481x_read_abilities,
+ .suspend = bcm54xx_suspend,
+ .resume = bcm54xx_resume,
+ .link_change_notify = bcm54xx_link_change_notify,
+ .led_brightness_set = bcm_phy_led_brightness_set,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM5482),
+ .name = "Broadcom BCM5482",
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .config_init = bcm54xx_config_init,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .link_change_notify = bcm54xx_link_change_notify,
+ .led_brightness_set = bcm_phy_led_brightness_set,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM50610),
+ .name = "Broadcom BCM50610",
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .config_init = bcm54xx_config_init,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .link_change_notify = bcm54xx_link_change_notify,
+ .suspend = bcm54xx_suspend,
+ .resume = bcm54xx_resume,
+ .led_brightness_set = bcm_phy_led_brightness_set,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM50610M),
+ .name = "Broadcom BCM50610M",
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .config_init = bcm54xx_config_init,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .link_change_notify = bcm54xx_link_change_notify,
+ .suspend = bcm54xx_suspend,
+ .resume = bcm54xx_resume,
+ .led_brightness_set = bcm_phy_led_brightness_set,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM57780),
+ .name = "Broadcom BCM57780",
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .config_init = bcm54xx_config_init,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .link_change_notify = bcm54xx_link_change_notify,
+ .led_brightness_set = bcm_phy_led_brightness_set,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCMAC131),
+ .name = "Broadcom BCMAC131",
+ /* PHY_BASIC_FEATURES */
+ .config_init = brcm_fet_config_init,
+ .config_intr = brcm_fet_config_intr,
+ .handle_interrupt = brcm_fet_handle_interrupt,
+ .suspend = brcm_fet_suspend,
+ .resume = brcm_fet_config_init,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM5241),
+ .name = "Broadcom BCM5241",
+ /* PHY_BASIC_FEATURES */
+ .config_init = brcm_fet_config_init,
+ .config_intr = brcm_fet_config_intr,
+ .handle_interrupt = brcm_fet_handle_interrupt,
+ .suspend = brcm_fet_suspend,
+ .resume = brcm_fet_config_init,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM5221),
+ .name = "Broadcom BCM5221",
+ /* PHY_BASIC_FEATURES */
+ .config_init = brcm_fet_config_init,
+ .config_intr = brcm_fet_config_intr,
+ .handle_interrupt = brcm_fet_handle_interrupt,
+ .suspend = brcm_fet_suspend,
+ .resume = brcm_fet_config_init,
+ .config_aneg = bcm5221_config_aneg,
+ .read_status = bcm5221_read_status,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM5395),
+ .name = "Broadcom BCM5395",
+ .flags = PHY_IS_INTERNAL,
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .link_change_notify = bcm54xx_link_change_notify,
+ .led_brightness_set = bcm_phy_led_brightness_set,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM53125),
+ .name = "Broadcom BCM53125",
+ .flags = PHY_IS_INTERNAL,
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .config_init = bcm54xx_config_init,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .link_change_notify = bcm54xx_link_change_notify,
+ .led_brightness_set = bcm_phy_led_brightness_set,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM53128),
+ .name = "Broadcom BCM53128",
+ .flags = PHY_IS_INTERNAL,
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .config_init = bcm54xx_config_init,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .link_change_notify = bcm54xx_link_change_notify,
+ .led_brightness_set = bcm_phy_led_brightness_set,
+ },
+ {
+ PHY_ID_MATCH_MODEL(PHY_ID_BCM89610),
+ .name = "Broadcom BCM89610",
+ /* PHY_GBIT_FEATURES */
+ .get_sset_count = bcm_phy_get_sset_count,
+ .get_strings = bcm_phy_get_strings,
+ .get_stats = bcm54xx_get_stats,
+ .probe = bcm54xx_phy_probe,
+ .config_init = bcm54xx_config_init,
+ .config_intr = bcm_phy_config_intr,
+ .handle_interrupt = bcm_phy_handle_interrupt,
+ .link_change_notify = bcm54xx_link_change_notify,
+ }
+};
module_phy_driver(broadcom_drivers);
static const struct mdio_device_id __maybe_unused broadcom_tbl[] = {
{ PHY_ID_MATCH_MODEL(PHY_ID_BCM5411) },
{ PHY_ID_MATCH_MODEL(PHY_ID_BCM5421) },
- { PHY_ID_MATCH_MODEL(PHY_ID_BCM54210E) },
+ { PHY_ID_MATCH_EXACT(PHY_ID_BCM54210E) },
+ { PHY_ID_MATCH_EXACT(PHY_ID_BCM54213PE) },
{ PHY_ID_MATCH_MODEL(PHY_ID_BCM5461) },
{ PHY_ID_MATCH_MODEL(PHY_ID_BCM54612E) },
{ PHY_ID_MATCH_MODEL(PHY_ID_BCM54616S) },
@@ -1763,7 +1799,7 @@ static const struct mdio_device_id __maybe_unused broadcom_tbl[] = {
{ PHY_ID_MATCH_MODEL(PHY_ID_BCM53125) },
{ PHY_ID_MATCH_MODEL(PHY_ID_BCM53128) },
{ PHY_ID_MATCH_MODEL(PHY_ID_BCM89610) },
- { }
+ {}
};
MODULE_DEVICE_TABLE(mdio, broadcom_tbl);
diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c
index dc8634e7bcbe..53f6f7c89237 100644
--- a/drivers/net/phy/microchip.c
+++ b/drivers/net/phy/microchip.c
@@ -198,6 +198,7 @@ static int lan88xx_probe(struct phy_device *phydev)
struct device *dev = &phydev->mdio.dev;
struct lan88xx_priv *priv;
u32 led_modes[4];
+ u32 downshift_after = 0;
int len;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -227,6 +228,32 @@ static int lan88xx_probe(struct phy_device *phydev)
return -EINVAL;
}
+ if (!of_property_read_u32(dev->of_node,
+ "microchip,downshift-after",
+ &downshift_after)) {
+ u32 mask = LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_MASK;
+ u32 val= LAN78XX_PHY_CTRL3_AUTO_DOWNSHIFT;
+
+ switch (downshift_after) {
+ case 2: val |= LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_2;
+ break;
+ case 3: val |= LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_3;
+ break;
+ case 4: val |= LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_4;
+ break;
+ case 5: val |= LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_5;
+ break;
+ case 0: // Disable completely
+ mask = LAN78XX_PHY_CTRL3_AUTO_DOWNSHIFT;
+ val = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ (void)phy_modify_paged(phydev, 1, LAN78XX_PHY_CTRL3,
+ mask, val);
+ }
+
/* these values can be used to identify internal PHY */
priv->chip_id = phy_read_mmd(phydev, 3, LAN88XX_MMD3_CHIP_ID);
priv->chip_rev = phy_read_mmd(phydev, 3, LAN88XX_MMD3_CHIP_REV);
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index 00397a807393..bb28ea01449a 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -596,6 +596,20 @@ static int lan78xx_alloc_tx_resources(struct lan78xx_net *dev)
dev->n_tx_urbs, dev->tx_urb_size, dev);
}
+/* TSO seems to be having some issue with Selective Acknowledge (SACK) that
+ * results in lost data never being retransmitted.
+ * Disable it by default now, but adds a module parameter to enable it for
+ * debug purposes (the full cause is not currently understood).
+ */
+static bool enable_tso;
+module_param(enable_tso, bool, 0644);
+MODULE_PARM_DESC(enable_tso, "Enables TCP segmentation offload");
+
+#define INT_URB_MICROFRAMES_PER_MS 8
+static int int_urb_interval_ms = 8;
+module_param(int_urb_interval_ms, int, 0);
+MODULE_PARM_DESC(int_urb_interval_ms, "Override usb interrupt urb interval");
+
static int lan78xx_read_reg(struct lan78xx_net *dev, u32 index, u32 *data)
{
u32 *buf;
@@ -1918,6 +1932,7 @@ static const struct ethtool_ops lan78xx_ethtool_ops = {
.set_link_ksettings = lan78xx_set_link_ksettings,
.get_regs_len = lan78xx_get_regs_len,
.get_regs = lan78xx_get_regs,
+ .get_ts_info = ethtool_op_get_ts_info,
};
static int lan78xx_init_mac_address(struct lan78xx_net *dev)
@@ -3294,6 +3309,10 @@ static int lan78xx_reset(struct lan78xx_net *dev)
buf |= HW_CFG_CLK125_EN_;
buf |= HW_CFG_REFCLK25_EN_;
+ /* If no valid EEPROM and no valid OTP, enable the LEDs by default */
+ if (!has_eeprom && !has_otp)
+ buf |= HW_CFG_LED0_EN_ | HW_CFG_LED1_EN_;
+
ret = lan78xx_write_reg(dev, HW_CFG, buf);
if (ret < 0)
return ret;
@@ -3756,8 +3775,14 @@ static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf)
if (DEFAULT_RX_CSUM_ENABLE)
dev->net->features |= NETIF_F_RXCSUM;
- if (DEFAULT_TSO_CSUM_ENABLE)
- dev->net->features |= NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG;
+ if (DEFAULT_TSO_CSUM_ENABLE) {
+ dev->net->features |= NETIF_F_SG;
+ /* Use module parameter to control TCP segmentation offload as
+ * it appears to cause issues.
+ */
+ if (enable_tso)
+ dev->net->features |= NETIF_F_TSO | NETIF_F_TSO6;
+ }
if (DEFAULT_VLAN_RX_OFFLOAD)
dev->net->features |= NETIF_F_HW_VLAN_CTAG_RX;
@@ -4720,7 +4745,13 @@ static int lan78xx_probe(struct usb_interface *intf,
if (ret < 0)
goto out4;
- period = ep_intr->desc.bInterval;
+ if (int_urb_interval_ms <= 0)
+ period = ep_intr->desc.bInterval;
+ else
+ period = int_urb_interval_ms * INT_URB_MICROFRAMES_PER_MS;
+
+ netif_notice(dev, probe, netdev, "int urb period %d\n", period);
+
maxp = usb_maxpacket(dev->udev, dev->pipe_intr);
dev->urb_intr = usb_alloc_urb(0, GFP_KERNEL);
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index de733e0488bf..b83a9840e3c6 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -82,6 +82,14 @@ static bool turbo_mode = true;
module_param(turbo_mode, bool, 0644);
MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
+static int packetsize = 2560;
+module_param(packetsize, int, 0644);
+MODULE_PARM_DESC(packetsize, "Override the RX URB packet size");
+
+static char *macaddr = ":";
+module_param(macaddr, charp, 0);
+MODULE_PARM_DESC(macaddr, "MAC address");
+
static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index,
u32 *data)
{
@@ -862,6 +870,21 @@ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
return phy_mii_ioctl(netdev->phydev, rq, cmd);
}
+/* Check the macaddr module parameter for a MAC address */
+static int smsc95xx_macaddr_param(struct usbnet *dev, struct net_device *nd)
+{
+ u8 mtbl[ETH_ALEN];
+
+ if (mac_pton(macaddr, mtbl)) {
+ netif_dbg(dev, ifup, dev->net,
+ "Overriding MAC address with: %pM\n", mtbl);
+ dev_addr_mod(nd, 0, mtbl, ETH_ALEN);
+ return 0;
+ } else {
+ return -EINVAL;
+ }
+}
+
static void smsc95xx_init_mac_address(struct usbnet *dev)
{
u8 addr[ETH_ALEN];
@@ -885,6 +908,14 @@ static void smsc95xx_init_mac_address(struct usbnet *dev)
}
}
+ /* Check module parameters */
+ if (smsc95xx_macaddr_param(dev, dev->net) == 0) {
+ if (is_valid_ether_addr(dev->net->dev_addr)) {
+ netif_dbg(dev, ifup, dev->net, "MAC address read from module parameter\n");
+ return;
+ }
+ }
+
/* no useful static MAC address found. generate a random one */
eth_hw_addr_random(dev->net);
netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n");
@@ -993,13 +1024,13 @@ static int smsc95xx_reset(struct usbnet *dev)
if (!turbo_mode) {
burst_cap = 0;
- dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE;
+ dev->rx_urb_size = packetsize ? packetsize : MAX_SINGLE_PACKET_SIZE;
} else if (dev->udev->speed == USB_SPEED_HIGH) {
- burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
- dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE;
+ dev->rx_urb_size = packetsize ? packetsize : DEFAULT_HS_BURST_CAP_SIZE;
+ burst_cap = dev->rx_urb_size / HS_USB_PKT_SIZE;
} else {
- burst_cap = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE;
- dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE;
+ dev->rx_urb_size = packetsize ? packetsize : DEFAULT_FS_BURST_CAP_SIZE;
+ burst_cap = dev->rx_urb_size / FS_USB_PKT_SIZE;
}
netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld\n",