hw_atl2_utils_fw.c (17334B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* Atlantic Network Driver 3 * Copyright (C) 2020 Marvell International Ltd. 4 */ 5 6#include <linux/iopoll.h> 7 8#include "aq_hw.h" 9#include "aq_hw_utils.h" 10#include "aq_nic.h" 11#include "hw_atl/hw_atl_llh.h" 12#include "hw_atl2_utils.h" 13#include "hw_atl2_llh.h" 14#include "hw_atl2_internal.h" 15 16#define AQ_A2_FW_READ_TRY_MAX 1000 17 18#define hw_atl2_shared_buffer_write(HW, ITEM, VARIABLE) \ 19{\ 20 BUILD_BUG_ON_MSG((offsetof(struct fw_interface_in, ITEM) % \ 21 sizeof(u32)) != 0,\ 22 "Unaligned write " # ITEM);\ 23 BUILD_BUG_ON_MSG((sizeof(VARIABLE) % sizeof(u32)) != 0,\ 24 "Unaligned write length " # ITEM);\ 25 hw_atl2_mif_shared_buf_write(HW,\ 26 (offsetof(struct fw_interface_in, ITEM) / sizeof(u32)),\ 27 (u32 *)&(VARIABLE), sizeof(VARIABLE) / sizeof(u32));\ 28} 29 30#define hw_atl2_shared_buffer_get(HW, ITEM, VARIABLE) \ 31{\ 32 BUILD_BUG_ON_MSG((offsetof(struct fw_interface_in, ITEM) % \ 33 sizeof(u32)) != 0,\ 34 "Unaligned get " # ITEM);\ 35 BUILD_BUG_ON_MSG((sizeof(VARIABLE) % sizeof(u32)) != 0,\ 36 "Unaligned get length " # ITEM);\ 37 hw_atl2_mif_shared_buf_get(HW, \ 38 (offsetof(struct fw_interface_in, ITEM) / sizeof(u32)),\ 39 (u32 *)&(VARIABLE), \ 40 sizeof(VARIABLE) / sizeof(u32));\ 41} 42 43/* This should never be used on non atomic fields, 44 * treat any > u32 read as non atomic. 45 */ 46#define hw_atl2_shared_buffer_read(HW, ITEM, VARIABLE) \ 47{\ 48 BUILD_BUG_ON_MSG((offsetof(struct fw_interface_out, ITEM) % \ 49 sizeof(u32)) != 0,\ 50 "Unaligned read " # ITEM);\ 51 BUILD_BUG_ON_MSG((sizeof(VARIABLE) % sizeof(u32)) != 0,\ 52 "Unaligned read length " # ITEM);\ 53 BUILD_BUG_ON_MSG(sizeof(VARIABLE) > sizeof(u32),\ 54 "Non atomic read " # ITEM);\ 55 hw_atl2_mif_shared_buf_read(HW, \ 56 (offsetof(struct fw_interface_out, ITEM) / sizeof(u32)),\ 57 (u32 *)&(VARIABLE), sizeof(VARIABLE) / sizeof(u32));\ 58} 59 60#define hw_atl2_shared_buffer_read_safe(HW, ITEM, DATA) \ 61({\ 62 BUILD_BUG_ON_MSG((offsetof(struct fw_interface_out, ITEM) % \ 63 sizeof(u32)) != 0,\ 64 "Unaligned read_safe " # ITEM);\ 65 BUILD_BUG_ON_MSG((sizeof(((struct fw_interface_out *)0)->ITEM) % \ 66 sizeof(u32)) != 0,\ 67 "Unaligned read_safe length " # ITEM);\ 68 hw_atl2_shared_buffer_read_block((HW), \ 69 (offsetof(struct fw_interface_out, ITEM) / sizeof(u32)),\ 70 sizeof(((struct fw_interface_out *)0)->ITEM) / sizeof(u32),\ 71 (DATA));\ 72}) 73 74static int hw_atl2_shared_buffer_read_block(struct aq_hw_s *self, 75 u32 offset, u32 dwords, void *data) 76{ 77 struct transaction_counter_s tid1, tid2; 78 int cnt = 0; 79 80 do { 81 do { 82 hw_atl2_shared_buffer_read(self, transaction_id, tid1); 83 cnt++; 84 if (cnt > AQ_A2_FW_READ_TRY_MAX) 85 return -ETIME; 86 if (tid1.transaction_cnt_a != tid1.transaction_cnt_b) 87 mdelay(1); 88 } while (tid1.transaction_cnt_a != tid1.transaction_cnt_b); 89 90 hw_atl2_mif_shared_buf_read(self, offset, (u32 *)data, dwords); 91 92 hw_atl2_shared_buffer_read(self, transaction_id, tid2); 93 94 cnt++; 95 if (cnt > AQ_A2_FW_READ_TRY_MAX) 96 return -ETIME; 97 } while (tid2.transaction_cnt_a != tid2.transaction_cnt_b || 98 tid1.transaction_cnt_a != tid2.transaction_cnt_a); 99 100 return 0; 101} 102 103static inline int hw_atl2_shared_buffer_finish_ack(struct aq_hw_s *self) 104{ 105 u32 val; 106 int err; 107 108 hw_atl2_mif_host_finished_write_set(self, 1U); 109 err = readx_poll_timeout_atomic(hw_atl2_mif_mcp_finished_read_get, 110 self, val, val == 0U, 111 100, 100000U); 112 WARN(err, "hw_atl2_shared_buffer_finish_ack"); 113 114 return err; 115} 116 117static int aq_a2_fw_init(struct aq_hw_s *self) 118{ 119 struct link_control_s link_control; 120 u32 mtu; 121 u32 val; 122 int err; 123 124 hw_atl2_shared_buffer_get(self, link_control, link_control); 125 link_control.mode = AQ_HOST_MODE_ACTIVE; 126 hw_atl2_shared_buffer_write(self, link_control, link_control); 127 128 hw_atl2_shared_buffer_get(self, mtu, mtu); 129 mtu = HW_ATL2_MTU_JUMBO; 130 hw_atl2_shared_buffer_write(self, mtu, mtu); 131 132 hw_atl2_mif_host_finished_write_set(self, 1U); 133 err = readx_poll_timeout_atomic(hw_atl2_mif_mcp_finished_read_get, 134 self, val, val == 0U, 135 100, 5000000U); 136 WARN(err, "hw_atl2_shared_buffer_finish_ack"); 137 138 return err; 139} 140 141static int aq_a2_fw_deinit(struct aq_hw_s *self) 142{ 143 struct link_control_s link_control; 144 145 hw_atl2_shared_buffer_get(self, link_control, link_control); 146 link_control.mode = AQ_HOST_MODE_SHUTDOWN; 147 hw_atl2_shared_buffer_write(self, link_control, link_control); 148 149 return hw_atl2_shared_buffer_finish_ack(self); 150} 151 152static void a2_link_speed_mask2fw(u32 speed, 153 struct link_options_s *link_options) 154{ 155 link_options->rate_10G = !!(speed & AQ_NIC_RATE_10G); 156 link_options->rate_5G = !!(speed & AQ_NIC_RATE_5G); 157 link_options->rate_N5G = link_options->rate_5G; 158 link_options->rate_2P5G = !!(speed & AQ_NIC_RATE_2G5); 159 link_options->rate_N2P5G = link_options->rate_2P5G; 160 link_options->rate_1G = !!(speed & AQ_NIC_RATE_1G); 161 link_options->rate_100M = !!(speed & AQ_NIC_RATE_100M); 162 link_options->rate_10M = !!(speed & AQ_NIC_RATE_10M); 163 164 link_options->rate_1G_hd = !!(speed & AQ_NIC_RATE_1G_HALF); 165 link_options->rate_100M_hd = !!(speed & AQ_NIC_RATE_100M_HALF); 166 link_options->rate_10M_hd = !!(speed & AQ_NIC_RATE_10M_HALF); 167} 168 169static u32 a2_fw_dev_to_eee_mask(struct device_link_caps_s *device_link_caps) 170{ 171 u32 rate = 0; 172 173 if (device_link_caps->eee_10G) 174 rate |= AQ_NIC_RATE_EEE_10G; 175 if (device_link_caps->eee_5G) 176 rate |= AQ_NIC_RATE_EEE_5G; 177 if (device_link_caps->eee_2P5G) 178 rate |= AQ_NIC_RATE_EEE_2G5; 179 if (device_link_caps->eee_1G) 180 rate |= AQ_NIC_RATE_EEE_1G; 181 if (device_link_caps->eee_100M) 182 rate |= AQ_NIC_RATE_EEE_100M; 183 184 return rate; 185} 186 187static u32 a2_fw_lkp_to_mask(struct lkp_link_caps_s *lkp_link_caps) 188{ 189 u32 rate = 0; 190 191 if (lkp_link_caps->rate_10G) 192 rate |= AQ_NIC_RATE_10G; 193 if (lkp_link_caps->rate_5G) 194 rate |= AQ_NIC_RATE_5G; 195 if (lkp_link_caps->rate_2P5G) 196 rate |= AQ_NIC_RATE_2G5; 197 if (lkp_link_caps->rate_1G) 198 rate |= AQ_NIC_RATE_1G; 199 if (lkp_link_caps->rate_1G_hd) 200 rate |= AQ_NIC_RATE_1G_HALF; 201 if (lkp_link_caps->rate_100M) 202 rate |= AQ_NIC_RATE_100M; 203 if (lkp_link_caps->rate_100M_hd) 204 rate |= AQ_NIC_RATE_100M_HALF; 205 if (lkp_link_caps->rate_10M) 206 rate |= AQ_NIC_RATE_10M; 207 if (lkp_link_caps->rate_10M_hd) 208 rate |= AQ_NIC_RATE_10M_HALF; 209 210 if (lkp_link_caps->eee_10G) 211 rate |= AQ_NIC_RATE_EEE_10G; 212 if (lkp_link_caps->eee_5G) 213 rate |= AQ_NIC_RATE_EEE_5G; 214 if (lkp_link_caps->eee_2P5G) 215 rate |= AQ_NIC_RATE_EEE_2G5; 216 if (lkp_link_caps->eee_1G) 217 rate |= AQ_NIC_RATE_EEE_1G; 218 if (lkp_link_caps->eee_100M) 219 rate |= AQ_NIC_RATE_EEE_100M; 220 221 return rate; 222} 223 224static int aq_a2_fw_set_link_speed(struct aq_hw_s *self, u32 speed) 225{ 226 struct link_options_s link_options; 227 228 hw_atl2_shared_buffer_get(self, link_options, link_options); 229 link_options.link_up = 1U; 230 a2_link_speed_mask2fw(speed, &link_options); 231 hw_atl2_shared_buffer_write(self, link_options, link_options); 232 233 return hw_atl2_shared_buffer_finish_ack(self); 234} 235 236static void aq_a2_fw_set_mpi_flow_control(struct aq_hw_s *self, 237 struct link_options_s *link_options) 238{ 239 u32 flow_control = self->aq_nic_cfg->fc.req; 240 241 link_options->pause_rx = !!(flow_control & AQ_NIC_FC_RX); 242 link_options->pause_tx = !!(flow_control & AQ_NIC_FC_TX); 243} 244 245static void aq_a2_fw_upd_eee_rate_bits(struct aq_hw_s *self, 246 struct link_options_s *link_options, 247 u32 eee_speeds) 248{ 249 link_options->eee_10G = !!(eee_speeds & AQ_NIC_RATE_EEE_10G); 250 link_options->eee_5G = !!(eee_speeds & AQ_NIC_RATE_EEE_5G); 251 link_options->eee_2P5G = !!(eee_speeds & AQ_NIC_RATE_EEE_2G5); 252 link_options->eee_1G = !!(eee_speeds & AQ_NIC_RATE_EEE_1G); 253 link_options->eee_100M = !!(eee_speeds & AQ_NIC_RATE_EEE_100M); 254} 255 256static int aq_a2_fw_set_state(struct aq_hw_s *self, 257 enum hal_atl_utils_fw_state_e state) 258{ 259 struct link_options_s link_options; 260 261 hw_atl2_shared_buffer_get(self, link_options, link_options); 262 263 switch (state) { 264 case MPI_INIT: 265 link_options.link_up = 1U; 266 aq_a2_fw_upd_eee_rate_bits(self, &link_options, 267 self->aq_nic_cfg->eee_speeds); 268 aq_a2_fw_set_mpi_flow_control(self, &link_options); 269 break; 270 case MPI_DEINIT: 271 link_options.link_up = 0U; 272 break; 273 case MPI_RESET: 274 case MPI_POWER: 275 /* No actions */ 276 break; 277 } 278 279 hw_atl2_shared_buffer_write(self, link_options, link_options); 280 281 return hw_atl2_shared_buffer_finish_ack(self); 282} 283 284static int aq_a2_fw_update_link_status(struct aq_hw_s *self) 285{ 286 struct lkp_link_caps_s lkp_link_caps; 287 struct link_status_s link_status; 288 289 hw_atl2_shared_buffer_read(self, link_status, link_status); 290 291 switch (link_status.link_rate) { 292 case AQ_A2_FW_LINK_RATE_10G: 293 self->aq_link_status.mbps = 10000; 294 break; 295 case AQ_A2_FW_LINK_RATE_5G: 296 self->aq_link_status.mbps = 5000; 297 break; 298 case AQ_A2_FW_LINK_RATE_2G5: 299 self->aq_link_status.mbps = 2500; 300 break; 301 case AQ_A2_FW_LINK_RATE_1G: 302 self->aq_link_status.mbps = 1000; 303 break; 304 case AQ_A2_FW_LINK_RATE_100M: 305 self->aq_link_status.mbps = 100; 306 break; 307 case AQ_A2_FW_LINK_RATE_10M: 308 self->aq_link_status.mbps = 10; 309 break; 310 default: 311 self->aq_link_status.mbps = 0; 312 } 313 self->aq_link_status.full_duplex = link_status.duplex; 314 315 hw_atl2_shared_buffer_read(self, lkp_link_caps, lkp_link_caps); 316 317 self->aq_link_status.lp_link_speed_msk = 318 a2_fw_lkp_to_mask(&lkp_link_caps); 319 self->aq_link_status.lp_flow_control = 320 ((lkp_link_caps.pause_rx) ? AQ_NIC_FC_RX : 0) | 321 ((lkp_link_caps.pause_tx) ? AQ_NIC_FC_TX : 0); 322 323 return 0; 324} 325 326static int aq_a2_fw_get_mac_permanent(struct aq_hw_s *self, u8 *mac) 327{ 328 struct mac_address_aligned_s mac_address; 329 330 hw_atl2_shared_buffer_get(self, mac_address, mac_address); 331 ether_addr_copy(mac, (u8 *)mac_address.aligned.mac_address); 332 333 return 0; 334} 335 336static void aq_a2_fill_a0_stats(struct aq_hw_s *self, 337 struct statistics_s *stats) 338{ 339 struct hw_atl2_priv *priv = (struct hw_atl2_priv *)self->priv; 340 struct aq_stats_s *cs = &self->curr_stats; 341 struct aq_stats_s curr_stats = *cs; 342 bool corrupted_stats = false; 343 344#define AQ_SDELTA(_N, _F) \ 345do { \ 346 if (!corrupted_stats && \ 347 ((s64)(stats->a0.msm._F - priv->last_stats.a0.msm._F)) >= 0) \ 348 curr_stats._N += stats->a0.msm._F - priv->last_stats.a0.msm._F;\ 349 else \ 350 corrupted_stats = true; \ 351} while (0) 352 353 if (self->aq_link_status.mbps) { 354 AQ_SDELTA(uprc, rx_unicast_frames); 355 AQ_SDELTA(mprc, rx_multicast_frames); 356 AQ_SDELTA(bprc, rx_broadcast_frames); 357 AQ_SDELTA(erpr, rx_error_frames); 358 359 AQ_SDELTA(uptc, tx_unicast_frames); 360 AQ_SDELTA(mptc, tx_multicast_frames); 361 AQ_SDELTA(bptc, tx_broadcast_frames); 362 AQ_SDELTA(erpt, tx_errors); 363 364 AQ_SDELTA(ubrc, rx_unicast_octets); 365 AQ_SDELTA(ubtc, tx_unicast_octets); 366 AQ_SDELTA(mbrc, rx_multicast_octets); 367 AQ_SDELTA(mbtc, tx_multicast_octets); 368 AQ_SDELTA(bbrc, rx_broadcast_octets); 369 AQ_SDELTA(bbtc, tx_broadcast_octets); 370 371 if (!corrupted_stats) 372 *cs = curr_stats; 373 } 374#undef AQ_SDELTA 375 376} 377 378static void aq_a2_fill_b0_stats(struct aq_hw_s *self, 379 struct statistics_s *stats) 380{ 381 struct hw_atl2_priv *priv = (struct hw_atl2_priv *)self->priv; 382 struct aq_stats_s *cs = &self->curr_stats; 383 struct aq_stats_s curr_stats = *cs; 384 bool corrupted_stats = false; 385 386#define AQ_SDELTA(_N, _F) \ 387do { \ 388 if (!corrupted_stats && \ 389 ((s64)(stats->b0._F - priv->last_stats.b0._F)) >= 0) \ 390 curr_stats._N += stats->b0._F - priv->last_stats.b0._F; \ 391 else \ 392 corrupted_stats = true; \ 393} while (0) 394 395 if (self->aq_link_status.mbps) { 396 AQ_SDELTA(uprc, rx_unicast_frames); 397 AQ_SDELTA(mprc, rx_multicast_frames); 398 AQ_SDELTA(bprc, rx_broadcast_frames); 399 AQ_SDELTA(erpr, rx_errors); 400 AQ_SDELTA(brc, rx_good_octets); 401 402 AQ_SDELTA(uptc, tx_unicast_frames); 403 AQ_SDELTA(mptc, tx_multicast_frames); 404 AQ_SDELTA(bptc, tx_broadcast_frames); 405 AQ_SDELTA(erpt, tx_errors); 406 AQ_SDELTA(btc, tx_good_octets); 407 408 if (!corrupted_stats) 409 *cs = curr_stats; 410 } 411#undef AQ_SDELTA 412} 413 414static int aq_a2_fw_update_stats(struct aq_hw_s *self) 415{ 416 struct hw_atl2_priv *priv = (struct hw_atl2_priv *)self->priv; 417 struct aq_stats_s *cs = &self->curr_stats; 418 struct statistics_s stats; 419 struct version_s version; 420 int err; 421 422 err = hw_atl2_shared_buffer_read_safe(self, version, &version); 423 if (err) 424 return err; 425 426 err = hw_atl2_shared_buffer_read_safe(self, stats, &stats); 427 if (err) 428 return err; 429 430 if (version.drv_iface_ver == AQ_A2_FW_INTERFACE_A0) 431 aq_a2_fill_a0_stats(self, &stats); 432 else 433 aq_a2_fill_b0_stats(self, &stats); 434 435 cs->dma_pkt_rc = hw_atl_stats_rx_dma_good_pkt_counter_get(self); 436 cs->dma_pkt_tc = hw_atl_stats_tx_dma_good_pkt_counter_get(self); 437 cs->dma_oct_rc = hw_atl_stats_rx_dma_good_octet_counter_get(self); 438 cs->dma_oct_tc = hw_atl_stats_tx_dma_good_octet_counter_get(self); 439 cs->dpc = hw_atl_rpb_rx_dma_drop_pkt_cnt_get(self); 440 441 memcpy(&priv->last_stats, &stats, sizeof(stats)); 442 443 return 0; 444} 445 446static int aq_a2_fw_get_phy_temp(struct aq_hw_s *self, int *temp) 447{ 448 struct phy_health_monitor_s phy_health_monitor; 449 450 hw_atl2_shared_buffer_read_safe(self, phy_health_monitor, 451 &phy_health_monitor); 452 453 *temp = (int8_t)phy_health_monitor.phy_temperature * 1000; 454 return 0; 455} 456 457static int aq_a2_fw_get_mac_temp(struct aq_hw_s *self, int *temp) 458{ 459 /* There's only one temperature sensor on A2, use it for 460 * both MAC and PHY. 461 */ 462 return aq_a2_fw_get_phy_temp(self, temp); 463} 464 465static int aq_a2_fw_set_eee_rate(struct aq_hw_s *self, u32 speed) 466{ 467 struct link_options_s link_options; 468 469 hw_atl2_shared_buffer_get(self, link_options, link_options); 470 471 aq_a2_fw_upd_eee_rate_bits(self, &link_options, speed); 472 473 hw_atl2_shared_buffer_write(self, link_options, link_options); 474 475 return hw_atl2_shared_buffer_finish_ack(self); 476} 477 478static int aq_a2_fw_get_eee_rate(struct aq_hw_s *self, u32 *rate, 479 u32 *supported_rates) 480{ 481 struct device_link_caps_s device_link_caps; 482 struct lkp_link_caps_s lkp_link_caps; 483 484 hw_atl2_shared_buffer_read(self, device_link_caps, device_link_caps); 485 hw_atl2_shared_buffer_read(self, lkp_link_caps, lkp_link_caps); 486 487 *supported_rates = a2_fw_dev_to_eee_mask(&device_link_caps); 488 *rate = a2_fw_lkp_to_mask(&lkp_link_caps); 489 490 return 0; 491} 492 493static int aq_a2_fw_renegotiate(struct aq_hw_s *self) 494{ 495 struct link_options_s link_options; 496 int err; 497 498 hw_atl2_shared_buffer_get(self, link_options, link_options); 499 link_options.link_renegotiate = 1U; 500 hw_atl2_shared_buffer_write(self, link_options, link_options); 501 502 err = hw_atl2_shared_buffer_finish_ack(self); 503 504 /* We should put renegotiate status back to zero 505 * after command completes 506 */ 507 link_options.link_renegotiate = 0U; 508 hw_atl2_shared_buffer_write(self, link_options, link_options); 509 510 return err; 511} 512 513static int aq_a2_fw_set_flow_control(struct aq_hw_s *self) 514{ 515 struct link_options_s link_options; 516 517 hw_atl2_shared_buffer_get(self, link_options, link_options); 518 519 aq_a2_fw_set_mpi_flow_control(self, &link_options); 520 521 hw_atl2_shared_buffer_write(self, link_options, link_options); 522 523 return hw_atl2_shared_buffer_finish_ack(self); 524} 525 526static u32 aq_a2_fw_get_flow_control(struct aq_hw_s *self, u32 *fcmode) 527{ 528 struct link_status_s link_status; 529 530 hw_atl2_shared_buffer_read(self, link_status, link_status); 531 532 *fcmode = ((link_status.pause_rx) ? AQ_NIC_FC_RX : 0) | 533 ((link_status.pause_tx) ? AQ_NIC_FC_TX : 0); 534 return 0; 535} 536 537static int aq_a2_fw_set_phyloopback(struct aq_hw_s *self, u32 mode, bool enable) 538{ 539 struct link_options_s link_options; 540 541 hw_atl2_shared_buffer_get(self, link_options, link_options); 542 543 switch (mode) { 544 case AQ_HW_LOOPBACK_PHYINT_SYS: 545 link_options.internal_loopback = enable; 546 break; 547 case AQ_HW_LOOPBACK_PHYEXT_SYS: 548 link_options.external_loopback = enable; 549 break; 550 default: 551 return -EINVAL; 552 } 553 554 hw_atl2_shared_buffer_write(self, link_options, link_options); 555 556 return hw_atl2_shared_buffer_finish_ack(self); 557} 558 559u32 hw_atl2_utils_get_fw_version(struct aq_hw_s *self) 560{ 561 struct version_s version; 562 563 hw_atl2_shared_buffer_read_safe(self, version, &version); 564 565 /* A2 FW version is stored in reverse order */ 566 return version.bundle.major << 24 | 567 version.bundle.minor << 16 | 568 version.bundle.build; 569} 570 571int hw_atl2_utils_get_action_resolve_table_caps(struct aq_hw_s *self, 572 u8 *base_index, u8 *count) 573{ 574 struct filter_caps_s filter_caps; 575 int err; 576 577 err = hw_atl2_shared_buffer_read_safe(self, filter_caps, &filter_caps); 578 if (err) 579 return err; 580 581 *base_index = filter_caps.rslv_tbl_base_index; 582 *count = filter_caps.rslv_tbl_count; 583 return 0; 584} 585 586static int aq_a2_fw_set_downshift(struct aq_hw_s *self, u32 counter) 587{ 588 struct link_options_s link_options; 589 590 hw_atl2_shared_buffer_get(self, link_options, link_options); 591 link_options.downshift = !!counter; 592 link_options.downshift_retry = counter; 593 hw_atl2_shared_buffer_write(self, link_options, link_options); 594 595 return hw_atl2_shared_buffer_finish_ack(self); 596} 597 598const struct aq_fw_ops aq_a2_fw_ops = { 599 .init = aq_a2_fw_init, 600 .deinit = aq_a2_fw_deinit, 601 .reset = NULL, 602 .renegotiate = aq_a2_fw_renegotiate, 603 .get_mac_permanent = aq_a2_fw_get_mac_permanent, 604 .set_link_speed = aq_a2_fw_set_link_speed, 605 .set_state = aq_a2_fw_set_state, 606 .update_link_status = aq_a2_fw_update_link_status, 607 .update_stats = aq_a2_fw_update_stats, 608 .get_mac_temp = aq_a2_fw_get_mac_temp, 609 .get_phy_temp = aq_a2_fw_get_phy_temp, 610 .set_eee_rate = aq_a2_fw_set_eee_rate, 611 .get_eee_rate = aq_a2_fw_get_eee_rate, 612 .set_flow_control = aq_a2_fw_set_flow_control, 613 .get_flow_control = aq_a2_fw_get_flow_control, 614 .set_phyloopback = aq_a2_fw_set_phyloopback, 615 .set_downshift = aq_a2_fw_set_downshift, 616};