1135 }
1136
1137 static int
1138 fcoe_crc_verify(fcoe_frame_t *frm)
1139 {
1140 uint32_t crc;
1141 uint8_t *crc_array = FRM2FMI(frm)->fmi_fft->fft_crc;
1142 uint32_t crc_from_frame = ~(crc_array[0] | (crc_array[1] << 8) |
1143 (crc_array[2] << 16) | (crc_array[3] << 24));
1144 CRC32(crc, frm->frm_fc_frame, frm->frm_fc_frame_size, -1U, crc32_table);
1145 return (crc == crc_from_frame ? FCOE_SUCCESS : FCOE_FAILURE);
1146 }
1147
1148 static void
1149 fcoe_worker_frame(void *arg)
1150 {
1151 fcoe_worker_t *w = (fcoe_worker_t *)arg;
1152 fcoe_i_frame_t *fmi;
1153 int ret;
1154
1155 atomic_add_32(&fcoe_nworkers_running, 1);
1156 mutex_enter(&w->worker_lock);
1157 w->worker_flags |= FCOE_WORKER_STARTED | FCOE_WORKER_ACTIVE;
1158 while ((w->worker_flags & FCOE_WORKER_TERMINATE) == 0) {
1159 /*
1160 * loop through the frames
1161 */
1162 while (fmi = list_head(&w->worker_frm_list)) {
1163 list_remove(&w->worker_frm_list, fmi);
1164 mutex_exit(&w->worker_lock);
1165 /*
1166 * do the checksum
1167 */
1168 ret = fcoe_crc_verify(fmi->fmi_frame);
1169 if (ret == FCOE_SUCCESS) {
1170 fmi->fmi_mac->fm_client.ect_rx_frame(
1171 fmi->fmi_frame);
1172 } else {
1173 fcoe_release_frame(fmi->fmi_frame);
1174 }
1175 mutex_enter(&w->worker_lock);
1176 w->worker_ntasks--;
1177 }
1178 w->worker_flags &= ~FCOE_WORKER_ACTIVE;
1179 cv_wait(&w->worker_cv, &w->worker_lock);
1180 w->worker_flags |= FCOE_WORKER_ACTIVE;
1181 }
1182 w->worker_flags &= ~(FCOE_WORKER_STARTED | FCOE_WORKER_ACTIVE);
1183 mutex_exit(&w->worker_lock);
1184 atomic_add_32(&fcoe_nworkers_running, -1);
1185 list_destroy(&w->worker_frm_list);
1186 }
1187
1188 void
1189 fcoe_post_frame(fcoe_frame_t *frm)
1190 {
1191 fcoe_worker_t *w;
1192 uint16_t oxid = FRM_OXID(frm);
1193
1194 w = &fcoe_workers[oxid % fcoe_nworkers_running];
1195 mutex_enter(&w->worker_lock);
1196 list_insert_tail(&w->worker_frm_list, frm->frm_fcoe_private);
1197 w->worker_ntasks++;
1198 if ((w->worker_flags & FCOE_WORKER_ACTIVE) == 0) {
1199 cv_signal(&w->worker_cv);
1200 }
1201 mutex_exit(&w->worker_lock);
1202 }
1203
1204 /*
|
1135 }
1136
1137 static int
1138 fcoe_crc_verify(fcoe_frame_t *frm)
1139 {
1140 uint32_t crc;
1141 uint8_t *crc_array = FRM2FMI(frm)->fmi_fft->fft_crc;
1142 uint32_t crc_from_frame = ~(crc_array[0] | (crc_array[1] << 8) |
1143 (crc_array[2] << 16) | (crc_array[3] << 24));
1144 CRC32(crc, frm->frm_fc_frame, frm->frm_fc_frame_size, -1U, crc32_table);
1145 return (crc == crc_from_frame ? FCOE_SUCCESS : FCOE_FAILURE);
1146 }
1147
1148 static void
1149 fcoe_worker_frame(void *arg)
1150 {
1151 fcoe_worker_t *w = (fcoe_worker_t *)arg;
1152 fcoe_i_frame_t *fmi;
1153 int ret;
1154
1155 atomic_inc_32(&fcoe_nworkers_running);
1156 mutex_enter(&w->worker_lock);
1157 w->worker_flags |= FCOE_WORKER_STARTED | FCOE_WORKER_ACTIVE;
1158 while ((w->worker_flags & FCOE_WORKER_TERMINATE) == 0) {
1159 /*
1160 * loop through the frames
1161 */
1162 while (fmi = list_head(&w->worker_frm_list)) {
1163 list_remove(&w->worker_frm_list, fmi);
1164 mutex_exit(&w->worker_lock);
1165 /*
1166 * do the checksum
1167 */
1168 ret = fcoe_crc_verify(fmi->fmi_frame);
1169 if (ret == FCOE_SUCCESS) {
1170 fmi->fmi_mac->fm_client.ect_rx_frame(
1171 fmi->fmi_frame);
1172 } else {
1173 fcoe_release_frame(fmi->fmi_frame);
1174 }
1175 mutex_enter(&w->worker_lock);
1176 w->worker_ntasks--;
1177 }
1178 w->worker_flags &= ~FCOE_WORKER_ACTIVE;
1179 cv_wait(&w->worker_cv, &w->worker_lock);
1180 w->worker_flags |= FCOE_WORKER_ACTIVE;
1181 }
1182 w->worker_flags &= ~(FCOE_WORKER_STARTED | FCOE_WORKER_ACTIVE);
1183 mutex_exit(&w->worker_lock);
1184 atomic_dec_32(&fcoe_nworkers_running);
1185 list_destroy(&w->worker_frm_list);
1186 }
1187
1188 void
1189 fcoe_post_frame(fcoe_frame_t *frm)
1190 {
1191 fcoe_worker_t *w;
1192 uint16_t oxid = FRM_OXID(frm);
1193
1194 w = &fcoe_workers[oxid % fcoe_nworkers_running];
1195 mutex_enter(&w->worker_lock);
1196 list_insert_tail(&w->worker_frm_list, frm->frm_fcoe_private);
1197 w->worker_ntasks++;
1198 if ((w->worker_flags & FCOE_WORKER_ACTIVE) == 0) {
1199 cv_signal(&w->worker_cv);
1200 }
1201 mutex_exit(&w->worker_lock);
1202 }
1203
1204 /*
|