diff options
Diffstat (limited to 'drivers/net/ethernet/sfc/mcdi.c')
-rw-r--r-- | drivers/net/ethernet/sfc/mcdi.c | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index 8150781b41eb..d8a20f514f80 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c | |||
@@ -48,6 +48,8 @@ struct efx_mcdi_async_param { | |||
48 | }; | 48 | }; |
49 | 49 | ||
50 | static void efx_mcdi_timeout_async(unsigned long context); | 50 | static void efx_mcdi_timeout_async(unsigned long context); |
51 | static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, | ||
52 | bool *was_attached_out); | ||
51 | 53 | ||
52 | static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx) | 54 | static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx) |
53 | { | 55 | { |
@@ -58,6 +60,8 @@ static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx) | |||
58 | int efx_mcdi_init(struct efx_nic *efx) | 60 | int efx_mcdi_init(struct efx_nic *efx) |
59 | { | 61 | { |
60 | struct efx_mcdi_iface *mcdi; | 62 | struct efx_mcdi_iface *mcdi; |
63 | bool already_attached; | ||
64 | int rc; | ||
61 | 65 | ||
62 | efx->mcdi = kzalloc(sizeof(*efx->mcdi), GFP_KERNEL); | 66 | efx->mcdi = kzalloc(sizeof(*efx->mcdi), GFP_KERNEL); |
63 | if (!efx->mcdi) | 67 | if (!efx->mcdi) |
@@ -78,12 +82,37 @@ int efx_mcdi_init(struct efx_nic *efx) | |||
78 | mcdi->new_epoch = true; | 82 | mcdi->new_epoch = true; |
79 | 83 | ||
80 | /* Recover from a failed assertion before probing */ | 84 | /* Recover from a failed assertion before probing */ |
81 | return efx_mcdi_handle_assertion(efx); | 85 | rc = efx_mcdi_handle_assertion(efx); |
86 | if (rc) | ||
87 | return rc; | ||
88 | |||
89 | /* Let the MC (and BMC, if this is a LOM) know that the driver | ||
90 | * is loaded. We should do this before we reset the NIC. | ||
91 | */ | ||
92 | rc = efx_mcdi_drv_attach(efx, true, &already_attached); | ||
93 | if (rc) { | ||
94 | netif_err(efx, probe, efx->net_dev, | ||
95 | "Unable to register driver with MCPU\n"); | ||
96 | return rc; | ||
97 | } | ||
98 | if (already_attached) | ||
99 | /* Not a fatal error */ | ||
100 | netif_err(efx, probe, efx->net_dev, | ||
101 | "Host already registered with MCPU\n"); | ||
102 | |||
103 | return 0; | ||
82 | } | 104 | } |
83 | 105 | ||
84 | void efx_mcdi_fini(struct efx_nic *efx) | 106 | void efx_mcdi_fini(struct efx_nic *efx) |
85 | { | 107 | { |
86 | BUG_ON(efx->mcdi && efx->mcdi->iface.state != MCDI_STATE_QUIESCENT); | 108 | if (!efx->mcdi) |
109 | return; | ||
110 | |||
111 | BUG_ON(efx->mcdi->iface.state != MCDI_STATE_QUIESCENT); | ||
112 | |||
113 | /* Relinquish the device (back to the BMC, if this is a LOM) */ | ||
114 | efx_mcdi_drv_attach(efx, false, NULL); | ||
115 | |||
87 | kfree(efx->mcdi); | 116 | kfree(efx->mcdi); |
88 | } | 117 | } |
89 | 118 | ||
@@ -889,8 +918,8 @@ fail: | |||
889 | buf[0] = 0; | 918 | buf[0] = 0; |
890 | } | 919 | } |
891 | 920 | ||
892 | int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, | 921 | static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, |
893 | bool *was_attached) | 922 | bool *was_attached) |
894 | { | 923 | { |
895 | MCDI_DECLARE_BUF(inbuf, MC_CMD_DRV_ATTACH_IN_LEN); | 924 | MCDI_DECLARE_BUF(inbuf, MC_CMD_DRV_ATTACH_IN_LEN); |
896 | MCDI_DECLARE_BUF(outbuf, MC_CMD_DRV_ATTACH_OUT_LEN); | 925 | MCDI_DECLARE_BUF(outbuf, MC_CMD_DRV_ATTACH_OUT_LEN); |