Commit 5e25b9dd authored by Koushik's avatar Koushik Committed by Jeff Garzik
Browse files

[PATCH] S2io: Hardware fixes



Hi,
Below patch addresses few h/w specific issues.
1. Check for additional ownership bit on Rx path before
   starting Rx processing.
2. Enable only 4 PCCs(Per Context Controller) for Xframe I
   revisions less than 4.
3. Program Rx and Tx round robin registers depending on
   no. of rings/FIFOs.
4. Tx continous interrupts is now a loadable parameter.
5. Reset the card if we get double-bit ECC errors.
6. A soft reset of XGXS being done to force a link state change has been
   eliminated.
7. After a reset, clear "parity error detected" bit,
   PCI-X ECC status register, and PCI_STATUS bit in
   tx_pic_int register.
8. The error in the disabling allmulticast implementation has been
   rectified.
9. Leave the PCI-X parameters MMRBC, OST etc. at their
   BIOS/system defaults.

Signed-off-by: default avatarRavinandan Arakali <ravinandan.arakali@neterion.com>
Signed-off-by: default avatarRaghavendra Koushik <raghavendra.koushik@neterion.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent 20346722
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ typedef struct _XENA_dev_config {
#define ADAPTER_STATUS_RMAC_REMOTE_FAULT   BIT(6)
#define ADAPTER_STATUS_RMAC_LOCAL_FAULT    BIT(7)
#define ADAPTER_STATUS_RMAC_PCC_IDLE       vBIT(0xFF,8,8)
#define ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE  vBIT(0x0F,8,8)
#define ADAPTER_STATUS_RC_PRC_QUIESCENT    vBIT(0xFF,16,8)
#define ADAPTER_STATUS_MC_DRAM_READY       BIT(24)
#define ADAPTER_STATUS_MC_QUEUES_READY     BIT(25)
@@ -245,6 +246,7 @@ typedef struct _XENA_dev_config {
#define STAT_TRSF_PER(n)           TBD
#define	PER_SEC					   0x208d5
#define	SET_UPDT_PERIOD(n)		   vBIT((PER_SEC*n),32,32)
#define	SET_UPDT_CLICKS(val)		   vBIT(val, 32, 32)

	u64 stat_addr;

@@ -289,6 +291,7 @@ typedef struct _XENA_dev_config {

	u64 pcc_err_reg;
#define PCC_FB_ECC_DB_ERR		vBIT(0xFF, 16, 8)
#define PCC_ENABLE_FOUR			vBIT(0x0F,0,8)

	u64 pcc_err_mask;
	u64 pcc_err_alarm;
@@ -690,6 +693,10 @@ typedef struct _XENA_dev_config {
#define MC_ERR_REG_MIRI_CRI_ERR_0          BIT(22)
#define MC_ERR_REG_MIRI_CRI_ERR_1          BIT(23)
#define MC_ERR_REG_SM_ERR                  BIT(31)
#define MC_ERR_REG_ECC_ALL_SNG		   (BIT(6) | \
					BIT(7) | BIT(17) | BIT(19))
#define MC_ERR_REG_ECC_ALL_DBL		   (BIT(14) | \
					BIT(15) | BIT(18) | BIT(20))
	u64 mc_err_mask;
	u64 mc_err_alarm;

+330 −80
Original line number Diff line number Diff line
@@ -68,6 +68,16 @@
static char s2io_driver_name[] = "Neterion";
static char s2io_driver_version[] = "Version 1.7.7";

static inline int RXD_IS_UP2DT(RxD_t *rxdp)
{
	int ret;

	ret = ((!(rxdp->Control_1 & RXD_OWN_XENA)) &&
		(GET_RXD_MARKER(rxdp->Control_2) != THE_RXD_MARK));

	return ret;
}

/*
 * Cards with following subsystem_id have a link state indication
 * problem, 600B, 600C, 600D, 640B, 640C and 640D.
@@ -230,6 +240,7 @@ static unsigned int rx_ring_sz[MAX_RX_RINGS] =
static unsigned int Stats_refresh_time = 4;
static unsigned int rts_frm_len[MAX_RX_RINGS] =
    {[0 ...(MAX_RX_RINGS - 1)] = 0 };
static unsigned int use_continuous_tx_intrs = 1;
static unsigned int rmac_pause_time = 65535;
static unsigned int mc_pause_threshold_q0q3 = 187;
static unsigned int mc_pause_threshold_q4q7 = 187;
@@ -638,7 +649,7 @@ static int init_nic(struct s2io_nic *nic)
	mac_control = &nic->mac_control;
	config = &nic->config;

	/* to set the swapper control on the card */
	/* to set the swapper controle on the card */
	if(s2io_set_swapper(nic)) {
		DBG_PRINT(ERR_DBG,"ERROR: Setting Swapper failed\n");
		return -1;
@@ -756,6 +767,13 @@ static int init_nic(struct s2io_nic *nic)
	val64 |= BIT(0);	/* To enable the FIFO partition. */
	writeq(val64, &bar0->tx_fifo_partition_0);

	/*
	 * Disable 4 PCCs for Xena1, 2 and 3 as per H/W bug
	 * SXE-008 TRANSMIT DMA ARBITRATION ISSUE.
	 */
	if (get_xena_rev_id(nic->pdev) < 4)
		writeq(PCC_ENABLE_FOUR, &bar0->pcc_enable);

	val64 = readq(&bar0->tx_fifo_partition_0);
	DBG_PRINT(INIT_DBG, "Fifo partition at: 0x%p is: 0x%llx\n",
		  &bar0->tx_fifo_partition_0, (unsigned long long) val64);
@@ -823,32 +841,245 @@ static int init_nic(struct s2io_nic *nic)
	}
	writeq(val64, &bar0->rx_queue_cfg);

	/* Initializing the Tx round robin registers to 0
	 * filling tx and rx round robin registers as per
	 * the number of FIFOs and Rings is still TODO
	/*
	 * Filling Tx round robin registers
	 * as per the number of FIFOs
	 */
	writeq(0, &bar0->tx_w_round_robin_0);
	writeq(0, &bar0->tx_w_round_robin_1);
	writeq(0, &bar0->tx_w_round_robin_2);
	writeq(0, &bar0->tx_w_round_robin_3);
	writeq(0, &bar0->tx_w_round_robin_4);
	switch (config->tx_fifo_num) {
	case 1:
		val64 = 0x0000000000000000ULL;
		writeq(val64, &bar0->tx_w_round_robin_0);
		writeq(val64, &bar0->tx_w_round_robin_1);
		writeq(val64, &bar0->tx_w_round_robin_2);
		writeq(val64, &bar0->tx_w_round_robin_3);
		writeq(val64, &bar0->tx_w_round_robin_4);
		break;
	case 2:
		val64 = 0x0000010000010000ULL;
		writeq(val64, &bar0->tx_w_round_robin_0);
		val64 = 0x0100000100000100ULL;
		writeq(val64, &bar0->tx_w_round_robin_1);
		val64 = 0x0001000001000001ULL;
		writeq(val64, &bar0->tx_w_round_robin_2);
		val64 = 0x0000010000010000ULL;
		writeq(val64, &bar0->tx_w_round_robin_3);
		val64 = 0x0100000000000000ULL;
		writeq(val64, &bar0->tx_w_round_robin_4);
		break;
	case 3:
		val64 = 0x0001000102000001ULL;
		writeq(val64, &bar0->tx_w_round_robin_0);
		val64 = 0x0001020000010001ULL;
		writeq(val64, &bar0->tx_w_round_robin_1);
		val64 = 0x0200000100010200ULL;
		writeq(val64, &bar0->tx_w_round_robin_2);
		val64 = 0x0001000102000001ULL;
		writeq(val64, &bar0->tx_w_round_robin_3);
		val64 = 0x0001020000000000ULL;
		writeq(val64, &bar0->tx_w_round_robin_4);
		break;
	case 4:
		val64 = 0x0001020300010200ULL;
		writeq(val64, &bar0->tx_w_round_robin_0);
		val64 = 0x0100000102030001ULL;
		writeq(val64, &bar0->tx_w_round_robin_1);
		val64 = 0x0200010000010203ULL;
		writeq(val64, &bar0->tx_w_round_robin_2);
		val64 = 0x0001020001000001ULL;
		writeq(val64, &bar0->tx_w_round_robin_3);
		val64 = 0x0203000100000000ULL;
		writeq(val64, &bar0->tx_w_round_robin_4);
		break;
	case 5:
		val64 = 0x0001000203000102ULL;
		writeq(val64, &bar0->tx_w_round_robin_0);
		val64 = 0x0001020001030004ULL;
		writeq(val64, &bar0->tx_w_round_robin_1);
		val64 = 0x0001000203000102ULL;
		writeq(val64, &bar0->tx_w_round_robin_2);
		val64 = 0x0001020001030004ULL;
		writeq(val64, &bar0->tx_w_round_robin_3);
		val64 = 0x0001000000000000ULL;
		writeq(val64, &bar0->tx_w_round_robin_4);
		break;
	case 6:
		val64 = 0x0001020304000102ULL;
		writeq(val64, &bar0->tx_w_round_robin_0);
		val64 = 0x0304050001020001ULL;
		writeq(val64, &bar0->tx_w_round_robin_1);
		val64 = 0x0203000100000102ULL;
		writeq(val64, &bar0->tx_w_round_robin_2);
		val64 = 0x0304000102030405ULL;
		writeq(val64, &bar0->tx_w_round_robin_3);
		val64 = 0x0001000200000000ULL;
		writeq(val64, &bar0->tx_w_round_robin_4);
		break;
	case 7:
		val64 = 0x0001020001020300ULL;
		writeq(val64, &bar0->tx_w_round_robin_0);
		val64 = 0x0102030400010203ULL;
		writeq(val64, &bar0->tx_w_round_robin_1);
		val64 = 0x0405060001020001ULL;
		writeq(val64, &bar0->tx_w_round_robin_2);
		val64 = 0x0304050000010200ULL;
		writeq(val64, &bar0->tx_w_round_robin_3);
		val64 = 0x0102030000000000ULL;
		writeq(val64, &bar0->tx_w_round_robin_4);
		break;
	case 8:
		val64 = 0x0001020300040105ULL;
		writeq(val64, &bar0->tx_w_round_robin_0);
		val64 = 0x0200030106000204ULL;
		writeq(val64, &bar0->tx_w_round_robin_1);
		val64 = 0x0103000502010007ULL;
		writeq(val64, &bar0->tx_w_round_robin_2);
		val64 = 0x0304010002060500ULL;
		writeq(val64, &bar0->tx_w_round_robin_3);
		val64 = 0x0103020400000000ULL;
		writeq(val64, &bar0->tx_w_round_robin_4);
		break;
	}

	/*
	 * TODO
	 * Disable Rx steering. Hard coding all packets to be steered to
	 * Queue 0 for now.
	/* Filling the Rx round robin registers as per the
	 * number of Rings and steering based on QoS.
         */
	switch (config->rx_ring_num) {
	case 1:
		val64 = 0x8080808080808080ULL;
		writeq(val64, &bar0->rts_qos_steering);
		break;
	case 2:
		val64 = 0x0000010000010000ULL;
		writeq(val64, &bar0->rx_w_round_robin_0);
		val64 = 0x0100000100000100ULL;
		writeq(val64, &bar0->rx_w_round_robin_1);
		val64 = 0x0001000001000001ULL;
		writeq(val64, &bar0->rx_w_round_robin_2);
		val64 = 0x0000010000010000ULL;
		writeq(val64, &bar0->rx_w_round_robin_3);
		val64 = 0x0100000000000000ULL;
		writeq(val64, &bar0->rx_w_round_robin_4);

		val64 = 0x8080808040404040ULL;
		writeq(val64, &bar0->rts_qos_steering);
		break;
	case 3:
		val64 = 0x0001000102000001ULL;
		writeq(val64, &bar0->rx_w_round_robin_0);
		val64 = 0x0001020000010001ULL;
		writeq(val64, &bar0->rx_w_round_robin_1);
		val64 = 0x0200000100010200ULL;
		writeq(val64, &bar0->rx_w_round_robin_2);
		val64 = 0x0001000102000001ULL;
		writeq(val64, &bar0->rx_w_round_robin_3);
		val64 = 0x0001020000000000ULL;
		writeq(val64, &bar0->rx_w_round_robin_4);

		val64 = 0x8080804040402020ULL;
		writeq(val64, &bar0->rts_qos_steering);
		break;
	case 4:
		val64 = 0x0001020300010200ULL;
		writeq(val64, &bar0->rx_w_round_robin_0);
		val64 = 0x0100000102030001ULL;
		writeq(val64, &bar0->rx_w_round_robin_1);
		val64 = 0x0200010000010203ULL;
		writeq(val64, &bar0->rx_w_round_robin_2);
		val64 = 0x0001020001000001ULL;	
		writeq(val64, &bar0->rx_w_round_robin_3);
		val64 = 0x0203000100000000ULL;
		writeq(val64, &bar0->rx_w_round_robin_4);

		val64 = 0x8080404020201010ULL;
		writeq(val64, &bar0->rts_qos_steering);
		break;
	case 5:
		val64 = 0x0001000203000102ULL;
		writeq(val64, &bar0->rx_w_round_robin_0);
		val64 = 0x0001020001030004ULL;
		writeq(val64, &bar0->rx_w_round_robin_1);
		val64 = 0x0001000203000102ULL;
		writeq(val64, &bar0->rx_w_round_robin_2);
		val64 = 0x0001020001030004ULL;
		writeq(val64, &bar0->rx_w_round_robin_3);
		val64 = 0x0001000000000000ULL;
		writeq(val64, &bar0->rx_w_round_robin_4);

		val64 = 0x8080404020201008ULL;
		writeq(val64, &bar0->rts_qos_steering);
		break;
	case 6:
		val64 = 0x0001020304000102ULL;
		writeq(val64, &bar0->rx_w_round_robin_0);
		val64 = 0x0304050001020001ULL;
		writeq(val64, &bar0->rx_w_round_robin_1);
		val64 = 0x0203000100000102ULL;
		writeq(val64, &bar0->rx_w_round_robin_2);
		val64 = 0x0304000102030405ULL;
		writeq(val64, &bar0->rx_w_round_robin_3);
		val64 = 0x0001000200000000ULL;
		writeq(val64, &bar0->rx_w_round_robin_4);

		val64 = 0x8080404020100804ULL;
		writeq(val64, &bar0->rts_qos_steering);
		break;
	case 7:
		val64 = 0x0001020001020300ULL;
		writeq(val64, &bar0->rx_w_round_robin_0);
		val64 = 0x0102030400010203ULL;
		writeq(val64, &bar0->rx_w_round_robin_1);
		val64 = 0x0405060001020001ULL;
		writeq(val64, &bar0->rx_w_round_robin_2);
		val64 = 0x0304050000010200ULL;
		writeq(val64, &bar0->rx_w_round_robin_3);
		val64 = 0x0102030000000000ULL;
		writeq(val64, &bar0->rx_w_round_robin_4);

		val64 = 0x8080402010080402ULL;
		writeq(val64, &bar0->rts_qos_steering);
		break;
	case 8:
		val64 = 0x0001020300040105ULL;
		writeq(val64, &bar0->rx_w_round_robin_0);
		val64 = 0x0200030106000204ULL;
		writeq(val64, &bar0->rx_w_round_robin_1);
		val64 = 0x0103000502010007ULL;
		writeq(val64, &bar0->rx_w_round_robin_2);
		val64 = 0x0304010002060500ULL;
		writeq(val64, &bar0->rx_w_round_robin_3);
		val64 = 0x0103020400000000ULL;
		writeq(val64, &bar0->rx_w_round_robin_4);

		val64 = 0x8040201008040201ULL;
		writeq(val64, &bar0->rts_qos_steering);
		break;
	}

	/* UDP Fix */
	val64 = 0;
	for (i = 0; i < 8; i++)
		writeq(val64, &bar0->rts_frm_len_n[i]);

	/* Set the default rts frame length for ring0 */
	writeq(MAC_RTS_FRM_LEN_SET(dev->mtu+22),
		&bar0->rts_frm_len_n[0]);
	/* Set the default rts frame length for the rings configured */
	val64 = MAC_RTS_FRM_LEN_SET(dev->mtu+22);
	for (i = 0 ; i < config->rx_ring_num ; i++)
		writeq(val64, &bar0->rts_frm_len_n[i]);

	/* Set the frame length for the configured rings
	 * desired by the user
	 */
	for (i = 0; i < config->rx_ring_num; i++) {
		/* If rts_frm_len[i] == 0 then it is assumed that user not
		 * specified frame length steering.
		 * If the user provides the frame length then program
		 * the rts_frm_len register for those values or else
		 * leave it as it is.
		 */
		if (rts_frm_len[i] != 0) {
			writeq(MAC_RTS_FRM_LEN_SET(rts_frm_len[i]),
				&bar0->rts_frm_len_n[i]);
		}
	}

	/* Program statistics memory */
	writeq(mac_control->stats_mem_phy, &bar0->stat_addr);
@@ -877,13 +1108,14 @@ static int init_nic(struct s2io_nic *nic)
	val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0x2078) |
	    TTI_DATA1_MEM_TX_URNG_A(0xA) |
	    TTI_DATA1_MEM_TX_URNG_B(0x10) |
	    TTI_DATA1_MEM_TX_URNG_C(0x30) | TTI_DATA1_MEM_TX_TIMER_AC_EN |
		TTI_DATA1_MEM_TX_TIMER_CI_EN;
	    TTI_DATA1_MEM_TX_URNG_C(0x30) | TTI_DATA1_MEM_TX_TIMER_AC_EN;
	if (use_continuous_tx_intrs)
		val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN;
	writeq(val64, &bar0->tti_data1_mem);

	val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) |
	    TTI_DATA2_MEM_TX_UFC_B(0x20) |
	    TTI_DATA2_MEM_TX_UFC_C(0x40) | TTI_DATA2_MEM_TX_UFC_D(0x80);
	    TTI_DATA2_MEM_TX_UFC_C(0x70) | TTI_DATA2_MEM_TX_UFC_D(0x80);
	writeq(val64, &bar0->tti_data2_mem);

	val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD;
