STAGING: Octeon: Support CN68XX style WQE

CN68XX has a bit different WQE structure. This patch provides the new
definitions and converts the code to use the proper variant based on
the actual model.

Signed-off-by: Janne Huttunen <janne.huttunen@nokia.com>
Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Acked-by: David Daney <david.daney@cavium.com>
Cc: David Daney <ddaney.cavm@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: Janne Huttunen <janne.huttunen@nokia.com>
Cc: Aaro Koskinen <aaro.koskinen@nokia.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: devel@driverdev.osuosl.org
Patchwork: https://patchwork.linux-mips.org/patch/10973/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
Janne Huttunen
2015-08-13 16:21:42 +03:00
committed by Ralf Baechle
parent d5f9bc7360
commit f8023da8ae
5 changed files with 304 additions and 98 deletions

View File

@@ -193,6 +193,53 @@ typedef union {
uint64_t bufs:8;
#endif
} s;
struct {
#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bufs:8;
uint64_t ip_offset:8;
uint64_t vlan_valid:1;
uint64_t vlan_stacked:1;
uint64_t unassigned:1;
uint64_t vlan_cfi:1;
uint64_t vlan_id:12;
uint64_t port:12; /* MAC/PIP port number. */
uint64_t dec_ipcomp:1;
uint64_t tcp_or_udp:1;
uint64_t dec_ipsec:1;
uint64_t is_v6:1;
uint64_t software:1;
uint64_t L4_error:1;
uint64_t is_frag:1;
uint64_t IP_exc:1;
uint64_t is_bcast:1;
uint64_t is_mcast:1;
uint64_t not_IP:1;
uint64_t rcv_error:1;
uint64_t err_code:8;
#else
uint64_t err_code:8;
uint64_t rcv_error:1;
uint64_t not_IP:1;
uint64_t is_mcast:1;
uint64_t is_bcast:1;
uint64_t IP_exc:1;
uint64_t is_frag:1;
uint64_t L4_error:1;
uint64_t software:1;
uint64_t is_v6:1;
uint64_t dec_ipsec:1;
uint64_t tcp_or_udp:1;
uint64_t dec_ipcomp:1;
uint64_t port:12;
uint64_t vlan_id:12;
uint64_t vlan_cfi:1;
uint64_t unassigned:1;
uint64_t vlan_stacked:1;
uint64_t vlan_valid:1;
uint64_t ip_offset:8;
uint64_t bufs:8;
#endif
} s_cn68xx;
/* use this to get at the 16 vlan bits */
struct {
@@ -355,6 +402,146 @@ typedef union {
} cvmx_pip_wqe_word2;
union cvmx_pip_wqe_word0 {
struct {
#ifdef __BIG_ENDIAN_BITFIELD
/**
* raw chksum result generated by the HW
*/
uint16_t hw_chksum;
/**
* Field unused by hardware - available for software
*/
uint8_t unused;
/**
* Next pointer used by hardware for list maintenance.
* May be written/read by HW before the work queue
* entry is scheduled to a PP (Only 36 bits used in
* Octeon 1)
*/
uint64_t next_ptr:40;
#else
uint64_t next_ptr:40;
uint8_t unused;
uint16_t hw_chksum;
#endif
} cn38xx;
struct {
#ifdef __BIG_ENDIAN_BITFIELD
uint64_t l4ptr:8; /* 56..63 */
uint64_t unused0:8; /* 48..55 */
uint64_t l3ptr:8; /* 40..47 */
uint64_t l2ptr:8; /* 32..39 */
uint64_t unused1:18; /* 14..31 */
uint64_t bpid:6; /* 8..13 */
uint64_t unused2:2; /* 6..7 */
uint64_t pknd:6; /* 0..5 */
#else
uint64_t pknd:6; /* 0..5 */
uint64_t unused2:2; /* 6..7 */
uint64_t bpid:6; /* 8..13 */
uint64_t unused1:18; /* 14..31 */
uint64_t l2ptr:8; /* 32..39 */
uint64_t l3ptr:8; /* 40..47 */
uint64_t unused0:8; /* 48..55 */
uint64_t l4ptr:8; /* 56..63 */
#endif
} cn68xx;
};
union cvmx_wqe_word0 {
uint64_t u64;
union cvmx_pip_wqe_word0 pip;
};
union cvmx_wqe_word1 {
uint64_t u64;
struct {
#ifdef __BIG_ENDIAN_BITFIELD
uint64_t len:16;
uint64_t varies:14;
/**
* the type of the tag (ORDERED, ATOMIC, NULL)
*/
uint64_t tag_type:2;
uint64_t tag:32;
#else
uint64_t tag:32;
uint64_t tag_type:2;
uint64_t varies:14;
uint64_t len:16;
#endif
};
struct {
#ifdef __BIG_ENDIAN_BITFIELD
uint64_t len:16;
uint64_t zero_0:1;
/**
* HW sets this to what it thought the priority of
* the input packet was
*/
uint64_t qos:3;
uint64_t zero_1:1;
/**
* the group that the work queue entry will be scheduled to
*/
uint64_t grp:6;
uint64_t zero_2:3;
uint64_t tag_type:2;
uint64_t tag:32;
#else
uint64_t tag:32;
uint64_t tag_type:2;
uint64_t zero_2:3;
uint64_t grp:6;
uint64_t zero_1:1;
uint64_t qos:3;
uint64_t zero_0:1;
uint64_t len:16;
#endif
} cn68xx;
struct {
#ifdef __BIG_ENDIAN_BITFIELD
/**
* HW sets to the total number of bytes in the packet
*/
uint64_t len:16;
/**
* HW sets this to input physical port
*/
uint64_t ipprt:6;
/**
* HW sets this to what it thought the priority of
* the input packet was
*/
uint64_t qos:3;
/**
* the group that the work queue entry will be scheduled to
*/
uint64_t grp:4;
/**
* the type of the tag (ORDERED, ATOMIC, NULL)
*/
uint64_t tag_type:3;
/**
* the synchronization/ordering tag
*/
uint64_t tag:32;
#else
uint64_t tag:32;
uint64_t tag_type:2;
uint64_t zero_2:1;
uint64_t grp:4;
uint64_t qos:3;
uint64_t ipprt:6;
uint64_t len:16;
#endif
} cn38xx;
};
/**
* Work queue entry format
*
@@ -366,70 +553,13 @@ typedef struct {
* WORD 0
* HW WRITE: the following 64 bits are filled by HW when a packet arrives
*/
#ifdef __BIG_ENDIAN_BITFIELD
/**
* raw chksum result generated by the HW
*/
uint16_t hw_chksum;
/**
* Field unused by hardware - available for software
*/
uint8_t unused;
/**
* Next pointer used by hardware for list maintenance.
* May be written/read by HW before the work queue
* entry is scheduled to a PP
* (Only 36 bits used in Octeon 1)
*/
uint64_t next_ptr:40;
#else
uint64_t next_ptr:40;
uint8_t unused;
uint16_t hw_chksum;
#endif
union cvmx_wqe_word0 word0;
/*****************************************************************
* WORD 1
* HW WRITE: the following 64 bits are filled by HW when a packet arrives
*/
#ifdef __BIG_ENDIAN_BITFIELD
/**
* HW sets to the total number of bytes in the packet
*/
uint64_t len:16;
/**
* HW sets this to input physical port
*/
uint64_t ipprt:6;
/**
* HW sets this to what it thought the priority of the input packet was
*/
uint64_t qos:3;
/**
* the group that the work queue entry will be scheduled to
*/
uint64_t grp:4;
/**
* the type of the tag (ORDERED, ATOMIC, NULL)
*/
uint64_t tag_type:3;
/**
* the synchronization/ordering tag
*/
uint64_t tag:32;
#else
uint64_t tag:32;
uint64_t tag_type:2;
uint64_t zero_2:1;
uint64_t grp:4;
uint64_t qos:3;
uint64_t ipprt:6;
uint64_t len:16;
#endif
union cvmx_wqe_word1 word1;
/**
* WORD 2 HW WRITE: the following 64-bits are filled in by
@@ -465,4 +595,64 @@ typedef struct {
} CVMX_CACHE_LINE_ALIGNED cvmx_wqe_t;
static inline int cvmx_wqe_get_port(cvmx_wqe_t *work)
{
int port;
if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
port = work->word2.s_cn68xx.port;
else
port = work->word1.cn38xx.ipprt;
return port;
}
static inline void cvmx_wqe_set_port(cvmx_wqe_t *work, int port)
{
if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
work->word2.s_cn68xx.port = port;
else
work->word1.cn38xx.ipprt = port;
}
static inline int cvmx_wqe_get_grp(cvmx_wqe_t *work)
{
int grp;
if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
grp = work->word1.cn68xx.grp;
else
grp = work->word1.cn38xx.grp;
return grp;
}
static inline void cvmx_wqe_set_grp(cvmx_wqe_t *work, int grp)
{
if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
work->word1.cn68xx.grp = grp;
else
work->word1.cn38xx.grp = grp;
}
static inline int cvmx_wqe_get_qos(cvmx_wqe_t *work)
{
int qos;
if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
qos = work->word1.cn68xx.qos;
else
qos = work->word1.cn38xx.qos;
return qos;
}
static inline void cvmx_wqe_set_qos(cvmx_wqe_t *work, int qos)
{
if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
work->word1.cn68xx.qos = qos;
else
work->word1.cn38xx.qos = qos;
}
#endif /* __CVMX_WQE_H__ */