diff options
author | Jacob Keller <jacob.e.keller@intel.com> | 2020-07-23 17:22:03 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-07-28 17:07:06 -0700 |
commit | d69ea414c9b498064d4cd3ebbe2fd4b8298568bc (patch) | |
tree | 1fab4c91bfe14e1f4f75e1ae699fbb154859d272 /drivers/net/ethernet/intel/ice/ice.h | |
parent | 2ab560a78e3b2f6b19626dcd47790f35b28cc5db (diff) | |
download | kernel_replicant_linux-d69ea414c9b498064d4cd3ebbe2fd4b8298568bc.tar.gz kernel_replicant_linux-d69ea414c9b498064d4cd3ebbe2fd4b8298568bc.tar.bz2 kernel_replicant_linux-d69ea414c9b498064d4cd3ebbe2fd4b8298568bc.zip |
ice: implement device flash update via devlink
Use the newly added pldmfw library to implement device flash update for
the Intel ice networking device driver. This support uses the devlink
flash update interface.
The main parts of the flash include the Option ROM, the netlist module,
and the main NVM data. The PLDM firmware file contains modules for each
of these components.
Using the pldmfw library, the provided firmware file will be scanned for
the three major components, "fw.undi" for the Option ROM, "fw.mgmt" for
the main NVM module containing the primary device firmware, and
"fw.netlist" containing the netlist module.
The flash is separated into two banks, the active bank containing the
running firmware, and the inactive bank which we use for update. Each
module is updated in a staged process. First, the inactive bank is
erased, preparing the device for update. Second, the contents of the
component are copied to the inactive portion of the flash. After all
components are updated, the driver signals the device to switch the
active bank during the next EMP reset (which would usually occur during
the next reboot).
Although the firmware AdminQ interface does report an immediate status
for each command, the NVM erase and NVM write commands receive status
asynchronously. The driver must not continue writing until previous
erase and write commands have finished. The real status of the NVM
commands is returned over the receive AdminQ. Implement a simple
interface that uses a wait queue so that the main update thread can
sleep until the completion status is reported by firmware. For erasing
the inactive banks, this can take quite a while in practice.
To help visualize the process to the devlink application and other
applications based on the devlink netlink interface, status is reported
via the devlink_flash_update_status_notify. While we do report status
after each 4k block when writing, there is no real status we can report
during erasing. We simply must wait for the complete module erasure to
finish.
With this implementation, basic flash update for the ice hardware is
supported.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice.h')
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice.h | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h index c665220bb637..7d194d2a031a 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h @@ -19,6 +19,7 @@ #include <linux/dma-mapping.h> #include <linux/pci.h> #include <linux/workqueue.h> +#include <linux/wait.h> #include <linux/aer.h> #include <linux/interrupt.h> #include <linux/ethtool.h> @@ -412,6 +413,12 @@ struct ice_pf { struct mutex sw_mutex; /* lock for protecting VSI alloc flow */ struct mutex tc_mutex; /* lock to protect TC changes */ u32 msg_enable; + + /* spinlock to protect the AdminQ wait list */ + spinlock_t aq_wait_lock; + struct hlist_head aq_wait_list; + wait_queue_head_t aq_wait_queue; + u32 hw_csum_rx_error; u16 oicr_idx; /* Other interrupt cause MSIX vector index */ u16 num_avail_sw_msix; /* remaining MSIX SW vectors left unclaimed */ @@ -593,6 +600,8 @@ void ice_fdir_release_flows(struct ice_hw *hw); void ice_fdir_replay_flows(struct ice_hw *hw); void ice_fdir_replay_fltrs(struct ice_pf *pf); int ice_fdir_create_dflt_rules(struct ice_pf *pf); +int ice_aq_wait_for_event(struct ice_pf *pf, u16 opcode, unsigned long timeout, + struct ice_rq_event_info *event); int ice_open(struct net_device *netdev); int ice_stop(struct net_device *netdev); void ice_service_task_schedule(struct ice_pf *pf); |