@@ -927,10 +1159,11 @@ static int init_nic(struct s2io_nic *nic)
	writeq(val64, &bar0->rti_command_mem);

	/*
	 * Once the operation completes, the Strobe bit of the command
	 * register will be reset. We poll for this particular condition
	 * We wait for a maximum of 500ms for the operation to complete,
	 * if it's not complete by then we return error.
	 * Once the operation completes, the Strobe bit of the
	 * command register will be reset. We poll for this
	 * particular condition. We wait for a maximum of 500ms
	 * for the operation to complete, if it's not complete
	 * by then we return error.
	 */
	time = 0;
	while (TRUE) {
@@ -1185,10 +1418,10 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
			temp64 &= ~((u64) val64);
			writeq(temp64, &bar0->general_int_mask);
			/*
			 * All MC block error interrupts are disabled for now.
			 * TODO
			 * Enable all MC Intrs.
			 */
			writeq(DISABLE_ALL_INTRS, &bar0->mc_int_mask);
			writeq(0x0, &bar0->mc_int_mask);
			writeq(0x0, &bar0->mc_err_mask);
		} else if (flag == DISABLE_INTRS) {
			/*
			 * Disable MC Intrs in the general intr mask register
@@ -1247,17 +1480,26 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
	}
}

static int check_prc_pcc_state(u64 val64, int flag)
static int check_prc_pcc_state(u64 val64, int flag, int rev_id)
{
	int ret = 0;

	if (flag == FALSE) {
		if (rev_id >= 4) {
			if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) &&
			    ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ==
			     ADAPTER_STATUS_RC_PRC_QUIESCENT)) {
				ret = 1;
			}
		} else {
			if (!(val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) &&
			    ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ==
			     ADAPTER_STATUS_RC_PRC_QUIESCENT)) {
				ret = 1;
			}
		}
	} else {
		if (rev_id >= 4) {
			if (((val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) ==
			     ADAPTER_STATUS_RMAC_PCC_IDLE) &&
			    (!(val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ||
@@ -1265,6 +1507,15 @@ static int check_prc_pcc_state(u64 val64, int flag)
			      ADAPTER_STATUS_RC_PRC_QUIESCENT))) {
				ret = 1;
			}
		} else {
			if (((val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) ==
			     ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) &&
			    (!(val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ||
			     ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ==
			      ADAPTER_STATUS_RC_PRC_QUIESCENT))) {
				ret = 1;
			}
		}
	}

	return ret;
@@ -1286,6 +1537,7 @@ static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag)
{
	int ret = 0;
	u64 tmp64 = ~((u64) val64);
	int rev_id = get_xena_rev_id(sp->pdev);

	if (!
	    (tmp64 &
@@ -1294,7 +1546,7 @@ static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag)
	      ADAPTER_STATUS_PIC_QUIESCENT | ADAPTER_STATUS_MC_DRAM_READY |
	      ADAPTER_STATUS_MC_QUEUES_READY | ADAPTER_STATUS_M_PLL_LOCK |
	      ADAPTER_STATUS_P_PLL_LOCK))) {
		ret = check_prc_pcc_state(val64, flag);
		ret = check_prc_pcc_state(val64, flag, rev_id);
	}

	return ret;
@@ -1407,7 +1659,7 @@ static int start_nic(struct s2io_nic *nic)

	/*  Enable select interrupts */
	interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR | TX_MAC_INTR |
	    RX_MAC_INTR;
	    RX_MAC_INTR | MC_INTR;
	en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS);

	/*
@@ -1439,21 +1691,6 @@ static int start_nic(struct s2io_nic *nic)
	 */
	schedule_work(&nic->set_link_task);

	/*
	 * Here we are performing soft reset on XGXS to
	 * force link down. Since link is already up, we will get
	 * link state change interrupt after this reset
	 */
	SPECIAL_REG_WRITE(0x80010515001E0000ULL, &bar0->dtx_control, UF);
	val64 = readq(&bar0->dtx_control);
	udelay(50);
	SPECIAL_REG_WRITE(0x80010515001E00E0ULL, &bar0->dtx_control, UF);
	val64 = readq(&bar0->dtx_control);
	udelay(50);
	SPECIAL_REG_WRITE(0x80070515001F00E4ULL, &bar0->dtx_control, UF);
	val64 = readq(&bar0->dtx_control);
	udelay(50);

	return SUCCESS;
}

