return err < 0 ? err : 1;
 }
 
+static void
+nfp_nsp_init_ports(struct pci_dev *pdev, struct nfp_pf *pf,
+                  struct nfp_nsp *nsp)
+{
+       bool needs_reinit = false;
+       int i;
+
+       pf->eth_tbl = __nfp_eth_read_ports(pf->cpp, nsp);
+       if (!pf->eth_tbl)
+               return;
+
+       if (!nfp_nsp_has_mac_reinit(nsp))
+               return;
+
+       for (i = 0; i < pf->eth_tbl->count; i++)
+               needs_reinit |= pf->eth_tbl->ports[i].override_changed;
+       if (!needs_reinit)
+               return;
+
+       kfree(pf->eth_tbl);
+       if (nfp_nsp_mac_reinit(nsp))
+               dev_warn(&pdev->dev, "MAC reinit failed\n");
+
+       pf->eth_tbl = __nfp_eth_read_ports(pf->cpp, nsp);
+}
+
 static int nfp_nsp_init(struct pci_dev *pdev, struct nfp_pf *pf)
 {
        struct nfp_nsp *nsp;
        if (err < 0)
                goto exit_close_nsp;
 
-       pf->eth_tbl = __nfp_eth_read_ports(pf->cpp, nsp);
+       nfp_nsp_init_ports(pdev, pf, nsp);
 
        pf->nspi = __nfp_nsp_identify(nsp);
        if (pf->nspi)
 
                return -EOPNOTSUPP;
 
        if (netif_running(netdev)) {
-               netdev_warn(netdev, "Changing settings not allowed on an active interface. It may cause the port to be disabled until reboot.\n");
+               netdev_warn(netdev, "Changing settings not allowed on an active interface. It may cause the port to be disabled until driver reload.\n");
                return -EBUSY;
        }
 
 
                return -EIO;
        }
        if (eth_port->override_changed) {
-               nfp_warn(cpp, "Port #%d config changed, unregistering. Reboot required before port will be operational again.\n", port->eth_id);
+               nfp_warn(cpp, "Port #%d config changed, unregistering. Driver reload required before port will be operational again.\n", port->eth_id);
                port->type = NFP_PORT_INVALID;
        }
 
 
        return nfp_nsp_command(state, SPCODE_SOFT_RESET, 0, 0, 0);
 }
 
+int nfp_nsp_mac_reinit(struct nfp_nsp *state)
+{
+       return nfp_nsp_command(state, SPCODE_MAC_INIT, 0, 0, 0);
+}
+
 int nfp_nsp_load_fw(struct nfp_nsp *state, const struct firmware *fw)
 {
        return nfp_nsp_command_buf(state, SPCODE_FW_LOAD, fw->size, fw->data,
 
 int nfp_nsp_wait(struct nfp_nsp *state);
 int nfp_nsp_device_soft_reset(struct nfp_nsp *state);
 int nfp_nsp_load_fw(struct nfp_nsp *state, const struct firmware *fw);
+int nfp_nsp_mac_reinit(struct nfp_nsp *state);
+
+static inline bool nfp_nsp_has_mac_reinit(struct nfp_nsp *state)
+{
+       return nfp_nsp_get_abi_ver_minor(state) > 20;
+}
 
 enum nfp_eth_interface {
        NFP_INTERFACE_NONE      = 0,