Merge branch 'stmmac-mq-part3'
Joao Pinto says: ==================== net: stmmac: adding multiple buffers and routing As agreed with David Miller, this patch-set is the third and last to enable multiple queues in stmmac. This third one focuses on: a) Enable multiple buffering to the driver and queue independent data b) Configuration of RX and TX queues' priority c) Configuration of RX queues' routing ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
03e1de5030
|
@ -83,6 +83,13 @@ Optional properties:
|
|||
- snps,dcb-algorithm: Queue to be enabled as DCB
|
||||
- snps,avb-algorithm: Queue to be enabled as AVB
|
||||
- snps,map-to-dma-channel: Channel to map
|
||||
- Specifiy specific packet routing:
|
||||
- snps,route-avcp: AV Untagged Control packets
|
||||
- snps,route-ptp: PTP Packets
|
||||
- snps,route-dcbcp: DCB Control Packets
|
||||
- snps,route-up: Untagged Packets
|
||||
- snps,route-multi-broad: Multicast & Broadcast Packets
|
||||
- snps,priority: RX queue priority (Range: 0x0 to 0xF)
|
||||
- Multiple TX Queues parameters: below the list of all the parameters to
|
||||
configure the multiple TX queues:
|
||||
- snps,tx-queues-to-use: number of TX queues to be used in the driver
|
||||
|
@ -101,6 +108,7 @@ Optional properties:
|
|||
- snps,idle_slope: unlock on WoL
|
||||
- snps,high_credit: max write outstanding req. limit
|
||||
- snps,low_credit: max read outstanding req. limit
|
||||
- snps,priority: TX queue priority (Range: 0x0 to 0xF)
|
||||
Examples:
|
||||
|
||||
stmmac_axi_setup: stmmac-axi-config {
|
||||
|
@ -115,6 +123,7 @@ Examples:
|
|||
queue0 {
|
||||
snps,dcb-algorithm;
|
||||
snps,map-to-dma-channel = <0x0>;
|
||||
snps,priority = <0x0>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -124,6 +133,7 @@ Examples:
|
|||
queue0 {
|
||||
snps,weight = <0x10>;
|
||||
snps,dcb-algorithm;
|
||||
snps,priority = <0x0>;
|
||||
};
|
||||
|
||||
queue1 {
|
||||
|
@ -132,6 +142,7 @@ Examples:
|
|||
snps,idle_slope = <0x1000>;
|
||||
snps,high_credit = <0x3E800>;
|
||||
snps,low_credit = <0xFFC18000>;
|
||||
snps,priority = <0x1>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -26,12 +26,15 @@
|
|||
|
||||
static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
|
||||
{
|
||||
struct stmmac_priv *priv = (struct stmmac_priv *)p;
|
||||
unsigned int entry = priv->cur_tx;
|
||||
struct dma_desc *desc = priv->dma_tx + entry;
|
||||
struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)p;
|
||||
unsigned int nopaged_len = skb_headlen(skb);
|
||||
struct stmmac_priv *priv = tx_q->priv_data;
|
||||
unsigned int entry = tx_q->cur_tx;
|
||||
unsigned int bmax, des2;
|
||||
unsigned int i = 1, len;
|
||||
struct dma_desc *desc;
|
||||
|
||||
desc = tx_q->dma_tx + entry;
|
||||
|
||||
if (priv->plat->enh_desc)
|
||||
bmax = BUF_SIZE_8KiB;
|
||||
|
@ -45,16 +48,16 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
|
|||
desc->des2 = cpu_to_le32(des2);
|
||||
if (dma_mapping_error(priv->device, des2))
|
||||
return -1;
|
||||
priv->tx_skbuff_dma[entry].buf = des2;
|
||||
priv->tx_skbuff_dma[entry].len = bmax;
|
||||
tx_q->tx_skbuff_dma[entry].buf = des2;
|
||||
tx_q->tx_skbuff_dma[entry].len = bmax;
|
||||
/* do not close the descriptor and do not set own bit */
|
||||
priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, STMMAC_CHAIN_MODE,
|
||||
0, false);
|
||||
|
||||
while (len != 0) {
|
||||
priv->tx_skbuff[entry] = NULL;
|
||||
tx_q->tx_skbuff[entry] = NULL;
|
||||
entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE);
|
||||
desc = priv->dma_tx + entry;
|
||||
desc = tx_q->dma_tx + entry;
|
||||
|
||||
if (len > bmax) {
|
||||
des2 = dma_map_single(priv->device,
|
||||
|
@ -63,8 +66,8 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
|
|||
desc->des2 = cpu_to_le32(des2);
|
||||
if (dma_mapping_error(priv->device, des2))
|
||||
return -1;
|
||||
priv->tx_skbuff_dma[entry].buf = des2;
|
||||
priv->tx_skbuff_dma[entry].len = bmax;
|
||||
tx_q->tx_skbuff_dma[entry].buf = des2;
|
||||
tx_q->tx_skbuff_dma[entry].len = bmax;
|
||||
priv->hw->desc->prepare_tx_desc(desc, 0, bmax, csum,
|
||||
STMMAC_CHAIN_MODE, 1,
|
||||
false);
|
||||
|
@ -77,8 +80,8 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
|
|||
desc->des2 = cpu_to_le32(des2);
|
||||
if (dma_mapping_error(priv->device, des2))
|
||||
return -1;
|
||||
priv->tx_skbuff_dma[entry].buf = des2;
|
||||
priv->tx_skbuff_dma[entry].len = len;
|
||||
tx_q->tx_skbuff_dma[entry].buf = des2;
|
||||
tx_q->tx_skbuff_dma[entry].len = len;
|
||||
/* last descriptor can be set now */
|
||||
priv->hw->desc->prepare_tx_desc(desc, 0, len, csum,
|
||||
STMMAC_CHAIN_MODE, 1,
|
||||
|
@ -87,7 +90,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
|
|||
}
|
||||
}
|
||||
|
||||
priv->cur_tx = entry;
|
||||
tx_q->cur_tx = entry;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
@ -136,32 +139,34 @@ static void stmmac_init_dma_chain(void *des, dma_addr_t phy_addr,
|
|||
|
||||
static void stmmac_refill_desc3(void *priv_ptr, struct dma_desc *p)
|
||||
{
|
||||
struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr;
|
||||
struct stmmac_rx_queue *rx_q = (struct stmmac_rx_queue *)priv_ptr;
|
||||
struct stmmac_priv *priv = rx_q->priv_data;
|
||||
|
||||
if (priv->hwts_rx_en && !priv->extend_desc)
|
||||
/* NOTE: Device will overwrite des3 with timestamp value if
|
||||
* 1588-2002 time stamping is enabled, hence reinitialize it
|
||||
* to keep explicit chaining in the descriptor.
|
||||
*/
|
||||
p->des3 = cpu_to_le32((unsigned int)(priv->dma_rx_phy +
|
||||
(((priv->dirty_rx) + 1) %
|
||||
p->des3 = cpu_to_le32((unsigned int)(rx_q->dma_rx_phy +
|
||||
(((rx_q->dirty_rx) + 1) %
|
||||
DMA_RX_SIZE) *
|
||||
sizeof(struct dma_desc)));
|
||||
}
|
||||
|
||||
static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p)
|
||||
{
|
||||
struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr;
|
||||
unsigned int entry = priv->dirty_tx;
|
||||
struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)priv_ptr;
|
||||
struct stmmac_priv *priv = tx_q->priv_data;
|
||||
unsigned int entry = tx_q->dirty_tx;
|
||||
|
||||
if (priv->tx_skbuff_dma[entry].last_segment && !priv->extend_desc &&
|
||||
if (tx_q->tx_skbuff_dma[entry].last_segment && !priv->extend_desc &&
|
||||
priv->hwts_tx_en)
|
||||
/* NOTE: Device will overwrite des3 with timestamp value if
|
||||
* 1588-2002 time stamping is enabled, hence reinitialize it
|
||||
* to keep explicit chaining in the descriptor.
|
||||
*/
|
||||
p->des3 = cpu_to_le32((unsigned int)((priv->dma_tx_phy +
|
||||
((priv->dirty_tx + 1) % DMA_TX_SIZE))
|
||||
p->des3 = cpu_to_le32((unsigned int)((tx_q->dma_tx_phy +
|
||||
((tx_q->dirty_tx + 1) % DMA_TX_SIZE))
|
||||
* sizeof(struct dma_desc)));
|
||||
}
|
||||
|
||||
|
|
|
@ -246,6 +246,15 @@ struct stmmac_extra_stats {
|
|||
#define STMMAC_TX_MAX_FRAMES 256
|
||||
#define STMMAC_TX_FRAMES 64
|
||||
|
||||
/* Packets types */
|
||||
enum packets_types {
|
||||
PACKET_AVCPQ = 0x1, /* AV Untagged Control packets */
|
||||
PACKET_PTPQ = 0x2, /* PTP Packets */
|
||||
PACKET_DCBCPQ = 0x3, /* DCB Control Packets */
|
||||
PACKET_UPQ = 0x4, /* Untagged Packets */
|
||||
PACKET_MCBCQ = 0x5, /* Multicast & Broadcast Packets */
|
||||
};
|
||||
|
||||
/* Rx IPC status */
|
||||
enum rx_frame_status {
|
||||
good_frame = 0x0,
|
||||
|
@ -469,6 +478,13 @@ struct stmmac_ops {
|
|||
int (*rx_ipc)(struct mac_device_info *hw);
|
||||
/* Enable RX Queues */
|
||||
void (*rx_queue_enable)(struct mac_device_info *hw, u8 mode, u32 queue);
|
||||
/* RX Queues Priority */
|
||||
void (*rx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue);
|
||||
/* TX Queues Priority */
|
||||
void (*tx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue);
|
||||
/* RX Queues Routing */
|
||||
void (*rx_queue_routing)(struct mac_device_info *hw, u8 packet,
|
||||
u32 queue);
|
||||
/* Program RX Algorithms */
|
||||
void (*prog_mtl_rx_algorithms)(struct mac_device_info *hw, u32 rx_alg);
|
||||
/* Program TX Algorithms */
|
||||
|
@ -577,6 +593,11 @@ struct mac_device_info {
|
|||
unsigned int ps;
|
||||
};
|
||||
|
||||
struct stmmac_rx_routing {
|
||||
u32 reg_mask;
|
||||
u32 reg_shift;
|
||||
};
|
||||
|
||||
struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
|
||||
int perfect_uc_entries,
|
||||
int *synopsys_id);
|
||||
|
|
|
@ -22,7 +22,12 @@
|
|||
#define GMAC_HASH_TAB_32_63 0x00000014
|
||||
#define GMAC_RX_FLOW_CTRL 0x00000090
|
||||
#define GMAC_QX_TX_FLOW_CTRL(x) (0x70 + x * 4)
|
||||
#define GMAC_TXQ_PRTY_MAP0 0x98
|
||||
#define GMAC_TXQ_PRTY_MAP1 0x9C
|
||||
#define GMAC_RXQ_CTRL0 0x000000a0
|
||||
#define GMAC_RXQ_CTRL1 0x000000a4
|
||||
#define GMAC_RXQ_CTRL2 0x000000a8
|
||||
#define GMAC_RXQ_CTRL3 0x000000ac
|
||||
#define GMAC_INT_STATUS 0x000000b0
|
||||
#define GMAC_INT_EN 0x000000b4
|
||||
#define GMAC_1US_TIC_COUNTER 0x000000dc
|
||||
|
@ -39,6 +44,22 @@
|
|||
#define GMAC_ADDR_HIGH(reg) (0x300 + reg * 8)
|
||||
#define GMAC_ADDR_LOW(reg) (0x304 + reg * 8)
|
||||
|
||||
/* RX Queues Routing */
|
||||
#define GMAC_RXQCTRL_AVCPQ_MASK GENMASK(2, 0)
|
||||
#define GMAC_RXQCTRL_AVCPQ_SHIFT 0
|
||||
#define GMAC_RXQCTRL_PTPQ_MASK GENMASK(6, 4)
|
||||
#define GMAC_RXQCTRL_PTPQ_SHIFT 4
|
||||
#define GMAC_RXQCTRL_DCBCPQ_MASK GENMASK(10, 8)
|
||||
#define GMAC_RXQCTRL_DCBCPQ_SHIFT 8
|
||||
#define GMAC_RXQCTRL_UPQ_MASK GENMASK(14, 12)
|
||||
#define GMAC_RXQCTRL_UPQ_SHIFT 12
|
||||
#define GMAC_RXQCTRL_MCBCQ_MASK GENMASK(18, 16)
|
||||
#define GMAC_RXQCTRL_MCBCQ_SHIFT 16
|
||||
#define GMAC_RXQCTRL_MCBCQEN BIT(20)
|
||||
#define GMAC_RXQCTRL_MCBCQEN_SHIFT 20
|
||||
#define GMAC_RXQCTRL_TACPQE BIT(21)
|
||||
#define GMAC_RXQCTRL_TACPQE_SHIFT 21
|
||||
|
||||
/* MAC Packet Filtering */
|
||||
#define GMAC_PACKET_FILTER_PR BIT(0)
|
||||
#define GMAC_PACKET_FILTER_HMC BIT(2)
|
||||
|
@ -54,6 +75,14 @@
|
|||
/* MAC Flow Control RX */
|
||||
#define GMAC_RX_FLOW_CTRL_RFE BIT(0)
|
||||
|
||||
/* RX Queues Priorities */
|
||||
#define GMAC_RXQCTRL_PSRQX_MASK(x) GENMASK(7 + ((x) * 8), 0 + ((x) * 8))
|
||||
#define GMAC_RXQCTRL_PSRQX_SHIFT(x) ((x) * 8)
|
||||
|
||||
/* TX Queues Priorities */
|
||||
#define GMAC_TXQCTRL_PSTQX_MASK(x) GENMASK(7 + ((x) * 8), 0 + ((x) * 8))
|
||||
#define GMAC_TXQCTRL_PSTQX_SHIFT(x) ((x) * 8)
|
||||
|
||||
/* MAC Flow Control TX */
|
||||
#define GMAC_TX_FLOW_CTRL_TFE BIT(1)
|
||||
#define GMAC_TX_FLOW_CTRL_PT_SHIFT 16
|
||||
|
|
|
@ -74,6 +74,74 @@ static void dwmac4_rx_queue_enable(struct mac_device_info *hw,
|
|||
writel(value, ioaddr + GMAC_RXQ_CTRL0);
|
||||
}
|
||||
|
||||
static void dwmac4_rx_queue_priority(struct mac_device_info *hw,
|
||||
u32 prio, u32 queue)
|
||||
{
|
||||
void __iomem *ioaddr = hw->pcsr;
|
||||
u32 base_register;
|
||||
u32 value;
|
||||
|
||||
base_register = (queue < 4) ? GMAC_RXQ_CTRL2 : GMAC_RXQ_CTRL3;
|
||||
|
||||
value = readl(ioaddr + base_register);
|
||||
|
||||
value &= ~GMAC_RXQCTRL_PSRQX_MASK(queue);
|
||||
value |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
|
||||
GMAC_RXQCTRL_PSRQX_MASK(queue);
|
||||
writel(value, ioaddr + base_register);
|
||||
}
|
||||
|
||||
static void dwmac4_tx_queue_priority(struct mac_device_info *hw,
|
||||
u32 prio, u32 queue)
|
||||
{
|
||||
void __iomem *ioaddr = hw->pcsr;
|
||||
u32 base_register;
|
||||
u32 value;
|
||||
|
||||
base_register = (queue < 4) ? GMAC_TXQ_PRTY_MAP0 : GMAC_TXQ_PRTY_MAP1;
|
||||
|
||||
value = readl(ioaddr + base_register);
|
||||
|
||||
value &= ~GMAC_TXQCTRL_PSTQX_MASK(queue);
|
||||
value |= (prio << GMAC_TXQCTRL_PSTQX_SHIFT(queue)) &
|
||||
GMAC_TXQCTRL_PSTQX_MASK(queue);
|
||||
|
||||
writel(value, ioaddr + base_register);
|
||||
}
|
||||
|
||||
static void dwmac4_tx_queue_routing(struct mac_device_info *hw,
|
||||
u8 packet, u32 queue)
|
||||
{
|
||||
void __iomem *ioaddr = hw->pcsr;
|
||||
u32 value;
|
||||
|
||||
const struct stmmac_rx_routing route_possibilities[] = {
|
||||
{ GMAC_RXQCTRL_AVCPQ_MASK, GMAC_RXQCTRL_AVCPQ_SHIFT },
|
||||
{ GMAC_RXQCTRL_PTPQ_MASK, GMAC_RXQCTRL_PTPQ_SHIFT },
|
||||
{ GMAC_RXQCTRL_DCBCPQ_MASK, GMAC_RXQCTRL_DCBCPQ_SHIFT },
|
||||
{ GMAC_RXQCTRL_UPQ_MASK, GMAC_RXQCTRL_UPQ_SHIFT },
|
||||
{ GMAC_RXQCTRL_MCBCQ_MASK, GMAC_RXQCTRL_MCBCQ_SHIFT },
|
||||
};
|
||||
|
||||
value = readl(ioaddr + GMAC_RXQ_CTRL1);
|
||||
|
||||
/* routing configuration */
|
||||
value &= ~route_possibilities[packet - 1].reg_mask;
|
||||
value |= (queue << route_possibilities[packet-1].reg_shift) &
|
||||
route_possibilities[packet - 1].reg_mask;
|
||||
|
||||
/* some packets require extra ops */
|
||||
if (packet == PACKET_AVCPQ) {
|
||||
value &= ~GMAC_RXQCTRL_TACPQE;
|
||||
value |= 0x1 << GMAC_RXQCTRL_TACPQE_SHIFT;
|
||||
} else if (packet == PACKET_MCBCQ) {
|
||||
value &= ~GMAC_RXQCTRL_MCBCQEN;
|
||||
value |= 0x1 << GMAC_RXQCTRL_MCBCQEN_SHIFT;
|
||||
}
|
||||
|
||||
writel(value, ioaddr + GMAC_RXQ_CTRL1);
|
||||
}
|
||||
|
||||
static void dwmac4_prog_mtl_rx_algorithms(struct mac_device_info *hw,
|
||||
u32 rx_alg)
|
||||
{
|
||||
|
@ -603,6 +671,9 @@ static const struct stmmac_ops dwmac4_ops = {
|
|||
.core_init = dwmac4_core_init,
|
||||
.rx_ipc = dwmac4_rx_ipc_enable,
|
||||
.rx_queue_enable = dwmac4_rx_queue_enable,
|
||||
.rx_queue_prio = dwmac4_rx_queue_priority,
|
||||
.tx_queue_prio = dwmac4_tx_queue_priority,
|
||||
.rx_queue_routing = dwmac4_tx_queue_routing,
|
||||
.prog_mtl_rx_algorithms = dwmac4_prog_mtl_rx_algorithms,
|
||||
.prog_mtl_tx_algorithms = dwmac4_prog_mtl_tx_algorithms,
|
||||
.set_mtl_tx_queue_weight = dwmac4_set_mtl_tx_queue_weight,
|
||||
|
|
|
@ -26,16 +26,17 @@
|
|||
|
||||
static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
|
||||
{
|
||||
struct stmmac_priv *priv = (struct stmmac_priv *)p;
|
||||
unsigned int entry = priv->cur_tx;
|
||||
struct dma_desc *desc;
|
||||
struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)p;
|
||||
unsigned int nopaged_len = skb_headlen(skb);
|
||||
struct stmmac_priv *priv = tx_q->priv_data;
|
||||
unsigned int entry = tx_q->cur_tx;
|
||||
unsigned int bmax, len, des2;
|
||||
struct dma_desc *desc;
|
||||
|
||||
if (priv->extend_desc)
|
||||
desc = (struct dma_desc *)(priv->dma_etx + entry);
|
||||
desc = (struct dma_desc *)(tx_q->dma_etx + entry);
|
||||
else
|
||||
desc = priv->dma_tx + entry;
|
||||
desc = tx_q->dma_tx + entry;
|
||||
|
||||
if (priv->plat->enh_desc)
|
||||
bmax = BUF_SIZE_8KiB;
|
||||
|
@ -52,29 +53,29 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
|
|||
if (dma_mapping_error(priv->device, des2))
|
||||
return -1;
|
||||
|
||||
priv->tx_skbuff_dma[entry].buf = des2;
|
||||
priv->tx_skbuff_dma[entry].len = bmax;
|
||||
priv->tx_skbuff_dma[entry].is_jumbo = true;
|
||||
tx_q->tx_skbuff_dma[entry].buf = des2;
|
||||
tx_q->tx_skbuff_dma[entry].len = bmax;
|
||||
tx_q->tx_skbuff_dma[entry].is_jumbo = true;
|
||||
|
||||
desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB);
|
||||
priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum,
|
||||
STMMAC_RING_MODE, 0, false);
|
||||
priv->tx_skbuff[entry] = NULL;
|
||||
tx_q->tx_skbuff[entry] = NULL;
|
||||
entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE);
|
||||
|
||||
if (priv->extend_desc)
|
||||
desc = (struct dma_desc *)(priv->dma_etx + entry);
|
||||
desc = (struct dma_desc *)(tx_q->dma_etx + entry);
|
||||
else
|
||||
desc = priv->dma_tx + entry;
|
||||
desc = tx_q->dma_tx + entry;
|
||||
|
||||
des2 = dma_map_single(priv->device, skb->data + bmax, len,
|
||||
DMA_TO_DEVICE);
|
||||
desc->des2 = cpu_to_le32(des2);
|
||||
if (dma_mapping_error(priv->device, des2))
|
||||
return -1;
|
||||
priv->tx_skbuff_dma[entry].buf = des2;
|
||||
priv->tx_skbuff_dma[entry].len = len;
|
||||
priv->tx_skbuff_dma[entry].is_jumbo = true;
|
||||
tx_q->tx_skbuff_dma[entry].buf = des2;
|
||||
tx_q->tx_skbuff_dma[entry].len = len;
|
||||
tx_q->tx_skbuff_dma[entry].is_jumbo = true;
|
||||
|
||||
desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB);
|
||||
priv->hw->desc->prepare_tx_desc(desc, 0, len, csum,
|
||||
|
@ -85,15 +86,15 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
|
|||
desc->des2 = cpu_to_le32(des2);
|
||||
if (dma_mapping_error(priv->device, des2))
|
||||
return -1;
|
||||
priv->tx_skbuff_dma[entry].buf = des2;
|
||||
priv->tx_skbuff_dma[entry].len = nopaged_len;
|
||||
priv->tx_skbuff_dma[entry].is_jumbo = true;
|
||||
tx_q->tx_skbuff_dma[entry].buf = des2;
|
||||
tx_q->tx_skbuff_dma[entry].len = nopaged_len;
|
||||
tx_q->tx_skbuff_dma[entry].is_jumbo = true;
|
||||
desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB);
|
||||
priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, csum,
|
||||
STMMAC_RING_MODE, 0, true);
|
||||
}
|
||||
|
||||
priv->cur_tx = entry;
|
||||
tx_q->cur_tx = entry;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
@ -125,12 +126,13 @@ static void stmmac_init_desc3(struct dma_desc *p)
|
|||
|
||||
static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p)
|
||||
{
|
||||
struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr;
|
||||
unsigned int entry = priv->dirty_tx;
|
||||
struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)priv_ptr;
|
||||
struct stmmac_priv *priv = tx_q->priv_data;
|
||||
unsigned int entry = tx_q->dirty_tx;
|
||||
|
||||
/* des3 is only used for jumbo frames tx or time stamping */
|
||||
if (unlikely(priv->tx_skbuff_dma[entry].is_jumbo ||
|
||||
(priv->tx_skbuff_dma[entry].last_segment &&
|
||||
if (unlikely(tx_q->tx_skbuff_dma[entry].is_jumbo ||
|
||||
(tx_q->tx_skbuff_dma[entry].last_segment &&
|
||||
!priv->extend_desc && priv->hwts_tx_en)))
|
||||
p->des3 = 0;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,35 @@ struct stmmac_tx_info {
|
|||
bool is_jumbo;
|
||||
};
|
||||
|
||||
/* Frequently used values are kept adjacent for cache effect */
|
||||
struct stmmac_tx_queue {
|
||||
u32 queue_index;
|
||||
struct stmmac_priv *priv_data;
|
||||
struct dma_extended_desc *dma_etx ____cacheline_aligned_in_smp;
|
||||
struct dma_desc *dma_tx;
|
||||
struct sk_buff **tx_skbuff;
|
||||
struct stmmac_tx_info *tx_skbuff_dma;
|
||||
unsigned int cur_tx;
|
||||
unsigned int dirty_tx;
|
||||
dma_addr_t dma_tx_phy;
|
||||
u32 tx_tail_addr;
|
||||
};
|
||||
|
||||
struct stmmac_rx_queue {
|
||||
u32 queue_index;
|
||||
struct stmmac_priv *priv_data;
|
||||
struct dma_extended_desc *dma_erx;
|
||||
struct dma_desc *dma_rx ____cacheline_aligned_in_smp;
|
||||
struct sk_buff **rx_skbuff;
|
||||
dma_addr_t *rx_skbuff_dma;
|
||||
struct napi_struct napi ____cacheline_aligned_in_smp;
|
||||
unsigned int cur_rx;
|
||||
unsigned int dirty_rx;
|
||||
u32 rx_zeroc_thresh;
|
||||
dma_addr_t dma_rx_phy;
|
||||
u32 rx_tail_addr;
|
||||
};
|
||||
|
||||
struct stmmac_priv {
|
||||
/* Frequently used values are kept adjacent for cache effect */
|
||||
struct dma_extended_desc *dma_etx ____cacheline_aligned_in_smp;
|
||||
|
@ -56,28 +85,22 @@ struct stmmac_priv {
|
|||
u32 tx_count_frames;
|
||||
u32 tx_coal_frames;
|
||||
u32 tx_coal_timer;
|
||||
struct stmmac_tx_info *tx_skbuff_dma;
|
||||
dma_addr_t dma_tx_phy;
|
||||
int tx_coalesce;
|
||||
int hwts_tx_en;
|
||||
bool tx_path_in_lpi_mode;
|
||||
struct timer_list txtimer;
|
||||
bool tso;
|
||||
|
||||
struct dma_desc *dma_rx ____cacheline_aligned_in_smp;
|
||||
struct dma_extended_desc *dma_erx;
|
||||
struct sk_buff **rx_skbuff;
|
||||
unsigned int cur_rx;
|
||||
unsigned int dirty_rx;
|
||||
/* TX Queue */
|
||||
struct stmmac_tx_queue *tx_queue;
|
||||
|
||||
/* RX Queue */
|
||||
struct stmmac_rx_queue *rx_queue;
|
||||
|
||||
unsigned int dma_buf_sz;
|
||||
unsigned int rx_copybreak;
|
||||
unsigned int rx_zeroc_thresh;
|
||||
u32 rx_riwt;
|
||||
int hwts_rx_en;
|
||||
dma_addr_t *rx_skbuff_dma;
|
||||
dma_addr_t dma_rx_phy;
|
||||
|
||||
struct napi_struct napi ____cacheline_aligned_in_smp;
|
||||
|
||||
void __iomem *ioaddr;
|
||||
struct net_device *dev;
|
||||
|
@ -119,8 +142,6 @@ struct stmmac_priv {
|
|||
spinlock_t ptp_lock;
|
||||
void __iomem *mmcaddr;
|
||||
void __iomem *ptpaddr;
|
||||
u32 rx_tail_addr;
|
||||
u32 tx_tail_addr;
|
||||
u32 mss;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -92,6 +92,13 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat)
|
|||
/* Set default number of RX and TX queues to use */
|
||||
plat->tx_queues_to_use = 1;
|
||||
plat->rx_queues_to_use = 1;
|
||||
|
||||
/* Disable Priority config by default */
|
||||
plat->tx_queues_cfg[0].use_prio = false;
|
||||
plat->rx_queues_cfg[0].use_prio = false;
|
||||
|
||||
/* Disable RX queues routing by default */
|
||||
plat->rx_queues_cfg[0].pkt_route = 0x0;
|
||||
}
|
||||
|
||||
static int quark_default_data(struct plat_stmmacenet_data *plat,
|
||||
|
|
|
@ -182,6 +182,28 @@ static void stmmac_mtl_setup(struct platform_device *pdev,
|
|||
plat->rx_queues_cfg[queue].chan = queue;
|
||||
/* TODO: Dynamic mapping to be included in the future */
|
||||
|
||||
if (of_property_read_u32(q_node, "snps,priority",
|
||||
&plat->rx_queues_cfg[queue].prio)) {
|
||||
plat->rx_queues_cfg[queue].prio = 0;
|
||||
plat->rx_queues_cfg[queue].use_prio = false;
|
||||
} else {
|
||||
plat->rx_queues_cfg[queue].use_prio = true;
|
||||
}
|
||||
|
||||
/* RX queue specific packet type routing */
|
||||
if (of_property_read_bool(q_node, "snps,route-avcp"))
|
||||
plat->rx_queues_cfg[queue].pkt_route = PACKET_AVCPQ;
|
||||
else if (of_property_read_bool(q_node, "snps,route-ptp"))
|
||||
plat->rx_queues_cfg[queue].pkt_route = PACKET_PTPQ;
|
||||
else if (of_property_read_bool(q_node, "snps,route-dcbcp"))
|
||||
plat->rx_queues_cfg[queue].pkt_route = PACKET_DCBCPQ;
|
||||
else if (of_property_read_bool(q_node, "snps,route-up"))
|
||||
plat->rx_queues_cfg[queue].pkt_route = PACKET_UPQ;
|
||||
else if (of_property_read_bool(q_node, "snps,route-multi-broad"))
|
||||
plat->rx_queues_cfg[queue].pkt_route = PACKET_MCBCQ;
|
||||
else
|
||||
plat->rx_queues_cfg[queue].pkt_route = 0x0;
|
||||
|
||||
queue++;
|
||||
}
|
||||
|
||||
|
@ -235,6 +257,14 @@ static void stmmac_mtl_setup(struct platform_device *pdev,
|
|||
plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
|
||||
}
|
||||
|
||||
if (of_property_read_u32(q_node, "snps,priority",
|
||||
&plat->tx_queues_cfg[queue].prio)) {
|
||||
plat->tx_queues_cfg[queue].prio = 0;
|
||||
plat->tx_queues_cfg[queue].use_prio = false;
|
||||
} else {
|
||||
plat->tx_queues_cfg[queue].use_prio = true;
|
||||
}
|
||||
|
||||
queue++;
|
||||
}
|
||||
|
||||
|
|
|
@ -127,6 +127,9 @@ struct stmmac_axi {
|
|||
struct stmmac_rxq_cfg {
|
||||
u8 mode_to_use;
|
||||
u8 chan;
|
||||
u8 pkt_route;
|
||||
bool use_prio;
|
||||
u32 prio;
|
||||
};
|
||||
|
||||
struct stmmac_txq_cfg {
|
||||
|
@ -137,6 +140,8 @@ struct stmmac_txq_cfg {
|
|||
u32 idle_slope;
|
||||
u32 high_credit;
|
||||
u32 low_credit;
|
||||
bool use_prio;
|
||||
u32 prio;
|
||||
};
|
||||
|
||||
struct plat_stmmacenet_data {
|
||||
|
|
Loading…
Reference in New Issue