#include <linux/packing.h>
 #include "sja1105.h"
 
+#define SJA1105_SIZE_PORT_CTRL         4
 #define SJA1105_SIZE_RESET_CMD         4
 #define SJA1105_SIZE_SPI_MSG_HEADER    4
 #define SJA1105_SIZE_SPI_MSG_MAXLEN    (64 * 4)
        return priv->info->reset_cmd(priv, &reset);
 }
 
+static int sja1105_inhibit_tx(const struct sja1105_private *priv,
+                             const unsigned long *port_bitmap)
+{
+       const struct sja1105_regs *regs = priv->info->regs;
+       u64 inhibit_cmd;
+       int port, rc;
+
+       rc = sja1105_spi_send_int(priv, SPI_READ, regs->port_control,
+                                 &inhibit_cmd, SJA1105_SIZE_PORT_CTRL);
+       if (rc < 0)
+               return rc;
+
+       for_each_set_bit(port, port_bitmap, SJA1105_NUM_PORTS)
+               inhibit_cmd |= BIT(port);
+
+       return sja1105_spi_send_int(priv, SPI_WRITE, regs->port_control,
+                                   &inhibit_cmd, SJA1105_SIZE_PORT_CTRL);
+}
+
 struct sja1105_status {
        u64 configs;
        u64 crcchkl;
 
 int sja1105_static_config_upload(struct sja1105_private *priv)
 {
+       unsigned long port_bitmap = GENMASK_ULL(SJA1105_NUM_PORTS - 1, 0);
        struct sja1105_static_config *config = &priv->static_config;
        const struct sja1105_regs *regs = priv->info->regs;
        struct device *dev = &priv->spidev->dev;
                dev_err(dev, "Invalid config, cannot upload\n");
                return -EINVAL;
        }
+       /* Prevent PHY jabbering during switch reset by inhibiting
+        * Tx on all ports and waiting for current packet to drain.
+        * Otherwise, the PHY will see an unterminated Ethernet packet.
+        */
+       rc = sja1105_inhibit_tx(priv, &port_bitmap);
+       if (rc < 0) {
+               dev_err(dev, "Failed to inhibit Tx on ports\n");
+               return -ENXIO;
+       }
+       /* Wait for an eventual egress packet to finish transmission
+        * (reach IFG). It is guaranteed that a second one will not
+        * follow, and that switch cold reset is thus safe
+        */
+       usleep_range(500, 1000);
        do {
                /* Put the SJA1105 in programming mode */
                rc = sja1105_cold_reset(priv);
        .device_id = 0x0,
        .prod_id = 0x100BC3,
        .status = 0x1,
+       .port_control = 0x11,
        .config = 0x020000,
        .rgu = 0x100440,
        .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
        .device_id = 0x0,
        .prod_id = 0x100BC3,
        .status = 0x1,
+       .port_control = 0x12,
        .config = 0x020000,
        .rgu = 0x100440,
        .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},