Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7b9c7d7d authored by Maxime Chevallier's avatar Maxime Chevallier Committed by David S. Miller
Browse files

net: mvpp2: Make TX / RX descriptors little-endian



The PPv2 controller always expect descriptors to be in little endian. We
must therefore force descriptors to use that format, and convert to the
host endianness when necessary.

Signed-off-by: default avatarMaxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ea5d0c32
Loading
Loading
Loading
Loading
+28 −28
Original line number Diff line number Diff line
@@ -831,52 +831,52 @@ struct mvpp2_port {

/* HW TX descriptor for PPv2.1 */
struct mvpp21_tx_desc {
	u32 command;		/* Options used by HW for packet transmitting.*/
	__le32 command;		/* Options used by HW for packet transmitting.*/
	u8  packet_offset;	/* the offset from the buffer beginning	*/
	u8  phys_txq;		/* destination queue ID			*/
	u16 data_size;		/* data size of transmitted packet in bytes */
	u32 buf_dma_addr;	/* physical addr of transmitted buffer	*/
	u32 buf_cookie;		/* cookie for access to TX buffer in tx path */
	u32 reserved1[3];	/* hw_cmd (for future use, BM, PON, PNC) */
	u32 reserved2;		/* reserved (for future use)		*/
	__le16 data_size;	/* data size of transmitted packet in bytes */
	__le32 buf_dma_addr;	/* physical addr of transmitted buffer	*/
	__le32 buf_cookie;	/* cookie for access to TX buffer in tx path */
	__le32 reserved1[3];	/* hw_cmd (for future use, BM, PON, PNC) */
	__le32 reserved2;	/* reserved (for future use)		*/
};

/* HW RX descriptor for PPv2.1 */
struct mvpp21_rx_desc {
	u32 status;		/* info about received packet		*/
	u16 reserved1;		/* parser_info (for future use, PnC)	*/
	u16 data_size;		/* size of received packet in bytes	*/
	u32 buf_dma_addr;	/* physical address of the buffer	*/
	u32 buf_cookie;		/* cookie for access to RX buffer in rx path */
	u16 reserved2;		/* gem_port_id (for future use, PON)	*/
	u16 reserved3;		/* csum_l4 (for future use, PnC)	*/
	__le32 status;		/* info about received packet		*/
	__le16 reserved1;	/* parser_info (for future use, PnC)	*/
	__le16 data_size;	/* size of received packet in bytes	*/
	__le32 buf_dma_addr;	/* physical address of the buffer	*/
	__le32 buf_cookie;	/* cookie for access to RX buffer in rx path */
	__le16 reserved2;	/* gem_port_id (for future use, PON)	*/
	__le16 reserved3;	/* csum_l4 (for future use, PnC)	*/
	u8  reserved4;		/* bm_qset (for future use, BM)		*/
	u8  reserved5;
	u16 reserved6;		/* classify_info (for future use, PnC)	*/
	u32 reserved7;		/* flow_id (for future use, PnC) */
	u32 reserved8;
	__le16 reserved6;	/* classify_info (for future use, PnC)	*/
	__le32 reserved7;	/* flow_id (for future use, PnC) */
	__le32 reserved8;
};

/* HW TX descriptor for PPv2.2 */
struct mvpp22_tx_desc {
	u32 command;
	__le32 command;
	u8  packet_offset;
	u8  phys_txq;
	u16 data_size;
	u64 reserved1;
	u64 buf_dma_addr_ptp;
	u64 buf_cookie_misc;
	__le16 data_size;
	__le64 reserved1;
	__le64 buf_dma_addr_ptp;
	__le64 buf_cookie_misc;
};

/* HW RX descriptor for PPv2.2 */
struct mvpp22_rx_desc {
	u32 status;
	u16 reserved1;
	u16 data_size;
	u32 reserved2;
	u32 reserved3;
	u64 buf_dma_addr_key_hash;
	u64 buf_cookie_misc;
	__le32 status;
	__le16 reserved1;
	__le16 data_size;
	__le32 reserved2;
	__le32 reserved3;
	__le64 buf_dma_addr_key_hash;
	__le64 buf_cookie_misc;
};

/* Opaque type used by the driver to manipulate the HW TX and RX
+22 −19
Original line number Diff line number Diff line
@@ -151,9 +151,10 @@ static dma_addr_t mvpp2_txdesc_dma_addr_get(struct mvpp2_port *port,
					    struct mvpp2_tx_desc *tx_desc)
{
	if (port->priv->hw_version == MVPP21)
		return tx_desc->pp21.buf_dma_addr;
		return le32_to_cpu(tx_desc->pp21.buf_dma_addr);
	else
		return tx_desc->pp22.buf_dma_addr_ptp & MVPP2_DESC_DMA_MASK;
		return le64_to_cpu(tx_desc->pp22.buf_dma_addr_ptp) &
		       MVPP2_DESC_DMA_MASK;
}

static void mvpp2_txdesc_dma_addr_set(struct mvpp2_port *port,
@@ -166,12 +167,12 @@ static void mvpp2_txdesc_dma_addr_set(struct mvpp2_port *port,
	offset = dma_addr & MVPP2_TX_DESC_ALIGN;

	if (port->priv->hw_version == MVPP21) {
		tx_desc->pp21.buf_dma_addr = addr;
		tx_desc->pp21.buf_dma_addr = cpu_to_le32(addr);
		tx_desc->pp21.packet_offset = offset;
	} else {
		u64 val = (u64)addr;
		__le64 val = cpu_to_le64(addr);

		tx_desc->pp22.buf_dma_addr_ptp &= ~MVPP2_DESC_DMA_MASK;
		tx_desc->pp22.buf_dma_addr_ptp &= ~cpu_to_le64(MVPP2_DESC_DMA_MASK);
		tx_desc->pp22.buf_dma_addr_ptp |= val;
		tx_desc->pp22.packet_offset = offset;
	}
@@ -181,9 +182,9 @@ static size_t mvpp2_txdesc_size_get(struct mvpp2_port *port,
				    struct mvpp2_tx_desc *tx_desc)
{
	if (port->priv->hw_version == MVPP21)
		return tx_desc->pp21.data_size;
		return le16_to_cpu(tx_desc->pp21.data_size);
	else
		return tx_desc->pp22.data_size;
		return le16_to_cpu(tx_desc->pp22.data_size);
}

static void mvpp2_txdesc_size_set(struct mvpp2_port *port,
@@ -191,9 +192,9 @@ static void mvpp2_txdesc_size_set(struct mvpp2_port *port,
				  size_t size)
{
	if (port->priv->hw_version == MVPP21)
		tx_desc->pp21.data_size = size;
		tx_desc->pp21.data_size = cpu_to_le16(size);
	else
		tx_desc->pp22.data_size = size;
		tx_desc->pp22.data_size = cpu_to_le16(size);
}

static void mvpp2_txdesc_txq_set(struct mvpp2_port *port,
@@ -211,9 +212,9 @@ static void mvpp2_txdesc_cmd_set(struct mvpp2_port *port,
				 unsigned int command)
{
	if (port->priv->hw_version == MVPP21)
		tx_desc->pp21.command = command;
		tx_desc->pp21.command = cpu_to_le32(command);
	else
		tx_desc->pp22.command = command;
		tx_desc->pp22.command = cpu_to_le32(command);
}

static unsigned int mvpp2_txdesc_offset_get(struct mvpp2_port *port,
@@ -229,36 +230,38 @@ static dma_addr_t mvpp2_rxdesc_dma_addr_get(struct mvpp2_port *port,
					    struct mvpp2_rx_desc *rx_desc)
{
	if (port->priv->hw_version == MVPP21)
		return rx_desc->pp21.buf_dma_addr;
		return le32_to_cpu(rx_desc->pp21.buf_dma_addr);
	else
		return rx_desc->pp22.buf_dma_addr_key_hash & MVPP2_DESC_DMA_MASK;
		return le64_to_cpu(rx_desc->pp22.buf_dma_addr_key_hash) &
		       MVPP2_DESC_DMA_MASK;
}

static unsigned long mvpp2_rxdesc_cookie_get(struct mvpp2_port *port,
					     struct mvpp2_rx_desc *rx_desc)
{
	if (port->priv->hw_version == MVPP21)
		return rx_desc->pp21.buf_cookie;
		return le32_to_cpu(rx_desc->pp21.buf_cookie);
	else
		return rx_desc->pp22.buf_cookie_misc & MVPP2_DESC_DMA_MASK;
		return le64_to_cpu(rx_desc->pp22.buf_cookie_misc) &
		       MVPP2_DESC_DMA_MASK;
}

static size_t mvpp2_rxdesc_size_get(struct mvpp2_port *port,
				    struct mvpp2_rx_desc *rx_desc)
{
	if (port->priv->hw_version == MVPP21)
		return rx_desc->pp21.data_size;
		return le16_to_cpu(rx_desc->pp21.data_size);
	else
		return rx_desc->pp22.data_size;
		return le16_to_cpu(rx_desc->pp22.data_size);
}

static u32 mvpp2_rxdesc_status_get(struct mvpp2_port *port,
				   struct mvpp2_rx_desc *rx_desc)
{
	if (port->priv->hw_version == MVPP21)
		return rx_desc->pp21.status;
		return le32_to_cpu(rx_desc->pp21.status);
	else
		return rx_desc->pp22.status;
		return le32_to_cpu(rx_desc->pp22.status);
}

static void mvpp2_txq_inc_get(struct mvpp2_txq_pcpu *txq_pcpu)