Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac731ab6 authored by Sreenivasa Honnur's avatar Sreenivasa Honnur Committed by Jeff Garzik
Browse files

S2io: Move all the transmit completions to a single msi-x (alarm) vector



- Move all the transmit completions to a single msi-x (alarm) vector.
- Enable the continuous timer interrupt for only one transmit fifo.

Signed-off-by: default avatarSantosh Rastapur <santosh.rastapur@neterion.com>
Signed-off-by: default avatarRamkrishna Vepa <ram.vepa@neterion.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent 25c16fff
Loading
Loading
Loading
Loading
+102 −68
Original line number Original line Diff line number Diff line
@@ -1220,15 +1220,33 @@ static int init_tti(struct s2io_nic *nic, int link)
				TTI_DATA1_MEM_TX_URNG_B(0x10) |
				TTI_DATA1_MEM_TX_URNG_B(0x10) |
				TTI_DATA1_MEM_TX_URNG_C(0x30) |
				TTI_DATA1_MEM_TX_URNG_C(0x30) |
				TTI_DATA1_MEM_TX_TIMER_AC_EN;
				TTI_DATA1_MEM_TX_TIMER_AC_EN;

		if (i == 0)
			if (use_continuous_tx_intrs && (link == LINK_UP))
			if (use_continuous_tx_intrs && (link == LINK_UP))
				val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN;
				val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN;
		writeq(val64, &bar0->tti_data1_mem);
		writeq(val64, &bar0->tti_data1_mem);


		if (nic->config.intr_type == MSI_X) {
			val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) |
				TTI_DATA2_MEM_TX_UFC_B(0x100) |
				TTI_DATA2_MEM_TX_UFC_C(0x200) |
				TTI_DATA2_MEM_TX_UFC_D(0x300);
		} else {
			if ((nic->config.tx_steering_type ==
				TX_DEFAULT_STEERING) &&
				(config->tx_fifo_num > 1) &&
				(i >= nic->udp_fifo_idx) &&
				(i < (nic->udp_fifo_idx +
				nic->total_udp_fifos)))
				val64 = TTI_DATA2_MEM_TX_UFC_A(0x50) |
					TTI_DATA2_MEM_TX_UFC_B(0x80) |
					TTI_DATA2_MEM_TX_UFC_C(0x100) |
					TTI_DATA2_MEM_TX_UFC_D(0x120);
			else
				val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) |
				val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) |
					TTI_DATA2_MEM_TX_UFC_B(0x20) |
					TTI_DATA2_MEM_TX_UFC_B(0x20) |
					TTI_DATA2_MEM_TX_UFC_C(0x40) |
					TTI_DATA2_MEM_TX_UFC_C(0x40) |
					TTI_DATA2_MEM_TX_UFC_D(0x80);
					TTI_DATA2_MEM_TX_UFC_D(0x80);
		}


		writeq(val64, &bar0->tti_data2_mem);
		writeq(val64, &bar0->tti_data2_mem);


