* Reconcile kernel and user view of the receive ring. * Same as for the txsync, this routine must be efficient. * The caller guarantees a single invocations, but races against * the rest of the driver should be handled here. * * On call, kring->rhead is the first packet that userspace wants * to keep, and kring->rcur is the wakeup point. * The kernel has previously reported packets up to kr
| 1126 | * of whether or not we received an interrupt. |
| 1127 | */ |
| 1128 | static int |
| 1129 | iflib_netmap_rxsync(struct netmap_kring *kring, int flags) |
| 1130 | { |
| 1131 | struct netmap_adapter *na = kring->na; |
| 1132 | struct netmap_ring *ring = kring->ring; |
| 1133 | if_t ifp = na->ifp; |
| 1134 | uint32_t nm_i; /* index into the netmap ring */ |
| 1135 | uint32_t nic_i; /* index into the NIC ring */ |
| 1136 | u_int n; |
| 1137 | u_int const lim = kring->nkr_num_slots - 1; |
| 1138 | int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; |
| 1139 | int i = 0; |
| 1140 | |
| 1141 | if_ctx_t ctx = ifp->if_softc; |
| 1142 | if_shared_ctx_t sctx = ctx->ifc_sctx; |
| 1143 | if_softc_ctx_t scctx = &ctx->ifc_softc_ctx; |
| 1144 | iflib_rxq_t rxq = &ctx->ifc_rxqs[kring->ring_id]; |
| 1145 | iflib_fl_t fl = &rxq->ifr_fl[0]; |
| 1146 | struct if_rxd_info ri; |
| 1147 | qidx_t *cidxp; |
| 1148 | |
| 1149 | /* |
| 1150 | * netmap only uses free list 0, to avoid out of order consumption |
| 1151 | * of receive buffers |
| 1152 | */ |
| 1153 | |
| 1154 | bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, |
| 1155 | BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); |
| 1156 | |
| 1157 | /* |
| 1158 | * First part: import newly received packets. |
| 1159 | * |
| 1160 | * nm_i is the index of the next free slot in the netmap ring, |
| 1161 | * nic_i is the index of the next received packet in the NIC ring |
| 1162 | * (or in the free list 0 if IFLIB_HAS_RXCQ is set), and they may |
| 1163 | * differ in case if_init() has been called while |
| 1164 | * in netmap mode. For the receive ring we have |
| 1165 | * |
| 1166 | * nic_i = fl->ifl_cidx; |
| 1167 | * nm_i = kring->nr_hwtail (previous) |
| 1168 | * and |
| 1169 | * nm_i == (nic_i + kring->nkr_hwofs) % ring_size |
| 1170 | * |
| 1171 | * fl->ifl_cidx is set to 0 on a ring reinit |
| 1172 | */ |
| 1173 | if (netmap_no_pendintr || force_update) { |
| 1174 | uint32_t hwtail_lim = nm_prev(kring->nr_hwcur, lim); |
| 1175 | bool have_rxcq = sctx->isc_flags & IFLIB_HAS_RXCQ; |
| 1176 | int crclen = iflib_crcstrip ? 0 : 4; |
| 1177 | int error, avail; |
| 1178 | |
| 1179 | /* |
| 1180 | * For the free list consumer index, we use the same |
| 1181 | * logic as in iflib_rxeof(). |
| 1182 | */ |
| 1183 | if (have_rxcq) |
| 1184 | cidxp = &rxq->ifr_cq_cidx; |
| 1185 | else |
nothing calls this directly
no test coverage detected