FreeBSD/sys/dev/qlxgb/qla_isr.c
/*
 * Name: qla_isr
 * Function: Main Interrupt Service Routine
 */
qla_isr
Function: Main Interrupt Service Routine
qla_isr Function : Main Interrupt Service Routine
static uint32_t
qla_rcv_isr(qla_host_t *ha, uint32_t sds_idx, uint32_t count)
{
	device_t dev;
	qla_hw_t *hw;
	uint32_t comp_idx, desc_count;
	q80_stat_desc_t *sdesc;
	struct lro_ctrl *lro;
	uint32_t ret = 0;
	dev = ha->pci_dev;
	hw = &ha->hw;
	hw->sds[sds_idx].rcv_active = 1;
	if (ha->flags.stop_rcv) {
		hw->sds[sds_idx].rcv_active = 0;
		return 0;
	}
	QL_DPRINT2((dev, "%s: [%d]enter\n", __func__, sds_idx));
	comp_idx = hw->sds[sds_idx].sdsr_next;
	lro = &hw->sds[sds_idx].lro;
	while (count--) {
		sdesc = (q80_stat_desc_t *)
				&hw->sds[sds_idx].sds_ring_base[comp_idx];
		if (Q8_STAT_DESC_OWNER((sdesc->data[0])) !=
			Q8_STAT_DESC_OWNER_HOST) {
			QL_DPRINT2((dev, "%s:  data %p sdsr_next 0x%08x\n",
				__func__, (void *)sdesc->data[0], comp_idx));
			break;
		}
		desc_count = Q8_STAT_DESC_COUNT((sdesc->data[0]));
		switch (Q8_STAT_DESC_OPCODE((sdesc->data[0]))) {
		case Q8_STAT_DESC_OPCODE_RCV_PKT:
		case Q8_STAT_DESC_OPCODE_SYN_OFFLOAD:
			qla_rx_intr(ha, (sdesc->data[0]), sds_idx, lro);
			break;
		default:
			device_printf(dev, "%s: default 0x%llx!\n", __func__,
					(long long unsigned int)sdesc->data[0]);
			break;
		}
		while (desc_count--) {
			sdesc->data[0] =
				Q8_STAT_DESC_SET_OWNER(Q8_STAT_DESC_OWNER_FW);
			comp_idx = (comp_idx + 1) & (NUM_STATUS_DESCRIPTORS-1);
			sdesc = (q80_stat_desc_t *)
				&hw->sds[sds_idx].sds_ring_base[comp_idx];
		}
	}
	tcp_lro_flush_all(lro);
	if (hw->sds[sds_idx].sdsr_next != comp_idx) {
		QL_UPDATE_SDS_CONSUMER_INDEX(ha, sds_idx, comp_idx);
	}
	hw->sds[sds_idx].sdsr_next = comp_idx;
	sdesc = (q80_stat_desc_t *)&hw->sds[sds_idx].sds_ring_base[comp_idx];
	if ((sds_idx == 0) && (Q8_STAT_DESC_OWNER((sdesc->data[0])) ==
					Q8_STAT_DESC_OWNER_HOST)) {
		ret = -1;
	}
	hw->sds[sds_idx].rcv_active = 0;
	return (ret);
}
static uint32_t qla_rcv_isr ( qla_host_t * ha , uint32_t sds_idx , uint32_t count ) { device_t dev ; qla_hw_t * hw ; uint32_t comp_idx , desc_count ; q80_stat_desc_t * sdesc ; struct lro_ctrl * lro ; uint32_t ret = 0 ; dev = ha -> pci_dev ; hw = & ha -> hw ; hw -> sds [ sds_idx ] . rcv_active = 1 ; if ( ha -> flags . stop_rcv ) { hw -> sds [ sds_idx ] . rcv_active = 0 ; return 0 ; } QL_DPRINT2 ( ( dev , " \n " , __func__ , sds_idx ) ) ; comp_idx = hw -> sds [ sds_idx ] . sdsr_next ; lro = & hw -> sds [ sds_idx ] . lro ; while ( count -- ) { sdesc = ( q80_stat_desc_t * ) & hw -> sds [ sds_idx ] . sds_ring_base [ comp_idx ] ; if ( Q8_STAT_DESC_OWNER ( ( sdesc -> data [ 0 ] ) ) != Q8_STAT_DESC_OWNER_HOST ) { QL_DPRINT2 ( ( dev , " \n " , __func__ , ( void * ) sdesc -> data [ 0 ] , comp_idx ) ) ; break ; } desc_count = Q8_STAT_DESC_COUNT ( ( sdesc -> data [ 0 ] ) ) ; switch ( Q8_STAT_DESC_OPCODE ( ( sdesc -> data [ 0 ] ) ) ) { case Q8_STAT_DESC_OPCODE_RCV_PKT : case Q8_STAT_DESC_OPCODE_SYN_OFFLOAD : qla_rx_intr ( ha , ( sdesc -> data [ 0 ] ) , sds_idx , lro ) ; break ; default : device_printf ( dev , " \n " , __func__ , ( long long unsigned int ) sdesc -> data [ 0 ] ) ; break ; } while ( desc_count -- ) { sdesc -> data [ 0 ] = Q8_STAT_DESC_SET_OWNER ( Q8_STAT_DESC_OWNER_FW ) ; comp_idx = ( comp_idx + 1 ) & ( NUM_STATUS_DESCRIPTORS - 1 ) ; sdesc = ( q80_stat_desc_t * ) & hw -> sds [ sds_idx ] . sds_ring_base [ comp_idx ] ; } } tcp_lro_flush_all ( lro ) ; if ( hw -> sds [ sds_idx ] . sdsr_next != comp_idx ) { QL_UPDATE_SDS_CONSUMER_INDEX ( ha , sds_idx , comp_idx ) ; } hw -> sds [ sds_idx ] . sdsr_next = comp_idx ; sdesc = ( q80_stat_desc_t * ) & hw -> sds [ sds_idx ] . sds_ring_base [ comp_idx ] ; if ( ( sds_idx == 0 ) && ( Q8_STAT_DESC_OWNER ( ( sdesc -> data [ 0 ] ) ) == Q8_STAT_DESC_OWNER_HOST ) ) { ret = -1 ; } hw -> sds [ sds_idx ] . rcv_active = 0 ; return ( ret ) ; }
Name: qla_isr
 Function: Main Interrupt Service Routine
Name : qla_isr Function : Main Interrupt Service Routine
/*
	 * receive interrupts
	 */