[5/5] net/cxgbe: read firmware configuration file from filesystem

Message ID f795d66bc336eb68d36ad8618c7c86e1cdf346e3.1650297776.git.rahul.lakkireddy@chelsio.com (mailing list archive)
State Changes Requested, archived
Delegated to: Ferruh Yigit
Headers
Series net/cxgbe: updates and bug fixes |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/iol-mellanox-Performance success Performance Testing PASS
ci/Intel-compilation success Compilation OK
ci/github-robot: build success github build: passed
ci/iol-abi-testing success Testing PASS
ci/iol-aarch64-unit-testing success Testing PASS
ci/iol-x86_64-compile-testing success Testing PASS
ci/iol-x86_64-unit-testing success Testing PASS
ci/intel-Testing success Testing PASS
ci/iol-aarch64-compile-testing success Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-intel-Performance success Performance Testing PASS

Commit Message

Rahul Lakkireddy April 18, 2022, 10:24 p.m. UTC
  Add support to read firmware configuration file from
/lib/firmware/cxgb4/ path in the filesystem.

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
 drivers/net/cxgbe/base/t4fw_interface.h |   1 +
 drivers/net/cxgbe/cxgbe_main.c          | 329 ++++++++++++++++--------
 2 files changed, 217 insertions(+), 113 deletions(-)
  

Comments

Ferruh Yigit May 5, 2022, 4:29 p.m. UTC | #1
On 4/18/2022 11:24 PM, Rahul Lakkireddy wrote:
> Add support to read firmware configuration file from
> /lib/firmware/cxgb4/ path in the filesystem.
> 

Hi Rahul,

Can you please document the FW config file in the driver documentation?
Please add:
- Path of the config file
- Content of the config file. As far as I can see from the code the 
config file directly sent to the FW, does this mean config file is binary?
- What happens when config file is not found

Also are these values overlap with the devargs that PMD has? If so what 
happens in that case, which one is used, devargs one or config file one?

Previously there was 'cxgbtool' tool to send the config file, is this 
method replacing it? Why not keep using 'cxgbtool'?

Thanks,
ferruh


> Signed-off-by: Rahul Lakkireddy<rahul.lakkireddy@chelsio.com>

<...>
  
Ferruh Yigit May 5, 2022, 4:36 p.m. UTC | #2
On 5/5/2022 5:29 PM, Ferruh Yigit wrote:
> On 4/18/2022 11:24 PM, Rahul Lakkireddy wrote:
>> Add support to read firmware configuration file from
>> /lib/firmware/cxgb4/ path in the filesystem.
>>
> 
> Hi Rahul,
> 
> Can you please document the FW config file in the driver documentation?
> Please add:
> - Path of the config file
> - Content of the config file. As far as I can see from the code the 
> config file directly sent to the FW, does this mean config file is binary?
> - What happens when config file is not found
> 
> Also are these values overlap with the devargs that PMD has? If so what 
> happens in that case, which one is used, devargs one or config file one?
> 
> Previously there was 'cxgbtool' tool to send the config file, is this 
> method replacing it? Why not keep using 'cxgbtool'?
> 

cc'ed more folks.

This patch introduces a userspace config file for runtime FW config.

What do you think about this approach?
Should we formalize this method more, like introducing an ethdev level 
config option to hold the config file, which can be used for driver 
and/or FW. And perhaps with a defined syntax (yaml?).
Can this be an alternative to PMD devargs?

Cheers,
ferruh
  
Rahul Lakkireddy May 6, 2022, 11:36 a.m. UTC | #3
On Thursday, May 05/05/22, 2022 at 17:36:06 +0100, Ferruh Yigit wrote:
> On 5/5/2022 5:29 PM, Ferruh Yigit wrote:
> > On 4/18/2022 11:24 PM, Rahul Lakkireddy wrote:
> > > Add support to read firmware configuration file from
> > > /lib/firmware/cxgb4/ path in the filesystem.
> > > 
> > 
> > Hi Rahul,
> > 
> > Can you please document the FW config file in the driver documentation?
> > Please add:
> > - Path of the config file
> > - Content of the config file. As far as I can see from the code the
> > config file directly sent to the FW, does this mean config file is
> > binary?
> > - What happens when config file is not found
> > 
> > Also are these values overlap with the devargs that PMD has? If so what
> > happens in that case, which one is used, devargs one or config file one?
> > 
> > Previously there was 'cxgbtool' tool to send the config file, is this
> > method replacing it? Why not keep using 'cxgbtool'?
> > 

The Chelsio FW config file contains a list of register=value pairs to
change configuration of the NIC before firmware is initialized.
It closely resembles the INI file format. It is mainly used to aid
in debugging FW initialization failures and to optimally partition
NIC hardware resources for specific requirements. Partitioning
generally involves moving resources on unused Physical Functions
(PFs) to the main PF, like redistributing queues, hardware TCAMs,
etc., before firmware begins initialization. Once the configuration
looks good, then the final FW config file is flashed onto the NIC
using the cxgbtool. The FW config file can then be removed from the
/lib/firmware/cxgb4/ directory and the FW will begin initializing
with the flashed FW config file on the NIC from next time onwards.

With this patch, the FW config file is selected in following order.

1) Check and select FW config file present in /lib/firmware/cxgb4/
   directory.

2) Otherwise, check and select FW config file flashed onto the
   NIC.

3) Otherwise, select the default FW config file embedded within the
   FW binary on the NIC.

Since this is pretty low-level hardware configuration, the users are
not expected to change this file without expert guidance. So,
exporting such a low-level configuration via devargs API does not
feel like the right fit for this specific requirement.

Once FW is up and running with the FW config file, some of the driver
and FW runtime features can be enabled/disabled via devargs API during
driver probe.

To summarize, the FW config file is intended to debug FW initialization
failures and/or aid in resources partitioning before FW starts
initialization. Once the FW is running, the whole or smaller slices
of these partitioned resources can be further redistributed across
the multiple physical ports controlled by the same underlying PF.

> 
> cc'ed more folks.
> 
> This patch introduces a userspace config file for runtime FW config.
> 
> What do you think about this approach?
> Should we formalize this method more, like introducing an ethdev level
> config option to hold the config file, which can be used for driver and/or
> FW. And perhaps with a defined syntax (yaml?).
> Can this be an alternative to PMD devargs?
> 
> Cheers,
> ferruh

Thanks,
Rahul
  
Thomas Monjalon May 10, 2022, 9:02 a.m. UTC | #4
06/05/2022 13:36, Rahul Lakkireddy:
> The Chelsio FW config file contains a list of register=value pairs to
> change configuration of the NIC before firmware is initialized.
> It closely resembles the INI file format. It is mainly used to aid
> in debugging FW initialization failures and to optimally partition
> NIC hardware resources for specific requirements. Partitioning
> generally involves moving resources on unused Physical Functions
> (PFs) to the main PF, like redistributing queues, hardware TCAMs,
> etc., before firmware begins initialization. Once the configuration
> looks good, then the final FW config file is flashed onto the NIC
> using the cxgbtool. The FW config file can then be removed from the
> /lib/firmware/cxgb4/ directory and the FW will begin initializing
> with the flashed FW config file on the NIC from next time onwards.
> 
> With this patch, the FW config file is selected in following order.
> 
> 1) Check and select FW config file present in /lib/firmware/cxgb4/
>    directory.
> 
> 2) Otherwise, check and select FW config file flashed onto the
>    NIC.
> 
> 3) Otherwise, select the default FW config file embedded within the
>    FW binary on the NIC.
> 
> Since this is pretty low-level hardware configuration, the users are
> not expected to change this file without expert guidance. So,
> exporting such a low-level configuration via devargs API does not
> feel like the right fit for this specific requirement.
> 
> Once FW is up and running with the FW config file, some of the driver
> and FW runtime features can be enabled/disabled via devargs API during
> driver probe.
> 
> To summarize, the FW config file is intended to debug FW initialization
> failures and/or aid in resources partitioning before FW starts
> initialization. Once the FW is running, the whole or smaller slices
> of these partitioned resources can be further redistributed across
> the multiple physical ports controlled by the same underlying PF.

Sorry it is not clear to me.
The FW file is used by cxgbtool to flash it, right?
The PMD may use the same FW file for debug diagnostics?
How is it used by the kernel?
  
Rahul Lakkireddy May 10, 2022, 2:11 p.m. UTC | #5
On Tuesday, May 05/10/22, 2022 at 11:02:05 +0200, Thomas Monjalon wrote:
> 06/05/2022 13:36, Rahul Lakkireddy:
> > The Chelsio FW config file contains a list of register=value pairs to
> > change configuration of the NIC before firmware is initialized.
> > It closely resembles the INI file format. It is mainly used to aid
> > in debugging FW initialization failures and to optimally partition
> > NIC hardware resources for specific requirements. Partitioning
> > generally involves moving resources on unused Physical Functions
> > (PFs) to the main PF, like redistributing queues, hardware TCAMs,
> > etc., before firmware begins initialization. Once the configuration
> > looks good, then the final FW config file is flashed onto the NIC
> > using the cxgbtool. The FW config file can then be removed from the
> > /lib/firmware/cxgb4/ directory and the FW will begin initializing
> > with the flashed FW config file on the NIC from next time onwards.
> > 
> > With this patch, the FW config file is selected in following order.
> > 
> > 1) Check and select FW config file present in /lib/firmware/cxgb4/
> >    directory.
> > 
> > 2) Otherwise, check and select FW config file flashed onto the
> >    NIC.
> > 
> > 3) Otherwise, select the default FW config file embedded within the
> >    FW binary on the NIC.
> > 
> > Since this is pretty low-level hardware configuration, the users are
> > not expected to change this file without expert guidance. So,
> > exporting such a low-level configuration via devargs API does not
> > feel like the right fit for this specific requirement.
> > 
> > Once FW is up and running with the FW config file, some of the driver
> > and FW runtime features can be enabled/disabled via devargs API during
> > driver probe.
> > 
> > To summarize, the FW config file is intended to debug FW initialization
> > failures and/or aid in resources partitioning before FW starts
> > initialization. Once the FW is running, the whole or smaller slices
> > of these partitioned resources can be further redistributed across
> > the multiple physical ports controlled by the same underlying PF.
> 
> Sorry it is not clear to me.
> The FW file is used by cxgbtool to flash it, right?
> The PMD may use the same FW file for debug diagnostics?


There are 2 FW related files in /lib/firmware/cxgb4 directory that
can be written into the NIC flash (at different locations in the flash)
using cxgbtool:

1) FW config file (t6-config.txt): This file contains register=value
   pairs to configure some HW registers before initializing FW
   (t6fw.bin). These register=value pairs are very low level and
   specific to HW. The FW config file can be used to enable/disable
   some paths in HW to debug FW initialization issues. Since it
   can disable some paths in HW, it can also be used to partition
   and redistribute resources from other unused PFs to main PF,
   before FW initialization.

2) FW binary (t6fw.bin): This contains the actual FW. This binary also
   has an embedded "default" FW config file that will be used if no
   FW config file (t6-config.txt) is present in NIC "flash" or in the
   "/lib/firmware/cxgb4/" directory.

> How is it used by the kernel?
> 

In kernel cxgb4 driver also, we follow the same sequence when
initializing FW. If any FW config file (t6-config.txt) is present
in "/lib/firmware/cxgb4" directory, then it is picked up first.
Otherwise, a FW config file that has been "flashed" onto the NIC
using cxgbtool, is picked up next. Otherwise, FW will init with
the "default" FW config file embedded inside the FW binary (t6fw.bin).

Currently, the DPDK cxgbe PMD only picks up the FW config file from
NIC "flash" or the "default" one inside the FW binary. This patch adds
a way to pick FW config file from "lib/firmware/cxgb4" directory when
a FW config file is placed there.

Thanks,
Rahul
  
Thomas Monjalon May 10, 2022, 2:30 p.m. UTC | #6
10/05/2022 16:11, Rahul Lakkireddy:
> On Tuesday, May 05/10/22, 2022 at 11:02:05 +0200, Thomas Monjalon wrote:
> > 06/05/2022 13:36, Rahul Lakkireddy:
> > > The Chelsio FW config file contains a list of register=value pairs to
> > > change configuration of the NIC before firmware is initialized.
> > > It closely resembles the INI file format. It is mainly used to aid
> > > in debugging FW initialization failures and to optimally partition
> > > NIC hardware resources for specific requirements. Partitioning
> > > generally involves moving resources on unused Physical Functions
> > > (PFs) to the main PF, like redistributing queues, hardware TCAMs,
> > > etc., before firmware begins initialization. Once the configuration
> > > looks good, then the final FW config file is flashed onto the NIC
> > > using the cxgbtool. The FW config file can then be removed from the
> > > /lib/firmware/cxgb4/ directory and the FW will begin initializing
> > > with the flashed FW config file on the NIC from next time onwards.
> > > 
> > > With this patch, the FW config file is selected in following order.
> > > 
> > > 1) Check and select FW config file present in /lib/firmware/cxgb4/
> > >    directory.
> > > 
> > > 2) Otherwise, check and select FW config file flashed onto the
> > >    NIC.
> > > 
> > > 3) Otherwise, select the default FW config file embedded within the
> > >    FW binary on the NIC.
> > > 
> > > Since this is pretty low-level hardware configuration, the users are
> > > not expected to change this file without expert guidance. So,
> > > exporting such a low-level configuration via devargs API does not
> > > feel like the right fit for this specific requirement.
> > > 
> > > Once FW is up and running with the FW config file, some of the driver
> > > and FW runtime features can be enabled/disabled via devargs API during
> > > driver probe.
> > > 
> > > To summarize, the FW config file is intended to debug FW initialization
> > > failures and/or aid in resources partitioning before FW starts
> > > initialization. Once the FW is running, the whole or smaller slices
> > > of these partitioned resources can be further redistributed across
> > > the multiple physical ports controlled by the same underlying PF.
> > 
> > Sorry it is not clear to me.
> > The FW file is used by cxgbtool to flash it, right?
> > The PMD may use the same FW file for debug diagnostics?
> 
> 
> There are 2 FW related files in /lib/firmware/cxgb4 directory that
> can be written into the NIC flash (at different locations in the flash)
> using cxgbtool:
> 
> 1) FW config file (t6-config.txt): This file contains register=value
>    pairs to configure some HW registers before initializing FW
>    (t6fw.bin). These register=value pairs are very low level and
>    specific to HW. The FW config file can be used to enable/disable
>    some paths in HW to debug FW initialization issues. Since it
>    can disable some paths in HW, it can also be used to partition
>    and redistribute resources from other unused PFs to main PF,
>    before FW initialization.
> 
> 2) FW binary (t6fw.bin): This contains the actual FW. This binary also
>    has an embedded "default" FW config file that will be used if no
>    FW config file (t6-config.txt) is present in NIC "flash" or in the
>    "/lib/firmware/cxgb4/" directory.
> 
> > How is it used by the kernel?
> > 
> 
> In kernel cxgb4 driver also, we follow the same sequence when
> initializing FW. If any FW config file (t6-config.txt) is present
> in "/lib/firmware/cxgb4" directory, then it is picked up first.
> Otherwise, a FW config file that has been "flashed" onto the NIC
> using cxgbtool, is picked up next. Otherwise, FW will init with
> the "default" FW config file embedded inside the FW binary (t6fw.bin).
> 
> Currently, the DPDK cxgbe PMD only picks up the FW config file from
> NIC "flash" or the "default" one inside the FW binary. This patch adds
> a way to pick FW config file from "lib/firmware/cxgb4" directory when
> a FW config file is placed there.

OK, so both Linux and DPDK drivers read the FW config file
to provide better diagnostics. Am I right?
  
Rahul Lakkireddy May 10, 2022, 3:05 p.m. UTC | #7
On Tuesday, May 05/10/22, 2022 at 16:30:59 +0200, Thomas Monjalon wrote:
> 10/05/2022 16:11, Rahul Lakkireddy:
> > On Tuesday, May 05/10/22, 2022 at 11:02:05 +0200, Thomas Monjalon wrote:
> > > 06/05/2022 13:36, Rahul Lakkireddy:
> > > > The Chelsio FW config file contains a list of register=value pairs to
> > > > change configuration of the NIC before firmware is initialized.
> > > > It closely resembles the INI file format. It is mainly used to aid
> > > > in debugging FW initialization failures and to optimally partition
> > > > NIC hardware resources for specific requirements. Partitioning
> > > > generally involves moving resources on unused Physical Functions
> > > > (PFs) to the main PF, like redistributing queues, hardware TCAMs,
> > > > etc., before firmware begins initialization. Once the configuration
> > > > looks good, then the final FW config file is flashed onto the NIC
> > > > using the cxgbtool. The FW config file can then be removed from the
> > > > /lib/firmware/cxgb4/ directory and the FW will begin initializing
> > > > with the flashed FW config file on the NIC from next time onwards.
> > > > 
> > > > With this patch, the FW config file is selected in following order.
> > > > 
> > > > 1) Check and select FW config file present in /lib/firmware/cxgb4/
> > > >    directory.
> > > > 
> > > > 2) Otherwise, check and select FW config file flashed onto the
> > > >    NIC.
> > > > 
> > > > 3) Otherwise, select the default FW config file embedded within the
> > > >    FW binary on the NIC.
> > > > 
> > > > Since this is pretty low-level hardware configuration, the users are
> > > > not expected to change this file without expert guidance. So,
> > > > exporting such a low-level configuration via devargs API does not
> > > > feel like the right fit for this specific requirement.
> > > > 
> > > > Once FW is up and running with the FW config file, some of the driver
> > > > and FW runtime features can be enabled/disabled via devargs API during
> > > > driver probe.
> > > > 
> > > > To summarize, the FW config file is intended to debug FW initialization
> > > > failures and/or aid in resources partitioning before FW starts
> > > > initialization. Once the FW is running, the whole or smaller slices
> > > > of these partitioned resources can be further redistributed across
> > > > the multiple physical ports controlled by the same underlying PF.
> > > 
> > > Sorry it is not clear to me.
> > > The FW file is used by cxgbtool to flash it, right?
> > > The PMD may use the same FW file for debug diagnostics?
> > 
> > 
> > There are 2 FW related files in /lib/firmware/cxgb4 directory that
> > can be written into the NIC flash (at different locations in the flash)
> > using cxgbtool:
> > 
> > 1) FW config file (t6-config.txt): This file contains register=value
> >    pairs to configure some HW registers before initializing FW
> >    (t6fw.bin). These register=value pairs are very low level and
> >    specific to HW. The FW config file can be used to enable/disable
> >    some paths in HW to debug FW initialization issues. Since it
> >    can disable some paths in HW, it can also be used to partition
> >    and redistribute resources from other unused PFs to main PF,
> >    before FW initialization.
> > 
> > 2) FW binary (t6fw.bin): This contains the actual FW. This binary also
> >    has an embedded "default" FW config file that will be used if no
> >    FW config file (t6-config.txt) is present in NIC "flash" or in the
> >    "/lib/firmware/cxgb4/" directory.
> > 
> > > How is it used by the kernel?
> > > 
> > 
> > In kernel cxgb4 driver also, we follow the same sequence when
> > initializing FW. If any FW config file (t6-config.txt) is present
> > in "/lib/firmware/cxgb4" directory, then it is picked up first.
> > Otherwise, a FW config file that has been "flashed" onto the NIC
> > using cxgbtool, is picked up next. Otherwise, FW will init with
> > the "default" FW config file embedded inside the FW binary (t6fw.bin).
> > 
> > Currently, the DPDK cxgbe PMD only picks up the FW config file from
> > NIC "flash" or the "default" one inside the FW binary. This patch adds
> > a way to pick FW config file from "lib/firmware/cxgb4" directory when
> > a FW config file is placed there.
> 
> OK, so both Linux and DPDK drivers read the FW config file
> to provide better diagnostics. Am I right?
> 

Yes, both use the FW config file to enable/disable specific paths in
HW to get better diagnostics for FW init failures.

Thanks,
Rahul
  
Thomas Monjalon May 10, 2022, 4:20 p.m. UTC | #8
10/05/2022 17:05, Rahul Lakkireddy:
> On Tuesday, May 05/10/22, 2022 at 16:30:59 +0200, Thomas Monjalon wrote:
> > 10/05/2022 16:11, Rahul Lakkireddy:
> > > On Tuesday, May 05/10/22, 2022 at 11:02:05 +0200, Thomas Monjalon wrote:
> > > > 06/05/2022 13:36, Rahul Lakkireddy:
> > > > > The Chelsio FW config file contains a list of register=value pairs to
> > > > > change configuration of the NIC before firmware is initialized.
> > > > > It closely resembles the INI file format. It is mainly used to aid
> > > > > in debugging FW initialization failures and to optimally partition
> > > > > NIC hardware resources for specific requirements. Partitioning
> > > > > generally involves moving resources on unused Physical Functions
> > > > > (PFs) to the main PF, like redistributing queues, hardware TCAMs,
> > > > > etc., before firmware begins initialization. Once the configuration
> > > > > looks good, then the final FW config file is flashed onto the NIC
> > > > > using the cxgbtool. The FW config file can then be removed from the
> > > > > /lib/firmware/cxgb4/ directory and the FW will begin initializing
> > > > > with the flashed FW config file on the NIC from next time onwards.
> > > > > 
> > > > > With this patch, the FW config file is selected in following order.
> > > > > 
> > > > > 1) Check and select FW config file present in /lib/firmware/cxgb4/
> > > > >    directory.
> > > > > 
> > > > > 2) Otherwise, check and select FW config file flashed onto the
> > > > >    NIC.
> > > > > 
> > > > > 3) Otherwise, select the default FW config file embedded within the
> > > > >    FW binary on the NIC.
> > > > > 
> > > > > Since this is pretty low-level hardware configuration, the users are
> > > > > not expected to change this file without expert guidance. So,
> > > > > exporting such a low-level configuration via devargs API does not
> > > > > feel like the right fit for this specific requirement.
> > > > > 
> > > > > Once FW is up and running with the FW config file, some of the driver
> > > > > and FW runtime features can be enabled/disabled via devargs API during
> > > > > driver probe.
> > > > > 
> > > > > To summarize, the FW config file is intended to debug FW initialization
> > > > > failures and/or aid in resources partitioning before FW starts
> > > > > initialization. Once the FW is running, the whole or smaller slices
> > > > > of these partitioned resources can be further redistributed across
> > > > > the multiple physical ports controlled by the same underlying PF.
> > > > 
> > > > Sorry it is not clear to me.
> > > > The FW file is used by cxgbtool to flash it, right?
> > > > The PMD may use the same FW file for debug diagnostics?
> > > 
> > > 
> > > There are 2 FW related files in /lib/firmware/cxgb4 directory that
> > > can be written into the NIC flash (at different locations in the flash)
> > > using cxgbtool:
> > > 
> > > 1) FW config file (t6-config.txt): This file contains register=value
> > >    pairs to configure some HW registers before initializing FW
> > >    (t6fw.bin). These register=value pairs are very low level and
> > >    specific to HW. The FW config file can be used to enable/disable
> > >    some paths in HW to debug FW initialization issues. Since it
> > >    can disable some paths in HW, it can also be used to partition
> > >    and redistribute resources from other unused PFs to main PF,
> > >    before FW initialization.
> > > 
> > > 2) FW binary (t6fw.bin): This contains the actual FW. This binary also
> > >    has an embedded "default" FW config file that will be used if no
> > >    FW config file (t6-config.txt) is present in NIC "flash" or in the
> > >    "/lib/firmware/cxgb4/" directory.
> > > 
> > > > How is it used by the kernel?
> > > > 
> > > 
> > > In kernel cxgb4 driver also, we follow the same sequence when
> > > initializing FW. If any FW config file (t6-config.txt) is present
> > > in "/lib/firmware/cxgb4" directory, then it is picked up first.
> > > Otherwise, a FW config file that has been "flashed" onto the NIC
> > > using cxgbtool, is picked up next. Otherwise, FW will init with
> > > the "default" FW config file embedded inside the FW binary (t6fw.bin).
> > > 
> > > Currently, the DPDK cxgbe PMD only picks up the FW config file from
> > > NIC "flash" or the "default" one inside the FW binary. This patch adds
> > > a way to pick FW config file from "lib/firmware/cxgb4" directory when
> > > a FW config file is placed there.
> > 
> > OK, so both Linux and DPDK drivers read the FW config file
> > to provide better diagnostics. Am I right?
> > 
> 
> Yes, both use the FW config file to enable/disable specific paths in
> HW to get better diagnostics for FW init failures.

OK thanks for the explanation.
The idea looks OK.
  

Patch

diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h
index a0a9292c0c..76f58d7c77 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -697,6 +697,7 @@  enum fw_params_param_dev {
 						 */
 	FW_PARAMS_PARAM_DEV_FWREV	= 0x0B, /* fw version */
 	FW_PARAMS_PARAM_DEV_TPREV	= 0x0C, /* tp version */
+	FW_PARAMS_PARAM_DEV_CF		= 0x0D,
 	FW_PARAMS_PARAM_DEV_ULPTX_MEMWRITE_DSGL = 0x17,
 	FW_PARAMS_PARAM_DEV_FILTER2_WR	= 0x1D,
 	FW_PARAMS_PARAM_DEV_OPAQUE_VIID_SMT_EXTN = 0x27,
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index e2a2ccb781..7b162af3e7 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -4,6 +4,7 @@ 
  */
 
 #include <sys/queue.h>
+#include <sys/stat.h>
 #include <stdio.h>
 #include <errno.h>
 #include <stdint.h>
@@ -11,6 +12,7 @@ 
 #include <unistd.h>
 #include <stdarg.h>
 #include <inttypes.h>
+#include <fcntl.h>
 #include <netinet/in.h>
 
 #include <rte_byteorder.h>
@@ -1006,6 +1008,218 @@  static int configure_filter_mode_mask(struct adapter *adap)
 			     params, val);
 }
 
+#define CXGBE_FW_CONFIG_PATH_T5 "/lib/firmware/cxgb4/t5-config.txt"
+#define CXGBE_FW_CONFIG_PATH_T6 "/lib/firmware/cxgb4/t6-config.txt"
+
+/*
+ * Load firmware configuration from file in /lib/firmware/cxgb4/ path,
+ * if it is present.
+ */
+static int cxgbe_load_fw_config_from_filesystem(struct adapter *adap,
+						const char **config_name,
+						u32 *mem_type, u32 *mem_addr)
+{
+	u32 param, val, mtype, maddr;
+	const char *fw_cfg_path;
+	char *fw_cfg = NULL;
+	struct stat st;
+	int ret, fd;
+
+	switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {
+	case CHELSIO_T5:
+		fw_cfg_path = CXGBE_FW_CONFIG_PATH_T5;
+		break;
+	case CHELSIO_T6:
+		fw_cfg_path = CXGBE_FW_CONFIG_PATH_T6;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	ret = open(fw_cfg_path, O_RDONLY);
+	if (ret < 0) {
+		dev_debug(adap, "Couldn't open FW config file\n");
+		return ret;
+	}
+
+	fd = ret;
+
+	ret = fstat(fd, &st);
+	if (ret < 0) {
+		dev_debug(adap, "Couldn't get FW config file size\n");
+		goto out_err;
+	}
+
+	if (st.st_size >= FLASH_CFG_MAX_SIZE) {
+		dev_debug(adap, "FW config file size >= max(%u)\n",
+			  FLASH_CFG_MAX_SIZE);
+		ret = -ENOMEM;
+		goto out_err;
+	}
+
+	fw_cfg = rte_zmalloc(NULL, st.st_size, 0);
+	if (fw_cfg == NULL) {
+		ret = -ENOMEM;
+		goto out_err;
+	}
+
+	if (read(fd, fw_cfg, st.st_size) != st.st_size) {
+		dev_debug(adap, "Couldn't read FW config file data\n");
+		ret = -EIO;
+		goto out_err;
+	}
+
+	close(fd);
+
+	/* Send it to FW to verify and update to new configuration */
+	param = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) |
+		V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CF);
+	ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1, &param, &val);
+	if (ret < 0) {
+		dev_debug(adap, "FW config param query failed: %d\n", ret);
+		goto out_free;
+	}
+
+	mtype = val >> 8;
+	maddr = (val & 0xff) << 16;
+
+	t4_os_lock(&adap->win0_lock);
+	ret = t4_memory_rw(adap, MEMWIN_NIC, mtype, maddr, st.st_size,
+			   fw_cfg, T4_MEMORY_WRITE);
+	t4_os_unlock(&adap->win0_lock);
+	if (ret < 0) {
+		dev_debug(adap, "FW config file update failed: %d\n", ret);
+		goto out_free;
+	}
+
+	rte_free(fw_cfg);
+
+	*mem_type = mtype;
+	*mem_addr = maddr;
+	*config_name = fw_cfg_path;
+	return 0;
+
+out_err:
+	close(fd);
+out_free:
+	rte_free(fw_cfg);
+	return ret;
+}
+
+static int cxgbe_load_fw_config(struct adapter *adap)
+{
+	u32 finiver, finicsum, cfcsum, mtype, maddr, param, val;
+	struct fw_caps_config_cmd caps_cmd = { 0 };
+	const char *config_name = NULL;
+	int ret;
+
+	ret = cxgbe_load_fw_config_from_filesystem(adap, &config_name,
+						   &mtype, &maddr);
+	if (ret < 0) {
+		config_name = "On Flash";
+
+		ret = t4_flash_cfg_addr(adap);
+		if (ret < 0) {
+			dev_warn(adap,
+				 "Finding address for FW config file in flash failed: %d\n",
+				 ret);
+			goto out_default_config;
+		}
+
+		mtype = FW_MEMTYPE_CF_FLASH;
+		maddr = ret;
+	}
+
+	/* Enable HASH filter region when support is available. */
+	val = 1;
+	param = CXGBE_FW_PARAM_DEV(HASHFILTER_WITH_OFLD);
+	t4_set_params(adap, adap->mbox, adap->pf, 0, 1, &param, &val);
+
+	/*
+	 * Issue a Capability Configuration command to the firmware to get it
+	 * to parse the Configuration File.
+	 */
+	caps_cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
+					   F_FW_CMD_REQUEST | F_FW_CMD_READ);
+	caps_cmd.cfvalid_to_len16 =
+		cpu_to_be32(F_FW_CAPS_CONFIG_CMD_CFVALID |
+			    V_FW_CAPS_CONFIG_CMD_MEMTYPE_CF(mtype) |
+			    V_FW_CAPS_CONFIG_CMD_MEMADDR64K_CF(maddr >> 16) |
+			    FW_LEN16(caps_cmd));
+	ret = t4_wr_mbox(adap, adap->mbox, &caps_cmd, sizeof(caps_cmd),
+			 &caps_cmd);
+
+out_default_config:
+	/*
+	 * If the CAPS_CONFIG failed with an ENOENT (for a Firmware
+	 * Configuration File in filesystem or FLASH), our last gasp
+	 * effort is to use the Firmware Configuration File which is
+	 * embedded in the firmware.
+	 */
+	if (ret == -ENOENT) {
+		config_name = "Firmware Default";
+
+		memset(&caps_cmd, 0, sizeof(caps_cmd));
+		caps_cmd.op_to_write =
+			cpu_to_be32(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
+				    F_FW_CMD_REQUEST | F_FW_CMD_READ);
+		caps_cmd.cfvalid_to_len16 = cpu_to_be32(FW_LEN16(caps_cmd));
+		ret = t4_wr_mbox(adap, adap->mbox, &caps_cmd, sizeof(caps_cmd),
+				 &caps_cmd);
+	}
+
+	if (ret < 0) {
+		dev_info(adap,
+			 "Failed to configure using %s Firmware Configuration file: %d\n",
+			 config_name, ret);
+		return ret;
+	}
+
+	finiver = be32_to_cpu(caps_cmd.finiver);
+	finicsum = be32_to_cpu(caps_cmd.finicsum);
+	cfcsum = be32_to_cpu(caps_cmd.cfcsum);
+	if (finicsum != cfcsum)
+		dev_warn(adap,
+			 "Configuration File checksum mismatch: [fini] csum=0x%x, computed csum=0x%x\n",
+			 finicsum, cfcsum);
+
+	/*
+	 * If we're a pure NIC driver then disable all offloading facilities.
+	 * This will allow the firmware to optimize aspects of the hardware
+	 * configuration which will result in improved performance.
+	 */
+	caps_cmd.niccaps &= cpu_to_be16(~FW_CAPS_CONFIG_NIC_ETHOFLD);
+	caps_cmd.toecaps = 0;
+	caps_cmd.iscsicaps = 0;
+	caps_cmd.rdmacaps = 0;
+	caps_cmd.fcoecaps = 0;
+	caps_cmd.cryptocaps = 0;
+
+	/*
+	 * And now tell the firmware to use the configuration we just loaded.
+	 */
+	caps_cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
+					   F_FW_CMD_REQUEST | F_FW_CMD_WRITE);
+	caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd));
+	ret = t4_wr_mbox(adap, adap->mbox, &caps_cmd, sizeof(caps_cmd),
+			 NULL);
+	if (ret < 0) {
+		dev_warn(adap, "Unable to finalize Firmware Capabilities %d\n",
+			 ret);
+		return ret;
+	}
+
+	/*
+	 * Return successfully and note that we're operating with parameters
+	 * not supplied by the driver, rather than from hard-wired
+	 * initialization constants buried in the driver.
+	 */
+	dev_info(adap,
+		 "Successfully configured using Firmware Configuration File \"%s\", version: 0x%x, computed csum: 0x%x\n",
+		 config_name, finiver, cfcsum);
+	return 0;
+}
+
 static void configure_pcie_ext_tag(struct adapter *adapter)
 {
 	u16 v;
@@ -1119,12 +1333,7 @@  static int adap_init0_tweaks(struct adapter *adapter)
  */
 static int adap_init0_config(struct adapter *adapter, int reset)
 {
-	u32 finiver, finicsum, cfcsum, param, val;
-	struct fw_caps_config_cmd caps_cmd;
-	unsigned long mtype = 0, maddr = 0;
-	u8 config_issued = 0;
-	char config_name[20];
-	int cfg_addr, ret;
+	int ret;
 
 	/*
 	 * Reset device if necessary.
@@ -1139,98 +1348,10 @@  static int adap_init0_config(struct adapter *adapter, int reset)
 		}
 	}
 
-	cfg_addr = t4_flash_cfg_addr(adapter);
-	if (cfg_addr < 0) {
-		ret = cfg_addr;
-		dev_warn(adapter, "Finding address for firmware config file in flash failed, error %d\n",
-			 -ret);
-		goto bye;
-	}
-
-	strcpy(config_name, "On Flash");
-	mtype = FW_MEMTYPE_CF_FLASH;
-	maddr = cfg_addr;
-
-	/* Enable HASH filter region when support is available. */
-	val = 1;
-	param = CXGBE_FW_PARAM_DEV(HASHFILTER_WITH_OFLD);
-	t4_set_params(adapter, adapter->mbox, adapter->pf, 0, 1,
-		      &param, &val);
-
-	/*
-	 * Issue a Capability Configuration command to the firmware to get it
-	 * to parse the Configuration File.  We don't use t4_fw_config_file()
-	 * because we want the ability to modify various features after we've
-	 * processed the configuration file ...
-	 */
-	memset(&caps_cmd, 0, sizeof(caps_cmd));
-	caps_cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
-					   F_FW_CMD_REQUEST | F_FW_CMD_READ);
-	caps_cmd.cfvalid_to_len16 =
-		cpu_to_be32(F_FW_CAPS_CONFIG_CMD_CFVALID |
-			    V_FW_CAPS_CONFIG_CMD_MEMTYPE_CF(mtype) |
-			    V_FW_CAPS_CONFIG_CMD_MEMADDR64K_CF(maddr >> 16) |
-			    FW_LEN16(caps_cmd));
-	ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, sizeof(caps_cmd),
-			 &caps_cmd);
-	/*
-	 * If the CAPS_CONFIG failed with an ENOENT (for a Firmware
-	 * Configuration File in FLASH), our last gasp effort is to use the
-	 * Firmware Configuration File which is embedded in the firmware.  A
-	 * very few early versions of the firmware didn't have one embedded
-	 * but we can ignore those.
-	 */
-	if (ret == -ENOENT) {
-		dev_info(adapter, "%s: Going for embedded config in firmware..\n",
-			 __func__);
-
-		memset(&caps_cmd, 0, sizeof(caps_cmd));
-		caps_cmd.op_to_write =
-			cpu_to_be32(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
-				    F_FW_CMD_REQUEST | F_FW_CMD_READ);
-		caps_cmd.cfvalid_to_len16 = cpu_to_be32(FW_LEN16(caps_cmd));
-		ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd,
-				 sizeof(caps_cmd), &caps_cmd);
-		strcpy(config_name, "Firmware Default");
-	}
-
-	config_issued = 1;
+	ret = cxgbe_load_fw_config(adapter);
 	if (ret < 0)
 		goto bye;
 
-	finiver = be32_to_cpu(caps_cmd.finiver);
-	finicsum = be32_to_cpu(caps_cmd.finicsum);
-	cfcsum = be32_to_cpu(caps_cmd.cfcsum);
-	if (finicsum != cfcsum)
-		dev_warn(adapter, "Configuration File checksum mismatch: [fini] csum=%#x, computed csum=%#x\n",
-			 finicsum, cfcsum);
-
-	/*
-	 * If we're a pure NIC driver then disable all offloading facilities.
-	 * This will allow the firmware to optimize aspects of the hardware
-	 * configuration which will result in improved performance.
-	 */
-	caps_cmd.niccaps &= cpu_to_be16(~FW_CAPS_CONFIG_NIC_ETHOFLD);
-	caps_cmd.toecaps = 0;
-	caps_cmd.iscsicaps = 0;
-	caps_cmd.rdmacaps = 0;
-	caps_cmd.fcoecaps = 0;
-	caps_cmd.cryptocaps = 0;
-
-	/*
-	 * And now tell the firmware to use the configuration we just loaded.
-	 */
-	caps_cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
-					   F_FW_CMD_REQUEST | F_FW_CMD_WRITE);
-	caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd));
-	ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, sizeof(caps_cmd),
-			 NULL);
-	if (ret < 0) {
-		dev_warn(adapter, "Unable to finalize Firmware Capabilities %d\n",
-			 -ret);
-		goto bye;
-	}
-
 	/*
 	 * Tweak configuration based on system architecture, etc.
 	 */
@@ -1251,27 +1372,9 @@  static int adap_init0_config(struct adapter *adapter, int reset)
 		goto bye;
 	}
 
-	/*
-	 * Return successfully and note that we're operating with parameters
-	 * not supplied by the driver, rather than from hard-wired
-	 * initialization constants buried in the driver.
-	 */
-	dev_info(adapter,
-		 "Successfully configured using Firmware Configuration File \"%s\", version %#x, computed checksum %#x\n",
-		 config_name, finiver, cfcsum);
-
 	return 0;
 
-	/*
-	 * Something bad happened.  Return the error ...  (If the "error"
-	 * is that there's no Configuration File on the adapter we don't
-	 * want to issue a warning since this is fairly common.)
-	 */
 bye:
-	if (config_issued && ret != -ENOENT)
-		dev_warn(adapter, "\"%s\" configuration file error %d\n",
-			 config_name, -ret);
-
 	dev_debug(adapter, "%s: returning ret = %d ..\n", __func__, ret);
 	return ret;
 }