can: mcp251xfd: add BQL support
This patch adds BQL support to the driver. Support for netdev_xmit_more() will be added in a separate patch series. Link: https://lore.kernel.org/r/20210114153448.1506901-7-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
Родитель
86f1e3b1dd
Коммит
4162e18e94
|
@ -335,6 +335,8 @@ static void mcp251xfd_ring_init(struct mcp251xfd_priv *priv)
|
||||||
u8 len;
|
u8 len;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
|
netdev_reset_queue(priv->ndev);
|
||||||
|
|
||||||
/* TEF */
|
/* TEF */
|
||||||
tef_ring = priv->tef;
|
tef_ring = priv->tef;
|
||||||
tef_ring->head = 0;
|
tef_ring->head = 0;
|
||||||
|
@ -1249,7 +1251,8 @@ mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
|
mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
|
||||||
const struct mcp251xfd_hw_tef_obj *hw_tef_obj)
|
const struct mcp251xfd_hw_tef_obj *hw_tef_obj,
|
||||||
|
unsigned int *frame_len_ptr)
|
||||||
{
|
{
|
||||||
struct net_device_stats *stats = &priv->ndev->stats;
|
struct net_device_stats *stats = &priv->ndev->stats;
|
||||||
u32 seq, seq_masked, tef_tail_masked;
|
u32 seq, seq_masked, tef_tail_masked;
|
||||||
|
@ -1271,7 +1274,8 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
|
||||||
stats->tx_bytes +=
|
stats->tx_bytes +=
|
||||||
can_rx_offload_get_echo_skb(&priv->offload,
|
can_rx_offload_get_echo_skb(&priv->offload,
|
||||||
mcp251xfd_get_tef_tail(priv),
|
mcp251xfd_get_tef_tail(priv),
|
||||||
hw_tef_obj->ts, NULL);
|
hw_tef_obj->ts,
|
||||||
|
frame_len_ptr);
|
||||||
stats->tx_packets++;
|
stats->tx_packets++;
|
||||||
priv->tef->tail++;
|
priv->tef->tail++;
|
||||||
|
|
||||||
|
@ -1329,6 +1333,7 @@ mcp251xfd_tef_obj_read(const struct mcp251xfd_priv *priv,
|
||||||
static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
|
static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
|
||||||
{
|
{
|
||||||
struct mcp251xfd_hw_tef_obj hw_tef_obj[MCP251XFD_TX_OBJ_NUM_MAX];
|
struct mcp251xfd_hw_tef_obj hw_tef_obj[MCP251XFD_TX_OBJ_NUM_MAX];
|
||||||
|
unsigned int total_frame_len = 0;
|
||||||
u8 tef_tail, len, l;
|
u8 tef_tail, len, l;
|
||||||
int err, i;
|
int err, i;
|
||||||
|
|
||||||
|
@ -1350,7 +1355,9 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i]);
|
unsigned int frame_len;
|
||||||
|
|
||||||
|
err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len);
|
||||||
/* -EAGAIN means the Sequence Number in the TEF
|
/* -EAGAIN means the Sequence Number in the TEF
|
||||||
* doesn't match our tef_tail. This can happen if we
|
* doesn't match our tef_tail. This can happen if we
|
||||||
* read the TEF objects too early. Leave loop let the
|
* read the TEF objects too early. Leave loop let the
|
||||||
|
@ -1360,6 +1367,8 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
|
||||||
goto out_netif_wake_queue;
|
goto out_netif_wake_queue;
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
total_frame_len += frame_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
out_netif_wake_queue:
|
out_netif_wake_queue:
|
||||||
|
@ -1390,6 +1399,7 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
tx_ring->tail += len;
|
tx_ring->tail += len;
|
||||||
|
netdev_completed_queue(priv->ndev, len, total_frame_len);
|
||||||
|
|
||||||
err = mcp251xfd_check_tef_tail(priv);
|
err = mcp251xfd_check_tef_tail(priv);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -2435,6 +2445,7 @@ static netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb,
|
||||||
struct mcp251xfd_priv *priv = netdev_priv(ndev);
|
struct mcp251xfd_priv *priv = netdev_priv(ndev);
|
||||||
struct mcp251xfd_tx_ring *tx_ring = priv->tx;
|
struct mcp251xfd_tx_ring *tx_ring = priv->tx;
|
||||||
struct mcp251xfd_tx_obj *tx_obj;
|
struct mcp251xfd_tx_obj *tx_obj;
|
||||||
|
unsigned int frame_len;
|
||||||
u8 tx_head;
|
u8 tx_head;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -2453,7 +2464,9 @@ static netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb,
|
||||||
if (mcp251xfd_get_tx_free(tx_ring) == 0)
|
if (mcp251xfd_get_tx_free(tx_ring) == 0)
|
||||||
netif_stop_queue(ndev);
|
netif_stop_queue(ndev);
|
||||||
|
|
||||||
can_put_echo_skb(skb, ndev, tx_head, 0);
|
frame_len = can_skb_get_frame_len(skb);
|
||||||
|
can_put_echo_skb(skb, ndev, tx_head, frame_len);
|
||||||
|
netdev_sent_queue(priv->ndev, frame_len);
|
||||||
|
|
||||||
err = mcp251xfd_tx_obj_write(priv, tx_obj);
|
err = mcp251xfd_tx_obj_write(priv, tx_obj);
|
||||||
if (err)
|
if (err)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче