Commit 7717c319 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller

nfp: make use of MAC reinit

Recent management FW images can perform full reinit of MAC cores
without requiring a reboot.  When loading the driver check if there
are changes pending and if so call NSP MAC reinit.  Full application
FW reload is still required, and all MACs need to be reinited at the
same time (not only the ones which have been reconfigured, and thus
potentially causing disruption to unrelated netdevs) therefore for
now changing MAC config without reloading the driver still remains
future work.
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Tested-by: default avatarDirk van der Merwe <dirk.vandermerwe@netronome.com>
Signed-off-by: default avatarSimon Horman <simon.horman@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4e595325
...@@ -346,6 +346,32 @@ nfp_fw_load(struct pci_dev *pdev, struct nfp_pf *pf, struct nfp_nsp *nsp) ...@@ -346,6 +346,32 @@ nfp_fw_load(struct pci_dev *pdev, struct nfp_pf *pf, struct nfp_nsp *nsp)
return err < 0 ? err : 1; 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) static int nfp_nsp_init(struct pci_dev *pdev, struct nfp_pf *pf)
{ {
struct nfp_nsp *nsp; struct nfp_nsp *nsp;
...@@ -366,7 +392,7 @@ static int nfp_nsp_init(struct pci_dev *pdev, struct nfp_pf *pf) ...@@ -366,7 +392,7 @@ static int nfp_nsp_init(struct pci_dev *pdev, struct nfp_pf *pf)
if (err < 0) if (err < 0)
goto exit_close_nsp; 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); pf->nspi = __nfp_nsp_identify(nsp);
if (pf->nspi) if (pf->nspi)
......
...@@ -328,7 +328,7 @@ nfp_net_set_link_ksettings(struct net_device *netdev, ...@@ -328,7 +328,7 @@ nfp_net_set_link_ksettings(struct net_device *netdev,
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (netif_running(netdev)) { 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 -EBUSY;
} }
......
...@@ -597,7 +597,7 @@ nfp_net_eth_port_update(struct nfp_cpp *cpp, struct nfp_port *port, ...@@ -597,7 +597,7 @@ nfp_net_eth_port_update(struct nfp_cpp *cpp, struct nfp_port *port,
return -EIO; return -EIO;
} }
if (eth_port->override_changed) { 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; port->type = NFP_PORT_INVALID;
} }
......
...@@ -477,6 +477,11 @@ int nfp_nsp_device_soft_reset(struct nfp_nsp *state) ...@@ -477,6 +477,11 @@ int nfp_nsp_device_soft_reset(struct nfp_nsp *state)
return nfp_nsp_command(state, SPCODE_SOFT_RESET, 0, 0, 0); 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) 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, return nfp_nsp_command_buf(state, SPCODE_FW_LOAD, fw->size, fw->data,
......
...@@ -48,6 +48,12 @@ u16 nfp_nsp_get_abi_ver_minor(struct nfp_nsp *state); ...@@ -48,6 +48,12 @@ u16 nfp_nsp_get_abi_ver_minor(struct nfp_nsp *state);
int nfp_nsp_wait(struct nfp_nsp *state); int nfp_nsp_wait(struct nfp_nsp *state);
int nfp_nsp_device_soft_reset(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_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 { enum nfp_eth_interface {
NFP_INTERFACE_NONE = 0, NFP_INTERFACE_NONE = 0,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment