Skip to content

Commit c0eab5b

Browse files
Raghu Vatsavayidavem330
authored andcommitted
liquidio: CN23XX firmware download
Add firmware download support for cn23xx device. Signed-off-by: Derek Chickles <[email protected]> Signed-off-by: Satanand Burla <[email protected]> Signed-off-by: Felix Manlunas <[email protected]> Signed-off-by: Raghu Vatsavayi <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5b07aee commit c0eab5b

File tree

3 files changed

+111
-46
lines changed

3 files changed

+111
-46
lines changed

drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,37 @@ void cn23xx_dump_pf_initialized_regs(struct octeon_device *oct)
214214
CVM_CAST64(octeon_read_csr64(oct, CN23XX_SLI_PKT_CNT_INT)));
215215
}
216216

217+
static int cn23xx_pf_soft_reset(struct octeon_device *oct)
218+
{
219+
octeon_write_csr64(oct, CN23XX_WIN_WR_MASK_REG, 0xFF);
220+
221+
dev_dbg(&oct->pci_dev->dev, "OCTEON[%d]: BIST enabled for CN23XX soft reset\n",
222+
oct->octeon_id);
223+
224+
octeon_write_csr64(oct, CN23XX_SLI_SCRATCH1, 0x1234ULL);
225+
226+
/* Initiate chip-wide soft reset */
227+
lio_pci_readq(oct, CN23XX_RST_SOFT_RST);
228+
lio_pci_writeq(oct, 1, CN23XX_RST_SOFT_RST);
229+
230+
/* Wait for 100ms as Octeon resets. */
231+
mdelay(100);
232+
233+
if (octeon_read_csr64(oct, CN23XX_SLI_SCRATCH1) == 0x1234ULL) {
234+
dev_err(&oct->pci_dev->dev, "OCTEON[%d]: Soft reset failed\n",
235+
oct->octeon_id);
236+
return 1;
237+
}
238+
239+
dev_dbg(&oct->pci_dev->dev, "OCTEON[%d]: Reset completed\n",
240+
oct->octeon_id);
241+
242+
/* restore the reset value*/
243+
octeon_write_csr64(oct, CN23XX_WIN_WR_MASK_REG, 0xFF);
244+
245+
return 0;
246+
}
247+
217248
static void cn23xx_enable_error_reporting(struct octeon_device *oct)
218249
{
219250
u32 regval;
@@ -1030,6 +1061,7 @@ int setup_cn23xx_octeon_pf_device(struct octeon_device *oct)
10301061
oct->fn_list.process_interrupt_regs = cn23xx_interrupt_handler;
10311062
oct->fn_list.msix_interrupt_handler = cn23xx_pf_msix_interrupt_handler;
10321063

1064+
oct->fn_list.soft_reset = cn23xx_pf_soft_reset;
10331065
oct->fn_list.setup_device_regs = cn23xx_setup_pf_device_regs;
10341066

10351067
oct->fn_list.enable_interrupt = cn23xx_enable_pf_interrupt;
@@ -1129,3 +1161,11 @@ void cn23xx_dump_iq_regs(struct octeon_device *oct)
11291161
CVM_CAST64(octeon_read_csr64(
11301162
oct, CN23XX_SLI_S2M_PORTX_CTL(oct->pcie_port))));
11311163
}
1164+
1165+
int cn23xx_fw_loaded(struct octeon_device *oct)
1166+
{
1167+
u64 val;
1168+
1169+
val = octeon_read_csr64(oct, CN23XX_SLI_SCRATCH1);
1170+
return (val >> 1) & 1ULL;
1171+
}

drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,6 @@ int validate_cn23xx_pf_config_info(struct octeon_device *oct,
5252
struct octeon_config *conf23xx);
5353

5454
void cn23xx_dump_pf_initialized_regs(struct octeon_device *oct);
55+
56+
int cn23xx_fw_loaded(struct octeon_device *oct);
5557
#endif

drivers/net/ethernet/cavium/liquidio/lio_main.c

Lines changed: 69 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,9 +1312,9 @@ static void octeon_destroy_resources(struct octeon_device *oct)
13121312

13131313
/* fallthrough */
13141314
case OCT_DEV_PCI_MAP_DONE:
1315-
13161315
/* Soft reset the octeon device before exiting */
1317-
oct->fn_list.soft_reset(oct);
1316+
if ((!OCTEON_CN23XX_PF(oct)) || !oct->octeon_id)
1317+
oct->fn_list.soft_reset(oct);
13181318

13191319
octeon_unmap_pci_barx(oct, 0);
13201320
octeon_unmap_pci_barx(oct, 1);
@@ -3823,6 +3823,7 @@ static void nic_starter(struct work_struct *work)
38233823
static int octeon_device_init(struct octeon_device *octeon_dev)
38243824
{
38253825
int j, ret;
3826+
int fw_loaded = 0;
38263827
char bootcmd[] = "\n";
38273828
struct octeon_device_priv *oct_priv =
38283829
(struct octeon_device_priv *)octeon_dev->priv;
@@ -3844,9 +3845,23 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
38443845

38453846
octeon_dev->app_mode = CVM_DRV_INVALID_APP;
38463847

3847-
/* Do a soft reset of the Octeon device. */
3848-
if (octeon_dev->fn_list.soft_reset(octeon_dev))
3848+
if (OCTEON_CN23XX_PF(octeon_dev)) {
3849+
if (!cn23xx_fw_loaded(octeon_dev)) {
3850+
fw_loaded = 0;
3851+
/* Do a soft reset of the Octeon device. */
3852+
if (octeon_dev->fn_list.soft_reset(octeon_dev))
3853+
return 1;
3854+
/* things might have changed */
3855+
if (!cn23xx_fw_loaded(octeon_dev))
3856+
fw_loaded = 0;
3857+
else
3858+
fw_loaded = 1;
3859+
} else {
3860+
fw_loaded = 1;
3861+
}
3862+
} else if (octeon_dev->fn_list.soft_reset(octeon_dev)) {
38493863
return 1;
3864+
}
38503865

38513866
/* Initialize the dispatch mechanism used to push packets arriving on
38523867
* Octeon Output queues.
@@ -3955,56 +3970,65 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
39553970

39563971
atomic_set(&octeon_dev->status, OCT_DEV_IO_QUEUES_DONE);
39573972

3958-
dev_dbg(&octeon_dev->pci_dev->dev, "Waiting for DDR initialization...\n");
3959-
3960-
if (ddr_timeout == 0)
3961-
dev_info(&octeon_dev->pci_dev->dev, "WAITING. Set ddr_timeout to non-zero value to proceed with initialization.\n");
3973+
if ((!OCTEON_CN23XX_PF(octeon_dev)) || !fw_loaded) {
3974+
dev_dbg(&octeon_dev->pci_dev->dev, "Waiting for DDR initialization...\n");
3975+
if (!ddr_timeout) {
3976+
dev_info(&octeon_dev->pci_dev->dev,
3977+
"WAITING. Set ddr_timeout to non-zero value to proceed with initialization.\n");
3978+
}
39623979

3963-
schedule_timeout_uninterruptible(HZ * LIO_RESET_SECS);
3980+
schedule_timeout_uninterruptible(HZ * LIO_RESET_SECS);
39643981

3965-
/* Wait for the octeon to initialize DDR after the soft-reset. */
3966-
while (ddr_timeout == 0) {
3967-
set_current_state(TASK_INTERRUPTIBLE);
3968-
if (schedule_timeout(HZ / 10)) {
3969-
/* user probably pressed Control-C */
3982+
/* Wait for the octeon to initialize DDR after the soft-reset.*/
3983+
while (!ddr_timeout) {
3984+
set_current_state(TASK_INTERRUPTIBLE);
3985+
if (schedule_timeout(HZ / 10)) {
3986+
/* user probably pressed Control-C */
3987+
return 1;
3988+
}
3989+
}
3990+
ret = octeon_wait_for_ddr_init(octeon_dev, &ddr_timeout);
3991+
if (ret) {
3992+
dev_err(&octeon_dev->pci_dev->dev,
3993+
"DDR not initialized. Please confirm that board is configured to boot from Flash, ret: %d\n",
3994+
ret);
39703995
return 1;
39713996
}
3972-
}
3973-
ret = octeon_wait_for_ddr_init(octeon_dev, &ddr_timeout);
3974-
if (ret) {
3975-
dev_err(&octeon_dev->pci_dev->dev,
3976-
"DDR not initialized. Please confirm that board is configured to boot from Flash, ret: %d\n",
3977-
ret);
3978-
return 1;
3979-
}
39803997

3981-
if (octeon_wait_for_bootloader(octeon_dev, 1000) != 0) {
3982-
dev_err(&octeon_dev->pci_dev->dev, "Board not responding\n");
3983-
return 1;
3984-
}
3998+
if (octeon_wait_for_bootloader(octeon_dev, 1000)) {
3999+
dev_err(&octeon_dev->pci_dev->dev, "Board not responding\n");
4000+
return 1;
4001+
}
39854002

3986-
/* Divert uboot to take commands from host instead. */
3987-
ret = octeon_console_send_cmd(octeon_dev, bootcmd, 50);
4003+
/* Divert uboot to take commands from host instead. */
4004+
ret = octeon_console_send_cmd(octeon_dev, bootcmd, 50);
39884005

3989-
dev_dbg(&octeon_dev->pci_dev->dev, "Initializing consoles\n");
3990-
ret = octeon_init_consoles(octeon_dev);
3991-
if (ret) {
3992-
dev_err(&octeon_dev->pci_dev->dev, "Could not access board consoles\n");
3993-
return 1;
3994-
}
3995-
ret = octeon_add_console(octeon_dev, 0);
3996-
if (ret) {
3997-
dev_err(&octeon_dev->pci_dev->dev, "Could not access board console\n");
3998-
return 1;
3999-
}
4006+
dev_dbg(&octeon_dev->pci_dev->dev, "Initializing consoles\n");
4007+
ret = octeon_init_consoles(octeon_dev);
4008+
if (ret) {
4009+
dev_err(&octeon_dev->pci_dev->dev, "Could not access board consoles\n");
4010+
return 1;
4011+
}
4012+
ret = octeon_add_console(octeon_dev, 0);
4013+
if (ret) {
4014+
dev_err(&octeon_dev->pci_dev->dev, "Could not access board console\n");
4015+
return 1;
4016+
}
40004017

4001-
atomic_set(&octeon_dev->status, OCT_DEV_CONSOLE_INIT_DONE);
4018+
atomic_set(&octeon_dev->status, OCT_DEV_CONSOLE_INIT_DONE);
40024019

4003-
dev_dbg(&octeon_dev->pci_dev->dev, "Loading firmware\n");
4004-
ret = load_firmware(octeon_dev);
4005-
if (ret) {
4006-
dev_err(&octeon_dev->pci_dev->dev, "Could not load firmware to board\n");
4007-
return 1;
4020+
dev_dbg(&octeon_dev->pci_dev->dev, "Loading firmware\n");
4021+
ret = load_firmware(octeon_dev);
4022+
if (ret) {
4023+
dev_err(&octeon_dev->pci_dev->dev, "Could not load firmware to board\n");
4024+
return 1;
4025+
}
4026+
/* set bit 1 of SLI_SCRATCH_1 to indicate that firmware is
4027+
* loaded
4028+
*/
4029+
if (OCTEON_CN23XX_PF(octeon_dev))
4030+
octeon_write_csr64(octeon_dev, CN23XX_SLI_SCRATCH1,
4031+
2ULL);
40084032
}
40094033

40104034
handshake[octeon_dev->octeon_id].init_ok = 1;
@@ -4020,7 +4044,6 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
40204044
octeon_dev->droq[j]->pkts_credit_reg);
40214045

40224046
/* Packets can start arriving on the output queues from this point. */
4023-
40244047
return 0;
40254048
}
40264049

0 commit comments

Comments
 (0)