mirror of https://gitee.com/openkylin/linux.git
net: aquantia: add PTP rings infrastructure
Add implementations of PTP rings alloc/free. PTP desing on this device uses two separate rings on a separate traffic class for traffic rx/tx. Third ring (hwts) is not a traffic ring, but is used only to receive timestamps of the transmitted packets. Signed-off-by: Egor Pomozov <epomozov@marvell.com> Co-developed-by: Sergey Samoilenko <sergey.samoilenko@aquantia.com> Signed-off-by: Sergey Samoilenko <sergey.samoilenko@aquantia.com> Co-developed-by: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com> Signed-off-by: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com> Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
910479a9f7
commit
94ad94558b
|
@ -240,6 +240,10 @@ struct aq_hw_ops {
|
||||||
int (*hw_set_offload)(struct aq_hw_s *self,
|
int (*hw_set_offload)(struct aq_hw_s *self,
|
||||||
struct aq_nic_cfg_s *aq_nic_cfg);
|
struct aq_nic_cfg_s *aq_nic_cfg);
|
||||||
|
|
||||||
|
int (*hw_tx_tc_mode_get)(struct aq_hw_s *self, u32 *tc_mode);
|
||||||
|
|
||||||
|
int (*hw_rx_tc_mode_get)(struct aq_hw_s *self, u32 *tc_mode);
|
||||||
|
|
||||||
void (*hw_get_ptp_ts)(struct aq_hw_s *self, u64 *stamp);
|
void (*hw_get_ptp_ts)(struct aq_hw_s *self, u64 *stamp);
|
||||||
|
|
||||||
int (*hw_adj_clock_freq)(struct aq_hw_s *self, s32 delta);
|
int (*hw_adj_clock_freq)(struct aq_hw_s *self, s32 delta);
|
||||||
|
|
|
@ -339,6 +339,14 @@ int aq_nic_init(struct aq_nic_s *self)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
|
|
||||||
|
err = aq_ptp_ring_alloc(self);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_exit;
|
||||||
|
|
||||||
|
err = aq_ptp_ring_init(self);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_exit;
|
||||||
|
|
||||||
netif_carrier_off(self->ndev);
|
netif_carrier_off(self->ndev);
|
||||||
|
|
||||||
err_exit:
|
err_exit:
|
||||||
|
@ -369,6 +377,10 @@ int aq_nic_start(struct aq_nic_s *self)
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = aq_ptp_ring_start(self);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_exit;
|
||||||
|
|
||||||
err = self->aq_hw_ops->hw_start(self->aq_hw);
|
err = self->aq_hw_ops->hw_start(self->aq_hw);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
|
@ -965,6 +977,8 @@ int aq_nic_stop(struct aq_nic_s *self)
|
||||||
self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
|
self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
|
||||||
aq_vec_stop(aq_vec);
|
aq_vec_stop(aq_vec);
|
||||||
|
|
||||||
|
aq_ptp_ring_stop(self);
|
||||||
|
|
||||||
return self->aq_hw_ops->hw_stop(self->aq_hw);
|
return self->aq_hw_ops->hw_stop(self->aq_hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -981,6 +995,8 @@ void aq_nic_deinit(struct aq_nic_s *self)
|
||||||
aq_vec_deinit(aq_vec);
|
aq_vec_deinit(aq_vec);
|
||||||
|
|
||||||
aq_ptp_unregister(self);
|
aq_ptp_unregister(self);
|
||||||
|
aq_ptp_ring_deinit(self);
|
||||||
|
aq_ptp_ring_free(self);
|
||||||
aq_ptp_free(self);
|
aq_ptp_free(self);
|
||||||
|
|
||||||
if (likely(self->aq_fw_ops->deinit)) {
|
if (likely(self->aq_fw_ops->deinit)) {
|
||||||
|
|
|
@ -12,14 +12,55 @@
|
||||||
|
|
||||||
#include "aq_nic.h"
|
#include "aq_nic.h"
|
||||||
#include "aq_ptp.h"
|
#include "aq_ptp.h"
|
||||||
|
#include "aq_ring.h"
|
||||||
|
|
||||||
|
struct ptp_skb_ring {
|
||||||
|
struct sk_buff **buff;
|
||||||
|
spinlock_t lock;
|
||||||
|
unsigned int size;
|
||||||
|
unsigned int head;
|
||||||
|
unsigned int tail;
|
||||||
|
};
|
||||||
|
|
||||||
struct aq_ptp_s {
|
struct aq_ptp_s {
|
||||||
struct aq_nic_s *aq_nic;
|
struct aq_nic_s *aq_nic;
|
||||||
spinlock_t ptp_lock;
|
spinlock_t ptp_lock;
|
||||||
|
spinlock_t ptp_ring_lock;
|
||||||
struct ptp_clock *ptp_clock;
|
struct ptp_clock *ptp_clock;
|
||||||
struct ptp_clock_info ptp_info;
|
struct ptp_clock_info ptp_info;
|
||||||
|
|
||||||
|
struct aq_ring_param_s ptp_ring_param;
|
||||||
|
|
||||||
|
struct aq_ring_s ptp_tx;
|
||||||
|
struct aq_ring_s ptp_rx;
|
||||||
|
struct aq_ring_s hwts_rx;
|
||||||
|
|
||||||
|
struct ptp_skb_ring skb_ring;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int aq_ptp_skb_ring_init(struct ptp_skb_ring *ring, unsigned int size)
|
||||||
|
{
|
||||||
|
struct sk_buff **buff = kmalloc(sizeof(*buff) * size, GFP_KERNEL);
|
||||||
|
|
||||||
|
if (!buff)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
spin_lock_init(&ring->lock);
|
||||||
|
|
||||||
|
ring->buff = buff;
|
||||||
|
ring->size = size;
|
||||||
|
ring->head = 0;
|
||||||
|
ring->tail = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void aq_ptp_skb_ring_release(struct ptp_skb_ring *ring)
|
||||||
|
{
|
||||||
|
kfree(ring->buff);
|
||||||
|
ring->buff = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* aq_ptp_adjfine
|
/* aq_ptp_adjfine
|
||||||
* @ptp: the ptp clock structure
|
* @ptp: the ptp clock structure
|
||||||
* @ppb: parts per billion adjustment from base
|
* @ppb: parts per billion adjustment from base
|
||||||
|
@ -107,6 +148,190 @@ static int aq_ptp_settime(struct ptp_clock_info *ptp,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int aq_ptp_ring_init(struct aq_nic_s *aq_nic)
|
||||||
|
{
|
||||||
|
struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (!aq_ptp)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err = aq_ring_init(&aq_ptp->ptp_tx);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_exit;
|
||||||
|
err = aq_nic->aq_hw_ops->hw_ring_tx_init(aq_nic->aq_hw,
|
||||||
|
&aq_ptp->ptp_tx,
|
||||||
|
&aq_ptp->ptp_ring_param);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_exit;
|
||||||
|
|
||||||
|
err = aq_ring_init(&aq_ptp->ptp_rx);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_exit;
|
||||||
|
err = aq_nic->aq_hw_ops->hw_ring_rx_init(aq_nic->aq_hw,
|
||||||
|
&aq_ptp->ptp_rx,
|
||||||
|
&aq_ptp->ptp_ring_param);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_exit;
|
||||||
|
|
||||||
|
err = aq_ring_rx_fill(&aq_ptp->ptp_rx);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_rx_free;
|
||||||
|
err = aq_nic->aq_hw_ops->hw_ring_rx_fill(aq_nic->aq_hw,
|
||||||
|
&aq_ptp->ptp_rx,
|
||||||
|
0U);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_rx_free;
|
||||||
|
|
||||||
|
err = aq_ring_init(&aq_ptp->hwts_rx);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_rx_free;
|
||||||
|
err = aq_nic->aq_hw_ops->hw_ring_rx_init(aq_nic->aq_hw,
|
||||||
|
&aq_ptp->hwts_rx,
|
||||||
|
&aq_ptp->ptp_ring_param);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err_rx_free:
|
||||||
|
aq_ring_rx_deinit(&aq_ptp->ptp_rx);
|
||||||
|
err_exit:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aq_ptp_ring_start(struct aq_nic_s *aq_nic)
|
||||||
|
{
|
||||||
|
struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (!aq_ptp)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err = aq_nic->aq_hw_ops->hw_ring_tx_start(aq_nic->aq_hw, &aq_ptp->ptp_tx);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_exit;
|
||||||
|
|
||||||
|
err = aq_nic->aq_hw_ops->hw_ring_rx_start(aq_nic->aq_hw, &aq_ptp->ptp_rx);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_exit;
|
||||||
|
|
||||||
|
err = aq_nic->aq_hw_ops->hw_ring_rx_start(aq_nic->aq_hw,
|
||||||
|
&aq_ptp->hwts_rx);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_exit;
|
||||||
|
|
||||||
|
err_exit:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aq_ptp_ring_stop(struct aq_nic_s *aq_nic)
|
||||||
|
{
|
||||||
|
struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
|
||||||
|
|
||||||
|
if (!aq_ptp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
aq_nic->aq_hw_ops->hw_ring_tx_stop(aq_nic->aq_hw, &aq_ptp->ptp_tx);
|
||||||
|
aq_nic->aq_hw_ops->hw_ring_rx_stop(aq_nic->aq_hw, &aq_ptp->ptp_rx);
|
||||||
|
|
||||||
|
aq_nic->aq_hw_ops->hw_ring_rx_stop(aq_nic->aq_hw, &aq_ptp->hwts_rx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void aq_ptp_ring_deinit(struct aq_nic_s *aq_nic)
|
||||||
|
{
|
||||||
|
struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
|
||||||
|
|
||||||
|
if (!aq_ptp || !aq_ptp->ptp_tx.aq_nic || !aq_ptp->ptp_rx.aq_nic)
|
||||||
|
return;
|
||||||
|
|
||||||
|
aq_ring_tx_clean(&aq_ptp->ptp_tx);
|
||||||
|
aq_ring_rx_deinit(&aq_ptp->ptp_rx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PTP_8TC_RING_IDX 8
|
||||||
|
#define PTP_4TC_RING_IDX 16
|
||||||
|
#define PTP_HWST_RING_IDX 31
|
||||||
|
|
||||||
|
int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic)
|
||||||
|
{
|
||||||
|
struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
|
||||||
|
unsigned int tx_ring_idx, rx_ring_idx;
|
||||||
|
struct aq_ring_s *hwts = 0;
|
||||||
|
u32 tx_tc_mode, rx_tc_mode;
|
||||||
|
struct aq_ring_s *ring;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!aq_ptp)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Index must to be 8 (8 TCs) or 16 (4 TCs).
|
||||||
|
* It depends from Traffic Class mode.
|
||||||
|
*/
|
||||||
|
aq_nic->aq_hw_ops->hw_tx_tc_mode_get(aq_nic->aq_hw, &tx_tc_mode);
|
||||||
|
if (tx_tc_mode == 0)
|
||||||
|
tx_ring_idx = PTP_8TC_RING_IDX;
|
||||||
|
else
|
||||||
|
tx_ring_idx = PTP_4TC_RING_IDX;
|
||||||
|
|
||||||
|
ring = aq_ring_tx_alloc(&aq_ptp->ptp_tx, aq_nic,
|
||||||
|
tx_ring_idx, &aq_nic->aq_nic_cfg);
|
||||||
|
if (!ring) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
aq_nic->aq_hw_ops->hw_rx_tc_mode_get(aq_nic->aq_hw, &rx_tc_mode);
|
||||||
|
if (rx_tc_mode == 0)
|
||||||
|
rx_ring_idx = PTP_8TC_RING_IDX;
|
||||||
|
else
|
||||||
|
rx_ring_idx = PTP_4TC_RING_IDX;
|
||||||
|
|
||||||
|
ring = aq_ring_rx_alloc(&aq_ptp->ptp_rx, aq_nic,
|
||||||
|
rx_ring_idx, &aq_nic->aq_nic_cfg);
|
||||||
|
if (!ring) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_exit_ptp_tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
hwts = aq_ring_hwts_rx_alloc(&aq_ptp->hwts_rx, aq_nic, PTP_HWST_RING_IDX,
|
||||||
|
aq_nic->aq_nic_cfg.rxds,
|
||||||
|
aq_nic->aq_nic_cfg.aq_hw_caps->rxd_size);
|
||||||
|
if (!hwts) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_exit_ptp_rx;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = aq_ptp_skb_ring_init(&aq_ptp->skb_ring, aq_nic->aq_nic_cfg.rxds);
|
||||||
|
if (err != 0) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_exit_hwts_rx;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_exit_hwts_rx:
|
||||||
|
aq_ring_free(&aq_ptp->hwts_rx);
|
||||||
|
err_exit_ptp_rx:
|
||||||
|
aq_ring_free(&aq_ptp->ptp_rx);
|
||||||
|
err_exit_ptp_tx:
|
||||||
|
aq_ring_free(&aq_ptp->ptp_tx);
|
||||||
|
err_exit:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aq_ptp_ring_free(struct aq_nic_s *aq_nic)
|
||||||
|
{
|
||||||
|
struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
|
||||||
|
|
||||||
|
if (!aq_ptp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
aq_ring_free(&aq_ptp->ptp_tx);
|
||||||
|
aq_ring_free(&aq_ptp->ptp_rx);
|
||||||
|
aq_ring_free(&aq_ptp->hwts_rx);
|
||||||
|
|
||||||
|
aq_ptp_skb_ring_release(&aq_ptp->skb_ring);
|
||||||
|
}
|
||||||
|
|
||||||
static struct ptp_clock_info aq_ptp_clock = {
|
static struct ptp_clock_info aq_ptp_clock = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "atlantic ptp",
|
.name = "atlantic ptp",
|
||||||
|
@ -122,6 +347,15 @@ static struct ptp_clock_info aq_ptp_clock = {
|
||||||
.pin_config = NULL,
|
.pin_config = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void aq_ptp_clock_init(struct aq_nic_s *aq_nic)
|
||||||
|
{
|
||||||
|
struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
|
||||||
|
struct timespec64 ts;
|
||||||
|
|
||||||
|
ktime_get_real_ts64(&ts);
|
||||||
|
aq_ptp_settime(&aq_ptp->ptp_info, &ts);
|
||||||
|
}
|
||||||
|
|
||||||
int aq_ptp_init(struct aq_nic_s *aq_nic, unsigned int idx_vec)
|
int aq_ptp_init(struct aq_nic_s *aq_nic, unsigned int idx_vec)
|
||||||
{
|
{
|
||||||
struct hw_atl_utils_mbox mbox;
|
struct hw_atl_utils_mbox mbox;
|
||||||
|
@ -155,6 +389,7 @@ int aq_ptp_init(struct aq_nic_s *aq_nic, unsigned int idx_vec)
|
||||||
aq_ptp->aq_nic = aq_nic;
|
aq_ptp->aq_nic = aq_nic;
|
||||||
|
|
||||||
spin_lock_init(&aq_ptp->ptp_lock);
|
spin_lock_init(&aq_ptp->ptp_lock);
|
||||||
|
spin_lock_init(&aq_ptp->ptp_ring_lock);
|
||||||
|
|
||||||
aq_ptp->ptp_info = aq_ptp_clock;
|
aq_ptp->ptp_info = aq_ptp_clock;
|
||||||
clock = ptp_clock_register(&aq_ptp->ptp_info, &aq_nic->ndev->dev);
|
clock = ptp_clock_register(&aq_ptp->ptp_info, &aq_nic->ndev->dev);
|
||||||
|
|
|
@ -17,6 +17,14 @@ int aq_ptp_init(struct aq_nic_s *aq_nic, unsigned int idx_vec);
|
||||||
void aq_ptp_unregister(struct aq_nic_s *aq_nic);
|
void aq_ptp_unregister(struct aq_nic_s *aq_nic);
|
||||||
void aq_ptp_free(struct aq_nic_s *aq_nic);
|
void aq_ptp_free(struct aq_nic_s *aq_nic);
|
||||||
|
|
||||||
|
int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic);
|
||||||
|
void aq_ptp_ring_free(struct aq_nic_s *aq_nic);
|
||||||
|
|
||||||
|
int aq_ptp_ring_init(struct aq_nic_s *aq_nic);
|
||||||
|
int aq_ptp_ring_start(struct aq_nic_s *aq_nic);
|
||||||
|
void aq_ptp_ring_stop(struct aq_nic_s *aq_nic);
|
||||||
|
void aq_ptp_ring_deinit(struct aq_nic_s *aq_nic);
|
||||||
|
|
||||||
void aq_ptp_clock_init(struct aq_nic_s *aq_nic);
|
void aq_ptp_clock_init(struct aq_nic_s *aq_nic);
|
||||||
|
|
||||||
#endif /* AQ_PTP_H */
|
#endif /* AQ_PTP_H */
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* aQuantia Corporation Network Driver
|
* aQuantia Corporation Network Driver
|
||||||
* Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
|
* Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* File aq_ring.c: Definition of functions for Rx/Tx rings. */
|
/* File aq_ring.c: Definition of functions for Rx/Tx rings. */
|
||||||
|
@ -177,6 +177,30 @@ struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self,
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct aq_ring_s *
|
||||||
|
aq_ring_hwts_rx_alloc(struct aq_ring_s *self, struct aq_nic_s *aq_nic,
|
||||||
|
unsigned int idx, unsigned int size, unsigned int dx_size)
|
||||||
|
{
|
||||||
|
struct device *dev = aq_nic_get_dev(aq_nic);
|
||||||
|
size_t sz = size * dx_size + AQ_CFG_RXDS_DEF;
|
||||||
|
|
||||||
|
memset(self, 0, sizeof(*self));
|
||||||
|
|
||||||
|
self->aq_nic = aq_nic;
|
||||||
|
self->idx = idx;
|
||||||
|
self->size = size;
|
||||||
|
self->dx_size = dx_size;
|
||||||
|
|
||||||
|
self->dx_ring = dma_alloc_coherent(dev, sz, &self->dx_ring_pa,
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!self->dx_ring) {
|
||||||
|
aq_ring_free(self);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
int aq_ring_init(struct aq_ring_s *self)
|
int aq_ring_init(struct aq_ring_s *self)
|
||||||
{
|
{
|
||||||
self->hw_head = 0;
|
self->hw_head = 0;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* aQuantia Corporation Network Driver
|
* aQuantia Corporation Network Driver
|
||||||
* Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
|
* Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* File aq_ring.h: Declaration of functions for Rx/Tx rings. */
|
/* File aq_ring.h: Declaration of functions for Rx/Tx rings. */
|
||||||
|
@ -174,4 +174,8 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
|
||||||
int budget);
|
int budget);
|
||||||
int aq_ring_rx_fill(struct aq_ring_s *self);
|
int aq_ring_rx_fill(struct aq_ring_s *self);
|
||||||
|
|
||||||
|
struct aq_ring_s *aq_ring_hwts_rx_alloc(struct aq_ring_s *self,
|
||||||
|
struct aq_nic_s *aq_nic, unsigned int idx,
|
||||||
|
unsigned int size, unsigned int dx_size);
|
||||||
|
|
||||||
#endif /* AQ_RING_H */
|
#endif /* AQ_RING_H */
|
||||||
|
|
|
@ -126,13 +126,16 @@ static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self)
|
||||||
hw_atl_tps_tx_pkt_shed_desc_tc_arb_mode_set(self, 0U);
|
hw_atl_tps_tx_pkt_shed_desc_tc_arb_mode_set(self, 0U);
|
||||||
hw_atl_tps_tx_pkt_shed_data_arb_mode_set(self, 0U);
|
hw_atl_tps_tx_pkt_shed_data_arb_mode_set(self, 0U);
|
||||||
|
|
||||||
hw_atl_tps_tx_pkt_shed_tc_data_max_credit_set(self, 0xFFF, 0U);
|
tc = 0;
|
||||||
hw_atl_tps_tx_pkt_shed_tc_data_weight_set(self, 0x64, 0U);
|
|
||||||
hw_atl_tps_tx_pkt_shed_desc_tc_max_credit_set(self, 0x50, 0U);
|
|
||||||
hw_atl_tps_tx_pkt_shed_desc_tc_weight_set(self, 0x1E, 0U);
|
|
||||||
|
|
||||||
/* Tx buf size */
|
/* TX Packet Scheduler Data TC0 */
|
||||||
buff_size = HW_ATL_B0_TXBUF_MAX;
|
hw_atl_tps_tx_pkt_shed_tc_data_max_credit_set(self, 0xFFF, tc);
|
||||||
|
hw_atl_tps_tx_pkt_shed_tc_data_weight_set(self, 0x64, tc);
|
||||||
|
hw_atl_tps_tx_pkt_shed_desc_tc_max_credit_set(self, 0x50, tc);
|
||||||
|
hw_atl_tps_tx_pkt_shed_desc_tc_weight_set(self, 0x1E, tc);
|
||||||
|
|
||||||
|
/* Tx buf size TC0 */
|
||||||
|
buff_size = HW_ATL_B0_TXBUF_MAX - HW_ATL_B0_PTP_TXBUF_SIZE;
|
||||||
|
|
||||||
hw_atl_tpb_tx_pkt_buff_size_per_tc_set(self, buff_size, tc);
|
hw_atl_tpb_tx_pkt_buff_size_per_tc_set(self, buff_size, tc);
|
||||||
hw_atl_tpb_tx_buff_hi_threshold_per_tc_set(self,
|
hw_atl_tpb_tx_buff_hi_threshold_per_tc_set(self,
|
||||||
|
@ -143,10 +146,15 @@ static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self)
|
||||||
(buff_size *
|
(buff_size *
|
||||||
(1024 / 32U) * 50U) /
|
(1024 / 32U) * 50U) /
|
||||||
100U, tc);
|
100U, tc);
|
||||||
|
/* Init TC2 for PTP_TX */
|
||||||
|
tc = 2;
|
||||||
|
|
||||||
|
hw_atl_tpb_tx_pkt_buff_size_per_tc_set(self, HW_ATL_B0_PTP_TXBUF_SIZE,
|
||||||
|
tc);
|
||||||
|
|
||||||
/* QoS Rx buf size per TC */
|
/* QoS Rx buf size per TC */
|
||||||
tc = 0;
|
tc = 0;
|
||||||
buff_size = HW_ATL_B0_RXBUF_MAX;
|
buff_size = HW_ATL_B0_RXBUF_MAX - HW_ATL_B0_PTP_RXBUF_SIZE;
|
||||||
|
|
||||||
hw_atl_rpb_rx_pkt_buff_size_per_tc_set(self, buff_size, tc);
|
hw_atl_rpb_rx_pkt_buff_size_per_tc_set(self, buff_size, tc);
|
||||||
hw_atl_rpb_rx_buff_hi_threshold_per_tc_set(self,
|
hw_atl_rpb_rx_buff_hi_threshold_per_tc_set(self,
|
||||||
|
@ -160,6 +168,14 @@ static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self)
|
||||||
|
|
||||||
hw_atl_b0_set_fc(self, self->aq_nic_cfg->flow_control, tc);
|
hw_atl_b0_set_fc(self, self->aq_nic_cfg->flow_control, tc);
|
||||||
|
|
||||||
|
/* Init TC2 for PTP_RX */
|
||||||
|
tc = 2;
|
||||||
|
|
||||||
|
hw_atl_rpb_rx_pkt_buff_size_per_tc_set(self, HW_ATL_B0_PTP_RXBUF_SIZE,
|
||||||
|
tc);
|
||||||
|
/* No flow control for PTP */
|
||||||
|
hw_atl_rpb_rx_xoff_en_per_tc_set(self, 0U, tc);
|
||||||
|
|
||||||
/* QoS 802.1p priority -> TC mapping */
|
/* QoS 802.1p priority -> TC mapping */
|
||||||
for (i_priority = 8U; i_priority--;)
|
for (i_priority = 8U; i_priority--;)
|
||||||
hw_atl_rpf_rpb_user_priority_tc_map_set(self, i_priority, 0U);
|
hw_atl_rpf_rpb_user_priority_tc_map_set(self, i_priority, 0U);
|
||||||
|
@ -1007,6 +1023,18 @@ static int hw_atl_b0_hw_ring_rx_stop(struct aq_hw_s *self,
|
||||||
return aq_hw_err_from_flags(self);
|
return aq_hw_err_from_flags(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hw_atl_b0_tx_tc_mode_get(struct aq_hw_s *self, u32 *tc_mode)
|
||||||
|
{
|
||||||
|
*tc_mode = hw_atl_rpb_tps_tx_tc_mode_get(self);
|
||||||
|
return aq_hw_err_from_flags(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hw_atl_b0_rx_tc_mode_get(struct aq_hw_s *self, u32 *tc_mode)
|
||||||
|
{
|
||||||
|
*tc_mode = hw_atl_rpb_rpf_rx_traf_class_mode_get(self);
|
||||||
|
return aq_hw_err_from_flags(self);
|
||||||
|
}
|
||||||
|
|
||||||
#define get_ptp_ts_val_u64(self, indx) \
|
#define get_ptp_ts_val_u64(self, indx) \
|
||||||
((u64)(hw_atl_pcs_ptp_clock_get(self, indx) & 0xffff))
|
((u64)(hw_atl_pcs_ptp_clock_get(self, indx) & 0xffff))
|
||||||
|
|
||||||
|
@ -1278,6 +1306,9 @@ const struct aq_hw_ops hw_atl_ops_b0 = {
|
||||||
.hw_get_hw_stats = hw_atl_utils_get_hw_stats,
|
.hw_get_hw_stats = hw_atl_utils_get_hw_stats,
|
||||||
.hw_get_fw_version = hw_atl_utils_get_fw_version,
|
.hw_get_fw_version = hw_atl_utils_get_fw_version,
|
||||||
|
|
||||||
|
.hw_tx_tc_mode_get = hw_atl_b0_tx_tc_mode_get,
|
||||||
|
.hw_rx_tc_mode_get = hw_atl_b0_rx_tc_mode_get,
|
||||||
|
|
||||||
.hw_get_ptp_ts = hw_atl_b0_get_ptp_ts,
|
.hw_get_ptp_ts = hw_atl_b0_get_ptp_ts,
|
||||||
.hw_adj_sys_clock = hw_atl_b0_adj_sys_clock,
|
.hw_adj_sys_clock = hw_atl_b0_adj_sys_clock,
|
||||||
.hw_set_sys_clock = hw_atl_b0_set_sys_clock,
|
.hw_set_sys_clock = hw_atl_b0_set_sys_clock,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* aQuantia Corporation Network Driver
|
* aQuantia Corporation Network Driver
|
||||||
* Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
|
* Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* File hw_atl_b0_internal.h: Definition of Atlantic B0 chip specific
|
/* File hw_atl_b0_internal.h: Definition of Atlantic B0 chip specific
|
||||||
|
@ -64,8 +64,11 @@
|
||||||
#define HW_ATL_B0_MPI_SPEED_MSK 0xFFFFU
|
#define HW_ATL_B0_MPI_SPEED_MSK 0xFFFFU
|
||||||
#define HW_ATL_B0_MPI_SPEED_SHIFT 16U
|
#define HW_ATL_B0_MPI_SPEED_SHIFT 16U
|
||||||
|
|
||||||
#define HW_ATL_B0_TXBUF_MAX 160U
|
#define HW_ATL_B0_TXBUF_MAX 160U
|
||||||
#define HW_ATL_B0_RXBUF_MAX 320U
|
#define HW_ATL_B0_PTP_TXBUF_SIZE 8U
|
||||||
|
|
||||||
|
#define HW_ATL_B0_RXBUF_MAX 320U
|
||||||
|
#define HW_ATL_B0_PTP_RXBUF_SIZE 16U
|
||||||
|
|
||||||
#define HW_ATL_B0_RSS_REDIRECTION_MAX 64U
|
#define HW_ATL_B0_RSS_REDIRECTION_MAX 64U
|
||||||
#define HW_ATL_B0_RSS_REDIRECTION_BITS 3U
|
#define HW_ATL_B0_RSS_REDIRECTION_BITS 3U
|
||||||
|
|
|
@ -572,6 +572,13 @@ void hw_atl_rpb_rpf_rx_traf_class_mode_set(struct aq_hw_s *aq_hw,
|
||||||
rx_traf_class_mode);
|
rx_traf_class_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 hw_atl_rpb_rpf_rx_traf_class_mode_get(struct aq_hw_s *aq_hw)
|
||||||
|
{
|
||||||
|
return aq_hw_read_reg_bit(aq_hw, HW_ATL_RPB_RPF_RX_TC_MODE_ADR,
|
||||||
|
HW_ATL_RPB_RPF_RX_TC_MODE_MSK,
|
||||||
|
HW_ATL_RPB_RPF_RX_TC_MODE_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
void hw_atl_rpb_rx_buff_en_set(struct aq_hw_s *aq_hw, u32 rx_buff_en)
|
void hw_atl_rpb_rx_buff_en_set(struct aq_hw_s *aq_hw, u32 rx_buff_en)
|
||||||
{
|
{
|
||||||
aq_hw_write_reg_bit(aq_hw, HW_ATL_RPB_RX_BUF_EN_ADR,
|
aq_hw_write_reg_bit(aq_hw, HW_ATL_RPB_RX_BUF_EN_ADR,
|
||||||
|
@ -1290,6 +1297,13 @@ void hw_atl_tpb_tx_buff_en_set(struct aq_hw_s *aq_hw, u32 tx_buff_en)
|
||||||
HW_ATL_TPB_TX_BUF_EN_SHIFT, tx_buff_en);
|
HW_ATL_TPB_TX_BUF_EN_SHIFT, tx_buff_en);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 hw_atl_rpb_tps_tx_tc_mode_get(struct aq_hw_s *aq_hw)
|
||||||
|
{
|
||||||
|
return aq_hw_read_reg_bit(aq_hw, HW_ATL_TPB_TX_TC_MODE_ADDR,
|
||||||
|
HW_ATL_TPB_TX_TC_MODE_MSK,
|
||||||
|
HW_ATL_TPB_TX_TC_MODE_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
void hw_atl_rpb_tps_tx_tc_mode_set(struct aq_hw_s *aq_hw,
|
void hw_atl_rpb_tps_tx_tc_mode_set(struct aq_hw_s *aq_hw,
|
||||||
u32 tx_traf_class_mode)
|
u32 tx_traf_class_mode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -292,6 +292,9 @@ void hw_atl_rpb_dma_sys_lbk_set(struct aq_hw_s *aq_hw, u32 dma_sys_lbk);
|
||||||
void hw_atl_rpb_rpf_rx_traf_class_mode_set(struct aq_hw_s *aq_hw,
|
void hw_atl_rpb_rpf_rx_traf_class_mode_set(struct aq_hw_s *aq_hw,
|
||||||
u32 rx_traf_class_mode);
|
u32 rx_traf_class_mode);
|
||||||
|
|
||||||
|
/* get rx traffic class mode */
|
||||||
|
u32 hw_atl_rpb_rpf_rx_traf_class_mode_get(struct aq_hw_s *aq_hw);
|
||||||
|
|
||||||
/* set rx buffer enable */
|
/* set rx buffer enable */
|
||||||
void hw_atl_rpb_rx_buff_en_set(struct aq_hw_s *aq_hw, u32 rx_buff_en);
|
void hw_atl_rpb_rx_buff_en_set(struct aq_hw_s *aq_hw, u32 rx_buff_en);
|
||||||
|
|
||||||
|
@ -605,6 +608,9 @@ void hw_atl_thm_lso_tcp_flag_of_middle_pkt_set(struct aq_hw_s *aq_hw,
|
||||||
void hw_atl_rpb_tps_tx_tc_mode_set(struct aq_hw_s *aq_hw,
|
void hw_atl_rpb_tps_tx_tc_mode_set(struct aq_hw_s *aq_hw,
|
||||||
u32 tx_traf_class_mode);
|
u32 tx_traf_class_mode);
|
||||||
|
|
||||||
|
/* get TX Traffic Class Mode */
|
||||||
|
u32 hw_atl_rpb_tps_tx_tc_mode_get(struct aq_hw_s *aq_hw);
|
||||||
|
|
||||||
/* set tx buffer enable */
|
/* set tx buffer enable */
|
||||||
void hw_atl_tpb_tx_buff_en_set(struct aq_hw_s *aq_hw, u32 tx_buff_en);
|
void hw_atl_tpb_tx_buff_en_set(struct aq_hw_s *aq_hw, u32 tx_buff_en);
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,14 @@ struct __packed hw_atl_rxd_wb_s {
|
||||||
u16 vlan;
|
u16 vlan;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Hardware rx HW TIMESTAMP writeback */
|
||||||
|
struct __packed hw_atl_rxd_hwts_wb_s {
|
||||||
|
u32 sec_hw;
|
||||||
|
u32 ns;
|
||||||
|
u32 sec_lw0;
|
||||||
|
u32 sec_lw1;
|
||||||
|
};
|
||||||
|
|
||||||
struct __packed hw_atl_stats_s {
|
struct __packed hw_atl_stats_s {
|
||||||
u32 uprc;
|
u32 uprc;
|
||||||
u32 mprc;
|
u32 mprc;
|
||||||
|
|
Loading…
Reference in New Issue