@@ -2100,46 +2100,59 @@ static int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
2100
2100
u16 ext , u16 * index , u32 * item_length ,
2101
2101
u32 * data_length );
2102
2102
2103
- static int bnxt_flash_nvram (struct net_device * dev ,
2104
- u16 dir_type ,
2105
- u16 dir_ordinal ,
2106
- u16 dir_ext ,
2107
- u16 dir_attr ,
2108
- const u8 * data ,
2109
- size_t data_len )
2103
+ static int __bnxt_flash_nvram (struct net_device * dev , u16 dir_type ,
2104
+ u16 dir_ordinal , u16 dir_ext , u16 dir_attr ,
2105
+ u32 dir_item_len , const u8 * data ,
2106
+ size_t data_len )
2110
2107
{
2111
2108
struct bnxt * bp = netdev_priv (dev );
2112
2109
int rc ;
2113
2110
struct hwrm_nvm_write_input req = {0 };
2114
2111
dma_addr_t dma_handle ;
2115
- u8 * kmem ;
2112
+ u8 * kmem = NULL ;
2116
2113
2117
2114
bnxt_hwrm_cmd_hdr_init (bp , & req , HWRM_NVM_WRITE , -1 , -1 );
2118
2115
2119
2116
req .dir_type = cpu_to_le16 (dir_type );
2120
2117
req .dir_ordinal = cpu_to_le16 (dir_ordinal );
2121
2118
req .dir_ext = cpu_to_le16 (dir_ext );
2122
2119
req .dir_attr = cpu_to_le16 (dir_attr );
2123
- req .dir_data_length = cpu_to_le32 (data_len );
2120
+ req .dir_item_length = cpu_to_le32 (dir_item_len );
2121
+ if (data_len && data ) {
2122
+ req .dir_data_length = cpu_to_le32 (data_len );
2124
2123
2125
- kmem = dma_alloc_coherent (& bp -> pdev -> dev , data_len , & dma_handle ,
2126
- GFP_KERNEL );
2127
- if (!kmem ) {
2128
- netdev_err (dev , "dma_alloc_coherent failure, length = %u\n" ,
2129
- (unsigned )data_len );
2130
- return - ENOMEM ;
2124
+ kmem = dma_alloc_coherent (& bp -> pdev -> dev , data_len , & dma_handle ,
2125
+ GFP_KERNEL );
2126
+ if (!kmem )
2127
+ return - ENOMEM ;
2128
+
2129
+ memcpy (kmem , data , data_len );
2130
+ req .host_src_addr = cpu_to_le64 (dma_handle );
2131
2131
}
2132
- memcpy (kmem , data , data_len );
2133
- req .host_src_addr = cpu_to_le64 (dma_handle );
2134
2132
2135
- rc = hwrm_send_message (bp , & req , sizeof (req ), FLASH_NVRAM_TIMEOUT );
2136
- dma_free_coherent (& bp -> pdev -> dev , data_len , kmem , dma_handle );
2133
+ rc = _hwrm_send_message (bp , & req , sizeof (req ), FLASH_NVRAM_TIMEOUT );
2134
+ if (kmem )
2135
+ dma_free_coherent (& bp -> pdev -> dev , data_len , kmem , dma_handle );
2137
2136
2138
2137
if (rc == - EACCES )
2139
2138
bnxt_print_admin_err (bp );
2140
2139
return rc ;
2141
2140
}
2142
2141
2142
+ static int bnxt_flash_nvram (struct net_device * dev , u16 dir_type ,
2143
+ u16 dir_ordinal , u16 dir_ext , u16 dir_attr ,
2144
+ const u8 * data , size_t data_len )
2145
+ {
2146
+ struct bnxt * bp = netdev_priv (dev );
2147
+ int rc ;
2148
+
2149
+ mutex_lock (& bp -> hwrm_cmd_lock );
2150
+ rc = __bnxt_flash_nvram (dev , dir_type , dir_ordinal , dir_ext , dir_attr ,
2151
+ 0 , data , data_len );
2152
+ mutex_unlock (& bp -> hwrm_cmd_lock );
2153
+ return rc ;
2154
+ }
2155
+
2143
2156
static int bnxt_hwrm_firmware_reset (struct net_device * dev , u8 proc_type ,
2144
2157
u8 self_reset , u8 flags )
2145
2158
{
@@ -2419,90 +2432,141 @@ static int bnxt_flash_firmware_from_file(struct net_device *dev,
2419
2432
return rc ;
2420
2433
}
2421
2434
2435
+ #define BNXT_PKG_DMA_SIZE 0x40000
2436
+ #define BNXT_NVM_MORE_FLAG (cpu_to_le16(NVM_MODIFY_REQ_FLAGS_BATCH_MODE))
2437
+ #define BNXT_NVM_LAST_FLAG (cpu_to_le16(NVM_MODIFY_REQ_FLAGS_BATCH_LAST))
2438
+
2422
2439
int bnxt_flash_package_from_fw_obj (struct net_device * dev , const struct firmware * fw ,
2423
2440
u32 install_type )
2424
2441
{
2425
- struct bnxt * bp = netdev_priv (dev );
2426
- struct hwrm_nvm_install_update_output * resp = bp -> hwrm_cmd_resp_addr ;
2427
2442
struct hwrm_nvm_install_update_input install = {0 };
2443
+ struct hwrm_nvm_install_update_output resp = {0 };
2444
+ struct hwrm_nvm_modify_input modify = {0 };
2445
+ struct bnxt * bp = netdev_priv (dev );
2446
+ bool defrag_attempted = false;
2447
+ dma_addr_t dma_handle ;
2448
+ u8 * kmem = NULL ;
2449
+ u32 modify_len ;
2428
2450
u32 item_len ;
2429
2451
int rc = 0 ;
2430
2452
u16 index ;
2431
2453
2432
2454
bnxt_hwrm_fw_set_time (bp );
2433
2455
2434
- rc = bnxt_find_nvram_item (dev , BNX_DIR_TYPE_UPDATE ,
2435
- BNX_DIR_ORDINAL_FIRST , BNX_DIR_EXT_NONE ,
2436
- & index , & item_len , NULL );
2437
- if (rc ) {
2438
- netdev_err (dev , "PKG update area not created in nvram\n" );
2439
- return rc ;
2456
+ bnxt_hwrm_cmd_hdr_init (bp , & modify , HWRM_NVM_MODIFY , -1 , -1 );
2457
+
2458
+ /* Try allocating a large DMA buffer first. Older fw will
2459
+ * cause excessive NVRAM erases when using small blocks.
2460
+ */
2461
+ modify_len = roundup_pow_of_two (fw -> size );
2462
+ modify_len = min_t (u32 , modify_len , BNXT_PKG_DMA_SIZE );
2463
+ while (1 ) {
2464
+ kmem = dma_alloc_coherent (& bp -> pdev -> dev , modify_len ,
2465
+ & dma_handle , GFP_KERNEL );
2466
+ if (!kmem && modify_len > PAGE_SIZE )
2467
+ modify_len /= 2 ;
2468
+ else
2469
+ break ;
2440
2470
}
2471
+ if (!kmem )
2472
+ return - ENOMEM ;
2441
2473
2442
- if (fw -> size > item_len ) {
2443
- netdev_err (dev , "PKG insufficient update area in nvram: %lu\n" ,
2444
- (unsigned long )fw -> size );
2445
- rc = - EFBIG ;
2446
- } else {
2447
- dma_addr_t dma_handle ;
2448
- u8 * kmem ;
2449
- struct hwrm_nvm_modify_input modify = {0 };
2474
+ modify .host_src_addr = cpu_to_le64 (dma_handle );
2450
2475
2451
- bnxt_hwrm_cmd_hdr_init (bp , & modify , HWRM_NVM_MODIFY , -1 , -1 );
2476
+ bnxt_hwrm_cmd_hdr_init (bp , & install , HWRM_NVM_INSTALL_UPDATE , -1 , -1 );
2477
+ if ((install_type & 0xffff ) == 0 )
2478
+ install_type >>= 16 ;
2479
+ install .install_type = cpu_to_le32 (install_type );
2480
+
2481
+ do {
2482
+ u32 copied = 0 , len = modify_len ;
2483
+
2484
+ rc = bnxt_find_nvram_item (dev , BNX_DIR_TYPE_UPDATE ,
2485
+ BNX_DIR_ORDINAL_FIRST ,
2486
+ BNX_DIR_EXT_NONE ,
2487
+ & index , & item_len , NULL );
2488
+ if (rc ) {
2489
+ netdev_err (dev , "PKG update area not created in nvram\n" );
2490
+ break ;
2491
+ }
2492
+ if (fw -> size > item_len ) {
2493
+ netdev_err (dev , "PKG insufficient update area in nvram: %lu\n" ,
2494
+ (unsigned long )fw -> size );
2495
+ rc = - EFBIG ;
2496
+ break ;
2497
+ }
2452
2498
2453
2499
modify .dir_idx = cpu_to_le16 (index );
2454
- modify .len = cpu_to_le32 (fw -> size );
2455
2500
2456
- kmem = dma_alloc_coherent (& bp -> pdev -> dev , fw -> size ,
2457
- & dma_handle , GFP_KERNEL );
2458
- if (!kmem ) {
2459
- netdev_err (dev ,
2460
- "dma_alloc_coherent failure, length = %u\n" ,
2461
- (unsigned int )fw -> size );
2462
- rc = - ENOMEM ;
2463
- } else {
2464
- memcpy (kmem , fw -> data , fw -> size );
2465
- modify .host_src_addr = cpu_to_le64 (dma_handle );
2501
+ if (fw -> size > modify_len )
2502
+ modify .flags = BNXT_NVM_MORE_FLAG ;
2503
+ while (copied < fw -> size ) {
2504
+ u32 balance = fw -> size - copied ;
2466
2505
2506
+ if (balance <= modify_len ) {
2507
+ len = balance ;
2508
+ if (copied )
2509
+ modify .flags |= BNXT_NVM_LAST_FLAG ;
2510
+ }
2511
+ memcpy (kmem , fw -> data + copied , len );
2512
+ modify .len = cpu_to_le32 (len );
2513
+ modify .offset = cpu_to_le32 (copied );
2467
2514
rc = hwrm_send_message (bp , & modify , sizeof (modify ),
2468
2515
FLASH_PACKAGE_TIMEOUT );
2469
- dma_free_coherent (& bp -> pdev -> dev , fw -> size , kmem ,
2470
- dma_handle );
2516
+ if (rc )
2517
+ goto pkg_abort ;
2518
+ copied += len ;
2471
2519
}
2472
- }
2473
- if (rc )
2474
- goto err_exit ;
2475
-
2476
- if ((install_type & 0xffff ) == 0 )
2477
- install_type >>= 16 ;
2478
- bnxt_hwrm_cmd_hdr_init (bp , & install , HWRM_NVM_INSTALL_UPDATE , -1 , -1 );
2479
- install .install_type = cpu_to_le32 (install_type );
2520
+ mutex_lock (& bp -> hwrm_cmd_lock );
2521
+ rc = _hwrm_send_message_silent (bp , & install , sizeof (install ),
2522
+ INSTALL_PACKAGE_TIMEOUT );
2523
+ memcpy (& resp , bp -> hwrm_cmd_resp_addr , sizeof (resp ));
2480
2524
2481
- mutex_lock (& bp -> hwrm_cmd_lock );
2482
- rc = _hwrm_send_message (bp , & install , sizeof (install ),
2483
- INSTALL_PACKAGE_TIMEOUT );
2484
- if (rc ) {
2485
- u8 error_code = ((struct hwrm_err_output * )resp )-> cmd_err ;
2525
+ if (defrag_attempted ) {
2526
+ /* We have tried to defragment already in the previous
2527
+ * iteration. Return with the result for INSTALL_UPDATE
2528
+ */
2529
+ mutex_unlock (& bp -> hwrm_cmd_lock );
2530
+ break ;
2531
+ }
2486
2532
2487
- if (resp -> error_code && error_code ==
2533
+ if (rc && (( struct hwrm_err_output * ) & resp ) -> cmd_err ==
2488
2534
NVM_INSTALL_UPDATE_CMD_ERR_CODE_FRAG_ERR ) {
2489
- install .flags |= cpu_to_le16 (
2490
- NVM_INSTALL_UPDATE_REQ_FLAGS_ALLOWED_TO_DEFRAG );
2491
- rc = _hwrm_send_message (bp , & install , sizeof (install ),
2492
- INSTALL_PACKAGE_TIMEOUT );
2535
+ install .flags |=
2536
+ cpu_to_le16 (NVM_INSTALL_UPDATE_REQ_FLAGS_ALLOWED_TO_DEFRAG );
2537
+
2538
+ rc = _hwrm_send_message_silent (bp , & install ,
2539
+ sizeof (install ),
2540
+ INSTALL_PACKAGE_TIMEOUT );
2541
+ memcpy (& resp , bp -> hwrm_cmd_resp_addr , sizeof (resp ));
2542
+
2543
+ if (rc && ((struct hwrm_err_output * )& resp )-> cmd_err ==
2544
+ NVM_INSTALL_UPDATE_CMD_ERR_CODE_NO_SPACE ) {
2545
+ /* FW has cleared NVM area, driver will create
2546
+ * UPDATE directory and try the flash again
2547
+ */
2548
+ defrag_attempted = true;
2549
+ rc = __bnxt_flash_nvram (bp -> dev ,
2550
+ BNX_DIR_TYPE_UPDATE ,
2551
+ BNX_DIR_ORDINAL_FIRST ,
2552
+ 0 , 0 , item_len , NULL ,
2553
+ 0 );
2554
+ } else if (rc ) {
2555
+ netdev_err (dev , "HWRM_NVM_INSTALL_UPDATE failure rc :%x\n" , rc );
2556
+ }
2557
+ } else if (rc ) {
2558
+ netdev_err (dev , "HWRM_NVM_INSTALL_UPDATE failure rc :%x\n" , rc );
2493
2559
}
2494
- if (rc )
2495
- goto flash_pkg_exit ;
2496
- }
2560
+ mutex_unlock (& bp -> hwrm_cmd_lock );
2561
+ } while (defrag_attempted && !rc );
2497
2562
2498
- if (resp -> result ) {
2563
+ pkg_abort :
2564
+ dma_free_coherent (& bp -> pdev -> dev , modify_len , kmem , dma_handle );
2565
+ if (resp .result ) {
2499
2566
netdev_err (dev , "PKG install error = %d, problem_item = %d\n" ,
2500
- (s8 )resp -> result , (int )resp -> problem_item );
2567
+ (s8 )resp . result , (int )resp . problem_item );
2501
2568
rc = - ENOPKG ;
2502
2569
}
2503
- flash_pkg_exit :
2504
- mutex_unlock (& bp -> hwrm_cmd_lock );
2505
- err_exit :
2506
2570
if (rc == - EACCES )
2507
2571
bnxt_print_admin_err (bp );
2508
2572
return rc ;
0 commit comments