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.

Merge branch 'add-functions-for-txgbe-aml-devices'

Jiawen Wu says:

====================
Support phylink and link/gpio irqs for AML 25G/10G devices, and complete
PTP and SRIOV.
====================

Link: https://patch.msgid.link/
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+833 -115
+8 -14
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) 222 + if (wx->mac.type == wx_mac_aml40) 223 223 return -EOPNOTSUPP; 224 224 225 225 return phylink_ethtool_nway_reset(wx->phylink); ··· 231 231 { 232 232 struct wx *wx = netdev_priv(netdev); 233 233 234 - if (wx->mac.type == wx_mac_aml) 235 - return -EOPNOTSUPP; 236 - 237 234 return phylink_ethtool_ksettings_get(wx->phylink, cmd); 238 235 } 239 236 EXPORT_SYMBOL(wx_get_link_ksettings); ··· 240 243 { 241 244 struct wx *wx = netdev_priv(netdev); 242 245 243 - if (wx->mac.type == wx_mac_aml) 246 + if (wx->mac.type == wx_mac_aml40) 244 247 return -EOPNOTSUPP; 245 248 246 249 return phylink_ethtool_ksettings_set(wx->phylink, cmd); ··· 252 255 { 253 256 struct wx *wx = netdev_priv(netdev); 254 257 255 - if (wx->mac.type == wx_mac_aml) 258 + if (wx->mac.type == wx_mac_aml40) 256 259 return; 257 260 258 261 phylink_ethtool_get_pauseparam(wx->phylink, pause); ··· 264 267 { 265 268 struct wx *wx = netdev_priv(netdev); 266 269 267 - if (wx->mac.type == wx_mac_aml) 270 + if (wx->mac.type == wx_mac_aml40) 268 271 return -EOPNOTSUPP; 269 272 270 273 return phylink_ethtool_set_pauseparam(wx->phylink, pause); ··· 342 345 max_eitr = WX_SP_MAX_EITR; 343 346 break; 344 347 case wx_mac_aml: 348 + case wx_mac_aml40: 345 349 max_eitr = WX_AML_MAX_EITR; 346 350 break; 347 351 default: ··· 373 375 switch (wx->mac.type) { 374 376 case wx_mac_sp: 375 377 case wx_mac_aml: 378 + case wx_mac_aml40: 376 379 tx_itr_param = WX_12K_ITR; 377 380 break; 378 381 default: ··· 412 413 max_combined = 1; 413 414 } else { 414 415 /* support up to max allowed queues with RSS */ 415 - switch (wx->mac.type) { 416 - case wx_mac_sp: 417 - case wx_mac_aml: 416 + if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) 418 417 max_combined = 63; 419 - break; 420 - default: 418 + else 421 419 max_combined = 8; 422 - break; 423 - } 424 420 } 425 421 426 422 return max_combined;
+17 -31
drivers/net/ethernet/wangxun/libwx/wx_hw.c
··· 113 113 if (mask) 114 114 wr32(wx, WX_PX_IMS(0), mask); 115 115 116 - switch (wx->mac.type) { 117 - case wx_mac_sp: 118 - case wx_mac_aml: 116 + if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) { 119 117 mask = (qmask >> 32); 120 118 if (mask) 121 119 wr32(wx, WX_PX_IMS(1), mask); 122 - break; 123 - default: 124 - break; 125 120 } 126 121 } 127 122 ··· 128 133 if (mask) 129 134 wr32(wx, WX_PX_IMC(0), mask); 130 135 131 - switch (wx->mac.type) { 132 - case wx_mac_sp: 133 - case wx_mac_aml: 136 + if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) { 134 137 mask = (qmask >> 32); 135 138 if (mask) 136 139 wr32(wx, WX_PX_IMC(1), mask); 137 - break; 138 - default: 139 - break; 140 140 } 141 141 } 142 142 EXPORT_SYMBOL(wx_intr_enable); ··· 695 705 switch (wx->mac.type) { 696 706 case wx_mac_sp: 697 707 case wx_mac_aml: 708 + case wx_mac_aml40: 698 709 if (wx_read_ee_hostif(wx, WX_SW_REGION_PTR, &data)) { 699 710 wx_err(wx, "NVM Read Error\n"); 700 711 return; ··· 765 774 /* setup VMDq pool mapping */ 766 775 wr32(wx, WX_PSR_MAC_SWC_VM_L, pools & 0xFFFFFFFF); 767 776 768 - switch (wx->mac.type) { 769 - case wx_mac_sp: 770 - case wx_mac_aml: 777 + if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) 771 778 wr32(wx, WX_PSR_MAC_SWC_VM_H, pools >> 32); 772 - break; 773 - default: 774 - break; 775 - } 776 779 777 780 /* HW expects these in little endian so we reverse the byte 778 781 * order from network order (big endian) to little endian ··· 904 919 905 920 wx_set_rar(wx, 0, wx->mac.addr, 0, WX_PSR_MAC_SWC_AD_H_AV); 906 921 907 - switch (wx->mac.type) { 908 - case wx_mac_sp: 909 - case wx_mac_aml: 922 + if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) { 910 923 /* clear VMDq pool/queue selection for RAR 0 */ 911 924 wx_clear_vmdq(wx, 0, WX_CLEAR_VMDQ_ALL); 912 - break; 913 - default: 914 - break; 915 925 } 916 926 } 917 927 ··· 1492 1512 wr32m(wx, WX_PSR_VM_L2CTL(pool), 1493 1513 WX_PSR_VM_L2CTL_AUPE, WX_PSR_VM_L2CTL_AUPE); 1494 1514 1495 - if (wx->mac.type == wx_mac_em) { 1515 + if (!test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) { 1496 1516 vf_shift = BIT(VMDQ_P(0)); 1497 1517 /* Enable only the PF pools for Tx/Rx */ 1498 1518 wr32(wx, WX_RDM_VF_RE(0), vf_shift); ··· 1523 1543 { 1524 1544 u32 value, i; 1525 1545 1526 - if (wx->mac.type == wx_mac_em) { 1546 + if (!test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) { 1527 1547 value = (wx->num_vfs == 0) ? 1528 1548 WX_CFG_PORT_CTL_NUM_VT_NONE : 1529 1549 WX_CFG_PORT_CTL_NUM_VT_8; ··· 2054 2074 WX_RDB_PL_CFG_TUN_OUTL2HDR | 2055 2075 WX_RDB_PL_CFG_TUN_TUNHDR; 2056 2076 2057 - if (wx->mac.type == wx_mac_em) { 2077 + if (!test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) { 2058 2078 for_each_set_bit(pool, &wx->fwd_bitmask, 8) 2059 2079 wr32(wx, WX_RDB_PL_CFG(VMDQ_P(pool)), psrtype); 2060 2080 } else { ··· 2252 2272 } 2253 2273 EXPORT_SYMBOL(wx_stop_adapter); 2254 2274 2255 - void wx_reset_misc(struct wx *wx) 2275 + void wx_reset_mac(struct wx *wx) 2256 2276 { 2257 - int i; 2258 - 2259 2277 /* receive packets that size > 2048 */ 2260 2278 wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_JE, WX_MAC_RX_CFG_JE); 2261 2279 ··· 2265 2287 WX_MAC_RX_FLOW_CTRL_RFE, WX_MAC_RX_FLOW_CTRL_RFE); 2266 2288 2267 2289 wr32(wx, WX_MAC_PKT_FLT, WX_MAC_PKT_FLT_PR); 2290 + } 2291 + EXPORT_SYMBOL(wx_reset_mac); 2292 + 2293 + void wx_reset_misc(struct wx *wx) 2294 + { 2295 + int i; 2296 + 2297 + wx_reset_mac(wx); 2268 2298 2269 2299 wr32m(wx, WX_MIS_RST_ST, 2270 2300 WX_MIS_RST_ST_RST_INIT, 0x1E00);
+1
drivers/net/ethernet/wangxun/libwx/wx_hw.h
··· 42 42 void wx_start_hw(struct wx *wx); 43 43 int wx_disable_pcie_master(struct wx *wx); 44 44 int wx_stop_adapter(struct wx *wx); 45 + void wx_reset_mac(struct wx *wx); 45 46 void wx_reset_misc(struct wx *wx); 46 47 int wx_get_pcie_msix_counts(struct wx *wx, u16 *msix_count, u16 max_msix_count); 47 48 int wx_sw_init(struct wx *wx);
+38 -5
drivers/net/ethernet/wangxun/libwx/wx_lib.c
··· 5 5 #include <net/ip6_checksum.h> 6 6 #include <net/page_pool/helpers.h> 7 7 #include <net/inet_ecn.h> 8 + #include <linux/workqueue.h> 8 9 #include <linux/iopoll.h> 9 10 #include <linux/sctp.h> 10 11 #include <linux/pci.h> ··· 1634 1633 /* Add starting offset to total pool count */ 1635 1634 vmdq_i += wx->ring_feature[RING_F_VMDQ].offset; 1636 1635 1637 - if (wx->mac.type == wx_mac_sp) { 1636 + if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) { 1638 1637 /* double check we are limited to maximum pools */ 1639 1638 vmdq_i = min_t(u16, 64, vmdq_i); 1640 1639 ··· 1694 1693 1695 1694 /* set mask for 16 queue limit of RSS */ 1696 1695 f = &wx->ring_feature[RING_F_RSS]; 1697 - if (wx->mac.type == wx_mac_sp) 1696 + if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) 1698 1697 f->mask = WX_RSS_64Q_MASK; 1699 1698 else 1700 1699 f->mask = WX_RSS_8Q_MASK; ··· 1854 1853 if (!test_bit(WX_FLAG_VMDQ_ENABLED, wx->flags)) 1855 1854 return false; 1856 1855 1857 - if (wx->mac.type == wx_mac_sp) { 1856 + if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) { 1858 1857 /* start at VMDq register offset for SR-IOV enabled setups */ 1859 1858 reg_idx = vmdq->offset * __ALIGN_MASK(1, ~vmdq->mask); 1860 1859 for (i = 0; i < wx->num_rx_queues; i++, reg_idx++) { ··· 1960 1959 switch (wx->mac.type) { 1961 1960 case wx_mac_sp: 1962 1961 case wx_mac_aml: 1962 + case wx_mac_aml40: 1963 1963 default_itr = WX_12K_ITR; 1964 1964 break; 1965 1965 default: ··· 2329 2327 itr_reg = q_vector->itr & WX_SP_MAX_EITR; 2330 2328 break; 2331 2329 case wx_mac_aml: 2330 + case wx_mac_aml40: 2332 2331 itr_reg = (q_vector->itr >> 3) & WX_AML_MAX_EITR; 2333 2332 break; 2334 2333 default: ··· 2357 2354 2358 2355 if (pdev->msix_enabled) { 2359 2356 /* Populate MSIX to EITR Select */ 2360 - if (wx->mac.type == wx_mac_sp) { 2357 + if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) { 2361 2358 if (wx->num_vfs >= 32) 2362 2359 eitrsel = BIT(wx->num_vfs % 32) - 1; 2363 - } else if (wx->mac.type == wx_mac_em) { 2360 + } else { 2364 2361 for (i = 0; i < wx->num_vfs; i++) 2365 2362 eitrsel |= BIT(i); 2366 2363 } ··· 3095 3092 } 3096 3093 } 3097 3094 EXPORT_SYMBOL(wx_set_ring); 3095 + 3096 + void wx_service_event_schedule(struct wx *wx) 3097 + { 3098 + if (!test_and_set_bit(WX_STATE_SERVICE_SCHED, wx->state)) 3099 + queue_work(system_power_efficient_wq, &wx->service_task); 3100 + } 3101 + EXPORT_SYMBOL(wx_service_event_schedule); 3102 + 3103 + void wx_service_event_complete(struct wx *wx) 3104 + { 3105 + if (WARN_ON(!test_bit(WX_STATE_SERVICE_SCHED, wx->state))) 3106 + return; 3107 + 3108 + /* flush memory to make sure state is correct before next watchdog */ 3109 + smp_mb__before_atomic(); 3110 + clear_bit(WX_STATE_SERVICE_SCHED, wx->state); 3111 + } 3112 + EXPORT_SYMBOL(wx_service_event_complete); 3113 + 3114 + void wx_service_timer(struct timer_list *t) 3115 + { 3116 + struct wx *wx = from_timer(wx, t, service_timer); 3117 + unsigned long next_event_offset = HZ * 2; 3118 + 3119 + /* Reset the timer */ 3120 + mod_timer(&wx->service_timer, next_event_offset + jiffies); 3121 + 3122 + wx_service_event_schedule(wx); 3123 + } 3124 + EXPORT_SYMBOL(wx_service_timer); 3098 3125 3099 3126 MODULE_DESCRIPTION("Common library for Wangxun(R) Ethernet drivers."); 3100 3127 MODULE_LICENSE("GPL");
+3
drivers/net/ethernet/wangxun/libwx/wx_lib.h
··· 38 38 netdev_features_t features); 39 39 void wx_set_ring(struct wx *wx, u32 new_tx_count, 40 40 u32 new_rx_count, struct wx_ring *temp_ring); 41 + void wx_service_event_schedule(struct wx *wx); 42 + void wx_service_event_complete(struct wx *wx); 43 + void wx_service_timer(struct timer_list *t); 41 44 42 45 #endif /* _WX_LIB_H_ */
+28 -6
drivers/net/ethernet/wangxun/libwx/wx_ptp.c
··· 15 15 #define WX_INCVAL_100 0xA00000 16 16 #define WX_INCVAL_10 0xC7F380 17 17 #define WX_INCVAL_EM 0x2000000 18 + #define WX_INCVAL_AML 0xA00000 18 19 19 20 #define WX_INCVAL_SHIFT_10GB 20 20 21 #define WX_INCVAL_SHIFT_1GB 18 21 22 #define WX_INCVAL_SHIFT_100 15 22 23 #define WX_INCVAL_SHIFT_10 12 23 24 #define WX_INCVAL_SHIFT_EM 22 25 + #define WX_INCVAL_SHIFT_AML 21 24 26 25 27 #define WX_OVERFLOW_PERIOD (HZ * 30) 26 28 #define WX_PTP_TX_TIMEOUT (HZ) ··· 506 504 wx->ptp_caps.gettimex64 = wx_ptp_gettimex64; 507 505 wx->ptp_caps.settime64 = wx_ptp_settime64; 508 506 wx->ptp_caps.do_aux_work = wx_ptp_do_aux_work; 509 - if (wx->mac.type == wx_mac_em) { 507 + switch (wx->mac.type) { 508 + case wx_mac_aml: 509 + case wx_mac_aml40: 510 + wx->ptp_caps.max_adj = 250000000; 511 + wx->ptp_caps.n_per_out = 1; 512 + wx->ptp_setup_sdp = wx_ptp_setup_sdp; 513 + wx->ptp_caps.enable = wx_ptp_feature_enable; 514 + break; 515 + case wx_mac_sp: 516 + wx->ptp_caps.max_adj = 250000000; 517 + wx->ptp_caps.n_per_out = 0; 518 + wx->ptp_setup_sdp = NULL; 519 + break; 520 + case wx_mac_em: 510 521 wx->ptp_caps.max_adj = 500000000; 511 522 wx->ptp_caps.n_per_out = 1; 512 523 wx->ptp_setup_sdp = wx_ptp_setup_sdp; 513 524 wx->ptp_caps.enable = wx_ptp_feature_enable; 514 - } else { 515 - wx->ptp_caps.max_adj = 250000000; 516 - wx->ptp_caps.n_per_out = 0; 517 - wx->ptp_setup_sdp = NULL; 525 + break; 526 + default: 527 + return -EOPNOTSUPP; 518 528 } 519 529 520 530 wx->ptp_clock = ptp_clock_register(&wx->ptp_caps, &wx->pdev->dev); ··· 661 647 662 648 static void wx_ptp_link_speed_adjust(struct wx *wx, u32 *shift, u32 *incval) 663 649 { 664 - if (wx->mac.type == wx_mac_em) { 650 + switch (wx->mac.type) { 651 + case wx_mac_aml: 652 + case wx_mac_aml40: 653 + *shift = WX_INCVAL_SHIFT_AML; 654 + *incval = WX_INCVAL_AML; 655 + return; 656 + case wx_mac_em: 665 657 *shift = WX_INCVAL_SHIFT_EM; 666 658 *incval = WX_INCVAL_EM; 667 659 return; 660 + default: 661 + break; 668 662 } 669 663 670 664 switch (wx->speed) {
+4 -4
drivers/net/ethernet/wangxun/libwx/wx_sriov.c
··· 106 106 wx->vfinfo[i].xcast_mode = WXVF_XCAST_MODE_NONE; 107 107 } 108 108 109 - if (wx->mac.type == wx_mac_em) { 109 + if (!test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) { 110 110 value = WX_CFG_PORT_CTL_NUM_VT_8; 111 111 } else { 112 112 if (num_vfs < 32) ··· 599 599 if (VMDQ_P(0) < 32) { 600 600 bits = rd32(wx, WX_PSR_VLAN_SWC_VM_L); 601 601 bits &= ~BIT(VMDQ_P(0)); 602 - if (wx->mac.type != wx_mac_em) 602 + if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) 603 603 bits |= rd32(wx, WX_PSR_VLAN_SWC_VM_H); 604 604 } else { 605 - if (wx->mac.type != wx_mac_em) 605 + if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) 606 606 bits = rd32(wx, WX_PSR_VLAN_SWC_VM_H); 607 607 bits &= ~BIT(VMDQ_P(0) % 32); 608 608 bits |= rd32(wx, WX_PSR_VLAN_SWC_VM_L); ··· 848 848 { 849 849 wr32(wx, WX_TDM_VFTE_CLR(0), U32_MAX); 850 850 wr32(wx, WX_RDM_VFRE_CLR(0), U32_MAX); 851 - if (wx->mac.type != wx_mac_em) { 851 + if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) { 852 852 wr32(wx, WX_TDM_VFTE_CLR(1), U32_MAX); 853 853 wr32(wx, WX_RDM_VFRE_CLR(1), U32_MAX); 854 854 }
+16 -6
drivers/net/ethernet/wangxun/libwx/wx_type.h
··· 838 838 wx_mac_sp, 839 839 wx_mac_em, 840 840 wx_mac_aml, 841 + wx_mac_aml40, 841 842 }; 842 843 843 - enum sp_media_type { 844 - sp_media_unknown = 0, 845 - sp_media_fiber, 846 - sp_media_copper, 847 - sp_media_backplane 844 + enum wx_media_type { 845 + wx_media_unknown = 0, 846 + wx_media_fiber, 847 + wx_media_copper, 848 + wx_media_backplane 848 849 }; 849 850 850 851 enum em_mac_type { ··· 1154 1153 WX_STATE_SWFW_BUSY, 1155 1154 WX_STATE_PTP_RUNNING, 1156 1155 WX_STATE_PTP_TX_IN_PROGRESS, 1156 + WX_STATE_SERVICE_SCHED, 1157 1157 WX_STATE_NBITS /* must be last */ 1158 1158 }; 1159 1159 ··· 1186 1184 }; 1187 1185 1188 1186 enum wx_pf_flags { 1187 + WX_FLAG_MULTI_64_FUNC, 1189 1188 WX_FLAG_SWFW_RING, 1190 1189 WX_FLAG_VMDQ_ENABLED, 1191 1190 WX_FLAG_VLAN_PROMISC, ··· 1198 1195 WX_FLAG_RX_HWTSTAMP_ENABLED, 1199 1196 WX_FLAG_RX_HWTSTAMP_IN_REGISTER, 1200 1197 WX_FLAG_PTP_PPS_ENABLED, 1198 + WX_FLAG_NEED_LINK_CONFIG, 1199 + WX_FLAG_NEED_SFP_RESET, 1201 1200 WX_PF_FLAGS_NBITS /* must be last */ 1202 1201 }; 1203 1202 ··· 1216 1211 struct wx_mbx_info mbx; 1217 1212 struct wx_mac_info mac; 1218 1213 enum em_mac_type mac_type; 1219 - enum sp_media_type media_type; 1214 + enum wx_media_type media_type; 1220 1215 struct wx_eeprom_info eeprom; 1221 1216 struct wx_addr_filter_info addr_ctrl; 1222 1217 struct wx_fc_info fc; ··· 1238 1233 1239 1234 /* PHY stuff */ 1240 1235 bool notify_down; 1236 + int adv_speed; 1237 + int adv_duplex; 1241 1238 unsigned int link; 1242 1239 int speed; 1243 1240 int duplex; ··· 1337 1330 struct ptp_clock_info ptp_caps; 1338 1331 struct kernel_hwtstamp_config tstamp_config; 1339 1332 struct sk_buff *ptp_tx_skb; 1333 + 1334 + struct timer_list service_timer; 1335 + struct work_struct service_task; 1340 1336 }; 1341 1337 1342 1338 #define WX_INTR_ALL (~0ULL)
+2 -1
drivers/net/ethernet/wangxun/txgbe/Makefile
··· 11 11 txgbe_phy.o \ 12 12 txgbe_irq.o \ 13 13 txgbe_fdir.o \ 14 - txgbe_ethtool.o 14 + txgbe_ethtool.o \ 15 + txgbe_aml.o
+385
drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2015 - 2025 Beijing WangXun Technology Co., Ltd. */ 3 + 4 + #include <linux/phylink.h> 5 + #include <linux/iopoll.h> 6 + #include <linux/pci.h> 7 + #include <linux/phy.h> 8 + 9 + #include "../libwx/wx_type.h" 10 + #include "../libwx/wx_lib.h" 11 + #include "../libwx/wx_ptp.h" 12 + #include "../libwx/wx_hw.h" 13 + #include "../libwx/wx_sriov.h" 14 + #include "txgbe_type.h" 15 + #include "txgbe_aml.h" 16 + #include "txgbe_hw.h" 17 + 18 + void txgbe_gpio_init_aml(struct wx *wx) 19 + { 20 + u32 status; 21 + 22 + wr32(wx, WX_GPIO_INTTYPE_LEVEL, TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3); 23 + wr32(wx, WX_GPIO_INTEN, TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3); 24 + 25 + status = rd32(wx, WX_GPIO_INTSTATUS); 26 + for (int i = 0; i < 6; i++) { 27 + if (status & BIT(i)) 28 + wr32(wx, WX_GPIO_EOI, BIT(i)); 29 + } 30 + } 31 + 32 + irqreturn_t txgbe_gpio_irq_handler_aml(int irq, void *data) 33 + { 34 + struct txgbe *txgbe = data; 35 + struct wx *wx = txgbe->wx; 36 + u32 status; 37 + 38 + wr32(wx, WX_GPIO_INTMASK, 0xFF); 39 + status = rd32(wx, WX_GPIO_INTSTATUS); 40 + if (status & TXGBE_GPIOBIT_2) { 41 + set_bit(WX_FLAG_NEED_SFP_RESET, wx->flags); 42 + wr32(wx, WX_GPIO_EOI, TXGBE_GPIOBIT_2); 43 + wx_service_event_schedule(wx); 44 + } 45 + if (status & TXGBE_GPIOBIT_3) { 46 + set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags); 47 + wx_service_event_schedule(wx); 48 + wr32(wx, WX_GPIO_EOI, TXGBE_GPIOBIT_3); 49 + } 50 + 51 + wr32(wx, WX_GPIO_INTMASK, 0); 52 + return IRQ_HANDLED; 53 + } 54 + 55 + int txgbe_test_hostif(struct wx *wx) 56 + { 57 + struct txgbe_hic_ephy_getlink buffer; 58 + 59 + if (wx->mac.type != wx_mac_aml) 60 + return 0; 61 + 62 + buffer.hdr.cmd = FW_PHY_GET_LINK_CMD; 63 + buffer.hdr.buf_len = sizeof(struct txgbe_hic_ephy_getlink) - 64 + sizeof(struct wx_hic_hdr); 65 + buffer.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; 66 + 67 + return wx_host_interface_command(wx, (u32 *)&buffer, sizeof(buffer), 68 + WX_HI_COMMAND_TIMEOUT, true); 69 + } 70 + 71 + static int txgbe_identify_sfp_hostif(struct wx *wx, struct txgbe_hic_i2c_read *buffer) 72 + { 73 + buffer->hdr.cmd = FW_READ_SFP_INFO_CMD; 74 + buffer->hdr.buf_len = sizeof(struct txgbe_hic_i2c_read) - 75 + sizeof(struct wx_hic_hdr); 76 + buffer->hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; 77 + 78 + return wx_host_interface_command(wx, (u32 *)buffer, 79 + sizeof(struct txgbe_hic_i2c_read), 80 + WX_HI_COMMAND_TIMEOUT, true); 81 + } 82 + 83 + static int txgbe_set_phy_link_hostif(struct wx *wx, int speed, int autoneg, int duplex) 84 + { 85 + struct txgbe_hic_ephy_setlink buffer; 86 + 87 + buffer.hdr.cmd = FW_PHY_SET_LINK_CMD; 88 + buffer.hdr.buf_len = sizeof(struct txgbe_hic_ephy_setlink) - 89 + sizeof(struct wx_hic_hdr); 90 + buffer.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; 91 + 92 + switch (speed) { 93 + case SPEED_25000: 94 + buffer.speed = TXGBE_LINK_SPEED_25GB_FULL; 95 + break; 96 + case SPEED_10000: 97 + buffer.speed = TXGBE_LINK_SPEED_10GB_FULL; 98 + break; 99 + } 100 + 101 + buffer.fec_mode = TXGBE_PHY_FEC_AUTO; 102 + buffer.autoneg = autoneg; 103 + buffer.duplex = duplex; 104 + 105 + return wx_host_interface_command(wx, (u32 *)&buffer, sizeof(buffer), 106 + WX_HI_COMMAND_TIMEOUT, true); 107 + } 108 + 109 + static void txgbe_get_link_capabilities(struct wx *wx) 110 + { 111 + struct txgbe *txgbe = wx->priv; 112 + 113 + if (test_bit(PHY_INTERFACE_MODE_25GBASER, txgbe->sfp_interfaces)) 114 + wx->adv_speed = SPEED_25000; 115 + else if (test_bit(PHY_INTERFACE_MODE_10GBASER, txgbe->sfp_interfaces)) 116 + wx->adv_speed = SPEED_10000; 117 + else 118 + wx->adv_speed = SPEED_UNKNOWN; 119 + 120 + wx->adv_duplex = wx->adv_speed == SPEED_UNKNOWN ? 121 + DUPLEX_HALF : DUPLEX_FULL; 122 + } 123 + 124 + static void txgbe_get_phy_link(struct wx *wx, int *speed) 125 + { 126 + u32 status; 127 + 128 + status = rd32(wx, TXGBE_CFG_PORT_ST); 129 + if (!(status & TXGBE_CFG_PORT_ST_LINK_UP)) 130 + *speed = SPEED_UNKNOWN; 131 + else if (status & TXGBE_CFG_PORT_ST_LINK_AML_25G) 132 + *speed = SPEED_25000; 133 + else if (status & TXGBE_CFG_PORT_ST_LINK_AML_10G) 134 + *speed = SPEED_10000; 135 + else 136 + *speed = SPEED_UNKNOWN; 137 + } 138 + 139 + int txgbe_set_phy_link(struct wx *wx) 140 + { 141 + int speed, err; 142 + u32 gpio; 143 + 144 + /* Check RX signal */ 145 + gpio = rd32(wx, WX_GPIO_EXT); 146 + if (gpio & TXGBE_GPIOBIT_3) 147 + return -ENODEV; 148 + 149 + txgbe_get_link_capabilities(wx); 150 + if (wx->adv_speed == SPEED_UNKNOWN) 151 + return -ENODEV; 152 + 153 + txgbe_get_phy_link(wx, &speed); 154 + if (speed == wx->adv_speed) 155 + return 0; 156 + 157 + err = txgbe_set_phy_link_hostif(wx, wx->adv_speed, 0, wx->adv_duplex); 158 + if (err) { 159 + wx_err(wx, "Failed to setup link\n"); 160 + return err; 161 + } 162 + 163 + return 0; 164 + } 165 + 166 + static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sfp_id *id) 167 + { 168 + __ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, }; 169 + DECLARE_PHY_INTERFACE_MASK(interfaces); 170 + struct txgbe *txgbe = wx->priv; 171 + 172 + if (id->com_25g_code & (TXGBE_SFF_25GBASESR_CAPABLE | 173 + TXGBE_SFF_25GBASEER_CAPABLE | 174 + TXGBE_SFF_25GBASELR_CAPABLE)) { 175 + phylink_set(modes, 25000baseSR_Full); 176 + __set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces); 177 + } 178 + if (id->com_10g_code & TXGBE_SFF_10GBASESR_CAPABLE) { 179 + phylink_set(modes, 10000baseSR_Full); 180 + __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces); 181 + } 182 + if (id->com_10g_code & TXGBE_SFF_10GBASELR_CAPABLE) { 183 + phylink_set(modes, 10000baseLR_Full); 184 + __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces); 185 + } 186 + 187 + if (phy_interface_empty(interfaces)) { 188 + wx_err(wx, "unsupported SFP module\n"); 189 + return -EINVAL; 190 + } 191 + 192 + phylink_set(modes, Pause); 193 + phylink_set(modes, Asym_Pause); 194 + phylink_set(modes, FIBRE); 195 + txgbe->link_port = PORT_FIBRE; 196 + 197 + if (!linkmode_equal(txgbe->sfp_support, modes)) { 198 + linkmode_copy(txgbe->sfp_support, modes); 199 + phy_interface_and(txgbe->sfp_interfaces, 200 + wx->phylink_config.supported_interfaces, 201 + interfaces); 202 + linkmode_copy(txgbe->advertising, modes); 203 + 204 + set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags); 205 + } 206 + 207 + return 0; 208 + } 209 + 210 + int txgbe_identify_sfp(struct wx *wx) 211 + { 212 + struct txgbe_hic_i2c_read buffer; 213 + struct txgbe_sfp_id *id; 214 + int err = 0; 215 + u32 gpio; 216 + 217 + gpio = rd32(wx, WX_GPIO_EXT); 218 + if (gpio & TXGBE_GPIOBIT_2) 219 + return -ENODEV; 220 + 221 + err = txgbe_identify_sfp_hostif(wx, &buffer); 222 + if (err) { 223 + wx_err(wx, "Failed to identify SFP module\n"); 224 + return err; 225 + } 226 + 227 + id = &buffer.id; 228 + if (id->identifier != TXGBE_SFF_IDENTIFIER_SFP) { 229 + wx_err(wx, "Invalid SFP module\n"); 230 + return -ENODEV; 231 + } 232 + 233 + err = txgbe_sfp_to_linkmodes(wx, id); 234 + if (err) 235 + return err; 236 + 237 + if (gpio & TXGBE_GPIOBIT_3) 238 + set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags); 239 + 240 + return 0; 241 + } 242 + 243 + void txgbe_setup_link(struct wx *wx) 244 + { 245 + struct txgbe *txgbe = wx->priv; 246 + 247 + phy_interface_zero(txgbe->sfp_interfaces); 248 + linkmode_zero(txgbe->sfp_support); 249 + 250 + txgbe_identify_sfp(wx); 251 + } 252 + 253 + static void txgbe_get_link_state(struct phylink_config *config, 254 + struct phylink_link_state *state) 255 + { 256 + struct wx *wx = phylink_to_wx(config); 257 + int speed; 258 + 259 + txgbe_get_phy_link(wx, &speed); 260 + state->link = speed != SPEED_UNKNOWN; 261 + state->speed = speed; 262 + state->duplex = state->link ? DUPLEX_FULL : DUPLEX_UNKNOWN; 263 + } 264 + 265 + static void txgbe_reconfig_mac(struct wx *wx) 266 + { 267 + u32 wdg, fc; 268 + 269 + wdg = rd32(wx, WX_MAC_WDG_TIMEOUT); 270 + fc = rd32(wx, WX_MAC_RX_FLOW_CTRL); 271 + 272 + wr32(wx, WX_MIS_RST, TXGBE_MIS_RST_MAC_RST(wx->bus.func)); 273 + /* wait for MAC reset complete */ 274 + usleep_range(1000, 1500); 275 + 276 + wr32m(wx, TXGBE_MAC_MISC_CTL, TXGBE_MAC_MISC_CTL_LINK_STS_MOD, 277 + TXGBE_MAC_MISC_CTL_LINK_BOTH); 278 + wx_reset_mac(wx); 279 + 280 + wr32(wx, WX_MAC_WDG_TIMEOUT, wdg); 281 + wr32(wx, WX_MAC_RX_FLOW_CTRL, fc); 282 + } 283 + 284 + static void txgbe_mac_link_up_aml(struct phylink_config *config, 285 + struct phy_device *phy, 286 + unsigned int mode, 287 + phy_interface_t interface, 288 + int speed, int duplex, 289 + bool tx_pause, bool rx_pause) 290 + { 291 + struct wx *wx = phylink_to_wx(config); 292 + u32 txcfg; 293 + 294 + wx_fc_enable(wx, tx_pause, rx_pause); 295 + 296 + txgbe_reconfig_mac(wx); 297 + 298 + txcfg = rd32(wx, TXGBE_AML_MAC_TX_CFG); 299 + txcfg &= ~TXGBE_AML_MAC_TX_CFG_SPEED_MASK; 300 + 301 + switch (speed) { 302 + case SPEED_25000: 303 + txcfg |= TXGBE_AML_MAC_TX_CFG_SPEED_25G; 304 + break; 305 + case SPEED_10000: 306 + txcfg |= TXGBE_AML_MAC_TX_CFG_SPEED_10G; 307 + break; 308 + default: 309 + break; 310 + } 311 + 312 + wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, WX_MAC_RX_CFG_RE); 313 + wr32(wx, TXGBE_AML_MAC_TX_CFG, txcfg | TXGBE_AML_MAC_TX_CFG_TE); 314 + 315 + wx->speed = speed; 316 + wx->last_rx_ptp_check = jiffies; 317 + if (test_bit(WX_STATE_PTP_RUNNING, wx->state)) 318 + wx_ptp_reset_cyclecounter(wx); 319 + /* ping all the active vfs to let them know we are going up */ 320 + wx_ping_all_vfs_with_link_status(wx, true); 321 + } 322 + 323 + static void txgbe_mac_link_down_aml(struct phylink_config *config, 324 + unsigned int mode, 325 + phy_interface_t interface) 326 + { 327 + struct wx *wx = phylink_to_wx(config); 328 + 329 + wr32m(wx, TXGBE_AML_MAC_TX_CFG, TXGBE_AML_MAC_TX_CFG_TE, 0); 330 + wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, 0); 331 + 332 + wx->speed = SPEED_UNKNOWN; 333 + if (test_bit(WX_STATE_PTP_RUNNING, wx->state)) 334 + wx_ptp_reset_cyclecounter(wx); 335 + /* ping all the active vfs to let them know we are going down */ 336 + wx_ping_all_vfs_with_link_status(wx, false); 337 + } 338 + 339 + static void txgbe_mac_config_aml(struct phylink_config *config, unsigned int mode, 340 + const struct phylink_link_state *state) 341 + { 342 + } 343 + 344 + static const struct phylink_mac_ops txgbe_mac_ops_aml = { 345 + .mac_config = txgbe_mac_config_aml, 346 + .mac_link_down = txgbe_mac_link_down_aml, 347 + .mac_link_up = txgbe_mac_link_up_aml, 348 + }; 349 + 350 + int txgbe_phylink_init_aml(struct txgbe *txgbe) 351 + { 352 + struct phylink_link_state state; 353 + struct phylink_config *config; 354 + struct wx *wx = txgbe->wx; 355 + phy_interface_t phy_mode; 356 + struct phylink *phylink; 357 + int err; 358 + 359 + config = &wx->phylink_config; 360 + config->dev = &wx->netdev->dev; 361 + config->type = PHYLINK_NETDEV; 362 + config->mac_capabilities = MAC_25000FD | MAC_10000FD | 363 + MAC_SYM_PAUSE | MAC_ASYM_PAUSE; 364 + config->get_fixed_state = txgbe_get_link_state; 365 + 366 + phy_mode = PHY_INTERFACE_MODE_25GBASER; 367 + __set_bit(PHY_INTERFACE_MODE_25GBASER, config->supported_interfaces); 368 + __set_bit(PHY_INTERFACE_MODE_10GBASER, config->supported_interfaces); 369 + 370 + phylink = phylink_create(config, NULL, phy_mode, &txgbe_mac_ops_aml); 371 + if (IS_ERR(phylink)) 372 + return PTR_ERR(phylink); 373 + 374 + state.speed = SPEED_25000; 375 + state.duplex = DUPLEX_FULL; 376 + err = phylink_set_fixed_link(phylink, &state); 377 + if (err) { 378 + wx_err(wx, "Failed to set fixed link\n"); 379 + return err; 380 + } 381 + 382 + wx->phylink = phylink; 383 + 384 + return 0; 385 + }
+15
drivers/net/ethernet/wangxun/txgbe/txgbe_aml.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* Copyright (c) 2015 - 2025 Beijing WangXun Technology Co., Ltd. */ 3 + 4 + #ifndef _TXGBE_AML_H_ 5 + #define _TXGBE_AML_H_ 6 + 7 + void txgbe_gpio_init_aml(struct wx *wx); 8 + irqreturn_t txgbe_gpio_irq_handler_aml(int irq, void *data); 9 + int txgbe_test_hostif(struct wx *wx); 10 + int txgbe_set_phy_link(struct wx *wx); 11 + int txgbe_identify_sfp(struct wx *wx); 12 + void txgbe_setup_link(struct wx *wx); 13 + int txgbe_phylink_init_aml(struct txgbe *txgbe); 14 + 15 + #endif /* _TXGBE_AML_H_ */
+26 -1
drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
··· 12 12 #include "txgbe_fdir.h" 13 13 #include "txgbe_ethtool.h" 14 14 15 + int txgbe_get_link_ksettings(struct net_device *netdev, 16 + struct ethtool_link_ksettings *cmd) 17 + { 18 + struct wx *wx = netdev_priv(netdev); 19 + struct txgbe *txgbe = wx->priv; 20 + int err; 21 + 22 + if (wx->mac.type == wx_mac_aml40) 23 + return -EOPNOTSUPP; 24 + 25 + err = wx_get_link_ksettings(netdev, cmd); 26 + if (err) 27 + return err; 28 + 29 + if (wx->mac.type == wx_mac_sp) 30 + return 0; 31 + 32 + cmd->base.port = txgbe->link_port; 33 + cmd->base.autoneg = AUTONEG_DISABLE; 34 + linkmode_copy(cmd->link_modes.supported, txgbe->sfp_support); 35 + linkmode_copy(cmd->link_modes.advertising, txgbe->advertising); 36 + 37 + return 0; 38 + } 39 + 15 40 static int txgbe_set_ringparam(struct net_device *netdev, 16 41 struct ethtool_ringparam *ring, 17 42 struct kernel_ethtool_ringparam *kernel_ring, ··· 535 510 .get_drvinfo = wx_get_drvinfo, 536 511 .nway_reset = wx_nway_reset, 537 512 .get_link = ethtool_op_get_link, 538 - .get_link_ksettings = wx_get_link_ksettings, 513 + .get_link_ksettings = txgbe_get_link_ksettings, 539 514 .set_link_ksettings = wx_set_link_ksettings, 540 515 .get_sset_count = wx_get_sset_count, 541 516 .get_strings = wx_get_strings,
+2
drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.h
··· 4 4 #ifndef _TXGBE_ETHTOOL_H_ 5 5 #define _TXGBE_ETHTOOL_H_ 6 6 7 + int txgbe_get_link_ksettings(struct net_device *netdev, 8 + struct ethtool_link_ksettings *cmd); 7 9 void txgbe_set_ethtool_ops(struct net_device *netdev); 8 10 9 11 #endif /* _TXGBE_ETHTOOL_H_ */
+2 -2
drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c
··· 188 188 if (status != 0) 189 189 return status; 190 190 191 - if (wx->media_type != sp_media_copper) { 191 + if (wx->media_type != wx_media_copper) { 192 192 u32 val; 193 193 194 194 val = WX_MIS_RST_LAN_RST(wx->bus.func); ··· 218 218 * clear the multicast table. Also reset num_rar_entries to 128, 219 219 * since we modify this value when programming the SAN MAC address. 220 220 */ 221 - wx->mac.num_rar_entries = TXGBE_SP_RAR_ENTRIES; 221 + wx->mac.num_rar_entries = TXGBE_RAR_ENTRIES; 222 222 wx_init_rx_addrs(wx); 223 223 224 224 pci_set_master(wx->pdev);
+41 -3
drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c
··· 6 6 7 7 #include "../libwx/wx_type.h" 8 8 #include "../libwx/wx_lib.h" 9 + #include "../libwx/wx_ptp.h" 9 10 #include "../libwx/wx_hw.h" 10 11 #include "../libwx/wx_sriov.h" 11 12 #include "txgbe_type.h" 12 13 #include "txgbe_phy.h" 13 14 #include "txgbe_irq.h" 15 + #include "txgbe_aml.h" 14 16 15 17 /** 16 18 * txgbe_irq_enable - Enable default interrupt generation settings ··· 21 19 **/ 22 20 void txgbe_irq_enable(struct wx *wx, bool queues) 23 21 { 24 - wr32(wx, WX_PX_MISC_IEN, TXGBE_PX_MISC_IEN_MASK); 22 + u32 misc_ien = TXGBE_PX_MISC_IEN_MASK; 23 + 24 + if (wx->mac.type == wx_mac_aml) { 25 + misc_ien |= TXGBE_PX_MISC_GPIO; 26 + txgbe_gpio_init_aml(wx); 27 + } 28 + 29 + wr32(wx, WX_PX_MISC_IEN, misc_ien); 25 30 26 31 /* unmask interrupt */ 27 32 wx_intr_enable(wx, TXGBE_INTR_MISC); ··· 88 79 return request_threaded_irq(txgbe->link_irq, NULL, 89 80 txgbe_link_irq_handler, 90 81 IRQF_ONESHOT, "txgbe-link-irq", txgbe); 82 + } 83 + 84 + static int txgbe_request_gpio_irq(struct txgbe *txgbe) 85 + { 86 + txgbe->gpio_irq = irq_find_mapping(txgbe->misc.domain, TXGBE_IRQ_GPIO); 87 + return request_threaded_irq(txgbe->gpio_irq, NULL, 88 + txgbe_gpio_irq_handler_aml, 89 + IRQF_ONESHOT, "txgbe-gpio-irq", txgbe); 91 90 } 92 91 93 92 static const struct irq_chip txgbe_irq_chip = { ··· 174 157 handle_nested_irq(sub_irq); 175 158 nhandled++; 176 159 } 160 + if (eicr & TXGBE_PX_MISC_GPIO) { 161 + sub_irq = irq_find_mapping(txgbe->misc.domain, TXGBE_IRQ_GPIO); 162 + handle_nested_irq(sub_irq); 163 + nhandled++; 164 + } 165 + if (unlikely(eicr & TXGBE_PX_MISC_IC_TIMESYNC)) { 166 + wx_ptp_check_pps_event(wx); 167 + nhandled++; 168 + } 177 169 178 170 wx_intr_enable(wx, TXGBE_INTR_MISC); 179 171 return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE); ··· 202 176 203 177 void txgbe_free_misc_irq(struct txgbe *txgbe) 204 178 { 205 - if (txgbe->wx->mac.type == wx_mac_aml) 179 + if (txgbe->wx->mac.type == wx_mac_aml40) 206 180 return; 181 + 182 + if (txgbe->wx->mac.type == wx_mac_aml) 183 + free_irq(txgbe->gpio_irq, txgbe); 207 184 208 185 free_irq(txgbe->link_irq, txgbe); 209 186 free_irq(txgbe->misc.irq, txgbe); ··· 219 190 struct wx *wx = txgbe->wx; 220 191 int hwirq, err; 221 192 222 - if (wx->mac.type == wx_mac_aml) 193 + if (wx->mac.type == wx_mac_aml40) 223 194 goto skip_sp_irq; 224 195 225 196 txgbe->misc.nirqs = TXGBE_IRQ_MAX; ··· 251 222 if (err) 252 223 goto free_msic_irq; 253 224 225 + if (wx->mac.type == wx_mac_sp) 226 + goto skip_sp_irq; 227 + 228 + err = txgbe_request_gpio_irq(txgbe); 229 + if (err) 230 + goto free_link_irq; 231 + 254 232 skip_sp_irq: 255 233 wx->misc_irq_domain = true; 256 234 257 235 return 0; 258 236 237 + free_link_irq: 238 + free_irq(txgbe->link_irq, txgbe); 259 239 free_msic_irq: 260 240 free_irq(txgbe->misc.irq, txgbe); 261 241 del_misc_irq:
+118 -22
drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
··· 21 21 #include "txgbe_type.h" 22 22 #include "txgbe_hw.h" 23 23 #include "txgbe_phy.h" 24 + #include "txgbe_aml.h" 24 25 #include "txgbe_irq.h" 25 26 #include "txgbe_fdir.h" 26 27 #include "txgbe_ethtool.h" ··· 89 88 return physfns; 90 89 } 91 90 91 + static void txgbe_sfp_detection_subtask(struct wx *wx) 92 + { 93 + int err; 94 + 95 + if (!test_bit(WX_FLAG_NEED_SFP_RESET, wx->flags)) 96 + return; 97 + 98 + /* wait for SFP module ready */ 99 + msleep(200); 100 + 101 + err = txgbe_identify_sfp(wx); 102 + if (err) 103 + return; 104 + 105 + clear_bit(WX_FLAG_NEED_SFP_RESET, wx->flags); 106 + } 107 + 108 + static void txgbe_link_config_subtask(struct wx *wx) 109 + { 110 + int err; 111 + 112 + if (!test_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags)) 113 + return; 114 + 115 + err = txgbe_set_phy_link(wx); 116 + if (err) 117 + return; 118 + 119 + clear_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags); 120 + } 121 + 122 + /** 123 + * txgbe_service_task - manages and runs subtasks 124 + * @work: pointer to work_struct containing our data 125 + **/ 126 + static void txgbe_service_task(struct work_struct *work) 127 + { 128 + struct wx *wx = container_of(work, struct wx, service_task); 129 + 130 + txgbe_sfp_detection_subtask(wx); 131 + txgbe_link_config_subtask(wx); 132 + 133 + wx_service_event_complete(wx); 134 + } 135 + 136 + static void txgbe_init_service(struct wx *wx) 137 + { 138 + timer_setup(&wx->service_timer, wx_service_timer, 0); 139 + INIT_WORK(&wx->service_task, txgbe_service_task); 140 + clear_bit(WX_STATE_SERVICE_SCHED, wx->state); 141 + } 142 + 92 143 static void txgbe_up_complete(struct wx *wx) 93 144 { 94 145 struct net_device *netdev = wx->netdev; 146 + u32 reg; 95 147 96 148 wx_control_hw(wx, true); 97 149 wx_configure_vectors(wx); ··· 153 99 smp_mb__before_atomic(); 154 100 wx_napi_enable_all(wx); 155 101 156 - if (wx->mac.type == wx_mac_aml) { 157 - u32 reg; 158 - 102 + switch (wx->mac.type) { 103 + case wx_mac_aml40: 159 104 reg = rd32(wx, TXGBE_AML_MAC_TX_CFG); 160 105 reg &= ~TXGBE_AML_MAC_TX_CFG_SPEED_MASK; 161 - reg |= TXGBE_AML_MAC_TX_CFG_SPEED_25G; 106 + reg |= TXGBE_AML_MAC_TX_CFG_SPEED_40G; 162 107 wr32(wx, WX_MAC_TX_CFG, reg); 163 108 txgbe_enable_sec_tx_path(wx); 164 109 netif_carrier_on(wx->netdev); 165 - } else { 110 + break; 111 + case wx_mac_aml: 112 + /* Enable TX laser */ 113 + wr32m(wx, WX_GPIO_DR, TXGBE_GPIOBIT_1, 0); 114 + txgbe_setup_link(wx); 166 115 phylink_start(wx->phylink); 116 + break; 117 + case wx_mac_sp: 118 + phylink_start(wx->phylink); 119 + break; 120 + default: 121 + break; 167 122 } 168 123 169 124 /* clear any pending interrupts, may auto mask */ ··· 183 120 184 121 /* enable transmits */ 185 122 netif_tx_start_all_queues(netdev); 123 + mod_timer(&wx->service_timer, jiffies); 186 124 187 125 /* Set PF Reset Done bit so PF/VF Mail Ops can work */ 188 126 wr32m(wx, WX_CFG_PORT_CTL, WX_CFG_PORT_CTL_PFRSTD, ··· 232 168 wx_irq_disable(wx); 233 169 wx_napi_disable_all(wx); 234 170 171 + timer_delete_sync(&wx->service_timer); 172 + 235 173 if (wx->bus.func < 2) 236 174 wr32m(wx, TXGBE_MIS_PRB_CTL, TXGBE_MIS_PRB_CTL_LAN_UP(wx->bus.func), 0); 237 175 else ··· 273 207 { 274 208 txgbe_disable_device(wx); 275 209 txgbe_reset(wx); 276 - if (wx->mac.type == wx_mac_aml) 210 + 211 + switch (wx->mac.type) { 212 + case wx_mac_aml40: 277 213 netif_carrier_off(wx->netdev); 278 - else 214 + break; 215 + case wx_mac_aml: 279 216 phylink_stop(wx->phylink); 217 + /* Disable TX laser */ 218 + wr32m(wx, WX_GPIO_DR, TXGBE_GPIOBIT_1, TXGBE_GPIOBIT_1); 219 + break; 220 + case wx_mac_sp: 221 + phylink_stop(wx->phylink); 222 + break; 223 + default: 224 + break; 225 + } 280 226 281 227 wx_clean_all_tx_rings(wx); 282 228 wx_clean_all_rx_rings(wx); ··· 318 240 case TXGBE_DEV_ID_AML5110: 319 241 case TXGBE_DEV_ID_AML5025: 320 242 case TXGBE_DEV_ID_AML5125: 243 + wx->mac.type = wx_mac_aml; 244 + break; 321 245 case TXGBE_DEV_ID_AML5040: 322 246 case TXGBE_DEV_ID_AML5140: 323 - wx->mac.type = wx_mac_aml; 247 + wx->mac.type = wx_mac_aml40; 324 248 break; 325 249 default: 326 250 wx->mac.type = wx_mac_unknown; ··· 331 251 332 252 switch (device_type) { 333 253 case TXGBE_ID_SFP: 334 - wx->media_type = sp_media_fiber; 254 + wx->media_type = wx_media_fiber; 335 255 break; 336 256 case TXGBE_ID_XAUI: 337 257 case TXGBE_ID_SGMII: 338 - wx->media_type = sp_media_copper; 258 + wx->media_type = wx_media_copper; 339 259 break; 340 260 case TXGBE_ID_KR_KX_KX4: 341 261 case TXGBE_ID_MAC_XAUI: 342 262 case TXGBE_ID_MAC_SGMII: 343 - wx->media_type = sp_media_backplane; 263 + wx->media_type = wx_media_backplane; 344 264 break; 345 265 case TXGBE_ID_SFI_XAUI: 346 266 if (wx->bus.func == 0) 347 - wx->media_type = sp_media_fiber; 267 + wx->media_type = wx_media_fiber; 348 268 else 349 - wx->media_type = sp_media_copper; 269 + wx->media_type = wx_media_copper; 350 270 break; 351 271 default: 352 - wx->media_type = sp_media_unknown; 272 + wx->media_type = wx_media_unknown; 353 273 break; 354 274 } 355 275 } ··· 363 283 u16 msix_count = 0; 364 284 int err; 365 285 366 - wx->mac.num_rar_entries = TXGBE_SP_RAR_ENTRIES; 367 - wx->mac.max_tx_queues = TXGBE_SP_MAX_TX_QUEUES; 368 - wx->mac.max_rx_queues = TXGBE_SP_MAX_RX_QUEUES; 369 - wx->mac.mcft_size = TXGBE_SP_MC_TBL_SIZE; 370 - wx->mac.vft_size = TXGBE_SP_VFT_TBL_SIZE; 371 - wx->mac.rx_pb_size = TXGBE_SP_RX_PB_SIZE; 372 - wx->mac.tx_pb_size = TXGBE_SP_TDB_PB_SZ; 286 + wx->mac.num_rar_entries = TXGBE_RAR_ENTRIES; 287 + wx->mac.max_tx_queues = TXGBE_MAX_TXQ; 288 + wx->mac.max_rx_queues = TXGBE_MAX_RXQ; 289 + wx->mac.mcft_size = TXGBE_MC_TBL_SIZE; 290 + wx->mac.vft_size = TXGBE_VFT_TBL_SIZE; 291 + wx->mac.rx_pb_size = TXGBE_RX_PB_SIZE; 292 + wx->mac.tx_pb_size = TXGBE_TDB_PB_SZ; 373 293 374 294 /* PCI config space info */ 375 295 err = wx_sw_init(wx); ··· 398 318 wx->configure_fdir = txgbe_configure_fdir; 399 319 400 320 set_bit(WX_FLAG_RSC_CAPABLE, wx->flags); 321 + set_bit(WX_FLAG_MULTI_64_FUNC, wx->flags); 401 322 402 323 /* enable itr by default in dynamic mode */ 403 324 wx->rx_itr_setting = 1; ··· 421 340 case wx_mac_sp: 422 341 break; 423 342 case wx_mac_aml: 343 + case wx_mac_aml40: 424 344 set_bit(WX_FLAG_SWFW_RING, wx->flags); 425 345 wx->swfw_index = 0; 426 346 break; ··· 817 735 eth_hw_addr_set(netdev, wx->mac.perm_addr); 818 736 wx_mac_set_default_filter(wx, wx->mac.perm_addr); 819 737 738 + txgbe_init_service(wx); 739 + 820 740 err = wx_init_interrupt_scheme(wx); 821 741 if (err) 822 - goto err_free_mac_table; 742 + goto err_cancel_service; 823 743 824 744 /* Save off EEPROM version number and Option Rom version which 825 745 * together make a unique identify for the eeprom ··· 863 779 864 780 if (etrack_id < 0x20010) 865 781 dev_warn(&pdev->dev, "Please upgrade the firmware to 0x20010 or above.\n"); 782 + 783 + err = txgbe_test_hostif(wx); 784 + if (err != 0) { 785 + dev_err(&pdev->dev, "Mismatched Firmware version\n"); 786 + err = -EIO; 787 + goto err_release_hw; 788 + } 866 789 867 790 txgbe = devm_kzalloc(&pdev->dev, sizeof(*txgbe), GFP_KERNEL); 868 791 if (!txgbe) { ··· 921 830 err_release_hw: 922 831 wx_clear_interrupt_scheme(wx); 923 832 wx_control_hw(wx, false); 833 + err_cancel_service: 834 + timer_delete_sync(&wx->service_timer); 835 + cancel_work_sync(&wx->service_task); 924 836 err_free_mac_table: 925 837 kfree(wx->rss_key); 926 838 kfree(wx->mac_table); ··· 949 855 struct wx *wx = pci_get_drvdata(pdev); 950 856 struct txgbe *txgbe = wx->priv; 951 857 struct net_device *netdev; 858 + 859 + cancel_work_sync(&wx->service_task); 952 860 953 861 netdev = wx->netdev; 954 862 wx_disable_sriov(wx);
+30 -11
drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
··· 20 20 #include "../libwx/wx_mbx.h" 21 21 #include "../libwx/wx_hw.h" 22 22 #include "txgbe_type.h" 23 + #include "txgbe_aml.h" 23 24 #include "txgbe_phy.h" 24 25 #include "txgbe_hw.h" 25 26 ··· 166 165 struct wx *wx = phylink_to_wx(config); 167 166 struct txgbe *txgbe = wx->priv; 168 167 169 - if (wx->media_type != sp_media_copper) 168 + if (wx->media_type != wx_media_copper) 170 169 return txgbe->pcs; 171 170 172 171 return NULL; ··· 279 278 config->mac_capabilities = MAC_10000FD | MAC_1000FD | MAC_100FD | 280 279 MAC_SYM_PAUSE | MAC_ASYM_PAUSE; 281 280 282 - if (wx->media_type == sp_media_copper) { 281 + if (wx->media_type == wx_media_copper) { 283 282 phy_mode = PHY_INTERFACE_MODE_XAUI; 284 283 __set_bit(PHY_INTERFACE_MODE_XAUI, config->supported_interfaces); 285 284 } else { ··· 319 318 status = rd32(wx, TXGBE_CFG_PORT_ST); 320 319 up = !!(status & TXGBE_CFG_PORT_ST_LINK_UP); 321 320 322 - phylink_pcs_change(txgbe->pcs, up); 321 + if (txgbe->pcs) 322 + phylink_pcs_change(txgbe->pcs, up); 323 + else 324 + phylink_mac_change(wx->phylink, up); 323 325 324 326 return IRQ_HANDLED; 325 327 } ··· 577 573 struct wx *wx = txgbe->wx; 578 574 int ret; 579 575 580 - if (wx->mac.type == wx_mac_aml) 576 + switch (wx->mac.type) { 577 + case wx_mac_aml40: 581 578 return 0; 582 - 583 - if (txgbe->wx->media_type == sp_media_copper) 584 - return txgbe_ext_phy_init(txgbe); 579 + case wx_mac_aml: 580 + return txgbe_phylink_init_aml(txgbe); 581 + case wx_mac_sp: 582 + if (wx->media_type == wx_media_copper) 583 + return txgbe_ext_phy_init(txgbe); 584 + break; 585 + default: 586 + break; 587 + } 585 588 586 589 ret = txgbe_swnodes_register(txgbe); 587 590 if (ret) { ··· 651 640 652 641 void txgbe_remove_phy(struct txgbe *txgbe) 653 642 { 654 - if (txgbe->wx->mac.type == wx_mac_aml) 643 + switch (txgbe->wx->mac.type) { 644 + case wx_mac_aml40: 655 645 return; 656 - 657 - if (txgbe->wx->media_type == sp_media_copper) { 658 - phylink_disconnect_phy(txgbe->wx->phylink); 646 + case wx_mac_aml: 659 647 phylink_destroy(txgbe->wx->phylink); 660 648 return; 649 + case wx_mac_sp: 650 + if (txgbe->wx->media_type == wx_media_copper) { 651 + phylink_disconnect_phy(txgbe->wx->phylink); 652 + phylink_destroy(txgbe->wx->phylink); 653 + return; 654 + } 655 + break; 656 + default: 657 + break; 661 658 } 662 659 663 660 platform_device_unregister(txgbe->sfp_dev);
+97 -9
drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
··· 6 6 7 7 #include <linux/property.h> 8 8 #include <linux/irq.h> 9 + #include <linux/phy.h> 10 + #include "../libwx/wx_type.h" 9 11 10 12 /* Device IDs */ 11 13 #define TXGBE_DEV_ID_SP1000 0x1001 ··· 52 50 53 51 /**************** SP Registers ****************************/ 54 52 /* chip control Registers */ 53 + #define TXGBE_MIS_RST 0x1000C 54 + #define TXGBE_MIS_RST_MAC_RST(_i) BIT(20 - (_i) * 3) 55 55 #define TXGBE_MIS_PRB_CTL 0x10010 56 56 #define TXGBE_MIS_PRB_CTL_LAN_UP(_i) BIT(1 - (_i)) 57 57 /* FMGR Registers */ ··· 66 62 #define TXGBE_TS_CTL 0x10300 67 63 #define TXGBE_TS_CTL_EVAL_MD BIT(31) 68 64 65 + /* MAC Misc Registers */ 66 + #define TXGBE_MAC_MISC_CTL 0x11F00 67 + #define TXGBE_MAC_MISC_CTL_LINK_STS_MOD BIT(0) 68 + #define TXGBE_MAC_MISC_CTL_LINK_PCS FIELD_PREP(BIT(0), 0) 69 + #define TXGBE_MAC_MISC_CTL_LINK_BOTH FIELD_PREP(BIT(0), 1) 69 70 /* GPIO register bit */ 70 71 #define TXGBE_GPIOBIT_0 BIT(0) /* I:tx fault */ 71 72 #define TXGBE_GPIOBIT_1 BIT(1) /* O:tx disabled */ ··· 82 73 /* Extended Interrupt Enable Set */ 83 74 #define TXGBE_PX_MISC_ETH_LKDN BIT(8) 84 75 #define TXGBE_PX_MISC_DEV_RST BIT(10) 76 + #define TXGBE_PX_MISC_IC_TIMESYNC BIT(11) 85 77 #define TXGBE_PX_MISC_ETH_EVENT BIT(17) 86 78 #define TXGBE_PX_MISC_ETH_LK BIT(18) 87 79 #define TXGBE_PX_MISC_ETH_AN BIT(19) ··· 93 83 (TXGBE_PX_MISC_ETH_LKDN | TXGBE_PX_MISC_DEV_RST | \ 94 84 TXGBE_PX_MISC_ETH_EVENT | TXGBE_PX_MISC_ETH_LK | \ 95 85 TXGBE_PX_MISC_ETH_AN | TXGBE_PX_MISC_INT_ERR | \ 96 - TXGBE_PX_MISC_IC_VF_MBOX) 86 + TXGBE_PX_MISC_IC_VF_MBOX | TXGBE_PX_MISC_IC_TIMESYNC) 97 87 98 88 /* Port cfg registers */ 99 89 #define TXGBE_CFG_PORT_ST 0x14404 100 90 #define TXGBE_CFG_PORT_ST_LINK_UP BIT(0) 91 + #define TXGBE_CFG_PORT_ST_LINK_AML_25G BIT(3) 92 + #define TXGBE_CFG_PORT_ST_LINK_AML_10G BIT(4) 101 93 #define TXGBE_CFG_VXLAN 0x14410 102 94 #define TXGBE_CFG_VXLAN_GPE 0x14414 103 95 #define TXGBE_CFG_GENEVE 0x14418 ··· 163 151 /*************************** Amber Lite Registers ****************************/ 164 152 #define TXGBE_PX_PF_BME 0x4B8 165 153 #define TXGBE_AML_MAC_TX_CFG 0x11000 154 + #define TXGBE_AML_MAC_TX_CFG_TE BIT(0) 166 155 #define TXGBE_AML_MAC_TX_CFG_SPEED_MASK GENMASK(30, 27) 167 - #define TXGBE_AML_MAC_TX_CFG_SPEED_25G BIT(28) 156 + #define TXGBE_AML_MAC_TX_CFG_SPEED_40G FIELD_PREP(GENMASK(30, 27), 0) 157 + #define TXGBE_AML_MAC_TX_CFG_SPEED_25G FIELD_PREP(GENMASK(30, 27), 2) 158 + #define TXGBE_AML_MAC_TX_CFG_SPEED_10G FIELD_PREP(GENMASK(30, 27), 8) 168 159 #define TXGBE_RDM_RSC_CTL 0x1200C 169 160 #define TXGBE_RDM_RSC_CTL_FREE_CTL BIT(7) 170 161 ··· 188 173 #define TXGBE_MAX_RX_QUEUES (TXGBE_MAX_FDIR_INDICES + 1) 189 174 #define TXGBE_MAX_TX_QUEUES (TXGBE_MAX_FDIR_INDICES + 1) 190 175 191 - #define TXGBE_SP_MAX_TX_QUEUES 128 192 - #define TXGBE_SP_MAX_RX_QUEUES 128 193 - #define TXGBE_SP_RAR_ENTRIES 128 194 - #define TXGBE_SP_MC_TBL_SIZE 128 195 - #define TXGBE_SP_VFT_TBL_SIZE 128 196 - #define TXGBE_SP_RX_PB_SIZE 512 197 - #define TXGBE_SP_TDB_PB_SZ (160 * 1024) /* 160KB Packet Buffer */ 176 + #define TXGBE_MAX_TXQ 128 177 + #define TXGBE_MAX_RXQ 128 178 + #define TXGBE_RAR_ENTRIES 128 179 + #define TXGBE_MC_TBL_SIZE 128 180 + #define TXGBE_VFT_TBL_SIZE 128 181 + #define TXGBE_RX_PB_SIZE 512 182 + #define TXGBE_TDB_PB_SZ (160 * 1024) /* 160KB Packet Buffer */ 198 183 199 184 #define TXGBE_MAX_VFS_DRV_LIMIT 63 200 185 ··· 314 299 int txgbe_setup_tc(struct net_device *dev, u8 tc); 315 300 void txgbe_do_reset(struct net_device *netdev); 316 301 302 + #define TXGBE_LINK_SPEED_10GB_FULL 4 303 + #define TXGBE_LINK_SPEED_25GB_FULL 0x10 304 + 305 + #define TXGBE_SFF_IDENTIFIER_SFP 0x3 306 + #define TXGBE_SFF_DA_PASSIVE_CABLE 0x4 307 + #define TXGBE_SFF_DA_ACTIVE_CABLE 0x8 308 + #define TXGBE_SFF_DA_SPEC_ACTIVE_LIMIT 0x4 309 + #define TXGBE_SFF_FCPI4_LIMITING 0x3 310 + #define TXGBE_SFF_10GBASESR_CAPABLE 0x10 311 + #define TXGBE_SFF_10GBASELR_CAPABLE 0x20 312 + #define TXGBE_SFF_25GBASESR_CAPABLE 0x2 313 + #define TXGBE_SFF_25GBASELR_CAPABLE 0x3 314 + #define TXGBE_SFF_25GBASEER_CAPABLE 0x4 315 + #define TXGBE_SFF_25GBASECR_91FEC 0xB 316 + #define TXGBE_SFF_25GBASECR_74FEC 0xC 317 + #define TXGBE_SFF_25GBASECR_NOFEC 0xD 318 + 319 + #define TXGBE_PHY_FEC_RS BIT(0) 320 + #define TXGBE_PHY_FEC_BASER BIT(1) 321 + #define TXGBE_PHY_FEC_OFF BIT(2) 322 + #define TXGBE_PHY_FEC_AUTO (TXGBE_PHY_FEC_OFF | \ 323 + TXGBE_PHY_FEC_BASER |\ 324 + TXGBE_PHY_FEC_RS) 325 + 326 + #define FW_PHY_GET_LINK_CMD 0xC0 327 + #define FW_PHY_SET_LINK_CMD 0xC1 328 + #define FW_READ_SFP_INFO_CMD 0xC5 329 + 330 + struct txgbe_sfp_id { 331 + u8 identifier; /* A0H 0x00 */ 332 + u8 com_1g_code; /* A0H 0x06 */ 333 + u8 com_10g_code; /* A0H 0x03 */ 334 + u8 com_25g_code; /* A0H 0x24 */ 335 + u8 cable_spec; /* A0H 0x3C */ 336 + u8 cable_tech; /* A0H 0x08 */ 337 + u8 vendor_oui0; /* A0H 0x25 */ 338 + u8 vendor_oui1; /* A0H 0x26 */ 339 + u8 vendor_oui2; /* A0H 0x27 */ 340 + u8 reserved[3]; 341 + }; 342 + 343 + struct txgbe_hic_i2c_read { 344 + struct wx_hic_hdr hdr; 345 + struct txgbe_sfp_id id; 346 + }; 347 + 348 + struct txgbe_hic_ephy_setlink { 349 + struct wx_hic_hdr hdr; 350 + u8 speed; 351 + u8 duplex; 352 + u8 autoneg; 353 + u8 fec_mode; 354 + u8 resv[4]; 355 + }; 356 + 357 + struct txgbe_hic_ephy_getlink { 358 + struct wx_hic_hdr hdr; 359 + u8 speed; 360 + u8 duplex; 361 + u8 autoneg; 362 + u8 flow_ctl; 363 + u8 power; 364 + u8 fec_mode; 365 + u8 resv[6]; 366 + }; 367 + 317 368 #define NODE_PROP(_NAME, _PROP) \ 318 369 (const struct software_node) { \ 319 370 .name = _NAME, \ ··· 417 336 418 337 enum txgbe_misc_irqs { 419 338 TXGBE_IRQ_LINK = 0, 339 + TXGBE_IRQ_GPIO, 420 340 TXGBE_IRQ_MAX 421 341 }; 422 342 ··· 439 357 struct clk *clk; 440 358 struct gpio_chip *gpio; 441 359 unsigned int link_irq; 360 + unsigned int gpio_irq; 442 361 u32 eicr; 443 362 444 363 /* flow director */ ··· 447 364 union txgbe_atr_input fdir_mask; 448 365 int fdir_filter_count; 449 366 spinlock_t fdir_perfect_lock; /* spinlock for FDIR */ 367 + 368 + DECLARE_PHY_INTERFACE_MASK(sfp_interfaces); 369 + __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support); 370 + __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising); 371 + u8 link_port; 450 372 }; 451 373 452 374 #endif /* _TXGBE_TYPE_H_ */