@@ -1524,7 +1761,7 @@ static void stop_nic(struct s2io_nic *nic)

	/*  Disable all interrupts */
	interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR | TX_MAC_INTR |
	    RX_MAC_INTR;
	    RX_MAC_INTR | MC_INTR;
	en_dis_able_nic_intrs(nic, interruptible, DISABLE_INTRS);

	/*  Disable PRCs */
@@ -1737,6 +1974,7 @@ int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
		off++;
		mac_control->rings[ring_no].rx_curr_put_info.offset = off;
#endif
		rxdp->Control_2 |= SET_RXD_MARKER;

		atomic_inc(&nic->rx_bufs_left[ring_no]);
		alloc_tab++;
@@ -1965,10 +2203,7 @@ static void rx_intr_handler(ring_info_t *ring_data)
	put_offset = (put_block * (MAX_RXDS_PER_BLOCK + 1)) +
		put_info.offset;
#endif
	while ((!(rxdp->Control_1 & RXD_OWN_XENA)) &&
#ifdef CONFIG_2BUFF_MODE
		(!rxdp->Control_2 & BIT(0)) &&
#endif
	while (RXD_IS_UP2DT(rxdp) &&
	       (((get_offset + 1) % ring_bufs) != put_offset)) {
		skb = (struct sk_buff *) ((unsigned long)rxdp->Host_Control);
		if (skb == NULL) {
@@ -2153,6 +2388,21 @@ static void alarm_intr_handler(struct s2io_nic *nic)
		schedule_work(&nic->set_link_task);
	}

	/* Handling Ecc errors */
	val64 = readq(&bar0->mc_err_reg);
	writeq(val64, &bar0->mc_err_reg);
	if (val64 & (MC_ERR_REG_ECC_ALL_SNG | MC_ERR_REG_ECC_ALL_DBL)) {
		if (val64 & MC_ERR_REG_ECC_ALL_DBL) {
			DBG_PRINT(ERR_DBG, "%s: Device indicates ",
				  dev->name);
			DBG_PRINT(ERR_DBG, "double ECC error!!\n");
			netif_stop_queue(dev);
			schedule_work(&nic->rst_timer_task);
		} else {
			/* Device can recover from Single ECC errors */
		}
	}

	/* In case of a serious error, the device will be Reset. */
	val64 = readq(&bar0->serr_source);
	if (val64 & SERR_SOURCE_ANY) {
@@ -2226,7 +2476,7 @@ void s2io_reset(nic_t * sp)
{
	XENA_dev_config_t __iomem *bar0 = sp->bar0;
	u64 val64;
	u16 subid;
	u16 subid, pci_cmd;

	val64 = SW_RESET_ALL;
	writeq(val64, &bar0->sw_reset);
@@ -2255,6 +2505,18 @@ void s2io_reset(nic_t * sp)
	/* Set swapper to enable I/O register access */
	s2io_set_swapper(sp);

	/* Clear certain PCI/PCI-X fields after reset */
	pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd);
	pci_cmd &= 0x7FFF; /* Clear parity err detect bit */
	pci_write_config_word(sp->pdev, PCI_COMMAND, pci_cmd);

	val64 = readq(&bar0->txpic_int_reg);
	val64 &= ~BIT(62); /* Clearing PCI_STATUS error reflected here */
	writeq(val64, &bar0->txpic_int_reg);

	/* Clearing PCIX Ecc status register */
	pci_write_config_dword(sp->pdev, 0x68, 0);

	/* Reset device statistics maintained by OS */
	memset(&sp->stats, 0, sizeof (struct net_device_stats));

@@ -2797,6 +3059,8 @@ static void s2io_set_multicast(struct net_device *dev)
		/*  Disable all Multicast addresses */
		writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr),
		       &bar0->rmac_addr_data0_mem);
		writeq(RMAC_ADDR_DATA1_MEM_MASK(0x0),
		       &bar0->rmac_addr_data1_mem);
		val64 = RMAC_ADDR_CMD_MEM_WE |
		    RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
		    RMAC_ADDR_CMD_MEM_OFFSET(sp->all_multi_pos);
@@ -4369,21 +4633,6 @@ static void s2io_init_pci(nic_t * sp)
			      (pci_cmd | PCI_COMMAND_PARITY));
	pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd);

	/* Set MMRB count to 1024 in PCI-X Command register. */
	pcix_cmd &= 0xFFF3;
	pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
			      (pcix_cmd | (0x1 << 2)));	/* MMRBC 1K */
	pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
			     &(pcix_cmd));

	/*  Setting Maximum outstanding splits based on system type. */
	pcix_cmd &= 0xFF8F;
	pcix_cmd |= XENA_MAX_OUTSTANDING_SPLITS(0x1);	/* 2 splits. */
	pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
			      pcix_cmd);
	pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
			     &(pcix_cmd));

	/* Forcibly disabling relaxed ordering capability of the card. */
	pcix_cmd &= 0xfffd;
	pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
@@ -4400,6 +4649,7 @@ module_param_array(tx_fifo_len, uint, NULL, 0);
module_param_array(rx_ring_sz, uint, NULL, 0);
module_param(Stats_refresh_time, int, 0);
module_param_array(rts_frm_len, uint, NULL, 0);
module_param(use_continuous_tx_intrs, int, 1);
module_param(rmac_pause_time, int, 0);
module_param(mc_pause_threshold_q0q3, int, 0);
module_param(mc_pause_threshold_q4q7, int, 0);
+4 −0
Original line number Diff line number Diff line
@@ -372,6 +372,10 @@ typedef struct _RxD_t {
#define RXD_GET_L4_CKSUM(val)   ((u16)(val) & 0xFFFF)

	u64 Control_2;
#define	THE_RXD_MARK		0x3
#define	SET_RXD_MARKER		vBIT(THE_RXD_MARK, 0, 2)
#define	GET_RXD_MARKER(ctrl)	((ctrl & SET_RXD_MARKER) >> 62)

#ifndef CONFIG_2BUFF_MODE
#define MASK_BUFFER0_SIZE       vBIT(0x3FFF,2,14)
#define SET_BUFFER0_SIZE(val)   vBIT(val,2,14)