nvme-fw-download(1)
===================

NAME
----
nvme-fw-download - Download all or a portion of an nvme firmware image.

SYNOPSIS
--------
[verse]
'nvme' [<global-options>] 'fw download' <device>
			[--fw=<firmware-file> | -f <firmware-file>]
			[--xfer=<transfer-size> | -x <transfer-size>]
			[--offset=<offset> | -O <offset>]
			[--stream]

DESCRIPTION
-----------
The Firmware Image Download command is used to download all or a portion
of the firmware image for a future update to the controller. The Firmware
Image Download command may be submitted while other commands on the Admin
Submission Queue or I/O Submission Queues are outstanding. The Firmware
Image Download command copies the new firmware image (in whole or in part)
to the controller.

The firmware image may be constructed of multiple pieces that
are individually downloaded with separate Firmware Image Download
commands. Each Firmware Image Download command includes a Dword
Offset and Number of Dwords that specify a Dword range. The host
software shall ensure that firmware pieces do not have Dword ranges
that overlap. Firmware portions may be submitted out of order to the
controller.

The new firmware image is not applied as part of the Firmware Image
Download command. It is applied following a reset, where the image to
apply and the firmware slot it should be committed to is specified with
the Firmware Commit command (nvme fw-commit <args>).

Note: nvme-cli must allocate a contiguous (linear) memory buffer and map
the firmware binary into it. To do this, nvme-cli first attempts to
allocate the buffer using huge TLB pages. If allocation using huge pages
fails, it falls back to using posix_memalign() combined with madvise(). If
the kernel rejects the huge page advice, nvme-cli keeps the aligned buffer
and lets the I/O path attempt to map it.

The optional `--stream` mode avoids allocating a buffer for the complete
firmware image. It reads and downloads one transfer-sized portion at a time.

To increase the likelihood of success, you may want to pre-allocate a
number of huge pages before initiating the firmware download:

  echo 20 > /proc/sys/vm/nr_hugepages

For more details, refer to:
https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt

The bare 'nvme fw-download' form (without a space) still works as a deprecated
alias and will be removed in a future major version. New scripts should
use 'nvme fw download' instead.

OPTIONS
-------
-f <firmware-file>::
--fw=<firmware-file>::
	Required argument. This specifies the path to the device's
	firmware file on your system that will be read by the program
	and sent to the device.

-x <transfer-size>::
--xfer=<transfer-size>::
	This specifies the size to split each transfer. This is useful if
	the device has a max transfer size requirement for firmware. It
	defaults to 4k.

-O <offset>::
--offset=<offset>::
	This specifies the starting offset in dwords. This is really only
	useful if your firmware is split in multiple files; otherwise
	the offset starts at zero and automatically adjusts based on the
	'xfer' size given.

--stream::
	Read and download one transfer-sized portion of the firmware image at
	a time instead of mapping the complete image into memory. This avoids
	the huge page requirement and limits memory use to the transfer size.

include::global-options.txt[]

EXAMPLES
--------
* Transfer a firmware size 128KiB at a time:
+
------------
# nvme fw download /dev/nvme0 --fw=/path/to/nvme.fw --xfer=0x20000
------------

* Read and download a firmware image one transfer-sized portion at a time:
+
------------
# nvme fw download /dev/nvme0 --fw=/path/to/nvme.fw --stream
------------

NVME
----
Part of the nvme-user suite
