diff options
Diffstat (limited to 'include')
77 files changed, 18620 insertions, 117 deletions
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 418d270..1c0cfc3 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -125,6 +125,7 @@ struct ablkcipher_walk { extern const struct crypto_type crypto_ablkcipher_type; extern const struct crypto_type crypto_aead_type; extern const struct crypto_type crypto_blkcipher_type; +extern const struct crypto_type crypto_pkc_type; void crypto_mod_put(struct crypto_alg *alg); @@ -227,6 +228,11 @@ static inline void *crypto_ablkcipher_ctx(struct crypto_ablkcipher *tfm) return crypto_tfm_ctx(&tfm->base); } +static inline void *crypto_pkc_ctx(struct crypto_pkc *tfm) +{ + return crypto_tfm_ctx(&tfm->base); +} + static inline void *crypto_ablkcipher_ctx_aligned(struct crypto_ablkcipher *tfm) { return crypto_tfm_ctx_aligned(&tfm->base); @@ -386,5 +392,12 @@ static inline int crypto_requires_sync(u32 type, u32 mask) return (type ^ CRYPTO_ALG_ASYNC) & mask & CRYPTO_ALG_ASYNC; } -#endif /* _CRYPTO_ALGAPI_H */ +noinline unsigned long __crypto_memneq(const void *a, const void *b, size_t size); +/* RSA Request Completion handler */ +static inline void pkc_request_complete(struct pkc_request *req, + int err) +{ + req->base.complete(&req->base, err); +} +#endif /* _CRYPTO_ALGAPI_H */ diff --git a/include/crypto/authenc.h b/include/crypto/authenc.h index e47b044..6775059 100644 --- a/include/crypto/authenc.h +++ b/include/crypto/authenc.h @@ -23,5 +23,15 @@ struct crypto_authenc_key_param { __be32 enckeylen; }; -#endif /* _CRYPTO_AUTHENC_H */ +struct crypto_authenc_keys { + const u8 *authkey; + const u8 *enckey; + + unsigned int authkeylen; + unsigned int enckeylen; +}; +int crypto_authenc_extractkeys(struct crypto_authenc_keys *keys, const u8 *key, + unsigned int keylen); + +#endif /* _CRYPTO_AUTHENC_H */ diff --git a/include/crypto/null.h b/include/crypto/null.h new file mode 100644 index 0000000..b7c864c --- /dev/null +++ b/include/crypto/null.h @@ -0,0 +1,11 @@ +/* Values for NULL algorithms */ + +#ifndef _CRYPTO_NULL_H +#define _CRYPTO_NULL_H + +#define NULL_KEY_SIZE 0 +#define NULL_BLOCK_SIZE 1 +#define NULL_DIGEST_SIZE 0 +#define NULL_IV_SIZE 0 + +#endif diff --git a/include/dt-bindings/clock/ls1021a-clock.h b/include/dt-bindings/clock/ls1021a-clock.h new file mode 100644 index 0000000..09b47d7 --- /dev/null +++ b/include/dt-bindings/clock/ls1021a-clock.h @@ -0,0 +1,55 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __DT_BINDINGS_CLOCK_LS1021A_H +#define __DT_BINDINGS_CLOCK_LS1021A_H + +#define LS1021A_CLK_DUMMY 0 +#define LS1021A_CLK_PBL_EN 1 +#define LS1021A_CLK_ESDHC_EN 2 +#define LS1021A_CLK_DMA1_EN 3 +#define LS1021A_CLK_DMA2_EN 4 +#define LS1021A_CLK_USB3_PHY_EN 5 +#define LS1021A_CLK_USB2_EN 6 +#define LS1021A_CLK_SATA_EN 7 +#define LS1021A_CLK_USB3_EN 8 +#define LS1021A_CLK_SEC_EN 9 +#define LS1021A_CLK_2D_ACE_EN 10 +#define LS1021A_CLK_QE_EN 11 +#define LS1021A_CLK_ETSEC1_EN 12 +#define LS1021A_CLK_ETSEC2_EN 13 +#define LS1021A_CLK_ETSEC3_EN 14 +#define LS1021A_CLK_PEX1_EN 15 +#define LS1021A_CLK_PEX2_EN 16 +#define LS1021A_CLK_DUART1_EN 17 +#define LS1021A_CLK_DUART2_EN 18 +#define LS1021A_CLK_QSPI_EN 19 +#define LS1021A_CLK_DDR_EN 20 +#define LS1021A_CLK_OCRAM1_EN 21 +#define LS1021A_CLK_IFC_EN 22 +#define LS1021A_CLK_GPIO_EN 23 +#define LS1021A_CLK_DBG_EN 24 +#define LS1021A_CLK_FLEXCAN1_EN 25 +#define LS1021A_CLK_FLEXCAN234_EN 26 +#define LS1021A_CLK_FLEXTIMER_EN 27 +#define LS1021A_CLK_SECMON_EN 28 +#define LS1021A_CLK_WDOG_EN 29 +#define LS1021A_CLK_WDOG12_EN 30 +#define LS1021A_CLK_I2C23_EN 31 +#define LS1021A_CLK_SAI_EN 32 +#define LS1021A_CLK_LPUART_EN 33 +#define LS1021A_CLK_DSPI12_EN 34 +#define LS1021A_CLK_ASRC_EN 35 +#define LS1021A_CLK_SPDIF_EN 36 +#define LS1021A_CLK_I2C1_EN 37 +#define LS1021A_CLK_LPUART1_EN 38 +#define LS1021A_CLK_FLEXTIMER1_EN 39 +#define LS1021A_CLK_END 40 + +#endif /* __DT_BINDINGS_CLOCK_LS1021A_H */ diff --git a/include/linux/ata.h b/include/linux/ata.h index bf4c69c..1e20557 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -80,6 +80,7 @@ enum { ATA_ID_SATA_CAPABILITY = 76, ATA_ID_SATA_CAPABILITY_2 = 77, ATA_ID_FEATURE_SUPP = 78, + ATA_ID_FEATURE_ENABLE = 79, ATA_ID_MAJOR_VER = 80, ATA_ID_COMMAND_SET_1 = 82, ATA_ID_COMMAND_SET_2 = 83, @@ -505,6 +506,8 @@ struct ata_bmdma_prd { ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 2))) +#define ata_id_enabled_fpdma_aa(id) \ + ((id)[ATA_ID_FEATURE_ENABLE] & (1 << 2)) #define ata_id_iordy_disable(id) ((id)[ATA_ID_CAPABILITY] & (1 << 10)) #define ata_id_has_iordy(id) ((id)[ATA_ID_CAPABILITY] & (1 << 11)) #define ata_id_u32(id,n) \ diff --git a/include/linux/crc64_ecma.h b/include/linux/crc64_ecma.h new file mode 100644 index 0000000..bba7a4d --- /dev/null +++ b/include/linux/crc64_ecma.h @@ -0,0 +1,56 @@ +/* + * Copyright 2013 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __CRC64_ECMA_H_ +#define __CRC64_ECMA_H_ + +#include <linux/types.h> + + +#define CRC64_DEFAULT_INITVAL 0xFFFFFFFFFFFFFFFFULL + + +/* + * crc64_ecma_seed - Initializes the CRC64 ECMA seed. + */ +u64 crc64_ecma_seed(void); + +/* + * crc64_ecma - Computes the 64 bit ECMA CRC. + * + * @pdata: pointer to the data to compute checksum for. + * @nbytes: number of bytes in data buffer. + * @seed: CRC seed. + */ +u64 crc64_ecma(u8 const *pdata, u32 nbytes, u64 seed); + +#endif /* __CRC64_ECMA_H_ */ diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 2b00d92..df663e5 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -52,7 +52,10 @@ #define CRYPTO_ALG_TYPE_HASH 0x00000008 #define CRYPTO_ALG_TYPE_SHASH 0x00000009 #define CRYPTO_ALG_TYPE_AHASH 0x0000000a +#define CRYPTO_ALG_TYPE_PKC_DH 0x0000000b #define CRYPTO_ALG_TYPE_RNG 0x0000000c +#define CRYPTO_ALG_TYPE_PKC_DSA 0x0000000d +#define CRYPTO_ALG_TYPE_PKC_RSA 0x0000000e #define CRYPTO_ALG_TYPE_PCOMPRESS 0x0000000f #define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e @@ -188,6 +191,315 @@ struct aead_request { void *__ctx[] CRYPTO_MINALIGN_ATTR; }; +enum pkc_req_type { + RSA_KEYGEN, + RSA_PUB, + RSA_PRIV_FORM1, + RSA_PRIV_FORM2, + RSA_PRIV_FORM3, + DSA_SIGN, + DSA_VERIFY, + ECDSA_SIGN, + ECDSA_VERIFY, + DH_COMPUTE_KEY, + ECDH_COMPUTE_KEY, + DLC_KEYGEN, + ECC_KEYGEN, + MAX_TYPES +}; + +/* RSA Encrypt request Struct from cryptoAPI + @n - n, e represents the public key + @e - Public key exponent, n is modulus + @g - Output RSA-encrypted value + */ +struct rsa_pub_req_s { + uint8_t *n; + uint8_t *e; + uint8_t *g; + uint8_t *f; + uint32_t n_len; + uint32_t e_len; + uint32_t g_len; + uint32_t f_len; +}; + +/* RSA PrivKey Form1 + @n - n, d represents the private key form1 representation + @d - d is the private exponent, n is the modules + */ +struct rsa_priv_frm1_req_s { + uint8_t *n; + uint8_t *d; + uint8_t *f; + uint8_t *g; + uint32_t f_len; + uint32_t g_len; + uint32_t n_len; + uint32_t d_len; +}; + +/* RSA PrivKey Form2 + @n - p, q, d represents the private key form2 representation + @d - d is private exponent, p and q are the two primes + @f - output pointer + @g - input pointer + */ +struct rsa_priv_frm2_req_s { + uint8_t *p; + uint8_t *q; + uint8_t *d; + uint8_t *f; + uint8_t *g; + uint32_t f_len; + uint32_t g_len; + uint32_t p_len; + uint32_t q_len; + uint32_t d_len; + uint32_t n_len; +}; + +/* RSA PrivKey Form3 + @n - p, q, dp, dq, c represents the private key form3 representation + @dp - First CRT exponent factor + @dq - Second CRT exponent factor + @c - CRT Coefficient + @f - output pointer + @g - input pointer + */ +struct rsa_priv_frm3_req_s { + uint8_t *p; + uint8_t *q; + uint8_t *dp; + uint8_t *dq; + uint8_t *c; + uint8_t *f; + uint8_t *g; + uint32_t f_len; + uint32_t g_len; + uint32_t p_len; + uint32_t q_len; + uint32_t dp_len; + uint32_t dq_len; + uint32_t c_len; +}; + +/* + * RSA keygen request + */ + +struct rsa_keygen_req_s { + uint8_t *p; + uint8_t *q; + uint8_t *dp; + uint8_t *dq; + uint8_t *d; + uint8_t *n; + uint8_t *c; + uint32_t p_len; + uint32_t q_len; + uint32_t dp_len; + uint32_t dq_len; + uint32_t d_len; + uint32_t n_len; + uint32_t c_len; +}; + +/* DLC and ECC Keygen request + @len_L - size of the field + @len_N - size of the group + @q -Prime number or irreducible polynomial that creates the field,length L + @r - Order of the field of private keys, length N + @g -Generator or generator point (ECC),length L or 2*L(ECC) + @ab -ECC curve parameters(for ECC only). length 2*L + */ +struct keygen_req_s { + uint8_t *q; + uint8_t *r; + uint8_t *g; + uint8_t *priv_key; + uint8_t *pub_key; + uint8_t *ab; + uint32_t q_len; + uint32_t r_len; + uint32_t g_len; + uint32_t priv_key_len; + uint32_t pub_key_len; + uint32_t ab_len; +}; + +/* + * Temporary Changes to make cryptodev work with OC release + * To be simply removed after OC final release + */ +#define ECDSA_KEYGEN ECC_KEYGEN +#define ECDH_KEYGEN ECC_KEYGEN +#define DSA_KEYGEN DLC_KEYGEN +#define DH_KEYGEN DLC_KEYGEN + +/* + @len_L - size of the field + @len_N - size of the group + @q -Prime number or irreducible polynomial that creates the field,length L + @r - Order of the field of private keys, length N + @g -Generator or generator point (ECC),length L or 2*L(ECC) + @ab -ECC curve parameters(for ECC only). length 2*L + */ +struct dsa_keygen_req_s { + uint8_t *q; + uint8_t *r; + uint8_t *g; + uint8_t *prvkey; + uint8_t *pubkey; + uint8_t *ab; + uint32_t q_len; + uint32_t r_len; + uint32_t g_len; + uint32_t prvkey_len; + uint32_t pubkey_len; + uint32_t ab_len; +}; + + +/* + @len_L - size of the field + @len_N - size of the group + @q -Prime number or irreducible polynomial that creates the field,length L + @r - Order of the field of private keys, length N + @g -Generator or generator point (ECC),length L or 2*L(ECC) + @ab -ECC curve parameters(for ECC only). length 2*L + */ +struct dh_keygen_req_s { + uint8_t *q; + uint8_t *r; + uint8_t *g; + uint8_t *prvkey; + uint8_t *pubkey; + uint8_t *ab; + uint32_t q_len; + uint32_t r_len; + uint32_t g_len; + uint32_t prvkey_len; + uint32_t pubkey_len; + uint32_t ab_len; +}; + +/* DSA Sign request + @len_L - size of the field + @len_N - size of the group + @q -Prime number or irreducible polynomial that creates the field,length L + @r - Order of the field of private keys, length N + @g -Generator or generator point (ECC),length L or 2*L(ECC) + @f(or m) -Message representative (typically the hash of the message) + or the actual message,length N + @s - Own private key, length N + @c - First part of digital signature, length N + @d - Second part of digital signature. The buffer for d must be a + multiple of 16 bytes, as it is used to store an encrypted + intermediate result, which may include padding. Length N + @ab -ECC curve parameters(for ECC only). length 2*L + */ +struct dsa_sign_req_s { + uint8_t *q; + uint8_t *r; + uint8_t *g; + uint8_t *priv_key; + uint8_t *m; + uint8_t *c; + uint8_t *d; + uint8_t *ab; + uint32_t q_len; + uint32_t r_len; + uint32_t g_len; + uint32_t priv_key_len; + uint32_t m_len; + uint32_t d_len; + uint32_t ab_len; +}; + +/* DSA Verify request + @q -Prime number or irreducible polynomial that creates the field,length L + @r - Order of the field of private keys, length N + @g -Generator or generator point (ECC),length L or 2*L(ECC) + @f(or m) -Message representative (typically the hash of the message) + or the actual message,length N + @pub_key - Public key, length N + @c - First part of digital signature, length N + @d - Second part of digital signature. The buffer for d must be a + multiple of 16 bytes, as it is used to store an encrypted + intermediate result, which may include padding. Length N + @ab -ECC curve parameters(for ECC only). length 2*L + */ +struct dsa_verify_req_s { + uint8_t *q; + uint8_t *r; + uint8_t *g; + uint8_t *pub_key; + uint8_t *m; + uint8_t *c; + uint8_t *d; + uint8_t *ab; + uint32_t q_len; + uint32_t r_len; + uint32_t g_len; + uint32_t pub_key_len; + uint32_t m_len; + uint32_t d_len; + uint32_t ab_len; +}; + +/* DH Compute_Key request + @q -Prime number or irreducible polynomial that creates the field,length L + @a,b -ECC curve parameters, Length 2L + @pub_key - Public key of other party, length L or 2L + @s - Own private Key + @z - Shared secret output of Length L + */ +struct dh_key_req_s { + uint8_t *q; + uint8_t *ab; + uint8_t *pub_key; /* Other party;s public key */ + uint8_t *s; + uint8_t *z; + uint32_t q_len; + uint32_t ab_len; + uint32_t pub_key_len; + uint32_t s_len; + uint32_t z_len; +}; + +enum curve_t { + DISCRETE_LOG, + ECC_PRIME, + ECC_BINARY, + MAX_ECC_TYPE +}; + +/* + * PKC request structure to be provided by cryptoAPI to driver hook functions. + * The request may be generated by application via crytodev interface or within + * kernel via tcrypt etc. + */ +struct pkc_request { + struct crypto_async_request base; + + enum pkc_req_type type; + enum curve_t curve_type; + union { + struct rsa_keygen_req_s rsa_keygen; + struct rsa_pub_req_s rsa_pub_req; + struct rsa_priv_frm1_req_s rsa_priv_f1; + struct rsa_priv_frm2_req_s rsa_priv_f2; + struct rsa_priv_frm3_req_s rsa_priv_f3; + struct dsa_sign_req_s dsa_sign; + struct dsa_verify_req_s dsa_verify; + struct keygen_req_s keygen; + struct dh_key_req_s dh_req; + struct dsa_keygen_req_s dsa_keygen; + struct dh_keygen_req_s dh_keygenreq; + } req_u; +}; + struct blkcipher_desc { struct crypto_blkcipher *tfm; void *info; @@ -282,6 +594,13 @@ struct rng_alg { unsigned int seedsize; }; +struct pkc_alg { + /* Public Key Crypto Operation Handler */ + int (*pkc_op)(struct pkc_request *); + /* Minimum and Maximum Key size supported by driver */ + unsigned int min_keysize; + unsigned int max_keysize; +}; #define cra_ablkcipher cra_u.ablkcipher #define cra_aead cra_u.aead @@ -289,6 +608,7 @@ struct rng_alg { #define cra_cipher cra_u.cipher #define cra_compress cra_u.compress #define cra_rng cra_u.rng +#define cra_pkc cra_u.pkc struct crypto_alg { struct list_head cra_list; @@ -314,6 +634,7 @@ struct crypto_alg { struct cipher_alg cipher; struct compress_alg compress; struct rng_alg rng; + struct pkc_alg pkc; } cra_u; int (*cra_init)(struct crypto_tfm *tfm); @@ -415,6 +736,16 @@ struct rng_tfm { int (*rng_reset)(struct crypto_rng *tfm, u8 *seed, unsigned int slen); }; +struct pkc_tfm { + /* Public Key Crypto Operation Handler */ + int (*pkc_op)(struct pkc_request *req); + + struct crypto_tfm *base; + + unsigned int min_keysize; + unsigned int max_keysize; +}; + #define crt_ablkcipher crt_u.ablkcipher #define crt_aead crt_u.aead #define crt_blkcipher crt_u.blkcipher @@ -422,6 +753,7 @@ struct rng_tfm { #define crt_hash crt_u.hash #define crt_compress crt_u.compress #define crt_rng crt_u.rng +#define crt_pkc crt_u.pkc struct crypto_tfm { @@ -435,6 +767,7 @@ struct crypto_tfm { struct hash_tfm hash; struct compress_tfm compress; struct rng_tfm rng; + struct pkc_tfm pkc; } crt_u; void (*exit)(struct crypto_tfm *tfm); @@ -460,6 +793,11 @@ struct crypto_cipher { struct crypto_tfm base; }; +/* PKC Transform structure */ +struct crypto_pkc { + struct crypto_tfm base; +}; + struct crypto_comp { struct crypto_tfm base; }; @@ -1028,6 +1366,77 @@ static inline void crypto_blkcipher_get_iv(struct crypto_blkcipher *tfm, memcpy(dst, crypto_blkcipher_crt(tfm)->iv, len); } +static inline struct crypto_tfm *crypto_pkc_tfm(struct crypto_pkc *tfm) +{ + return &tfm->base; +} + +static inline void pkc_request_set_tfm( + struct pkc_request *req, struct crypto_pkc *tfm) +{ + req->base.tfm = crypto_pkc_tfm(tfm); +} + +static inline struct pkc_request *pkc_request_alloc( + struct crypto_pkc *tfm, gfp_t gfp) +{ + struct pkc_request *req; + + req = kzalloc(sizeof(struct pkc_request), gfp); + + if (likely(req)) + pkc_request_set_tfm(req, tfm); + + return req; +} + +static inline void pkc_request_set_callback( + struct pkc_request *req, + u32 flags, crypto_completion_t complete, void *data) +{ + req->base.complete = complete; + req->base.data = data; + req->base.flags = flags; +} + +static inline struct crypto_pkc *__crypto_pkc_cast( + struct crypto_tfm *tfm) +{ + return (struct crypto_pkc *)tfm; +} + +static inline struct crypto_pkc *crypto_pkc_reqtfm( + struct pkc_request *req) +{ + return __crypto_pkc_cast(req->base.tfm); +} + +static inline struct crypto_pkc *crypto_alloc_pkc(const char *alg_name, + u32 type, u32 mask) +{ + mask |= CRYPTO_ALG_TYPE_MASK; + + return __crypto_pkc_cast(crypto_alloc_base(alg_name, type, mask)); +} + +static inline void crypto_free_pkc(struct crypto_pkc *tfm) +{ + crypto_free_tfm(crypto_pkc_tfm(tfm)); +} + +static inline struct pkc_tfm *crypto_pkc_crt( + struct crypto_pkc *tfm) +{ + return &crypto_pkc_tfm(tfm)->crt_pkc; +} + +static inline int crypto_pkc_op(struct pkc_request *req) +{ + struct pkc_tfm *tfm = + crypto_pkc_crt(crypto_pkc_reqtfm(req)); + return tfm->pkc_op(req); +} + static inline struct crypto_cipher *__crypto_cipher_cast(struct crypto_tfm *tfm) { return (struct crypto_cipher *)tfm; diff --git a/include/linux/device.h b/include/linux/device.h index 2a9d6ed..4713d9c 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -26,6 +26,7 @@ #include <linux/atomic.h> #include <linux/ratelimit.h> #include <linux/uidgid.h> +#include <linux/gfp.h> #include <asm/device.h> struct device; @@ -602,8 +603,24 @@ extern void devres_close_group(struct device *dev, void *id); extern void devres_remove_group(struct device *dev, void *id); extern int devres_release_group(struct device *dev, void *id); -/* managed kzalloc/kfree for device drivers, no kmalloc, always use kzalloc */ -extern void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp); +/* managed devm_k.alloc/kfree for device drivers */ +extern void *devm_kmalloc(struct device *dev, size_t size, gfp_t gfp); +static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp) +{ + return devm_kmalloc(dev, size, gfp | __GFP_ZERO); +} +static inline void *devm_kmalloc_array(struct device *dev, + size_t n, size_t size, gfp_t flags) +{ + if (size != 0 && n > SIZE_MAX / size) + return NULL; + return devm_kmalloc(dev, n * size, flags); +} +static inline void *devm_kcalloc(struct device *dev, + size_t n, size_t size, gfp_t flags) +{ + return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO); +} extern void devm_kfree(struct device *dev, void *p); void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res); diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 0bc7275..41cf0c3 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -45,13 +45,13 @@ static inline int dma_submit_error(dma_cookie_t cookie) /** * enum dma_status - DMA transaction status - * @DMA_SUCCESS: transaction completed successfully + * @DMA_COMPLETE: transaction completed * @DMA_IN_PROGRESS: transaction not yet processed * @DMA_PAUSED: transaction is paused * @DMA_ERROR: transaction failed */ enum dma_status { - DMA_SUCCESS, + DMA_COMPLETE, DMA_IN_PROGRESS, DMA_PAUSED, DMA_ERROR, @@ -171,12 +171,6 @@ struct dma_interleaved_template { * @DMA_CTRL_ACK - if clear, the descriptor cannot be reused until the client * acknowledges receipt, i.e. has has a chance to establish any dependency * chains - * @DMA_COMPL_SKIP_SRC_UNMAP - set to disable dma-unmapping the source buffer(s) - * @DMA_COMPL_SKIP_DEST_UNMAP - set to disable dma-unmapping the destination(s) - * @DMA_COMPL_SRC_UNMAP_SINGLE - set to do the source dma-unmapping as single - * (if not set, do the source dma-unmapping as page) - * @DMA_COMPL_DEST_UNMAP_SINGLE - set to do the destination dma-unmapping as single - * (if not set, do the destination dma-unmapping as page) * @DMA_PREP_PQ_DISABLE_P - prevent generation of P while generating Q * @DMA_PREP_PQ_DISABLE_Q - prevent generation of Q while generating P * @DMA_PREP_CONTINUE - indicate to a driver that it is reusing buffers as @@ -188,14 +182,10 @@ struct dma_interleaved_template { enum dma_ctrl_flags { DMA_PREP_INTERRUPT = (1 << 0), DMA_CTRL_ACK = (1 << 1), - DMA_COMPL_SKIP_SRC_UNMAP = (1 << 2), - DMA_COMPL_SKIP_DEST_UNMAP = (1 << 3), - DMA_COMPL_SRC_UNMAP_SINGLE = (1 << 4), - DMA_COMPL_DEST_UNMAP_SINGLE = (1 << 5), - DMA_PREP_PQ_DISABLE_P = (1 << 6), - DMA_PREP_PQ_DISABLE_Q = (1 << 7), - DMA_PREP_CONTINUE = (1 << 8), - DMA_PREP_FENCE = (1 << 9), + DMA_PREP_PQ_DISABLE_P = (1 << 2), + DMA_PREP_PQ_DISABLE_Q = (1 << 3), + DMA_PREP_CONTINUE = (1 << 4), + DMA_PREP_FENCE = (1 << 5), }; /** @@ -413,6 +403,17 @@ void dma_chan_cleanup(struct kref *kref); typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param); typedef void (*dma_async_tx_callback)(void *dma_async_param); + +struct dmaengine_unmap_data { + u8 to_cnt; + u8 from_cnt; + u8 bidi_cnt; + struct device *dev; + struct kref kref; + size_t len; + dma_addr_t addr[0]; +}; + /** * struct dma_async_tx_descriptor - async transaction descriptor * ---dma generic offload fields--- @@ -438,6 +439,7 @@ struct dma_async_tx_descriptor { dma_cookie_t (*tx_submit)(struct dma_async_tx_descriptor *tx); dma_async_tx_callback callback; void *callback_param; + struct dmaengine_unmap_data *unmap; #ifdef CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH struct dma_async_tx_descriptor *next; struct dma_async_tx_descriptor *parent; @@ -445,6 +447,40 @@ struct dma_async_tx_descriptor { #endif }; +#ifdef CONFIG_DMA_ENGINE +static inline void dma_set_unmap(struct dma_async_tx_descriptor *tx, + struct dmaengine_unmap_data *unmap) +{ + kref_get(&unmap->kref); + tx->unmap = unmap; +} + +struct dmaengine_unmap_data * +dmaengine_get_unmap_data(struct device *dev, int nr, gfp_t flags); +void dmaengine_unmap_put(struct dmaengine_unmap_data *unmap); +#else +static inline void dma_set_unmap(struct dma_async_tx_descriptor *tx, + struct dmaengine_unmap_data *unmap) +{ +} +static inline struct dmaengine_unmap_data * +dmaengine_get_unmap_data(struct device *dev, int nr, gfp_t flags) +{ + return NULL; +} +static inline void dmaengine_unmap_put(struct dmaengine_unmap_data *unmap) +{ +} +#endif + +static inline void dma_descriptor_unmap(struct dma_async_tx_descriptor *tx) +{ + if (tx->unmap) { + dmaengine_unmap_put(tx->unmap); + tx->unmap = NULL; + } +} + #ifndef CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH static inline void txd_lock(struct dma_async_tx_descriptor *txd) { @@ -979,10 +1015,10 @@ static inline enum dma_status dma_async_is_complete(dma_cookie_t cookie, { if (last_complete <= last_used) { if ((cookie <= last_complete) || (cookie > last_used)) - return DMA_SUCCESS; + return DMA_COMPLETE; } else { if ((cookie <= last_complete) && (cookie > last_used)) - return DMA_SUCCESS; + return DMA_COMPLETE; } return DMA_IN_PROGRESS; } @@ -1013,11 +1049,11 @@ static inline struct dma_chan *dma_find_channel(enum dma_transaction_type tx_typ } static inline enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie) { - return DMA_SUCCESS; + return DMA_COMPLETE; } static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx) { - return DMA_SUCCESS; + return DMA_COMPLETE; } static inline void dma_issue_pending_all(void) { diff --git a/include/linux/fsl/bestcomm/sram.h b/include/linux/fsl/bestcomm/sram.h index b6d6689..8555dab 100644 --- a/include/linux/fsl/bestcomm/sram.h +++ b/include/linux/fsl/bestcomm/sram.h @@ -12,7 +12,7 @@ #ifndef __BESTCOMM_SRAM_H__ #define __BESTCOMM_SRAM_H__ -#include <asm/rheap.h> +#include <linux/fsl/rheap.h> #include <asm/mmu.h> #include <linux/spinlock.h> @@ -25,7 +25,7 @@ struct bcom_sram { phys_addr_t base_phys; void *base_virt; unsigned int size; - rh_info_t *rh; + struct _rh_info *rh; spinlock_t lock; }; diff --git a/include/linux/fsl/immap_qe.h b/include/linux/fsl/immap_qe.h new file mode 100644 index 0000000..bd1ebd4 --- /dev/null +++ b/include/linux/fsl/immap_qe.h @@ -0,0 +1,488 @@ +/* + * QUICC Engine (QE) Internal Memory Map. + * The Internal Memory Map for devices with QE on them. This + * is the superset of all QE devices (8360, etc.). + * Copyright (C) 2006. Freescale Semiconductor, Inc. All rights reserved. + * + * Authors: + * Shlomi Gridish <gridish@freescale.com> + * Li Yang <leoli@freescale.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef _ASM_POWERPC_IMMAP_QE_H +#define _ASM_POWERPC_IMMAP_QE_H +#ifdef __KERNEL__ + +#include <linux/kernel.h> +#include <linux/io.h> + +#define QE_IMMAP_SIZE (1024 * 1024) /* 1MB from 1MB+IMMR */ + +/* QE I-RAM */ +struct qe_iram { + __be32 iadd; /* I-RAM Address Register */ + __be32 idata; /* I-RAM Data Register */ + u8 res0[0x04]; + __be32 iready; /* I-RAM Ready Register */ + u8 res1[0x70]; +} __packed; + +/* QE Interrupt Controller */ +struct qe_ic_regs { + __be32 qicr; + __be32 qivec; + __be32 qripnr; + __be32 qipnr; + __be32 qipxcc; + __be32 qipycc; + __be32 qipwcc; + __be32 qipzcc; + __be32 qimr; + __be32 qrimr; + __be32 qicnr; + u8 res0[0x4]; + __be32 qiprta; + __be32 qiprtb; + u8 res1[0x4]; + __be32 qricr; + u8 res2[0x20]; + __be32 qhivec; + u8 res3[0x1C]; +} __packed; + +/* Communications Processor */ +struct cp_qe { + __be32 cecr; /* QE command register */ + __be32 ceccr; /* QE controller configuration register */ + __be32 cecdr; /* QE command data register */ + u8 res0[0xA]; + __be16 ceter; /* QE timer event register */ + u8 res1[0x2]; + __be16 cetmr; /* QE timers mask register */ + __be32 cetscr; /* QE time-stamp timer control register */ + __be32 cetsr1; /* QE time-stamp register 1 */ + __be32 cetsr2; /* QE time-stamp register 2 */ + u8 res2[0x8]; + __be32 cevter; /* QE virtual tasks event register */ + __be32 cevtmr; /* QE virtual tasks mask register */ + __be16 cercr; /* QE RAM control register */ + u8 res3[0x2]; + u8 res4[0x24]; + __be16 ceexe1; /* QE external request 1 event register */ + u8 res5[0x2]; + __be16 ceexm1; /* QE external request 1 mask register */ + u8 res6[0x2]; + __be16 ceexe2; /* QE external request 2 event register */ + u8 res7[0x2]; + __be16 ceexm2; /* QE external request 2 mask register */ + u8 res8[0x2]; + __be16 ceexe3; /* QE external request 3 event register */ + u8 res9[0x2]; + __be16 ceexm3; /* QE external request 3 mask register */ + u8 res10[0x2]; + __be16 ceexe4; /* QE external request 4 event register */ + u8 res11[0x2]; + __be16 ceexm4; /* QE external request 4 mask register */ + u8 res12[0x3A]; + __be32 ceurnr; /* QE microcode revision number register */ + u8 res13[0x244]; +} __packed; + +/* QE Multiplexer */ +struct qe_mux { + __be32 cmxgcr; /* CMX general clock route register */ + __be32 cmxsi1cr_l; /* CMX SI1 clock route low register */ + __be32 cmxsi1cr_h; /* CMX SI1 clock route high register */ + __be32 cmxsi1syr; /* CMX SI1 SYNC route register */ + __be32 cmxucr[4]; /* CMX UCCx clock route registers */ + __be32 cmxupcr; /* CMX UPC clock route register */ + u8 res0[0x1C]; +} __packed; + +/* QE Timers */ +struct qe_timers { + u8 gtcfr1; /* Timer 1 and Timer 2 global config register*/ + u8 res0[0x3]; + u8 gtcfr2; /* Timer 3 and timer 4 global config register*/ + u8 res1[0xB]; + __be16 gtmdr1; /* Timer 1 mode register */ + __be16 gtmdr2; /* Timer 2 mode register */ + __be16 gtrfr1; /* Timer 1 reference register */ + __be16 gtrfr2; /* Timer 2 reference register */ + __be16 gtcpr1; /* Timer 1 capture register */ + __be16 gtcpr2; /* Timer 2 capture register */ + __be16 gtcnr1; /* Timer 1 counter */ + __be16 gtcnr2; /* Timer 2 counter */ + __be16 gtmdr3; /* Timer 3 mode register */ + __be16 gtmdr4; /* Timer 4 mode register */ + __be16 gtrfr3; /* Timer 3 reference register */ + __be16 gtrfr4; /* Timer 4 reference register */ + __be16 gtcpr3; /* Timer 3 capture register */ + __be16 gtcpr4; /* Timer 4 capture register */ + __be16 gtcnr3; /* Timer 3 counter */ + __be16 gtcnr4; /* Timer 4 counter */ + __be16 gtevr1; /* Timer 1 event register */ + __be16 gtevr2; /* Timer 2 event register */ + __be16 gtevr3; /* Timer 3 event register */ + __be16 gtevr4; /* Timer 4 event register */ + __be16 gtps; /* Timer 1 prescale register */ + u8 res2[0x46]; +} __packed; + +/* BRG */ +struct qe_brg { + __be32 brgc[16]; /* BRG configuration registers */ + u8 res0[0x40]; +} __packed; + +/* SPI */ +struct spi { + u8 res0[0x20]; + __be32 spmode; /* SPI mode register */ + u8 res1[0x2]; + u8 spie; /* SPI event register */ + u8 res2[0x1]; + u8 res3[0x2]; + u8 spim; /* SPI mask register */ + u8 res4[0x1]; + u8 res5[0x1]; + u8 spcom; /* SPI command register */ + u8 res6[0x2]; + __be32 spitd; /* SPI transmit data register (cpu mode) */ + __be32 spird; /* SPI receive data register (cpu mode) */ + u8 res7[0x8]; +} __packed; + +/* SI */ +struct si1 { + __be16 sixmr1[4]; /* SI1 TDMx (x = A B C D) mode register */ + u8 siglmr1_h; /* SI1 global mode register high */ + u8 res0[0x1]; + u8 sicmdr1_h; /* SI1 command register high */ + u8 res2[0x1]; + u8 sistr1_h; /* SI1 status register high */ + u8 res3[0x1]; + __be16 sirsr1_h; /* SI1 RAM shadow address register high */ + u8 sitarc1; /* SI1 RAM counter Tx TDMA */ + u8 sitbrc1; /* SI1 RAM counter Tx TDMB */ + u8 sitcrc1; /* SI1 RAM counter Tx TDMC */ + u8 sitdrc1; /* SI1 RAM counter Tx TDMD */ + u8 sirarc1; /* SI1 RAM counter Rx TDMA */ + u8 sirbrc1; /* SI1 RAM counter Rx TDMB */ + u8 sircrc1; /* SI1 RAM counter Rx TDMC */ + u8 sirdrc1; /* SI1 RAM counter Rx TDMD */ + u8 res4[0x8]; + __be16 siemr1; /* SI1 TDME mode register 16 bits */ + __be16 sifmr1; /* SI1 TDMF mode register 16 bits */ + __be16 sigmr1; /* SI1 TDMG mode register 16 bits */ + __be16 sihmr1; /* SI1 TDMH mode register 16 bits */ + u8 siglmg1_l; /* SI1 global mode register low 8 bits */ + u8 res5[0x1]; + u8 sicmdr1_l; /* SI1 command register low 8 bits */ + u8 res6[0x1]; + u8 sistr1_l; /* SI1 status register low 8 bits */ + u8 res7[0x1]; + __be16 sirsr1_l; /* SI1 RAM shadow address register low 16 bits*/ + u8 siterc1; /* SI1 RAM counter Tx TDME 8 bits */ + u8 sitfrc1; /* SI1 RAM counter Tx TDMF 8 bits */ + u8 sitgrc1; /* SI1 RAM counter Tx TDMG 8 bits */ + u8 sithrc1; /* SI1 RAM counter Tx TDMH 8 bits */ + u8 sirerc1; /* SI1 RAM counter Rx TDME 8 bits */ + u8 sirfrc1; /* SI1 RAM counter Rx TDMF 8 bits */ + u8 sirgrc1; /* SI1 RAM counter Rx TDMG 8 bits */ + u8 sirhrc1; /* SI1 RAM counter Rx TDMH 8 bits */ + u8 res8[0x8]; + __be32 siml1; /* SI1 multiframe limit register */ + u8 siedm1; /* SI1 extended diagnostic mode register */ + u8 res9[0xBB]; +} __packed; + +/* SI Routing Tables */ +struct sir { + u8 tx[0x400]; + u8 rx[0x400]; + u8 res0[0x800]; +} __packed; + +/* USB Controller */ +struct qe_usb_ctlr { + u8 usb_usmod; + u8 usb_usadr; + u8 usb_uscom; + u8 res1[1]; + __be16 usb_usep[4]; + u8 res2[4]; + __be16 usb_usber; + u8 res3[2]; + __be16 usb_usbmr; + u8 res4[1]; + u8 usb_usbs; + __be16 usb_ussft; + u8 res5[2]; + __be16 usb_usfrn; + u8 res6[0x22]; +} __packed; + +/* MCC */ +struct qe_mcc { + __be32 mcce; /* MCC event register */ + __be32 mccm; /* MCC mask register */ + __be32 mccf; /* MCC configuration register */ + __be32 merl; /* MCC emergency request level register */ + u8 res0[0xF0]; +} __packed; + +/* QE UCC Slow */ +struct ucc_slow { + __be32 gumr_l; /* UCCx general mode register (low) */ + __be32 gumr_h; /* UCCx general mode register (high) */ + __be16 upsmr; /* UCCx protocol-specific mode register */ + u8 res0[0x2]; + __be16 utodr; /* UCCx transmit on demand register */ + __be16 udsr; /* UCCx data synchronization register */ + __be16 ucce; /* UCCx event register */ + u8 res1[0x2]; + __be16 uccm; /* UCCx mask register */ + u8 res2[0x1]; + u8 uccs; /* UCCx status register */ + u8 res3[0x24]; + __be16 utpt; + u8 res4[0x52]; + u8 guemr; /* UCC general extended mode register */ +} __packed; + +/* QE UCC Fast */ +struct ucc_fast { + __be32 gumr; /* UCCx general mode register */ + __be32 upsmr; /* UCCx protocol-specific mode register */ + __be16 utodr; /* UCCx transmit on demand register */ + u8 res0[0x2]; + __be16 udsr; /* UCCx data synchronization register */ + u8 res1[0x2]; + __be32 ucce; /* UCCx event register */ + __be32 uccm; /* UCCx mask register */ + u8 uccs; /* UCCx status register */ + u8 res2[0x7]; + __be32 urfb; /* UCC receive FIFO base */ + __be16 urfs; /* UCC receive FIFO size */ + u8 res3[0x2]; + __be16 urfet; /* UCC receive FIFO emergency threshold */ + __be16 urfset; /* UCC receive FIFO special emergency + threshold */ + __be32 utfb; /* UCC transmit FIFO base */ + __be16 utfs; /* UCC transmit FIFO size */ + u8 res4[0x2]; + __be16 utfet; /* UCC transmit FIFO emergency threshold */ + u8 res5[0x2]; + __be16 utftt; /* UCC transmit FIFO transmit threshold */ + u8 res6[0x2]; + __be16 utpt; /* UCC transmit polling timer */ + u8 res7[0x2]; + __be32 urtry; /* UCC retry counter register */ + u8 res8[0x4C]; + u8 guemr; /* UCC general extended mode register */ +} __packed; + +struct ucc { + union { + struct ucc_slow slow; + struct ucc_fast fast; + u8 res[0x200]; /* UCC blocks are 512 bytes each */ + }; +} __packed; + +/* MultiPHY UTOPIA POS Controllers (UPC) */ +struct upc { + __be32 upgcr; /* UTOPIA/POS general configuration register */ + __be32 uplpa; /* UTOPIA/POS last PHY address */ + __be32 uphec; /* ATM HEC register */ + __be32 upuc; /* UTOPIA/POS UCC configuration */ + __be32 updc1; /* UTOPIA/POS device 1 configuration */ + __be32 updc2; /* UTOPIA/POS device 2 configuration */ + __be32 updc3; /* UTOPIA/POS device 3 configuration */ + __be32 updc4; /* UTOPIA/POS device 4 configuration */ + __be32 upstpa; /* UTOPIA/POS STPA threshold */ + u8 res0[0xC]; + __be32 updrs1_h; /* UTOPIA/POS device 1 rate select */ + __be32 updrs1_l; /* UTOPIA/POS device 1 rate select */ + __be32 updrs2_h; /* UTOPIA/POS device 2 rate select */ + __be32 updrs2_l; /* UTOPIA/POS device 2 rate select */ + __be32 updrs3_h; /* UTOPIA/POS device 3 rate select */ + __be32 updrs3_l; /* UTOPIA/POS device 3 rate select */ + __be32 updrs4_h; /* UTOPIA/POS device 4 rate select */ + __be32 updrs4_l; /* UTOPIA/POS device 4 rate select */ + __be32 updrp1; /* UTOPIA/POS device 1 receive priority low */ + __be32 updrp2; /* UTOPIA/POS device 2 receive priority low */ + __be32 updrp3; /* UTOPIA/POS device 3 receive priority low */ + __be32 updrp4; /* UTOPIA/POS device 4 receive priority low */ + __be32 upde1; /* UTOPIA/POS device 1 event */ + __be32 upde2; /* UTOPIA/POS device 2 event */ + __be32 upde3; /* UTOPIA/POS device 3 event */ + __be32 upde4; /* UTOPIA/POS device 4 event */ + __be16 uprp1; + __be16 uprp2; + __be16 uprp3; + __be16 uprp4; + u8 res1[0x8]; + __be16 uptirr1_0; /* Device 1 transmit internal rate 0 */ + __be16 uptirr1_1; /* Device 1 transmit internal rate 1 */ + __be16 uptirr1_2; /* Device 1 transmit internal rate 2 */ + __be16 uptirr1_3; /* Device 1 transmit internal rate 3 */ + __be16 uptirr2_0; /* Device 2 transmit internal rate 0 */ + __be16 uptirr2_1; /* Device 2 transmit internal rate 1 */ + __be16 uptirr2_2; /* Device 2 transmit internal rate 2 */ + __be16 uptirr2_3; /* Device 2 transmit internal rate 3 */ + __be16 uptirr3_0; /* Device 3 transmit internal rate 0 */ + __be16 uptirr3_1; /* Device 3 transmit internal rate 1 */ + __be16 uptirr3_2; /* Device 3 transmit internal rate 2 */ + __be16 uptirr3_3; /* Device 3 transmit internal rate 3 */ + __be16 uptirr4_0; /* Device 4 transmit internal rate 0 */ + __be16 uptirr4_1; /* Device 4 transmit internal rate 1 */ + __be16 uptirr4_2; /* Device 4 transmit internal rate 2 */ + __be16 uptirr4_3; /* Device 4 transmit internal rate 3 */ + __be32 uper1; /* Device 1 port enable register */ + __be32 uper2; /* Device 2 port enable register */ + __be32 uper3; /* Device 3 port enable register */ + __be32 uper4; /* Device 4 port enable register */ + u8 res2[0x150]; +} __packed; + +/* SDMA */ +struct sdma { + __be32 sdsr; /* Serial DMA status register */ + __be32 sdmr; /* Serial DMA mode register */ + __be32 sdtr1; /* SDMA system bus threshold register */ + __be32 sdtr2; /* SDMA secondary bus threshold register */ + __be32 sdhy1; /* SDMA system bus hysteresis register */ + __be32 sdhy2; /* SDMA secondary bus hysteresis register */ + __be32 sdta1; /* SDMA system bus address register */ + __be32 sdta2; /* SDMA secondary bus address register */ + __be32 sdtm1; /* SDMA system bus MSNUM register */ + __be32 sdtm2; /* SDMA secondary bus MSNUM register */ + u8 res0[0x10]; + __be32 sdaqr; /* SDMA address bus qualify register */ + __be32 sdaqmr; /* SDMA address bus qualify mask register */ + u8 res1[0x4]; + __be32 sdebcr; /* SDMA CAM entries base register */ + u8 res2[0x38]; +} __packed; + +/* Debug Space */ +struct dbg { + __be32 bpdcr; /* Breakpoint debug command register */ + __be32 bpdsr; /* Breakpoint debug status register */ + __be32 bpdmr; /* Breakpoint debug mask register */ + __be32 bprmrr0; /* Breakpoint request mode risc register 0 */ + __be32 bprmrr1; /* Breakpoint request mode risc register 1 */ + u8 res0[0x8]; + __be32 bprmtr0; /* Breakpoint request mode trb register 0 */ + __be32 bprmtr1; /* Breakpoint request mode trb register 1 */ + u8 res1[0x8]; + __be32 bprmir; /* Breakpoint request mode immediate register */ + __be32 bprmsr; /* Breakpoint request mode serial register */ + __be32 bpemr; /* Breakpoint exit mode register */ + u8 res2[0x48]; +} __packed; + +/* + * RISC Special Registers (Trap and Breakpoint). These are described in + * the QE Developer's Handbook. + */ +struct rsp { + __be32 tibcr[16]; /* Trap/instruction breakpoint control regs */ + u8 res0[64]; + __be32 ibcr0; + __be32 ibs0; + __be32 ibcnr0; + u8 res1[4]; + __be32 ibcr1; + __be32 ibs1; + __be32 ibcnr1; + __be32 npcr; + __be32 dbcr; + __be32 dbar; + __be32 dbamr; + __be32 dbsr; + __be32 dbcnr; + u8 res2[12]; + __be32 dbdr_h; + __be32 dbdr_l; + __be32 dbdmr_h; + __be32 dbdmr_l; + __be32 bsr; + __be32 bor; + __be32 bior; + u8 res3[4]; + __be32 iatr[4]; + __be32 eccr; /* Exception control configuration register */ + __be32 eicr; + u8 res4[0x100-0xf8]; +} __packed; + +struct qe_immap { + struct qe_iram iram; /* I-RAM */ + struct qe_ic_regs ic; /* Interrupt Controller */ + struct cp_qe cp; /* Communications Processor */ + struct qe_mux qmx; /* QE Multiplexer */ + struct qe_timers qet; /* QE Timers */ + struct spi spi[0x2]; /* spi */ + struct qe_mcc mcc; /* mcc */ + struct qe_brg brg; /* brg */ + struct qe_usb_ctlr usb; /* USB */ + struct si1 si1; /* SI */ + u8 res11[0x800]; + struct sir sir; /* SI Routing Tables */ + struct ucc ucc1; /* ucc1 */ + struct ucc ucc3; /* ucc3 */ + struct ucc ucc5; /* ucc5 */ + struct ucc ucc7; /* ucc7 */ + u8 res12[0x600]; + struct upc upc1; /* MultiPHY UTOPIA POS Ctrlr 1*/ + struct ucc ucc2; /* ucc2 */ + struct ucc ucc4; /* ucc4 */ + struct ucc ucc6; /* ucc6 */ + struct ucc ucc8; /* ucc8 */ + u8 res13[0x600]; + struct upc upc2; /* MultiPHY UTOPIA POS Ctrlr 2*/ + struct sdma sdma; /* SDMA */ + struct dbg dbg; /* 0x104080 - 0x1040FF + Debug Space */ + struct rsp rsp[0x2]; /* 0x104100 - 0x1042FF + RISC Special Registers + (Trap and Breakpoint) */ + u8 res14[0x300]; /* 0x104300 - 0x1045FF */ + u8 res15[0x3A00]; /* 0x104600 - 0x107FFF */ + u8 res16[0x8000]; /* 0x108000 - 0x110000 */ + u8 muram[0xC000]; /* 0x110000 - 0x11C000 + Multi-user RAM */ + u8 res17[0x24000]; /* 0x11C000 - 0x140000 */ + u8 res18[0xC0000]; /* 0x140000 - 0x200000 */ +} __packed; + +extern struct qe_immap __iomem *qe_immr; +extern phys_addr_t get_qe_base(void); + +/* + * Returns the offset within the QE address space of the given pointer. + * + * Note that the QE does not support 36-bit physical addresses, so if + * get_qe_base() returns a number above 4GB, the caller will probably fail. + */ +static inline phys_addr_t immrbar_virt_to_phys(void *address) +{ + void *q = (void *)qe_immr; + + /* Is it a MURAM address? */ + if ((address >= q) && (address < (q + QE_IMMAP_SIZE))) + return get_qe_base() + (address - q); + + /* It's an address returned by kmalloc */ + return virt_to_phys(address); +} + +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_IMMAP_QE_H */ diff --git a/include/linux/fsl/qe.h b/include/linux/fsl/qe.h new file mode 100644 index 0000000..ef4422c --- /dev/null +++ b/include/linux/fsl/qe.h @@ -0,0 +1,810 @@ +/* + * Copyright (C) 2006, 2012 Freescale Semiconductor, Inc. All rights reserved. + * + * Authors: Shlomi Gridish <gridish@freescale.com> + * Li Yang <leoli@freescale.com> + * + * Description: + * QUICC Engine (QE) external definitions and structure. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef _ASM_POWERPC_QE_H +#define _ASM_POWERPC_QE_H +#ifdef __KERNEL__ + +#include <linux/spinlock.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/fsl/immap_qe.h> + +#define QE_NUM_OF_SNUM 256 /* There are 256 serial number in QE */ +#define QE_NUM_OF_BRGS 16 +#define QE_NUM_OF_PORTS 1024 + +/* Memory partitions +*/ +#define MEM_PART_SYSTEM 0 +#define MEM_PART_SECONDARY 1 +#define MEM_PART_MURAM 2 + +extern int siram_init_flag; + +/* Clocks and BRGs */ +enum qe_clock { + QE_CLK_NONE = 0, + QE_BRG1, /* Baud Rate Generator 1 */ + QE_BRG2, /* Baud Rate Generator 2 */ + QE_BRG3, /* Baud Rate Generator 3 */ + QE_BRG4, /* Baud Rate Generator 4 */ + QE_BRG5, /* Baud Rate Generator 5 */ + QE_BRG6, /* Baud Rate Generator 6 */ + QE_BRG7, /* Baud Rate Generator 7 */ + QE_BRG8, /* Baud Rate Generator 8 */ + QE_BRG9, /* Baud Rate Generator 9 */ + QE_BRG10, /* Baud Rate Generator 10 */ + QE_BRG11, /* Baud Rate Generator 11 */ + QE_BRG12, /* Baud Rate Generator 12 */ + QE_BRG13, /* Baud Rate Generator 13 */ + QE_BRG14, /* Baud Rate Generator 14 */ + QE_BRG15, /* Baud Rate Generator 15 */ + QE_BRG16, /* Baud Rate Generator 16 */ + QE_CLK1, /* Clock 1 */ + QE_CLK2, /* Clock 2 */ + QE_CLK3, /* Clock 3 */ + QE_CLK4, /* Clock 4 */ + QE_CLK5, /* Clock 5 */ + QE_CLK6, /* Clock 6 */ + QE_CLK7, /* Clock 7 */ + QE_CLK8, /* Clock 8 */ + QE_CLK9, /* Clock 9 */ + QE_CLK10, /* Clock 10 */ + QE_CLK11, /* Clock 11 */ + QE_CLK12, /* Clock 12 */ + QE_CLK13, /* Clock 13 */ + QE_CLK14, /* Clock 14 */ + QE_CLK15, /* Clock 15 */ + QE_CLK16, /* Clock 16 */ + QE_CLK17, /* Clock 17 */ + QE_CLK18, /* Clock 18 */ + QE_CLK19, /* Clock 19 */ + QE_CLK20, /* Clock 20 */ + QE_CLK21, /* Clock 21 */ + QE_CLK22, /* Clock 22 */ + QE_CLK23, /* Clock 23 */ + QE_CLK24, /* Clock 24 */ + QE_RSYNC_PIN, /* RSYNC from pin */ + QE_TSYNC_PIN, /* TSYNC from pin */ + QE_CLK_DUMMY +}; + +static inline bool qe_clock_is_brg(enum qe_clock clk) +{ + return clk >= QE_BRG1 && clk <= QE_BRG16; +} + +extern spinlock_t cmxgcr_lock; + +/* Export QE common operations */ +#ifdef CONFIG_QUICC_ENGINE +extern void qe_reset(void); +#else +static inline void qe_reset(void) {} +#endif + +/* QE PIO */ +#define QE_PIO_PINS 32 + +struct qe_pio_regs { + __be32 cpodr; /* Open drain register */ + __be32 cpdata; /* Data register */ + __be32 cpdir1; /* Direction register */ + __be32 cpdir2; /* Direction register */ + __be32 cppar1; /* Pin assignment register */ + __be32 cppar2; /* Pin assignment register */ +#ifdef CONFIG_PPC_85xx + u8 pad[8]; +#endif +}; + +#define QE_PIO_DIR_IN 2 +#define QE_PIO_DIR_OUT 1 +extern void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, + int dir, int open_drain, int assignment, + int has_irq); +#ifdef CONFIG_QUICC_ENGINE +extern int par_io_init(struct device_node *np); +extern int par_io_of_config(struct device_node *np); +extern int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain, + int assignment, int has_irq); +extern int par_io_data_set(u8 port, u8 pin, u8 val); +#else +static inline int par_io_init(struct device_node *np) { return -ENOSYS; } +static inline int par_io_of_config(struct device_node *np) { return -ENOSYS; } +static inline int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain, + int assignment, int has_irq) { return -ENOSYS; } +static inline int par_io_data_set(u8 port, u8 pin, u8 val) { return -ENOSYS; } +#endif /* CONFIG_QUICC_ENGINE */ + +/* + * Pin multiplexing functions. + */ +struct qe_pin; +#ifdef CONFIG_QE_GPIO +extern struct qe_pin *qe_pin_request(struct device_node *np, int index); +extern void qe_pin_free(struct qe_pin *qe_pin); +extern void qe_pin_set_gpio(struct qe_pin *qe_pin); +extern void qe_pin_set_dedicated(struct qe_pin *pin); +#else +static inline struct qe_pin *qe_pin_request(struct device_node *np, int index) +{ + return ERR_PTR(-ENOSYS); +} +static inline void qe_pin_free(struct qe_pin *qe_pin) {} +static inline void qe_pin_set_gpio(struct qe_pin *qe_pin) {} +static inline void qe_pin_set_dedicated(struct qe_pin *pin) {} +#endif /* CONFIG_QE_GPIO */ + +#ifdef CONFIG_QUICC_ENGINE +int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input); +#else +static inline int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, + u32 cmd_input) +{ + return -ENOSYS; +} +#endif /* CONFIG_QUICC_ENGINE */ + +/* QE internal API */ +enum qe_clock qe_clock_source(const char *source); +unsigned int qe_get_brg_clk(void); +int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier); +int qe_get_snum(void); +void qe_put_snum(u8 snum); +unsigned int qe_get_num_of_risc(void); +unsigned int qe_get_num_of_snums(void); + +static inline int qe_alive_during_sleep(void) +{ + /* + * MPC8568E reference manual says: + * + * "...power down sequence waits for all I/O interfaces to become idle. + * In some applications this may happen eventually without actively + * shutting down interfaces, but most likely, software will have to + * take steps to shut down the eTSEC, QUICC Engine Block, and PCI + * interfaces before issuing the command (either the write to the core + * MSR[WE] as described above or writing to POWMGTCSR) to put the + * device into sleep state." + * + * MPC8569E reference manual has a similar paragraph. + */ +#ifdef CONFIG_PPC_85xx + return 0; +#else + return 1; +#endif +} + +int qe_muram_init(void); + +#if defined(CONFIG_QUICC_ENGINE) +unsigned long qe_muram_alloc(unsigned long size, unsigned long align); +int qe_muram_free(unsigned long offset); +unsigned long qe_muram_alloc_fixed(unsigned long offset, unsigned long size); +void __iomem *qe_muram_addr(unsigned long offset); +unsigned long qe_muram_offset(void __iomem *addr); +dma_addr_t qe_muram_dma(void __iomem *addr); +#else +static inline unsigned long qe_muram_alloc(unsigned long size, + unsigned long align) +{ + return -ENOSYS; +} + +static inline int qe_muram_free(unsigned long offset) +{ + return -ENOSYS; +} + +static inline unsigned long qe_muram_alloc_fixed(unsigned long offset, + unsigned long size) +{ + return -ENOSYS; +} + +static inline void __iomem *qe_muram_addr(unsigned long offset) +{ + return NULL; +} + +static inline unsigned long qe_muram_offset(void __iomem *addr) +{ + return -ENOSYS; +} + +static inline dma_addr_t qe_muram_dma(void __iomem *addr) +{ + return 0; +} +#endif /* defined(CONFIG_QUICC_ENGINE) */ + +/* Structure that defines QE firmware binary files. + * + * See Documentation/powerpc/qe_firmware.txt for a description of these + * fields. + */ +struct qe_firmware { + struct qe_header { + __be32 length; /* Length of the entire structure, in bytes */ + u8 magic[3]; /* Set to { 'Q', 'E', 'F' } */ + u8 version; /* Version of this layout. First ver is '1' */ + } header; + u8 id[62]; /* Null-terminated identifier string */ + u8 split; /* 0 = shared I-RAM, 1 = split I-RAM */ + u8 count; /* Number of microcode[] structures */ + struct { + __be16 model; /* The SOC model */ + u8 major; /* The SOC revision major */ + u8 minor; /* The SOC revision minor */ + } __packed soc; + u8 padding[4]; /* Reserved, for alignment */ + __be64 extended_modes; /* Extended modes */ + __be32 vtraps[8]; /* Virtual trap addresses */ + u8 reserved[4]; /* Reserved, for future expansion */ + struct qe_microcode { + u8 id[32]; /* Null-terminated identifier */ + __be32 traps[16]; /* Trap addresses, 0 == ignore */ + __be32 eccr; /* The value for the ECCR register */ + __be32 iram_offset; /* Offset into I-RAM for the code */ + __be32 count; /* Number of 32-bit words of the code */ + __be32 code_offset; /* Offset of the actual microcode */ + u8 major; /* The microcode version major */ + u8 minor; /* The microcode version minor */ + u8 revision; /* The microcode version revision */ + u8 padding; /* Reserved, for alignment */ + u8 reserved[4]; /* Reserved, for future expansion */ + } __packed microcode[1]; + /* All microcode binaries should be located here */ + /* CRC32 should be located here, after the microcode binaries */ +} __packed; + +struct qe_firmware_info { + char id[64]; /* Firmware name */ + u32 vtraps[8]; /* Virtual trap addresses */ + u64 extended_modes; /* Extended modes */ +}; + +#ifdef CONFIG_QUICC_ENGINE +/* Upload a firmware to the QE */ +int qe_upload_firmware(const struct qe_firmware *firmware); +#else +static inline int qe_upload_firmware(const struct qe_firmware *firmware) +{ + return -ENOSYS; +} +#endif /* CONFIG_QUICC_ENGINE */ + +/* Obtain information on the uploaded firmware */ +struct qe_firmware_info *qe_get_firmware_info(void); + +/* QE USB */ +int qe_usb_clock_set(enum qe_clock clk, int rate); + +/* Buffer descriptors */ +struct qe_bd { + __be16 status; + __be16 length; + __be32 buf; +} __packed; + +#define BD_STATUS_MASK 0xffff0000 +#define BD_LENGTH_MASK 0x0000ffff + +/* Buffer descriptor control/status used by serial + */ + +#define BD_SC_EMPTY (0x8000) /* Receive is empty */ +#define BD_SC_READY (0x8000) /* Transmit is ready */ +#define BD_SC_WRAP (0x2000) /* Last buffer descriptor */ +#define BD_SC_INTRPT (0x1000) /* Interrupt on change */ +#define BD_SC_LAST (0x0800) /* Last buffer in frame */ +#define BD_SC_TC (0x0400) /* Transmit CRC */ +#define BD_SC_CM (0x0200) /* Continuous mode */ +#define BD_SC_ID (0x0100) /* Rec'd too many idles */ +#define BD_SC_P (0x0100) /* xmt preamble */ +#define BD_SC_BR (0x0020) /* Break received */ +#define BD_SC_FR (0x0010) /* Framing error */ +#define BD_SC_PR (0x0008) /* Parity error */ +#define BD_SC_NAK (0x0004) /* NAK - did not respond */ +#define BD_SC_OV (0x0002) /* Overrun */ +#define BD_SC_UN (0x0002) /* Underrun */ +#define BD_SC_CD (0x0001) /* */ +#define BD_SC_CL (0x0001) /* Collision */ + +/* Alignment */ +#define QE_INTR_TABLE_ALIGN 16 /* ??? */ +#define QE_ALIGNMENT_OF_BD 8 +#define QE_ALIGNMENT_OF_PRAM 64 + +/* RISC allocation */ +#define QE_RISC_ALLOCATION_RISC1 0x1 /* RISC 1 */ +#define QE_RISC_ALLOCATION_RISC2 0x2 /* RISC 2 */ +#define QE_RISC_ALLOCATION_RISC3 0x4 /* RISC 3 */ +#define QE_RISC_ALLOCATION_RISC4 0x8 /* RISC 4 */ +#define QE_RISC_ALLOCATION_RISC1_AND_RISC2 (QE_RISC_ALLOCATION_RISC1 | \ + QE_RISC_ALLOCATION_RISC2) +#define QE_RISC_ALLOCATION_FOUR_RISCS (QE_RISC_ALLOCATION_RISC1 | \ + QE_RISC_ALLOCATION_RISC2 | \ + QE_RISC_ALLOCATION_RISC3 | \ + QE_RISC_ALLOCATION_RISC4) + +/* QE extended filtering Table Lookup Key Size */ +enum qe_fltr_tbl_lookup_key_size { + QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES + = 0x3f, /* LookupKey parsed by the Generate LookupKey + CMD is truncated to 8 bytes */ + QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES + = 0x5f, /* LookupKey parsed by the Generate LookupKey + CMD is truncated to 16 bytes */ +}; + +/* QE FLTR extended filtering Largest External Table Lookup Key Size */ +enum qe_fltr_largest_external_tbl_lookup_key_size { + QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE + = 0x0,/* not used */ + QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES + = QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES, /* 8 bytes */ + QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES + = QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES, /* 16 bytes */ +}; + +/* structure representing QE parameter RAM */ +struct qe_timer_tables { + u16 tm_base; /* QE timer table base adr */ + u16 tm_ptr; /* QE timer table pointer */ + u16 r_tmr; /* QE timer mode register */ + u16 r_tmv; /* QE timer valid register */ + u32 tm_cmd; /* QE timer cmd register */ + u32 tm_cnt; /* QE timer internal cnt */ +} __packed; + +#define QE_FLTR_TAD_SIZE 8 + +/* QE extended filtering Termination Action Descriptor (TAD) */ +struct qe_fltr_tad { + u8 serialized[QE_FLTR_TAD_SIZE]; +} __packed; + +/* Communication Direction */ +enum comm_dir { + COMM_DIR_NONE = 0, + COMM_DIR_RX = 1, + COMM_DIR_TX = 2, + COMM_DIR_RX_AND_TX = 3 +}; + +/* QE CMXUCR Registers. + * There are two UCCs represented in each of the four CMXUCR registers. + * These values are for the UCC in the LSBs + */ +#define QE_CMXUCR_MII_ENET_MNG 0x00007000 +#define QE_CMXUCR_MII_ENET_MNG_SHIFT 12 +#define QE_CMXUCR_GRANT 0x00008000 +#define QE_CMXUCR_TSA 0x00004000 +#define QE_CMXUCR_BKPT 0x00000100 +#define QE_CMXUCR_TX_CLK_SRC_MASK 0x0000000F + +/* QE CMXGCR Registers. +*/ +#define QE_CMXGCR_MII_ENET_MNG 0x00007000 +#define QE_CMXGCR_MII_ENET_MNG_SHIFT 12 +#define QE_CMXGCR_USBCS 0x0000000f +#define QE_CMXGCR_USBCS_CLK3 0x1 +#define QE_CMXGCR_USBCS_CLK5 0x2 +#define QE_CMXGCR_USBCS_CLK7 0x3 +#define QE_CMXGCR_USBCS_CLK9 0x4 +#define QE_CMXGCR_USBCS_CLK13 0x5 +#define QE_CMXGCR_USBCS_CLK17 0x6 +#define QE_CMXGCR_USBCS_CLK19 0x7 +#define QE_CMXGCR_USBCS_CLK21 0x8 +#define QE_CMXGCR_USBCS_BRG9 0x9 +#define QE_CMXGCR_USBCS_BRG10 0xa + +/* QE CECR Commands. +*/ +#define QE_CR_FLG 0x00010000 +#define QE_RESET 0x80000000 +#define QE_INIT_TX_RX 0x00000000 +#define QE_INIT_RX 0x00000001 +#define QE_INIT_TX 0x00000002 +#define QE_ENTER_HUNT_MODE 0x00000003 +#define QE_STOP_TX 0x00000004 +#define QE_GRACEFUL_STOP_TX 0x00000005 +#define QE_RESTART_TX 0x00000006 +#define QE_CLOSE_RX_BD 0x00000007 +#define QE_SWITCH_COMMAND 0x00000007 +#define QE_SET_GROUP_ADDRESS 0x00000008 +#define QE_START_IDMA 0x00000009 +#define QE_MCC_STOP_RX 0x00000009 +#define QE_ATM_TRANSMIT 0x0000000a +#define QE_HPAC_CLEAR_ALL 0x0000000b +#define QE_GRACEFUL_STOP_RX 0x0000001a +#define QE_RESTART_RX 0x0000001b +#define QE_HPAC_SET_PRIORITY 0x0000010b +#define QE_HPAC_STOP_TX 0x0000020b +#define QE_HPAC_STOP_RX 0x0000030b +#define QE_HPAC_GRACEFUL_STOP_TX 0x0000040b +#define QE_HPAC_GRACEFUL_STOP_RX 0x0000050b +#define QE_HPAC_START_TX 0x0000060b +#define QE_HPAC_START_RX 0x0000070b +#define QE_USB_STOP_TX 0x0000000a +#define QE_USB_RESTART_TX 0x0000000c +#define QE_QMC_STOP_TX 0x0000000c +#define QE_QMC_STOP_RX 0x0000000d +#define QE_SS7_SU_FIL_RESET 0x0000000e +/* jonathbr added from here down for 83xx */ +#define QE_RESET_BCS 0x0000000a +#define QE_MCC_INIT_TX_RX_16 0x00000003 +#define QE_MCC_STOP_TX 0x00000004 +#define QE_MCC_INIT_TX_1 0x00000005 +#define QE_MCC_INIT_RX_1 0x00000006 +#define QE_MCC_RESET 0x00000007 +#define QE_SET_TIMER 0x00000008 +#define QE_RANDOM_NUMBER 0x0000000c +#define QE_ATM_MULTI_THREAD_INIT 0x00000011 +#define QE_ASSIGN_PAGE 0x00000012 +#define QE_ADD_REMOVE_HASH_ENTRY 0x00000013 +#define QE_START_FLOW_CONTROL 0x00000014 +#define QE_STOP_FLOW_CONTROL 0x00000015 +#define QE_ASSIGN_PAGE_TO_DEVICE 0x00000016 + +#define QE_ASSIGN_RISC 0x00000010 +#define QE_CR_MCN_NORMAL_SHIFT 6 +#define QE_CR_MCN_USB_SHIFT 4 +#define QE_CR_MCN_RISC_ASSIGN_SHIFT 8 +#define QE_CR_SNUM_SHIFT 17 + +/* QE CECR Sub Block - sub block of QE command. +*/ +#define QE_CR_SUBBLOCK_INVALID 0x00000000 +#define QE_CR_SUBBLOCK_USB 0x03200000 +#define QE_CR_SUBBLOCK_UCCFAST1 0x02000000 +#define QE_CR_SUBBLOCK_UCCFAST2 0x02200000 +#define QE_CR_SUBBLOCK_UCCFAST3 0x02400000 +#define QE_CR_SUBBLOCK_UCCFAST4 0x02600000 +#define QE_CR_SUBBLOCK_UCCFAST5 0x02800000 +#define QE_CR_SUBBLOCK_UCCFAST6 0x02a00000 +#define QE_CR_SUBBLOCK_UCCFAST7 0x02c00000 +#define QE_CR_SUBBLOCK_UCCFAST8 0x02e00000 +#define QE_CR_SUBBLOCK_UCCSLOW1 0x00000000 +#define QE_CR_SUBBLOCK_UCCSLOW2 0x00200000 +#define QE_CR_SUBBLOCK_UCCSLOW3 0x00400000 +#define QE_CR_SUBBLOCK_UCCSLOW4 0x00600000 +#define QE_CR_SUBBLOCK_UCCSLOW5 0x00800000 +#define QE_CR_SUBBLOCK_UCCSLOW6 0x00a00000 +#define QE_CR_SUBBLOCK_UCCSLOW7 0x00c00000 +#define QE_CR_SUBBLOCK_UCCSLOW8 0x00e00000 +#define QE_CR_SUBBLOCK_MCC1 0x03800000 +#define QE_CR_SUBBLOCK_MCC2 0x03a00000 +#define QE_CR_SUBBLOCK_MCC3 0x03000000 +#define QE_CR_SUBBLOCK_IDMA1 0x02800000 +#define QE_CR_SUBBLOCK_IDMA2 0x02a00000 +#define QE_CR_SUBBLOCK_IDMA3 0x02c00000 +#define QE_CR_SUBBLOCK_IDMA4 0x02e00000 +#define QE_CR_SUBBLOCK_HPAC 0x01e00000 +#define QE_CR_SUBBLOCK_SPI1 0x01400000 +#define QE_CR_SUBBLOCK_SPI2 0x01600000 +#define QE_CR_SUBBLOCK_RAND 0x01c00000 +#define QE_CR_SUBBLOCK_TIMER 0x01e00000 +#define QE_CR_SUBBLOCK_GENERAL 0x03c00000 + +/* QE CECR Protocol - For non-MCC, specifies mode for QE CECR command */ +#define QE_CR_PROTOCOL_UNSPECIFIED 0x00 /* For all other protocols */ +#define QE_CR_PROTOCOL_HDLC_TRANSPARENT 0x00 +#define QE_CR_PROTOCOL_QMC 0x02 +#define QE_CR_PROTOCOL_UART 0x04 +#define QE_CR_PROTOCOL_ATM_POS 0x0A +#define QE_CR_PROTOCOL_ETHERNET 0x0C +#define QE_CR_PROTOCOL_L2_SWITCH 0x0D + +/* BRG configuration register */ +#define QE_BRGC_ENABLE 0x00010000 +#define QE_BRGC_DIVISOR_SHIFT 1 +#define QE_BRGC_DIVISOR_MAX 0xFFF +#define QE_BRGC_DIV16 1 + +/* QE Timers registers */ +#define QE_GTCFR1_PCAS 0x80 +#define QE_GTCFR1_STP2 0x20 +#define QE_GTCFR1_RST2 0x10 +#define QE_GTCFR1_GM2 0x08 +#define QE_GTCFR1_GM1 0x04 +#define QE_GTCFR1_STP1 0x02 +#define QE_GTCFR1_RST1 0x01 + +/* SDMA registers */ +#define QE_SDSR_BER1 0x02000000 +#define QE_SDSR_BER2 0x01000000 + +#define QE_SDMR_GLB_1_MSK 0x80000000 +#define QE_SDMR_ADR_SEL 0x20000000 +#define QE_SDMR_BER1_MSK 0x02000000 +#define QE_SDMR_BER2_MSK 0x01000000 +#define QE_SDMR_EB1_MSK 0x00800000 +#define QE_SDMR_ER1_MSK 0x00080000 +#define QE_SDMR_ER2_MSK 0x00040000 +#define QE_SDMR_CEN_MASK 0x0000E000 +#define QE_SDMR_SBER_1 0x00000200 +#define QE_SDMR_SBER_2 0x00000200 +#define QE_SDMR_EB1_PR_MASK 0x000000C0 +#define QE_SDMR_ER1_PR 0x00000008 + +#define QE_SDMR_CEN_SHIFT 13 +#define QE_SDMR_EB1_PR_SHIFT 6 + +#define QE_SDTM_MSNUM_SHIFT 24 + +#define QE_SDEBCR_BA_MASK 0x01FFFFFF + +/* Communication Processor */ +#define QE_CP_CERCR_MEE 0x8000 /* Multi-user RAM ECC enable */ +#define QE_CP_CERCR_IEE 0x4000 /* Instruction RAM ECC enable */ +#define QE_CP_CERCR_CIR 0x0800 /* Common instruction RAM */ + +/* I-RAM */ +#define QE_IRAM_IADD_AIE 0x80000000 /* Auto Increment Enable */ +#define QE_IRAM_IADD_BADDR 0x00080000 /* Base Address */ +#define QE_IRAM_READY 0x80000000 /* Ready */ + +/* UPC */ +#define UPGCR_PROTOCOL 0x80000000 /* protocol ul2 or pl2 */ +#define UPGCR_TMS 0x40000000 /* Transmit master/slave mode */ +#define UPGCR_RMS 0x20000000 /* Receive master/slave mode */ +#define UPGCR_ADDR 0x10000000 /* Master MPHY Addr multiplexing */ +#define UPGCR_DIAG 0x01000000 /* Diagnostic mode */ + +/* UCC GUEMR register */ +#define UCC_GUEMR_MODE_MASK_RX 0x02 +#define UCC_GUEMR_MODE_FAST_RX 0x02 +#define UCC_GUEMR_MODE_SLOW_RX 0x00 +#define UCC_GUEMR_MODE_MASK_TX 0x01 +#define UCC_GUEMR_MODE_FAST_TX 0x01 +#define UCC_GUEMR_MODE_SLOW_TX 0x00 +#define UCC_GUEMR_MODE_MASK (UCC_GUEMR_MODE_MASK_RX | UCC_GUEMR_MODE_MASK_TX) +#define UCC_GUEMR_SET_RESERVED3 0x10 /* Bit 3 in the guemr is reserved but + must be set 1 */ + +/* structure representing UCC SLOW parameter RAM */ +struct ucc_slow_pram { + __be16 rbase; /* RX BD base address */ + __be16 tbase; /* TX BD base address */ + u8 rbmr; /* RX bus mode register (same as CPM's RFCR) */ + u8 tbmr; /* TX bus mode register (same as CPM's TFCR) */ + __be16 mrblr; /* Rx buffer length */ + __be32 rstate; /* Rx internal state */ + __be32 rptr; /* Rx internal data pointer */ + __be16 rbptr; /* rb BD Pointer */ + __be16 rcount; /* Rx internal byte count */ + __be32 rtemp; /* Rx temp */ + __be32 tstate; /* Tx internal state */ + __be32 tptr; /* Tx internal data pointer */ + __be16 tbptr; /* Tx BD pointer */ + __be16 tcount; /* Tx byte count */ + __be32 ttemp; /* Tx temp */ + __be32 rcrc; /* temp receive CRC */ + __be32 tcrc; /* temp transmit CRC */ +} __packed; + +/* General UCC SLOW Mode Register (GUMRH & GUMRL) */ +#define UCC_SLOW_GUMR_H_SAM_QMC 0x00000000 +#define UCC_SLOW_GUMR_H_SAM_SATM 0x00008000 +#define UCC_SLOW_GUMR_H_REVD 0x00002000 +#define UCC_SLOW_GUMR_H_TRX 0x00001000 +#define UCC_SLOW_GUMR_H_TTX 0x00000800 +#define UCC_SLOW_GUMR_H_CDP 0x00000400 +#define UCC_SLOW_GUMR_H_CTSP 0x00000200 +#define UCC_SLOW_GUMR_H_CDS 0x00000100 +#define UCC_SLOW_GUMR_H_CTSS 0x00000080 +#define UCC_SLOW_GUMR_H_TFL 0x00000040 +#define UCC_SLOW_GUMR_H_RFW 0x00000020 +#define UCC_SLOW_GUMR_H_TXSY 0x00000010 +#define UCC_SLOW_GUMR_H_4SYNC 0x00000004 +#define UCC_SLOW_GUMR_H_8SYNC 0x00000008 +#define UCC_SLOW_GUMR_H_16SYNC 0x0000000c +#define UCC_SLOW_GUMR_H_RTSM 0x00000002 +#define UCC_SLOW_GUMR_H_RSYN 0x00000001 + +#define UCC_SLOW_GUMR_L_TCI 0x10000000 +#define UCC_SLOW_GUMR_L_RINV 0x02000000 +#define UCC_SLOW_GUMR_L_TINV 0x01000000 +#define UCC_SLOW_GUMR_L_TEND 0x00040000 +#define UCC_SLOW_GUMR_L_TDCR_MASK 0x00030000 +#define UCC_SLOW_GUMR_L_TDCR_32 0x00030000 +#define UCC_SLOW_GUMR_L_TDCR_16 0x00020000 +#define UCC_SLOW_GUMR_L_TDCR_8 0x00010000 +#define UCC_SLOW_GUMR_L_TDCR_1 0x00000000 +#define UCC_SLOW_GUMR_L_RDCR_MASK 0x0000c000 +#define UCC_SLOW_GUMR_L_RDCR_32 0x0000c000 +#define UCC_SLOW_GUMR_L_RDCR_16 0x00008000 +#define UCC_SLOW_GUMR_L_RDCR_8 0x00004000 +#define UCC_SLOW_GUMR_L_RDCR_1 0x00000000 +#define UCC_SLOW_GUMR_L_RENC_NRZI 0x00000800 +#define UCC_SLOW_GUMR_L_RENC_NRZ 0x00000000 +#define UCC_SLOW_GUMR_L_TENC_NRZI 0x00000100 +#define UCC_SLOW_GUMR_L_TENC_NRZ 0x00000000 +#define UCC_SLOW_GUMR_L_DIAG_MASK 0x000000c0 +#define UCC_SLOW_GUMR_L_DIAG_LE 0x000000c0 +#define UCC_SLOW_GUMR_L_DIAG_ECHO 0x00000080 +#define UCC_SLOW_GUMR_L_DIAG_LOOP 0x00000040 +#define UCC_SLOW_GUMR_L_DIAG_NORM 0x00000000 +#define UCC_SLOW_GUMR_L_ENR 0x00000020 +#define UCC_SLOW_GUMR_L_ENT 0x00000010 +#define UCC_SLOW_GUMR_L_MODE_MASK 0x0000000F +#define UCC_SLOW_GUMR_L_MODE_BISYNC 0x00000008 +#define UCC_SLOW_GUMR_L_MODE_AHDLC 0x00000006 +#define UCC_SLOW_GUMR_L_MODE_UART 0x00000004 +#define UCC_SLOW_GUMR_L_MODE_QMC 0x00000002 + +/* General UCC FAST Mode Register */ +#define UCC_FAST_GUMR_TCI 0x20000000 +#define UCC_FAST_GUMR_TRX 0x10000000 +#define UCC_FAST_GUMR_TTX 0x08000000 +#define UCC_FAST_GUMR_CDP 0x04000000 +#define UCC_FAST_GUMR_CTSP 0x02000000 +#define UCC_FAST_GUMR_CDS 0x01000000 +#define UCC_FAST_GUMR_CTSS 0x00800000 +#define UCC_FAST_GUMR_TXSY 0x00020000 +#define UCC_FAST_GUMR_RSYN 0x00010000 +#define UCC_FAST_GUMR_RTSM 0x00002000 +#define UCC_FAST_GUMR_REVD 0x00000400 +#define UCC_FAST_GUMR_ENR 0x00000020 +#define UCC_FAST_GUMR_ENT 0x00000010 + +/* UART Slow UCC Event Register (UCCE) */ +#define UCC_UART_UCCE_AB 0x0200 +#define UCC_UART_UCCE_IDLE 0x0100 +#define UCC_UART_UCCE_GRA 0x0080 +#define UCC_UART_UCCE_BRKE 0x0040 +#define UCC_UART_UCCE_BRKS 0x0020 +#define UCC_UART_UCCE_CCR 0x0008 +#define UCC_UART_UCCE_BSY 0x0004 +#define UCC_UART_UCCE_TX 0x0002 +#define UCC_UART_UCCE_RX 0x0001 + +/* HDLC Slow UCC Event Register (UCCE) */ +#define UCC_HDLC_UCCE_GLR 0x1000 +#define UCC_HDLC_UCCE_GLT 0x0800 +#define UCC_HDLC_UCCE_IDLE 0x0100 +#define UCC_HDLC_UCCE_BRKE 0x0040 +#define UCC_HDLC_UCCE_BRKS 0x0020 +#define UCC_HDLC_UCCE_TXE 0x0010 +#define UCC_HDLC_UCCE_RXF 0x0008 +#define UCC_HDLC_UCCE_BSY 0x0004 +#define UCC_HDLC_UCCE_TXB 0x0002 +#define UCC_HDLC_UCCE_RXB 0x0001 + +/* BISYNC Slow UCC Event Register (UCCE) */ +#define UCC_BISYNC_UCCE_GRA 0x0080 +#define UCC_BISYNC_UCCE_TXE 0x0010 +#define UCC_BISYNC_UCCE_RCH 0x0008 +#define UCC_BISYNC_UCCE_BSY 0x0004 +#define UCC_BISYNC_UCCE_TXB 0x0002 +#define UCC_BISYNC_UCCE_RXB 0x0001 + +/* Transparent UCC Event Register (UCCE) */ +#define UCC_TRANS_UCCE_GRA 0x0080 +#define UCC_TRANS_UCCE_TXE 0x0010 +#define UCC_TRANS_UCCE_RXF 0x0008 +#define UCC_TRANS_UCCE_BSY 0x0004 +#define UCC_TRANS_UCCE_TXB 0x0002 +#define UCC_TRANS_UCCE_RXB 0x0001 + + +/* Gigabit Ethernet Fast UCC Event Register (UCCE) */ +#define UCC_GETH_UCCE_MPD 0x80000000 +#define UCC_GETH_UCCE_SCAR 0x40000000 +#define UCC_GETH_UCCE_GRA 0x20000000 +#define UCC_GETH_UCCE_CBPR 0x10000000 +#define UCC_GETH_UCCE_BSY 0x08000000 +#define UCC_GETH_UCCE_RXC 0x04000000 +#define UCC_GETH_UCCE_TXC 0x02000000 +#define UCC_GETH_UCCE_TXE 0x01000000 +#define UCC_GETH_UCCE_TXB7 0x00800000 +#define UCC_GETH_UCCE_TXB6 0x00400000 +#define UCC_GETH_UCCE_TXB5 0x00200000 +#define UCC_GETH_UCCE_TXB4 0x00100000 +#define UCC_GETH_UCCE_TXB3 0x00080000 +#define UCC_GETH_UCCE_TXB2 0x00040000 +#define UCC_GETH_UCCE_TXB1 0x00020000 +#define UCC_GETH_UCCE_TXB0 0x00010000 +#define UCC_GETH_UCCE_RXB7 0x00008000 +#define UCC_GETH_UCCE_RXB6 0x00004000 +#define UCC_GETH_UCCE_RXB5 0x00002000 +#define UCC_GETH_UCCE_RXB4 0x00001000 +#define UCC_GETH_UCCE_RXB3 0x00000800 +#define UCC_GETH_UCCE_RXB2 0x00000400 +#define UCC_GETH_UCCE_RXB1 0x00000200 +#define UCC_GETH_UCCE_RXB0 0x00000100 +#define UCC_GETH_UCCE_RXF7 0x00000080 +#define UCC_GETH_UCCE_RXF6 0x00000040 +#define UCC_GETH_UCCE_RXF5 0x00000020 +#define UCC_GETH_UCCE_RXF4 0x00000010 +#define UCC_GETH_UCCE_RXF3 0x00000008 +#define UCC_GETH_UCCE_RXF2 0x00000004 +#define UCC_GETH_UCCE_RXF1 0x00000002 +#define UCC_GETH_UCCE_RXF0 0x00000001 + +/* UCC Protocol Specific Mode Register (UPSMR), when used for UART */ +#define UCC_UART_UPSMR_FLC 0x8000 +#define UCC_UART_UPSMR_SL 0x4000 +#define UCC_UART_UPSMR_CL_MASK 0x3000 +#define UCC_UART_UPSMR_CL_8 0x3000 +#define UCC_UART_UPSMR_CL_7 0x2000 +#define UCC_UART_UPSMR_CL_6 0x1000 +#define UCC_UART_UPSMR_CL_5 0x0000 +#define UCC_UART_UPSMR_UM_MASK 0x0c00 +#define UCC_UART_UPSMR_UM_NORMAL 0x0000 +#define UCC_UART_UPSMR_UM_MAN_MULTI 0x0400 +#define UCC_UART_UPSMR_UM_AUTO_MULTI 0x0c00 +#define UCC_UART_UPSMR_FRZ 0x0200 +#define UCC_UART_UPSMR_RZS 0x0100 +#define UCC_UART_UPSMR_SYN 0x0080 +#define UCC_UART_UPSMR_DRT 0x0040 +#define UCC_UART_UPSMR_PEN 0x0010 +#define UCC_UART_UPSMR_RPM_MASK 0x000c +#define UCC_UART_UPSMR_RPM_ODD 0x0000 +#define UCC_UART_UPSMR_RPM_LOW 0x0004 +#define UCC_UART_UPSMR_RPM_EVEN 0x0008 +#define UCC_UART_UPSMR_RPM_HIGH 0x000C +#define UCC_UART_UPSMR_TPM_MASK 0x0003 +#define UCC_UART_UPSMR_TPM_ODD 0x0000 +#define UCC_UART_UPSMR_TPM_LOW 0x0001 +#define UCC_UART_UPSMR_TPM_EVEN 0x0002 +#define UCC_UART_UPSMR_TPM_HIGH 0x0003 + +/* UCC Protocol Specific Mode Register (UPSMR), when used for Ethernet */ +#define UCC_GETH_UPSMR_FTFE 0x80000000 +#define UCC_GETH_UPSMR_PTPE 0x40000000 +#define UCC_GETH_UPSMR_ECM 0x04000000 +#define UCC_GETH_UPSMR_HSE 0x02000000 +#define UCC_GETH_UPSMR_PRO 0x00400000 +#define UCC_GETH_UPSMR_CAP 0x00200000 +#define UCC_GETH_UPSMR_RSH 0x00100000 +#define UCC_GETH_UPSMR_RPM 0x00080000 +#define UCC_GETH_UPSMR_R10M 0x00040000 +#define UCC_GETH_UPSMR_RLPB 0x00020000 +#define UCC_GETH_UPSMR_TBIM 0x00010000 +#define UCC_GETH_UPSMR_RES1 0x00002000 +#define UCC_GETH_UPSMR_RMM 0x00001000 +#define UCC_GETH_UPSMR_CAM 0x00000400 +#define UCC_GETH_UPSMR_BRO 0x00000200 +#define UCC_GETH_UPSMR_SMM 0x00000080 +#define UCC_GETH_UPSMR_SGMM 0x00000020 + +/* UCC Transmit On Demand Register (UTODR) */ +#define UCC_SLOW_TOD 0x8000 +#define UCC_FAST_TOD 0x8000 + +/* UCC Bus Mode Register masks */ +/* Not to be confused with the Bundle Mode Register */ +#define UCC_BMR_GBL 0x20 +#define UCC_BMR_BO_BE 0x10 +#define UCC_BMR_CETM 0x04 +#define UCC_BMR_DTB 0x02 +#define UCC_BMR_BDB 0x01 + +/* Function code masks */ +#define FC_GBL 0x20 +#define FC_DTB_LCL 0x02 +#define UCC_FAST_FUNCTION_CODE_GBL 0x20 +#define UCC_FAST_FUNCTION_CODE_DTB_LCL 0x02 +#define UCC_FAST_FUNCTION_CODE_BDB_LCL 0x01 + +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_QE_H */ diff --git a/include/linux/fsl/qe_ic.h b/include/linux/fsl/qe_ic.h new file mode 100644 index 0000000..79f162c --- /dev/null +++ b/include/linux/fsl/qe_ic.h @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved. + * + * Authors: Shlomi Gridish <gridish@freescale.com> + * Li Yang <leoli@freescale.com> + * + * Description: + * QE IC external definitions and structure. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef _ASM_POWERPC_QE_IC_H +#define _ASM_POWERPC_QE_IC_H + +#include <linux/irq.h> + +struct device_node; +struct qe_ic; + +#define NUM_OF_QE_IC_GROUPS 6 + +/* Flags when we init the QE IC */ +#define QE_IC_SPREADMODE_GRP_W 0x00000001 +#define QE_IC_SPREADMODE_GRP_X 0x00000002 +#define QE_IC_SPREADMODE_GRP_Y 0x00000004 +#define QE_IC_SPREADMODE_GRP_Z 0x00000008 +#define QE_IC_SPREADMODE_GRP_RISCA 0x00000010 +#define QE_IC_SPREADMODE_GRP_RISCB 0x00000020 + +#define QE_IC_LOW_SIGNAL 0x00000100 +#define QE_IC_HIGH_SIGNAL 0x00000200 + +#define QE_IC_GRP_W_PRI0_DEST_SIGNAL_HIGH 0x00001000 +#define QE_IC_GRP_W_PRI1_DEST_SIGNAL_HIGH 0x00002000 +#define QE_IC_GRP_X_PRI0_DEST_SIGNAL_HIGH 0x00004000 +#define QE_IC_GRP_X_PRI1_DEST_SIGNAL_HIGH 0x00008000 +#define QE_IC_GRP_Y_PRI0_DEST_SIGNAL_HIGH 0x00010000 +#define QE_IC_GRP_Y_PRI1_DEST_SIGNAL_HIGH 0x00020000 +#define QE_IC_GRP_Z_PRI0_DEST_SIGNAL_HIGH 0x00040000 +#define QE_IC_GRP_Z_PRI1_DEST_SIGNAL_HIGH 0x00080000 +#define QE_IC_GRP_RISCA_PRI0_DEST_SIGNAL_HIGH 0x00100000 +#define QE_IC_GRP_RISCA_PRI1_DEST_SIGNAL_HIGH 0x00200000 +#define QE_IC_GRP_RISCB_PRI0_DEST_SIGNAL_HIGH 0x00400000 +#define QE_IC_GRP_RISCB_PRI1_DEST_SIGNAL_HIGH 0x00800000 +#define QE_IC_GRP_W_DEST_SIGNAL_SHIFT (12) + +/* QE interrupt sources groups */ +enum qe_ic_grp_id { + QE_IC_GRP_W = 0, /* QE interrupt controller group W */ + QE_IC_GRP_X, /* QE interrupt controller group X */ + QE_IC_GRP_Y, /* QE interrupt controller group Y */ + QE_IC_GRP_Z, /* QE interrupt controller group Z */ + QE_IC_GRP_RISCA, /* QE interrupt controller RISC group A */ + QE_IC_GRP_RISCB /* QE interrupt controller RISC group B */ +}; + +#ifdef CONFIG_QUICC_ENGINE +void qe_ic_init(struct device_node *node, unsigned int flags, + void (*low_handler)(unsigned int irq, struct irq_desc *desc), + void (*high_handler)(unsigned int irq, struct irq_desc *desc)); +unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic); +unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic); +#else +static inline void qe_ic_init(struct device_node *node, unsigned int flags, + void (*low_handler)(unsigned int irq, struct irq_desc *desc), + void (*high_handler)(unsigned int irq, struct irq_desc *desc)) +{} +static inline unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic) +{ return 0; } +static inline unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic) +{ return 0; } +#endif /* CONFIG_QUICC_ENGINE */ + +void qe_ic_set_highest_priority(unsigned int virq, int high); +int qe_ic_set_priority(unsigned int virq, unsigned int priority); +int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high); + +static inline void qe_ic_cascade_low_ipic(unsigned int irq, + struct irq_desc *desc) +{ + struct qe_ic *qe_ic = irq_desc_get_handler_data(desc); + unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic); + + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq); +} + +static inline void qe_ic_cascade_high_ipic(unsigned int irq, + struct irq_desc *desc) +{ + struct qe_ic *qe_ic = irq_desc_get_handler_data(desc); + unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic); + + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq); +} + +static inline void qe_ic_cascade_low_mpic(unsigned int irq, + struct irq_desc *desc) +{ + struct qe_ic *qe_ic = irq_desc_get_handler_data(desc); + unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic); + struct irq_chip *chip = irq_desc_get_chip(desc); + + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq); + + chip->irq_eoi(&desc->irq_data); +} + +static inline void qe_ic_cascade_high_mpic(unsigned int irq, + struct irq_desc *desc) +{ + struct qe_ic *qe_ic = irq_desc_get_handler_data(desc); + unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic); + struct irq_chip *chip = irq_desc_get_chip(desc); + + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq); + + chip->irq_eoi(&desc->irq_data); +} + +static inline void qe_ic_cascade_muxed_mpic(unsigned int irq, + struct irq_desc *desc) +{ + struct qe_ic *qe_ic = irq_desc_get_handler_data(desc); + unsigned int cascade_irq; + struct irq_chip *chip = irq_desc_get_chip(desc); + + cascade_irq = qe_ic_get_high_irq(qe_ic); + if (cascade_irq == NO_IRQ) + cascade_irq = qe_ic_get_low_irq(qe_ic); + + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq); + + chip->irq_eoi(&desc->irq_data); +} + +#endif /* _ASM_POWERPC_QE_IC_H */ diff --git a/include/linux/fsl/rheap.h b/include/linux/fsl/rheap.h new file mode 100644 index 0000000..88149da --- /dev/null +++ b/include/linux/fsl/rheap.h @@ -0,0 +1,93 @@ +/* + * include/asm-ppc/rheap.h + * + * Header file for the implementation of a remote heap. + * + * Author: Pantelis Antoniou <panto@intracom.gr> + * + * 2004 (c) INTRACOM S.A. Greece. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#ifndef __ASM_PPC_RHEAP_H__ +#define __ASM_PPC_RHEAP_H__ + +#include <linux/list.h> + +struct _rh_block { + struct list_head list; + unsigned long start; + int size; + const char *owner; +}; + +struct _rh_info { + unsigned int alignment; + int max_blocks; + int empty_slots; + struct _rh_block *block; + struct list_head empty_list; + struct list_head free_list; + struct list_head taken_list; + unsigned int flags; +}; + +#define RHIF_STATIC_INFO 0x1 +#define RHIF_STATIC_BLOCK 0x2 + +struct _rh_stats { + unsigned long start; + int size; + const char *owner; +}; + +#define RHGS_FREE 0 +#define RHGS_TAKEN 1 + +/* Create a remote heap dynamically */ +extern struct _rh_info *rh_create(unsigned int alignment); + +/* Destroy a remote heap, created by rh_create() */ +extern void rh_destroy(struct _rh_info *info); + +/* Initialize in place a remote info block */ +extern void rh_init(struct _rh_info *info, unsigned int alignment, + int max_blocks, struct _rh_block *block); + +/* Attach a free region to manage */ +extern int rh_attach_region(struct _rh_info *info, unsigned long start, + int size); + +/* Detach a free region */ +extern unsigned long rh_detach_region(struct _rh_info *info, + unsigned long start, int size); + +/* Allocate the given size from the remote heap (with alignment) */ +extern unsigned long rh_alloc_align(struct _rh_info *info, int size, + int alignment, const char *owner); + +/* Allocate the given size from the remote heap */ +extern unsigned long rh_alloc(struct _rh_info *info, int size, + const char *owner); + +/* Allocate the given size from the given address */ +extern unsigned long rh_alloc_fixed(struct _rh_info *info, unsigned long start, + int size, const char *owner); + +/* Free the allocated area */ +extern int rh_free(struct _rh_info *info, unsigned long start); + +/* Get stats for debugging purposes */ +extern int rh_get_stats(struct _rh_info *info, int what, int max_stats, + struct _rh_stats *stats); + +/* Simple dump of remote heap info */ +extern void rh_dump(struct _rh_info *info); + +/* Set owner of taken block */ +extern int rh_set_owner(struct _rh_info *info, unsigned long start, + const char *owner); + +#endif /* __ASM_PPC_RHEAP_H__ */ diff --git a/include/linux/fsl/ucc.h b/include/linux/fsl/ucc.h new file mode 100644 index 0000000..622e2fc --- /dev/null +++ b/include/linux/fsl/ucc.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2006, 2012 Freescale Semiconductor, Inc. All rights reserved. + * + * Authors: Shlomi Gridish <gridish@freescale.com> + * Li Yang <leoli@freescale.com> + * + * Description: + * Internal header file for UCC unit routines. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef __UCC_H__ +#define __UCC_H__ + +#include <linux/fsl/immap_qe.h> +#include <linux/fsl/qe.h> + +#define STATISTICS + +#define UCC_MAX_NUM 8 + +/* Slow or fast type for UCCs. +*/ +enum ucc_speed_type { + UCC_SPEED_TYPE_FAST = UCC_GUEMR_MODE_FAST_RX | UCC_GUEMR_MODE_FAST_TX, + UCC_SPEED_TYPE_SLOW = UCC_GUEMR_MODE_SLOW_RX | UCC_GUEMR_MODE_SLOW_TX +}; + +/* ucc_set_type + * Sets UCC to slow or fast mode. + * + * ucc_num - (In) number of UCC (0-7). + * speed - (In) slow or fast mode for UCC. + */ +int ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed); + +int ucc_set_qe_mux_mii_mng(unsigned int ucc_num); + +int ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock, + enum comm_dir mode); +int ucc_set_tdm_rxtx_clk(unsigned int tdm_num, enum qe_clock clock, + enum comm_dir mode); +int ucc_set_tdm_rxtx_sync(unsigned int tdm_num, enum qe_clock clock, + enum comm_dir mode); + +int ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask); + +/* QE MUX clock routing for UCC +*/ +static inline int ucc_set_qe_mux_grant(unsigned int ucc_num, int set) +{ + return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_GRANT); +} + +static inline int ucc_set_qe_mux_tsa(unsigned int ucc_num, int set) +{ + return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_TSA); +} + +static inline int ucc_set_qe_mux_bkpt(unsigned int ucc_num, int set) +{ + return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_BKPT); +} + +#endif /* __UCC_H__ */ diff --git a/include/linux/fsl/ucc_fast.h b/include/linux/fsl/ucc_fast.h new file mode 100644 index 0000000..ec24f28 --- /dev/null +++ b/include/linux/fsl/ucc_fast.h @@ -0,0 +1,251 @@ +/* + * Internal header file for UCC FAST unit routines. + * + * Copyright (C) 2006, 2012 Freescale Semiconductor, Inc. All rights reserved. + * + * Authors: Shlomi Gridish <gridish@freescale.com> + * Li Yang <leoli@freescale.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef __UCC_FAST_H__ +#define __UCC_FAST_H__ + +#include <linux/kernel.h> + +#include <linux/fsl/immap_qe.h> +#include <linux/fsl/qe.h> + +#include <linux/fsl/ucc.h> + +/* Receive BD's status */ +#define R_E 0x80000000 /* buffer empty */ +#define R_W 0x20000000 /* wrap bit */ +#define R_I 0x10000000 /* interrupt on reception */ +#define R_L 0x08000000 /* last */ +#define R_F 0x04000000 /* first */ +#define R_CM 0x02000000 /* CM */ + +/* transmit BD's status */ +#define T_R 0x80000000 /* ready bit */ +#define T_W 0x20000000 /* wrap bit */ +#define T_I 0x10000000 /* interrupt on completion */ +#define T_L 0x08000000 /* last */ +#define T_TC 0x04000000 /* crc */ +#define T_CM 0x02000000 /* CM */ + +/* Rx Data buffer must be 4 bytes aligned in most cases */ +#define UCC_FAST_RX_ALIGN 4 +#define UCC_FAST_MRBLR_ALIGNMENT 4 +#define UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT 8 + +/* Sizes */ +#define UCC_FAST_URFS_MIN_VAL 0x88 +#define UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR 8 + +/* ucc_fast_channel_protocol_mode - UCC FAST mode */ +enum ucc_fast_channel_protocol_mode { + UCC_FAST_PROTOCOL_MODE_HDLC = 0x00000000, + UCC_FAST_PROTOCOL_MODE_RESERVED01 = 0x00000001, + UCC_FAST_PROTOCOL_MODE_RESERVED_QMC = 0x00000002, + UCC_FAST_PROTOCOL_MODE_RESERVED02 = 0x00000003, + UCC_FAST_PROTOCOL_MODE_RESERVED_UART = 0x00000004, + UCC_FAST_PROTOCOL_MODE_RESERVED03 = 0x00000005, + UCC_FAST_PROTOCOL_MODE_RESERVED_EX_MAC_1 = 0x00000006, + UCC_FAST_PROTOCOL_MODE_RESERVED_EX_MAC_2 = 0x00000007, + UCC_FAST_PROTOCOL_MODE_RESERVED_BISYNC = 0x00000008, + UCC_FAST_PROTOCOL_MODE_RESERVED04 = 0x00000009, + UCC_FAST_PROTOCOL_MODE_ATM = 0x0000000A, + UCC_FAST_PROTOCOL_MODE_RESERVED05 = 0x0000000B, + UCC_FAST_PROTOCOL_MODE_ETHERNET = 0x0000000C, + UCC_FAST_PROTOCOL_MODE_RESERVED06 = 0x0000000D, + UCC_FAST_PROTOCOL_MODE_POS = 0x0000000E, + UCC_FAST_PROTOCOL_MODE_RESERVED07 = 0x0000000F +}; + +/* ucc_fast_transparent_txrx - UCC Fast Transparent TX & RX */ +enum ucc_fast_transparent_txrx { + UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_NORMAL = 0x00000000, + UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_TRANSPARENT = 0x18000000 +}; + +/* UCC fast diagnostic mode */ +enum ucc_fast_diag_mode { + UCC_FAST_DIAGNOSTIC_NORMAL = 0x0, + UCC_FAST_DIAGNOSTIC_LOCAL_LOOP_BACK = 0x40000000, + UCC_FAST_DIAGNOSTIC_AUTO_ECHO = 0x80000000, + UCC_FAST_DIAGNOSTIC_LOOP_BACK_AND_ECHO = 0xC0000000 +}; + +/* UCC fast Sync length (transparent mode only) */ +enum ucc_fast_sync_len { + UCC_FAST_SYNC_LEN_NOT_USED = 0x0, + UCC_FAST_SYNC_LEN_AUTOMATIC = 0x00004000, + UCC_FAST_SYNC_LEN_8_BIT = 0x00008000, + UCC_FAST_SYNC_LEN_16_BIT = 0x0000C000 +}; + +/* UCC fast RTS mode */ +enum ucc_fast_ready_to_send { + UCC_FAST_SEND_IDLES_BETWEEN_FRAMES = 0x00000000, + UCC_FAST_SEND_FLAGS_BETWEEN_FRAMES = 0x00002000 +}; + +/* UCC fast receiver decoding mode */ +enum ucc_fast_rx_decoding_method { + UCC_FAST_RX_ENCODING_NRZ = 0x00000000, + UCC_FAST_RX_ENCODING_NRZI = 0x00000800, + UCC_FAST_RX_ENCODING_RESERVED0 = 0x00001000, + UCC_FAST_RX_ENCODING_RESERVED1 = 0x00001800 +}; + +/* UCC fast transmitter encoding mode */ +enum ucc_fast_tx_encoding_method { + UCC_FAST_TX_ENCODING_NRZ = 0x00000000, + UCC_FAST_TX_ENCODING_NRZI = 0x00000100, + UCC_FAST_TX_ENCODING_RESERVED0 = 0x00000200, + UCC_FAST_TX_ENCODING_RESERVED1 = 0x00000300 +}; + +/* UCC fast CRC length */ +enum ucc_fast_transparent_tcrc { + UCC_FAST_16_BIT_CRC = 0x00000000, + UCC_FAST_CRC_RESERVED0 = 0x00000040, + UCC_FAST_32_BIT_CRC = 0x00000080, + UCC_FAST_CRC_RESERVED1 = 0x000000C0 +}; + +/* Fast UCC initialization structure */ +struct ucc_fast_info { + int ucc_num; + int tdm_num; + enum qe_clock rx_clock; + enum qe_clock tx_clock; + enum qe_clock rx_sync; + enum qe_clock tx_sync; + resource_size_t regs; + int irq; + u32 uccm_mask; + int bd_mem_part; + int brkpt_support; + int grant_support; + int tsa; + int cdp; + int cds; + int ctsp; + int ctss; + int tci; + int txsy; + int rtsm; + int revd; + int rsyn; + u16 max_rx_buf_length; + u16 urfs; + u16 urfet; + u16 urfset; + u16 utfs; + u16 utfet; + u16 utftt; + u16 ufpt; + enum ucc_fast_channel_protocol_mode mode; + enum ucc_fast_transparent_txrx ttx_trx; + enum ucc_fast_tx_encoding_method tenc; + enum ucc_fast_rx_decoding_method renc; + enum ucc_fast_transparent_tcrc tcrc; + enum ucc_fast_sync_len synl; +}; + +struct ucc_fast_private { + struct ucc_fast_info *uf_info; + struct ucc_fast __iomem *uf_regs; /* a pointer to the UCC regs. */ + u32 __iomem *p_ucce; /* a pointer to the event register in memory. */ + u32 __iomem *p_uccm; /* a pointer to the mask register in memory. */ +#ifdef CONFIG_UGETH_TX_ON_DEMAND + u16 __iomem *p_utodr; /* pointer to the transmit on demand register */ +#endif + int enabled_tx; /* Whether channel is enabled for Tx (ENT) */ + int enabled_rx; /* Whether channel is enabled for Rx (ENR) */ + int stopped_tx; /* Whether channel has been stopped for Tx + (STOP_TX, etc.) */ + int stopped_rx; /* Whether channel has been stopped for Rx */ + u32 ucc_fast_tx_virtual_fifo_base_offset;/* pointer to base of Tx + virtual fifo */ + u32 ucc_fast_rx_virtual_fifo_base_offset;/* pointer to base of Rx + virtual fifo */ +#ifdef STATISTICS + u32 tx_frames; /* Transmitted frames counter. */ + u32 rx_frames; /* Received frames counter (only frames + passed to application). */ + u32 tx_discarded; /* Discarded tx frames counter (frames that + were discarded by the driver due to errors). + */ + u32 rx_discarded; /* Discarded rx frames counter (frames that + were discarded by the driver due to errors). + */ +#endif /* STATISTICS */ + u16 mrblr; /* maximum receive buffer length */ +}; + +/* ucc_fast_init + * Initializes Fast UCC according to user provided parameters. + * + * uf_info - (In) pointer to the fast UCC info structure. + * uccf_ret - (Out) pointer to the fast UCC structure. + */ +int ucc_fast_init(struct ucc_fast_info *uf_info, + struct ucc_fast_private **uccf_ret); + +/* ucc_fast_free + * Frees all resources for fast UCC. + * + * uccf - (In) pointer to the fast UCC structure. + */ +void ucc_fast_free(struct ucc_fast_private *uccf); + +/* ucc_fast_enable + * Enables a fast UCC port. + * This routine enables Tx and/or Rx through the General UCC Mode Register. + * + * uccf - (In) pointer to the fast UCC structure. + * mode - (In) TX, RX, or both. + */ +void ucc_fast_enable(struct ucc_fast_private *uccf, enum comm_dir mode); + +/* ucc_fast_disable + * Disables a fast UCC port. + * This routine disables Tx and/or Rx through the General UCC Mode Register. + * + * uccf - (In) pointer to the fast UCC structure. + * mode - (In) TX, RX, or both. + */ +void ucc_fast_disable(struct ucc_fast_private *uccf, enum comm_dir mode); + +/* ucc_fast_irq + * Handles interrupts on fast UCC. + * Called from the general interrupt routine to handle interrupts on fast UCC. + * + * uccf - (In) pointer to the fast UCC structure. + */ +void ucc_fast_irq(struct ucc_fast_private *uccf); + +/* ucc_fast_transmit_on_demand + * Immediately forces a poll of the transmitter for data to be sent. + * Typically, the hardware performs a periodic poll for data that the + * transmit routine has set up to be transmitted. In cases where + * this polling cycle is not soon enough, this optional routine can + * be invoked to force a poll right away, instead. Proper use for + * each transmission for which this functionality is desired is to + * call the transmit routine and then this routine right after. + * + * uccf - (In) pointer to the fast UCC structure. + */ +void ucc_fast_transmit_on_demand(struct ucc_fast_private *uccf); + +u32 ucc_fast_get_qe_cr_subblock(int uccf_num); + +void ucc_fast_dump_regs(struct ucc_fast_private *uccf); + +#endif /* __UCC_FAST_H__ */ diff --git a/include/linux/fsl/ucc_slow.h b/include/linux/fsl/ucc_slow.h new file mode 100644 index 0000000..56c0318 --- /dev/null +++ b/include/linux/fsl/ucc_slow.h @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved. + * + * Authors: Shlomi Gridish <gridish@freescale.com> + * Li Yang <leoli@freescale.com> + * + * Description: + * Internal header file for UCC SLOW unit routines. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef __UCC_SLOW_H__ +#define __UCC_SLOW_H__ + +#include <linux/kernel.h> + +#include <linux/fsl/immap_qe.h> +#include <linux/fsl/qe.h> + +#include <linux/fsl/ucc.h> + +/* transmit BD's status */ +#define T_R 0x80000000 /* ready bit */ +#define T_PAD 0x40000000 /* add pads to short frames */ +#define T_W 0x20000000 /* wrap bit */ +#define T_I 0x10000000 /* interrupt on completion */ +#define T_L 0x08000000 /* last */ + +#define T_A 0x04000000 /* Address - the data transmitted as address + chars */ +#define T_TC 0x04000000 /* transmit CRC */ +#define T_CM 0x02000000 /* continuous mode */ +#define T_DEF 0x02000000 /* collision on previous attempt to transmit */ +#define T_P 0x01000000 /* Preamble - send Preamble sequence before + data */ +#define T_HB 0x01000000 /* heartbeat */ +#define T_NS 0x00800000 /* No Stop */ +#define T_LC 0x00800000 /* late collision */ +#define T_RL 0x00400000 /* retransmission limit */ +#define T_UN 0x00020000 /* underrun */ +#define T_CT 0x00010000 /* CTS lost */ +#define T_CSL 0x00010000 /* carrier sense lost */ +#define T_RC 0x003c0000 /* retry count */ + +/* Receive BD's status */ +#define R_E 0x80000000 /* buffer empty */ +#define R_W 0x20000000 /* wrap bit */ +#define R_I 0x10000000 /* interrupt on reception */ +#define R_L 0x08000000 /* last */ +#define R_C 0x08000000 /* the last byte in this buffer is a cntl + char */ +#define R_F 0x04000000 /* first */ +#define R_A 0x04000000 /* the first byte in this buffer is address + byte */ +#define R_CM 0x02000000 /* continuous mode */ +#define R_ID 0x01000000 /* buffer close on reception of idles */ +#define R_M 0x01000000 /* Frame received because of promiscuous + mode */ +#define R_AM 0x00800000 /* Address match */ +#define R_DE 0x00800000 /* Address match */ +#define R_LG 0x00200000 /* Break received */ +#define R_BR 0x00200000 /* Frame length violation */ +#define R_NO 0x00100000 /* Rx Non Octet Aligned Packet */ +#define R_FR 0x00100000 /* Framing Error (no stop bit) character + received */ +#define R_PR 0x00080000 /* Parity Error character received */ +#define R_AB 0x00080000 /* Frame Aborted */ +#define R_SH 0x00080000 /* frame is too short */ +#define R_CR 0x00040000 /* CRC Error */ +#define R_OV 0x00020000 /* Overrun */ +#define R_CD 0x00010000 /* CD lost */ +#define R_CL 0x00010000 /* this frame is closed because of a + collision */ + +/* Rx Data buffer must be 4 bytes aligned in most cases.*/ +#define UCC_SLOW_RX_ALIGN 4 +#define UCC_SLOW_MRBLR_ALIGNMENT 4 +#define UCC_SLOW_PRAM_SIZE 0x100 +#define ALIGNMENT_OF_UCC_SLOW_PRAM 64 + +/* UCC Slow Channel Protocol Mode */ +enum ucc_slow_channel_protocol_mode { + UCC_SLOW_CHANNEL_PROTOCOL_MODE_QMC = 0x00000002, + UCC_SLOW_CHANNEL_PROTOCOL_MODE_UART = 0x00000004, + UCC_SLOW_CHANNEL_PROTOCOL_MODE_BISYNC = 0x00000008, +}; + +/* UCC Slow Transparent Transmit CRC (TCRC) */ +enum ucc_slow_transparent_tcrc { + /* 16-bit CCITT CRC (HDLC). (X16 + X12 + X5 + 1) */ + UCC_SLOW_TRANSPARENT_TCRC_CCITT_CRC16 = 0x00000000, + /* CRC16 (BISYNC). (X16 + X15 + X2 + 1) */ + UCC_SLOW_TRANSPARENT_TCRC_CRC16 = 0x00004000, + /* 32-bit CCITT CRC (Ethernet and HDLC) */ + UCC_SLOW_TRANSPARENT_TCRC_CCITT_CRC32 = 0x00008000, +}; + +/* UCC Slow oversampling rate for transmitter (TDCR) */ +enum ucc_slow_tx_oversampling_rate { + /* 1x clock mode */ + UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_1 = 0x00000000, + /* 8x clock mode */ + UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_8 = 0x00010000, + /* 16x clock mode */ + UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_16 = 0x00020000, + /* 32x clock mode */ + UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_32 = 0x00030000, +}; + +/* UCC Slow Oversampling rate for receiver (RDCR) +*/ +enum ucc_slow_rx_oversampling_rate { + /* 1x clock mode */ + UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_1 = 0x00000000, + /* 8x clock mode */ + UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_8 = 0x00004000, + /* 16x clock mode */ + UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_16 = 0x00008000, + /* 32x clock mode */ + UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_32 = 0x0000c000, +}; + +/* UCC Slow Transmitter encoding method (TENC) +*/ +enum ucc_slow_tx_encoding_method { + UCC_SLOW_TRANSMITTER_ENCODING_METHOD_TENC_NRZ = 0x00000000, + UCC_SLOW_TRANSMITTER_ENCODING_METHOD_TENC_NRZI = 0x00000100 +}; + +/* UCC Slow Receiver decoding method (RENC) +*/ +enum ucc_slow_rx_decoding_method { + UCC_SLOW_RECEIVER_DECODING_METHOD_RENC_NRZ = 0x00000000, + UCC_SLOW_RECEIVER_DECODING_METHOD_RENC_NRZI = 0x00000800 +}; + +/* UCC Slow Diagnostic mode (DIAG) +*/ +enum ucc_slow_diag_mode { + UCC_SLOW_DIAG_MODE_NORMAL = 0x00000000, + UCC_SLOW_DIAG_MODE_LOOPBACK = 0x00000040, + UCC_SLOW_DIAG_MODE_ECHO = 0x00000080, + UCC_SLOW_DIAG_MODE_LOOPBACK_ECHO = 0x000000c0 +}; + +struct ucc_slow_info { + int ucc_num; + int protocol; /* QE_CR_PROTOCOL_xxx */ + enum qe_clock rx_clock; + enum qe_clock tx_clock; + phys_addr_t regs; + int irq; + u16 uccm_mask; + int data_mem_part; + int init_tx; + int init_rx; + u32 tx_bd_ring_len; + u32 rx_bd_ring_len; + int rx_interrupts; + int brkpt_support; + int grant_support; + int tsa; + int cdp; + int cds; + int ctsp; + int ctss; + int rinv; + int tinv; + int rtsm; + int rfw; + int tci; + int tend; + int tfl; + int txsy; + u16 max_rx_buf_length; + enum ucc_slow_transparent_tcrc tcrc; + enum ucc_slow_channel_protocol_mode mode; + enum ucc_slow_diag_mode diag; + enum ucc_slow_tx_oversampling_rate tdcr; + enum ucc_slow_rx_oversampling_rate rdcr; + enum ucc_slow_tx_encoding_method tenc; + enum ucc_slow_rx_decoding_method renc; +}; + +struct ucc_slow_private { + struct ucc_slow_info *us_info; + struct ucc_slow __iomem *us_regs; /* Ptr to memory map of UCC regs */ + struct ucc_slow_pram *us_pram; /* a pointer to the parameter RAM */ + u32 us_pram_offset; + int enabled_tx; /* Whether channel is enabled for Tx (ENT) */ + int enabled_rx; /* Whether channel is enabled for Rx (ENR) */ + int stopped_tx; /* Whether channel has been stopped for Tx + (STOP_TX, etc.) */ + int stopped_rx; /* Whether channel has been stopped for Rx */ + struct list_head confQ; /* frames passed to chip waiting for tx */ + u32 first_tx_bd_mask; /* mask is used in Tx routine to save status + and length for first BD in a frame */ + u32 tx_base_offset; /* first BD in Tx BD table offset (In MURAM) */ + u32 rx_base_offset; /* first BD in Rx BD table offset (In MURAM) */ + struct qe_bd *confBd; /* next BD for confirm after Tx */ + struct qe_bd *tx_bd; /* next BD for new Tx request */ + struct qe_bd *rx_bd; /* next BD to collect after Rx */ + void *p_rx_frame; /* accumulating receive frame */ + u16 *p_ucce; /* a pointer to the event register in memory. + */ + u16 *p_uccm; /* a pointer to the mask register in memory */ + u16 saved_uccm; /* a saved mask for the RX Interrupt bits */ +#ifdef STATISTICS + u32 tx_frames; /* Transmitted frames counters */ + u32 rx_frames; /* Received frames counters (only frames + passed to application) */ + u32 rx_discarded; /* Discarded frames counters (frames that + were discarded by the driver due to + errors) */ +#endif /* STATISTICS */ +}; + +/* ucc_slow_init + * Initializes Slow UCC according to provided parameters. + * + * us_info - (In) pointer to the slow UCC info structure. + * uccs_ret - (Out) pointer to the slow UCC structure. + */ +int ucc_slow_init(struct ucc_slow_info *us_info, + struct ucc_slow_private **uccs_ret); + +/* ucc_slow_free + * Frees all resources for slow UCC. + * + * uccs - (In) pointer to the slow UCC structure. + */ +void ucc_slow_free(struct ucc_slow_private *uccs); + +/* ucc_slow_enable + * Enables a fast UCC port. + * This routine enables Tx and/or Rx through the General UCC Mode Register. + * + * uccs - (In) pointer to the slow UCC structure. + * mode - (In) TX, RX, or both. + */ +void ucc_slow_enable(struct ucc_slow_private *uccs, enum comm_dir mode); + +/* ucc_slow_disable + * Disables a fast UCC port. + * This routine disables Tx and/or Rx through the General UCC Mode Register. + * + * uccs - (In) pointer to the slow UCC structure. + * mode - (In) TX, RX, or both. + */ +void ucc_slow_disable(struct ucc_slow_private *uccs, enum comm_dir mode); + +/* ucc_slow_poll_transmitter_now + * Immediately forces a poll of the transmitter for data to be sent. + * Typically, the hardware performs a periodic poll for data that the + * transmit routine has set up to be transmitted. In cases where + * this polling cycle is not soon enough, this optional routine can + * be invoked to force a poll right away, instead. Proper use for + * each transmission for which this functionality is desired is to + * call the transmit routine and then this routine right after. + * + * uccs - (In) pointer to the slow UCC structure. + */ +void ucc_slow_poll_transmitter_now(struct ucc_slow_private *uccs); + +/* ucc_slow_graceful_stop_tx + * Smoothly stops transmission on a specified slow UCC. + * + * uccs - (In) pointer to the slow UCC structure. + */ +void ucc_slow_graceful_stop_tx(struct ucc_slow_private *uccs); + +/* ucc_slow_stop_tx + * Stops transmission on a specified slow UCC. + * + * uccs - (In) pointer to the slow UCC structure. + */ +void ucc_slow_stop_tx(struct ucc_slow_private *uccs); + +/* ucc_slow_restart_tx + * Restarts transmitting on a specified slow UCC. + * + * uccs - (In) pointer to the slow UCC structure. + */ +void ucc_slow_restart_tx(struct ucc_slow_private *uccs); + +u32 ucc_slow_get_qe_cr_subblock(int uccs_num); + +#endif /* __UCC_SLOW_H__ */ diff --git a/include/linux/fsl_bman.h b/include/linux/fsl_bman.h new file mode 100644 index 0000000..265d806 --- /dev/null +++ b/include/linux/fsl_bman.h @@ -0,0 +1,519 @@ +/* Copyright 2008-2012 Freescale Semiconductor, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FSL_BMAN_H +#define FSL_BMAN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Last updated for v00.79 of the BG */ + +/* Portal processing (interrupt) sources */ +#define BM_PIRQ_RCRI 0x00000002 /* RCR Ring (below threshold) */ +#define BM_PIRQ_BSCN 0x00000001 /* Buffer depletion State Change */ + +/* This wrapper represents a bit-array for the depletion state of the 64 Bman + * buffer pools. */ +struct bman_depletion { + u32 __state[2]; +}; +#define BMAN_DEPLETION_EMPTY { { 0x00000000, 0x00000000 } } +#define BMAN_DEPLETION_FULL { { 0xffffffff, 0xffffffff } } +#define __bmdep_word(x) ((x) >> 5) +#define __bmdep_shift(x) ((x) & 0x1f) +#define __bmdep_bit(x) (0x80000000 >> __bmdep_shift(x)) +static inline void bman_depletion_init(struct bman_depletion *c) +{ + c->__state[0] = c->__state[1] = 0; +} +static inline void bman_depletion_fill(struct bman_depletion *c) +{ + c->__state[0] = c->__state[1] = ~0; +} +static inline int bman_depletion_get(const struct bman_depletion *c, u8 bpid) +{ + return c->__state[__bmdep_word(bpid)] & __bmdep_bit(bpid); +} +static inline void bman_depletion_set(struct bman_depletion *c, u8 bpid) +{ + c->__state[__bmdep_word(bpid)] |= __bmdep_bit(bpid); +} +static inline void bman_depletion_unset(struct bman_depletion *c, u8 bpid) +{ + c->__state[__bmdep_word(bpid)] &= ~__bmdep_bit(bpid); +} + +/* ------------------------------------------------------- */ +/* --- Bman data structures (and associated constants) --- */ + +/* Represents s/w corenet portal mapped data structures */ +struct bm_rcr_entry; /* RCR (Release Command Ring) entries */ +struct bm_mc_command; /* MC (Management Command) command */ +struct bm_mc_result; /* MC result */ + +/* Code-reduction, define a wrapper for 48-bit buffers. In cases where a buffer + * pool id specific to this buffer is needed (BM_RCR_VERB_CMD_BPID_MULTI, + * BM_MCC_VERB_ACQUIRE), the 'bpid' field is used. */ +struct bm_buffer { + union { + struct { + u8 __reserved1; + u8 bpid; + u16 hi; /* High 16-bits of 48-bit address */ + u32 lo; /* Low 32-bits of 48-bit address */ + }; + struct { + u64 __notaddress:16; + u64 addr:48; + }; + }; +} __aligned(8); +static inline u64 bm_buffer_get64(const struct bm_buffer *buf) +{ + return buf->addr; +} +static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf) +{ + return (dma_addr_t)buf->addr; +} +/* Macro, so we compile better if 'v' isn't always 64-bit */ +#define bm_buffer_set64(buf, v) \ + do { \ + struct bm_buffer *__buf931 = (buf); \ + __buf931->hi = upper_32_bits(v); \ + __buf931->lo = lower_32_bits(v); \ + } while (0) + +/* See 1.5.3.5.4: "Release Command" */ +struct bm_rcr_entry { + union { + struct { + u8 __dont_write_directly__verb; + u8 bpid; /* used with BM_RCR_VERB_CMD_BPID_SINGLE */ + u8 __reserved1[62]; + }; + struct bm_buffer bufs[8]; + }; +} __packed; +#define BM_RCR_VERB_VBIT 0x80 +#define BM_RCR_VERB_CMD_MASK 0x70 /* one of two values; */ +#define BM_RCR_VERB_CMD_BPID_SINGLE 0x20 +#define BM_RCR_VERB_CMD_BPID_MULTI 0x30 +#define BM_RCR_VERB_BUFCOUNT_MASK 0x0f /* values 1..8 */ + +/* See 1.5.3.1: "Acquire Command" */ +/* See 1.5.3.2: "Query Command" */ +struct bm_mcc_acquire { + u8 bpid; + u8 __reserved1[62]; +} __packed; +struct bm_mcc_query { + u8 __reserved2[63]; +} __packed; +struct bm_mc_command { + u8 __dont_write_directly__verb; + union { + struct bm_mcc_acquire acquire; + struct bm_mcc_query query; + }; +} __packed; +#define BM_MCC_VERB_VBIT 0x80 +#define BM_MCC_VERB_CMD_MASK 0x70 /* where the verb contains; */ +#define BM_MCC_VERB_CMD_ACQUIRE 0x10 +#define BM_MCC_VERB_CMD_QUERY 0x40 +#define BM_MCC_VERB_ACQUIRE_BUFCOUNT 0x0f /* values 1..8 go here */ + +/* See 1.5.3.3: "Acquire Response" */ +/* See 1.5.3.4: "Query Response" */ +struct bm_pool_state { + u8 __reserved1[32]; + /* "availability state" and "depletion state" */ + struct { + u8 __reserved1[8]; + /* Access using bman_depletion_***() */ + struct bman_depletion state; + } as, ds; +}; +struct bm_mc_result { + union { + struct { + u8 verb; + u8 __reserved1[63]; + }; + union { + struct { + u8 __reserved1; + u8 bpid; + u8 __reserved2[62]; + }; + struct bm_buffer bufs[8]; + } acquire; + struct bm_pool_state query; + }; +} __packed; +#define BM_MCR_VERB_VBIT 0x80 +#define BM_MCR_VERB_CMD_MASK BM_MCC_VERB_CMD_MASK +#define BM_MCR_VERB_CMD_ACQUIRE BM_MCC_VERB_CMD_ACQUIRE +#define BM_MCR_VERB_CMD_QUERY BM_MCC_VERB_CMD_QUERY +#define BM_MCR_VERB_CMD_ERR_INVALID 0x60 +#define BM_MCR_VERB_CMD_ERR_ECC 0x70 +#define BM_MCR_VERB_ACQUIRE_BUFCOUNT BM_MCC_VERB_ACQUIRE_BUFCOUNT /* 0..8 */ +/* Determine the "availability state" of pool 'p' from a query result 'r' */ +#define BM_MCR_QUERY_AVAILABILITY(r, p) \ + bman_depletion_get(&r->query.as.state, p) +/* Determine the "depletion state" of pool 'p' from a query result 'r' */ +#define BM_MCR_QUERY_DEPLETION(r, p) \ + bman_depletion_get(&r->query.ds.state, p) + +/*******************************************************************/ +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */ +/*******************************************************************/ + + /* Portal and Buffer Pools */ + /* ----------------------- */ +/* Represents a managed portal */ +struct bman_portal; + +/* This object type represents Bman buffer pools. */ +struct bman_pool; + +struct bman_portal_config { + /* This is used for any "core-affine" portals, ie. default portals + * associated to the corresponding cpu. -1 implies that there is no core + * affinity configured. */ + int cpu; + /* portal interrupt line */ + int irq; + /* the unique index of this portal */ + u32 index; + /* Is this portal shared? (If so, it has coarser locking and demuxes + * processing on behalf of other CPUs.) */ + int is_shared; + /* These are the buffer pool IDs that may be used via this portal. */ + struct bman_depletion mask; +}; + +/* This callback type is used when handling pool depletion entry/exit. The + * 'cb_ctx' value is the opaque value associated with the pool object in + * bman_new_pool(). 'depleted' is non-zero on depletion-entry, and zero on + * depletion-exit. */ +typedef void (*bman_cb_depletion)(struct bman_portal *bm, + struct bman_pool *pool, void *cb_ctx, int depleted); + +/* This struct specifies parameters for a bman_pool object. */ +struct bman_pool_params { + /* index of the buffer pool to encapsulate (0-63), ignored if + * BMAN_POOL_FLAG_DYNAMIC_BPID is set. */ + u32 bpid; + /* bit-mask of BMAN_POOL_FLAG_*** options */ + u32 flags; + /* depletion-entry/exit callback, if BMAN_POOL_FLAG_DEPLETION is set */ + bman_cb_depletion cb; + /* opaque user value passed as a parameter to 'cb' */ + void *cb_ctx; + /* depletion-entry/exit thresholds, if BMAN_POOL_FLAG_THRESH is set. NB: + * this is only allowed if BMAN_POOL_FLAG_DYNAMIC_BPID is used *and* + * when run in the control plane (which controls Bman CCSR). This array + * matches the definition of bm_pool_set(). */ + u32 thresholds[4]; +}; + +/* Flags to bman_new_pool() */ +#define BMAN_POOL_FLAG_NO_RELEASE 0x00000001 /* can't release to pool */ +#define BMAN_POOL_FLAG_ONLY_RELEASE 0x00000002 /* can only release to pool */ +#define BMAN_POOL_FLAG_DEPLETION 0x00000004 /* track depletion entry/exit */ +#define BMAN_POOL_FLAG_DYNAMIC_BPID 0x00000008 /* (de)allocate bpid */ +#define BMAN_POOL_FLAG_THRESH 0x00000010 /* set depletion thresholds */ +#define BMAN_POOL_FLAG_STOCKPILE 0x00000020 /* stockpile to reduce hw ops */ + +/* Flags to bman_release() */ +#ifdef CONFIG_FSL_DPA_CAN_WAIT +#define BMAN_RELEASE_FLAG_WAIT 0x00000001 /* wait if RCR is full */ +#define BMAN_RELEASE_FLAG_WAIT_INT 0x00000002 /* if we wait, interruptible? */ +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC +#define BMAN_RELEASE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */ +#endif +#endif +#define BMAN_RELEASE_FLAG_NOW 0x00000008 /* issue immediate release */ + +/* Flags to bman_acquire() */ +#define BMAN_ACQUIRE_FLAG_STOCKPILE 0x00000001 /* no hw op, stockpile only */ + + /* Portal Management */ + /* ----------------- */ +/** + * bman_get_portal_config - get portal configuration settings + * + * This returns a read-only view of the current cpu's affine portal settings. + */ +const struct bman_portal_config *bman_get_portal_config(void); + +/** + * bman_irqsource_get - return the portal work that is interrupt-driven + * + * Returns a bitmask of BM_PIRQ_**I processing sources that are currently + * enabled for interrupt handling on the current cpu's affine portal. These + * sources will trigger the portal interrupt and the interrupt handler (or a + * tasklet/bottom-half it defers to) will perform the corresponding processing + * work. The bman_poll_***() functions will only process sources that are not in + * this bitmask. If the current CPU is sharing a portal hosted on another CPU, + * this always returns zero. + */ +u32 bman_irqsource_get(void); + +/** + * bman_irqsource_add - add processing sources to be interrupt-driven + * @bits: bitmask of BM_PIRQ_**I processing sources + * + * Adds processing sources that should be interrupt-driven (rather than + * processed via bman_poll_***() functions). Returns zero for success, or + * -EINVAL if the current CPU is sharing a portal hosted on another CPU. */ +int bman_irqsource_add(u32 bits); + +/** + * bman_irqsource_remove - remove processing sources from being interrupt-driven + * @bits: bitmask of BM_PIRQ_**I processing sources + * + * Removes processing sources from being interrupt-driven, so that they will + * instead be processed via bman_poll_***() functions. Returns zero for success, + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU. */ +int bman_irqsource_remove(u32 bits); + +/** + * bman_affine_cpus - return a mask of cpus that have affine portals + */ +const cpumask_t *bman_affine_cpus(void); + +/** + * bman_poll_slow - process anything that isn't interrupt-driven. + * + * This function does any portal processing that isn't interrupt-driven. If the + * current CPU is sharing a portal hosted on another CPU, this function will + * return -EINVAL, otherwise the return value is a bitmask of BM_PIRQ_* sources + * indicating what interrupt sources were actually processed by the call. + * + * NB, unlike the legacy wrapper bman_poll(), this function will + * deterministically check for the presence of portal processing work and do it, + * which implies some latency even if there's nothing to do. The bman_poll() + * wrapper on the other hand (like the qman_poll() wrapper) attenuates this by + * checking for (and doing) portal processing infrequently. Ie. such that + * qman_poll() and bman_poll() can be called from core-processing loops. Use + * bman_poll_slow() when you yourself are deciding when to incur the overhead of + * processing. + */ +u32 bman_poll_slow(void); + +/** + * bman_poll - process anything that isn't interrupt-driven. + * + * Dispatcher logic on a cpu can use this to trigger any maintenance of the + * affine portal. This function does whatever processing is not triggered by + * interrupts. This is a legacy wrapper that can be used in core-processing + * loops but mitigates the performance overhead of portal processing by + * adaptively bypassing true portal processing most of the time. (Processing is + * done once every 10 calls if the previous processing revealed that work needed + * to be done, or once very 1000 calls if the previous processing revealed no + * work needed doing.) If you wish to control this yourself, call + * bman_poll_slow() instead, which always checks for portal processing work. + */ +void bman_poll(void); + +/** + * bman_rcr_is_empty - Determine if portal's RCR is empty + * + * For use in situations where a cpu-affine caller needs to determine when all + * releases for the local portal have been processed by Bman but can't use the + * BMAN_RELEASE_FLAG_WAIT_SYNC flag to do this from the final bman_release(). + * The function forces tracking of RCR consumption (which normally doesn't + * happen until release processing needs to find space to put new release + * commands), and returns zero if the ring still has unprocessed entries, + * non-zero if it is empty. + */ +int bman_rcr_is_empty(void); + +/** + * bman_alloc_bpid_range - Allocate a contiguous range of BPIDs + * @result: is set by the API to the base BPID of the allocated range + * @count: the number of BPIDs required + * @align: required alignment of the allocated range + * @partial: non-zero if the API can return fewer than @count BPIDs + * + * Returns the number of buffer pools allocated, or a negative error code. If + * @partial is non zero, the allocation request may return a smaller range of + * BPs than requested (though alignment will be as requested). If @partial is + * zero, the return value will either be 'count' or negative. + */ +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial); +static inline int bman_alloc_bpid(u32 *result) +{ + int ret = bman_alloc_bpid_range(result, 1, 0, 0); + return (ret > 0) ? 0 : ret; +} + +/** + * bman_release_bpid_range - Release the specified range of buffer pool IDs + * @bpid: the base BPID of the range to deallocate + * @count: the number of BPIDs in the range + * + * This function can also be used to seed the allocator with ranges of BPIDs + * that it can subsequently allocate from. + */ +void bman_release_bpid_range(u32 bpid, unsigned int count); +static inline void bman_release_bpid(u32 bpid) +{ + bman_release_bpid_range(bpid, 1); +} + +int bman_reserve_bpid_range(u32 bpid, unsigned int count); +static inline int bman_reserve_bpid(u32 bpid) +{ + return bman_reserve_bpid_range(bpid, 1); +} + +void bman_seed_bpid_range(u32 bpid, unsigned int count); + + +int bman_shutdown_pool(u32 bpid); + + /* Pool management */ + /* --------------- */ +/** + * bman_new_pool - Allocates a Buffer Pool object + * @params: parameters specifying the buffer pool ID and behaviour + * + * Creates a pool object for the given @params. A portal and the depletion + * callback field of @params are only used if the BMAN_POOL_FLAG_DEPLETION flag + * is set. NB, the fields from @params are copied into the new pool object, so + * the structure provided by the caller can be released or reused after the + * function returns. + */ +struct bman_pool *bman_new_pool(const struct bman_pool_params *params); + +/** + * bman_free_pool - Deallocates a Buffer Pool object + * @pool: the pool object to release + * + */ +void bman_free_pool(struct bman_pool *pool); + +/** + * bman_get_params - Returns a pool object's parameters. + * @pool: the pool object + * + * The returned pointer refers to state within the pool object so must not be + * modified and can no longer be read once the pool object is destroyed. + */ +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool); + +/** + * bman_release - Release buffer(s) to the buffer pool + * @pool: the buffer pool object to release to + * @bufs: an array of buffers to release + * @num: the number of buffers in @bufs (1-8) + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options + * + * Adds the given buffers to RCR entries. If the portal @p was created with the + * "COMPACT" flag, then it will be using a compaction algorithm to improve + * utilisation of RCR. As such, these buffers may join an existing ring entry + * and/or it may not be issued right away so as to allow future releases to join + * the same ring entry. Use the BMAN_RELEASE_FLAG_NOW flag to override this + * behaviour by committing the RCR entry (or entries) right away. If the RCR + * ring is full, the function will return -EBUSY unless BMAN_RELEASE_FLAG_WAIT + * is selected, in which case it will sleep waiting for space to become + * available in RCR. If the function receives a signal before such time (and + * BMAN_RELEASE_FLAG_WAIT_INT is set), the function returns -EINTR. Otherwise, + * it returns zero. + */ +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num, + u32 flags); + +/** + * bman_acquire - Acquire buffer(s) from a buffer pool + * @pool: the buffer pool object to acquire from + * @bufs: array for storing the acquired buffers + * @num: the number of buffers desired (@bufs is at least this big) + * + * Issues an "Acquire" command via the portal's management command interface. + * The return value will be the number of buffers obtained from the pool, or a + * negative error code if a h/w error or pool starvation was encountered. In + * the latter case, the content of @bufs is undefined. + */ +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num, + u32 flags); + +/** + * bman_flush_stockpile - Flush stockpile buffer(s) to the buffer pool + * @pool: the buffer pool object the stockpile belongs + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options + * + * Adds stockpile buffers to RCR entries until the stockpile is empty. + * The return value will be a negative error code if a h/w error occurred. + * If BMAN_RELEASE_FLAG_NOW flag is passed and RCR ring is full, + * -EAGAIN will be returned. + */ +int bman_flush_stockpile(struct bman_pool *pool, u32 flags); + +/** + * bman_query_pools - Query all buffer pool states + * @state: storage for the queried availability and depletion states + */ +int bman_query_pools(struct bm_pool_state *state); + +#ifdef CONFIG_FSL_BMAN_CONFIG +/** + * bman_query_free_buffers - Query how many free buffers are in buffer pool + * @pool: the buffer pool object to query + * + * Return the number of the free buffers + */ +u32 bman_query_free_buffers(struct bman_pool *pool); + +/** + * bman_update_pool_thresholds - Change the buffer pool's depletion thresholds + * @pool: the buffer pool object to which the thresholds will be set + * @thresholds: the new thresholds + */ +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds); +#endif + +/** + * The below bman_p_***() variant might be called in a situation that the cpu + * which the portal affine to is not online yet. + * @bman_portal specifies which portal the API will use. +*/ +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits); +#ifdef __cplusplus +} +#endif + +#endif /* FSL_BMAN_H */ diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index a82296a..7308073 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -24,6 +24,7 @@ #define FSL_USB_VER_1_6 1 #define FSL_USB_VER_2_2 2 #define FSL_USB_VER_2_4 3 +#define FSL_USB_VER_2_5 4 #include <linux/types.h> @@ -64,6 +65,7 @@ enum fsl_usb2_phy_modes { FSL_USB2_PHY_UTMI, FSL_USB2_PHY_UTMI_WIDE, FSL_USB2_PHY_SERIAL, + FSL_USB2_PHY_UTMI_DUAL, }; struct clk; @@ -92,6 +94,11 @@ struct fsl_usb2_platform_data { unsigned suspended:1; unsigned already_suspended:1; + unsigned has_fsl_erratum_a005275:1; + unsigned has_fsl_erratum_a006918:1; + unsigned has_fsl_erratum_a005697:1; + unsigned has_fsl_erratum_a007792:1; + unsigned has_fsl_erratum_14:1; /* register save area for suspend/resume */ u32 pm_command; diff --git a/include/linux/fsl_dpa_classifier.h b/include/linux/fsl_dpa_classifier.h new file mode 100644 index 0000000..22d5f6e --- /dev/null +++ b/include/linux/fsl_dpa_classifier.h @@ -0,0 +1,1600 @@ + +/* Copyright 2008-2012 Freescale Semiconductor, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * DPA Classifier Application Programming Interface. + */ + +#ifndef __FSL_DPA_CLASSIFIER_H +#define __FSL_DPA_CLASSIFIER_H + + +/* DPA offloading layer includes */ +#include "fsl_dpa_offload.h" + + +/* General definitions */ + +/* Maximum number of VLAN tags supported by the insert header manipulation */ +#define DPA_CLS_HM_MAX_VLANs 6 +/* Maximum number of MPLS labels supported by the insert header manipulation */ +#define DPA_CLS_HM_MAX_MPLS_LABELS 6 +/* Standard size of the DSCP-to-VPri mapping table */ +#define DPA_CLS_HM_DSCP_TO_VLAN_TABLE_SIZE 32 +/* Number of entries in the DSCP-to-VPri mapping table */ +#define DPA_CLS_HM_DSCP_TO_VPRI_TABLE_SIZE 64 + + +/* API functions, definitions and enums */ + +/* Table API */ + +/* DPA Classifier Table Types */ +enum dpa_cls_tbl_type { + DPA_CLS_TBL_HASH = 0, /* HASH table */ + DPA_CLS_TBL_INDEXED, /* Indexed table */ + DPA_CLS_TBL_EXACT_MATCH /* Exact match table */ +}; + +/* DPA Classifier Table Action Types */ +enum dpa_cls_tbl_action_type { + + /* Unspecified action */ + DPA_CLS_TBL_ACTION_NONE = 0, + + /* Drop frame */ + DPA_CLS_TBL_ACTION_DROP, + + /* Send frame into a frame queue (enqueue) */ + DPA_CLS_TBL_ACTION_ENQ, + + /* Go to another table and re-classify the packet */ + DPA_CLS_TBL_ACTION_NEXT_TABLE, + + /* Send frames to a multicast group */ + DPA_CLS_TBL_ACTION_MCAST + +}; + +/* DPA Classifier Table Entry Modification Types */ +enum dpa_cls_tbl_modify_type { + + /* + * Modify the entry key. This modification is supported only on exact + * match tables. + */ + DPA_CLS_TBL_MODIFY_KEY = 0, + + /* Modify the entry action */ + DPA_CLS_TBL_MODIFY_ACTION, + + /* + * Modify the entry key and action. This modification is supported only + * on exact match tables. + */ + DPA_CLS_TBL_MODIFY_KEY_AND_ACTION +}; + +/* DPA Classifier Table Entry Management Types */ +enum dpa_cls_tbl_entry_mgmt { + /* + * Manage entries by key (shadow table). The shadow table consumes more + * RAM, but allows the user to do software lookups and refer to the + * table entries by their key as well as by their reference (Id) + */ + DPA_CLS_TBL_MANAGE_BY_KEY = 0, + + /* + * Manage entries by reference only (no shadow table). Saves memory and + * speeds up runtime operations, but the user cannot do software + * lookups and can only refer to the entries by their reference (Id) + */ + DPA_CLS_TBL_MANAGE_BY_REF, +}; + + +/* DPA Classifier HASH table parameters */ +struct dpa_cls_tbl_hash_params { + + /* Number of sets (buckets) of the HASH table */ + unsigned int num_sets; + + /* Number of ways of the HASH table (capability to resolve conflicts) */ + unsigned int max_ways; + + /* HASH offset */ + unsigned int hash_offs; + + /* Key size in bytes */ + uint8_t key_size; +}; + +/* DPA Classifier indexed table parameters */ +struct dpa_cls_tbl_indexed_params { + + unsigned int entries_cnt; /* Number of entries in the table */ +}; + +/* DPA Classifier exact match table parameters */ +struct dpa_cls_tbl_exact_match_params { + + /* Number of entries in the table */ + unsigned int entries_cnt; + + /* Key size in bytes */ + uint8_t key_size; + + /* Use priorities for each entry in table if nonzero */ + bool use_priorities; +}; + +/* DPA Classifier table parameters */ +struct dpa_cls_tbl_params { + /* + * Handle of the initial FM Cc node for this table + * + * This Cc node must be connected to a Cc tree. + */ + void *cc_node; + + /* + * Handle to a FMan distribution to send frames to instead of + * enqueuing frames. If this handle is provided (not NULL) the enqueue + * action will only select the frame queue, but it will NOT actually + * enqueue the frame to the selected frame queue. Instead it will send + * the frame to the indicated distribution for further processing. + */ + void *distribution; + + /* + * Handle to a FMan classification to send frames after distribution + */ + void *classification; + + /* The type of the DPA Classifier table */ + enum dpa_cls_tbl_type type; + + /* Table entry management mechanism for runtime */ + enum dpa_cls_tbl_entry_mgmt entry_mgmt; + + union { + /* Parameters for HASH table */ + struct dpa_cls_tbl_hash_params hash_params; + + /* Parameters for indexed table */ + struct dpa_cls_tbl_indexed_params indexed_params; + + /* Parameters for exact match table */ + struct dpa_cls_tbl_exact_match_params exact_match_params; + }; + + /* + * Number of entries in the table which are pre-filled from the + * skeleton. The assumption is always that these entries are the first + * entries in the table and with the highest priority. + */ + unsigned int prefilled_entries; +}; + +/* Policer parameters */ +struct dpa_cls_tbl_policer_params { + + /* [True] if the default policer parameters will be overridden */ + bool modify_policer_params; + + /* [True] if this policer profile is shared between ports; relevant + * only if [modify_policer_params] is set to [true]. */ + bool shared_profile; + + /* + * This parameter should indicate the policer profile offset within the + * port's policer profiles or from the SHARED window; relevant only if + * [modify_policer_params] is set to [true]. + */ + unsigned int new_rel_profile_id; +}; + +/* Enqueue action parameters */ +struct dpa_cls_tbl_enq_action_desc { + + /* + * Override the frame queue Id from KeyGen and use the one + * specified in this enqueue action descriptor if set to true + */ + bool override_fqid; + + /* + * Id of the frame queue where to send the frames in case of + * rule hit. + */ + uint32_t new_fqid; + + /* + * Pointer to the policer parameters. If NULL, no policing is + * applied during the enqueue. + */ + struct dpa_cls_tbl_policer_params *policer_params; + + /* + * Descriptor of the header manipulation chain to use with this + * entry. + */ + int hmd; + + /* + * New virtual storage profile Id. This parameter is mandatory when + * [override_fqid] is set to [true] and the port has virtual storage + * profiles defined. Otherwise it is not used. + */ + uint8_t new_rel_vsp_id; +}; + +/* Action parameters to route to a new classifier table */ +struct dpa_cls_tbl_next_table_desc { + + /* + * Descriptor of the next DPA Classifier table to continue + * classification with + */ + int next_td; + + /* + * Descriptor of the header manipulation chain to use before sending + * the frames to the next table. + */ + int hmd; +}; + +struct dpa_cls_tbl_mcast_group_desc { + + /* + * Descriptor of the multicast group to use with a specific table entry. + */ + int grpd; + + /* + * Descriptor of the header manipulation chain that will be performed + * before sending the frames to the multicast group + */ + int hmd; +}; + +/* DPA Classifier action descriptor */ +struct dpa_cls_tbl_action { + + /* + * Action type specifier. Drop action doesn't require any + * further parameters + */ + enum dpa_cls_tbl_action_type type; + + /* Enable statistics for this entry if nonzero */ + bool enable_statistics; + + union { + + /* Specific parameters for enqueue action */ + struct dpa_cls_tbl_enq_action_desc enq_params; + + /* + * Specific parameters for sending the frames to a new + * classifier table + */ + struct dpa_cls_tbl_next_table_desc next_table_params; + + /* + * Specific parameters for sending the frame to a multicast + * group + */ + struct dpa_cls_tbl_mcast_group_desc mcast_params; + + }; +}; + +/* DPA Classifier entry modification parameters */ +struct dpa_cls_tbl_entry_mod_params { + + /* The type of modification */ + enum dpa_cls_tbl_modify_type type; + + /* + * The new key parameters to replace the existing key + * parameters of the entry. Ignored for modify types which + * do not refer to the key. + */ + struct dpa_offload_lookup_key *key; + + /* + * The new action parameters to replace the existing action + * parameters of the entry. Ignored for modify types which + * do not refer to the action. + */ + struct dpa_cls_tbl_action *action; +}; + +/* DPA Classifier table entry statistics */ +struct dpa_cls_tbl_entry_stats { + + /* The total number of packets that have hit the entry */ + uint32_t pkts; + + /* The total number of bytes that have hit the entry */ + uint32_t bytes; +}; + + +/* + * Creates and initializes a DPA Classifier table using a FMan + * coarse classification node. Depending on the type of table, + * this call can result in MURAM allocation. + * + * Once the DPA Classifier takes control of a FMan Cc node, all + * its management must be performed through this API. If + * applications use different APIs to modify the Cc node's + * properties in the same time while the DPA Classifier has + * ownership of the node, unpredictable behavior and data + * inconsistency can occur. + */ +int dpa_classif_table_create(const struct dpa_cls_tbl_params *params, + int *td); + +/* + * Releases all resources associated with a DPA Classifier table + * and destroys it. + */ +int dpa_classif_table_free(int td); + +/* Modifies the action taken in case of lookup miss condition. */ +int dpa_classif_table_modify_miss_action(int td, + const struct dpa_cls_tbl_action *miss_action); + +/* + * Adds an entry (classification rule) in the specified DPA + * Classifier table. If the MURAM for the table was pre-allocated, + * this operation doesn't consume MURAM. + * + * The hardware currently doesn't support longest prefix match on + * the exact match tables. If there are more entries in the + * table that match the lookup (e.g. because of their mask) the + * first one will always be returned by the hardware lookup. + * + * The priority parameter is meaningful only if [td] is an exact match table + * with priority per entries. The priority value of the entry influences the + * position of the entry in the table relative to the other entries. Entries + * with lower priority values go to the top of the table. Priority values can + * be negative. If two entries with the same priority are inserted in the + * table, they will be positioned one after the other in the table, and the + * older one first. + */ +int dpa_classif_table_insert_entry(int td, + const struct dpa_offload_lookup_key *key, + const struct dpa_cls_tbl_action *action, + int priority, + int *entry_id); + +/* + * Modifies an entry in the specified DPA Classifier table. The + * entry is identified by the lookup key. This function never + * allocates new MURAM space. + */ +int dpa_classif_table_modify_entry_by_key(int td, + const struct dpa_offload_lookup_key *key, + const struct dpa_cls_tbl_entry_mod_params *mod_params); + +/* + * Modifies an entry in the specified DPA Classifier table. The + * entry is identified by its ref (Id). This function never + * allocates new MURAM space. + */ +int dpa_classif_table_modify_entry_by_ref(int td, + int entry_id, + const struct dpa_cls_tbl_entry_mod_params *mod_params); + +/* + * Removes an entry in the specified DPA Classifier table. The + * entry is identified by the lookup key. If the MURAM for the + * table was pre-allocated, this function doesn't free up any + * MURAM space. + */ +int dpa_classif_table_delete_entry_by_key(int td, + const struct dpa_offload_lookup_key *key); + +/* + * Removes an entry in the specified DPA Classifier table. The + * entry is identified by its ref (Id). If the MURAM for the + * table was pre-allocated, this function doesn't free up any + * MURAM space. + */ +int dpa_classif_table_delete_entry_by_ref(int td, int entry_id); + +/* + * Performs a lookup in the specified table for an entry specified + * by a key. If successful (i.e. the entry exists in that table) + * the action descriptor for that entry is returned. + * + * Table lookup works only if entry management by key is selected + * for the DPA Classifier table. + * + * This is not a hardware accelerated lookup. This lookup is + * performed by the DPA Classifier in its internal shadow tables. + * It is recommended to use this function with consideration. + */ +int dpa_classif_table_lookup_by_key(int td, + const struct dpa_offload_lookup_key *key, + struct dpa_cls_tbl_action *action); + +/* + * Performs a lookup in the specified table for an entry specified + * by its ref (Id). The action descriptor for that entry is + * returned. + * + * Table lookup works only if entry management by key is selected + * for the DPA Classifier table. + */ +int dpa_classif_table_lookup_by_ref(int td, + int entry_id, + struct dpa_cls_tbl_action *action); + +/* + * Removes all the entries in a DPA Classifier Table. After this + * operation is completed the entries cannot be recovered. + */ +int dpa_classif_table_flush(int td); + +/* + * Returns the statistics for a specified entry in a specified + * table. The entry is identified by the lookup key. + */ +int dpa_classif_table_get_entry_stats_by_key(int td, + const struct dpa_offload_lookup_key *key, + struct dpa_cls_tbl_entry_stats *stats); + +/* + * Returns the statistics for a specified entry in a specified + * table. The entry is identified by its ref (pointer). + */ +int dpa_classif_table_get_entry_stats_by_ref(int td, + int entry_id, + struct dpa_cls_tbl_entry_stats *stats); + +/* Returns the miss statistics for the specified table. */ +int dpa_classif_table_get_miss_stats(int td, + struct dpa_cls_tbl_entry_stats *stats); + + +/* Returns the parameters of a classifier table. */ +int dpa_classif_table_get_params(int td, struct dpa_cls_tbl_params *params); + + +/* Header Manipulation API */ + + +/* Supported protocols for NAT header manipulations */ +enum dpa_cls_hm_nat_proto { + DPA_CLS_NAT_PROTO_UDP, + DPA_CLS_NAT_PROTO_TCP, + DPA_CLS_NAT_PROTO_ICMP, + DPA_CLS_NAT_PROTO_LAST_ENTRY +}; + +/* NAT operation type */ +enum dpa_cls_hm_nat_type { + /* Traditional NAT */ + DPA_CLS_HM_NAT_TYPE_TRADITIONAL, + + /* NAT w/ protocol translation */ + DPA_CLS_HM_NAT_TYPE_NAT_PT, + + DPA_CLS_HM_NAT_TYPE_LAST_ENTRY +}; + +/* + * Flag values indicating the possible fields to be updated with the + * NAT header manipulation + */ +enum dpa_cls_hm_nat_flags { + DPA_CLS_HM_NAT_UPDATE_SIP = 0x01, + DPA_CLS_HM_NAT_UPDATE_DIP = 0x02, + DPA_CLS_HM_NAT_UPDATE_SPORT = 0x04, + DPA_CLS_HM_NAT_UPDATE_DPORT = 0x08 +}; + +/* Type of protocol translation for NAT */ +enum dpa_cls_hm_nat_pt_type { + DPA_CLS_HM_NAT_PT_IPv6_TO_IPv4, + DPA_CLS_HM_NAT_PT_IPv4_TO_IPv6 +}; + +/* + * Flag values indicating which attributes of the NAT header manipulation to + * modify + */ +enum dpa_cls_hm_nat_modify_flags { + DPA_CLS_HM_NAT_MOD_FLAGS = 0x01, + DPA_CLS_HM_NAT_MOD_SIP = 0x02, + DPA_CLS_HM_NAT_MOD_DIP = 0x04, + DPA_CLS_HM_NAT_MOD_SPORT = 0x08, + DPA_CLS_HM_NAT_MOD_DPORT = 0x10, + DPA_CLS_HM_NAT_MOD_IP_HDR = 0x20 +}; + +/* NAT header manipulation low level driver resources */ +struct dpa_cls_hm_nat_resources { + /* + * Handle to a header manipulation node which may combine a local + * IPv4/IPv6 update header manipulation with an IP protocol replace. + * This is a FMan driver header manipulation node handle and it is + * mandatory for the import to succeed. + */ + void *l3_update_node; + + /* + * Handle to the local TCP/UDP update header manipulation node. This is + * a FMan driver header manipulation node handle and it is optional + * (can be NULL in case no L4 header updates are necessary for this NAT + * flow). + */ + void *l4_update_node; +}; + +/* Traditional NAT parameters */ +struct dpa_cls_hm_traditional_nat_params { + /* New source IP address */ + struct dpa_offload_ip_address sip; + + /* New destination IP address */ + struct dpa_offload_ip_address dip; +}; + +/* NAT-PT parameters */ +struct dpa_cls_hm_nat_pt_params { + /* + * Specifies the protocol replacement for NAT-PT: either IPv4-to-IPv6 + * or IPv6-to-IPv4 + */ + enum dpa_cls_hm_nat_pt_type type; + + union { + /* New IPv4 header data to replace IPv6 with */ + struct ipv4_header ipv4; + + /* New IPv6 header data to replace IPv4 with */ + struct ipv6_header ipv6; + } new_header; +}; + +/* Definition of a NAT related header manipulation */ +struct dpa_cls_hm_nat_params { + /* + * NAT operation flags specify which fields in the packet should be + * updated. This is a combination of the values in the + * dpa_cls_hm_nat_flags enum. + */ + int flags; + + /* Protocol to perform NAT for */ + enum dpa_cls_hm_nat_proto proto; + + /* Selects the flavor of NAT to configure */ + enum dpa_cls_hm_nat_type type; + + + union { + /* + * Traditional NAT header manipulation parameters. Used only + * when traditional NAT is selected using the [type] attribute. + */ + struct dpa_cls_hm_traditional_nat_params nat; + + /* + * NAT-PT header manipulation parameters. Used only when NAT-PT + * is selected using the [type] attribute. + */ + struct dpa_cls_hm_nat_pt_params nat_pt; + }; + + /* + * New L4 protocol source port number; used when selected using the + * flags attribute. + */ + uint16_t sport; + + /* + * New L4 protocol destination port number; used only when selected + * using the flags attribute + */ + uint16_t dport; + + /* + * Handle to the low level driver PCD to use when creating the header + * manipulation object. + */ + void *fm_pcd; + + /* + * Request re-parsing of the packet headers after this NAT. + */ + bool reparse; +}; + +/* Output interface type for forwarding */ +enum dpa_cls_hm_out_if_type { + DPA_CLS_HM_IF_TYPE_ETHERNET, + DPA_CLS_HM_IF_TYPE_PPPoE, + DPA_CLS_HM_IF_TYPE_PPP, + DPA_CLS_HM_IF_TYPE_LAST_ENTRY +}; + +/* + * Flag values indicating which forwarding header manipulation attributes to + * modify + */ +enum dpa_cls_hm_fwd_modify_flags { + DPA_CLS_HM_FWD_MOD_ETH_MACSA = 0x01, + DPA_CLS_HM_FWD_MOD_ETH_MACDA = 0x02, + DPA_CLS_HM_FWD_MOD_PPPoE_HEADER = 0x04, + DPA_CLS_HM_FWD_MOD_PPP_PID = 0x08, + DPA_CLS_HM_FWD_MOD_IP_FRAG_MTU = 0x10, + DPA_CLS_HM_FWD_MOD_IP_FRAG_SCRATCH_BPID = 0x20, + DPA_CLS_HM_FWD_MOD_IP_FRAG_DF_ACTION = 0x40 +}; + +enum dpa_cls_hm_frag_df_action { + DPA_CLS_HM_DF_ACTION_FRAG_ANYWAY, + DPA_CLS_HM_DF_ACTION_DONT_FRAG, + DPA_CLS_HM_DF_ACTION_DROP +}; + +/* IP fragmentation parameters */ +struct dpa_cls_hm_ip_frag_params { + /* Maximum Transfer Unit. Use zero to disable IP fragmentation. */ + uint16_t mtu; + + /* + * Scratch buffer pool ID. This is necessary for the IP fragmentation + * on FMan v2 devices only. On FMan v3 or newer devices this parameter + * is ignored. It is also ignored if IP fragmentation is disabled. + */ + uint8_t scratch_bpid; + + /* Specifies how to deal with packets with DF flag on */ + enum dpa_cls_hm_frag_df_action df_action; +}; + +struct dpa_cls_hm_fwd_l2_param { + /* New Ethernet destination MAC address to update the L2 header */ + uint8_t macda[ETH_ALEN]; + + /* New Ethernet source MAC address to update the L2 header */ + uint8_t macsa[ETH_ALEN]; +}; + +/* Forwarding header manipulation parameters for a PPPoE output interface */ +struct dpa_cls_hm_fwd_pppoe_param { + /* L2 header update parameters */ + struct dpa_cls_hm_fwd_l2_param l2; + + /* + * PPPoE header to be inserted in the packets. The PPPoE payload length + * field is updated automatically (you can set it to zero). + */ + struct pppoe_header pppoe_header; +}; + +/* Forwarding header manipulation parameters for a PPP output interface */ +struct dpa_cls_hm_fwd_ppp_param { + /* PPP PID value to use in the PPP header to be inserted */ + uint16_t ppp_pid; +}; + +/* Forwarding header manipulation low level driver resources */ +struct dpa_cls_hm_fwd_resources { + /* + * Handle to the forwarding header manipulation node. + * + * In case of an Ethernet or a PPPoE output interface this is a local + * header replace header manipulation node (for Ethernet MAC addresses). + * + * In case of a PPP output interface this is a protocol specific header + * removal node (for Ethernet and VLAN tags) combined with an internal + * header insert. + * + * This is a FMan driver header manipulation node handle and it is + * mandatory for the import to succeed. + */ + void *fwd_node; + + /* + * Handle to the PPPoE specific node. This is an internal protocol + * specific insert PPPoE header manipulation node. This is a FMan driver + * header manipulation node handle and it is optional (can be NULL in + * case the output interface type is not PPPoE). + */ + void *pppoe_node; + + /* + * Handle to the IP fragmentation node. This is a FMan driver header + * manipulation node handle and it is optional (can be NULL in case no + * IP fragmentation is enabled for this IP forwarding flow). + */ + void *ip_frag_node; +}; + +/* Forwarding header manipulation parameters */ +struct dpa_cls_hm_fwd_params { + /* + * Output interface type. Based on this selection the DPA Classifier + * decides which header manipulations are needed to perform forwarding. + */ + enum dpa_cls_hm_out_if_type out_if_type; + + union { + /* Necessary parameters for an Ethernet output interface */ + struct dpa_cls_hm_fwd_l2_param eth; + + /* Necessary parameters for a PPPoE output interface */ + struct dpa_cls_hm_fwd_pppoe_param pppoe; + + /* Necessary parameters for a PPP output interface */ + struct dpa_cls_hm_fwd_ppp_param ppp; + }; + + /* Parameters related to optional IP fragmentation */ + struct dpa_cls_hm_ip_frag_params ip_frag_params; + + /* + * Handle to the low level driver PCD to use when creating the header + * manipulation object. + */ + void *fm_pcd; + + /* + * Request re-parsing of the packet headers after this forwarding + * header manipulation. + */ + bool reparse; +}; + +/* Types of the remove header manipulation operations */ +enum dpa_cls_hm_remove_type { + DPA_CLS_HM_REMOVE_ETHERNET, /* removes ETH and all QTags */ + DPA_CLS_HM_REMOVE_PPPoE, /* removes ETH, all QTags and PPPoE */ + DPA_CLS_HM_REMOVE_PPP, + DPA_CLS_HM_REMOVE_CUSTOM, /* General remove */ + DPA_CLS_HM_REMOVE_LAST_ENTRY +}; + +/* + * Flag values indicating which attributes of the remove header manipulation + * to modify + */ +enum dpa_cls_hm_remove_modify_flags { + DPA_CLS_HM_RM_MOD_TYPE = 0x01, + DPA_CLS_HM_RM_MOD_CUSTOM_OFFSET = 0x02, + DPA_CLS_HM_RM_MOD_CUSTOM_SIZE = 0x04 +}; + +/* General (custom) remove header manipulation parameters */ +struct dpa_cls_hm_custom_rm_params { + /* + * Offset in bytes, relative to the start of the packet, to start + * removing data from + */ + uint8_t offset; + + /* The size in bytes of the section to remove */ + uint8_t size; +}; + +/* Ingress remove header manipulation low level driver resources */ +struct dpa_cls_hm_remove_resources { + /* + * Handle to either a header removal node or a protocol specific header + * removal node (for Ethernet and all VLAN tags). This is a FMan driver + * header manipulation node handle and it is mandatory for the import + * to succeed. + */ + void *remove_node; +}; + +/* Ingress (remove) header manipulation parameters */ +struct dpa_cls_hm_remove_params { + + /* + * Selects the type of the remove header manipulation operation to + * perform. Protocol specific header removals don't need any further + * parameters. + */ + enum dpa_cls_hm_remove_type type; + + /* + * Parameters for the custom remove header manipulation. If [type] is + * anything else than "custom remove", these parameters are ignored + */ + struct dpa_cls_hm_custom_rm_params custom; + + /* + * Handle to the low level driver PCD to use when creating the header + * manipulation object. + */ + void *fm_pcd; + + /* + * Request re-parsing of the packet headers after this header remove. + */ + bool reparse; +}; + +/* Types of insert header manipulation operations */ +enum dpa_cls_hm_insert_type { + DPA_CLS_HM_INSERT_ETHERNET, /* Insert Ethernet + QTags */ + DPA_CLS_HM_INSERT_PPPoE, /* Insert PPPoE, ETH and QTags */ + DPA_CLS_HM_INSERT_PPP, + DPA_CLS_HM_INSERT_CUSTOM, /* General insert */ + DPA_CLS_HM_INSERT_LAST_ENTRY +}; + +/* + * Flag values indicating which attributes of the insert header manipulation + * to modify + */ +enum dpa_cls_hm_insert_modify_flags { + /* Ethernet and PPPoE insert group */ + DPA_CLS_HM_INS_MOD_ETH_HEADER = 0x01, + DPA_CLS_HM_INS_MOD_QTAGS = 0x02, + DPA_CLS_HM_INS_MOD_PPPoE_HEADER = 0x04, + + /* PPP insert group */ + DPA_CLS_HM_INS_MOD_PPP_PID = 0x08, + + /* Custom insert group */ + DPA_CLS_HM_INS_MOD_CUSTOM_OFFSET = 0x10, + DPA_CLS_HM_INS_MOD_CUSTOM_DATA = 0x20 +}; + +/* General insert parameters */ +struct dpa_cls_hm_custom_ins_params { + /* + * Offset in bytes relative to the start of the frame to insert new + * header at. + */ + uint8_t offset; + + /* The size in bytes of the header to insert */ + uint8_t size; + + /* + * The data buffer containing the header to insert. This buffer must be + * at least [size] bytes long + */ + const uint8_t *data; +}; + +/* Egress insert header manipulation low level driver resources */ +struct dpa_cls_hm_insert_resources { + /* + * Handle to either an internal header insert or an internal protocol + * specific header insert node. This is a FMan driver header + * manipulation node handle and it is mandatory for the import to + * succeed. + */ + void *insert_node; +}; + +/* Ethernet header insert params */ +struct dpa_cls_hm_eth_ins_params { + /* Ethernet header to insert */ + struct ethhdr eth_header; + + /* + * Number of VLAN tags to insert. If zero, no VLAN tags will be inserted + * in the packet + */ + unsigned int num_tags; + + /* + * Relevant only if [num_tags] is not zero. Contains an array with the + * data of the VLAN QTags to insert + */ + struct vlan_header qtag[DPA_CLS_HM_MAX_VLANs]; +}; + +/* PPPoE header insert params */ +struct dpa_cls_hm_pppoe_ins_params { + /* + * Parameters of the Ethernet header to insert together with PPPoE + * header + */ + struct dpa_cls_hm_eth_ins_params eth; + + /* PPPoE header to insert */ + struct pppoe_header pppoe_header; +}; + +/* Ethernet header insert params */ +struct dpa_cls_hm_insert_params { + /* Specifies the type of insert header manipulation */ + enum dpa_cls_hm_insert_type type; + + union { + /* + * Ethernet header insert parameters if type is "insert + * Ethernet" + */ + struct dpa_cls_hm_eth_ins_params eth; + + /* PPPoE header insert parameters if type is "insert PPPoE" */ + struct dpa_cls_hm_pppoe_ins_params pppoe; + + /* + * PPP PID value to use in the PPP header if type is "insert + * PPP" + */ + uint16_t ppp_pid; + + /* + * Custom insert header manipulation operation parameters. + * These are relevant only if a custom insert header + * manipulation operation is selected. + */ + struct dpa_cls_hm_custom_ins_params custom; + }; + + /* + * Handle to the low level driver PCD to use when creating the header + * manipulation object. + */ + void *fm_pcd; + + /* + * Request re-parsing of the packet headers after this header insert. + */ + bool reparse; +}; + +/* Update header manipulation op flags */ +enum dpa_cls_hm_update_op_flags { + DPA_CLS_HM_UPDATE_NONE = 0, + + DPA_CLS_HM_UPDATE_IPv4_UPDATE = 0x01, + DPA_CLS_HM_UPDATE_IPv6_UPDATE = 0x02, + DPA_CLS_HM_UPDATE_UDP_TCP_UPDATE = 0x04, + + DPA_CLS_HM_REPLACE_IPv4_BY_IPv6 = 0x08, + DPA_CLS_HM_REPLACE_IPv6_BY_IPv4 = 0x10 +}; + +/* Update header manipulation field flags */ +enum dpa_cls_hm_l3_field_flags { + DPA_CLS_HM_IP_UPDATE_IPSA = 0x01, + DPA_CLS_HM_IP_UPDATE_IPDA = 0x02, + DPA_CLS_HM_IP_UPDATE_TOS_TC = 0x04, + DPA_CLS_HM_IP_UPDATE_ID = 0x08, + DPA_CLS_HM_IP_UPDATE_TTL_HOPL_DECREMENT = 0x10 +}; + +/* L4 header update field flags */ +enum dpa_cls_hm_l4_field_flags { + DPA_CLS_HM_L4_UPDATE_SPORT = 0x01, + DPA_CLS_HM_L4_UPDATE_DPORT = 0x02, + DPA_CLS_HM_L4_UPDATE_CALCULATE_CKSUM = 0x04 +}; + +/* + * Flag values indicating which attributes of the update header manipulation + * to modify + */ +enum dpa_cls_hm_update_modify_flags { + DPA_CLS_HM_UPDATE_MOD_IPHDR = 0x0001, + + /* L3 protocol flags group */ + DPA_CLS_HM_UPDATE_MOD_SIP = 0x0002, + DPA_CLS_HM_UPDATE_MOD_DIP = 0x0004, + DPA_CLS_HM_UPDATE_MOD_TOS_TC = 0x0008, + DPA_CLS_HM_UPDATE_MOD_IP_ID = 0x0010, + DPA_CLS_HM_UPDATE_MOD_L3_FLAGS = 0x0020, + + /* L4 protocol flags group */ + DPA_CLS_HM_UPDATE_MOD_SPORT = 0x0040, + DPA_CLS_HM_UPDATE_MOD_DPORT = 0x0080, + DPA_CLS_HM_UPDATE_MOD_L4_FLAGS = 0x0100, + + DPA_CLS_HM_UPDATE_MOD_IP_FRAG_MTU = 0x0200, + DPA_CLS_HM_UPDATE_MOD_IP_FRAG_SCRATCH_BPID = 0x0400, + DPA_CLS_HM_UPDATE_MOD_IP_FRAG_DF_ACTION = 0x0800 +}; + +/* L3 protocols field update parameters */ +struct dpa_cls_hm_l3_update_params { + /* New source IP address */ + struct dpa_offload_ip_address ipsa; + + /* New destination IP address */ + struct dpa_offload_ip_address ipda; + + /* New TOS (for IPv4) or Traffic Class (for IPv6) */ + uint8_t tos_tc; + + /* + * Initial IPv4 ID. This is used only if op_flags selected IPv4 update + */ + uint16_t initial_id; + + /* + * A combination of flags designating the header fields to replace. The + * available options are defined in the dpa_cls_hm_l3_field_flags enum + */ + int field_flags; +}; + +/* L4 protocols field update parameters */ +struct dpa_cls_hm_l4_update_params { + uint16_t sport; /* new L4 source port value */ + uint16_t dport; /* new L4 destination port value */ + + /* + * A combination of flags designating the header fields to replace. The + * available options are defined in the dpa_cls_hm_l4_field_flags enum + */ + int field_flags; +}; + +/* Egress update header manipulation low level driver resources */ +struct dpa_cls_hm_update_resources { + /* + * Handle to a header manipulation node with different header + * manipulations enabled, depending on the options selected in the + * parameters: local IPv4/IPv6 update header manipulation, a local + * TCP/UDP update header manipulation and an internal IP header replace. + * This is a FMan driver header manipulation node handle and it is + * optional (can be NULL in case no L3 or L4 field updates or header + * replace features are enabled for this flow) + */ + void *update_node; + + /* + * Handle to the IP fragmentation node. This is a FMan driver header + * manipulation node handle and it is optional (can be NULL in case no + * IP fragmentation is enabled for this flow). + */ + void *ip_frag_node; +}; + +/* Egress update header manipulation parameters */ +struct dpa_cls_hm_update_params { + /* + * Flags defining the header manipulation operations to perform. They + * are a combination of the flags defined in the + * dpa_cls_hm_update_op_flags enum. + */ + int op_flags; + + union { + /* + * IPv4 header data. This header is used for IPv6 to IPv4 header + * replace. + */ + struct ipv4_header new_ipv4_hdr; + + /* + * IPv6 header data. This header is used for IPv4 to IPv6 + * header replace. + */ + struct ipv6_header new_ipv6_hdr; + } replace; + + union { + /* + * L3 protocol field values. This data is used for L3 protocol + * header updates + */ + struct dpa_cls_hm_l3_update_params l3; + + /* + * L4 protocol field values. This data is used for L4 protocol + * header updates. + */ + struct dpa_cls_hm_l4_update_params l4; + } update; + + /* + * IP fragmentation parameters. This is an optional operation and can + * be disabled. + */ + struct dpa_cls_hm_ip_frag_params ip_frag_params; + + /* + * Handle to the low level driver PCD to use when creating the header + * manipulation object. + */ + void *fm_pcd; + + /* + * Request re-parsing of the packet headers after this header update. + */ + bool reparse; +}; + +/* VLAN specific header manipulation operation types */ +enum dpa_cls_hm_vlan_type { + DPA_CLS_HM_VLAN_INGRESS, + DPA_CLS_HM_VLAN_EGRESS, + DPA_CLS_HM_VLAN_LAST_ENTRY +}; + +/* Types of supported VLAN update operations */ +enum dpa_cls_hm_vlan_update_type { + DPA_CLS_HM_VLAN_UPDATE_NONE, + DPA_CLS_HM_VLAN_UPDATE_VPri, /* manual VPri update */ + DPA_CLS_HM_VLAN_UPDATE_VPri_BY_DSCP, + DPA_CLS_HM_VLAN_UPDATE_LAST_ENTRY +}; + +/* VLAN QTag identifier */ +enum dpa_cls_hm_vlan_count { + DPA_CLS_HM_VLAN_CNT_NONE, + DPA_CLS_HM_VLAN_CNT_1QTAG, /* outer QTag */ + DPA_CLS_HM_VLAN_CNT_2QTAGS, /* outer most 2 QTags */ + DPA_CLS_HM_VLAN_CNT_3QTAGS, /* outer most 3 QTags */ + DPA_CLS_HM_VLAN_CNT_4QTAGS, /* outer most 4 QTags */ + DPA_CLS_HM_VLAN_CNT_5QTAGS, /* outer most 5 QTags */ + DPA_CLS_HM_VLAN_CNT_6QTAGS, /* outer most 6 QTags */ + DPA_CLS_HM_VLAN_CNT_ALL_QTAGS, + DPA_CLS_HM_VLAN_CNT_LAST_ENTRY +}; + +/* + * Flag values indicating which attributes of the VLAN specific header + * manipulation to modify + */ +enum dpa_cls_hm_vlan_modify_flags { + /* This flag cannot be combined with any other flags */ + DPA_CLS_HM_VLAN_MOD_INGRESS_NUM_QTAGS = 0x01, + + DPA_CLS_HM_VLAN_MOD_EGRESS_QTAGS = 0x02, + DPA_CLS_HM_VLAN_MOD_EGRESS_UPDATE_OP = 0x04, + DPA_CLS_HM_VLAN_MOD_EGRESS_VPRI = 0x08, + DPA_CLS_HM_VLAN_MOD_EGRESS_DSCP_TO_VPRI_ARRAY = 0x10 +}; + +/* Ingress VLAN specific header manipulation parameters */ +struct dpa_cls_hm_ingress_vlan_params { + /* Number of VLAN tags to remove */ + enum dpa_cls_hm_vlan_count num_tags; +}; + +/* Egress VLAN specific header manipulation parameters */ +struct dpa_cls_hm_egress_vlan_params { + enum dpa_cls_hm_vlan_update_type update_op; + + /* + * Number of VLAN tags to insert. If zero, no VLAN tags will be + * inserted in the packet. + */ + unsigned int num_tags; + + /* + * Relevant only if [num_tags] is not zero. Contains an array with the + * data of the VLAN tags to insert. + */ + struct vlan_header qtag[DPA_CLS_HM_MAX_VLANs]; + + union { + /* + * New VPri field value if [update_flag] selects manual VPri + * update. + */ + uint8_t vpri; + + /* + * DSCP-to-VPri mapping table to use for VPri field update if + * [update_flag] selects VPri update by mapping to DSCP. + */ + uint8_t dscp_to_vpri[DPA_CLS_HM_DSCP_TO_VPRI_TABLE_SIZE]; + + } update; +}; + +/* VLAN specific header manipulation low level resources */ +struct dpa_cls_hm_vlan_resources { + /* + * Handle to a header manipulation node with different operations + * depending on the selected type of VLAN specific header manipulation. + * + * In case of VLAN ingress header manipulation this is a VLAN protocol + * specific removal node. + * + * In case of VLAN egress header manipulation this is a header + * manipulation node which may combine an internal header insert (in + * case there are VLANs to insert) with a protocol specific VLAN update + * operation. + * + * This is a FMan driver header manipulation node handle and it is + * mandatory for the import to succeed. + */ + void *vlan_node; +}; + +/* VLAN specific header manipulation parameters */ +struct dpa_cls_hm_vlan_params { + /* Selects the type of the VLAN specific header manipulation */ + enum dpa_cls_hm_vlan_type type; + + union { + /* Parameters for ingress VLAN header manipulations */ + struct dpa_cls_hm_ingress_vlan_params ingress; + + /* Parameters for egress VLAN header manipulations */ + struct dpa_cls_hm_egress_vlan_params egress; + }; + + /* + * Handle to the low level driver PCD to use when creating the header + * manipulation object. + */ + void *fm_pcd; + + /* + * Request re-parsing of the packet headers after this VLAN header + * update. + */ + bool reparse; +}; + +/* MPLS specific header manipulation operation types */ +enum dpa_cls_hm_mpls_type { + DPA_CLS_HM_MPLS_INSERT_LABELS, + DPA_CLS_HM_MPLS_REMOVE_ALL_LABELS, + DPA_CLS_HM_MPLS_LAST_ENTRY +}; + +/* + * Flag values indicating which attributes of the MPLS specific header + * manipulation to modify + */ +enum dpa_cls_hm_mpls_modify_flags { + DPA_CLS_HM_MPLS_MOD_NUM_LABELS = 0x01, + DPA_CLS_HM_MPLS_MOD_HDR_ARRAY = 0x02, +}; + +/* MPLS specific header manipulation low level driver resources */ +struct dpa_cls_hm_mpls_resources { + /* + * Handle to the protocol specific header insert (MPLS) or to the + * protocol specific header removal (MPLS) node. This is a FMan driver + * header manipulation node handle and it is mandatory for the import + * to succeed. + */ + void *ins_rm_node; +}; + +/* MPLS specific header manipulation parameters */ +struct dpa_cls_hm_mpls_params { + /* Specifies the type of header manipulation */ + enum dpa_cls_hm_mpls_type type; + + /* + * Stores the MPLS labels to insert if the operation type is "insert + * MPLS labels" + */ + struct mpls_header mpls_hdr[DPA_CLS_HM_MAX_MPLS_LABELS]; + + /* + * Number of MPLS labels to insert. This is relevant only if the + * operation type is "insert MPLS labels" */ + unsigned int num_labels; + + /* + * Handle to the low level driver PCD to use when creating the header + * manipulation object. + */ + void *fm_pcd; + + /* + * Request re-parsing of the packet headers after this MPLS header + * update. + */ + bool reparse; +}; + + +/* + * Creates or imports a NAT type header manipulation object. If the function is + * successful it returns at the [hmd] location the descriptor of the created + * header manipulation object. + * + * If the [res] parameter is provided, the function will import the low level + * driver resources specified therein rather than create them. In this case the + * [fm_pcd] handle in the parameters structure is not used and can be provided + * as NULL. When working in this mode the function doesn't allocate MURAM. + */ +int dpa_classif_set_nat_hm(const struct dpa_cls_hm_nat_params *nat_params, + int next_hmd, + int *hmd, + bool chain_head, + const struct dpa_cls_hm_nat_resources *res); + +/* + * Modify the parameters of an existing NAT header manipulation. + * + * [modify_flags] is a combination of flags indicating which header manipulation + * attributes to modify (and hence indicating which of the attributes in the + * [new_nat_params] data structure are valid). Select the flag values from the + * dpa_cls_hm_nat_modify_flags enum and combine them using the "or" logical + * operand. + */ +int dpa_classif_modify_nat_hm(int hmd, + const struct dpa_cls_hm_nat_params *new_nat_params, int modify_flags); + +/* + * Creates or imports a forwarding type header manipulation object. DPA + * Classifier takes into account an Ethernet/IP frame to start with and, + * depending on the selection of output interface type, it decides what header + * manipulations are necessary. + * + * If the [res] parameter is provided, the function will import the low level + * driver resources specified therein rather than create them. In this case the + * [fm_pcd] handle in the parameters structure is not used and can be provided + * as NULL. When working in this mode the function doesn't allocate MURAM. + */ +int dpa_classif_set_fwd_hm(const struct dpa_cls_hm_fwd_params *fwd_params, + int next_hmd, + int *hmd, + bool chain_head, + const struct dpa_cls_hm_fwd_resources *res); + +/* + * Modify the parameters of an existing forwarding type header manipulation. + * + * [modify_flags] is a combination of flags indicating which header manipulation + * attributes to modify (and hence indicating which of the attributes in the + * [new_fwd_params] data structure are valid). Select the flag values from the + * dpa_cls_hm_fwd_modify_flags enum and combine them using the "or" logical + * operand. + */ +int dpa_classif_modify_fwd_hm(int hmd, + const struct dpa_cls_hm_fwd_params *new_fwd_params, int modify_flags); + +/* Creates or imports a remove type header manipulation object. + * + * If the [res] parameter is provided, the function will import the low level + * driver resources specified therein rather than create them. In this case the + * [fm_pcd] handle in the parameters structure is not used and can be provided + * as NULL. When working in this mode the function doesn't allocate MURAM. + */ +int dpa_classif_set_remove_hm(const struct dpa_cls_hm_remove_params + *remove_params, int next_hmd, int *hmd, bool chain_head, + const struct dpa_cls_hm_remove_resources *res); + +/* + * Modify the parameters of an existing remove type header manipulation. + * + * [modify_flags] is a combination of flags indicating which header manipulation + * attributes to modify (and hence indicating which of the attributes in the + * [new_remove_params] data structure are valid). Select the flag values from + * the dpa_cls_hm_remove_modify_flags enum and combine them using the "or" + * logical operand. + */ +int dpa_classif_modify_remove_hm(int hmd, + const struct dpa_cls_hm_remove_params *new_remove_params, + int modify_flags); + +/* + * Creates or imports an insert type header manipulation object. + * + * If the [res] parameter is provided, the function will import the low level + * driver resources specified therein rather than create them. In this case the + * [fm_pcd] handle in the parameters structure is not used and can be provided + * as NULL. When working in this mode the function doesn't allocate MURAM. + */ +int dpa_classif_set_insert_hm(const struct dpa_cls_hm_insert_params + *insert_params, int next_hmd, int *hmd, bool chain_head, + const struct dpa_cls_hm_insert_resources *res); + +/* + * Modify the parameters of an existing insert header manipulation. + * + * [modify_flags] is a combination of flags indicating which header manipulation + * attributes to modify (and hence indicating which of the attributes in the + * [new_insert_params] data structure are valid). Select the flag values from + * the dpa_cls_hm_insert_modify_flags enum and combine them using the "or" + * logical operand. + */ +int dpa_classif_modify_insert_hm(int hmd, + const struct dpa_cls_hm_insert_params *new_insert_params, + int modify_flags); + +/* + * Creates or imports an update type header manipulation object. + * + * If the [res] parameter is provided, the function will import the low level + * driver resources specified therein rather than create them. In this case the + * [fm_pcd] handle in the parameters structure is not used and can be provided + * as NULL. When working in this mode the function doesn't allocate MURAM. + */ +int dpa_classif_set_update_hm(const struct dpa_cls_hm_update_params + *update_params, int next_hmd, int *hmd, bool chain_head, + const struct dpa_cls_hm_update_resources *res); + +/* + * Modify the parameters of an existing update header manipulation. + * + * [modify_flags] is a combination of flags indicating which header manipulation + * attributes to modify (and hence indicating which of the attributes in the + * [new_update_params] data structure are valid). Select the flag values from + * the dpa_cls_hm_update_modify_flags enum and combine them using the "or" + * logical operand. + */ +int dpa_classif_modify_update_hm(int hmd, + const struct dpa_cls_hm_update_params *new_update_params, + int modify_flags); + +/* + * Creates or imports a VLAN specific header manipulation (either ingress or + * egress) object. + * + * If the [res] parameter is provided, the function will import the low level + * driver resources specified therein rather than create them. In this case the + * [fm_pcd] handle in the parameters structure is not used and can be provided + * as NULL. When working in this mode the function doesn't allocate MURAM. + */ +int dpa_classif_set_vlan_hm(const struct dpa_cls_hm_vlan_params *vlan_params, + int next_hmd, + int *hmd, + bool chain_head, + const struct dpa_cls_hm_vlan_resources *res); + +/* + * Modify the parameters of an existing VLAN specific header manipulation. + * + * [modify_flags] is a combination of flags indicating which header manipulation + * attributes to modify (and hence indicating which of the attributes in the + * [new_vlan_params] data structure are valid). Select the flag values from the + * dpa_cls_hm_vlan_modify_flags enum and combine them using the "or" logical + * operand. + */ +int dpa_classif_modify_vlan_hm(int hmd, + const struct dpa_cls_hm_vlan_params *new_vlan_params, int modify_flags); + +/* + * Creates or imports a MPLS specific header manipulation object. + * + * If the [res] parameter is provided, the function will import the low level + * driver resources specified therein rather than create them. In this case the + * [fm_pcd] handle in the parameters structure is not used and can be provided + * as NULL. When working in this mode the function doesn't allocate MURAM. + */ +int dpa_classif_set_mpls_hm(const struct dpa_cls_hm_mpls_params *mpls_params, + int next_hmd, + int *hmd, + bool chain_head, + const struct dpa_cls_hm_mpls_resources *res); + +/* + * Modify the parameters of an existing MPLS specific header manipulation. + * + * [modify_flags] is a combination of flags indicating which header manipulation + * attributes to modify (and hence indicating which of the attributes in the + * [new_mpls_params] data structure are valid). Select the flag values from the + * dpa_cls_hm_mpls_modify_flags enum and combine them using the "or" logical + * operand. + */ +int dpa_classif_modify_mpls_hm(int hmd, + const struct dpa_cls_hm_mpls_params *new_mpls_params, int modify_flags); + +/* + * Releases a header manipulation object and frees up all related resources + * allocated for it. The header manipulation operations must be removed in the + * reverse order they were created in (i.e. starting with the header + * manipulation chain head and working towards the tail). + */ +int dpa_classif_free_hm(int hmd); + + +/* + * Multicast API + */ + +/* + * Multicast group parameters + */ +struct dpa_cls_mcast_group_params { + /* + * Maximum number of members in group + */ + uint8_t max_members; + + /* + * Handle of the FM PCD that owns the Cc node that will + * point to the group + */ + void *fm_pcd; + + /* + * Member parameters. A group must have at least + * one member + */ + struct dpa_cls_tbl_enq_action_desc first_member_params; + + /* + * Number of members that already exist in the imported group + */ + unsigned int prefilled_members; + + /* + * External distribution handle. When provided, replicated frames + * are not enqueued to members' frame queues. They are sent to this + * distribution. + */ + void *distribution; + + /* + * Handle to a FMan classification to send frames after distribution + */ + void *classification; +}; + +/* Multicast group external resource */ +struct dpa_cls_mcast_group_resources { + /* + * Multicast group handle used when importing an external group node + */ + void *group_node; +}; + +/* + * Creates a multicast group with one member + */ +int dpa_classif_mcast_create_group( + const struct dpa_cls_mcast_group_params *group_params, + int *grpd, + const struct dpa_cls_mcast_group_resources *res); + +/* + * Adds a new member to a multicast group + */ +int dpa_classif_mcast_add_member(int grpd, + const struct dpa_cls_tbl_enq_action_desc *member_params, + int *md); + +/* + * Removes a member from a multicast group + */ +int dpa_classif_mcast_remove_member(int grpd, int md); + +/* + * Removes an existing group + */ +int dpa_classif_mcast_free_group(int grpd); + + +#endif /* __FSL_DPA_CLASSIFIER_H */ diff --git a/include/linux/fsl_dpa_ipsec.h b/include/linux/fsl_dpa_ipsec.h new file mode 100644 index 0000000..63e8601 --- /dev/null +++ b/include/linux/fsl_dpa_ipsec.h @@ -0,0 +1,638 @@ +/* Copyright 2008-2012 Freescale Semiconductor, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * DPA-IPSec Application Programming Interface. + */ + +#ifndef __FSL_DPA_IPSEC_H +#define __FSL_DPA_IPSEC_H + +#include "fsl_dpa_classifier.h" + +/* General DPA-IPSec defines */ +#define IP_PROTO_FIELD_LEN 1 +#define ESP_SPI_FIELD_LEN 4 +#define PORT_FIELD_LEN 2 +#define ICMP_HDR_FIELD_LEN 1 +#define DSCP_FIELD_LEN_IPv4 1 +/* + * In order to extract Traffic Class in case of IPv6, the keygen will add two + * bytes to the key, which hold: IPv6 version(4bits), TC(8bits) and 4 bits zero. + */ +#define DSCP_FIELD_LEN_IPv6 2 + +#define MAX_SIZE_IP_UDP_SPI_KEY \ + (1 * DPA_OFFLD_IPv6_ADDR_LEN_BYTES + \ + IP_PROTO_FIELD_LEN + \ + 2 * PORT_FIELD_LEN + \ + ESP_SPI_FIELD_LEN) + +#define MAX_SIZE_IP_UDP_SPI_KEY_IPV4 \ + (1 * DPA_OFFLD_IPv4_ADDR_LEN_BYTES + \ + IP_PROTO_FIELD_LEN + \ + 2 * PORT_FIELD_LEN + \ + ESP_SPI_FIELD_LEN) + +#define MAX_SIZE_POLICY_KEY \ + (2 * DPA_OFFLD_IPv6_ADDR_LEN_BYTES + \ + IP_PROTO_FIELD_LEN + \ + 2 * PORT_FIELD_LEN) + +#define MAX_SIZE_POLICY_KEY_IPV4 \ + (2 * DPA_OFFLD_IPv4_ADDR_LEN_BYTES + \ + IP_PROTO_FIELD_LEN + \ + 2 * PORT_FIELD_LEN) + + +#define DPA_IPSEC_MAX_IV_LEN 16 /* Maximum length of IV(in bytes) */ +#define DPA_IPSEC_MAX_POL_PER_SA 255 /* Maximum supported number of + * policies per SA */ + +/* + * IPSec Special Operations + */ +#define DPA_IPSEC_HDR_COPY_TOS 0x01 /* Copy TOS / DiffServ byte from + * inner / outer header to outer / + * inner header */ +#define DPA_IPSEC_HDR_COPY_DF 0x02 /* Copy DF bit from outer header + * to outer / inner header */ +#define DPA_IPSEC_HDR_DEC_TTL 0x04 /* Automatically decrment the TTL + * value in the inner / outer hdr*/ +#define DPA_IPSEC_HDR_COPY_DSCP 0x08 /* Copy DSCP bits from inner / + * outer header to outer / inner + * header */ +#define DPA_IPSEC_HDR_COPY_ECN 0x10 /* Copy ECN bits from inner / + * outer header to outer / inner + * header */ + +#define DPA_IPSEC_KEY_FIELD_SIP 0x01 /* Use source IP address in key */ +#define DPA_IPSEC_KEY_FIELD_DIP 0x02 /* Use destination IP in key */ +#define DPA_IPSEC_KEY_FIELD_PROTO 0x04 /* Use IP protocol field in key */ +#define DPA_IPSEC_KEY_FIELD_DSCP 0x08 /* Use DSCP field in key */ +#define DPA_IPSEC_KEY_FIELD_SPORT 0x10 /* Use source port in key */ +#define DPA_IPSEC_KEY_FIELD_ICMP_TYPE 0x10 /* Use ICMP type field in key */ +#define DPA_IPSEC_KEY_FIELD_DPORT 0x20 /* Use destination port in key */ +#define DPA_IPSEC_KEY_FIELD_ICMP_CODE 0x20 /* Use ICMP code field in key */ +#define DPA_IPSEC_MAX_KEY_FIELDS 6 /* Maximum key components */ + +#define DPA_IPSEC_DEF_PAD_VAL 0xAA /* Value to be used as padding in + * classification keys */ + +/* DPA-IPSec Supported Protocols (for policy offloading) */ +enum dpa_ipsec_proto { + DPA_IPSEC_PROTO_TCP_IPV4 = 0, + DPA_IPSEC_PROTO_TCP_IPV6, + DPA_IPSEC_PROTO_UDP_IPV4, + DPA_IPSEC_PROTO_UDP_IPV6, + DPA_IPSEC_PROTO_ICMP_IPV4, + DPA_IPSEC_PROTO_ICMP_IPV6, + DPA_IPSEC_PROTO_SCTP_IPV4, + DPA_IPSEC_PROTO_SCTP_IPV6, + DPA_IPSEC_PROTO_ANY_IPV4, + DPA_IPSEC_PROTO_ANY_IPV6, + DPA_IPSEC_MAX_SUPPORTED_PROTOS +}; + +/* DPA IPSec supported types of SAs */ +enum dpa_ipsec_sa_type { + DPA_IPSEC_SA_IPV4 = 0, + DPA_IPSEC_SA_IPV4_NATT, + DPA_IPSEC_SA_IPV6, + DPA_IPSEC_MAX_SA_TYPE +}; + +/* + * DPA-IPSec Post SEC Data Offsets. 1 BURST = 32 or 64 bytes + * depending on SEC configuration. Default BURST size = 64 bytes + */ +enum dpa_ipsec_data_off { + DPA_IPSEC_DATA_OFF_NONE = 0, + DPA_IPSEC_DATA_OFF_1_BURST, + DPA_IPSEC_DATA_OFF_2_BURST, + DPA_IPSEC_DATA_OFF_3_BURST +}; + +/* DPA IPSec outbound policy lookup table parameters */ +struct dpa_ipsec_pol_table { + int dpa_cls_td; /* DPA Classifier table descriptor */ + uint8_t key_fields; /* Flags indicating policy key components. + * (use DPA_IPSEC_KEY_FIELD* macros to configure) */ +}; + +/* DPA-IPSec Pre-Sec Inbound Parameters */ +struct dpa_ipsec_pre_sec_in_params { + int dpa_cls_td[DPA_IPSEC_MAX_SA_TYPE]; /* SA lookup tables descriptors*/ +}; + +/* DPA-IPSec Pre-Sec Outbound Parameters */ +struct dpa_ipsec_pre_sec_out_params { + /* Oubound policy lookup tables parameters */ + struct dpa_ipsec_pol_table table[DPA_IPSEC_MAX_SUPPORTED_PROTOS]; +}; + +/* DPA-IPSec Post-Sec-Inbound Parameters */ +struct dpa_ipsec_post_sec_in_params { + enum dpa_ipsec_data_off data_off;/*Data offset in the decrypted buffer*/ + uint16_t qm_tx_ch; /* QMan channel of the post decryption OH port */ + int dpa_cls_td; /* Index table descriptor */ + bool do_pol_check; /* Enable inbound policy verification */ + uint8_t key_fields; /* Flags indicating policy key components. + * (use DPA_IPSEC_KEY_FIELD* macros to configure) + * Relevant only if do_pol_check = TRUE */ + bool use_ipv6_pol; /* Activate support for IPv6 policies. Allows + * better MURAM management. Relevant only if + * do_pol_check = TRUE */ + uint16_t base_flow_id; /* The start value of the range of flow ID values + * used by this instance in post decryption */ +}; + +/* DPA-IPSec Post-Sec-Inbound Parameters */ +struct dpa_ipsec_post_sec_out_params { + enum dpa_ipsec_data_off data_off;/*Data offset in the decrypted buffer*/ + uint16_t qm_tx_ch; /* QMan channel of the post encrytion OH port */ +}; + +/* DPA IPSec FQID range parameters */ +struct dpa_ipsec_fqid_range { + uint32_t start_fqid; + uint32_t end_fqid; +}; + +/* IPsec parameters used to configure the DPA IPsec instance */ +struct dpa_ipsec_params { + struct dpa_ipsec_pre_sec_in_params pre_sec_in_params; + struct dpa_ipsec_post_sec_in_params post_sec_in_params; + struct dpa_ipsec_pre_sec_out_params pre_sec_out_params; + struct dpa_ipsec_post_sec_out_params post_sec_out_params; + void *fm_pcd; /* Handle of the PCD object */ + uint16_t qm_sec_ch; /* QMan channel# for the SEC */ + uint16_t max_sa_pairs; /* Maximum number of SA pairs + * (1 SA Pair = 1 In SA + 1 Out SA) */ + + /* + * Maximum number of special IPSec + * manipulation operations that can be + * enabled. eg DSCP/ECN update, IP variable + * length. The max_sa_manip_ops + * should be incremented with the number + * of manipulations per every outbound + * policy + */ + uint32_t max_sa_manip_ops; + struct dpa_ipsec_fqid_range *fqid_range; /* FQID range to be used by + * DPA IPSec for allocating + * FQIDs for internal FQs */ + uint8_t ipf_bpid; /* Scratch buffer pool for IP Frag. */ +}; + +/* Initialize a DPA-IPSec instance. */ +int dpa_ipsec_init(const struct dpa_ipsec_params *params, int *dpa_ipsec_id); + +/* Free a DPA-IPSec instance */ +int dpa_ipsec_free(int dpa_ipsec_id); + +/* DPA-IPSec data flow source specification */ +enum dpa_ipsec_direction { + DPA_IPSEC_INBOUND = 0, /* Inbound */ + DPA_IPSEC_OUTBOUND /* Outbound */ +}; + +/* DPA-IPSec Supported Cipher Suites */ +enum dpa_ipsec_cipher_alg { + DPA_IPSEC_CIPHER_ALG_3DES_CBC_HMAC_96_MD5_128, + DPA_IPSEC_CIPHER_ALG_3DES_CBC_HMAC_96_SHA_160, + DPA_IPSEC_CIPHER_ALG_3DES_CBC_HMAC_MD5_128, + DPA_IPSEC_CIPHER_ALG_3DES_CBC_HMAC_SHA_160, + DPA_IPSEC_CIPHER_ALG_3DES_CBC_HMAC_SHA_256_128, + DPA_IPSEC_CIPHER_ALG_3DES_CBC_HMAC_SHA_384_192, + DPA_IPSEC_CIPHER_ALG_3DES_CBC_HMAC_SHA_512_256, + DPA_IPSEC_CIPHER_ALG_NULL_ENC_HMAC_96_MD5_128, + DPA_IPSEC_CIPHER_ALG_NULL_ENC_HMAC_96_SHA_160, + DPA_IPSEC_CIPHER_ALG_NULL_ENC_AES_XCBC_MAC_96, + DPA_IPSEC_CIPHER_ALG_NULL_ENC_HMAC_MD5_128, + DPA_IPSEC_CIPHER_ALG_NULL_ENC_HMAC_SHA_160, + DPA_IPSEC_CIPHER_ALG_NULL_ENC_HMAC_SHA_256_128, + DPA_IPSEC_CIPHER_ALG_NULL_ENC_HMAC_SHA_384_192, + DPA_IPSEC_CIPHER_ALG_NULL_ENC_HMAC_SHA_512_256, + DPA_IPSEC_CIPHER_ALG_AES_CBC_HMAC_96_MD5_128, + DPA_IPSEC_CIPHER_ALG_AES_CBC_HMAC_96_SHA_160, + DPA_IPSEC_CIPHER_ALG_AES_CBC_AES_XCBC_MAC_96, + DPA_IPSEC_CIPHER_ALG_AES_CBC_HMAC_MD5_128, + DPA_IPSEC_CIPHER_ALG_AES_CBC_HMAC_SHA_160, + DPA_IPSEC_CIPHER_ALG_AES_CBC_HMAC_SHA_256_128, + DPA_IPSEC_CIPHER_ALG_AES_CBC_HMAC_SHA_384_192, + DPA_IPSEC_CIPHER_ALG_AES_CBC_HMAC_SHA_512_256, + DPA_IPSEC_CIPHER_ALG_AES_CTR_HMAC_96_MD5_128, + DPA_IPSEC_CIPHER_ALG_AES_CTR_HMAC_96_SHA_160, + DPA_IPSEC_CIPHER_ALG_AES_CTR_AES_XCBC_MAC_96, + DPA_IPSEC_CIPHER_ALG_AES_CTR_HMAC_MD5_128, + DPA_IPSEC_CIPHER_ALG_AES_CTR_HMAC_SHA_160, + DPA_IPSEC_CIPHER_ALG_AES_CTR_HMAC_SHA_256_128, + DPA_IPSEC_CIPHER_ALG_AES_CTR_HMAC_SHA_384_192, + DPA_IPSEC_CIPHER_ALG_AES_CTR_HMAC_SHA_512_256 +}; + +/* DPA-IPSec Initialization Vector */ +struct dpa_ipsec_init_vector { + uint8_t *init_vector; /* Pointer to the initialization vector */ + uint8_t length; /* Length in bytes. May be 8 or 16 bytes */ +}; + +/* DPA IPSEC Anti Replay Window Size */ +enum dpa_ipsec_arw { + DPA_IPSEC_ARSNONE = 0, /* No Anti Replay Protection */ + DPA_IPSEC_ARS32 = 1, /* 32 bit Anti Replay Window size */ + DPA_IPSEC_ARS64 = 3, /* 64 bit Anti Replay Window size */ +}; + +/* DPA-IPSec Security Association Cryptographic Parameters */ +struct dpa_ipsec_sa_crypto_params { + enum dpa_ipsec_cipher_alg alg_suite; /* Algorithm suite specifying + * encryption and authentication + * algorithms to be used */ + uint8_t *cipher_key; /* Address of the encryption key */ + uint8_t cipher_key_len; /* Length of the encryption key in bytes */ + uint8_t *auth_key; /* Address of the authentication key */ + uint8_t auth_key_len; /* Length of the authentication key in bytes */ +}; + +/* DPA-IPSec SA Modes */ +enum dpa_ipsec_sa_mode { + DPA_IPSEC_SA_MODE_TUNNEL = 0, + DPA_IPSEC_SA_MODE_TRANSPORT +}; + +/* DPA-IPSec SA Protocols */ +enum dpa_ipsec_sa_proto { + DPA_IPSEC_SA_PROTO_ESP = 0, + DPA_IPSEC_SA_PROTO_AH +}; + +/* DPA-IPSec Security Association Out Parameters */ +struct dpa_ipsec_sa_out_params { + /* + * Initialization vector (IV). Null for using the internal random + * number generator + */ + struct dpa_ipsec_init_vector *init_vector; + unsigned int ip_ver; /* IPv4 or IPv6 address type */ + uint16_t ip_hdr_size; /* IP header size including any IP options */ + void *outer_ip_header; /* IP encapsulation header */ + /* UDP encapsulation header (for SAs using NAT-T) */ + void *outer_udp_header; + /* Flow ID used to mark frames encrypted using this SA */ + uint16_t post_sec_flow_id; + uint8_t dscp_start; /* DSCP range start value; ignored if the DSCP + * selector wasn't enabled for this SA */ + uint8_t dscp_end; /* DSCP range end value; ignored if the DSCP + * selector wasn't enabled for this SA */ +}; + +/* DPA-IPSec Security Association In Parameters */ +struct dpa_ipsec_sa_in_params { + enum dpa_ipsec_arw arw; /* Anti replay window */ + bool use_var_iphdr_len; /* Enable variable IP header length support */ + struct dpa_offload_ip_address src_addr; /* Source IP address */ + struct dpa_offload_ip_address dest_addr; /* Destination IP address */ + bool use_udp_encap; /* NAT-T is activated (UDP encapsulated ESP) */ + uint16_t src_port; /* Source UDP port (UDP encapsulated ESP) */ + uint16_t dest_port; /* Destination UDP port (UDP encapsulated ESP)*/ + /* Action for frames that fail inbound policy verification */ + struct dpa_cls_tbl_action policy_miss_action; + /* + * Action to be performed on the frames after inbound IPSec processing + * is completed + */ + struct dpa_cls_tbl_action post_ipsec_action; +}; + +/* DPA-IPSec Security Association Parameters */ +struct dpa_ipsec_sa_params { + uint32_t spi; /* IPSec Security parameter index */ + bool use_ext_seq_num; /* Enable extended sequence number */ + uint64_t start_seq_num; /* Sequence number to start with */ + uint32_t l2_hdr_size; /* Size of the Ethernet header, including any + * VLAN information. */ + enum dpa_ipsec_sa_mode sa_mode; /* Tunnel or transport mode selection */ + enum dpa_ipsec_sa_proto sa_proto; /* Protocol to be used (AH or ESP)- + * Only ESP supported currently */ + uint8_t hdr_upd_flags; /* Flags for propagating information from inner + * to outer header and vice versa */ + uint8_t sa_wqid; /* Work queue Id for all the queues in this SA*/ + uint8_t sa_bpid; /* Buffer Pool ID to be used with this SA */ + uint16_t sa_bufsize; /* Buffer Pool buffer size */ + bool enable_stats; /* Enable counting packets and bytes processed*/ + /* + * Enable extended statistics per SA, beside counting IPSec processed + * packets the dpa offload will also count the input packets that + * require IPSec processing. + */ + bool enable_extended_stats; + struct dpa_ipsec_sa_crypto_params crypto_params;/* IPSec crypto params*/ + enum dpa_ipsec_direction sa_dir; /* SA direction: Outbound/Inbound */ + union { + struct dpa_ipsec_sa_in_params sa_in_params; /* Inb SA params */ + struct dpa_ipsec_sa_out_params sa_out_params; /* Out SA params*/ + }; +}; + +/* DPA-IPSEC Rekeying error callback */ +typedef int (*dpa_ipsec_rekey_event_cb) (int dpa_ipsec_id, int sa_id, + int error); + +/* Offload an SA. */ +int dpa_ipsec_create_sa(int dpa_ipsec_id, + struct dpa_ipsec_sa_params *sa_params, int *sa_id); + +/* This function will be used when rekeying a SA. + * - The new SA will inherit the old SA's policies. + * - To SEC FQ of the new SA will be created in parked mode and + * will be scheduled after the to SEC FQ of the old SA is empty, + * exception only when auto_rmv_old_sa if false. + * This will ensure the preservation of the frame order. + * - To SEC FQ of the old SA will be retired and destroyed when it + * has no purpose. + * - Memory allocated for old SA will be returned to the SA memory pool + * - auto_rmv_old_sa + * - relevant only for an inbound SA. + * - if true: + * - the old SA will be removed automatically when + * encrypted traffic starts flowing on the new SA + * - the new SA is not scheduled until traffic arrives on + * its TO SEC FQ. + * - if false: + * - the old and new SA will be active in the same time. + * - the old SA has to be removed using the + * dpa_ipsec_remove_sa function when the hard SA + * expiration time limit is reached + * - Since the difference between soft and hard limit + * can be several seconds it is required to schedule the + * TO SEC FQ of the new SA. + * + * - rekey_event_cb (UNUSED parameter) + */ +int dpa_ipsec_sa_rekeying(int sa_id, + struct dpa_ipsec_sa_params *sa_params, + dpa_ipsec_rekey_event_cb rekey_event_cb, + bool auto_rmv_old_sa, int *new_sa_id); + +/* + * Disables a SA before removal (no more packets will be processed + * using this SA). The resource associated with this SA are not + * freed until dpa_ipsec_remove_sa is called. + */ +int dpa_ipsec_disable_sa(int sa_id); + +/* Unregister a SA and destroys the accelerated path. */ +int dpa_ipsec_remove_sa(int sa_id); + +/* + * This function will remove all SAs (in a specified DPA IPSec + * instance)that were offloaded using the DPA IPsec API + */ +int dpa_ipsec_flush_all_sa(int dpa_ipsec_id); + +struct dpa_ipsec_l4_params { + uint16_t src_port; /* Source port */ + uint16_t src_port_mask; /* Source port mask */ + uint16_t dest_port; /* Destination port */ + uint16_t dest_port_mask;/* Destination port mask */ +}; + +struct dpa_ipsec_icmp_params { + uint8_t icmp_type; /* Type of ICMP message */ + uint8_t icmp_type_mask; /* Mask for ICMP type field */ + uint8_t icmp_code; /* ICMP message code */ + uint8_t icmp_code_mask; /* Mask for ICMP code field */ +}; + +/* DPA IPSec direction specific policy params types */ +enum dpa_ipsec_pol_dir_params_type { + /* + * No direction specific params + */ + DPA_IPSEC_POL_DIR_PARAMS_NONE = 0, + + /* + * Fragmentation or header manipulation + * params (outbound policies only) + */ + DPA_IPSEC_POL_DIR_PARAMS_MANIP, + + /* + * Action params (inbound policies only) + */ + DPA_IPSEC_POL_DIR_PARAMS_ACT +}; + +/* DPA IPSec direction specific parameters for Security Policies */ +struct dpa_ipsec_pol_dir_params { + enum dpa_ipsec_pol_dir_params_type type; + union { + /* + * Manipulation descriptor for fragmentation or + * header manipulation + */ + int manip_desc; + struct dpa_cls_tbl_action in_action; /* Action to be performed + * for frames matching + * the policy selectors */ + }; +}; + +/* DPA-IPSec Security Policy Parameters */ +struct dpa_ipsec_policy_params { + struct dpa_offload_ip_address src_addr; /* Source IP address */ + uint8_t src_prefix_len; /* Source network prefix */ + struct dpa_offload_ip_address dest_addr; /**< Destination IP address */ + uint8_t dest_prefix_len; /* Destination network prefix */ + uint8_t protocol; /* Protocol */ + bool masked_proto; /* Mask the entire protocol field */ + bool use_dscp; /* Enable DSCP value in policy selector */ + union { + struct dpa_ipsec_l4_params l4; /* L4 protos params */ + struct dpa_ipsec_icmp_params icmp; /* ICMP proto params */ + }; + struct dpa_ipsec_pol_dir_params dir_params; + int priority; /* Policy priority */ +}; + +/* Add a new rule for policy verification / lookup. */ +int dpa_ipsec_sa_add_policy(int sa_id, + struct dpa_ipsec_policy_params *policy_params); + +/* Removes a rule for policy verification / lookup. */ +int dpa_ipsec_sa_remove_policy(int sa_id, + struct dpa_ipsec_policy_params *policy_params); + +/* + * Retrieves all the policies linked to the specified SA. In order + * to determine the size of the policy_params array, the function + * must first be called with policy_params = NULL. In this case it + * will only return the number of policy entries linked to the SA. + * num_pol must not be greater than DPA_IPSEC_MAX_POL_PER_SA + */ +int dpa_ipsec_sa_get_policies(int sa_id, + struct dpa_ipsec_policy_params *policy_params, + int *num_pol); + +/* This function will remove all policies associated with the specified SA */ +int dpa_ipsec_sa_flush_policies(int sa_id); + +/* DPA-IPSec SA Statistics */ +struct dpa_ipsec_sa_stats { + uint32_t packets_count; /* Number of IPSec processed packets */ + uint32_t bytes_count; /* Number of IPSec processed bytes */ + /* + * Number of packets which required IPSec processing + * for inbound SA: number of packets received + * for outbound SA: number of packets sent + */ + uint32_t input_packets; +}; + +/* DPA-IPSec Global Statistics */ +struct dpa_ipsec_stats { + /* Packets that missed inbound SA lookup */ + uint32_t inbound_miss_pkts; + + /* Bytes that missed inbound SA lookup */ + uint32_t inbound_miss_bytes; + + /* Packets that missed outbound policy lookup */ + uint32_t outbound_miss_pkts; + + /* Bytes that missed outbound policy lookup */ + uint32_t outbound_miss_bytes; +}; + +/* This function will populate sa_stats with SEC statistics for SA with sa_id */ +int dpa_ipsec_sa_get_stats(int sa_id, struct dpa_ipsec_sa_stats *sa_stats); + +/* Return IPSec global statistics in the "stats" data structure */ +int dpa_ipsec_get_stats(int dpa_ipsec_id, struct dpa_ipsec_stats *stats); + +enum dpa_ipsec_sa_modify_type { + DPA_IPSEC_SA_MODIFY_ARS = 0, /* Set the anti replay window size */ + DPA_IPSEC_SA_MODIFY_SEQ_NUM, /* Set the sequence number for this SA */ + DPA_IPSEC_SA_MODIFY_EXT_SEQ_NUM, /* Set the extended sequence number */ + DPA_IPSEC_SA_MODIFY_CRYPTO /* Reset the crypto algorithms for this SA */ +}; + +struct dpa_ipsec_sa_modify_prm { + + /* Use to select a modify operation */ + enum dpa_ipsec_sa_modify_type type; + + union { + /* Anti replay window size */ + enum dpa_ipsec_arw arw; + + /* + * 32 bit or extended sequence number depending on how the + * SA was created by dpa_ipsec_create_sa + * Only the least significant word is used for 32 bit SEQ + */ + uint64_t seq_num; + + /* New cryptographic parameters for this SA */ + struct dpa_ipsec_sa_crypto_params crypto_params; + }; +}; + +/* + * Modify an SA asynchronous + * + * SEC will dequeue a frame with RDJ, run it and after this create an + * output frame with status of user error. The frame will have always the + * length of 5 bytes, first one representing the operation code that has + * finished and the next 4 will determine the SA id on which the operation took + * place. + * + * Returned error code: + * 0 if successful; + * -EBUSY if can't acquire lock for this SA + * -EINVAL if input parameters are wrong + * -ENXIO if failed to DMA map Replacement Job Descriptor or SHD + * -ETXTBSY if failed to enqueue to SEC the FD with RJD + * -EALREADY if ARS is already set to the required value + * + */ +int dpa_ipsec_sa_modify(int sa_id, struct dpa_ipsec_sa_modify_prm *modify_prm); + +/* + * Request the sequence number of an SA asynchronous + * + * SEC will dequeue a frame with RJD, run it and after this create an + * output frame with status of user error. The frame will have always the + * length of 5 bytes, first one representing the operation code that has + * finished and the next 4 will determine the SA id on which the operation took + * place. + * + * + * Returned error code: + * 0 if successful; + * -EBUSY if can't acquire lock for this SA + * -ENXIO if failed to DMA map Replacement Job Descriptor + * -ETXTBSY if failed to enqueue to SEC the FD with RJD + */ +int dpa_ipsec_sa_request_seq_number(int sa_id); + +int dpa_ipsec_sa_get_seq_number(int sa_id, uint64_t *seq); + +/* + * The dpa_ipsec_sa_modify and dpa_ipsec_sa_get_seq_number are asynchronous + * operations. + * + * When finished the frame exiting the SEC will have the status + * of user error and inside the frame (total length 5 bytes) the first byte will + * be the code of the operation that has finished followed by the SA id in the + * next 4 bytes. + * + * Use this enumeration to know what asynchronous operation has finished and on + * what SA. + */ +enum dpa_ipsec_sa_operation_code { + DPA_IPSEC_SA_MODIFY_ARS_DONE = 0, + DPA_IPSEC_SA_MODIFY_SEQ_NUM_DONE, + DPA_IPSEC_SA_MODIFY_EXT_SEQ_NUM_DONE, + DPA_IPSEC_SA_MODIFY_CRYPTO_DONE, + DPA_IPSEC_SA_GET_SEQ_NUM_DONE +}; + +/* + * Get frame queue id to IPSec for a specified SA in order to bypass outbound + * policy lookup and directly apply IPSec processing. + */ +int dpa_ipsec_sa_get_out_path(int sa_id, uint32_t *fqid); + +#endif /* __FSL_DPA_IPSEC_H */ diff --git a/include/linux/fsl_dpa_offload.h b/include/linux/fsl_dpa_offload.h new file mode 100644 index 0000000..b5f4e6e --- /dev/null +++ b/include/linux/fsl_dpa_offload.h @@ -0,0 +1,175 @@ + +/* Copyright 2008-2012 Freescale Semiconductor, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * DPA Offloading Driver General Data Types. + */ + +#ifndef __FSL_DPA_OFFLOAD_H +#define __FSL_DPA_OFFLOAD_H + + +#include <linux/if_ether.h> +#include <linux/ip.h> + + +/* General definitions */ +#define DPA_OFFLD_IPv4_ADDR_LEN_BYTES 4 +#define DPA_OFFLD_IPv6_ADDR_LEN_BYTES 16 +#define DPA_OFFLD_IPv6_ADDR_LEN_WORDS 4 +#define DPA_OFFLD_IPv6_ADDR_LEN_LONG 2 + +/* Maximum size of a lookup key, in bytes */ +#define DPA_OFFLD_MAXENTRYKEYSIZE 56 + +#define DPA_OFFLD_DESC_NONE -1 +#define DPA_OFFLD_INVALID_OBJECT_ID -1 + +#define log_err(...) \ + do { \ + pr_err("Error - %s:%d (%s)\n", \ + __FILE__, __LINE__, __func__); \ + pr_err(__VA_ARGS__); \ + } while (0); + +#define log_warn(...) \ + do { \ + pr_warn("Warning - %s:%d (%s)\n", \ + __FILE__, __LINE__, __func__); \ + pr_warn(__VA_ARGS__); \ + } while (0); + + +/* Description of lookup key */ +struct dpa_offload_lookup_key { + + /* + * The data (bytes) of the key. For indexed tables the index is the + * first byte of this array + */ + uint8_t *byte; + + /* + * The mask of the key. The bits corresponding to zeros in the mask are + * ignored. NULL is the table doesn't have the mask support enabled. + */ + uint8_t *mask; + + /* + * The size of the key in bytes. Must not exceed + * DPA_OFFLD_MAXENTRYKEYSIZE + */ + uint8_t size; +}; + +/* Description of the IPv4 address */ +union dpa_offload_ipv4_address { + /* Address as 32bit word */ + uint32_t word; + + /* Address as byte array*/ + uint8_t byte[DPA_OFFLD_IPv4_ADDR_LEN_BYTES]; +}; + +/* Description of the IPv6 address */ +union dpa_offload_ipv6_address { + /* Address as byte array*/ + uint8_t byte[DPA_OFFLD_IPv6_ADDR_LEN_BYTES]; + + /* Address as word array */ + uint32_t word[DPA_OFFLD_IPv6_ADDR_LEN_WORDS]; + + /* Address as long word */ + uint64_t lword[DPA_OFFLD_IPv6_ADDR_LEN_LONG]; +}; + +struct dpa_offload_ip_address { + /* + * IP version. Must be either 4 or 6. No other values are considered + * valid. + */ + unsigned int version; + + union { + union dpa_offload_ipv4_address ipv4; + union dpa_offload_ipv6_address ipv6; + } addr; +}; + +/* Description of the well known PPPoE header */ +struct pppoe_header { + uint8_t version:4; /* Protocol version */ + uint8_t type:4; /* Type */ + uint8_t code; /* Packet type code */ + uint16_t sid; /* Session Id */ + uint16_t length; /* Payload size */ +}; + +/* Description of the MPLS header */ +struct mpls_header { + uint32_t label:20; /* Label value */ + uint32_t exp:3; /* Experimental */ + uint32_t s:1; /* Bottom of stack */ + uint32_t ttl:8; /* Time to live */ +}; + +/* Description of the IPv6 header */ +struct ipv6_header { + uint32_t version:4; /* Version */ + uint32_t tc:8; /* Traffic Class */ + uint32_t flow_label:20; /* Label */ + uint16_t payload_len; /* Payload size */ + uint8_t next_hdr; /* Next protocol */ + uint8_t hop_limit; /* Hop Limit */ + union dpa_offload_ipv6_address ipsa; /* Source address */ + union dpa_offload_ipv6_address ipda; /* Destination addr */ +}; + +struct ipv4_header { + /* IPv4 header */ + struct iphdr header; + + /* IPv4 options buffer. NULL for no options. */ + uint8_t *options; + + /* Size of IPv4 options buffer. Zero for no options. */ + uint8_t options_size; +}; + +/* Description of the VLAN header */ +struct vlan_header { + uint16_t tpid; + uint16_t tci; +}; + + +#endif /* __FSL_DPA_OFFLOAD_H */ diff --git a/include/linux/fsl_dpa_stats.h b/include/linux/fsl_dpa_stats.h new file mode 100644 index 0000000..927b2c2 --- /dev/null +++ b/include/linux/fsl_dpa_stats.h @@ -0,0 +1,856 @@ +/* Copyright 2008-2012 Freescale Semiconductor, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * DPA Statistics Application Programming Interface. + */ + +#ifndef __FSL_DPA_STATS_H +#define __FSL_DPA_STATS_H + +/* DPA offloading layer includes */ +#include "fsl_dpa_offload.h" + +/* Other includes */ +#include <linux/types.h> + +/* Maximum number simultaneous counters requests */ +#define DPA_STATS_MAX_NUM_OF_REQUESTS 256 + +/* Maximum number of single and class counters */ +#define DPA_STATS_MAX_NUM_OF_COUNTERS 512 + +/* Maximum number of class counter members */ +#define DPA_STATS_MAX_NUM_OF_CLASS_MEMBERS 256 + +/* Number of bytes occupied by one counter selection */ +#define DPA_STATS_CNT_SEL_LEN 4 + +/* Maximum size occupied by storage area: 10 MB */ +#define DPA_STATS_MAX_STORAGE_AREA_SIZE (10 * (1 << 20)) + +/* Maximum number of counters that can be processed in a request. Each counter + * can be repeated a maximum of two times in a request */ +#define DPA_STATS_REQ_CNTS_IDS_LEN (2 * DPA_STATS_MAX_NUM_OF_COUNTERS) + +/* DPA Stats instance parameters */ +struct dpa_stats_params { + + /* Maximum number of counters managed by DPA Stats instance */ + unsigned int max_counters; + + /* Pointer to the memory area where the values of the counters + * will be written by the DPA Stats instance */ + void *storage_area; + + /* Length in bytes of the storage memory area (must be between + * DPA_STATS_CNT_SEL_LEN and DPA_STATS_MAX_STORAGE_AREA_SIZE) */ + unsigned int storage_area_len; +}; + +/* + * Callback used to notify the upper layer that the requested counters values + * were written in the storage area. The 'storage_area_offset' is the offset + * in the storage_area and the 'cnts_written' represents the number of counters + * successfully written. The 'bytes_written' parameter can have a positive value + * and in this case it's value the size of the memory area written or it can + * have a negative value and contain the code of the error that occurred. + */ +typedef void (*dpa_stats_request_cb)(int dpa_stats_id, + unsigned int storage_area_offset, + unsigned int cnts_written, + int bytes_written); + +/* DPA Stats Request parameters */ +struct dpa_stats_cnt_request_params { + /* Array of counter IDs to retrieve values for */ + int *cnts_ids; + + /* Size of array of counters to retrieve values for (must be between + * 1 and DPA_STATS_REQ_CNTS_IDS_LEN) */ + unsigned int cnts_ids_len; + + /* Reset counters after the retrieve operation */ + bool reset_cnts; + + /* Storage area offset, expressed in bytes */ + unsigned int storage_area_offset; +}; + +/* DPA Stats counter types */ +enum dpa_stats_cnt_type { + DPA_STATS_CNT_ETH = 0, /* Ethernet counter */ + DPA_STATS_CNT_REASS, /* IP Reassembly counter */ + DPA_STATS_CNT_FRAG, /* IP Fragmentation counter */ + DPA_STATS_CNT_POLICER, /* Policer counter */ + DPA_STATS_CNT_CLASSIF_TBL, /* Classification Table counter */ + DPA_STATS_CNT_CLASSIF_NODE, /* Classification Node counter */ + DPA_STATS_CNT_IPSEC, /* IPSec counter */ + DPA_STATS_CNT_TRAFFIC_MNG, /* Traffic Manager counter */ +#ifdef DPA_STATS_UNDER_CONSTRUCTION + DPA_STATS_CNT_RAPIDIO /* RapidIO counter */ +#endif +}; + +/* DPA Stats counter selection */ +enum dpa_stats_cnt_sel { + /* Total number of bytes */ + DPA_STATS_CNT_NUM_OF_BYTES = 0, + /* Total number of packets */ + DPA_STATS_CNT_NUM_OF_PACKETS, + /* Total number of bytes and total number of packets */ + DPA_STATS_CNT_NUM_ALL +}; + +/* DPA Stats Ethernet counter selection */ +enum dpa_stats_cnt_eth_sel { + /* Total number of dropped packets on receive */ + DPA_STATS_CNT_ETH_DROP_PKTS = 0x00000001, + /* Total number of received bytes of data */ + DPA_STATS_CNT_ETH_BYTES = 0x00000002, + /* Total number of received packets */ + DPA_STATS_CNT_ETH_PKTS = 0x00000004, + /* Total number of received broadcast packets */ + DPA_STATS_CNT_ETH_BC_PKTS = 0x00000008, + /* Total number of received multicast packets */ + DPA_STATS_CNT_ETH_MC_PKTS = 0x00000010, + /* Total number of received frames with alignment error or invalid FCS*/ + DPA_STATS_CNT_ETH_CRC_ALIGN_ERR = 0x00000020, + /* + * Total number of received packets that were + * less than 64 bytes and were well formed + */ + DPA_STATS_CNT_ETH_UNDERSIZE_PKTS = 0x00000040, + /* + * Total number of received packets that were above 1518 bytes + * (non-VLAN) or 1522 (VLAN) or above a configured maximum frame + * length and were well formed + */ + DPA_STATS_CNT_ETH_OVERSIZE_PKTS = 0x00000080, + /* + * Total number of received packets that were less than + * 64 bytes and had a bad FCS + */ + DPA_STATS_CNT_ETH_FRAGMENTS = 0x00000100, + /* + * Total number of received packets with size above 1518 bytes + * (non-VLAN) or 1522 (VLAN) or a configured maximum frame length + * and with an invalid FCS or an alignment error + */ + DPA_STATS_CNT_ETH_JABBERS = 0x00000200, + /* Total number of received packets with size below 64 bytes*/ + DPA_STATS_CNT_ETH_64BYTE_PKTS = 0x00000400, + /* Total number of received packets with size between 65 and 127bytes */ + DPA_STATS_CNT_ETH_65_127BYTE_PKTS = 0x00000800, + /* Total number of received packets with size between 128-255bytes */ + DPA_STATS_CNT_ETH_128_255BYTE_PKTS = 0x00001000, + /* Total number of received packets with size between 256-511bytes */ + DPA_STATS_CNT_ETH_256_511BYTE_PKTS = 0x00002000, + /* Total number of received packets with size between 512-1023bytes */ + DPA_STATS_CNT_ETH_512_1023BYTE_PKTS = 0x00004000, + /* Total number of received packets with size between 1024-1518bytes */ + DPA_STATS_CNT_ETH_1024_1518BYTE_PKTS = 0x00008000, + /* Total number of packets on transmit */ + DPA_STATS_CNT_ETH_OUT_PKTS = 0x00010000, + /* Total number of dropped packets on transmit */ + DPA_STATS_CNT_ETH_OUT_DROP_PKTS = 0x00020000, + /* Total number of transmitted bytes of data */ + DPA_STATS_CNT_ETH_OUT_BYTES = 0x00040000, + /* Total number of received frames with errors */ + DPA_STATS_CNT_ETH_IN_ERRORS = 0x00080000, + /* Total number of transmitted frames with errors */ + DPA_STATS_CNT_ETH_OUT_ERRORS = 0x00100000, + /* Total number of unicast packets on receive */ + DPA_STATS_CNT_ETH_IN_UNICAST_PKTS = 0x00200000, + /* Total number of unicast packets on transmit */ + DPA_STATS_CNT_ETH_OUT_UNICAST_PKTS = 0x00400000, + /* Select all counters */ + DPA_STATS_CNT_ETH_ALL = 0x00800000 +}; + +/* DPA Stats Ethernet id */ +enum dpa_stats_cnt_eth_id { + DPA_STATS_ETH_1G_PORT0 = 0, /* 1G port, ETH id 0 */ + DPA_STATS_ETH_1G_PORT1, /* 1G port, ETH id 1 */ + DPA_STATS_ETH_1G_PORT2, /* 1G port, ETH id 2 */ + DPA_STATS_ETH_1G_PORT3, /* 1G port, ETH id 3 */ + DPA_STATS_ETH_1G_PORT4, /* 1G port, ETH id 4 */ + DPA_STATS_ETH_1G_PORT5, /* 1G port, ETH id 5 */ + DPA_STATS_ETH_10G_PORT0, /* 10G port, ETH id 0 */ + DPA_STATS_ETH_10G_PORT1 /* 10G port, ETH id 1 */ +}; + +/* DPA Stats Ethernet counter source definition */ +struct dpa_stats_cnt_eth_src { + /* Index of the engine device the Ethernet interface belongs to */ + uint8_t engine_id; + + /* Index of the Ethernet interface, relative to the engine */ + enum dpa_stats_cnt_eth_id eth_id; +}; + +/* DPA Stats Ethernet counter parameters */ +struct dpa_stats_cnt_eth { + /* Ethernet counter source */ + struct dpa_stats_cnt_eth_src src; + + /* + * Single or multiple selections of Ethernet counters + * from enumeration dpa_stats_cnt_eth_sel + */ + uint32_t cnt_sel; +}; + +/* + * DPA Stats IP Reassembly selection of counters that provide + * common information for both IPv4 and IPv6 protocols + */ +enum dpa_stats_cnt_reass_gen_sel { + /* Number of timeout occurrences */ + DPA_STATS_CNT_REASS_TIMEOUT = 0x00000001, + /* Number of failed attempts to allocate a Reassembly Frame Descriptor*/ + DPA_STATS_CNT_REASS_RFD_POOL_BUSY = 0x00000002, + /* Number of internal buffer busy occurrences */ + DPA_STATS_CNT_REASS_INT_BUFF_BUSY = 0x00000004, + /* Number of external buffer busy occurrences */ + DPA_STATS_CNT_REASS_EXT_BUFF_BUSY = 0x00000008, + /* Number of Scatter/Gather fragments */ + DPA_STATS_CNT_REASS_SG_FRAGS = 0x00000010, + /* Number of failed attempts to allocate a DMA semaphore */ + DPA_STATS_CNT_REASS_DMA_SEM = 0x00000020, + /* + * Number of Non Consistent Storage Profile occurrences for successfully + * reassembled frames + */ + DPA_STATS_CNT_REASS_NON_CONSISTENT_SP = 0x00000040, + /* Select all counters from dpa_stats_cnt_reass_gen_sel */ + DPA_STATS_CNT_REASS_GEN_ALL = 0x00000080 +}; + +/* + * DPA Stats IP Reassembly selection of counters that provide + * information only for IPv4 protocol + */ +enum dpa_stats_cnt_reass_ipv4_sel { + /* Number of successfully reassembled IPv4 frames */ + DPA_STATS_CNT_REASS_IPv4_FRAMES = 0x00000100, + /* Number of valid IPv4 fragments */ + DPA_STATS_CNT_REASS_IPv4_FRAGS_VALID = 0x00000200, + /* Number of processed IPv4 fragments */ + DPA_STATS_CNT_REASS_IPv4_FRAGS_TOTAL = 0x00000400, + /* Number of malformed IPv4 fragments */ + DPA_STATS_CNT_REASS_IPv4_FRAGS_MALFORMED = 0x00000800, + /* Number of discarded IPv4 fragments except Timeout condition */ + DPA_STATS_CNT_REASS_IPv4_FRAGS_DISCARDED = 0x00001000, + /* Number of busy conditions due to Automatic Learning Hash access */ + DPA_STATS_CNT_REASS_IPv4_AUTOLEARN_BUSY = 0x00002000, + /* + * Number of IPv4 fragments occurrences when the number of + * fragments-per-frame exceeds 16 + */ + DPA_STATS_CNT_REASS_IPv4_EXCEED_16FRAGS = 0x00004000, + /* Select all counters from dpa_stats_cnt_reass_ipv4_sel */ + DPA_STATS_CNT_REASS_IPv4_ALL = 0x00008000 +}; + +/* + * DPA Stats IP Reassembly selection of counters that provide + * information only for IPv6 protocol + */ +enum dpa_stats_cnt_reass_ipv6_sel { + /* Number of successfully reassembled IPv6 frames*/ + DPA_STATS_CNT_REASS_IPv6_FRAMES = 0x00010000, + /* Number of valid IPv6 fragments */ + DPA_STATS_CNT_REASS_IPv6_FRAGS_VALID = 0x00020000, + /* Number of processed IPv6 fragments */ + DPA_STATS_CNT_REASS_IPv6_FRAGS_TOTAL = 0x00040000, + /* Number of malformed IPv6 fragments */ + DPA_STATS_CNT_REASS_IPv6_FRAGS_MALFORMED = 0x00080000, + /* Number of discarded IPv6 fragments except Timeout condition */ + DPA_STATS_CNT_REASS_IPv6_FRAGS_DISCARDED = 0x00100000, + /* Number of busy conditions due to Automatic Learning Hash access */ + DPA_STATS_CNT_REASS_IPv6_AUTOLEARN_BUSY = 0x00200000, + /* + * Number of IPv6 fragments occurrences when the number of + * fragments-per-frame exceeds 16 + */ + DPA_STATS_CNT_REASS_IPv6_EXCEED_16FRAGS = 0x00400000, + /* Select all counters from dpa_stats_cnt_reass_ipv6_sel */ + DPA_STATS_CNT_REASS_IPv6_ALL = 0x00800000 +}; + +/* DPA Stats IP Reassembly counter parameters */ +struct dpa_stats_cnt_reass { + /* Pointer to the IP Reassembly object*/ + void *reass; + + /* + * Single or multiple selection of IP Reassembly counters from one of + * the enums: dpa_stats_cnt_reass_gen_sel, dpa_stats_cnt_reass_ipv4_sel + * or dpa_stats_cnt_reass_ipv6_sel + */ + unsigned int cnt_sel; +}; + +/* DPA Stats Fragmentation counters */ +enum dpa_stats_cnt_frag_sel { + /* Number of frames processed by fragmentation manipulation */ + DPA_STATS_CNT_FRAG_TOTAL_FRAMES = 0x00000001, + /* Number of fragmented frames */ + DPA_STATS_CNT_FRAG_FRAMES = 0x00000002, + /* Number of generated fragments */ + DPA_STATS_CNT_FRAG_GEN_FRAGS = 0x00000004, + /* Select all counters from dpa_stats_cnt_frag_sel */ + DPA_STATS_CNT_FRAG_ALL = 0x00000008 +}; + +/* DPA Stats Fragmentation counter parameters */ +struct dpa_stats_cnt_frag { + /* Pointer to the IP Fragmentation object*/ + void *frag; + + /* + * Single or multiple selection of Fragmentation + * counters from enum dpa_stats_cnt_frag_sel + */ + unsigned int cnt_sel; +}; + +/* DPA Stats Policer counters */ +enum dpa_stats_cnt_plcr_sel { + /* Number of 'green' frames */ + DPA_STATS_CNT_PLCR_GREEN_PKTS = 0x00000001, + /* Number of 'yellow' frames */ + DPA_STATS_CNT_PLCR_YELLOW_PKTS = 0x00000002, + /* Number of 'red' frames */ + DPA_STATS_CNT_PLCR_RED_PKTS = 0x00000004, + /* Number of recolored 'yellow' frames */ + DPA_STATS_CNT_PLCR_RECOLOR_YELLOW_PKTS = 0x00000008, + /* Number of recolored 'red' frames */ + DPA_STATS_CNT_PLCR_RECOLOR_RED_PKTS = 0x00000010, + /* Select all counters */ + DPA_STATS_CNT_PLCR_ALL = 0x00000020 +}; + +/* DPA Stats Policer counter parameters */ +struct dpa_stats_cnt_plcr { + /* Pointer to the Policer object */ + void *plcr; + + /* + * Single or multiple selection of Policer counters + * from enum dpa_stats_cnt_plcr_sel + */ + unsigned int cnt_sel; +}; + +/* DPA Stats Classification counters */ +enum dpa_stats_cnt_classif_sel { + /* Number of bytes processed by classification entry */ + DPA_STATS_CNT_CLASSIF_BYTES = 0x00000010, + /* Number of frames processed by classification entry */ + DPA_STATS_CNT_CLASSIF_PACKETS = 0x00000020, + /* Number of frames for frame length range 0 */ + DPA_STATS_CNT_CLASSIF_RMON_RANGE0 = 0x00000040, + /* Number of frames for frame length range 1 */ + DPA_STATS_CNT_CLASSIF_RMON_RANGE1 = 0x00000080, + /* Number of frames for frame length range 2 */ + DPA_STATS_CNT_CLASSIF_RMON_RANGE2 = 0x00000100, + /* Number of frames for frame length range 3 */ + DPA_STATS_CNT_CLASSIF_RMON_RANGE3 = 0x00000200, + /* Number of frames for frame length range 4 */ + DPA_STATS_CNT_CLASSIF_RMON_RANGE4 = 0x00000400, + /* Number of frames for frame length range 5 */ + DPA_STATS_CNT_CLASSIF_RMON_RANGE5 = 0x00000800, + /* Number of frames for frame length range 6 */ + DPA_STATS_CNT_CLASSIF_RMON_RANGE6 = 0x00001000, + /* Number of frames for frame length range 7 */ + DPA_STATS_CNT_CLASSIF_RMON_RANGE7 = 0x00002000, + /* Number of frames for frame length range 8 */ + DPA_STATS_CNT_CLASSIF_RMON_RANGE8 = 0x00004000, + /* Number of frames for frame length range 9 */ + DPA_STATS_CNT_CLASSIF_RMON_RANGE9 = 0x00008000, + /* Select all counters */ + DPA_STATS_CNT_CLASSIF_ALL = 0x00010000 +}; + +/* DPA Stats Classifier Table counter parameters */ +struct dpa_stats_cnt_classif_tbl { + + /* Table descriptor */ + int td; + + /* + * Pointer to a key that identifies a specific entry or NULL in order + * to obtain statistics for miss entry + */ + struct dpa_offload_lookup_key *key; + + /* + * Single or multiple selection of Classifier Table counters + * from one of the enums: dpa_stats_cnt_classif_sel or + * dpa_stats_cnt_frag_sel + */ + unsigned int cnt_sel; +}; + +/* DPA Stats Classification Node Type */ +enum dpa_stats_classif_node_type { + /* Classification Node type HASH */ + DPA_STATS_CLASSIF_NODE_HASH = 0, + /* Classification Node type Indexed */ + DPA_STATS_CLASSIF_NODE_INDEXED, + /* Classification Node type Exact match */ + DPA_STATS_CLASSIF_NODE_EXACT_MATCH +}; + +/* DPA Stats Classification Node parameters */ +struct dpa_stats_cnt_classif_node { + /* + * Handle of the FMAN Cc node, more precisely handle of + * the classification element previously created in the + * distribution XML file + */ + void *cc_node; + + /* The type of FMAN Classification Node */ + enum dpa_stats_classif_node_type ccnode_type; + + /* + * Pointer to a key that identifies a specific entry or NULL in order + * to obtain statistics for miss entry + */ + struct dpa_offload_lookup_key *key; + + /* + * Single or multiple selection of Classifier + * counters from enum: dpa_stats_cnt_classif_sel + */ + unsigned int cnt_sel; +}; + +/* DPA Stats IPSec counter parameters */ +struct dpa_stats_cnt_ipsec { + + /* Security Association id */ + int sa_id; + + /* Select IPSec counter */ + enum dpa_stats_cnt_sel cnt_sel; +}; + +/* DPA Stats Traffic Manager counter source */ +enum dpa_stats_cnt_traffic_mng_src { + /* Traffic Manager Class counter */ + DPA_STATS_CNT_TRAFFIC_CLASS = 0, + /* Traffic Manager Congestion Group counter */ + DPA_STATS_CNT_TRAFFIC_CG +}; + +/* DPA Stats Traffic Manager counter parameters */ +struct dpa_stats_cnt_traffic_mng { + /* Traffic Manager counter source */ + enum dpa_stats_cnt_traffic_mng_src src; + + /* + * Depending on the Traffic Manager source, the 'traffic_mng' has a + * different meaning: it represents a pointer to a structure of type + * 'qm_ceetm_cq' in case the traffic source is a "Class Queue" or a + * pointer to a structure of type 'qm_ceetm_ccg' in case the traffic + * source is a "Class Congestion Group" + */ + void *traffic_mng; + + /* + * Traffic Manager Class: Number of bytes/frames dequeued from a Class + * Traffic Manager Congestion Group: Number of bytes/frames whose + * enqueues was rejected in all Class queues that belong to the + * Congestion Group + */ + enum dpa_stats_cnt_sel cnt_sel; +}; + +/* DPA Stats counter parameters */ +struct dpa_stats_cnt_params { + + /* The type of DPA Stats counter */ + enum dpa_stats_cnt_type type; + + union { + /* Parameters for Ethernet counter */ + struct dpa_stats_cnt_eth eth_params; + + /* Parameters for IP Reassembly counter */ + struct dpa_stats_cnt_reass reass_params; + + /* Parameters for IP Fragmentation counter */ + struct dpa_stats_cnt_frag frag_params; + + /* Parameters for Policer counter */ + struct dpa_stats_cnt_plcr plcr_params; + + /* Parameters for Classification Table counter */ + struct dpa_stats_cnt_classif_tbl classif_tbl_params; + + /* Parameters for Classification Node counter */ + struct dpa_stats_cnt_classif_node classif_node_params; + + /* Parameters for IPSec counter */ + struct dpa_stats_cnt_ipsec ipsec_params; + + /* Parameters for Traffic Manager counter */ + struct dpa_stats_cnt_traffic_mng traffic_mng_params; + }; +}; + +/* DPA Stats Ethernet class counter parameters */ +struct dpa_stats_cls_cnt_eth { + /* Array of Ethernet counters sources */ + struct dpa_stats_cnt_eth_src *src; + + /* Single selection of Ethernet counter */ + enum dpa_stats_cnt_eth_sel cnt_sel; +}; + +/* DPA Stats IP Reassembly class counter parameters */ +struct dpa_stats_cls_cnt_reass { + /* Array of pointers of IP Reassembly objects */ + void **reass; + + /* + * Single or multiple selections of IP Reassembly counters + * from one of the enums dpa_stats_cnt_reass_gen_sel, + * dpa_stats_cnt_reass_ipv4_sel or dpa_stats_cnt_reass_ipv6_sel + */ + unsigned int cnt_sel; +}; + +/* DPA Stats IP Fragmentation counter parameters */ +struct dpa_stats_cls_cnt_frag { + /* Array of pointers of IP Fragmentation objects */ + void **frag; + + /* + * Single or multiple selection of Fragmentation + * counters from enum dpa_stats_cnt_frag_sel + */ + unsigned int cnt_sel; +}; + +/* DPA Stats Policer class counter parameters */ +struct dpa_stats_cls_cnt_plcr { + /* Array of pointers of Policer objects */ + void **plcr; + + /* + * Single or multiple selection of Policer counters + * from enum dpa_stats_cnt_plcr_sel + */ + unsigned int cnt_sel; +}; + +/* DPA Stats Classification key type */ +enum dpa_stats_classif_key_type { + + /* Entry identified through a single key */ + DPA_STATS_CLASSIF_SINGLE_KEY = 0, + + /* + * Entry identified through a pair of keys: the first key + * uniquely identifies the first entry, while the second key + * identifies the entry connected to the first entry + */ + DPA_STATS_CLASSIF_PAIR_KEY +}; + +/* DPA Stats Classification counter - pair of keys */ +struct dpa_offload_lookup_key_pair { + + /* + * Pointer to a key that identifies the first entry or NULL in order + * to identify the miss entry of the first table + */ + struct dpa_offload_lookup_key *first_key; + + /* + * Pointer to a key that identifies the entry connected to the first + * entry first entry or NULL in order to identify the miss entry + */ + struct dpa_offload_lookup_key *second_key; +}; + +/* DPA Stats Classifier Table class counter parameters */ +struct dpa_stats_cls_cnt_classif_tbl { + + /* Table descriptor */ + int td; + + /* Mechanism used to identify an entry */ + enum dpa_stats_classif_key_type key_type; + + union { + /* + * Invalid keys can be provided during class counter creation + * and the statistics values for such keys will be 0. Function + * 'dpa_stats_modify_class_counter' can be further used to + * modify a specific key. + */ + + /* + * Pointer to an array of keys, where each element of the array + * can either be a key that identifies a specific entry or NULL + * in order to obtain the statistics for the miss entry. A key + * can be'invalidated' by providing the 'byte' pointer set + * to NULL. + */ + struct dpa_offload_lookup_key **keys; + + /* + * Array of 'pair-keys' to identify specific entries. A key pair + * can be 'invalidated' by providing the 'byte' and 'mask' + * pointers of the first key set to NULL + */ + + /* + * Pointer to an array of ‘pair-keys’, where each element of the + * array can either be a ‘pair-key’ that identifies a specific + * entry or NULL in in order to obtain the statistics for the + * miss entry. A key pair can be 'invalidated' by providing the + * 'byte' pointer of the first key set to NULL. + */ + struct dpa_offload_lookup_key_pair **pairs; + }; + + /* + * Single or multiple selection of Classifier Table counters + * from one of the enums: dpa_stats_cnt_classif_sel or + * dpa_stats_cnt_frag_sel + */ + unsigned int cnt_sel; +}; + +/* DPA Stats Classification Node class counter parameters */ +struct dpa_stats_cls_cnt_classif_node { + /* + * Handle of the FMAN Cc node, more precisely handle of + * the classification element previously created in the + * distribution XML file + */ + void *cc_node; + + /* The type of FMAN Classification Node */ + enum dpa_stats_classif_node_type ccnode_type; + + /* Array of keys to identify specific entries */ + struct dpa_offload_lookup_key **keys; + + /* + * Single or multiple selection of Classifier counters + * from enum dpa_stats_cnt_classif_sel + */ + unsigned int cnt_sel; +}; + +/* DPA Stats IPSec class counter parameters */ +struct dpa_stats_cls_cnt_ipsec { + + /* + * Array of security association IDs. Invalid security association + * identifiers(DPA_OFFLD_INVALID_OBJECT_ID) can be provided during + * class counter creation and the statistics values for such ids will + * be 0. Function 'dpa_stats_modify_class_counter' can be further used + * to modify a specific security association identifier. + */ + int *sa_id; + + /* Select IPSec counter */ + enum dpa_stats_cnt_sel cnt_sel; +}; + +/* DPA Stats Traffic Manager class counter parameters */ +struct dpa_stats_cls_cnt_traffic_mng { + + /* Traffic Manager source */ + enum dpa_stats_cnt_traffic_mng_src src; + + /* + * Depending on the Traffic Manager source, the 'traffic_mng' has a + * different meaning: it represents an array of pointers to structures + * of type 'qm_ceetm_cq' in case the traffic source is a "Class Queue" + * or an array of pointers to structures of type 'qm_ceetm_ccg' in case + * the traffic source is a "Class Congestion Group" + */ + void **traffic_mng; + + /* + * Traffic Manager Class: Number of bytes/frames dequeued from a Class + * Traffic Manager Congestion Group: Number of bytes/frames whose + * enqueues was rejected in all Class queues that belong to the + * Congestion Group + */ + enum dpa_stats_cnt_sel cnt_sel; +}; + +/* DPA Stats class counter parameters */ +struct dpa_stats_cls_cnt_params { + + /* Number of members the class can have */ + unsigned int class_members; + + /* The type of DPA Stats class counter */ + enum dpa_stats_cnt_type type; + + union { + /* Parameters for Ethernet class counter */ + struct dpa_stats_cls_cnt_eth eth_params; + + /* Parameters for IP Reassembly class counter */ + struct dpa_stats_cls_cnt_reass reass_params; + + /* Parameters for IP Fragmentation class counter */ + struct dpa_stats_cls_cnt_frag frag_params; + + /* Parameters for Policer class counter */ + struct dpa_stats_cls_cnt_plcr plcr_params; + + /* Parameters for Classifier Table class counter */ + struct dpa_stats_cls_cnt_classif_tbl classif_tbl_params; + + /* Parameters for Classification Node class counter */ + struct dpa_stats_cls_cnt_classif_node classif_node_params; + + /* Parameters for IPSec class counter */ + struct dpa_stats_cls_cnt_ipsec ipsec_params; + + /* Parameters for Traffic Manager class counter */ + struct dpa_stats_cls_cnt_traffic_mng traffic_mng_params; + }; +}; + +/* DPA Stats class counter member type */ +enum dpa_stats_cls_member_type { + /* Classifier table class member single key */ + DPA_STATS_CLS_MEMBER_SINGLE_KEY = 0, + /* Classifier table class member pair key */ + DPA_STATS_CLS_MEMBER_PAIR_KEY, + /* IPSec class member security association id */ + DPA_STATS_CLS_MEMBER_SA_ID +}; + +/* DPA Stats class member parameters */ +struct dpa_stats_cls_member_params { + + /* The type of DPA Stats class counter member */ + enum dpa_stats_cls_member_type type; + + union { + /* + * Pointer to a key to set or update in case the byte pointer is + * not NULL, or class member to invalidate otherwise. The + * pointer can be NULL, in which case it represents the miss + * entry. + */ + struct dpa_offload_lookup_key *key; + + /* + * Pointer to a 'pair-key' to set or update in case the byte + * pointer of the first key is not NULL, or class member to + * invalidate otherwise. The pointer can be NULL, in which case + * it represents the miss entry. + */ + struct dpa_offload_lookup_key_pair *pair; + + /* + * Security association identifier to set or update or class + * member to invalidate in case the security association has + * an invalid value + */ + int sa_id; + }; +}; + +/* Creates and initializes a DPA Stats instance */ +int dpa_stats_init(const struct dpa_stats_params *params, int *dpa_stats_id); + +/* + * Create and initialize a DPA Stats counter. The returned 'dpa_stats_cnt_id' + * will be further used to uniquely identify a counter + */ +int dpa_stats_create_counter(int dpa_stats_id, + const struct dpa_stats_cnt_params *params, + int *dpa_stats_cnt_id); + +/* + * Creates and initializes a DPA Stats class counter. The returned + * 'dpa_stats_cnt_id' will be further used to uniquely identify a counter + */ +int dpa_stats_create_class_counter(int dpa_stats_id, + const struct dpa_stats_cls_cnt_params *params, + int *dpa_stats_cnt_id); + +/* + * Modify a specific member of a DPA Stats class counter. The member to be + * modified is identified through the 'member_index' parameter which represents + * the member position in the corresponding class counter. + */ +int dpa_stats_modify_class_counter(int dpa_stats_cnt_id, + const struct dpa_stats_cls_member_params *params, + int member_index); + +/* Remove a DPA Stats counter by releasing all associated resources */ +int dpa_stats_remove_counter(int dpa_stats_cnt_id); + +/* + * Create a request to retrieve the values of one or multiple single or class + * of counters. Counters that are in the 'requested_cnts' array will be + * retrieved in the order given by the position in the array. The counters + * values are written in the storage area, at offset defined by + * 'storage_area_offset' and the user is notified through the callback + * 'request_done'. + */ +int dpa_stats_get_counters(struct dpa_stats_cnt_request_params params, + int *cnts_len, + dpa_stats_request_cb request_done); + +/* Reset the statistics for a group of counters */ +int dpa_stats_reset_counters(int *cnts_ids, + unsigned int cnts_ids_len); +/* + * Releases all resources associated with a DPA Stats instance + * and destroys it. + */ +int dpa_stats_free(int dpa_stats_id); + +int dpa_stats_create_sampling_group(void); + +int dpa_stats_remove_sampling_group(void); + +#endif /* __FSL_DPA_STATS_H */ diff --git a/include/linux/fsl_ifc.h b/include/linux/fsl_ifc.h new file mode 100644 index 0000000..3833238 --- /dev/null +++ b/include/linux/fsl_ifc.h @@ -0,0 +1,886 @@ +/* Freescale Integrated Flash Controller + * + * Copyright 2011 Freescale Semiconductor, Inc + * + * Author: Dipen Dudhat <dipen.dudhat@freescale.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_FSL_IFC_H +#define __ASM_FSL_IFC_H + +#include <linux/compiler.h> +#include <linux/types.h> +#include <linux/io.h> + +#include <linux/of_platform.h> +#include <linux/interrupt.h> + +#define FSL_IFC_BANK_COUNT 4 + +/* + * CSPR - Chip Select Property Register + */ +#define CSPR_BA 0xFFFF0000 +#define CSPR_BA_SHIFT 16 +#define CSPR_PORT_SIZE 0x00000180 +#define CSPR_PORT_SIZE_SHIFT 7 +/* Port Size 8 bit */ +#define CSPR_PORT_SIZE_8 0x00000080 +/* Port Size 16 bit */ +#define CSPR_PORT_SIZE_16 0x00000100 +/* Port Size 32 bit */ +#define CSPR_PORT_SIZE_32 0x00000180 +/* Write Protect */ +#define CSPR_WP 0x00000040 +#define CSPR_WP_SHIFT 6 +/* Machine Select */ +#define CSPR_MSEL 0x00000006 +#define CSPR_MSEL_SHIFT 1 +/* NOR */ +#define CSPR_MSEL_NOR 0x00000000 +/* NAND */ +#define CSPR_MSEL_NAND 0x00000002 +/* GPCM */ +#define CSPR_MSEL_GPCM 0x00000004 +/* Bank Valid */ +#define CSPR_V 0x00000001 +#define CSPR_V_SHIFT 0 + +/* + * Address Mask Register + */ +#define IFC_AMASK_MASK 0xFFFF0000 +#define IFC_AMASK_SHIFT 16 +#define IFC_AMASK(n) (IFC_AMASK_MASK << \ + (__ilog2(n) - IFC_AMASK_SHIFT)) + +/* + * Chip Select Option Register IFC_NAND Machine + */ +/* Enable ECC Encoder */ +#define CSOR_NAND_ECC_ENC_EN 0x80000000 +#define CSOR_NAND_ECC_MODE_MASK 0x30000000 +/* 4 bit correction per 520 Byte sector */ +#define CSOR_NAND_ECC_MODE_4 0x00000000 +/* 8 bit correction per 528 Byte sector */ +#define CSOR_NAND_ECC_MODE_8 0x10000000 +/* Enable ECC Decoder */ +#define CSOR_NAND_ECC_DEC_EN 0x04000000 +/* Row Address Length */ +#define CSOR_NAND_RAL_MASK 0x01800000 +#define CSOR_NAND_RAL_SHIFT 20 +#define CSOR_NAND_RAL_1 0x00000000 +#define CSOR_NAND_RAL_2 0x00800000 +#define CSOR_NAND_RAL_3 0x01000000 +#define CSOR_NAND_RAL_4 0x01800000 +/* Page Size 512b, 2k, 4k */ +#define CSOR_NAND_PGS_MASK 0x00180000 +#define CSOR_NAND_PGS_SHIFT 16 +#define CSOR_NAND_PGS_512 0x00000000 +#define CSOR_NAND_PGS_2K 0x00080000 +#define CSOR_NAND_PGS_4K 0x00100000 +#define CSOR_NAND_PGS_8K 0x00180000 +/* Spare region Size */ +#define CSOR_NAND_SPRZ_MASK 0x0000E000 +#define CSOR_NAND_SPRZ_SHIFT 13 +#define CSOR_NAND_SPRZ_16 0x00000000 +#define CSOR_NAND_SPRZ_64 0x00002000 +#define CSOR_NAND_SPRZ_128 0x00004000 +#define CSOR_NAND_SPRZ_210 0x00006000 +#define CSOR_NAND_SPRZ_218 0x00008000 +#define CSOR_NAND_SPRZ_224 0x0000A000 +#define CSOR_NAND_SPRZ_CSOR_EXT 0x0000C000 +/* Pages Per Block */ +#define CSOR_NAND_PB_MASK 0x00000700 +#define CSOR_NAND_PB_SHIFT 8 +#define CSOR_NAND_PB(n) ((__ilog2(n) - 5) << CSOR_NAND_PB_SHIFT) +/* Time for Read Enable High to Output High Impedance */ +#define CSOR_NAND_TRHZ_MASK 0x0000001C +#define CSOR_NAND_TRHZ_SHIFT 2 +#define CSOR_NAND_TRHZ_20 0x00000000 +#define CSOR_NAND_TRHZ_40 0x00000004 +#define CSOR_NAND_TRHZ_60 0x00000008 +#define CSOR_NAND_TRHZ_80 0x0000000C +#define CSOR_NAND_TRHZ_100 0x00000010 +/* Buffer control disable */ +#define CSOR_NAND_BCTLD 0x00000001 + +/* + * Chip Select Option Register - NOR Flash Mode + */ +/* Enable Address shift Mode */ +#define CSOR_NOR_ADM_SHFT_MODE_EN 0x80000000 +/* Page Read Enable from NOR device */ +#define CSOR_NOR_PGRD_EN 0x10000000 +/* AVD Toggle Enable during Burst Program */ +#define CSOR_NOR_AVD_TGL_PGM_EN 0x01000000 +/* Address Data Multiplexing Shift */ +#define CSOR_NOR_ADM_MASK 0x0003E000 +#define CSOR_NOR_ADM_SHIFT_SHIFT 13 +#define CSOR_NOR_ADM_SHIFT(n) ((n) << CSOR_NOR_ADM_SHIFT_SHIFT) +/* Type of the NOR device hooked */ +#define CSOR_NOR_NOR_MODE_AYSNC_NOR 0x00000000 +#define CSOR_NOR_NOR_MODE_AVD_NOR 0x00000020 +/* Time for Read Enable High to Output High Impedance */ +#define CSOR_NOR_TRHZ_MASK 0x0000001C +#define CSOR_NOR_TRHZ_SHIFT 2 +#define CSOR_NOR_TRHZ_20 0x00000000 +#define CSOR_NOR_TRHZ_40 0x00000004 +#define CSOR_NOR_TRHZ_60 0x00000008 +#define CSOR_NOR_TRHZ_80 0x0000000C +#define CSOR_NOR_TRHZ_100 0x00000010 +/* Buffer control disable */ +#define CSOR_NOR_BCTLD 0x00000001 + +/* + * Chip Select Option Register - GPCM Mode + */ +/* GPCM Mode - Normal */ +#define CSOR_GPCM_GPMODE_NORMAL 0x00000000 +/* GPCM Mode - GenericASIC */ +#define CSOR_GPCM_GPMODE_ASIC 0x80000000 +/* Parity Mode odd/even */ +#define CSOR_GPCM_PARITY_EVEN 0x40000000 +/* Parity Checking enable/disable */ +#define CSOR_GPCM_PAR_EN 0x20000000 +/* GPCM Timeout Count */ +#define CSOR_GPCM_GPTO_MASK 0x0F000000 +#define CSOR_GPCM_GPTO_SHIFT 24 +#define CSOR_GPCM_GPTO(n) ((__ilog2(n) - 8) << CSOR_GPCM_GPTO_SHIFT) +/* GPCM External Access Termination mode for read access */ +#define CSOR_GPCM_RGETA_EXT 0x00080000 +/* GPCM External Access Termination mode for write access */ +#define CSOR_GPCM_WGETA_EXT 0x00040000 +/* Address Data Multiplexing Shift */ +#define CSOR_GPCM_ADM_MASK 0x0003E000 +#define CSOR_GPCM_ADM_SHIFT_SHIFT 13 +#define CSOR_GPCM_ADM_SHIFT(n) ((n) << CSOR_GPCM_ADM_SHIFT_SHIFT) +/* Generic ASIC Parity error indication delay */ +#define CSOR_GPCM_GAPERRD_MASK 0x00000180 +#define CSOR_GPCM_GAPERRD_SHIFT 7 +#define CSOR_GPCM_GAPERRD(n) (((n) - 1) << CSOR_GPCM_GAPERRD_SHIFT) +/* Time for Read Enable High to Output High Impedance */ +#define CSOR_GPCM_TRHZ_MASK 0x0000001C +#define CSOR_GPCM_TRHZ_20 0x00000000 +#define CSOR_GPCM_TRHZ_40 0x00000004 +#define CSOR_GPCM_TRHZ_60 0x00000008 +#define CSOR_GPCM_TRHZ_80 0x0000000C +#define CSOR_GPCM_TRHZ_100 0x00000010 +/* Buffer control disable */ +#define CSOR_GPCM_BCTLD 0x00000001 + +/* + * Ready Busy Status Register (RB_STAT) + */ +/* CSn is READY */ +#define IFC_RB_STAT_READY_CS0 0x80000000 +#define IFC_RB_STAT_READY_CS1 0x40000000 +#define IFC_RB_STAT_READY_CS2 0x20000000 +#define IFC_RB_STAT_READY_CS3 0x10000000 + +/* + * General Control Register (GCR) + */ +#define IFC_GCR_MASK 0x8000F800 +/* reset all IFC hardware */ +#define IFC_GCR_SOFT_RST_ALL 0x80000000 +/* Turnaroud Time of external buffer */ +#define IFC_GCR_TBCTL_TRN_TIME 0x0000F800 +#define IFC_GCR_TBCTL_TRN_TIME_SHIFT 11 + +/* + * Common Event and Error Status Register (CM_EVTER_STAT) + */ +/* Chip select error */ +#define IFC_CM_EVTER_STAT_CSER 0x80000000 + +/* + * Common Event and Error Enable Register (CM_EVTER_EN) + */ +/* Chip select error checking enable */ +#define IFC_CM_EVTER_EN_CSEREN 0x80000000 + +/* + * Common Event and Error Interrupt Enable Register (CM_EVTER_INTR_EN) + */ +/* Chip select error interrupt enable */ +#define IFC_CM_EVTER_INTR_EN_CSERIREN 0x80000000 + +/* + * Common Transfer Error Attribute Register-0 (CM_ERATTR0) + */ +/* transaction type of error Read/Write */ +#define IFC_CM_ERATTR0_ERTYP_READ 0x80000000 +#define IFC_CM_ERATTR0_ERAID 0x0FF00000 +#define IFC_CM_ERATTR0_ERAID_SHIFT 20 +#define IFC_CM_ERATTR0_ESRCID 0x0000FF00 +#define IFC_CM_ERATTR0_ESRCID_SHIFT 8 + +/* + * Clock Control Register (CCR) + */ +#define IFC_CCR_MASK 0x0F0F8800 +/* Clock division ratio */ +#define IFC_CCR_CLK_DIV_MASK 0x0F000000 +#define IFC_CCR_CLK_DIV_SHIFT 24 +#define IFC_CCR_CLK_DIV(n) ((n-1) << IFC_CCR_CLK_DIV_SHIFT) +/* IFC Clock Delay */ +#define IFC_CCR_CLK_DLY_MASK 0x000F0000 +#define IFC_CCR_CLK_DLY_SHIFT 16 +#define IFC_CCR_CLK_DLY(n) ((n) << IFC_CCR_CLK_DLY_SHIFT) +/* Invert IFC clock before sending out */ +#define IFC_CCR_INV_CLK_EN 0x00008000 +/* Fedback IFC Clock */ +#define IFC_CCR_FB_IFC_CLK_SEL 0x00000800 + +/* + * Clock Status Register (CSR) + */ +/* Clk is stable */ +#define IFC_CSR_CLK_STAT_STABLE 0x80000000 + +/* + * IFC_NAND Machine Specific Registers + */ +/* + * NAND Configuration Register (NCFGR) + */ +/* Auto Boot Mode */ +#define IFC_NAND_NCFGR_BOOT 0x80000000 +/* SRAM INIT EN */ +#define IFC_NAND_SRAM_INIT_EN 0x20000000 +/* Addressing Mode-ROW0+n/COL0 */ +#define IFC_NAND_NCFGR_ADDR_MODE_RC0 0x00000000 +/* Addressing Mode-ROW0+n/COL0+n */ +#define IFC_NAND_NCFGR_ADDR_MODE_RC1 0x00400000 +/* Number of loop iterations of FIR sequences for multi page operations */ +#define IFC_NAND_NCFGR_NUM_LOOP_MASK 0x0000F000 +#define IFC_NAND_NCFGR_NUM_LOOP_SHIFT 12 +#define IFC_NAND_NCFGR_NUM_LOOP(n) ((n) << IFC_NAND_NCFGR_NUM_LOOP_SHIFT) +/* Number of wait cycles */ +#define IFC_NAND_NCFGR_NUM_WAIT_MASK 0x000000FF +#define IFC_NAND_NCFGR_NUM_WAIT_SHIFT 0 + +/* + * NAND Flash Command Registers (NAND_FCR0/NAND_FCR1) + */ +/* General purpose FCM flash command bytes CMD0-CMD7 */ +#define IFC_NAND_FCR0_CMD0 0xFF000000 +#define IFC_NAND_FCR0_CMD0_SHIFT 24 +#define IFC_NAND_FCR0_CMD1 0x00FF0000 +#define IFC_NAND_FCR0_CMD1_SHIFT 16 +#define IFC_NAND_FCR0_CMD2 0x0000FF00 +#define IFC_NAND_FCR0_CMD2_SHIFT 8 +#define IFC_NAND_FCR0_CMD3 0x000000FF +#define IFC_NAND_FCR0_CMD3_SHIFT 0 +#define IFC_NAND_FCR1_CMD4 0xFF000000 +#define IFC_NAND_FCR1_CMD4_SHIFT 24 +#define IFC_NAND_FCR1_CMD5 0x00FF0000 +#define IFC_NAND_FCR1_CMD5_SHIFT 16 +#define IFC_NAND_FCR1_CMD6 0x0000FF00 +#define IFC_NAND_FCR1_CMD6_SHIFT 8 +#define IFC_NAND_FCR1_CMD7 0x000000FF +#define IFC_NAND_FCR1_CMD7_SHIFT 0 + +/* + * Flash ROW and COL Address Register (ROWn, COLn) + */ +/* Main/spare region locator */ +#define IFC_NAND_COL_MS 0x80000000 +/* Column Address */ +#define IFC_NAND_COL_CA_MASK 0x00000FFF + +/* + * NAND Flash Byte Count Register (NAND_BC) + */ +/* Byte Count for read/Write */ +#define IFC_NAND_BC 0x000001FF + +/* + * NAND Flash Instruction Registers (NAND_FIR0/NAND_FIR1/NAND_FIR2) + */ +/* NAND Machine specific opcodes OP0-OP14*/ +#define IFC_NAND_FIR0_OP0 0xFC000000 +#define IFC_NAND_FIR0_OP0_SHIFT 26 +#define IFC_NAND_FIR0_OP1 0x03F00000 +#define IFC_NAND_FIR0_OP1_SHIFT 20 +#define IFC_NAND_FIR0_OP2 0x000FC000 +#define IFC_NAND_FIR0_OP2_SHIFT 14 +#define IFC_NAND_FIR0_OP3 0x00003F00 +#define IFC_NAND_FIR0_OP3_SHIFT 8 +#define IFC_NAND_FIR0_OP4 0x000000FC +#define IFC_NAND_FIR0_OP4_SHIFT 2 +#define IFC_NAND_FIR1_OP5 0xFC000000 +#define IFC_NAND_FIR1_OP5_SHIFT 26 +#define IFC_NAND_FIR1_OP6 0x03F00000 +#define IFC_NAND_FIR1_OP6_SHIFT 20 +#define IFC_NAND_FIR1_OP7 0x000FC000 +#define IFC_NAND_FIR1_OP7_SHIFT 14 +#define IFC_NAND_FIR1_OP8 0x00003F00 +#define IFC_NAND_FIR1_OP8_SHIFT 8 +#define IFC_NAND_FIR1_OP9 0x000000FC +#define IFC_NAND_FIR1_OP9_SHIFT 2 +#define IFC_NAND_FIR2_OP10 0xFC000000 +#define IFC_NAND_FIR2_OP10_SHIFT 26 +#define IFC_NAND_FIR2_OP11 0x03F00000 +#define IFC_NAND_FIR2_OP11_SHIFT 20 +#define IFC_NAND_FIR2_OP12 0x000FC000 +#define IFC_NAND_FIR2_OP12_SHIFT 14 +#define IFC_NAND_FIR2_OP13 0x00003F00 +#define IFC_NAND_FIR2_OP13_SHIFT 8 +#define IFC_NAND_FIR2_OP14 0x000000FC +#define IFC_NAND_FIR2_OP14_SHIFT 2 + +/* + * Instruction opcodes to be programmed + * in FIR registers- 6bits + */ +enum ifc_nand_fir_opcodes { + IFC_FIR_OP_NOP, + IFC_FIR_OP_CA0, + IFC_FIR_OP_CA1, + IFC_FIR_OP_CA2, + IFC_FIR_OP_CA3, + IFC_FIR_OP_RA0, + IFC_FIR_OP_RA1, + IFC_FIR_OP_RA2, + IFC_FIR_OP_RA3, + IFC_FIR_OP_CMD0, + IFC_FIR_OP_CMD1, + IFC_FIR_OP_CMD2, + IFC_FIR_OP_CMD3, + IFC_FIR_OP_CMD4, + IFC_FIR_OP_CMD5, + IFC_FIR_OP_CMD6, + IFC_FIR_OP_CMD7, + IFC_FIR_OP_CW0, + IFC_FIR_OP_CW1, + IFC_FIR_OP_CW2, + IFC_FIR_OP_CW3, + IFC_FIR_OP_CW4, + IFC_FIR_OP_CW5, + IFC_FIR_OP_CW6, + IFC_FIR_OP_CW7, + IFC_FIR_OP_WBCD, + IFC_FIR_OP_RBCD, + IFC_FIR_OP_BTRD, + IFC_FIR_OP_RDSTAT, + IFC_FIR_OP_NWAIT, + IFC_FIR_OP_WFR, + IFC_FIR_OP_SBRD, + IFC_FIR_OP_UA, + IFC_FIR_OP_RB, +}; + +/* + * NAND Chip Select Register (NAND_CSEL) + */ +#define IFC_NAND_CSEL 0x0C000000 +#define IFC_NAND_CSEL_SHIFT 26 +#define IFC_NAND_CSEL_CS0 0x00000000 +#define IFC_NAND_CSEL_CS1 0x04000000 +#define IFC_NAND_CSEL_CS2 0x08000000 +#define IFC_NAND_CSEL_CS3 0x0C000000 + +/* + * NAND Operation Sequence Start (NANDSEQ_STRT) + */ +/* NAND Flash Operation Start */ +#define IFC_NAND_SEQ_STRT_FIR_STRT 0x80000000 +/* Automatic Erase */ +#define IFC_NAND_SEQ_STRT_AUTO_ERS 0x00800000 +/* Automatic Program */ +#define IFC_NAND_SEQ_STRT_AUTO_PGM 0x00100000 +/* Automatic Copyback */ +#define IFC_NAND_SEQ_STRT_AUTO_CPB 0x00020000 +/* Automatic Read Operation */ +#define IFC_NAND_SEQ_STRT_AUTO_RD 0x00004000 +/* Automatic Status Read */ +#define IFC_NAND_SEQ_STRT_AUTO_STAT_RD 0x00000800 + +/* + * NAND Event and Error Status Register (NAND_EVTER_STAT) + */ +/* Operation Complete */ +#define IFC_NAND_EVTER_STAT_OPC 0x80000000 +/* Flash Timeout Error */ +#define IFC_NAND_EVTER_STAT_FTOER 0x08000000 +/* Write Protect Error */ +#define IFC_NAND_EVTER_STAT_WPER 0x04000000 +/* ECC Error */ +#define IFC_NAND_EVTER_STAT_ECCER 0x02000000 +/* RCW Load Done */ +#define IFC_NAND_EVTER_STAT_RCW_DN 0x00008000 +/* Boot Loadr Done */ +#define IFC_NAND_EVTER_STAT_BOOT_DN 0x00004000 +/* Bad Block Indicator search select */ +#define IFC_NAND_EVTER_STAT_BBI_SRCH_SE 0x00000800 + +/* + * NAND Flash Page Read Completion Event Status Register + * (PGRDCMPL_EVT_STAT) + */ +#define PGRDCMPL_EVT_STAT_MASK 0xFFFF0000 +/* Small Page 0-15 Done */ +#define PGRDCMPL_EVT_STAT_SECTION_SP(n) (1 << (31 - (n))) +/* Large Page(2K) 0-3 Done */ +#define PGRDCMPL_EVT_STAT_LP_2K(n) (0xF << (28 - (n)*4)) +/* Large Page(4K) 0-1 Done */ +#define PGRDCMPL_EVT_STAT_LP_4K(n) (0xFF << (24 - (n)*8)) + +/* + * NAND Event and Error Enable Register (NAND_EVTER_EN) + */ +/* Operation complete event enable */ +#define IFC_NAND_EVTER_EN_OPC_EN 0x80000000 +/* Page read complete event enable */ +#define IFC_NAND_EVTER_EN_PGRDCMPL_EN 0x20000000 +/* Flash Timeout error enable */ +#define IFC_NAND_EVTER_EN_FTOER_EN 0x08000000 +/* Write Protect error enable */ +#define IFC_NAND_EVTER_EN_WPER_EN 0x04000000 +/* ECC error logging enable */ +#define IFC_NAND_EVTER_EN_ECCER_EN 0x02000000 + +/* + * NAND Event and Error Interrupt Enable Register (NAND_EVTER_INTR_EN) + */ +/* Enable interrupt for operation complete */ +#define IFC_NAND_EVTER_INTR_OPCIR_EN 0x80000000 +/* Enable interrupt for Page read complete */ +#define IFC_NAND_EVTER_INTR_PGRDCMPLIR_EN 0x20000000 +/* Enable interrupt for Flash timeout error */ +#define IFC_NAND_EVTER_INTR_FTOERIR_EN 0x08000000 +/* Enable interrupt for Write protect error */ +#define IFC_NAND_EVTER_INTR_WPERIR_EN 0x04000000 +/* Enable interrupt for ECC error*/ +#define IFC_NAND_EVTER_INTR_ECCERIR_EN 0x02000000 + +/* + * NAND Transfer Error Attribute Register-0 (NAND_ERATTR0) + */ +#define IFC_NAND_ERATTR0_MASK 0x0C080000 +/* Error on CS0-3 for NAND */ +#define IFC_NAND_ERATTR0_ERCS_CS0 0x00000000 +#define IFC_NAND_ERATTR0_ERCS_CS1 0x04000000 +#define IFC_NAND_ERATTR0_ERCS_CS2 0x08000000 +#define IFC_NAND_ERATTR0_ERCS_CS3 0x0C000000 +/* Transaction type of error Read/Write */ +#define IFC_NAND_ERATTR0_ERTTYPE_READ 0x00080000 + +/* + * NAND Flash Status Register (NAND_FSR) + */ +/* First byte of data read from read status op */ +#define IFC_NAND_NFSR_RS0 0xFF000000 +/* Second byte of data read from read status op */ +#define IFC_NAND_NFSR_RS1 0x00FF0000 + +/* + * ECC Error Status Registers (ECCSTAT0-ECCSTAT3) + */ +/* Number of ECC errors on sector n (n = 0-15) */ +#define IFC_NAND_ECCSTAT0_ERRCNT_SECTOR0_MASK 0x0F000000 +#define IFC_NAND_ECCSTAT0_ERRCNT_SECTOR0_SHIFT 24 +#define IFC_NAND_ECCSTAT0_ERRCNT_SECTOR1_MASK 0x000F0000 +#define IFC_NAND_ECCSTAT0_ERRCNT_SECTOR1_SHIFT 16 +#define IFC_NAND_ECCSTAT0_ERRCNT_SECTOR2_MASK 0x00000F00 +#define IFC_NAND_ECCSTAT0_ERRCNT_SECTOR2_SHIFT 8 +#define IFC_NAND_ECCSTAT0_ERRCNT_SECTOR3_MASK 0x0000000F +#define IFC_NAND_ECCSTAT0_ERRCNT_SECTOR3_SHIFT 0 +#define IFC_NAND_ECCSTAT1_ERRCNT_SECTOR4_MASK 0x0F000000 +#define IFC_NAND_ECCSTAT1_ERRCNT_SECTOR4_SHIFT 24 +#define IFC_NAND_ECCSTAT1_ERRCNT_SECTOR5_MASK 0x000F0000 +#define IFC_NAND_ECCSTAT1_ERRCNT_SECTOR5_SHIFT 16 +#define IFC_NAND_ECCSTAT1_ERRCNT_SECTOR6_MASK 0x00000F00 +#define IFC_NAND_ECCSTAT1_ERRCNT_SECTOR6_SHIFT 8 +#define IFC_NAND_ECCSTAT1_ERRCNT_SECTOR7_MASK 0x0000000F +#define IFC_NAND_ECCSTAT1_ERRCNT_SECTOR7_SHIFT 0 +#define IFC_NAND_ECCSTAT2_ERRCNT_SECTOR8_MASK 0x0F000000 +#define IFC_NAND_ECCSTAT2_ERRCNT_SECTOR8_SHIFT 24 +#define IFC_NAND_ECCSTAT2_ERRCNT_SECTOR9_MASK 0x000F0000 +#define IFC_NAND_ECCSTAT2_ERRCNT_SECTOR9_SHIFT 16 +#define IFC_NAND_ECCSTAT2_ERRCNT_SECTOR10_MASK 0x00000F00 +#define IFC_NAND_ECCSTAT2_ERRCNT_SECTOR10_SHIFT 8 +#define IFC_NAND_ECCSTAT2_ERRCNT_SECTOR11_MASK 0x0000000F +#define IFC_NAND_ECCSTAT2_ERRCNT_SECTOR11_SHIFT 0 +#define IFC_NAND_ECCSTAT3_ERRCNT_SECTOR12_MASK 0x0F000000 +#define IFC_NAND_ECCSTAT3_ERRCNT_SECTOR12_SHIFT 24 +#define IFC_NAND_ECCSTAT3_ERRCNT_SECTOR13_MASK 0x000F0000 +#define IFC_NAND_ECCSTAT3_ERRCNT_SECTOR13_SHIFT 16 +#define IFC_NAND_ECCSTAT3_ERRCNT_SECTOR14_MASK 0x00000F00 +#define IFC_NAND_ECCSTAT3_ERRCNT_SECTOR14_SHIFT 8 +#define IFC_NAND_ECCSTAT3_ERRCNT_SECTOR15_MASK 0x0000000F +#define IFC_NAND_ECCSTAT3_ERRCNT_SECTOR15_SHIFT 0 + +/* + * NAND Control Register (NANDCR) + */ +#define IFC_NAND_NCR_FTOCNT_MASK 0x1E000000 +#define IFC_NAND_NCR_FTOCNT_SHIFT 25 +#define IFC_NAND_NCR_FTOCNT(n) ((_ilog2(n) - 8) << IFC_NAND_NCR_FTOCNT_SHIFT) + +/* + * NAND_AUTOBOOT_TRGR + */ +/* Trigger RCW load */ +#define IFC_NAND_AUTOBOOT_TRGR_RCW_LD 0x80000000 +/* Trigget Auto Boot */ +#define IFC_NAND_AUTOBOOT_TRGR_BOOT_LD 0x20000000 + +/* + * NAND_MDR + */ +/* 1st read data byte when opcode SBRD */ +#define IFC_NAND_MDR_RDATA0 0xFF000000 +/* 2nd read data byte when opcode SBRD */ +#define IFC_NAND_MDR_RDATA1 0x00FF0000 + +/* + * NOR Machine Specific Registers + */ +/* + * NOR Event and Error Status Register (NOR_EVTER_STAT) + */ +/* NOR Command Sequence Operation Complete */ +#define IFC_NOR_EVTER_STAT_OPC_NOR 0x80000000 +/* Write Protect Error */ +#define IFC_NOR_EVTER_STAT_WPER 0x04000000 +/* Command Sequence Timeout Error */ +#define IFC_NOR_EVTER_STAT_STOER 0x01000000 + +/* + * NOR Event and Error Enable Register (NOR_EVTER_EN) + */ +/* NOR Command Seq complete event enable */ +#define IFC_NOR_EVTER_EN_OPCEN_NOR 0x80000000 +/* Write Protect Error Checking Enable */ +#define IFC_NOR_EVTER_EN_WPEREN 0x04000000 +/* Timeout Error Enable */ +#define IFC_NOR_EVTER_EN_STOEREN 0x01000000 + +/* + * NOR Event and Error Interrupt Enable Register (NOR_EVTER_INTR_EN) + */ +/* Enable interrupt for OPC complete */ +#define IFC_NOR_EVTER_INTR_OPCEN_NOR 0x80000000 +/* Enable interrupt for write protect error */ +#define IFC_NOR_EVTER_INTR_WPEREN 0x04000000 +/* Enable interrupt for timeout error */ +#define IFC_NOR_EVTER_INTR_STOEREN 0x01000000 + +/* + * NOR Transfer Error Attribute Register-0 (NOR_ERATTR0) + */ +/* Source ID for error transaction */ +#define IFC_NOR_ERATTR0_ERSRCID 0xFF000000 +/* AXI ID for error transation */ +#define IFC_NOR_ERATTR0_ERAID 0x000FF000 +/* Chip select corresponds to NOR error */ +#define IFC_NOR_ERATTR0_ERCS_CS0 0x00000000 +#define IFC_NOR_ERATTR0_ERCS_CS1 0x00000010 +#define IFC_NOR_ERATTR0_ERCS_CS2 0x00000020 +#define IFC_NOR_ERATTR0_ERCS_CS3 0x00000030 +/* Type of transaction read/write */ +#define IFC_NOR_ERATTR0_ERTYPE_READ 0x00000001 + +/* + * NOR Transfer Error Attribute Register-2 (NOR_ERATTR2) + */ +#define IFC_NOR_ERATTR2_ER_NUM_PHASE_EXP 0x000F0000 +#define IFC_NOR_ERATTR2_ER_NUM_PHASE_PER 0x00000F00 + +/* + * NOR Control Register (NORCR) + */ +#define IFC_NORCR_MASK 0x0F0F0000 +/* No. of Address/Data Phase */ +#define IFC_NORCR_NUM_PHASE_MASK 0x0F000000 +#define IFC_NORCR_NUM_PHASE_SHIFT 24 +#define IFC_NORCR_NUM_PHASE(n) ((n-1) << IFC_NORCR_NUM_PHASE_SHIFT) +/* Sequence Timeout Count */ +#define IFC_NORCR_STOCNT_MASK 0x000F0000 +#define IFC_NORCR_STOCNT_SHIFT 16 +#define IFC_NORCR_STOCNT(n) ((__ilog2(n) - 8) << IFC_NORCR_STOCNT_SHIFT) + +/* + * GPCM Machine specific registers + */ +/* + * GPCM Event and Error Status Register (GPCM_EVTER_STAT) + */ +/* Timeout error */ +#define IFC_GPCM_EVTER_STAT_TOER 0x04000000 +/* Parity error */ +#define IFC_GPCM_EVTER_STAT_PER 0x01000000 + +/* + * GPCM Event and Error Enable Register (GPCM_EVTER_EN) + */ +/* Timeout error enable */ +#define IFC_GPCM_EVTER_EN_TOER_EN 0x04000000 +/* Parity error enable */ +#define IFC_GPCM_EVTER_EN_PER_EN 0x01000000 + +/* + * GPCM Event and Error Interrupt Enable Register (GPCM_EVTER_INTR_EN) + */ +/* Enable Interrupt for timeout error */ +#define IFC_GPCM_EEIER_TOERIR_EN 0x04000000 +/* Enable Interrupt for Parity error */ +#define IFC_GPCM_EEIER_PERIR_EN 0x01000000 + +/* + * GPCM Transfer Error Attribute Register-0 (GPCM_ERATTR0) + */ +/* Source ID for error transaction */ +#define IFC_GPCM_ERATTR0_ERSRCID 0xFF000000 +/* AXI ID for error transaction */ +#define IFC_GPCM_ERATTR0_ERAID 0x000FF000 +/* Chip select corresponds to GPCM error */ +#define IFC_GPCM_ERATTR0_ERCS_CS0 0x00000000 +#define IFC_GPCM_ERATTR0_ERCS_CS1 0x00000040 +#define IFC_GPCM_ERATTR0_ERCS_CS2 0x00000080 +#define IFC_GPCM_ERATTR0_ERCS_CS3 0x000000C0 +/* Type of transaction read/Write */ +#define IFC_GPCM_ERATTR0_ERTYPE_READ 0x00000001 + +/* + * GPCM Transfer Error Attribute Register-2 (GPCM_ERATTR2) + */ +/* On which beat of address/data parity error is observed */ +#define IFC_GPCM_ERATTR2_PERR_BEAT 0x00000C00 +/* Parity Error on byte */ +#define IFC_GPCM_ERATTR2_PERR_BYTE 0x000000F0 +/* Parity Error reported in addr or data phase */ +#define IFC_GPCM_ERATTR2_PERR_DATA_PHASE 0x00000001 + +/* + * GPCM Status Register (GPCM_STAT) + */ +#define IFC_GPCM_STAT_BSY 0x80000000 /* GPCM is busy */ + +/* + * IFC Controller NAND Machine registers + */ +struct fsl_ifc_nand { + __be32 ncfgr; + u32 res1[0x4]; + __be32 nand_fcr0; + __be32 nand_fcr1; + u32 res2[0x8]; + __be32 row0; + u32 res3; + __be32 col0; + u32 res4; + __be32 row1; + u32 res5; + __be32 col1; + u32 res6; + __be32 row2; + u32 res7; + __be32 col2; + u32 res8; + __be32 row3; + u32 res9; + __be32 col3; + u32 res10[0x24]; + __be32 nand_fbcr; + u32 res11; + __be32 nand_fir0; + __be32 nand_fir1; + __be32 nand_fir2; + u32 res12[0x10]; + __be32 nand_csel; + u32 res13; + __be32 nandseq_strt; + u32 res14; + __be32 nand_evter_stat; + u32 res15; + __be32 pgrdcmpl_evt_stat; + u32 res16[0x2]; + __be32 nand_evter_en; + u32 res17[0x2]; + __be32 nand_evter_intr_en; + u32 res18[0x2]; + __be32 nand_erattr0; + __be32 nand_erattr1; + u32 res19[0x10]; + __be32 nand_fsr; + u32 res20; + __be32 nand_eccstat[4]; + u32 res21[0x20]; + __be32 nanndcr; + u32 res22[0x2]; + __be32 nand_autoboot_trgr; + u32 res23; + __be32 nand_mdr; + u32 res24[0x5C]; +}; + +/* + * IFC controller NOR Machine registers + */ +struct fsl_ifc_nor { + __be32 nor_evter_stat; + u32 res1[0x2]; + __be32 nor_evter_en; + u32 res2[0x2]; + __be32 nor_evter_intr_en; + u32 res3[0x2]; + __be32 nor_erattr0; + __be32 nor_erattr1; + __be32 nor_erattr2; + u32 res4[0x4]; + __be32 norcr; + u32 res5[0xEF]; +}; + +/* + * IFC controller GPCM Machine registers + */ +struct fsl_ifc_gpcm { + __be32 gpcm_evter_stat; + u32 res1[0x2]; + __be32 gpcm_evter_en; + u32 res2[0x2]; + __be32 gpcm_evter_intr_en; + u32 res3[0x2]; + __be32 gpcm_erattr0; + __be32 gpcm_erattr1; + __be32 gpcm_erattr2; + __be32 gpcm_stat; + u32 res4[0x1F3]; +}; + +/* + * IFC Controller Registers + */ +struct fsl_ifc_regs { + __be32 ifc_rev; + u32 res1[0x2]; + struct { + __be32 cspr_ext; + __be32 cspr; + u32 res2; + } cspr_cs[FSL_IFC_BANK_COUNT]; + u32 res3[0x19]; + struct { + __be32 amask; + u32 res4[0x2]; + } amask_cs[FSL_IFC_BANK_COUNT]; + u32 res5[0x17]; + struct { + __be32 csor_ext; + __be32 csor; + u32 res6; + } csor_cs[FSL_IFC_BANK_COUNT]; + u32 res7[0x19]; + struct { + __be32 ftim[4]; + u32 res8[0x8]; + } ftim_cs[FSL_IFC_BANK_COUNT]; + u32 res9[0x60]; + __be32 rb_stat; + u32 res10[0x2]; + __be32 ifc_gcr; + u32 res11[0x2]; + __be32 cm_evter_stat; + u32 res12[0x2]; + __be32 cm_evter_en; + u32 res13[0x2]; + __be32 cm_evter_intr_en; + u32 res14[0x2]; + __be32 cm_erattr0; + __be32 cm_erattr1; + u32 res15[0x2]; + __be32 ifc_ccr; + __be32 ifc_csr; + u32 res16[0x2EB]; + struct fsl_ifc_nand ifc_nand; + struct fsl_ifc_nor ifc_nor; + struct fsl_ifc_gpcm ifc_gpcm; +}; + +extern unsigned int convert_ifc_address(phys_addr_t addr_base); +extern int fsl_ifc_find(phys_addr_t addr_base); + +/* overview of the fsl ifc controller */ + +struct fsl_ifc_ctrl { + /* device info */ + struct device *dev; + struct fsl_ifc_regs __iomem *regs; + int irq; + int nand_irq; + spinlock_t lock; + void *nand; + + u32 nand_stat; + wait_queue_head_t nand_wait; + bool little_endian; +#ifdef CONFIG_PM_SLEEP + /* save regs when system go to deep-sleep */ + struct fsl_ifc_regs *saved_regs; +#endif +}; + +extern struct fsl_ifc_ctrl *fsl_ifc_ctrl_dev; + +static inline u32 ifc_in32(void __iomem *addr) +{ + if (fsl_ifc_ctrl_dev->little_endian) + return ioread32(addr); + else + return ioread32be(addr); +} + +static inline u16 ifc_in16(void __iomem *addr) +{ + if (fsl_ifc_ctrl_dev->little_endian) + return ioread16(addr); + else + return ioread16be(addr); +} + +static inline u8 ifc_in8(void __iomem *addr) +{ + return ioread8(addr); +} + +static inline void ifc_out32(u32 val, void __iomem *addr) +{ + if (fsl_ifc_ctrl_dev->little_endian) + return iowrite32(val, addr); + else + return iowrite32be(val, addr); +} + +static inline void ifc_out16(u16 val, void __iomem *addr) +{ + if (fsl_ifc_ctrl_dev->little_endian) + return iowrite16(val, addr); + else + return iowrite16be(val, addr); +} + +static inline void ifc_out8(u8 val, void __iomem *addr) +{ + return iowrite8(val, addr); +} + +#endif /* __ASM_FSL_IFC_H */ diff --git a/include/linux/fsl_pme.h b/include/linux/fsl_pme.h new file mode 100644 index 0000000..fbeec4f --- /dev/null +++ b/include/linux/fsl_pme.h @@ -0,0 +1,845 @@ +/* Copyright 2009-2011 Freescale Semiconductor, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FSL_PME_H +#define FSL_PME_H + +/* pme_fd_res_status() returns this enum */ +enum pme_status { + pme_status_ok = 0x00, + pme_status_kes_ccl = 0x40, /* KES Confidence Collision Limit */ + pme_status_kes_cme = 0x41, /* KES Confidence Mask Error */ + pme_status_dxe_ire = 0x48, /* DXE Invalid Repeat Error */ + pme_status_dxe_tlse = 0x49, /* DXE Test Line Syntax Error */ + pme_status_dxe_ile = 0x4b, /* DXE Instruction Limit Error */ + pme_status_dxe_pdsrsore = 0x4c, /* DXE PDSR Space Out Range Error */ + pme_status_dxe_soe = 0x4d, /* DXE Stack Overflow Error */ + pme_status_dxe_alse = 0x4e, /* DXE Alternate Link Same Error */ + pme_status_dxe_slse = 0x4f, /* DXE Subsequent Link Same Error */ + pme_status_dxe_slre = 0x50, /* DXE Subsequent Link Reverse Error */ + pme_status_dxe_itlb = 0x51, /* DXE Invalid Test Line Branch */ + pme_status_dxe_cle = 0x52, /* DXE Compare Limit Exceeded */ + pme_status_dxe_mle = 0x53, /* DXE Match Limit Exceeded */ + pme_status_sre_irhbni = 0x59, /* SRE Invalid Reaction Head Block */ + /* Number Instructions */ + pme_status_sre_rl = 0x5a, /* SRE Reaction Limit */ + pme_status_sre_pdsrsore = 0x5b, /* SRE PDSR Space Out Range Error */ + pme_status_sre_score = 0x5c, /* SRE Session Context Out Range Error */ + pme_status_sre_ctore = 0x5d, /* SRE Context Table Out Range Error */ + pme_status_sre_il = 0x5e, /* SRE Instruction Limit */ + pme_status_sre_iij = 0x5f, /* SRE Invalid Instruction Jump */ + pme_status_sre_ise = 0x60, /* SRE Instruction Syntax Error */ + pme_status_pmfa_pmtcce = 0x80, /* PMFA PCTCC Error */ + pme_status_pmfa_fcwe = 0x90, /* PMFA Flow Context Write Command Error */ + pme_status_pmfa_fcre = 0x91, /* PMFA Flow Context Read Command Error */ + pme_status_pmfa_ume = 0x93, /* PMFA Unrecognized Mode Error */ + pme_status_pmfa_uce = 0x94, /* PMFA Unrecognized Command Error */ + pme_status_pmfa_ufe = 0x95, /* PMFA Unrecognized Frame Error */ + pme_status_sre_csmre = 0xc0, /* SRE Context System Memory Read Error */ + pme_status_sre_ismre = 0xc1, /* SRE Instruction System Memory Read */ + /* Error */ + pme_status_dxe_smre = 0xc2, /* DXE System Memory Read Error */ + pme_status_pmfa_pmtccsmre = 0xc4, /* PMFA PMTCC System Memory Read */ + /* Error */ + pme_status_pmfa_csmre = 0xc5, /* PMFA Context System Memory Read */ + /* Error */ + pme_status_pmfa_dsmre = 0xc6, /* PMFA Data System Memory Read Error */ + pme_status_kes_cmecce = 0xd2, /* KES Confidence Memory ECC Error */ + pme_status_kes_2btmecce = 0xd4, /*KES 2-Byte Trigger Memory ECC Error */ + pme_status_kes_vltmecce = 0xd5, /*KES Variable Length Trigger Memory */ + /* ECC Error */ + pme_status_pmfa_cmecce = 0xd7, /* PMFA Confidence Memory ECC Error */ + pme_status_pmfa_2btmecce = 0xd9, /* PMFA 2-Byte Trigger Memory ECC */ + /* Error */ + pme_status_pmfa_vltmecce = 0xda, /* PMFA Variable Length Trigger */ + /* Memory ECC Error */ + pme_status_dxe_iemce = 0xdb, /* DXE Internal Examination Memory */ + /* Collision Error */ + pme_status_dxe_iemecce = 0xdc, /* DXE Internal Examination Memory */ + /* ECC Error */ + pme_status_dxe_icmecce = 0xdd, /* DXE Internal Context Memory ECC */ + /* Error */ + pme_status_sre_ctsmwe = 0xe0, /* SRE Context Table System Memory */ + /* Write Error */ + pme_status_pmfa_pmtccsmwe = 0xe7, /* PMFA PMTCC System Memory Write */ + /* Error */ + pme_status_pmfa_csmwe = 0xe8, /* PMFA Context System Memory Write */ + /* Error */ + pme_status_pmfa_dsmwe = 0xe9, /* PMFA Data System Memory Write Error */ +}; + +/* pme_fd_res_flags() returns these flags */ +#define PME_STATUS_UNRELIABLE 0x80 +#define PME_STATUS_TRUNCATED 0x10 +#define PME_STATUS_MASK 0x90 + +/**************/ +/* USER SPACE */ +/**************/ + +#define PME_IOCTL_MAGIC 'p' + +/* Wrapper for a pointer and size. */ +struct pme_buffer { + void __user *data; + size_t size; +}; + +/***************/ +/* SCAN DEVICE */ +/***************/ +/* + * The /dev/pme_scan device creates a file-descriptor that uses scheduled FQs + * serviced by PME's datapath portal. This can only be used for scanning. + */ +#define PME_DEV_SCAN_NODE "pme_scan" +#define PME_DEV_SCAN_PATH "/dev/" PME_DEV_SCAN_NODE + +/* ioctls for 'scan' device */ +#define PMEIO_SETSCAN _IOW(PME_IOCTL_MAGIC, 0x06, struct pme_scan_params) +#define PMEIO_GETSCAN _IOR(PME_IOCTL_MAGIC, 0x07, struct pme_scan_params) +#define PMEIO_RESETSEQ _IO(PME_IOCTL_MAGIC, 0x08) +#define PMEIO_RESETRES _IO(PME_IOCTL_MAGIC, 0x09) +#define PMEIO_SCAN_W1 _IOW(PME_IOCTL_MAGIC, 0x0a, struct pme_scan_cmd) +#define PMEIO_SCAN_Wn _IOWR(PME_IOCTL_MAGIC, 0x0b, struct pme_scan_cmds) +#define PMEIO_SCAN_R1 _IOR(PME_IOCTL_MAGIC, 0x0c, struct pme_scan_result) +#define PMEIO_SCAN_Rn _IOWR(PME_IOCTL_MAGIC, 0x0d, struct pme_scan_results) +#define PMEIO_SCAN _IOWR(PME_IOCTL_MAGIC, 0x0e, struct pme_scan) +/* The release_bufs ioctl takes as parameter a (void *) */ +#define PMEIO_RELEASE_BUFS _IOW(PME_IOCTL_MAGIC, 0x0f, void *) + +/* + * Parameters for PMEIO_SETSCAN and PMEIO_GETSCAN ioctl()s. This doesn't cover + * "sequence" fields ('soc' and 'seqnum'), they can only be influenced by flags + * passed to scan operations, or by PMEIO_RESETSEQ ioctl()s. + */ +struct pme_scan_params { + __u32 flags; /* PME_SCAN_PARAMS_*** bitmask */ + struct pme_scan_params_residue { + __u8 enable; /* boolean, residue enable */ + __u8 length; /* read-only for GETSCAN, ignored for SETSCAN */ + } residue; + struct pme_scan_params_sre { + __u32 sessionid; /* 27-bit */ + __u8 verbose; /* 0-3 */ + __u8 esee; /* boolean, End Of Sui Event Enable */ + } sre; + struct pme_scan_params_dxe { + __u16 clim; /* compare limit */ + __u16 mlim; /* match limit */ + } dxe; + struct pme_scan_params_pattern { + __u8 set; + __u16 subset; + } pattern; +}; +#define PME_SCAN_PARAMS_RESIDUE 0x00000001 +#define PME_SCAN_PARAMS_SRE 0x00000002 +#define PME_SCAN_PARAMS_DXE 0x00000004 +#define PME_SCAN_PARAMS_PATTERN 0x00000008 + +/* argument to PMEIO_SCAN_W1 ioctl */ +struct pme_scan_cmd { + __u32 flags; /* PME_SCAN_CMD_*** bitmask */ + void *opaque; /* value carried through in the pme_scan_result */ + struct pme_buffer input; + struct pme_buffer output; /* ignored for 'RES_BMAN' output */ +}; + +#define PME_SCAN_CMD_RES_BMAN 0x00000001 /* use Bman for output */ +#define PME_SCAN_CMD_STARTRESET 0x00000002 +#define PME_SCAN_CMD_END 0x00000004 + +/* argument to PMEIO_SCAN_Wn ioctl + * 'num' indicates how many 'cmds' are present on input and is updated on the + * response to indicate how many were sent. */ +struct pme_scan_cmds { + unsigned num; + struct pme_scan_cmd __user *cmds; +}; + +/* + * argument to PMEIO_SCAN_R1 ioctl. The ioctl doesn't read any of these + * fields, they are only written to. If the output comes from BMAN buffer + * then 'flags' will have PME_SCAN_RESULT_BMAN set. + */ +struct pme_scan_result { + __u8 flags; /* PME_SCAN_RESULT_*** bitmask */ + enum pme_status status; + struct pme_buffer output; + void *opaque; /* value carried from the pme_scan_cmd */ +}; +#define PME_SCAN_RESULT_UNRELIABLE PME_STATUS_UNRELIABLE +#define PME_SCAN_RESULT_TRUNCATED PME_STATUS_TRUNCATED +#define PME_SCAN_RESULT_BMAN 0x01 + +/* + * argument to PMEIO_SCAN_Rn ioctl. + * 'num' indicates how many 'cmds' are present on input and is updated on the + * response to indicate how many were retrieved. + */ +struct pme_scan_results { + unsigned num; + struct pme_scan_result *results; +}; + +/* argument to PMEIO_SCANWR ioctl. */ +struct pme_scan { + struct pme_scan_cmd cmd; + struct pme_scan_result result; +}; + +/*************/ +/* DB DEVICE */ +/*************/ +/* + * The /dev/pme_db device creates a file-descriptor that uses parked FQs + * serviced by the PME's EFQC (Exclusive Frame Queue Control) mechanism. This is + * usually for PMTCC commands for programming the database, though can also be + * used for high-priority scanning. This device would typically require root + * perms. The EFQC exclusivity is reference-counted, so by default is asserted + * on-demand and released when processing quiesces for the context, but + * exclusivity can be maintained across inter-frame gaps using the INC and DEC + * ioctls, which provide supplementary increments and decrements of the + * reference count. + */ +#define PME_DEV_DB_NODE "pme_db" +#define PME_DEV_DB_PATH "/dev/" PME_DEV_DB_NODE + +/* ioctls for 'db' device */ +#define PMEIO_EXL_INC _IO(PME_IOCTL_MAGIC, 0x00) +#define PMEIO_EXL_DEC _IO(PME_IOCTL_MAGIC, 0x01) +#define PMEIO_EXL_GET _IOR(PME_IOCTL_MAGIC, 0x02, int) +#define PMEIO_PMTCC _IOWR(PME_IOCTL_MAGIC, 0x03, struct pme_db) +#define PMEIO_SRE_RESET _IOR(PME_IOCTL_MAGIC, 0x04, struct pme_db_sre_reset) +#define PMEIO_NOP _IO(PME_IOCTL_MAGIC, 0x05) + +/* Database structures */ +#define PME_DB_RESULT_UNRELIABLE PME_STATUS_UNRELIABLE +#define PME_DB_RESULT_TRUNCATED PME_STATUS_TRUNCATED + +struct pme_db { + struct pme_buffer input; + struct pme_buffer output; + __u8 flags; /* PME_DB_RESULT_*** bitmask */ + enum pme_status status; +}; + +/* This is related to the sre_reset ioctl */ +#define PME_SRE_RULE_VECTOR_SIZE 8 +struct pme_db_sre_reset { + __u32 rule_vector[PME_SRE_RULE_VECTOR_SIZE]; + __u32 rule_index; + __u16 rule_increment; + __u32 rule_repetitions; + __u16 rule_reset_interval; + __u8 rule_reset_priority; +}; + +/****************/ +/* KERNEL SPACE */ +/****************/ + +#ifdef __KERNEL__ + +#include <linux/fsl_qman.h> +#include <linux/fsl_bman.h> + +/* + * "struct pme_hw_flow" represents a flow-context resource for h/w, whereas + * "struct pme_flow" (below) is the s/w type used to provide (and receive) + * parameters to(/from) the h/w resource. + */ +struct pme_hw_flow; + +/* "struct pme_hw_residue" represents a residue resource for h/w. */ +struct pme_hw_residue; + +/* + * This is the pme_flow structure type, used for querying or updating a PME flow + * context + */ +struct pme_flow { + u8 sos:1; + u8 __reserved1:1; + u8 srvm:2; + u8 esee:1; + u8 __reserved2:3; + u8 ren:1; + u8 rlen:7; + /* Sequence Number (48-bit) */ + u16 seqnum_hi; + u32 seqnum_lo; + u32 __reserved3; + u32 sessionid:27; + u32 __reserved4:5; + u16 __reserved5; + /* Residue pointer (48-bit), ignored if ren==0 */ + u16 rptr_hi; + u32 rptr_lo; + u16 clim; + u16 mlim; + u32 __reserved6; +} __packed; +static inline u64 pme_flow_seqnum_get64(const struct pme_flow *p) +{ + return ((u64)p->seqnum_hi << 32) | (u64)p->seqnum_lo; +} +static inline u64 pme_flow_rptr_get64(const struct pme_flow *p) +{ + return ((u64)p->rptr_hi << 32) | (u64)p->rptr_lo; +} +/* Macro, so we compile better if 'v' isn't always 64-bit */ +#define pme_flow_seqnum_set64(p, v) \ + do { \ + struct pme_flow *__p931 = (p); \ + __p931->seqnum_hi = upper_32_bits(v); \ + __p931->seqnum_lo = lower_32_bits(v); \ + } while (0) +#define pme_flow_rptr_set64(p, v) \ + do { \ + struct pme_flow *__p931 = (p); \ + __p931->rptr_hi = upper_32_bits(v); \ + __p931->rptr_lo = lower_32_bits(v); \ + } while (0) + +/* + * pme_ctx_ctrl_update_flow(), pme_fd_cmd_fcw() and pme_scan_params::flags + * use these; + */ +#define PME_CMD_FCW_RES 0x80 /* "Residue": ren, rlen */ +#define PME_CMD_FCW_SEQ 0x40 /* "Sequence": sos, sequnum */ +#define PME_CMD_FCW_SRE 0x20 /* "Stateful Rule": srvm, esee, sessionid */ +#define PME_CMD_FCW_DXE 0x10 /* "Data Examination": clim, mlim */ +#define PME_CMD_FCW_ALL 0xf0 + +/* pme_ctx_scan() and pme_fd_cmd_scan() use these; */ +#define PME_CMD_SCAN_SRVM(n) ((n) << 3) /* n in [0..3] */ +#define PME_CMD_SCAN_FLUSH 0x04 +#define PME_CMD_SCAN_SR 0x02 /* aka "Start of Flow or Reset */ +#define PME_CMD_SCAN_E 0x01 /* aka "End of Flow */ + +/***********************/ +/* low-level functions */ +/***********************/ + +/* (De)Allocate PME hardware resources */ +struct pme_hw_residue *pme_hw_residue_new(void); +void pme_hw_residue_free(struct pme_hw_residue *); +struct pme_hw_flow *pme_hw_flow_new(void); +void pme_hw_flow_free(struct pme_hw_flow *); + +/* Initialise a flow context to known default values */ +void pme_sw_flow_init(struct pme_flow *); + +/* + * Fill in an "Initialise FQ" management command for a PME input FQ. NB, the + * caller is responsible for setting the following fields, they will not be set + * by the API; + * - initfq->fqid, the frame queue to be initialised + * - initfq->count, should most likely be zero. A count of 0 initialises 1 FQ, + * a count of 1 initialises 2 FQs, etc/ + * The 'qos' parameter indicates which workqueue in the PME channel the + * FQ should schedule to for regular scanning (0..7). If 'flow' is non-NULL the + * FQ is configured for Flow Mode, otherwise it is configured for Direct Action + * Mode. 'bpid' is the buffer pool ID to use when Bman-based output is + * produced, and 'rfqid' is the frame queue ID to enqueue output frames to. + * Following this api, when calling qm_mc_commit(), use QM_MCC_VERB_INITFQ_SCHED + * for regular PMEscanning or QM_MCC_VERB_INITFQ_PARK for exclusive PME + * processing (usually PMTCC). + */ +void pme_initfq(struct qm_mcc_initfq *initfq, struct pme_hw_flow *flow, u8 qos, + u8 rbpid, u32 rfqid); + +/* Given a dequeued frame from PME, return status/flags */ +static inline enum pme_status pme_fd_res_status(const struct qm_fd *fd) +{ + return (enum pme_status)(fd->status >> 24); +} +static inline u8 pme_fd_res_flags(const struct qm_fd *fd) +{ + return (fd->status >> 16) & PME_STATUS_MASK; +} + +/* Fill in a frame descriptor for a NOP command. */ +void pme_fd_cmd_nop(struct qm_fd *fd); + +/* + * Fill in a frame descriptor for a Flow Context Write command. NB, the caller + * is responsible for setting all the relevant fields in 'flow', only the + * following fields are set by the API; + * - flow->rptr_hi + * - flow->rptr_lo + * The fields in 'flow' are divided into 4 groups, 'flags' indicates which of + * them should be written to the h/w flow context using PME_CMD_FCW_*** defines. + * 'residue' should be non-NULL iff flow->ren is non-zero and PME_CMD_FCW_RES is + * set. + */ +void pme_fd_cmd_fcw(struct qm_fd *fd, u8 flags, struct pme_flow *flow, + struct pme_hw_residue *residue); + +/* Fill in a frame descriptor for a Flow Context Read command. */ +void pme_fd_cmd_fcr(struct qm_fd *fd, struct pme_flow *flow); + +/* Modify a frame descriptor for a PMTCC command (only modifies 'cmd' field) */ +void pme_fd_cmd_pmtcc(struct qm_fd *fd); + +/* + * Modify a frame descriptor for a Scan command (only modifies 'cmd' field). + * 'flags' are chosen from PME_CMD_SCAN_*** symbols. NB, the use of the + * intermediary representation (and PME_SCAN_ARGS) improves performance - ie. + * if the scan params are essentially constant, this compacts them for storage + * into the same format used in the interface to h/w. So it reduces parameter + * passing, stack-use, and encoding time. + */ +#define PME_SCAN_ARGS(flags, set, subset) \ +({ \ + u8 __flags461 = (flags); \ + u8 __set461 = (set); \ + u16 __subset461 = (subset); \ + u32 __res461 = ((u32)__flags461 << 24) | \ + ((u32)__set461 << 16) | \ + (u32)__subset461; \ + __res461; \ +}) +void pme_fd_cmd_scan(struct qm_fd *fd, u32 args); + +/* convert pointer to physical address for use by PME */ +dma_addr_t pme_map(void *ptr); +int pme_map_error(dma_addr_t dma_addr); + +enum pme_cmd_type { + pme_cmd_nop = 0x7, + pme_cmd_flow_read = 0x5, /* aka FCR */ + pme_cmd_flow_write = 0x4, /* aka FCW */ + pme_cmd_pmtcc = 0x1, + pme_cmd_scan = 0 +}; + +/************************/ +/* high-level functions */ +/************************/ + +/* predeclaration of a private structure" */ +struct pme_ctx; +struct pme_nostash; + +/* + * Calls to pme_ctx_scan() and pme_ctx_pmtcc() provide these, and they are + * provided back in the completion callback. You can embed this within a larger + * structure in order to maintain per-command data of your own. The fields are + * owned by the driver until the callback is invoked, so for example do not link + * this token into a list while the command is in-flight! + */ +struct pme_ctx_token { + u32 blob[4]; + struct list_head node; + enum pme_cmd_type cmd_type:8; + u8 is_disable_flush; +}; + +struct pme_ctx_ctrl_token { + void (*cb)(struct pme_ctx *, const struct qm_fd *, + struct pme_ctx_ctrl_token *); + void (*ern_cb)(struct pme_ctx *, const struct qm_mr_entry *, + struct pme_ctx_ctrl_token *); + /* don't touch the rest */ + struct pme_hw_flow *internal_flow_ptr; + struct pme_flow *usr_flow_ptr; + struct pme_ctx_token base_token; +}; + +/* Scan results invoke a user-provided callback of this type */ +typedef void (*pme_scan_cb)(struct pme_ctx *, const struct qm_fd *, + struct pme_ctx_token *); +/* + * Enqueue rejections may happen before order-restoration or after (eg. if due + * to congestion or tail-drop). Use * 'rc' code of the 'mr_entry' to + * determine. + */ +typedef void (*pme_scan_ern_cb)(struct pme_ctx *, const struct qm_mr_entry *, + struct pme_ctx_token *); + +/* + * PME "association" - ie. connects two frame-queues, with or without a PME flow + * (if not, direct action mode), and manages mux/demux of scans and flow-context + * updates. To allow state used by your callback to be stashed, as well as + * optimising the PME driver and the Qman driver beneath it, embed this + * structure as the first field in your own context structure. + */ +struct pme_ctx { + struct qman_fq fq; + /* + * IMPORTANT: Set (only) these two fields prior to calling + * pme_ctx_init(). 'ern_cb' can be NULL if you know you will not + * receive enqueue rejections. + */ + pme_scan_cb cb; + pme_scan_ern_cb ern_cb; + /* + * These fields should not be manipulated directly. Also the structure + * may change and/or grow, so avoid making any alignment or size + * assumptions. + */ + atomic_t refs; + volatile u32 flags; + spinlock_t lock; + wait_queue_head_t queue; + struct list_head tokens; + /* + * TODO: the following "slow-path" values should be bundled into a + * secondary structure so that sizeof(struct pme_ctx) is minimised (for + * stashing of caller-side fast-path state). + */ + struct pme_hw_flow *hw_flow; + struct pme_hw_residue *hw_residue; + struct qm_fqd_stashing stashing; + struct qm_fd update_fd; + struct pme_nostash *us_data; + u32 pme_rev1; + u32 pme_rev2; + int max_scan_size; +}; + +/* Flags for pme_ctx_init() */ +#define PME_CTX_FLAG_LOCKED 0x00000001 /* use QMAN_FQ_FLAG_LOCKED */ +#define PME_CTX_FLAG_EXCLUSIVE 0x00000002 /* unscheduled, exclusive mode */ +#define PME_CTX_FLAG_PMTCC 0x00000004 /* PMTCC rather than scanning */ +#define PME_CTX_FLAG_DIRECT 0x00000008 /* Direct Action mode (not Flow) */ +#define PME_CTX_FLAG_LOCAL 0x00000020 /* Ignore dest, use cpu portal */ + +/* Flags for operations */ +#ifdef CONFIG_FSL_DPA_CAN_WAIT +#define PME_CTX_OP_WAIT QMAN_ENQUEUE_FLAG_WAIT +#define PME_CTX_OP_WAIT_INT QMAN_ENQUEUE_FLAG_WAIT_INT +#endif +#define PME_CTX_OP_RESETRESLEN 0x00000001 /* no en/disable, just set len */ +/* + * Note that pme_ctx_ctrl_update_flow() also uses PME_CMD_FCW flags, so they + * mustn't conflict with PME_CTX_OP_***. + * Also, the above are defined to match QMAN_ENQUEUE values for optimisation + * purposes (ie. fast-path operations that don't _WAIT will not incur PME->QMAN + * flag conversion overheads). + */ + +/** + * pme_ctx_init - Initialise a PME context + * @ctx: the context structure to initialise + * @flags: bit-mask of PME_CTX_FLAG_*** options + * @bpid: buffer pool ID used for any Bman-generated output + * @qosin: workqueue priority on the PME channel (0-7) + * @qosout: workqueue priority on the result channel (0-7) + * @dest: channel to receive results from PME + * @stashing: desired dequeue stashing behaviour + * + * This creates and initialises a PME context, composed of two FQs, an optional + * flow-context, and scheduling parameters for the datapath. The ctx->cb and + * ctx->pool fields must have been initialised prior to calling this api. The + * initialised context is left 'disabled', meaning that the FQ towards PME is + * Parked and no operations are possible. If PME_CTX_INIT_EXCLUSIVE is specified + * in @flags, then the input FQ is not scheduled, otherwise enabling the context + * will schedule the FQ to PME. Exclusive access is only available if the driver + * is built with control functionality and if the operating system has access to + * PME's CCSR map. @qosin applies if EXCLUSIVE is not set, and indicates which + * of the PME's 8 prioritised workqueues the FQ should schedule to. @dest + * indicates the channel that should receive results from PME, unless + * PME_CTX_FLAG_LOCAL is set in which case this parameter is ignored and the + * dedicated portal channel for the current cpu will be used instead. @qosout + * indicates which of the 8 prioritised workqueus the FQ should schedule to on + * the s/w portal. @stashing configures whether FQ context, frame data, and/or + * frame annotation should be stashed into cpu cache when dequeuing output, and + * if so, how many cachelines. For the FQ context part, set the number of + * cachelines to cover; 1. sizeof(struct qman_fq_base), to accelerate only Qman + * driver processing, 2. sizeof(struct pme_ctx), to accelerate Qman and PME + * driver processing, or 3. sizeof(<user-struct>), where <user-struct> is the + * caller's structure of which the pme_ctx is the first member - this will allow + * callbacks to operate on state which has a high probability of already being + * in-cache. + * Returns 0 on success. + */ +int pme_ctx_init(struct pme_ctx *ctx, u32 flags, u32 bpid, u8 qosin, + u8 qosout, u16 dest, + const struct qm_fqd_stashing *stashing); + +/* Cleanup allocated resources */ +void pme_ctx_finish(struct pme_ctx *ctx); + +/* enable a context */ +int pme_ctx_enable(struct pme_ctx *ctx); + +/* + * disable a context + * If it returns zero, the context is disabled. + * If it returns +1, the context is disabling and the token's completion + * callback will be invoked when disabling is complete. + * Returns -EBUSY on error, in which case the context remains enabled. + * If the PME_CTX_OP_WAIT flag is specified, it should only fail if + * PME_CTX_OP_WAIT_INT is also specified and a signal is pending. + */ +int pme_ctx_disable(struct pme_ctx *ctx, u32 flags, + struct pme_ctx_ctrl_token *token); + +/* query whether a context is disabled. Returns > 0 if the ctx is disabled. */ +int pme_ctx_is_disabled(struct pme_ctx *ctx); + +/* query whether a context is in an error state. */ +int pme_ctx_is_dead(struct pme_ctx *ctx); + +/* + * A pre-condition for the following APIs is the ctx must be disabled + * dest maybe ignored if the flags parameter indicated LOCAL during the + * corresponding pme_ctx_init. + */ +int pme_ctx_reconfigure_tx(struct pme_ctx *ctx, u32 bpid, u8 qosin); +int pme_ctx_reconfigure_rx(struct pme_ctx *ctx, u8 qosout, + u16 dest, const struct qm_fqd_stashing *stashing); + +/* + * Precondition: pme_ctx must be enabled + * if PME_CTX_OP_WAIT is specified, it'll wait (if it has to) to start the ctrl + * command but never waits for it to complete. The callback serves that purpose. + * NB: 'params' may be modified by this call. For instance if + * PME_CTX_OP_RESETRESLEN was specified and residue is enabled, then the + * params->ren will be set to 1 (in order not to disabled residue). + * NB: _update() will overwrite the 'params->rptr_[hi/low]' fields since the + * residue resource is managed by this layer. + */ +int pme_ctx_ctrl_update_flow(struct pme_ctx *ctx, u32 flags, + struct pme_flow *params, struct pme_ctx_ctrl_token *token); +int pme_ctx_ctrl_read_flow(struct pme_ctx *ctx, u32 flags, + struct pme_flow *params, struct pme_ctx_ctrl_token *token); +int pme_ctx_ctrl_nop(struct pme_ctx *ctx, u32 flags, + struct pme_ctx_ctrl_token *token); + +/* + * if PME_CTX_OP_WAIT is specified, it'll wait (if it has to) to start the scan + * but never waits for it to complete. The scan callback serves that purpose. + * 'fd' is modified by both these calls, but only the 'cmd' field. The 'args' + * parameters is produced by the PME_SCAN_ARGS() inline function. + */ +int pme_ctx_scan(struct pme_ctx *ctx, u32 flags, struct qm_fd *fd, u32 args, + struct pme_ctx_token *token); +int pme_ctx_pmtcc(struct pme_ctx *ctx, u32 flags, struct qm_fd *fd, + struct pme_ctx_token *token); + +/* + * This is extends pme_ctx_scan() to provide ORP support. 'orp_fq' represents + * the FQD that is used as the ORP and 'seqnum' is the sequence number to use + * for order restoration, these are usually the FQ the frame was dequeued from + * and the sequence number of that dequeued frame (respectively). + */ +int pme_ctx_scan_orp(struct pme_ctx *ctx, u32 flags, struct qm_fd *fd, u32 args, + struct pme_ctx_token *token, struct qman_fq *orp_fq, u16 seqnum); + +/* Precondition: must be PME_CTX_FLAG_EXCLUSIVE */ +int pme_ctx_exclusive_inc(struct pme_ctx *ctx, u32 flags); +void pme_ctx_exclusive_dec(struct pme_ctx *ctx); + +/* Does pme have access to ccsr */ +int pme2_have_control(void); + +/**************************/ +/* control-plane only API */ +/**************************/ +#ifdef CONFIG_FSL_PME2_CTRL + +/* Attributes for pme_reg_[set|get]() */ +enum pme_attr { + pme_attr_efqc_int, + pme_attr_sw_db, + pme_attr_dmcr, + pme_attr_smcr, + pme_attr_famcr, + pme_attr_kvlts, + pme_attr_max_chain_length, + pme_attr_pattern_range_counter_idx, + pme_attr_pattern_range_counter_mask, + pme_attr_max_allowed_test_line_per_pattern, + pme_attr_max_pdsr_index, + pme_attr_max_pattern_matches_per_sui, + pme_attr_max_pattern_evaluations_per_sui, + pme_attr_report_length_limit, + pme_attr_end_of_simple_sui_report, + pme_attr_aim, + pme_attr_sre_context_size, + pme_attr_sre_rule_num, + pme_attr_sre_session_ctx_num, + pme_attr_end_of_sui_reaction_ptr, + pme_attr_sre_pscl, + pme_attr_sre_max_block_num, + pme_attr_sre_max_instruction_limit, + pme_attr_sre_max_index_size, + pme_attr_sre_max_offset_ctrl, + pme_attr_src_id, + pme_attr_liodnr, + pme_attr_rev1, + pme_attr_rev2, + pme_attr_srrv0, + pme_attr_srrv1, + pme_attr_srrv2, + pme_attr_srrv3, + pme_attr_srrv4, + pme_attr_srrv5, + pme_attr_srrv6, + pme_attr_srrv7, + pme_attr_srrfi, + pme_attr_srri, + pme_attr_srrwc, + pme_attr_srrr, + pme_attr_trunci, + pme_attr_rbc, + pme_attr_tbt0ecc1ec, + pme_attr_tbt1ecc1ec, + pme_attr_vlt0ecc1ec, + pme_attr_vlt1ecc1ec, + pme_attr_cmecc1ec, + pme_attr_dxcmecc1ec, + pme_attr_dxemecc1ec, + pme_attr_stnib, + pme_attr_stnis, + pme_attr_stnth1, + pme_attr_stnth2, + pme_attr_stnthv, + pme_attr_stnths, + pme_attr_stnch, + pme_attr_stnpm, + pme_attr_stns1m, + pme_attr_stnpmr, + pme_attr_stndsr, + pme_attr_stnesr, + pme_attr_stns1r, + pme_attr_stnob, + pme_attr_mia_byc, + pme_attr_mia_blc, + pme_attr_isr, + pme_attr_tbt0ecc1th, + pme_attr_tbt1ecc1th, + pme_attr_vlt0ecc1th, + pme_attr_vlt1ecc1th, + pme_attr_cmecc1th, + pme_attr_dxcmecc1th, + pme_attr_dxemecc1th, + pme_attr_esr, + pme_attr_ecr0, + pme_attr_ecr1, + pme_attr_pmstat, + pme_attr_pmtr, + pme_attr_pehd, + pme_attr_ecc1bes, + pme_attr_ecc2bes, + pme_attr_eccaddr, + pme_attr_ecccode, + pme_attr_miace, + pme_attr_miacr, + pme_attr_cdcr, + pme_attr_faconf, + pme_attr_ier, + pme_attr_isdr, + pme_attr_iir, + pme_attr_pdsrbah, + pme_attr_pdsrbal, + pme_attr_scbarh, + pme_attr_scbarl, + pme_attr_bsc_first, /* create 64-wide space for bsc */ + pme_attr_bsc_last = pme_attr_bsc_first + 63, + pme_attr_faconf_rst, + pme_attr_faconf_en, + pme_attr_efqc +}; + +#define pme_attr_bsc(n) (pme_attr_bsc_first + (n)) +/* Get/set driver attributes */ +int pme_attr_set(enum pme_attr attr, u32 val); +int pme_attr_get(enum pme_attr attr, u32 *val); +int pme_stat_get(enum pme_attr stat, u64 *value, int reset); +#endif /* defined(CONFIG_FSL_PME2_CTRL) */ + +#ifdef CONFIG_COMPAT +#include <linux/compat.h> + +struct compat_pme_buffer { + compat_uptr_t data; + compat_size_t size; +}; + +struct compat_pme_scan_cmd { + __u32 flags; /* PME_SCAN_CMD_*** bitmask */ + compat_uptr_t opaque; + struct compat_pme_buffer input; + struct compat_pme_buffer output; +}; +#define PMEIO_SCAN_W132 _IOW(PME_IOCTL_MAGIC, 0x0a, struct compat_pme_scan_cmd) + +struct compat_pme_scan_cmds { + compat_uint_t num; + compat_uptr_t cmds; +}; +#define PMEIO_SCAN_Wn32 _IOWR(PME_IOCTL_MAGIC, 0x0b, \ + struct compat_pme_scan_cmds) + + +struct compat_pme_scan_result { + __u8 flags; /* PME_SCAN_RESULT_*** bitmask */ + enum pme_status status; + struct compat_pme_buffer output; + compat_uptr_t opaque; /* value carried from the pme_scan_cmd */ +}; +#define PMEIO_SCAN_R132 _IOR(PME_IOCTL_MAGIC, 0x0c, \ + struct compat_pme_scan_result) + + +struct compat_pme_scan_results { + compat_uint_t num; + compat_uptr_t results; +}; +#define PMEIO_SCAN_Rn32 _IOWR(PME_IOCTL_MAGIC, 0x0d, \ + struct compat_pme_scan_results) + + +struct compat_pme_scan { + struct compat_pme_scan_cmd cmd; + struct compat_pme_scan_result result; +}; +#define PMEIO_SCAN32 _IOWR(PME_IOCTL_MAGIC, 0x0e, struct compat_pme_scan) + +struct compat_pme_db { + struct compat_pme_buffer input; + struct compat_pme_buffer output; + __u8 flags; /* PME_DB_RESULT_*** bitmask */ + enum pme_status status; +}; +#define PMEIO_PMTCC32 _IOWR(PME_IOCTL_MAGIC, 0x03, struct compat_pme_db) + +#endif /* CONFIG_COMPAT */ + +#endif /* __KERNEL__ */ + +#endif /* FSL_PME_H */ diff --git a/include/linux/fsl_qman.h b/include/linux/fsl_qman.h new file mode 100644 index 0000000..3b594cc --- /dev/null +++ b/include/linux/fsl_qman.h @@ -0,0 +1,3368 @@ +/* Copyright 2008-2012 Freescale Semiconductor, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FSL_QMAN_H +#define FSL_QMAN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Last updated for v00.800 of the BG */ + +/* Hardware constants */ +#define QM_CHANNEL_SWPORTAL0 0 +#define QMAN_CHANNEL_POOL1 0x21 +#define QMAN_CHANNEL_CAAM 0x80 +#define QMAN_CHANNEL_PME 0xa0 +#define QMAN_CHANNEL_POOL1_REV3 0x401 +#define QMAN_CHANNEL_CAAM_REV3 0x840 +#define QMAN_CHANNEL_PME_REV3 0x860 +#define QMAN_CHANNEL_DCE 0x8a0 +#define QMAN_CHANNEL_DCE_QMANREV312 0x880 +extern u16 qm_channel_pool1; +extern u16 qm_channel_caam; +extern u16 qm_channel_pme; +extern u16 qm_channel_dce; +enum qm_dc_portal { + qm_dc_portal_fman0 = 0, + qm_dc_portal_fman1 = 1, + qm_dc_portal_caam = 2, + qm_dc_portal_pme = 3, + qm_dc_portal_rman = 4, + qm_dc_portal_dce = 5 +}; + +/* Portal processing (interrupt) sources */ +#define QM_PIRQ_CCSCI 0x00200000 /* CEETM Congestion State Change */ +#define QM_PIRQ_CSCI 0x00100000 /* Congestion State Change */ +#define QM_PIRQ_EQCI 0x00080000 /* Enqueue Command Committed */ +#define QM_PIRQ_EQRI 0x00040000 /* EQCR Ring (below threshold) */ +#define QM_PIRQ_DQRI 0x00020000 /* DQRR Ring (non-empty) */ +#define QM_PIRQ_MRI 0x00010000 /* MR Ring (non-empty) */ +/* This mask contains all the interrupt sources that need handling except DQRI, + * ie. that if present should trigger slow-path processing. */ +#define QM_PIRQ_SLOW (QM_PIRQ_CSCI | QM_PIRQ_EQCI | QM_PIRQ_EQRI | \ + QM_PIRQ_MRI | QM_PIRQ_CCSCI) + +/* --- Clock speed --- */ +/* A qman driver instance may or may not know the current qman clock speed. + * However, certain CEETM calculations may not be possible if this is not known. + * The 'set' function will only succeed (return zero) if the driver did not + * already know the clock speed. Likewise, the 'get' function will only succeed + * if the driver does know the clock speed (either because it knew when booting, + * or was told via 'set'). In cases where software is running on a driver + * instance that does not know the clock speed (eg. on a hypervised data-plane), + * and the user can obtain the current qman clock speed by other means (eg. from + * a message sent from the control-plane), then the 'set' function can be used + * to enable rate-calculations in a driver where it would otherwise not be + * possible. */ +int qm_get_clock(u64 *clock_hz); +int qm_set_clock(u64 clock_hz); + +/* For qman_static_dequeue_*** APIs */ +#define QM_SDQCR_CHANNELS_POOL_MASK 0x00007fff +/* for n in [1,15] */ +#define QM_SDQCR_CHANNELS_POOL(n) (0x00008000 >> (n)) +/* for conversion from n of qm_channel */ +static inline u32 QM_SDQCR_CHANNELS_POOL_CONV(u16 channel) +{ + return QM_SDQCR_CHANNELS_POOL(channel + 1 - qm_channel_pool1); +} + +/* For qman_volatile_dequeue(); Choose one PRECEDENCE. EXACT is optional. Use + * NUMFRAMES(n) (6-bit) or NUMFRAMES_TILLEMPTY to fill in the frame-count. Use + * FQID(n) to fill in the frame queue ID. */ +#define QM_VDQCR_PRECEDENCE_VDQCR 0x0 +#define QM_VDQCR_PRECEDENCE_SDQCR 0x80000000 +#define QM_VDQCR_EXACT 0x40000000 +#define QM_VDQCR_NUMFRAMES_MASK 0x3f000000 +#define QM_VDQCR_NUMFRAMES_SET(n) (((n) & 0x3f) << 24) +#define QM_VDQCR_NUMFRAMES_GET(n) (((n) >> 24) & 0x3f) +#define QM_VDQCR_NUMFRAMES_TILLEMPTY QM_VDQCR_NUMFRAMES_SET(0) + + +/* ------------------------------------------------------- */ +/* --- Qman data structures (and associated constants) --- */ + +/* Represents s/w corenet portal mapped data structures */ +struct qm_eqcr_entry; /* EQCR (EnQueue Command Ring) entries */ +struct qm_dqrr_entry; /* DQRR (DeQueue Response Ring) entries */ +struct qm_mr_entry; /* MR (Message Ring) entries */ +struct qm_mc_command; /* MC (Management Command) command */ +struct qm_mc_result; /* MC result */ + +/* See David Lapp's "Frame formats" document, "dpateam", Jan 07, 2008 */ +#define QM_FD_FORMAT_SG 0x4 +#define QM_FD_FORMAT_LONG 0x2 +#define QM_FD_FORMAT_COMPOUND 0x1 +enum qm_fd_format { + /* 'contig' implies a contiguous buffer, whereas 'sg' implies a + * scatter-gather table. 'big' implies a 29-bit length with no offset + * field, otherwise length is 20-bit and offset is 9-bit. 'compound' + * implies a s/g-like table, where each entry itself represents a frame + * (contiguous or scatter-gather) and the 29-bit "length" is + * interpreted purely for congestion calculations, ie. a "congestion + * weight". */ + qm_fd_contig = 0, + qm_fd_contig_big = QM_FD_FORMAT_LONG, + qm_fd_sg = QM_FD_FORMAT_SG, + qm_fd_sg_big = QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG, + qm_fd_compound = QM_FD_FORMAT_COMPOUND +}; + +/* Capitalised versions are un-typed but can be used in static expressions */ +#define QM_FD_CONTIG 0 +#define QM_FD_CONTIG_BIG QM_FD_FORMAT_LONG +#define QM_FD_SG QM_FD_FORMAT_SG +#define QM_FD_SG_BIG (QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG) +#define QM_FD_COMPOUND QM_FD_FORMAT_COMPOUND + +/* See 1.5.1.1: "Frame Descriptor (FD)" */ +struct qm_fd { + union { + struct { + u8 dd:2; /* dynamic debug */ + u8 liodn_offset:6; + u8 bpid:8; /* Buffer Pool ID */ + u8 eliodn_offset:4; + u8 __reserved:4; + u8 addr_hi; /* high 8-bits of 40-bit address */ + u32 addr_lo; /* low 32-bits of 40-bit address */ + }; + struct { + u64 __notaddress:24; + /* More efficient address accessor */ + u64 addr:40; + }; + u64 opaque_addr; + }; + /* The 'format' field indicates the interpretation of the remaining 29 + * bits of the 32-bit word. For packing reasons, it is duplicated in the + * other union elements. Note, union'd structs are difficult to use with + * static initialisation under gcc, in which case use the "opaque" form + * with one of the macros. */ + union { + /* For easier/faster copying of this part of the fd (eg. from a + * DQRR entry to an EQCR entry) copy 'opaque' */ + u32 opaque; + /* If 'format' is _contig or _sg, 20b length and 9b offset */ + struct { + enum qm_fd_format format:3; + u16 offset:9; + u32 length20:20; + }; + /* If 'format' is _contig_big or _sg_big, 29b length */ + struct { + enum qm_fd_format _format1:3; + u32 length29:29; + }; + /* If 'format' is _compound, 29b "congestion weight" */ + struct { + enum qm_fd_format _format2:3; + u32 cong_weight:29; + }; + }; + union { + u32 cmd; + u32 status; + }; +} __aligned(8); +#define QM_FD_DD_NULL 0x00 +#define QM_FD_PID_MASK 0x3f +static inline u64 qm_fd_addr_get64(const struct qm_fd *fd) +{ + return fd->addr; +} + +static inline dma_addr_t qm_fd_addr(const struct qm_fd *fd) +{ + return (dma_addr_t)fd->addr; +} +/* Macro, so we compile better if 'v' isn't always 64-bit */ +#define qm_fd_addr_set64(fd, v) \ + do { \ + struct qm_fd *__fd931 = (fd); \ + __fd931->addr = v; \ + } while (0) + +/* For static initialisation of FDs (which is complicated by the use of unions + * in "struct qm_fd"), use the following macros. Note that; + * - 'dd', 'pid' and 'bpid' are ignored because there's no static initialisation + * use-case), + * - use capitalised QM_FD_*** formats for static initialisation. + */ +#define QM_FD_FMT_20(cmd, addr_hi, addr_lo, fmt, off, len) \ + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \ + { (((fmt)&0x7) << 29) | (((off)&0x1ff) << 20) | ((len)&0xfffff) }, \ + { cmd } } +#define QM_FD_FMT_29(cmd, addr_hi, addr_lo, fmt, len) \ + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \ + { (((fmt)&0x7) << 29) | ((len)&0x1fffffff) }, \ + { cmd } } + +/* See 2.2.1.3 Multi-Core Datapath Acceleration Architecture */ +#define QM_SG_OFFSET_MASK 0x1FFF +struct qm_sg_entry { + union { + struct { + u8 __reserved1[3]; + u8 addr_hi; /* high 8-bits of 40-bit address */ + u32 addr_lo; /* low 32-bits of 40-bit address */ + }; + struct { + u64 __notaddress:24; + u64 addr:40; + }; + }; + u32 extension:1; /* Extension bit */ + u32 final:1; /* Final bit */ + u32 length:30; + u8 __reserved2; + u8 bpid; + u16 __reserved3:3; + u16 offset:13; +} __packed; +static inline u64 qm_sg_entry_get64(const struct qm_sg_entry *sg) +{ + return sg->addr; +} +static inline dma_addr_t qm_sg_addr(const struct qm_sg_entry *sg) +{ + return (dma_addr_t)sg->addr; +} +/* Macro, so we compile better if 'v' isn't always 64-bit */ +#define qm_sg_entry_set64(sg, v) \ + do { \ + struct qm_sg_entry *__sg931 = (sg); \ + __sg931->addr = v; \ + } while (0) + +/* See 1.5.8.1: "Enqueue Command" */ +struct qm_eqcr_entry { + u8 __dont_write_directly__verb; + u8 dca; + u16 seqnum; + u32 orp; /* 24-bit */ + u32 fqid; /* 24-bit */ + u32 tag; + struct qm_fd fd; + u8 __reserved3[32]; +} __packed; +#define QM_EQCR_VERB_VBIT 0x80 +#define QM_EQCR_VERB_CMD_MASK 0x61 /* but only one value; */ +#define QM_EQCR_VERB_CMD_ENQUEUE 0x01 +#define QM_EQCR_VERB_COLOUR_MASK 0x18 /* 4 possible values; */ +#define QM_EQCR_VERB_COLOUR_GREEN 0x00 +#define QM_EQCR_VERB_COLOUR_YELLOW 0x08 +#define QM_EQCR_VERB_COLOUR_RED 0x10 +#define QM_EQCR_VERB_COLOUR_OVERRIDE 0x18 +#define QM_EQCR_VERB_INTERRUPT 0x04 /* on command consumption */ +#define QM_EQCR_VERB_ORP 0x02 /* enable order restoration */ +#define QM_EQCR_DCA_ENABLE 0x80 +#define QM_EQCR_DCA_PARK 0x40 +#define QM_EQCR_DCA_IDXMASK 0x0f /* "DQRR::idx" goes here */ +#define QM_EQCR_SEQNUM_NESN 0x8000 /* Advance NESN */ +#define QM_EQCR_SEQNUM_NLIS 0x4000 /* More fragments to come */ +#define QM_EQCR_SEQNUM_SEQMASK 0x3fff /* sequence number goes here */ +#define QM_EQCR_FQID_NULL 0 /* eg. for an ORP seqnum hole */ + +/* See 1.5.8.2: "Frame Dequeue Response" */ +struct qm_dqrr_entry { + u8 verb; + u8 stat; + u16 seqnum; /* 15-bit */ + u8 tok; + u8 __reserved2[3]; + u32 fqid; /* 24-bit */ + u32 contextB; + struct qm_fd fd; + u8 __reserved4[32]; +}; +#define QM_DQRR_VERB_VBIT 0x80 +#define QM_DQRR_VERB_MASK 0x7f /* where the verb contains; */ +#define QM_DQRR_VERB_FRAME_DEQUEUE 0x60 /* "this format" */ +#define QM_DQRR_STAT_FQ_EMPTY 0x80 /* FQ empty */ +#define QM_DQRR_STAT_FQ_HELDACTIVE 0x40 /* FQ held active */ +#define QM_DQRR_STAT_FQ_FORCEELIGIBLE 0x20 /* FQ was force-eligible'd */ +#define QM_DQRR_STAT_FD_VALID 0x10 /* has a non-NULL FD */ +#define QM_DQRR_STAT_UNSCHEDULED 0x02 /* Unscheduled dequeue */ +#define QM_DQRR_STAT_DQCR_EXPIRED 0x01 /* VDQCR or PDQCR expired*/ + +/* See 1.5.8.3: "ERN Message Response" */ +/* See 1.5.8.4: "FQ State Change Notification" */ +struct qm_mr_entry { + u8 verb; + union { + struct { + u8 dca; + u16 seqnum; + u8 rc; /* Rejection Code */ + u32 orp:24; + u32 fqid; /* 24-bit */ + u32 tag; + struct qm_fd fd; + } __packed ern; + struct { + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */ + u8 __reserved1:3; + enum qm_dc_portal portal:3; + u16 __reserved2; + u8 rc; /* Rejection Code */ + u32 __reserved3:24; + u32 fqid; /* 24-bit */ + u32 tag; + struct qm_fd fd; + } __packed dcern; + struct { + u8 fqs; /* Frame Queue Status */ + u8 __reserved1[6]; + u32 fqid; /* 24-bit */ + u32 contextB; + u8 __reserved2[16]; + } __packed fq; /* FQRN/FQRNI/FQRL/FQPN */ + }; + u8 __reserved2[32]; +} __packed; +#define QM_MR_VERB_VBIT 0x80 +/* The "ern" VERB bits match QM_EQCR_VERB_*** so aren't reproduced here. ERNs + * originating from direct-connect portals ("dcern") use 0x20 as a verb which + * would be invalid as a s/w enqueue verb. A s/w ERN can be distinguished from + * the other MR types by noting if the 0x20 bit is unset. */ +#define QM_MR_VERB_TYPE_MASK 0x27 +#define QM_MR_VERB_DC_ERN 0x20 +#define QM_MR_VERB_FQRN 0x21 +#define QM_MR_VERB_FQRNI 0x22 +#define QM_MR_VERB_FQRL 0x23 +#define QM_MR_VERB_FQPN 0x24 +#define QM_MR_RC_MASK 0xf0 /* contains one of; */ +#define QM_MR_RC_CGR_TAILDROP 0x00 +#define QM_MR_RC_WRED 0x10 +#define QM_MR_RC_ERROR 0x20 +#define QM_MR_RC_ORPWINDOW_EARLY 0x30 +#define QM_MR_RC_ORPWINDOW_LATE 0x40 +#define QM_MR_RC_FQ_TAILDROP 0x50 +#define QM_MR_RC_ORPWINDOW_RETIRED 0x60 +#define QM_MR_RC_ORP_ZERO 0x70 +#define QM_MR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */ +#define QM_MR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */ +#define QM_MR_DCERN_COLOUR_GREEN 0x00 +#define QM_MR_DCERN_COLOUR_YELLOW 0x01 +#define QM_MR_DCERN_COLOUR_RED 0x02 +#define QM_MR_DCERN_COLOUR_OVERRIDE 0x03 + +/* An identical structure of FQD fields is present in the "Init FQ" command and + * the "Query FQ" result, it's suctioned out into the "struct qm_fqd" type. + * Within that, the 'stashing' and 'taildrop' pieces are also factored out, the + * latter has two inlines to assist with converting to/from the mant+exp + * representation. */ +struct qm_fqd_stashing { + /* See QM_STASHING_EXCL_<...> */ + u8 exclusive; + u8 __reserved1:2; + /* Numbers of cachelines */ + u8 annotation_cl:2; + u8 data_cl:2; + u8 context_cl:2; +} __packed; +struct qm_fqd_taildrop { + u16 __reserved1:3; + u16 mant:8; + u16 exp:5; +} __packed; +struct qm_fqd_oac { + /* See QM_OAC_<...> */ + u8 oac:2; /* "Overhead Accounting Control" */ + u8 __reserved1:6; + /* Two's-complement value (-128 to +127) */ + signed char oal; /* "Overhead Accounting Length" */ +} __packed; +struct qm_fqd { + union { + u8 orpc; + struct { + u8 __reserved1:2; + u8 orprws:3; + u8 oa:1; + u8 olws:2; + } __packed; + }; + u8 cgid; + u16 fq_ctrl; /* See QM_FQCTRL_<...> */ + union { + u16 dest_wq; + struct { + u16 channel:13; /* qm_channel */ + u16 wq:3; + } __packed dest; + }; + u16 __reserved2:1; + u16 ics_cred:15; + /* For "Initialize Frame Queue" commands, the write-enable mask + * determines whether 'td' or 'oac_init' is observed. For query + * commands, this field is always 'td', and 'oac_query' (below) reflects + * the Overhead ACcounting values. */ + union { + struct qm_fqd_taildrop td; + struct qm_fqd_oac oac_init; + }; + u32 context_b; + union { + /* Treat it as 64-bit opaque */ + u64 opaque; + struct { + u32 hi; + u32 lo; + }; + /* Treat it as s/w portal stashing config */ + /* See 1.5.6.7.1: "FQD Context_A field used for [...] */ + struct { + struct qm_fqd_stashing stashing; + /* 48-bit address of FQ context to + * stash, must be cacheline-aligned */ + u16 context_hi; + u32 context_lo; + } __packed; + } context_a; + struct qm_fqd_oac oac_query; +} __packed; +/* 64-bit converters for context_hi/lo */ +static inline u64 qm_fqd_stashing_get64(const struct qm_fqd *fqd) +{ + return ((u64)fqd->context_a.context_hi << 32) | + (u64)fqd->context_a.context_lo; +} +static inline dma_addr_t qm_fqd_stashing_addr(const struct qm_fqd *fqd) +{ + return (dma_addr_t)qm_fqd_stashing_get64(fqd); +} +static inline u64 qm_fqd_context_a_get64(const struct qm_fqd *fqd) +{ + return ((u64)fqd->context_a.hi << 32) | + (u64)fqd->context_a.lo; +} +/* Macro, so we compile better when 'v' isn't necessarily 64-bit */ +#define qm_fqd_stashing_set64(fqd, v) \ + do { \ + struct qm_fqd *__fqd931 = (fqd); \ + __fqd931->context_a.context_hi = upper_32_bits(v); \ + __fqd931->context_a.context_lo = lower_32_bits(v); \ + } while (0) +#define qm_fqd_context_a_set64(fqd, v) \ + do { \ + struct qm_fqd *__fqd931 = (fqd); \ + __fqd931->context_a.hi = upper_32_bits(v); \ + __fqd931->context_a.lo = lower_32_bits(v); \ + } while (0) +/* convert a threshold value into mant+exp representation */ +static inline int qm_fqd_taildrop_set(struct qm_fqd_taildrop *td, u32 val, + int roundup) +{ + u32 e = 0; + int oddbit = 0; + if (val > 0xe0000000) + return -ERANGE; + while (val > 0xff) { + oddbit = val & 1; + val >>= 1; + e++; + if (roundup && oddbit) + val++; + } + td->exp = e; + td->mant = val; + return 0; +} +/* and the other direction */ +static inline u32 qm_fqd_taildrop_get(const struct qm_fqd_taildrop *td) +{ + return (u32)td->mant << td->exp; +} + +/* See 1.5.2.2: "Frame Queue Descriptor (FQD)" */ +/* Frame Queue Descriptor (FQD) field 'fq_ctrl' uses these constants */ +#define QM_FQCTRL_MASK 0x07ff /* 'fq_ctrl' flags; */ +#define QM_FQCTRL_CGE 0x0400 /* Congestion Group Enable */ +#define QM_FQCTRL_TDE 0x0200 /* Tail-Drop Enable */ +#define QM_FQCTRL_ORP 0x0100 /* ORP Enable */ +#define QM_FQCTRL_CTXASTASHING 0x0080 /* Context-A stashing */ +#define QM_FQCTRL_CPCSTASH 0x0040 /* CPC Stash Enable */ +#define QM_FQCTRL_FORCESFDR 0x0008 /* High-priority SFDRs */ +#define QM_FQCTRL_AVOIDBLOCK 0x0004 /* Don't block active */ +#define QM_FQCTRL_HOLDACTIVE 0x0002 /* Hold active in portal */ +#define QM_FQCTRL_PREFERINCACHE 0x0001 /* Aggressively cache FQD */ +#define QM_FQCTRL_LOCKINCACHE QM_FQCTRL_PREFERINCACHE /* older naming */ + +/* See 1.5.6.7.1: "FQD Context_A field used for [...] */ +/* Frame Queue Descriptor (FQD) field 'CONTEXT_A' uses these constants */ +#define QM_STASHING_EXCL_ANNOTATION 0x04 +#define QM_STASHING_EXCL_DATA 0x02 +#define QM_STASHING_EXCL_CTX 0x01 + +/* See 1.5.5.3: "Intra Class Scheduling" */ +/* FQD field 'OAC' (Overhead ACcounting) uses these constants */ +#define QM_OAC_ICS 0x2 /* Accounting for Intra-Class Scheduling */ +#define QM_OAC_CG 0x1 /* Accounting for Congestion Groups */ + +/* See 1.5.8.4: "FQ State Change Notification" */ +/* This struct represents the 32-bit "WR_PARM_[GYR]" parameters in CGR fields + * and associated commands/responses. The WRED parameters are calculated from + * these fields as follows; + * MaxTH = MA * (2 ^ Mn) + * Slope = SA / (2 ^ Sn) + * MaxP = 4 * (Pn + 1) + */ +struct qm_cgr_wr_parm { + union { + u32 word; + struct { + u32 MA:8; + u32 Mn:5; + u32 SA:7; /* must be between 64-127 */ + u32 Sn:6; + u32 Pn:6; + } __packed; + }; +} __packed; +/* This struct represents the 13-bit "CS_THRES" CGR field. In the corresponding + * management commands, this is padded to a 16-bit structure field, so that's + * how we represent it here. The congestion state threshold is calculated from + * these fields as follows; + * CS threshold = TA * (2 ^ Tn) + */ +struct qm_cgr_cs_thres { + u16 __reserved:3; + u16 TA:8; + u16 Tn:5; +} __packed; +/* This identical structure of CGR fields is present in the "Init/Modify CGR" + * commands and the "Query CGR" result. It's suctioned out here into its own + * struct. */ +struct __qm_mc_cgr { + struct qm_cgr_wr_parm wr_parm_g; + struct qm_cgr_wr_parm wr_parm_y; + struct qm_cgr_wr_parm wr_parm_r; + u8 wr_en_g; /* boolean, use QM_CGR_EN */ + u8 wr_en_y; /* boolean, use QM_CGR_EN */ + u8 wr_en_r; /* boolean, use QM_CGR_EN */ + u8 cscn_en; /* boolean, use QM_CGR_EN */ + union { + struct { + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */ + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */ + }; + u32 cscn_targ; /* use QM_CGR_TARG_* */ + }; + u8 cstd_en; /* boolean, use QM_CGR_EN */ + u8 cs; /* boolean, only used in query response */ + struct qm_cgr_cs_thres cs_thres; /* use qm_cgr_cs_thres_set64() */ + u8 mode; /* QMAN_CGR_MODE_FRAME not supported in rev1.0 */ +} __packed; +#define QM_CGR_EN 0x01 /* For wr_en_*, cscn_en, cstd_en */ +#define QM_CGR_TARG_UDP_CTRL_WRITE_BIT 0x8000 /* value written to portal bit*/ +#define QM_CGR_TARG_UDP_CTRL_DCP 0x4000 /* 0: SWP, 1: DCP */ +#define QM_CGR_TARG_PORTAL(n) (0x80000000 >> (n)) /* s/w portal, 0-9 */ +#define QM_CGR_TARG_FMAN0 0x00200000 /* direct-connect portal: fman0 */ +#define QM_CGR_TARG_FMAN1 0x00100000 /* : fman1 */ +/* Convert CGR thresholds to/from "cs_thres" format */ +static inline u64 qm_cgr_cs_thres_get64(const struct qm_cgr_cs_thres *th) +{ + return (u64)th->TA << th->Tn; +} +static inline int qm_cgr_cs_thres_set64(struct qm_cgr_cs_thres *th, u64 val, + int roundup) +{ + u32 e = 0; + int oddbit = 0; + while (val > 0xff) { + oddbit = val & 1; + val >>= 1; + e++; + if (roundup && oddbit) + val++; + } + th->Tn = e; + th->TA = val; + return 0; +} + +/* See 1.5.8.5.1: "Initialize FQ" */ +/* See 1.5.8.5.2: "Query FQ" */ +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */ +/* See 1.5.8.5.4: "Alter FQ State Commands " */ +/* See 1.5.8.6.1: "Initialize/Modify CGR" */ +/* See 1.5.8.6.2: "CGR Test Write" */ +/* See 1.5.8.6.3: "Query CGR" */ +/* See 1.5.8.6.4: "Query Congestion Group State" */ +struct qm_mcc_initfq { + u8 __reserved1; + u16 we_mask; /* Write Enable Mask */ + u32 fqid; /* 24-bit */ + u16 count; /* Initialises 'count+1' FQDs */ + struct qm_fqd fqd; /* the FQD fields go here */ + u8 __reserved3[30]; +} __packed; +struct qm_mcc_queryfq { + u8 __reserved1[3]; + u32 fqid; /* 24-bit */ + u8 __reserved2[56]; +} __packed; +struct qm_mcc_queryfq_np { + u8 __reserved1[3]; + u32 fqid; /* 24-bit */ + u8 __reserved2[56]; +} __packed; +struct qm_mcc_alterfq { + u8 __reserved1[3]; + u32 fqid; /* 24-bit */ + u8 __reserved2; + u8 count; /* number of consecutive FQID */ + u8 __reserved3[10]; + u32 context_b; /* frame queue context b */ + u8 __reserved4[40]; +} __packed; +struct qm_mcc_initcgr { + u8 __reserved1; + u16 we_mask; /* Write Enable Mask */ + struct __qm_mc_cgr cgr; /* CGR fields */ + u8 __reserved2[2]; + u8 cgid; + u8 __reserved4[32]; +} __packed; +struct qm_mcc_cgrtestwrite { + u8 __reserved1[2]; + u8 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */ + u32 i_bcnt_lo; /* low 32-bits of 40-bit */ + u8 __reserved2[23]; + u8 cgid; + u8 __reserved3[32]; +} __packed; +struct qm_mcc_querycgr { + u8 __reserved1[30]; + u8 cgid; + u8 __reserved2[32]; +} __packed; +struct qm_mcc_querycongestion { + u8 __reserved[63]; +} __packed; +struct qm_mcc_querywq { + u8 __reserved; + /* select channel if verb != QUERYWQ_DEDICATED */ + union { + u16 channel_wq; /* ignores wq (3 lsbits) */ + struct { + u16 id:13; /* qm_channel */ + u16 __reserved1:3; + } __packed channel; + }; + u8 __reserved2[60]; +} __packed; + +struct qm_mcc_ceetm_lfqmt_config { + u8 __reserved1[4]; + u32 lfqid:24; + u8 __reserved2[2]; + u16 cqid; + u8 __reserved3[2]; + u16 dctidx; + u8 __reserved4[48]; +} __packed; + +struct qm_mcc_ceetm_lfqmt_query { + u8 __reserved1[4]; + u32 lfqid:24; + u8 __reserved2[56]; +} __packed; + +struct qm_mcc_ceetm_cq_config { + u8 __reserved1; + u16 cqid; + u8 dcpid; + u8 __reserved2; + u16 ccgid; + u8 __reserved3[56]; +} __packed; + +struct qm_mcc_ceetm_cq_query { + u8 __reserved1; + u16 cqid; + u8 dcpid; + u8 __reserved2[59]; +} __packed; + +struct qm_mcc_ceetm_dct_config { + u8 __reserved1; + u16 dctidx; + u8 dcpid; + u8 __reserved2[15]; + u32 context_b; + u64 context_a; + u8 __reserved3[32]; +} __packed; + +struct qm_mcc_ceetm_dct_query { + u8 __reserved1; + u16 dctidx; + u8 dcpid; + u8 __reserved2[59]; +} __packed; + +struct qm_mcc_ceetm_class_scheduler_config { + u8 __reserved1; + u16 cqcid; + u8 dcpid; + u8 __reserved2[6]; + u8 gpc; + u16 crem; + u16 erem; + u8 w[8]; + u8 __reserved3[40]; +} __packed; + +struct qm_mcc_ceetm_class_scheduler_query { + u8 __reserved1; + u16 cqcid; + u8 dcpid; + u8 __reserved2[59]; +} __packed; + +#define CEETM_COMMAND_CHANNEL_MAPPING (0 << 12) +#define CEETM_COMMAND_SP_MAPPING (1 << 12) +#define CEETM_COMMAND_CHANNEL_SHAPER (2 << 12) +#define CEETM_COMMAND_LNI_SHAPER (3 << 12) +#define CEETM_COMMAND_TCFC (4 << 12) + +#define CEETM_CCGRID_MASK 0x01FF +#define CEETM_CCGR_CM_CONFIGURE (0 << 14) +#define CEETM_CCGR_DN_CONFIGURE (1 << 14) +#define CEETM_CCGR_TEST_WRITE (2 << 14) +#define CEETM_CCGR_CM_QUERY (0 << 14) +#define CEETM_CCGR_DN_QUERY (1 << 14) +#define CEETM_CCGR_DN_QUERY_FLUSH (2 << 14) +#define CEETM_QUERY_CONGESTION_STATE (3 << 14) + +struct qm_mcc_ceetm_mapping_shaper_tcfc_config { + u8 __reserved1; + u16 cid; + u8 dcpid; + union { + struct { + u8 map; + u8 __reserved2[58]; + } __packed channel_mapping; + struct { + u8 map_reserved:5; + u8 map_lni_id:3; + u8 __reserved2[58]; + } __packed sp_mapping; + struct { + u8 cpl; + u32 crtcr:24; + u32 ertcr:24; + u16 crtbl; + u16 ertbl; + u8 __reserved2[48]; + } __packed shaper_config; + struct { + u8 __reserved2[11]; + u64 lnitcfcc; + u8 __reserved3[40]; + } __packed tcfc_config; + }; +} __packed; + +struct qm_mcc_ceetm_mapping_shaper_tcfc_query { + u8 __reserved1; + u16 cid; + u8 dcpid; + u8 __reserved2[59]; +} __packed; + +struct qm_mcc_ceetm_ccgr_config { + u8 __reserved1; + u16 ccgrid; + u8 dcpid; + u8 __reserved2; + u16 we_mask; + union { + struct { + u8 ctl; + u8 cdv; + u16 cscn_tupd; + u8 oal; + u8 __reserved3; + struct qm_cgr_cs_thres cs_thres; + struct qm_cgr_cs_thres cs_thres_x; + struct qm_cgr_cs_thres td_thres; + struct qm_cgr_wr_parm wr_parm_g; + struct qm_cgr_wr_parm wr_parm_y; + struct qm_cgr_wr_parm wr_parm_r; + } __packed cm_config; + struct { + u8 dnc; + u8 dn0; + u8 dn1; + u64 dnba:40; + u8 __reserved3[2]; + u16 dnth_0; + u8 __reserved4[2]; + u16 dnth_1; + u8 __reserved5[8]; + } __packed dn_config; + struct { + u8 __reserved3[3]; + u64 i_cnt:40; + u8 __reserved4[16]; + } __packed test_write; + }; + u8 __reserved5[32]; +} __packed; + +struct qm_mcc_ceetm_ccgr_query { + u8 __reserved1; + u16 ccgrid; + u8 dcpid; + u8 __reserved2[59]; +} __packed; + +struct qm_mcc_ceetm_cq_peek_pop_xsfdrread { + u8 __reserved1; + u16 cqid; + u8 dcpid; + u8 ct; + u16 xsfdr; + u8 __reserved2[56]; +} __packed; + +#define CEETM_QUERY_DEQUEUE_STATISTICS 0x00 +#define CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS 0x01 +#define CEETM_WRITE_DEQUEUE_STATISTICS 0x02 +#define CEETM_QUERY_REJECT_STATISTICS 0x03 +#define CEETM_QUERY_REJECT_CLEAR_STATISTICS 0x04 +#define CEETM_WRITE_REJECT_STATISTICS 0x05 +struct qm_mcc_ceetm_statistics_query_write { + u8 __reserved1; + u16 cid; + u8 dcpid; + u8 ct; + u8 __reserved2[13]; + u64 frm_cnt:40; + u8 __reserved3[2]; + u64 byte_cnt:48; + u8 __reserved[32]; +} __packed; + +struct qm_mc_command { + u8 __dont_write_directly__verb; + union { + struct qm_mcc_initfq initfq; + struct qm_mcc_queryfq queryfq; + struct qm_mcc_queryfq_np queryfq_np; + struct qm_mcc_alterfq alterfq; + struct qm_mcc_initcgr initcgr; + struct qm_mcc_cgrtestwrite cgrtestwrite; + struct qm_mcc_querycgr querycgr; + struct qm_mcc_querycongestion querycongestion; + struct qm_mcc_querywq querywq; + struct qm_mcc_ceetm_lfqmt_config lfqmt_config; + struct qm_mcc_ceetm_lfqmt_query lfqmt_query; + struct qm_mcc_ceetm_cq_config cq_config; + struct qm_mcc_ceetm_cq_query cq_query; + struct qm_mcc_ceetm_dct_config dct_config; + struct qm_mcc_ceetm_dct_query dct_query; + struct qm_mcc_ceetm_class_scheduler_config csch_config; + struct qm_mcc_ceetm_class_scheduler_query csch_query; + struct qm_mcc_ceetm_mapping_shaper_tcfc_config mst_config; + struct qm_mcc_ceetm_mapping_shaper_tcfc_query mst_query; + struct qm_mcc_ceetm_ccgr_config ccgr_config; + struct qm_mcc_ceetm_ccgr_query ccgr_query; + struct qm_mcc_ceetm_cq_peek_pop_xsfdrread cq_ppxr; + struct qm_mcc_ceetm_statistics_query_write stats_query_write; + }; +} __packed; +#define QM_MCC_VERB_VBIT 0x80 +#define QM_MCC_VERB_MASK 0x7f /* where the verb contains; */ +#define QM_MCC_VERB_INITFQ_PARKED 0x40 +#define QM_MCC_VERB_INITFQ_SCHED 0x41 +#define QM_MCC_VERB_QUERYFQ 0x44 +#define QM_MCC_VERB_QUERYFQ_NP 0x45 /* "non-programmable" fields */ +#define QM_MCC_VERB_QUERYWQ 0x46 +#define QM_MCC_VERB_QUERYWQ_DEDICATED 0x47 +#define QM_MCC_VERB_ALTER_SCHED 0x48 /* Schedule FQ */ +#define QM_MCC_VERB_ALTER_FE 0x49 /* Force Eligible FQ */ +#define QM_MCC_VERB_ALTER_RETIRE 0x4a /* Retire FQ */ +#define QM_MCC_VERB_ALTER_OOS 0x4b /* Take FQ out of service */ +#define QM_MCC_VERB_ALTER_FQXON 0x4d /* FQ XON */ +#define QM_MCC_VERB_ALTER_FQXOFF 0x4e /* FQ XOFF */ +#define QM_MCC_VERB_INITCGR 0x50 +#define QM_MCC_VERB_MODIFYCGR 0x51 +#define QM_MCC_VERB_CGRTESTWRITE 0x52 +#define QM_MCC_VERB_QUERYCGR 0x58 +#define QM_MCC_VERB_QUERYCONGESTION 0x59 +/* INITFQ-specific flags */ +#define QM_INITFQ_WE_MASK 0x01ff /* 'Write Enable' flags; */ +#define QM_INITFQ_WE_OAC 0x0100 +#define QM_INITFQ_WE_ORPC 0x0080 +#define QM_INITFQ_WE_CGID 0x0040 +#define QM_INITFQ_WE_FQCTRL 0x0020 +#define QM_INITFQ_WE_DESTWQ 0x0010 +#define QM_INITFQ_WE_ICSCRED 0x0008 +#define QM_INITFQ_WE_TDTHRESH 0x0004 +#define QM_INITFQ_WE_CONTEXTB 0x0002 +#define QM_INITFQ_WE_CONTEXTA 0x0001 +/* INITCGR/MODIFYCGR-specific flags */ +#define QM_CGR_WE_MASK 0x07ff /* 'Write Enable Mask'; */ +#define QM_CGR_WE_WR_PARM_G 0x0400 +#define QM_CGR_WE_WR_PARM_Y 0x0200 +#define QM_CGR_WE_WR_PARM_R 0x0100 +#define QM_CGR_WE_WR_EN_G 0x0080 +#define QM_CGR_WE_WR_EN_Y 0x0040 +#define QM_CGR_WE_WR_EN_R 0x0020 +#define QM_CGR_WE_CSCN_EN 0x0010 +#define QM_CGR_WE_CSCN_TARG 0x0008 +#define QM_CGR_WE_CSTD_EN 0x0004 +#define QM_CGR_WE_CS_THRES 0x0002 +#define QM_CGR_WE_MODE 0x0001 + +/* See 1.5.9.7 CEETM Management Commands */ +#define QM_CEETM_VERB_LFQMT_CONFIG 0x70 +#define QM_CEETM_VERB_LFQMT_QUERY 0x71 +#define QM_CEETM_VERB_CQ_CONFIG 0x72 +#define QM_CEETM_VERB_CQ_QUERY 0x73 +#define QM_CEETM_VERB_DCT_CONFIG 0x74 +#define QM_CEETM_VERB_DCT_QUERY 0x75 +#define QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG 0x76 +#define QM_CEETM_VERB_CLASS_SCHEDULER_QUERY 0x77 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG 0x78 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY 0x79 +#define QM_CEETM_VERB_CCGR_CONFIG 0x7A +#define QM_CEETM_VERB_CCGR_QUERY 0x7B +#define QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD 0x7C +#define QM_CEETM_VERB_STATISTICS_QUERY_WRITE 0x7D + +/* See 1.5.8.5.1: "Initialize FQ" */ +/* See 1.5.8.5.2: "Query FQ" */ +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */ +/* See 1.5.8.5.4: "Alter FQ State Commands " */ +/* See 1.5.8.6.1: "Initialize/Modify CGR" */ +/* See 1.5.8.6.2: "CGR Test Write" */ +/* See 1.5.8.6.3: "Query CGR" */ +/* See 1.5.8.6.4: "Query Congestion Group State" */ +struct qm_mcr_initfq { + u8 __reserved1[62]; +} __packed; +struct qm_mcr_queryfq { + u8 __reserved1[8]; + struct qm_fqd fqd; /* the FQD fields are here */ + u8 __reserved2[30]; +} __packed; +struct qm_mcr_queryfq_np { + u8 __reserved1; + u8 state; /* QM_MCR_NP_STATE_*** */ + u8 __reserved2; + u32 fqd_link:24; + u16 __reserved3:2; + u16 odp_seq:14; + u16 __reserved4:2; + u16 orp_nesn:14; + u16 __reserved5:1; + u16 orp_ea_hseq:15; + u16 __reserved6:1; + u16 orp_ea_tseq:15; + u8 __reserved7; + u32 orp_ea_hptr:24; + u8 __reserved8; + u32 orp_ea_tptr:24; + u8 __reserved9; + u32 pfdr_hptr:24; + u8 __reserved10; + u32 pfdr_tptr:24; + u8 __reserved11[5]; + u8 __reserved12:7; + u8 is:1; + u16 ics_surp; + u32 byte_cnt; + u8 __reserved13; + u32 frm_cnt:24; + u32 __reserved14; + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */ + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */ + u16 __reserved15; + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */ + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */ + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */ +} __packed; +struct qm_mcr_alterfq { + u8 fqs; /* Frame Queue Status */ + u8 __reserved1[61]; +} __packed; +struct qm_mcr_initcgr { + u8 __reserved1[62]; +} __packed; +struct qm_mcr_cgrtestwrite { + u16 __reserved1; + struct __qm_mc_cgr cgr; /* CGR fields */ + u8 __reserved2[3]; + u32 __reserved3:24; + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */ + u32 i_bcnt_lo; /* low 32-bits of 40-bit */ + u32 __reserved4:24; + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */ + u32 a_bcnt_lo; /* low 32-bits of 40-bit */ + u16 lgt; /* Last Group Tick */ + u16 wr_prob_g; + u16 wr_prob_y; + u16 wr_prob_r; + u8 __reserved5[8]; +} __packed; +struct qm_mcr_querycgr { + u16 __reserved1; + struct __qm_mc_cgr cgr; /* CGR fields */ + u8 __reserved2[3]; + u32 __reserved3:24; + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */ + u32 i_bcnt_lo; /* low 32-bits of 40-bit */ + u32 __reserved4:24; + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */ + u32 a_bcnt_lo; /* low 32-bits of 40-bit */ + union { + u32 cscn_targ_swp[4]; + u8 __reserved5[16]; + }; +} __packed; +static inline u64 qm_mcr_querycgr_i_get64(const struct qm_mcr_querycgr *q) +{ + return ((u64)q->i_bcnt_hi << 32) | (u64)q->i_bcnt_lo; +} +static inline u64 qm_mcr_querycgr_a_get64(const struct qm_mcr_querycgr *q) +{ + return ((u64)q->a_bcnt_hi << 32) | (u64)q->a_bcnt_lo; +} +static inline u64 qm_mcr_cgrtestwrite_i_get64( + const struct qm_mcr_cgrtestwrite *q) +{ + return ((u64)q->i_bcnt_hi << 32) | (u64)q->i_bcnt_lo; +} +static inline u64 qm_mcr_cgrtestwrite_a_get64( + const struct qm_mcr_cgrtestwrite *q) +{ + return ((u64)q->a_bcnt_hi << 32) | (u64)q->a_bcnt_lo; +} +/* Macro, so we compile better if 'v' isn't always 64-bit */ +#define qm_mcr_querycgr_i_set64(q, v) \ + do { \ + struct qm_mcr_querycgr *__q931 = (fd); \ + __q931->i_bcnt_hi = upper_32_bits(v); \ + __q931->i_bcnt_lo = lower_32_bits(v); \ + } while (0) +#define qm_mcr_querycgr_a_set64(q, v) \ + do { \ + struct qm_mcr_querycgr *__q931 = (fd); \ + __q931->a_bcnt_hi = upper_32_bits(v); \ + __q931->a_bcnt_lo = lower_32_bits(v); \ + } while (0) +struct __qm_mcr_querycongestion { + u32 __state[8]; +}; +struct qm_mcr_querycongestion { + u8 __reserved[30]; + /* Access this struct using QM_MCR_QUERYCONGESTION() */ + struct __qm_mcr_querycongestion state; +} __packed; +struct qm_mcr_querywq { + union { + u16 channel_wq; /* ignores wq (3 lsbits) */ + struct { + u16 id:13; /* qm_channel */ + u16 __reserved:3; + } __packed channel; + }; + u8 __reserved[28]; + u32 wq_len[8]; +} __packed; + +/* QMAN CEETM Management Command Response */ +struct qm_mcr_ceetm_lfqmt_config { + u8 __reserved1[62]; +} __packed; +struct qm_mcr_ceetm_lfqmt_query { + u8 __reserved1[8]; + u16 cqid; + u8 __reserved2[2]; + u16 dctidx; + u8 __reserved3[2]; + u16 ccgid; + u8 __reserved4[44]; +} __packed; + +struct qm_mcr_ceetm_cq_config { + u8 __reserved1[62]; +} __packed; + +struct qm_mcr_ceetm_cq_query { + u8 __reserved1[4]; + u16 ccgid; + u16 state; + u32 pfdr_hptr:24; + u32 pfdr_tptr:24; + u16 od1_xsfdr; + u16 od2_xsfdr; + u16 od3_xsfdr; + u16 od4_xsfdr; + u16 od5_xsfdr; + u16 od6_xsfdr; + u16 ra1_xsfdr; + u16 ra2_xsfdr; + u8 __reserved2; + u32 frm_cnt:24; + u8 __reserved333[28]; +} __packed; + +struct qm_mcr_ceetm_dct_config { + u8 __reserved1[62]; +} __packed; + +struct qm_mcr_ceetm_dct_query { + u8 __reserved1[18]; + u32 context_b; + u64 context_a; + u8 __reserved2[32]; +} __packed; + +struct qm_mcr_ceetm_class_scheduler_config { + u8 __reserved1[62]; +} __packed; + +struct qm_mcr_ceetm_class_scheduler_query { + u8 __reserved1[9]; + u8 gpc; + u16 crem; + u16 erem; + u8 w[8]; + u8 __reserved2[5]; + u32 wbfslist:24; + u32 d8; + u32 d9; + u32 d10; + u32 d11; + u32 d12; + u32 d13; + u32 d14; + u32 d15; +} __packed; + +struct qm_mcr_ceetm_mapping_shaper_tcfc_config { + u16 cid; + u8 __reserved2[60]; +} __packed; + +struct qm_mcr_ceetm_mapping_shaper_tcfc_query { + u16 cid; + u8 __reserved1; + union { + struct { + u8 map; + u8 __reserved2[58]; + } __packed channel_mapping_query; + struct { + u8 map_reserved:5; + u8 map_lni_id:3; + u8 __reserved2[58]; + } __packed sp_mapping_query; + struct { + u8 cpl; + u32 crtcr:24; + u32 ertcr:24; + u16 crtbl; + u16 ertbl; + u8 __reserved2[16]; + u32 crat; + u32 erat; + u8 __reserved3[24]; + } __packed shaper_query; + struct { + u8 __reserved1[11]; + u64 lnitcfcc; + u8 __reserved3[40]; + } __packed tcfc_query; + }; +} __packed; + +struct qm_mcr_ceetm_ccgr_config { + u8 __reserved1[46]; + union { + u8 __reserved2[8]; + struct { + u16 timestamp; + u16 wr_porb_g; + u16 wr_prob_y; + u16 wr_prob_r; + } __packed test_write; + }; + u8 __reserved3[8]; +} __packed; + +struct qm_mcr_ceetm_ccgr_query { + u8 __reserved1[6]; + union { + struct { + u8 ctl; + u8 cdv; + u8 __reserved2[2]; + u8 oal; + u8 __reserved3; + struct qm_cgr_cs_thres cs_thres; + struct qm_cgr_cs_thres cs_thres_x; + struct qm_cgr_cs_thres td_thres; + struct qm_cgr_wr_parm wr_parm_g; + struct qm_cgr_wr_parm wr_parm_y; + struct qm_cgr_wr_parm wr_parm_r; + u8 cscn_targ_dcp; + u16 dcp_lsn; + u64 i_cnt:40; + u8 __reserved4[3]; + u64 a_cnt:40; + u32 cscn_targ_swp[4]; + } __packed cm_query; + struct { + u8 dnc; + u8 dn0; + u8 dn1; + u64 dnba:40; + u8 __reserved2[2]; + u16 dnth_0; + u8 __reserved3[2]; + u16 dnth_1; + u8 __reserved4[10]; + u16 dnacc_0; + u8 __reserved5[2]; + u16 dnacc_1; + u8 __reserved6[24]; + } __packed dn_query; + struct { + u8 __reserved2[24]; + struct __qm_mcr_querycongestion state; + } __packed congestion_state; + + }; +} __packed; + +struct qm_mcr_ceetm_cq_peek_pop_xsfdrread { + u8 stat; + u8 __reserved1[11]; + u16 dctidx; + struct qm_fd fd; + u8 __reserved2[32]; +} __packed; + +struct qm_mcr_ceetm_statistics_query { + u8 __reserved1[17]; + u64 frm_cnt:40; + u8 __reserved2[2]; + u64 byte_cnt:48; + u8 __reserved3[32]; +} __packed; + +struct qm_mc_result { + u8 verb; + u8 result; + union { + struct qm_mcr_initfq initfq; + struct qm_mcr_queryfq queryfq; + struct qm_mcr_queryfq_np queryfq_np; + struct qm_mcr_alterfq alterfq; + struct qm_mcr_initcgr initcgr; + struct qm_mcr_cgrtestwrite cgrtestwrite; + struct qm_mcr_querycgr querycgr; + struct qm_mcr_querycongestion querycongestion; + struct qm_mcr_querywq querywq; + struct qm_mcr_ceetm_lfqmt_config lfqmt_config; + struct qm_mcr_ceetm_lfqmt_query lfqmt_query; + struct qm_mcr_ceetm_cq_config cq_config; + struct qm_mcr_ceetm_cq_query cq_query; + struct qm_mcr_ceetm_dct_config dct_config; + struct qm_mcr_ceetm_dct_query dct_query; + struct qm_mcr_ceetm_class_scheduler_config csch_config; + struct qm_mcr_ceetm_class_scheduler_query csch_query; + struct qm_mcr_ceetm_mapping_shaper_tcfc_config mst_config; + struct qm_mcr_ceetm_mapping_shaper_tcfc_query mst_query; + struct qm_mcr_ceetm_ccgr_config ccgr_config; + struct qm_mcr_ceetm_ccgr_query ccgr_query; + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread cq_ppxr; + struct qm_mcr_ceetm_statistics_query stats_query; + }; +} __packed; + +#define QM_MCR_VERB_RRID 0x80 +#define QM_MCR_VERB_MASK QM_MCC_VERB_MASK +#define QM_MCR_VERB_INITFQ_PARKED QM_MCC_VERB_INITFQ_PARKED +#define QM_MCR_VERB_INITFQ_SCHED QM_MCC_VERB_INITFQ_SCHED +#define QM_MCR_VERB_QUERYFQ QM_MCC_VERB_QUERYFQ +#define QM_MCR_VERB_QUERYFQ_NP QM_MCC_VERB_QUERYFQ_NP +#define QM_MCR_VERB_QUERYWQ QM_MCC_VERB_QUERYWQ +#define QM_MCR_VERB_QUERYWQ_DEDICATED QM_MCC_VERB_QUERYWQ_DEDICATED +#define QM_MCR_VERB_ALTER_SCHED QM_MCC_VERB_ALTER_SCHED +#define QM_MCR_VERB_ALTER_FE QM_MCC_VERB_ALTER_FE +#define QM_MCR_VERB_ALTER_RETIRE QM_MCC_VERB_ALTER_RETIRE +#define QM_MCR_VERB_ALTER_OOS QM_MCC_VERB_ALTER_OOS +#define QM_MCR_RESULT_NULL 0x00 +#define QM_MCR_RESULT_OK 0xf0 +#define QM_MCR_RESULT_ERR_FQID 0xf1 +#define QM_MCR_RESULT_ERR_FQSTATE 0xf2 +#define QM_MCR_RESULT_ERR_NOTEMPTY 0xf3 /* OOS fails if FQ is !empty */ +#define QM_MCR_RESULT_ERR_BADCHANNEL 0xf4 +#define QM_MCR_RESULT_PENDING 0xf8 +#define QM_MCR_RESULT_ERR_BADCOMMAND 0xff +#define QM_MCR_NP_STATE_FE 0x10 +#define QM_MCR_NP_STATE_R 0x08 +#define QM_MCR_NP_STATE_MASK 0x07 /* Reads FQD::STATE; */ +#define QM_MCR_NP_STATE_OOS 0x00 +#define QM_MCR_NP_STATE_RETIRED 0x01 +#define QM_MCR_NP_STATE_TEN_SCHED 0x02 +#define QM_MCR_NP_STATE_TRU_SCHED 0x03 +#define QM_MCR_NP_STATE_PARKED 0x04 +#define QM_MCR_NP_STATE_ACTIVE 0x05 +#define QM_MCR_NP_PTR_MASK 0x07ff /* for RA[12] & OD[123] */ +#define QM_MCR_NP_RA1_NRA(v) (((v) >> 14) & 0x3) /* FQD::NRA */ +#define QM_MCR_NP_RA2_IT(v) (((v) >> 14) & 0x1) /* FQD::IT */ +#define QM_MCR_NP_OD1_NOD(v) (((v) >> 14) & 0x3) /* FQD::NOD */ +#define QM_MCR_NP_OD3_NPC(v) (((v) >> 14) & 0x3) /* FQD::NPC */ +#define QM_MCR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */ +#define QM_MCR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */ +/* This extracts the state for congestion group 'n' from a query response. + * Eg. + * u8 cgr = [...]; + * struct qm_mc_result *res = [...]; + * printf("congestion group %d congestion state: %d\n", cgr, + * QM_MCR_QUERYCONGESTION(&res->querycongestion.state, cgr)); + */ +#define __CGR_WORD(num) (num >> 5) +#define __CGR_SHIFT(num) (num & 0x1f) +#define __CGR_NUM (sizeof(struct __qm_mcr_querycongestion) << 3) +static inline int QM_MCR_QUERYCONGESTION(struct __qm_mcr_querycongestion *p, + u8 cgr) +{ + return p->__state[__CGR_WORD(cgr)] & (0x80000000 >> __CGR_SHIFT(cgr)); +} + + +/*********************/ +/* Utility interface */ +/*********************/ + +/* Represents an allocator over a range of FQIDs. NB, accesses are not locked, + * spinlock them yourself if needed. */ +struct qman_fqid_pool; + +/* Create/destroy a FQID pool, num must be a multiple of 32. NB, _destroy() + * always succeeds, but returns non-zero if there were "leaked" FQID + * allocations. */ +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num); +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool); +/* Alloc/free a FQID from the range. _alloc() returns zero for success. */ +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid); +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid); +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool); + +/*******************************************************************/ +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */ +/*******************************************************************/ + + /* Portal and Frame Queues */ + /* ----------------------- */ +/* Represents a managed portal */ +struct qman_portal; + +/* This object type represents Qman frame queue descriptors (FQD), it is + * cacheline-aligned, and initialised by qman_create_fq(). The structure is + * defined further down. */ +struct qman_fq; + +/* This object type represents a Qman congestion group, it is defined further + * down. */ +struct qman_cgr; + +struct qman_portal_config { + /* If the caller enables DQRR stashing (and thus wishes to operate the + * portal from only one cpu), this is the logical CPU that the portal + * will stash to. Whether stashing is enabled or not, this setting is + * also used for any "core-affine" portals, ie. default portals + * associated to the corresponding cpu. -1 implies that there is no core + * affinity configured. */ + int cpu; + /* portal interrupt line */ + int irq; + /* the unique index of this portal */ + u32 index; + /* Is this portal shared? (If so, it has coarser locking and demuxes + * processing on behalf of other CPUs.) */ + int is_shared; + /* The portal's dedicated channel id, use this value for initialising + * frame queues to target this portal when scheduled. */ + u16 channel; + /* A mask of which pool channels this portal has dequeue access to + * (using QM_SDQCR_CHANNELS_POOL(n) for the bitmask) */ + u32 pools; +}; + +/* This enum, and the callback type that returns it, are used when handling + * dequeued frames via DQRR. Note that for "null" callbacks registered with the + * portal object (for handling dequeues that do not demux because contextB is + * NULL), the return value *MUST* be qman_cb_dqrr_consume. */ +enum qman_cb_dqrr_result { + /* DQRR entry can be consumed */ + qman_cb_dqrr_consume, + /* Like _consume, but requests parking - FQ must be held-active */ + qman_cb_dqrr_park, + /* Does not consume, for DCA mode only. This allows out-of-order + * consumes by explicit calls to qman_dca() and/or the use of implicit + * DCA via EQCR entries. */ + qman_cb_dqrr_defer, + /* Stop processing without consuming this ring entry. Exits the current + * qman_poll_dqrr() or interrupt-handling, as appropriate. If within an + * interrupt handler, the callback would typically call + * qman_irqsource_remove(QM_PIRQ_DQRI) before returning this value, + * otherwise the interrupt will reassert immediately. */ + qman_cb_dqrr_stop, + /* Like qman_cb_dqrr_stop, but consumes the current entry. */ + qman_cb_dqrr_consume_stop +}; +typedef enum qman_cb_dqrr_result (*qman_cb_dqrr)(struct qman_portal *qm, + struct qman_fq *fq, + const struct qm_dqrr_entry *dqrr); + +/* This callback type is used when handling ERNs, FQRNs and FQRLs via MR. They + * are always consumed after the callback returns. */ +typedef void (*qman_cb_mr)(struct qman_portal *qm, struct qman_fq *fq, + const struct qm_mr_entry *msg); + +/* This callback type is used when handling DCP ERNs */ +typedef void (*qman_cb_dc_ern)(struct qman_portal *qm, + const struct qm_mr_entry *msg); + +/* s/w-visible states. Ie. tentatively scheduled + truly scheduled + active + + * held-active + held-suspended are just "sched". Things like "retired" will not + * be assumed until it is complete (ie. QMAN_FQ_STATE_CHANGING is set until + * then, to indicate it's completing and to gate attempts to retry the retire + * command). Note, park commands do not set QMAN_FQ_STATE_CHANGING because it's + * technically impossible in the case of enqueue DCAs (which refer to DQRR ring + * index rather than the FQ that ring entry corresponds to), so repeated park + * commands are allowed (if you're silly enough to try) but won't change FQ + * state, and the resulting park notifications move FQs from "sched" to + * "parked". */ +enum qman_fq_state { + qman_fq_state_oos, + qman_fq_state_parked, + qman_fq_state_sched, + qman_fq_state_retired +}; + +/* Frame queue objects (struct qman_fq) are stored within memory passed to + * qman_create_fq(), as this allows stashing of caller-provided demux callback + * pointers at no extra cost to stashing of (driver-internal) FQ state. If the + * caller wishes to add per-FQ state and have it benefit from dequeue-stashing, + * they should; + * + * (a) extend the qman_fq structure with their state; eg. + * + * // myfq is allocated and driver_fq callbacks filled in; + * struct my_fq { + * struct qman_fq base; + * int an_extra_field; + * [ ... add other fields to be associated with each FQ ...] + * } *myfq = some_my_fq_allocator(); + * struct qman_fq *fq = qman_create_fq(fqid, flags, &myfq->base); + * + * // in a dequeue callback, access extra fields from 'fq' via a cast; + * struct my_fq *myfq = (struct my_fq *)fq; + * do_something_with(myfq->an_extra_field); + * [...] + * + * (b) when and if configuring the FQ for context stashing, specify how ever + * many cachelines are required to stash 'struct my_fq', to accelerate not + * only the Qman driver but the callback as well. + */ + +struct qman_fq_cb { + qman_cb_dqrr dqrr; /* for dequeued frames */ + qman_cb_mr ern; /* for s/w ERNs */ + qman_cb_mr fqs; /* frame-queue state changes*/ +}; + +struct qman_fq { + /* Caller of qman_create_fq() provides these demux callbacks */ + struct qman_fq_cb cb; + /* These are internal to the driver, don't touch. In particular, they + * may change, be removed, or extended (so you shouldn't rely on + * sizeof(qman_fq) being a constant). */ + spinlock_t fqlock; + u32 fqid; + volatile unsigned long flags; + enum qman_fq_state state; + int cgr_groupid; + struct rb_node node; +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP + u32 key; +#endif +}; + +/* This callback type is used when handling congestion group entry/exit. + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit. */ +typedef void (*qman_cb_cgr)(struct qman_portal *qm, + struct qman_cgr *cgr, int congested); + +struct qman_cgr { + /* Set these prior to qman_create_cgr() */ + u32 cgrid; /* 0..255, but u32 to allow specials like -1, 256, etc.*/ + qman_cb_cgr cb; + /* These are private to the driver */ + u16 chan; /* portal channel this object is created on */ + struct list_head node; +}; + +/* Flags to qman_create_fq() */ +#define QMAN_FQ_FLAG_NO_ENQUEUE 0x00000001 /* can't enqueue */ +#define QMAN_FQ_FLAG_NO_MODIFY 0x00000002 /* can only enqueue */ +#define QMAN_FQ_FLAG_TO_DCPORTAL 0x00000004 /* consumed by CAAM/PME/Fman */ +#define QMAN_FQ_FLAG_LOCKED 0x00000008 /* multi-core locking */ +#define QMAN_FQ_FLAG_AS_IS 0x00000010 /* query h/w state */ +#define QMAN_FQ_FLAG_DYNAMIC_FQID 0x00000020 /* (de)allocate fqid */ + +/* Flags to qman_destroy_fq() */ +#define QMAN_FQ_DESTROY_PARKED 0x00000001 /* FQ can be parked or OOS */ + +/* Flags from qman_fq_state() */ +#define QMAN_FQ_STATE_CHANGING 0x80000000 /* 'state' is changing */ +#define QMAN_FQ_STATE_NE 0x40000000 /* retired FQ isn't empty */ +#define QMAN_FQ_STATE_ORL 0x20000000 /* retired FQ has ORL */ +#define QMAN_FQ_STATE_BLOCKOOS 0xe0000000 /* if any are set, no OOS */ +#define QMAN_FQ_STATE_CGR_EN 0x10000000 /* CGR enabled */ +#define QMAN_FQ_STATE_VDQCR 0x08000000 /* being volatile dequeued */ + +/* Flags to qman_init_fq() */ +#define QMAN_INITFQ_FLAG_SCHED 0x00000001 /* schedule rather than park */ +#define QMAN_INITFQ_FLAG_LOCAL 0x00000004 /* set dest portal */ + +/* Flags to qman_volatile_dequeue() */ +#ifdef CONFIG_FSL_DPA_CAN_WAIT +#define QMAN_VOLATILE_FLAG_WAIT 0x00000001 /* wait if VDQCR is in use */ +#define QMAN_VOLATILE_FLAG_WAIT_INT 0x00000002 /* if wait, interruptible? */ +#define QMAN_VOLATILE_FLAG_FINISH 0x00000004 /* wait till VDQCR completes */ +#endif + +/* Flags to qman_enqueue(). NB, the strange numbering is to align with hardware, + * bit-wise. (NB: the PME API is sensitive to these precise numberings too, so + * any change here should be audited in PME.) */ +#ifdef CONFIG_FSL_DPA_CAN_WAIT +#define QMAN_ENQUEUE_FLAG_WAIT 0x00010000 /* wait if EQCR is full */ +#define QMAN_ENQUEUE_FLAG_WAIT_INT 0x00020000 /* if wait, interruptible? */ +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC +#define QMAN_ENQUEUE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */ +#endif +#endif +#define QMAN_ENQUEUE_FLAG_WATCH_CGR 0x00080000 /* watch congestion state */ +#define QMAN_ENQUEUE_FLAG_DCA 0x00008000 /* perform enqueue-DCA */ +#define QMAN_ENQUEUE_FLAG_DCA_PARK 0x00004000 /* If DCA, requests park */ +#define QMAN_ENQUEUE_FLAG_DCA_PTR(p) /* If DCA, p is DQRR entry */ \ + (((u32)(p) << 2) & 0x00000f00) +#define QMAN_ENQUEUE_FLAG_C_GREEN 0x00000000 /* choose one C_*** flag */ +#define QMAN_ENQUEUE_FLAG_C_YELLOW 0x00000008 +#define QMAN_ENQUEUE_FLAG_C_RED 0x00000010 +#define QMAN_ENQUEUE_FLAG_C_OVERRIDE 0x00000018 +/* For the ORP-specific qman_enqueue_orp() variant; + * - this flag indicates "Not Last In Sequence", ie. all but the final fragment + * of a frame. */ +#define QMAN_ENQUEUE_FLAG_NLIS 0x01000000 +/* - this flag performs no enqueue but fills in an ORP sequence number that + * would otherwise block it (eg. if a frame has been dropped). */ +#define QMAN_ENQUEUE_FLAG_HOLE 0x02000000 +/* - this flag performs no enqueue but advances NESN to the given sequence + * number. */ +#define QMAN_ENQUEUE_FLAG_NESN 0x04000000 + +/* Flags to qman_modify_cgr() */ +#define QMAN_CGR_FLAG_USE_INIT 0x00000001 +#define QMAN_CGR_MODE_FRAME 0x00000001 + + /* Portal Management */ + /* ----------------- */ +/** + * qman_get_portal_config - get portal configuration settings + * + * This returns a read-only view of the current cpu's affine portal settings. + */ +const struct qman_portal_config *qman_get_portal_config(void); + +/** + * qman_irqsource_get - return the portal work that is interrupt-driven + * + * Returns a bitmask of QM_PIRQ_**I processing sources that are currently + * enabled for interrupt handling on the current cpu's affine portal. These + * sources will trigger the portal interrupt and the interrupt handler (or a + * tasklet/bottom-half it defers to) will perform the corresponding processing + * work. The qman_poll_***() functions will only process sources that are not in + * this bitmask. If the current CPU is sharing a portal hosted on another CPU, + * this always returns zero. + */ +u32 qman_irqsource_get(void); + +/** + * qman_irqsource_add - add processing sources to be interrupt-driven + * @bits: bitmask of QM_PIRQ_**I processing sources + * + * Adds processing sources that should be interrupt-driven (rather than + * processed via qman_poll_***() functions). Returns zero for success, or + * -EINVAL if the current CPU is sharing a portal hosted on another CPU. + */ +int qman_irqsource_add(u32 bits); + +/** + * qman_irqsource_remove - remove processing sources from being interrupt-driven + * @bits: bitmask of QM_PIRQ_**I processing sources + * + * Removes processing sources from being interrupt-driven, so that they will + * instead be processed via qman_poll_***() functions. Returns zero for success, + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU. + */ +int qman_irqsource_remove(u32 bits); + +/** + * qman_affine_cpus - return a mask of cpus that have affine portals + */ +const cpumask_t *qman_affine_cpus(void); + +/** + * qman_affine_channel - return the channel ID of an portal + * @cpu: the cpu whose affine portal is the subject of the query + * + * If @cpu is -1, the affine portal for the current CPU will be used. It is a + * bug to call this function for any value of @cpu (other than -1) that is not a + * member of the mask returned from qman_affine_cpus(). + */ +u16 qman_affine_channel(int cpu); + +/** + * qman_get_affine_portal - return the portal pointer affine to cpu + * @cpu: the cpu whose affine portal is the subject of the query + * + */ +void *qman_get_affine_portal(int cpu); + +/** + * qman_poll_dqrr - process DQRR (fast-path) entries + * @limit: the maximum number of DQRR entries to process + * + * Use of this function requires that DQRR processing not be interrupt-driven. + * Ie. the value returned by qman_irqsource_get() should not include + * QM_PIRQ_DQRI. If the current CPU is sharing a portal hosted on another CPU, + * this function will return -EINVAL, otherwise the return value is >=0 and + * represents the number of DQRR entries processed. + */ +int qman_poll_dqrr(unsigned int limit); + +/** + * qman_poll_slow - process anything (except DQRR) that isn't interrupt-driven. + * + * This function does any portal processing that isn't interrupt-driven. If the + * current CPU is sharing a portal hosted on another CPU, this function will + * return (u32)-1, otherwise the return value is a bitmask of QM_PIRQ_* sources + * indicating what interrupt sources were actually processed by the call. + */ +u32 qman_poll_slow(void); + +/** + * qman_poll - legacy wrapper for qman_poll_dqrr() and qman_poll_slow() + * + * Dispatcher logic on a cpu can use this to trigger any maintenance of the + * affine portal. There are two classes of portal processing in question; + * fast-path (which involves demuxing dequeue ring (DQRR) entries and tracking + * enqueue ring (EQCR) consumption), and slow-path (which involves EQCR + * thresholds, congestion state changes, etc). This function does whatever + * processing is not triggered by interrupts. + * + * Note, if DQRR and some slow-path processing are poll-driven (rather than + * interrupt-driven) then this function uses a heuristic to determine how often + * to run slow-path processing - as slow-path processing introduces at least a + * minimum latency each time it is run, whereas fast-path (DQRR) processing is + * close to zero-cost if there is no work to be done. Applications can tune this + * behaviour themselves by using qman_poll_dqrr() and qman_poll_slow() directly + * rather than going via this wrapper. + */ +void qman_poll(void); + +/** + * qman_stop_dequeues - Stop h/w dequeuing to the s/w portal + * + * Disables DQRR processing of the portal. This is reference-counted, so + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to + * truly re-enable dequeuing. + */ +void qman_stop_dequeues(void); + +/** + * qman_start_dequeues - (Re)start h/w dequeuing to the s/w portal + * + * Enables DQRR processing of the portal. This is reference-counted, so + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to + * truly re-enable dequeuing. + */ +void qman_start_dequeues(void); + +/** + * qman_static_dequeue_add - Add pool channels to the portal SDQCR + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n) + * + * Adds a set of pool channels to the portal's static dequeue command register + * (SDQCR). The requested pools are limited to those the portal has dequeue + * access to. + */ +void qman_static_dequeue_add(u32 pools); + +/** + * qman_static_dequeue_del - Remove pool channels from the portal SDQCR + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n) + * + * Removes a set of pool channels from the portal's static dequeue command + * register (SDQCR). The requested pools are limited to those the portal has + * dequeue access to. + */ +void qman_static_dequeue_del(u32 pools); + +/** + * qman_static_dequeue_get - return the portal's current SDQCR + * + * Returns the portal's current static dequeue command register (SDQCR). The + * entire register is returned, so if only the currently-enabled pool channels + * are desired, mask the return value with QM_SDQCR_CHANNELS_POOL_MASK. + */ +u32 qman_static_dequeue_get(void); + +/** + * qman_dca - Perform a Discrete Consumption Acknowledgement + * @dq: the DQRR entry to be consumed + * @park_request: indicates whether the held-active @fq should be parked + * + * Only allowed in DCA-mode portals, for DQRR entries whose handler callback had + * previously returned 'qman_cb_dqrr_defer'. NB, as with the other APIs, this + * does not take a 'portal' argument but implies the core affine portal from the + * cpu that is currently executing the function. For reasons of locking, this + * function must be called from the same CPU as that which processed the DQRR + * entry in the first place. + */ +void qman_dca(struct qm_dqrr_entry *dq, int park_request); + +/** + * qman_eqcr_is_empty - Determine if portal's EQCR is empty + * + * For use in situations where a cpu-affine caller needs to determine when all + * enqueues for the local portal have been processed by Qman but can't use the + * QMAN_ENQUEUE_FLAG_WAIT_SYNC flag to do this from the final qman_enqueue(). + * The function forces tracking of EQCR consumption (which normally doesn't + * happen until enqueue processing needs to find space to put new enqueue + * commands), and returns zero if the ring still has unprocessed entries, + * non-zero if it is empty. + */ +int qman_eqcr_is_empty(void); + +/** + * qman_set_dc_ern - Set the handler for DCP enqueue rejection notifications + * @handler: callback for processing DCP ERNs + * @affine: whether this handler is specific to the locally affine portal + * + * If a hardware block's interface to Qman (ie. its direct-connect portal, or + * DCP) is configured not to receive enqueue rejections, then any enqueues + * through that DCP that are rejected will be sent to a given software portal. + * If @affine is non-zero, then this handler will only be used for DCP ERNs + * received on the portal affine to the current CPU. If multiple CPUs share a + * portal and they all call this function, they will be setting the handler for + * the same portal! If @affine is zero, then this handler will be global to all + * portals handled by this instance of the driver. Only those portals that do + * not have their own affine handler will use the global handler. + */ +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine); + + /* FQ management */ + /* ------------- */ +/** + * qman_create_fq - Allocates a FQ + * @fqid: the index of the FQD to encapsulate, must be "Out of Service" + * @flags: bit-mask of QMAN_FQ_FLAG_*** options + * @fq: memory for storing the 'fq', with callbacks filled in + * + * Creates a frame queue object for the given @fqid, unless the + * QMAN_FQ_FLAG_DYNAMIC_FQID flag is set in @flags, in which case a FQID is + * dynamically allocated (or the function fails if none are available). Once + * created, the caller should not touch the memory at 'fq' except as extended to + * adjacent memory for user-defined fields (see the definition of "struct + * qman_fq" for more info). NO_MODIFY is only intended for enqueuing to + * pre-existing frame-queues that aren't to be otherwise interfered with, it + * prevents all other modifications to the frame queue. The TO_DCPORTAL flag + * causes the driver to honour any contextB modifications requested in the + * qm_init_fq() API, as this indicates the frame queue will be consumed by a + * direct-connect portal (PME, CAAM, or Fman). When frame queues are consumed by + * software portals, the contextB field is controlled by the driver and can't be + * modified by the caller. If the AS_IS flag is specified, management commands + * will be used on portal @p to query state for frame queue @fqid and construct + * a frame queue object based on that, rather than assuming/requiring that it be + * Out of Service. + */ +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq); + +/** + * qman_destroy_fq - Deallocates a FQ + * @fq: the frame queue object to release + * @flags: bit-mask of QMAN_FQ_FREE_*** options + * + * The memory for this frame queue object ('fq' provided in qman_create_fq()) is + * not deallocated but the caller regains ownership, to do with as desired. The + * FQ must be in the 'out-of-service' state unless the QMAN_FQ_FREE_PARKED flag + * is specified, in which case it may also be in the 'parked' state. + */ +void qman_destroy_fq(struct qman_fq *fq, u32 flags); + +/** + * qman_fq_fqid - Queries the frame queue ID of a FQ object + * @fq: the frame queue object to query + */ +u32 qman_fq_fqid(struct qman_fq *fq); + +/** + * qman_fq_state - Queries the state of a FQ object + * @fq: the frame queue object to query + * @state: pointer to state enum to return the FQ scheduling state + * @flags: pointer to state flags to receive QMAN_FQ_STATE_*** bitmask + * + * Queries the state of the FQ object, without performing any h/w commands. + * This captures the state, as seen by the driver, at the time the function + * executes. + */ +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags); + +/** + * qman_init_fq - Initialises FQ fields, leaves the FQ "parked" or "scheduled" + * @fq: the frame queue object to modify, must be 'parked' or new. + * @flags: bit-mask of QMAN_INITFQ_FLAG_*** options + * @opts: the FQ-modification settings, as defined in the low-level API + * + * The @opts parameter comes from the low-level portal API. Select + * QMAN_INITFQ_FLAG_SCHED in @flags to cause the frame queue to be scheduled + * rather than parked. NB, @opts can be NULL. + * + * Note that some fields and options within @opts may be ignored or overwritten + * by the driver; + * 1. the 'count' and 'fqid' fields are always ignored (this operation only + * affects one frame queue: @fq). + * 2. the QM_INITFQ_WE_CONTEXTB option of the 'we_mask' field and the associated + * 'fqd' structure's 'context_b' field are sometimes overwritten; + * - if @fq was not created with QMAN_FQ_FLAG_TO_DCPORTAL, then context_b is + * initialised to a value used by the driver for demux. + * - if context_b is initialised for demux, so is context_a in case stashing + * is requested (see item 4). + * (So caller control of context_b is only possible for TO_DCPORTAL frame queue + * objects.) + * 3. if @flags contains QMAN_INITFQ_FLAG_LOCAL, the 'fqd' structure's + * 'dest::channel' field will be overwritten to match the portal used to issue + * the command. If the WE_DESTWQ write-enable bit had already been set by the + * caller, the channel workqueue will be left as-is, otherwise the write-enable + * bit is set and the workqueue is set to a default of 4. If the "LOCAL" flag + * isn't set, the destination channel/workqueue fields and the write-enable bit + * are left as-is. + * 4. if the driver overwrites context_a/b for demux, then if + * QM_INITFQ_WE_CONTEXTA is set, the driver will only overwrite + * context_a.address fields and will leave the stashing fields provided by the + * user alone, otherwise it will zero out the context_a.stashing fields. + */ +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts); + +/** + * qman_schedule_fq - Schedules a FQ + * @fq: the frame queue object to schedule, must be 'parked' + * + * Schedules the frame queue, which must be Parked, which takes it to + * Tentatively-Scheduled or Truly-Scheduled depending on its fill-level. + */ +int qman_schedule_fq(struct qman_fq *fq); + +/** + * qman_retire_fq - Retires a FQ + * @fq: the frame queue object to retire + * @flags: FQ flags (as per qman_fq_state) if retirement completes immediately + * + * Retires the frame queue. This returns zero if it succeeds immediately, +1 if + * the retirement was started asynchronously, otherwise it returns negative for + * failure. When this function returns zero, @flags is set to indicate whether + * the retired FQ is empty and/or whether it has any ORL fragments (to show up + * as ERNs). Otherwise the corresponding flags will be known when a subsequent + * FQRN message shows up on the portal's message ring. + * + * NB, if the retirement is asynchronous (the FQ was in the Truly Scheduled or + * Active state), the completion will be via the message ring as a FQRN - but + * the corresponding callback may occur before this function returns!! Ie. the + * caller should be prepared to accept the callback as the function is called, + * not only once it has returned. + */ +int qman_retire_fq(struct qman_fq *fq, u32 *flags); + +/** + * qman_oos_fq - Puts a FQ "out of service" + * @fq: the frame queue object to be put out-of-service, must be 'retired' + * + * The frame queue must be retired and empty, and if any order restoration list + * was released as ERNs at the time of retirement, they must all be consumed. + */ +int qman_oos_fq(struct qman_fq *fq); + +/** + * qman_fq_flow_control - Set the XON/XOFF state of a FQ + * @fq: the frame queue object to be set to XON/XOFF state, must not be 'oos', + * or 'retired' or 'parked' state + * @xon: boolean to set fq in XON or XOFF state + * + * The frame should be in Tentatively Scheduled state or Truly Schedule sate, + * otherwise the IFSI interrupt will be asserted. + */ +int qman_fq_flow_control(struct qman_fq *fq, int xon); + +/** + * qman_query_fq - Queries FQD fields (via h/w query command) + * @fq: the frame queue object to be queried + * @fqd: storage for the queried FQD fields + */ +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd); + +/** + * qman_query_fq_np - Queries non-programmable FQD fields + * @fq: the frame queue object to be queried + * @np: storage for the queried FQD fields + */ +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np); + +/** + * qman_query_wq - Queries work queue lengths + * @query_dedicated: If non-zero, query length of WQs in the channel dedicated + * to this software portal. Otherwise, query length of WQs in a + * channel specified in wq. + * @wq: storage for the queried WQs lengths. Also specified the channel to + * to query if query_dedicated is zero. + */ +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq); + +/** + * qman_volatile_dequeue - Issue a volatile dequeue command + * @fq: the frame queue object to dequeue from + * @flags: a bit-mask of QMAN_VOLATILE_FLAG_*** options + * @vdqcr: bit mask of QM_VDQCR_*** options, as per qm_dqrr_vdqcr_set() + * + * Attempts to lock access to the portal's VDQCR volatile dequeue functionality. + * The function will block and sleep if QMAN_VOLATILE_FLAG_WAIT is specified and + * the VDQCR is already in use, otherwise returns non-zero for failure. If + * QMAN_VOLATILE_FLAG_FINISH is specified, the function will only return once + * the VDQCR command has finished executing (ie. once the callback for the last + * DQRR entry resulting from the VDQCR command has been called). If not using + * the FINISH flag, completion can be determined either by detecting the + * presence of the QM_DQRR_STAT_UNSCHEDULED and QM_DQRR_STAT_DQCR_EXPIRED bits + * in the "stat" field of the "struct qm_dqrr_entry" passed to the FQ's dequeue + * callback, or by waiting for the QMAN_FQ_STATE_VDQCR bit to disappear from the + * "flags" retrieved from qman_fq_state(). + */ +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags, u32 vdqcr); + +/** + * qman_enqueue - Enqueue a frame to a frame queue + * @fq: the frame queue object to enqueue to + * @fd: a descriptor of the frame to be enqueued + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options + * + * Fills an entry in the EQCR of portal @qm to enqueue the frame described by + * @fd. The descriptor details are copied from @fd to the EQCR entry, the 'pid' + * field is ignored. The return value is non-zero on error, such as ring full + * (and FLAG_WAIT not specified), congestion avoidance (FLAG_WATCH_CGR + * specified), etc. If the ring is full and FLAG_WAIT is specified, this + * function will block. If FLAG_INTERRUPT is set, the EQCI bit of the portal + * interrupt will assert when Qman consumes the EQCR entry (subject to "status + * disable", "enable", and "inhibit" registers). If FLAG_DCA is set, Qman will + * perform an implied "discrete consumption acknowledgement" on the dequeue + * ring's (DQRR) entry, at the ring index specified by the FLAG_DCA_IDX(x) + * macro. (As an alternative to issuing explicit DCA actions on DQRR entries, + * this implicit DCA can delay the release of a "held active" frame queue + * corresponding to a DQRR entry until Qman consumes the EQCR entry - providing + * order-preservation semantics in packet-forwarding scenarios.) If FLAG_DCA is + * set, then FLAG_DCA_PARK can also be set to imply that the DQRR consumption + * acknowledgement should "park request" the "held active" frame queue. Ie. + * when the portal eventually releases that frame queue, it will be left in the + * Parked state rather than Tentatively Scheduled or Truly Scheduled. If the + * portal is watching congestion groups, the QMAN_ENQUEUE_FLAG_WATCH_CGR flag + * is requested, and the FQ is a member of a congestion group, then this + * function returns -EAGAIN if the congestion group is currently congested. + * Note, this does not eliminate ERNs, as the async interface means we can be + * sending enqueue commands to an un-congested FQ that becomes congested before + * the enqueue commands are processed, but it does minimise needless thrashing + * of an already busy hardware resource by throttling many of the to-be-dropped + * enqueues "at the source". + */ +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags); + +typedef int (*qman_cb_precommit) (void *arg); +/** + * qman_enqueue_precommit - Enqueue a frame to a frame queue and call cb + * @fq: the frame queue object to enqueue to + * @fd: a descriptor of the frame to be enqueued + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options + * @cb: user supplied callback function to invoke before writing commit verb. + * @cb_arg: callback function argument + * + * This is similar to qman_enqueue except that it will invoke a user supplied + * callback function just before writng the commit verb. This is useful + * when the user want to do something *just before* enqueuing the request and + * the enqueue can't fail. + */ +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd, + u32 flags, qman_cb_precommit cb, void *cb_arg); + +/** + * qman_enqueue_orp - Enqueue a frame to a frame queue using an ORP + * @fq: the frame queue object to enqueue to + * @fd: a descriptor of the frame to be enqueued + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options + * @orp: the frame queue object used as an order restoration point. + * @orp_seqnum: the sequence number of this frame in the order restoration path + * + * Similar to qman_enqueue(), but with the addition of an Order Restoration + * Point (@orp) and corresponding sequence number (@orp_seqnum) for this + * enqueue operation to employ order restoration. Each frame queue object acts + * as an Order Definition Point (ODP) by providing each frame dequeued from it + * with an incrementing sequence number, this value is generally ignored unless + * that sequence of dequeued frames will need order restoration later. Each + * frame queue object also encapsulates an Order Restoration Point (ORP), which + * is a re-assembly context for re-ordering frames relative to their sequence + * numbers as they are enqueued. The ORP does not have to be within the frame + * queue that receives the enqueued frame, in fact it is usually the frame + * queue from which the frames were originally dequeued. For the purposes of + * order restoration, multiple frames (or "fragments") can be enqueued for a + * single sequence number by setting the QMAN_ENQUEUE_FLAG_NLIS flag for all + * enqueues except the final fragment of a given sequence number. Ordering + * between sequence numbers is guaranteed, even if fragments of different + * sequence numbers are interlaced with one another. Fragments of the same + * sequence number will retain the order in which they are enqueued. If no + * enqueue is to performed, QMAN_ENQUEUE_FLAG_HOLE indicates that the given + * sequence number is to be "skipped" by the ORP logic (eg. if a frame has been + * dropped from a sequence), or QMAN_ENQUEUE_FLAG_NESN indicates that the given + * sequence number should become the ORP's "Next Expected Sequence Number". + * + * Side note: a frame queue object can be used purely as an ORP, without + * carrying any frames at all. Care should be taken not to deallocate a frame + * queue object that is being actively used as an ORP, as a future allocation + * of the frame queue object may start using the internal ORP before the + * previous use has finished. + */ +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags, + struct qman_fq *orp, u16 orp_seqnum); + +/** + * qman_alloc_fqid_range - Allocate a contiguous range of FQIDs + * @result: is set by the API to the base FQID of the allocated range + * @count: the number of FQIDs required + * @align: required alignment of the allocated range + * @partial: non-zero if the API can return fewer than @count FQIDs + * + * Returns the number of frame queues allocated, or a negative error code. If + * @partial is non zero, the allocation request may return a smaller range of + * FQs than requested (though alignment will be as requested). If @partial is + * zero, the return value will either be 'count' or negative. + */ +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial); +static inline int qman_alloc_fqid(u32 *result) +{ + int ret = qman_alloc_fqid_range(result, 1, 0, 0); + return (ret > 0) ? 0 : ret; +} + +/** + * qman_release_fqid_range - Release the specified range of frame queue IDs + * @fqid: the base FQID of the range to deallocate + * @count: the number of FQIDs in the range + * + * This function can also be used to seed the allocator with ranges of FQIDs + * that it can subsequently allocate from. + */ +void qman_release_fqid_range(u32 fqid, unsigned int count); +static inline void qman_release_fqid(u32 fqid) +{ + qman_release_fqid_range(fqid, 1); +} + +void qman_seed_fqid_range(u32 fqid, unsigned int count); + + +int qman_shutdown_fq(u32 fqid); + +/** + * qman_reserve_fqid_range - Reserve the specified range of frame queue IDs + * @fqid: the base FQID of the range to deallocate + * @count: the number of FQIDs in the range + */ +int qman_reserve_fqid_range(u32 fqid, unsigned int count); +static inline int qman_reserve_fqid(u32 fqid) +{ + return qman_reserve_fqid_range(fqid, 1); +} + + /* Pool-channel management */ + /* ----------------------- */ +/** + * qman_alloc_pool_range - Allocate a contiguous range of pool-channel IDs + * @result: is set by the API to the base pool-channel ID of the allocated range + * @count: the number of pool-channel IDs required + * @align: required alignment of the allocated range + * @partial: non-zero if the API can return fewer than @count + * + * Returns the number of pool-channel IDs allocated, or a negative error code. + * If @partial is non zero, the allocation request may return a smaller range of + * than requested (though alignment will be as requested). If @partial is zero, + * the return value will either be 'count' or negative. + */ +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial); +static inline int qman_alloc_pool(u32 *result) +{ + int ret = qman_alloc_pool_range(result, 1, 0, 0); + return (ret > 0) ? 0 : ret; +} + +/** + * qman_release_pool_range - Release the specified range of pool-channel IDs + * @id: the base pool-channel ID of the range to deallocate + * @count: the number of pool-channel IDs in the range + */ +void qman_release_pool_range(u32 id, unsigned int count); +static inline void qman_release_pool(u32 id) +{ + qman_release_pool_range(id, 1); +} + +/** + * qman_reserve_pool_range - Reserve the specified range of pool-channel IDs + * @id: the base pool-channel ID of the range to reserve + * @count: the number of pool-channel IDs in the range + */ +int qman_reserve_pool_range(u32 id, unsigned int count); +static inline int qman_reserve_pool(u32 id) +{ + return qman_reserve_pool_range(id, 1); +} + +void qman_seed_pool_range(u32 id, unsigned int count); + + /* CGR management */ + /* -------------- */ +/** + * qman_create_cgr - Register a congestion group object + * @cgr: the 'cgr' object, with fields filled in + * @flags: QMAN_CGR_FLAG_* values + * @opts: optional state of CGR settings + * + * Registers this object to receiving congestion entry/exit callbacks on the + * portal affine to the cpu portal on which this API is executed. If opts is + * NULL then only the callback (cgr->cb) function is registered. If @flags + * contains QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset + * any unspecified parameters) will be used rather than a modify hw hardware + * (which only modifies the specified parameters). + */ +int qman_create_cgr(struct qman_cgr *cgr, u32 flags, + struct qm_mcc_initcgr *opts); + +/** + * qman_create_cgr_to_dcp - Register a congestion group object to DCP portal + * @cgr: the 'cgr' object, with fields filled in + * @flags: QMAN_CGR_FLAG_* values + * @dcp_portal: the DCP portal to which the cgr object is registered. + * @opts: optional state of CGR settings + * + */ +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal, + struct qm_mcc_initcgr *opts); + +/** + * qman_delete_cgr - Deregisters a congestion group object + * @cgr: the 'cgr' object to deregister + * + * "Unplugs" this CGR object from the portal affine to the cpu on which this API + * is executed. This must be excuted on the same affine portal on which it was + * created. + */ +int qman_delete_cgr(struct qman_cgr *cgr); + +/** + * qman_modify_cgr - Modify CGR fields + * @cgr: the 'cgr' object to modify + * @flags: QMAN_CGR_FLAG_* values + * @opts: the CGR-modification settings + * + * The @opts parameter comes from the low-level portal API, and can be NULL. + * Note that some fields and options within @opts may be ignored or overwritten + * by the driver, in particular the 'cgrid' field is ignored (this operation + * only affects the given CGR object). If @flags contains + * QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset any + * unspecified parameters) will be used rather than a modify hw hardware (which + * only modifies the specified parameters). + */ +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags, + struct qm_mcc_initcgr *opts); + +/** +* qman_query_cgr - Queries CGR fields +* @cgr: the 'cgr' object to query +* @result: storage for the queried congestion group record +*/ +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *result); + +/** + * qman_query_congestion - Queries the state of all congestion groups + * @congestion: storage for the queried state of all congestion groups + */ +int qman_query_congestion(struct qm_mcr_querycongestion *congestion); + +/** + * qman_alloc_cgrid_range - Allocate a contiguous range of CGR IDs + * @result: is set by the API to the base CGR ID of the allocated range + * @count: the number of CGR IDs required + * @align: required alignment of the allocated range + * @partial: non-zero if the API can return fewer than @count + * + * Returns the number of CGR IDs allocated, or a negative error code. + * If @partial is non zero, the allocation request may return a smaller range of + * than requested (though alignment will be as requested). If @partial is zero, + * the return value will either be 'count' or negative. + */ +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial); +static inline int qman_alloc_cgrid(u32 *result) +{ + int ret = qman_alloc_cgrid_range(result, 1, 0, 0); + return (ret > 0) ? 0 : ret; +} + +/** + * qman_release_cgrid_range - Release the specified range of CGR IDs + * @id: the base CGR ID of the range to deallocate + * @count: the number of CGR IDs in the range + */ +void qman_release_cgrid_range(u32 id, unsigned int count); +static inline void qman_release_cgrid(u32 id) +{ + qman_release_cgrid_range(id, 1); +} + +/** + * qman_reserve_cgrid_range - Reserve the specified range of CGR ID + * @id: the base CGR ID of the range to reserve + * @count: the number of CGR IDs in the range + */ +int qman_reserve_cgrid_range(u32 id, unsigned int count); +static inline int qman_reserve_cgrid(u32 id) +{ + return qman_reserve_cgrid_range(id, 1); +} + +void qman_seed_cgrid_range(u32 id, unsigned int count); + + + /* Helpers */ + /* ------- */ +/** + * qman_poll_fq_for_init - Check if an FQ has been initialised from OOS + * @fqid: the FQID that will be initialised by other s/w + * + * In many situations, a FQID is provided for communication between s/w + * entities, and whilst the consumer is responsible for initialising and + * scheduling the FQ, the producer(s) generally create a wrapper FQ object using + * and only call qman_enqueue() (no FQ initialisation, scheduling, etc). Ie; + * qman_create_fq(..., QMAN_FQ_FLAG_NO_MODIFY, ...); + * However, data can not be enqueued to the FQ until it is initialised out of + * the OOS state - this function polls for that condition. It is particularly + * useful for users of IPC functions - each endpoint's Rx FQ is the other + * endpoint's Tx FQ, so each side can initialise and schedule their Rx FQ object + * and then use this API on the (NO_MODIFY) Tx FQ object in order to + * synchronise. The function returns zero for success, +1 if the FQ is still in + * the OOS state, or negative if there was an error. + */ +static inline int qman_poll_fq_for_init(struct qman_fq *fq) +{ + struct qm_mcr_queryfq_np np; + int err; + err = qman_query_fq_np(fq, &np); + if (err) + return err; + if ((np.state & QM_MCR_NP_STATE_MASK) == QM_MCR_NP_STATE_OOS) + return 1; + return 0; +} + + /* -------------- */ + /* CEETM :: types */ + /* -------------- */ +/** + * Token Rate Structure + * Shaping rates are based on a "credit" system and a pre-configured h/w + * internal timer. The following type represents a shaper "rate" parameter as a + * fractional number of "tokens". Here's how it works. This (fractional) number + * of tokens is added to the shaper's "credit" every time the h/w timer elapses + * (up to a limit which is set by another shaper parameter). Every time a frame + * is enqueued through a shaper, the shaper deducts as many tokens as there are + * bytes of data in the enqueued frame. A shaper will not allow itself to + * enqueue any frames if its token count is negative. As such; + * + * The rate at which data is enqueued is limited by the + * rate at which tokens are added. + * + * Therefore if the user knows the period between these h/w timer updates in + * seconds, they can calculate the maximum traffic rate of the shaper (in + * bytes-per-second) from the token rate. And vice versa, they can calculate + * the token rate to use in order to achieve a given traffic rate. + */ +struct qm_ceetm_rate { + /* The token rate is; whole + (fraction/8192) */ + u32 whole:11; /* 0..2047 */ + u32 fraction:13; /* 0..8191 */ +}; + +struct qm_ceetm_weight_code { + /* The weight code is; 5 msbits + 3 lsbits */ + u8 y:5; + u8 x:3; +}; + +struct qm_ceetm { + unsigned int idx; + struct list_head sub_portals; + struct list_head lnis; + unsigned int sp_range[2]; + unsigned int lni_range[2]; +}; + +struct qm_ceetm_sp { + struct list_head node; + unsigned int idx; + unsigned int dcp_idx; + int is_claimed; + struct qm_ceetm_lni *lni; +}; + +/* Logical Network Interface */ +struct qm_ceetm_lni { + struct list_head node; + unsigned int idx; + unsigned int dcp_idx; + int is_claimed; + struct qm_ceetm_sp *sp; + struct list_head channels; + int shaper_enable; + int shaper_couple; + int oal; + struct qm_ceetm_rate cr_token_rate; + struct qm_ceetm_rate er_token_rate; + u16 cr_token_bucket_limit; + u16 er_token_bucket_limit; +}; + +/* Class Queue Channel */ +struct qm_ceetm_channel { + struct list_head node; + unsigned int idx; + unsigned int lni_idx; + unsigned int dcp_idx; + struct list_head class_queues; + struct list_head ccgs; + u8 shaper_enable; + u8 shaper_couple; + struct qm_ceetm_rate cr_token_rate; + struct qm_ceetm_rate er_token_rate; + u16 cr_token_bucket_limit; + u16 er_token_bucket_limit; +}; + +struct qm_ceetm_ccg; + +/* This callback type is used when handling congestion entry/exit. The + * 'cb_ctx' value is the opaque value associated with ccg object. + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit. + */ +typedef void (*qman_cb_ccgr)(struct qm_ceetm_ccg *ccg, void *cb_ctx, + int congested); + +/* Class Congestion Group */ +struct qm_ceetm_ccg { + struct qm_ceetm_channel *parent; + struct list_head node; + struct list_head cb_node; + qman_cb_ccgr cb; + void *cb_ctx; + unsigned int idx; +}; + +/* Class Queue */ +struct qm_ceetm_cq { + struct qm_ceetm_channel *parent; + struct qm_ceetm_ccg *ccg; + struct list_head node; + unsigned int idx; + int is_claimed; + struct list_head bound_lfqids; + struct list_head binding_node; +}; + +/* Logical Frame Queue */ +struct qm_ceetm_lfq { + struct qm_ceetm_channel *parent; + struct list_head node; + unsigned int idx; + unsigned int dctidx; + u64 context_a; + u32 context_b; + qman_cb_mr ern; +}; + +/** + * qman_ceetm_bps2tokenrate - Given a desired rate 'bps' measured in bps + * (ie. bits-per-second), compute the 'token_rate' fraction that best + * approximates that rate. + * @bps: the desired shaper rate in bps. + * @token_rate: the output token rate computed with the given kbps. + * @rounding: dictates how to round if an exact conversion is not possible; if + * it is negative then 'token_rate' will round down to the highest value that + * does not exceed the desired rate, if it is positive then 'token_rate' will + * round up to the lowest value that is greater than or equal to the desired + * rate, and if it is zero then it will round to the nearest approximation, + * whether that be up or down. + * + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available. + */ +int qman_ceetm_bps2tokenrate(u64 bps, + struct qm_ceetm_rate *token_rate, + int rounding); + +/** + * qman_ceetm_tokenrate2bps - Given a 'token_rate', compute the + * corresponding number of 'bps'. + * @token_rate: the input desired token_rate fraction. + * @bps: the output shaper rate in bps computed with the give token rate. + * @rounding: has the same semantics as the previous function. + * + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available. + */ +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate, + u64 *bps, + int rounding); + +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align, + int partial); +static inline int qman_alloc_ceetm0_channel(u32 *result) +{ + int ret = qman_alloc_ceetm0_channel_range(result, 1, 0, 0); + return (ret > 0) ? 0 : ret; +} +void qman_release_ceetm0_channel_range(u32 channelid, u32 count); +static inline void qman_release_ceetm0_channelid(u32 channelid) +{ + qman_release_ceetm0_channel_range(channelid, 1); +} + +int qman_reserve_ceetm0_channel_range(u32 channelid, u32 count); +static inline int qman_reserve_ceetm0_channelid(u32 channelid) +{ + return qman_reserve_ceetm0_channel_range(channelid, 1); +} + +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count); + + +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align, + int partial); +static inline int qman_alloc_ceetm1_channel(u32 *result) +{ + int ret = qman_alloc_ceetm1_channel_range(result, 1, 0, 0); + return (ret > 0) ? 0 : ret; +} +void qman_release_ceetm1_channel_range(u32 channelid, u32 count); +static inline void qman_release_ceetm1_channelid(u32 channelid) +{ + qman_release_ceetm1_channel_range(channelid, 1); +} +int qman_reserve_ceetm1_channel_range(u32 channelid, u32 count); +static inline int qman_reserve_ceetm1_channelid(u32 channelid) +{ + return qman_reserve_ceetm1_channel_range(channelid, 1); +} + +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count); + + +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align, + int partial); +static inline int qman_alloc_ceetm0_lfqid(u32 *result) +{ + int ret = qman_alloc_ceetm0_lfqid_range(result, 1, 0, 0); + return (ret > 0) ? 0 : ret; +} +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count); +static inline void qman_release_ceetm0_lfqid(u32 lfqid) +{ + qman_release_ceetm0_lfqid_range(lfqid, 1); +} +int qman_reserve_ceetm0_lfqid_range(u32 lfqid, u32 count); +static inline int qman_reserve_ceetm0_lfqid(u32 lfqid) +{ + return qman_reserve_ceetm0_lfqid_range(lfqid, 1); +} + +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count); + + +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align, + int partial); +static inline int qman_alloc_ceetm1_lfqid(u32 *result) +{ + int ret = qman_alloc_ceetm1_lfqid_range(result, 1, 0, 0); + return (ret > 0) ? 0 : ret; +} +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count); +static inline void qman_release_ceetm1_lfqid(u32 lfqid) +{ + qman_release_ceetm1_lfqid_range(lfqid, 1); +} +int qman_reserve_ceetm1_lfqid_range(u32 lfqid, u32 count); +static inline int qman_reserve_ceetm1_lfqid(u32 lfqid) +{ + return qman_reserve_ceetm1_lfqid_range(lfqid, 1); +} + +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count); + + + /* ----------------------------- */ + /* CEETM :: sub-portals */ + /* ----------------------------- */ + +/** + * qman_ceetm_claim_sp - Claims the given sub-portal, provided it is available + * to us and configured for traffic-management. + * @sp: the returned sub-portal object, if successful. + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM + * instance), + * @sp_idx" is the desired sub-portal index from 0 to 15. + * + * Returns zero for success, or -ENODEV if the sub-portal is in use, or -EINVAL + * if the sp_idx is out of range. + * + * Note that if there are multiple driver domains (eg. a linux kernel versus + * user-space drivers in USDPAA, or multiple guests running under a hypervisor) + * then a sub-portal may be accessible by more than one instance of a qman + * driver and so it may be claimed multiple times. If this is the case, it is + * up to the system architect to prevent conflicting configuration actions + * coming from the different driver domains. The qman drivers do not have any + * behind-the-scenes coordination to prevent this from happening. + */ +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp, + enum qm_dc_portal dcp_idx, + unsigned int sp_idx); + +/** + * qman_ceetm_sp_release - Releases a previously claimed sub-portal. + * @sp: the sub-portal to be released. + * + * Returns 0 for success, or -EBUSY for failure if the dependencies are not + * released. + */ +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp); + + /* ----------------------------------- */ + /* CEETM :: logical network interfaces */ + /* ----------------------------------- */ + +/** + * qman_ceetm_lni_claim - Claims an unclaimed LNI. + * @lni: the returned LNI object, if successful. + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM + * instance) + * @lni_idx: is the desired LNI index. + * + * Returns zero for success, or -EINVAL on failure, which will happen if the LNI + * is not available or has already been claimed (and not yet successfully + * released), or lni_dix is out of range. + * + * Note that there may be multiple driver domains (or instances) that need to + * transmit out the same LNI, so this claim is only guaranteeing exclusivity + * within the domain of the driver being called. See qman_ceetm_sp_claim() and + * qman_ceetm_sp_get_lni() for more information. + */ +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni, + enum qm_dc_portal dcp_id, + unsigned int lni_idx); + +/** + * qman_ceetm_lni_releaes - Releases a previously claimed LNI. + * @lni: the lni needs to be released. + * + * This will only succeed if all dependent objects have been released. + * Returns zero for success, or -EBUSY if the dependencies are not released. + */ +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni); + +/** + * qman_ceetm_sp_set_lni + * qman_ceetm_sp_get_lni - Set/get the LNI that the sub-portal is currently + * mapped to. + * @sp: the given sub-portal. + * @lni(in "set"function): the LNI object which the sp will be mappaed to. + * @lni_idx(in "get" function): the LNI index which the sp is mapped to. + * + * Returns zero for success, or -EINVAL for the "set" function when this sp-lni + * mapping has been set, or configure mapping command returns error, and + * -EINVAL for "get" function when this sp-lni mapping is not set or the query + * mapping command returns error. + * + * This may be useful in situations where multiple driver domains have access + * to the same sub-portals in order to all be able to transmit out the same + * physical interface (perhaps they're on different IP addresses or VPNs, so + * Fman is splitting Rx traffic and here we need to converge Tx traffic). In + * that case, a control-plane is likely to use qman_ceetm_lni_claim() followed + * by qman_ceetm_sp_set_lni() to configure the sub-portal, and other domains + * are likely to use qman_ceetm_sp_get_lni() followed by qman_ceetm_lni_claim() + * in order to determine the LNI that the control-plane had assigned. This is + * why the "get" returns an index, whereas the "set" takes an (already claimed) + * LNI object. + */ +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp, + struct qm_ceetm_lni *lni); +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp, + unsigned int *lni_idx); + +/** + * qman_ceetm_lni_enable_shaper + * qman_ceetm_lni_disable_shaper - Enables/disables shaping on the LNI. + * @lni: the given LNI. + * @coupled: indicates whether CR and ER are coupled. + * @oal: the overhead accounting length which is added to the actual length of + * each frame when performing shaper calculations. + * + * When the number of (unused) committed-rate tokens reach the committed-rate + * token limit, 'coupled' indicates whether surplus tokens should be added to + * the excess-rate token count (up to the excess-rate token limit). + * When LNI is claimed, the shaper is disabled by default. The enable function + * will turn on this shaper for this lni. + * Whenever a claimed LNI is first enabled for shaping, its committed and + * excess token rates and limits are zero, so will need to be changed to do + * anything useful. The shaper can subsequently be enabled/disabled without + * resetting the shaping parameters, but the shaping parameters will be reset + * when the LNI is released. + * + * Returns zero for success, or errno for "enable" function in the cases as: + * a) -EINVAL if the shaper is already enabled, + * b) -EIO if the configure shaper command returns error. + * For "disable" function, returns: + * a) -EINVAL if the shaper is has already disabled. + * b) -EIO if calling configure shaper command returns error. + */ +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled, + int oal); +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni); + +/** + * qman_ceetm_lni_set_commit_rate + * qman_ceetm_lni_get_commit_rate + * qman_ceetm_lni_set_excess_rate + * qman_ceetm_lni_get_excess_rate - Set/get the shaper CR/ER token rate and + * token limit for the given LNI. + * @lni: the given LNI. + * @token_rate: the desired token rate for "set" fuction, or the token rate of + * the LNI queried by "get" function. + * @token_limit: the desired token bucket limit for "set" function, or the token + * limit of the given LNI queried by "get" function. + * + * Returns zero for success. The "set" function returns -EINVAL if the given + * LNI is unshapped or -EIO if the configure shaper command returns error. + * The "get" function returns -EINVAL if the token rate or the token limit is + * not set or the query command returns error. + */ +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni, + const struct qm_ceetm_rate *token_rate, + u16 token_limit); +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni, + struct qm_ceetm_rate *token_rate, + u16 *token_limit); +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni, + const struct qm_ceetm_rate *token_rate, + u16 token_limit); +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni, + struct qm_ceetm_rate *token_rate, + u16 *token_limit); + +/** + * qman_ceetm_lni_set_tcfcc + * qman_ceetm_lni_get_tcfcc - Configure/query "Traffic Class Flow Control". + * @lni: the given LNI. + * @cq_level: is between 0 and 15, representing individual class queue levels + * (CQ0 to CQ7 for every channel) and grouped class queue levels (CQ8 to CQ15 + * for every channel). + * @traffic_class: is between 0 and 7 when associating a given class queue level + * to a traffic class, or -1 when disabling traffic class flow control for this + * class queue level. + * + * Return zero for success, or -EINVAL if the cq_level or traffic_class is out + * of range as indicated above, or -EIO if the configure/query tcfcc command + * returns error. + * + * Refer to the section of QMan CEETM traffic class flow control in the + * Reference Manual. + */ +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni, + unsigned int cq_level, + int traffic_class); +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni, + unsigned int cq_level, + int *traffic_class); + + /* ----------------------------- */ + /* CEETM :: class queue channels */ + /* ----------------------------- */ + +/** + * qman_ceetm_channel_claim - Claims an unclaimed CQ channel that is mapped to + * the given LNI. + * @channel: the returned class queue channel object, if successful. + * @lni: the LNI that the channel belongs to. + * + * Channels are always initially "unshaped". + * + * Return zero for success, or -ENODEV if there is no channel available(all 32 + * channels are claimed) or -EINVAL if the channel mapping command returns + * error. + */ +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel, + struct qm_ceetm_lni *lni); + +/** + * qman_ceetm_channel_release - Releases a previously claimed CQ channel. + * @channel: the channel needs to be released. + * + * Returns zero for success, or -EBUSY if the dependencies are still in use. + * + * Note any shaping of the channel will be cleared to leave it in an unshaped + * state. + */ +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel); + +/** + * qman_ceetm_channel_enable_shaper + * qman_ceetm_channel_disable_shaper - Enables/disables shaping on the channel. + * @channel: the given channel. + * @coupled: indicates whether surplus CR tokens should be added to the + * excess-rate token count (up to the excess-rate token limit) when the number + * of (unused) committed-rate tokens reach the committed_rate token limit. + * + * Whenever a claimed channel is first enabled for shaping, its committed and + * excess token rates and limits are zero, so will need to be changed to do + * anything useful. The shaper can subsequently be enabled/disabled without + * resetting the shaping parameters, but the shaping parameters will be reset + * when the channel is released. + * + * Return 0 for success, or -EINVAL for failure, in the case that the channel + * shaper has been enabled/disabled or the management command returns error. + */ +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel, + int coupled); +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel); + +/** + * qman_ceetm_channel_set_commit_rate + * qman_ceetm_channel_get_commit_rate + * qman_ceetm_channel_set_excess_rate + * qman_ceetm_channel_get_excess_rate - Set/get channel CR/ER shaper parameters. + * @channel: the given channel. + * @token_rate: the desired token rate for "set" function, or the queried token + * rate for "get" function. + * @token_limit: the desired token limit for "set" function, or the queried + * token limit for "get" function. + * + * Return zero for success. The "set" function returns -EINVAL if the channel + * is unshaped, or -EIO if the configure shapper command returns error. The + * "get" function returns -EINVAL if token rate of token limit is not set, or + * the query shaper command returns error. + */ +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel, + const struct qm_ceetm_rate *token_rate, + u16 token_limit); +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel, + struct qm_ceetm_rate *token_rate, + u16 *token_limit); +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel, + const struct qm_ceetm_rate *token_rate, + u16 token_limit); +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel, + struct qm_ceetm_rate *token_rate, + u16 *token_limit); + +/** + * qman_ceetm_channel_set_weight + * qman_ceetm_channel_get_weight - Set/get the weight for unshaped channel + * @channel: the given channel. + * @token_limit: the desired token limit as the weight of the unshaped channel + * for "set" function, or the queried token limit for "get" function. + * + * The algorithm of unshaped fair queuing (uFQ) is used for unshaped channel. + * It allows the unshaped channels to be included in the CR time eligible list, + * and thus use the configured CR token limit value as their fair queuing + * weight. + * + * Return zero for success, or -EINVAL if the channel is a shaped channel or + * the management command returns error. + */ +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel, + u16 token_limit); +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel, + u16 *token_limit); + +/** + * qman_ceetm_channel_set_group + * qman_ceetm_channel_get_group - Set/get the grouping of the class scheduler. + * @channel: the given channel. + * @group_b: indicates whether there is group B in this channel. + * @prio_a: the priority of group A. + * @prio_b: the priority of group B. + * + * There are 8 individual class queues (CQ0-CQ7), and 8 grouped class queues + * (CQ8-CQ15). If 'group_b' is zero, then all the grouped class queues are in + * group A, otherwise they are split into group A (CQ8-11) and group B + * (CQ12-C15). The individual class queues and the group(s) are in strict + * priority order relative to each other. Within the group(s), the scheduling + * is not strict priority order, but the result of scheduling within a group + * is in strict priority order relative to the other class queues in the + * channel. 'prio_a' and 'prio_b' control the priority order of the groups + * relative to the individual class queues, and take values from 0-7. Eg. if + * 'group_b' is non-zero, 'prio_a' is 2 and 'prio_b' is 6, then the strict + * priority order would be; + * CQ0, CQ1, CQ2, GROUPA, CQ3, CQ4, CQ5, CQ6, GROUPB, CQ7 + * + * Return 0 for success. For "set" function, returns -EINVAL if prio_a or + * prio_b are out of the range 1 - 7 (priority of group A or group B can not + * be 0, CQ0 is always the highest class queue in this channel.), or -EIO if + * the configure scheduler command returns error. For "get" function, return + * -EINVAL if the query scheduler command returns error. + */ +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel, + int group_b, + unsigned int prio_a, + unsigned int prio_b); +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel, + int *group_b, + unsigned int *prio_a, + unsigned int *prio_b); + +/** + * qman_ceetm_channel_set_group_cr_eligibility + * qman_ceetm_channel_set_group_er_eligibility - Set channel group eligibility + * @channel: the given channel object + * @group_b: indicates whether there is group B in this channel. + * @cre: the commit rate eligibility, 1 for enable, 0 for disable. + * + * Return zero for success, or -EINVAL if eligibility setting fails. +*/ +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel + *channel, int group_b, int cre); +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel + *channel, int group_b, int ere); + +/** + * qman_ceetm_channel_set_cq_cr_eligibility + * qman_ceetm_channel_set_cq_er_eligibility - Set channel cq eligibility + * @channel: the given channel object + * @idx: is from 0 to 7 (representing CQ0 to CQ7). + * @cre: the commit rate eligibility, 1 for enable, 0 for disable. + * + * Return zero for success, or -EINVAL if eligibility setting fails. +*/ +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel, + unsigned int idx, int cre); +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel, + unsigned int idx, int ere); + + /* --------------------- */ + /* CEETM :: class queues */ + /* --------------------- */ + +/** + * qman_ceetm_cq_claim - Claims an individual class queue. + * @cq: the returned class queue object, if successful. + * @channel: the class queue channel. + * @idx: is from 0 to 7 (representing CQ0 to CQ7). + * @ccg: represents the class congestion group that this class queue should be + * subscribed to, or NULL if no congestion group membership is desired. + * + * Returns zero for success, or -EINVAL if @idx is out of range 0 - 7 or + * if this class queue has been claimed, or configure class queue command + * returns error, or returns -ENOMEM if allocating CQ memory fails. + */ +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq, + struct qm_ceetm_channel *channel, + unsigned int idx, + struct qm_ceetm_ccg *ccg); + +/** + * qman_ceetm_cq_claim_A - Claims a class queue group A. + * @cq: the returned class queue object, if successful. + * @channel: the class queue channel. + * @idx: is from 8 to 15 if only group A exits, otherwise, it is from 8 to 11. + * @ccg: represents the class congestion group that this class queue should be + * subscribed to, or NULL if no congestion group membership is desired. + * + * Return zero for success, or -EINVAL if @idx is out the range or if + * this class queue has been claimed or configure class queue command returns + * error, or returns -ENOMEM if allocating CQ memory fails. + */ +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq, + struct qm_ceetm_channel *channel, + unsigned int idx, + struct qm_ceetm_ccg *ccg); + +/** + * qman_ceetm_cq_claim_B - Claims a class queue group B. + * @cq: the returned class queue object, if successful. + * @channel: the class queue channel. + * @idx: is from 0 to 3 (CQ12 to CQ15). + * @ccg: represents the class congestion group that this class queue should be + * subscribed to, or NULL if no congestion group membership is desired. + * + * Return zero for success, or -EINVAL if @idx is out the range or if + * this class queue has been claimed or configure class queue command returns + * error, or returns -ENOMEM if allocating CQ memory fails. + */ +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq, + struct qm_ceetm_channel *channel, + unsigned int idx, + struct qm_ceetm_ccg *ccg); + +/** + * qman_ceetm_cq_release - Releases a previously claimed class queue. + * @cq: The class queue to be released. + * + * Return zero for success, or -EBUSY if the dependent objects (eg. logical + * FQIDs) have not been released. + */ +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq); + +/** + * qman_ceetm_set_queue_weight + * qman_ceetm_get_queue_weight - Configure/query the weight of a grouped class + * queue. + * @cq: the given class queue. + * @weight_code: the desired weight code to set for the given class queue for + * "set" function or the queired weight code for "get" function. + * + * Grouped class queues have a default weight code of zero, which corresponds to + * a scheduler weighting of 1. This function can be used to modify a grouped + * class queue to another weight, (Use the helpers qman_ceetm_wbfs2ratio() + * and qman_ceetm_ratio2wbfs() to convert between these 'weight_code' values + * and the corresponding sharing weight.) + * + * Returns zero for success, or -EIO if the configure weight command returns + * error for "set" function, or -EINVAL if the query command returns + * error for "get" function. + * See section "CEETM Weighted Scheduling among Grouped Classes" in Reference + * Manual for weight and weight code. + */ +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq, + struct qm_ceetm_weight_code *weight_code); +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq, + struct qm_ceetm_weight_code *weight_code); + +/* Weights are encoded using a pseudo-exponential scheme. The weight codes 0, + * 32, 64, [...] correspond to weights of 1, 2, 4, [...]. The weights + * corresponding to intermediate weight codes are calculated using linear + * interpolation on the inverted values. Or put another way, the inverse weights + * for each 32nd weight code are 1, 1/2, 1/4, [...], and so the intervals + * between these are divided linearly into 32 intermediate values, the inverses + * of which form the remaining weight codes. + * + * The Weighted Bandwidth Fair Scheduling (WBFS) algorithm provides a form of + * scheduling within a group of class queues (group A or B). Weights are used to + * normalise the class queues to an underlying BFS algorithm where all class + * queues are assumed to require "equal bandwidth". So the weights referred to + * by the weight codes act as divisors on the size of frames being enqueued. Ie. + * one class queue in a group is assigned a weight of 2 whilst the other class + * queues in the group keep the default weight of 1, then the WBFS scheduler + * will effectively treat all frames enqueued on the weight-2 class queue as + * having half the number of bytes they really have. Ie. if all other things are + * equal, that class queue would get twice as much bytes-per-second bandwidth as + * the others. So weights should be chosen to provide bandwidth ratios between + * members of the same class queue group. These weights have no bearing on + * behaviour outside that group's WBFS mechanism though. + */ + +/** + * qman_ceetm_wbfs2ratio - Given a weight code ('wbfs'), an accurate fractional + * representation of the corresponding weight is given (in order to not lose + * any precision). + * @weight_code: The given weight code in WBFS. + * @numerator: the numerator part of the weight computed by the weight code. + * @denominator: the denominator part of the weight computed by the weight code + * + * Returns zero for success or -EINVAL if the given weight code is illegal. + */ +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code, + u32 *numerator, + u32 *denominator); +/** + * qman_ceetm_ratio2wbfs - Given a weight, find the nearest possible weight code + * If the user needs to know how close this is, convert the resulting weight + * code back to a weight and compare. + * @numerator: numerator part of the given weight. + * @denominator: denominator part of the given weight. + * @weight_code: the weight code computed from the given weight. + * + * Returns zero for success, or -ERANGE if "numerator/denominator" is outside + * the range of weights. + */ +int qman_ceetm_ratio2wbfs(u32 numerator, + u32 denominator, + struct qm_ceetm_weight_code *weight_code, + int rounding); + +#define QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER 0x1 +/** + * qman_ceetm_cq_get_dequeue_statistics - Get the statistics provided by CEETM + * CQ counters. + * @cq: the given CQ object. + * @flags: indicates whether the statistics counter will be cleared after query. + * @frame_count: The number of the frames that have been counted since the + * counter was cleared last time. + * @byte_count: the number of bytes in all frames that have been counted. + * + * Return zero for success or -EINVAL if query statistics command returns error. + * + */ +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags, + u64 *frame_count, u64 *byte_count); + + /* ---------------------- */ + /* CEETM :: logical FQIDs */ + /* ---------------------- */ +/** + * qman_ceetm_lfq_claim - Claims an unused logical FQID, associates it with + * the given class queue. + * @lfq: the returned lfq object, if successful. + * @cq: the class queue which needs to claim a LFQID. + * + * Return zero for success, or -ENODEV if no LFQID is available or -ENOMEM if + * allocating memory for lfq fails, or -EINVAL if configuring LFQMT fails. + */ +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq, + struct qm_ceetm_cq *cq); + +/** + * qman_ceetm_lfq_release - Releases a previously claimed logical FQID. + * @lfq: the lfq to be released. + * + * Return zero for success. + */ +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq); + +/** + * qman_ceetm_lfq_set_context + * qman_ceetm_lfq_get_context - Set/get the context_a/context_b pair to the + * "dequeue context table" associated with the logical FQID. + * @lfq: the given logical FQ object. + * @context_a: contextA of the dequeue context. + * @context_b: contextB of the dequeue context. + * + * Returns zero for success, or -EINVAL if there is error to set/get the + * context pair. + */ +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq, + u64 context_a, + u32 context_b); +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq, + u64 *context_a, + u32 *context_b); + +/** + * qman_ceetm_create_fq - Initialise a FQ object for the LFQ. + * @lfq: the given logic fq. + * @fq: the fq object created for the given logic fq. + * + * The FQ object can be used in qman_enqueue() and qman_enqueue_orp() APIs to + * target a logical FQID (and the class queue it is associated with). + * Note that this FQ object can only be used for enqueues, and + * in the case of qman_enqueue_orp() it can not be used as the 'orp' parameter, + * only as 'fq'. This FQ object can not (and shouldn't) be destroyed, it is only + * valid as long as the underlying 'lfq' remains claimed. It is the user's + * responsibility to ensure that the underlying 'lfq' is not released until any + * enqueues to this FQ object have completed. The only field the user needs to + * fill in is fq->cb.ern, as that enqueue rejection handler is the callback that + * could conceivably be called on this FQ object. This API can be called + * multiple times to create multiple FQ objects referring to the same logical + * FQID, and any enqueue rejections will respect the callback of the object that + * issued the enqueue (and will identify the object via the parameter passed to + * the callback too). There is no 'flags' parameter to this API as there is for + * qman_create_fq() - the created FQ object behaves as though qman_create_fq() + * had been called with the single flag QMAN_FQ_FLAG_NO_MODIFY. + * + * Returns 0 for success. + */ +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq); + + /* -------------------------------- */ + /* CEETM :: class congestion groups */ + /* -------------------------------- */ + +/** + * qman_ceetm_ccg_claim - Claims an unused CCG. + * @ccg: the returned CCG object, if successful. + * @channel: the given class queue channel + * @cscn: the callback function of this CCG. + * @cb_ctx: the corresponding context to be used used if state change + * notifications are later enabled for this CCG. + * + * The congestion group is local to the given class queue channel, so only + * class queues within the channel can be associated with that congestion group. + * The association of class queues to congestion groups occurs when the class + * queues are claimed, see qman_ceetm_cq_claim() and related functions. + * Congestion groups are in a "zero" state when initially claimed, and they are + * returned to that state when released. + * + * Return zero for success, or -EINVAL if no CCG in the channel is available. + */ +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg, + struct qm_ceetm_channel *channel, + unsigned int idx, + void (*cscn)(struct qm_ceetm_ccg *, + void *cb_ctx, + int congested), + void *cb_ctx); + +/** + * qman_ceetm_ccg_release - Releases a previously claimed CCG. + * @ccg: the given ccg. + * + * Returns zero for success, or -EBUSY if the given ccg's dependent objects + * (class queues that are associated with the CCG) have not been released. + */ +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg); + +/* This struct is used to specify attributes for a CCG. The 'we_mask' field + * controls which CCG attributes are to be updated, and the remainder specify + * the values for those attributes. A CCG counts either frames or the bytes + * within those frames, but not both ('mode'). A CCG can optionally cause + * enqueues to be rejected, due to tail-drop or WRED, or both (they are + * independent options, 'td_en' and 'wr_en_g,wr_en_y,wr_en_r'). Tail-drop can be + * level-triggered due to a single threshold ('td_thres') or edge-triggered due + * to a "congestion state", but not both ('td_mode'). Congestion state has + * distinct entry and exit thresholds ('cs_thres_in' and 'cs_thres_out'), and + * notifications can be sent to software the CCG goes in to and out of this + * congested state ('cscn_en'). */ +struct qm_ceetm_ccg_params { + /* Boolean fields together in a single bitfield struct */ + struct { + /* Whether to count bytes or frames. 1==frames */ + u8 mode:1; + /* En/disable tail-drop. 1==enable */ + u8 td_en:1; + /* Tail-drop on congestion-state or threshold. 1=threshold */ + u8 td_mode:1; + /* Generate congestion state change notifications. 1==enable */ + u8 cscn_en:1; + /* Enable WRED rejections (per colour). 1==enable */ + u8 wr_en_g:1; + u8 wr_en_y:1; + u8 wr_en_r:1; + } __packed; + /* Tail-drop threshold. See qm_cgr_thres_[gs]et64(). */ + struct qm_cgr_cs_thres td_thres; + /* Congestion state thresholds, for entry and exit. */ + struct qm_cgr_cs_thres cs_thres_in; + struct qm_cgr_cs_thres cs_thres_out; + /* Overhead accounting length. Per-packet "tax", from -128 to +127 */ + signed char oal; + /* Congestion state change notification for DCP portal, virtual CCGID*/ + /* WRED parameters. */ + struct qm_cgr_wr_parm wr_parm_g; + struct qm_cgr_wr_parm wr_parm_y; + struct qm_cgr_wr_parm wr_parm_r; +}; +/* Bits used in 'we_mask' to qman_ceetm_ccg_set(), controls which attributes of + * the CCGR are to be updated. */ +#define QM_CCGR_WE_CDV 0x0000 /* cdv */ +#define QM_CCGR_WE_MODE 0x0001 /* mode (bytes/frames) */ +#define QM_CCGR_WE_CS_THRES_IN 0x0002 /* congestion state entry threshold */ +#define QM_CCGR_WE_TD_EN 0x0004 /* congestion state tail-drop enable */ +#define QM_CCGR_WE_CSCN_TUPD 0x0008 /* CSCN target update */ +#define QM_CCGR_WE_CSCN_EN 0x0010 /* congestion notification enable */ +#define QM_CCGR_WE_WR_EN_R 0x0020 /* WRED enable - red */ +#define QM_CCGR_WE_WR_EN_Y 0x0040 /* WRED enable - yellow */ +#define QM_CCGR_WE_WR_EN_G 0x0080 /* WRED enable - green */ +#define QM_CCGR_WE_WR_PARM_R 0x0100 /* WRED parameters - red */ +#define QM_CCGR_WE_WR_PARM_Y 0x0200 /* WRED parameters - yellow */ +#define QM_CCGR_WE_WR_PARM_G 0x0400 /* WRED parameters - green */ +#define QM_CCGR_WE_OAL 0x0800 /* overhead accounting length */ +#define QM_CCGR_WE_CS_THRES_OUT 0x1000 /* congestion state exit threshold */ +#define QM_CCGR_WE_TD_THRES 0x2000 /* tail-drop threshold */ +#define QM_CCGR_WE_TD_MODE 0x4000 /* tail-drop mode (state/threshold) */ + +/** + * qman_ceetm_ccg_set + * qman_ceetm_ccg_get - Configure/query a subset of CCG attributes. + * @ccg: the given CCG object. + * @we_mask: the write enable mask. + * @params: the parameters setting for this ccg + * + * Return 0 for success, or -EIO if configure ccg command returns error for + * "set" function, or -EINVAL if query ccg command returns error for "get" + * function. + */ +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg, + u16 we_mask, + const struct qm_ceetm_ccg_params *params); +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg, + struct qm_ceetm_ccg_params *params); + +/** qman_ceetm_cscn_swp_set - Add or remove a software portal from the target + * mask. + * qman_ceetm_cscn_swp_get - Query whether a given software portal index is + * in the cscn target mask. + * @ccg: the give CCG object. + * @swp_idx: the index of the software portal. + * @cscn_enabled: 1: Set the swp to be cscn target. 0: remove the swp from + * the target mask. + * @we_mask: the write enable mask. + * @params: the parameters setting for this ccg + * + * Return 0 for success, or -EINVAL if command in set/get function fails. + */ +int qman_ceetm_cscn_swp_set(struct qm_ceetm_ccg *ccg, + u16 swp_idx, + unsigned int cscn_enabled, + u16 we_mask, + const struct qm_ceetm_ccg_params *params); +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg, + u16 swp_idx, + unsigned int *cscn_enabled); + +/** qman_ceetm_cscn_dcp_set - Add or remove a direct connect portal from the\ + * target mask. + * qman_ceetm_cscn_swp_get - Query whether a given direct connect portal index + * is in the cscn target mask. + * @ccg: the give CCG object. + * @dcp_idx: the index of the direct connect portal. + * @vcgid: congestion state change notification for dcp portal, virtual CGID. + * @cscn_enabled: 1: Set the dcp to be cscn target. 0: remove the dcp from + * the target mask. + * @we_mask: the write enable mask. + * @params: the parameters setting for this ccg + * + * Return 0 for success, or -EINVAL if command in set/get function fails. + */ +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg, + u16 dcp_idx, + u8 vcgid, + unsigned int cscn_enabled, + u16 we_mask, + const struct qm_ceetm_ccg_params *params); +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg, + u16 dcp_idx, + u8 *vcgid, + unsigned int *cscn_enabled); + +/** + * qman_ceetm_ccg_get_reject_statistics - Get the statistics provided by + * CEETM CCG counters. + * @ccg: the given CCG object. + * @flags: indicates whether the statistics counter will be cleared after query. + * @frame_count: The number of the frames that have been counted since the + * counter was cleared last time. + * @byte_count: the number of bytes in all frames that have been counted. + * + * Return zero for success or -EINVAL if query statistics command returns error. + * + */ +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags, + u64 *frame_count, u64 *byte_count); + +/** + * qman_set_wpm - Set waterfall power management + * + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm. + * + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not + * accessible. + */ +int qman_set_wpm(int wpm_enable); + +/** + * qman_get_swp - Query the waterfall power management setting + * + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm. + * + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not + * accessible. + */ +int qman_get_wpm(int *wpm_enable); + +/* The below qman_p_***() variants might be called in a migration situation + * (e.g. cpu hotplug). They are used to continue accessing the portal that + * execution was affine to prior to migration. + * @qman_portal specifies which portal the APIs will use. +*/ +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal + *p); +int qman_p_irqsource_add(struct qman_portal *p, u32 bits); +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits); +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit); +u32 qman_p_poll_slow(struct qman_portal *p); +void qman_p_poll(struct qman_portal *p); +void qman_p_stop_dequeues(struct qman_portal *p); +void qman_p_start_dequeues(struct qman_portal *p); +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools); +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools); +u32 qman_p_static_dequeue_get(struct qman_portal *p); +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq, + int park_request); +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq, + u32 flags __maybe_unused, u32 vdqcr); +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq, + const struct qm_fd *fd, u32 flags); +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq, + const struct qm_fd *fd, u32 flags, + struct qman_fq *orp, u16 orp_seqnum); +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq, + const struct qm_fd *fd, u32 flags, + qman_cb_precommit cb, void *cb_arg); +#ifdef __cplusplus +} +#endif + +#endif /* FSL_QMAN_H */ diff --git a/include/linux/fsl_usdpaa.h b/include/linux/fsl_usdpaa.h new file mode 100644 index 0000000..896c03a --- /dev/null +++ b/include/linux/fsl_usdpaa.h @@ -0,0 +1,372 @@ +/* Copyright 2011-2012 Freescale Semiconductor, Inc. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#ifndef FSL_USDPAA_H +#define FSL_USDPAA_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <linux/uaccess.h> +#include <linux/ioctl.h> +#include <linux/fsl_qman.h> /* For "enum qm_channel" */ +#include <linux/compat.h> + +#ifdef CONFIG_FSL_USDPAA + +/******************************/ +/* Allocation of resource IDs */ +/******************************/ + +/* This enum is used to distinguish between the type of underlying object being + * manipulated. */ +enum usdpaa_id_type { + usdpaa_id_fqid, + usdpaa_id_bpid, + usdpaa_id_qpool, + usdpaa_id_cgrid, + usdpaa_id_ceetm0_lfqid, + usdpaa_id_ceetm0_channelid, + usdpaa_id_ceetm1_lfqid, + usdpaa_id_ceetm1_channelid, + usdpaa_id_max /* <-- not a valid type, represents the number of types */ +}; +#define USDPAA_IOCTL_MAGIC 'u' +struct usdpaa_ioctl_id_alloc { + uint32_t base; /* Return value, the start of the allocated range */ + enum usdpaa_id_type id_type; /* what kind of resource(s) to allocate */ + uint32_t num; /* how many IDs to allocate (and return value) */ + uint32_t align; /* must be a power of 2, 0 is treated like 1 */ + int partial; /* whether to allow less than 'num' */ +}; +struct usdpaa_ioctl_id_release { + /* Input; */ + enum usdpaa_id_type id_type; + uint32_t base; + uint32_t num; +}; +struct usdpaa_ioctl_id_reserve { + enum usdpaa_id_type id_type; + uint32_t base; + uint32_t num; +}; + + +/* ioctl() commands */ +#define USDPAA_IOCTL_ID_ALLOC \ + _IOWR(USDPAA_IOCTL_MAGIC, 0x01, struct usdpaa_ioctl_id_alloc) +#define USDPAA_IOCTL_ID_RELEASE \ + _IOW(USDPAA_IOCTL_MAGIC, 0x02, struct usdpaa_ioctl_id_release) +#define USDPAA_IOCTL_ID_RESERVE \ + _IOW(USDPAA_IOCTL_MAGIC, 0x0A, struct usdpaa_ioctl_id_reserve) + +/**********************/ +/* Mapping DMA memory */ +/**********************/ + +/* Maximum length for a map name, including NULL-terminator */ +#define USDPAA_DMA_NAME_MAX 16 +/* Flags for requesting DMA maps. Maps are private+unnamed or sharable+named. + * For a sharable and named map, specify _SHARED (whether creating one or + * binding to an existing one). If _SHARED is specified and _CREATE is not, then + * the mapping must already exist. If _SHARED and _CREATE are specified and the + * mapping doesn't already exist, it will be created. If _SHARED and _CREATE are + * specified and the mapping already exists, the mapping will fail unless _LAZY + * is specified. When mapping to a pre-existing sharable map, the length must be + * an exact match. Lengths must be a power-of-4 multiple of page size. + * + * Note that this does not actually map the memory to user-space, that is done + * by a subsequent mmap() using the page offset returned from this ioctl(). The + * ioctl() is what gives the process permission to do this, and a page-offset + * with which to do so. + */ +#define USDPAA_DMA_FLAG_SHARE 0x01 +#define USDPAA_DMA_FLAG_CREATE 0x02 +#define USDPAA_DMA_FLAG_LAZY 0x04 +#define USDPAA_DMA_FLAG_RDONLY 0x08 +struct usdpaa_ioctl_dma_map { + /* Output parameters - virtual and physical addresses */ + void *ptr; + uint64_t phys_addr; + /* Input parameter, the length of the region to be created (or if + * mapping an existing region, this must match it). Must be a power-of-4 + * multiple of page size. */ + uint64_t len; + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */ + uint32_t flags; + /* If _FLAG_SHARE is specified, the name of the region to be created (or + * of the existing mapping to use). */ + char name[USDPAA_DMA_NAME_MAX]; + /* If this ioctl() creates the mapping, this is an input parameter + * stating whether the region supports locking. If mapping an existing + * region, this is a return value indicating the same thing. */ + int has_locking; + /* In the case of a successful map with _CREATE and _LAZY, this return + * value indicates whether we created the mapped region or whether it + * already existed. */ + int did_create; +}; + +#ifdef CONFIG_COMPAT +struct usdpaa_ioctl_dma_map_compat { + /* Output parameters - virtual and physical addresses */ + compat_uptr_t ptr; + uint64_t phys_addr; + /* Input parameter, the length of the region to be created (or if + * mapping an existing region, this must match it). Must be a power-of-4 + * multiple of page size. */ + uint64_t len; + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */ + uint32_t flags; + /* If _FLAG_SHARE is specified, the name of the region to be created (or + * of the existing mapping to use). */ + char name[USDPAA_DMA_NAME_MAX]; + /* If this ioctl() creates the mapping, this is an input parameter + * stating whether the region supports locking. If mapping an existing + * region, this is a return value indicating the same thing. */ + int has_locking; + /* In the case of a successful map with _CREATE and _LAZY, this return + * value indicates whether we created the mapped region or whether it + * already existed. */ + int did_create; +}; + +#define USDPAA_IOCTL_DMA_MAP_COMPAT \ + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map_compat) +#endif + + +#define USDPAA_IOCTL_DMA_MAP \ + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map) +/* munmap() does not remove the DMA map, just the user-space mapping to it. + * This ioctl will do both (though you can munmap() before calling the ioctl + * too). */ +#define USDPAA_IOCTL_DMA_UNMAP \ + _IOW(USDPAA_IOCTL_MAGIC, 0x04, unsigned char) +/* We implement a cross-process locking scheme per DMA map. Call this ioctl() + * with a mmap()'d address, and the process will (interruptible) sleep if the + * lock is already held by another process. Process destruction will + * automatically clean up any held locks. */ +#define USDPAA_IOCTL_DMA_LOCK \ + _IOW(USDPAA_IOCTL_MAGIC, 0x05, unsigned char) +#define USDPAA_IOCTL_DMA_UNLOCK \ + _IOW(USDPAA_IOCTL_MAGIC, 0x06, unsigned char) + +/***************************************/ +/* Mapping and using QMan/BMan portals */ +/***************************************/ +enum usdpaa_portal_type { + usdpaa_portal_qman, + usdpaa_portal_bman, +}; + +#define QBMAN_ANY_PORTAL_IDX 0xffffffff + +struct usdpaa_ioctl_portal_map { + /* Input parameter, is a qman or bman portal required. */ + + enum usdpaa_portal_type type; + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX + for don't care. The portal index will be populated by the + driver when the ioctl() successfully completes */ + uint32_t index; + + /* Return value if the map succeeds, this gives the mapped + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */ + struct usdpaa_portal_map { + void *cinh; + void *cena; + } addr; + /* Qman-specific return values */ + uint16_t channel; + uint32_t pools; +}; + +#ifdef CONFIG_COMPAT +struct compat_usdpaa_ioctl_portal_map { + /* Input parameter, is a qman or bman portal required. */ + enum usdpaa_portal_type type; + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX + for don't care. The portal index will be populated by the + driver when the ioctl() successfully completes */ + uint32_t index; + /* Return value if the map succeeds, this gives the mapped + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */ + struct usdpaa_portal_map_compat { + compat_uptr_t cinh; + compat_uptr_t cena; + } addr; + /* Qman-specific return values */ + uint16_t channel; + uint32_t pools; +}; +#define USDPAA_IOCTL_PORTAL_MAP_COMPAT \ + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct compat_usdpaa_ioctl_portal_map) +#define USDPAA_IOCTL_PORTAL_UNMAP_COMPAT \ + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map_compat) +#endif + +#define USDPAA_IOCTL_PORTAL_MAP \ + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct usdpaa_ioctl_portal_map) +#define USDPAA_IOCTL_PORTAL_UNMAP \ + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map) + +struct usdpaa_ioctl_irq_map { + enum usdpaa_portal_type type; /* Type of portal to map */ + int fd; /* File descriptor that contains the portal */ + void *portal_cinh; /* Cache inhibited area to identify the portal */ +}; + +#define USDPAA_IOCTL_PORTAL_IRQ_MAP \ + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct usdpaa_ioctl_irq_map) + +#ifdef CONFIG_COMPAT + +struct compat_ioctl_irq_map { + enum usdpaa_portal_type type; /* Type of portal to map */ + compat_int_t fd; /* File descriptor that contains the portal */ + compat_uptr_t portal_cinh; /* Used identify the portal */}; + +#define USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT \ + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct compat_ioctl_irq_map) +#endif + +/* ioctl to query the amount of DMA memory used in the system */ +struct usdpaa_ioctl_dma_used { + uint64_t free_bytes; + uint64_t total_bytes; +}; +#define USDPAA_IOCTL_DMA_USED \ + _IOR(USDPAA_IOCTL_MAGIC, 0x0B, struct usdpaa_ioctl_dma_used) + +/* ioctl to allocate a raw portal */ +struct usdpaa_ioctl_raw_portal { + /* inputs */ + enum usdpaa_portal_type type; /* Type of portal to allocate */ + + /* set to non zero to turn on stashing */ + uint8_t enable_stash; + /* Stashing attributes for the portal */ + uint32_t cpu; + uint32_t cache; + uint32_t window; + + /* Specifies the stash request queue this portal should use */ + uint8_t sdest; + + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX + * for don't care. The portal index will be populated by the + * driver when the ioctl() successfully completes */ + uint32_t index; + + /* outputs */ + uint64_t cinh; + uint64_t cena; +}; + +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL \ + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct usdpaa_ioctl_raw_portal) + +#define USDPAA_IOCTL_FREE_RAW_PORTAL \ + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct usdpaa_ioctl_raw_portal) + +#ifdef CONFIG_COMPAT + +struct compat_ioctl_raw_portal { + /* inputs */ + enum usdpaa_portal_type type; /* Type of portal to allocate */ + + /* set to non zero to turn on stashing */ + uint8_t enable_stash; + /* Stashing attributes for the portal */ + uint32_t cpu; + uint32_t cache; + uint32_t window; + /* Specifies the stash request queue this portal should use */ + uint8_t sdest; + + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX + * for don't care. The portal index will be populated by the + * driver when the ioctl() successfully completes */ + uint32_t index; + + /* outputs */ + uint64_t cinh; + uint64_t cena; +}; + +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT \ + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct compat_ioctl_raw_portal) + +#define USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT \ + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct compat_ioctl_raw_portal) + +#endif + +#ifdef __KERNEL__ + +/* Early-boot hook */ +void __init fsl_usdpaa_init_early(void); + +/* Fault-handling in arch/powerpc/mm/mem.c gives USDPAA an opportunity to detect + * faults within its ranges via this hook. */ +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size); + +#endif /* __KERNEL__ */ + +#endif /* CONFIG_FSL_USDPAA */ + +#ifdef __KERNEL__ +/* This interface is needed in a few places and though it's not specific to + * USDPAA as such, creating a new header for it doesn't make any sense. The + * qbman kernel driver implements this interface and uses it as the backend for + * both the FQID and BPID allocators. The fsl_usdpaa driver also uses this + * interface for tracking per-process allocations handed out to user-space. */ +struct dpa_alloc { + struct list_head free; + spinlock_t lock; + struct list_head used; +}; +#define DECLARE_DPA_ALLOC(name) \ + struct dpa_alloc name = { \ + .free = { \ + .prev = &name.free, \ + .next = &name.free \ + }, \ + .lock = __SPIN_LOCK_UNLOCKED(name.lock), \ + .used = { \ + .prev = &name.used, \ + .next = &name.used \ + } \ + } +static inline void dpa_alloc_init(struct dpa_alloc *alloc) +{ + INIT_LIST_HEAD(&alloc->free); + INIT_LIST_HEAD(&alloc->used); + spin_lock_init(&alloc->lock); +} +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align, + int partial); +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count); +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 fqid, u32 count); + +/* Like 'new' but specifies the desired range, returns -ENOMEM if the entire + * desired range is not available, or 0 for success. */ +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base_id, u32 count); +/* Pops and returns contiguous ranges from the allocator. Returns -ENOMEM when + * 'alloc' is empty. */ +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count); +/* Returns 1 if the specified id is alloced, 0 otherwise */ +int dpa_alloc_check(struct dpa_alloc *list, u32 id); +#endif /* __KERNEL__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* FSL_USDPAA_H */ diff --git a/include/linux/hwmon.h b/include/linux/hwmon.h index b2514f7..09354f6 100644 --- a/include/linux/hwmon.h +++ b/include/linux/hwmon.h @@ -15,9 +15,19 @@ #define _HWMON_H_ struct device; +struct attribute_group; struct device *hwmon_device_register(struct device *dev); +struct device * +hwmon_device_register_with_groups(struct device *dev, const char *name, + void *drvdata, + const struct attribute_group **groups); +struct device * +devm_hwmon_device_register_with_groups(struct device *dev, const char *name, + void *drvdata, + const struct attribute_group **groups); void hwmon_device_unregister(struct device *dev); +void devm_hwmon_device_unregister(struct device *dev); #endif diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 7ea319e..76b6be5 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -76,6 +76,7 @@ enum iommu_attr { DOMAIN_ATTR_PAGING, DOMAIN_ATTR_WINDOWS, DOMAIN_ATTR_FSL_PAMU_STASH, + DOMAIN_ATTR_FSL_PAMU_OP_MAP, DOMAIN_ATTR_FSL_PAMU_ENABLE, DOMAIN_ATTR_FSL_PAMUV1, DOMAIN_ATTR_MAX, @@ -127,6 +128,7 @@ struct iommu_ops { int (*domain_set_windows)(struct iommu_domain *domain, u32 w_count); /* Get the numer of window per domain */ u32 (*domain_get_windows)(struct iommu_domain *domain); + struct iommu_domain *(*get_dev_iommu_domain)(struct device *dev); unsigned long pgsize_bitmap; }; @@ -190,6 +192,7 @@ extern int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr, phys_addr_t offset, u64 size, int prot); extern void iommu_domain_window_disable(struct iommu_domain *domain, u32 wnd_nr); +extern struct iommu_domain *iommu_get_dev_domain(struct device *dev); /** * report_iommu_fault() - report about an IOMMU fault to the IOMMU framework * @domain: the iommu domain where the fault has happened @@ -388,6 +391,10 @@ static inline int iommu_domain_set_attr(struct iommu_domain *domain, return -EINVAL; } +static inline struct iommu_domain *iommu_get_dev_domain(struct device *dev) +{ + return NULL; +} #endif /* CONFIG_IOMMU_API */ #endif /* __LINUX_IOMMU_H */ diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index 10308c6..552d51e 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -1,7 +1,7 @@ /* * A generic kernel FIFO implementation * - * Copyright (C) 2009/2010 Stefani Seibold <stefani@seibold.net> + * Copyright (C) 2013 Stefani Seibold <stefani@seibold.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -67,9 +67,10 @@ struct __kfifo { union { \ struct __kfifo kfifo; \ datatype *type; \ + const datatype *const_type; \ char (*rectype)[recsize]; \ ptrtype *ptr; \ - const ptrtype *ptr_const; \ + ptrtype const *ptr_const; \ } #define __STRUCT_KFIFO(type, size, recsize, ptrtype) \ @@ -386,16 +387,12 @@ __kfifo_int_must_check_helper( \ #define kfifo_put(fifo, val) \ ({ \ typeof((fifo) + 1) __tmp = (fifo); \ - typeof((val) + 1) __val = (val); \ + typeof(*__tmp->const_type) __val = (val); \ unsigned int __ret; \ - const size_t __recsize = sizeof(*__tmp->rectype); \ + size_t __recsize = sizeof(*__tmp->rectype); \ struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) { \ - typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ - __dummy = (typeof(__val))NULL; \ - } \ if (__recsize) \ - __ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \ + __ret = __kfifo_in_r(__kfifo, &__val, sizeof(__val), \ __recsize); \ else { \ __ret = !kfifo_is_full(__tmp); \ @@ -404,7 +401,7 @@ __kfifo_int_must_check_helper( \ ((typeof(__tmp->type))__kfifo->data) : \ (__tmp->buf) \ )[__kfifo->in & __tmp->kfifo.mask] = \ - *(typeof(__tmp->type))__val; \ + (typeof(*__tmp->type))__val; \ smp_wmb(); \ __kfifo->in++; \ } \ @@ -415,7 +412,7 @@ __kfifo_int_must_check_helper( \ /** * kfifo_get - get data from the fifo * @fifo: address of the fifo to be used - * @val: the var where to store the data to be added + * @val: address where to store the data * * This macro reads the data from the fifo. * It returns 0 if the fifo was empty. Otherwise it returns the number @@ -428,12 +425,10 @@ __kfifo_int_must_check_helper( \ __kfifo_uint_must_check_helper( \ ({ \ typeof((fifo) + 1) __tmp = (fifo); \ - typeof((val) + 1) __val = (val); \ + typeof(__tmp->ptr) __val = (val); \ unsigned int __ret; \ const size_t __recsize = sizeof(*__tmp->rectype); \ struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) \ - __val = (typeof(__tmp->ptr))0; \ if (__recsize) \ __ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \ __recsize); \ @@ -456,7 +451,7 @@ __kfifo_uint_must_check_helper( \ /** * kfifo_peek - get data from the fifo without removing * @fifo: address of the fifo to be used - * @val: the var where to store the data to be added + * @val: address where to store the data * * This reads the data from the fifo without removing it from the fifo. * It returns 0 if the fifo was empty. Otherwise it returns the number @@ -469,12 +464,10 @@ __kfifo_uint_must_check_helper( \ __kfifo_uint_must_check_helper( \ ({ \ typeof((fifo) + 1) __tmp = (fifo); \ - typeof((val) + 1) __val = (val); \ + typeof(__tmp->ptr) __val = (val); \ unsigned int __ret; \ const size_t __recsize = sizeof(*__tmp->rectype); \ struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) \ - __val = (typeof(__tmp->ptr))NULL; \ if (__recsize) \ __ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \ __recsize); \ @@ -508,14 +501,10 @@ __kfifo_uint_must_check_helper( \ #define kfifo_in(fifo, buf, n) \ ({ \ typeof((fifo) + 1) __tmp = (fifo); \ - typeof((buf) + 1) __buf = (buf); \ + typeof(__tmp->ptr_const) __buf = (buf); \ unsigned long __n = (n); \ const size_t __recsize = sizeof(*__tmp->rectype); \ struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) { \ - typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ - __dummy = (typeof(__buf))NULL; \ - } \ (__recsize) ?\ __kfifo_in_r(__kfifo, __buf, __n, __recsize) : \ __kfifo_in(__kfifo, __buf, __n); \ @@ -561,14 +550,10 @@ __kfifo_uint_must_check_helper( \ __kfifo_uint_must_check_helper( \ ({ \ typeof((fifo) + 1) __tmp = (fifo); \ - typeof((buf) + 1) __buf = (buf); \ + typeof(__tmp->ptr) __buf = (buf); \ unsigned long __n = (n); \ const size_t __recsize = sizeof(*__tmp->rectype); \ struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) { \ - typeof(__tmp->ptr) __dummy = NULL; \ - __buf = __dummy; \ - } \ (__recsize) ?\ __kfifo_out_r(__kfifo, __buf, __n, __recsize) : \ __kfifo_out(__kfifo, __buf, __n); \ @@ -773,14 +758,10 @@ __kfifo_uint_must_check_helper( \ __kfifo_uint_must_check_helper( \ ({ \ typeof((fifo) + 1) __tmp = (fifo); \ - typeof((buf) + 1) __buf = (buf); \ + typeof(__tmp->ptr) __buf = (buf); \ unsigned long __n = (n); \ const size_t __recsize = sizeof(*__tmp->rectype); \ struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) { \ - typeof(__tmp->ptr) __dummy __attribute__ ((unused)) = NULL; \ - __buf = __dummy; \ - } \ (__recsize) ? \ __kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \ __kfifo_out_peek(__kfifo, __buf, __n); \ diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index e47c7e2..b26594b 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -840,13 +840,6 @@ static inline int memslot_id(struct kvm *kvm, gfn_t gfn) return gfn_to_memslot(kvm, gfn)->id; } -static inline gfn_t gfn_to_index(gfn_t gfn, gfn_t base_gfn, int level) -{ - /* KVM_HPAGE_GFN_SHIFT(PT_PAGE_TABLE_LEVEL) must be 0. */ - return (gfn >> KVM_HPAGE_GFN_SHIFT(level)) - - (base_gfn >> KVM_HPAGE_GFN_SHIFT(level)); -} - static inline gfn_t hva_to_gfn_memslot(unsigned long hva, struct kvm_memory_slot *slot) { diff --git a/include/linux/libata.h b/include/linux/libata.h index e13b3ae..47938b0 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -204,11 +204,14 @@ enum { ATA_LFLAG_SW_ACTIVITY = (1 << 7), /* keep activity stats */ ATA_LFLAG_NO_LPM = (1 << 8), /* disable LPM on this link */ ATA_LFLAG_RST_ONCE = (1 << 9), /* limit recovery to one reset */ + ATA_LFLAG_DELAY = (1 << 10), /* delay some time */ /* struct ata_port flags */ ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */ /* (doesn't imply presence) */ ATA_FLAG_SATA = (1 << 1), + ATA_FLAG_BROKENAA = (1 << 2), /* host not support DMA AA + enabled by default */ ATA_FLAG_NO_ATAPI = (1 << 6), /* No ATAPI support */ ATA_FLAG_PIO_DMA = (1 << 7), /* PIO cmds via DMA */ ATA_FLAG_PIO_LBA48 = (1 << 8), /* Host DMA engine is LBA28 only */ diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 3b0c33a..f6e07a0 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -281,6 +281,7 @@ struct mmc_host { MMC_CAP2_PACKED_WR) #define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */ #define MMC_CAP2_SANITIZE (1 << 15) /* Support Sanitize */ +#define MMC_CAP2_NO_TRIM (1 << 16) /* Don't Support trim */ mmc_pm_flag_t pm_caps; /* supported pm features */ @@ -397,7 +398,8 @@ static inline void mmc_signal_sdio_irq(struct mmc_host *host) { host->ops->enable_sdio_irq(host, 0); host->sdio_irq_pending = true; - wake_up_process(host->sdio_irq_thread); + if (host->sdio_irq_thread) + wake_up_process(host->sdio_irq_thread); } #ifdef CONFIG_REGULATOR diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index 3e781b8..91bb4c9 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -98,6 +98,18 @@ struct sdhci_host { #define SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON (1<<4) /* Controller has a non-standard host control register */ #define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5) +/* Controller can't perform reset all successfully */ +#define SDHCI_QUIRK2_BROKEN_RESET_ALL (1U<<31) +/* Controller need long time to generate command complete interrupt */ +#define SDHCI_QUIRK2_LONG_TIME_CMD_COMPLETE_IRQ (1<<30) +/* Controller can only supports 1.8V, but the peripheral hardware + * circuit has capability to support 3.3V + */ +#define SDHCI_QUIRK2_CIRCUIT_SUPPORT_VS33 (1<<29) +#define SDHCI_QUIRK2_FORCE_CMD13_DETECT_CARD (1<<28) +/* Controller need to disable clock before reset all */ +#define SDHCI_QUIRK2_DISABLE_CLOCK_BEFORE_RESET (1<<27) +#define SDHCI_QUIRK2_BROKEN_TRIM (1<<28) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 45e9214..3e15a8b 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -422,6 +422,17 @@ struct i2c_device_id { kernel_ulong_t driver_data; /* Data private to the driver */ }; +/* tdm */ + +#define TDM_NAME_SIZE 20 +#define TDM_MODULE_PREFIX "tdm:" + +struct tdm_device_id { + char name[TDM_NAME_SIZE]; + kernel_ulong_t driver_data /* Data private to the driver */ + __attribute__((aligned(sizeof(kernel_ulong_t)))); +}; + /* spi */ #define SPI_NAME_SIZE 32 diff --git a/include/linux/msi.h b/include/linux/msi.h index b17ead8..e55d4cb 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -50,6 +50,12 @@ struct msi_desc { struct kobject kobj; }; +struct msi_region { + int region_num; + dma_addr_t addr; + size_t size; +}; + /* * The arch hooks to setup up msi irqs. Those functions are * implemented as weak symbols so that they /can/ be overriden by @@ -60,6 +66,8 @@ void arch_teardown_msi_irq(unsigned int irq); int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); void arch_teardown_msi_irqs(struct pci_dev *dev); int arch_msi_check_device(struct pci_dev* dev, int nvec, int type); +int arch_msi_get_region_count(void); +int arch_msi_get_region(int region_num, struct msi_region *region); void arch_restore_msi_irqs(struct pci_dev *dev, int irq); void default_teardown_msi_irqs(struct pci_dev *dev); diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h new file mode 100644 index 0000000..bde191c --- /dev/null +++ b/include/linux/mtd/spi-nor.h @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __LINUX_MTD_SPI_NOR_H +#define __LINUX_MTD_SPI_NOR_H + +/* + * Note on opcode nomenclature: some opcodes have a format like + * SPINOR_OP_FUNCTION{4,}_x_y_z{_D}. The numbers x, y,and z stand for the number + * of I/O lines used for the opcode, address, and data (respectively). The + * FUNCTION has an optional suffix of '4', to represent an opcode which + * requires a 4-byte (32-bit) address. The suffix of 'D' stands for the + * DDR mode. + */ + +/* Flash opcodes. */ +#define SPINOR_OP_WREN 0x06 /* Write enable */ +#define SPINOR_OP_RDSR 0x05 /* Read status register */ +#define SPINOR_OP_WRSR 0x01 /* Write status register 1 byte */ +#define SPINOR_OP_READ 0x03 /* Read data bytes (low frequency) */ +#define SPINOR_OP_READ_FAST 0x0b /* Read data bytes (high frequency) */ +#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual SPI) */ +#define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad SPI) */ +#define SPINOR_OP_READ_1_1_4_D 0x6d /* Read data bytes (DDR Quad SPI) */ +#define SPINOR_OP_READ_1_4_4_D 0xed /* Read data bytes (DDR Quad SPI) */ +#define SPINOR_OP_PP 0x02 /* Page program (up to 256 bytes) */ +#define SPINOR_OP_BE_4K 0x20 /* Erase 4KiB block */ +#define SPINOR_OP_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */ +#define SPINOR_OP_BE_32K 0x52 /* Erase 32KiB block */ +#define SPINOR_OP_CHIP_ERASE 0xc7 /* Erase whole flash chip */ +#define SPINOR_OP_SE 0xd8 /* Sector erase (usually 64KiB) */ +#define SPINOR_OP_RDID 0x9f /* Read JEDEC ID */ +#define SPINOR_OP_RDCR 0x35 /* Read configuration register */ +#define SPINOR_OP_RDFSR 0x70 /* Read flag status register */ + +/* 4-byte address opcodes - used on Spansion and some Macronix flashes. */ +#define SPINOR_OP_READ4 0x13 /* Read data bytes (low frequency) */ +#define SPINOR_OP_READ4_FAST 0x0c /* Read data bytes (high frequency) */ +#define SPINOR_OP_READ4_1_1_2 0x3c /* Read data bytes (Dual SPI) */ +#define SPINOR_OP_READ4_1_1_4 0x6c /* Read data bytes (Quad SPI) */ +#define SPINOR_OP_READ4_1_4_4_D 0xee /* Read data bytes (DDR Quad SPI) */ +#define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */ +#define SPINOR_OP_SE_4B 0xdc /* Sector erase (usually 64KiB) */ + +/* Used for SST flashes only. */ +#define SPINOR_OP_BP 0x02 /* Byte program */ +#define SPINOR_OP_WRDI 0x04 /* Write disable */ +#define SPINOR_OP_AAI_WP 0xad /* Auto address increment word program */ + +/* Used for Macronix and Winbond flashes. */ +#define SPINOR_OP_EN4B 0xb7 /* Enter 4-byte mode */ +#define SPINOR_OP_EX4B 0xe9 /* Exit 4-byte mode */ + +/* Used for Spansion flashes only. */ +#define SPINOR_OP_BRWR 0x17 /* Bank register write */ + +/* Status Register bits. */ +#define SR_WIP 1 /* Write in progress */ +#define SR_WEL 2 /* Write enable latch */ +/* meaning of other SR_* bits may differ between vendors */ +#define SR_BP0 4 /* Block protect 0 */ +#define SR_BP1 8 /* Block protect 1 */ +#define SR_BP2 0x10 /* Block protect 2 */ +#define SR_SRWD 0x80 /* SR write protect */ + +#define SR_QUAD_EN_MX 0x40 /* Macronix Quad I/O */ + +/* Flag Status Register bits */ +#define FSR_READY 0x80 + +/* Configuration Register bits. */ +#define CR_QUAD_EN_SPAN 0x2 /* Spansion Quad I/O */ + +enum read_mode { + SPI_NOR_NORMAL = 0, + SPI_NOR_FAST, + SPI_NOR_DUAL, + SPI_NOR_QUAD, + SPI_NOR_DDR_QUAD, +}; + +/** + * struct spi_nor_xfer_cfg - Structure for defining a Serial Flash transfer + * @wren: command for "Write Enable", or 0x00 for not required + * @cmd: command for operation + * @cmd_pins: number of pins to send @cmd (1, 2, 4) + * @addr: address for operation + * @addr_pins: number of pins to send @addr (1, 2, 4) + * @addr_width: number of address bytes + * (3,4, or 0 for address not required) + * @mode: mode data + * @mode_pins: number of pins to send @mode (1, 2, 4) + * @mode_cycles: number of mode cycles (0 for mode not required) + * @dummy_cycles: number of dummy cycles (0 for dummy not required) + */ +struct spi_nor_xfer_cfg { + u8 wren; + u8 cmd; + u8 cmd_pins; + u32 addr; + u8 addr_pins; + u8 addr_width; + u8 mode; + u8 mode_pins; + u8 mode_cycles; + u8 dummy_cycles; +}; + +#define SPI_NOR_MAX_CMD_SIZE 8 +enum spi_nor_ops { + SPI_NOR_OPS_READ = 0, + SPI_NOR_OPS_WRITE, + SPI_NOR_OPS_ERASE, + SPI_NOR_OPS_LOCK, + SPI_NOR_OPS_UNLOCK, +}; + +/** + * struct spi_nor - Structure for defining a the SPI NOR layer + * @mtd: point to a mtd_info structure + * @lock: the lock for the read/write/erase/lock/unlock operations + * @dev: point to a spi device, or a spi nor controller device. + * @np: If exit, it points to a device_node which stands for the + * SPI NOR flash child node. + * @page_size: the page size of the SPI NOR + * @addr_width: number of address bytes + * @erase_opcode: the opcode for erasing a sector + * @read_opcode: the read opcode + * @read_dummy: the dummy needed by the read operation + * @program_opcode: the program opcode + * @flash_read: the mode of the read + * @sst_write_second: used by the SST write operation + * @cfg: used by the read_xfer/write_xfer + * @cmd_buf: used by the write_reg + * @prepare: [OPTIONAL] do some preparations for the + * read/write/erase/lock/unlock operations + * @unprepare: [OPTIONAL] do some post work after the + * read/write/erase/lock/unlock operations + * @read_xfer: [OPTIONAL] the read fundamental primitive + * @write_xfer: [OPTIONAL] the writefundamental primitive + * @read_reg: [DRIVER-SPECIFIC] read out the register + * @write_reg: [DRIVER-SPECIFIC] write data to the register + * @read_id: [REPLACEABLE] read out the ID data, and find + * the proper spi_device_id + * @wait_till_ready: [REPLACEABLE] wait till the NOR becomes ready + * @read: [DRIVER-SPECIFIC] read data from the SPI NOR + * @write: [DRIVER-SPECIFIC] write data to the SPI NOR + * @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR + * at the offset @offs + * @priv: the private data + */ +struct spi_nor { + struct mtd_info *mtd; + struct mutex lock; + struct device *dev; + struct device_node *np; + u32 page_size; + u8 addr_width; + u8 erase_opcode; + u8 read_opcode; + u8 read_dummy; + u8 program_opcode; + enum read_mode flash_read; + bool sst_write_second; + struct spi_nor_xfer_cfg cfg; + u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE]; + + int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops); + void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops); + int (*read_xfer)(struct spi_nor *nor, struct spi_nor_xfer_cfg *cfg, + u8 *buf, size_t len); + int (*write_xfer)(struct spi_nor *nor, struct spi_nor_xfer_cfg *cfg, + u8 *buf, size_t len); + int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len); + int (*write_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len, + int write_enable); + const struct spi_device_id *(*read_id)(struct spi_nor *nor); + int (*wait_till_ready)(struct spi_nor *nor); + + int (*read)(struct spi_nor *nor, loff_t from, + size_t len, size_t *retlen, u_char *read_buf); + void (*write)(struct spi_nor *nor, loff_t to, + size_t len, size_t *retlen, const u_char *write_buf); + int (*erase)(struct spi_nor *nor, loff_t offs); + + void *priv; +}; + +/** + * spi_nor_scan() - scan the SPI NOR + * @nor: the spi_nor structure + * @id: the spi_device_id provided by the driver + * @mode: the read mode supported by the driver + * + * The drivers can use this fuction to scan the SPI NOR. + * In the scanning, it will try to get all the necessary information to + * fill the mtd_info{} and the spi_nor{}. + * + * The board may assigns a spi_device_id with @id which be used to compared with + * the spi_device_id detected by the scanning. + * + * Return: 0 for success, others for failure. + */ +int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id, + enum read_mode mode); +extern const struct spi_device_id spi_nor_ids[]; + +/** + * spi_nor_match_id() - find the spi_device_id by the name + * @name: the name of the spi_device_id + * + * The drivers use this function to find the spi_device_id + * specified by the @name. + * + * Return: returns the right spi_device_id pointer on success, + * and returns NULL on failure. + */ +const struct spi_device_id *spi_nor_match_id(char *name); + +#endif diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h index a2a89a5..fa21ca9 100644 --- a/include/linux/netdev_features.h +++ b/include/linux/netdev_features.h @@ -61,6 +61,10 @@ enum { NETIF_F_HW_VLAN_STAG_RX_BIT, /* Receive VLAN STAG HW acceleration */ NETIF_F_HW_VLAN_STAG_FILTER_BIT,/* Receive filtering on VLAN STAGs */ + /* Freescale DPA support */ + NETIF_F_HW_QDISC_BIT, /* Supports hardware Qdisc */ + NETIF_F_HW_ACCEL_MQ_BIT, /* Hardware-accelerated multiqueue */ + /* * Add your fresh new feature above and remember to update * netdev_features_strings[] in net/core/ethtool.c and maybe @@ -112,6 +116,9 @@ enum { #define NETIF_F_HW_VLAN_STAG_FILTER __NETIF_F(HW_VLAN_STAG_FILTER) #define NETIF_F_HW_VLAN_STAG_RX __NETIF_F(HW_VLAN_STAG_RX) #define NETIF_F_HW_VLAN_STAG_TX __NETIF_F(HW_VLAN_STAG_TX) +/* Freescale DPA support */ +#define NETIF_F_HW_QDISC __NETIF_F(HW_QDISC) +#define NETIF_F_HW_ACCEL_MQ __NETIF_F(HW_ACCEL_MQ) /* Features valid for ethtool to change */ /* = all defined minus driver/device-class-related */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 3fab02f..30e0620 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1167,7 +1167,10 @@ struct net_device { /* Interface index. Unique device identifier */ int ifindex; int iflink; - +#ifdef CONFIG_AS_FASTPATH + /* Common interface id for ASF */ + int cii; +#endif struct net_device_stats stats; atomic_long_t rx_dropped; /* dropped packets by core network * Do not use this in drivers. @@ -1298,7 +1301,9 @@ struct net_device { /* root qdisc from userspace point of view */ struct Qdisc *qdisc; - +#ifdef CONFIG_ASF_EGRESS_QOS + void *asf_qdisc; +#endif unsigned long tx_queue_len; /* Max frames per queue allowed */ spinlock_t tx_global_lock; diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 708fe72ab9..dceeb75 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -336,4 +336,33 @@ extern struct nfq_ct_hook __rcu *nfq_ct_hook; static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {} #endif +#ifdef CONFIG_ASF_INGRESS_MARKER +#define MAX_MARKER_RULES 20 + +typedef struct { + uint32_t src_ip[4]; + uint32_t dst_ip[4]; + uint16_t src_port; + uint16_t dst_port; + uint8_t proto; + uint8_t uciDscp; +} markerRule_t; + +typedef struct { + markerRule_t *rule; + uint32_t num_rules; +} marker_db_t; + +typedef int marker_add_hook(marker_db_t *arg); +typedef void marker_flush_hook(void); + +extern marker_add_hook *marker_add_fn; +extern marker_flush_hook *marker_flush_fn; + +void marker_v4_hook_fn_register(marker_add_hook *add, + marker_flush_hook *flush); +void marker_v6_hook_fn_register(marker_add_hook *add, + marker_flush_hook *flush); +#endif + #endif /*__LINUX_NETFILTER_H*/ diff --git a/include/linux/netfilter/nf_conntrack_tcp.h b/include/linux/netfilter/nf_conntrack_tcp.h index 22db961..781a68d 100644 --- a/include/linux/netfilter/nf_conntrack_tcp.h +++ b/include/linux/netfilter/nf_conntrack_tcp.h @@ -11,6 +11,12 @@ struct ip_ct_tcp_state { u_int32_t td_maxack; /* max of ack */ u_int8_t td_scale; /* window scale factor */ u_int8_t flags; /* per direction options */ +#ifdef CONFIG_AS_FASTPATH + u_int32_t td_tcptimestamp;/* Time Stamp */ + int32_t td_delta; /* for Packet mangling */ + /* Last window advertisement seen in dir */ + u_int32_t td_rcvwin; +#endif }; struct ip_ct_tcp { diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h index 901e84d..951dd00 100644 --- a/include/linux/netfilter_ipv4/ip_tables.h +++ b/include/linux/netfilter_ipv4/ip_tables.h @@ -69,6 +69,14 @@ extern unsigned int ipt_do_table(struct sk_buff *skb, const struct net_device *out, struct xt_table *table); +#ifdef CONFIG_AS_FASTPATH +struct firewall_asfctrl { + void (*firewall_asfctrl_cb)(void); +}; + +extern void hook_firewall_asfctrl_cb(const struct firewall_asfctrl *); +#endif + #ifdef CONFIG_COMPAT #include <net/compat.h> diff --git a/include/linux/of.h b/include/linux/of.h index 9007c86..da95cf0 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -67,7 +67,7 @@ struct device_node { #endif }; -#define MAX_PHANDLE_ARGS 8 +#define MAX_PHANDLE_ARGS 16 struct of_phandle_args { struct device_node *np; int args_count; @@ -226,6 +226,17 @@ static inline int of_get_child_count(const struct device_node *np) return num; } +static inline int of_get_available_child_count(const struct device_node *np) +{ + struct device_node *child; + int num = 0; + + for_each_available_child_of_node(np, child) + num++; + + return num; +} + extern struct device_node *of_find_node_with_property( struct device_node *from, const char *prop_name); #define for_each_node_with_property(dn, prop_name) \ @@ -374,6 +385,11 @@ static inline int of_get_child_count(const struct device_node *np) return 0; } +static inline int of_get_available_child_count(const struct device_node *np) +{ + return 0; +} + static inline int of_device_is_compatible(const struct device_node *device, const char *name) { diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h index fcd63ba..9984a3e 100644 --- a/include/linux/of_irq.h +++ b/include/linux/of_irq.h @@ -47,7 +47,10 @@ static inline int of_irq_map_oldworld(struct device_node *device, int index, } #endif /* CONFIG_PPC32 && CONFIG_PPC_PMAC */ - +extern int of_irq_parse_raw(const __be32 *addr, + struct of_phandle_args *out_irq); +extern int of_irq_parse_one(struct device_node *device, int index, + struct of_phandle_args *out_irq); extern int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, u32 ointsize, const __be32 *addr, struct of_irq *out_irq); @@ -56,6 +59,7 @@ extern int of_irq_map_one(struct device_node *device, int index, extern unsigned int irq_create_of_mapping(struct device_node *controller, const u32 *intspec, unsigned int intsize); +extern unsigned int irq_create_of_mapping_new(struct of_phandle_args *irq_data); extern int of_irq_to_resource(struct device_node *dev, int index, struct resource *r); extern int of_irq_count(struct device_node *dev); diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h index 8163107..59f30ba 100644 --- a/include/linux/of_mdio.h +++ b/include/linux/of_mdio.h @@ -19,6 +19,10 @@ extern struct phy_device *of_phy_connect(struct net_device *dev, struct device_node *phy_np, void (*hndlr)(struct net_device *), u32 flags, phy_interface_t iface); +extern struct phy_device *of_phy_attach(struct net_device *dev, + struct device_node *phy_np, + u32 flags, + phy_interface_t iface); extern struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, void (*hndlr)(struct net_device *), phy_interface_t iface); @@ -44,6 +48,14 @@ static inline struct phy_device *of_phy_connect(struct net_device *dev, return NULL; } +static inline struct phy_device *of_phy_attach(struct net_device *dev, + struct device_node *phy_np, + u32 flags, + phy_interface_t iface) +{ + return NULL; +} + static inline struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, void (*hndlr)(struct net_device *), phy_interface_t iface) diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h index fd9c408..790db04 100644 --- a/include/linux/of_pci.h +++ b/include/linux/of_pci.h @@ -5,14 +5,50 @@ #include <linux/msi.h> struct pci_dev; +struct of_phandle_args; struct of_irq; int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq); struct device_node; + +#ifdef CONFIG_OF +int of_irq_parse_pci(const struct pci_dev *pdev, + struct of_phandle_args *out_irq); struct device_node *of_pci_find_child_device(struct device_node *parent, unsigned int devfn); int of_pci_get_devfn(struct device_node *np); +int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin); int of_pci_parse_bus_range(struct device_node *node, struct resource *res); +#else +static inline int of_irq_parse_pci(const struct pci_dev *pdev, + struct of_phandle_args *out_irq) +{ + return 0; +} + +static inline struct device_node * +of_pci_find_child_device(struct device_node *parent, unsigned int devfn) +{ + return NULL; +} + +static inline int of_pci_get_devfn(struct device_node *np) +{ + return -EINVAL; +} + +static inline int +of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin) +{ + return 0; +} + +static inline int +of_pci_parse_bus_range(struct device_node *node, struct resource *res) +{ + return -EINVAL; +} +#endif #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI) int of_pci_msi_chip_add(struct msi_chip *chip); diff --git a/include/linux/pci.h b/include/linux/pci.h index 573c049..825d604 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1152,6 +1152,7 @@ struct msix_entry { u16 entry; /* driver uses to specify entry, OS writes */ }; +struct msi_region; #ifndef CONFIG_PCI_MSI static inline int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec) @@ -1194,6 +1195,16 @@ static inline int pci_msi_enabled(void) { return 0; } + +static inline int msi_get_region_count(void) +{ + return 0; +} + +static inline int msi_get_region(int region_num, struct msi_region *region) +{ + return 0; +} #else int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec); @@ -1206,6 +1217,8 @@ void pci_disable_msix(struct pci_dev *dev); void msi_remove_pci_irq_vectors(struct pci_dev *dev); void pci_restore_msi_state(struct pci_dev *dev); int pci_msi_enabled(void); +int msi_get_region_count(void); +int msi_get_region(int region_num, struct msi_region *region); #endif #ifdef CONFIG_PCIEPORTBUS diff --git a/include/linux/phy.h b/include/linux/phy.h index 64ab823..a17366b 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -66,6 +66,7 @@ typedef enum { PHY_INTERFACE_MODE_RGMII_TXID, PHY_INTERFACE_MODE_RTBI, PHY_INTERFACE_MODE_SMII, + PHY_INTERFACE_MODE_XGMII, } phy_interface_t; @@ -498,6 +499,21 @@ static inline int phy_read(struct phy_device *phydev, u32 regnum) } /** + * phy_read_mmd - Convenience function for reading a register + * from an MMD on a given PHY. + * @phydev: The phy_device struct + * @devad: The MMD to read from + * @regnum: The register on the MMD to read + * + * Same rules as for phy_read(); + */ +static inline int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum) +{ + return mdiobus_read(phydev->bus, phydev->addr, + MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff)); +} + +/** * phy_write - Convenience function for writing a given PHY register * @phydev: the phy_device struct * @regnum: register number to write @@ -513,6 +529,24 @@ static inline int phy_write(struct phy_device *phydev, u32 regnum, u16 val) } /** + * phy_write_mmd - Convenience function for writing a register + * on an MMD on a given PHY. + * @phydev: The phy_device struct + * @devad: The MMD to read from + * @regnum: The register on the MMD to read + * @val: value to write to @regnum + * + * Same rules as for phy_write(); + */ +static inline int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, + u16 val) +{ + regnum = MII_ADDR_C45 | ((devad & 0x1f) << 16) | (regnum & 0xffff); + + return mdiobus_write(phydev->bus, phydev->addr, regnum, val); +} + +/** * phy_interrupt_is_valid - Convenience function for testing a given PHY irq * @phydev: the phy_device struct * @@ -541,6 +575,8 @@ int phy_init_hw(struct phy_device *phydev); struct phy_device * phy_attach(struct net_device *dev, const char *bus_id, phy_interface_t interface); struct phy_device *phy_find_first(struct mii_bus *bus); +int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, + u32 flags, phy_interface_t interface); int phy_connect_direct(struct net_device *dev, struct phy_device *phydev, void (*handler)(struct net_device *), phy_interface_t interface); @@ -559,6 +595,7 @@ static inline int phy_read_status(struct phy_device *phydev) { return phydev->drv->read_status(phydev); } +int genphy_setup_forced(struct phy_device *phydev); int genphy_restart_aneg(struct phy_device *phydev); int genphy_config_aneg(struct phy_device *phydev); int genphy_update_link(struct phy_device *phydev); diff --git a/include/linux/platform_data/video-twrfb.h b/include/linux/platform_data/video-twrfb.h new file mode 100644 index 0000000..10bdf07 --- /dev/null +++ b/include/linux/platform_data/video-twrfb.h @@ -0,0 +1,22 @@ +/* + * Copyright 2013 Freescale Semiconductor, Inc. All Rights Reserved. + * + * Freescale TFT LCD Platform data for SSD1289 framebuffer driver + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* LCD description */ +struct fsl_ssd1289_fb_display { + /* Screen size */ + unsigned short width; + unsigned short height; + + /* Screen info */ + unsigned short xres; + unsigned short yres; + unsigned short bpp; +}; diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index cb79fd4..e13de0b 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -418,8 +418,11 @@ struct sk_buff { * want to keep them across layers you have to do a skb_clone() * first. This is owned by whoever has the skb queued ATM. */ +#ifdef CONFIG_AS_FASTPATH + char cb[96] __aligned(8); +#else char cb[48] __aligned(8); - +#endif unsigned long _skb_refdst; #ifdef CONFIG_XFRM struct sec_path *sp; @@ -511,6 +514,10 @@ struct sk_buff { __be16 inner_protocol; __u16 inner_transport_header; __u16 inner_network_header; +#if defined(CONFIG_GIANFAR) && defined(CONFIG_AS_FASTPATH) + __u8 owner; + struct sk_buff *new_skb; +#endif __u16 inner_mac_header; __u16 transport_header; __u16 network_header; @@ -658,29 +665,24 @@ static inline struct sk_buff *alloc_skb_head(gfp_t priority) return __alloc_skb_head(priority, -1); } -extern struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src); -extern int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask); -extern struct sk_buff *skb_clone(struct sk_buff *skb, - gfp_t priority); -extern struct sk_buff *skb_copy(const struct sk_buff *skb, - gfp_t priority); -extern struct sk_buff *__pskb_copy(struct sk_buff *skb, - int headroom, gfp_t gfp_mask); - -extern int pskb_expand_head(struct sk_buff *skb, - int nhead, int ntail, - gfp_t gfp_mask); -extern struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, - unsigned int headroom); -extern struct sk_buff *skb_copy_expand(const struct sk_buff *skb, - int newheadroom, int newtailroom, - gfp_t priority); -extern int skb_to_sgvec(struct sk_buff *skb, - struct scatterlist *sg, int offset, - int len); -extern int skb_cow_data(struct sk_buff *skb, int tailbits, - struct sk_buff **trailer); -extern int skb_pad(struct sk_buff *skb, int pad); +void skb_recycle(struct sk_buff *skb); +bool skb_recycle_check(struct sk_buff *skb, int skb_size); + +struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src); +int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask); +struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t priority); +struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t priority); +struct sk_buff *__pskb_copy(struct sk_buff *skb, int headroom, gfp_t gfp_mask); + +int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, gfp_t gfp_mask); +struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, + unsigned int headroom); +struct sk_buff *skb_copy_expand(const struct sk_buff *skb, int newheadroom, + int newtailroom, gfp_t priority); +int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, + int len); +int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer); +int skb_pad(struct sk_buff *skb, int pad); #define dev_kfree_skb(a) consume_skb(a) extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, @@ -2811,6 +2813,27 @@ static inline void skb_checksum_none_assert(const struct sk_buff *skb) bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off); +static inline bool skb_is_recycleable(const struct sk_buff *skb, int skb_size) +{ + if (irqs_disabled()) + return false; + + if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) + return false; + + if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE) + return false; + + skb_size = SKB_DATA_ALIGN(skb_size + NET_SKB_PAD); + if (skb_end_offset(skb) < skb_size) + return false; + + if (skb_shared(skb) || skb_cloned(skb)) + return false; + + return true; +} + u32 __skb_get_poff(const struct sk_buff *skb); /** diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 887116d..bc7942b 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -611,6 +611,9 @@ struct spi_message { unsigned actual_length; int status; + /* deliver the address width of spi device to spi controller */ + u8 addr_width; + /* for optional use by whatever driver currently owns the * spi_message ... between calls to spi_async and then later * complete(), that's the spi_master controller driver. diff --git a/include/linux/tdm.h b/include/linux/tdm.h new file mode 100644 index 0000000..93ec1c0 --- /dev/null +++ b/include/linux/tdm.h @@ -0,0 +1,355 @@ +/* include/linux/tdm.h + * + * Copyright 2012 Freescale Semiconductor, Inc. + * + * tdm.h - definitions for the tdm-device framework interface + * + * Author:Hemant Agrawal <hemant@freescale.com> + * Rajesh Gumasta <rajesh.gumasta@freescale.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef _LINUX_TDM_H +#define _LINUX_TDM_H + +#ifdef __KERNEL__ +#include <linux/types.h> +#include <linux/module.h> +#include <linux/mod_devicetable.h> +#include <linux/device.h> /* for struct device */ +#include <linux/sched.h> /* for completion */ +#include <linux/mutex.h> +#include <linux/interrupt.h> + +#define CHANNEL_8BIT_LIN 0 /* 8 bit linear */ +#define CHANNEL_8BIT_ULAW 1 /* 8 bit Mu-law */ +#define CHANNEL_8BIT_ALAW 2 /* 8 bit A-law */ +#define CHANNEL_16BIT_LIN 3 /* 16 bit Linear */ + +#define NUM_CHANNELS 16 +#define NUM_SAMPLES_PER_MS 8 /* 8 samples per milli sec per + channel. Req for voice data */ +#define NUM_MS 10 +#define NUM_SAMPLES_PER_FRAME (NUM_MS * NUM_SAMPLES_PER_MS) /* Number of + samples for 1 client buffer */ +#define NUM_OF_TDM_BUF 3 + +/* General options */ + +struct tdm_adapt_algorithm; +struct tdm_adapter; +struct tdm_port; +struct tdm_driver; + +/* Align addr on a size boundary - adjust address up if needed */ +/* returns min value greater than size which is multiple of alignment */ +static inline int ALIGN_SIZE(u64 size, u32 alignment) +{ + return (size + alignment - 1) & (~(alignment - 1)); +} + +int tdm_master_send(struct tdm_adapter *adap, void **buf, int count); +int tdm_master_recv(struct tdm_adapter *adap, void **buf); +int tdm_read_direct(struct tdm_adapter *adap, u8 *buf, u32 len); +int tdm_write_direct(struct tdm_adapter *adap, u8 *buf, u32 len); + +/** + * struct tdm_driver - represent an TDM device driver + * @class: What kind of tdm device we instantiate (for detect) + * @id:Driver id + * @name: Name of the driver + * @attach_adapter: Callback for device addition (for legacy drivers) + * @detach_adapter: Callback for device removal (for legacy drivers) + * @probe: Callback for device binding + * @remove: Callback for device unbinding + * @shutdown: Callback for device shutdown + * @suspend: Callback for device suspend + * @resume: Callback for device resume + * @command: Callback for sending commands to device + * @id_table: List of TDM devices supported by this driver + * @list: List of drivers created (for tdm-core use only) + */ +struct tdm_driver { + unsigned int class; + unsigned int id; + char name[TDM_NAME_SIZE]; + + int (*attach_adapter)(struct tdm_adapter *); + int (*detach_adapter)(struct tdm_adapter *); + + /* Standard driver model interfaces */ + int (*probe)(const struct tdm_device_id *); + int (*remove)(void); + + /* driver model interfaces that don't relate to enumeration */ + void (*shutdown)(void); + int (*suspend)(pm_message_t mesg); + int (*resume)(void); + + /* a ioctl like command that can be used to perform specific functions + * with the device. + */ + int (*command)(unsigned int cmd, void *arg); + + const struct tdm_device_id *id_table; + + /* The associated adapter for this driver */ + struct tdm_adapter *adapter; + struct list_head list; +}; + +/* tdm per port statistics structure, used for providing and storing tdm port + * statistics. + */ +struct tdm_port_stats { + unsigned int rx_pkt_count; /* Rx frame count per channel */ + unsigned int rx_pkt_drop_count; /* Rx drop count per channel to + clean space for new buffer */ + unsigned int tx_pkt_count; /* Tx frame count per channel */ + unsigned int tx_pkt_conf_count; /* Tx frame confirmation count per + channel */ + unsigned int tx_pkt_drop_count; /* Tx drop count per channel due to + queue full */ +}; + + +/* tdm Buffer Descriptor, used for Creating Interleaved and De-interleaved + * FIFOs + */ +struct tdm_bd { + unsigned char flag; /* BD is full or empty */ + unsigned char wrap; /* BD is last in the queue */ + unsigned short length; /* Length of Data in BD */ + /*TODO: use dyanmic memory */ + unsigned short p_data[NUM_SAMPLES_PER_FRAME]; /* Data Pointer */ + unsigned long offset; /* Offset of the Data Pointer to be used */ +}; + +#define TDM_CH_RX_BD_RING_SIZE 3 +#define TDM_CH_TX_BD_RING_SIZE 3 + +/* tdm RX-TX Channelised Data */ +struct tdm_port_data { + struct tdm_bd rx_data_fifo[TDM_CH_RX_BD_RING_SIZE]; /* Rx Channel Data + BD Ring */ + struct tdm_bd *rx_in_data; /* Current Channel Rx BD to be filled by + de-interleave function */ + struct tdm_bd *rx_out_data; /* Current Channel Rx BD to be + read by App */ + struct tdm_bd tx_data_fifo[TDM_CH_TX_BD_RING_SIZE]; /* Tx Channel Data + BD Ring */ + struct tdm_bd *tx_in_data; /* Current Channel Tx BD to be + filled by App */ + struct tdm_bd *tx_out_data; /* Current Channel Tx BD to be read by + interleave function */ + spinlock_t rx_channel_lock; /* Spin Lock for Rx Channel */ + spinlock_t tx_channel_lock; /* Spin Lock for Tx Channel */ +}; + +/* structure tdm_port_cfg - contains configuration params for a port */ +struct tdm_port_cfg { + unsigned short port_mode; +}; + +/* struct tdm_port - represent an TDM ports for a device */ +struct tdm_port { + unsigned short port_id; + unsigned short in_use; /* Port is enabled? */ + uint16_t rx_max_frames; /* Received Port frames + before allowing Read Operation in + Port Mode */ + + struct tdm_port_stats port_stat;/* A structure parameters defining + TDM port statistics. */ + struct tdm_port_data *p_port_data; /* a structure parameters + defining tdm channelised data */ + + struct tdm_driver *driver; /* driver for this port */ + struct tdm_adapter *adapter; /* adapter for this port */ + struct list_head list; /* list of ports */ + struct list_head mychannels; /* list of channels, created on this + port*/ + spinlock_t ch_list_lock; /* Spin Lock for channel_list */ + struct tdm_port_cfg port_cfg;/* A structure parameters defining + TDM port configuration. */ +}; + +/* tdm RX-TX Channelised Data */ +struct tdm_ch_data { + struct tdm_bd rx_data_fifo[TDM_CH_RX_BD_RING_SIZE]; /* Rx Port Data BD + Ring */ + struct tdm_bd *rx_in_data; /* Current Port Rx BD to be filled by + de-interleave function */ + struct tdm_bd *rx_out_data; /* Current Port Rx BD to be read by App */ + struct tdm_bd tx_data_fifo[TDM_CH_TX_BD_RING_SIZE]; /* Tx Port Data BD + Ring */ + struct tdm_bd *tx_in_data; /* Current Port Tx BD to be filled by + App */ + struct tdm_bd *tx_out_data; /* Current Port Tx BD to be read by + interleave function */ + spinlock_t rx_channel_lock; /* Spin Lock for Rx Port */ + spinlock_t tx_channel_lock; /* Spin Lock for Tx Port */ +}; + +/* Channel config params */ +struct tdm_ch_cfg { + unsigned short num_slots; + unsigned short first_slot; +}; + +/* struct tdm_channel- represent a TDM channel for a port */ +struct tdm_channel { + u16 ch_id; /* logical channel number */ + struct list_head list; /* list of channels in a port*/ + struct tdm_port *port; /* port for this channel */ + u16 in_use; /* channel is enabled? */ + struct tdm_ch_cfg ch_cfg; /* channel configuration */ + struct tdm_ch_data *p_ch_data; /* data storage space for channel */ + wait_queue_head_t ch_wait_queue;/* waitQueue for RX Channel Data */ +}; + +/* tdm_adapt_algorithm is for accessing the routines of device */ +struct tdm_adapt_algorithm { + u32 (*tdm_read)(struct tdm_adapter *, u16 **); + u32 (*tdm_get_write_buf)(struct tdm_adapter *, u16 **); + int (*tdm_read_simple)(struct tdm_adapter *, u8 *, u32 len); + int (*tdm_write_simple)(struct tdm_adapter *, u8 *, u32 len); + u32 (*tdm_write)(struct tdm_adapter *, void * , unsigned int len); + int (*tdm_enable)(struct tdm_adapter *); + int (*tdm_disable)(struct tdm_adapter *); +}; + +/* tdm_adapter_mode is to define in mode of the device */ +enum tdm_adapter_mode { + e_TDM_ADAPTER_MODE_NONE = 0x00, + e_TDM_ADAPTER_MODE_T1 = 0x01, + e_TDM_ADAPTER_MODE_E1 = 0x02, + e_TDM_ADAPTER_MODE_T1_RAW = 0x10, + e_TDM_ADAPTER_MODE_E1_RAW = 0x20, +}; + +/* tdm_port_mode defines the mode in which the port is configured to operate + * It can be channelized/full/fractional. + */ +enum tdm_port_mode { + e_TDM_PORT_CHANNELIZED = 0 /* Channelized mode */ + , e_TDM_PORT_FULL = 1 /* Full mode */ + , e_TDM_PORT_FRACTIONAL = 2 /* Fractional mode */ +}; + +/* tdm_process_mode used for testing the tdm device in normal mode or internal + * loopback or external loopback + */ +enum tdm_process_mode { + e_TDM_PROCESS_NORMAL = 0 /* Normal mode */ + , e_TDM_PROCESS_INT_LPB = 1 /* Internal loop mode */ + , e_TDM_PROCESS_EXT_LPB = 2 /* External Loopback mode */ +}; + + +/* TDM configuration parameters */ +struct fsl_tdm_adapt_cfg { + u8 num_ch; /* Number of channels in this adpater */ + u8 ch_size_type; /* reciever/transmit channel + size for all channels */ + u8 slot_width; /* 1 or 2 Is defined by channel type */ + u8 frame_len; /* Length of frame in samples */ + u32 num_frames; + u8 loopback; /* loopback or normal */ + u8 adap_mode; /* 0=None, 1= T1, 2= T1-FULL, 3=E1, + 4 = E1-FULL */ + int max_num_ports; /* Not Used: Max Number of ports that + can be created on this adapter */ + int max_timeslots; /* Max Number of timeslots that are + supported on this adapter */ +}; + +/* + * tdm_adapter is the structure used to identify a physical tdm device along + * with the access algorithms necessary to access it. + */ +struct tdm_adapter { + struct module *owner; /* owner of the adapter module */ + unsigned int id; /* Adapter Id */ + unsigned int class; /* classes to allow probing for */ + unsigned int drv_count; /* Number of drivers associated with the + adapter */ + + const struct tdm_adapt_algorithm *algo; /* the algorithm to access the + adapter*/ + + char name[TDM_NAME_SIZE]; /* Name of Adapter */ + struct mutex adap_lock; + struct device *parent; /*Not Used*/ + + struct tasklet_struct tdm_data_tasklet; /* tasklet handle to perform + data processing*/ + int tasklet_conf; /* flag for tasklet configuration */ + int tdm_rx_flag; + + struct list_head myports; /* list of ports, created on this + adapter */ + struct list_head list; + spinlock_t portlist_lock; /* Spin Lock for port_list */ + void *data; + struct fsl_tdm_adapt_cfg adapt_cfg; +}; + +static inline void *tdm_get_adapdata(const struct tdm_adapter *dev) +{ + return dev->data; +} + +static inline void tdm_set_adapdata(struct tdm_adapter *dev, void *data) +{ + dev->data = data; +} + +/* functions exported by tdm.o */ + +extern int tdm_add_adapter(struct tdm_adapter *); +extern int tdm_del_adapter(struct tdm_adapter *); +extern int tdm_register_driver(struct tdm_driver *); +extern void tdm_del_driver(struct tdm_driver *); +extern void tdm_unregister_driver(struct tdm_driver *); +extern void init_config_adapter(struct tdm_adapter *); +extern int tdm_adap_enable(struct tdm_driver *drv); +extern int tdm_adap_disable(struct tdm_driver *drv); +extern unsigned int tdm_port_open(struct tdm_driver *, void **); +extern unsigned int tdm_port_close(void *); +extern unsigned int tdm_port_ioctl(void *, unsigned int, unsigned long); +extern unsigned int tdm_channel_read(void *, void *, void *, u16 *); +extern unsigned int tdm_channel_write(void *, void * , void *, u16); +extern unsigned int tdm_ch_poll(void *, unsigned int); + +extern int tdm_channel_open(u16, u16, struct tdm_port *, void **); +extern int tdm_channel_close(u16, u16, struct tdm_port *, + struct tdm_channel *); + +static inline int tdm_add_driver(struct tdm_driver *driver) +{ + return tdm_register_driver(driver); +} + +extern struct tdm_adapter *tdm_get_adapter(int id); +extern void tdm_put_adapter(struct tdm_adapter *adap); + +#endif /* __KERNEL__ */ + +#define TDM_E_OK 0 + +#endif /* _LINUX_TDM_H */ diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h index 1ad4724..66af0e9 100644 --- a/include/linux/uio_driver.h +++ b/include/linux/uio_driver.h @@ -80,6 +80,7 @@ struct uio_device; * @open: open operation for this uio device * @release: release operation for this uio device * @irqcontrol: disable/enable irqs when 0/1 is written to /dev/uioX + * @set_pgprot: allow driver to override default(noncached) pgprot */ struct uio_info { struct uio_device *uio_dev; @@ -95,6 +96,8 @@ struct uio_info { int (*open)(struct uio_info *info, struct inode *inode); int (*release)(struct uio_info *info, struct inode *inode); int (*irqcontrol)(struct uio_info *info, s32 irq_on); + pgprot_t (*set_pgprot)(struct uio_info *uio, unsigned int mem_idx, + pgprot_t prot); }; extern int __must_check diff --git a/include/linux/usb.h b/include/linux/usb.h index 39cfa0a..5aa5bb2 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -330,6 +330,7 @@ struct usb_bus { * for control transfers? */ u8 otg_port; /* 0, or number of OTG/HNP port */ + unsigned is_otg:1; /* true when host is also otg */ unsigned is_b_host:1; /* true during some HNP roleswitches */ unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */ unsigned no_stop_on_short:1; /* diff --git a/include/net/ip.h b/include/net/ip.h index 53573e0..7193c65 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -431,19 +431,20 @@ extern int ip_forward(struct sk_buff *skb); * Functions provided by ip_options.c */ -extern void ip_options_build(struct sk_buff *skb, struct ip_options *opt, - __be32 daddr, struct rtable *rt, int is_frag); -extern int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb); -extern void ip_options_fragment(struct sk_buff *skb); -extern int ip_options_compile(struct net *net, - struct ip_options *opt, struct sk_buff *skb); -extern int ip_options_get(struct net *net, struct ip_options_rcu **optp, - unsigned char *data, int optlen); -extern int ip_options_get_from_user(struct net *net, struct ip_options_rcu **optp, - unsigned char __user *data, int optlen); -extern void ip_options_undo(struct ip_options * opt); -extern void ip_forward_options(struct sk_buff *skb); -extern int ip_options_rcv_srr(struct sk_buff *skb); +void ip_options_build(struct sk_buff *skb, struct ip_options *opt, + __be32 daddr, struct rtable *rt, int is_frag); +int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb); +void ip_options_fragment(struct sk_buff *skb); +int ip_options_compile(struct net *net, struct ip_options *opt, + struct sk_buff *skb); +int ip_options_get(struct net *net, struct ip_options_rcu **optp, + unsigned char *data, int optlen); +int ip_options_get_from_user(struct net *net, struct ip_options_rcu **optp, + unsigned char __user *data, int optlen); +void ip_options_undo(struct ip_options *opt); +void ip_forward_options(struct sk_buff *skb); +int ip_rcv_options(struct sk_buff *skb); +int ip_options_rcv_srr(struct sk_buff *skb); /* * Functions provided by ip_sockglue.c diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index a210b33..3ba53d9 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -204,4 +204,9 @@ static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt) return &rt->rt6i_gateway; } +#ifdef CONFIG_AS_FASTPATH +typedef void ipv6_route_flush_hook(void); +void ipv6_route_hook_fn_register(ipv6_route_flush_hook *flush); +#endif + #endif diff --git a/include/net/route.h b/include/net/route.h index afdeeb5..eb678cc 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -306,6 +306,11 @@ static inline int inet_iif(const struct sk_buff *skb) return skb->skb_iif; } +#ifdef CONFIG_AS_FASTPATH +typedef void route_flush_hook(void); +void route_hook_fn_register(route_flush_hook *flush); +#endif + extern int sysctl_ip_default_ttl; static inline int ip4_dst_hoplimit(const struct dst_entry *dst) diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index f4eb365..6fabded 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -713,4 +713,63 @@ static inline void psched_ratecfg_getrate(struct tc_ratespec *res, res->linklayer = (r->linklayer & TC_LINKLAYER_MASK); } +#if defined(CONFIG_ASF_EGRESS_SCH) || defined(CONFIG_ASF_HW_SCH) +typedef int prio_add_hook( + struct net_device *dev, + uint32_t handle, + uint32_t parent, + uint32_t bands); +typedef int prio_flush_hook( + struct net_device *dev, + uint32_t handle, + uint32_t parent); + +void prio_hook_fn_register(prio_add_hook *add, + prio_flush_hook *flush); + +typedef int drr_add_hook( + struct net_device *dev, + uint32_t handle, + uint32_t parent, + uint32_t quantum); +typedef int drr_flush_hook( + struct net_device *dev, + uint32_t handle, + uint32_t parent); + +typedef void invalidate_flows(void); + +void drr_hook_fn_register(drr_add_hook *add, + drr_flush_hook *flush, + invalidate_flows *invalidate); +u32 drr_filter_lookup(struct sk_buff *skb, struct Qdisc *sch); +#endif + +#if defined(CONFIG_ASF_EGRESS_SHAPER) || defined(CONFIG_ASF_HW_SHAPER) +struct tbf_opt { + struct net_device *dev; + uint32_t handle; + uint32_t parent; + uint32_t rate; + uint32_t limit; + uint32_t buffer; + uint16_t mpu; +}; + +typedef int tbf_add_hook(struct tbf_opt *opt); +typedef int tbf_del_hook( + struct net_device *dev, + uint32_t handle, + uint32_t parent); + +void tbf_hook_fn_register(tbf_add_hook *add, + tbf_del_hook *del); +struct Qdisc *tbf_get_inner_qdisc(struct Qdisc *sch); +#endif + +#ifdef CONFIG_ASF_EGRESS_QOS +typedef int asf_qos_fn_hook(struct sk_buff *skb); +void asf_qos_fn_register(asf_qos_fn_hook *fn); +#endif + #endif diff --git a/include/net/xfrm.h b/include/net/xfrm.h index e253bf0..a3e5040 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -229,7 +229,10 @@ struct xfrm_state { /* Security context */ struct xfrm_sec_ctx *security; - +#ifdef CONFIG_AS_FASTPATH + uintptr_t asf_sa_cookie; + u32 asf_sa_direction; +#endif /* Private data of this transformer, format is opaque, * interpreted by xfrm_type methods. */ void *data; @@ -533,6 +536,9 @@ struct xfrm_policy { struct xfrm_lifetime_cur curlft; struct xfrm_policy_walk_entry walk; struct xfrm_policy_queue polq; +#ifdef CONFIG_AS_FASTPATH + u32 asf_cookie; +#endif u8 type; u8 action; u8 flags; @@ -593,6 +599,7 @@ struct xfrm_mgr { const struct xfrm_migrate *m, int num_bundles, const struct xfrm_kmaddress *k); + bool (*is_alive)(const struct km_event *c); }; extern int xfrm_register_km(struct xfrm_mgr *km); @@ -1169,12 +1176,12 @@ extern void xfrm_garbage_collect(struct net *net); static inline void xfrm_sk_free_policy(struct sock *sk) {} static inline int xfrm_sk_clone_policy(struct sock *sk) { return 0; } -static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; } -static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; } +static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; } +static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; } static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) -{ - return 1; -} +{ + return 1; +} static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) { return 1; @@ -1528,7 +1535,7 @@ extern int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int static inline int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen) { return -ENOPROTOOPT; -} +} static inline int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb) { @@ -1632,6 +1639,20 @@ static inline int xfrm_aevent_is_on(struct net *net) rcu_read_unlock(); return ret; } + +static inline int xfrm_acquire_is_on(struct net *net) +{ + struct sock *nlsk; + int ret = 0; + + rcu_read_lock(); + nlsk = rcu_dereference(net->xfrm.nlsk); + if (nlsk) + ret = netlink_has_listeners(nlsk, XFRMNLGRP_ACQUIRE); + rcu_read_unlock(); + + return ret; +} #endif static inline int xfrm_alg_len(const struct xfrm_algo *alg) @@ -1723,4 +1744,29 @@ static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m) return ret; } +#ifdef CONFIG_AS_FASTPATH +struct asf_ipsec_callbackfn_s { + /* Callback to offload the encryption Info*/ + int (*ipsec_enc_hook)(struct xfrm_policy *xp, + struct xfrm_state *xfrm, struct flowi *fl, int ifindex); + + /* Callback to offload the decryption Info*/ + int (*ipsec_dec_hook)(struct xfrm_policy *xp, + struct xfrm_state *xfrm, struct flowi *fl, int ifindex); + + /* Callback to receive the live SA Sync Info*/ + int (*ipsec_sync_sa)(struct xfrm_state *xfrm, int dir, + int seq_no, int bytes); + + /* Callback to send the packet to ASF for further IPSEC processing */ + int (*ipsec_encrypt_n_send)(struct sk_buff *skb, + struct xfrm_state *xfrm); + + /* Callback to send the packet to ASF for further IPSEC processing */ + int (*ipsec_decrypt_n_send)(struct sk_buff *skb, + struct xfrm_state *xfrm); +}; +extern struct asf_ipsec_callbackfn_s asf_cb_fns; +#endif + #endif /* _NET_XFRM_H */ diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 84b10f9..a07b670 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -418,6 +418,8 @@ struct snd_pcm_substream { #endif /* misc flags */ unsigned int hw_opened: 1; + /* data swapped flags */ + unsigned int data_swapped; }; #define SUBSTREAM_BUSY(substream) ((substream)->ref_count > 0) diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 115add2..e560650 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -3,6 +3,7 @@ header-y += byteorder/ header-y += can/ header-y += caif/ header-y += dvb/ +header-y += fmd/ header-y += hdlc/ header-y += hsi/ header-y += isdn/ @@ -125,6 +126,7 @@ header-y += firewire-constants.h header-y += flat.h header-y += fs.h header-y += fsl_hypervisor.h +header-y += fsl_pci_ep_vfio.h header-y += fuse.h header-y += futex.h header-y += gameport.h diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h index 38dbafa..71387e8 100644 --- a/include/uapi/linux/ethtool.h +++ b/include/uapi/linux/ethtool.h @@ -1051,6 +1051,7 @@ enum ethtool_sfeatures_retval_bits { #define RXH_IP_DST (1 << 5) #define RXH_L4_B_0_1 (1 << 6) /* src port in case of TCP/UDP/SCTP */ #define RXH_L4_B_2_3 (1 << 7) /* dst port in case of TCP/UDP/SCTP */ +#define RXH_AH_ESP_SPI (1 << 8) /* SPI field, for AH/ESP flows */ #define RXH_DISCARD (1 << 31) #define RX_CLS_FLOW_DISC 0xffffffffffffffffULL diff --git a/include/uapi/linux/fmd/Kbuild b/include/uapi/linux/fmd/Kbuild new file mode 100644 index 0000000..56a2040 --- /dev/null +++ b/include/uapi/linux/fmd/Kbuild @@ -0,0 +1,5 @@ +header-y += integrations/ +header-y += Peripherals/ + +header-y += ioctls.h +header-y += net_ioctls.h diff --git a/include/uapi/linux/fmd/Peripherals/Kbuild b/include/uapi/linux/fmd/Peripherals/Kbuild new file mode 100644 index 0000000..43883ef --- /dev/null +++ b/include/uapi/linux/fmd/Peripherals/Kbuild @@ -0,0 +1,4 @@ +header-y += fm_ioctls.h +header-y += fm_port_ioctls.h +header-y += fm_pcd_ioctls.h +header-y += fm_test_ioctls.h diff --git a/include/uapi/linux/fmd/Peripherals/fm_ioctls.h b/include/uapi/linux/fmd/Peripherals/fm_ioctls.h new file mode 100644 index 0000000..54e65b7 --- /dev/null +++ b/include/uapi/linux/fmd/Peripherals/fm_ioctls.h @@ -0,0 +1,628 @@ +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/**************************************************************************//** + @File fm_ioctls.h + + @Description FM Char device ioctls +*//***************************************************************************/ +#ifndef __FM_IOCTLS_H +#define __FM_IOCTLS_H + + +/**************************************************************************//** + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API + + @Description FM Linux ioctls definitions and enums + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Collection FM IOCTL device ('/dev') definitions +*//***************************************************************************/ +#define DEV_FM_NAME "fm" /**< Name of the FM chardev */ + +#define DEV_FM_MINOR_BASE 0 +#define DEV_FM_PCD_MINOR_BASE (DEV_FM_MINOR_BASE + 1) /*/dev/fmx-pcd */ +#define DEV_FM_OH_PORTS_MINOR_BASE (DEV_FM_PCD_MINOR_BASE + 1) /*/dev/fmx-port-ohy */ +#define DEV_FM_RX_PORTS_MINOR_BASE (DEV_FM_OH_PORTS_MINOR_BASE + FM_MAX_NUM_OF_OH_PORTS) /*/dev/fmx-port-rxy */ +#define DEV_FM_TX_PORTS_MINOR_BASE (DEV_FM_RX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_RX_PORTS) /*/dev/fmx-port-txy */ +#define DEV_FM_MAX_MINORS (DEV_FM_TX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_TX_PORTS) + +#define FM_IOC_NUM(n) (n) +#define FM_PCD_IOC_NUM(n) (n+20) +#define FM_PORT_IOC_NUM(n) (n+70) +/* @} */ + +#define IOC_FM_MAX_NUM_OF_PORTS 64 + + +/**************************************************************************//** + @Description Enum for defining port types + (must match enum e_FmPortType defined in fm_ext.h) +*//***************************************************************************/ +typedef enum ioc_fm_port_type { + e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */ + e_IOC_FM_PORT_TYPE_RX, /**< 1G Rx port */ + e_IOC_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */ + e_IOC_FM_PORT_TYPE_TX, /**< 1G Tx port */ + e_IOC_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */ + e_IOC_FM_PORT_TYPE_DUMMY +} ioc_fm_port_type; + + +/**************************************************************************//** + @Group lnx_ioctl_FM_lib_grp FM library + + @Description FM API functions, definitions and enums + The FM module is the main driver module and is a mandatory module + for FM driver users. Before any further module initialization, + this module must be initialized. + The FM is a "single-tone" module. It is responsible of the common + HW modules: FPM, DMA, common QMI, common BMI initializations and + run-time control routines. This module must be initialized always + when working with any of the FM modules. + NOTE - We assumes that the FML will be initialize only by core No. 0! + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Description FM Exceptions +*//***************************************************************************/ +typedef enum ioc_fm_exceptions { + e_IOC_FM_EX_DMA_BUS_ERROR, /**< DMA bus error. */ + e_IOC_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/ + e_IOC_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/ + e_IOC_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/ + e_IOC_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/ + e_IOC_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */ + e_IOC_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */ + e_IOC_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */ + e_IOC_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */ + e_IOC_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */ + e_IOC_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */ + e_IOC_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */ + e_IOC_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */ + e_IOC_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */ + e_IOC_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */ + e_IOC_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/ + e_IOC_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/ +} ioc_fm_exceptions; + +/**************************************************************************//** + @Group lnx_ioctl_FM_runtime_control_grp FM Runtime Control Unit + + @Description FM Runtime control unit API functions, definitions and enums. + The FM driver provides a set of control routines for each module. + These routines may only be called after the module was fully + initialized (both configuration and initialization routines were + called). They are typically used to get information from hardware + (status, counters/statistics, revision etc.), to modify a current + state or to force/enable a required action. Run-time control may + be called whenever necessary and as many times as needed. + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Collection General FM defines. + *//***************************************************************************/ +#define IOC_FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \ + FM_MAX_NUM_OF_1G_RX_PORTS + \ + FM_MAX_NUM_OF_10G_RX_PORTS + \ + FM_MAX_NUM_OF_1G_TX_PORTS + \ + FM_MAX_NUM_OF_10G_TX_PORTS) +/* @} */ + +/**************************************************************************//** + @Description Structure for Port bandwidth requirement. Port is identified + by type and relative id. + (must be identical to t_FmPortBandwidth defined in fm_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_port_bandwidth_t { + ioc_fm_port_type type; /**< FM port type */ + uint8_t relative_port_id; /**< Type relative port id */ + uint8_t bandwidth; /**< bandwidth - (in term of percents) */ +} ioc_fm_port_bandwidth_t; + +/**************************************************************************//** + @Description A Structure containing an array of Port bandwidth requirements. + The user should state the ports requiring bandwidth in terms of + percentage - i.e. all port's bandwidths in the array must add + up to 100. + (must be identical to t_FmPortsBandwidthParams defined in fm_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_port_bandwidth_params { + uint8_t num_of_ports; + /**< num of ports listed in the array below */ + ioc_fm_port_bandwidth_t ports_bandwidths[IOC_FM_MAX_NUM_OF_VALID_PORTS]; + /**< for each port, it's bandwidth (all port's + bandwidths must add up to 100.*/ +} ioc_fm_port_bandwidth_params; + +/**************************************************************************//** + @Description enum for defining FM counters +*//***************************************************************************/ +typedef enum ioc_fm_counters { + e_IOC_FM_COUNTERS_ENQ_TOTAL_FRAME, /**< QMI total enqueued frames counter */ + e_IOC_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */ + e_IOC_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */ + e_IOC_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */ + e_IOC_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */ + e_IOC_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */ + e_IOC_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */ + e_IOC_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */ + e_IOC_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */ + e_IOC_FM_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */ +} ioc_fm_counters; + +typedef struct ioc_fm_obj_t { + void *obj; +} ioc_fm_obj_t; + +/**************************************************************************//** + @Description A structure for returning revision information + (must match struct t_FmRevisionInfo declared in fm_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_revision_info_t { + uint8_t major; /**< Major revision */ + uint8_t minor; /**< Minor revision */ +} ioc_fm_revision_info_t; + +/**************************************************************************//** + @Description A structure for FM counters +*//***************************************************************************/ +typedef struct ioc_fm_counters_params_t { + ioc_fm_counters cnt; /**< The requested counter */ + uint32_t val; /**< The requested value to get/set from/into the counter */ +} ioc_fm_counters_params_t; + +typedef union ioc_fm_api_version_t { + struct { + uint8_t major; + uint8_t minor; + uint8_t respin; + uint8_t reserved; + } version; + uint32_t ver; +} ioc_fm_api_version_t; + +#if (DPAA_VERSION >= 11) +/**************************************************************************//** + @Description A structure of information about each of the external + buffer pools used by a port or storage-profile. + (must be identical to t_FmExtPoolParams defined in fm_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_ext_pool_params { + uint8_t id; /**< External buffer pool id */ + uint16_t size; /**< External buffer pool buffer size */ +} ioc_fm_ext_pool_params; + +/**************************************************************************//** + @Description A structure for informing the driver about the external + buffer pools allocated in the BM and used by a port or a + storage-profile. + (must be identical to t_FmExtPools defined in fm_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_ext_pools { + uint8_t num_of_pools_used; /**< Number of pools use by this port */ + ioc_fm_ext_pool_params ext_buf_pool[FM_PORT_MAX_NUM_OF_EXT_POOLS]; + /**< Parameters for each port */ +} ioc_fm_ext_pools; + +typedef struct ioc_fm_vsp_params_t { + void *p_fm; /**< A handle to the FM object this VSP related to */ + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes. + parameter associated with Rx / OP port */ + uint16_t liodn_offset; /**< VSP's LIODN offset */ + struct { + ioc_fm_port_type port_type; /**< Port type */ + uint8_t port_id; /**< Port Id - relative to type */ + } port_params; + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range + defined in relevant FM object */ + void *id; /**< return value */ +} ioc_fm_vsp_params_t; +#endif /* (DPAA_VERSION >= 11) */ + +/**************************************************************************//** + @Description A structure for defining BM pool depletion criteria +*//***************************************************************************/ +typedef struct ioc_fm_buf_pool_depletion_t { + bool pools_grp_mode_enable; /**< select mode in which pause frames will be sent after + a number of pools (all together!) are depleted */ + uint8_t num_of_pools; /**< the number of depleted pools that will invoke + pause frames transmission. */ + bool pools_to_consider[BM_MAX_NUM_OF_POOLS]; + /**< For each pool, TRUE if it should be considered for + depletion (Note - this pool must be used by this port!). */ + bool single_pool_mode_enable; /**< select mode in which pause frames will be sent after + a single-pool is depleted; */ + bool pools_to_consider_for_single_mode[BM_MAX_NUM_OF_POOLS]; + /**< For each pool, TRUE if it should be considered for + depletion (Note - this pool must be used by this port!) */ +#if (DPAA_VERSION >= 11) + bool pfc_priorities_en[FM_MAX_NUM_OF_PFC_PRIORITIES]; + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame + which is transmitted */ +#endif /* (DPAA_VERSION >= 11) */ +} ioc_fm_buf_pool_depletion_t; + +#if (DPAA_VERSION >= 11) +typedef struct ioc_fm_buf_pool_depletion_params_t { + void *p_fm_vsp; + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion; +} ioc_fm_buf_pool_depletion_params_t; +#endif /* (DPAA_VERSION >= 11) */ + +typedef struct ioc_fm_buffer_prefix_content_t { + uint16_t priv_data_size; /**< Number of bytes to be left at the beginning + of the external buffer; Note that the private-area will + start from the base of the buffer address. */ + bool pass_prs_result; /**< TRUE to pass the parse result to/from the FM; + User may use FM_PORT_GetBufferPrsResult() in order to + get the parser-result from a buffer. */ + bool pass_time_stamp; /**< TRUE to pass the timeStamp to/from the FM + User may use FM_PORT_GetBufferTimeStamp() in order to + get the parser-result from a buffer. */ + bool pass_hash_result; /**< TRUE to pass the KG hash result to/from the FM + User may use FM_PORT_GetBufferHashResult() in order to + get the parser-result from a buffer. */ + bool pass_all_other_pcd_info; /**< Add all other Internal-Context information: + AD, hash-result, key, etc. */ + uint16_t data_align; /**< 0 to use driver's default alignment [64], + other value for selecting a data alignment (must be a power of 2); + if write optimization is used, must be >= 16. */ + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size); + Note that this field impacts the size of the buffer-prefix + (i.e. it pushes the data offset); + This field is irrelevant if DPAA_VERSION==10 */ +} ioc_fm_buffer_prefix_content_t; + +typedef struct ioc_fm_buffer_prefix_content_params_t { + void *p_fm_vsp; + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content; +} ioc_fm_buffer_prefix_content_params_t; + +#if (DPAA_VERSION >= 11) +typedef struct ioc_fm_vsp_config_no_sg_params_t { + void *p_fm_vsp; + bool no_sg; +} ioc_fm_vsp_config_no_sg_params_t; + +typedef struct ioc_fm_vsp_prs_result_params_t { + void *p_fm_vsp; + void *p_data; +} ioc_fm_vsp_prs_result_params_t; +#endif + +typedef struct fm_ctrl_mon_t { + uint8_t percent_cnt[1]; +} fm_ctrl_mon_t; + +typedef struct ioc_fm_ctrl_mon_counters_params_t { + uint8_t fm_ctrl_index; + fm_ctrl_mon_t *p_mon; +} ioc_fm_ctrl_mon_counters_params_t; + +/**************************************************************************//** + @Function FM_IOC_SET_PORTS_BANDWIDTH + + @Description Sets relative weights between ports when accessing common resources. + + @Param[in] ioc_fm_port_bandwidth_params Port bandwidth percentages, + their sum must equal 100. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Init(). +*//***************************************************************************/ +#define FM_IOC_SET_PORTS_BANDWIDTH _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(2), ioc_fm_port_bandwidth_params) + +/**************************************************************************//** + @Function FM_IOC_GET_REVISION + + @Description Returns the FM revision + + @Param[out] ioc_fm_revision_info_t A structure of revision information parameters. + + @Return None. + + @Cautions Allowed only following FM_Init(). +*//***************************************************************************/ +#define FM_IOC_GET_REVISION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(3), ioc_fm_revision_info_t) + +/**************************************************************************//** + @Function FM_IOC_GET_COUNTER + + @Description Reads one of the FM counters. + + @Param[in,out] ioc_fm_counters_params_t The requested counter parameters. + + @Return Counter's current value. + + @Cautions Allowed only following FM_Init(). + Note that it is user's responsibilty to call this routine only + for enabled counters, and there will be no indication if a + disabled counter is accessed. +*//***************************************************************************/ +#define FM_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(4), ioc_fm_counters_params_t) + +/**************************************************************************//** + @Function FM_IOC_SET_COUNTER + + @Description Sets a value to an enabled counter. Use "0" to reset the counter. + + @Param[in] ioc_fm_counters_params_t The requested counter parameters. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Init(). +*//***************************************************************************/ +#define FM_IOC_SET_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(5), ioc_fm_counters_params_t) + +/**************************************************************************//** + @Function FM_IOC_FORCE_INTR + + @Description Causes an interrupt event on the requested source. + + @Param[in] ioc_fm_exceptions An exception to be forced. + + @Return E_OK on success; Error code if the exception is not enabled, + or is not able to create interrupt. + + @Cautions Allowed only following FM_Init(). +*//***************************************************************************/ +#define FM_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(6), ioc_fm_exceptions) + +/**************************************************************************//** + @Function FM_IOC_GET_API_VERSION + + @Description Reads the FMD IOCTL API version. + + @Param[in,out] ioc_fm_api_version_t The requested counter parameters. + + @Return Version's value. +*//***************************************************************************/ +#define FM_IOC_GET_API_VERSION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(7), ioc_fm_api_version_t) + +#if (DPAA_VERSION >= 11) +/**************************************************************************//** + @Function FM_VSP_Config + + @Description Creates descriptor for the FM VSP module. + + The routine returns a handle (descriptor) to the FM VSP object. + This descriptor must be passed as first parameter to all other + FM VSP function calls. + + No actual initialization or configuration of FM hardware is + done by this routine. + +@Param[in] p_FmVspParams Pointer to data structure of parameters + + @Retval Handle to FM VSP object, or NULL for Failure. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_IOC_VSP_CONFIG_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_compat_fm_vsp_params_t) +#endif +#define FM_IOC_VSP_CONFIG _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_fm_vsp_params_t) + +/**************************************************************************//** + @Function FM_VSP_Init + + @Description Initializes the FM VSP module + + @Param[in] h_FmVsp - FM VSP module descriptor + + @Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_IOC_VSP_INIT_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_compat_fm_obj_t) +#endif +#define FM_IOC_VSP_INIT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_fm_obj_t) + +/**************************************************************************//** + @Function FM_VSP_Free + + @Description Frees all resources that were assigned to FM VSP module. + + Calling this routine invalidates the descriptor. + + @Param[in] h_FmVsp - FM VSP module descriptor + + @Return E_OK on success; Error code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_IOC_VSP_FREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_compat_fm_obj_t) +#endif +#define FM_IOC_VSP_FREE _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_fm_obj_t) + +/**************************************************************************//** + @Function FM_VSP_ConfigPoolDepletion + + @Description Calling this routine enables pause frame generation depending on the + depletion status of BM pools. It also defines the conditions to activate + this functionality. By default, this functionality is disabled. + + @Param[in] ioc_fm_buf_pool_depletion_params_t A structure holding the required parameters. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_IOC_VSP_CONFIG_POOL_DEPLETION_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(11), ioc_compat_fm_buf_pool_depletion_params_t) +#endif +#define FM_IOC_VSP_CONFIG_POOL_DEPLETION _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(11), ioc_fm_buf_pool_depletion_params_t) + +/**************************************************************************//** + @Function FM_VSP_ConfigBufferPrefixContent + + @Description Defines the structure, size and content of the application buffer. + + The prefix will + In VSPs defined for Tx ports, if 'passPrsResult', the application + should set a value to their offsets in the prefix of + the FM will save the first 'privDataSize', than, + depending on 'passPrsResult' and 'passTimeStamp', copy parse result + and timeStamp, and the packet itself (in this order), to the + application buffer, and to offset. + + Calling this routine changes the buffer margins definitions + in the internal driver data base from its default + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize] + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult]. + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp]. + + @Param[in] ioc_fm_buffer_prefix_content_params_t A structure holding the required parameters. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(12), ioc_compat_fm_buffer_prefix_content_params_t) +#endif +#define FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(12), ioc_fm_buffer_prefix_content_params_t) + +/**************************************************************************//** + @Function FM_VSP_ConfigNoScatherGather + + @Description Calling this routine changes the possibility to receive S/G frame + in the internal driver data base + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather] + + @Param[in] ioc_fm_vsp_config_no_sg_params_t A structure holding the required parameters. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_IOC_VSP_CONFIG_NO_SG_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(13), ioc_compat_fm_vsp_config_no_sg_params_t) +#endif +#define FM_IOC_VSP_CONFIG_NO_SG _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(13), ioc_fm_vsp_config_no_sg_params_t) + +/**************************************************************************//** + @Function FM_VSP_GetBufferPrsResult + + @Description Returns the pointer to the parse result in the data buffer. + In Rx ports this is relevant after reception, if parse + result is configured to be part of the data passed to the + application. For non Rx ports it may be used to get the pointer + of the area in the buffer where parse result should be + initialized - if so configured. + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix + configuration. + + @Param[in] ioc_fm_vsp_prs_result_params_t A structure holding the required parameters. + + @Return Parse result pointer on success, NULL if parse result was not + configured for this port. + + @Cautions Allowed only following FM_VSP_Init(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_IOC_VSP_GET_BUFFER_PRS_RESULT_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(14), ioc_compat_fm_vsp_prs_result_params_t) +#endif +#define FM_IOC_VSP_GET_BUFFER_PRS_RESULT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(14), ioc_fm_vsp_prs_result_params_t) +#endif /* (DPAA_VERSION >= 11) */ + +/**************************************************************************//** + @Function FM_CtrlMonStart + + @Description Start monitoring utilization of all available FM controllers. + + In order to obtain FM controllers utilization the following sequence + should be used: + -# FM_CtrlMonStart() + -# FM_CtrlMonStop() + -# FM_CtrlMonGetCounters() - issued for each FM controller + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Init(). +*//***************************************************************************/ +#define FM_IOC_CTRL_MON_START _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(15)) + + +/**************************************************************************//** + @Function FM_CtrlMonStop + + @Description Stop monitoring utilization of all available FM controllers. + + In order to obtain FM controllers utilization the following sequence + should be used: + -# FM_CtrlMonStart() + -# FM_CtrlMonStop() + -# FM_CtrlMonGetCounters() - issued for each FM controller + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Init(). +*//***************************************************************************/ +#define FM_IOC_CTRL_MON_STOP _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(16)) + +/**************************************************************************//** + @Function FM_CtrlMonGetCounters + + @Description Obtain FM controller utilization parameters. + + In order to obtain FM controllers utilization the following sequence + should be used: + -# FM_CtrlMonStart() + -# FM_CtrlMonStop() + -# FM_CtrlMonGetCounters() - issued for each FM controller + + @Param[in] ioc_fm_ctrl_mon_counters_params_t A structure holding the required parameters. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Init(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_IOC_CTRL_MON_GET_COUNTERS_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(17), ioc_compat_fm_ctrl_mon_counters_params_t) +#endif +#define FM_IOC_CTRL_MON_GET_COUNTERS _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(17), ioc_fm_ctrl_mon_counters_params_t) + +/** @} */ /* end of lnx_ioctl_FM_runtime_control_grp group */ +/** @} */ /* end of lnx_ioctl_FM_lib_grp group */ +/** @} */ /* end of lnx_ioctl_FM_grp */ + +#define FMD_API_VERSION_MAJOR 21 +#define FMD_API_VERSION_MINOR 1 +#define FMD_API_VERSION_RESPIN 0 + +#endif /* __FM_IOCTLS_H */ diff --git a/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h b/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h new file mode 100644 index 0000000..da52749 --- /dev/null +++ b/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h @@ -0,0 +1,2994 @@ +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +/****************************************************************************** + @File fm_pcd_ioctls.h + + @Description FM PCD ... +*//***************************************************************************/ +#ifndef __FM_PCD_IOCTLS_H +#define __FM_PCD_IOCTLS_H + +#include "net_ioctls.h" +#include "fm_ioctls.h" + + +/**************************************************************************//** + + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API + + @Description Frame Manager Linux ioctls definitions and enums + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Group lnx_ioctl_FM_PCD_grp FM PCD + + @Description Frame Manager PCD API functions, definitions and enums + + The FM PCD module is responsible for the initialization of all + global classifying FM modules. This includes the parser general and + common registers, the key generator global and common registers, + and the policer global and common registers. + In addition, the FM PCD SW module will initialize all required + key generator schemes, coarse classification flows, and policer + profiles. When an FM module is configured to work with one of these + entities, it will register to it using the FM PORT API. The PCD + module will manage the PCD resources - i.e. resource management of + KeyGen schemes, etc. + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Collection General PCD defines +*//***************************************************************************/ +#define IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */ + +#define IOC_FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */ +#define IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS) + /**< Number of distinction units is limited by + register size (32 bits) minus reserved bits + for private headers. */ +#define IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers + in a distinction unit */ +#define IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS 8 /**< Total number of generic KeyGen registers */ +#define IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration; + For HW implementation reasons, in most + cases less than this will be allowed; The + driver will return an initialization error + if resource is unavailable. */ +#define IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */ +#define IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */ + +#define IOC_FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */ +#define IOC_FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */ +#define IOC_FM_PCD_PRS_SW_OFFSET 0x00000040 /**< Size of illegal addresses at the beginning + of the SW parser area */ + +#define IOC_FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for + insert manipulation */ + +#if DPAA_VERSION >= 11 +#define IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */ +#endif /* DPAA_VERSION >= 11 */ +/* @} */ + +#ifdef FM_CAPWAP_SUPPORT +#error "FM_CAPWAP_SUPPORT not implemented!" +#endif + + +/**************************************************************************//** + @Group lnx_ioctl_FM_PCD_init_grp FM PCD Initialization Unit + + @Description Frame Manager PCD Initialization Unit API + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Description PCD counters + (must match enum e_FmPcdCounters defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef enum ioc_fm_pcd_counters { + e_IOC_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */ + e_IOC_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */ + e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */ + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer; + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */ + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer; + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */ + e_IOC_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */ + e_IOC_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */ + e_IOC_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */ + e_IOC_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */ + e_IOC_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */ + e_IOC_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */ + e_IOC_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */ + e_IOC_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L2 parse result is returned with errors. */ + e_IOC_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L3 parse result is returned with errors. */ + e_IOC_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L4 parse result is returned with errors. */ + e_IOC_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times SHIM parse result is returned with errors. */ + e_IOC_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */ + e_IOC_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES, /**< Parser counter - counts the number of cycles stalled waiting for parser internal memory reads while executing soft parser instruction. */ + e_IOC_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES, /**< Parser counter - counts the number of cycles spent executing hard parser (including stall cycles). */ + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */ + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */ + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */ + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */ + e_IOC_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */ +} ioc_fm_pcd_counters; + +/**************************************************************************//** + @Description PCD interrupts + (must match enum e_FmPcdExceptions defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef enum ioc_fm_pcd_exceptions { + e_IOC_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */ + e_IOC_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */ + e_IOC_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */ + e_IOC_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */ + e_IOC_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */ + e_IOC_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */ + e_IOC_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */ + e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */ +} ioc_fm_pcd_exceptions; + +/** @} */ /* end of lnx_ioctl_FM_PCD_init_grp group */ + + +/**************************************************************************//** + @Group lnx_ioctl_FM_PCD_Runtime_grp FM PCD Runtime Unit + + @Description Frame Manager PCD Runtime Unit + + The runtime control allows creation of PCD infrastructure modules + such as Network Environment Characteristics, Classification Plan + Groups and Coarse Classification Trees. + It also allows on-the-fly initialization, modification and removal + of PCD modules such as KeyGen schemes, coarse classification nodes + and Policer profiles. + + In order to explain the programming model of the PCD driver interface + a few terms should be explained, and will be used below. + - Distinction Header - One of the 16 protocols supported by the FM parser, + or one of the SHIM headers (1 or 2). May be a header with a special + option (see below). + - Interchangeable Headers Group - This is a group of Headers recognized + by either one of them. For example, if in a specific context the user + chooses to treat IPv4 and IPV6 in the same way, they may create an + interchangeable Headers Unit consisting of these 2 headers. + - A Distinction Unit - a Distinction Header or an Interchangeable Headers + Group. + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and + IPv6, includes multicast, broadcast and other protocol specific options. + In terms of hardware it relates to the options available in the classification + plan. + - Network Environment Characteristics - a set of Distinction Units that define + the total recognizable header selection for a certain environment. This is + NOT the list of all headers that will ever appear in a flow, but rather + everything that needs distinction in a flow, where distinction is made by KeyGen + schemes and coarse classification action descriptors. + + The PCD runtime modules initialization is done in stages. The first stage after + initializing the PCD module itself is to establish a Network Flows Environment + Definition. The application may choose to establish one or more such environments. + Later, when needed, the application will have to state, for some of its modules, + to which single environment it belongs. + + @{ +*//***************************************************************************/ + + +/**************************************************************************//** + @Description structure for FM counters +*//***************************************************************************/ +typedef struct ioc_fm_pcd_counters_params_t { + ioc_fm_pcd_counters cnt; /**< The requested counter */ + uint32_t val; /**< The requested value to get/set from/into the counter */ +} ioc_fm_pcd_counters_params_t; + +/**************************************************************************//** + @Description structure for FM exception definitios +*//***************************************************************************/ +typedef struct ioc_fm_pcd_exception_params_t { + ioc_fm_pcd_exceptions exception; /**< The requested exception */ + bool enable; /**< TRUE to enable interrupt, FALSE to mask it. */ +} ioc_fm_pcd_exception_params_t; + +/**************************************************************************//** + @Description A structure for SW parser labels + (must be identical to struct t_FmPcdPrsLabelParams defined in fm_pcd_ext.h) + *//***************************************************************************/ +typedef struct ioc_fm_pcd_prs_label_params_t { + uint32_t instruction_offset; /**< SW parser label instruction offset (2 bytes + resolution), relative to Parser RAM. */ + ioc_net_header_type hdr; /**< The existence of this header will invoke + the SW parser code. */ + uint8_t index_per_hdr; /**< Normally 0, if more than one SW parser + attachments for the same header, use this + index to distinguish between them. */ +} ioc_fm_pcd_prs_label_params_t; + +/**************************************************************************//** + @Description A structure for SW parser + (Must match struct t_FmPcdPrsSwParams defined in fm_pcd_ext.h) + *//***************************************************************************/ +typedef struct ioc_fm_pcd_prs_sw_params_t { + bool override; /**< FALSE to invoke a check that nothing else + was loaded to this address, including + internal patches. + TRUE to override any existing code.*/ + uint32_t size; /**< SW parser code size */ + uint16_t base; /**< SW parser base (in instruction counts! + must be larger than 0x20)*/ + uint8_t *p_code; /**< SW parser code */ + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS]; + /**< SW parser data (parameters) */ + uint8_t num_of_labels; /**< Number of labels for SW parser. */ + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS]; + /**< SW parser labels table, + containing num_of_labels entries */ +} ioc_fm_pcd_prs_sw_params_t; + +/**************************************************************************//** + @Description A structure to set the a KeyGen default value + *//***************************************************************************/ +typedef struct ioc_fm_pcd_kg_dflt_value_params_t { + uint8_t valueId; /**< 0,1 - one of 2 global default values */ + uint32_t value; /**< The requested default value */ +} ioc_fm_pcd_kg_dflt_value_params_t; + + +/**************************************************************************//** + @Function FM_PCD_Enable + + @Description This routine should be called after PCD is initialized for enabling all + PCD engines according to their existing configuration. + + @Return 0 on success; Error code otherwise. + + @Cautions Allowed only when PCD is disabled. +*//***************************************************************************/ +#define FM_PCD_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(1)) + +/**************************************************************************//** + @Function FM_PCD_Disable + + @Description This routine may be called when PCD is enabled in order to + disable all PCD engines. It may be called + only when none of the ports in the system are using the PCD. + + @Return 0 on success; Error code otherwise. + + @Cautions Allowed only when PCD is enabled. +*//***************************************************************************/ +#define FM_PCD_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(2)) + + /**************************************************************************//** + @Function FM_PCD_PrsLoadSw + + @Description This routine may be called only when all ports in the + system are actively using the classification plan scheme. + In such cases it is recommended in order to save resources. + The driver automatically saves 8 classification plans for + ports that do NOT use the classification plan mechanism, to + avoid this (in order to save those entries) this routine may + be called. + + @Param[in] ioc_fm_pcd_prs_sw_params_t A pointer to the image of the software parser code. + + @Return 0 on success; Error code otherwise. + + @Cautions Allowed only when PCD is disabled. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_PRS_LOAD_SW_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(3), ioc_compat_fm_pcd_prs_sw_params_t) +#endif +#define FM_PCD_IOC_PRS_LOAD_SW _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(3), ioc_fm_pcd_prs_sw_params_t) + +/**************************************************************************//** + @Function FM_PCD_KgSetDfltValue + + @Description Calling this routine sets a global default value to be used + by the KeyGen when parser does not recognize a required + field/header. + By default default values are 0. + + @Param[in] ioc_fm_pcd_kg_dflt_value_params_t A pointer to a structure with the relevant parameters + + @Return 0 on success; Error code otherwise. + + @Cautions Allowed only when PCD is disabled. +*//***************************************************************************/ +#define FM_PCD_IOC_KG_SET_DFLT_VALUE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(6), ioc_fm_pcd_kg_dflt_value_params_t) + +/**************************************************************************//** + @Function FM_PCD_KgSetAdditionalDataAfterParsing + + @Description Calling this routine allows the keygen to access data past + the parser finishing point. + + @Param[in] uint8_t payload-offset; the number of bytes beyond the parser location. + + @Return 0 on success; Error code otherwise. + + @Cautions Allowed only when PCD is disabled. +*//***************************************************************************/ +#define FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(7), uint8_t) + +/**************************************************************************//** + @Function FM_PCD_SetException + + @Description Calling this routine enables/disables PCD interrupts. + + @Param[in] ioc_fm_pcd_exception_params_t Arguments struct with exception to be enabled/disabled. + + @Return 0 on success; Error code otherwise. +*//***************************************************************************/ +#define FM_PCD_IOC_SET_EXCEPTION _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(8), ioc_fm_pcd_exception_params_t) + +/**************************************************************************//** + @Function FM_PCD_GetCounter + + @Description Reads one of the FM PCD counters. + + @Param[in,out] ioc_fm_pcd_counters_params_t The requested counter parameters. + + @Return 0 on success; Error code otherwise. + + @Cautions Note that it is user's responsibilty to call this routine only + for enabled counters, and there will be no indication if a + disabled counter is accessed. +*//***************************************************************************/ +#define FM_PCD_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(9), ioc_fm_pcd_counters_params_t) + +#if 0 +TODO: unused IOCTL +/**************************************************************************//** + @Function FM_PCD_ModifyCounter + + @Description Writes a value to an enabled counter. Use "0" to reset the counter. + + @Param[in] ioc_fm_pcd_counters_params_t - The requested counter parameters. + + @Return 0 on success; Error code otherwise. +*//***************************************************************************/ +#define FM_PCD_IOC_MODIFY_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(10), ioc_fm_pcd_counters_params_t) +#define FM_PCD_IOC_SET_COUNTER FM_PCD_IOC_MODIFY_COUNTER +#endif + +/**************************************************************************//** + @Function FM_PCD_ForceIntr + + @Description Causes an interrupt event on the requested source. + + @Param[in] ioc_fm_pcd_exceptions - An exception to be forced. + + @Return 0 on success; error code if the exception is not enabled, + or is not able to create interrupt. +*//***************************************************************************/ +#define FM_PCD_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(11), ioc_fm_pcd_exceptions) + +/**************************************************************************//** + @Collection Definitions of coarse classification parameters as required by KeyGen + (when coarse classification is the next engine after this scheme). +*//***************************************************************************/ +#define IOC_FM_PCD_MAX_NUM_OF_CC_TREES 8 +#define IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS 16 +#define IOC_FM_PCD_MAX_NUM_OF_CC_UNITS 4 +#define IOC_FM_PCD_MAX_NUM_OF_KEYS 256 +#define IOC_FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE) +#define IOC_FM_PCD_MAX_SIZE_OF_KEY 56 +#define IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16 +#define IOC_FM_PCD_LAST_KEY_INDEX 0xffff +#define IOC_FM_PCD_MANIP_DSCP_VALUES 64 +/* @} */ + +/**************************************************************************//** + @Collection A set of definitions to allow protocol + special option description. +*//***************************************************************************/ +typedef uint32_t ioc_protocol_opt_t; /**< A general type to define a protocol option. */ + +typedef ioc_protocol_opt_t ioc_eth_protocol_opt_t; /**< Ethernet protocol options. */ +#define IOC_ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */ +#define IOC_ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */ + +typedef ioc_protocol_opt_t ioc_vlan_protocol_opt_t; /**< Vlan protocol options. */ +#define IOC_VLAN_STACKED 0x20000000 /**< Stacked VLAN. */ + +typedef ioc_protocol_opt_t ioc_mpls_protocol_opt_t; /**< MPLS protocol options. */ +#define IOC_MPLS_STACKED 0x10000000 /**< Stacked MPLS. */ + +typedef ioc_protocol_opt_t ioc_ipv4_protocol_opt_t; /**< IPv4 protocol options. */ +#define IOC_IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */ +#define IOC_IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */ +#define IOC_IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */ +#define IOC_IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */ + +#define IOC_IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option. + IPV4 Reassembly manipulation requires network + environment with IPV4 header and IPV4_FRAG_1 option */ + +typedef ioc_protocol_opt_t ioc_ipv6_protocol_opt_t; /**< IPv6 protocol options. */ +#define IOC_IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */ +#define IOC_IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */ +#define IOC_IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */ + +#define IOC_IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option. + IPV6 Reassembly manipulation requires network + environment with IPV6 header and IPV6_FRAG_1 option */ +#if (DPAA_VERSION >= 11) +typedef ioc_protocol_opt_t ioc_capwap_protocol_opt_t; /**< CAPWAP protocol options. */ +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option. + CAPWAP Reassembly manipulation requires network + environment with CAPWAP header and CAPWAP_FRAG_1 option; + in case where fragment found, the fragment-extension offset + may be found at 'shim2' (in parser-result). */ +#endif /* (DPAA_VERSION >= 11) */ + +/* @} */ + +#define IOC_FM_PCD_MANIP_MAX_HDR_SIZE 256 +#define IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64 +/**************************************************************************//** + @Collection A set of definitions to support Header Manipulation selection. +*//***************************************************************************/ +typedef uint32_t ioc_hdr_manip_flags_t; /**< A general type to define a HMan update command flags. */ + +typedef ioc_hdr_manip_flags_t ioc_ipv4_hdr_manip_update_flags_t; /**< IPv4 protocol HMan update command flags. */ + +#define IOC_HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */ +#define IOC_HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */ +#define IOC_HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */ +#define IOC_HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */ +#define IOC_HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */ + +typedef ioc_hdr_manip_flags_t ioc_ipv6_hdr_manip_update_flags_t; /**< IPv6 protocol HMan update command flags. */ + +#define IOC_HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value + ('traffic_class' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */ +#define IOC_HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */ +#define IOC_HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */ +#define IOC_HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */ + +typedef ioc_hdr_manip_flags_t ioc_tcp_udp_hdr_manip_update_flags_t;/**< TCP/UDP protocol HMan update command flags. */ + +#define IOC_HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value + ('src' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */ +#define IOC_HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */ +#define IOC_HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */ + +/* @} */ + +/**************************************************************************//** + @Description A type used for returning the order of the key extraction. + each value in this array represents the index of the extraction + command as defined by the user in the initialization extraction array. + The valid size of this array is the user define number of extractions + required (also marked by the second '0' in this array). +*//***************************************************************************/ +typedef uint8_t ioc_fm_pcd_kg_key_order_t [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; + +/**************************************************************************//** + @Description All PCD engines + (must match enum e_FmPcdEngine defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef enum ioc_fm_pcd_engine { + e_IOC_FM_PCD_INVALID = 0, /**< Invalid PCD engine */ + e_IOC_FM_PCD_DONE, /**< No PCD Engine indicated */ + e_IOC_FM_PCD_KG, /**< KeyGen */ + e_IOC_FM_PCD_CC, /**< Coarse Classifier */ + e_IOC_FM_PCD_PLCR, /**< Policer */ + e_IOC_FM_PCD_PRS, /**< Parser */ +#if DPAA_VERSION >= 11 + e_IOC_FM_PCD_FR, /**< Frame Replicator */ +#endif /* DPAA_VERSION >= 11 */ + e_IOC_FM_PCD_HASH /**< Hash Table */ +} ioc_fm_pcd_engine; + +/**************************************************************************//** + @Description An enum for selecting extraction by header types + (Must match enum e_FmPcdExtractByHdrType defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef enum ioc_fm_pcd_extract_by_hdr_type { + e_IOC_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */ + e_IOC_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */ + e_IOC_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */ +} ioc_fm_pcd_extract_by_hdr_type; + +/**************************************************************************//** + @Description An enum for selecting extraction source (when it is not the header) + (Must match enum e_FmPcdExtractFrom defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef enum ioc_fm_pcd_extract_from { + e_IOC_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */ + e_IOC_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */ + e_IOC_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG only: Extract from the point where parsing had finished */ + e_IOC_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */ + e_IOC_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */ + e_IOC_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG & CC: Extract from the parser result */ + e_IOC_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */ + e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */ +} ioc_fm_pcd_extract_from; + +/**************************************************************************//** + @Description An enum for selecting extraction type +*//***************************************************************************/ +typedef enum ioc_fm_pcd_extract_type { + e_IOC_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */ + e_IOC_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */ + e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */ +} ioc_fm_pcd_extract_type; + +/**************************************************************************//** + @Description An enum for selecting a default +*//***************************************************************************/ +typedef enum ioc_fm_pcd_kg_extract_dflt_select { + e_IOC_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */ + e_IOC_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */ + e_IOC_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */ + e_IOC_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */ + e_IOC_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */ +} ioc_fm_pcd_kg_extract_dflt_select; + +/**************************************************************************//** + @Description Enumeration type defining all default groups - each group shares + a default value, one of four user-initialized values. +*//***************************************************************************/ +typedef enum ioc_fm_pcd_kg_known_fields_dflt_types { + e_IOC_FM_PCD_KG_MAC_ADDR, /**< MAC Address */ + e_IOC_FM_PCD_KG_TCI, /**< TCI field */ + e_IOC_FM_PCD_KG_ENET_TYPE, /**< ENET Type */ + e_IOC_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */ + e_IOC_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */ + e_IOC_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */ + e_IOC_FM_PCD_KG_IP_ADDR, /**< IP addr */ + e_IOC_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */ + e_IOC_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */ + e_IOC_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */ + e_IOC_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */ + e_IOC_FM_PCD_KG_L4_PORT, /**< L4 Port */ + e_IOC_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */ + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW, + any data extraction that is not the full + field described above */ + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW, + any data extraction without validation */ + e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW, + extraction from parser result or + direct use of default value */ +} ioc_fm_pcd_kg_known_fields_dflt_types; + +/**************************************************************************//** + @Description Enumeration type for defining header index for scenarios with + multiple (tunneled) headers +*//***************************************************************************/ +typedef enum ioc_fm_pcd_hdr_index { + e_IOC_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also + to specify regular IP (not tunneled). */ + e_IOC_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */ + e_IOC_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */ + e_IOC_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */ + e_IOC_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */ +} ioc_fm_pcd_hdr_index; + +/**************************************************************************//** + @Description Enumeration type for selecting the policer profile functional type +*//***************************************************************************/ +typedef enum ioc_fm_pcd_profile_type_selection { + e_IOC_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */ + e_IOC_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */ +} ioc_fm_pcd_profile_type_selection; + +/**************************************************************************//** + @Description Enumeration type for selecting the policer profile algorithm +*//***************************************************************************/ +typedef enum ioc_fm_pcd_plcr_algorithm_selection { + e_IOC_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */ + e_IOC_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */ + e_IOC_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */ +} ioc_fm_pcd_plcr_algorithm_selection; + +/**************************************************************************//** + @Description Enumeration type for selecting a policer profile color mode +*//***************************************************************************/ +typedef enum ioc_fm_pcd_plcr_color_mode { + e_IOC_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */ + e_IOC_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */ +} ioc_fm_pcd_plcr_color_mode; + +/**************************************************************************//** + @Description Enumeration type for selecting a policer profile color +*//***************************************************************************/ +typedef enum ioc_fm_pcd_plcr_color { + e_IOC_FM_PCD_PLCR_GREEN, /**< Green */ + e_IOC_FM_PCD_PLCR_YELLOW, /**< Yellow */ + e_IOC_FM_PCD_PLCR_RED, /**< Red */ + e_IOC_FM_PCD_PLCR_OVERRIDE /**< Color override */ +} ioc_fm_pcd_plcr_color; + +/**************************************************************************//** + @Description Enumeration type for selecting the policer profile packet frame length selector +*//***************************************************************************/ +typedef enum ioc_fm_pcd_plcr_frame_length_select { + e_IOC_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */ + e_IOC_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */ + e_IOC_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */ + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */ +} ioc_fm_pcd_plcr_frame_length_select; + +/**************************************************************************//** + @Description Enumeration type for selecting roll-back frame +*//***************************************************************************/ +typedef enum ioc_fm_pcd_plcr_roll_back_frame_select { + e_IOC_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Rollback L2 frame length */ + e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Rollback Full frame length */ +} ioc_fm_pcd_plcr_roll_back_frame_select; + +/**************************************************************************//** + @Description Enumeration type for selecting the policer profile packet or byte mode +*//***************************************************************************/ +typedef enum ioc_fm_pcd_plcr_rate_mode { + e_IOC_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */ + e_IOC_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */ +} ioc_fm_pcd_plcr_rate_mode; + +/**************************************************************************//** + @Description Enumeration type for defining action of frame +*//***************************************************************************/ +typedef enum ioc_fm_pcd_done_action { + e_IOC_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */ + e_IOC_FM_PCD_DROP_FRAME /**< Drop frame */ +} ioc_fm_pcd_done_action; + +/**************************************************************************//** + @Description Enumeration type for selecting the policer counter +*//***************************************************************************/ +typedef enum ioc_fm_pcd_plcr_profile_counters { + e_IOC_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */ + e_IOC_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */ + e_IOC_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */ + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */ + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */ +} ioc_fm_pcd_plcr_profile_counters; + +/**************************************************************************//** + @Description Enumeration type for selecting the PCD action after extraction +*//***************************************************************************/ +typedef enum ioc_fm_pcd_action { + e_IOC_FM_PCD_ACTION_NONE, /**< NONE */ + e_IOC_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction*/ + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction*/ +} ioc_fm_pcd_action; + +/**************************************************************************//** + @Description Enumeration type for selecting type of insert manipulation +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_hdr_insrt_type { + e_IOC_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */ + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */ +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) + e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */ +#endif /* FM_CAPWAP_SUPPORT */ +} ioc_fm_pcd_manip_hdr_insrt_type; + +/**************************************************************************//** + @Description Enumeration type for selecting type of remove manipulation +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_hdr_rmv_type { + e_IOC_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */ + e_IOC_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */ +} ioc_fm_pcd_manip_hdr_rmv_type; + +/**************************************************************************//** + @Description An enum for selecting specific L2 fields removal +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_hdr_rmv_specific_l2 { + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */ + e_IOC_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */ + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until + the header which follows the MPLS header */ + e_IOC_FM_PCD_MANIP_HDR_RMV_MPLS /**< Remove MPLS header (Unlimited MPLS labels) */ +} ioc_fm_pcd_manip_hdr_rmv_specific_l2; + +/**************************************************************************//** + @Description Enumeration type for selecting specific fields updates +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_hdr_field_update_type { + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */ + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */ + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */ + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */ +} ioc_fm_pcd_manip_hdr_field_update_type; + +/**************************************************************************//** + @Description Enumeration type for selecting VLAN updates +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_hdr_field_update_vlan { + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */ + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */ +} ioc_fm_pcd_manip_hdr_field_update_vlan; + +/**************************************************************************//** + @Description Enumeration type for selecting specific L2 fields removal +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_hdr_insrt_specific_l2 { + e_IOC_FM_PCD_MANIP_HDR_INSRT_MPLS /**< Insert MPLS header (Unlimited MPLS labels) */ +} ioc_fm_pcd_manip_hdr_insrt_specific_l2; + +#if (DPAA_VERSION >= 11) +/**************************************************************************//** + @Description Enumeration type for selecting QoS mapping mode + + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE' + User should instruct the port to read the parser-result +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_hdr_qos_mapping_mode { + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */ + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the parser-result. */ +} ioc_fm_pcd_manip_hdr_qos_mapping_mode; + +/**************************************************************************//** + @Description Enumeration type for selecting QoS source + + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE' + User should left room for the parser-result on input/output buffer + and instruct the port to read/write the parser-result to the buffer (RPD should be set) +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_hdr_qos_src { + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */ + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the parser-result. */ +} ioc_fm_pcd_manip_hdr_qos_src; +#endif /* (DPAA_VERSION >= 11) */ + +/**************************************************************************//** + @Description Enumeration type for selecting type of header insertion +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_hdr_insrt_by_hdr_type { + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */ +#if (DPAA_VERSION >= 11) + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */ + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */ + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */ + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */ +#endif /* (DPAA_VERSION >= 11) */ +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_type; + +/**************************************************************************//** + @Description Enumeration type for selecting specific custom command +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_hdr_custom_type { + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */ +} ioc_fm_pcd_manip_hdr_custom_type; + +/**************************************************************************//** + @Description Enumeration type for selecting specific custom command +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_hdr_custom_ip_replace { + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */ + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */ +} ioc_fm_pcd_manip_hdr_custom_ip_replace; + +/**************************************************************************//** + @Description Enumeration type for selecting type of header removal +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_hdr_rmv_by_hdr_type { + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */ +#if (DPAA_VERSION >= 11) + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */ +#endif /* (DPAA_VERSION >= 11) */ +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */ +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_type; + +/**************************************************************************//** + @Description Enumeration type for selecting type of timeout mode +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_reassem_time_out_mode { + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process + from the first fragment to the last */ + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */ +} ioc_fm_pcd_manip_reassem_time_out_mode; + +/**************************************************************************//** + @Description Enumeration type for selecting type of WaysNumber mode +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_reassem_ways_number { + e_IOC_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */ + e_IOC_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */ + e_IOC_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */ + e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */ + e_IOC_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */ + e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */ + e_IOC_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */ + e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */ +} ioc_fm_pcd_manip_reassem_ways_number; + +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) +/**************************************************************************//** + @Description Enumeration type for selecting type of statistics mode +*//***************************************************************************/ +typedef enum ioc_fm_pcd_stats { + e_IOC_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */ +} ioc_fm_pcd_stats; +#endif + +/**************************************************************************//** + @Description Enumeration type for selecting manipulation type +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_type { + e_IOC_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */ + e_IOC_FM_PCD_MANIP_REASSEM, /**< Reassembly */ + e_IOC_FM_PCD_MANIP_FRAG, /**< Fragmentation */ + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */ +} ioc_fm_pcd_manip_type; + +/**************************************************************************//** + @Description Enumeration type for selecting type of statistics mode +*//***************************************************************************/ +typedef enum ioc_fm_pcd_cc_stats_mode { + e_IOC_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */ + e_IOC_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */ + e_IOC_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */ +#if (DPAA_VERSION >= 11) + e_IOC_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics */ +#endif /* (DPAA_VERSION >= 11) */ +} ioc_fm_pcd_cc_stats_mode; + +/**************************************************************************//** + @Description Enumeration type for determining the action in case an IP packet + is larger than MTU but its DF (Don't Fragment) bit is set. +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_dont_frag_action { + e_IOC_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */ + e_IOC_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_IOC_FM_PCD_MANIP_DISCARD_PACKET, + /**< Obsolete, cannot enqueue to error queue; + In practice, selects to discard packets; + Will be removed in the future */ + e_IOC_FM_PCD_MANIP_FRAGMENT_PACKECT, /**< Fragment packet and continue normal processing */ + e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */ +} ioc_fm_pcd_manip_dont_frag_action; + +/**************************************************************************//** + @Description Enumeration type for selecting type of special offload manipulation +*//***************************************************************************/ +typedef enum ioc_fm_pcd_manip_special_offload_type { + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */ +#if (DPAA_VERSION >= 11) + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */ +#endif /* (DPAA_VERSION >= 11) */ +} ioc_fm_pcd_manip_special_offload_type; + +/**************************************************************************//** + @Description A union of protocol dependent special options + (Must match union u_FmPcdHdrProtocolOpt defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef union ioc_fm_pcd_hdr_protocol_opt_u { + ioc_eth_protocol_opt_t eth_opt; /**< Ethernet options */ + ioc_vlan_protocol_opt_t vlan_opt; /**< Vlan options */ + ioc_mpls_protocol_opt_t mpls_opt; /**< MPLS options */ + ioc_ipv4_protocol_opt_t ipv4_opt; /**< IPv4 options */ + ioc_ipv6_protocol_opt_t ipv6_opt; /**< IPv6 options */ +#if (DPAA_VERSION >= 11) + ioc_capwap_protocol_opt_t capwap_opt; /**< CAPWAP options */ +#endif /* (DPAA_VERSION >= 11) */ +} ioc_fm_pcd_hdr_protocol_opt_u; + +/**************************************************************************//** + @Description A union holding all known protocol fields +*//***************************************************************************/ +typedef union ioc_fm_pcd_fields_u { + ioc_header_field_eth_t eth; /**< Ethernet */ + ioc_header_field_vlan_t vlan; /**< VLAN */ + ioc_header_field_llc_snap_t llc_snap; /**< LLC SNAP */ + ioc_header_field_pppoe_t pppoe; /**< PPPoE */ + ioc_header_field_mpls_t mpls; /**< MPLS */ + ioc_header_field_ip_t ip; /**< IP */ + ioc_header_field_ipv4_t ipv4; /**< IPv4 */ + ioc_header_field_ipv6_t ipv6; /**< IPv6 */ + ioc_header_field_udp_t udp; /**< UDP */ + ioc_header_field_udp_lite_t udp_lite; /**< UDP_Lite */ + ioc_header_field_tcp_t tcp; /**< TCP */ + ioc_header_field_sctp_t sctp; /**< SCTP */ + ioc_header_field_dccp_t dccp; /**< DCCP */ + ioc_header_field_gre_t gre; /**< GRE */ + ioc_header_field_minencap_t minencap; /**< Minimal Encapsulation */ + ioc_header_field_ipsec_ah_t ipsec_ah; /**< IPSec AH */ + ioc_header_field_ipsec_esp_t ipsec_esp; /**< IPSec ESP */ + ioc_header_field_udp_encap_esp_t udp_encap_esp; /**< UDP Encapsulation ESP */ +} ioc_fm_pcd_fields_u; + +/**************************************************************************//** + @Description Parameters for defining header extraction for key generation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_from_hdr_t { + uint8_t size; /**< Size in byte */ + uint8_t offset; /**< Byte offset */ +} ioc_fm_pcd_from_hdr_t; + +/**************************************************************************//** + @Description Parameters for defining field extraction for key generation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_from_field_t { + ioc_fm_pcd_fields_u field; /**< Field selection */ + uint8_t size; /**< Size in byte */ + uint8_t offset; /**< Byte offset */ +} ioc_fm_pcd_from_field_t; + +/**************************************************************************//** + @Description Parameters for defining a single network environment unit + A distinction unit should be defined if it will later be used + by one or more PCD engines to distinguish between flows. + (Must match struct t_FmPcdDistinctionUnit defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_distinction_unit_t { + struct { + ioc_net_header_type hdr; /**< One of the headers supported by the FM */ + ioc_fm_pcd_hdr_protocol_opt_u opt; /**< Select only one option! */ + } hdrs[IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS]; +} ioc_fm_pcd_distinction_unit_t; + +/**************************************************************************//** + @Description Parameters for defining all different distinction units supported + by a specific PCD Network Environment Characteristics module. + + Each unit represent a protocol or a group of protocols that may + be used later by the different PCD engines to distinguish between flows. + (Must match struct t_FmPcdNetEnvParams defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_net_env_params_t { + uint8_t num_of_distinction_units;/**< Number of different units to be identified */ + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; + /**< An array of num_of_distinction_units of the + different units to be identified */ + void *id; /**< Output parameter; Returns the net-env Id to be used */ +} ioc_fm_pcd_net_env_params_t; + +/**************************************************************************//** + @Description Parameters for defining a single extraction action when + creating a key +*//***************************************************************************/ +typedef struct ioc_fm_pcd_extract_entry_t { + ioc_fm_pcd_extract_type type; /**< Extraction type select */ + union { + struct { + ioc_net_header_type hdr; /**< Header selection */ + bool ignore_protocol_validation; + /**< Ignore protocol validation */ + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled + IP. Otherwise should be cleared.*/ + ioc_fm_pcd_extract_by_hdr_type type; /**< Header extraction type select */ + union { + ioc_fm_pcd_from_hdr_t from_hdr; /**< Extract bytes from header parameters */ + ioc_fm_pcd_from_field_t from_field; /**< Extract bytes from field parameters */ + ioc_fm_pcd_fields_u full_field; /**< Extract full field parameters */ + } extract_by_hdr_type; + } extract_by_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */ + struct { + ioc_fm_pcd_extract_from src; /**< Non-header extraction source */ + ioc_fm_pcd_action action; /**< Relevant for CC Only */ + uint16_t ic_indx_mask; /**< Relevant only for CC when + action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP; + Note that the number of bits that are set within + this mask must be log2 of the CC-node 'num_of_keys'. + Note that the mask cannot be set on the lower bits. */ + uint8_t offset; /**< Byte offset */ + uint8_t size; /**< Size in bytes */ + } extract_non_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */ + } extract_params; +} ioc_fm_pcd_extract_entry_t; + +/**************************************************************************//** + @Description A structure for defining masks for each extracted + field in the key. +*//***************************************************************************/ +typedef struct ioc_fm_pcd_kg_extract_mask_t { + uint8_t extract_array_index; /**< Index in the extraction array, as initialized by user */ + uint8_t offset; /**< Byte offset */ + uint8_t mask; /**< A byte mask (selected bits will be ignored) */ +} ioc_fm_pcd_kg_extract_mask_t; + +/**************************************************************************//** + @Description A structure for defining default selection per groups + of fields +*//***************************************************************************/ +typedef struct ioc_fm_pcd_kg_extract_dflt_t { + ioc_fm_pcd_kg_known_fields_dflt_types type; /**< Default type select*/ + ioc_fm_pcd_kg_extract_dflt_select dflt_select; /**< Default register select */ +} ioc_fm_pcd_kg_extract_dflt_t; + + +/**************************************************************************//** + @Description A structure for defining all parameters needed for + generation a key and using a hash function +*//***************************************************************************/ +typedef struct ioc_fm_pcd_kg_key_extract_and_hash_params_t { + uint32_t private_dflt0; /**< Scheme default register 0 */ + uint32_t private_dflt1; /**< Scheme default register 1 */ + uint8_t num_of_used_extracts; /**< defines the valid size of the following array */ + ioc_fm_pcd_extract_entry_t extract_array [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; + /**< An array of extraction definitions. */ + uint8_t num_of_used_dflts; /**< defines the valid size of the following array */ + ioc_fm_pcd_kg_extract_dflt_t dflts[IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS]; + /**< For each extraction used in this scheme, specify the required + default register to be used when header is not found. + types not specified in this array will get undefined value. */ + uint8_t num_of_used_masks; /**< Defines the valid size of the following array */ + ioc_fm_pcd_kg_extract_mask_t masks[IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS]; + uint8_t hash_shift; /**< Hash result right shift. + Selects the 24 bits out of the 64 hash result. + 0 means using the 24 LSB's, otherwise use the + 24 LSB's after shifting right.*/ + uint32_t hash_distribution_num_of_fqids; /**< must be > 1 and a power of 2. Represents the range + of queues for the key and hash functionality */ + uint8_t hash_distribution_fqids_shift; /**< selects the FQID bits that will be effected by the hash */ + bool symmetric_hash; /**< TRUE to generate the same hash for frames with swapped source and + destination fields on all layers; If TRUE, driver will check that for + all layers, if SRC extraction is selected, DST extraction must also be + selected, and vice versa. */ +} ioc_fm_pcd_kg_key_extract_and_hash_params_t; + +/**************************************************************************//** + @Description A structure of parameters for defining a single + Qid mask (extracted OR). +*//***************************************************************************/ +typedef struct ioc_fm_pcd_kg_extracted_or_params_t { + ioc_fm_pcd_extract_type type; /**< Extraction type select */ + union { + struct { /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */ + ioc_net_header_type hdr; + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled + IP. Otherwise should be cleared.*/ + bool ignore_protocol_validation; + + } extract_by_hdr; + ioc_fm_pcd_extract_from src; /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */ + } extract_params; + uint8_t extraction_offset; /**< Offset for extraction */ + ioc_fm_pcd_kg_extract_dflt_select dflt_value; /**< Select register from which extraction is taken if + field not found */ + uint8_t mask; /**< Mask LSB byte of extraction (specified bits are ignored) */ + uint8_t bit_offset_in_fqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using + the extracted byte; Assume byte is placed as the 8 MSB's in + a 32 bit word where the lower bits + are the FQID; i.e if bitOffsetInFqid=1 than its LSB + will effect the FQID MSB, if bitOffsetInFqid=24 than the + extracted byte will effect the 8 LSB's of the FQID, + if bitOffsetInFqid=31 than the byte's MSB will effect + the FQID's LSB; 0 means - no effect on FQID; + Note that one, and only one of + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e, + extracted byte must effect either FQID or Policer profile).*/ + uint8_t bit_offset_in_plcr_profile; + /**< 0-15, Selects which bits of the 8 policer profile id bits to + effect using the extracted byte; Assume byte is placed + as the 8 MSB's in a 16 bit word where the lower bits + are the policer profile id; i.e if bitOffsetInPlcrProfile=1 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8 + than the extracted byte will effect the whole policer profile id, + if bitOffsetInFqid=15 than the byte's MSB will effect + the Policer Profile id's LSB; + 0 means - no effect on policer profile; Note that one, and only one of + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e, + extracted byte must effect either FQID or Policer profile).*/ +} ioc_fm_pcd_kg_extracted_or_params_t; + +/**************************************************************************//** + @Description A structure for configuring scheme counter +*//***************************************************************************/ +typedef struct ioc_fm_pcd_kg_scheme_counter_t { + bool update; /**< FALSE to keep the current counter state + and continue from that point, TRUE to update/reset + the counter when the scheme is written. */ + uint32_t value; /**< If update=TRUE, this value will be written into the + counter; clear this field to reset the counter. */ +} ioc_fm_pcd_kg_scheme_counter_t; + +/**************************************************************************//** + @Description A structure for defining policer profile parameters as required by keygen + (when policer is the next engine after this scheme). + (Must match struct t_FmPcdKgPlcrProfile defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_kg_plcr_profile_t { + bool shared_profile; /**< TRUE if this profile is shared between ports + (i.e. managed by master partition) May not be TRUE + if profile is after Coarse Classification*/ + bool direct; /**< If TRUE, direct_relative_profile_id only selects the profile + id, if FALSE fqid_offset_relative_profile_id_base is used + together with fqid_offset_shift and num_of_profiles + parameters, to define a range of profiles from + which the KeyGen result will determine the + destination policer profile. */ + union { + uint16_t direct_relative_profile_id; /**< Used if 'direct' is TRUE, to select policer profile. + This parameter should indicate the policer profile offset within the port's + policer profiles or SHARED window. */ + struct { + uint8_t fqid_offset_shift; /**< Shift of KG results without the qid base */ + uint8_t fqid_offset_relative_profile_id_base; + /**< OR of KG results without the qid base + This parameter should indicate the policer profile + offset within the port's policer profiles window + or SHARED window depends on shared_profile */ + uint8_t num_of_profiles; /**< Range of profiles starting at base */ + } indirect_profile; /**< Indirect profile parameters */ + } profile_select; /**< Direct/indirect profile selection and parameters */ +} ioc_fm_pcd_kg_plcr_profile_t; + +#if DPAA_VERSION >= 11 +/**************************************************************************//** + @Description Parameters for configuring a storage profile for a KeyGen scheme. +*//***************************************************************************/ +typedef struct ioc_fm_pcd_kg_storage_profile_t { + bool direct; /**< If TRUE, directRelativeProfileId only selects the + profile id; + If FALSE, fqidOffsetRelativeProfileIdBase is used + together with fqidOffsetShift and numOfProfiles + parameters to define a range of profiles from which + the KeyGen result will determine the destination + storage profile. */ + union { + uint16_t direct_relative_profileId; /**< Used when 'direct' is TRUE, to select a storage profile; + should indicate the storage profile offset within the + port's storage profiles window. */ + struct { + uint8_t fqid_offset_shift; /**< Shift of KeyGen results without the FQID base */ + uint8_t fqid_offset_relative_profile_id_base; + /**< OR of KeyGen results without the FQID base; + should indicate the policer profile offset within the + port's storage profiles window. */ + uint8_t num_of_profiles; /**< Range of profiles starting at base. */ + } indirect_profile; /**< Indirect profile parameters. */ + } profile_select; /**< Direct/indirect profile selection and parameters. */ +} ioc_fm_pcd_kg_storage_profile_t; +#endif /* DPAA_VERSION >= 11 */ + +/**************************************************************************//** + @Description Parameters for defining CC as the next engine after KeyGen + (Must match struct t_FmPcdKgCc defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_kg_cc_t { + void *tree_id; /**< CC Tree id */ + uint8_t grp_id; /**< CC group id within the CC tree */ + bool plcr_next; /**< TRUE if after CC, in case of data frame, + policing is required. */ + bool bypass_plcr_profile_generation; + /**< TRUE to bypass KeyGen policer profile generation; + selected profile is the one set at port initialization. */ + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Valid only if plcr_next = TRUE and + bypass_plcr_profile_generation = FALSE */ +} ioc_fm_pcd_kg_cc_t; + +/**************************************************************************//** + @Description Parameters for defining initializing a KeyGen scheme + (Must match struct t_FmPcdKgSchemeParams defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_kg_scheme_params_t { + bool modify; /**< TRUE to change an existing scheme */ + union { + uint8_t relative_scheme_id; + /**< if modify=FALSE: partition-relative scheme id */ + void *scheme_id; /**< if modify=TRUE: the id of an existing scheme */ + } scm_id; + bool always_direct; /**< This scheme is reached only directly, i.e. no need + for match vector; KeyGen will ignore it when matching */ + struct { /**< HL relevant only if always_direct=FALSE */ + void *net_env_id; /**< The id of the Network Environment as returned + by FM_PCD_NetEnvCharacteristicsSet() */ + uint8_t num_of_distinction_units; + /**< Number of NetEnv units listed in unit_ids array */ + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; + /**< Indexes as passed to SetNetEnvCharacteristics (?) array */ + } net_env_params; + bool use_hash; /**< use the KG Hash functionality */ + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params; + /**< used only if useHash = TRUE */ + bool bypass_fqid_generation; + /**< Normally - FALSE, TRUE to avoid FQID update in the IC; + In such a case FQID after KG will be the default FQID + defined for the relevant port, or the FQID defined by CC + in cases where CC was the previous engine. */ + uint32_t base_fqid; /**< Base FQID; Relevant only if bypass_fqid_generation = FALSE; + If hash is used and an even distribution is expected + according to hash_distribution_num_of_fqids, base_fqid must be aligned to + hash_distribution_num_of_fqids. */ + uint8_t num_of_used_extracted_ors; + /**< Number of FQID masks listed in extracted_ors array*/ + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS]; + /**< IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS + registers are shared between qid_masks + functionality and some of the extraction + actions; Normally only some will be used + for qid_mask. Driver will return error if + resource is full at initialization time. */ +#if DPAA_VERSION >= 11 + bool override_storage_profile; + /**< TRUE if KeyGen override previously decided storage profile */ + ioc_fm_pcd_kg_storage_profile_t storage_profile;/**< Used when override_storage_profile=TRUE */ +#endif /* DPAA_VERSION >= 11 */ + ioc_fm_pcd_engine next_engine; /**< may be BMI, PLCR or CC */ + union { /**< depends on nextEngine */ + ioc_fm_pcd_done_action done_action; /**< Used when next engine is BMI (done) */ + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Used when next engine is PLCR */ + ioc_fm_pcd_kg_cc_t cc; /**< Used when next engine is CC */ + } kg_next_engine_params; + ioc_fm_pcd_kg_scheme_counter_t scheme_counter; /**< A structure of parameters for updating + the scheme counter */ + void *id; /**< Returns the scheme Id to be used */ +} ioc_fm_pcd_kg_scheme_params_t; + +/**************************************************************************//** + @Collection +*//***************************************************************************/ +#if DPAA_VERSION >= 11 +#define IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */ +#define IOC_FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */ +#endif /* DPAA_VERSION >= 11 */ +#define IOC_FM_PCD_CC_STATS_FLR_COUNT_SIZE 4 /* Size in bytes of a frame length range counter */ +/* @} */ + +/**************************************************************************//** + @Description Parameters for defining CC as the next engine after a CC node. + (Must match struct t_FmPcdCcNextCcParams defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_cc_next_cc_params_t { + void *cc_node_id; /**< Id of the next CC node */ +} ioc_fm_pcd_cc_next_cc_params_t; + +#if DPAA_VERSION >= 11 +/**************************************************************************//** + @Description A structure for defining Frame Replicator as the next engine after a CC node. + (Must match struct t_FmPcdCcNextFrParams defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_cc_next_fr_params_t { + void* frm_replic_id; /**< The id of the next frame replicator group */ +} ioc_fm_pcd_cc_next_fr_params_t; +#endif /* DPAA_VERSION >= 11 */ + +/**************************************************************************//** + @Description A structure for defining PLCR params when PLCR is the + next engine after a CC node + (Must match struct t_FmPcdCcNextPlcrParams defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_cc_next_plcr_params_t { + bool override_params; /**< TRUE if CC override previously decided parameters*/ + bool shared_profile; /**< Relevant only if overrideParams=TRUE: + TRUE if this profile is shared between ports */ + uint16_t new_relative_profile_id; /**< Relevant only if overrideParams=TRUE: + (otherwise profile id is taken from keygen); + This parameter should indicate the policer + profile offset within the port's + policer profiles or from SHARED window.*/ + uint32_t new_fqid; /**< Relevant only if overrideParams=TRUE: + FQID for enquing the frame; + In earlier chips if policer next engine is KEYGEN, + this parameter can be 0, because the KEYGEN always decides + the enqueue FQID.*/ +#if DPAA_VERSION >= 11 + uint8_t new_relative_storage_profile_id; + /**< Indicates the relative storage profile offset within + the port's storage profiles window; + Relevant only if the port was configured with VSP. */ +#endif /* DPAA_VERSION >= 11 */ +} ioc_fm_pcd_cc_next_plcr_params_t; + +/**************************************************************************//** + @Description A structure for defining enqueue params when BMI is the + next engine after a CC node + (Must match struct t_FmPcdCcNextEnqueueParams defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_cc_next_enqueue_params_t { + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */ + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid, + relevant if action = e_IOC_FM_PCD_ENQ_FRAME */ + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame + (otherwise FQID is taken from KeyGen), + relevant if action = e_IOC_FM_PCD_ENQ_FRAME*/ +#if DPAA_VERSION >= 11 + uint8_t new_relative_storage_profile_id; + /**< Valid if override_fqid=TRUE, Indicates the relative virtual + storage profile offset within the port's storage profiles + window; Relevant only if the port was configured with VSP. */ +#endif /* DPAA_VERSION >= 11 */ + +} ioc_fm_pcd_cc_next_enqueue_params_t; + +/**************************************************************************//** + @Description A structure for defining KG params when KG is the next engine after a CC node + (Must match struct t_FmPcdCcNextKgParams defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_cc_next_kg_params_t { + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid, + Note - this parameters are irrelevant for earlier chips */ + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame + (otherwise FQID is taken from KeyGen), + Note - this parameters are irrelevant for earlier chips */ +#if DPAA_VERSION >= 11 + uint8_t new_relative_storage_profile_id; + /**< Valid if override_fqid=TRUE, Indicates the relative virtual + storage profile offset within the port's storage profiles + window; Relevant only if the port was configured with VSP. */ +#endif /* DPAA_VERSION >= 11 */ + void *p_direct_scheme; /**< Direct scheme id to go to. */ +} ioc_fm_pcd_cc_next_kg_params_t; + +/**************************************************************************//** + @Description Parameters for defining the next engine after a CC node. + (Must match struct t_FmPcdCcNextEngineParams defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_cc_next_engine_params_t { + ioc_fm_pcd_engine next_engine; /**< User has to initialize parameters + according to nextEngine definition */ + union { + ioc_fm_pcd_cc_next_cc_params_t cc_params; /**< Parameters in case next engine is CC */ + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< Parameters in case next engine is PLCR */ + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< Parameters in case next engine is BMI */ + ioc_fm_pcd_cc_next_kg_params_t kg_params; /**< Parameters in case next engine is KG */ +#if DPAA_VERSION >= 11 + ioc_fm_pcd_cc_next_fr_params_t fr_params; /**< Parameters in case next engine is FR */ +#endif /* DPAA_VERSION >= 11 */ + } params; /**< Union used for all the next-engine parameters options */ + void *manip_id; /**< Handle to Manipulation object. + Relevant if next engine is of type result + (e_IOC_FM_PCD_PLCR, e_IOC_FM_PCD_KG, e_IOC_FM_PCD_DONE) */ + bool statistics_en; /**< If TRUE, statistics counters are incremented + for each frame passing through this + Coarse Classification entry. */ +} ioc_fm_pcd_cc_next_engine_params_t; + +/**************************************************************************//** + @Description Parameters for defining a single CC key +*//***************************************************************************/ +typedef struct ioc_fm_pcd_cc_key_params_t { + uint8_t *p_key; /**< pointer to the key of the size defined in key_size */ + uint8_t *p_mask; /**< pointer to the Mask per key of the size defined + in keySize. p_key and p_mask (if defined) has to be + of the same size defined in the key_size */ + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params; + /**< parameters for the next for the defined Key in p_key */ + +} ioc_fm_pcd_cc_key_params_t; + +/**************************************************************************//** + @Description Parameters for defining CC keys parameters + The driver supports two methods for CC node allocation: dynamic and static. + Static mode was created in order to prevent runtime alloc/free + of FMan memory (MURAM), which may cause fragmentation; in this mode, + the driver automatically allocates the memory according to + 'max_num_of_keys' parameter. The driver calculates the maximal memory + size that may be used for this CC-Node taking into consideration + 'mask_support' and 'statistics_mode' parameters. + When 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction + parameters of this node, 'max_num_of_keys' must be equal to 'num_of_keys'. + In dynamic mode, 'max_num_of_keys' must be zero. At initialization, + all required structures are allocated according to 'num_of_keys' + parameter. During runtime modification, these structures are + re-allocated according to the updated number of keys. + + Please note that 'action' and 'ic_indx_mask' mentioned in the + specific parameter explanations are passed in the extraction + parameters of the node (fields of extractccparams.extractnonhdr). +*//***************************************************************************/ +typedef struct ioc_keys_params_t { + uint16_t max_num_of_keys;/**< Maximum number of keys that will (ever) be used in this CC-Node; + A value of zero may be used for dynamic memory allocation. */ + bool mask_support; /**< This parameter is relevant only if a node is initialized with + action = e_IOC_FM_PCD_ACTION_EXACT_MATCH and max_num_of_keys > 0; + Should be TRUE to reserve table memory for key masks, even if + initial keys do not contain masks, or if the node was initialized + as 'empty' (without keys); this will allow user to add keys with + masks at runtime. */ + ioc_fm_pcd_cc_stats_mode statistics_mode;/**< Determines the supported statistics mode for all node's keys. + To enable statistics gathering, statistics should be enabled per + every key, using 'statistics_en' in next engine parameters structure + of that key; + If 'max_num_of_keys' is set, all required structures will be + preallocated for all keys. */ +#if (DPAA_VERSION >= 11) + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR]; + /**< Relevant only for 'RMON' statistics mode + (this feature is supported only on B4860 device); + Holds a list of programmable thresholds. For each received frame, + its length in bytes is examined against these range thresholds and + the appropriate counter is incremented by 1. For example, to belong + to range i, the following should hold: + range i-1 threshold < frame length <= range i threshold + Each range threshold must be larger then its preceding range + threshold. Last range threshold must be 0xFFFF. */ +#endif /* (DPAA_VERSION >= 11) */ + uint16_t num_of_keys; /**< Number of initial keys; + Note that in case of 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP, + this field should be power-of-2 of the number of bits that are + set in 'ic_indx_mask'. */ + uint8_t key_size; /**< Size of key - for extraction of type FULL_FIELD, 'key_size' has + to be the standard size of the selected key; For other extraction + types, 'key_size' has to be as size of extraction; When 'action' = + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */ + ioc_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS]; + /**< An array with 'num_of_keys' entries, each entry specifies the + corresponding key parameters; + When 'action' = e_IOC_FM_PCD_ACTION_EXACT_MATCH, this value must not + exceed 255 (IOC_FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved + for the 'miss' entry. */ + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss; + /**< Parameters for defining the next engine when a key is not matched; + Not relevant if action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP. */ +} ioc_keys_params_t; + +/**************************************************************************//** + @Description Parameters for defining a CC node +*//***************************************************************************/ +typedef struct ioc_fm_pcd_cc_node_params_t { + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< Extraction parameters */ + ioc_keys_params_t keys_params; /**< Keys definition matching the selected extraction */ + void *id; /**< Output parameter; returns the CC node Id to be used */ +} ioc_fm_pcd_cc_node_params_t; + +/**************************************************************************//** + @Description Parameters for defining a hash table + (Must match struct t_FmPcdHashTableParams defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_hash_table_params_t { + uint16_t max_num_of_keys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */ + ioc_fm_pcd_cc_stats_mode statistics_mode; /**< If not e_IOC_FM_PCD_CC_STATS_MODE_NONE, the required structures for the + requested statistics mode will be allocated according to max_num_of_keys. */ + uint8_t kg_hash_shift; /**< KG-Hash-shift as it was configured in the KG-scheme + that leads to this hash-table. */ + uint16_t hash_res_mask; /**< Mask that will be used on the hash-result; + The number-of-sets for this hash will be calculated + as (2^(number of bits set in 'hash_res_mask')); + The 4 lower bits must be cleared. */ + uint8_t hash_shift; /**< Byte offset from the beginning of the KeyGen hash result to the + 2-bytes to be used as hash index. */ + uint8_t match_key_size; /**< Size of the exact match keys held by the hash buckets */ + + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss; + /**< Parameters for defining the next engine when a key is not matched */ + void *id; +} ioc_fm_pcd_hash_table_params_t; + +/**************************************************************************//** + @Description A structure with the arguments for the FM_PCD_HashTableAddKey ioctl() call +*//***************************************************************************/ +typedef struct ioc_fm_pcd_hash_table_add_key_params_t { + void *p_hash_tbl; + uint8_t key_size; + ioc_fm_pcd_cc_key_params_t key_params; +} ioc_fm_pcd_hash_table_add_key_params_t; + +/**************************************************************************//** + @Description Parameters for defining a CC tree group. + + This structure defines a CC group in terms of NetEnv units + and the action to be taken in each case. The unit_ids list must + be given in order from low to high indices. + + ioc_fm_pcd_cc_next_engine_params_t is a list of 2^num_of_distinction_units + structures where each defines the next action to be taken for + each units combination. for example: + num_of_distinction_units = 2 + unit_ids = {1,3} + next_engine_per_entries_in_grp[0] = ioc_fm_pcd_cc_next_engine_params_t for the case that + unit 1 - not found; unit 3 - not found; + next_engine_per_entries_in_grp[1] = ioc_fm_pcd_cc_next_engine_params_t for the case that + unit 1 - not found; unit 3 - found; + next_engine_per_entries_in_grp[2] = ioc_fm_pcd_cc_next_engine_params_t for the case that + unit 1 - found; unit 3 - not found; + next_engine_per_entries_in_grp[3] = ioc_fm_pcd_cc_next_engine_params_t for the case that + unit 1 - found; unit 3 - found; +*//***************************************************************************/ +typedef struct ioc_fm_pcd_cc_grp_params_t { + uint8_t num_of_distinction_units; /**< Up to 4 */ + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS]; + /**< Indexes of the units as defined in + FM_PCD_NetEnvCharacteristicsSet() */ + ioc_fm_pcd_cc_next_engine_params_t next_engine_per_entries_in_grp[IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP]; + /**< Maximum entries per group is 16 */ +} ioc_fm_pcd_cc_grp_params_t; + +/**************************************************************************//** + @Description Parameters for defining the CC tree groups + (Must match struct t_FmPcdCcTreeParams defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_cc_tree_params_t { + void *net_env_id; /**< Id of the Network Environment as returned + by FM_PCD_NetEnvCharacteristicsSet() */ + uint8_t num_of_groups; /**< Number of CC groups within the CC tree */ + ioc_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS]; + /**< Parameters for each group. */ + void *id; /**< Output parameter; Returns the tree Id to be used */ +} ioc_fm_pcd_cc_tree_params_t; + +/**************************************************************************//** + @Description Parameters for defining policer byte rate +*//***************************************************************************/ +typedef struct ioc_fm_pcd_plcr_byte_rate_mode_param_t { + ioc_fm_pcd_plcr_frame_length_select frame_length_selection; /**< Frame length selection */ + ioc_fm_pcd_plcr_roll_back_frame_select roll_back_frame_selection; /**< relevant option only e_IOC_FM_PCD_PLCR_L2_FRM_LEN, + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN */ +} ioc_fm_pcd_plcr_byte_rate_mode_param_t; + +/**************************************************************************//** + @Description Parameters for defining the policer profile (based on + RFC-2698 or RFC-4115 attributes). +*//***************************************************************************/ +typedef struct ioc_fm_pcd_plcr_non_passthrough_alg_param_t { + ioc_fm_pcd_plcr_rate_mode rate_mode; /**< Byte / Packet */ + ioc_fm_pcd_plcr_byte_rate_mode_param_t byte_mode_param; /**< Valid for Byte NULL for Packet */ + uint32_t comitted_info_rate; /**< KBits/Sec or Packets/Sec */ + uint32_t comitted_burst_size; /**< KBits or Packets */ + uint32_t peak_or_accessive_info_rate; /**< KBits/Sec or Packets/Sec */ + uint32_t peak_or_accessive_burst_size; /**< KBits or Packets */ +} ioc_fm_pcd_plcr_non_passthrough_alg_param_t; + +/**************************************************************************//** + @Description Parameters for defining the next engine after policer +*//***************************************************************************/ +typedef union ioc_fm_pcd_plcr_next_engine_params_u { + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */ + void *p_profile; /**< Policer profile handle - used when next engine + is PLCR, must be a SHARED profile */ + void *p_direct_scheme; /**< Direct scheme select - when next engine is Keygen */ +} ioc_fm_pcd_plcr_next_engine_params_u; + +typedef struct ioc_fm_pcd_port_params_t { + ioc_fm_port_type port_type; /**< Type of port for this profile */ + uint8_t port_id; /**< FM-Port id of port for this profile */ +} ioc_fm_pcd_port_params_t; + +/**************************************************************************//** + @Description Parameters for defining the policer profile entry + (Must match struct t_FmPcdPlcrProfileParams defined in fm_pcd_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_plcr_profile_params_t { + bool modify; /**< TRUE to change an existing profile */ + union { + struct { + ioc_fm_pcd_profile_type_selection profile_type; /**< Type of policer profile */ + ioc_fm_pcd_port_params_t *p_fm_port; /**< Relevant for per-port profiles only */ + uint16_t relative_profile_id; /**< Profile id - relative to shared group or to port */ + } new_params; /**< Use it when modify = FALSE */ + void *p_profile; /**< A handle to a profile - use it when modify=TRUE */ + } profile_select; + ioc_fm_pcd_plcr_algorithm_selection alg_selection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */ + ioc_fm_pcd_plcr_color_mode color_mode; /**< COLOR_BLIND, COLOR_AWARE */ + + union { + ioc_fm_pcd_plcr_color dflt_color; /**< For Color-Blind Pass-Through mode; the policer will re-color + any incoming packet with the default value. */ + ioc_fm_pcd_plcr_color override; /**< For Color-Aware modes; the profile response to a + pre-color value of 2'b11. */ + } color; + + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param; /**< RFC2698 or RFC4115 parameters */ + + ioc_fm_pcd_engine next_engine_on_green; /**< Next engine for green-colored frames */ + ioc_fm_pcd_plcr_next_engine_params_u params_on_green; /**< Next engine parameters for green-colored frames */ + + ioc_fm_pcd_engine next_engine_on_yellow; /**< Next engine for yellow-colored frames */ + ioc_fm_pcd_plcr_next_engine_params_u params_on_yellow; /**< Next engine parameters for yellow-colored frames */ + + ioc_fm_pcd_engine next_engine_on_red; /**< Next engine for red-colored frames */ + ioc_fm_pcd_plcr_next_engine_params_u params_on_red; /**< Next engine parameters for red-colored frames */ + + bool trap_profile_on_flow_A; /**< Obsolete - do not use */ + bool trap_profile_on_flow_B; /**< Obsolete - do not use */ + bool trap_profile_on_flow_C; /**< Obsolete - do not use */ + + void *id; /**< output parameter; Returns the profile Id to be used */ +} ioc_fm_pcd_plcr_profile_params_t; + +/**************************************************************************//** + @Description A structure for modifying CC tree next engine +*//***************************************************************************/ +typedef struct ioc_fm_pcd_cc_tree_modify_next_engine_params_t { + void *id; /**< CC tree Id to be used */ + uint8_t grp_indx; /**< A Group index in the tree */ + uint8_t indx; /**< Entry index in the group defined by grp_index */ + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params; + /**< Parameters for the next for the defined Key in the p_Key */ +} ioc_fm_pcd_cc_tree_modify_next_engine_params_t; + +/**************************************************************************//** + @Description A structure for modifying CC node next engine +*//***************************************************************************/ +typedef struct ioc_fm_pcd_cc_node_modify_next_engine_params_t { + void *id; /**< CC node Id to be used */ + uint16_t key_indx; /**< Key index for Next Engine Params modifications; + NOTE: This parameter is IGNORED for miss-key! */ + uint8_t key_size; /**< Key size of added key */ + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params; + /**< parameters for the next for the defined Key in the p_Key */ +} ioc_fm_pcd_cc_node_modify_next_engine_params_t; + +/**************************************************************************//** + @Description A structure for remove CC node key +*//***************************************************************************/ +typedef struct ioc_fm_pcd_cc_node_remove_key_params_t { + void *id; /**< CC node Id to be used */ + uint16_t key_indx; /**< Key index for Next Engine Params modifications; + NOTE: This parameter is IGNORED for miss-key! */ +} ioc_fm_pcd_cc_node_remove_key_params_t; + +/**************************************************************************//** + @Description A structure for modifying CC node key and next engine +*//***************************************************************************/ +typedef struct ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t { + void *id; /**< CC node Id to be used */ + uint16_t key_indx; /**< Key index for Next Engine Params modifications; + NOTE: This parameter is IGNORED for miss-key! */ + uint8_t key_size; /**< Key size of added key */ + ioc_fm_pcd_cc_key_params_t key_params; /**< it's array with numOfKeys entries each entry in + the array of the type ioc_fm_pcd_cc_key_params_t */ +} ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t; + +/**************************************************************************//** + @Description A structure for modifying CC node key +*//***************************************************************************/ +typedef struct ioc_fm_pcd_cc_node_modify_key_params_t { + void *id; /**< CC node Id to be used */ + uint16_t key_indx; /**< Key index for Next Engine Params modifications; + NOTE: This parameter is IGNORED for miss-key! */ + uint8_t key_size; /**< Key size of added key */ + uint8_t *p_key; /**< Pointer to the key of the size defined in key_size */ + uint8_t *p_mask; /**< Pointer to the Mask per key of the size defined + in keySize. p_Key and p_Mask (if defined) have to be + of the same size as defined in the key_size */ +} ioc_fm_pcd_cc_node_modify_key_params_t; + +/**************************************************************************//** + @Description A structure with the arguments for the FM_PCD_HashTableRemoveKey ioctl() call +*//***************************************************************************/ +typedef struct ioc_fm_pcd_hash_table_remove_key_params_t { + void *p_hash_tbl; /**< The id of the hash table */ + uint8_t key_size; /**< The size of the key to remove */ + uint8_t *p_key; /**< Pointer to the key to remove */ +} ioc_fm_pcd_hash_table_remove_key_params_t; + +/**************************************************************************//** + @Description Parameters for selecting a location for requested manipulation +*//***************************************************************************/ +typedef struct ioc_fm_manip_hdr_info_t { + ioc_net_header_type hdr; /**< Header selection */ + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */ + bool by_field; /**< TRUE if the location of manipulation is according to some field in the specific header*/ + ioc_fm_pcd_fields_u full_field; /**< Relevant only when by_field = TRUE: Extract field */ +} ioc_fm_manip_hdr_info_t; + +/**************************************************************************//** + @Description Parameters for defining header removal by header type +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t { + ioc_fm_pcd_manip_hdr_rmv_by_hdr_type type; /**< Selection of header removal location */ + union { +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) + struct { + bool include;/**< If FALSE, remove until the specified header (not including the header); + If TRUE, remove also the specified header. */ + ioc_fm_manip_hdr_info_t hdr_info; + } from_start_by_hdr; /**< Relevant when type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */ +#endif /* FM_CAPWAP_SUPPORT */ +#if (DPAA_VERSION >= 11) + ioc_fm_manip_hdr_info_t hdr_info; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */ +#endif /* (DPAA_VERSION >= 11) */ + ioc_fm_pcd_manip_hdr_rmv_specific_l2 specific_l2;/**< Relevant when type = e_IOC_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2; + Defines which L2 headers to remove. */ + } u; +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t; + +/**************************************************************************//** + @Description Parameters for configuring IP fragmentation manipulation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_frag_ip_params_t { + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value, + IP fragmentation will be executed.*/ +#if DPAA_VERSION == 10 + uint8_t scratch_bpid; /**< Absolute buffer pool id according to BM configuration.*/ +#endif /* DPAA_VERSION == 10 */ + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation; + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the + received frame's buffer. */ + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id; + This parameter is relevant when 'sg_bpid_en=TRUE'; + Same LIODN number is used for these buffers as for the received frames buffers, so buffers + of this pool need to be allocated in the same memory area as the received buffers. + If the received buffers arrive from different sources, the Scatter/Gather BP id should be + mutual to all these sources. */ + ioc_fm_pcd_manip_dont_frag_action dont_frag_action; /**< Dont Fragment Action - If an IP packet is larger + than MTU and its DF bit is set, then this field will + determine the action to be taken.*/ +} ioc_fm_pcd_manip_frag_ip_params_t; + +/**************************************************************************//** + @Description Parameters for configuring IP reassembly manipulation. + + This is a common structure for both IPv4 and IPv6 reassembly + manipulation. For reassembly of both IPv4 and IPv6, make sure to + set the 'hdr' field in ioc_fm_pcd_manip_reassem_params_t to IOC_HEADER_TYPE_IPv6. +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_reassem_ip_params_t { + uint8_t relative_scheme_id[2]; /**< Partition relative scheme id: + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation; + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation; + NOTE: The following comment is relevant only for FMAN v2 devices: + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than + the user schemes id to ensure that the reassembly's schemes will be first match. + The remaining schemes, if defined, should have higher relative scheme ID. */ +#if DPAA_VERSION >= 11 + uint32_t non_consistent_sp_fqid; /**< In case that other fragments of the frame corresponds to different storage + profile than the opening fragment (Non-Consistent-SP state) + then one of two possible scenarios occurs: + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/ +#else + uint8_t sg_bpid; /**< Buffer pool id for the S/G frame created by the reassembly process */ +#endif /* DPAA_VERSION >= 11 */ + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */ + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */ + uint16_t min_frag_size[2]; /**< Minimum fragment size: + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */ + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry[2]; + /**< Number of frames per hash entry needed for reassembly process: + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH); + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH). */ + uint16_t max_num_frames_in_process;/**< Number of frames which can be processed by Reassembly in the same time; + Must be power of 2; + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH, + maxNumFramesInProcess has to be in the range of 4 - 512; + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH, + maxNumFramesInProcess has to be in the range of 8 - 2048. */ + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */ + uint32_t fqid_for_time_out_frames;/**< FQID in which time out frames will enqueue during Time Out Process */ + uint32_t timeout_threshold_for_reassm_process; + /**< Represents the time interval in microseconds which defines + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/ +} ioc_fm_pcd_manip_reassem_ip_params_t; + +/**************************************************************************//** + @Description Parameters for defining IPSEC manipulation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_special_offload_ipsec_params_t { + bool decryption; /**< TRUE if being used in decryption direction; + FALSE if being used in encryption direction. */ + bool ecn_copy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner + (direction depends on the 'decryption' field). */ + bool dscp_copy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner + (direction depends on the 'decryption' field). */ + bool variable_ip_hdr_len; /**< TRUE for supporting variable IP header length in decryption. */ + bool variable_ip_version; /**< TRUE for supporting both IP version on the same SA in encryption */ + uint8_t outer_ip_hdr_len; /**< If 'variable_ip_version == TRUE' than this field must be set to non-zero value; + It is specifies the length of the outer IP header that was configured in the + corresponding SA. */ +} ioc_fm_pcd_manip_special_offload_ipsec_params_t; + +#if (DPAA_VERSION >= 11) +/**************************************************************************//** + @Description Parameters for configuring CAPWAP fragmentation manipulation + + Restrictions: + - Maximum number of fragments per frame is 16. + - Transmit confirmation is not supported. + - Fragmentation nodes must be set as the last PCD action (i.e. the + corresponding CC node key must have next engine set to e_FM_PCD_DONE). + - Only BMan buffers shall be used for frames to be fragmented. + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF + does not support VSP. Therefore, on the same port where we have IPF we + cannot support VSP. +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_frag_capwap_params_t { + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value, + CAPWAP fragmentation will be executed.*/ + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation; + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the + received frame's buffer. */ + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id; + This parameters is relevant when 'sgBpidEn=TRUE'; + Same LIODN number is used for these buffers as for the received frames buffers, so buffers + of this pool need to be allocated in the same memory area as the received buffers. + If the received buffers arrive from different sources, the Scatter/Gather BP id should be + mutual to all these sources. */ + bool compress_mode_en; /**< CAPWAP Header Options Compress Enable mode; + When this mode is enabled then only the first fragment include the CAPWAP header options + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP + options field (CAPWAP header is updated accordingly).*/ +} ioc_fm_pcd_manip_frag_capwap_params_t; + +/**************************************************************************//** + @Description Parameters for configuring CAPWAP reassembly manipulation. + + Restrictions: + - Application must define one scheme to catch the reassembled frames. + - Maximum number of fragments per frame is 16. + +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_reassem_capwap_params_t { + uint8_t relative_scheme_id; /**< Partition relative scheme id; + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match; + Rest schemes, if defined, should have higher relative scheme ID. */ + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */ + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */ + uint16_t max_reassembled_frame_length;/**< The maximum CAPWAP reassembled frame length in bytes; + If maxReassembledFrameLength == 0, any successful reassembled frame length is + considered as a valid length; + if maxReassembledFrameLength > 0, a successful reassembled frame which its length + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */ + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry; + /**< Number of frames per hash entry needed for reassembly process */ + uint16_t max_num_frames_in_process; /**< Number of frames which can be processed by reassembly in the same time; + Must be power of 2; + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH, + maxNumFramesInProcess has to be in the range of 4 - 512; + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH, + maxNumFramesInProcess has to be in the range of 8 - 2048. */ + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */ + uint32_t fqid_for_time_out_frames; /**< FQID in which time out frames will enqueue during Time Out Process; + Recommended value for this field is 0; in this way timed-out frames will be discarded */ + uint32_t timeout_threshold_for_reassm_process; + /**< Represents the time interval in microseconds which defines + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/ +} ioc_fm_pcd_manip_reassem_capwap_params_t; + +/**************************************************************************//** + @Description structure for defining CAPWAP manipulation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_special_offload_capwap_params_t { + bool dtls; /**< TRUE if continue to SEC DTLS encryption */ + ioc_fm_pcd_manip_hdr_qos_src qos_src; /**< TODO */ +} ioc_fm_pcd_manip_special_offload_capwap_params_t; + +#endif /* (DPAA_VERSION >= 11) */ + +/**************************************************************************//** + @Description Parameters for defining special offload manipulation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_special_offload_params_t { + ioc_fm_pcd_manip_special_offload_type type; /**< Type of special offload manipulation */ + union + { + ioc_fm_pcd_manip_special_offload_ipsec_params_t ipsec; /**< Parameters for IPSec; Relevant when + type = e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */ + +#if (DPAA_VERSION >= 11) + ioc_fm_pcd_manip_special_offload_capwap_params_t capwap; /**< Parameters for CAPWAP; Relevant when + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */ +#endif /* (DPAA_VERSION >= 11) */ + } u; +} ioc_fm_pcd_manip_special_offload_params_t; + +/**************************************************************************//** + @Description Parameters for defining generic removal manipulation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_rmv_generic_params_t { + uint8_t offset; /**< Offset from beginning of header to the start + location of the removal */ + uint8_t size; /**< Size of removed section */ +} ioc_fm_pcd_manip_hdr_rmv_generic_params_t; + +/**************************************************************************//** + @Description Parameters for defining insertion manipulation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_insrt_t { + uint8_t size; /**< size of inserted section */ + uint8_t *p_data; /**< data to be inserted */ +} ioc_fm_pcd_manip_hdr_insrt_t; + +/**************************************************************************//** + @Description Parameters for defining generic insertion manipulation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_insrt_generic_params_t { + uint8_t offset; /**< Offset from beginning of header to the start + location of the insertion */ + uint8_t size; /**< Size of inserted section */ + bool replace; /**< TRUE to override (replace) existing data at + 'offset', FALSE to insert */ + uint8_t *p_data; /**< Pointer to data to be inserted */ +} ioc_fm_pcd_manip_hdr_insrt_generic_params_t; + +/**************************************************************************//** + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t { + uint8_t dscp_to_vpri_table[IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS]; + /**< A table of VPri values for each DSCP value; + The index is the D_SCP value (0-0x3F) and the + value is the corresponding VPRI (0-15). */ + uint8_t vpri_def_val; /**< 0-7, Relevant only if if update_type = + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN, + this field is the Q Tag default value if the + IP header is not found. */ +} ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t; + +/**************************************************************************//** + @Description Parameters for defining header manipulation VLAN fields updates +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_t { + ioc_fm_pcd_manip_hdr_field_update_vlan update_type; /**< Selects VLAN update type */ + union { + uint8_t vpri; /**< 0-7, Relevant only if If update_type = + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this + is the new VLAN pri. */ + ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t dscp_to_vpri; + /**< Parameters structure, Relevant only if update_type = + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */ + } u; +} ioc_fm_pcd_manip_hdr_field_update_vlan_t; + +/**************************************************************************//** + @Description Parameters for defining header manipulation IPV4 fields updates +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv4_t { + ioc_ipv4_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */ + uint8_t tos; /**< 8 bit New TOS; Relevant if valid_updates contains + IOC_HDR_MANIP_IPV4_TOS */ + uint16_t id; /**< 16 bit New IP ID; Relevant only if valid_updates + contains IOC_HDR_MANIP_IPV4_ID */ + uint32_t src; /**< 32 bit New IP SRC; Relevant only if valid_updates + contains IOC_HDR_MANIP_IPV4_SRC */ + uint32_t dst; /**< 32 bit New IP DST; Relevant only if valid_updates + contains IOC_HDR_MANIP_IPV4_DST */ +} ioc_fm_pcd_manip_hdr_field_update_ipv4_t; + +/**************************************************************************//** + @Description Parameters for defining header manipulation IPV6 fields updates +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv6_t { + ioc_ipv6_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */ + uint8_t traffic_class; /**< 8 bit New Traffic Class; Relevant if valid_updates contains + IOC_HDR_MANIP_IPV6_TC */ + uint8_t src[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE]; + /**< 16 byte new IP SRC; Relevant only if valid_updates + contains IOC_HDR_MANIP_IPV6_SRC */ + uint8_t dst[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE]; + /**< 16 byte new IP DST; Relevant only if valid_updates + contains IOC_HDR_MANIP_IPV6_DST */ +} ioc_fm_pcd_manip_hdr_field_update_ipv6_t; + +/**************************************************************************//** + @Description Parameters for defining header manipulation TCP/UDP fields updates +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t { + ioc_tcp_udp_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */ + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if valid_updates + contains IOC_HDR_MANIP_TCP_UDP_SRC */ + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if valid_updates + contains IOC_HDR_MANIP_TCP_UDP_DST */ +} ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t; + +/**************************************************************************//** + @Description Parameters for defining header manipulation fields updates +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_field_update_params_t { + ioc_fm_pcd_manip_hdr_field_update_type type; /**< Type of header field update manipulation */ + union { + ioc_fm_pcd_manip_hdr_field_update_vlan_t vlan; /**< Parameters for VLAN update. Relevant when + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */ + ioc_fm_pcd_manip_hdr_field_update_ipv4_t ipv4; /**< Parameters for IPv4 update. Relevant when + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */ + ioc_fm_pcd_manip_hdr_field_update_ipv6_t ipv6; /**< Parameters for IPv6 update. Relevant when + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */ + ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t tcp_udp;/**< Parameters for TCP/UDP update. Relevant when + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */ + } u; +} ioc_fm_pcd_manip_hdr_field_update_params_t; + +/**************************************************************************//** + @Description Parameters for defining custom header manipulation for IP replacement +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t { + ioc_fm_pcd_manip_hdr_custom_ip_replace replace_type; /**< Selects replace update type */ + bool dec_ttl_hl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */ + bool update_ipv4_id; /**< Relevant when replace_type = + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */ + uint16_t id; /**< 16 bit New IP ID; Relevant only if + update_ipv4_id = TRUE */ + uint8_t hdr_size; /**< The size of the new IP header */ + uint8_t hdr[IOC_FM_PCD_MANIP_MAX_HDR_SIZE]; + /**< The new IP header */ +} ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t; + +/**************************************************************************//** + @Description Parameters for defining custom header manipulation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_custom_params_t { + ioc_fm_pcd_manip_hdr_custom_type type; /**< Type of header field update manipulation */ + union { + ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t ip_hdr_replace; + /**< Parameters IP header replacement */ + } u; +} ioc_fm_pcd_manip_hdr_custom_params_t; + +/**************************************************************************//** + @Description Parameters for defining specific L2 insertion manipulation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t { + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2; /**< Selects which L2 headers to insert */ + bool update; /**< TRUE to update MPLS header */ + uint8_t size; /**< size of inserted section */ + uint8_t *p_data; /**< data to be inserted */ +} ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t; + +#if (DPAA_VERSION >= 11) +/**************************************************************************//** + @Description Parameters for defining IP insertion manipulation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_insrt_ip_params_t { + bool calc_l4_checksum; /**< Calculate L4 checksum. */ + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */ + uint8_t last_pid_offset; /**< the offset of the last Protocol within + the inserted header */ + uint16_t id; /**< 16 bit New IP ID */ + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */ +} ioc_fm_pcd_manip_hdr_insrt_ip_params_t; +#endif /* (DPAA_VERSION >= 11) */ + +/**************************************************************************//** + @Description Parameters for defining header insertion manipulation by header type +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t { + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type; /**< Selects manipulation type */ + union { + ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params; + /**< Used when type = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2: + Selects which L2 headers to remove */ +#if (DPAA_VERSION >= 11) + ioc_fm_pcd_manip_hdr_insrt_ip_params_t ip_params; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */ + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP, + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */ +#endif /* (DPAA_VERSION >= 11) */ + } u; +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t; + +/**************************************************************************//** + @Description Parameters for defining header insertion manipulation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_insrt_params_t { + ioc_fm_pcd_manip_hdr_insrt_type type; /**< Type of insertion manipulation */ + union { + ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr; /**< Parameters for defining header insertion manipulation by header type, + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR */ + ioc_fm_pcd_manip_hdr_insrt_generic_params_t generic;/**< Parameters for defining generic header insertion manipulation, + relevant if type = e_IOC_FM_PCD_MANIP_INSRT_GENERIC */ +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template; + /**< Parameters for defining header insertion manipulation by template, + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE */ +#endif /* FM_CAPWAP_SUPPORT */ + } u; +} ioc_fm_pcd_manip_hdr_insrt_params_t; + +/**************************************************************************//** + @Description Parameters for defining header removal manipulation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_rmv_params_t { + ioc_fm_pcd_manip_hdr_rmv_type type; /**< Type of header removal manipulation */ + union { + ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t by_hdr; /**< Parameters for defining header removal manipulation by header type, + relevant if type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR */ + ioc_fm_pcd_manip_hdr_rmv_generic_params_t generic; /**< Parameters for defining generic header removal manipulation, + relevant if type = e_IOC_FM_PCD_MANIP_RMV_GENERIC */ + } u; +} ioc_fm_pcd_manip_hdr_rmv_params_t; + +/**************************************************************************//** + @Description Parameters for defining header manipulation node +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_hdr_params_t { + bool rmv; /**< TRUE, to define removal manipulation */ + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */ + + bool insrt; /**< TRUE, to define insertion manipulation */ + ioc_fm_pcd_manip_hdr_insrt_params_t insrt_params; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */ + + bool field_update; /**< TRUE, to define field update manipulation */ + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */ + + bool custom; /**< TRUE, to define custom manipulation */ + ioc_fm_pcd_manip_hdr_custom_params_t custom_params; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */ + + bool dont_parse_after_manip;/**< FALSE to activate the parser a second time after + completing the manipulation on the frame */ +} ioc_fm_pcd_manip_hdr_params_t; + + +/**************************************************************************//** + @Description structure for defining fragmentation manipulation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_frag_params_t { + ioc_net_header_type hdr; /**< Header selection */ + union { +#if (DPAA_VERSION >= 11) + ioc_fm_pcd_manip_frag_capwap_params_t capwap_frag; /**< Parameters for defining CAPWAP fragmentation, + relevant if 'hdr' = HEADER_TYPE_CAPWAP */ +#endif /* (DPAA_VERSION >= 11) */ + ioc_fm_pcd_manip_frag_ip_params_t ip_frag; /**< Parameters for defining IP fragmentation, + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */ + } u; +} ioc_fm_pcd_manip_frag_params_t; + +/**************************************************************************//** + @Description structure for defining reassemble manipulation +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_reassem_params_t { + ioc_net_header_type hdr; /**< Header selection */ + union { +#if (DPAA_VERSION >= 11) + ioc_fm_pcd_manip_reassem_capwap_params_t capwap_reassem; /**< Parameters for defining CAPWAP reassembly, + relevant if 'hdr' = HEADER_TYPE_CAPWAP */ +#endif /* (DPAA_VERSION >= 11) */ + ioc_fm_pcd_manip_reassem_ip_params_t ip_reassem; /**< Parameters for defining IP reassembly, + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */ + } u; +} ioc_fm_pcd_manip_reassem_params_t; + +/**************************************************************************//** + @Description Parameters for defining a manipulation node +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_params_t { + ioc_fm_pcd_manip_type type; /**< Selects type of manipulation node */ + union { + ioc_fm_pcd_manip_hdr_params_t hdr; /**< Parameters for defining header manipulation node */ + ioc_fm_pcd_manip_reassem_params_t reassem;/**< Parameters for defining reassembly manipulation node */ + ioc_fm_pcd_manip_frag_params_t frag; /**< Parameters for defining fragmentation manipulation node */ + ioc_fm_pcd_manip_special_offload_params_t special_offload;/**< Parameters for defining special offload manipulation node */ + } u; + void *p_next_manip;/**< Handle to another (previously defined) manipulation node; + Allows concatenation of manipulation actions + This parameter is optional and may be NULL. */ +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) + bool frag_or_reasm;/**< TRUE, if defined fragmentation/reassembly manipulation */ + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;/**< Parameters for fragmentation/reassembly manipulation, + relevant if frag_or_reasm = TRUE */ +#endif /* FM_CAPWAP_SUPPORT */ + void *id; +} ioc_fm_pcd_manip_params_t; + +/**************************************************************************//** + @Description Structure for retrieving IP reassembly statistics +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_reassem_ip_stats_t { + /* common counters for both IPv4 and IPv6 */ + uint32_t timeout; /**< Counts the number of TimeOut occurrences */ + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate + a Reassembly Frame Descriptor */ + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */ + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */ + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */ + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */ +#if (DPAA_VERSION >= 11) + uint32_t non_consistent_sp; /**< Counts the number of Non Consistent Storage Profile events for + successfully reassembled frames */ +#endif /* (DPAA_VERSION >= 11) */ +struct { + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */ + uint32_t valid_fragments; /**< Counts the total number of valid fragments that + have been processed for all frames */ + uint32_t processed_fragments; /**< Counts the number of processed fragments + (valid and error fragments) for all frames */ + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */ + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */ + uint32_t auto_learn_busy; /**< Counts the number of times a busy condition occurs when attempting + to access an IP-Reassembly Automatic Learning Hash set */ + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame + exceeds 16 */ + } specific_hdr_statistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */ +} ioc_fm_pcd_manip_reassem_ip_stats_t; + +/**************************************************************************//** + @Description Structure for retrieving IP fragmentation statistics +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_frag_ip_stats_t { + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */ + uint32_t fragmented_frames; /**< Number of frames that were fragmented */ + uint32_t generated_fragments; /**< Number of fragments that were generated */ +} ioc_fm_pcd_manip_frag_ip_stats_t; + +#if (DPAA_VERSION >= 11) +/**************************************************************************//** + @Description Structure for retrieving CAPWAP reassembly statistics +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_reassem_capwap_stats_t { + uint32_t timeout; /**< Counts the number of timeout occurrences */ + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate + a Reassembly Frame Descriptor */ + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */ + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */ + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */ + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */ + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */ + uint32_t valid_fragments; /**< Counts the total number of valid fragments that + have been processed for all frames */ + uint32_t processed_fragments; /**< Counts the number of processed fragments + (valid and error fragments) for all frames */ + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */ + uint32_t autoLearn_busy; /**< Counts the number of times a busy condition occurs when attempting + to access an Reassembly Automatic Learning Hash set */ + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */ + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame + exceeds 16 */ + uint32_t exceed_max_reassembly_frame_len;/**< ounts the number of times that a successful reassembled frame + length exceeds MaxReassembledFrameLength value */ +} ioc_fm_pcd_manip_reassem_capwap_stats_t; + +/**************************************************************************//** + @Description Structure for retrieving CAPWAP fragmentation statistics +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_frag_capwap_stats_t { + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */ + uint32_t fragmented_frames; /**< Number of frames that were fragmented */ + uint32_t generated_fragments; /**< Number of fragments that were generated */ +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) + uint8_t sg_allocation_failure; /**< Number of allocation failure of s/g buffers */ +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */ +} ioc_fm_pcd_manip_frag_capwap_stats_t; +#endif /* (DPAA_VERSION >= 11) */ + +/**************************************************************************//** + @Description Structure for retrieving reassembly statistics +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_reassem_stats_t { + union { + ioc_fm_pcd_manip_reassem_ip_stats_t ip_reassem; /**< Structure for IP reassembly statistics */ +#if (DPAA_VERSION >= 11) + ioc_fm_pcd_manip_reassem_capwap_stats_t capwap_reassem; /**< Structure for CAPWAP reassembly statistics */ +#endif /* (DPAA_VERSION >= 11) */ + } u; +} ioc_fm_pcd_manip_reassem_stats_t; + +/**************************************************************************//** + @Description structure for retrieving fragmentation statistics +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_frag_stats_t { + union { + ioc_fm_pcd_manip_frag_ip_stats_t ip_frag; /**< Structure for IP fragmentation statistics */ +#if (DPAA_VERSION >= 11) + ioc_fm_pcd_manip_frag_capwap_stats_t capwap_frag; /**< Structure for CAPWAP fragmentation statistics */ +#endif /* (DPAA_VERSION >= 11) */ + } u; +} ioc_fm_pcd_manip_frag_stats_t; + +/**************************************************************************//** + @Description structure for defining manipulation statistics +*//***************************************************************************/ +typedef struct ioc_fm_pcd_manip_stats_t { + union { + ioc_fm_pcd_manip_reassem_stats_t reassem; /**< Structure for reassembly statistics */ + ioc_fm_pcd_manip_frag_stats_t frag; /**< Structure for fragmentation statistics */ + } u; +} ioc_fm_pcd_manip_stats_t; + +#if DPAA_VERSION >= 11 +/**************************************************************************//** + @Description Parameters for defining frame replicator group and its members +*//***************************************************************************/ +typedef struct ioc_fm_pcd_frm_replic_group_params_t { + uint8_t max_num_of_entries; /**< Maximal number of members in the group - must be at least two */ + uint8_t num_of_entries; /**< Number of members in the group - must be at least 1 */ + ioc_fm_pcd_cc_next_engine_params_t next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES]; + /**< Array of members' parameters */ + void *id; +} ioc_fm_pcd_frm_replic_group_params_t; + +typedef struct ioc_fm_pcd_frm_replic_member_t { + void *h_replic_group; + uint16_t member_index; +} ioc_fm_pcd_frm_replic_member_t; + +typedef struct ioc_fm_pcd_frm_replic_member_params_t { + ioc_fm_pcd_frm_replic_member_t member; + ioc_fm_pcd_cc_next_engine_params_t next_engine_params; +} ioc_fm_pcd_frm_replic_member_params_t; +#endif /* DPAA_VERSION >= 11 */ + + +typedef struct ioc_fm_pcd_cc_key_statistics_t { + uint32_t byte_count; /**< This counter reflects byte count of frames that + were matched by this key. */ + uint32_t frame_count; /**< This counter reflects count of frames that + were matched by this key. */ +#if (DPAA_VERSION >= 11) + uint32_t frame_length_range_count[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR]; + /**< These counters reflect how many frames matched + this key in 'RMON' statistics mode: + Each counter holds the number of frames of a + specific frames length range, according to the + ranges provided at initialization. */ +#endif /* (DPAA_VERSION >= 11) */ +} ioc_fm_pcd_cc_key_statistics_t; + + +typedef struct ioc_fm_pcd_cc_tbl_get_miss_params_t { + void *id; + ioc_fm_pcd_cc_key_statistics_t miss_statistics; +} ioc_fm_pcd_cc_tbl_get_miss_params_t; + + +/**************************************************************************//** + @Function FM_PCD_MatchTableGetMissStatistics + + @Description This routine may be used to get statistics counters of miss entry + in a CC Node. + + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, + these counters reflect how many frames were not matched to any + existing key and therefore passed through the miss entry; The + total frames count will be returned in the counter of the + first range (as only one frame length range was defined). + + @Param[in] h_CcNode A handle to the node + @Param[out] p_MissStatistics Statistics counters for 'miss' + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_MatchTableSet(). +*//***************************************************************************/ + +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(12), ioc_compat_fm_pcd_cc_tbl_get_miss_params_t) +#endif +#define FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(12), ioc_fm_pcd_cc_tbl_get_miss_params_t) + +/**************************************************************************//** + @Function FM_PCD_HashTableGetMissStatistics + + @Description This routine may be used to get statistics counters of 'miss' + entry of the a hash table. + + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, + these counters reflect how many frames were not matched to any + existing key and therefore passed through the miss entry; + + @Param[in] h_HashTbl A handle to a hash table + @Param[out] p_MissStatistics Statistics counters for 'miss' + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_HashTableSet(). +*//***************************************************************************/ + +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(13), ioc_compat_fm_pcd_cc_tbl_get_miss_params_t) +#endif +#define FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(13), ioc_fm_pcd_cc_tbl_get_miss_params_t) + + +/**************************************************************************//** + @Function FM_PCD_NetEnvCharacteristicsSet + + @Description Define a set of Network Environment Characteristics. + + When setting an environment it is important to understand its + application. It is not meant to describe the flows that will run + on the ports using this environment, but what the user means TO DO + with the PCD mechanisms in order to parse-classify-distribute those + frames. + By specifying a distinction unit, the user means it would use that option + for distinction between frames at either a KeyGen scheme or a coarse + classification action descriptor. Using interchangeable headers to define a + unit means that the user is indifferent to which of the interchangeable + headers is present in the frame, and wants the distinction to be based + on the presence of either one of them. + + Depending on context, there are limitations to the use of environments. A + port using the PCD functionality is bound to an environment. Some or even + all ports may share an environment but also an environment per port is + possible. When initializing a scheme, a classification plan group (see below), + or a coarse classification tree, one of the initialized environments must be + stated and related to. When a port is bound to a scheme, a classification + plan group, or a coarse classification tree, it MUST be bound to the same + environment. + + The different PCD modules, may relate (for flows definition) ONLY on + distinction units as defined by their environment. When initializing a + scheme for example, it may not choose to select IPV4 as a match for + recognizing flows unless it was defined in the relating environment. In + fact, to guide the user through the configuration of the PCD, each module's + characterization in terms of flows is not done using protocol names, but using + environment indexes. + + In terms of HW implementation, the list of distinction units sets the LCV vectors + and later used for match vector, classification plan vectors and coarse classification + indexing. + + @Param[in,out] ioc_fm_pcd_net_env_params_t A structure defining the distiction units for this configuration. + + @Return 0 on success; Error code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(20), ioc_compat_fm_pcd_net_env_params_t) +#endif +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(20), ioc_fm_pcd_net_env_params_t) + +/**************************************************************************//** + @Function FM_PCD_NetEnvCharacteristicsDelete + + @Description Deletes a set of Network Environment Charecteristics. + + @Param[in] ioc_fm_obj_t - The id of a Network Environment object. + + @Return 0 on success; Error code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_compat_fm_obj_t) +#endif +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_fm_obj_t) + +/**************************************************************************//** + @Function FM_PCD_KgSchemeSet + + @Description Initializing or modifying and enabling a scheme for the KeyGen. + This routine should be called for adding or modifying a scheme. + When a scheme needs modifying, the API requires that it will be + rewritten. In such a case 'modify' should be TRUE. If the + routine is called for a valid scheme and 'modify' is FALSE, + it will return error. + + @Param[in,out] ioc_fm_pcd_kg_scheme_params_t A structure of parameters for defining the scheme + + @Return 0 on success; Error code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_KG_SCHEME_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(24), ioc_compat_fm_pcd_kg_scheme_params_t) +#endif +#define FM_PCD_IOC_KG_SCHEME_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(24), ioc_fm_pcd_kg_scheme_params_t) + +/**************************************************************************//** + @Function FM_PCD_KgSchemeDelete + + @Description Deleting an initialized scheme. + + @Param[in] ioc_fm_obj_t scheme id as initalized by application at FM_PCD_IOC_KG_SET_SCHEME + + @Return 0 on success; Error code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_compat_fm_obj_t) +#endif +#define FM_PCD_IOC_KG_SCHEME_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_fm_obj_t) + +/**************************************************************************//** + @Function FM_PCD_CcRootBuild + + @Description This routine must be called to define a complete coarse + classification tree. This is the way to define coarse + classification to a certain flow - the KeyGen schemes + may point only to trees defined in this way. + + @Param[in,out] ioc_fm_pcd_cc_tree_params_t A structure of parameters to define the tree. + + @Return 0 on success; Error code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_CC_ROOT_BUILD_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), compat_uptr_t) +#endif +#define FM_PCD_IOC_CC_ROOT_BUILD _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), void *) /* workaround ...*/ + +/**************************************************************************//** + @Function FM_PCD_CcRootDelete + + @Description Deleting a built tree. + + @Param[in] ioc_fm_obj_t - The id of a CC tree. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_CC_ROOT_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_compat_fm_obj_t) +#endif +#define FM_PCD_IOC_CC_ROOT_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_fm_obj_t) + +/**************************************************************************//** + @Function FM_PCD_MatchTableSet + + @Description This routine should be called for each CC (coarse classification) + node. The whole CC tree should be built bottom up so that each + node points to already defined nodes. p_NodeId returns the node + Id to be used by other nodes. + + @Param[in,out] ioc_fm_pcd_cc_node_params_t A structure for defining the CC node params + + @Return 0 on success; Error code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_MATCH_TABLE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), compat_uptr_t) +#endif +#define FM_PCD_IOC_MATCH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), void *) /* workaround ...*/ + +/**************************************************************************//** + @Function FM_PCD_MatchTableDelete + + @Description Deleting a built node. + + @Param[in] ioc_fm_obj_t - The id of a CC node. + + @Return 0 on success; Error code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_compat_fm_obj_t) +#endif +#define FM_PCD_IOC_MATCH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_fm_obj_t) + +/**************************************************************************//** + @Function FM_PCD_CcRootModifyNextEngine + + @Description Modify the Next Engine Parameters in the entry of the tree. + + @Param[in] ioc_fm_pcd_cc_tree_modify_next_engine_params_t - Pointer to a structure with the relevant parameters + + @Return 0 on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_CcRootBuild(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(30), ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t) +#endif +#define FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(30), ioc_fm_pcd_cc_tree_modify_next_engine_params_t) + +/**************************************************************************//** + @Function FM_PCD_MatchTableModifyNextEngine + + @Description Modify the Next Engine Parameters in the relevant key entry of the node. + + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t A pointer to a structure with the relevant parameters + + @Return 0 on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_MatchTableSet(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(31), ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t) +#endif +#define FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(31), ioc_fm_pcd_cc_node_modify_next_engine_params_t) + +/**************************************************************************//** + @Function FM_PCD_MatchTableModifyMissNextEngine + + @Description Modify the Next Engine Parameters of the Miss key case of the node. + + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t - Pointer to a structure with the relevant parameters + + @Return 0 on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_MatchTableSet(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(32), ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t) +#endif +#define FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(32), ioc_fm_pcd_cc_node_modify_next_engine_params_t) + +/**************************************************************************//** + @Function FM_PCD_MatchTableRemoveKey + + @Description Remove the key (including next engine parameters of this key) + defined by the index of the relevant node. + + @Param[in] ioc_fm_pcd_cc_node_remove_key_params_t A pointer to a structure with the relevant parameters + + @Return 0 on success; Error code otherwise. + + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this + node and for all of the nodes that lead to it. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(33), ioc_compat_fm_pcd_cc_node_remove_key_params_t) +#endif +#define FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(33), ioc_fm_pcd_cc_node_remove_key_params_t) + +/**************************************************************************//** + @Function FM_PCD_MatchTableAddKey + + @Description Add the key (including next engine parameters of this key in the + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX' + may be used when the user doesn't care about the position of the + key in the table - in that case, the key will be automatically + added by the driver in the last available entry. + + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters + + @Return 0 on success; Error code otherwise. + + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this + node and for all of the nodes that lead to it. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(34), ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t) +#endif +#define FM_PCD_IOC_MATCH_TABLE_ADD_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(34), ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t) + +/**************************************************************************//** + @Function FM_PCD_MatchTableModifyKeyAndNextEngine + + @Description Modify the key and Next Engine Parameters of this key in the index defined by key_index. + + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters + + @Return 0 on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_MatchTableSet() not only of the relevnt node but also + the node that points to this node +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(35), ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t) +#endif +#define FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(35), ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t) + +/**************************************************************************//** + @Function FM_PCD_MatchTableModifyKey + + @Description Modify the key at the index defined by key_index. + + @Param[in] ioc_fm_pcd_cc_node_modify_key_params_t - Pointer to a structure with the relevant parameters + + @Return 0 on success; Error code otherwise. + + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this + node and for all of the nodes that lead to it. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(36), ioc_compat_fm_pcd_cc_node_modify_key_params_t) +#endif +#define FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(36), ioc_fm_pcd_cc_node_modify_key_params_t) + +/**************************************************************************//** + @Function FM_PCD_HashTableSet + + @Description This routine initializes a hash table structure. + KeyGen hash result determines the hash bucket. + Next, KeyGen key is compared against all keys of this + bucket (exact match). + Number of sets (number of buckets) of the hash equals to the + number of 1-s in 'hash_res_mask' in the provided parameters. + Number of hash table ways is then calculated by dividing + 'max_num_of_keys' equally between the hash sets. This is the maximal + number of keys that a hash bucket may hold. + The hash table is initialized empty and keys may be + added to it following the initialization. Keys masks are not + supported in current hash table implementation. + The initialized hash table can be integrated as a node in a + CC tree. + + @Param[in,out] ioc_fm_pcd_hash_table_params_t - Pointer to a structure with the relevant parameters + + @Return 0 on success; Error code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_HASH_TABLE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_compat_fm_pcd_hash_table_params_t) +#endif +#define FM_PCD_IOC_HASH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_pcd_hash_table_params_t) + + +/**************************************************************************//** + @Function FM_PCD_HashTableDelete + + @Description This routine deletes the provided hash table and released all + its allocated resources. + + @Param[in] ioc_fm_obj_t - The ID of a hash table. + + @Return 0 on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_HashTableSet(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_compat_fm_obj_t) +#endif +#define FM_PCD_IOC_HASH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_obj_t) + +/**************************************************************************//** + @Function FM_PCD_HashTableAddKey + + @Description This routine adds the provided key (including next engine + parameters of this key) to the hash table. + The key is added as the last key of the bucket that it is + mapped to. + + @Param[in] ioc_fm_pcd_hash_table_add_key_params_t - Pointer to a structure with the relevant parameters + + @Return 0 on success; error code otherwise. + + @Cautions Allowed only following FM_PCD_HashTableSet(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_HASH_TABLE_ADD_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(39), ioc_compat_fm_pcd_hash_table_add_key_params_t) +#endif +#define FM_PCD_IOC_HASH_TABLE_ADD_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(39), ioc_fm_pcd_hash_table_add_key_params_t) + +/**************************************************************************//** + @Function FM_PCD_HashTableRemoveKey + + @Description This routine removes the requested key (including next engine + parameters of this key) from the hash table. + + @Param[in] ioc_fm_pcd_hash_table_remove_key_params_t - Pointer to a structure with the relevant parameters + + @Return 0 on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_HashTableSet(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_HASH_TABLE_REMOVE_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(40), ioc_compat_fm_pcd_hash_table_remove_key_params_t) +#endif +#define FM_PCD_IOC_HASH_TABLE_REMOVE_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(40), ioc_fm_pcd_hash_table_remove_key_params_t) + +/**************************************************************************//** + @Function FM_PCD_PlcrProfileSet + + @Description Sets a profile entry in the policer profile table. + The routine overrides any existing value. + + @Param[in,out] ioc_fm_pcd_plcr_profile_params_t A structure of parameters for defining a + policer profile entry. + + @Return 0 on success; Error code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_compat_fm_pcd_plcr_profile_params_t) +#endif +#define FM_PCD_IOC_PLCR_PROFILE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_pcd_plcr_profile_params_t) + +/**************************************************************************//** + @Function FM_PCD_PlcrProfileDelete + + @Description Delete a profile entry in the policer profile table. + The routine set entry to invalid. + + @Param[in] ioc_fm_obj_t The id of a policer profile. + + @Return 0 on success; Error code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_compat_fm_obj_t) +#endif +#define FM_PCD_IOC_PLCR_PROFILE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_obj_t) + +/**************************************************************************//** + @Function FM_PCD_ManipNodeSet + + @Description This routine should be called for defining a manipulation + node. A manipulation node must be defined before the CC node + that precedes it. + + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation + + @Return A handle to the initialized object on success; NULL code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_MANIP_NODE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(43), ioc_compat_fm_pcd_manip_params_t) +#endif +#define FM_PCD_IOC_MANIP_NODE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(43), ioc_fm_pcd_manip_params_t) + +/**************************************************************************//** + @Function FM_PCD_ManipNodeReplace + + @Description Change existing manipulation node to be according to new requirement. + (Here, it's implemented as a variant of the same IOCTL as for + FM_PCD_ManipNodeSet(), and one that when called, the 'id' member + in its 'ioc_fm_pcd_manip_params_t' argument is set to contain + the manip node's handle) + + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation + + @Return 0 on success; error code otherwise. + + @Cautions Allowed only following FM_PCD_ManipNodeSet(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_MANIP_NODE_REPLACE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT +#endif +#define FM_PCD_IOC_MANIP_NODE_REPLACE FM_PCD_IOC_MANIP_NODE_SET + +/**************************************************************************//** + @Function FM_PCD_ManipNodeDelete + + @Description Delete an existing manipulation node. + + @Param[in] ioc_fm_obj_t The id of the manipulation node to delete. + + @Return 0 on success; error code otherwise. + + @Cautions Allowed only following FM_PCD_ManipNodeSet(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_compat_fm_obj_t) +#endif +#define FM_PCD_IOC_MANIP_NODE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_fm_obj_t) + +/**************************************************************************//** +@Function FM_PCD_SetAdvancedOffloadSupport + +@Description This routine must be called in order to support the following features: + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator. + +@Param[in] h_FmPcd FM PCD module descriptor. + +@Return 0 on success; error code otherwise. + +@Cautions Allowed only when PCD is disabled. +*//***************************************************************************/ +#define FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45)) + +#if (DPAA_VERSION >= 11) +/**************************************************************************//** + @Function FM_PCD_FrmReplicSetGroup + + @Description Initialize a Frame Replicator group. + + @Param[in] h_FmPcd FM PCD module descriptor. + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of + the frame replicator group. + + @Return A handle to the initialized object on success; NULL code otherwise. + + @Cautions Allowed only following FM_PCD_Init(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_FRM_REPLIC_GROUP_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(46), ioc_compat_fm_pcd_frm_replic_group_params_t) +#endif +#define FM_PCD_IOC_FRM_REPLIC_GROUP_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(46), ioc_fm_pcd_frm_replic_group_params_t) + +/**************************************************************************//** + @Function FM_PCD_FrmReplicDeleteGroup + + @Description Delete a Frame Replicator group. + + @Param[in] h_FrmReplicGroup A handle to the frame replicator group. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_compat_fm_obj_t) +#endif +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_fm_obj_t) + +/**************************************************************************//** + @Function FM_PCD_FrmReplicAddMember + + @Description Add the member in the index defined by the memberIndex. + + @Param[in] h_FrmReplicGroup A handle to the frame replicator group. + @Param[in] memberIndex member index for adding. + @Param[in] p_MemberParams A pointer to the new member parameters. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(48), ioc_compat_fm_pcd_frm_replic_member_params_t) +#endif +#define FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(48), ioc_fm_pcd_frm_replic_member_params_t) + +/**************************************************************************//** + @Function FM_PCD_FrmReplicRemoveMember + + @Description Remove the member defined by the index from the relevant group. + + @Param[in] h_FrmReplicGroup A handle to the frame replicator group. + @Param[in] memberIndex member index for removing. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(49), ioc_compat_fm_pcd_frm_replic_member_t) +#endif +#define FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(49), ioc_fm_pcd_frm_replic_member_t) + +#endif + +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) +/**************************************************************************//** + @Function FM_PCD_StatisticsSetNode + + @Description This routine should be called for defining a statistics node. + + @Param[in,out] ioc_fm_pcd_stats_params_t A structure of parameters defining the statistics + + @Return 0 on success; Error code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *) +#endif +#define FM_PCD_IOC_STATISTICS_SET_NODE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *) + +#endif /* FM_CAPWAP_SUPPORT */ + +#ifdef NCSW_BACKWARD_COMPATIBLE_API +#if defined(CONFIG_COMPAT) +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS_COMPAT \ + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS_COMPAT \ + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT +#define FM_PCD_IOC_KG_SET_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_SET_COMPAT +#define FM_PCD_IOC_KG_DEL_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT +#define FM_PCD_IOC_CC_BUILD_TREE_COMPAT FM_PCD_IOC_CC_ROOT_BUILD_COMPAT +#define FM_PCD_IOC_CC_DELETE_TREE_COMPAT FM_PCD_IOC_CC_ROOT_DELETE_COMPAT +#define FM_PCD_IOC_CC_DELETE_NODE_COMPAT FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE_COMPAT \ + FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE_COMPAT \ + FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE_COMPAT \ + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT +#define FM_PCD_IOC_CC_NODE_ADD_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT \ + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT +#define FM_PCD_IOC_PLCR_SET_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT +#define FM_PCD_IOC_PLCR_DEL_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT +#define FM_PCD_IOC_MANIP_SET_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT +#define FM_PCD_IOC_MANIP_DELETE_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT +#endif +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS \ + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE +#define FM_PCD_IOC_KG_SET_SCHEME FM_PCD_IOC_KG_SCHEME_SET +#define FM_PCD_IOC_KG_DEL_SCHEME FM_PCD_IOC_KG_SCHEME_DELETE +#define FM_PCD_IOC_CC_BUILD_TREE FM_PCD_IOC_CC_ROOT_BUILD +#define FM_PCD_IOC_CC_DELETE_TREE FM_PCD_IOC_CC_ROOT_DELETE +#define FM_PCD_IOC_CC_DELETE_NODE FM_PCD_IOC_MATCH_TABLE_DELETE +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE \ + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY +#define FM_PCD_IOC_CC_NODE_ADD_KEY FM_PCD_IOC_MATCH_TABLE_ADD_KEY +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE \ + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY +#define FM_PCD_IOC_PLCR_SET_PROFILE FM_PCD_IOC_PLCR_PROFILE_SET +#define FM_PCD_IOC_PLCR_DEL_PROFILE FM_PCD_IOC_PLCR_PROFILE_DELETE +#define FM_PCD_IOC_MANIP_SET_NODE FM_PCD_IOC_MANIP_NODE_SET +#define FM_PCD_IOC_MANIP_DELETE_NODE FM_PCD_IOC_MANIP_NODE_DELETE +#endif /* NCSW_BACKWARD_COMPATIBLE_API */ + +#endif /* __FM_PCD_IOCTLS_H */ +/** @} */ /* end of lnx_ioctl_FM_PCD_Runtime_grp group */ +/** @} */ /* end of lnx_ioctl_FM_PCD_grp group */ +/** @} */ /* end of lnx_ioctl_FM_grp group */ diff --git a/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h b/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h new file mode 100644 index 0000000..49d1f50 --- /dev/null +++ b/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h @@ -0,0 +1,923 @@ +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/****************************************************************************** + @File fm_port_ioctls.h + + @Description FM Port routines +*//***************************************************************************/ +#ifndef __FM_PORT_IOCTLS_H +#define __FM_PORT_IOCTLS_H + +#include "enet_ext.h" +#include "net_ioctls.h" +#include "fm_ioctls.h" +#include "fm_pcd_ioctls.h" + + +/**************************************************************************//** + + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API + + @Description FM Linux ioctls definitions and enums + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Group lnx_ioctl_FM_PORT_grp FM Port + + @Description FM Port API + + The FM uses a general module called "port" to represent a Tx port + (MAC), an Rx port (MAC), offline parsing flow or host command + flow. There may be up to 17 (may change) ports in an FM - 5 Tx + ports (4 for the 1G MACs, 1 for the 10G MAC), 5 Rx Ports, and 7 + Host command/Offline parsing ports. The SW driver manages these + ports as sub-modules of the FM, i.e. after an FM is initialized, + its ports may be initialized and operated upon. + + The port is initialized aware of its type, but other functions on + a port may be indifferent to its type. When necessary, the driver + verifies coherency and returns error if applicable. + + On initialization, user specifies the port type and it's index + (relative to the port's type). Host command and Offline parsing + ports share the same id range, I.e user may not initialized host + command port 0 and offline parsing port 0. + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Description An enum for defining port PCD modes. + (Must match enum e_FmPortPcdSupport defined in fm_port_ext.h) + + This enum defines the superset of PCD engines support - i.e. not + all engines have to be used, but all have to be enabled. The real + flow of a specific frame depends on the PCD configuration and the + frame headers and payload. + Note: the first engine and the first engine after the parser (if + exists) should be in order, the order is important as it will + define the flow of the port. However, as for the rest engines + (the ones that follows), the order is not important anymore as + it is defined by the PCD graph itself. +*//***************************************************************************/ +typedef enum ioc_fm_port_pcd_support { + e_IOC_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */ + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */ + , e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */ + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */ + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */ + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */ + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR + /**< Use all PCD engines */ + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */ + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */ + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */ + , e_IOC_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */ +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */ + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */ +#endif /* FM_CAPWAP_SUPPORT */ +} ioc_fm_port_pcd_support; + + +/**************************************************************************//** + @Collection FM Frame error +*//***************************************************************************/ +typedef uint32_t ioc_fm_port_frame_err_select_t; /**< typedef for defining Frame Descriptor errors */ + +/* @} */ + + +/**************************************************************************//** + @Description An enum for defining Dual Tx rate limiting scale. + (Must match e_FmPortDualRateLimiterScaleDown defined in fm_port_ext.h) +*//***************************************************************************/ +typedef enum ioc_fm_port_dual_rate_limiter_scale_down { + e_IOC_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */ + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */ + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */ + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */ +} ioc_fm_port_dual_rate_limiter_scale_down; + +/**************************************************************************//** + @Description A structure for defining Tx rate limiting + (Must match struct t_FmPortRateLimit defined in fm_port_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_port_rate_limit_t { + uint16_t max_burst_size; /**< in KBytes for Tx ports, in frames + for offline parsing ports. (note that + for early chips burst size is + rounded up to a multiply of 1000 frames).*/ + uint32_t rate_limit; /**< in Kb/sec for Tx ports, in frame/sec for + offline parsing ports. Rate limit refers to + data rate (rather than line rate). */ + ioc_fm_port_dual_rate_limiter_scale_down rate_limit_divider; /**< For offline parsing ports only. Not-valid + for some earlier chip revisions */ +} ioc_fm_port_rate_limit_t; + + + +/**************************************************************************//** + @Group lnx_ioctl_FM_PORT_runtime_control_grp FM Port Runtime Control Unit + + @Description FM Port Runtime control unit API functions, definitions and enums. + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Description An enum for defining FM Port counters. + (Must match enum e_FmPortCounters defined in fm_port_ext.h) +*//***************************************************************************/ +typedef enum ioc_fm_port_counters { + e_IOC_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */ + e_IOC_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */ + e_IOC_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */ + e_IOC_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */ + e_IOC_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */ + e_IOC_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */ + e_IOC_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */ + e_IOC_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */ + e_IOC_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */ + e_IOC_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */ + e_IOC_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */ + e_IOC_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */ + e_IOC_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */ + e_IOC_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */ + e_IOC_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */ + e_IOC_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */ + e_IOC_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */ + e_IOC_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */ + e_IOC_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */ + e_IOC_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */ + e_IOC_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */ + e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */ +} ioc_fm_port_counters; + +/**************************************************************************//** + @Description Structure for Port id parameters. + (Description may be inaccurate; + must match struct t_FmPortCongestionGrps defined in fm_port_ext.h) + + Fields commented 'IN' are passed by the port module to be used + by the FM module. + Fields commented 'OUT' will be filled by FM before returning to port. +*//***************************************************************************/ +typedef struct ioc_fm_port_congestion_groups_t { + uint16_t num_of_congestion_grps_to_consider; /**< The number of required congestion groups + to define the size of the following array */ + uint8_t congestion_grps_to_consider [FM_PORT_NUM_OF_CONGESTION_GRPS]; + /**< An array of CG indexes; + Note that the size of the array should be + 'num_of_congestion_grps_to_consider'. */ +#if DPAA_VERSION >= 11 + bool pfc_priorities_enable[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES]; + /**< A matrix that represents the map between the CG ids + defined in 'congestion_grps_to_consider' to the priorities + mapping array. */ +#endif /* DPAA_VERSION >= 11 */ +} ioc_fm_port_congestion_groups_t; + + + +/**************************************************************************//** + @Function FM_PORT_Disable + + @Description Gracefully disable an FM port. The port will not start new tasks after all + tasks associated with the port are terminated. + + @Return 0 on success; error code otherwise. + + @Cautions This is a blocking routine, it returns after port is + gracefully stopped, i.e. the port will not except new frames, + but it will finish all frames or tasks which were already began +*//***************************************************************************/ +#define FM_PORT_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(1)) + +/**************************************************************************//** + @Function FM_PORT_Enable + + @Description A runtime routine provided to allow disable/enable of port. + + @Return 0 on success; error code otherwise. +*//***************************************************************************/ +#define FM_PORT_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(2)) + +/**************************************************************************//** + @Function FM_PORT_SetRateLimit + + @Description Calling this routine enables rate limit algorithm. + By default, this functionality is disabled. + Note that rate-limit mechanism uses the FM time stamp. + The selected rate limit specified here would be + rounded DOWN to the nearest 16M. + + May be used for Tx and offline parsing ports only + + @Param[in] ioc_fm_port_rate_limit A structure of rate limit parameters + + @Return 0 on success; error code otherwise. +*//***************************************************************************/ +#define FM_PORT_IOC_SET_RATE_LIMIT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(3), ioc_fm_port_rate_limit_t) + +/**************************************************************************//** + @Function FM_PORT_DeleteRateLimit + + @Description Calling this routine disables the previously enabled rate limit. + + May be used for Tx and offline parsing ports only + + @Return 0 on success; error code otherwise. +*//***************************************************************************/ +#define FM_PORT_IOC_DELETE_RATE_LIMIT _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(5)) +#define FM_PORT_IOC_REMOVE_RATE_LIMIT FM_PORT_IOC_DELETE_RATE_LIMIT + + +/**************************************************************************//** + @Function FM_PORT_AddCongestionGrps + + @Description This routine effects the corresponding Tx port. + It should be called in order to enable pause + frame transmission in case of congestion in one or more + of the congestion groups relevant to this port. + Each call to this routine may add one or more congestion + groups to be considered relevant to this port. + + May be used for Rx, or RX+OP ports only (depending on chip) + + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of + congestion group ids to consider. + + @Return 0 on success; error code otherwise. +*//***************************************************************************/ +#define FM_PORT_IOC_ADD_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(34), ioc_fm_port_congestion_groups_t) + +/**************************************************************************//** + @Function FM_PORT_RemoveCongestionGrps + + @Description This routine effects the corresponding Tx port. It should be + called when congestion groups were + defined for this port and are no longer relevant, or pause + frames transmitting is not required on their behalf. + Each call to this routine may remove one or more congestion + groups to be considered relevant to this port. + + May be used for Rx, or RX+OP ports only (depending on chip) + + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of + congestion group ids to consider. + + @Return 0 on success; error code otherwise. +*//***************************************************************************/ +#define FM_PORT_IOC_REMOVE_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(35), ioc_fm_port_congestion_groups_t) + +/**************************************************************************//** + @Function FM_PORT_SetErrorsRoute + + @Description Errors selected for this routine will cause a frame with that error + to be enqueued to error queue. + Errors not selected for this routine will cause a frame with that error + to be enqueued to the one of the other port queues. + By default all errors are defined to be enqueued to error queue. + Errors that were configured to be discarded (at initialization) + may not be selected here. + + May be used for Rx and offline parsing ports only + + @Param[in] ioc_fm_port_frame_err_select_t A list of errors to enqueue to error queue + + @Return 0 on success; error code otherwise. + + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). + (szbs001: How is it possible to have one function that needs to be + called BEFORE FM_PORT_Init() implemented as an ioctl, + which will ALWAYS be called AFTER the FM_PORT_Init() + for that port!?!?!?!???!?!??!?!?) +*//***************************************************************************/ +#define FM_PORT_IOC_SET_ERRORS_ROUTE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(4), ioc_fm_port_frame_err_select_t) + + +/**************************************************************************//** + @Group lnx_ioctl_FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit + + @Description FM Port PCD Runtime control unit API functions, definitions and enums. + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Description A structure defining the KG scheme after the parser. + (Must match struct t_FmPcdKgSchemeSelect defined in fm_port_ext.h) + + This is relevant only to change scheme selection mode - from + direct to indirect and vice versa, or when the scheme is selected directly, + to select the scheme id. + +*//***************************************************************************/ +typedef struct ioc_fm_pcd_kg_scheme_select_t { + bool direct; /**< TRUE to use 'scheme_id' directly, FALSE to use LCV.*/ + void *scheme_id; /**< Relevant for 'direct'=TRUE only. + 'scheme_id' selects the scheme after parser. */ +} ioc_fm_pcd_kg_scheme_select_t; + +/**************************************************************************//** + @Description Scheme IDs structure + (Must match struct t_FmPcdPortSchemesParams defined in fm_port_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_port_schemes_params_t { + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */ + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'num_of_schemes' schemes for the + port to be bound to */ +} ioc_fm_pcd_port_schemes_params_t; + +/**************************************************************************//** + @Description A union for defining port protocol parameters for parser + (Must match union u_FmPcdHdrPrsOpts defined in fm_port_ext.h) +*//***************************************************************************/ +typedef union ioc_fm_pcd_hdr_prs_opts_u { + /* MPLS */ + struct { + bool label_interpretation_enable;/**< When this bit is set, the last MPLS label will be + interpreted as described in HW spec table. When the bit + is cleared, the parser will advance to MPLS next parse */ + ioc_net_header_type next_parse; /**< must be equal or higher than IPv4 */ + } mpls_prs_options; + + /* VLAN */ + struct { + uint16_t tag_protocol_id1; /**< User defined Tag Protocol Identifier, to be recognized + on VLAN TAG on top of 0x8100 and 0x88A8 */ + uint16_t tag_protocol_id2; /**< User defined Tag Protocol Identifier, to be recognized + on VLAN TAG on top of 0x8100 and 0x88A8 */ + } vlan_prs_options; + + /* PPP */ + struct{ + bool enable_mtu_check; /**< Check validity of MTU according to RFC2516 */ + } pppoe_prs_options; + + /* IPV6 */ + struct { + bool routing_hdr_disable; /**< Disable routing header */ + } ipv6_prs_options; + + /* UDP */ + struct { + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */ + } udp_prs_options; + + /* TCP */ + struct { + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */ + } tcp_prs_options; +} ioc_fm_pcd_hdr_prs_opts_u; + +/**************************************************************************//** + @Description A structure for defining each header for the parser + (must match struct t_FmPcdPrsAdditionalHdrParams defined in fm_port_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_prs_additional_hdr_params_t { + ioc_net_header_type hdr; /**< Selected header */ + bool err_disable; /**< TRUE to disable error indication */ + bool soft_prs_enable; /**< Enable jump to SW parser when this + header is recognized by the HW parser. */ + uint8_t index_per_hdr; /**< Normally 0, if more than one sw parser + attachments exists for the same header, + (in the main sw parser code) use this + index to distinguish between them. */ + bool use_prs_opts; /**< TRUE to use parser options. */ + ioc_fm_pcd_hdr_prs_opts_u prs_opts; /**< A unuion according to header type, + defining the parser options selected.*/ +} ioc_fm_pcd_prs_additional_hdr_params_t; + +/**************************************************************************//** + @Description A structure for defining port PCD parameters + (Must match t_FmPortPcdPrsParams defined in fm_port_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_port_pcd_prs_params_t { + uint8_t prs_res_priv_info; /**< The private info provides a method of inserting + port information into the parser result. This information + may be extracted by KeyGen and be used for frames + distribution when a per-port distinction is required, + it may also be used as a port logical id for analyzing + incoming frames. */ + uint8_t parsing_offset; /**< Number of bytes from begining of packet to start parsing */ + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at 'parsing_offset' */ + bool include_in_prs_statistics; /**< TRUE to include this port in the parser statistics */ + uint8_t num_of_hdrs_with_additional_params; + /**< Normally 0, some headers may get special parameters */ + ioc_fm_pcd_prs_additional_hdr_params_t additional_params[IOC_FM_PCD_PRS_NUM_OF_HDRS]; + /**< 'num_of_hdrs_with_additional_params' structures + additional parameters for each header that requires them */ + bool set_vlan_tpid1; /**< TRUE to configure user selection of Ethertype to + indicate a VLAN tag (in addition to the TPID values + 0x8100 and 0x88A8). */ + uint16_t vlan_tpid1; /**< extra tag to use if set_vlan_tpid1=TRUE. */ + bool set_vlan_tpid2; /**< TRUE to configure user selection of Ethertype to + indicate a VLAN tag (in addition to the TPID values + 0x8100 and 0x88A8). */ + uint16_t vlan_tpid2; /**< extra tag to use if set_vlan_tpid1=TRUE. */ +} ioc_fm_port_pcd_prs_params_t; + +/**************************************************************************//** + @Description A structure for defining coarse alassification parameters + (Must match t_FmPortPcdCcParams defined in fm_port_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_port_pcd_cc_params_t { + void *cc_tree_id; /**< CC tree id */ +} ioc_fm_port_pcd_cc_params_t; + +/**************************************************************************//** + @Description A structure for defining keygen parameters + (Must match t_FmPortPcdKgParams defined in fm_port_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_port_pcd_kg_params_t { + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */ + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES]; + /**< Array of 'num_of_schemes' schemes for the + port to be bound to */ + bool direct_scheme; /**< TRUE for going from parser to a specific scheme, + regardless of parser result */ + void *direct_scheme_id; /**< Scheme id, as returned by FM_PCD_KgSetScheme; + relevant only if direct=TRUE. */ +} ioc_fm_port_pcd_kg_params_t; + +/**************************************************************************//** + @Description A structure for defining policer parameters + (Must match t_FmPortPcdPlcrParams defined in fm_port_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_port_pcd_plcr_params_t { + void *plcr_profile_id; /**< Selected profile handle; + relevant in one of the following cases: + e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY or + e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected, + or if any flow uses a KG scheme where policer + profile is not generated (bypass_plcr_profile_generation selected) */ +} ioc_fm_port_pcd_plcr_params_t; + +/**************************************************************************//** + @Description A structure for defining port PCD parameters + (Must match struct t_FmPortPcdParams defined in fm_port_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_port_pcd_params_t { + ioc_fm_port_pcd_support pcd_support; /**< Relevant for Rx and offline ports only. + Describes the active PCD engines for this port. */ + void *net_env_id; /**< HL Unused in PLCR only mode */ + ioc_fm_port_pcd_prs_params_t *p_prs_params; /**< Parser parameters for this port */ + ioc_fm_port_pcd_cc_params_t *p_cc_params; /**< Coarse classification parameters for this port */ + ioc_fm_port_pcd_kg_params_t *p_kg_params; /**< Keygen parameters for this port */ + ioc_fm_port_pcd_plcr_params_t *p_plcr_params; /**< Policer parameters for this port */ + void *p_ip_reassembly_manip;/**< IP Reassembly manipulation */ +#if (DPAA_VERSION >= 11) + void *p_capwap_reassembly_manip;/**< CAPWAP Reassembly manipulation */ +#endif /* (DPAA_VERSION >= 11) */ +} ioc_fm_port_pcd_params_t; + +/**************************************************************************//** + @Description A structure for defining the Parser starting point + (Must match struct t_FmPcdPrsStart defined in fm_port_ext.h) +*//***************************************************************************/ +typedef struct ioc_fm_pcd_prs_start_t { + uint8_t parsing_offset; /**< Number of bytes from begining of packet to + start parsing */ + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at + 'parsing_offset' */ +} ioc_fm_pcd_prs_start_t; + + +/**************************************************************************//** + @Description FQID parameters structure +*//***************************************************************************/ +typedef struct ioc_fm_port_pcd_fqids_params_t { + uint32_t num_fqids; /**< Number of fqids to be allocated for the port */ + uint8_t alignment; /**< Alignment required for this port */ + uint32_t base_fqid; /**< output parameter - the base fqid */ +} ioc_fm_port_pcd_fqids_params_t; + + +/**************************************************************************//** + @Function FM_PORT_IOC_ALLOC_PCD_FQIDS + + @Description Allocates FQID's + + May be used for Rx and offline parsing ports only + + @Param[in,out] ioc_fm_port_pcd_fqids_params_t Parameters for allocating FQID's + + @Return 0 on success; error code otherwise. +*//***************************************************************************/ +#define FM_PORT_IOC_ALLOC_PCD_FQIDS _IOWR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), ioc_fm_port_pcd_fqids_params_t) + +/**************************************************************************//** + @Function FM_PORT_IOC_FREE_PCD_FQIDS + + @Description Frees previously-allocated FQIDs + + May be used for Rx and offline parsing ports only + + @Param[in] uint32_t Base FQID of previously allocated range. + + @Return 0 on success; error code otherwise. +*//***************************************************************************/ +#define FM_PORT_IOC_FREE_PCD_FQIDS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), uint32_t) + + +/**************************************************************************//** + @Function FM_PORT_SetPCD + + @Description Calling this routine defines the port's PCD configuration. + It changes it from its default configuration which is PCD + disabled (BMI to BMI) and configures it according to the passed + parameters. + + May be used for Rx and offline parsing ports only + + @Param[in] ioc_fm_port_pcd_params_t A Structure of parameters defining the port's PCD + configuration. + + @Return 0 on success; error code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PORT_IOC_SET_PCD_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_compat_fm_port_pcd_params_t) +#endif +#define FM_PORT_IOC_SET_PCD _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_fm_port_pcd_params_t) + +/**************************************************************************//** + @Function FM_PORT_DeletePCD + + @Description Calling this routine releases the port's PCD configuration. + The port returns to its default configuration which is PCD + disabled (BMI to BMI) and all PCD configuration is removed. + + May be used for Rx and offline parsing ports which are + in PCD mode only + + @Return 0 on success; error code otherwise. +*//***************************************************************************/ +#define FM_PORT_IOC_DELETE_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(21)) + +/**************************************************************************//** + @Function FM_PORT_AttachPCD + + @Description This routine may be called after FM_PORT_DetachPCD was called, + to return to the originally configured PCD support flow. + The couple of routines are used to allow PCD configuration changes + that demand that PCD will not be used while changes take place. + + May be used for Rx and offline parsing ports which are + in PCD mode only + + @Return 0 on success; error code otherwise. +*//***************************************************************************/ +#define FM_PORT_IOC_ATTACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(23)) + +/**************************************************************************//** + @Function FM_PORT_DetachPCD + + @Description Calling this routine detaches the port from its PCD functionality. + The port returns to its default flow which is BMI to BMI. + + May be used for Rx and offline parsing ports which are + in PCD mode only + + @Return 0 on success; error code otherwise. +*//***************************************************************************/ +#define FM_PORT_IOC_DETACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(22)) + +/**************************************************************************//** + @Function FM_PORT_PcdPlcrAllocProfiles + + @Description This routine may be called only for ports that use the Policer in + order to allocate private policer profiles. + + @Param[in] uint16_t The number of required policer profiles + + @Return 0 on success; error code otherwise. + + @Cautions Allowed before FM_PORT_SetPCD() only. +*//***************************************************************************/ +#define FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(24), uint16_t) + +/**************************************************************************//** + @Function FM_PORT_PcdPlcrFreeProfiles + + @Description This routine should be called for freeing private policer profiles. + + @Return 0 on success; error code otherwise. + + @Cautions Allowed before FM_PORT_SetPCD() only. +*//***************************************************************************/ +#define FM_PORT_IOC_PCD_PLCR_FREE_PROFILES _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(25)) + +/**************************************************************************//** + @Function FM_PORT_PcdKgModifyInitialScheme + + @Description This routine may be called only for ports that use the keygen in + order to change the initial scheme frame should be routed to. + The change may be of a scheme id (in case of direct mode), + from direct to indirect, or from indirect to direct - specifying the scheme id. + + @Param[in] ioc_fm_pcd_kg_scheme_select_t A structure of parameters for defining whether + a scheme is direct/indirect, and if direct - scheme id. + + @Return 0 on success; error code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(26), ioc_compat_fm_pcd_kg_scheme_select_t) +#endif +#define FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(26), ioc_fm_pcd_kg_scheme_select_t) + +/**************************************************************************//** + @Function FM_PORT_PcdPlcrModifyInitialProfile + + @Description This routine may be called for ports with flows + e_IOC_FM_PCD_SUPPORT_PLCR_ONLY or e_IOC_FM_PCD_SUPPORT_PRS_AND_PLCR only, + to change the initial Policer profile frame should be routed to. + The change may be of a profile and/or absolute/direct mode selection. + + @Param[in] ioc_fm_obj_t Policer profile Id as returned from FM_PCD_PlcrSetProfile. + + @Return 0 on success; error code otherwise. +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(27), ioc_compat_fm_obj_t) +#endif +#define FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(27), ioc_fm_obj_t) + +/**************************************************************************//** + @Function FM_PORT_PcdCcModifyTree + + @Description This routine may be called to change this port connection to + a pre-initializes coarse classification Tree. + + @Param[in] ioc_fm_obj_t Id of new coarse classification tree selected for this port. + + @Return 0 on success; error code otherwise. + + @Cautions Allowed only following FM_PORT_SetPCD() and FM_PORT_DetachPCD() +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_compat_fm_obj_t) +#endif +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_fm_obj_t) + +/**************************************************************************//** + @Function FM_PORT_PcdKgBindSchemes + + @Description These routines may be called for modifying the binding of ports + to schemes. The scheme itself is not added, + just this specific port starts using it. + + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre + + @Return 0 on success; error code otherwise. + + @Cautions Allowed only following FM_PORT_SetPCD(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PORT_IOC_PCD_KG_BIND_SCHEMES_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(30), ioc_compat_fm_pcd_port_schemes_params_t) +#endif +#define FM_PORT_IOC_PCD_KG_BIND_SCHEMES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(30), ioc_fm_pcd_port_schemes_params_t) + +/**************************************************************************//** + @Function FM_PORT_PcdKgUnbindSchemes + + @Description These routines may be called for modifying the binding of ports + to schemes. The scheme itself is not removed or invalidated, + just this specific port stops using it. + + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre + + @Return 0 on success; error code otherwise. + + @Cautions Allowed only following FM_PORT_SetPCD(). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(31), ioc_compat_fm_pcd_port_schemes_params_t) +#endif +#define FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(31), ioc_fm_pcd_port_schemes_params_t) + +/**************************************************************************//** + @Function FM_PORT_PcdPrsModifyStartOffset + + @Description Runtime change of the parser start offset within the header. + + @Param[in] ioc_fm_pcd_prs_start_t A structure of parameters for defining the + start point for the parser. + + @Return 0 on success; error code otherwise. +*//***************************************************************************/ +#define FM_PORT_IOC_PCD_PRS_MODIFY_START_OFFSET _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(32), ioc_fm_pcd_prs_start_t) + +typedef struct ioc_fm_port_mac_addr_params_t { + uint8_t addr[ENET_NUM_OCTETS_PER_ADDRESS]; +} ioc_fm_port_mac_addr_params_t; + +/**************************************************************************//** + @Function FM_MAC_AddHashMacAddr + + @Description Add an Address to the hash table. This is for filter purpose only. + + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address. + @Cautions Some address need to be filtered out in upper FM blocks. +*//***************************************************************************/ +#define FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(36), ioc_fm_port_mac_addr_params_t) + +/**************************************************************************//** + @Function FM_MAC_RemoveHashMacAddr + + @Description Delete an Address to the hash table. This is for filter purpose only. + + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MAC_Init(). +*//***************************************************************************/ +#define FM_PORT_IOC_REMOVE_RX_HASH_MAC_ADDR _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(37), ioc_fm_port_mac_addr_params_t) + +typedef struct ioc_fm_port_tx_pause_frames_params_t { + uint8_t priority; + uint16_t pause_time; + uint16_t thresh_time; +} ioc_fm_port_tx_pause_frames_params_t; + +/**************************************************************************//** + @Function FM_MAC_SetTxPauseFrames + + @Description Enable/Disable transmission of Pause-Frames. + The routine changes the default configuration: + pause-time - [0xf000] + threshold-time - [0] + + @Param[in] ioc_fm_port_tx_pause_frames_params_t A structure holding the required parameters. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_MAC_Init(). + PFC is supported only on new mEMAC; i.e. in MACs that don't have + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC' + in the 'priority' field. +*//***************************************************************************/ +#define FM_PORT_IOC_SET_TX_PAUSE_FRAMES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(40), ioc_fm_port_tx_pause_frames_params_t) + +typedef struct ioc_fm_port_mac_statistics_t { + /* RMON */ + uint64_t e_stat_pkts_64; /**< r-10G tr-DT 64 byte frame counter */ + uint64_t e_stat_pkts_65_to_127; /**< r-10G 65 to 127 byte frame counter */ + uint64_t e_stat_pkts_128_to_255; /**< r-10G 128 to 255 byte frame counter */ + uint64_t e_stat_pkts_256_to_511; /**< r-10G 256 to 511 byte frame counter */ + uint64_t e_stat_pkts_512_to_1023; /**< r-10G 512 to 1023 byte frame counter */ + uint64_t e_stat_pkts_1024_to_1518; /**< r-10G 1024 to 1518 byte frame counter */ + uint64_t e_stat_pkts_1519_to_1522; /**< r-10G 1519 to 1522 byte good frame count */ + /* */ + uint64_t e_stat_fragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/ + uint64_t e_stat_jabbers; /**< Total number of packets longer than valid maximum length octets */ + uint64_t e_stat_drop_events; /**< number of dropped packets due to internal errors of the MAC Client (during recieve). */ + uint64_t e_stat_CRC_align_errors; /**< Incremented when frames of correct length but with CRC error are received.*/ + uint64_t e_stat_undersize_pkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed; + This count does not include range length errors */ + uint64_t e_stat_oversize_pkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains + a valid FCS and otherwise well formed */ + /* Pause */ + uint64_t te_stat_pause; /**< Pause MAC Control received */ + uint64_t re_stat_pause; /**< Pause MAC Control sent */ + /* MIB II */ + uint64_t if_in_octets; /**< Total number of byte received. */ + uint64_t if_in_pkts; /**< Total number of packets received.*/ + uint64_t if_in_ucast_pkts; /**< Total number of unicast frame received; + NOTE: this counter is not supported on dTSEC MAC */ + uint64_t if_in_mcast_pkts; /**< Total number of multicast frame received*/ + uint64_t if_in_bcast_pkts; /**< Total number of broadcast frame received */ + uint64_t if_in_discards; /**< Frames received, but discarded due to problems within the MAC RX. */ + uint64_t if_in_errors; /**< Number of frames received with error: + - FIFO Overflow Error + - CRC Error + - Frame Too Long Error + - Alignment Error + - The dedicated Error Code (0xfe, not a code error) was received */ + uint64_t if_out_octets; /**< Total number of byte sent. */ + uint64_t if_out_pkts; /**< Total number of packets sent .*/ + uint64_t if_out_ucast_pkts; /**< Total number of unicast frame sent; + NOTE: this counter is not supported on dTSEC MAC */ + uint64_t if_out_mcast_pkts; /**< Total number of multicast frame sent */ + uint64_t if_out_bcast_pkts; /**< Total number of multicast frame sent */ + uint64_t if_out_discards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/ + uint64_t if_out_errors; /**< Number of frames transmitted with error: + - FIFO Overflow Error + - FIFO Underflow Error + - Other */ +} ioc_fm_port_mac_statistics_t; + +/**************************************************************************//** + @Function FM_MAC_GetStatistics + + @Description get all MAC statistics counters + + @Param[out] ioc_fm_port_mac_statistics_t A structure holding the statistics + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_Init(). +*//***************************************************************************/ +#define FM_PORT_IOC_GET_MAC_STATISTICS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(41), ioc_fm_port_mac_statistics_t) + +/**************************************************************************//** + @Function FM_PORT_ConfigBufferPrefixContent + + @Description Defines the structure, size and content of the application buffer. + The prefix will + In Tx ports, if 'passPrsResult', the application + should set a value to their offsets in the prefix of + the FM will save the first 'privDataSize', than, + depending on 'passPrsResult' and 'passTimeStamp', copy parse result + and timeStamp, and the packet itself (in this order), to the + application buffer, and to offset. + Calling this routine changes the buffer margins definitions + in the internal driver data base from its default + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize] + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult]. + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp]. + + May be used for all ports + + @Param[in] ioc_fm_buffer_prefix_content_t A structure holding the required parameters. + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). +*//***************************************************************************/ +#define FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(39), ioc_fm_buffer_prefix_content_t) + +#if (DPAA_VERSION >= 11) +typedef struct ioc_fm_port_vsp_alloc_params_t { + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */ + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port + The same default Virtual-Storage-Profile-id will be for coupled Tx port + if relevant function called for Rx port */ + void *p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */ +}ioc_fm_port_vsp_alloc_params_t; + +/**************************************************************************//** + @Function FM_PORT_VSPAlloc + + @Description This routine allocated VSPs per port and forces the port to work + in VSP mode. Note that the port is initialized by default with the + physical-storage-profile only. + + @Param[in] h_FmPort A handle to a FM Port module. + @Param[in] p_Params A structure of parameters for allocation VSP's per port + + @Return E_OK on success; Error code otherwise. + + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD() + and also before FM_PORT_Enable() (i.e. the port should be disabled). +*//***************************************************************************/ +#if defined(CONFIG_COMPAT) +#define FM_PORT_IOC_VSP_ALLOC_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(38), ioc_compat_fm_port_vsp_alloc_params_t) +#endif +#define FM_PORT_IOC_VSP_ALLOC _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(38), ioc_fm_port_vsp_alloc_params_t) +#endif /* (DPAA_VERSION >= 11) */ + +/** @} */ /* end of lnx_ioctl_FM_PORT_pcd_runtime_control_grp group */ +/** @} */ /* end of lnx_ioctl_FM_PORT_runtime_control_grp group */ + +/** @} */ /* end of lnx_ioctl_FM_PORT_grp group */ +/** @} */ /* end of lnx_ioctl_FM_grp group */ +#endif /* __FM_PORT_IOCTLS_H */ diff --git a/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h b/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h new file mode 100644 index 0000000..207ed1e --- /dev/null +++ b/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h @@ -0,0 +1,208 @@ +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/**************************************************************************//** + @File fm_test_ioctls.h + + @Description FM Char device ioctls +*//***************************************************************************/ +#ifndef __FM_TEST_IOCTLS_H +#define __FM_TEST_IOCTLS_H + +#include "ioctls.h" + + +/**************************************************************************//** + @Group lnx_ioctl_FMT_grp Frame Manager Test Linux IOCTL API + + @Description FM-Test Linux ioctls definitions and enums + + @{ +*//***************************************************************************/ + +#define IOC_FMT_MAX_NUM_OF_PORTS 26 + +/**************************************************************************//** + @Collection TEST Parameters +*//***************************************************************************/ +/**************************************************************************//** + @Description: Name of the FM-Test chardev +*//***************************************************************************/ +#define DEV_FM_TEST_NAME "fm-test-port" + +#define DEV_FM_TEST_PORTS_MINOR_BASE 0 +#define DEV_FM_TEST_MAX_MINORS (DEV_FM_TEST_PORTS_MINOR_BASE + IOC_FMT_MAX_NUM_OF_PORTS) + +#define FMT_PORT_IOC_NUM(n) n +/* @} */ + +/**************************************************************************//** + @Group lnx_ioctl_FMT_lib_grp FM-Test library + + @Description TODO + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Description TODO +*//***************************************************************************/ +typedef uint8_t ioc_fmt_xxx_t; + +#define FM_PRS_MAX 32 +#define FM_TIME_STAMP_MAX 8 + +/**************************************************************************//** + @Description FM Port buffer content description +*//***************************************************************************/ +typedef struct ioc_fmt_buff_context_t { + void *p_user_priv; + uint8_t fm_prs_res[FM_PRS_MAX]; + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX]; +} ioc_fmt_buff_context_t; + +#if defined(__KERNEL__) && defined(CONFIG_COMPAT) +typedef struct ioc_fmt_compat_buff_context_t { + compat_uptr_t p_user_priv; + uint8_t fm_prs_res[FM_PRS_MAX]; + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX]; +} ioc_fmt_compat_buff_context_t; +#endif + +/**************************************************************************//** + @Description Buffer descriptor +*//***************************************************************************/ +typedef struct ioc_fmt_buff_desc_t { + uint32_t qid; + void *p_data; + uint32_t size; + uint32_t status; + ioc_fmt_buff_context_t buff_context; +} ioc_fmt_buff_desc_t; + +#if defined(__KERNEL__) && defined(CONFIG_COMPAT) +typedef struct ioc_fmt_compat_buff_desc_t { + uint32_t qid; + compat_uptr_t p_data; + uint32_t size; + uint32_t status; + ioc_fmt_compat_buff_context_t buff_context; +} ioc_fmt_compat_buff_desc_t; +#endif + +/**************************************************************************//** + @Group lnx_ioctl_FMT_runtime_control_grp FM-Test Runtime Control Unit + + @Description TODO + @{ +*//***************************************************************************/ + +/** @} */ /* end of lnx_ioctl_FMT_runtime_control_grp group */ + + +/**************************************************************************//** + @Group lnx_ioctl_FMTP_lib_grp FM-Port-Test library + + @Description TODO + + @{ +*//***************************************************************************/ + +/**************************************************************************//** + @Description FM-Test FM port type +*//***************************************************************************/ +typedef enum ioc_fmt_port_type { + e_IOC_FMT_PORT_T_RXTX, /**< Standard port */ + e_IOC_FMT_PORT_T_OP, /**< Offline-parsing port */ +} ioc_fmt_port_type; + +/**************************************************************************//** + @Description TODO +*//***************************************************************************/ +typedef struct ioc_fmt_port_param_t { + uint8_t fm_id; + ioc_fmt_port_type fm_port_type; + uint8_t fm_port_id; + uint32_t num_tx_queues; +} ioc_fmt_port_param_t; + + +/**************************************************************************//** + @Function FMT_PORT_IOC_INIT + + @Description TODO + + @Param[in] ioc_fmt_port_param_t TODO + + @Cautions Allowed only after the FM equivalent port is already initialized. +*//***************************************************************************/ +#define FMT_PORT_IOC_INIT _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(0), ioc_fmt_port_param_t) + +/**************************************************************************//** + @Function FMT_PORT_IOC_SET_DIAG_MODE + + @Description TODO + + @Param[in] ioc_diag_mode TODO + + @Cautions Allowed only following FMT_PORT_IOC_INIT(). +*//***************************************************************************/ +#define FMT_PORT_IOC_SET_DIAG_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(1), ioc_diag_mode) + +/**************************************************************************//** + @Function FMT_PORT_IOC_SET_IP_HEADER_MANIP + + @Description Set IP header manipulations for this port. + + @Param[in] int 1 to enable; 0 to disable + + @Cautions Allowed only following FMT_PORT_IOC_INIT(). +*//***************************************************************************/ +#define FMT_PORT_IOC_SET_IP_HEADER_MANIP _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(2), int) + +/**************************************************************************//** + @Function FMT_PORT_IOC_SET_DPAECHO_MODE + + @Description Set DPA in echo mode - all frame are sent back. + + @Param[in] int 1 to enable; 0 to disable + + @Cautions Allowed only following FMT_PORT_IOC_INIT(). +*//***************************************************************************/ +#define FMT_PORT_IOC_SET_DPAECHO_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(3), int) + +/** @} */ /* end of lnx_ioctl_FMTP_lib_grp group */ +/** @} */ /* end of lnx_ioctl_FMT_lib_grp group */ +/** @} */ /* end of lnx_ioctl_FMT_grp */ + + +#endif /* __FM_TEST_IOCTLS_H */ diff --git a/include/uapi/linux/fmd/integrations/Kbuild b/include/uapi/linux/fmd/integrations/Kbuild new file mode 100644 index 0000000..e548d676 --- /dev/null +++ b/include/uapi/linux/fmd/integrations/Kbuild @@ -0,0 +1 @@ +header-y += integration_ioctls.h diff --git a/include/uapi/linux/fmd/integrations/integration_ioctls.h b/include/uapi/linux/fmd/integrations/integration_ioctls.h new file mode 100644 index 0000000..61d696e --- /dev/null +++ b/include/uapi/linux/fmd/integrations/integration_ioctls.h @@ -0,0 +1,56 @@ +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/**************************************************************************//** + @File integration_ioctls.h + + @Description External header file for Integration unit routines. +*//***************************************************************************/ + +#ifndef __INTG_IOCTLS_H +#define __INTG_IOCTLS_H + + +#define FM_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+1) +#define FMT_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+3) + +/*#define FM_IOCTL_DBG*/ + +#if defined(FM_IOCTL_DBG) + #define _fm_ioctl_dbg(format, arg...) \ + printk("fm ioctl [%s:%u](cpu:%u) - " format, \ + __func__, __LINE__, smp_processor_id(), ##arg) +#else +# define _fm_ioctl_dbg(arg...) +#endif + +#endif /* __INTG_IOCTLS_H */ diff --git a/include/uapi/linux/fmd/ioctls.h b/include/uapi/linux/fmd/ioctls.h new file mode 100644 index 0000000..4f36cb0 --- /dev/null +++ b/include/uapi/linux/fmd/ioctls.h @@ -0,0 +1,96 @@ +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/**************************************************************************//** + @File ioctls.h + + @Description Structures and definitions for Command Relay Ioctls +*//***************************************************************************/ + +#ifndef __IOCTLS_H__ +#define __IOCTLS_H__ + +#include <asm/ioctl.h> + +#include "integration_ioctls.h" + + +/**************************************************************************//** + @Group lnx_ioctl_ncsw_grp NetCommSw Linux User-Space (IOCTL) API + @{ +*//***************************************************************************/ + +#define NCSW_IOC_TYPE_BASE 0xe0 /**< defines the IOCTL type for all + the NCSW Linux module commands */ + + +/**************************************************************************//** + @Description IOCTL Memory allocation types. +*//***************************************************************************/ +typedef enum ioc_mem_type { + e_IOC_MEM_INVALID = 0x00000000, /**< Invalid memory type (error) */ + e_IOC_MEM_CACHABLE_SYS = 0x00000001, /**< Primary DDR, cacheable segment */ + e_IOC_MEM_NOCACHE_SYS = 0x00000004, /**< Primary DDR, non-cacheable segment */ + e_IOC_MEM_SECONDARY = 0x00000002, /**< Either secondary DDR or SDRAM */ + e_IOC_MEM_PRAM = 0x00000008 /**< Multi-user RAM identifier */ +} ioc_mem_type; + +/**************************************************************************//** + @Description Enumeration (bit flags) of communication modes (Transmit, + receive or both). +*//***************************************************************************/ +typedef enum ioc_comm_mode { + e_IOC_COMM_MODE_NONE = 0 /**< No transmit/receive communication */ + , e_IOC_COMM_MODE_RX = 1 /**< Only receive communication */ + , e_IOC_COMM_MODE_TX = 2 /**< Only transmit communication */ + , e_IOC_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */ +} ioc_comm_mode; + +/**************************************************************************//** + @Description General Diagnostic Mode +*//***************************************************************************/ +typedef enum ioc_diag_mode +{ + e_IOC_DIAG_MODE_NONE = 0, + e_IOC_DIAG_MODE_CTRL_LOOPBACK, /**< loopback in the controller; E.g. MAC, TDM, etc. */ + e_IOC_DIAG_MODE_CHIP_LOOPBACK, /**< loopback in the chip but not in controller; + E.g. IO-pins, SerDes, etc. */ + e_IOC_DIAG_MODE_PHY_LOOPBACK, /**< loopback in the external PHY */ + e_IOC_DIAG_MODE_LINE_LOOPBACK, /**< loopback in the external line */ + e_IOC_DIAG_MODE_CTRL_ECHO, /**< */ + e_IOC_DIAG_MODE_PHY_ECHO /**< */ +} ioc_diag_mode; + +/** @} */ /* end of lnx_ioctl_ncsw_grp */ + + +#endif /* __IOCTLS_H__ */ diff --git a/include/uapi/linux/fmd/net_ioctls.h b/include/uapi/linux/fmd/net_ioctls.h new file mode 100644 index 0000000..c99d64c --- /dev/null +++ b/include/uapi/linux/fmd/net_ioctls.h @@ -0,0 +1,430 @@ +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +/**************************************************************************//** + @File net_ioctls.h + + @Description This file contains common and general netcomm headers definitions. +*//***************************************************************************/ +#ifndef __NET_IOCTLS_H +#define __NET_IOCTLS_H + +#include "ioctls.h" + + +typedef uint8_t ioc_header_field_ppp_t; + +#define IOC_NET_HEADER_FIELD_PPP_PID (1) +#define IOC_NET_HEADER_FIELD_PPP_COMPRESSED (IOC_NET_HEADER_FIELD_PPP_PID << 1) +#define IOC_NET_HEADER_FIELD_PPP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPP_PID << 2) - 1) + + +typedef uint8_t ioc_header_field_pppoe_t; + +#define IOC_NET_HEADER_FIELD_PPPoE_VER (1) +#define IOC_NET_HEADER_FIELD_PPPoE_TYPE (IOC_NET_HEADER_FIELD_PPPoE_VER << 1) +#define IOC_NET_HEADER_FIELD_PPPoE_CODE (IOC_NET_HEADER_FIELD_PPPoE_VER << 2) +#define IOC_NET_HEADER_FIELD_PPPoE_SID (IOC_NET_HEADER_FIELD_PPPoE_VER << 3) +#define IOC_NET_HEADER_FIELD_PPPoE_LEN (IOC_NET_HEADER_FIELD_PPPoE_VER << 4) +#define IOC_NET_HEADER_FIELD_PPPoE_SESSION (IOC_NET_HEADER_FIELD_PPPoE_VER << 5) +#define IOC_NET_HEADER_FIELD_PPPoE_PID (IOC_NET_HEADER_FIELD_PPPoE_VER << 6) +#define IOC_NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPoE_VER << 7) - 1) + +#define IOC_NET_HEADER_FIELD_PPPMUX_PID (1) +#define IOC_NET_HEADER_FIELD_PPPMUX_CKSUM (IOC_NET_HEADER_FIELD_PPPMUX_PID << 1) +#define IOC_NET_HEADER_FIELD_PPPMUX_COMPRESSED (IOC_NET_HEADER_FIELD_PPPMUX_PID << 2) +#define IOC_NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_PID << 3) - 1) + +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1) +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1) +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2) +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3) +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4) +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1) + + +typedef uint8_t ioc_header_field_eth_t; + +#define IOC_NET_HEADER_FIELD_ETH_DA (1) +#define IOC_NET_HEADER_FIELD_ETH_SA (IOC_NET_HEADER_FIELD_ETH_DA << 1) +#define IOC_NET_HEADER_FIELD_ETH_LENGTH (IOC_NET_HEADER_FIELD_ETH_DA << 2) +#define IOC_NET_HEADER_FIELD_ETH_TYPE (IOC_NET_HEADER_FIELD_ETH_DA << 3) +#define IOC_NET_HEADER_FIELD_ETH_FINAL_CKSUM (IOC_NET_HEADER_FIELD_ETH_DA << 4) +#define IOC_NET_HEADER_FIELD_ETH_PADDING (IOC_NET_HEADER_FIELD_ETH_DA << 5) +#define IOC_NET_HEADER_FIELD_ETH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ETH_DA << 6) - 1) + +#define IOC_NET_HEADER_FIELD_ETH_ADDR_SIZE 6 + +typedef uint16_t ioc_header_field_ip_t; + +#define IOC_NET_HEADER_FIELD_IP_VER (1) +#define IOC_NET_HEADER_FIELD_IP_DSCP (IOC_NET_HEADER_FIELD_IP_VER << 2) +#define IOC_NET_HEADER_FIELD_IP_ECN (IOC_NET_HEADER_FIELD_IP_VER << 3) +#define IOC_NET_HEADER_FIELD_IP_PROTO (IOC_NET_HEADER_FIELD_IP_VER << 4) + +#define IOC_NET_HEADER_FIELD_IP_PROTO_SIZE 1 + +typedef uint16_t ioc_header_field_ipv4_t; + +#define IOC_NET_HEADER_FIELD_IPv4_VER (1) +#define IOC_NET_HEADER_FIELD_IPv4_HDR_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 1) +#define IOC_NET_HEADER_FIELD_IPv4_TOS (IOC_NET_HEADER_FIELD_IPv4_VER << 2) +#define IOC_NET_HEADER_FIELD_IPv4_TOTAL_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 3) +#define IOC_NET_HEADER_FIELD_IPv4_ID (IOC_NET_HEADER_FIELD_IPv4_VER << 4) +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_D (IOC_NET_HEADER_FIELD_IPv4_VER << 5) +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_M (IOC_NET_HEADER_FIELD_IPv4_VER << 6) +#define IOC_NET_HEADER_FIELD_IPv4_OFFSET (IOC_NET_HEADER_FIELD_IPv4_VER << 7) +#define IOC_NET_HEADER_FIELD_IPv4_TTL (IOC_NET_HEADER_FIELD_IPv4_VER << 8) +#define IOC_NET_HEADER_FIELD_IPv4_PROTO (IOC_NET_HEADER_FIELD_IPv4_VER << 9) +#define IOC_NET_HEADER_FIELD_IPv4_CKSUM (IOC_NET_HEADER_FIELD_IPv4_VER << 10) +#define IOC_NET_HEADER_FIELD_IPv4_SRC_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 11) +#define IOC_NET_HEADER_FIELD_IPv4_DST_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 12) +#define IOC_NET_HEADER_FIELD_IPv4_OPTS (IOC_NET_HEADER_FIELD_IPv4_VER << 13) +#define IOC_NET_HEADER_FIELD_IPv4_OPTS_COUNT (IOC_NET_HEADER_FIELD_IPv4_VER << 14) +#define IOC_NET_HEADER_FIELD_IPv4_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv4_VER << 15) - 1) + +#define IOC_NET_HEADER_FIELD_IPv4_ADDR_SIZE 4 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO_SIZE 1 + + +typedef uint8_t ioc_header_field_ipv6_t; + +#define IOC_NET_HEADER_FIELD_IPv6_VER (1) +#define IOC_NET_HEADER_FIELD_IPv6_TC (IOC_NET_HEADER_FIELD_IPv6_VER << 1) +#define IOC_NET_HEADER_FIELD_IPv6_SRC_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 2) +#define IOC_NET_HEADER_FIELD_IPv6_DST_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 3) +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR (IOC_NET_HEADER_FIELD_IPv6_VER << 4) +#define IOC_NET_HEADER_FIELD_IPv6_FL (IOC_NET_HEADER_FIELD_IPv6_VER << 5) +#define IOC_NET_HEADER_FIELD_IPv6_HOP_LIMIT (IOC_NET_HEADER_FIELD_IPv6_VER << 6) +#define IOC_NET_HEADER_FIELD_IPv6_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv6_VER << 7) - 1) + +#define IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE 16 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1 + +#define IOC_NET_HEADER_FIELD_ICMP_TYPE (1) +#define IOC_NET_HEADER_FIELD_ICMP_CODE (IOC_NET_HEADER_FIELD_ICMP_TYPE << 1) +#define IOC_NET_HEADER_FIELD_ICMP_CKSUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 2) +#define IOC_NET_HEADER_FIELD_ICMP_ID (IOC_NET_HEADER_FIELD_ICMP_TYPE << 3) +#define IOC_NET_HEADER_FIELD_ICMP_SQ_NUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 4) +#define IOC_NET_HEADER_FIELD_ICMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ICMP_TYPE << 5) - 1) + +#define IOC_NET_HEADER_FIELD_ICMP_CODE_SIZE 1 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE_SIZE 1 + +#define IOC_NET_HEADER_FIELD_IGMP_VERSION (1) +#define IOC_NET_HEADER_FIELD_IGMP_TYPE (IOC_NET_HEADER_FIELD_IGMP_VERSION << 1) +#define IOC_NET_HEADER_FIELD_IGMP_CKSUM (IOC_NET_HEADER_FIELD_IGMP_VERSION << 2) +#define IOC_NET_HEADER_FIELD_IGMP_DATA (IOC_NET_HEADER_FIELD_IGMP_VERSION << 3) +#define IOC_NET_HEADER_FIELD_IGMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IGMP_VERSION << 4) - 1) + + +typedef uint16_t ioc_header_field_tcp_t; + +#define IOC_NET_HEADER_FIELD_TCP_PORT_SRC (1) +#define IOC_NET_HEADER_FIELD_TCP_PORT_DST (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 1) +#define IOC_NET_HEADER_FIELD_TCP_SEQ (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 2) +#define IOC_NET_HEADER_FIELD_TCP_ACK (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 3) +#define IOC_NET_HEADER_FIELD_TCP_OFFSET (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 4) +#define IOC_NET_HEADER_FIELD_TCP_FLAGS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 5) +#define IOC_NET_HEADER_FIELD_TCP_WINDOW (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 6) +#define IOC_NET_HEADER_FIELD_TCP_CKSUM (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 7) +#define IOC_NET_HEADER_FIELD_TCP_URGPTR (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 8) +#define IOC_NET_HEADER_FIELD_TCP_OPTS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 9) +#define IOC_NET_HEADER_FIELD_TCP_OPTS_COUNT (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 10) +#define IOC_NET_HEADER_FIELD_TCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1) + +#define IOC_NET_HEADER_FIELD_TCP_PORT_SIZE 2 + + +typedef uint8_t ioc_header_field_sctp_t; + +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SRC (1) +#define IOC_NET_HEADER_FIELD_SCTP_PORT_DST (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 1) +#define IOC_NET_HEADER_FIELD_SCTP_VER_TAG (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 2) +#define IOC_NET_HEADER_FIELD_SCTP_CKSUM (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 3) +#define IOC_NET_HEADER_FIELD_SCTP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1) + +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SIZE 2 + +typedef uint8_t ioc_header_field_dccp_t; + +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SRC (1) +#define IOC_NET_HEADER_FIELD_DCCP_PORT_DST (IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 1) +#define IOC_NET_HEADER_FIELD_DCCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1) + +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SIZE 2 + + +typedef uint8_t ioc_header_field_udp_t; + +#define IOC_NET_HEADER_FIELD_UDP_PORT_SRC (1) +#define IOC_NET_HEADER_FIELD_UDP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 1) +#define IOC_NET_HEADER_FIELD_UDP_LEN (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 2) +#define IOC_NET_HEADER_FIELD_UDP_CKSUM (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 3) +#define IOC_NET_HEADER_FIELD_UDP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1) + +#define IOC_NET_HEADER_FIELD_UDP_PORT_SIZE 2 + +typedef uint8_t ioc_header_field_udp_lite_t; + +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1) +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_DST (IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1) +#define IOC_NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1) + +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2 + +typedef uint8_t ioc_header_field_udp_encap_esp_t; + +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1) +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1) +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2) +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3) +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4) +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5) +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1) + +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4 + +#define IOC_NET_HEADER_FIELD_IPHC_CID (1) +#define IOC_NET_HEADER_FIELD_IPHC_CID_TYPE (IOC_NET_HEADER_FIELD_IPHC_CID << 1) +#define IOC_NET_HEADER_FIELD_IPHC_HCINDEX (IOC_NET_HEADER_FIELD_IPHC_CID << 2) +#define IOC_NET_HEADER_FIELD_IPHC_GEN (IOC_NET_HEADER_FIELD_IPHC_CID << 3) +#define IOC_NET_HEADER_FIELD_IPHC_D_BIT (IOC_NET_HEADER_FIELD_IPHC_CID << 4) +#define IOC_NET_HEADER_FIELD_IPHC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPHC_CID << 5) - 1) + +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1) +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1) +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2) +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3) +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4) +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5) +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6) +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7) +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8) +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9) +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1) + +#define IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1) +#define IOC_NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1) +#define IOC_NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2) +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3) +#define IOC_NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4) +#define IOC_NET_HEADER_FIELD_L2TPv2_VERSION (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5) +#define IOC_NET_HEADER_FIELD_L2TPv2_LEN (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6) +#define IOC_NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7) +#define IOC_NET_HEADER_FIELD_L2TPv2_SESSION_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8) +#define IOC_NET_HEADER_FIELD_L2TPv2_NS (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9) +#define IOC_NET_HEADER_FIELD_L2TPv2_NR (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10) +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11) +#define IOC_NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12) +#define IOC_NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1) + +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1) +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1) +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2) +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3) +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4) +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5) +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SENT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6) +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_RECV (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7) +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8) +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1) + +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1) +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1) +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ID (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2) +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3) +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1) + + +typedef uint8_t ioc_header_field_vlan_t; + +#define IOC_NET_HEADER_FIELD_VLAN_VPRI (1) +#define IOC_NET_HEADER_FIELD_VLAN_CFI (IOC_NET_HEADER_FIELD_VLAN_VPRI << 1) +#define IOC_NET_HEADER_FIELD_VLAN_VID (IOC_NET_HEADER_FIELD_VLAN_VPRI << 2) +#define IOC_NET_HEADER_FIELD_VLAN_LENGTH (IOC_NET_HEADER_FIELD_VLAN_VPRI << 3) +#define IOC_NET_HEADER_FIELD_VLAN_TYPE (IOC_NET_HEADER_FIELD_VLAN_VPRI << 4) +#define IOC_NET_HEADER_FIELD_VLAN_ALL_FIELDS ((IOC_NET_HEADER_FIELD_VLAN_VPRI << 5) - 1) + +#define IOC_NET_HEADER_FIELD_VLAN_TCI (IOC_NET_HEADER_FIELD_VLAN_VPRI | \ + IOC_NET_HEADER_FIELD_VLAN_CFI | \ + IOC_NET_HEADER_FIELD_VLAN_VID) + + +typedef uint8_t ioc_header_field_llc_t; + +#define IOC_NET_HEADER_FIELD_LLC_DSAP (1) +#define IOC_NET_HEADER_FIELD_LLC_SSAP (IOC_NET_HEADER_FIELD_LLC_DSAP << 1) +#define IOC_NET_HEADER_FIELD_LLC_CTRL (IOC_NET_HEADER_FIELD_LLC_DSAP << 2) +#define IOC_NET_HEADER_FIELD_LLC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_DSAP << 3) - 1) + +#define IOC_NET_HEADER_FIELD_NLPID_NLPID (1) +#define IOC_NET_HEADER_FIELD_NLPID_ALL_FIELDS ((IOC_NET_HEADER_FIELD_NLPID_NLPID << 1) - 1) + + +typedef uint8_t ioc_header_field_snap_t; + +#define IOC_NET_HEADER_FIELD_SNAP_OUI (1) +#define IOC_NET_HEADER_FIELD_SNAP_PID (IOC_NET_HEADER_FIELD_SNAP_OUI << 1) +#define IOC_NET_HEADER_FIELD_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SNAP_OUI << 2) - 1) + + +typedef uint8_t ioc_header_field_llc_snap_t; + +#define IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE (1) +#define IOC_NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1) + +#define IOC_NET_HEADER_FIELD_ARP_HTYPE (1) +#define IOC_NET_HEADER_FIELD_ARP_PTYPE (IOC_NET_HEADER_FIELD_ARP_HTYPE << 1) +#define IOC_NET_HEADER_FIELD_ARP_HLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 2) +#define IOC_NET_HEADER_FIELD_ARP_PLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 3) +#define IOC_NET_HEADER_FIELD_ARP_OPER (IOC_NET_HEADER_FIELD_ARP_HTYPE << 4) +#define IOC_NET_HEADER_FIELD_ARP_SHA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 5) +#define IOC_NET_HEADER_FIELD_ARP_SPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 6) +#define IOC_NET_HEADER_FIELD_ARP_THA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 7) +#define IOC_NET_HEADER_FIELD_ARP_TPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 8) +#define IOC_NET_HEADER_FIELD_ARP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ARP_HTYPE << 9) - 1) + +#define IOC_NET_HEADER_FIELD_RFC2684_LLC (1) +#define IOC_NET_HEADER_FIELD_RFC2684_NLPID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 1) +#define IOC_NET_HEADER_FIELD_RFC2684_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 2) +#define IOC_NET_HEADER_FIELD_RFC2684_PID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 3) +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 4) +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_IDX (IOC_NET_HEADER_FIELD_RFC2684_LLC << 5) +#define IOC_NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((IOC_NET_HEADER_FIELD_RFC2684_LLC << 6) - 1) + +#define IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1) +#define IOC_NET_HEADER_FIELD_USER_DEFINED_PCDID (IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1) +#define IOC_NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1) + +#define IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER (1) +#define IOC_NET_HEADER_FIELD_PAYLOAD_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 1) +#define IOC_NET_HEADER_FIELD_MAX_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 2) +#define IOC_NET_HEADER_FIELD_MIN_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 3) +#define IOC_NET_HEADER_FIELD_PAYLOAD_TYPE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 4) +#define IOC_NET_HEADER_FIELD_FRAME_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 5) +#define IOC_NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1) + + +typedef uint8_t ioc_header_field_gre_t; + +#define IOC_NET_HEADER_FIELD_GRE_TYPE (1) +#define IOC_NET_HEADER_FIELD_GRE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_GRE_TYPE << 1) - 1) + + +typedef uint8_t ioc_header_field_minencap_t; + +#define IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP (1) +#define IOC_NET_HEADER_FIELD_MINENCAP_DST_IP (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 1) +#define IOC_NET_HEADER_FIELD_MINENCAP_TYPE (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 2) +#define IOC_NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1) + + +typedef uint8_t ioc_header_field_ipsec_ah_t; + +#define IOC_NET_HEADER_FIELD_IPSEC_AH_SPI (1) +#define IOC_NET_HEADER_FIELD_IPSEC_AH_NH (IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 1) +#define IOC_NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1) + + +typedef uint8_t ioc_header_field_ipsec_esp_t; + +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI (1) +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 1) +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1) + +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4 + + +typedef uint8_t ioc_header_field_mpls_t; + +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK (1) +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1) + + +typedef uint8_t ioc_header_field_macsec_t; + +#define IOC_NET_HEADER_FIELD_MACSEC_SECTAG (1) +#define IOC_NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1) + + +typedef enum { + e_IOC_NET_HEADER_TYPE_NONE = 0, + e_IOC_NET_HEADER_TYPE_PAYLOAD, + e_IOC_NET_HEADER_TYPE_ETH, + e_IOC_NET_HEADER_TYPE_VLAN, + e_IOC_NET_HEADER_TYPE_IPv4, + e_IOC_NET_HEADER_TYPE_IPv6, + e_IOC_NET_HEADER_TYPE_IP, + e_IOC_NET_HEADER_TYPE_TCP, + e_IOC_NET_HEADER_TYPE_UDP, + e_IOC_NET_HEADER_TYPE_UDP_LITE, + e_IOC_NET_HEADER_TYPE_IPHC, + e_IOC_NET_HEADER_TYPE_SCTP, + e_IOC_NET_HEADER_TYPE_SCTP_CHUNK_DATA, + e_IOC_NET_HEADER_TYPE_PPPoE, + e_IOC_NET_HEADER_TYPE_PPP, + e_IOC_NET_HEADER_TYPE_PPPMUX, + e_IOC_NET_HEADER_TYPE_PPPMUX_SUBFRAME, + e_IOC_NET_HEADER_TYPE_L2TPv2, + e_IOC_NET_HEADER_TYPE_L2TPv3_CTRL, + e_IOC_NET_HEADER_TYPE_L2TPv3_SESS, + e_IOC_NET_HEADER_TYPE_LLC, + e_IOC_NET_HEADER_TYPE_LLC_SNAP, + e_IOC_NET_HEADER_TYPE_NLPID, + e_IOC_NET_HEADER_TYPE_SNAP, + e_IOC_NET_HEADER_TYPE_MPLS, + e_IOC_NET_HEADER_TYPE_IPSEC_AH, + e_IOC_NET_HEADER_TYPE_IPSEC_ESP, + e_IOC_NET_HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */ + e_IOC_NET_HEADER_TYPE_MACSEC, + e_IOC_NET_HEADER_TYPE_GRE, + e_IOC_NET_HEADER_TYPE_MINENCAP, + e_IOC_NET_HEADER_TYPE_DCCP, + e_IOC_NET_HEADER_TYPE_ICMP, + e_IOC_NET_HEADER_TYPE_IGMP, + e_IOC_NET_HEADER_TYPE_ARP, + e_IOC_NET_HEADER_TYPE_CAPWAP, + e_IOC_NET_HEADER_TYPE_CAPWAP_DTLS, + e_IOC_NET_HEADER_TYPE_RFC2684, + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L2, + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L3, + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L4, + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM1, + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM2, + e_IOC_NET_MAX_HEADER_TYPE_COUNT +} ioc_net_header_type; + + +#endif /* __NET_IOCTLS_H */ diff --git a/include/uapi/linux/fsl_pci_ep_vfio.h b/include/uapi/linux/fsl_pci_ep_vfio.h new file mode 100644 index 0000000..8960157 --- /dev/null +++ b/include/uapi/linux/fsl_pci_ep_vfio.h @@ -0,0 +1,79 @@ +/* + * Copyright 2013 Freescale Semiconductor, Inc. + * + * Author: Minghuan Lian <Minghuan.Lian@freescale.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef _FSL_PCI_EP_VFIO_H +#define _FSL_PCI_EP_VFIO_H + +#include <linux/vfio.h> + +enum { + PCI_EP_TYPE_PF, + PCI_EP_TYPE_VF, +}; + +enum PCI_EP_REGION_TYPE { + PCI_EP_REGION_IBWIN, + PCI_EP_REGION_OBWIN, + PCI_EP_REGION_VF_IBWIN, + PCI_EP_REGION_VF_OBWIN, + PCI_EP_REGION_REGS, + PCI_EP_REGION_CONFIG, + PCI_EP_REGION_MEM, + PCI_EP_REGION_MSIX_OBWIN +}; + +enum PCI_EP_REGION_INDEX { + PCI_EP_WIN0_INDEX, + PCI_EP_WIN1_INDEX, + PCI_EP_WIN2_INDEX, + PCI_EP_WIN3_INDEX, + PCI_EP_WIN4_INDEX, + PCI_EP_WIN5_INDEX, +}; + +#define PCI_EP_MSI_WIN_INDEX PCI_EP_WIN1_INDEX +#define PCI_EP_CCSR_WIN_INDEX PCI_EP_WIN0_INDEX +#define PCI_EP_DEFAULT_OW_INDEX PCI_EP_WIN0_INDEX + +struct pci_ep_win { + uint64_t pci_addr; + uint64_t cpu_addr; + uint64_t size; + uint64_t offset; + uint32_t attr; + uint32_t type; + uint32_t idx; +}; + +#define VFIO_DEVICE_SET_WIN_INFO _IO(VFIO_TYPE, VFIO_BASE + 20) +#define VFIO_DEVICE_GET_WIN_INFO _IO(VFIO_TYPE, VFIO_BASE + 21) + +struct pci_ep_info { + uint32_t type; + uint32_t pf_idx; + uint32_t vf_idx; + uint32_t iw_num; + uint32_t ow_num; + uint32_t vf_iw_num; + uint32_t vf_ow_num; + bool msix_enable; +}; + +#endif diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 99c2533..e32e776 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1012,6 +1012,7 @@ struct kvm_s390_ucas_mapping { /* VM is being stopped by host */ #define KVM_KVMCLOCK_CTRL _IO(KVMIO, 0xad) #define KVM_ARM_VCPU_INIT _IOW(KVMIO, 0xae, struct kvm_vcpu_init) +#define KVM_ARM_PREFERRED_TARGET _IOR(KVMIO, 0xaf, struct kvm_vcpu_init) #define KVM_GET_REG_LIST _IOWR(KVMIO, 0xb0, struct kvm_reg_list) #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index b47dba2..f04d8a4 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -54,7 +54,8 @@ #define PORT_ALTR_16550_F32 26 /* Altera 16550 UART with 32 FIFOs */ #define PORT_ALTR_16550_F64 27 /* Altera 16550 UART with 64 FIFOs */ #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */ -#define PORT_MAX_8250 28 /* max port ID */ +#define PORT_16550A_FSL64 29 /* Freescale 16550 UART with 64 FIFOs */ +#define PORT_MAX_8250 30 /* max port ID */ /* * ARM specific type numbers. These are not currently guaranteed diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h index e632260..c1ff1e7 100644 --- a/include/uapi/linux/serial_reg.h +++ b/include/uapi/linux/serial_reg.h @@ -86,7 +86,8 @@ #define UART_FCR6_T_TRIGGER_8 0x10 /* Mask for transmit trigger set at 8 */ #define UART_FCR6_T_TRIGGER_24 0x20 /* Mask for transmit trigger set at 24 */ #define UART_FCR6_T_TRIGGER_30 0x30 /* Mask for transmit trigger set at 30 */ -#define UART_FCR7_64BYTE 0x20 /* Go into 64 byte mode (TI16C750) */ +#define UART_FCR7_64BYTE 0x20 /* Go into 64 byte mode (TI16C750 and + some Freescale UARTs) */ #define UART_LCR 3 /* Out: Line Control Register */ /* diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index 0fd47f5..44578d2 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h @@ -23,6 +23,8 @@ #define VFIO_TYPE1_IOMMU 1 #define VFIO_SPAPR_TCE_IOMMU 2 +#define VFIO_FSL_PAMU_IOMMU 1000 +#define VFIO_IOMMU_DUMMY 1001 /* * The IOCTL interface is designed for extensibility by embedding the @@ -418,6 +420,105 @@ struct vfio_iommu_type1_dma_unmap { #define VFIO_IOMMU_UNMAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 14) +/*********** APIs for VFIO_PAMU type only ****************/ +/* + * VFIO_IOMMU_PAMU_GET_ATTR - _IO(VFIO_TYPE, VFIO_BASE + 15, + * struct vfio_pamu_attr) + * + * Gets the iommu attributes for the current vfio container. + * Caller sets argsz and attribute. The ioctl fills in + * the provided struct vfio_pamu_attr based on the attribute + * value that was set. + * Return: 0 on success, -errno on failure + */ +struct vfio_pamu_attr { + __u32 argsz; + __u32 flags; /* no flags currently */ +#define VFIO_ATTR_GEOMETRY 0 +#define VFIO_ATTR_WINDOWS 1 +#define VFIO_ATTR_PAMU_STASH 2 + __u32 attribute; + + union { + /* VFIO_ATTR_GEOMETRY */ + struct { + /* first addr that can be mapped */ + __u64 aperture_start; + /* last addr that can be mapped */ + __u64 aperture_end; + } attr; + + /* VFIO_ATTR_WINDOWS */ + __u32 windows; /* number of windows in the aperture + * initially this will be the max number + * of windows that can be set + */ + /* VFIO_ATTR_PAMU_STASH */ + struct { + __u32 cpu; /* CPU number for stashing */ + __u32 cache; /* cache ID for stashing */ + } stash; + } attr_info; +}; +#define VFIO_IOMMU_PAMU_GET_ATTR _IO(VFIO_TYPE, VFIO_BASE + 15) + +/* + * VFIO_IOMMU_PAMU_SET_ATTR - _IO(VFIO_TYPE, VFIO_BASE + 16, + * struct vfio_pamu_attr) + * + * Sets the iommu attributes for the current vfio container. + * Caller sets struct vfio_pamu attr, including argsz and attribute and + * setting any fields that are valid for the attribute. + * Return: 0 on success, -errno on failure + */ +#define VFIO_IOMMU_PAMU_SET_ATTR _IO(VFIO_TYPE, VFIO_BASE + 16) + +/* + * VFIO_IOMMU_PAMU_GET_MSI_BANK_COUNT - _IO(VFIO_TYPE, VFIO_BASE + 17, __u32) + * + * Returns the number of MSI banks for this platform. This tells user space + * how many aperture windows should be reserved for MSI banks when setting + * the PAMU geometry and window count. + * Return: __u32 bank count on success, -errno on failure + */ +#define VFIO_IOMMU_PAMU_GET_MSI_BANK_COUNT _IO(VFIO_TYPE, VFIO_BASE + 17) + +/* + * VFIO_IOMMU_PAMU_MAP_MSI_BANK - _IO(VFIO_TYPE, VFIO_BASE + 18, + * struct vfio_pamu_msi_bank_map) + * + * Maps the MSI bank at the specified index and iova. User space must + * call this ioctl once for each MSI bank (count of banks is returned by + * VFIO_IOMMU_PAMU_GET_MSI_BANK_COUNT). + * Caller provides struct vfio_pamu_msi_bank_map with all fields set. + * Return: 0 on success, -errno on failure + */ + +struct vfio_pamu_msi_bank_map { + __u32 argsz; + __u32 flags; /* no flags currently */ + __u32 msi_bank_index; /* the index of the MSI bank */ + __u64 iova; /* the iova the bank is to be mapped to */ +}; +#define VFIO_IOMMU_PAMU_MAP_MSI_BANK _IO(VFIO_TYPE, VFIO_BASE + 18) + +/* + * VFIO_IOMMU_PAMU_UNMAP_MSI_BANK - _IO(VFIO_TYPE, VFIO_BASE + 19, + * struct vfio_pamu_msi_bank_unmap) + * + * Unmaps the MSI bank at the specified iova. + * Caller provides struct vfio_pamu_msi_bank_unmap with all fields set. + * Operates on VFIO file descriptor (/dev/vfio/vfio). + * Return: 0 on success, -errno on failure + */ + +struct vfio_pamu_msi_bank_unmap { + __u32 argsz; + __u32 flags; /* no flags currently */ + __u64 iova; /* the iova to be unmapped to */ +}; +#define VFIO_IOMMU_PAMU_UNMAP_MSI_BANK _IO(VFIO_TYPE, VFIO_BASE + 19) + /* * IOCTLs to enable/disable IOMMU container usage. * No parameters are supported. |