Commit dfe76a36 authored by David S. Miller's avatar David S. Miller

Merge branch 'mvpp2-Add-big-endian-support'

Maxime Chevallier says:

====================
net: mvpp2: Add big-endian support

This series allows to use PPv2 on system built as big endian.

The first patch fixes the way we represent TX and RX descriptors, so that
they used fixed little endianness as expected by the PPv2 controller.

The second reworks the way we handle the software representation of the
Header Parser entries, so that we don't use a union of arrays.

The last two patches fixes some incorrect byte swapping logic, that wen't
un-noticed on little-endian.

This whole series doesn't fix any existing bug for little-endian systems, and
since big-endian never worked for this driver, I didn't include 'fixes' tags.

This was tested on MacchiatoBin (Armada 8040).
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ea5d0c32 dc734dbe
...@@ -553,6 +553,8 @@ ...@@ -553,6 +553,8 @@
((total_size) - NET_SKB_PAD - MVPP2_SKB_SHINFO_SIZE) ((total_size) - NET_SKB_PAD - MVPP2_SKB_SHINFO_SIZE)
#define MVPP2_BIT_TO_BYTE(bit) ((bit) / 8) #define MVPP2_BIT_TO_BYTE(bit) ((bit) / 8)
#define MVPP2_BIT_TO_WORD(bit) ((bit) / 32)
#define MVPP2_BIT_IN_WORD(bit) ((bit) % 32)
/* IPv6 max L3 address size */ /* IPv6 max L3 address size */
#define MVPP2_MAX_L3_ADDR_SIZE 16 #define MVPP2_MAX_L3_ADDR_SIZE 16
...@@ -831,52 +833,52 @@ struct mvpp2_port { ...@@ -831,52 +833,52 @@ struct mvpp2_port {
/* HW TX descriptor for PPv2.1 */ /* HW TX descriptor for PPv2.1 */
struct mvpp21_tx_desc { 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 packet_offset; /* the offset from the buffer beginning */
u8 phys_txq; /* destination queue ID */ u8 phys_txq; /* destination queue ID */
u16 data_size; /* data size of transmitted packet in bytes */ __le16 data_size; /* data size of transmitted packet in bytes */
u32 buf_dma_addr; /* physical addr of transmitted buffer */ __le32 buf_dma_addr; /* physical addr of transmitted buffer */
u32 buf_cookie; /* cookie for access to TX buffer in tx path */ __le32 buf_cookie; /* cookie for access to TX buffer in tx path */
u32 reserved1[3]; /* hw_cmd (for future use, BM, PON, PNC) */ __le32 reserved1[3]; /* hw_cmd (for future use, BM, PON, PNC) */
u32 reserved2; /* reserved (for future use) */ __le32 reserved2; /* reserved (for future use) */
}; };
/* HW RX descriptor for PPv2.1 */ /* HW RX descriptor for PPv2.1 */
struct mvpp21_rx_desc { struct mvpp21_rx_desc {
u32 status; /* info about received packet */ __le32 status; /* info about received packet */
u16 reserved1; /* parser_info (for future use, PnC) */ __le16 reserved1; /* parser_info (for future use, PnC) */
u16 data_size; /* size of received packet in bytes */ __le16 data_size; /* size of received packet in bytes */
u32 buf_dma_addr; /* physical address of the buffer */ __le32 buf_dma_addr; /* physical address of the buffer */
u32 buf_cookie; /* cookie for access to RX buffer in rx path */ __le32 buf_cookie; /* cookie for access to RX buffer in rx path */
u16 reserved2; /* gem_port_id (for future use, PON) */ __le16 reserved2; /* gem_port_id (for future use, PON) */
u16 reserved3; /* csum_l4 (for future use, PnC) */ __le16 reserved3; /* csum_l4 (for future use, PnC) */
u8 reserved4; /* bm_qset (for future use, BM) */ u8 reserved4; /* bm_qset (for future use, BM) */
u8 reserved5; u8 reserved5;
u16 reserved6; /* classify_info (for future use, PnC) */ __le16 reserved6; /* classify_info (for future use, PnC) */
u32 reserved7; /* flow_id (for future use, PnC) */ __le32 reserved7; /* flow_id (for future use, PnC) */
u32 reserved8; __le32 reserved8;
}; };
/* HW TX descriptor for PPv2.2 */ /* HW TX descriptor for PPv2.2 */
struct mvpp22_tx_desc { struct mvpp22_tx_desc {
u32 command; __le32 command;
u8 packet_offset; u8 packet_offset;
u8 phys_txq; u8 phys_txq;
u16 data_size; __le16 data_size;
u64 reserved1; __le64 reserved1;
u64 buf_dma_addr_ptp; __le64 buf_dma_addr_ptp;
u64 buf_cookie_misc; __le64 buf_cookie_misc;
}; };
/* HW RX descriptor for PPv2.2 */ /* HW RX descriptor for PPv2.2 */
struct mvpp22_rx_desc { struct mvpp22_rx_desc {
u32 status; __le32 status;
u16 reserved1; __le16 reserved1;
u16 data_size; __le16 data_size;
u32 reserved2; __le32 reserved2;
u32 reserved3; __le32 reserved3;
u64 buf_dma_addr_key_hash; __le64 buf_dma_addr_key_hash;
u64 buf_cookie_misc; __le64 buf_cookie_misc;
}; };
/* Opaque type used by the driver to manipulate the HW TX and RX /* Opaque type used by the driver to manipulate the HW TX and RX
......
...@@ -151,9 +151,10 @@ static dma_addr_t mvpp2_txdesc_dma_addr_get(struct mvpp2_port *port, ...@@ -151,9 +151,10 @@ static dma_addr_t mvpp2_txdesc_dma_addr_get(struct mvpp2_port *port,
struct mvpp2_tx_desc *tx_desc) struct mvpp2_tx_desc *tx_desc)
{ {
if (port->priv->hw_version == MVPP21) if (port->priv->hw_version == MVPP21)
return tx_desc->pp21.buf_dma_addr; return le32_to_cpu(tx_desc->pp21.buf_dma_addr);
else 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, 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, ...@@ -166,12 +167,12 @@ static void mvpp2_txdesc_dma_addr_set(struct mvpp2_port *port,
offset = dma_addr & MVPP2_TX_DESC_ALIGN; offset = dma_addr & MVPP2_TX_DESC_ALIGN;
if (port->priv->hw_version == MVPP21) { 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; tx_desc->pp21.packet_offset = offset;
} else { } 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.buf_dma_addr_ptp |= val;
tx_desc->pp22.packet_offset = offset; tx_desc->pp22.packet_offset = offset;
} }
...@@ -181,9 +182,9 @@ static size_t mvpp2_txdesc_size_get(struct mvpp2_port *port, ...@@ -181,9 +182,9 @@ static size_t mvpp2_txdesc_size_get(struct mvpp2_port *port,
struct mvpp2_tx_desc *tx_desc) struct mvpp2_tx_desc *tx_desc)
{ {
if (port->priv->hw_version == MVPP21) if (port->priv->hw_version == MVPP21)
return tx_desc->pp21.data_size; return le16_to_cpu(tx_desc->pp21.data_size);
else 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, static void mvpp2_txdesc_size_set(struct mvpp2_port *port,
...@@ -191,9 +192,9 @@ 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) size_t size)
{ {
if (port->priv->hw_version == MVPP21) if (port->priv->hw_version == MVPP21)
tx_desc->pp21.data_size = size; tx_desc->pp21.data_size = cpu_to_le16(size);
else 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, static void mvpp2_txdesc_txq_set(struct mvpp2_port *port,
...@@ -211,9 +212,9 @@ static void mvpp2_txdesc_cmd_set(struct mvpp2_port *port, ...@@ -211,9 +212,9 @@ static void mvpp2_txdesc_cmd_set(struct mvpp2_port *port,
unsigned int command) unsigned int command)
{ {
if (port->priv->hw_version == MVPP21) if (port->priv->hw_version == MVPP21)
tx_desc->pp21.command = command; tx_desc->pp21.command = cpu_to_le32(command);
else 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, 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, ...@@ -229,36 +230,38 @@ static dma_addr_t mvpp2_rxdesc_dma_addr_get(struct mvpp2_port *port,
struct mvpp2_rx_desc *rx_desc) struct mvpp2_rx_desc *rx_desc)
{ {
if (port->priv->hw_version == MVPP21) if (port->priv->hw_version == MVPP21)
return rx_desc->pp21.buf_dma_addr; return le32_to_cpu(rx_desc->pp21.buf_dma_addr);
else 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, static unsigned long mvpp2_rxdesc_cookie_get(struct mvpp2_port *port,
struct mvpp2_rx_desc *rx_desc) struct mvpp2_rx_desc *rx_desc)
{ {
if (port->priv->hw_version == MVPP21) if (port->priv->hw_version == MVPP21)
return rx_desc->pp21.buf_cookie; return le32_to_cpu(rx_desc->pp21.buf_cookie);
else 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, static size_t mvpp2_rxdesc_size_get(struct mvpp2_port *port,
struct mvpp2_rx_desc *rx_desc) struct mvpp2_rx_desc *rx_desc)
{ {
if (port->priv->hw_version == MVPP21) if (port->priv->hw_version == MVPP21)
return rx_desc->pp21.data_size; return le16_to_cpu(rx_desc->pp21.data_size);
else 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, static u32 mvpp2_rxdesc_status_get(struct mvpp2_port *port,
struct mvpp2_rx_desc *rx_desc) struct mvpp2_rx_desc *rx_desc)
{ {
if (port->priv->hw_version == MVPP21) if (port->priv->hw_version == MVPP21)
return rx_desc->pp21.status; return le32_to_cpu(rx_desc->pp21.status);
else 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) static void mvpp2_txq_inc_get(struct mvpp2_txq_pcpu *txq_pcpu)
...@@ -1735,7 +1738,7 @@ static u32 mvpp2_txq_desc_csum(int l3_offs, int l3_proto, ...@@ -1735,7 +1738,7 @@ static u32 mvpp2_txq_desc_csum(int l3_offs, int l3_proto,
command |= (ip_hdr_len << MVPP2_TXD_IP_HLEN_SHIFT); command |= (ip_hdr_len << MVPP2_TXD_IP_HLEN_SHIFT);
command |= MVPP2_TXD_IP_CSUM_DISABLE; command |= MVPP2_TXD_IP_CSUM_DISABLE;
if (l3_proto == swab16(ETH_P_IP)) { if (l3_proto == htons(ETH_P_IP)) {
command &= ~MVPP2_TXD_IP_CSUM_DISABLE; /* enable IPv4 csum */ command &= ~MVPP2_TXD_IP_CSUM_DISABLE; /* enable IPv4 csum */
command &= ~MVPP2_TXD_L3_IP6; /* enable IPv4 */ command &= ~MVPP2_TXD_L3_IP6; /* enable IPv4 */
} else { } else {
......
...@@ -50,16 +50,24 @@ ...@@ -50,16 +50,24 @@
* The fields are represented by MVPP2_PRS_TCAM_DATA_REG(5)->(0). * The fields are represented by MVPP2_PRS_TCAM_DATA_REG(5)->(0).
*/ */
#define MVPP2_PRS_AI_BITS 8 #define MVPP2_PRS_AI_BITS 8
#define MVPP2_PRS_AI_MASK 0xff
#define MVPP2_PRS_PORT_MASK 0xff #define MVPP2_PRS_PORT_MASK 0xff
#define MVPP2_PRS_LU_MASK 0xf #define MVPP2_PRS_LU_MASK 0xf
#define MVPP2_PRS_TCAM_DATA_BYTE(offs) \
(((offs) - ((offs) % 2)) * 2 + ((offs) % 2)) /* TCAM entries in registers are accessed using 16 data bits + 16 enable bits */
#define MVPP2_PRS_TCAM_DATA_BYTE_EN(offs) \ #define MVPP2_PRS_BYTE_TO_WORD(byte) ((byte) / 2)
(((offs) * 2) - ((offs) % 2) + 2) #define MVPP2_PRS_BYTE_IN_WORD(byte) ((byte) % 2)
#define MVPP2_PRS_TCAM_AI_BYTE 16
#define MVPP2_PRS_TCAM_PORT_BYTE 17 #define MVPP2_PRS_TCAM_EN(data) ((data) << 16)
#define MVPP2_PRS_TCAM_LU_BYTE 20 #define MVPP2_PRS_TCAM_AI_WORD 4
#define MVPP2_PRS_TCAM_EN_OFFS(offs) ((offs) + 2) #define MVPP2_PRS_TCAM_AI(ai) (ai)
#define MVPP2_PRS_TCAM_AI_EN(ai) MVPP2_PRS_TCAM_EN(MVPP2_PRS_TCAM_AI(ai))
#define MVPP2_PRS_TCAM_PORT_WORD 4
#define MVPP2_PRS_TCAM_PORT(p) ((p) << 8)
#define MVPP2_PRS_TCAM_PORT_EN(p) MVPP2_PRS_TCAM_EN(MVPP2_PRS_TCAM_PORT(p))
#define MVPP2_PRS_TCAM_LU_WORD 5
#define MVPP2_PRS_TCAM_LU(lu) (lu)
#define MVPP2_PRS_TCAM_LU_EN(lu) MVPP2_PRS_TCAM_EN(MVPP2_PRS_TCAM_LU(lu))
#define MVPP2_PRS_TCAM_INV_WORD 5 #define MVPP2_PRS_TCAM_INV_WORD 5
#define MVPP2_PRS_VID_TCAM_BYTE 2 #define MVPP2_PRS_VID_TCAM_BYTE 2
...@@ -146,6 +154,7 @@ ...@@ -146,6 +154,7 @@
#define MVPP2_PRS_SRAM_RI_CTRL_BITS 32 #define MVPP2_PRS_SRAM_RI_CTRL_BITS 32
#define MVPP2_PRS_SRAM_SHIFT_OFFS 64 #define MVPP2_PRS_SRAM_SHIFT_OFFS 64
#define MVPP2_PRS_SRAM_SHIFT_SIGN_BIT 72 #define MVPP2_PRS_SRAM_SHIFT_SIGN_BIT 72
#define MVPP2_PRS_SRAM_SHIFT_MASK 0xff
#define MVPP2_PRS_SRAM_UDF_OFFS 73 #define MVPP2_PRS_SRAM_UDF_OFFS 73
#define MVPP2_PRS_SRAM_UDF_BITS 8 #define MVPP2_PRS_SRAM_UDF_BITS 8
#define MVPP2_PRS_SRAM_UDF_MASK 0xff #define MVPP2_PRS_SRAM_UDF_MASK 0xff
...@@ -255,20 +264,10 @@ enum mvpp2_prs_lookup { ...@@ -255,20 +264,10 @@ enum mvpp2_prs_lookup {
MVPP2_PRS_LU_LAST, MVPP2_PRS_LU_LAST,
}; };
union mvpp2_prs_tcam_entry {
u32 word[MVPP2_PRS_TCAM_WORDS];
u8 byte[MVPP2_PRS_TCAM_WORDS * 4];
};
union mvpp2_prs_sram_entry {
u32 word[MVPP2_PRS_SRAM_WORDS];
u8 byte[MVPP2_PRS_SRAM_WORDS * 4];
};
struct mvpp2_prs_entry { struct mvpp2_prs_entry {
u32 index; u32 index;
union mvpp2_prs_tcam_entry tcam; u32 tcam[MVPP2_PRS_TCAM_WORDS];
union mvpp2_prs_sram_entry sram; u32 sram[MVPP2_PRS_SRAM_WORDS];
}; };
struct mvpp2_prs_shadow { struct mvpp2_prs_shadow {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment