Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: txgbe: Add basic support for new AML devices

There is a new 40/25/10 Gigabit Ethernet device.

To support basic functions, PHYLINK is temporarily skipped as it is
intended to implement these configurations in the firmware. And the
associated link IRQ is also skipped.

And Implement the new SW-FW interaction interface, which use 64 Byte
message buffer.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
Link: https://patch.msgid.link/20250221065718.197544-1-jiawenwu@trustnetic.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Jiawen Wu and committed by
Jakub Kicinski
2e5af6b2 6538c8ca

+333 -54
+38 -6
drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
··· 219 219 { 220 220 struct wx *wx = netdev_priv(netdev); 221 221 222 + if (wx->mac.type == wx_mac_aml) 223 + return -EOPNOTSUPP; 224 + 222 225 return phylink_ethtool_nway_reset(wx->phylink); 223 226 } 224 227 EXPORT_SYMBOL(wx_nway_reset); ··· 230 227 struct ethtool_link_ksettings *cmd) 231 228 { 232 229 struct wx *wx = netdev_priv(netdev); 230 + 231 + if (wx->mac.type == wx_mac_aml) 232 + return -EOPNOTSUPP; 233 233 234 234 return phylink_ethtool_ksettings_get(wx->phylink, cmd); 235 235 } ··· 243 237 { 244 238 struct wx *wx = netdev_priv(netdev); 245 239 240 + if (wx->mac.type == wx_mac_aml) 241 + return -EOPNOTSUPP; 242 + 246 243 return phylink_ethtool_ksettings_set(wx->phylink, cmd); 247 244 } 248 245 EXPORT_SYMBOL(wx_set_link_ksettings); ··· 255 246 { 256 247 struct wx *wx = netdev_priv(netdev); 257 248 249 + if (wx->mac.type == wx_mac_aml) 250 + return; 251 + 258 252 phylink_ethtool_get_pauseparam(wx->phylink, pause); 259 253 } 260 254 EXPORT_SYMBOL(wx_get_pauseparam); ··· 266 254 struct ethtool_pauseparam *pause) 267 255 { 268 256 struct wx *wx = netdev_priv(netdev); 257 + 258 + if (wx->mac.type == wx_mac_aml) 259 + return -EOPNOTSUPP; 269 260 270 261 return phylink_ethtool_set_pauseparam(wx->phylink, pause); 271 262 } ··· 340 325 if (ec->tx_max_coalesced_frames_irq) 341 326 wx->tx_work_limit = ec->tx_max_coalesced_frames_irq; 342 327 343 - if (wx->mac.type == wx_mac_sp) 328 + switch (wx->mac.type) { 329 + case wx_mac_sp: 344 330 max_eitr = WX_SP_MAX_EITR; 345 - else 331 + break; 332 + case wx_mac_aml: 333 + max_eitr = WX_AML_MAX_EITR; 334 + break; 335 + default: 346 336 max_eitr = WX_EM_MAX_EITR; 337 + break; 338 + } 347 339 348 340 if ((ec->rx_coalesce_usecs > (max_eitr >> 2)) || 349 341 (ec->tx_coalesce_usecs > (max_eitr >> 2))) ··· 372 350 wx->tx_itr_setting = ec->tx_coalesce_usecs; 373 351 374 352 if (wx->tx_itr_setting == 1) { 375 - if (wx->mac.type == wx_mac_sp) 353 + switch (wx->mac.type) { 354 + case wx_mac_sp: 355 + case wx_mac_aml: 376 356 tx_itr_param = WX_12K_ITR; 377 - else 357 + break; 358 + default: 378 359 tx_itr_param = WX_20K_ITR; 360 + break; 361 + } 379 362 } else { 380 363 tx_itr_param = wx->tx_itr_setting; 381 364 } ··· 413 386 max_combined = 1; 414 387 } else { 415 388 /* support up to max allowed queues with RSS */ 416 - if (wx->mac.type == wx_mac_sp) 389 + switch (wx->mac.type) { 390 + case wx_mac_sp: 391 + case wx_mac_aml: 417 392 max_combined = 63; 418 - else 393 + break; 394 + default: 419 395 max_combined = 8; 396 + break; 397 + } 420 398 } 421 399 422 400 return max_combined;
+178 -35
drivers/net/ethernet/wangxun/libwx/wx_hw.c
··· 112 112 if (mask) 113 113 wr32(wx, WX_PX_IMS(0), mask); 114 114 115 - if (wx->mac.type == wx_mac_sp) { 115 + switch (wx->mac.type) { 116 + case wx_mac_sp: 117 + case wx_mac_aml: 116 118 mask = (qmask >> 32); 117 119 if (mask) 118 120 wr32(wx, WX_PX_IMS(1), mask); 121 + break; 122 + default: 123 + break; 119 124 } 120 125 } 121 126 ··· 131 126 mask = (qmask & U32_MAX); 132 127 if (mask) 133 128 wr32(wx, WX_PX_IMC(0), mask); 134 - if (wx->mac.type == wx_mac_sp) { 129 + 130 + switch (wx->mac.type) { 131 + case wx_mac_sp: 132 + case wx_mac_aml: 135 133 mask = (qmask >> 32); 136 134 if (mask) 137 135 wr32(wx, WX_PX_IMC(1), mask); 136 + break; 137 + default: 138 + break; 138 139 } 139 140 } 140 141 EXPORT_SYMBOL(wx_intr_enable); ··· 289 278 return ret; 290 279 } 291 280 292 - /** 293 - * wx_host_interface_command - Issue command to manageability block 294 - * @wx: pointer to the HW structure 295 - * @buffer: contains the command to write and where the return status will 296 - * be placed 297 - * @length: length of buffer, must be multiple of 4 bytes 298 - * @timeout: time in ms to wait for command completion 299 - * @return_data: read and return data from the buffer (true) or not (false) 300 - * Needed because FW structures are big endian and decoding of 301 - * these fields can be 8 bit or 16 bit based on command. Decoding 302 - * is not easily understood without making a table of commands. 303 - * So we will leave this up to the caller to read back the data 304 - * in these cases. 305 - **/ 306 - int wx_host_interface_command(struct wx *wx, u32 *buffer, 307 - u32 length, u32 timeout, bool return_data) 281 + static int wx_host_interface_command_s(struct wx *wx, u32 *buffer, 282 + u32 length, u32 timeout, bool return_data) 308 283 { 309 284 u32 hdr_size = sizeof(struct wx_hic_hdr); 310 285 u32 hicr, i, bi, buf[64] = {}; ··· 298 301 u32 dword_len; 299 302 u16 buf_len; 300 303 301 - if (length == 0 || length > WX_HI_MAX_BLOCK_BYTE_LENGTH) { 302 - wx_err(wx, "Buffer length failure buffersize=%d.\n", length); 303 - return -EINVAL; 304 - } 305 - 306 304 status = wx_acquire_sw_sync(wx, WX_MNG_SWFW_SYNC_SW_MB); 307 305 if (status != 0) 308 306 return status; 309 - 310 - /* Calculate length in DWORDs. We must be DWORD aligned */ 311 - if ((length % (sizeof(u32))) != 0) { 312 - wx_err(wx, "Buffer length failure, not aligned to dword"); 313 - status = -EINVAL; 314 - goto rel_out; 315 - } 316 307 317 308 dword_len = length >> 2; 318 309 ··· 376 391 wx_release_sw_sync(wx, WX_MNG_SWFW_SYNC_SW_MB); 377 392 return status; 378 393 } 394 + 395 + static bool wx_poll_fw_reply(struct wx *wx, u32 *buffer, u8 send_cmd) 396 + { 397 + u32 dword_len = sizeof(struct wx_hic_hdr) >> 2; 398 + struct wx_hic_hdr *recv_hdr; 399 + u32 i; 400 + 401 + /* read hdr */ 402 + for (i = 0; i < dword_len; i++) { 403 + buffer[i] = rd32a(wx, WX_FW2SW_MBOX, i); 404 + le32_to_cpus(&buffer[i]); 405 + } 406 + 407 + /* check hdr */ 408 + recv_hdr = (struct wx_hic_hdr *)buffer; 409 + if (recv_hdr->cmd == send_cmd && 410 + recv_hdr->index == wx->swfw_index) 411 + return true; 412 + 413 + return false; 414 + } 415 + 416 + static int wx_host_interface_command_r(struct wx *wx, u32 *buffer, 417 + u32 length, u32 timeout, bool return_data) 418 + { 419 + struct wx_hic_hdr *hdr = (struct wx_hic_hdr *)buffer; 420 + u32 hdr_size = sizeof(struct wx_hic_hdr); 421 + bool busy, reply; 422 + u32 dword_len; 423 + u16 buf_len; 424 + int err = 0; 425 + u8 send_cmd; 426 + u32 i; 427 + 428 + /* wait to get lock */ 429 + might_sleep(); 430 + err = read_poll_timeout(test_and_set_bit, busy, !busy, 1000, timeout * 1000, 431 + false, WX_STATE_SWFW_BUSY, wx->state); 432 + if (err) 433 + return err; 434 + 435 + /* index to unique seq id for each mbox message */ 436 + hdr->index = wx->swfw_index; 437 + send_cmd = hdr->cmd; 438 + 439 + dword_len = length >> 2; 440 + /* write data to SW-FW mbox array */ 441 + for (i = 0; i < dword_len; i++) { 442 + wr32a(wx, WX_SW2FW_MBOX, i, (__force u32)cpu_to_le32(buffer[i])); 443 + /* write flush */ 444 + rd32a(wx, WX_SW2FW_MBOX, i); 445 + } 446 + 447 + /* generate interrupt to notify FW */ 448 + wr32m(wx, WX_SW2FW_MBOX_CMD, WX_SW2FW_MBOX_CMD_VLD, 0); 449 + wr32m(wx, WX_SW2FW_MBOX_CMD, WX_SW2FW_MBOX_CMD_VLD, WX_SW2FW_MBOX_CMD_VLD); 450 + 451 + /* polling reply from FW */ 452 + err = read_poll_timeout(wx_poll_fw_reply, reply, reply, 1000, 50000, 453 + true, wx, buffer, send_cmd); 454 + if (err) { 455 + wx_err(wx, "Polling from FW messages timeout, cmd: 0x%x, index: %d\n", 456 + send_cmd, wx->swfw_index); 457 + goto rel_out; 458 + } 459 + 460 + /* expect no reply from FW then return */ 461 + if (!return_data) 462 + goto rel_out; 463 + 464 + /* If there is any thing in data position pull it in */ 465 + buf_len = hdr->buf_len; 466 + if (buf_len == 0) 467 + goto rel_out; 468 + 469 + if (length < buf_len + hdr_size) { 470 + wx_err(wx, "Buffer not large enough for reply message.\n"); 471 + err = -EFAULT; 472 + goto rel_out; 473 + } 474 + 475 + /* Calculate length in DWORDs, add 3 for odd lengths */ 476 + dword_len = (buf_len + 3) >> 2; 477 + for (i = hdr_size >> 2; i <= dword_len; i++) { 478 + buffer[i] = rd32a(wx, WX_FW2SW_MBOX, i); 479 + le32_to_cpus(&buffer[i]); 480 + } 481 + 482 + rel_out: 483 + /* index++, index replace wx_hic_hdr.checksum */ 484 + if (wx->swfw_index == WX_HIC_HDR_INDEX_MAX) 485 + wx->swfw_index = 0; 486 + else 487 + wx->swfw_index++; 488 + 489 + clear_bit(WX_STATE_SWFW_BUSY, wx->state); 490 + return err; 491 + } 492 + 493 + /** 494 + * wx_host_interface_command - Issue command to manageability block 495 + * @wx: pointer to the HW structure 496 + * @buffer: contains the command to write and where the return status will 497 + * be placed 498 + * @length: length of buffer, must be multiple of 4 bytes 499 + * @timeout: time in ms to wait for command completion 500 + * @return_data: read and return data from the buffer (true) or not (false) 501 + * Needed because FW structures are big endian and decoding of 502 + * these fields can be 8 bit or 16 bit based on command. Decoding 503 + * is not easily understood without making a table of commands. 504 + * So we will leave this up to the caller to read back the data 505 + * in these cases. 506 + **/ 507 + int wx_host_interface_command(struct wx *wx, u32 *buffer, 508 + u32 length, u32 timeout, bool return_data) 509 + { 510 + if (length == 0 || length > WX_HI_MAX_BLOCK_BYTE_LENGTH) { 511 + wx_err(wx, "Buffer length failure buffersize=%d.\n", length); 512 + return -EINVAL; 513 + } 514 + 515 + /* Calculate length in DWORDs. We must be DWORD aligned */ 516 + if ((length % (sizeof(u32))) != 0) { 517 + wx_err(wx, "Buffer length failure, not aligned to dword"); 518 + return -EINVAL; 519 + } 520 + 521 + if (test_bit(WX_FLAG_SWFW_RING, wx->flags)) 522 + return wx_host_interface_command_r(wx, buffer, length, 523 + timeout, return_data); 524 + 525 + return wx_host_interface_command_s(wx, buffer, length, timeout, return_data); 526 + } 379 527 EXPORT_SYMBOL(wx_host_interface_command); 380 528 381 529 int wx_set_pps(struct wx *wx, bool enable, u64 nsec, u64 cycles) ··· 560 442 if (status != 0) 561 443 return status; 562 444 563 - *data = (u16)rd32a(wx, WX_MNG_MBOX, FW_NVM_DATA_OFFSET); 445 + if (!test_bit(WX_FLAG_SWFW_RING, wx->flags)) 446 + *data = (u16)rd32a(wx, WX_MNG_MBOX, FW_NVM_DATA_OFFSET); 447 + else 448 + *data = (u16)rd32a(wx, WX_FW2SW_MBOX, FW_NVM_DATA_OFFSET); 564 449 565 450 return status; 566 451 } ··· 607 486 u16 words_to_read; 608 487 u32 value = 0; 609 488 int status; 489 + u32 mbox; 610 490 u32 i; 611 491 612 492 /* Take semaphore for the entire operation. */ ··· 640 518 goto out; 641 519 } 642 520 521 + if (!test_bit(WX_FLAG_SWFW_RING, wx->flags)) 522 + mbox = WX_MNG_MBOX; 523 + else 524 + mbox = WX_FW2SW_MBOX; 643 525 for (i = 0; i < words_to_read; i++) { 644 - u32 reg = WX_MNG_MBOX + (FW_NVM_DATA_OFFSET << 2) + 2 * i; 526 + u32 reg = mbox + (FW_NVM_DATA_OFFSET << 2) + 2 * i; 645 527 646 528 value = rd32(wx, reg); 647 529 data[current_word] = (u16)(value & 0xffff); ··· 695 569 } 696 570 } 697 571 698 - if (wx->mac.type == wx_mac_sp) { 572 + switch (wx->mac.type) { 573 + case wx_mac_sp: 574 + case wx_mac_aml: 699 575 if (wx_read_ee_hostif(wx, WX_SW_REGION_PTR, &data)) { 700 576 wx_err(wx, "NVM Read Error\n"); 701 577 return; 702 578 } 703 579 data = data >> 1; 580 + break; 581 + default: 582 + break; 704 583 } 705 584 706 585 eeprom->sw_region_offset = data; ··· 766 635 767 636 /* setup VMDq pool mapping */ 768 637 wr32(wx, WX_PSR_MAC_SWC_VM_L, pools & 0xFFFFFFFF); 769 - if (wx->mac.type == wx_mac_sp) 638 + 639 + switch (wx->mac.type) { 640 + case wx_mac_sp: 641 + case wx_mac_aml: 770 642 wr32(wx, WX_PSR_MAC_SWC_VM_H, pools >> 32); 643 + break; 644 + default: 645 + break; 646 + } 771 647 772 648 /* HW expects these in little endian so we reverse the byte 773 649 * order from network order (big endian) to little endian ··· 912 774 913 775 wx_set_rar(wx, 0, wx->mac.addr, 0, WX_PSR_MAC_SWC_AD_H_AV); 914 776 915 - if (wx->mac.type == wx_mac_sp) { 777 + switch (wx->mac.type) { 778 + case wx_mac_sp: 779 + case wx_mac_aml: 916 780 /* clear VMDq pool/queue selection for RAR 0 */ 917 781 wx_clear_vmdq(wx, 0, WX_CLEAR_VMDQ_ALL); 782 + break; 783 + default: 784 + break; 918 785 } 919 786 } 920 787
+19 -6
drivers/net/ethernet/wangxun/libwx/wx_lib.c
··· 1823 1823 /* initialize pointer to rings */ 1824 1824 ring = q_vector->ring; 1825 1825 1826 - if (wx->mac.type == wx_mac_sp) 1826 + switch (wx->mac.type) { 1827 + case wx_mac_sp: 1828 + case wx_mac_aml: 1827 1829 default_itr = WX_12K_ITR; 1828 - else 1830 + break; 1831 + default: 1829 1832 default_itr = WX_7K_ITR; 1833 + break; 1834 + } 1835 + 1830 1836 /* initialize ITR */ 1831 1837 if (txr_count && !rxr_count) 1832 1838 /* tx only vector */ ··· 2188 2182 int v_idx = q_vector->v_idx; 2189 2183 u32 itr_reg; 2190 2184 2191 - if (wx->mac.type == wx_mac_sp) 2185 + switch (wx->mac.type) { 2186 + case wx_mac_sp: 2192 2187 itr_reg = q_vector->itr & WX_SP_MAX_EITR; 2193 - else 2188 + break; 2189 + case wx_mac_aml: 2190 + itr_reg = (q_vector->itr >> 3) & WX_AML_MAX_EITR; 2191 + break; 2192 + default: 2194 2193 itr_reg = q_vector->itr & WX_EM_MAX_EITR; 2194 + break; 2195 + } 2195 2196 2196 2197 itr_reg |= WX_PX_ITR_CNT_WDIS; 2197 2198 ··· 2774 2761 2775 2762 netdev->features = features; 2776 2763 2777 - if (wx->mac.type == wx_mac_sp && changed & NETIF_F_HW_VLAN_CTAG_RX) 2764 + if (changed & NETIF_F_HW_VLAN_CTAG_RX && wx->do_reset) 2778 2765 wx->do_reset(netdev); 2779 2766 else if (changed & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER)) 2780 2767 wx_set_rx_mode(netdev); ··· 2806 2793 break; 2807 2794 } 2808 2795 2809 - if (need_reset) 2796 + if (need_reset && wx->do_reset) 2810 2797 wx->do_reset(netdev); 2811 2798 2812 2799 return 0;
+24 -5
drivers/net/ethernet/wangxun/libwx/wx_type.h
··· 309 309 #define WX_MNG_MBOX_CTL_FWRDY BIT(2) 310 310 #define WX_MNG_BMC2OS_CNT 0x1E090 311 311 #define WX_MNG_OS2BMC_CNT 0x1E094 312 + #define WX_SW2FW_MBOX_CMD 0x1E0A0 313 + #define WX_SW2FW_MBOX_CMD_VLD BIT(31) 314 + #define WX_SW2FW_MBOX 0x1E200 315 + #define WX_FW2SW_MBOX 0x1E300 312 316 313 317 /************************************* ETH MAC *****************************/ 314 318 #define WX_MAC_TX_CFG 0x11000 ··· 376 372 #define WX_12K_ITR 336 377 373 #define WX_20K_ITR 200 378 374 #define WX_SP_MAX_EITR 0x00000FF8U 375 + #define WX_AML_MAX_EITR 0x00000FFFU 379 376 #define WX_EM_MAX_EITR 0x00007FFCU 380 377 381 378 /* transmit DMA Registers */ ··· 420 415 /****************** Manageablility Host Interface defines ********************/ 421 416 #define WX_HI_MAX_BLOCK_BYTE_LENGTH 256 /* Num of bytes in range */ 422 417 #define WX_HI_COMMAND_TIMEOUT 1000 /* Process HI command limit */ 418 + #define WX_HIC_HDR_INDEX_MAX 255 423 419 424 420 #define FW_READ_SHADOW_RAM_CMD 0x31 425 421 #define FW_READ_SHADOW_RAM_LEN 0x6 ··· 717 711 u8 cmd_resv; 718 712 u8 ret_status; 719 713 } cmd_or_resp; 720 - u8 checksum; 714 + union { 715 + u8 checksum; 716 + u8 index; 717 + }; 721 718 }; 722 719 723 720 struct wx_hic_hdr2_req { 724 721 u8 cmd; 725 722 u8 buf_lenh; 726 723 u8 buf_lenl; 727 - u8 checksum; 724 + union { 725 + u8 checksum; 726 + u8 index; 727 + }; 728 728 }; 729 729 730 730 struct wx_hic_hdr2_rsp { 731 731 u8 cmd; 732 732 u8 buf_lenl; 733 733 u8 buf_lenh_status; /* 7-5: high bits of buf_len, 4-0: status */ 734 - u8 checksum; 734 + union { 735 + u8 checksum; 736 + u8 index; 737 + }; 735 738 }; 736 739 737 740 union wx_hic_hdr2 { ··· 788 773 enum wx_mac_type { 789 774 wx_mac_unknown = 0, 790 775 wx_mac_sp, 791 - wx_mac_em 776 + wx_mac_em, 777 + wx_mac_aml, 792 778 }; 793 779 794 780 enum sp_media_type { ··· 1101 1085 1102 1086 enum wx_state { 1103 1087 WX_STATE_RESETTING, 1088 + WX_STATE_SWFW_BUSY, 1104 1089 WX_STATE_PTP_RUNNING, 1105 1090 WX_STATE_PTP_TX_IN_PROGRESS, 1106 - WX_STATE_NBITS, /* must be last */ 1091 + WX_STATE_NBITS /* must be last */ 1107 1092 }; 1108 1093 1109 1094 enum wx_pf_flags { 1095 + WX_FLAG_SWFW_RING, 1110 1096 WX_FLAG_FDIR_CAPABLE, 1111 1097 WX_FLAG_FDIR_HASH, 1112 1098 WX_FLAG_FDIR_PERFECT, ··· 1148 1130 char eeprom_id[32]; 1149 1131 char *driver_name; 1150 1132 enum wx_reset_type reset_type; 1133 + u8 swfw_index; 1151 1134 1152 1135 /* PHY stuff */ 1153 1136 unsigned int link;
+6
drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c
··· 197 197 198 198 txgbe_reset_misc(wx); 199 199 200 + if (wx->mac.type != wx_mac_sp) { 201 + wr32(wx, TXGBE_PX_PF_BME, 0x1); 202 + wr32m(wx, TXGBE_RDM_RSC_CTL, TXGBE_RDM_RSC_CTL_FREE_CTL, 203 + TXGBE_RDM_RSC_CTL_FREE_CTL); 204 + } 205 + 200 206 wx_clear_hw_cntrs(wx); 201 207 202 208 /* Store the permanent mac address */
+7
drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c
··· 166 166 167 167 void txgbe_free_misc_irq(struct txgbe *txgbe) 168 168 { 169 + if (txgbe->wx->mac.type == wx_mac_aml) 170 + return; 171 + 169 172 free_irq(txgbe->link_irq, txgbe); 170 173 free_irq(txgbe->misc.irq, txgbe); 171 174 txgbe_del_irq_domain(txgbe); ··· 179 176 unsigned long flags = IRQF_ONESHOT; 180 177 struct wx *wx = txgbe->wx; 181 178 int hwirq, err; 179 + 180 + if (wx->mac.type == wx_mac_aml) 181 + goto skip_sp_irq; 182 182 183 183 txgbe->misc.nirqs = 1; 184 184 txgbe->misc.domain = irq_domain_add_simple(NULL, txgbe->misc.nirqs, 0, ··· 212 206 if (err) 213 207 goto free_msic_irq; 214 208 209 + skip_sp_irq: 215 210 wx->misc_irq_domain = true; 216 211 217 212 return 0;
+41 -2
drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
··· 35 35 static const struct pci_device_id txgbe_pci_tbl[] = { 36 36 { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_SP1000), 0}, 37 37 { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_WX1820), 0}, 38 + { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_AML5010), 0}, 39 + { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_AML5110), 0}, 40 + { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_AML5025), 0}, 41 + { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_AML5125), 0}, 42 + { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_AML5040), 0}, 43 + { PCI_VDEVICE(WANGXUN, TXGBE_DEV_ID_AML5140), 0}, 38 44 /* required last entry */ 39 45 { .device = 0 } 40 46 }; ··· 96 90 smp_mb__before_atomic(); 97 91 wx_napi_enable_all(wx); 98 92 99 - phylink_start(wx->phylink); 93 + if (wx->mac.type == wx_mac_aml) { 94 + u32 reg; 95 + 96 + reg = rd32(wx, TXGBE_AML_MAC_TX_CFG); 97 + reg &= ~TXGBE_AML_MAC_TX_CFG_SPEED_MASK; 98 + reg |= TXGBE_AML_MAC_TX_CFG_SPEED_25G; 99 + wr32(wx, WX_MAC_TX_CFG, reg); 100 + txgbe_enable_sec_tx_path(wx); 101 + netif_carrier_on(wx->netdev); 102 + } else { 103 + phylink_start(wx->phylink); 104 + } 100 105 101 106 /* clear any pending interrupts, may auto mask */ 102 107 rd32(wx, WX_PX_IC(0)); ··· 188 171 { 189 172 txgbe_disable_device(wx); 190 173 txgbe_reset(wx); 191 - phylink_stop(wx->phylink); 174 + if (wx->mac.type == wx_mac_aml) 175 + netif_carrier_off(wx->netdev); 176 + else 177 + phylink_stop(wx->phylink); 192 178 193 179 wx_clean_all_tx_rings(wx); 194 180 wx_clean_all_rx_rings(wx); ··· 216 196 case TXGBE_DEV_ID_SP1000: 217 197 case TXGBE_DEV_ID_WX1820: 218 198 wx->mac.type = wx_mac_sp; 199 + break; 200 + case TXGBE_DEV_ID_AML5010: 201 + case TXGBE_DEV_ID_AML5110: 202 + case TXGBE_DEV_ID_AML5025: 203 + case TXGBE_DEV_ID_AML5125: 204 + case TXGBE_DEV_ID_AML5040: 205 + case TXGBE_DEV_ID_AML5140: 206 + wx->mac.type = wx_mac_aml; 219 207 break; 220 208 default: 221 209 wx->mac.type = wx_mac_unknown; ··· 311 283 wx->rx_work_limit = TXGBE_DEFAULT_RX_WORK; 312 284 313 285 wx->do_reset = txgbe_do_reset; 286 + 287 + switch (wx->mac.type) { 288 + case wx_mac_sp: 289 + break; 290 + case wx_mac_aml: 291 + set_bit(WX_FLAG_SWFW_RING, wx->flags); 292 + wx->swfw_index = 0; 293 + break; 294 + default: 295 + break; 296 + } 314 297 315 298 return 0; 316 299 }
+6
drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
··· 567 567 struct wx *wx = txgbe->wx; 568 568 int ret; 569 569 570 + if (wx->mac.type == wx_mac_aml) 571 + return 0; 572 + 570 573 if (txgbe->wx->media_type == sp_media_copper) 571 574 return txgbe_ext_phy_init(txgbe); 572 575 ··· 634 631 635 632 void txgbe_remove_phy(struct txgbe *txgbe) 636 633 { 634 + if (txgbe->wx->mac.type == wx_mac_aml) 635 + return; 636 + 637 637 if (txgbe->wx->media_type == sp_media_copper) { 638 638 phylink_disconnect_phy(txgbe->wx->phylink); 639 639 phylink_destroy(txgbe->wx->phylink);
+14
drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
··· 10 10 /* Device IDs */ 11 11 #define TXGBE_DEV_ID_SP1000 0x1001 12 12 #define TXGBE_DEV_ID_WX1820 0x2001 13 + #define TXGBE_DEV_ID_AML5010 0x5010 14 + #define TXGBE_DEV_ID_AML5110 0x5110 15 + #define TXGBE_DEV_ID_AML5025 0x5025 16 + #define TXGBE_DEV_ID_AML5125 0x5125 17 + #define TXGBE_DEV_ID_AML5040 0x5040 18 + #define TXGBE_DEV_ID_AML5140 0x5140 13 19 14 20 /* Subsystem IDs */ 15 21 /* SFP */ ··· 142 136 #define TXGBE_RDB_FDIR_FLEX_CFG_BASE_MAC FIELD_PREP(GENMASK(1, 0), 0) 143 137 #define TXGBE_RDB_FDIR_FLEX_CFG_MSK BIT(2) 144 138 #define TXGBE_RDB_FDIR_FLEX_CFG_OFST(v) FIELD_PREP(GENMASK(7, 3), v) 139 + 140 + /*************************** Amber Lite Registers ****************************/ 141 + #define TXGBE_PX_PF_BME 0x4B8 142 + #define TXGBE_AML_MAC_TX_CFG 0x11000 143 + #define TXGBE_AML_MAC_TX_CFG_SPEED_MASK GENMASK(30, 27) 144 + #define TXGBE_AML_MAC_TX_CFG_SPEED_25G BIT(28) 145 + #define TXGBE_RDM_RSC_CTL 0x1200C 146 + #define TXGBE_RDM_RSC_CTL_FREE_CTL BIT(7) 145 147 146 148 /* Checksum and EEPROM pointers */ 147 149 #define TXGBE_EEPROM_LAST_WORD 0x800