1 /* 2 * aQuantia Corporation Network Driver 3 * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved 4 * 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. 8 */ 9 10 /* File hw_atl_utils_fw2x.c: Definition of firmware 2.x functions for 11 * Atlantic hardware abstraction layer. 12 */ 13 14 #include "../aq_hw.h" 15 #include "../aq_hw_utils.h" 16 #include "../aq_pci_func.h" 17 #include "../aq_ring.h" 18 #include "../aq_vec.h" 19 #include "../aq_nic.h" 20 #include "hw_atl_utils.h" 21 #include "hw_atl_llh.h" 22 23 #define HW_ATL_FW2X_MPI_RPC_ADDR 0x334 24 25 #define HW_ATL_FW2X_MPI_MBOX_ADDR 0x360 26 #define HW_ATL_FW2X_MPI_EFUSE_ADDR 0x364 27 #define HW_ATL_FW2X_MPI_CONTROL_ADDR 0x368 28 #define HW_ATL_FW2X_MPI_CONTROL2_ADDR 0x36C 29 #define HW_ATL_FW2X_MPI_STATE_ADDR 0x370 30 #define HW_ATL_FW2X_MPI_STATE2_ADDR 0x374 31 32 #define HW_ATL_FW2X_CAP_PAUSE BIT(CAPS_HI_PAUSE) 33 #define HW_ATL_FW2X_CAP_ASYM_PAUSE BIT(CAPS_HI_ASYMMETRIC_PAUSE) 34 #define HW_ATL_FW2X_CAP_SLEEP_PROXY BIT(CAPS_HI_SLEEP_PROXY) 35 #define HW_ATL_FW2X_CAP_WOL BIT(CAPS_HI_WOL) 36 37 #define HW_ATL_FW2X_CTRL_SLEEP_PROXY BIT(CTRL_SLEEP_PROXY) 38 #define HW_ATL_FW2X_CTRL_WOL BIT(CTRL_WOL) 39 #define HW_ATL_FW2X_CTRL_LINK_DROP BIT(CTRL_LINK_DROP) 40 #define HW_ATL_FW2X_CTRL_PAUSE BIT(CTRL_PAUSE) 41 #define HW_ATL_FW2X_CTRL_ASYMMETRIC_PAUSE BIT(CTRL_ASYMMETRIC_PAUSE) 42 #define HW_ATL_FW2X_CTRL_FORCE_RECONNECT BIT(CTRL_FORCE_RECONNECT) 43 44 #define HW_ATL_FW2X_CAP_EEE_1G_MASK BIT(CAPS_HI_1000BASET_FD_EEE) 45 #define HW_ATL_FW2X_CAP_EEE_2G5_MASK BIT(CAPS_HI_2P5GBASET_FD_EEE) 46 #define HW_ATL_FW2X_CAP_EEE_5G_MASK BIT(CAPS_HI_5GBASET_FD_EEE) 47 #define HW_ATL_FW2X_CAP_EEE_10G_MASK BIT(CAPS_HI_10GBASET_FD_EEE) 48 49 #define HAL_ATLANTIC_WOL_FILTERS_COUNT 8 50 #define HAL_ATLANTIC_UTILS_FW2X_MSG_WOL 0x0E 51 52 struct __packed fw2x_msg_wol_pattern { 53 u8 mask[16]; 54 u32 crc; 55 }; 56 57 struct __packed fw2x_msg_wol { 58 u32 msg_id; 59 u8 hw_addr[ETH_ALEN]; 60 u8 magic_packet_enabled; 61 u8 filter_count; 62 struct fw2x_msg_wol_pattern filter[HAL_ATLANTIC_WOL_FILTERS_COUNT]; 63 u8 link_up_enabled; 64 u8 link_down_enabled; 65 u16 reserved; 66 u32 link_up_timeout; 67 u32 link_down_timeout; 68 }; 69 70 static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed); 71 static int aq_fw2x_set_state(struct aq_hw_s *self, 72 enum hal_atl_utils_fw_state_e state); 73 74 static u32 aq_fw2x_mbox_get(struct aq_hw_s *self); 75 static u32 aq_fw2x_rpc_get(struct aq_hw_s *self); 76 static u32 aq_fw2x_state2_get(struct aq_hw_s *self); 77 78 static int aq_fw2x_init(struct aq_hw_s *self) 79 { 80 int err = 0; 81 82 /* check 10 times by 1ms */ 83 err = readx_poll_timeout_atomic(aq_fw2x_mbox_get, 84 self, self->mbox_addr, 85 self->mbox_addr != 0U, 86 1000U, 10000U); 87 88 err = readx_poll_timeout_atomic(aq_fw2x_rpc_get, 89 self, self->rpc_addr, 90 self->rpc_addr != 0U, 91 1000U, 100000U); 92 93 return err; 94 } 95 96 static int aq_fw2x_deinit(struct aq_hw_s *self) 97 { 98 int err = aq_fw2x_set_link_speed(self, 0); 99 100 if (!err) 101 err = aq_fw2x_set_state(self, MPI_DEINIT); 102 103 return err; 104 } 105 106 static enum hw_atl_fw2x_rate link_speed_mask_2fw2x_ratemask(u32 speed) 107 { 108 enum hw_atl_fw2x_rate rate = 0; 109 110 if (speed & AQ_NIC_RATE_10G) 111 rate |= FW2X_RATE_10G; 112 113 if (speed & AQ_NIC_RATE_5G) 114 rate |= FW2X_RATE_5G; 115 116 if (speed & AQ_NIC_RATE_5GSR) 117 rate |= FW2X_RATE_5G; 118 119 if (speed & AQ_NIC_RATE_2GS) 120 rate |= FW2X_RATE_2G5; 121 122 if (speed & AQ_NIC_RATE_1G) 123 rate |= FW2X_RATE_1G; 124 125 if (speed & AQ_NIC_RATE_100M) 126 rate |= FW2X_RATE_100M; 127 128 return rate; 129 } 130 131 static u32 fw2x_to_eee_mask(u32 speed) 132 { 133 u32 rate = 0; 134 135 if (speed & HW_ATL_FW2X_CAP_EEE_10G_MASK) 136 rate |= AQ_NIC_RATE_EEE_10G; 137 if (speed & HW_ATL_FW2X_CAP_EEE_5G_MASK) 138 rate |= AQ_NIC_RATE_EEE_5G; 139 if (speed & HW_ATL_FW2X_CAP_EEE_2G5_MASK) 140 rate |= AQ_NIC_RATE_EEE_2GS; 141 if (speed & HW_ATL_FW2X_CAP_EEE_1G_MASK) 142 rate |= AQ_NIC_RATE_EEE_1G; 143 144 return rate; 145 } 146 147 static u32 eee_mask_to_fw2x(u32 speed) 148 { 149 u32 rate = 0; 150 151 if (speed & AQ_NIC_RATE_EEE_10G) 152 rate |= HW_ATL_FW2X_CAP_EEE_10G_MASK; 153 if (speed & AQ_NIC_RATE_EEE_5G) 154 rate |= HW_ATL_FW2X_CAP_EEE_5G_MASK; 155 if (speed & AQ_NIC_RATE_EEE_2GS) 156 rate |= HW_ATL_FW2X_CAP_EEE_2G5_MASK; 157 if (speed & AQ_NIC_RATE_EEE_1G) 158 rate |= HW_ATL_FW2X_CAP_EEE_1G_MASK; 159 160 return rate; 161 } 162 163 static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed) 164 { 165 u32 val = link_speed_mask_2fw2x_ratemask(speed); 166 167 aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR, val); 168 169 return 0; 170 } 171 172 static void aq_fw2x_set_mpi_flow_control(struct aq_hw_s *self, u32 *mpi_state) 173 { 174 if (self->aq_nic_cfg->flow_control & AQ_NIC_FC_RX) 175 *mpi_state |= BIT(CAPS_HI_PAUSE); 176 else 177 *mpi_state &= ~BIT(CAPS_HI_PAUSE); 178 179 if (self->aq_nic_cfg->flow_control & AQ_NIC_FC_TX) 180 *mpi_state |= BIT(CAPS_HI_ASYMMETRIC_PAUSE); 181 else 182 *mpi_state &= ~BIT(CAPS_HI_ASYMMETRIC_PAUSE); 183 } 184 185 static void aq_fw2x_upd_eee_rate_bits(struct aq_hw_s *self, u32 *mpi_opts, 186 u32 eee_speeds) 187 { 188 *mpi_opts &= ~(HW_ATL_FW2X_CAP_EEE_1G_MASK | 189 HW_ATL_FW2X_CAP_EEE_2G5_MASK | 190 HW_ATL_FW2X_CAP_EEE_5G_MASK | 191 HW_ATL_FW2X_CAP_EEE_10G_MASK); 192 193 *mpi_opts |= eee_mask_to_fw2x(eee_speeds); 194 } 195 196 static int aq_fw2x_set_state(struct aq_hw_s *self, 197 enum hal_atl_utils_fw_state_e state) 198 { 199 u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); 200 struct aq_nic_cfg_s *cfg = self->aq_nic_cfg; 201 202 switch (state) { 203 case MPI_INIT: 204 mpi_state &= ~BIT(CAPS_HI_LINK_DROP); 205 aq_fw2x_upd_eee_rate_bits(self, &mpi_state, cfg->eee_speeds); 206 aq_fw2x_set_mpi_flow_control(self, &mpi_state); 207 break; 208 case MPI_DEINIT: 209 mpi_state |= BIT(CAPS_HI_LINK_DROP); 210 break; 211 case MPI_RESET: 212 case MPI_POWER: 213 /* No actions */ 214 break; 215 } 216 aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_state); 217 return 0; 218 } 219 220 static int aq_fw2x_update_link_status(struct aq_hw_s *self) 221 { 222 u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR); 223 u32 speed = mpi_state & (FW2X_RATE_100M | FW2X_RATE_1G | 224 FW2X_RATE_2G5 | FW2X_RATE_5G | FW2X_RATE_10G); 225 struct aq_hw_link_status_s *link_status = &self->aq_link_status; 226 227 if (speed) { 228 if (speed & FW2X_RATE_10G) 229 link_status->mbps = 10000; 230 else if (speed & FW2X_RATE_5G) 231 link_status->mbps = 5000; 232 else if (speed & FW2X_RATE_2G5) 233 link_status->mbps = 2500; 234 else if (speed & FW2X_RATE_1G) 235 link_status->mbps = 1000; 236 else if (speed & FW2X_RATE_100M) 237 link_status->mbps = 100; 238 else 239 link_status->mbps = 10000; 240 } else { 241 link_status->mbps = 0; 242 } 243 244 return 0; 245 } 246 247 static int aq_fw2x_get_mac_permanent(struct aq_hw_s *self, u8 *mac) 248 { 249 int err = 0; 250 u32 h = 0U; 251 u32 l = 0U; 252 u32 mac_addr[2] = { 0 }; 253 u32 efuse_addr = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_EFUSE_ADDR); 254 255 if (efuse_addr != 0) { 256 err = hw_atl_utils_fw_downld_dwords(self, 257 efuse_addr + (40U * 4U), 258 mac_addr, 259 ARRAY_SIZE(mac_addr)); 260 if (err) 261 return err; 262 mac_addr[0] = __swab32(mac_addr[0]); 263 mac_addr[1] = __swab32(mac_addr[1]); 264 } 265 266 ether_addr_copy(mac, (u8 *)mac_addr); 267 268 if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) { 269 unsigned int rnd = 0; 270 271 get_random_bytes(&rnd, sizeof(unsigned int)); 272 273 l = 0xE3000000U | (0xFFFFU & rnd) | (0x00 << 16); 274 h = 0x8001300EU; 275 276 mac[5] = (u8)(0xFFU & l); 277 l >>= 8; 278 mac[4] = (u8)(0xFFU & l); 279 l >>= 8; 280 mac[3] = (u8)(0xFFU & l); 281 l >>= 8; 282 mac[2] = (u8)(0xFFU & l); 283 mac[1] = (u8)(0xFFU & h); 284 h >>= 8; 285 mac[0] = (u8)(0xFFU & h); 286 } 287 return err; 288 } 289 290 static int aq_fw2x_update_stats(struct aq_hw_s *self) 291 { 292 int err = 0; 293 u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); 294 u32 orig_stats_val = mpi_opts & BIT(CAPS_HI_STATISTICS); 295 u32 stats_val; 296 297 /* Toggle statistics bit for FW to update */ 298 mpi_opts = mpi_opts ^ BIT(CAPS_HI_STATISTICS); 299 aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts); 300 301 /* Wait FW to report back */ 302 err = readx_poll_timeout_atomic(aq_fw2x_state2_get, 303 self, stats_val, 304 orig_stats_val != (stats_val & 305 BIT(CAPS_HI_STATISTICS)), 306 1U, 10000U); 307 if (err) 308 return err; 309 310 return hw_atl_utils_update_stats(self); 311 } 312 313 static int aq_fw2x_set_sleep_proxy(struct aq_hw_s *self, u8 *mac) 314 { 315 struct hw_atl_utils_fw_rpc *rpc = NULL; 316 struct offload_info *cfg = NULL; 317 unsigned int rpc_size = 0U; 318 u32 mpi_opts; 319 int err = 0; 320 u32 val; 321 322 rpc_size = sizeof(rpc->msg_id) + sizeof(*cfg); 323 324 err = hw_atl_utils_fw_rpc_wait(self, &rpc); 325 if (err < 0) 326 goto err_exit; 327 328 memset(rpc, 0, rpc_size); 329 cfg = (struct offload_info *)(&rpc->msg_id + 1); 330 331 memcpy(cfg->mac_addr, mac, ETH_ALEN); 332 cfg->len = sizeof(*cfg); 333 334 /* Clear bit 0x36C.23 and 0x36C.22 */ 335 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); 336 mpi_opts &= ~HW_ATL_FW2X_CTRL_SLEEP_PROXY; 337 mpi_opts &= ~HW_ATL_FW2X_CTRL_LINK_DROP; 338 339 aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts); 340 341 err = hw_atl_utils_fw_rpc_call(self, rpc_size); 342 if (err < 0) 343 goto err_exit; 344 345 /* Set bit 0x36C.23 */ 346 mpi_opts |= HW_ATL_FW2X_CTRL_SLEEP_PROXY; 347 aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts); 348 349 err = readx_poll_timeout_atomic(aq_fw2x_state2_get, 350 self, val, 351 val & HW_ATL_FW2X_CTRL_SLEEP_PROXY, 352 1U, 10000U); 353 354 err_exit: 355 return err; 356 } 357 358 static int aq_fw2x_set_wol_params(struct aq_hw_s *self, u8 *mac) 359 { 360 struct hw_atl_utils_fw_rpc *rpc = NULL; 361 struct fw2x_msg_wol *msg = NULL; 362 u32 mpi_opts; 363 int err = 0; 364 u32 val; 365 366 err = hw_atl_utils_fw_rpc_wait(self, &rpc); 367 if (err < 0) 368 goto err_exit; 369 370 msg = (struct fw2x_msg_wol *)rpc; 371 372 msg->msg_id = HAL_ATLANTIC_UTILS_FW2X_MSG_WOL; 373 msg->magic_packet_enabled = true; 374 memcpy(msg->hw_addr, mac, ETH_ALEN); 375 376 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); 377 mpi_opts &= ~(HW_ATL_FW2X_CTRL_SLEEP_PROXY | HW_ATL_FW2X_CTRL_WOL); 378 379 aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts); 380 381 err = hw_atl_utils_fw_rpc_call(self, sizeof(*msg)); 382 if (err < 0) 383 goto err_exit; 384 385 /* Set bit 0x36C.24 */ 386 mpi_opts |= HW_ATL_FW2X_CTRL_WOL; 387 aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts); 388 389 err = readx_poll_timeout_atomic(aq_fw2x_state2_get, 390 self, val, val & HW_ATL_FW2X_CTRL_WOL, 391 1U, 10000U); 392 393 err_exit: 394 return err; 395 } 396 397 static int aq_fw2x_set_power(struct aq_hw_s *self, unsigned int power_state, 398 u8 *mac) 399 { 400 int err = 0; 401 402 if (self->aq_nic_cfg->wol & AQ_NIC_WOL_ENABLED) { 403 err = aq_fw2x_set_sleep_proxy(self, mac); 404 if (err < 0) 405 goto err_exit; 406 err = aq_fw2x_set_wol_params(self, mac); 407 } 408 409 err_exit: 410 return err; 411 } 412 413 static int aq_fw2x_set_eee_rate(struct aq_hw_s *self, u32 speed) 414 { 415 u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); 416 417 aq_fw2x_upd_eee_rate_bits(self, &mpi_opts, speed); 418 419 aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts); 420 421 return 0; 422 } 423 424 static int aq_fw2x_get_eee_rate(struct aq_hw_s *self, u32 *rate, 425 u32 *supported_rates) 426 { 427 u32 mpi_state; 428 u32 caps_hi; 429 int err = 0; 430 u32 addr = self->mbox_addr + offsetof(struct hw_atl_utils_mbox, info) + 431 offsetof(struct hw_aq_info, caps_hi); 432 433 err = hw_atl_utils_fw_downld_dwords(self, addr, &caps_hi, 434 sizeof(caps_hi) / sizeof(u32)); 435 436 if (err) 437 return err; 438 439 *supported_rates = fw2x_to_eee_mask(caps_hi); 440 441 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR); 442 *rate = fw2x_to_eee_mask(mpi_state); 443 444 return err; 445 } 446 447 static int aq_fw2x_renegotiate(struct aq_hw_s *self) 448 { 449 u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); 450 451 mpi_opts |= BIT(CTRL_FORCE_RECONNECT); 452 453 aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts); 454 455 return 0; 456 } 457 458 static int aq_fw2x_set_flow_control(struct aq_hw_s *self) 459 { 460 u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR); 461 462 aq_fw2x_set_mpi_flow_control(self, &mpi_state); 463 464 aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_state); 465 466 return 0; 467 } 468 469 static u32 aq_fw2x_get_flow_control(struct aq_hw_s *self, u32 *fcmode) 470 { 471 u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR); 472 473 if (mpi_state & HW_ATL_FW2X_CAP_PAUSE) 474 if (mpi_state & HW_ATL_FW2X_CAP_ASYM_PAUSE) 475 *fcmode = AQ_NIC_FC_RX; 476 else 477 *fcmode = AQ_NIC_FC_RX | AQ_NIC_FC_TX; 478 else 479 if (mpi_state & HW_ATL_FW2X_CAP_ASYM_PAUSE) 480 *fcmode = AQ_NIC_FC_TX; 481 else 482 *fcmode = 0; 483 484 return 0; 485 } 486 487 static u32 aq_fw2x_mbox_get(struct aq_hw_s *self) 488 { 489 return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_MBOX_ADDR); 490 } 491 492 static u32 aq_fw2x_rpc_get(struct aq_hw_s *self) 493 { 494 return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_RPC_ADDR); 495 } 496 497 static u32 aq_fw2x_state2_get(struct aq_hw_s *self) 498 { 499 return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR); 500 } 501 502 const struct aq_fw_ops aq_fw_2x_ops = { 503 .init = aq_fw2x_init, 504 .deinit = aq_fw2x_deinit, 505 .reset = NULL, 506 .renegotiate = aq_fw2x_renegotiate, 507 .get_mac_permanent = aq_fw2x_get_mac_permanent, 508 .set_link_speed = aq_fw2x_set_link_speed, 509 .set_state = aq_fw2x_set_state, 510 .update_link_status = aq_fw2x_update_link_status, 511 .update_stats = aq_fw2x_update_stats, 512 .set_power = aq_fw2x_set_power, 513 .set_eee_rate = aq_fw2x_set_eee_rate, 514 .get_eee_rate = aq_fw2x_get_eee_rate, 515 .set_flow_control = aq_fw2x_set_flow_control, 516 .get_flow_control = aq_fw2x_get_flow_control 517 }; 518