Skip to content

Commit 0c58c35

Browse files
caildavem330
authored andcommitted
net: aquantia: Introduce firmware ops callbacks
New AQC cards will have an updated firmware with new binary interface. This patch extracts firmware specific operations into a separate table and prepares for the introduction of new fw 2.x and 3.x Signed-off-by: Igor Russkikh <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 76c19c6 commit 0c58c35

File tree

8 files changed

+101
-81
lines changed

8 files changed

+101
-81
lines changed

drivers/net/ethernet/aquantia/atlantic/aq_hw.h

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ struct aq_stats_s {
102102
struct aq_hw_s {
103103
atomic_t flags;
104104
struct aq_nic_cfg_s *aq_nic_cfg;
105+
const struct aq_fw_ops *aq_fw_ops;
105106
void __iomem *mmio;
106107
struct aq_hw_link_status_s aq_link_status;
107108
struct hw_aq_atl_utils_mbox mbox;
@@ -121,7 +122,6 @@ struct aq_hw_s {
121122

122123
struct aq_ring_s;
123124
struct aq_ring_param_s;
124-
struct aq_nic_cfg_s;
125125
struct sk_buff;
126126

127127
struct aq_hw_ops {
@@ -138,15 +138,8 @@ struct aq_hw_ops {
138138
int (*hw_ring_tx_head_update)(struct aq_hw_s *self,
139139
struct aq_ring_s *aq_ring);
140140

141-
int (*hw_get_mac_permanent)(struct aq_hw_s *self,
142-
u8 *mac);
143-
144141
int (*hw_set_mac_address)(struct aq_hw_s *self, u8 *mac_addr);
145142

146-
int (*hw_get_link_status)(struct aq_hw_s *self);
147-
148-
int (*hw_set_link_speed)(struct aq_hw_s *self, u32 speed);
149-
150143
int (*hw_reset)(struct aq_hw_s *self);
151144

152145
int (*hw_init)(struct aq_hw_s *self, u8 *mac_addr);
@@ -200,8 +193,6 @@ struct aq_hw_ops {
200193
const struct aq_hw_caps_s *aq_hw_caps,
201194
u32 *regs_buff);
202195

203-
int (*hw_update_stats)(struct aq_hw_s *self);
204-
205196
struct aq_stats_s *(*hw_get_hw_stats)(struct aq_hw_s *self);
206197

207198
int (*hw_get_fw_version)(struct aq_hw_s *self, u32 *fw_version);
@@ -211,4 +202,20 @@ struct aq_hw_ops {
211202
int (*hw_set_power)(struct aq_hw_s *self, unsigned int power_state);
212203
};
213204

205+
struct aq_fw_ops {
206+
int (*init)(struct aq_hw_s *self);
207+
208+
int (*reset)(struct aq_hw_s *self);
209+
210+
int (*get_mac_permanent)(struct aq_hw_s *self, u8 *mac);
211+
212+
int (*set_link_speed)(struct aq_hw_s *self, u32 speed);
213+
214+
int (*set_state)(struct aq_hw_s *self, enum hal_atl_utils_fw_state_e state);
215+
216+
int (*update_link_status)(struct aq_hw_s *self);
217+
218+
int (*update_stats)(struct aq_hw_s *self);
219+
};
220+
214221
#endif /* AQ_HW_H */

drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ do { \
3535
} \
3636
} while (0)
3737

38+
#define aq_pr_err(...) pr_err(AQ_CFG_DRV_NAME ": " __VA_ARGS__)
39+
#define aq_pr_trace(...) pr_info(AQ_CFG_DRV_NAME ": " __VA_ARGS__)
40+
3841
struct aq_hw_s;
3942

4043
void aq_hw_write_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk,

drivers/net/ethernet/aquantia/atlantic/aq_nic.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ void aq_nic_cfg_start(struct aq_nic_s *self)
122122

123123
static int aq_nic_update_link_status(struct aq_nic_s *self)
124124
{
125-
int err = self->aq_hw_ops->hw_get_link_status(self->aq_hw);
125+
int err = self->aq_fw_ops->update_link_status(self->aq_hw);
126126

127127
if (err)
128128
return err;
@@ -164,8 +164,8 @@ static void aq_nic_service_timer_cb(struct timer_list *t)
164164
if (err)
165165
goto err_exit;
166166

167-
if (self->aq_hw_ops->hw_update_stats)
168-
self->aq_hw_ops->hw_update_stats(self->aq_hw);
167+
if (self->aq_fw_ops->update_stats)
168+
self->aq_fw_ops->update_stats(self->aq_hw);
169169

170170
aq_nic_update_ndev_stats(self);
171171

@@ -200,7 +200,11 @@ int aq_nic_ndev_register(struct aq_nic_s *self)
200200
goto err_exit;
201201
}
202202

203-
err = self->aq_hw_ops->hw_get_mac_permanent(self->aq_hw,
203+
err = hw_atl_utils_initfw(self->aq_hw, &self->aq_fw_ops);
204+
if (err)
205+
goto err_exit;
206+
207+
err = self->aq_fw_ops->get_mac_permanent(self->aq_hw,
204208
self->ndev->dev_addr);
205209
if (err)
206210
goto err_exit;
@@ -799,7 +803,7 @@ int aq_nic_set_link_ksettings(struct aq_nic_s *self,
799803
self->aq_nic_cfg.is_autoneg = false;
800804
}
801805

802-
err = self->aq_hw_ops->hw_set_link_speed(self->aq_hw, rate);
806+
err = self->aq_fw_ops->set_link_speed(self->aq_hw, rate);
803807
if (err < 0)
804808
goto err_exit;
805809

drivers/net/ethernet/aquantia/atlantic/aq_nic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ struct aq_nic_s {
6868
unsigned int power_state;
6969
u8 port;
7070
const struct aq_hw_ops *aq_hw_ops;
71+
const struct aq_fw_ops *aq_fw_ops;
7172
struct aq_nic_cfg_s aq_nic_cfg;
7273
struct timer_list service_timer;
7374
struct timer_list polling_timer;

drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ static int hw_atl_a0_hw_reset(struct aq_hw_s *self)
105105
if (err < 0)
106106
goto err_exit;
107107

108-
hw_atl_utils_mpi_set(self, MPI_RESET, 0x0U);
108+
self->aq_fw_ops->set_state(self, MPI_RESET);
109109

110110
err = aq_hw_err_from_flags(self);
111111

@@ -354,7 +354,8 @@ static int hw_atl_a0_hw_init(struct aq_hw_s *self, u8 *mac_addr)
354354

355355
hw_atl_a0_hw_mac_addr_set(self, mac_addr);
356356

357-
hw_atl_utils_mpi_set(self, MPI_INIT, aq_nic_cfg->link_speed_msk);
357+
self->aq_fw_ops->set_link_speed(self, aq_nic_cfg->link_speed_msk);
358+
self->aq_fw_ops->set_state(self, MPI_INIT);
358359

359360
hw_atl_reg_tx_dma_debug_ctl_set(self, 0x800000b8U);
360361
hw_atl_reg_tx_dma_debug_ctl_set(self, 0x000000b8U);
@@ -365,7 +366,7 @@ static int hw_atl_a0_hw_init(struct aq_hw_s *self, u8 *mac_addr)
365366

366367
/* Reset link status and read out initial hardware counters */
367368
self->aq_link_status.mbps = 0;
368-
hw_atl_utils_update_stats(self);
369+
self->aq_fw_ops->update_stats(self);
369370

370371
err = aq_hw_err_from_flags(self);
371372
if (err < 0)
@@ -871,23 +872,8 @@ static int hw_atl_a0_hw_ring_rx_stop(struct aq_hw_s *self,
871872
return aq_hw_err_from_flags(self);
872873
}
873874

874-
static int hw_atl_a0_hw_set_speed(struct aq_hw_s *self, u32 speed)
875-
{
876-
int err = 0;
877-
878-
err = hw_atl_utils_mpi_set_speed(self, speed, MPI_INIT);
879-
if (err < 0)
880-
goto err_exit;
881-
882-
err_exit:
883-
return err;
884-
}
885-
886875
const struct aq_hw_ops hw_atl_ops_a0 = {
887-
.hw_get_mac_permanent = hw_atl_utils_get_mac_permanent,
888876
.hw_set_mac_address = hw_atl_a0_hw_mac_addr_set,
889-
.hw_get_link_status = hw_atl_utils_mpi_get_link_status,
890-
.hw_set_link_speed = hw_atl_a0_hw_set_speed,
891877
.hw_init = hw_atl_a0_hw_init,
892878
.hw_deinit = hw_atl_utils_hw_deinit,
893879
.hw_set_power = hw_atl_utils_hw_set_power,
@@ -917,7 +903,6 @@ const struct aq_hw_ops hw_atl_ops_a0 = {
917903
.hw_rss_set = hw_atl_a0_hw_rss_set,
918904
.hw_rss_hash_set = hw_atl_a0_hw_rss_hash_set,
919905
.hw_get_regs = hw_atl_utils_hw_get_regs,
920-
.hw_update_stats = hw_atl_utils_update_stats,
921906
.hw_get_hw_stats = hw_atl_utils_get_hw_stats,
922907
.hw_get_fw_version = hw_atl_utils_get_fw_version,
923908
};

drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ static int hw_atl_b0_hw_reset(struct aq_hw_s *self)
108108
if (err < 0)
109109
goto err_exit;
110110

111-
hw_atl_utils_mpi_set(self, MPI_RESET, 0x0U);
111+
self->aq_fw_ops->set_state(self, MPI_RESET);
112112

113113
err = aq_hw_err_from_flags(self);
114114

@@ -403,7 +403,8 @@ static int hw_atl_b0_hw_init(struct aq_hw_s *self, u8 *mac_addr)
403403

404404
hw_atl_b0_hw_mac_addr_set(self, mac_addr);
405405

406-
hw_atl_utils_mpi_set(self, MPI_INIT, aq_nic_cfg->link_speed_msk);
406+
self->aq_fw_ops->set_link_speed(self, aq_nic_cfg->link_speed_msk);
407+
self->aq_fw_ops->set_state(self, MPI_INIT);
407408

408409
hw_atl_b0_hw_qos_set(self);
409410
hw_atl_b0_hw_rss_set(self, &aq_nic_cfg->aq_rss);
@@ -422,7 +423,7 @@ static int hw_atl_b0_hw_init(struct aq_hw_s *self, u8 *mac_addr)
422423

423424
/* Reset link status and read out initial hardware counters */
424425
self->aq_link_status.mbps = 0;
425-
hw_atl_utils_update_stats(self);
426+
self->aq_fw_ops->update_stats(self);
426427

427428
err = aq_hw_err_from_flags(self);
428429
if (err < 0)
@@ -947,23 +948,8 @@ static int hw_atl_b0_hw_ring_rx_stop(struct aq_hw_s *self,
947948
return aq_hw_err_from_flags(self);
948949
}
949950

950-
static int hw_atl_b0_hw_set_speed(struct aq_hw_s *self, u32 speed)
951-
{
952-
int err = 0;
953-
954-
err = hw_atl_utils_mpi_set_speed(self, speed, MPI_INIT);
955-
if (err < 0)
956-
goto err_exit;
957-
958-
err_exit:
959-
return err;
960-
}
961-
962951
const struct aq_hw_ops hw_atl_ops_b0 = {
963-
.hw_get_mac_permanent = hw_atl_utils_get_mac_permanent,
964952
.hw_set_mac_address = hw_atl_b0_hw_mac_addr_set,
965-
.hw_get_link_status = hw_atl_utils_mpi_get_link_status,
966-
.hw_set_link_speed = hw_atl_b0_hw_set_speed,
967953
.hw_init = hw_atl_b0_hw_init,
968954
.hw_deinit = hw_atl_utils_hw_deinit,
969955
.hw_set_power = hw_atl_utils_hw_set_power,
@@ -993,7 +979,6 @@ const struct aq_hw_ops hw_atl_ops_b0 = {
993979
.hw_rss_set = hw_atl_b0_hw_rss_set,
994980
.hw_rss_hash_set = hw_atl_b0_hw_rss_hash_set,
995981
.hw_get_regs = hw_atl_utils_hw_get_regs,
996-
.hw_update_stats = hw_atl_utils_update_stats,
997982
.hw_get_hw_stats = hw_atl_utils_get_hw_stats,
998983
.hw_get_fw_version = hw_atl_utils_get_fw_version,
999984
};

drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,49 @@
1313

1414
#include "../aq_nic.h"
1515
#include "../aq_hw_utils.h"
16-
#include "../aq_pci_func.h"
1716
#include "hw_atl_utils.h"
1817
#include "hw_atl_llh.h"
18+
#include "hw_atl_llh_internal.h"
1919

2020
#include <linux/random.h>
2121

2222
#define HW_ATL_UCP_0X370_REG 0x0370U
2323

2424
#define HW_ATL_FW_SM_RAM 0x2U
25+
#define HW_ATL_MPI_FW_VERSION 0x18
2526
#define HW_ATL_MPI_CONTROL_ADR 0x0368U
2627
#define HW_ATL_MPI_STATE_ADR 0x036CU
2728

2829
#define HW_ATL_MPI_STATE_MSK 0x00FFU
2930
#define HW_ATL_MPI_STATE_SHIFT 0U
30-
#define HW_ATL_MPI_SPEED_MSK 0xFFFFU
31+
#define HW_ATL_MPI_SPEED_MSK 0xFFFF0000U
3132
#define HW_ATL_MPI_SPEED_SHIFT 16U
3233

34+
#define HW_ATL_FW_VER_1X 0x01050006U
35+
36+
static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual);
37+
38+
int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)
39+
{
40+
int err = 0;
41+
42+
hw_atl_utils_hw_chip_features_init(self,
43+
&self->chip_features);
44+
45+
hw_atl_utils_get_fw_version(self, &self->fw_ver_actual);
46+
47+
if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X, self->fw_ver_actual) == 0)
48+
*fw_ops = &aq_fw_1x_ops;
49+
else {
50+
aq_pr_err("Bad FW version detected: %x\n",
51+
self->fw_ver_actual);
52+
return -EOPNOTSUPP;
53+
}
54+
self->aq_fw_ops = *fw_ops;
55+
err = self->aq_fw_ops->init(self);
56+
return err;
57+
}
58+
3359
static int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
3460
u32 *p, u32 cnt)
3561
{
@@ -137,14 +163,6 @@ static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
137163
AQ_HW_WAIT_FOR(0U != (self->mbox_addr =
138164
aq_hw_read_reg(self, 0x360U)), 1000U, 10U);
139165

140-
err = hw_atl_utils_ver_match(aq_hw_caps->fw_ver_expected,
141-
aq_hw_read_reg(self, 0x18U));
142-
143-
if (err < 0)
144-
pr_err("%s: Bad FW version detected: expected=%x, actual=%x\n",
145-
AQ_CFG_DRV_NAME,
146-
aq_hw_caps->fw_ver_expected,
147-
aq_hw_read_reg(self, 0x18U));
148166
return err;
149167
}
150168

@@ -286,19 +304,19 @@ void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
286304
err_exit:;
287305
}
288306

289-
int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed,
290-
enum hal_atl_utils_fw_state_e state)
307+
int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed)
291308
{
292-
u32 ucp_0x368 = 0;
309+
u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
293310

294-
ucp_0x368 = (speed << HW_ATL_MPI_SPEED_SHIFT) | state;
295-
aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, ucp_0x368);
311+
val = (val & HW_ATL_MPI_STATE_MSK) | (speed << HW_ATL_MPI_SPEED_SHIFT);
312+
aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
296313

297314
return 0;
298315
}
299316

300317
void hw_atl_utils_mpi_set(struct aq_hw_s *self,
301-
enum hal_atl_utils_fw_state_e state, u32 speed)
318+
enum hal_atl_utils_fw_state_e state,
319+
u32 speed)
302320
{
303321
int err = 0;
304322
u32 transaction_id = 0;
@@ -317,11 +335,22 @@ void hw_atl_utils_mpi_set(struct aq_hw_s *self,
317335
goto err_exit;
318336
}
319337

320-
err = hw_atl_utils_mpi_set_speed(self, speed, state);
338+
aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR,
339+
(speed << HW_ATL_MPI_SPEED_SHIFT) | state);
321340

322341
err_exit:;
323342
}
324343

344+
static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
345+
enum hal_atl_utils_fw_state_e state)
346+
{
347+
u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
348+
349+
val = state | (val & HW_ATL_MPI_SPEED_MSK);
350+
aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
351+
return 0;
352+
}
353+
325354
int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)
326355
{
327356
u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
@@ -369,13 +398,6 @@ int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
369398
u32 l = 0U;
370399
u32 mac_addr[2];
371400

372-
hw_atl_utils_hw_chip_features_init(self,
373-
&self->chip_features);
374-
375-
err = hw_atl_utils_mpi_create(self);
376-
if (err < 0)
377-
goto err_exit;
378-
379401
if (!aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) {
380402
unsigned int rnd = 0;
381403
unsigned int ucp_0x370 = 0;
@@ -421,7 +443,6 @@ int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
421443
mac[0] = (u8)(0xFFU & h);
422444
}
423445

424-
err_exit:
425446
return err;
426447
}
427448

@@ -578,3 +599,13 @@ int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version)
578599
*fw_version = aq_hw_read_reg(self, 0x18U);
579600
return 0;
580601
}
602+
603+
const struct aq_fw_ops aq_fw_1x_ops = {
604+
.init = hw_atl_utils_mpi_create,
605+
.reset = NULL,
606+
.get_mac_permanent = hw_atl_utils_get_mac_permanent,
607+
.set_link_speed = hw_atl_utils_mpi_set_speed,
608+
.set_state = hw_atl_utils_mpi_set_state,
609+
.update_link_status = hw_atl_utils_mpi_get_link_status,
610+
.update_stats = hw_atl_utils_update_stats,
611+
};

0 commit comments

Comments
 (0)