| .. | .. |
|---|
| 1 | | -/* |
|---|
| 2 | | - * aQuantia Corporation Network Driver |
|---|
| 3 | | - * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 2 | +/* Atlantic Network Driver |
|---|
| 4 | 3 | * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 6 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 7 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 4 | + * Copyright (C) 2014-2019 aQuantia Corporation |
|---|
| 5 | + * Copyright (C) 2019-2020 Marvell International Ltd. |
|---|
| 8 | 6 | */ |
|---|
| 9 | 7 | |
|---|
| 10 | 8 | /* File hw_atl_utils_fw2x.c: Definition of firmware 2.x functions for |
|---|
| .. | .. |
|---|
| 16 | 14 | #include "../aq_pci_func.h" |
|---|
| 17 | 15 | #include "../aq_ring.h" |
|---|
| 18 | 16 | #include "../aq_vec.h" |
|---|
| 17 | +#include "../aq_nic.h" |
|---|
| 19 | 18 | #include "hw_atl_utils.h" |
|---|
| 20 | 19 | #include "hw_atl_llh.h" |
|---|
| 21 | 20 | |
|---|
| 22 | | -#define HW_ATL_FW2X_MPI_EFUSE_ADDR 0x364 |
|---|
| 23 | | -#define HW_ATL_FW2X_MPI_MBOX_ADDR 0x360 |
|---|
| 24 | | -#define HW_ATL_FW2X_MPI_RPC_ADDR 0x334 |
|---|
| 21 | +#define HW_ATL_FW2X_MPI_LED_ADDR 0x31c |
|---|
| 22 | +#define HW_ATL_FW2X_MPI_RPC_ADDR 0x334 |
|---|
| 25 | 23 | |
|---|
| 26 | | -#define HW_ATL_FW2X_MPI_CONTROL_ADDR 0x368 |
|---|
| 27 | | -#define HW_ATL_FW2X_MPI_CONTROL2_ADDR 0x36C |
|---|
| 24 | +#define HW_ATL_FW2X_MPI_MBOX_ADDR 0x360 |
|---|
| 25 | +#define HW_ATL_FW2X_MPI_EFUSE_ADDR 0x364 |
|---|
| 26 | +#define HW_ATL_FW2X_MPI_CONTROL_ADDR 0x368 |
|---|
| 27 | +#define HW_ATL_FW2X_MPI_CONTROL2_ADDR 0x36C |
|---|
| 28 | +#define HW_ATL_FW2X_MPI_STATE_ADDR 0x370 |
|---|
| 29 | +#define HW_ATL_FW2X_MPI_STATE2_ADDR 0x374 |
|---|
| 28 | 30 | |
|---|
| 29 | | -#define HW_ATL_FW2X_MPI_STATE_ADDR 0x370 |
|---|
| 30 | | -#define HW_ATL_FW2X_MPI_STATE2_ADDR 0x374 |
|---|
| 31 | +#define HW_ATL_FW3X_EXT_CONTROL_ADDR 0x378 |
|---|
| 32 | +#define HW_ATL_FW3X_EXT_STATE_ADDR 0x37c |
|---|
| 33 | + |
|---|
| 34 | +#define HW_ATL_FW3X_PTP_ADJ_LSW_ADDR 0x50a0 |
|---|
| 35 | +#define HW_ATL_FW3X_PTP_ADJ_MSW_ADDR 0x50a4 |
|---|
| 36 | + |
|---|
| 37 | +#define HW_ATL_FW2X_CAP_PAUSE BIT(CAPS_HI_PAUSE) |
|---|
| 38 | +#define HW_ATL_FW2X_CAP_ASYM_PAUSE BIT(CAPS_HI_ASYMMETRIC_PAUSE) |
|---|
| 39 | +#define HW_ATL_FW2X_CAP_SLEEP_PROXY BIT(CAPS_HI_SLEEP_PROXY) |
|---|
| 40 | +#define HW_ATL_FW2X_CAP_WOL BIT(CAPS_HI_WOL) |
|---|
| 41 | + |
|---|
| 42 | +#define HW_ATL_FW2X_CTRL_WAKE_ON_LINK BIT(CTRL_WAKE_ON_LINK) |
|---|
| 43 | +#define HW_ATL_FW2X_CTRL_SLEEP_PROXY BIT(CTRL_SLEEP_PROXY) |
|---|
| 44 | +#define HW_ATL_FW2X_CTRL_WOL BIT(CTRL_WOL) |
|---|
| 45 | +#define HW_ATL_FW2X_CTRL_LINK_DROP BIT(CTRL_LINK_DROP) |
|---|
| 46 | +#define HW_ATL_FW2X_CTRL_PAUSE BIT(CTRL_PAUSE) |
|---|
| 47 | +#define HW_ATL_FW2X_CTRL_TEMPERATURE BIT(CTRL_TEMPERATURE) |
|---|
| 48 | +#define HW_ATL_FW2X_CTRL_ASYMMETRIC_PAUSE BIT(CTRL_ASYMMETRIC_PAUSE) |
|---|
| 49 | +#define HW_ATL_FW2X_CTRL_INT_LOOPBACK BIT(CTRL_INT_LOOPBACK) |
|---|
| 50 | +#define HW_ATL_FW2X_CTRL_EXT_LOOPBACK BIT(CTRL_EXT_LOOPBACK) |
|---|
| 51 | +#define HW_ATL_FW2X_CTRL_DOWNSHIFT BIT(CTRL_DOWNSHIFT) |
|---|
| 52 | +#define HW_ATL_FW2X_CTRL_FORCE_RECONNECT BIT(CTRL_FORCE_RECONNECT) |
|---|
| 53 | + |
|---|
| 54 | +#define HW_ATL_FW2X_CAP_EEE_1G_MASK BIT(CAPS_HI_1000BASET_FD_EEE) |
|---|
| 55 | +#define HW_ATL_FW2X_CAP_EEE_2G5_MASK BIT(CAPS_HI_2P5GBASET_FD_EEE) |
|---|
| 56 | +#define HW_ATL_FW2X_CAP_EEE_5G_MASK BIT(CAPS_HI_5GBASET_FD_EEE) |
|---|
| 57 | +#define HW_ATL_FW2X_CAP_EEE_10G_MASK BIT(CAPS_HI_10GBASET_FD_EEE) |
|---|
| 58 | + |
|---|
| 59 | +#define HW_ATL_FW2X_CAP_MACSEC BIT(CAPS_LO_MACSEC) |
|---|
| 60 | + |
|---|
| 61 | +#define HAL_ATLANTIC_WOL_FILTERS_COUNT 8 |
|---|
| 62 | +#define HAL_ATLANTIC_UTILS_FW2X_MSG_WOL 0x0E |
|---|
| 63 | + |
|---|
| 64 | +#define HW_ATL_FW_VER_LED 0x03010026U |
|---|
| 65 | +#define HW_ATL_FW_VER_MEDIA_CONTROL 0x0301005aU |
|---|
| 66 | + |
|---|
| 67 | +struct __packed fw2x_msg_wol_pattern { |
|---|
| 68 | + u8 mask[16]; |
|---|
| 69 | + u32 crc; |
|---|
| 70 | +}; |
|---|
| 71 | + |
|---|
| 72 | +struct __packed fw2x_msg_wol { |
|---|
| 73 | + u32 msg_id; |
|---|
| 74 | + u8 hw_addr[ETH_ALEN]; |
|---|
| 75 | + u8 magic_packet_enabled; |
|---|
| 76 | + u8 filter_count; |
|---|
| 77 | + struct fw2x_msg_wol_pattern filter[HAL_ATLANTIC_WOL_FILTERS_COUNT]; |
|---|
| 78 | + u8 link_up_enabled; |
|---|
| 79 | + u8 link_down_enabled; |
|---|
| 80 | + u16 reserved; |
|---|
| 81 | + u32 link_up_timeout; |
|---|
| 82 | + u32 link_down_timeout; |
|---|
| 83 | +}; |
|---|
| 31 | 84 | |
|---|
| 32 | 85 | static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed); |
|---|
| 33 | 86 | static int aq_fw2x_set_state(struct aq_hw_s *self, |
|---|
| 34 | 87 | enum hal_atl_utils_fw_state_e state); |
|---|
| 88 | + |
|---|
| 89 | +static u32 aq_fw2x_mbox_get(struct aq_hw_s *self); |
|---|
| 90 | +static u32 aq_fw2x_rpc_get(struct aq_hw_s *self); |
|---|
| 91 | +static int aq_fw2x_settings_get(struct aq_hw_s *self, u32 *addr); |
|---|
| 92 | +static u32 aq_fw2x_state_get(struct aq_hw_s *self); |
|---|
| 93 | +static u32 aq_fw2x_state2_get(struct aq_hw_s *self); |
|---|
| 35 | 94 | |
|---|
| 36 | 95 | static int aq_fw2x_init(struct aq_hw_s *self) |
|---|
| 37 | 96 | { |
|---|
| 38 | 97 | int err = 0; |
|---|
| 39 | 98 | |
|---|
| 40 | 99 | /* check 10 times by 1ms */ |
|---|
| 41 | | - AQ_HW_WAIT_FOR(0U != (self->mbox_addr = |
|---|
| 42 | | - aq_hw_read_reg(self, HW_ATL_FW2X_MPI_MBOX_ADDR)), |
|---|
| 43 | | - 1000U, 10U); |
|---|
| 44 | | - AQ_HW_WAIT_FOR(0U != (self->rpc_addr = |
|---|
| 45 | | - aq_hw_read_reg(self, HW_ATL_FW2X_MPI_RPC_ADDR)), |
|---|
| 46 | | - 1000U, 100U); |
|---|
| 100 | + err = readx_poll_timeout_atomic(aq_fw2x_mbox_get, |
|---|
| 101 | + self, self->mbox_addr, |
|---|
| 102 | + self->mbox_addr != 0U, |
|---|
| 103 | + 1000U, 10000U); |
|---|
| 104 | + |
|---|
| 105 | + err = readx_poll_timeout_atomic(aq_fw2x_rpc_get, |
|---|
| 106 | + self, self->rpc_addr, |
|---|
| 107 | + self->rpc_addr != 0U, |
|---|
| 108 | + 1000U, 100000U); |
|---|
| 109 | + |
|---|
| 110 | + err = aq_fw2x_settings_get(self, &self->settings_addr); |
|---|
| 47 | 111 | |
|---|
| 48 | 112 | return err; |
|---|
| 49 | 113 | } |
|---|
| .. | .. |
|---|
| 68 | 132 | if (speed & AQ_NIC_RATE_5G) |
|---|
| 69 | 133 | rate |= FW2X_RATE_5G; |
|---|
| 70 | 134 | |
|---|
| 71 | | - if (speed & AQ_NIC_RATE_5GSR) |
|---|
| 72 | | - rate |= FW2X_RATE_5G; |
|---|
| 73 | | - |
|---|
| 74 | | - if (speed & AQ_NIC_RATE_2GS) |
|---|
| 135 | + if (speed & AQ_NIC_RATE_2G5) |
|---|
| 75 | 136 | rate |= FW2X_RATE_2G5; |
|---|
| 76 | 137 | |
|---|
| 77 | 138 | if (speed & AQ_NIC_RATE_1G) |
|---|
| .. | .. |
|---|
| 79 | 140 | |
|---|
| 80 | 141 | if (speed & AQ_NIC_RATE_100M) |
|---|
| 81 | 142 | rate |= FW2X_RATE_100M; |
|---|
| 143 | + |
|---|
| 144 | + return rate; |
|---|
| 145 | +} |
|---|
| 146 | + |
|---|
| 147 | +static u32 fw2x_to_eee_mask(u32 speed) |
|---|
| 148 | +{ |
|---|
| 149 | + u32 rate = 0; |
|---|
| 150 | + |
|---|
| 151 | + if (speed & HW_ATL_FW2X_CAP_EEE_10G_MASK) |
|---|
| 152 | + rate |= AQ_NIC_RATE_EEE_10G; |
|---|
| 153 | + if (speed & HW_ATL_FW2X_CAP_EEE_5G_MASK) |
|---|
| 154 | + rate |= AQ_NIC_RATE_EEE_5G; |
|---|
| 155 | + if (speed & HW_ATL_FW2X_CAP_EEE_2G5_MASK) |
|---|
| 156 | + rate |= AQ_NIC_RATE_EEE_2G5; |
|---|
| 157 | + if (speed & HW_ATL_FW2X_CAP_EEE_1G_MASK) |
|---|
| 158 | + rate |= AQ_NIC_RATE_EEE_1G; |
|---|
| 159 | + |
|---|
| 160 | + return rate; |
|---|
| 161 | +} |
|---|
| 162 | + |
|---|
| 163 | +static u32 eee_mask_to_fw2x(u32 speed) |
|---|
| 164 | +{ |
|---|
| 165 | + u32 rate = 0; |
|---|
| 166 | + |
|---|
| 167 | + if (speed & AQ_NIC_RATE_EEE_10G) |
|---|
| 168 | + rate |= HW_ATL_FW2X_CAP_EEE_10G_MASK; |
|---|
| 169 | + if (speed & AQ_NIC_RATE_EEE_5G) |
|---|
| 170 | + rate |= HW_ATL_FW2X_CAP_EEE_5G_MASK; |
|---|
| 171 | + if (speed & AQ_NIC_RATE_EEE_2G5) |
|---|
| 172 | + rate |= HW_ATL_FW2X_CAP_EEE_2G5_MASK; |
|---|
| 173 | + if (speed & AQ_NIC_RATE_EEE_1G) |
|---|
| 174 | + rate |= HW_ATL_FW2X_CAP_EEE_1G_MASK; |
|---|
| 82 | 175 | |
|---|
| 83 | 176 | return rate; |
|---|
| 84 | 177 | } |
|---|
| .. | .. |
|---|
| 92 | 185 | return 0; |
|---|
| 93 | 186 | } |
|---|
| 94 | 187 | |
|---|
| 95 | | -static void aq_fw2x_set_mpi_flow_control(struct aq_hw_s *self, u32 *mpi_state) |
|---|
| 188 | +static void aq_fw2x_upd_flow_control_bits(struct aq_hw_s *self, |
|---|
| 189 | + u32 *mpi_state, u32 fc) |
|---|
| 96 | 190 | { |
|---|
| 97 | | - if (self->aq_nic_cfg->flow_control & AQ_NIC_FC_RX) |
|---|
| 98 | | - *mpi_state |= BIT(CAPS_HI_PAUSE); |
|---|
| 99 | | - else |
|---|
| 100 | | - *mpi_state &= ~BIT(CAPS_HI_PAUSE); |
|---|
| 191 | + *mpi_state &= ~(HW_ATL_FW2X_CTRL_PAUSE | |
|---|
| 192 | + HW_ATL_FW2X_CTRL_ASYMMETRIC_PAUSE); |
|---|
| 101 | 193 | |
|---|
| 102 | | - if (self->aq_nic_cfg->flow_control & AQ_NIC_FC_TX) |
|---|
| 103 | | - *mpi_state |= BIT(CAPS_HI_ASYMMETRIC_PAUSE); |
|---|
| 104 | | - else |
|---|
| 105 | | - *mpi_state &= ~BIT(CAPS_HI_ASYMMETRIC_PAUSE); |
|---|
| 194 | + switch (fc) { |
|---|
| 195 | + /* There is not explicit mode of RX only pause frames, |
|---|
| 196 | + * thus, we join this mode with FC full. |
|---|
| 197 | + * FC full is either Rx, either Tx, or both. |
|---|
| 198 | + */ |
|---|
| 199 | + case AQ_NIC_FC_FULL: |
|---|
| 200 | + case AQ_NIC_FC_RX: |
|---|
| 201 | + *mpi_state |= HW_ATL_FW2X_CTRL_PAUSE | |
|---|
| 202 | + HW_ATL_FW2X_CTRL_ASYMMETRIC_PAUSE; |
|---|
| 203 | + break; |
|---|
| 204 | + case AQ_NIC_FC_TX: |
|---|
| 205 | + *mpi_state |= HW_ATL_FW2X_CTRL_ASYMMETRIC_PAUSE; |
|---|
| 206 | + break; |
|---|
| 207 | + } |
|---|
| 208 | +} |
|---|
| 209 | + |
|---|
| 210 | +static void aq_fw2x_upd_eee_rate_bits(struct aq_hw_s *self, u32 *mpi_opts, |
|---|
| 211 | + u32 eee_speeds) |
|---|
| 212 | +{ |
|---|
| 213 | + *mpi_opts &= ~(HW_ATL_FW2X_CAP_EEE_1G_MASK | |
|---|
| 214 | + HW_ATL_FW2X_CAP_EEE_2G5_MASK | |
|---|
| 215 | + HW_ATL_FW2X_CAP_EEE_5G_MASK | |
|---|
| 216 | + HW_ATL_FW2X_CAP_EEE_10G_MASK); |
|---|
| 217 | + |
|---|
| 218 | + *mpi_opts |= eee_mask_to_fw2x(eee_speeds); |
|---|
| 106 | 219 | } |
|---|
| 107 | 220 | |
|---|
| 108 | 221 | static int aq_fw2x_set_state(struct aq_hw_s *self, |
|---|
| 109 | 222 | enum hal_atl_utils_fw_state_e state) |
|---|
| 110 | 223 | { |
|---|
| 111 | 224 | u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); |
|---|
| 225 | + struct aq_nic_cfg_s *cfg = self->aq_nic_cfg; |
|---|
| 112 | 226 | |
|---|
| 113 | 227 | switch (state) { |
|---|
| 114 | 228 | case MPI_INIT: |
|---|
| 115 | 229 | mpi_state &= ~BIT(CAPS_HI_LINK_DROP); |
|---|
| 116 | | - aq_fw2x_set_mpi_flow_control(self, &mpi_state); |
|---|
| 230 | + aq_fw2x_upd_eee_rate_bits(self, &mpi_state, cfg->eee_speeds); |
|---|
| 231 | + aq_fw2x_upd_flow_control_bits(self, &mpi_state, |
|---|
| 232 | + self->aq_nic_cfg->fc.req); |
|---|
| 117 | 233 | break; |
|---|
| 118 | 234 | case MPI_DEINIT: |
|---|
| 119 | 235 | mpi_state |= BIT(CAPS_HI_LINK_DROP); |
|---|
| .. | .. |
|---|
| 124 | 240 | break; |
|---|
| 125 | 241 | } |
|---|
| 126 | 242 | aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_state); |
|---|
| 243 | + |
|---|
| 127 | 244 | return 0; |
|---|
| 128 | 245 | } |
|---|
| 129 | 246 | |
|---|
| 130 | 247 | static int aq_fw2x_update_link_status(struct aq_hw_s *self) |
|---|
| 131 | 248 | { |
|---|
| 132 | | - u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR); |
|---|
| 133 | | - u32 speed = mpi_state & (FW2X_RATE_100M | FW2X_RATE_1G | |
|---|
| 134 | | - FW2X_RATE_2G5 | FW2X_RATE_5G | FW2X_RATE_10G); |
|---|
| 135 | 249 | struct aq_hw_link_status_s *link_status = &self->aq_link_status; |
|---|
| 250 | + u32 mpi_state; |
|---|
| 251 | + u32 speed; |
|---|
| 252 | + |
|---|
| 253 | + mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR); |
|---|
| 254 | + speed = mpi_state & (FW2X_RATE_100M | FW2X_RATE_1G | |
|---|
| 255 | + FW2X_RATE_2G5 | FW2X_RATE_5G | |
|---|
| 256 | + FW2X_RATE_10G); |
|---|
| 136 | 257 | |
|---|
| 137 | 258 | if (speed) { |
|---|
| 138 | 259 | if (speed & FW2X_RATE_10G) |
|---|
| .. | .. |
|---|
| 150 | 271 | } else { |
|---|
| 151 | 272 | link_status->mbps = 0; |
|---|
| 152 | 273 | } |
|---|
| 274 | + link_status->full_duplex = true; |
|---|
| 153 | 275 | |
|---|
| 154 | 276 | return 0; |
|---|
| 155 | 277 | } |
|---|
| 156 | 278 | |
|---|
| 157 | 279 | static int aq_fw2x_get_mac_permanent(struct aq_hw_s *self, u8 *mac) |
|---|
| 158 | 280 | { |
|---|
| 159 | | - int err = 0; |
|---|
| 160 | | - u32 h = 0U; |
|---|
| 161 | | - u32 l = 0U; |
|---|
| 162 | | - u32 mac_addr[2] = { 0 }; |
|---|
| 163 | 281 | u32 efuse_addr = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_EFUSE_ADDR); |
|---|
| 282 | + u32 mac_addr[2] = { 0 }; |
|---|
| 283 | + int err = 0; |
|---|
| 164 | 284 | |
|---|
| 165 | 285 | if (efuse_addr != 0) { |
|---|
| 166 | 286 | err = hw_atl_utils_fw_downld_dwords(self, |
|---|
| .. | .. |
|---|
| 175 | 295 | |
|---|
| 176 | 296 | ether_addr_copy(mac, (u8 *)mac_addr); |
|---|
| 177 | 297 | |
|---|
| 178 | | - if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) { |
|---|
| 179 | | - unsigned int rnd = 0; |
|---|
| 180 | | - |
|---|
| 181 | | - get_random_bytes(&rnd, sizeof(unsigned int)); |
|---|
| 182 | | - |
|---|
| 183 | | - l = 0xE3000000U |
|---|
| 184 | | - | (0xFFFFU & rnd) |
|---|
| 185 | | - | (0x00 << 16); |
|---|
| 186 | | - h = 0x8001300EU; |
|---|
| 187 | | - |
|---|
| 188 | | - mac[5] = (u8)(0xFFU & l); |
|---|
| 189 | | - l >>= 8; |
|---|
| 190 | | - mac[4] = (u8)(0xFFU & l); |
|---|
| 191 | | - l >>= 8; |
|---|
| 192 | | - mac[3] = (u8)(0xFFU & l); |
|---|
| 193 | | - l >>= 8; |
|---|
| 194 | | - mac[2] = (u8)(0xFFU & l); |
|---|
| 195 | | - mac[1] = (u8)(0xFFU & h); |
|---|
| 196 | | - h >>= 8; |
|---|
| 197 | | - mac[0] = (u8)(0xFFU & h); |
|---|
| 198 | | - } |
|---|
| 199 | 298 | return err; |
|---|
| 200 | 299 | } |
|---|
| 201 | 300 | |
|---|
| 202 | 301 | static int aq_fw2x_update_stats(struct aq_hw_s *self) |
|---|
| 203 | 302 | { |
|---|
| 204 | | - int err = 0; |
|---|
| 205 | 303 | u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); |
|---|
| 206 | 304 | u32 orig_stats_val = mpi_opts & BIT(CAPS_HI_STATISTICS); |
|---|
| 305 | + u32 stats_val; |
|---|
| 306 | + int err = 0; |
|---|
| 207 | 307 | |
|---|
| 208 | 308 | /* Toggle statistics bit for FW to update */ |
|---|
| 209 | 309 | mpi_opts = mpi_opts ^ BIT(CAPS_HI_STATISTICS); |
|---|
| 210 | 310 | aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts); |
|---|
| 211 | 311 | |
|---|
| 212 | 312 | /* Wait FW to report back */ |
|---|
| 213 | | - AQ_HW_WAIT_FOR(orig_stats_val != |
|---|
| 214 | | - (aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR) & |
|---|
| 215 | | - BIT(CAPS_HI_STATISTICS)), |
|---|
| 216 | | - 1U, 10000U); |
|---|
| 313 | + err = readx_poll_timeout_atomic(aq_fw2x_state2_get, |
|---|
| 314 | + self, stats_val, |
|---|
| 315 | + orig_stats_val != (stats_val & |
|---|
| 316 | + BIT(CAPS_HI_STATISTICS)), |
|---|
| 317 | + 1U, 10000U); |
|---|
| 217 | 318 | if (err) |
|---|
| 218 | 319 | return err; |
|---|
| 219 | 320 | |
|---|
| 220 | 321 | return hw_atl_utils_update_stats(self); |
|---|
| 322 | +} |
|---|
| 323 | + |
|---|
| 324 | +static int aq_fw2x_get_phy_temp(struct aq_hw_s *self, int *temp) |
|---|
| 325 | +{ |
|---|
| 326 | + u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); |
|---|
| 327 | + u32 temp_val = mpi_opts & HW_ATL_FW2X_CTRL_TEMPERATURE; |
|---|
| 328 | + u32 phy_temp_offset; |
|---|
| 329 | + u32 temp_res; |
|---|
| 330 | + int err = 0; |
|---|
| 331 | + u32 val; |
|---|
| 332 | + |
|---|
| 333 | + phy_temp_offset = self->mbox_addr + offsetof(struct hw_atl_utils_mbox, |
|---|
| 334 | + info.phy_temperature); |
|---|
| 335 | + |
|---|
| 336 | + /* Toggle statistics bit for FW to 0x36C.18 (CTRL_TEMPERATURE) */ |
|---|
| 337 | + mpi_opts = mpi_opts ^ HW_ATL_FW2X_CTRL_TEMPERATURE; |
|---|
| 338 | + aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts); |
|---|
| 339 | + /* Wait FW to report back */ |
|---|
| 340 | + err = readx_poll_timeout_atomic(aq_fw2x_state2_get, self, val, |
|---|
| 341 | + temp_val != |
|---|
| 342 | + (val & HW_ATL_FW2X_CTRL_TEMPERATURE), |
|---|
| 343 | + 1U, 10000U); |
|---|
| 344 | + err = hw_atl_utils_fw_downld_dwords(self, phy_temp_offset, |
|---|
| 345 | + &temp_res, 1); |
|---|
| 346 | + |
|---|
| 347 | + if (err) |
|---|
| 348 | + return err; |
|---|
| 349 | + |
|---|
| 350 | + /* Convert PHY temperature from 1/256 degree Celsius |
|---|
| 351 | + * to 1/1000 degree Celsius. |
|---|
| 352 | + */ |
|---|
| 353 | + *temp = (int16_t)(temp_res & 0xFFFF) * 1000 / 256; |
|---|
| 354 | + |
|---|
| 355 | + return 0; |
|---|
| 356 | +} |
|---|
| 357 | + |
|---|
| 358 | +static int aq_fw2x_set_wol(struct aq_hw_s *self, u8 *mac) |
|---|
| 359 | +{ |
|---|
| 360 | + struct hw_atl_utils_fw_rpc *rpc = NULL; |
|---|
| 361 | + struct offload_info *info = NULL; |
|---|
| 362 | + u32 wol_bits = 0; |
|---|
| 363 | + u32 rpc_size; |
|---|
| 364 | + int err = 0; |
|---|
| 365 | + u32 val; |
|---|
| 366 | + |
|---|
| 367 | + if (self->aq_nic_cfg->wol & WAKE_PHY) { |
|---|
| 368 | + aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, |
|---|
| 369 | + HW_ATL_FW2X_CTRL_LINK_DROP); |
|---|
| 370 | + readx_poll_timeout_atomic(aq_fw2x_state2_get, self, val, |
|---|
| 371 | + (val & |
|---|
| 372 | + HW_ATL_FW2X_CTRL_LINK_DROP) != 0, |
|---|
| 373 | + 1000, 100000); |
|---|
| 374 | + wol_bits |= HW_ATL_FW2X_CTRL_WAKE_ON_LINK; |
|---|
| 375 | + } |
|---|
| 376 | + |
|---|
| 377 | + if (self->aq_nic_cfg->wol & WAKE_MAGIC) { |
|---|
| 378 | + wol_bits |= HW_ATL_FW2X_CTRL_SLEEP_PROXY | |
|---|
| 379 | + HW_ATL_FW2X_CTRL_WOL; |
|---|
| 380 | + |
|---|
| 381 | + err = hw_atl_utils_fw_rpc_wait(self, &rpc); |
|---|
| 382 | + if (err < 0) |
|---|
| 383 | + goto err_exit; |
|---|
| 384 | + |
|---|
| 385 | + rpc_size = sizeof(*info) + |
|---|
| 386 | + offsetof(struct hw_atl_utils_fw_rpc, fw2x_offloads); |
|---|
| 387 | + memset(rpc, 0, rpc_size); |
|---|
| 388 | + info = &rpc->fw2x_offloads; |
|---|
| 389 | + memcpy(info->mac_addr, mac, ETH_ALEN); |
|---|
| 390 | + info->len = sizeof(*info); |
|---|
| 391 | + |
|---|
| 392 | + err = hw_atl_utils_fw_rpc_call(self, rpc_size); |
|---|
| 393 | + if (err < 0) |
|---|
| 394 | + goto err_exit; |
|---|
| 395 | + } |
|---|
| 396 | + |
|---|
| 397 | + aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, wol_bits); |
|---|
| 398 | + |
|---|
| 399 | +err_exit: |
|---|
| 400 | + return err; |
|---|
| 401 | +} |
|---|
| 402 | + |
|---|
| 403 | +static int aq_fw2x_set_power(struct aq_hw_s *self, unsigned int power_state, |
|---|
| 404 | + u8 *mac) |
|---|
| 405 | +{ |
|---|
| 406 | + int err = 0; |
|---|
| 407 | + |
|---|
| 408 | + if (self->aq_nic_cfg->wol) |
|---|
| 409 | + err = aq_fw2x_set_wol(self, mac); |
|---|
| 410 | + |
|---|
| 411 | + return err; |
|---|
| 412 | +} |
|---|
| 413 | + |
|---|
| 414 | +static int aq_fw2x_send_fw_request(struct aq_hw_s *self, |
|---|
| 415 | + const struct hw_fw_request_iface *fw_req, |
|---|
| 416 | + size_t size) |
|---|
| 417 | +{ |
|---|
| 418 | + u32 ctrl2, orig_ctrl2; |
|---|
| 419 | + u32 dword_cnt; |
|---|
| 420 | + int err = 0; |
|---|
| 421 | + u32 val; |
|---|
| 422 | + |
|---|
| 423 | + /* Write data to drvIface Mailbox */ |
|---|
| 424 | + dword_cnt = size / sizeof(u32); |
|---|
| 425 | + if (size % sizeof(u32)) |
|---|
| 426 | + dword_cnt++; |
|---|
| 427 | + err = hw_atl_write_fwcfg_dwords(self, (void *)fw_req, dword_cnt); |
|---|
| 428 | + if (err < 0) |
|---|
| 429 | + goto err_exit; |
|---|
| 430 | + |
|---|
| 431 | + /* Toggle statistics bit for FW to update */ |
|---|
| 432 | + ctrl2 = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); |
|---|
| 433 | + orig_ctrl2 = ctrl2 & BIT(CAPS_HI_FW_REQUEST); |
|---|
| 434 | + ctrl2 = ctrl2 ^ BIT(CAPS_HI_FW_REQUEST); |
|---|
| 435 | + aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, ctrl2); |
|---|
| 436 | + |
|---|
| 437 | + /* Wait FW to report back */ |
|---|
| 438 | + err = readx_poll_timeout_atomic(aq_fw2x_state2_get, self, val, |
|---|
| 439 | + orig_ctrl2 != (val & |
|---|
| 440 | + BIT(CAPS_HI_FW_REQUEST)), |
|---|
| 441 | + 1U, 10000U); |
|---|
| 442 | + |
|---|
| 443 | +err_exit: |
|---|
| 444 | + return err; |
|---|
| 445 | +} |
|---|
| 446 | + |
|---|
| 447 | +static void aq_fw3x_enable_ptp(struct aq_hw_s *self, int enable) |
|---|
| 448 | +{ |
|---|
| 449 | + u32 ptp_opts = aq_hw_read_reg(self, HW_ATL_FW3X_EXT_STATE_ADDR); |
|---|
| 450 | + u32 all_ptp_features = BIT(CAPS_EX_PHY_PTP_EN) | |
|---|
| 451 | + BIT(CAPS_EX_PTP_GPIO_EN); |
|---|
| 452 | + |
|---|
| 453 | + if (enable) |
|---|
| 454 | + ptp_opts |= all_ptp_features; |
|---|
| 455 | + else |
|---|
| 456 | + ptp_opts &= ~all_ptp_features; |
|---|
| 457 | + |
|---|
| 458 | + aq_hw_write_reg(self, HW_ATL_FW3X_EXT_CONTROL_ADDR, ptp_opts); |
|---|
| 459 | +} |
|---|
| 460 | + |
|---|
| 461 | +static void aq_fw3x_adjust_ptp(struct aq_hw_s *self, uint64_t adj) |
|---|
| 462 | +{ |
|---|
| 463 | + aq_hw_write_reg(self, HW_ATL_FW3X_PTP_ADJ_LSW_ADDR, |
|---|
| 464 | + (adj >> 0) & 0xffffffff); |
|---|
| 465 | + aq_hw_write_reg(self, HW_ATL_FW3X_PTP_ADJ_MSW_ADDR, |
|---|
| 466 | + (adj >> 32) & 0xffffffff); |
|---|
| 467 | +} |
|---|
| 468 | + |
|---|
| 469 | +static int aq_fw2x_led_control(struct aq_hw_s *self, u32 mode) |
|---|
| 470 | +{ |
|---|
| 471 | + if (self->fw_ver_actual < HW_ATL_FW_VER_LED) |
|---|
| 472 | + return -EOPNOTSUPP; |
|---|
| 473 | + |
|---|
| 474 | + aq_hw_write_reg(self, HW_ATL_FW2X_MPI_LED_ADDR, mode); |
|---|
| 475 | + |
|---|
| 476 | + return 0; |
|---|
| 477 | +} |
|---|
| 478 | + |
|---|
| 479 | +static int aq_fw2x_set_eee_rate(struct aq_hw_s *self, u32 speed) |
|---|
| 480 | +{ |
|---|
| 481 | + u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); |
|---|
| 482 | + |
|---|
| 483 | + aq_fw2x_upd_eee_rate_bits(self, &mpi_opts, speed); |
|---|
| 484 | + |
|---|
| 485 | + aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts); |
|---|
| 486 | + |
|---|
| 487 | + return 0; |
|---|
| 488 | +} |
|---|
| 489 | + |
|---|
| 490 | +static int aq_fw2x_get_eee_rate(struct aq_hw_s *self, u32 *rate, |
|---|
| 491 | + u32 *supported_rates) |
|---|
| 492 | +{ |
|---|
| 493 | + u32 mpi_state; |
|---|
| 494 | + u32 caps_hi; |
|---|
| 495 | + int err = 0; |
|---|
| 496 | + u32 offset; |
|---|
| 497 | + |
|---|
| 498 | + offset = self->mbox_addr + offsetof(struct hw_atl_utils_mbox, |
|---|
| 499 | + info.caps_hi); |
|---|
| 500 | + |
|---|
| 501 | + err = hw_atl_utils_fw_downld_dwords(self, offset, &caps_hi, 1); |
|---|
| 502 | + |
|---|
| 503 | + if (err) |
|---|
| 504 | + return err; |
|---|
| 505 | + |
|---|
| 506 | + *supported_rates = fw2x_to_eee_mask(caps_hi); |
|---|
| 507 | + |
|---|
| 508 | + mpi_state = aq_fw2x_state2_get(self); |
|---|
| 509 | + *rate = fw2x_to_eee_mask(mpi_state); |
|---|
| 510 | + |
|---|
| 511 | + return err; |
|---|
| 221 | 512 | } |
|---|
| 222 | 513 | |
|---|
| 223 | 514 | static int aq_fw2x_renegotiate(struct aq_hw_s *self) |
|---|
| .. | .. |
|---|
| 235 | 526 | { |
|---|
| 236 | 527 | u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); |
|---|
| 237 | 528 | |
|---|
| 238 | | - aq_fw2x_set_mpi_flow_control(self, &mpi_state); |
|---|
| 529 | + aq_fw2x_upd_flow_control_bits(self, &mpi_state, |
|---|
| 530 | + self->aq_nic_cfg->fc.req); |
|---|
| 239 | 531 | |
|---|
| 240 | 532 | aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_state); |
|---|
| 241 | 533 | |
|---|
| 242 | 534 | return 0; |
|---|
| 243 | 535 | } |
|---|
| 244 | 536 | |
|---|
| 537 | +static u32 aq_fw2x_get_flow_control(struct aq_hw_s *self, u32 *fcmode) |
|---|
| 538 | +{ |
|---|
| 539 | + u32 mpi_state = aq_fw2x_state2_get(self); |
|---|
| 540 | + *fcmode = 0; |
|---|
| 541 | + |
|---|
| 542 | + if (mpi_state & HW_ATL_FW2X_CAP_PAUSE) |
|---|
| 543 | + *fcmode |= AQ_NIC_FC_RX; |
|---|
| 544 | + |
|---|
| 545 | + if (mpi_state & HW_ATL_FW2X_CAP_ASYM_PAUSE) |
|---|
| 546 | + *fcmode |= AQ_NIC_FC_TX; |
|---|
| 547 | + |
|---|
| 548 | + return 0; |
|---|
| 549 | +} |
|---|
| 550 | + |
|---|
| 551 | +static int aq_fw2x_set_phyloopback(struct aq_hw_s *self, u32 mode, bool enable) |
|---|
| 552 | +{ |
|---|
| 553 | + u32 mpi_opts; |
|---|
| 554 | + |
|---|
| 555 | + switch (mode) { |
|---|
| 556 | + case AQ_HW_LOOPBACK_PHYINT_SYS: |
|---|
| 557 | + mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); |
|---|
| 558 | + if (enable) |
|---|
| 559 | + mpi_opts |= HW_ATL_FW2X_CTRL_INT_LOOPBACK; |
|---|
| 560 | + else |
|---|
| 561 | + mpi_opts &= ~HW_ATL_FW2X_CTRL_INT_LOOPBACK; |
|---|
| 562 | + aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts); |
|---|
| 563 | + break; |
|---|
| 564 | + case AQ_HW_LOOPBACK_PHYEXT_SYS: |
|---|
| 565 | + mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); |
|---|
| 566 | + if (enable) |
|---|
| 567 | + mpi_opts |= HW_ATL_FW2X_CTRL_EXT_LOOPBACK; |
|---|
| 568 | + else |
|---|
| 569 | + mpi_opts &= ~HW_ATL_FW2X_CTRL_EXT_LOOPBACK; |
|---|
| 570 | + aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts); |
|---|
| 571 | + break; |
|---|
| 572 | + default: |
|---|
| 573 | + return -EINVAL; |
|---|
| 574 | + } |
|---|
| 575 | + |
|---|
| 576 | + return 0; |
|---|
| 577 | +} |
|---|
| 578 | + |
|---|
| 579 | +static u32 aq_fw2x_mbox_get(struct aq_hw_s *self) |
|---|
| 580 | +{ |
|---|
| 581 | + return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_MBOX_ADDR); |
|---|
| 582 | +} |
|---|
| 583 | + |
|---|
| 584 | +static u32 aq_fw2x_rpc_get(struct aq_hw_s *self) |
|---|
| 585 | +{ |
|---|
| 586 | + return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_RPC_ADDR); |
|---|
| 587 | +} |
|---|
| 588 | + |
|---|
| 589 | +static int aq_fw2x_settings_get(struct aq_hw_s *self, u32 *addr) |
|---|
| 590 | +{ |
|---|
| 591 | + int err = 0; |
|---|
| 592 | + u32 offset; |
|---|
| 593 | + |
|---|
| 594 | + offset = self->mbox_addr + offsetof(struct hw_atl_utils_mbox, |
|---|
| 595 | + info.setting_address); |
|---|
| 596 | + |
|---|
| 597 | + err = hw_atl_utils_fw_downld_dwords(self, offset, addr, 1); |
|---|
| 598 | + |
|---|
| 599 | + return err; |
|---|
| 600 | +} |
|---|
| 601 | + |
|---|
| 602 | +static u32 aq_fw2x_state_get(struct aq_hw_s *self) |
|---|
| 603 | +{ |
|---|
| 604 | + return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR); |
|---|
| 605 | +} |
|---|
| 606 | + |
|---|
| 607 | +static u32 aq_fw2x_state2_get(struct aq_hw_s *self) |
|---|
| 608 | +{ |
|---|
| 609 | + return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR); |
|---|
| 610 | +} |
|---|
| 611 | + |
|---|
| 612 | +static int aq_fw2x_set_downshift(struct aq_hw_s *self, u32 counter) |
|---|
| 613 | +{ |
|---|
| 614 | + int err = 0; |
|---|
| 615 | + u32 mpi_opts; |
|---|
| 616 | + u32 offset; |
|---|
| 617 | + |
|---|
| 618 | + offset = offsetof(struct hw_atl_utils_settings, downshift_retry_count); |
|---|
| 619 | + err = hw_atl_write_fwsettings_dwords(self, offset, &counter, 1); |
|---|
| 620 | + if (err) |
|---|
| 621 | + return err; |
|---|
| 622 | + |
|---|
| 623 | + mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); |
|---|
| 624 | + if (counter) |
|---|
| 625 | + mpi_opts |= HW_ATL_FW2X_CTRL_DOWNSHIFT; |
|---|
| 626 | + else |
|---|
| 627 | + mpi_opts &= ~HW_ATL_FW2X_CTRL_DOWNSHIFT; |
|---|
| 628 | + aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts); |
|---|
| 629 | + |
|---|
| 630 | + return err; |
|---|
| 631 | +} |
|---|
| 632 | + |
|---|
| 633 | +static int aq_fw2x_set_media_detect(struct aq_hw_s *self, bool on) |
|---|
| 634 | +{ |
|---|
| 635 | + u32 enable; |
|---|
| 636 | + u32 offset; |
|---|
| 637 | + |
|---|
| 638 | + if (self->fw_ver_actual < HW_ATL_FW_VER_MEDIA_CONTROL) |
|---|
| 639 | + return -EOPNOTSUPP; |
|---|
| 640 | + |
|---|
| 641 | + offset = offsetof(struct hw_atl_utils_settings, media_detect); |
|---|
| 642 | + enable = on; |
|---|
| 643 | + |
|---|
| 644 | + return hw_atl_write_fwsettings_dwords(self, offset, &enable, 1); |
|---|
| 645 | +} |
|---|
| 646 | + |
|---|
| 647 | +static u32 aq_fw2x_get_link_capabilities(struct aq_hw_s *self) |
|---|
| 648 | +{ |
|---|
| 649 | + int err = 0; |
|---|
| 650 | + u32 offset; |
|---|
| 651 | + u32 val; |
|---|
| 652 | + |
|---|
| 653 | + offset = self->mbox_addr + |
|---|
| 654 | + offsetof(struct hw_atl_utils_mbox, info.caps_lo); |
|---|
| 655 | + |
|---|
| 656 | + err = hw_atl_utils_fw_downld_dwords(self, offset, &val, 1); |
|---|
| 657 | + |
|---|
| 658 | + if (err) |
|---|
| 659 | + return 0; |
|---|
| 660 | + |
|---|
| 661 | + return val; |
|---|
| 662 | +} |
|---|
| 663 | + |
|---|
| 664 | +static int aq_fw2x_send_macsec_req(struct aq_hw_s *hw, |
|---|
| 665 | + struct macsec_msg_fw_request *req, |
|---|
| 666 | + struct macsec_msg_fw_response *response) |
|---|
| 667 | +{ |
|---|
| 668 | + u32 low_status, low_req = 0; |
|---|
| 669 | + u32 dword_cnt; |
|---|
| 670 | + u32 caps_lo; |
|---|
| 671 | + u32 offset; |
|---|
| 672 | + int err; |
|---|
| 673 | + |
|---|
| 674 | + if (!req || !response) |
|---|
| 675 | + return -EINVAL; |
|---|
| 676 | + |
|---|
| 677 | + caps_lo = aq_fw2x_get_link_capabilities(hw); |
|---|
| 678 | + if (!(caps_lo & BIT(CAPS_LO_MACSEC))) |
|---|
| 679 | + return -EOPNOTSUPP; |
|---|
| 680 | + |
|---|
| 681 | + /* Write macsec request to cfg memory */ |
|---|
| 682 | + dword_cnt = (sizeof(*req) + sizeof(u32) - 1) / sizeof(u32); |
|---|
| 683 | + err = hw_atl_write_fwcfg_dwords(hw, (void *)req, dword_cnt); |
|---|
| 684 | + if (err < 0) |
|---|
| 685 | + return err; |
|---|
| 686 | + |
|---|
| 687 | + /* Toggle 0x368.CAPS_LO_MACSEC bit */ |
|---|
| 688 | + low_req = aq_hw_read_reg(hw, HW_ATL_FW2X_MPI_CONTROL_ADDR); |
|---|
| 689 | + low_req ^= HW_ATL_FW2X_CAP_MACSEC; |
|---|
| 690 | + aq_hw_write_reg(hw, HW_ATL_FW2X_MPI_CONTROL_ADDR, low_req); |
|---|
| 691 | + |
|---|
| 692 | + /* Wait FW to report back */ |
|---|
| 693 | + err = readx_poll_timeout_atomic(aq_fw2x_state_get, hw, low_status, |
|---|
| 694 | + low_req != (low_status & BIT(CAPS_LO_MACSEC)), 1U, 10000U); |
|---|
| 695 | + if (err) |
|---|
| 696 | + return -EIO; |
|---|
| 697 | + |
|---|
| 698 | + /* Read status of write operation */ |
|---|
| 699 | + offset = hw->rpc_addr + sizeof(u32); |
|---|
| 700 | + err = hw_atl_utils_fw_downld_dwords(hw, offset, (u32 *)(void *)response, |
|---|
| 701 | + sizeof(*response) / sizeof(u32)); |
|---|
| 702 | + |
|---|
| 703 | + return err; |
|---|
| 704 | +} |
|---|
| 705 | + |
|---|
| 245 | 706 | const struct aq_fw_ops aq_fw_2x_ops = { |
|---|
| 246 | | - .init = aq_fw2x_init, |
|---|
| 247 | | - .deinit = aq_fw2x_deinit, |
|---|
| 248 | | - .reset = NULL, |
|---|
| 249 | | - .renegotiate = aq_fw2x_renegotiate, |
|---|
| 250 | | - .get_mac_permanent = aq_fw2x_get_mac_permanent, |
|---|
| 251 | | - .set_link_speed = aq_fw2x_set_link_speed, |
|---|
| 252 | | - .set_state = aq_fw2x_set_state, |
|---|
| 707 | + .init = aq_fw2x_init, |
|---|
| 708 | + .deinit = aq_fw2x_deinit, |
|---|
| 709 | + .reset = NULL, |
|---|
| 710 | + .renegotiate = aq_fw2x_renegotiate, |
|---|
| 711 | + .get_mac_permanent = aq_fw2x_get_mac_permanent, |
|---|
| 712 | + .set_link_speed = aq_fw2x_set_link_speed, |
|---|
| 713 | + .set_state = aq_fw2x_set_state, |
|---|
| 253 | 714 | .update_link_status = aq_fw2x_update_link_status, |
|---|
| 254 | | - .update_stats = aq_fw2x_update_stats, |
|---|
| 715 | + .update_stats = aq_fw2x_update_stats, |
|---|
| 716 | + .get_mac_temp = NULL, |
|---|
| 717 | + .get_phy_temp = aq_fw2x_get_phy_temp, |
|---|
| 718 | + .set_power = aq_fw2x_set_power, |
|---|
| 719 | + .set_eee_rate = aq_fw2x_set_eee_rate, |
|---|
| 720 | + .get_eee_rate = aq_fw2x_get_eee_rate, |
|---|
| 255 | 721 | .set_flow_control = aq_fw2x_set_flow_control, |
|---|
| 722 | + .get_flow_control = aq_fw2x_get_flow_control, |
|---|
| 723 | + .send_fw_request = aq_fw2x_send_fw_request, |
|---|
| 724 | + .enable_ptp = aq_fw3x_enable_ptp, |
|---|
| 725 | + .led_control = aq_fw2x_led_control, |
|---|
| 726 | + .set_phyloopback = aq_fw2x_set_phyloopback, |
|---|
| 727 | + .set_downshift = aq_fw2x_set_downshift, |
|---|
| 728 | + .set_media_detect = aq_fw2x_set_media_detect, |
|---|
| 729 | + .adjust_ptp = aq_fw3x_adjust_ptp, |
|---|
| 730 | + .get_link_capabilities = aq_fw2x_get_link_capabilities, |
|---|
| 731 | + .send_macsec_req = aq_fw2x_send_macsec_req, |
|---|
| 256 | 732 | }; |
|---|