mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 11:03:43 +02:00
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>
This commit is contained in:
commit
e272bbc9bf
|
|
@ -219,7 +219,7 @@ int wx_nway_reset(struct net_device *netdev)
|
|||
{
|
||||
struct wx *wx = netdev_priv(netdev);
|
||||
|
||||
if (wx->mac.type == wx_mac_aml)
|
||||
if (wx->mac.type == wx_mac_aml40)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return phylink_ethtool_nway_reset(wx->phylink);
|
||||
|
|
@ -231,9 +231,6 @@ int wx_get_link_ksettings(struct net_device *netdev,
|
|||
{
|
||||
struct wx *wx = netdev_priv(netdev);
|
||||
|
||||
if (wx->mac.type == wx_mac_aml)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return phylink_ethtool_ksettings_get(wx->phylink, cmd);
|
||||
}
|
||||
EXPORT_SYMBOL(wx_get_link_ksettings);
|
||||
|
|
@ -243,7 +240,7 @@ int wx_set_link_ksettings(struct net_device *netdev,
|
|||
{
|
||||
struct wx *wx = netdev_priv(netdev);
|
||||
|
||||
if (wx->mac.type == wx_mac_aml)
|
||||
if (wx->mac.type == wx_mac_aml40)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return phylink_ethtool_ksettings_set(wx->phylink, cmd);
|
||||
|
|
@ -255,7 +252,7 @@ void wx_get_pauseparam(struct net_device *netdev,
|
|||
{
|
||||
struct wx *wx = netdev_priv(netdev);
|
||||
|
||||
if (wx->mac.type == wx_mac_aml)
|
||||
if (wx->mac.type == wx_mac_aml40)
|
||||
return;
|
||||
|
||||
phylink_ethtool_get_pauseparam(wx->phylink, pause);
|
||||
|
|
@ -267,7 +264,7 @@ int wx_set_pauseparam(struct net_device *netdev,
|
|||
{
|
||||
struct wx *wx = netdev_priv(netdev);
|
||||
|
||||
if (wx->mac.type == wx_mac_aml)
|
||||
if (wx->mac.type == wx_mac_aml40)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return phylink_ethtool_set_pauseparam(wx->phylink, pause);
|
||||
|
|
@ -345,6 +342,7 @@ int wx_set_coalesce(struct net_device *netdev,
|
|||
max_eitr = WX_SP_MAX_EITR;
|
||||
break;
|
||||
case wx_mac_aml:
|
||||
case wx_mac_aml40:
|
||||
max_eitr = WX_AML_MAX_EITR;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -375,6 +373,7 @@ int wx_set_coalesce(struct net_device *netdev,
|
|||
switch (wx->mac.type) {
|
||||
case wx_mac_sp:
|
||||
case wx_mac_aml:
|
||||
case wx_mac_aml40:
|
||||
tx_itr_param = WX_12K_ITR;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -413,15 +412,10 @@ static unsigned int wx_max_channels(struct wx *wx)
|
|||
max_combined = 1;
|
||||
} else {
|
||||
/* support up to max allowed queues with RSS */
|
||||
switch (wx->mac.type) {
|
||||
case wx_mac_sp:
|
||||
case wx_mac_aml:
|
||||
if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags))
|
||||
max_combined = 63;
|
||||
break;
|
||||
default:
|
||||
else
|
||||
max_combined = 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return max_combined;
|
||||
|
|
|
|||
|
|
@ -113,15 +113,10 @@ static void wx_intr_disable(struct wx *wx, u64 qmask)
|
|||
if (mask)
|
||||
wr32(wx, WX_PX_IMS(0), mask);
|
||||
|
||||
switch (wx->mac.type) {
|
||||
case wx_mac_sp:
|
||||
case wx_mac_aml:
|
||||
if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) {
|
||||
mask = (qmask >> 32);
|
||||
if (mask)
|
||||
wr32(wx, WX_PX_IMS(1), mask);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -133,15 +128,10 @@ void wx_intr_enable(struct wx *wx, u64 qmask)
|
|||
if (mask)
|
||||
wr32(wx, WX_PX_IMC(0), mask);
|
||||
|
||||
switch (wx->mac.type) {
|
||||
case wx_mac_sp:
|
||||
case wx_mac_aml:
|
||||
if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) {
|
||||
mask = (qmask >> 32);
|
||||
if (mask)
|
||||
wr32(wx, WX_PX_IMC(1), mask);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(wx_intr_enable);
|
||||
|
|
@ -705,6 +695,7 @@ void wx_init_eeprom_params(struct wx *wx)
|
|||
switch (wx->mac.type) {
|
||||
case wx_mac_sp:
|
||||
case wx_mac_aml:
|
||||
case wx_mac_aml40:
|
||||
if (wx_read_ee_hostif(wx, WX_SW_REGION_PTR, &data)) {
|
||||
wx_err(wx, "NVM Read Error\n");
|
||||
return;
|
||||
|
|
@ -774,14 +765,8 @@ static int wx_set_rar(struct wx *wx, u32 index, u8 *addr, u64 pools,
|
|||
/* setup VMDq pool mapping */
|
||||
wr32(wx, WX_PSR_MAC_SWC_VM_L, pools & 0xFFFFFFFF);
|
||||
|
||||
switch (wx->mac.type) {
|
||||
case wx_mac_sp:
|
||||
case wx_mac_aml:
|
||||
if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags))
|
||||
wr32(wx, WX_PSR_MAC_SWC_VM_H, pools >> 32);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* HW expects these in little endian so we reverse the byte
|
||||
* order from network order (big endian) to little endian
|
||||
|
|
@ -919,14 +904,9 @@ void wx_init_rx_addrs(struct wx *wx)
|
|||
|
||||
wx_set_rar(wx, 0, wx->mac.addr, 0, WX_PSR_MAC_SWC_AD_H_AV);
|
||||
|
||||
switch (wx->mac.type) {
|
||||
case wx_mac_sp:
|
||||
case wx_mac_aml:
|
||||
if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) {
|
||||
/* clear VMDq pool/queue selection for RAR 0 */
|
||||
wx_clear_vmdq(wx, 0, WX_CLEAR_VMDQ_ALL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1512,7 +1492,7 @@ static void wx_configure_virtualization(struct wx *wx)
|
|||
wr32m(wx, WX_PSR_VM_L2CTL(pool),
|
||||
WX_PSR_VM_L2CTL_AUPE, WX_PSR_VM_L2CTL_AUPE);
|
||||
|
||||
if (wx->mac.type == wx_mac_em) {
|
||||
if (!test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) {
|
||||
vf_shift = BIT(VMDQ_P(0));
|
||||
/* Enable only the PF pools for Tx/Rx */
|
||||
wr32(wx, WX_RDM_VF_RE(0), vf_shift);
|
||||
|
|
@ -1543,7 +1523,7 @@ static void wx_configure_port(struct wx *wx)
|
|||
{
|
||||
u32 value, i;
|
||||
|
||||
if (wx->mac.type == wx_mac_em) {
|
||||
if (!test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) {
|
||||
value = (wx->num_vfs == 0) ?
|
||||
WX_CFG_PORT_CTL_NUM_VT_NONE :
|
||||
WX_CFG_PORT_CTL_NUM_VT_8;
|
||||
|
|
@ -2074,7 +2054,7 @@ static void wx_setup_psrtype(struct wx *wx)
|
|||
WX_RDB_PL_CFG_TUN_OUTL2HDR |
|
||||
WX_RDB_PL_CFG_TUN_TUNHDR;
|
||||
|
||||
if (wx->mac.type == wx_mac_em) {
|
||||
if (!test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) {
|
||||
for_each_set_bit(pool, &wx->fwd_bitmask, 8)
|
||||
wr32(wx, WX_RDB_PL_CFG(VMDQ_P(pool)), psrtype);
|
||||
} else {
|
||||
|
|
@ -2272,10 +2252,8 @@ int wx_stop_adapter(struct wx *wx)
|
|||
}
|
||||
EXPORT_SYMBOL(wx_stop_adapter);
|
||||
|
||||
void wx_reset_misc(struct wx *wx)
|
||||
void wx_reset_mac(struct wx *wx)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* receive packets that size > 2048 */
|
||||
wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_JE, WX_MAC_RX_CFG_JE);
|
||||
|
||||
|
|
@ -2287,6 +2265,14 @@ void wx_reset_misc(struct wx *wx)
|
|||
WX_MAC_RX_FLOW_CTRL_RFE, WX_MAC_RX_FLOW_CTRL_RFE);
|
||||
|
||||
wr32(wx, WX_MAC_PKT_FLT, WX_MAC_PKT_FLT_PR);
|
||||
}
|
||||
EXPORT_SYMBOL(wx_reset_mac);
|
||||
|
||||
void wx_reset_misc(struct wx *wx)
|
||||
{
|
||||
int i;
|
||||
|
||||
wx_reset_mac(wx);
|
||||
|
||||
wr32m(wx, WX_MIS_RST_ST,
|
||||
WX_MIS_RST_ST_RST_INIT, 0x1E00);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ void wx_configure(struct wx *wx);
|
|||
void wx_start_hw(struct wx *wx);
|
||||
int wx_disable_pcie_master(struct wx *wx);
|
||||
int wx_stop_adapter(struct wx *wx);
|
||||
void wx_reset_mac(struct wx *wx);
|
||||
void wx_reset_misc(struct wx *wx);
|
||||
int wx_get_pcie_msix_counts(struct wx *wx, u16 *msix_count, u16 max_msix_count);
|
||||
int wx_sw_init(struct wx *wx);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <net/ip6_checksum.h>
|
||||
#include <net/page_pool/helpers.h>
|
||||
#include <net/inet_ecn.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/sctp.h>
|
||||
#include <linux/pci.h>
|
||||
|
|
@ -1633,7 +1634,7 @@ static bool wx_set_vmdq_queues(struct wx *wx)
|
|||
/* Add starting offset to total pool count */
|
||||
vmdq_i += wx->ring_feature[RING_F_VMDQ].offset;
|
||||
|
||||
if (wx->mac.type == wx_mac_sp) {
|
||||
if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) {
|
||||
/* double check we are limited to maximum pools */
|
||||
vmdq_i = min_t(u16, 64, vmdq_i);
|
||||
|
||||
|
|
@ -1693,7 +1694,7 @@ static void wx_set_rss_queues(struct wx *wx)
|
|||
|
||||
/* set mask for 16 queue limit of RSS */
|
||||
f = &wx->ring_feature[RING_F_RSS];
|
||||
if (wx->mac.type == wx_mac_sp)
|
||||
if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags))
|
||||
f->mask = WX_RSS_64Q_MASK;
|
||||
else
|
||||
f->mask = WX_RSS_8Q_MASK;
|
||||
|
|
@ -1853,7 +1854,7 @@ static bool wx_cache_ring_vmdq(struct wx *wx)
|
|||
if (!test_bit(WX_FLAG_VMDQ_ENABLED, wx->flags))
|
||||
return false;
|
||||
|
||||
if (wx->mac.type == wx_mac_sp) {
|
||||
if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) {
|
||||
/* start at VMDq register offset for SR-IOV enabled setups */
|
||||
reg_idx = vmdq->offset * __ALIGN_MASK(1, ~vmdq->mask);
|
||||
for (i = 0; i < wx->num_rx_queues; i++, reg_idx++) {
|
||||
|
|
@ -1959,6 +1960,7 @@ static int wx_alloc_q_vector(struct wx *wx,
|
|||
switch (wx->mac.type) {
|
||||
case wx_mac_sp:
|
||||
case wx_mac_aml:
|
||||
case wx_mac_aml40:
|
||||
default_itr = WX_12K_ITR;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -2327,6 +2329,7 @@ void wx_write_eitr(struct wx_q_vector *q_vector)
|
|||
itr_reg = q_vector->itr & WX_SP_MAX_EITR;
|
||||
break;
|
||||
case wx_mac_aml:
|
||||
case wx_mac_aml40:
|
||||
itr_reg = (q_vector->itr >> 3) & WX_AML_MAX_EITR;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -2354,10 +2357,10 @@ void wx_configure_vectors(struct wx *wx)
|
|||
|
||||
if (pdev->msix_enabled) {
|
||||
/* Populate MSIX to EITR Select */
|
||||
if (wx->mac.type == wx_mac_sp) {
|
||||
if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) {
|
||||
if (wx->num_vfs >= 32)
|
||||
eitrsel = BIT(wx->num_vfs % 32) - 1;
|
||||
} else if (wx->mac.type == wx_mac_em) {
|
||||
} else {
|
||||
for (i = 0; i < wx->num_vfs; i++)
|
||||
eitrsel |= BIT(i);
|
||||
}
|
||||
|
|
@ -3093,5 +3096,35 @@ void wx_set_ring(struct wx *wx, u32 new_tx_count,
|
|||
}
|
||||
EXPORT_SYMBOL(wx_set_ring);
|
||||
|
||||
void wx_service_event_schedule(struct wx *wx)
|
||||
{
|
||||
if (!test_and_set_bit(WX_STATE_SERVICE_SCHED, wx->state))
|
||||
queue_work(system_power_efficient_wq, &wx->service_task);
|
||||
}
|
||||
EXPORT_SYMBOL(wx_service_event_schedule);
|
||||
|
||||
void wx_service_event_complete(struct wx *wx)
|
||||
{
|
||||
if (WARN_ON(!test_bit(WX_STATE_SERVICE_SCHED, wx->state)))
|
||||
return;
|
||||
|
||||
/* flush memory to make sure state is correct before next watchdog */
|
||||
smp_mb__before_atomic();
|
||||
clear_bit(WX_STATE_SERVICE_SCHED, wx->state);
|
||||
}
|
||||
EXPORT_SYMBOL(wx_service_event_complete);
|
||||
|
||||
void wx_service_timer(struct timer_list *t)
|
||||
{
|
||||
struct wx *wx = from_timer(wx, t, service_timer);
|
||||
unsigned long next_event_offset = HZ * 2;
|
||||
|
||||
/* Reset the timer */
|
||||
mod_timer(&wx->service_timer, next_event_offset + jiffies);
|
||||
|
||||
wx_service_event_schedule(wx);
|
||||
}
|
||||
EXPORT_SYMBOL(wx_service_timer);
|
||||
|
||||
MODULE_DESCRIPTION("Common library for Wangxun(R) Ethernet drivers.");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -38,5 +38,8 @@ netdev_features_t wx_features_check(struct sk_buff *skb,
|
|||
netdev_features_t features);
|
||||
void wx_set_ring(struct wx *wx, u32 new_tx_count,
|
||||
u32 new_rx_count, struct wx_ring *temp_ring);
|
||||
void wx_service_event_schedule(struct wx *wx);
|
||||
void wx_service_event_complete(struct wx *wx);
|
||||
void wx_service_timer(struct timer_list *t);
|
||||
|
||||
#endif /* _WX_LIB_H_ */
|
||||
|
|
|
|||
|
|
@ -15,12 +15,14 @@
|
|||
#define WX_INCVAL_100 0xA00000
|
||||
#define WX_INCVAL_10 0xC7F380
|
||||
#define WX_INCVAL_EM 0x2000000
|
||||
#define WX_INCVAL_AML 0xA00000
|
||||
|
||||
#define WX_INCVAL_SHIFT_10GB 20
|
||||
#define WX_INCVAL_SHIFT_1GB 18
|
||||
#define WX_INCVAL_SHIFT_100 15
|
||||
#define WX_INCVAL_SHIFT_10 12
|
||||
#define WX_INCVAL_SHIFT_EM 22
|
||||
#define WX_INCVAL_SHIFT_AML 21
|
||||
|
||||
#define WX_OVERFLOW_PERIOD (HZ * 30)
|
||||
#define WX_PTP_TX_TIMEOUT (HZ)
|
||||
|
|
@ -504,15 +506,27 @@ static long wx_ptp_create_clock(struct wx *wx)
|
|||
wx->ptp_caps.gettimex64 = wx_ptp_gettimex64;
|
||||
wx->ptp_caps.settime64 = wx_ptp_settime64;
|
||||
wx->ptp_caps.do_aux_work = wx_ptp_do_aux_work;
|
||||
if (wx->mac.type == wx_mac_em) {
|
||||
switch (wx->mac.type) {
|
||||
case wx_mac_aml:
|
||||
case wx_mac_aml40:
|
||||
wx->ptp_caps.max_adj = 250000000;
|
||||
wx->ptp_caps.n_per_out = 1;
|
||||
wx->ptp_setup_sdp = wx_ptp_setup_sdp;
|
||||
wx->ptp_caps.enable = wx_ptp_feature_enable;
|
||||
break;
|
||||
case wx_mac_sp:
|
||||
wx->ptp_caps.max_adj = 250000000;
|
||||
wx->ptp_caps.n_per_out = 0;
|
||||
wx->ptp_setup_sdp = NULL;
|
||||
break;
|
||||
case wx_mac_em:
|
||||
wx->ptp_caps.max_adj = 500000000;
|
||||
wx->ptp_caps.n_per_out = 1;
|
||||
wx->ptp_setup_sdp = wx_ptp_setup_sdp;
|
||||
wx->ptp_caps.enable = wx_ptp_feature_enable;
|
||||
} else {
|
||||
wx->ptp_caps.max_adj = 250000000;
|
||||
wx->ptp_caps.n_per_out = 0;
|
||||
wx->ptp_setup_sdp = NULL;
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
wx->ptp_clock = ptp_clock_register(&wx->ptp_caps, &wx->pdev->dev);
|
||||
|
|
@ -647,10 +661,18 @@ static u64 wx_ptp_read(const struct cyclecounter *hw_cc)
|
|||
|
||||
static void wx_ptp_link_speed_adjust(struct wx *wx, u32 *shift, u32 *incval)
|
||||
{
|
||||
if (wx->mac.type == wx_mac_em) {
|
||||
switch (wx->mac.type) {
|
||||
case wx_mac_aml:
|
||||
case wx_mac_aml40:
|
||||
*shift = WX_INCVAL_SHIFT_AML;
|
||||
*incval = WX_INCVAL_AML;
|
||||
return;
|
||||
case wx_mac_em:
|
||||
*shift = WX_INCVAL_SHIFT_EM;
|
||||
*incval = WX_INCVAL_EM;
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (wx->speed) {
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ static int __wx_enable_sriov(struct wx *wx, u8 num_vfs)
|
|||
wx->vfinfo[i].xcast_mode = WXVF_XCAST_MODE_NONE;
|
||||
}
|
||||
|
||||
if (wx->mac.type == wx_mac_em) {
|
||||
if (!test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) {
|
||||
value = WX_CFG_PORT_CTL_NUM_VT_8;
|
||||
} else {
|
||||
if (num_vfs < 32)
|
||||
|
|
@ -599,10 +599,10 @@ static int wx_set_vf_vlan_msg(struct wx *wx, u32 *msgbuf, u16 vf)
|
|||
if (VMDQ_P(0) < 32) {
|
||||
bits = rd32(wx, WX_PSR_VLAN_SWC_VM_L);
|
||||
bits &= ~BIT(VMDQ_P(0));
|
||||
if (wx->mac.type != wx_mac_em)
|
||||
if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags))
|
||||
bits |= rd32(wx, WX_PSR_VLAN_SWC_VM_H);
|
||||
} else {
|
||||
if (wx->mac.type != wx_mac_em)
|
||||
if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags))
|
||||
bits = rd32(wx, WX_PSR_VLAN_SWC_VM_H);
|
||||
bits &= ~BIT(VMDQ_P(0) % 32);
|
||||
bits |= rd32(wx, WX_PSR_VLAN_SWC_VM_L);
|
||||
|
|
@ -848,7 +848,7 @@ void wx_disable_vf_rx_tx(struct wx *wx)
|
|||
{
|
||||
wr32(wx, WX_TDM_VFTE_CLR(0), U32_MAX);
|
||||
wr32(wx, WX_RDM_VFRE_CLR(0), U32_MAX);
|
||||
if (wx->mac.type != wx_mac_em) {
|
||||
if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) {
|
||||
wr32(wx, WX_TDM_VFTE_CLR(1), U32_MAX);
|
||||
wr32(wx, WX_RDM_VFRE_CLR(1), U32_MAX);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -838,13 +838,14 @@ enum wx_mac_type {
|
|||
wx_mac_sp,
|
||||
wx_mac_em,
|
||||
wx_mac_aml,
|
||||
wx_mac_aml40,
|
||||
};
|
||||
|
||||
enum sp_media_type {
|
||||
sp_media_unknown = 0,
|
||||
sp_media_fiber,
|
||||
sp_media_copper,
|
||||
sp_media_backplane
|
||||
enum wx_media_type {
|
||||
wx_media_unknown = 0,
|
||||
wx_media_fiber,
|
||||
wx_media_copper,
|
||||
wx_media_backplane
|
||||
};
|
||||
|
||||
enum em_mac_type {
|
||||
|
|
@ -1153,6 +1154,7 @@ enum wx_state {
|
|||
WX_STATE_SWFW_BUSY,
|
||||
WX_STATE_PTP_RUNNING,
|
||||
WX_STATE_PTP_TX_IN_PROGRESS,
|
||||
WX_STATE_SERVICE_SCHED,
|
||||
WX_STATE_NBITS /* must be last */
|
||||
};
|
||||
|
||||
|
|
@ -1184,6 +1186,7 @@ struct vf_macvlans {
|
|||
};
|
||||
|
||||
enum wx_pf_flags {
|
||||
WX_FLAG_MULTI_64_FUNC,
|
||||
WX_FLAG_SWFW_RING,
|
||||
WX_FLAG_VMDQ_ENABLED,
|
||||
WX_FLAG_VLAN_PROMISC,
|
||||
|
|
@ -1195,6 +1198,8 @@ enum wx_pf_flags {
|
|||
WX_FLAG_RX_HWTSTAMP_ENABLED,
|
||||
WX_FLAG_RX_HWTSTAMP_IN_REGISTER,
|
||||
WX_FLAG_PTP_PPS_ENABLED,
|
||||
WX_FLAG_NEED_LINK_CONFIG,
|
||||
WX_FLAG_NEED_SFP_RESET,
|
||||
WX_PF_FLAGS_NBITS /* must be last */
|
||||
};
|
||||
|
||||
|
|
@ -1211,7 +1216,7 @@ struct wx {
|
|||
struct wx_mbx_info mbx;
|
||||
struct wx_mac_info mac;
|
||||
enum em_mac_type mac_type;
|
||||
enum sp_media_type media_type;
|
||||
enum wx_media_type media_type;
|
||||
struct wx_eeprom_info eeprom;
|
||||
struct wx_addr_filter_info addr_ctrl;
|
||||
struct wx_fc_info fc;
|
||||
|
|
@ -1233,6 +1238,8 @@ struct wx {
|
|||
|
||||
/* PHY stuff */
|
||||
bool notify_down;
|
||||
int adv_speed;
|
||||
int adv_duplex;
|
||||
unsigned int link;
|
||||
int speed;
|
||||
int duplex;
|
||||
|
|
@ -1330,6 +1337,9 @@ struct wx {
|
|||
struct ptp_clock_info ptp_caps;
|
||||
struct kernel_hwtstamp_config tstamp_config;
|
||||
struct sk_buff *ptp_tx_skb;
|
||||
|
||||
struct timer_list service_timer;
|
||||
struct work_struct service_task;
|
||||
};
|
||||
|
||||
#define WX_INTR_ALL (~0ULL)
|
||||
|
|
|
|||
|
|
@ -11,4 +11,5 @@ txgbe-objs := txgbe_main.o \
|
|||
txgbe_phy.o \
|
||||
txgbe_irq.o \
|
||||
txgbe_fdir.o \
|
||||
txgbe_ethtool.o
|
||||
txgbe_ethtool.o \
|
||||
txgbe_aml.o
|
||||
|
|
|
|||
385
drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
Normal file
385
drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
Normal file
|
|
@ -0,0 +1,385 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2015 - 2025 Beijing WangXun Technology Co., Ltd. */
|
||||
|
||||
#include <linux/phylink.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
#include "../libwx/wx_type.h"
|
||||
#include "../libwx/wx_lib.h"
|
||||
#include "../libwx/wx_ptp.h"
|
||||
#include "../libwx/wx_hw.h"
|
||||
#include "../libwx/wx_sriov.h"
|
||||
#include "txgbe_type.h"
|
||||
#include "txgbe_aml.h"
|
||||
#include "txgbe_hw.h"
|
||||
|
||||
void txgbe_gpio_init_aml(struct wx *wx)
|
||||
{
|
||||
u32 status;
|
||||
|
||||
wr32(wx, WX_GPIO_INTTYPE_LEVEL, TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3);
|
||||
wr32(wx, WX_GPIO_INTEN, TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3);
|
||||
|
||||
status = rd32(wx, WX_GPIO_INTSTATUS);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (status & BIT(i))
|
||||
wr32(wx, WX_GPIO_EOI, BIT(i));
|
||||
}
|
||||
}
|
||||
|
||||
irqreturn_t txgbe_gpio_irq_handler_aml(int irq, void *data)
|
||||
{
|
||||
struct txgbe *txgbe = data;
|
||||
struct wx *wx = txgbe->wx;
|
||||
u32 status;
|
||||
|
||||
wr32(wx, WX_GPIO_INTMASK, 0xFF);
|
||||
status = rd32(wx, WX_GPIO_INTSTATUS);
|
||||
if (status & TXGBE_GPIOBIT_2) {
|
||||
set_bit(WX_FLAG_NEED_SFP_RESET, wx->flags);
|
||||
wr32(wx, WX_GPIO_EOI, TXGBE_GPIOBIT_2);
|
||||
wx_service_event_schedule(wx);
|
||||
}
|
||||
if (status & TXGBE_GPIOBIT_3) {
|
||||
set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags);
|
||||
wx_service_event_schedule(wx);
|
||||
wr32(wx, WX_GPIO_EOI, TXGBE_GPIOBIT_3);
|
||||
}
|
||||
|
||||
wr32(wx, WX_GPIO_INTMASK, 0);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int txgbe_test_hostif(struct wx *wx)
|
||||
{
|
||||
struct txgbe_hic_ephy_getlink buffer;
|
||||
|
||||
if (wx->mac.type != wx_mac_aml)
|
||||
return 0;
|
||||
|
||||
buffer.hdr.cmd = FW_PHY_GET_LINK_CMD;
|
||||
buffer.hdr.buf_len = sizeof(struct txgbe_hic_ephy_getlink) -
|
||||
sizeof(struct wx_hic_hdr);
|
||||
buffer.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
|
||||
|
||||
return wx_host_interface_command(wx, (u32 *)&buffer, sizeof(buffer),
|
||||
WX_HI_COMMAND_TIMEOUT, true);
|
||||
}
|
||||
|
||||
static int txgbe_identify_sfp_hostif(struct wx *wx, struct txgbe_hic_i2c_read *buffer)
|
||||
{
|
||||
buffer->hdr.cmd = FW_READ_SFP_INFO_CMD;
|
||||
buffer->hdr.buf_len = sizeof(struct txgbe_hic_i2c_read) -
|
||||
sizeof(struct wx_hic_hdr);
|
||||
buffer->hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
|
||||
|
||||
return wx_host_interface_command(wx, (u32 *)buffer,
|
||||
sizeof(struct txgbe_hic_i2c_read),
|
||||
WX_HI_COMMAND_TIMEOUT, true);
|
||||
}
|
||||
|
||||
static int txgbe_set_phy_link_hostif(struct wx *wx, int speed, int autoneg, int duplex)
|
||||
{
|
||||
struct txgbe_hic_ephy_setlink buffer;
|
||||
|
||||
buffer.hdr.cmd = FW_PHY_SET_LINK_CMD;
|
||||
buffer.hdr.buf_len = sizeof(struct txgbe_hic_ephy_setlink) -
|
||||
sizeof(struct wx_hic_hdr);
|
||||
buffer.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
|
||||
|
||||
switch (speed) {
|
||||
case SPEED_25000:
|
||||
buffer.speed = TXGBE_LINK_SPEED_25GB_FULL;
|
||||
break;
|
||||
case SPEED_10000:
|
||||
buffer.speed = TXGBE_LINK_SPEED_10GB_FULL;
|
||||
break;
|
||||
}
|
||||
|
||||
buffer.fec_mode = TXGBE_PHY_FEC_AUTO;
|
||||
buffer.autoneg = autoneg;
|
||||
buffer.duplex = duplex;
|
||||
|
||||
return wx_host_interface_command(wx, (u32 *)&buffer, sizeof(buffer),
|
||||
WX_HI_COMMAND_TIMEOUT, true);
|
||||
}
|
||||
|
||||
static void txgbe_get_link_capabilities(struct wx *wx)
|
||||
{
|
||||
struct txgbe *txgbe = wx->priv;
|
||||
|
||||
if (test_bit(PHY_INTERFACE_MODE_25GBASER, txgbe->sfp_interfaces))
|
||||
wx->adv_speed = SPEED_25000;
|
||||
else if (test_bit(PHY_INTERFACE_MODE_10GBASER, txgbe->sfp_interfaces))
|
||||
wx->adv_speed = SPEED_10000;
|
||||
else
|
||||
wx->adv_speed = SPEED_UNKNOWN;
|
||||
|
||||
wx->adv_duplex = wx->adv_speed == SPEED_UNKNOWN ?
|
||||
DUPLEX_HALF : DUPLEX_FULL;
|
||||
}
|
||||
|
||||
static void txgbe_get_phy_link(struct wx *wx, int *speed)
|
||||
{
|
||||
u32 status;
|
||||
|
||||
status = rd32(wx, TXGBE_CFG_PORT_ST);
|
||||
if (!(status & TXGBE_CFG_PORT_ST_LINK_UP))
|
||||
*speed = SPEED_UNKNOWN;
|
||||
else if (status & TXGBE_CFG_PORT_ST_LINK_AML_25G)
|
||||
*speed = SPEED_25000;
|
||||
else if (status & TXGBE_CFG_PORT_ST_LINK_AML_10G)
|
||||
*speed = SPEED_10000;
|
||||
else
|
||||
*speed = SPEED_UNKNOWN;
|
||||
}
|
||||
|
||||
int txgbe_set_phy_link(struct wx *wx)
|
||||
{
|
||||
int speed, err;
|
||||
u32 gpio;
|
||||
|
||||
/* Check RX signal */
|
||||
gpio = rd32(wx, WX_GPIO_EXT);
|
||||
if (gpio & TXGBE_GPIOBIT_3)
|
||||
return -ENODEV;
|
||||
|
||||
txgbe_get_link_capabilities(wx);
|
||||
if (wx->adv_speed == SPEED_UNKNOWN)
|
||||
return -ENODEV;
|
||||
|
||||
txgbe_get_phy_link(wx, &speed);
|
||||
if (speed == wx->adv_speed)
|
||||
return 0;
|
||||
|
||||
err = txgbe_set_phy_link_hostif(wx, wx->adv_speed, 0, wx->adv_duplex);
|
||||
if (err) {
|
||||
wx_err(wx, "Failed to setup link\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sfp_id *id)
|
||||
{
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, };
|
||||
DECLARE_PHY_INTERFACE_MASK(interfaces);
|
||||
struct txgbe *txgbe = wx->priv;
|
||||
|
||||
if (id->com_25g_code & (TXGBE_SFF_25GBASESR_CAPABLE |
|
||||
TXGBE_SFF_25GBASEER_CAPABLE |
|
||||
TXGBE_SFF_25GBASELR_CAPABLE)) {
|
||||
phylink_set(modes, 25000baseSR_Full);
|
||||
__set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces);
|
||||
}
|
||||
if (id->com_10g_code & TXGBE_SFF_10GBASESR_CAPABLE) {
|
||||
phylink_set(modes, 10000baseSR_Full);
|
||||
__set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
|
||||
}
|
||||
if (id->com_10g_code & TXGBE_SFF_10GBASELR_CAPABLE) {
|
||||
phylink_set(modes, 10000baseLR_Full);
|
||||
__set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
|
||||
}
|
||||
|
||||
if (phy_interface_empty(interfaces)) {
|
||||
wx_err(wx, "unsupported SFP module\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
phylink_set(modes, Pause);
|
||||
phylink_set(modes, Asym_Pause);
|
||||
phylink_set(modes, FIBRE);
|
||||
txgbe->link_port = PORT_FIBRE;
|
||||
|
||||
if (!linkmode_equal(txgbe->sfp_support, modes)) {
|
||||
linkmode_copy(txgbe->sfp_support, modes);
|
||||
phy_interface_and(txgbe->sfp_interfaces,
|
||||
wx->phylink_config.supported_interfaces,
|
||||
interfaces);
|
||||
linkmode_copy(txgbe->advertising, modes);
|
||||
|
||||
set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int txgbe_identify_sfp(struct wx *wx)
|
||||
{
|
||||
struct txgbe_hic_i2c_read buffer;
|
||||
struct txgbe_sfp_id *id;
|
||||
int err = 0;
|
||||
u32 gpio;
|
||||
|
||||
gpio = rd32(wx, WX_GPIO_EXT);
|
||||
if (gpio & TXGBE_GPIOBIT_2)
|
||||
return -ENODEV;
|
||||
|
||||
err = txgbe_identify_sfp_hostif(wx, &buffer);
|
||||
if (err) {
|
||||
wx_err(wx, "Failed to identify SFP module\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
id = &buffer.id;
|
||||
if (id->identifier != TXGBE_SFF_IDENTIFIER_SFP) {
|
||||
wx_err(wx, "Invalid SFP module\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = txgbe_sfp_to_linkmodes(wx, id);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (gpio & TXGBE_GPIOBIT_3)
|
||||
set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void txgbe_setup_link(struct wx *wx)
|
||||
{
|
||||
struct txgbe *txgbe = wx->priv;
|
||||
|
||||
phy_interface_zero(txgbe->sfp_interfaces);
|
||||
linkmode_zero(txgbe->sfp_support);
|
||||
|
||||
txgbe_identify_sfp(wx);
|
||||
}
|
||||
|
||||
static void txgbe_get_link_state(struct phylink_config *config,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
struct wx *wx = phylink_to_wx(config);
|
||||
int speed;
|
||||
|
||||
txgbe_get_phy_link(wx, &speed);
|
||||
state->link = speed != SPEED_UNKNOWN;
|
||||
state->speed = speed;
|
||||
state->duplex = state->link ? DUPLEX_FULL : DUPLEX_UNKNOWN;
|
||||
}
|
||||
|
||||
static void txgbe_reconfig_mac(struct wx *wx)
|
||||
{
|
||||
u32 wdg, fc;
|
||||
|
||||
wdg = rd32(wx, WX_MAC_WDG_TIMEOUT);
|
||||
fc = rd32(wx, WX_MAC_RX_FLOW_CTRL);
|
||||
|
||||
wr32(wx, WX_MIS_RST, TXGBE_MIS_RST_MAC_RST(wx->bus.func));
|
||||
/* wait for MAC reset complete */
|
||||
usleep_range(1000, 1500);
|
||||
|
||||
wr32m(wx, TXGBE_MAC_MISC_CTL, TXGBE_MAC_MISC_CTL_LINK_STS_MOD,
|
||||
TXGBE_MAC_MISC_CTL_LINK_BOTH);
|
||||
wx_reset_mac(wx);
|
||||
|
||||
wr32(wx, WX_MAC_WDG_TIMEOUT, wdg);
|
||||
wr32(wx, WX_MAC_RX_FLOW_CTRL, fc);
|
||||
}
|
||||
|
||||
static void txgbe_mac_link_up_aml(struct phylink_config *config,
|
||||
struct phy_device *phy,
|
||||
unsigned int mode,
|
||||
phy_interface_t interface,
|
||||
int speed, int duplex,
|
||||
bool tx_pause, bool rx_pause)
|
||||
{
|
||||
struct wx *wx = phylink_to_wx(config);
|
||||
u32 txcfg;
|
||||
|
||||
wx_fc_enable(wx, tx_pause, rx_pause);
|
||||
|
||||
txgbe_reconfig_mac(wx);
|
||||
|
||||
txcfg = rd32(wx, TXGBE_AML_MAC_TX_CFG);
|
||||
txcfg &= ~TXGBE_AML_MAC_TX_CFG_SPEED_MASK;
|
||||
|
||||
switch (speed) {
|
||||
case SPEED_25000:
|
||||
txcfg |= TXGBE_AML_MAC_TX_CFG_SPEED_25G;
|
||||
break;
|
||||
case SPEED_10000:
|
||||
txcfg |= TXGBE_AML_MAC_TX_CFG_SPEED_10G;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, WX_MAC_RX_CFG_RE);
|
||||
wr32(wx, TXGBE_AML_MAC_TX_CFG, txcfg | TXGBE_AML_MAC_TX_CFG_TE);
|
||||
|
||||
wx->speed = speed;
|
||||
wx->last_rx_ptp_check = jiffies;
|
||||
if (test_bit(WX_STATE_PTP_RUNNING, wx->state))
|
||||
wx_ptp_reset_cyclecounter(wx);
|
||||
/* ping all the active vfs to let them know we are going up */
|
||||
wx_ping_all_vfs_with_link_status(wx, true);
|
||||
}
|
||||
|
||||
static void txgbe_mac_link_down_aml(struct phylink_config *config,
|
||||
unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
struct wx *wx = phylink_to_wx(config);
|
||||
|
||||
wr32m(wx, TXGBE_AML_MAC_TX_CFG, TXGBE_AML_MAC_TX_CFG_TE, 0);
|
||||
wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, 0);
|
||||
|
||||
wx->speed = SPEED_UNKNOWN;
|
||||
if (test_bit(WX_STATE_PTP_RUNNING, wx->state))
|
||||
wx_ptp_reset_cyclecounter(wx);
|
||||
/* ping all the active vfs to let them know we are going down */
|
||||
wx_ping_all_vfs_with_link_status(wx, false);
|
||||
}
|
||||
|
||||
static void txgbe_mac_config_aml(struct phylink_config *config, unsigned int mode,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct phylink_mac_ops txgbe_mac_ops_aml = {
|
||||
.mac_config = txgbe_mac_config_aml,
|
||||
.mac_link_down = txgbe_mac_link_down_aml,
|
||||
.mac_link_up = txgbe_mac_link_up_aml,
|
||||
};
|
||||
|
||||
int txgbe_phylink_init_aml(struct txgbe *txgbe)
|
||||
{
|
||||
struct phylink_link_state state;
|
||||
struct phylink_config *config;
|
||||
struct wx *wx = txgbe->wx;
|
||||
phy_interface_t phy_mode;
|
||||
struct phylink *phylink;
|
||||
int err;
|
||||
|
||||
config = &wx->phylink_config;
|
||||
config->dev = &wx->netdev->dev;
|
||||
config->type = PHYLINK_NETDEV;
|
||||
config->mac_capabilities = MAC_25000FD | MAC_10000FD |
|
||||
MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
|
||||
config->get_fixed_state = txgbe_get_link_state;
|
||||
|
||||
phy_mode = PHY_INTERFACE_MODE_25GBASER;
|
||||
__set_bit(PHY_INTERFACE_MODE_25GBASER, config->supported_interfaces);
|
||||
__set_bit(PHY_INTERFACE_MODE_10GBASER, config->supported_interfaces);
|
||||
|
||||
phylink = phylink_create(config, NULL, phy_mode, &txgbe_mac_ops_aml);
|
||||
if (IS_ERR(phylink))
|
||||
return PTR_ERR(phylink);
|
||||
|
||||
state.speed = SPEED_25000;
|
||||
state.duplex = DUPLEX_FULL;
|
||||
err = phylink_set_fixed_link(phylink, &state);
|
||||
if (err) {
|
||||
wx_err(wx, "Failed to set fixed link\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
wx->phylink = phylink;
|
||||
|
||||
return 0;
|
||||
}
|
||||
15
drivers/net/ethernet/wangxun/txgbe/txgbe_aml.h
Normal file
15
drivers/net/ethernet/wangxun/txgbe/txgbe_aml.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2015 - 2025 Beijing WangXun Technology Co., Ltd. */
|
||||
|
||||
#ifndef _TXGBE_AML_H_
|
||||
#define _TXGBE_AML_H_
|
||||
|
||||
void txgbe_gpio_init_aml(struct wx *wx);
|
||||
irqreturn_t txgbe_gpio_irq_handler_aml(int irq, void *data);
|
||||
int txgbe_test_hostif(struct wx *wx);
|
||||
int txgbe_set_phy_link(struct wx *wx);
|
||||
int txgbe_identify_sfp(struct wx *wx);
|
||||
void txgbe_setup_link(struct wx *wx);
|
||||
int txgbe_phylink_init_aml(struct txgbe *txgbe);
|
||||
|
||||
#endif /* _TXGBE_AML_H_ */
|
||||
|
|
@ -12,6 +12,31 @@
|
|||
#include "txgbe_fdir.h"
|
||||
#include "txgbe_ethtool.h"
|
||||
|
||||
int txgbe_get_link_ksettings(struct net_device *netdev,
|
||||
struct ethtool_link_ksettings *cmd)
|
||||
{
|
||||
struct wx *wx = netdev_priv(netdev);
|
||||
struct txgbe *txgbe = wx->priv;
|
||||
int err;
|
||||
|
||||
if (wx->mac.type == wx_mac_aml40)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
err = wx_get_link_ksettings(netdev, cmd);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (wx->mac.type == wx_mac_sp)
|
||||
return 0;
|
||||
|
||||
cmd->base.port = txgbe->link_port;
|
||||
cmd->base.autoneg = AUTONEG_DISABLE;
|
||||
linkmode_copy(cmd->link_modes.supported, txgbe->sfp_support);
|
||||
linkmode_copy(cmd->link_modes.advertising, txgbe->advertising);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int txgbe_set_ringparam(struct net_device *netdev,
|
||||
struct ethtool_ringparam *ring,
|
||||
struct kernel_ethtool_ringparam *kernel_ring,
|
||||
|
|
@ -510,7 +535,7 @@ static const struct ethtool_ops txgbe_ethtool_ops = {
|
|||
.get_drvinfo = wx_get_drvinfo,
|
||||
.nway_reset = wx_nway_reset,
|
||||
.get_link = ethtool_op_get_link,
|
||||
.get_link_ksettings = wx_get_link_ksettings,
|
||||
.get_link_ksettings = txgbe_get_link_ksettings,
|
||||
.set_link_ksettings = wx_set_link_ksettings,
|
||||
.get_sset_count = wx_get_sset_count,
|
||||
.get_strings = wx_get_strings,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
#ifndef _TXGBE_ETHTOOL_H_
|
||||
#define _TXGBE_ETHTOOL_H_
|
||||
|
||||
int txgbe_get_link_ksettings(struct net_device *netdev,
|
||||
struct ethtool_link_ksettings *cmd);
|
||||
void txgbe_set_ethtool_ops(struct net_device *netdev);
|
||||
|
||||
#endif /* _TXGBE_ETHTOOL_H_ */
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ int txgbe_reset_hw(struct wx *wx)
|
|||
if (status != 0)
|
||||
return status;
|
||||
|
||||
if (wx->media_type != sp_media_copper) {
|
||||
if (wx->media_type != wx_media_copper) {
|
||||
u32 val;
|
||||
|
||||
val = WX_MIS_RST_LAN_RST(wx->bus.func);
|
||||
|
|
@ -218,7 +218,7 @@ int txgbe_reset_hw(struct wx *wx)
|
|||
* clear the multicast table. Also reset num_rar_entries to 128,
|
||||
* since we modify this value when programming the SAN MAC address.
|
||||
*/
|
||||
wx->mac.num_rar_entries = TXGBE_SP_RAR_ENTRIES;
|
||||
wx->mac.num_rar_entries = TXGBE_RAR_ENTRIES;
|
||||
wx_init_rx_addrs(wx);
|
||||
|
||||
pci_set_master(wx->pdev);
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@
|
|||
|
||||
#include "../libwx/wx_type.h"
|
||||
#include "../libwx/wx_lib.h"
|
||||
#include "../libwx/wx_ptp.h"
|
||||
#include "../libwx/wx_hw.h"
|
||||
#include "../libwx/wx_sriov.h"
|
||||
#include "txgbe_type.h"
|
||||
#include "txgbe_phy.h"
|
||||
#include "txgbe_irq.h"
|
||||
#include "txgbe_aml.h"
|
||||
|
||||
/**
|
||||
* txgbe_irq_enable - Enable default interrupt generation settings
|
||||
|
|
@ -19,7 +21,14 @@
|
|||
**/
|
||||
void txgbe_irq_enable(struct wx *wx, bool queues)
|
||||
{
|
||||
wr32(wx, WX_PX_MISC_IEN, TXGBE_PX_MISC_IEN_MASK);
|
||||
u32 misc_ien = TXGBE_PX_MISC_IEN_MASK;
|
||||
|
||||
if (wx->mac.type == wx_mac_aml) {
|
||||
misc_ien |= TXGBE_PX_MISC_GPIO;
|
||||
txgbe_gpio_init_aml(wx);
|
||||
}
|
||||
|
||||
wr32(wx, WX_PX_MISC_IEN, misc_ien);
|
||||
|
||||
/* unmask interrupt */
|
||||
wx_intr_enable(wx, TXGBE_INTR_MISC);
|
||||
|
|
@ -81,6 +90,14 @@ static int txgbe_request_link_irq(struct txgbe *txgbe)
|
|||
IRQF_ONESHOT, "txgbe-link-irq", txgbe);
|
||||
}
|
||||
|
||||
static int txgbe_request_gpio_irq(struct txgbe *txgbe)
|
||||
{
|
||||
txgbe->gpio_irq = irq_find_mapping(txgbe->misc.domain, TXGBE_IRQ_GPIO);
|
||||
return request_threaded_irq(txgbe->gpio_irq, NULL,
|
||||
txgbe_gpio_irq_handler_aml,
|
||||
IRQF_ONESHOT, "txgbe-gpio-irq", txgbe);
|
||||
}
|
||||
|
||||
static const struct irq_chip txgbe_irq_chip = {
|
||||
.name = "txgbe-misc-irq",
|
||||
};
|
||||
|
|
@ -157,6 +174,15 @@ static irqreturn_t txgbe_misc_irq_thread_fn(int irq, void *data)
|
|||
handle_nested_irq(sub_irq);
|
||||
nhandled++;
|
||||
}
|
||||
if (eicr & TXGBE_PX_MISC_GPIO) {
|
||||
sub_irq = irq_find_mapping(txgbe->misc.domain, TXGBE_IRQ_GPIO);
|
||||
handle_nested_irq(sub_irq);
|
||||
nhandled++;
|
||||
}
|
||||
if (unlikely(eicr & TXGBE_PX_MISC_IC_TIMESYNC)) {
|
||||
wx_ptp_check_pps_event(wx);
|
||||
nhandled++;
|
||||
}
|
||||
|
||||
wx_intr_enable(wx, TXGBE_INTR_MISC);
|
||||
return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
|
||||
|
|
@ -176,9 +202,12 @@ static void txgbe_del_irq_domain(struct txgbe *txgbe)
|
|||
|
||||
void txgbe_free_misc_irq(struct txgbe *txgbe)
|
||||
{
|
||||
if (txgbe->wx->mac.type == wx_mac_aml)
|
||||
if (txgbe->wx->mac.type == wx_mac_aml40)
|
||||
return;
|
||||
|
||||
if (txgbe->wx->mac.type == wx_mac_aml)
|
||||
free_irq(txgbe->gpio_irq, txgbe);
|
||||
|
||||
free_irq(txgbe->link_irq, txgbe);
|
||||
free_irq(txgbe->misc.irq, txgbe);
|
||||
txgbe_del_irq_domain(txgbe);
|
||||
|
|
@ -190,7 +219,7 @@ int txgbe_setup_misc_irq(struct txgbe *txgbe)
|
|||
struct wx *wx = txgbe->wx;
|
||||
int hwirq, err;
|
||||
|
||||
if (wx->mac.type == wx_mac_aml)
|
||||
if (wx->mac.type == wx_mac_aml40)
|
||||
goto skip_sp_irq;
|
||||
|
||||
txgbe->misc.nirqs = TXGBE_IRQ_MAX;
|
||||
|
|
@ -222,11 +251,20 @@ int txgbe_setup_misc_irq(struct txgbe *txgbe)
|
|||
if (err)
|
||||
goto free_msic_irq;
|
||||
|
||||
if (wx->mac.type == wx_mac_sp)
|
||||
goto skip_sp_irq;
|
||||
|
||||
err = txgbe_request_gpio_irq(txgbe);
|
||||
if (err)
|
||||
goto free_link_irq;
|
||||
|
||||
skip_sp_irq:
|
||||
wx->misc_irq_domain = true;
|
||||
|
||||
return 0;
|
||||
|
||||
free_link_irq:
|
||||
free_irq(txgbe->link_irq, txgbe);
|
||||
free_msic_irq:
|
||||
free_irq(txgbe->misc.irq, txgbe);
|
||||
del_misc_irq:
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "txgbe_type.h"
|
||||
#include "txgbe_hw.h"
|
||||
#include "txgbe_phy.h"
|
||||
#include "txgbe_aml.h"
|
||||
#include "txgbe_irq.h"
|
||||
#include "txgbe_fdir.h"
|
||||
#include "txgbe_ethtool.h"
|
||||
|
|
@ -88,9 +89,62 @@ static int txgbe_enumerate_functions(struct wx *wx)
|
|||
return physfns;
|
||||
}
|
||||
|
||||
static void txgbe_sfp_detection_subtask(struct wx *wx)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!test_bit(WX_FLAG_NEED_SFP_RESET, wx->flags))
|
||||
return;
|
||||
|
||||
/* wait for SFP module ready */
|
||||
msleep(200);
|
||||
|
||||
err = txgbe_identify_sfp(wx);
|
||||
if (err)
|
||||
return;
|
||||
|
||||
clear_bit(WX_FLAG_NEED_SFP_RESET, wx->flags);
|
||||
}
|
||||
|
||||
static void txgbe_link_config_subtask(struct wx *wx)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!test_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags))
|
||||
return;
|
||||
|
||||
err = txgbe_set_phy_link(wx);
|
||||
if (err)
|
||||
return;
|
||||
|
||||
clear_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_service_task - manages and runs subtasks
|
||||
* @work: pointer to work_struct containing our data
|
||||
**/
|
||||
static void txgbe_service_task(struct work_struct *work)
|
||||
{
|
||||
struct wx *wx = container_of(work, struct wx, service_task);
|
||||
|
||||
txgbe_sfp_detection_subtask(wx);
|
||||
txgbe_link_config_subtask(wx);
|
||||
|
||||
wx_service_event_complete(wx);
|
||||
}
|
||||
|
||||
static void txgbe_init_service(struct wx *wx)
|
||||
{
|
||||
timer_setup(&wx->service_timer, wx_service_timer, 0);
|
||||
INIT_WORK(&wx->service_task, txgbe_service_task);
|
||||
clear_bit(WX_STATE_SERVICE_SCHED, wx->state);
|
||||
}
|
||||
|
||||
static void txgbe_up_complete(struct wx *wx)
|
||||
{
|
||||
struct net_device *netdev = wx->netdev;
|
||||
u32 reg;
|
||||
|
||||
wx_control_hw(wx, true);
|
||||
wx_configure_vectors(wx);
|
||||
|
|
@ -99,17 +153,26 @@ static void txgbe_up_complete(struct wx *wx)
|
|||
smp_mb__before_atomic();
|
||||
wx_napi_enable_all(wx);
|
||||
|
||||
if (wx->mac.type == wx_mac_aml) {
|
||||
u32 reg;
|
||||
|
||||
switch (wx->mac.type) {
|
||||
case wx_mac_aml40:
|
||||
reg = rd32(wx, TXGBE_AML_MAC_TX_CFG);
|
||||
reg &= ~TXGBE_AML_MAC_TX_CFG_SPEED_MASK;
|
||||
reg |= TXGBE_AML_MAC_TX_CFG_SPEED_25G;
|
||||
reg |= TXGBE_AML_MAC_TX_CFG_SPEED_40G;
|
||||
wr32(wx, WX_MAC_TX_CFG, reg);
|
||||
txgbe_enable_sec_tx_path(wx);
|
||||
netif_carrier_on(wx->netdev);
|
||||
} else {
|
||||
break;
|
||||
case wx_mac_aml:
|
||||
/* Enable TX laser */
|
||||
wr32m(wx, WX_GPIO_DR, TXGBE_GPIOBIT_1, 0);
|
||||
txgbe_setup_link(wx);
|
||||
phylink_start(wx->phylink);
|
||||
break;
|
||||
case wx_mac_sp:
|
||||
phylink_start(wx->phylink);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* clear any pending interrupts, may auto mask */
|
||||
|
|
@ -120,6 +183,7 @@ static void txgbe_up_complete(struct wx *wx)
|
|||
|
||||
/* enable transmits */
|
||||
netif_tx_start_all_queues(netdev);
|
||||
mod_timer(&wx->service_timer, jiffies);
|
||||
|
||||
/* Set PF Reset Done bit so PF/VF Mail Ops can work */
|
||||
wr32m(wx, WX_CFG_PORT_CTL, WX_CFG_PORT_CTL_PFRSTD,
|
||||
|
|
@ -168,6 +232,8 @@ static void txgbe_disable_device(struct wx *wx)
|
|||
wx_irq_disable(wx);
|
||||
wx_napi_disable_all(wx);
|
||||
|
||||
timer_delete_sync(&wx->service_timer);
|
||||
|
||||
if (wx->bus.func < 2)
|
||||
wr32m(wx, TXGBE_MIS_PRB_CTL, TXGBE_MIS_PRB_CTL_LAN_UP(wx->bus.func), 0);
|
||||
else
|
||||
|
|
@ -207,10 +273,22 @@ void txgbe_down(struct wx *wx)
|
|||
{
|
||||
txgbe_disable_device(wx);
|
||||
txgbe_reset(wx);
|
||||
if (wx->mac.type == wx_mac_aml)
|
||||
|
||||
switch (wx->mac.type) {
|
||||
case wx_mac_aml40:
|
||||
netif_carrier_off(wx->netdev);
|
||||
else
|
||||
break;
|
||||
case wx_mac_aml:
|
||||
phylink_stop(wx->phylink);
|
||||
/* Disable TX laser */
|
||||
wr32m(wx, WX_GPIO_DR, TXGBE_GPIOBIT_1, TXGBE_GPIOBIT_1);
|
||||
break;
|
||||
case wx_mac_sp:
|
||||
phylink_stop(wx->phylink);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
wx_clean_all_tx_rings(wx);
|
||||
wx_clean_all_rx_rings(wx);
|
||||
|
|
@ -240,9 +318,11 @@ static void txgbe_init_type_code(struct wx *wx)
|
|||
case TXGBE_DEV_ID_AML5110:
|
||||
case TXGBE_DEV_ID_AML5025:
|
||||
case TXGBE_DEV_ID_AML5125:
|
||||
wx->mac.type = wx_mac_aml;
|
||||
break;
|
||||
case TXGBE_DEV_ID_AML5040:
|
||||
case TXGBE_DEV_ID_AML5140:
|
||||
wx->mac.type = wx_mac_aml;
|
||||
wx->mac.type = wx_mac_aml40;
|
||||
break;
|
||||
default:
|
||||
wx->mac.type = wx_mac_unknown;
|
||||
|
|
@ -251,25 +331,25 @@ static void txgbe_init_type_code(struct wx *wx)
|
|||
|
||||
switch (device_type) {
|
||||
case TXGBE_ID_SFP:
|
||||
wx->media_type = sp_media_fiber;
|
||||
wx->media_type = wx_media_fiber;
|
||||
break;
|
||||
case TXGBE_ID_XAUI:
|
||||
case TXGBE_ID_SGMII:
|
||||
wx->media_type = sp_media_copper;
|
||||
wx->media_type = wx_media_copper;
|
||||
break;
|
||||
case TXGBE_ID_KR_KX_KX4:
|
||||
case TXGBE_ID_MAC_XAUI:
|
||||
case TXGBE_ID_MAC_SGMII:
|
||||
wx->media_type = sp_media_backplane;
|
||||
wx->media_type = wx_media_backplane;
|
||||
break;
|
||||
case TXGBE_ID_SFI_XAUI:
|
||||
if (wx->bus.func == 0)
|
||||
wx->media_type = sp_media_fiber;
|
||||
wx->media_type = wx_media_fiber;
|
||||
else
|
||||
wx->media_type = sp_media_copper;
|
||||
wx->media_type = wx_media_copper;
|
||||
break;
|
||||
default:
|
||||
wx->media_type = sp_media_unknown;
|
||||
wx->media_type = wx_media_unknown;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -283,13 +363,13 @@ static int txgbe_sw_init(struct wx *wx)
|
|||
u16 msix_count = 0;
|
||||
int err;
|
||||
|
||||
wx->mac.num_rar_entries = TXGBE_SP_RAR_ENTRIES;
|
||||
wx->mac.max_tx_queues = TXGBE_SP_MAX_TX_QUEUES;
|
||||
wx->mac.max_rx_queues = TXGBE_SP_MAX_RX_QUEUES;
|
||||
wx->mac.mcft_size = TXGBE_SP_MC_TBL_SIZE;
|
||||
wx->mac.vft_size = TXGBE_SP_VFT_TBL_SIZE;
|
||||
wx->mac.rx_pb_size = TXGBE_SP_RX_PB_SIZE;
|
||||
wx->mac.tx_pb_size = TXGBE_SP_TDB_PB_SZ;
|
||||
wx->mac.num_rar_entries = TXGBE_RAR_ENTRIES;
|
||||
wx->mac.max_tx_queues = TXGBE_MAX_TXQ;
|
||||
wx->mac.max_rx_queues = TXGBE_MAX_RXQ;
|
||||
wx->mac.mcft_size = TXGBE_MC_TBL_SIZE;
|
||||
wx->mac.vft_size = TXGBE_VFT_TBL_SIZE;
|
||||
wx->mac.rx_pb_size = TXGBE_RX_PB_SIZE;
|
||||
wx->mac.tx_pb_size = TXGBE_TDB_PB_SZ;
|
||||
|
||||
/* PCI config space info */
|
||||
err = wx_sw_init(wx);
|
||||
|
|
@ -318,6 +398,7 @@ static int txgbe_sw_init(struct wx *wx)
|
|||
wx->configure_fdir = txgbe_configure_fdir;
|
||||
|
||||
set_bit(WX_FLAG_RSC_CAPABLE, wx->flags);
|
||||
set_bit(WX_FLAG_MULTI_64_FUNC, wx->flags);
|
||||
|
||||
/* enable itr by default in dynamic mode */
|
||||
wx->rx_itr_setting = 1;
|
||||
|
|
@ -340,6 +421,7 @@ static int txgbe_sw_init(struct wx *wx)
|
|||
case wx_mac_sp:
|
||||
break;
|
||||
case wx_mac_aml:
|
||||
case wx_mac_aml40:
|
||||
set_bit(WX_FLAG_SWFW_RING, wx->flags);
|
||||
wx->swfw_index = 0;
|
||||
break;
|
||||
|
|
@ -735,9 +817,11 @@ static int txgbe_probe(struct pci_dev *pdev,
|
|||
eth_hw_addr_set(netdev, wx->mac.perm_addr);
|
||||
wx_mac_set_default_filter(wx, wx->mac.perm_addr);
|
||||
|
||||
txgbe_init_service(wx);
|
||||
|
||||
err = wx_init_interrupt_scheme(wx);
|
||||
if (err)
|
||||
goto err_free_mac_table;
|
||||
goto err_cancel_service;
|
||||
|
||||
/* Save off EEPROM version number and Option Rom version which
|
||||
* together make a unique identify for the eeprom
|
||||
|
|
@ -780,6 +864,13 @@ static int txgbe_probe(struct pci_dev *pdev,
|
|||
if (etrack_id < 0x20010)
|
||||
dev_warn(&pdev->dev, "Please upgrade the firmware to 0x20010 or above.\n");
|
||||
|
||||
err = txgbe_test_hostif(wx);
|
||||
if (err != 0) {
|
||||
dev_err(&pdev->dev, "Mismatched Firmware version\n");
|
||||
err = -EIO;
|
||||
goto err_release_hw;
|
||||
}
|
||||
|
||||
txgbe = devm_kzalloc(&pdev->dev, sizeof(*txgbe), GFP_KERNEL);
|
||||
if (!txgbe) {
|
||||
err = -ENOMEM;
|
||||
|
|
@ -830,6 +921,9 @@ static int txgbe_probe(struct pci_dev *pdev,
|
|||
err_release_hw:
|
||||
wx_clear_interrupt_scheme(wx);
|
||||
wx_control_hw(wx, false);
|
||||
err_cancel_service:
|
||||
timer_delete_sync(&wx->service_timer);
|
||||
cancel_work_sync(&wx->service_task);
|
||||
err_free_mac_table:
|
||||
kfree(wx->rss_key);
|
||||
kfree(wx->mac_table);
|
||||
|
|
@ -856,6 +950,8 @@ static void txgbe_remove(struct pci_dev *pdev)
|
|||
struct txgbe *txgbe = wx->priv;
|
||||
struct net_device *netdev;
|
||||
|
||||
cancel_work_sync(&wx->service_task);
|
||||
|
||||
netdev = wx->netdev;
|
||||
wx_disable_sriov(wx);
|
||||
unregister_netdev(netdev);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "../libwx/wx_mbx.h"
|
||||
#include "../libwx/wx_hw.h"
|
||||
#include "txgbe_type.h"
|
||||
#include "txgbe_aml.h"
|
||||
#include "txgbe_phy.h"
|
||||
#include "txgbe_hw.h"
|
||||
|
||||
|
|
@ -165,7 +166,7 @@ static struct phylink_pcs *txgbe_phylink_mac_select(struct phylink_config *confi
|
|||
struct wx *wx = phylink_to_wx(config);
|
||||
struct txgbe *txgbe = wx->priv;
|
||||
|
||||
if (wx->media_type != sp_media_copper)
|
||||
if (wx->media_type != wx_media_copper)
|
||||
return txgbe->pcs;
|
||||
|
||||
return NULL;
|
||||
|
|
@ -278,7 +279,7 @@ static int txgbe_phylink_init(struct txgbe *txgbe)
|
|||
config->mac_capabilities = MAC_10000FD | MAC_1000FD | MAC_100FD |
|
||||
MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
|
||||
|
||||
if (wx->media_type == sp_media_copper) {
|
||||
if (wx->media_type == wx_media_copper) {
|
||||
phy_mode = PHY_INTERFACE_MODE_XAUI;
|
||||
__set_bit(PHY_INTERFACE_MODE_XAUI, config->supported_interfaces);
|
||||
} else {
|
||||
|
|
@ -318,7 +319,10 @@ irqreturn_t txgbe_link_irq_handler(int irq, void *data)
|
|||
status = rd32(wx, TXGBE_CFG_PORT_ST);
|
||||
up = !!(status & TXGBE_CFG_PORT_ST_LINK_UP);
|
||||
|
||||
phylink_pcs_change(txgbe->pcs, up);
|
||||
if (txgbe->pcs)
|
||||
phylink_pcs_change(txgbe->pcs, up);
|
||||
else
|
||||
phylink_mac_change(wx->phylink, up);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
|
@ -573,11 +577,18 @@ int txgbe_init_phy(struct txgbe *txgbe)
|
|||
struct wx *wx = txgbe->wx;
|
||||
int ret;
|
||||
|
||||
if (wx->mac.type == wx_mac_aml)
|
||||
switch (wx->mac.type) {
|
||||
case wx_mac_aml40:
|
||||
return 0;
|
||||
|
||||
if (txgbe->wx->media_type == sp_media_copper)
|
||||
return txgbe_ext_phy_init(txgbe);
|
||||
case wx_mac_aml:
|
||||
return txgbe_phylink_init_aml(txgbe);
|
||||
case wx_mac_sp:
|
||||
if (wx->media_type == wx_media_copper)
|
||||
return txgbe_ext_phy_init(txgbe);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret = txgbe_swnodes_register(txgbe);
|
||||
if (ret) {
|
||||
|
|
@ -640,13 +651,21 @@ int txgbe_init_phy(struct txgbe *txgbe)
|
|||
|
||||
void txgbe_remove_phy(struct txgbe *txgbe)
|
||||
{
|
||||
if (txgbe->wx->mac.type == wx_mac_aml)
|
||||
switch (txgbe->wx->mac.type) {
|
||||
case wx_mac_aml40:
|
||||
return;
|
||||
|
||||
if (txgbe->wx->media_type == sp_media_copper) {
|
||||
phylink_disconnect_phy(txgbe->wx->phylink);
|
||||
case wx_mac_aml:
|
||||
phylink_destroy(txgbe->wx->phylink);
|
||||
return;
|
||||
case wx_mac_sp:
|
||||
if (txgbe->wx->media_type == wx_media_copper) {
|
||||
phylink_disconnect_phy(txgbe->wx->phylink);
|
||||
phylink_destroy(txgbe->wx->phylink);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
platform_device_unregister(txgbe->sfp_dev);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include <linux/property.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/phy.h>
|
||||
#include "../libwx/wx_type.h"
|
||||
|
||||
/* Device IDs */
|
||||
#define TXGBE_DEV_ID_SP1000 0x1001
|
||||
|
|
@ -50,6 +52,8 @@
|
|||
|
||||
/**************** SP Registers ****************************/
|
||||
/* chip control Registers */
|
||||
#define TXGBE_MIS_RST 0x1000C
|
||||
#define TXGBE_MIS_RST_MAC_RST(_i) BIT(20 - (_i) * 3)
|
||||
#define TXGBE_MIS_PRB_CTL 0x10010
|
||||
#define TXGBE_MIS_PRB_CTL_LAN_UP(_i) BIT(1 - (_i))
|
||||
/* FMGR Registers */
|
||||
|
|
@ -62,6 +66,11 @@
|
|||
#define TXGBE_TS_CTL 0x10300
|
||||
#define TXGBE_TS_CTL_EVAL_MD BIT(31)
|
||||
|
||||
/* MAC Misc Registers */
|
||||
#define TXGBE_MAC_MISC_CTL 0x11F00
|
||||
#define TXGBE_MAC_MISC_CTL_LINK_STS_MOD BIT(0)
|
||||
#define TXGBE_MAC_MISC_CTL_LINK_PCS FIELD_PREP(BIT(0), 0)
|
||||
#define TXGBE_MAC_MISC_CTL_LINK_BOTH FIELD_PREP(BIT(0), 1)
|
||||
/* GPIO register bit */
|
||||
#define TXGBE_GPIOBIT_0 BIT(0) /* I:tx fault */
|
||||
#define TXGBE_GPIOBIT_1 BIT(1) /* O:tx disabled */
|
||||
|
|
@ -73,6 +82,7 @@
|
|||
/* Extended Interrupt Enable Set */
|
||||
#define TXGBE_PX_MISC_ETH_LKDN BIT(8)
|
||||
#define TXGBE_PX_MISC_DEV_RST BIT(10)
|
||||
#define TXGBE_PX_MISC_IC_TIMESYNC BIT(11)
|
||||
#define TXGBE_PX_MISC_ETH_EVENT BIT(17)
|
||||
#define TXGBE_PX_MISC_ETH_LK BIT(18)
|
||||
#define TXGBE_PX_MISC_ETH_AN BIT(19)
|
||||
|
|
@ -83,11 +93,13 @@
|
|||
(TXGBE_PX_MISC_ETH_LKDN | TXGBE_PX_MISC_DEV_RST | \
|
||||
TXGBE_PX_MISC_ETH_EVENT | TXGBE_PX_MISC_ETH_LK | \
|
||||
TXGBE_PX_MISC_ETH_AN | TXGBE_PX_MISC_INT_ERR | \
|
||||
TXGBE_PX_MISC_IC_VF_MBOX)
|
||||
TXGBE_PX_MISC_IC_VF_MBOX | TXGBE_PX_MISC_IC_TIMESYNC)
|
||||
|
||||
/* Port cfg registers */
|
||||
#define TXGBE_CFG_PORT_ST 0x14404
|
||||
#define TXGBE_CFG_PORT_ST_LINK_UP BIT(0)
|
||||
#define TXGBE_CFG_PORT_ST_LINK_AML_25G BIT(3)
|
||||
#define TXGBE_CFG_PORT_ST_LINK_AML_10G BIT(4)
|
||||
#define TXGBE_CFG_VXLAN 0x14410
|
||||
#define TXGBE_CFG_VXLAN_GPE 0x14414
|
||||
#define TXGBE_CFG_GENEVE 0x14418
|
||||
|
|
@ -151,8 +163,11 @@
|
|||
/*************************** Amber Lite Registers ****************************/
|
||||
#define TXGBE_PX_PF_BME 0x4B8
|
||||
#define TXGBE_AML_MAC_TX_CFG 0x11000
|
||||
#define TXGBE_AML_MAC_TX_CFG_TE BIT(0)
|
||||
#define TXGBE_AML_MAC_TX_CFG_SPEED_MASK GENMASK(30, 27)
|
||||
#define TXGBE_AML_MAC_TX_CFG_SPEED_25G BIT(28)
|
||||
#define TXGBE_AML_MAC_TX_CFG_SPEED_40G FIELD_PREP(GENMASK(30, 27), 0)
|
||||
#define TXGBE_AML_MAC_TX_CFG_SPEED_25G FIELD_PREP(GENMASK(30, 27), 2)
|
||||
#define TXGBE_AML_MAC_TX_CFG_SPEED_10G FIELD_PREP(GENMASK(30, 27), 8)
|
||||
#define TXGBE_RDM_RSC_CTL 0x1200C
|
||||
#define TXGBE_RDM_RSC_CTL_FREE_CTL BIT(7)
|
||||
|
||||
|
|
@ -173,13 +188,13 @@
|
|||
#define TXGBE_MAX_RX_QUEUES (TXGBE_MAX_FDIR_INDICES + 1)
|
||||
#define TXGBE_MAX_TX_QUEUES (TXGBE_MAX_FDIR_INDICES + 1)
|
||||
|
||||
#define TXGBE_SP_MAX_TX_QUEUES 128
|
||||
#define TXGBE_SP_MAX_RX_QUEUES 128
|
||||
#define TXGBE_SP_RAR_ENTRIES 128
|
||||
#define TXGBE_SP_MC_TBL_SIZE 128
|
||||
#define TXGBE_SP_VFT_TBL_SIZE 128
|
||||
#define TXGBE_SP_RX_PB_SIZE 512
|
||||
#define TXGBE_SP_TDB_PB_SZ (160 * 1024) /* 160KB Packet Buffer */
|
||||
#define TXGBE_MAX_TXQ 128
|
||||
#define TXGBE_MAX_RXQ 128
|
||||
#define TXGBE_RAR_ENTRIES 128
|
||||
#define TXGBE_MC_TBL_SIZE 128
|
||||
#define TXGBE_VFT_TBL_SIZE 128
|
||||
#define TXGBE_RX_PB_SIZE 512
|
||||
#define TXGBE_TDB_PB_SZ (160 * 1024) /* 160KB Packet Buffer */
|
||||
|
||||
#define TXGBE_MAX_VFS_DRV_LIMIT 63
|
||||
|
||||
|
|
@ -299,6 +314,72 @@ void txgbe_up(struct wx *wx);
|
|||
int txgbe_setup_tc(struct net_device *dev, u8 tc);
|
||||
void txgbe_do_reset(struct net_device *netdev);
|
||||
|
||||
#define TXGBE_LINK_SPEED_10GB_FULL 4
|
||||
#define TXGBE_LINK_SPEED_25GB_FULL 0x10
|
||||
|
||||
#define TXGBE_SFF_IDENTIFIER_SFP 0x3
|
||||
#define TXGBE_SFF_DA_PASSIVE_CABLE 0x4
|
||||
#define TXGBE_SFF_DA_ACTIVE_CABLE 0x8
|
||||
#define TXGBE_SFF_DA_SPEC_ACTIVE_LIMIT 0x4
|
||||
#define TXGBE_SFF_FCPI4_LIMITING 0x3
|
||||
#define TXGBE_SFF_10GBASESR_CAPABLE 0x10
|
||||
#define TXGBE_SFF_10GBASELR_CAPABLE 0x20
|
||||
#define TXGBE_SFF_25GBASESR_CAPABLE 0x2
|
||||
#define TXGBE_SFF_25GBASELR_CAPABLE 0x3
|
||||
#define TXGBE_SFF_25GBASEER_CAPABLE 0x4
|
||||
#define TXGBE_SFF_25GBASECR_91FEC 0xB
|
||||
#define TXGBE_SFF_25GBASECR_74FEC 0xC
|
||||
#define TXGBE_SFF_25GBASECR_NOFEC 0xD
|
||||
|
||||
#define TXGBE_PHY_FEC_RS BIT(0)
|
||||
#define TXGBE_PHY_FEC_BASER BIT(1)
|
||||
#define TXGBE_PHY_FEC_OFF BIT(2)
|
||||
#define TXGBE_PHY_FEC_AUTO (TXGBE_PHY_FEC_OFF | \
|
||||
TXGBE_PHY_FEC_BASER |\
|
||||
TXGBE_PHY_FEC_RS)
|
||||
|
||||
#define FW_PHY_GET_LINK_CMD 0xC0
|
||||
#define FW_PHY_SET_LINK_CMD 0xC1
|
||||
#define FW_READ_SFP_INFO_CMD 0xC5
|
||||
|
||||
struct txgbe_sfp_id {
|
||||
u8 identifier; /* A0H 0x00 */
|
||||
u8 com_1g_code; /* A0H 0x06 */
|
||||
u8 com_10g_code; /* A0H 0x03 */
|
||||
u8 com_25g_code; /* A0H 0x24 */
|
||||
u8 cable_spec; /* A0H 0x3C */
|
||||
u8 cable_tech; /* A0H 0x08 */
|
||||
u8 vendor_oui0; /* A0H 0x25 */
|
||||
u8 vendor_oui1; /* A0H 0x26 */
|
||||
u8 vendor_oui2; /* A0H 0x27 */
|
||||
u8 reserved[3];
|
||||
};
|
||||
|
||||
struct txgbe_hic_i2c_read {
|
||||
struct wx_hic_hdr hdr;
|
||||
struct txgbe_sfp_id id;
|
||||
};
|
||||
|
||||
struct txgbe_hic_ephy_setlink {
|
||||
struct wx_hic_hdr hdr;
|
||||
u8 speed;
|
||||
u8 duplex;
|
||||
u8 autoneg;
|
||||
u8 fec_mode;
|
||||
u8 resv[4];
|
||||
};
|
||||
|
||||
struct txgbe_hic_ephy_getlink {
|
||||
struct wx_hic_hdr hdr;
|
||||
u8 speed;
|
||||
u8 duplex;
|
||||
u8 autoneg;
|
||||
u8 flow_ctl;
|
||||
u8 power;
|
||||
u8 fec_mode;
|
||||
u8 resv[6];
|
||||
};
|
||||
|
||||
#define NODE_PROP(_NAME, _PROP) \
|
||||
(const struct software_node) { \
|
||||
.name = _NAME, \
|
||||
|
|
@ -336,6 +417,7 @@ struct txgbe_nodes {
|
|||
|
||||
enum txgbe_misc_irqs {
|
||||
TXGBE_IRQ_LINK = 0,
|
||||
TXGBE_IRQ_GPIO,
|
||||
TXGBE_IRQ_MAX
|
||||
};
|
||||
|
||||
|
|
@ -357,6 +439,7 @@ struct txgbe {
|
|||
struct clk *clk;
|
||||
struct gpio_chip *gpio;
|
||||
unsigned int link_irq;
|
||||
unsigned int gpio_irq;
|
||||
u32 eicr;
|
||||
|
||||
/* flow director */
|
||||
|
|
@ -364,6 +447,11 @@ struct txgbe {
|
|||
union txgbe_atr_input fdir_mask;
|
||||
int fdir_filter_count;
|
||||
spinlock_t fdir_perfect_lock; /* spinlock for FDIR */
|
||||
|
||||
DECLARE_PHY_INTERFACE_MASK(sfp_interfaces);
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support);
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
|
||||
u8 link_port;
|
||||
};
|
||||
|
||||
#endif /* _TXGBE_TYPE_H_ */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user