@@ -3771,7 +3789,7 @@ static void store_xmsi_data(struct s2io_nic *nic)
static int s2io_enable_msi_x(struct s2io_nic *nic)
static int s2io_enable_msi_x(struct s2io_nic *nic)
{
{
	struct XENA_dev_config __iomem *bar0 = nic->bar0;
	struct XENA_dev_config __iomem *bar0 = nic->bar0;
	u64 tx_mat, rx_mat;
	u64 rx_mat;
	u16 msi_control; /* Temp variable */
	u16 msi_control; /* Temp variable */
	int ret, i, j, msix_indx = 1;
	int ret, i, j, msix_indx = 1;


@@ -3801,22 +3819,19 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
	 nic->mac_control.stats_info->sw_stat.mem_allocated
	 nic->mac_control.stats_info->sw_stat.mem_allocated
		+= (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
		+= (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));


	for (i=0; i< MAX_REQUESTED_MSI_X; i++) {
	nic->entries[0].entry = 0;
	nic->s2io_entries[0].entry = 0;
	nic->s2io_entries[0].in_use = MSIX_FLG;
	nic->s2io_entries[0].type = MSIX_ALARM_TYPE;
	nic->s2io_entries[0].arg = &nic->mac_control.fifos;

	for (i = 1; i < MAX_REQUESTED_MSI_X; i++) {
		nic->entries[i].entry = i;
		nic->entries[i].entry = i;
		nic->s2io_entries[i].entry = i;
		nic->s2io_entries[i].entry = i;
		nic->s2io_entries[i].arg = NULL;
		nic->s2io_entries[i].arg = NULL;
		nic->s2io_entries[i].in_use = 0;
		nic->s2io_entries[i].in_use = 0;
	}
	}


	tx_mat = readq(&bar0->tx_mat0_n[0]);
	for (i=0; i<nic->config.tx_fifo_num; i++, msix_indx++) {
		tx_mat |= TX_MAT_SET(i, msix_indx);
		nic->s2io_entries[msix_indx].arg = &nic->mac_control.fifos[i];
		nic->s2io_entries[msix_indx].type = MSIX_FIFO_TYPE;
		nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
	}
	writeq(tx_mat, &bar0->tx_mat0_n[0]);

	rx_mat = readq(&bar0->rx_mat);
	rx_mat = readq(&bar0->rx_mat);
	for (j = 0; j < nic->config.rx_ring_num; j++, msix_indx++) {
	for (j = 0; j < nic->config.rx_ring_num; j++, msix_indx++) {
		rx_mat |= RX_MAT_SET(j, msix_indx);
		rx_mat |= RX_MAT_SET(j, msix_indx);
@@ -4353,15 +4368,35 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id)


static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id)
static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id)
{
{
	struct fifo_info *fifo = (struct fifo_info *)dev_id;
	int i;
	struct s2io_nic *sp = fifo->nic;
	struct fifo_info *fifos = (struct fifo_info *)dev_id;
	struct s2io_nic *sp = fifos->nic;
	struct XENA_dev_config __iomem *bar0 = sp->bar0;
	struct config_param *config  = &sp->config;
	u64 reason;


	if (!is_s2io_card_up(sp))
	if (unlikely(!is_s2io_card_up(sp)))
		return IRQ_NONE;

	reason = readq(&bar0->general_int_status);
	if (unlikely(reason == S2IO_MINUS_ONE))
		/* Nothing much can be done. Get out */
		return IRQ_HANDLED;
		return IRQ_HANDLED;


	tx_intr_handler(fifo);
	writeq(S2IO_MINUS_ONE, &bar0->general_int_mask);

	if (reason & GEN_INTR_TXTRAFFIC)
		writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);

	for (i = 0; i < config->tx_fifo_num; i++)
		tx_intr_handler(&fifos[i]);

	writeq(sp->general_int_mask, &bar0->general_int_mask);
	readl(&bar0->general_int_status);

	return IRQ_HANDLED;
	return IRQ_HANDLED;
}
}

static void s2io_txpic_intr_handle(struct s2io_nic *sp)
static void s2io_txpic_intr_handle(struct s2io_nic *sp)
{
{
	struct XENA_dev_config __iomem *bar0 = sp->bar0;
	struct XENA_dev_config __iomem *bar0 = sp->bar0;
@@ -6985,62 +7020,61 @@ static int s2io_add_isr(struct s2io_nic * sp)


	/* After proper initialization of H/W, register ISR */
	/* After proper initialization of H/W, register ISR */
	if (sp->config.intr_type == MSI_X) {
	if (sp->config.intr_type == MSI_X) {
		int i, msix_tx_cnt=0,msix_rx_cnt=0;
		int i, msix_rx_cnt = 0;


		for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) {
		for (i = 0; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) {
			if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) {
			if (sp->s2io_entries[i].type ==
				sprintf(sp->desc[i], "%s:MSI-X-%d-TX",
					MSIX_RING_TYPE) {
					sprintf(sp->desc[i], "%s:MSI-X-%d-RX",
						dev->name, i);
						dev->name, i);
					err = request_irq(sp->entries[i].vector,
					err = request_irq(sp->entries[i].vector,
					  s2io_msix_fifo_handle, 0, sp->desc[i],
						s2io_msix_ring_handle, 0,
						sp->desc[i],
						sp->s2io_entries[i].arg);
						sp->s2io_entries[i].arg);
				/* If either data or addr is zero print it */
				} else if (sp->s2io_entries[i].type ==
				if(!(sp->msix_info[i].addr &&
					MSIX_ALARM_TYPE) {
					sp->msix_info[i].data)) {
					sprintf(sp->desc[i], "%s:MSI-X-%d-TX",
					DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx "
						"Data:0x%llx\n",sp->desc[i],
						(unsigned long long)
						sp->msix_info[i].addr,
						(unsigned long long)
						sp->msix_info[i].data);
				} else {
					msix_tx_cnt++;
				}
			} else {
				sprintf(sp->desc[i], "%s:MSI-X-%d-RX",
					dev->name, i);
					dev->name, i);
					err = request_irq(sp->entries[i].vector,
					err = request_irq(sp->entries[i].vector,
					  s2io_msix_ring_handle, 0, sp->desc[i],
						s2io_msix_fifo_handle, 0,
						sp->desc[i],
						sp->s2io_entries[i].arg);
						sp->s2io_entries[i].arg);
				/* If either data or addr is zero print it */

				}
				/* if either data or addr is zero print it. */
				if (!(sp->msix_info[i].addr &&
				if (!(sp->msix_info[i].addr &&
					sp->msix_info[i].data)) {
					sp->msix_info[i].data)) {
					DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx "
					DBG_PRINT(ERR_DBG,
						"Data:0x%llx\n",sp->desc[i],
						"%s @Addr:0x%llx Data:0x%llx\n",
						sp->desc[i],
						(unsigned long long)
						(unsigned long long)
						sp->msix_info[i].addr,
						sp->msix_info[i].addr,
						(unsigned long long)
						(unsigned long long)
						sp->msix_info[i].data);
						ntohl(sp->msix_info[i].data));
				} else {
				} else
					msix_rx_cnt++;
					msix_rx_cnt++;
				}
			}
				if (err) {
				if (err) {
					remove_msix_isr(sp);
					remove_msix_isr(sp);
				DBG_PRINT(ERR_DBG,"%s:MSI-X-%d registration "

					DBG_PRINT(ERR_DBG,
						"%s:MSI-X-%d registration "
						"failed\n", dev->name, i);
						"failed\n", dev->name, i);
				DBG_PRINT(ERR_DBG, "%s: defaulting to INTA\n",

					DBG_PRINT(ERR_DBG,
						"%s: Defaulting to INTA\n",
						dev->name);
						dev->name);
					sp->config.intr_type = INTA;
					sp->config.intr_type = INTA;
					break;
					break;
				}
				}
			sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS;
				sp->s2io_entries[i].in_use =
					MSIX_REGISTERED_SUCCESS;

		}
		}
		if (!err) {
		if (!err) {
			printk(KERN_INFO "MSI-X-TX %d entries enabled\n",
				msix_tx_cnt);
			printk(KERN_INFO "MSI-X-RX %d entries enabled\n",
			printk(KERN_INFO "MSI-X-RX %d entries enabled\n",
				msix_rx_cnt);
				--msix_rx_cnt);
			DBG_PRINT(INFO_DBG, "MSI-X-TX entries enabled"
						" through alarm vector\n");
		}
		}
	}
	}
	if (sp->config.intr_type == INTA) {
	if (sp->config.intr_type == INTA) {
@@ -7218,7 +7252,7 @@ static int s2io_card_up(struct s2io_nic * sp)
	/*  Enable select interrupts */
	/*  Enable select interrupts */
	en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS);
	en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS);
	if (sp->config.intr_type != INTA)
	if (sp->config.intr_type != INTA)
		en_dis_able_nic_intrs(sp, ENA_ALL_INTRS, DISABLE_INTRS);
		en_dis_able_nic_intrs(sp, TX_TRAFFIC_INTR, ENABLE_INTRS);
	else {
	else {
		interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
		interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
		interruptible |= TX_PIC_INTR;
		interruptible |= TX_PIC_INTR;
+3 −2
Original line number Original line Diff line number Diff line
@@ -849,7 +849,7 @@ struct s2io_msix_entry
	void *arg;
	void *arg;


	u8 type;
	u8 type;
#define	MSIX_FIFO_TYPE	1
#define        MSIX_ALARM_TYPE         1
#define        MSIX_RING_TYPE          2
#define        MSIX_RING_TYPE          2


	u8 in_use;
	u8 in_use;
@@ -982,6 +982,7 @@ struct s2io_nic {
	u16		lro_max_aggr_per_sess;
	u16		lro_max_aggr_per_sess;
	volatile unsigned long state;
	volatile unsigned long state;
	u64		general_int_mask;
	u64		general_int_mask;

#define VPD_STRING_LEN 80
#define VPD_STRING_LEN 80
	u8  product_name[VPD_STRING_LEN];
	u8  product_name[VPD_STRING_LEN];
	u8  serial_num[VPD_STRING_LEN];
	u8  serial_num[VPD_STRING_LEN];