forked from luck/tmp_suning_uos_patched
Merge branch 'qed-PTP-fixes'
Sudarsana Reddy Kalluru says: ==================== qed*: PTP bug fixes. The series addresses couple of issues in the PTP implementation. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
5657f89abb
|
@ -188,39 +188,73 @@ static int qed_ptp_hw_read_cc(struct qed_dev *cdev, u64 *phc_cycles)
|
|||
}
|
||||
|
||||
/* Filter PTP protocol packets that need to be timestamped */
|
||||
static int qed_ptp_hw_cfg_rx_filters(struct qed_dev *cdev,
|
||||
enum qed_ptp_filter_type type)
|
||||
static int qed_ptp_hw_cfg_filters(struct qed_dev *cdev,
|
||||
enum qed_ptp_filter_type rx_type,
|
||||
enum qed_ptp_hwtstamp_tx_type tx_type)
|
||||
{
|
||||
struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
|
||||
struct qed_ptt *p_ptt = p_hwfn->p_ptp_ptt;
|
||||
u32 rule_mask, parm_mask;
|
||||
u32 rule_mask, enable_cfg = 0x0;
|
||||
|
||||
switch (type) {
|
||||
case QED_PTP_FILTER_L2_IPV4_IPV6:
|
||||
parm_mask = 0x6AA;
|
||||
rule_mask = 0x3EEE;
|
||||
switch (rx_type) {
|
||||
case QED_PTP_FILTER_NONE:
|
||||
enable_cfg = 0x0;
|
||||
rule_mask = 0x3FFF;
|
||||
break;
|
||||
case QED_PTP_FILTER_L2:
|
||||
parm_mask = 0x6BF;
|
||||
case QED_PTP_FILTER_ALL:
|
||||
enable_cfg = 0x7;
|
||||
rule_mask = 0x3CAA;
|
||||
break;
|
||||
case QED_PTP_FILTER_V1_L4_EVENT:
|
||||
enable_cfg = 0x3;
|
||||
rule_mask = 0x3FFA;
|
||||
break;
|
||||
case QED_PTP_FILTER_V1_L4_GEN:
|
||||
enable_cfg = 0x3;
|
||||
rule_mask = 0x3FFE;
|
||||
break;
|
||||
case QED_PTP_FILTER_V2_L4_EVENT:
|
||||
enable_cfg = 0x5;
|
||||
rule_mask = 0x3FAA;
|
||||
break;
|
||||
case QED_PTP_FILTER_V2_L4_GEN:
|
||||
enable_cfg = 0x5;
|
||||
rule_mask = 0x3FEE;
|
||||
break;
|
||||
case QED_PTP_FILTER_V2_L2_EVENT:
|
||||
enable_cfg = 0x5;
|
||||
rule_mask = 0x3CFF;
|
||||
break;
|
||||
case QED_PTP_FILTER_V2_L2_GEN:
|
||||
enable_cfg = 0x5;
|
||||
rule_mask = 0x3EFF;
|
||||
break;
|
||||
case QED_PTP_FILTER_IPV4_IPV6:
|
||||
parm_mask = 0x7EA;
|
||||
rule_mask = 0x3FFE;
|
||||
case QED_PTP_FILTER_V2_EVENT:
|
||||
enable_cfg = 0x5;
|
||||
rule_mask = 0x3CAA;
|
||||
break;
|
||||
case QED_PTP_FILTER_IPV4:
|
||||
parm_mask = 0x7EE;
|
||||
rule_mask = 0x3FFE;
|
||||
case QED_PTP_FILTER_V2_GEN:
|
||||
enable_cfg = 0x5;
|
||||
rule_mask = 0x3EEE;
|
||||
break;
|
||||
default:
|
||||
DP_INFO(p_hwfn, "Invalid PTP filter type %d\n", type);
|
||||
DP_INFO(p_hwfn, "Invalid PTP filter type %d\n", rx_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_PARAM_MASK, parm_mask);
|
||||
qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_PARAM_MASK, 0);
|
||||
qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_RULE_MASK, rule_mask);
|
||||
qed_wr(p_hwfn, p_ptt, NIG_REG_RX_PTP_EN, enable_cfg);
|
||||
|
||||
qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_TO_HOST, 0x1);
|
||||
if (tx_type == QED_PTP_HWTSTAMP_TX_OFF) {
|
||||
qed_wr(p_hwfn, p_ptt, NIG_REG_TX_PTP_EN, 0x0);
|
||||
qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_PARAM_MASK, 0x7FF);
|
||||
qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_RULE_MASK, 0x3FFF);
|
||||
} else {
|
||||
qed_wr(p_hwfn, p_ptt, NIG_REG_TX_PTP_EN, enable_cfg);
|
||||
qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_PARAM_MASK, 0);
|
||||
qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_RULE_MASK, rule_mask);
|
||||
}
|
||||
|
||||
/* Reset possibly old timestamps */
|
||||
qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_HOST_BUF_SEQID,
|
||||
|
@ -383,17 +417,6 @@ static int qed_ptp_hw_enable(struct qed_dev *cdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int qed_ptp_hw_hwtstamp_tx_on(struct qed_dev *cdev)
|
||||
{
|
||||
struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
|
||||
struct qed_ptt *p_ptt = p_hwfn->p_ptp_ptt;
|
||||
|
||||
qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_PARAM_MASK, 0x6AA);
|
||||
qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_RULE_MASK, 0x3EEE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qed_ptp_hw_disable(struct qed_dev *cdev)
|
||||
{
|
||||
struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
|
||||
|
@ -419,8 +442,7 @@ static int qed_ptp_hw_disable(struct qed_dev *cdev)
|
|||
}
|
||||
|
||||
const struct qed_eth_ptp_ops qed_ptp_ops_pass = {
|
||||
.hwtstamp_tx_on = qed_ptp_hw_hwtstamp_tx_on,
|
||||
.cfg_rx_filters = qed_ptp_hw_cfg_rx_filters,
|
||||
.cfg_filters = qed_ptp_hw_cfg_filters,
|
||||
.read_rx_ts = qed_ptp_hw_read_rx_ts,
|
||||
.read_tx_ts = qed_ptp_hw_read_tx_ts,
|
||||
.read_cc = qed_ptp_hw_read_cc,
|
||||
|
|
|
@ -167,10 +167,11 @@ struct qede_dev {
|
|||
u32 dp_module;
|
||||
u8 dp_level;
|
||||
|
||||
u32 flags;
|
||||
#define QEDE_FLAG_IS_VF BIT(0)
|
||||
unsigned long flags;
|
||||
#define QEDE_FLAG_IS_VF BIT(0)
|
||||
#define IS_VF(edev) (!!((edev)->flags & QEDE_FLAG_IS_VF))
|
||||
#define QEDE_TX_TIMESTAMPING_EN BIT(1)
|
||||
#define QEDE_FLAGS_PTP_TX_IN_PRORGESS BIT(2)
|
||||
|
||||
const struct qed_eth_ops *ops;
|
||||
struct qede_ptp *ptp;
|
||||
|
|
|
@ -181,6 +181,7 @@ static void qede_ptp_task(struct work_struct *work)
|
|||
skb_tstamp_tx(ptp->tx_skb, &shhwtstamps);
|
||||
dev_kfree_skb_any(ptp->tx_skb);
|
||||
ptp->tx_skb = NULL;
|
||||
clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags);
|
||||
|
||||
DP_VERBOSE(edev, QED_MSG_DEBUG,
|
||||
"Tx timestamp, timestamp cycles = %llu, ns = %llu\n",
|
||||
|
@ -208,6 +209,8 @@ static u64 qede_ptp_read_cc(const struct cyclecounter *cc)
|
|||
|
||||
static int qede_ptp_cfg_filters(struct qede_dev *edev)
|
||||
{
|
||||
enum qed_ptp_hwtstamp_tx_type tx_type = QED_PTP_HWTSTAMP_TX_ON;
|
||||
enum qed_ptp_filter_type rx_filter = QED_PTP_FILTER_NONE;
|
||||
struct qede_ptp *ptp = edev->ptp;
|
||||
|
||||
if (!ptp)
|
||||
|
@ -221,7 +224,12 @@ static int qede_ptp_cfg_filters(struct qede_dev *edev)
|
|||
switch (ptp->tx_type) {
|
||||
case HWTSTAMP_TX_ON:
|
||||
edev->flags |= QEDE_TX_TIMESTAMPING_EN;
|
||||
ptp->ops->hwtstamp_tx_on(edev->cdev);
|
||||
tx_type = QED_PTP_HWTSTAMP_TX_ON;
|
||||
break;
|
||||
|
||||
case HWTSTAMP_TX_OFF:
|
||||
edev->flags &= ~QEDE_TX_TIMESTAMPING_EN;
|
||||
tx_type = QED_PTP_HWTSTAMP_TX_OFF;
|
||||
break;
|
||||
|
||||
case HWTSTAMP_TX_ONESTEP_SYNC:
|
||||
|
@ -232,42 +240,57 @@ static int qede_ptp_cfg_filters(struct qede_dev *edev)
|
|||
spin_lock_bh(&ptp->lock);
|
||||
switch (ptp->rx_filter) {
|
||||
case HWTSTAMP_FILTER_NONE:
|
||||
rx_filter = QED_PTP_FILTER_NONE;
|
||||
break;
|
||||
case HWTSTAMP_FILTER_ALL:
|
||||
case HWTSTAMP_FILTER_SOME:
|
||||
ptp->rx_filter = HWTSTAMP_FILTER_NONE;
|
||||
rx_filter = QED_PTP_FILTER_ALL;
|
||||
break;
|
||||
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
|
||||
ptp->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
|
||||
rx_filter = QED_PTP_FILTER_V1_L4_EVENT;
|
||||
break;
|
||||
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
|
||||
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
|
||||
ptp->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
|
||||
/* Initialize PTP detection for UDP/IPv4 events */
|
||||
ptp->ops->cfg_rx_filters(edev->cdev, QED_PTP_FILTER_IPV4);
|
||||
rx_filter = QED_PTP_FILTER_V1_L4_GEN;
|
||||
break;
|
||||
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
|
||||
ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
|
||||
rx_filter = QED_PTP_FILTER_V2_L4_EVENT;
|
||||
break;
|
||||
case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
|
||||
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
|
||||
ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
|
||||
/* Initialize PTP detection for UDP/IPv4 or UDP/IPv6 events */
|
||||
ptp->ops->cfg_rx_filters(edev->cdev, QED_PTP_FILTER_IPV4_IPV6);
|
||||
rx_filter = QED_PTP_FILTER_V2_L4_GEN;
|
||||
break;
|
||||
case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
|
||||
ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
|
||||
rx_filter = QED_PTP_FILTER_V2_L2_EVENT;
|
||||
break;
|
||||
case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
|
||||
case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
|
||||
ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
|
||||
/* Initialize PTP detection L2 events */
|
||||
ptp->ops->cfg_rx_filters(edev->cdev, QED_PTP_FILTER_L2);
|
||||
rx_filter = QED_PTP_FILTER_V2_L2_GEN;
|
||||
break;
|
||||
case HWTSTAMP_FILTER_PTP_V2_EVENT:
|
||||
ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
|
||||
rx_filter = QED_PTP_FILTER_V2_EVENT;
|
||||
break;
|
||||
case HWTSTAMP_FILTER_PTP_V2_SYNC:
|
||||
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
|
||||
ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
|
||||
/* Initialize PTP detection L2, UDP/IPv4 or UDP/IPv6 events */
|
||||
ptp->ops->cfg_rx_filters(edev->cdev,
|
||||
QED_PTP_FILTER_L2_IPV4_IPV6);
|
||||
rx_filter = QED_PTP_FILTER_V2_GEN;
|
||||
break;
|
||||
}
|
||||
|
||||
ptp->ops->cfg_filters(edev->cdev, rx_filter, tx_type);
|
||||
|
||||
spin_unlock_bh(&ptp->lock);
|
||||
|
||||
return 0;
|
||||
|
@ -485,6 +508,9 @@ void qede_ptp_tx_ts(struct qede_dev *edev, struct sk_buff *skb)
|
|||
if (!ptp)
|
||||
return;
|
||||
|
||||
if (test_and_set_bit_lock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags))
|
||||
return;
|
||||
|
||||
if (unlikely(!(edev->flags & QEDE_TX_TIMESTAMPING_EN))) {
|
||||
DP_NOTICE(edev,
|
||||
"Tx timestamping was not enabled, this packet will not be timestamped\n");
|
||||
|
|
|
@ -164,10 +164,21 @@ struct qed_eth_cb_ops {
|
|||
#define QED_MAX_PHC_DRIFT_PPB 291666666
|
||||
|
||||
enum qed_ptp_filter_type {
|
||||
QED_PTP_FILTER_L2,
|
||||
QED_PTP_FILTER_IPV4,
|
||||
QED_PTP_FILTER_IPV4_IPV6,
|
||||
QED_PTP_FILTER_L2_IPV4_IPV6
|
||||
QED_PTP_FILTER_NONE,
|
||||
QED_PTP_FILTER_ALL,
|
||||
QED_PTP_FILTER_V1_L4_EVENT,
|
||||
QED_PTP_FILTER_V1_L4_GEN,
|
||||
QED_PTP_FILTER_V2_L4_EVENT,
|
||||
QED_PTP_FILTER_V2_L4_GEN,
|
||||
QED_PTP_FILTER_V2_L2_EVENT,
|
||||
QED_PTP_FILTER_V2_L2_GEN,
|
||||
QED_PTP_FILTER_V2_EVENT,
|
||||
QED_PTP_FILTER_V2_GEN
|
||||
};
|
||||
|
||||
enum qed_ptp_hwtstamp_tx_type {
|
||||
QED_PTP_HWTSTAMP_TX_OFF,
|
||||
QED_PTP_HWTSTAMP_TX_ON,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DCB
|
||||
|
@ -230,8 +241,8 @@ struct qed_eth_dcbnl_ops {
|
|||
#endif
|
||||
|
||||
struct qed_eth_ptp_ops {
|
||||
int (*hwtstamp_tx_on)(struct qed_dev *);
|
||||
int (*cfg_rx_filters)(struct qed_dev *, enum qed_ptp_filter_type);
|
||||
int (*cfg_filters)(struct qed_dev *, enum qed_ptp_filter_type,
|
||||
enum qed_ptp_hwtstamp_tx_type);
|
||||
int (*read_rx_ts)(struct qed_dev *, u64 *);
|
||||
int (*read_tx_ts)(struct qed_dev *, u64 *);
|
||||
int (*read_cc)(struct qed_dev *, u64 *);
|
||||
|
|
Loading…
Reference in New Issue
Block a user