1*99a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 2*99a2dd95SBruce Richardson * Copyright(c) 2018-2020 Intel Corporation 3*99a2dd95SBruce Richardson */ 4*99a2dd95SBruce Richardson 5*99a2dd95SBruce Richardson #ifndef _MISC_H_ 6*99a2dd95SBruce Richardson #define _MISC_H_ 7*99a2dd95SBruce Richardson 8*99a2dd95SBruce Richardson /** 9*99a2dd95SBruce Richardson * @file misc.h 10*99a2dd95SBruce Richardson * Contains miscellaneous functions/structures/macros used internally 11*99a2dd95SBruce Richardson * by ipsec library. 12*99a2dd95SBruce Richardson */ 13*99a2dd95SBruce Richardson 14*99a2dd95SBruce Richardson /* 15*99a2dd95SBruce Richardson * Move bad (unprocessed) mbufs beyond the good (processed) ones. 16*99a2dd95SBruce Richardson * bad_idx[] contains the indexes of bad mbufs inside the mb[]. 17*99a2dd95SBruce Richardson */ 18*99a2dd95SBruce Richardson static inline void 19*99a2dd95SBruce Richardson move_bad_mbufs(struct rte_mbuf *mb[], const uint32_t bad_idx[], uint32_t nb_mb, 20*99a2dd95SBruce Richardson uint32_t nb_bad) 21*99a2dd95SBruce Richardson { 22*99a2dd95SBruce Richardson uint32_t i, j, k; 23*99a2dd95SBruce Richardson struct rte_mbuf *drb[nb_bad]; 24*99a2dd95SBruce Richardson 25*99a2dd95SBruce Richardson j = 0; 26*99a2dd95SBruce Richardson k = 0; 27*99a2dd95SBruce Richardson 28*99a2dd95SBruce Richardson /* copy bad ones into a temp place */ 29*99a2dd95SBruce Richardson for (i = 0; i != nb_mb; i++) { 30*99a2dd95SBruce Richardson if (j != nb_bad && i == bad_idx[j]) 31*99a2dd95SBruce Richardson drb[j++] = mb[i]; 32*99a2dd95SBruce Richardson else 33*99a2dd95SBruce Richardson mb[k++] = mb[i]; 34*99a2dd95SBruce Richardson } 35*99a2dd95SBruce Richardson 36*99a2dd95SBruce Richardson /* copy bad ones after the good ones */ 37*99a2dd95SBruce Richardson for (i = 0; i != nb_bad; i++) 38*99a2dd95SBruce Richardson mb[k + i] = drb[i]; 39*99a2dd95SBruce Richardson } 40*99a2dd95SBruce Richardson 41*99a2dd95SBruce Richardson /* 42*99a2dd95SBruce Richardson * Find packet's segment for the specified offset. 43*99a2dd95SBruce Richardson * ofs - at input should contain required offset, at output would contain 44*99a2dd95SBruce Richardson * offset value within the segment. 45*99a2dd95SBruce Richardson */ 46*99a2dd95SBruce Richardson static inline struct rte_mbuf * 47*99a2dd95SBruce Richardson mbuf_get_seg_ofs(struct rte_mbuf *mb, uint32_t *ofs) 48*99a2dd95SBruce Richardson { 49*99a2dd95SBruce Richardson uint32_t k, n, plen; 50*99a2dd95SBruce Richardson struct rte_mbuf *ms; 51*99a2dd95SBruce Richardson 52*99a2dd95SBruce Richardson plen = mb->pkt_len; 53*99a2dd95SBruce Richardson n = *ofs; 54*99a2dd95SBruce Richardson 55*99a2dd95SBruce Richardson if (n == plen) { 56*99a2dd95SBruce Richardson ms = rte_pktmbuf_lastseg(mb); 57*99a2dd95SBruce Richardson n = n + rte_pktmbuf_data_len(ms) - plen; 58*99a2dd95SBruce Richardson } else { 59*99a2dd95SBruce Richardson ms = mb; 60*99a2dd95SBruce Richardson for (k = rte_pktmbuf_data_len(ms); n >= k; 61*99a2dd95SBruce Richardson k = rte_pktmbuf_data_len(ms)) { 62*99a2dd95SBruce Richardson ms = ms->next; 63*99a2dd95SBruce Richardson n -= k; 64*99a2dd95SBruce Richardson } 65*99a2dd95SBruce Richardson } 66*99a2dd95SBruce Richardson 67*99a2dd95SBruce Richardson *ofs = n; 68*99a2dd95SBruce Richardson return ms; 69*99a2dd95SBruce Richardson } 70*99a2dd95SBruce Richardson 71*99a2dd95SBruce Richardson /* 72*99a2dd95SBruce Richardson * Trim multi-segment packet at the specified offset, and free 73*99a2dd95SBruce Richardson * all unused segments. 74*99a2dd95SBruce Richardson * mb - input packet 75*99a2dd95SBruce Richardson * ms - segment where to cut 76*99a2dd95SBruce Richardson * ofs - offset within the *ms* 77*99a2dd95SBruce Richardson * len - length to cut (from given offset to the end of the packet) 78*99a2dd95SBruce Richardson * Can be used in conjunction with mbuf_get_seg_ofs(): 79*99a2dd95SBruce Richardson * ofs = new_len; 80*99a2dd95SBruce Richardson * ms = mbuf_get_seg_ofs(mb, &ofs); 81*99a2dd95SBruce Richardson * mbuf_cut_seg_ofs(mb, ms, ofs, mb->pkt_len - new_len); 82*99a2dd95SBruce Richardson */ 83*99a2dd95SBruce Richardson static inline void 84*99a2dd95SBruce Richardson mbuf_cut_seg_ofs(struct rte_mbuf *mb, struct rte_mbuf *ms, uint32_t ofs, 85*99a2dd95SBruce Richardson uint32_t len) 86*99a2dd95SBruce Richardson { 87*99a2dd95SBruce Richardson uint32_t n, slen; 88*99a2dd95SBruce Richardson struct rte_mbuf *mn; 89*99a2dd95SBruce Richardson 90*99a2dd95SBruce Richardson slen = ms->data_len; 91*99a2dd95SBruce Richardson ms->data_len = ofs; 92*99a2dd95SBruce Richardson 93*99a2dd95SBruce Richardson /* tail spawns through multiple segments */ 94*99a2dd95SBruce Richardson if (slen < ofs + len) { 95*99a2dd95SBruce Richardson mn = ms->next; 96*99a2dd95SBruce Richardson ms->next = NULL; 97*99a2dd95SBruce Richardson for (n = 0; mn != NULL; n++) { 98*99a2dd95SBruce Richardson ms = mn->next; 99*99a2dd95SBruce Richardson rte_pktmbuf_free_seg(mn); 100*99a2dd95SBruce Richardson mn = ms; 101*99a2dd95SBruce Richardson } 102*99a2dd95SBruce Richardson mb->nb_segs -= n; 103*99a2dd95SBruce Richardson } 104*99a2dd95SBruce Richardson 105*99a2dd95SBruce Richardson mb->pkt_len -= len; 106*99a2dd95SBruce Richardson } 107*99a2dd95SBruce Richardson 108*99a2dd95SBruce Richardson /* 109*99a2dd95SBruce Richardson * process packets using sync crypto engine. 110*99a2dd95SBruce Richardson * expects *num* to be greater than zero. 111*99a2dd95SBruce Richardson */ 112*99a2dd95SBruce Richardson static inline void 113*99a2dd95SBruce Richardson cpu_crypto_bulk(const struct rte_ipsec_session *ss, 114*99a2dd95SBruce Richardson union rte_crypto_sym_ofs ofs, struct rte_mbuf *mb[], 115*99a2dd95SBruce Richardson struct rte_crypto_va_iova_ptr iv[], 116*99a2dd95SBruce Richardson struct rte_crypto_va_iova_ptr aad[], 117*99a2dd95SBruce Richardson struct rte_crypto_va_iova_ptr dgst[], uint32_t l4ofs[], 118*99a2dd95SBruce Richardson uint32_t clen[], uint32_t num) 119*99a2dd95SBruce Richardson { 120*99a2dd95SBruce Richardson uint32_t i, j, n; 121*99a2dd95SBruce Richardson int32_t vcnt, vofs; 122*99a2dd95SBruce Richardson int32_t st[num]; 123*99a2dd95SBruce Richardson struct rte_crypto_sgl vecpkt[num]; 124*99a2dd95SBruce Richardson struct rte_crypto_vec vec[UINT8_MAX]; 125*99a2dd95SBruce Richardson struct rte_crypto_sym_vec symvec; 126*99a2dd95SBruce Richardson 127*99a2dd95SBruce Richardson const uint32_t vnum = RTE_DIM(vec); 128*99a2dd95SBruce Richardson 129*99a2dd95SBruce Richardson j = 0, n = 0; 130*99a2dd95SBruce Richardson vofs = 0; 131*99a2dd95SBruce Richardson for (i = 0; i != num; i++) { 132*99a2dd95SBruce Richardson 133*99a2dd95SBruce Richardson vcnt = rte_crypto_mbuf_to_vec(mb[i], l4ofs[i], clen[i], 134*99a2dd95SBruce Richardson &vec[vofs], vnum - vofs); 135*99a2dd95SBruce Richardson 136*99a2dd95SBruce Richardson /* not enough space in vec[] to hold all segments */ 137*99a2dd95SBruce Richardson if (vcnt < 0) { 138*99a2dd95SBruce Richardson /* fill the request structure */ 139*99a2dd95SBruce Richardson symvec.sgl = &vecpkt[j]; 140*99a2dd95SBruce Richardson symvec.iv = &iv[j]; 141*99a2dd95SBruce Richardson symvec.digest = &dgst[j]; 142*99a2dd95SBruce Richardson symvec.aad = &aad[j]; 143*99a2dd95SBruce Richardson symvec.status = &st[j]; 144*99a2dd95SBruce Richardson symvec.num = i - j; 145*99a2dd95SBruce Richardson 146*99a2dd95SBruce Richardson /* flush vec array and try again */ 147*99a2dd95SBruce Richardson n += rte_cryptodev_sym_cpu_crypto_process( 148*99a2dd95SBruce Richardson ss->crypto.dev_id, ss->crypto.ses, ofs, 149*99a2dd95SBruce Richardson &symvec); 150*99a2dd95SBruce Richardson vofs = 0; 151*99a2dd95SBruce Richardson vcnt = rte_crypto_mbuf_to_vec(mb[i], l4ofs[i], clen[i], 152*99a2dd95SBruce Richardson vec, vnum); 153*99a2dd95SBruce Richardson RTE_ASSERT(vcnt > 0); 154*99a2dd95SBruce Richardson j = i; 155*99a2dd95SBruce Richardson } 156*99a2dd95SBruce Richardson 157*99a2dd95SBruce Richardson vecpkt[i].vec = &vec[vofs]; 158*99a2dd95SBruce Richardson vecpkt[i].num = vcnt; 159*99a2dd95SBruce Richardson vofs += vcnt; 160*99a2dd95SBruce Richardson } 161*99a2dd95SBruce Richardson 162*99a2dd95SBruce Richardson /* fill the request structure */ 163*99a2dd95SBruce Richardson symvec.sgl = &vecpkt[j]; 164*99a2dd95SBruce Richardson symvec.iv = &iv[j]; 165*99a2dd95SBruce Richardson symvec.aad = &aad[j]; 166*99a2dd95SBruce Richardson symvec.digest = &dgst[j]; 167*99a2dd95SBruce Richardson symvec.status = &st[j]; 168*99a2dd95SBruce Richardson symvec.num = i - j; 169*99a2dd95SBruce Richardson 170*99a2dd95SBruce Richardson n += rte_cryptodev_sym_cpu_crypto_process(ss->crypto.dev_id, 171*99a2dd95SBruce Richardson ss->crypto.ses, ofs, &symvec); 172*99a2dd95SBruce Richardson 173*99a2dd95SBruce Richardson j = num - n; 174*99a2dd95SBruce Richardson for (i = 0; j != 0 && i != num; i++) { 175*99a2dd95SBruce Richardson if (st[i] != 0) { 176*99a2dd95SBruce Richardson mb[i]->ol_flags |= PKT_RX_SEC_OFFLOAD_FAILED; 177*99a2dd95SBruce Richardson j--; 178*99a2dd95SBruce Richardson } 179*99a2dd95SBruce Richardson } 180*99a2dd95SBruce Richardson } 181*99a2dd95SBruce Richardson 182*99a2dd95SBruce Richardson #endif /* _MISC_H_ */ 183