ice_virtchnl_fdir.c 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (C) 2021-2023, Intel Corporation. */
  3. #include "ice.h"
  4. #include "ice_base.h"
  5. #include "ice_lib.h"
  6. #include "ice_flow.h"
  7. #include "ice_vf_lib_private.h"
  8. #define to_fltr_conf_from_desc(p) \
  9. container_of(p, struct virtchnl_fdir_fltr_conf, input)
  10. #define GTPU_TEID_OFFSET 4
  11. #define GTPU_EH_QFI_OFFSET 1
  12. #define GTPU_EH_QFI_MASK 0x3F
  13. #define PFCP_S_OFFSET 0
  14. #define PFCP_S_MASK 0x1
  15. #define PFCP_PORT_NR 8805
  16. #define FDIR_INSET_FLAG_ESP_S 0
  17. #define FDIR_INSET_FLAG_ESP_M BIT_ULL(FDIR_INSET_FLAG_ESP_S)
  18. #define FDIR_INSET_FLAG_ESP_UDP BIT_ULL(FDIR_INSET_FLAG_ESP_S)
  19. #define FDIR_INSET_FLAG_ESP_IPSEC (0ULL << FDIR_INSET_FLAG_ESP_S)
  20. enum ice_fdir_tunnel_type {
  21. ICE_FDIR_TUNNEL_TYPE_NONE = 0,
  22. ICE_FDIR_TUNNEL_TYPE_GTPU,
  23. ICE_FDIR_TUNNEL_TYPE_GTPU_EH,
  24. ICE_FDIR_TUNNEL_TYPE_ECPRI,
  25. ICE_FDIR_TUNNEL_TYPE_GTPU_INNER,
  26. ICE_FDIR_TUNNEL_TYPE_GTPU_EH_INNER,
  27. ICE_FDIR_TUNNEL_TYPE_GRE,
  28. ICE_FDIR_TUNNEL_TYPE_GTPOGRE,
  29. ICE_FDIR_TUNNEL_TYPE_GTPOGRE_INNER,
  30. ICE_FDIR_TUNNEL_TYPE_GRE_INNER,
  31. ICE_FDIR_TUNNEL_TYPE_L2TPV2,
  32. ICE_FDIR_TUNNEL_TYPE_L2TPV2_INNER,
  33. };
  34. struct virtchnl_fdir_fltr_conf {
  35. struct ice_fdir_fltr input;
  36. enum ice_fdir_tunnel_type ttype;
  37. u64 inset_flag;
  38. u32 flow_id;
  39. struct ice_parser_profile *prof;
  40. bool parser_ena;
  41. u8 *pkt_buf;
  42. u8 pkt_len;
  43. };
  44. struct virtchnl_fdir_inset_map {
  45. enum virtchnl_proto_hdr_field field;
  46. enum ice_flow_field fld;
  47. u64 flag;
  48. u64 mask;
  49. };
  50. static const struct virtchnl_fdir_inset_map fdir_inset_map[] = {
  51. {VIRTCHNL_PROTO_HDR_ETH_ETHERTYPE, ICE_FLOW_FIELD_IDX_ETH_TYPE, 0, 0},
  52. {VIRTCHNL_PROTO_HDR_IPV4_SRC, ICE_FLOW_FIELD_IDX_IPV4_SA, 0, 0},
  53. {VIRTCHNL_PROTO_HDR_IPV4_DST, ICE_FLOW_FIELD_IDX_IPV4_DA, 0, 0},
  54. {VIRTCHNL_PROTO_HDR_IPV4_DSCP, ICE_FLOW_FIELD_IDX_IPV4_DSCP, 0, 0},
  55. {VIRTCHNL_PROTO_HDR_IPV4_TTL, ICE_FLOW_FIELD_IDX_IPV4_TTL, 0, 0},
  56. {VIRTCHNL_PROTO_HDR_IPV4_PROT, ICE_FLOW_FIELD_IDX_IPV4_PROT, 0, 0},
  57. {VIRTCHNL_PROTO_HDR_IPV6_SRC, ICE_FLOW_FIELD_IDX_IPV6_SA, 0, 0},
  58. {VIRTCHNL_PROTO_HDR_IPV6_DST, ICE_FLOW_FIELD_IDX_IPV6_DA, 0, 0},
  59. {VIRTCHNL_PROTO_HDR_IPV6_TC, ICE_FLOW_FIELD_IDX_IPV6_DSCP, 0, 0},
  60. {VIRTCHNL_PROTO_HDR_IPV6_HOP_LIMIT, ICE_FLOW_FIELD_IDX_IPV6_TTL, 0, 0},
  61. {VIRTCHNL_PROTO_HDR_IPV6_PROT, ICE_FLOW_FIELD_IDX_IPV6_PROT, 0, 0},
  62. {VIRTCHNL_PROTO_HDR_UDP_SRC_PORT, ICE_FLOW_FIELD_IDX_UDP_SRC_PORT, 0, 0},
  63. {VIRTCHNL_PROTO_HDR_UDP_DST_PORT, ICE_FLOW_FIELD_IDX_UDP_DST_PORT, 0, 0},
  64. {VIRTCHNL_PROTO_HDR_TCP_SRC_PORT, ICE_FLOW_FIELD_IDX_TCP_SRC_PORT, 0, 0},
  65. {VIRTCHNL_PROTO_HDR_TCP_DST_PORT, ICE_FLOW_FIELD_IDX_TCP_DST_PORT, 0, 0},
  66. {VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT, ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT, 0, 0},
  67. {VIRTCHNL_PROTO_HDR_SCTP_DST_PORT, ICE_FLOW_FIELD_IDX_SCTP_DST_PORT, 0, 0},
  68. {VIRTCHNL_PROTO_HDR_GTPU_IP_TEID, ICE_FLOW_FIELD_IDX_GTPU_IP_TEID, 0, 0},
  69. {VIRTCHNL_PROTO_HDR_GTPU_EH_QFI, ICE_FLOW_FIELD_IDX_GTPU_EH_QFI, 0, 0},
  70. {VIRTCHNL_PROTO_HDR_ESP_SPI, ICE_FLOW_FIELD_IDX_ESP_SPI,
  71. FDIR_INSET_FLAG_ESP_IPSEC, FDIR_INSET_FLAG_ESP_M},
  72. {VIRTCHNL_PROTO_HDR_ESP_SPI, ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI,
  73. FDIR_INSET_FLAG_ESP_UDP, FDIR_INSET_FLAG_ESP_M},
  74. {VIRTCHNL_PROTO_HDR_AH_SPI, ICE_FLOW_FIELD_IDX_AH_SPI, 0, 0},
  75. {VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID, ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID, 0, 0},
  76. {VIRTCHNL_PROTO_HDR_PFCP_S_FIELD, ICE_FLOW_FIELD_IDX_UDP_DST_PORT, 0, 0},
  77. };
  78. /**
  79. * ice_vc_fdir_param_check
  80. * @vf: pointer to the VF structure
  81. * @vsi_id: VF relative VSI ID
  82. *
  83. * Check for the valid VSI ID, PF's state and VF's state
  84. *
  85. * Return: 0 on success, and -EINVAL on error.
  86. */
  87. static int
  88. ice_vc_fdir_param_check(struct ice_vf *vf, u16 vsi_id)
  89. {
  90. struct ice_pf *pf = vf->pf;
  91. if (!test_bit(ICE_FLAG_FD_ENA, pf->flags))
  92. return -EINVAL;
  93. if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states))
  94. return -EINVAL;
  95. if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_FDIR_PF))
  96. return -EINVAL;
  97. if (!ice_vc_isvalid_vsi_id(vf, vsi_id))
  98. return -EINVAL;
  99. if (!ice_get_vf_vsi(vf))
  100. return -EINVAL;
  101. return 0;
  102. }
  103. /**
  104. * ice_vf_start_ctrl_vsi
  105. * @vf: pointer to the VF structure
  106. *
  107. * Allocate ctrl_vsi for the first time and open the ctrl_vsi port for VF
  108. *
  109. * Return: 0 on success, and other on error.
  110. */
  111. static int ice_vf_start_ctrl_vsi(struct ice_vf *vf)
  112. {
  113. struct ice_pf *pf = vf->pf;
  114. struct ice_vsi *ctrl_vsi;
  115. struct device *dev;
  116. int err;
  117. dev = ice_pf_to_dev(pf);
  118. if (vf->ctrl_vsi_idx != ICE_NO_VSI)
  119. return -EEXIST;
  120. ctrl_vsi = ice_vf_ctrl_vsi_setup(vf);
  121. if (!ctrl_vsi) {
  122. dev_dbg(dev, "Could not setup control VSI for VF %d\n",
  123. vf->vf_id);
  124. return -ENOMEM;
  125. }
  126. err = ice_vsi_open_ctrl(ctrl_vsi);
  127. if (err) {
  128. dev_dbg(dev, "Could not open control VSI for VF %d\n",
  129. vf->vf_id);
  130. goto err_vsi_open;
  131. }
  132. return 0;
  133. err_vsi_open:
  134. ice_vsi_release(ctrl_vsi);
  135. if (vf->ctrl_vsi_idx != ICE_NO_VSI) {
  136. pf->vsi[vf->ctrl_vsi_idx] = NULL;
  137. vf->ctrl_vsi_idx = ICE_NO_VSI;
  138. }
  139. return err;
  140. }
  141. /**
  142. * ice_vc_fdir_alloc_prof - allocate profile for this filter flow type
  143. * @vf: pointer to the VF structure
  144. * @flow: filter flow type
  145. *
  146. * Return: 0 on success, and other on error.
  147. */
  148. static int
  149. ice_vc_fdir_alloc_prof(struct ice_vf *vf, enum ice_fltr_ptype flow)
  150. {
  151. struct ice_vf_fdir *fdir = &vf->fdir;
  152. if (!fdir->fdir_prof) {
  153. fdir->fdir_prof = devm_kcalloc(ice_pf_to_dev(vf->pf),
  154. ICE_FLTR_PTYPE_MAX,
  155. sizeof(*fdir->fdir_prof),
  156. GFP_KERNEL);
  157. if (!fdir->fdir_prof)
  158. return -ENOMEM;
  159. }
  160. if (!fdir->fdir_prof[flow]) {
  161. fdir->fdir_prof[flow] = devm_kzalloc(ice_pf_to_dev(vf->pf),
  162. sizeof(**fdir->fdir_prof),
  163. GFP_KERNEL);
  164. if (!fdir->fdir_prof[flow])
  165. return -ENOMEM;
  166. }
  167. return 0;
  168. }
  169. /**
  170. * ice_vc_fdir_free_prof - free profile for this filter flow type
  171. * @vf: pointer to the VF structure
  172. * @flow: filter flow type
  173. */
  174. static void
  175. ice_vc_fdir_free_prof(struct ice_vf *vf, enum ice_fltr_ptype flow)
  176. {
  177. struct ice_vf_fdir *fdir = &vf->fdir;
  178. if (!fdir->fdir_prof)
  179. return;
  180. if (!fdir->fdir_prof[flow])
  181. return;
  182. devm_kfree(ice_pf_to_dev(vf->pf), fdir->fdir_prof[flow]);
  183. fdir->fdir_prof[flow] = NULL;
  184. }
  185. /**
  186. * ice_vc_fdir_free_prof_all - free all the profile for this VF
  187. * @vf: pointer to the VF structure
  188. */
  189. static void ice_vc_fdir_free_prof_all(struct ice_vf *vf)
  190. {
  191. struct ice_vf_fdir *fdir = &vf->fdir;
  192. enum ice_fltr_ptype flow;
  193. if (!fdir->fdir_prof)
  194. return;
  195. for (flow = ICE_FLTR_PTYPE_NONF_NONE; flow < ICE_FLTR_PTYPE_MAX; flow++)
  196. ice_vc_fdir_free_prof(vf, flow);
  197. devm_kfree(ice_pf_to_dev(vf->pf), fdir->fdir_prof);
  198. fdir->fdir_prof = NULL;
  199. }
  200. /**
  201. * ice_vc_fdir_parse_flow_fld
  202. * @proto_hdr: virtual channel protocol filter header
  203. * @conf: FDIR configuration for each filter
  204. * @fld: field type array
  205. * @fld_cnt: field counter
  206. *
  207. * Parse the virtual channel filter header and store them into field type array
  208. *
  209. * Return: 0 on success, and other on error.
  210. */
  211. static int
  212. ice_vc_fdir_parse_flow_fld(struct virtchnl_proto_hdr *proto_hdr,
  213. struct virtchnl_fdir_fltr_conf *conf,
  214. enum ice_flow_field *fld, int *fld_cnt)
  215. {
  216. struct virtchnl_proto_hdr hdr;
  217. u32 i;
  218. memcpy(&hdr, proto_hdr, sizeof(hdr));
  219. for (i = 0; (i < ARRAY_SIZE(fdir_inset_map)) &&
  220. VIRTCHNL_GET_PROTO_HDR_FIELD(&hdr); i++)
  221. if (VIRTCHNL_TEST_PROTO_HDR(&hdr, fdir_inset_map[i].field)) {
  222. if (fdir_inset_map[i].mask &&
  223. ((fdir_inset_map[i].mask & conf->inset_flag) !=
  224. fdir_inset_map[i].flag))
  225. continue;
  226. fld[*fld_cnt] = fdir_inset_map[i].fld;
  227. *fld_cnt += 1;
  228. if (*fld_cnt >= ICE_FLOW_FIELD_IDX_MAX)
  229. return -EINVAL;
  230. VIRTCHNL_DEL_PROTO_HDR_FIELD(&hdr,
  231. fdir_inset_map[i].field);
  232. }
  233. return 0;
  234. }
  235. /**
  236. * ice_vc_fdir_set_flow_fld
  237. * @vf: pointer to the VF structure
  238. * @fltr: virtual channel add cmd buffer
  239. * @conf: FDIR configuration for each filter
  240. * @seg: array of one or more packet segments that describe the flow
  241. *
  242. * Parse the virtual channel add msg buffer's field vector and store them into
  243. * flow's packet segment field
  244. *
  245. * Return: 0 on success, and other on error.
  246. */
  247. static int
  248. ice_vc_fdir_set_flow_fld(struct ice_vf *vf, struct virtchnl_fdir_add *fltr,
  249. struct virtchnl_fdir_fltr_conf *conf,
  250. struct ice_flow_seg_info *seg)
  251. {
  252. struct virtchnl_fdir_rule *rule = &fltr->rule_cfg;
  253. enum ice_flow_field fld[ICE_FLOW_FIELD_IDX_MAX];
  254. struct device *dev = ice_pf_to_dev(vf->pf);
  255. struct virtchnl_proto_hdrs *proto;
  256. int fld_cnt = 0;
  257. int i;
  258. proto = &rule->proto_hdrs;
  259. for (i = 0; i < proto->count; i++) {
  260. struct virtchnl_proto_hdr *hdr = &proto->proto_hdr[i];
  261. int ret;
  262. ret = ice_vc_fdir_parse_flow_fld(hdr, conf, fld, &fld_cnt);
  263. if (ret)
  264. return ret;
  265. }
  266. if (fld_cnt == 0) {
  267. dev_dbg(dev, "Empty input set for VF %d\n", vf->vf_id);
  268. return -EINVAL;
  269. }
  270. for (i = 0; i < fld_cnt; i++)
  271. ice_flow_set_fld(seg, fld[i],
  272. ICE_FLOW_FLD_OFF_INVAL,
  273. ICE_FLOW_FLD_OFF_INVAL,
  274. ICE_FLOW_FLD_OFF_INVAL, false);
  275. return 0;
  276. }
  277. /**
  278. * ice_vc_fdir_set_flow_hdr - config the flow's packet segment header
  279. * @vf: pointer to the VF structure
  280. * @conf: FDIR configuration for each filter
  281. * @seg: array of one or more packet segments that describe the flow
  282. *
  283. * Return: 0 on success, and other on error.
  284. */
  285. static int
  286. ice_vc_fdir_set_flow_hdr(struct ice_vf *vf,
  287. struct virtchnl_fdir_fltr_conf *conf,
  288. struct ice_flow_seg_info *seg)
  289. {
  290. enum ice_fltr_ptype flow = conf->input.flow_type;
  291. enum ice_fdir_tunnel_type ttype = conf->ttype;
  292. struct device *dev = ice_pf_to_dev(vf->pf);
  293. switch (flow) {
  294. case ICE_FLTR_PTYPE_NON_IP_L2:
  295. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_ETH_NON_IP);
  296. break;
  297. case ICE_FLTR_PTYPE_NONF_IPV4_L2TPV3:
  298. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_L2TPV3 |
  299. ICE_FLOW_SEG_HDR_IPV4 |
  300. ICE_FLOW_SEG_HDR_IPV_OTHER);
  301. break;
  302. case ICE_FLTR_PTYPE_NONF_IPV4_ESP:
  303. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_ESP |
  304. ICE_FLOW_SEG_HDR_IPV4 |
  305. ICE_FLOW_SEG_HDR_IPV_OTHER);
  306. break;
  307. case ICE_FLTR_PTYPE_NONF_IPV4_AH:
  308. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_AH |
  309. ICE_FLOW_SEG_HDR_IPV4 |
  310. ICE_FLOW_SEG_HDR_IPV_OTHER);
  311. break;
  312. case ICE_FLTR_PTYPE_NONF_IPV4_NAT_T_ESP:
  313. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_NAT_T_ESP |
  314. ICE_FLOW_SEG_HDR_IPV4 |
  315. ICE_FLOW_SEG_HDR_IPV_OTHER);
  316. break;
  317. case ICE_FLTR_PTYPE_NONF_IPV4_PFCP_NODE:
  318. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_PFCP_NODE |
  319. ICE_FLOW_SEG_HDR_IPV4 |
  320. ICE_FLOW_SEG_HDR_IPV_OTHER);
  321. break;
  322. case ICE_FLTR_PTYPE_NONF_IPV4_PFCP_SESSION:
  323. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_PFCP_SESSION |
  324. ICE_FLOW_SEG_HDR_IPV4 |
  325. ICE_FLOW_SEG_HDR_IPV_OTHER);
  326. break;
  327. case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
  328. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV4 |
  329. ICE_FLOW_SEG_HDR_IPV_OTHER);
  330. break;
  331. case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
  332. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_TCP |
  333. ICE_FLOW_SEG_HDR_IPV4 |
  334. ICE_FLOW_SEG_HDR_IPV_OTHER);
  335. break;
  336. case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
  337. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_UDP |
  338. ICE_FLOW_SEG_HDR_IPV4 |
  339. ICE_FLOW_SEG_HDR_IPV_OTHER);
  340. break;
  341. case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP:
  342. case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP:
  343. case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP:
  344. case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER:
  345. if (ttype == ICE_FDIR_TUNNEL_TYPE_GTPU) {
  346. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_GTPU_IP |
  347. ICE_FLOW_SEG_HDR_IPV4 |
  348. ICE_FLOW_SEG_HDR_IPV_OTHER);
  349. } else if (ttype == ICE_FDIR_TUNNEL_TYPE_GTPU_EH) {
  350. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_GTPU_EH |
  351. ICE_FLOW_SEG_HDR_GTPU_IP |
  352. ICE_FLOW_SEG_HDR_IPV4 |
  353. ICE_FLOW_SEG_HDR_IPV_OTHER);
  354. } else {
  355. dev_dbg(dev, "Invalid tunnel type 0x%x for VF %d\n",
  356. flow, vf->vf_id);
  357. return -EINVAL;
  358. }
  359. break;
  360. case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
  361. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_SCTP |
  362. ICE_FLOW_SEG_HDR_IPV4 |
  363. ICE_FLOW_SEG_HDR_IPV_OTHER);
  364. break;
  365. case ICE_FLTR_PTYPE_NONF_IPV6_L2TPV3:
  366. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_L2TPV3 |
  367. ICE_FLOW_SEG_HDR_IPV6 |
  368. ICE_FLOW_SEG_HDR_IPV_OTHER);
  369. break;
  370. case ICE_FLTR_PTYPE_NONF_IPV6_ESP:
  371. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_ESP |
  372. ICE_FLOW_SEG_HDR_IPV6 |
  373. ICE_FLOW_SEG_HDR_IPV_OTHER);
  374. break;
  375. case ICE_FLTR_PTYPE_NONF_IPV6_AH:
  376. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_AH |
  377. ICE_FLOW_SEG_HDR_IPV6 |
  378. ICE_FLOW_SEG_HDR_IPV_OTHER);
  379. break;
  380. case ICE_FLTR_PTYPE_NONF_IPV6_NAT_T_ESP:
  381. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_NAT_T_ESP |
  382. ICE_FLOW_SEG_HDR_IPV6 |
  383. ICE_FLOW_SEG_HDR_IPV_OTHER);
  384. break;
  385. case ICE_FLTR_PTYPE_NONF_IPV6_PFCP_NODE:
  386. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_PFCP_NODE |
  387. ICE_FLOW_SEG_HDR_IPV6 |
  388. ICE_FLOW_SEG_HDR_IPV_OTHER);
  389. break;
  390. case ICE_FLTR_PTYPE_NONF_IPV6_PFCP_SESSION:
  391. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_PFCP_SESSION |
  392. ICE_FLOW_SEG_HDR_IPV6 |
  393. ICE_FLOW_SEG_HDR_IPV_OTHER);
  394. break;
  395. case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
  396. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV6 |
  397. ICE_FLOW_SEG_HDR_IPV_OTHER);
  398. break;
  399. case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
  400. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_TCP |
  401. ICE_FLOW_SEG_HDR_IPV6 |
  402. ICE_FLOW_SEG_HDR_IPV_OTHER);
  403. break;
  404. case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
  405. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_UDP |
  406. ICE_FLOW_SEG_HDR_IPV6 |
  407. ICE_FLOW_SEG_HDR_IPV_OTHER);
  408. break;
  409. case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
  410. ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_SCTP |
  411. ICE_FLOW_SEG_HDR_IPV6 |
  412. ICE_FLOW_SEG_HDR_IPV_OTHER);
  413. break;
  414. default:
  415. dev_dbg(dev, "Invalid flow type 0x%x for VF %d failed\n",
  416. flow, vf->vf_id);
  417. return -EINVAL;
  418. }
  419. return 0;
  420. }
  421. /**
  422. * ice_vc_fdir_rem_prof - remove profile for this filter flow type
  423. * @vf: pointer to the VF structure
  424. * @flow: filter flow type
  425. * @tun: 0 implies non-tunnel type filter, 1 implies tunnel type filter
  426. */
  427. static void
  428. ice_vc_fdir_rem_prof(struct ice_vf *vf, enum ice_fltr_ptype flow, int tun)
  429. {
  430. struct ice_vf_fdir *fdir = &vf->fdir;
  431. struct ice_fd_hw_prof *vf_prof;
  432. struct ice_pf *pf = vf->pf;
  433. struct ice_vsi *vf_vsi;
  434. struct device *dev;
  435. struct ice_hw *hw;
  436. u64 prof_id;
  437. int i;
  438. dev = ice_pf_to_dev(pf);
  439. hw = &pf->hw;
  440. if (!fdir->fdir_prof || !fdir->fdir_prof[flow])
  441. return;
  442. vf_prof = fdir->fdir_prof[flow];
  443. prof_id = vf_prof->prof_id[tun];
  444. vf_vsi = ice_get_vf_vsi(vf);
  445. if (!vf_vsi) {
  446. dev_dbg(dev, "NULL vf %d vsi pointer\n", vf->vf_id);
  447. return;
  448. }
  449. if (!fdir->prof_entry_cnt[flow][tun])
  450. return;
  451. for (i = 0; i < fdir->prof_entry_cnt[flow][tun]; i++)
  452. if (vf_prof->entry_h[i][tun]) {
  453. u16 vsi_num = ice_get_hw_vsi_num(hw, vf_prof->vsi_h[i]);
  454. ice_rem_prof_id_flow(hw, ICE_BLK_FD, vsi_num, prof_id);
  455. ice_flow_rem_entry(hw, ICE_BLK_FD,
  456. vf_prof->entry_h[i][tun]);
  457. vf_prof->entry_h[i][tun] = 0;
  458. }
  459. ice_flow_rem_prof(hw, ICE_BLK_FD, prof_id);
  460. devm_kfree(dev, vf_prof->fdir_seg[tun]);
  461. vf_prof->fdir_seg[tun] = NULL;
  462. for (i = 0; i < vf_prof->cnt; i++)
  463. vf_prof->vsi_h[i] = 0;
  464. fdir->prof_entry_cnt[flow][tun] = 0;
  465. }
  466. /**
  467. * ice_vc_fdir_rem_prof_all - remove profile for this VF
  468. * @vf: pointer to the VF structure
  469. */
  470. static void ice_vc_fdir_rem_prof_all(struct ice_vf *vf)
  471. {
  472. enum ice_fltr_ptype flow;
  473. for (flow = ICE_FLTR_PTYPE_NONF_NONE;
  474. flow < ICE_FLTR_PTYPE_MAX; flow++) {
  475. ice_vc_fdir_rem_prof(vf, flow, 0);
  476. ice_vc_fdir_rem_prof(vf, flow, 1);
  477. }
  478. }
  479. /**
  480. * ice_vc_fdir_reset_cnt_all - reset all FDIR counters for this VF FDIR
  481. * @fdir: pointer to the VF FDIR structure
  482. */
  483. static void ice_vc_fdir_reset_cnt_all(struct ice_vf_fdir *fdir)
  484. {
  485. enum ice_fltr_ptype flow;
  486. for (flow = ICE_FLTR_PTYPE_NONF_NONE;
  487. flow < ICE_FLTR_PTYPE_MAX; flow++) {
  488. fdir->fdir_fltr_cnt[flow][0] = 0;
  489. fdir->fdir_fltr_cnt[flow][1] = 0;
  490. }
  491. fdir->fdir_fltr_cnt_total = 0;
  492. }
  493. /**
  494. * ice_vc_fdir_has_prof_conflict
  495. * @vf: pointer to the VF structure
  496. * @conf: FDIR configuration for each filter
  497. *
  498. * Check if @conf has conflicting profile with existing profiles
  499. *
  500. * Return: true on success, and false on error.
  501. */
  502. static bool
  503. ice_vc_fdir_has_prof_conflict(struct ice_vf *vf,
  504. struct virtchnl_fdir_fltr_conf *conf)
  505. {
  506. struct ice_fdir_fltr *desc;
  507. list_for_each_entry(desc, &vf->fdir.fdir_rule_list, fltr_node) {
  508. struct virtchnl_fdir_fltr_conf *existing_conf;
  509. enum ice_fltr_ptype flow_type_a, flow_type_b;
  510. struct ice_fdir_fltr *a, *b;
  511. existing_conf = to_fltr_conf_from_desc(desc);
  512. a = &existing_conf->input;
  513. b = &conf->input;
  514. flow_type_a = a->flow_type;
  515. flow_type_b = b->flow_type;
  516. /* No need to compare two rules with different tunnel types or
  517. * with the same protocol type.
  518. */
  519. if (existing_conf->ttype != conf->ttype ||
  520. flow_type_a == flow_type_b)
  521. continue;
  522. switch (flow_type_a) {
  523. case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
  524. case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
  525. case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
  526. if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
  527. return true;
  528. break;
  529. case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
  530. if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
  531. flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
  532. flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_SCTP)
  533. return true;
  534. break;
  535. case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
  536. case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
  537. case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
  538. if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_OTHER)
  539. return true;
  540. break;
  541. case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
  542. if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_UDP ||
  543. flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_TCP ||
  544. flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_SCTP)
  545. return true;
  546. break;
  547. default:
  548. break;
  549. }
  550. }
  551. return false;
  552. }
  553. /**
  554. * ice_vc_fdir_write_flow_prof
  555. * @vf: pointer to the VF structure
  556. * @flow: filter flow type
  557. * @seg: array of one or more packet segments that describe the flow
  558. * @tun: 0 implies non-tunnel type filter, 1 implies tunnel type filter
  559. *
  560. * Write the flow's profile config and packet segment into the hardware
  561. *
  562. * Return: 0 on success, and other on error.
  563. */
  564. static int
  565. ice_vc_fdir_write_flow_prof(struct ice_vf *vf, enum ice_fltr_ptype flow,
  566. struct ice_flow_seg_info *seg, int tun)
  567. {
  568. struct ice_vf_fdir *fdir = &vf->fdir;
  569. struct ice_vsi *vf_vsi, *ctrl_vsi;
  570. struct ice_flow_seg_info *old_seg;
  571. struct ice_flow_prof *prof = NULL;
  572. struct ice_fd_hw_prof *vf_prof;
  573. struct device *dev;
  574. struct ice_pf *pf;
  575. struct ice_hw *hw;
  576. u64 entry1_h = 0;
  577. u64 entry2_h = 0;
  578. int ret;
  579. pf = vf->pf;
  580. dev = ice_pf_to_dev(pf);
  581. hw = &pf->hw;
  582. vf_vsi = ice_get_vf_vsi(vf);
  583. if (!vf_vsi)
  584. return -EINVAL;
  585. ctrl_vsi = pf->vsi[vf->ctrl_vsi_idx];
  586. if (!ctrl_vsi)
  587. return -EINVAL;
  588. vf_prof = fdir->fdir_prof[flow];
  589. old_seg = vf_prof->fdir_seg[tun];
  590. if (old_seg) {
  591. if (!memcmp(old_seg, seg, sizeof(*seg))) {
  592. dev_dbg(dev, "Duplicated profile for VF %d!\n",
  593. vf->vf_id);
  594. return -EEXIST;
  595. }
  596. if (fdir->fdir_fltr_cnt[flow][tun]) {
  597. ret = -EINVAL;
  598. dev_dbg(dev, "Input set conflicts for VF %d\n",
  599. vf->vf_id);
  600. goto err_exit;
  601. }
  602. /* remove previously allocated profile */
  603. ice_vc_fdir_rem_prof(vf, flow, tun);
  604. }
  605. ret = ice_flow_add_prof(hw, ICE_BLK_FD, ICE_FLOW_RX, seg,
  606. tun + 1, false, &prof);
  607. if (ret) {
  608. dev_dbg(dev, "Could not add VSI flow 0x%x for VF %d\n",
  609. flow, vf->vf_id);
  610. goto err_exit;
  611. }
  612. ret = ice_flow_add_entry(hw, ICE_BLK_FD, prof->id, vf_vsi->idx,
  613. vf_vsi->idx, ICE_FLOW_PRIO_NORMAL,
  614. seg, &entry1_h);
  615. if (ret) {
  616. dev_dbg(dev, "Could not add flow 0x%x VSI entry for VF %d\n",
  617. flow, vf->vf_id);
  618. goto err_prof;
  619. }
  620. ret = ice_flow_add_entry(hw, ICE_BLK_FD, prof->id, vf_vsi->idx,
  621. ctrl_vsi->idx, ICE_FLOW_PRIO_NORMAL,
  622. seg, &entry2_h);
  623. if (ret) {
  624. dev_dbg(dev,
  625. "Could not add flow 0x%x Ctrl VSI entry for VF %d\n",
  626. flow, vf->vf_id);
  627. goto err_entry_1;
  628. }
  629. vf_prof->fdir_seg[tun] = seg;
  630. vf_prof->cnt = 0;
  631. fdir->prof_entry_cnt[flow][tun] = 0;
  632. vf_prof->entry_h[vf_prof->cnt][tun] = entry1_h;
  633. vf_prof->vsi_h[vf_prof->cnt] = vf_vsi->idx;
  634. vf_prof->cnt++;
  635. fdir->prof_entry_cnt[flow][tun]++;
  636. vf_prof->entry_h[vf_prof->cnt][tun] = entry2_h;
  637. vf_prof->vsi_h[vf_prof->cnt] = ctrl_vsi->idx;
  638. vf_prof->cnt++;
  639. fdir->prof_entry_cnt[flow][tun]++;
  640. vf_prof->prof_id[tun] = prof->id;
  641. return 0;
  642. err_entry_1:
  643. ice_rem_prof_id_flow(hw, ICE_BLK_FD,
  644. ice_get_hw_vsi_num(hw, vf_vsi->idx), prof->id);
  645. ice_flow_rem_entry(hw, ICE_BLK_FD, entry1_h);
  646. err_prof:
  647. ice_flow_rem_prof(hw, ICE_BLK_FD, prof->id);
  648. err_exit:
  649. return ret;
  650. }
  651. /**
  652. * ice_vc_fdir_config_input_set
  653. * @vf: pointer to the VF structure
  654. * @fltr: virtual channel add cmd buffer
  655. * @conf: FDIR configuration for each filter
  656. * @tun: 0 implies non-tunnel type filter, 1 implies tunnel type filter
  657. *
  658. * Config the input set type and value for virtual channel add msg buffer
  659. *
  660. * Return: 0 on success, and other on error.
  661. */
  662. static int
  663. ice_vc_fdir_config_input_set(struct ice_vf *vf, struct virtchnl_fdir_add *fltr,
  664. struct virtchnl_fdir_fltr_conf *conf, int tun)
  665. {
  666. struct ice_fdir_fltr *input = &conf->input;
  667. struct device *dev = ice_pf_to_dev(vf->pf);
  668. struct ice_flow_seg_info *seg;
  669. enum ice_fltr_ptype flow;
  670. int ret;
  671. ret = ice_vc_fdir_has_prof_conflict(vf, conf);
  672. if (ret) {
  673. dev_dbg(dev, "Found flow profile conflict for VF %d\n",
  674. vf->vf_id);
  675. return ret;
  676. }
  677. flow = input->flow_type;
  678. ret = ice_vc_fdir_alloc_prof(vf, flow);
  679. if (ret) {
  680. dev_dbg(dev, "Alloc flow prof for VF %d failed\n", vf->vf_id);
  681. return ret;
  682. }
  683. seg = devm_kzalloc(dev, sizeof(*seg), GFP_KERNEL);
  684. if (!seg)
  685. return -ENOMEM;
  686. ret = ice_vc_fdir_set_flow_fld(vf, fltr, conf, seg);
  687. if (ret) {
  688. dev_dbg(dev, "Set flow field for VF %d failed\n", vf->vf_id);
  689. goto err_exit;
  690. }
  691. ret = ice_vc_fdir_set_flow_hdr(vf, conf, seg);
  692. if (ret) {
  693. dev_dbg(dev, "Set flow hdr for VF %d failed\n", vf->vf_id);
  694. goto err_exit;
  695. }
  696. ret = ice_vc_fdir_write_flow_prof(vf, flow, seg, tun);
  697. if (ret == -EEXIST) {
  698. devm_kfree(dev, seg);
  699. } else if (ret) {
  700. dev_dbg(dev, "Write flow profile for VF %d failed\n",
  701. vf->vf_id);
  702. goto err_exit;
  703. }
  704. return 0;
  705. err_exit:
  706. devm_kfree(dev, seg);
  707. return ret;
  708. }
  709. /**
  710. * ice_vc_fdir_is_raw_flow - check if FDIR flow is raw (binary)
  711. * @proto: virtchnl protocol headers
  712. *
  713. * Check if the FDIR rule is raw flow (protocol agnostic flow) or not. Note
  714. * that common FDIR rule must have non-zero proto->count. Thus, we choose the
  715. * tunnel_level and count of proto as the indicators. If both tunnel_level and
  716. * count of proto are zero, this FDIR rule will be regarded as raw flow.
  717. *
  718. * Returns: true if headers describe raw flow, false otherwise.
  719. */
  720. static bool
  721. ice_vc_fdir_is_raw_flow(struct virtchnl_proto_hdrs *proto)
  722. {
  723. return (proto->tunnel_level == 0 && proto->count == 0);
  724. }
  725. /**
  726. * ice_vc_fdir_parse_raw - parse a virtchnl raw FDIR rule
  727. * @vf: pointer to the VF info
  728. * @proto: virtchnl protocol headers
  729. * @conf: FDIR configuration for each filter
  730. *
  731. * Parse the virtual channel filter's raw flow and store it in @conf
  732. *
  733. * Return: 0 on success or negative errno on failure.
  734. */
  735. static int
  736. ice_vc_fdir_parse_raw(struct ice_vf *vf,
  737. struct virtchnl_proto_hdrs *proto,
  738. struct virtchnl_fdir_fltr_conf *conf)
  739. {
  740. u8 *pkt_buf, *msk_buf __free(kfree);
  741. struct ice_parser_result rslt;
  742. struct ice_pf *pf = vf->pf;
  743. struct ice_parser *psr;
  744. int status = -ENOMEM;
  745. struct ice_hw *hw;
  746. u16 udp_port = 0;
  747. pkt_buf = kzalloc(proto->raw.pkt_len, GFP_KERNEL);
  748. msk_buf = kzalloc(proto->raw.pkt_len, GFP_KERNEL);
  749. if (!pkt_buf || !msk_buf)
  750. goto err_mem_alloc;
  751. memcpy(pkt_buf, proto->raw.spec, proto->raw.pkt_len);
  752. memcpy(msk_buf, proto->raw.mask, proto->raw.pkt_len);
  753. hw = &pf->hw;
  754. /* Get raw profile info via Parser Lib */
  755. psr = ice_parser_create(hw);
  756. if (IS_ERR(psr)) {
  757. status = PTR_ERR(psr);
  758. goto err_mem_alloc;
  759. }
  760. ice_parser_dvm_set(psr, ice_is_dvm_ena(hw));
  761. if (ice_get_open_tunnel_port(hw, &udp_port, TNL_VXLAN))
  762. ice_parser_vxlan_tunnel_set(psr, udp_port, true);
  763. status = ice_parser_run(psr, pkt_buf, proto->raw.pkt_len, &rslt);
  764. if (status)
  765. goto err_parser_destroy;
  766. if (hw->debug_mask & ICE_DBG_PARSER)
  767. ice_parser_result_dump(hw, &rslt);
  768. conf->prof = kzalloc(sizeof(*conf->prof), GFP_KERNEL);
  769. if (!conf->prof) {
  770. status = -ENOMEM;
  771. goto err_parser_destroy;
  772. }
  773. status = ice_parser_profile_init(&rslt, pkt_buf, msk_buf,
  774. proto->raw.pkt_len, ICE_BLK_FD,
  775. conf->prof);
  776. if (status)
  777. goto err_parser_profile_init;
  778. if (hw->debug_mask & ICE_DBG_PARSER)
  779. ice_parser_profile_dump(hw, conf->prof);
  780. /* Store raw flow info into @conf */
  781. conf->pkt_len = proto->raw.pkt_len;
  782. conf->pkt_buf = pkt_buf;
  783. conf->parser_ena = true;
  784. ice_parser_destroy(psr);
  785. return 0;
  786. err_parser_profile_init:
  787. kfree(conf->prof);
  788. err_parser_destroy:
  789. ice_parser_destroy(psr);
  790. err_mem_alloc:
  791. kfree(pkt_buf);
  792. return status;
  793. }
  794. /**
  795. * ice_vc_fdir_parse_pattern
  796. * @vf: pointer to the VF info
  797. * @fltr: virtual channel add cmd buffer
  798. * @conf: FDIR configuration for each filter
  799. *
  800. * Parse the virtual channel filter's pattern and store them into conf
  801. *
  802. * Return: 0 on success, and other on error.
  803. */
  804. static int
  805. ice_vc_fdir_parse_pattern(struct ice_vf *vf, struct virtchnl_fdir_add *fltr,
  806. struct virtchnl_fdir_fltr_conf *conf)
  807. {
  808. struct virtchnl_proto_hdrs *proto = &fltr->rule_cfg.proto_hdrs;
  809. enum virtchnl_proto_hdr_type l3 = VIRTCHNL_PROTO_HDR_NONE;
  810. enum virtchnl_proto_hdr_type l4 = VIRTCHNL_PROTO_HDR_NONE;
  811. struct device *dev = ice_pf_to_dev(vf->pf);
  812. struct ice_fdir_fltr *input = &conf->input;
  813. int i;
  814. if (proto->count > VIRTCHNL_MAX_NUM_PROTO_HDRS) {
  815. dev_dbg(dev, "Invalid protocol count:0x%x for VF %d\n",
  816. proto->count, vf->vf_id);
  817. return -EINVAL;
  818. }
  819. /* For raw FDIR filters created by the parser */
  820. if (ice_vc_fdir_is_raw_flow(proto))
  821. return ice_vc_fdir_parse_raw(vf, proto, conf);
  822. for (i = 0; i < proto->count; i++) {
  823. struct virtchnl_proto_hdr *hdr = &proto->proto_hdr[i];
  824. struct ip_esp_hdr *esph;
  825. struct ip_auth_hdr *ah;
  826. struct sctphdr *sctph;
  827. struct ipv6hdr *ip6h;
  828. struct udphdr *udph;
  829. struct tcphdr *tcph;
  830. struct ethhdr *eth;
  831. struct iphdr *iph;
  832. u8 s_field;
  833. u8 *rawh;
  834. switch (hdr->type) {
  835. case VIRTCHNL_PROTO_HDR_ETH:
  836. eth = (struct ethhdr *)hdr->buffer;
  837. input->flow_type = ICE_FLTR_PTYPE_NON_IP_L2;
  838. if (hdr->field_selector)
  839. input->ext_data.ether_type = eth->h_proto;
  840. break;
  841. case VIRTCHNL_PROTO_HDR_IPV4:
  842. iph = (struct iphdr *)hdr->buffer;
  843. l3 = VIRTCHNL_PROTO_HDR_IPV4;
  844. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_OTHER;
  845. if (hdr->field_selector) {
  846. input->ip.v4.src_ip = iph->saddr;
  847. input->ip.v4.dst_ip = iph->daddr;
  848. input->ip.v4.tos = iph->tos;
  849. input->ip.v4.proto = iph->protocol;
  850. }
  851. break;
  852. case VIRTCHNL_PROTO_HDR_IPV6:
  853. ip6h = (struct ipv6hdr *)hdr->buffer;
  854. l3 = VIRTCHNL_PROTO_HDR_IPV6;
  855. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_OTHER;
  856. if (hdr->field_selector) {
  857. memcpy(input->ip.v6.src_ip,
  858. ip6h->saddr.in6_u.u6_addr8,
  859. sizeof(ip6h->saddr));
  860. memcpy(input->ip.v6.dst_ip,
  861. ip6h->daddr.in6_u.u6_addr8,
  862. sizeof(ip6h->daddr));
  863. input->ip.v6.tc = ((u8)(ip6h->priority) << 4) |
  864. (ip6h->flow_lbl[0] >> 4);
  865. input->ip.v6.proto = ip6h->nexthdr;
  866. }
  867. break;
  868. case VIRTCHNL_PROTO_HDR_TCP:
  869. tcph = (struct tcphdr *)hdr->buffer;
  870. if (l3 == VIRTCHNL_PROTO_HDR_IPV4)
  871. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_TCP;
  872. else if (l3 == VIRTCHNL_PROTO_HDR_IPV6)
  873. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_TCP;
  874. if (hdr->field_selector) {
  875. if (l3 == VIRTCHNL_PROTO_HDR_IPV4) {
  876. input->ip.v4.src_port = tcph->source;
  877. input->ip.v4.dst_port = tcph->dest;
  878. } else if (l3 == VIRTCHNL_PROTO_HDR_IPV6) {
  879. input->ip.v6.src_port = tcph->source;
  880. input->ip.v6.dst_port = tcph->dest;
  881. }
  882. }
  883. break;
  884. case VIRTCHNL_PROTO_HDR_UDP:
  885. udph = (struct udphdr *)hdr->buffer;
  886. if (l3 == VIRTCHNL_PROTO_HDR_IPV4)
  887. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_UDP;
  888. else if (l3 == VIRTCHNL_PROTO_HDR_IPV6)
  889. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_UDP;
  890. if (hdr->field_selector) {
  891. if (l3 == VIRTCHNL_PROTO_HDR_IPV4) {
  892. input->ip.v4.src_port = udph->source;
  893. input->ip.v4.dst_port = udph->dest;
  894. } else if (l3 == VIRTCHNL_PROTO_HDR_IPV6) {
  895. input->ip.v6.src_port = udph->source;
  896. input->ip.v6.dst_port = udph->dest;
  897. }
  898. }
  899. break;
  900. case VIRTCHNL_PROTO_HDR_SCTP:
  901. sctph = (struct sctphdr *)hdr->buffer;
  902. if (l3 == VIRTCHNL_PROTO_HDR_IPV4)
  903. input->flow_type =
  904. ICE_FLTR_PTYPE_NONF_IPV4_SCTP;
  905. else if (l3 == VIRTCHNL_PROTO_HDR_IPV6)
  906. input->flow_type =
  907. ICE_FLTR_PTYPE_NONF_IPV6_SCTP;
  908. if (hdr->field_selector) {
  909. if (l3 == VIRTCHNL_PROTO_HDR_IPV4) {
  910. input->ip.v4.src_port = sctph->source;
  911. input->ip.v4.dst_port = sctph->dest;
  912. } else if (l3 == VIRTCHNL_PROTO_HDR_IPV6) {
  913. input->ip.v6.src_port = sctph->source;
  914. input->ip.v6.dst_port = sctph->dest;
  915. }
  916. }
  917. break;
  918. case VIRTCHNL_PROTO_HDR_L2TPV3:
  919. if (l3 == VIRTCHNL_PROTO_HDR_IPV4)
  920. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_L2TPV3;
  921. else if (l3 == VIRTCHNL_PROTO_HDR_IPV6)
  922. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_L2TPV3;
  923. if (hdr->field_selector)
  924. input->l2tpv3_data.session_id = *((__be32 *)hdr->buffer);
  925. break;
  926. case VIRTCHNL_PROTO_HDR_ESP:
  927. esph = (struct ip_esp_hdr *)hdr->buffer;
  928. if (l3 == VIRTCHNL_PROTO_HDR_IPV4 &&
  929. l4 == VIRTCHNL_PROTO_HDR_UDP)
  930. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_NAT_T_ESP;
  931. else if (l3 == VIRTCHNL_PROTO_HDR_IPV6 &&
  932. l4 == VIRTCHNL_PROTO_HDR_UDP)
  933. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_NAT_T_ESP;
  934. else if (l3 == VIRTCHNL_PROTO_HDR_IPV4 &&
  935. l4 == VIRTCHNL_PROTO_HDR_NONE)
  936. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_ESP;
  937. else if (l3 == VIRTCHNL_PROTO_HDR_IPV6 &&
  938. l4 == VIRTCHNL_PROTO_HDR_NONE)
  939. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_ESP;
  940. if (l4 == VIRTCHNL_PROTO_HDR_UDP)
  941. conf->inset_flag |= FDIR_INSET_FLAG_ESP_UDP;
  942. else
  943. conf->inset_flag |= FDIR_INSET_FLAG_ESP_IPSEC;
  944. if (hdr->field_selector) {
  945. if (l3 == VIRTCHNL_PROTO_HDR_IPV4)
  946. input->ip.v4.sec_parm_idx = esph->spi;
  947. else if (l3 == VIRTCHNL_PROTO_HDR_IPV6)
  948. input->ip.v6.sec_parm_idx = esph->spi;
  949. }
  950. break;
  951. case VIRTCHNL_PROTO_HDR_AH:
  952. ah = (struct ip_auth_hdr *)hdr->buffer;
  953. if (l3 == VIRTCHNL_PROTO_HDR_IPV4)
  954. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_AH;
  955. else if (l3 == VIRTCHNL_PROTO_HDR_IPV6)
  956. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_AH;
  957. if (hdr->field_selector) {
  958. if (l3 == VIRTCHNL_PROTO_HDR_IPV4)
  959. input->ip.v4.sec_parm_idx = ah->spi;
  960. else if (l3 == VIRTCHNL_PROTO_HDR_IPV6)
  961. input->ip.v6.sec_parm_idx = ah->spi;
  962. }
  963. break;
  964. case VIRTCHNL_PROTO_HDR_PFCP:
  965. rawh = (u8 *)hdr->buffer;
  966. s_field = (rawh[0] >> PFCP_S_OFFSET) & PFCP_S_MASK;
  967. if (l3 == VIRTCHNL_PROTO_HDR_IPV4 && s_field == 0)
  968. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_PFCP_NODE;
  969. else if (l3 == VIRTCHNL_PROTO_HDR_IPV4 && s_field == 1)
  970. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_PFCP_SESSION;
  971. else if (l3 == VIRTCHNL_PROTO_HDR_IPV6 && s_field == 0)
  972. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_PFCP_NODE;
  973. else if (l3 == VIRTCHNL_PROTO_HDR_IPV6 && s_field == 1)
  974. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV6_PFCP_SESSION;
  975. if (hdr->field_selector) {
  976. if (l3 == VIRTCHNL_PROTO_HDR_IPV4)
  977. input->ip.v4.dst_port = cpu_to_be16(PFCP_PORT_NR);
  978. else if (l3 == VIRTCHNL_PROTO_HDR_IPV6)
  979. input->ip.v6.dst_port = cpu_to_be16(PFCP_PORT_NR);
  980. }
  981. break;
  982. case VIRTCHNL_PROTO_HDR_GTPU_IP:
  983. rawh = (u8 *)hdr->buffer;
  984. input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER;
  985. if (hdr->field_selector)
  986. input->gtpu_data.teid = *(__be32 *)(&rawh[GTPU_TEID_OFFSET]);
  987. conf->ttype = ICE_FDIR_TUNNEL_TYPE_GTPU;
  988. break;
  989. case VIRTCHNL_PROTO_HDR_GTPU_EH:
  990. rawh = (u8 *)hdr->buffer;
  991. if (hdr->field_selector)
  992. input->gtpu_data.qfi = rawh[GTPU_EH_QFI_OFFSET] & GTPU_EH_QFI_MASK;
  993. conf->ttype = ICE_FDIR_TUNNEL_TYPE_GTPU_EH;
  994. break;
  995. default:
  996. dev_dbg(dev, "Invalid header type 0x:%x for VF %d\n",
  997. hdr->type, vf->vf_id);
  998. return -EINVAL;
  999. }
  1000. }
  1001. return 0;
  1002. }
  1003. /**
  1004. * ice_vc_fdir_parse_action
  1005. * @vf: pointer to the VF info
  1006. * @fltr: virtual channel add cmd buffer
  1007. * @conf: FDIR configuration for each filter
  1008. *
  1009. * Parse the virtual channel filter's action and store them into conf
  1010. *
  1011. * Return: 0 on success, and other on error.
  1012. */
  1013. static int
  1014. ice_vc_fdir_parse_action(struct ice_vf *vf, struct virtchnl_fdir_add *fltr,
  1015. struct virtchnl_fdir_fltr_conf *conf)
  1016. {
  1017. struct virtchnl_filter_action_set *as = &fltr->rule_cfg.action_set;
  1018. struct device *dev = ice_pf_to_dev(vf->pf);
  1019. struct ice_fdir_fltr *input = &conf->input;
  1020. u32 dest_num = 0;
  1021. u32 mark_num = 0;
  1022. int i;
  1023. if (as->count > VIRTCHNL_MAX_NUM_ACTIONS) {
  1024. dev_dbg(dev, "Invalid action numbers:0x%x for VF %d\n",
  1025. as->count, vf->vf_id);
  1026. return -EINVAL;
  1027. }
  1028. for (i = 0; i < as->count; i++) {
  1029. struct virtchnl_filter_action *action = &as->actions[i];
  1030. switch (action->type) {
  1031. case VIRTCHNL_ACTION_PASSTHRU:
  1032. dest_num++;
  1033. input->dest_ctl = ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER;
  1034. break;
  1035. case VIRTCHNL_ACTION_DROP:
  1036. dest_num++;
  1037. input->dest_ctl = ICE_FLTR_PRGM_DESC_DEST_DROP_PKT;
  1038. break;
  1039. case VIRTCHNL_ACTION_QUEUE:
  1040. dest_num++;
  1041. input->dest_ctl = ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QINDEX;
  1042. input->q_index = action->act_conf.queue.index;
  1043. break;
  1044. case VIRTCHNL_ACTION_Q_REGION:
  1045. dest_num++;
  1046. input->dest_ctl = ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QGROUP;
  1047. input->q_index = action->act_conf.queue.index;
  1048. input->q_region = action->act_conf.queue.region;
  1049. break;
  1050. case VIRTCHNL_ACTION_MARK:
  1051. mark_num++;
  1052. input->fltr_id = action->act_conf.mark_id;
  1053. input->fdid_prio = ICE_FXD_FLTR_QW1_FDID_PRI_THREE;
  1054. break;
  1055. default:
  1056. dev_dbg(dev, "Invalid action type:0x%x for VF %d\n",
  1057. action->type, vf->vf_id);
  1058. return -EINVAL;
  1059. }
  1060. }
  1061. if (dest_num == 0 || dest_num >= 2) {
  1062. dev_dbg(dev, "Invalid destination action for VF %d\n",
  1063. vf->vf_id);
  1064. return -EINVAL;
  1065. }
  1066. if (mark_num >= 2) {
  1067. dev_dbg(dev, "Too many mark actions for VF %d\n", vf->vf_id);
  1068. return -EINVAL;
  1069. }
  1070. return 0;
  1071. }
  1072. /**
  1073. * ice_vc_validate_fdir_fltr - validate the virtual channel filter
  1074. * @vf: pointer to the VF info
  1075. * @fltr: virtual channel add cmd buffer
  1076. * @conf: FDIR configuration for each filter
  1077. *
  1078. * Return: 0 on success, and other on error.
  1079. */
  1080. static int
  1081. ice_vc_validate_fdir_fltr(struct ice_vf *vf, struct virtchnl_fdir_add *fltr,
  1082. struct virtchnl_fdir_fltr_conf *conf)
  1083. {
  1084. struct virtchnl_proto_hdrs *proto = &fltr->rule_cfg.proto_hdrs;
  1085. int ret;
  1086. /* For raw FDIR filters created by the parser */
  1087. if (!ice_vc_fdir_is_raw_flow(proto))
  1088. if (!ice_vc_validate_pattern(vf, proto))
  1089. return -EINVAL;
  1090. ret = ice_vc_fdir_parse_pattern(vf, fltr, conf);
  1091. if (ret)
  1092. return ret;
  1093. return ice_vc_fdir_parse_action(vf, fltr, conf);
  1094. }
  1095. /**
  1096. * ice_vc_fdir_comp_rules - compare if two filter rules have the same value
  1097. * @conf_a: FDIR configuration for filter a
  1098. * @conf_b: FDIR configuration for filter b
  1099. *
  1100. * Return: 0 on success, and other on error.
  1101. */
  1102. static bool
  1103. ice_vc_fdir_comp_rules(struct virtchnl_fdir_fltr_conf *conf_a,
  1104. struct virtchnl_fdir_fltr_conf *conf_b)
  1105. {
  1106. struct ice_fdir_fltr *a = &conf_a->input;
  1107. struct ice_fdir_fltr *b = &conf_b->input;
  1108. if (conf_a->ttype != conf_b->ttype)
  1109. return false;
  1110. if (a->flow_type != b->flow_type)
  1111. return false;
  1112. if (memcmp(&a->ip, &b->ip, sizeof(a->ip)))
  1113. return false;
  1114. if (memcmp(&a->mask, &b->mask, sizeof(a->mask)))
  1115. return false;
  1116. if (memcmp(&a->gtpu_data, &b->gtpu_data, sizeof(a->gtpu_data)))
  1117. return false;
  1118. if (memcmp(&a->gtpu_mask, &b->gtpu_mask, sizeof(a->gtpu_mask)))
  1119. return false;
  1120. if (memcmp(&a->l2tpv3_data, &b->l2tpv3_data, sizeof(a->l2tpv3_data)))
  1121. return false;
  1122. if (memcmp(&a->l2tpv3_mask, &b->l2tpv3_mask, sizeof(a->l2tpv3_mask)))
  1123. return false;
  1124. if (memcmp(&a->ext_data, &b->ext_data, sizeof(a->ext_data)))
  1125. return false;
  1126. if (memcmp(&a->ext_mask, &b->ext_mask, sizeof(a->ext_mask)))
  1127. return false;
  1128. return true;
  1129. }
  1130. /**
  1131. * ice_vc_fdir_is_dup_fltr
  1132. * @vf: pointer to the VF info
  1133. * @conf: FDIR configuration for each filter
  1134. *
  1135. * Check if there is duplicated rule with same conf value
  1136. *
  1137. * Return: 0 true success, and false on error.
  1138. */
  1139. static bool
  1140. ice_vc_fdir_is_dup_fltr(struct ice_vf *vf, struct virtchnl_fdir_fltr_conf *conf)
  1141. {
  1142. struct ice_fdir_fltr *desc;
  1143. bool ret;
  1144. list_for_each_entry(desc, &vf->fdir.fdir_rule_list, fltr_node) {
  1145. struct virtchnl_fdir_fltr_conf *node =
  1146. to_fltr_conf_from_desc(desc);
  1147. ret = ice_vc_fdir_comp_rules(node, conf);
  1148. if (ret)
  1149. return true;
  1150. }
  1151. return false;
  1152. }
  1153. /**
  1154. * ice_vc_fdir_insert_entry
  1155. * @vf: pointer to the VF info
  1156. * @conf: FDIR configuration for each filter
  1157. * @id: pointer to ID value allocated by driver
  1158. *
  1159. * Insert FDIR conf entry into list and allocate ID for this filter
  1160. *
  1161. * Return: 0 true success, and other on error.
  1162. */
  1163. static int
  1164. ice_vc_fdir_insert_entry(struct ice_vf *vf,
  1165. struct virtchnl_fdir_fltr_conf *conf, u32 *id)
  1166. {
  1167. struct ice_fdir_fltr *input = &conf->input;
  1168. int i;
  1169. /* alloc ID corresponding with conf */
  1170. i = idr_alloc(&vf->fdir.fdir_rule_idr, conf, 0,
  1171. ICE_FDIR_MAX_FLTRS, GFP_KERNEL);
  1172. if (i < 0)
  1173. return -EINVAL;
  1174. *id = i;
  1175. list_add(&input->fltr_node, &vf->fdir.fdir_rule_list);
  1176. return 0;
  1177. }
  1178. /**
  1179. * ice_vc_fdir_remove_entry - remove FDIR conf entry by ID value
  1180. * @vf: pointer to the VF info
  1181. * @conf: FDIR configuration for each filter
  1182. * @id: filter rule's ID
  1183. */
  1184. static void
  1185. ice_vc_fdir_remove_entry(struct ice_vf *vf,
  1186. struct virtchnl_fdir_fltr_conf *conf, u32 id)
  1187. {
  1188. struct ice_fdir_fltr *input = &conf->input;
  1189. idr_remove(&vf->fdir.fdir_rule_idr, id);
  1190. list_del(&input->fltr_node);
  1191. }
  1192. /**
  1193. * ice_vc_fdir_lookup_entry - lookup FDIR conf entry by ID value
  1194. * @vf: pointer to the VF info
  1195. * @id: filter rule's ID
  1196. *
  1197. * Return: NULL on error, and other on success.
  1198. */
  1199. static struct virtchnl_fdir_fltr_conf *
  1200. ice_vc_fdir_lookup_entry(struct ice_vf *vf, u32 id)
  1201. {
  1202. return idr_find(&vf->fdir.fdir_rule_idr, id);
  1203. }
  1204. /**
  1205. * ice_vc_fdir_flush_entry - remove all FDIR conf entry
  1206. * @vf: pointer to the VF info
  1207. */
  1208. static void ice_vc_fdir_flush_entry(struct ice_vf *vf)
  1209. {
  1210. struct virtchnl_fdir_fltr_conf *conf;
  1211. struct ice_fdir_fltr *desc, *temp;
  1212. list_for_each_entry_safe(desc, temp,
  1213. &vf->fdir.fdir_rule_list, fltr_node) {
  1214. conf = to_fltr_conf_from_desc(desc);
  1215. list_del(&desc->fltr_node);
  1216. devm_kfree(ice_pf_to_dev(vf->pf), conf);
  1217. }
  1218. }
  1219. /**
  1220. * ice_vc_fdir_write_fltr - write filter rule into hardware
  1221. * @vf: pointer to the VF info
  1222. * @conf: FDIR configuration for each filter
  1223. * @add: true implies add rule, false implies del rules
  1224. * @is_tun: false implies non-tunnel type filter, true implies tunnel filter
  1225. *
  1226. * Return: 0 on success, and other on error.
  1227. */
  1228. static int ice_vc_fdir_write_fltr(struct ice_vf *vf,
  1229. struct virtchnl_fdir_fltr_conf *conf,
  1230. bool add, bool is_tun)
  1231. {
  1232. struct ice_fdir_fltr *input = &conf->input;
  1233. struct ice_vsi *vsi, *ctrl_vsi;
  1234. struct ice_fltr_desc desc;
  1235. struct device *dev;
  1236. struct ice_pf *pf;
  1237. struct ice_hw *hw;
  1238. int ret;
  1239. u8 *pkt;
  1240. pf = vf->pf;
  1241. dev = ice_pf_to_dev(pf);
  1242. hw = &pf->hw;
  1243. vsi = ice_get_vf_vsi(vf);
  1244. if (!vsi) {
  1245. dev_dbg(dev, "Invalid vsi for VF %d\n", vf->vf_id);
  1246. return -EINVAL;
  1247. }
  1248. input->dest_vsi = vsi->idx;
  1249. input->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
  1250. ctrl_vsi = pf->vsi[vf->ctrl_vsi_idx];
  1251. if (!ctrl_vsi) {
  1252. dev_dbg(dev, "Invalid ctrl_vsi for VF %d\n", vf->vf_id);
  1253. return -EINVAL;
  1254. }
  1255. pkt = devm_kzalloc(dev, ICE_FDIR_MAX_RAW_PKT_SIZE, GFP_KERNEL);
  1256. if (!pkt)
  1257. return -ENOMEM;
  1258. ice_fdir_get_prgm_desc(hw, input, &desc, add);
  1259. if (conf->parser_ena) {
  1260. memcpy(pkt, conf->pkt_buf, conf->pkt_len);
  1261. } else {
  1262. ret = ice_fdir_get_gen_prgm_pkt(hw, input, pkt, false, is_tun);
  1263. if (ret) {
  1264. dev_dbg(dev, "Gen training pkt for VF %d ptype %d failed\n",
  1265. vf->vf_id, input->flow_type);
  1266. goto err_free_pkt;
  1267. }
  1268. }
  1269. ret = ice_prgm_fdir_fltr(ctrl_vsi, &desc, pkt);
  1270. if (ret)
  1271. goto err_free_pkt;
  1272. return 0;
  1273. err_free_pkt:
  1274. devm_kfree(dev, pkt);
  1275. return ret;
  1276. }
  1277. /**
  1278. * ice_vf_fdir_timer - FDIR program waiting timer interrupt handler
  1279. * @t: pointer to timer_list
  1280. */
  1281. static void ice_vf_fdir_timer(struct timer_list *t)
  1282. {
  1283. struct ice_vf_fdir_ctx *ctx_irq = from_timer(ctx_irq, t, rx_tmr);
  1284. struct ice_vf_fdir_ctx *ctx_done;
  1285. struct ice_vf_fdir *fdir;
  1286. unsigned long flags;
  1287. struct ice_vf *vf;
  1288. struct ice_pf *pf;
  1289. fdir = container_of(ctx_irq, struct ice_vf_fdir, ctx_irq);
  1290. vf = container_of(fdir, struct ice_vf, fdir);
  1291. ctx_done = &fdir->ctx_done;
  1292. pf = vf->pf;
  1293. spin_lock_irqsave(&fdir->ctx_lock, flags);
  1294. if (!(ctx_irq->flags & ICE_VF_FDIR_CTX_VALID)) {
  1295. spin_unlock_irqrestore(&fdir->ctx_lock, flags);
  1296. WARN_ON_ONCE(1);
  1297. return;
  1298. }
  1299. ctx_irq->flags &= ~ICE_VF_FDIR_CTX_VALID;
  1300. ctx_done->flags |= ICE_VF_FDIR_CTX_VALID;
  1301. ctx_done->conf = ctx_irq->conf;
  1302. ctx_done->stat = ICE_FDIR_CTX_TIMEOUT;
  1303. ctx_done->v_opcode = ctx_irq->v_opcode;
  1304. spin_unlock_irqrestore(&fdir->ctx_lock, flags);
  1305. set_bit(ICE_FD_VF_FLUSH_CTX, pf->state);
  1306. ice_service_task_schedule(pf);
  1307. }
  1308. /**
  1309. * ice_vc_fdir_irq_handler - ctrl_vsi Rx queue interrupt handler
  1310. * @ctrl_vsi: pointer to a VF's CTRL VSI
  1311. * @rx_desc: pointer to FDIR Rx queue descriptor
  1312. */
  1313. void
  1314. ice_vc_fdir_irq_handler(struct ice_vsi *ctrl_vsi,
  1315. union ice_32b_rx_flex_desc *rx_desc)
  1316. {
  1317. struct ice_pf *pf = ctrl_vsi->back;
  1318. struct ice_vf *vf = ctrl_vsi->vf;
  1319. struct ice_vf_fdir_ctx *ctx_done;
  1320. struct ice_vf_fdir_ctx *ctx_irq;
  1321. struct ice_vf_fdir *fdir;
  1322. unsigned long flags;
  1323. struct device *dev;
  1324. int ret;
  1325. if (WARN_ON(!vf))
  1326. return;
  1327. fdir = &vf->fdir;
  1328. ctx_done = &fdir->ctx_done;
  1329. ctx_irq = &fdir->ctx_irq;
  1330. dev = ice_pf_to_dev(pf);
  1331. spin_lock_irqsave(&fdir->ctx_lock, flags);
  1332. if (!(ctx_irq->flags & ICE_VF_FDIR_CTX_VALID)) {
  1333. spin_unlock_irqrestore(&fdir->ctx_lock, flags);
  1334. WARN_ON_ONCE(1);
  1335. return;
  1336. }
  1337. ctx_irq->flags &= ~ICE_VF_FDIR_CTX_VALID;
  1338. ctx_done->flags |= ICE_VF_FDIR_CTX_VALID;
  1339. ctx_done->conf = ctx_irq->conf;
  1340. ctx_done->stat = ICE_FDIR_CTX_IRQ;
  1341. ctx_done->v_opcode = ctx_irq->v_opcode;
  1342. memcpy(&ctx_done->rx_desc, rx_desc, sizeof(*rx_desc));
  1343. spin_unlock_irqrestore(&fdir->ctx_lock, flags);
  1344. ret = del_timer(&ctx_irq->rx_tmr);
  1345. if (!ret)
  1346. dev_err(dev, "VF %d: Unexpected inactive timer!\n", vf->vf_id);
  1347. set_bit(ICE_FD_VF_FLUSH_CTX, pf->state);
  1348. ice_service_task_schedule(pf);
  1349. }
  1350. /**
  1351. * ice_vf_fdir_dump_info - dump FDIR information for diagnosis
  1352. * @vf: pointer to the VF info
  1353. */
  1354. static void ice_vf_fdir_dump_info(struct ice_vf *vf)
  1355. {
  1356. u32 fd_size, fd_cnt, fd_size_g, fd_cnt_g, fd_size_b, fd_cnt_b;
  1357. struct ice_vsi *vf_vsi;
  1358. struct device *dev;
  1359. struct ice_pf *pf;
  1360. struct ice_hw *hw;
  1361. u16 vsi_num;
  1362. pf = vf->pf;
  1363. hw = &pf->hw;
  1364. dev = ice_pf_to_dev(pf);
  1365. vf_vsi = ice_get_vf_vsi(vf);
  1366. if (!vf_vsi) {
  1367. dev_dbg(dev, "VF %d: invalid VSI pointer\n", vf->vf_id);
  1368. return;
  1369. }
  1370. vsi_num = ice_get_hw_vsi_num(hw, vf_vsi->idx);
  1371. fd_size = rd32(hw, VSIQF_FD_SIZE(vsi_num));
  1372. fd_cnt = rd32(hw, VSIQF_FD_CNT(vsi_num));
  1373. switch (hw->mac_type) {
  1374. case ICE_MAC_E830:
  1375. fd_size_g = FIELD_GET(E830_VSIQF_FD_CNT_FD_GCNT_M, fd_size);
  1376. fd_size_b = FIELD_GET(E830_VSIQF_FD_CNT_FD_BCNT_M, fd_size);
  1377. fd_cnt_g = FIELD_GET(E830_VSIQF_FD_CNT_FD_GCNT_M, fd_cnt);
  1378. fd_cnt_b = FIELD_GET(E830_VSIQF_FD_CNT_FD_BCNT_M, fd_cnt);
  1379. break;
  1380. case ICE_MAC_E810:
  1381. default:
  1382. fd_size_g = FIELD_GET(E800_VSIQF_FD_CNT_FD_GCNT_M, fd_size);
  1383. fd_size_b = FIELD_GET(E800_VSIQF_FD_CNT_FD_BCNT_M, fd_size);
  1384. fd_cnt_g = FIELD_GET(E800_VSIQF_FD_CNT_FD_GCNT_M, fd_cnt);
  1385. fd_cnt_b = FIELD_GET(E800_VSIQF_FD_CNT_FD_BCNT_M, fd_cnt);
  1386. }
  1387. dev_dbg(dev, "VF %d: Size in the FD table: guaranteed:0x%x, best effort:0x%x\n",
  1388. vf->vf_id, fd_size_g, fd_size_b);
  1389. dev_dbg(dev, "VF %d: Filter counter in the FD table: guaranteed:0x%x, best effort:0x%x\n",
  1390. vf->vf_id, fd_cnt_g, fd_cnt_b);
  1391. }
  1392. /**
  1393. * ice_vf_verify_rx_desc - verify received FDIR programming status descriptor
  1394. * @vf: pointer to the VF info
  1395. * @ctx: FDIR context info for post processing
  1396. * @status: virtchnl FDIR program status
  1397. *
  1398. * Return: 0 on success, and other on error.
  1399. */
  1400. static int
  1401. ice_vf_verify_rx_desc(struct ice_vf *vf, struct ice_vf_fdir_ctx *ctx,
  1402. enum virtchnl_fdir_prgm_status *status)
  1403. {
  1404. struct device *dev = ice_pf_to_dev(vf->pf);
  1405. u32 stat_err, error, prog_id;
  1406. int ret;
  1407. stat_err = le16_to_cpu(ctx->rx_desc.wb.status_error0);
  1408. if (FIELD_GET(ICE_FXD_FLTR_WB_QW1_DD_M, stat_err) !=
  1409. ICE_FXD_FLTR_WB_QW1_DD_YES) {
  1410. *status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
  1411. dev_err(dev, "VF %d: Desc Done not set\n", vf->vf_id);
  1412. ret = -EINVAL;
  1413. goto err_exit;
  1414. }
  1415. prog_id = FIELD_GET(ICE_FXD_FLTR_WB_QW1_PROG_ID_M, stat_err);
  1416. if (prog_id == ICE_FXD_FLTR_WB_QW1_PROG_ADD &&
  1417. ctx->v_opcode != VIRTCHNL_OP_ADD_FDIR_FILTER) {
  1418. dev_err(dev, "VF %d: Desc show add, but ctx not",
  1419. vf->vf_id);
  1420. *status = VIRTCHNL_FDIR_FAILURE_RULE_INVALID;
  1421. ret = -EINVAL;
  1422. goto err_exit;
  1423. }
  1424. if (prog_id == ICE_FXD_FLTR_WB_QW1_PROG_DEL &&
  1425. ctx->v_opcode != VIRTCHNL_OP_DEL_FDIR_FILTER) {
  1426. dev_err(dev, "VF %d: Desc show del, but ctx not",
  1427. vf->vf_id);
  1428. *status = VIRTCHNL_FDIR_FAILURE_RULE_INVALID;
  1429. ret = -EINVAL;
  1430. goto err_exit;
  1431. }
  1432. error = FIELD_GET(ICE_FXD_FLTR_WB_QW1_FAIL_M, stat_err);
  1433. if (error == ICE_FXD_FLTR_WB_QW1_FAIL_YES) {
  1434. if (prog_id == ICE_FXD_FLTR_WB_QW1_PROG_ADD) {
  1435. dev_err(dev, "VF %d, Failed to add FDIR rule due to no space in the table",
  1436. vf->vf_id);
  1437. *status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
  1438. } else {
  1439. dev_err(dev, "VF %d, Failed to remove FDIR rule, attempt to remove non-existent entry",
  1440. vf->vf_id);
  1441. *status = VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST;
  1442. }
  1443. ret = -EINVAL;
  1444. goto err_exit;
  1445. }
  1446. error = FIELD_GET(ICE_FXD_FLTR_WB_QW1_FAIL_PROF_M, stat_err);
  1447. if (error == ICE_FXD_FLTR_WB_QW1_FAIL_PROF_YES) {
  1448. dev_err(dev, "VF %d: Profile matching error", vf->vf_id);
  1449. *status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
  1450. ret = -EINVAL;
  1451. goto err_exit;
  1452. }
  1453. *status = VIRTCHNL_FDIR_SUCCESS;
  1454. return 0;
  1455. err_exit:
  1456. ice_vf_fdir_dump_info(vf);
  1457. return ret;
  1458. }
  1459. static int ice_fdir_is_tunnel(enum ice_fdir_tunnel_type ttype)
  1460. {
  1461. return (ttype == ICE_FDIR_TUNNEL_TYPE_GRE_INNER ||
  1462. ttype == ICE_FDIR_TUNNEL_TYPE_GTPU_INNER ||
  1463. ttype == ICE_FDIR_TUNNEL_TYPE_GTPU_EH_INNER ||
  1464. ttype == ICE_FDIR_TUNNEL_TYPE_GTPOGRE_INNER ||
  1465. ttype == ICE_FDIR_TUNNEL_TYPE_ECPRI ||
  1466. ttype == ICE_FDIR_TUNNEL_TYPE_L2TPV2_INNER);
  1467. }
  1468. /**
  1469. * ice_vc_add_fdir_fltr_post
  1470. * @vf: pointer to the VF structure
  1471. * @ctx: FDIR context info for post processing
  1472. * @status: virtchnl FDIR program status
  1473. * @success: true implies success, false implies failure
  1474. *
  1475. * Post process for flow director add command. If success, then do post process
  1476. * and send back success msg by virtchnl. Otherwise, do context reversion and
  1477. * send back failure msg by virtchnl.
  1478. *
  1479. * Return: 0 on success, and other on error.
  1480. */
  1481. static int
  1482. ice_vc_add_fdir_fltr_post(struct ice_vf *vf, struct ice_vf_fdir_ctx *ctx,
  1483. enum virtchnl_fdir_prgm_status status,
  1484. bool success)
  1485. {
  1486. struct virtchnl_fdir_fltr_conf *conf = ctx->conf;
  1487. struct device *dev = ice_pf_to_dev(vf->pf);
  1488. enum virtchnl_status_code v_ret;
  1489. struct virtchnl_fdir_add *resp;
  1490. int ret, len, is_tun;
  1491. v_ret = VIRTCHNL_STATUS_SUCCESS;
  1492. len = sizeof(*resp);
  1493. resp = kzalloc(len, GFP_KERNEL);
  1494. if (!resp) {
  1495. len = 0;
  1496. v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
  1497. dev_dbg(dev, "VF %d: Alloc resp buf fail", vf->vf_id);
  1498. goto err_exit;
  1499. }
  1500. if (!success)
  1501. goto err_exit;
  1502. is_tun = 0;
  1503. resp->status = status;
  1504. resp->flow_id = conf->flow_id;
  1505. vf->fdir.fdir_fltr_cnt[conf->input.flow_type][is_tun]++;
  1506. vf->fdir.fdir_fltr_cnt_total++;
  1507. ret = ice_vc_send_msg_to_vf(vf, ctx->v_opcode, v_ret,
  1508. (u8 *)resp, len);
  1509. kfree(resp);
  1510. dev_dbg(dev, "VF %d: flow_id:0x%X, FDIR %s success!\n",
  1511. vf->vf_id, conf->flow_id,
  1512. (ctx->v_opcode == VIRTCHNL_OP_ADD_FDIR_FILTER) ?
  1513. "add" : "del");
  1514. return ret;
  1515. err_exit:
  1516. if (resp)
  1517. resp->status = status;
  1518. ice_vc_fdir_remove_entry(vf, conf, conf->flow_id);
  1519. devm_kfree(dev, conf);
  1520. ret = ice_vc_send_msg_to_vf(vf, ctx->v_opcode, v_ret,
  1521. (u8 *)resp, len);
  1522. kfree(resp);
  1523. return ret;
  1524. }
  1525. /**
  1526. * ice_vc_del_fdir_fltr_post
  1527. * @vf: pointer to the VF structure
  1528. * @ctx: FDIR context info for post processing
  1529. * @status: virtchnl FDIR program status
  1530. * @success: true implies success, false implies failure
  1531. *
  1532. * Post process for flow director del command. If success, then do post process
  1533. * and send back success msg by virtchnl. Otherwise, do context reversion and
  1534. * send back failure msg by virtchnl.
  1535. *
  1536. * Return: 0 on success, and other on error.
  1537. */
  1538. static int
  1539. ice_vc_del_fdir_fltr_post(struct ice_vf *vf, struct ice_vf_fdir_ctx *ctx,
  1540. enum virtchnl_fdir_prgm_status status,
  1541. bool success)
  1542. {
  1543. struct virtchnl_fdir_fltr_conf *conf = ctx->conf;
  1544. struct device *dev = ice_pf_to_dev(vf->pf);
  1545. enum virtchnl_status_code v_ret;
  1546. struct virtchnl_fdir_del *resp;
  1547. int ret, len, is_tun;
  1548. v_ret = VIRTCHNL_STATUS_SUCCESS;
  1549. len = sizeof(*resp);
  1550. resp = kzalloc(len, GFP_KERNEL);
  1551. if (!resp) {
  1552. len = 0;
  1553. v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
  1554. dev_dbg(dev, "VF %d: Alloc resp buf fail", vf->vf_id);
  1555. goto err_exit;
  1556. }
  1557. if (!success)
  1558. goto err_exit;
  1559. is_tun = 0;
  1560. resp->status = status;
  1561. ice_vc_fdir_remove_entry(vf, conf, conf->flow_id);
  1562. vf->fdir.fdir_fltr_cnt[conf->input.flow_type][is_tun]--;
  1563. vf->fdir.fdir_fltr_cnt_total--;
  1564. ret = ice_vc_send_msg_to_vf(vf, ctx->v_opcode, v_ret,
  1565. (u8 *)resp, len);
  1566. kfree(resp);
  1567. dev_dbg(dev, "VF %d: flow_id:0x%X, FDIR %s success!\n",
  1568. vf->vf_id, conf->flow_id,
  1569. (ctx->v_opcode == VIRTCHNL_OP_ADD_FDIR_FILTER) ?
  1570. "add" : "del");
  1571. devm_kfree(dev, conf);
  1572. return ret;
  1573. err_exit:
  1574. if (resp)
  1575. resp->status = status;
  1576. if (success)
  1577. devm_kfree(dev, conf);
  1578. ret = ice_vc_send_msg_to_vf(vf, ctx->v_opcode, v_ret,
  1579. (u8 *)resp, len);
  1580. kfree(resp);
  1581. return ret;
  1582. }
  1583. /**
  1584. * ice_flush_fdir_ctx
  1585. * @pf: pointer to the PF structure
  1586. *
  1587. * Flush all the pending event on ctx_done list and process them.
  1588. */
  1589. void ice_flush_fdir_ctx(struct ice_pf *pf)
  1590. {
  1591. struct ice_vf *vf;
  1592. unsigned int bkt;
  1593. if (!test_and_clear_bit(ICE_FD_VF_FLUSH_CTX, pf->state))
  1594. return;
  1595. mutex_lock(&pf->vfs.table_lock);
  1596. ice_for_each_vf(pf, bkt, vf) {
  1597. struct device *dev = ice_pf_to_dev(pf);
  1598. enum virtchnl_fdir_prgm_status status;
  1599. struct ice_vf_fdir_ctx *ctx;
  1600. unsigned long flags;
  1601. int ret;
  1602. if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states))
  1603. continue;
  1604. if (vf->ctrl_vsi_idx == ICE_NO_VSI)
  1605. continue;
  1606. ctx = &vf->fdir.ctx_done;
  1607. spin_lock_irqsave(&vf->fdir.ctx_lock, flags);
  1608. if (!(ctx->flags & ICE_VF_FDIR_CTX_VALID)) {
  1609. spin_unlock_irqrestore(&vf->fdir.ctx_lock, flags);
  1610. continue;
  1611. }
  1612. spin_unlock_irqrestore(&vf->fdir.ctx_lock, flags);
  1613. WARN_ON(ctx->stat == ICE_FDIR_CTX_READY);
  1614. if (ctx->stat == ICE_FDIR_CTX_TIMEOUT) {
  1615. status = VIRTCHNL_FDIR_FAILURE_RULE_TIMEOUT;
  1616. dev_err(dev, "VF %d: ctrl_vsi irq timeout\n",
  1617. vf->vf_id);
  1618. goto err_exit;
  1619. }
  1620. ret = ice_vf_verify_rx_desc(vf, ctx, &status);
  1621. if (ret)
  1622. goto err_exit;
  1623. if (ctx->v_opcode == VIRTCHNL_OP_ADD_FDIR_FILTER)
  1624. ice_vc_add_fdir_fltr_post(vf, ctx, status, true);
  1625. else if (ctx->v_opcode == VIRTCHNL_OP_DEL_FDIR_FILTER)
  1626. ice_vc_del_fdir_fltr_post(vf, ctx, status, true);
  1627. else
  1628. dev_err(dev, "VF %d: Unsupported opcode\n", vf->vf_id);
  1629. spin_lock_irqsave(&vf->fdir.ctx_lock, flags);
  1630. ctx->flags &= ~ICE_VF_FDIR_CTX_VALID;
  1631. spin_unlock_irqrestore(&vf->fdir.ctx_lock, flags);
  1632. continue;
  1633. err_exit:
  1634. if (ctx->v_opcode == VIRTCHNL_OP_ADD_FDIR_FILTER)
  1635. ice_vc_add_fdir_fltr_post(vf, ctx, status, false);
  1636. else if (ctx->v_opcode == VIRTCHNL_OP_DEL_FDIR_FILTER)
  1637. ice_vc_del_fdir_fltr_post(vf, ctx, status, false);
  1638. else
  1639. dev_err(dev, "VF %d: Unsupported opcode\n", vf->vf_id);
  1640. spin_lock_irqsave(&vf->fdir.ctx_lock, flags);
  1641. ctx->flags &= ~ICE_VF_FDIR_CTX_VALID;
  1642. spin_unlock_irqrestore(&vf->fdir.ctx_lock, flags);
  1643. }
  1644. mutex_unlock(&pf->vfs.table_lock);
  1645. }
  1646. /**
  1647. * ice_vc_fdir_set_irq_ctx - set FDIR context info for later IRQ handler
  1648. * @vf: pointer to the VF structure
  1649. * @conf: FDIR configuration for each filter
  1650. * @v_opcode: virtual channel operation code
  1651. *
  1652. * Return: 0 on success, and other on error.
  1653. */
  1654. static int
  1655. ice_vc_fdir_set_irq_ctx(struct ice_vf *vf, struct virtchnl_fdir_fltr_conf *conf,
  1656. enum virtchnl_ops v_opcode)
  1657. {
  1658. struct device *dev = ice_pf_to_dev(vf->pf);
  1659. struct ice_vf_fdir_ctx *ctx;
  1660. unsigned long flags;
  1661. ctx = &vf->fdir.ctx_irq;
  1662. spin_lock_irqsave(&vf->fdir.ctx_lock, flags);
  1663. if ((vf->fdir.ctx_irq.flags & ICE_VF_FDIR_CTX_VALID) ||
  1664. (vf->fdir.ctx_done.flags & ICE_VF_FDIR_CTX_VALID)) {
  1665. spin_unlock_irqrestore(&vf->fdir.ctx_lock, flags);
  1666. dev_dbg(dev, "VF %d: Last request is still in progress\n",
  1667. vf->vf_id);
  1668. return -EBUSY;
  1669. }
  1670. ctx->flags |= ICE_VF_FDIR_CTX_VALID;
  1671. spin_unlock_irqrestore(&vf->fdir.ctx_lock, flags);
  1672. ctx->conf = conf;
  1673. ctx->v_opcode = v_opcode;
  1674. ctx->stat = ICE_FDIR_CTX_READY;
  1675. timer_setup(&ctx->rx_tmr, ice_vf_fdir_timer, 0);
  1676. mod_timer(&ctx->rx_tmr, round_jiffies(msecs_to_jiffies(10) + jiffies));
  1677. return 0;
  1678. }
  1679. /**
  1680. * ice_vc_fdir_clear_irq_ctx - clear FDIR context info for IRQ handler
  1681. * @vf: pointer to the VF structure
  1682. *
  1683. * Return: 0 on success, and other on error.
  1684. */
  1685. static void ice_vc_fdir_clear_irq_ctx(struct ice_vf *vf)
  1686. {
  1687. struct ice_vf_fdir_ctx *ctx = &vf->fdir.ctx_irq;
  1688. unsigned long flags;
  1689. del_timer(&ctx->rx_tmr);
  1690. spin_lock_irqsave(&vf->fdir.ctx_lock, flags);
  1691. ctx->flags &= ~ICE_VF_FDIR_CTX_VALID;
  1692. spin_unlock_irqrestore(&vf->fdir.ctx_lock, flags);
  1693. }
  1694. /**
  1695. * ice_vc_parser_fv_check_diff - check two parsed FDIR profile fv context
  1696. * @fv_a: struct of parsed FDIR profile field vector
  1697. * @fv_b: struct of parsed FDIR profile field vector
  1698. *
  1699. * Check if the two parsed FDIR profile field vector context are different,
  1700. * including proto_id, offset and mask.
  1701. *
  1702. * Return: true on different, false on otherwise.
  1703. */
  1704. static bool ice_vc_parser_fv_check_diff(struct ice_parser_fv *fv_a,
  1705. struct ice_parser_fv *fv_b)
  1706. {
  1707. return (fv_a->proto_id != fv_b->proto_id ||
  1708. fv_a->offset != fv_b->offset ||
  1709. fv_a->msk != fv_b->msk);
  1710. }
  1711. /**
  1712. * ice_vc_parser_fv_save - save parsed FDIR profile fv context
  1713. * @fv: struct of parsed FDIR profile field vector
  1714. * @fv_src: parsed FDIR profile field vector context to save
  1715. *
  1716. * Save the parsed FDIR profile field vector context, including proto_id,
  1717. * offset and mask.
  1718. *
  1719. * Return: Void.
  1720. */
  1721. static void ice_vc_parser_fv_save(struct ice_parser_fv *fv,
  1722. struct ice_parser_fv *fv_src)
  1723. {
  1724. fv->proto_id = fv_src->proto_id;
  1725. fv->offset = fv_src->offset;
  1726. fv->msk = fv_src->msk;
  1727. fv->spec = 0;
  1728. }
  1729. /**
  1730. * ice_vc_add_fdir_raw - add a raw FDIR filter for VF
  1731. * @vf: pointer to the VF info
  1732. * @conf: FDIR configuration for each filter
  1733. * @v_ret: the final VIRTCHNL code
  1734. * @stat: pointer to the VIRTCHNL_OP_ADD_FDIR_FILTER
  1735. * @len: length of the stat
  1736. *
  1737. * Return: 0 on success or negative errno on failure.
  1738. */
  1739. static int
  1740. ice_vc_add_fdir_raw(struct ice_vf *vf,
  1741. struct virtchnl_fdir_fltr_conf *conf,
  1742. enum virtchnl_status_code *v_ret,
  1743. struct virtchnl_fdir_add *stat, int len)
  1744. {
  1745. struct ice_vsi *vf_vsi, *ctrl_vsi;
  1746. struct ice_fdir_prof_info *pi;
  1747. struct ice_pf *pf = vf->pf;
  1748. int ret, ptg, id, i;
  1749. struct device *dev;
  1750. struct ice_hw *hw;
  1751. bool fv_found;
  1752. dev = ice_pf_to_dev(pf);
  1753. hw = &pf->hw;
  1754. *v_ret = VIRTCHNL_STATUS_ERR_PARAM;
  1755. stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
  1756. id = find_first_bit(conf->prof->ptypes, ICE_FLOW_PTYPE_MAX);
  1757. ptg = hw->blk[ICE_BLK_FD].xlt1.t[id];
  1758. vf_vsi = ice_get_vf_vsi(vf);
  1759. if (!vf_vsi) {
  1760. dev_err(dev, "Can not get FDIR vf_vsi for VF %d\n", vf->vf_id);
  1761. return -ENODEV;
  1762. }
  1763. ctrl_vsi = pf->vsi[vf->ctrl_vsi_idx];
  1764. if (!ctrl_vsi) {
  1765. dev_err(dev, "Can not get FDIR ctrl_vsi for VF %d\n",
  1766. vf->vf_id);
  1767. return -ENODEV;
  1768. }
  1769. fv_found = false;
  1770. /* Check if profile info already exists, then update the counter */
  1771. pi = &vf->fdir_prof_info[ptg];
  1772. if (pi->fdir_active_cnt != 0) {
  1773. for (i = 0; i < ICE_MAX_FV_WORDS; i++)
  1774. if (ice_vc_parser_fv_check_diff(&pi->prof.fv[i],
  1775. &conf->prof->fv[i]))
  1776. break;
  1777. if (i == ICE_MAX_FV_WORDS) {
  1778. fv_found = true;
  1779. pi->fdir_active_cnt++;
  1780. }
  1781. }
  1782. /* HW profile setting is only required for the first time */
  1783. if (!fv_found) {
  1784. ret = ice_flow_set_parser_prof(hw, vf_vsi->idx,
  1785. ctrl_vsi->idx, conf->prof,
  1786. ICE_BLK_FD);
  1787. if (ret) {
  1788. *v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
  1789. dev_dbg(dev, "VF %d: insert hw prof failed\n",
  1790. vf->vf_id);
  1791. return ret;
  1792. }
  1793. }
  1794. ret = ice_vc_fdir_insert_entry(vf, conf, &conf->flow_id);
  1795. if (ret) {
  1796. *v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
  1797. dev_dbg(dev, "VF %d: insert FDIR list failed\n",
  1798. vf->vf_id);
  1799. return ret;
  1800. }
  1801. ret = ice_vc_fdir_set_irq_ctx(vf, conf,
  1802. VIRTCHNL_OP_ADD_FDIR_FILTER);
  1803. if (ret) {
  1804. dev_dbg(dev, "VF %d: set FDIR context failed\n",
  1805. vf->vf_id);
  1806. goto err_rem_entry;
  1807. }
  1808. ret = ice_vc_fdir_write_fltr(vf, conf, true, false);
  1809. if (ret) {
  1810. dev_err(dev, "VF %d: adding FDIR raw flow rule failed, ret:%d\n",
  1811. vf->vf_id, ret);
  1812. goto err_clr_irq;
  1813. }
  1814. /* Save parsed profile fv info of the FDIR rule for the first time */
  1815. if (!fv_found) {
  1816. for (i = 0; i < conf->prof->fv_num; i++)
  1817. ice_vc_parser_fv_save(&pi->prof.fv[i],
  1818. &conf->prof->fv[i]);
  1819. pi->prof.fv_num = conf->prof->fv_num;
  1820. pi->fdir_active_cnt = 1;
  1821. }
  1822. return 0;
  1823. err_clr_irq:
  1824. ice_vc_fdir_clear_irq_ctx(vf);
  1825. err_rem_entry:
  1826. ice_vc_fdir_remove_entry(vf, conf, conf->flow_id);
  1827. return ret;
  1828. }
  1829. /**
  1830. * ice_vc_add_fdir_fltr - add a FDIR filter for VF by the msg buffer
  1831. * @vf: pointer to the VF info
  1832. * @msg: pointer to the msg buffer
  1833. *
  1834. * Return: 0 on success, and other on error.
  1835. */
  1836. int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg)
  1837. {
  1838. struct virtchnl_fdir_add *fltr = (struct virtchnl_fdir_add *)msg;
  1839. struct virtchnl_fdir_add *stat = NULL;
  1840. struct virtchnl_fdir_fltr_conf *conf;
  1841. enum virtchnl_status_code v_ret;
  1842. struct ice_vsi *vf_vsi;
  1843. struct device *dev;
  1844. struct ice_pf *pf;
  1845. int is_tun = 0;
  1846. int len = 0;
  1847. int ret;
  1848. pf = vf->pf;
  1849. dev = ice_pf_to_dev(pf);
  1850. vf_vsi = ice_get_vf_vsi(vf);
  1851. if (!vf_vsi) {
  1852. dev_err(dev, "Can not get FDIR vf_vsi for VF %u\n", vf->vf_id);
  1853. v_ret = VIRTCHNL_STATUS_ERR_PARAM;
  1854. goto err_exit;
  1855. }
  1856. #define ICE_VF_MAX_FDIR_FILTERS 128
  1857. if (!ice_fdir_num_avail_fltr(&pf->hw, vf_vsi) ||
  1858. vf->fdir.fdir_fltr_cnt_total >= ICE_VF_MAX_FDIR_FILTERS) {
  1859. v_ret = VIRTCHNL_STATUS_ERR_PARAM;
  1860. dev_err(dev, "Max number of FDIR filters for VF %d is reached\n",
  1861. vf->vf_id);
  1862. goto err_exit;
  1863. }
  1864. ret = ice_vc_fdir_param_check(vf, fltr->vsi_id);
  1865. if (ret) {
  1866. v_ret = VIRTCHNL_STATUS_ERR_PARAM;
  1867. dev_dbg(dev, "Parameter check for VF %d failed\n", vf->vf_id);
  1868. goto err_exit;
  1869. }
  1870. ret = ice_vf_start_ctrl_vsi(vf);
  1871. if (ret && (ret != -EEXIST)) {
  1872. v_ret = VIRTCHNL_STATUS_ERR_PARAM;
  1873. dev_err(dev, "Init FDIR for VF %d failed, ret:%d\n",
  1874. vf->vf_id, ret);
  1875. goto err_exit;
  1876. }
  1877. stat = kzalloc(sizeof(*stat), GFP_KERNEL);
  1878. if (!stat) {
  1879. v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
  1880. dev_dbg(dev, "Alloc stat for VF %d failed\n", vf->vf_id);
  1881. goto err_exit;
  1882. }
  1883. conf = devm_kzalloc(dev, sizeof(*conf), GFP_KERNEL);
  1884. if (!conf) {
  1885. v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
  1886. dev_dbg(dev, "Alloc conf for VF %d failed\n", vf->vf_id);
  1887. goto err_exit;
  1888. }
  1889. len = sizeof(*stat);
  1890. ret = ice_vc_validate_fdir_fltr(vf, fltr, conf);
  1891. if (ret) {
  1892. v_ret = VIRTCHNL_STATUS_ERR_PARAM;
  1893. stat->status = VIRTCHNL_FDIR_FAILURE_RULE_INVALID;
  1894. dev_dbg(dev, "Invalid FDIR filter from VF %d\n", vf->vf_id);
  1895. goto err_free_conf;
  1896. }
  1897. if (fltr->validate_only) {
  1898. v_ret = VIRTCHNL_STATUS_SUCCESS;
  1899. stat->status = VIRTCHNL_FDIR_SUCCESS;
  1900. devm_kfree(dev, conf);
  1901. ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ADD_FDIR_FILTER,
  1902. v_ret, (u8 *)stat, len);
  1903. goto exit;
  1904. }
  1905. /* For raw FDIR filters created by the parser */
  1906. if (conf->parser_ena) {
  1907. ret = ice_vc_add_fdir_raw(vf, conf, &v_ret, stat, len);
  1908. if (ret)
  1909. goto err_free_conf;
  1910. goto exit;
  1911. }
  1912. is_tun = ice_fdir_is_tunnel(conf->ttype);
  1913. ret = ice_vc_fdir_config_input_set(vf, fltr, conf, is_tun);
  1914. if (ret) {
  1915. v_ret = VIRTCHNL_STATUS_SUCCESS;
  1916. stat->status = VIRTCHNL_FDIR_FAILURE_RULE_CONFLICT;
  1917. dev_err(dev, "VF %d: FDIR input set configure failed, ret:%d\n",
  1918. vf->vf_id, ret);
  1919. goto err_free_conf;
  1920. }
  1921. ret = ice_vc_fdir_is_dup_fltr(vf, conf);
  1922. if (ret) {
  1923. v_ret = VIRTCHNL_STATUS_SUCCESS;
  1924. stat->status = VIRTCHNL_FDIR_FAILURE_RULE_EXIST;
  1925. dev_dbg(dev, "VF %d: duplicated FDIR rule detected\n",
  1926. vf->vf_id);
  1927. goto err_free_conf;
  1928. }
  1929. ret = ice_vc_fdir_insert_entry(vf, conf, &conf->flow_id);
  1930. if (ret) {
  1931. v_ret = VIRTCHNL_STATUS_SUCCESS;
  1932. stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
  1933. dev_dbg(dev, "VF %d: insert FDIR list failed\n", vf->vf_id);
  1934. goto err_free_conf;
  1935. }
  1936. ret = ice_vc_fdir_set_irq_ctx(vf, conf, VIRTCHNL_OP_ADD_FDIR_FILTER);
  1937. if (ret) {
  1938. v_ret = VIRTCHNL_STATUS_SUCCESS;
  1939. stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
  1940. dev_dbg(dev, "VF %d: set FDIR context failed\n", vf->vf_id);
  1941. goto err_rem_entry;
  1942. }
  1943. ret = ice_vc_fdir_write_fltr(vf, conf, true, is_tun);
  1944. if (ret) {
  1945. v_ret = VIRTCHNL_STATUS_SUCCESS;
  1946. stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
  1947. dev_err(dev, "VF %d: writing FDIR rule failed, ret:%d\n",
  1948. vf->vf_id, ret);
  1949. goto err_clr_irq;
  1950. }
  1951. exit:
  1952. kfree(stat);
  1953. return ret;
  1954. err_clr_irq:
  1955. ice_vc_fdir_clear_irq_ctx(vf);
  1956. err_rem_entry:
  1957. ice_vc_fdir_remove_entry(vf, conf, conf->flow_id);
  1958. err_free_conf:
  1959. devm_kfree(dev, conf);
  1960. err_exit:
  1961. ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ADD_FDIR_FILTER, v_ret,
  1962. (u8 *)stat, len);
  1963. kfree(stat);
  1964. return ret;
  1965. }
  1966. /**
  1967. * ice_vc_del_fdir_raw - delete a raw FDIR filter for VF
  1968. * @vf: pointer to the VF info
  1969. * @conf: FDIR configuration for each filter
  1970. * @v_ret: the final VIRTCHNL code
  1971. * @stat: pointer to the VIRTCHNL_OP_DEL_FDIR_FILTER
  1972. * @len: length of the stat
  1973. *
  1974. * Return: 0 on success or negative errno on failure.
  1975. */
  1976. static int
  1977. ice_vc_del_fdir_raw(struct ice_vf *vf,
  1978. struct virtchnl_fdir_fltr_conf *conf,
  1979. enum virtchnl_status_code *v_ret,
  1980. struct virtchnl_fdir_del *stat, int len)
  1981. {
  1982. struct ice_vsi *vf_vsi, *ctrl_vsi;
  1983. enum ice_block blk = ICE_BLK_FD;
  1984. struct ice_fdir_prof_info *pi;
  1985. struct ice_pf *pf = vf->pf;
  1986. struct device *dev;
  1987. struct ice_hw *hw;
  1988. unsigned long id;
  1989. u16 vsi_num;
  1990. int ptg;
  1991. int ret;
  1992. dev = ice_pf_to_dev(pf);
  1993. hw = &pf->hw;
  1994. *v_ret = VIRTCHNL_STATUS_ERR_PARAM;
  1995. stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
  1996. id = find_first_bit(conf->prof->ptypes, ICE_FLOW_PTYPE_MAX);
  1997. ptg = hw->blk[ICE_BLK_FD].xlt1.t[id];
  1998. ret = ice_vc_fdir_write_fltr(vf, conf, false, false);
  1999. if (ret) {
  2000. dev_err(dev, "VF %u: deleting FDIR raw flow rule failed: %d\n",
  2001. vf->vf_id, ret);
  2002. return ret;
  2003. }
  2004. vf_vsi = ice_get_vf_vsi(vf);
  2005. if (!vf_vsi) {
  2006. dev_err(dev, "Can not get FDIR vf_vsi for VF %u\n", vf->vf_id);
  2007. return -ENODEV;
  2008. }
  2009. ctrl_vsi = pf->vsi[vf->ctrl_vsi_idx];
  2010. if (!ctrl_vsi) {
  2011. dev_err(dev, "Can not get FDIR ctrl_vsi for VF %u\n",
  2012. vf->vf_id);
  2013. return -ENODEV;
  2014. }
  2015. pi = &vf->fdir_prof_info[ptg];
  2016. if (pi->fdir_active_cnt != 0) {
  2017. pi->fdir_active_cnt--;
  2018. /* Remove the profile id flow if no active FDIR rule left */
  2019. if (!pi->fdir_active_cnt) {
  2020. vsi_num = ice_get_hw_vsi_num(hw, ctrl_vsi->idx);
  2021. ice_rem_prof_id_flow(hw, blk, vsi_num, id);
  2022. vsi_num = ice_get_hw_vsi_num(hw, vf_vsi->idx);
  2023. ice_rem_prof_id_flow(hw, blk, vsi_num, id);
  2024. }
  2025. }
  2026. conf->parser_ena = false;
  2027. return 0;
  2028. }
  2029. /**
  2030. * ice_vc_del_fdir_fltr - delete a FDIR filter for VF by the msg buffer
  2031. * @vf: pointer to the VF info
  2032. * @msg: pointer to the msg buffer
  2033. *
  2034. * Return: 0 on success, and other on error.
  2035. */
  2036. int ice_vc_del_fdir_fltr(struct ice_vf *vf, u8 *msg)
  2037. {
  2038. struct virtchnl_fdir_del *fltr = (struct virtchnl_fdir_del *)msg;
  2039. struct virtchnl_fdir_del *stat = NULL;
  2040. struct virtchnl_fdir_fltr_conf *conf;
  2041. struct ice_vf_fdir *fdir = &vf->fdir;
  2042. enum virtchnl_status_code v_ret;
  2043. struct ice_fdir_fltr *input;
  2044. enum ice_fltr_ptype flow;
  2045. struct device *dev;
  2046. struct ice_pf *pf;
  2047. int is_tun = 0;
  2048. int len = 0;
  2049. int ret;
  2050. pf = vf->pf;
  2051. dev = ice_pf_to_dev(pf);
  2052. ret = ice_vc_fdir_param_check(vf, fltr->vsi_id);
  2053. if (ret) {
  2054. v_ret = VIRTCHNL_STATUS_ERR_PARAM;
  2055. dev_dbg(dev, "Parameter check for VF %d failed\n", vf->vf_id);
  2056. goto err_exit;
  2057. }
  2058. stat = kzalloc(sizeof(*stat), GFP_KERNEL);
  2059. if (!stat) {
  2060. v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
  2061. dev_dbg(dev, "Alloc stat for VF %d failed\n", vf->vf_id);
  2062. goto err_exit;
  2063. }
  2064. len = sizeof(*stat);
  2065. conf = ice_vc_fdir_lookup_entry(vf, fltr->flow_id);
  2066. if (!conf) {
  2067. v_ret = VIRTCHNL_STATUS_SUCCESS;
  2068. stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST;
  2069. dev_dbg(dev, "VF %d: FDIR invalid flow_id:0x%X\n",
  2070. vf->vf_id, fltr->flow_id);
  2071. goto err_exit;
  2072. }
  2073. /* Just return failure when ctrl_vsi idx is invalid */
  2074. if (vf->ctrl_vsi_idx == ICE_NO_VSI) {
  2075. v_ret = VIRTCHNL_STATUS_SUCCESS;
  2076. stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
  2077. dev_err(dev, "Invalid FDIR ctrl_vsi for VF %d\n", vf->vf_id);
  2078. goto err_exit;
  2079. }
  2080. ret = ice_vc_fdir_set_irq_ctx(vf, conf, VIRTCHNL_OP_DEL_FDIR_FILTER);
  2081. if (ret) {
  2082. v_ret = VIRTCHNL_STATUS_SUCCESS;
  2083. stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
  2084. dev_dbg(dev, "VF %d: set FDIR context failed\n", vf->vf_id);
  2085. goto err_exit;
  2086. }
  2087. /* For raw FDIR filters created by the parser */
  2088. if (conf->parser_ena) {
  2089. ret = ice_vc_del_fdir_raw(vf, conf, &v_ret, stat, len);
  2090. if (ret)
  2091. goto err_del_tmr;
  2092. goto exit;
  2093. }
  2094. is_tun = ice_fdir_is_tunnel(conf->ttype);
  2095. ret = ice_vc_fdir_write_fltr(vf, conf, false, is_tun);
  2096. if (ret) {
  2097. v_ret = VIRTCHNL_STATUS_SUCCESS;
  2098. stat->status = VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE;
  2099. dev_err(dev, "VF %d: writing FDIR rule failed, ret:%d\n",
  2100. vf->vf_id, ret);
  2101. goto err_del_tmr;
  2102. }
  2103. /* Remove unused profiles to avoid unexpected behaviors */
  2104. input = &conf->input;
  2105. flow = input->flow_type;
  2106. if (fdir->fdir_fltr_cnt[flow][is_tun] == 1)
  2107. ice_vc_fdir_rem_prof(vf, flow, is_tun);
  2108. exit:
  2109. kfree(stat);
  2110. return ret;
  2111. err_del_tmr:
  2112. ice_vc_fdir_clear_irq_ctx(vf);
  2113. err_exit:
  2114. ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DEL_FDIR_FILTER, v_ret,
  2115. (u8 *)stat, len);
  2116. kfree(stat);
  2117. return ret;
  2118. }
  2119. /**
  2120. * ice_vf_fdir_init - init FDIR resource for VF
  2121. * @vf: pointer to the VF info
  2122. */
  2123. void ice_vf_fdir_init(struct ice_vf *vf)
  2124. {
  2125. struct ice_vf_fdir *fdir = &vf->fdir;
  2126. idr_init(&fdir->fdir_rule_idr);
  2127. INIT_LIST_HEAD(&fdir->fdir_rule_list);
  2128. spin_lock_init(&fdir->ctx_lock);
  2129. fdir->ctx_irq.flags = 0;
  2130. fdir->ctx_done.flags = 0;
  2131. ice_vc_fdir_reset_cnt_all(fdir);
  2132. }
  2133. /**
  2134. * ice_vf_fdir_exit - destroy FDIR resource for VF
  2135. * @vf: pointer to the VF info
  2136. */
  2137. void ice_vf_fdir_exit(struct ice_vf *vf)
  2138. {
  2139. ice_vc_fdir_flush_entry(vf);
  2140. idr_destroy(&vf->fdir.fdir_rule_idr);
  2141. ice_vc_fdir_rem_prof_all(vf);
  2142. ice_vc_fdir_free_prof_all(vf);
  2143. }