net: aquantia: Change inefficient wait loop on fw data reads
authorIgor Russkikh <igor.russkikh@aquantia.com>
Tue, 20 Mar 2018 11:40:33 +0000 (14:40 +0300)
committerDavid S. Miller <davem@davemloft.net>
Thu, 22 Mar 2018 16:02:49 +0000 (12:02 -0400)
B1 hardware changes behavior of mailbox interface, it has busy bit
always raised. Data ready condition should be detected by increment
of address register.

Old code has empty `for` loop, and that caused cpu overloads on B1
hardware. aq_nic_service_timer_cb consumed ~100ms because of that.

Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h

index dcb27bc7e97c34703f192a91dcf55df24a754641..d3b847ec7465cc6a87f345d53b777662c969140b 100644 (file)
 
 #define HW_ATL_UCP_0X370_REG    0x0370U
 
+#define HW_ATL_MIF_CMD          0x0200U
+#define HW_ATL_MIF_ADDR         0x0208U
+#define HW_ATL_MIF_VAL          0x020CU
+
 #define HW_ATL_FW_SM_RAM        0x2U
 #define HW_ATL_MPI_FW_VERSION  0x18
 #define HW_ATL_MPI_CONTROL_ADR  0x0368U
@@ -269,18 +273,22 @@ int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
                }
        }
 
-       aq_hw_write_reg(self, 0x00000208U, a);
-
-       for (++cnt; --cnt;) {
-               u32 i = 0U;
+       aq_hw_write_reg(self, HW_ATL_MIF_ADDR, a);
 
-               aq_hw_write_reg(self, 0x00000200U, 0x00008000U);
+       for (++cnt; --cnt && !err;) {
+               aq_hw_write_reg(self, HW_ATL_MIF_CMD, 0x00008000U);
 
-               for (i = 1024U;
-                       (0x100U & aq_hw_read_reg(self, 0x00000200U)) && --i;) {
-               }
+               if (IS_CHIP_FEATURE(REVISION_B1))
+                       AQ_HW_WAIT_FOR(a != aq_hw_read_reg(self,
+                                                          HW_ATL_MIF_ADDR),
+                                      1, 1000U);
+               else
+                       AQ_HW_WAIT_FOR(!(0x100 & aq_hw_read_reg(self,
+                                                          HW_ATL_MIF_CMD)),
+                                      1, 1000U);
 
-               *(p++) = aq_hw_read_reg(self, 0x0000020CU);
+               *(p++) = aq_hw_read_reg(self, HW_ATL_MIF_VAL);
+               a += 4;
        }
 
        hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
@@ -676,14 +684,18 @@ void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p)
        u32 val = hw_atl_reg_glb_mif_id_get(self);
        u32 mif_rev = val & 0xFFU;
 
-       if ((3U & mif_rev) == 1U) {
-               chip_features |=
-                       HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 |
+       if ((0xFU & mif_rev) == 1U) {
+               chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 |
                        HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
                        HAL_ATLANTIC_UTILS_CHIP_MIPS;
-       } else if ((3U & mif_rev) == 2U) {
-               chip_features |=
-                       HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 |
+       } else if ((0xFU & mif_rev) == 2U) {
+               chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 |
+                       HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
+                       HAL_ATLANTIC_UTILS_CHIP_MIPS |
+                       HAL_ATLANTIC_UTILS_CHIP_TPO2 |
+                       HAL_ATLANTIC_UTILS_CHIP_RPF2;
+       } else if ((0xFU & mif_rev) == 0xAU) {
+               chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B1 |
                        HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
                        HAL_ATLANTIC_UTILS_CHIP_MIPS |
                        HAL_ATLANTIC_UTILS_CHIP_TPO2 |
index 2c690947910a3927f559efd63df20d99b0e8010b..cd8f18f39c611f8f709f71c7a1c23da8332a3fa4 100644 (file)
@@ -161,6 +161,7 @@ struct __packed hw_aq_atl_utils_mbox {
 #define HAL_ATLANTIC_UTILS_CHIP_MPI_AQ       0x00000010U
 #define HAL_ATLANTIC_UTILS_CHIP_REVISION_A0  0x01000000U
 #define HAL_ATLANTIC_UTILS_CHIP_REVISION_B0  0x02000000U
+#define HAL_ATLANTIC_UTILS_CHIP_REVISION_B1  0x04000000U
 
 #define IS_CHIP_FEATURE(_F_) (HAL_ATLANTIC_UTILS_CHIP_##_F_ & \
        self->chip_features)