@@ -1140,6 +1140,14 @@ static int bnxt_discard_rx(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
11401140 return 0 ;
11411141}
11421142
1143+ static void bnxt_queue_fw_reset_work (struct bnxt * bp , unsigned long delay )
1144+ {
1145+ if (BNXT_PF (bp ))
1146+ queue_delayed_work (bnxt_pf_wq , & bp -> fw_reset_task , delay );
1147+ else
1148+ schedule_delayed_work (& bp -> fw_reset_task , delay );
1149+ }
1150+
11431151static void bnxt_queue_sp_work (struct bnxt * bp )
11441152{
11451153 if (BNXT_PF (bp ))
@@ -6355,6 +6363,8 @@ static int bnxt_hwrm_func_qcfg(struct bnxt *bp)
63556363 struct bnxt_vf_info * vf = & bp -> vf ;
63566364
63576365 vf -> vlan = le16_to_cpu (resp -> vlan ) & VLAN_VID_MASK ;
6366+ } else {
6367+ bp -> pf .registered_vfs = le16_to_cpu (resp -> registered_vfs );
63586368 }
63596369#endif
63606370 flags = le16_to_cpu (resp -> flags );
@@ -9980,6 +9990,53 @@ static void bnxt_reset(struct bnxt *bp, bool silent)
99809990 bnxt_rtnl_unlock_sp (bp );
99819991}
99829992
9993+ static void bnxt_fw_reset_close (struct bnxt * bp )
9994+ {
9995+ __bnxt_close_nic (bp , true, false);
9996+ bnxt_ulp_irq_stop (bp );
9997+ bnxt_clear_int_mode (bp );
9998+ bnxt_hwrm_func_drv_unrgtr (bp );
9999+ bnxt_free_ctx_mem (bp );
10000+ kfree (bp -> ctx );
10001+ bp -> ctx = NULL ;
10002+ }
10003+
10004+ void bnxt_fw_reset (struct bnxt * bp )
10005+ {
10006+ int rc ;
10007+
10008+ bnxt_rtnl_lock_sp (bp );
10009+ if (test_bit (BNXT_STATE_OPEN , & bp -> state ) &&
10010+ !test_bit (BNXT_STATE_IN_FW_RESET , & bp -> state )) {
10011+ set_bit (BNXT_STATE_IN_FW_RESET , & bp -> state );
10012+ if (BNXT_PF (bp ) && bp -> pf .active_vfs ) {
10013+ rc = bnxt_hwrm_func_qcfg (bp );
10014+ if (rc ) {
10015+ netdev_err (bp -> dev , "Firmware reset aborted, first func_qcfg cmd failed, rc = %d\n" ,
10016+ rc );
10017+ clear_bit (BNXT_STATE_IN_FW_RESET , & bp -> state );
10018+ dev_close (bp -> dev );
10019+ goto fw_reset_exit ;
10020+ }
10021+ if (bp -> pf .registered_vfs || bp -> sriov_cfg ) {
10022+ u16 vf_tmo_dsecs = bp -> pf .registered_vfs * 10 ;
10023+
10024+ if (bp -> fw_reset_max_dsecs < vf_tmo_dsecs )
10025+ bp -> fw_reset_max_dsecs = vf_tmo_dsecs ;
10026+ bp -> fw_reset_state =
10027+ BNXT_FW_RESET_STATE_POLL_VF ;
10028+ bnxt_queue_fw_reset_work (bp , HZ / 10 );
10029+ goto fw_reset_exit ;
10030+ }
10031+ }
10032+ bnxt_fw_reset_close (bp );
10033+ bp -> fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV ;
10034+ bnxt_queue_fw_reset_work (bp , bp -> fw_reset_min_dsecs * HZ / 10 );
10035+ }
10036+ fw_reset_exit :
10037+ bnxt_rtnl_unlock_sp (bp );
10038+ }
10039+
998310040static void bnxt_chk_missed_irq (struct bnxt * bp )
998410041{
998510042 int i ;
@@ -10339,6 +10396,98 @@ static int bnxt_fw_init_one(struct bnxt *bp)
1033910396 return 0 ;
1034010397}
1034110398
10399+ static void bnxt_fw_reset_task (struct work_struct * work )
10400+ {
10401+ struct bnxt * bp = container_of (work , struct bnxt , fw_reset_task .work );
10402+ int rc ;
10403+
10404+ if (!test_bit (BNXT_STATE_IN_FW_RESET , & bp -> state )) {
10405+ netdev_err (bp -> dev , "bnxt_fw_reset_task() called when not in fw reset mode!\n" );
10406+ return ;
10407+ }
10408+
10409+ switch (bp -> fw_reset_state ) {
10410+ case BNXT_FW_RESET_STATE_POLL_VF :
10411+ rc = bnxt_hwrm_func_qcfg (bp );
10412+ if (rc ) {
10413+ netdev_err (bp -> dev , "Firmware reset aborted, subsequent func_qcfg cmd failed, rc = %d, %d msecs since reset timestamp\n" ,
10414+ rc , jiffies_to_msecs (jiffies -
10415+ bp -> fw_reset_timestamp ));
10416+ goto fw_reset_abort ;
10417+ }
10418+ if (bp -> pf .registered_vfs || bp -> sriov_cfg ) {
10419+ if (time_after (jiffies , bp -> fw_reset_timestamp +
10420+ (bp -> fw_reset_max_dsecs * HZ / 10 ))) {
10421+ clear_bit (BNXT_STATE_IN_FW_RESET , & bp -> state );
10422+ bp -> fw_reset_state = 0 ;
10423+ netdev_err (bp -> dev , "Firmware reset aborted, %d VFs still registered, sriov_cfg %d\n" ,
10424+ bp -> pf .registered_vfs ,
10425+ bp -> sriov_cfg );
10426+ return ;
10427+ }
10428+ bnxt_queue_fw_reset_work (bp , HZ / 10 );
10429+ return ;
10430+ }
10431+ bp -> fw_reset_timestamp = jiffies ;
10432+ rtnl_lock ();
10433+ bnxt_fw_reset_close (bp );
10434+ bp -> fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV ;
10435+ rtnl_unlock ();
10436+ bnxt_queue_fw_reset_work (bp , bp -> fw_reset_min_dsecs * HZ / 10 );
10437+ return ;
10438+ case BNXT_FW_RESET_STATE_ENABLE_DEV :
10439+ if (pci_enable_device (bp -> pdev )) {
10440+ netdev_err (bp -> dev , "Cannot re-enable PCI device\n" );
10441+ goto fw_reset_abort ;
10442+ }
10443+ pci_set_master (bp -> pdev );
10444+ bp -> fw_reset_state = BNXT_FW_RESET_STATE_POLL_FW ;
10445+ /* fall through */
10446+ case BNXT_FW_RESET_STATE_POLL_FW :
10447+ bp -> hwrm_cmd_timeout = SHORT_HWRM_CMD_TIMEOUT ;
10448+ rc = __bnxt_hwrm_ver_get (bp , true);
10449+ if (rc ) {
10450+ if (time_after (jiffies , bp -> fw_reset_timestamp +
10451+ (bp -> fw_reset_max_dsecs * HZ / 10 ))) {
10452+ netdev_err (bp -> dev , "Firmware reset aborted\n" );
10453+ goto fw_reset_abort ;
10454+ }
10455+ bnxt_queue_fw_reset_work (bp , HZ / 5 );
10456+ return ;
10457+ }
10458+ bp -> hwrm_cmd_timeout = DFLT_HWRM_CMD_TIMEOUT ;
10459+ bp -> fw_reset_state = BNXT_FW_RESET_STATE_OPENING ;
10460+ /* fall through */
10461+ case BNXT_FW_RESET_STATE_OPENING :
10462+ while (!rtnl_trylock ()) {
10463+ bnxt_queue_fw_reset_work (bp , HZ / 10 );
10464+ return ;
10465+ }
10466+ rc = bnxt_open (bp -> dev );
10467+ if (rc ) {
10468+ netdev_err (bp -> dev , "bnxt_open_nic() failed\n" );
10469+ clear_bit (BNXT_STATE_IN_FW_RESET , & bp -> state );
10470+ dev_close (bp -> dev );
10471+ }
10472+ bnxt_ulp_irq_restart (bp , rc );
10473+ rtnl_unlock ();
10474+
10475+ bp -> fw_reset_state = 0 ;
10476+ /* Make sure fw_reset_state is 0 before clearing the flag */
10477+ smp_mb__before_atomic ();
10478+ clear_bit (BNXT_STATE_IN_FW_RESET , & bp -> state );
10479+ break ;
10480+ }
10481+ return ;
10482+
10483+ fw_reset_abort :
10484+ clear_bit (BNXT_STATE_IN_FW_RESET , & bp -> state );
10485+ bp -> fw_reset_state = 0 ;
10486+ rtnl_lock ();
10487+ dev_close (bp -> dev );
10488+ rtnl_unlock ();
10489+ }
10490+
1034210491static int bnxt_init_board (struct pci_dev * pdev , struct net_device * dev )
1034310492{
1034410493 int rc ;
@@ -10401,6 +10550,7 @@ static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev)
1040110550 pci_enable_pcie_error_reporting (pdev );
1040210551
1040310552 INIT_WORK (& bp -> sp_task , bnxt_sp_task );
10553+ INIT_DELAYED_WORK (& bp -> fw_reset_task , bnxt_fw_reset_task );
1040410554
1040510555 spin_lock_init (& bp -> ntp_fltr_lock );
1040610556#if BITS_PER_LONG == 32
0 commit comments