44 #define OCS_DEBUG_ENABLE(x) (x ? ~0 : 0)
47 #define OCS_DEBUG_MASK \
48 (OCS_DEBUG_ENABLE(1) & OCS_DEBUG_ALWAYS) | \
49 (OCS_DEBUG_ENABLE(0) & OCS_DEBUG_ENABLE_MQ_DUMP) | \
50 (OCS_DEBUG_ENABLE(0) & OCS_DEBUG_ENABLE_CQ_DUMP) | \
51 (OCS_DEBUG_ENABLE(0) & OCS_DEBUG_ENABLE_WQ_DUMP) | \
52 (OCS_DEBUG_ENABLE(0) & OCS_DEBUG_ENABLE_IO_TRACE) | \
53 (OCS_DEBUG_ENABLE(0) & OCS_DEBUG_ENABLE_SM_TRACE) | \
54 (OCS_DEBUG_ENABLE(0) & OCS_DEBUG_ENABLE_SCSI_TGT_TRACE) | \
55 (OCS_DEBUG_ENABLE(0) & OCS_DEBUG_ENABLE_ISNS_LOG)
59 #if defined(OCS_DEBUG_QUEUE_HISTORY)
63 typedef struct ocs_q_hist_wqe_mask_s {
66 } ocs_q_hist_wqe_mask_t;
71 typedef struct ocs_q_hist_cqe_mask_s {
73 uint32_t :Q_HIST_MASK_LEN,
76 } ocs_q_hist_cqe_mask_t;
143 ocs_dump32(uint32_t mask, ocs_os_handle_t os,
const char *label,
void *buf, uint32_t buf_length) {
144 const uint32_t columns = 8;
145 uint32_t word_count = buf_length /
sizeof(uint32_t);
146 uint32_t *wbuf = buf;
158 ocs_log_debug(os,
"%s\n", label);
161 while (word_count > 0) {
162 ocs_snprintf(str, ARRAY_SIZE(str),
"%08X: ", offset);
163 n = (word_count > columns ? columns : word_count);
164 for (i = 0; i < n; i ++) {
165 ocs_snprintf(temp, ARRAY_SIZE(temp),
" %08X", wbuf[i]);
169 ocs_log_debug(os,
"%s\n", str);
172 offset += n *
sizeof(uint32_t);
193 #define MAX_BUF_BYTES 1024
194 #define MAX_BUF_WORDS (MAX_BUF_BYTES/sizeof(uint32_t))
196 void ocs_swap_and_dump32(uint32_t mask, ocs_os_handle_t os,
const char *label,
void *buf, uint32_t buf_length) {
208 for (i=0; i<(buf_length /
sizeof(uint32_t)); i++) {
209 *dst = ocs_be32toh(*src);
214 ocs_dump32(mask, os, label, swapped_buf, buf_length);
218 #if !defined(OCS_EXPORT)
219 #define OCS_EXPORT(...)
222 #if defined(OCS_DEBUG_QUEUE_HISTORY)
225 #define OCS_Q_HIST_WQE_WORD_MASK_DEFAULT (BIT(6) | BIT(7) | BIT(9) | BIT(11))
226 #define OCS_Q_HIST_IWRITE_WQE_WORD_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(6) | BIT(7) | BIT(10) | BIT(11))
227 #define OCS_Q_HIST_ITMF_WQE_WORD_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(7))
228 #define OCS_Q_HIST_INOP_WQE_WORD_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(7))
229 #define OCS_Q_HIST_IREAD_WQE_WORD_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(6) | BIT(7) | BIT(10) | BIT(11))
230 #define OCS_Q_HIST_CXTUPD_WQE_WORD_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(8) | BIT(11))
231 #define OCS_Q_HIST_TSTS_WQE_WORD_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(6) | BIT(7) | BIT(10) | BIT(11))
232 #define OCS_Q_HIST_TDATAIN_WQE_WORD_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(6) | BIT(10) | BIT(11))
233 #define OCS_Q_HIST_TSOS_WQE_WORD_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(11))
234 #define OCS_Q_HIST_DMCMD_WQE_WORD_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(7) | BIT(11))
235 #define OCS_Q_HIST_ISOL_CQE_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
236 #define OCS_Q_HIST_TSOL_CQE_MASK (BIT(1) | BIT(2) | BIT(3))
237 #define OCS_Q_HIST_DDIGEST_CQE_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
238 #define OCS_Q_HIST_CNXINV_CQE_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
239 #define OCS_Q_HIST_CMDINV_CQE_MASK (BIT(2) | BIT(3))
240 #define OCS_Q_HIST_DPDU_CQE_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
241 #define OCS_Q_HIST_DMSG_CQE_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
242 #define OCS_Q_HIST_ASYNC_CQE_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
243 #define OCS_Q_HIST_MQ_CQE_MASK (BIT(0) | BIT(1) | BIT(2))
244 #define OCS_Q_HIST_TX_DIFF_CQE_MASK (BIT(0) | BIT(2) | BIT(3))
247 #define OCS_Q_HIST_ENABLE_Q_INFO 1
248 uint8_t ocs_queue_history_q_info_enabled(
void)
250 return OCS_Q_HIST_ENABLE_Q_INFO;
254 #define OCS_Q_HIST_ENABLE_TIMESTAMPS 0
255 uint8_t ocs_queue_history_timestamp_enabled(
void)
257 return OCS_Q_HIST_ENABLE_TIMESTAMPS;
261 ocs_q_hist_wqe_mask_t ocs_q_hist_wqe_masks[] = {
275 ocs_q_hist_cqe_mask_t ocs_q_hist_cqe_masks[] = {
277 {
SLI_CQENTRY_RQ, OCS_Q_HIST_TYPE_CQE_RQ, OCS_Q_HIST_DPDU_CQE_MASK},
292 for (i = 0; i < ARRAY_SIZE(ocs_q_hist_wqe_masks); i++) {
293 if (ocs_q_hist_wqe_masks[i].type == wqe->
type) {
294 return ocs_q_hist_wqe_masks[i].mask;
298 return OCS_Q_HIST_WQE_WORD_MASK_DEFAULT;
314 if (q_hist->q_hist != NULL) {
316 ocs_log_debug(ocs,
"q_hist not NULL, skipping init\n");
320 q_hist->q_hist = ocs_malloc(ocs,
sizeof(*q_hist->q_hist)*OCS_Q_HIST_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
322 if (q_hist->q_hist == NULL) {
323 ocs_log_err(ocs,
"Could not allocate queue history buffer\n");
325 ocs_lock_init(ocs, &q_hist->q_hist_lock,
"queue history lock[%d]",
ocs_instance(ocs));
328 q_hist->q_hist_index = 0;
342 ocs_t *ocs = q_hist->ocs;
344 if (q_hist->q_hist != NULL) {
345 ocs_free(ocs, q_hist->q_hist,
sizeof(*q_hist->q_hist)*OCS_Q_HIST_SIZE);
346 ocs_lock_free(&q_hist->q_hist_lock);
347 q_hist->q_hist = NULL;
352 ocs_queue_history_add_q_info(ocs_hal_q_hist_t *q_hist, uint32_t qid, uint32_t qindex)
354 if (ocs_queue_history_q_info_enabled()) {
356 q_hist->q_hist[q_hist->q_hist_index] = (qid << 16) | qindex;
357 q_hist->q_hist_index++;
358 q_hist->q_hist_index = q_hist->q_hist_index % OCS_Q_HIST_SIZE;
363 ocs_queue_history_add_timestamp(ocs_hal_q_hist_t *q_hist)
365 if (ocs_queue_history_timestamp_enabled()) {
368 tsc_value = ocs_get_tsc();
369 q_hist->q_hist[q_hist->q_hist_index] = ((tsc_value >> 32 ) & 0xFFFFFFFF);
370 q_hist->q_hist_index++;
371 q_hist->q_hist_index = q_hist->q_hist_index % OCS_Q_HIST_SIZE;
372 q_hist->q_hist[q_hist->q_hist_index] = (tsc_value & 0xFFFFFFFF);
373 q_hist->q_hist_index++;
374 q_hist->q_hist_index = q_hist->q_hist_index % OCS_Q_HIST_SIZE;
393 ocs_q_hist_ftr_t ftr;
396 if (q_hist->q_hist == NULL) {
402 ftr.s.type = OCS_Q_HIST_TYPE_WQE;
403 ocs_lock(&q_hist->q_hist_lock);
405 for (i = ((
sizeof(wqe_word_mask)*8) - 1); i >= 0; i--){
406 if ((wqe_word_mask >> i) & 1) {
407 q_hist->q_hist[q_hist->q_hist_index] = entryw[i];
408 q_hist->q_hist_index++;
409 q_hist->q_hist_index = q_hist->q_hist_index % OCS_Q_HIST_SIZE;
413 ocs_queue_history_add_q_info(q_hist, qid, qindex);
414 ocs_queue_history_add_timestamp(q_hist);
418 ftr.s.mask = wqe_word_mask;
419 q_hist->q_hist[q_hist->q_hist_index] = ftr.word;
420 q_hist->q_hist_index++;
421 q_hist->q_hist_index = q_hist->q_hist_index % OCS_Q_HIST_SIZE;
424 ocs_unlock(&q_hist->q_hist_lock);
441 ocs_q_hist_ftr_t ftr;
444 if (q_hist->q_hist == NULL) {
450 ftr.s.type = OCS_Q_HIST_TYPE_MISC;
451 ocs_lock(&q_hist->q_hist_lock);
453 for (i = num_words-1; i >= 0; i--) {
454 q_hist->q_hist[q_hist->q_hist_index] = entryw[i];
455 q_hist->q_hist_index++;
456 q_hist->q_hist_index = q_hist->q_hist_index % OCS_Q_HIST_SIZE;
460 ocs_queue_history_add_timestamp(q_hist);
465 q_hist->q_hist[q_hist->q_hist_index] = ftr.word;
466 q_hist->q_hist_index++;
467 q_hist->q_hist_index = q_hist->q_hist_index % OCS_Q_HIST_SIZE;
470 ocs_unlock(&q_hist->q_hist_lock);
487 ocs_queue_history_cqe(ocs_hal_q_hist_t *q_hist, uint8_t ctype, uint32_t *entryw, uint32_t qid, uint32_t qindex)
491 uint32_t cqe_word_mask = 0;
492 ocs_q_hist_ftr_t ftr;
494 if (q_hist->q_hist == NULL) {
500 for (j = 0; j < ARRAY_SIZE(ocs_q_hist_cqe_masks); j++) {
501 if (ocs_q_hist_cqe_masks[j].ctype == ctype) {
502 ftr.s.type = ocs_q_hist_cqe_masks[j].type;
503 cqe_word_mask = ocs_q_hist_cqe_masks[j].mask;
506 ocs_lock(&q_hist->q_hist_lock);
508 for (i = ((
sizeof(cqe_word_mask)*8) - 1); i >= 0; i--){
509 if ((cqe_word_mask >> i) & 1) {
510 q_hist->q_hist[q_hist->q_hist_index] = entryw[i];
511 q_hist->q_hist_index++;
512 q_hist->q_hist_index = q_hist->q_hist_index % OCS_Q_HIST_SIZE;
515 ocs_queue_history_add_q_info(q_hist, qid, qindex);
516 ocs_queue_history_add_timestamp(q_hist);
520 ftr.s.mask = cqe_word_mask;
521 q_hist->q_hist[q_hist->q_hist_index] = ftr.word;
522 q_hist->q_hist_index++;
523 q_hist->q_hist_index = q_hist->q_hist_index % OCS_Q_HIST_SIZE;
526 ocs_unlock(&q_hist->q_hist_lock);
535 ocs_queue_history_prev_index(uint32_t index)
538 return OCS_Q_HIST_SIZE - 1;
544 #endif // OCS_DEBUG_QUEUE_HISTORY
#define ocs_queue_history_misc(...)
#define SLI4_WQE_INI_READ
#define ocs_queue_history_wq(...)
#define ocs_queue_history_init(...)
#define ocs_queue_history_cqe(...)
#define SLI4_WQE_UNASSISTED
#define SLI4_WQE_TGT_DATAIN
void ocs_dump32(uint32_t mask, ocs_os_handle_t os, const char *label, void *buf, uint32_t buf_length)
Dump 32 bit hex/ascii data.
void ocs_swap_and_dump32(uint32_t mask, ocs_os_handle_t os, const char *label, void *buf, uint32_t buf_length)
#define ocs_queue_history_free(...)
uint32_t ocs_instance(void *os)
Return the instance index of an opaque ocs structure.
#define SLI4_WQE_INI_WRITE
WQE used to transmit a PDU without any modificiation (TGT_DM_CMD)
#define MAX_BUF_BYTES
Dump 32 bit hex/ascii data after first swapping endianess.
void ocs_debug_enable(uint32_t mask)
enable debug options
int ocs_debug_is_enabled(uint32_t mask)
return true if debug bits are enabled
static uint32_t ocs_debug_mask
#define SLI4_WQE_CONTEXT_UPDATE
void ocs_debug_disable(uint32_t mask)
disable debug options