⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s2io.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	for (i = 0; i < config->rx_ring_num; i++) {		blk_cnt = mac_control->rings[i].block_count;		for (j = 0; j < blk_cnt; j++) {			tmp_v_addr = mac_control->rings[i].rx_blocks[j].				block_virt_addr;			tmp_p_addr = mac_control->rings[i].rx_blocks[j].				block_dma_addr;			if (tmp_v_addr == NULL)				break;			pci_free_consistent(nic->pdev, size,					    tmp_v_addr, tmp_p_addr);			nic->mac_control.stats_info->sw_stat.mem_freed += size;			kfree(mac_control->rings[i].rx_blocks[j].rxds);			nic->mac_control.stats_info->sw_stat.mem_freed +=			( sizeof(struct rxd_info)* rxd_count[nic->rxd_mode]);		}	}	if (nic->rxd_mode == RXD_MODE_3B) {		/* Freeing buffer storage addresses in 2BUFF mode. */		for (i = 0; i < config->rx_ring_num; i++) {			blk_cnt = config->rx_cfg[i].num_rxd /			    (rxd_count[nic->rxd_mode] + 1);			for (j = 0; j < blk_cnt; j++) {				int k = 0;				if (!mac_control->rings[i].ba[j])					continue;				while (k != rxd_count[nic->rxd_mode]) {					struct buffAdd *ba =						&mac_control->rings[i].ba[j][k];					kfree(ba->ba_0_org);					nic->mac_control.stats_info->sw_stat.\					mem_freed += (BUF0_LEN + ALIGN_SIZE);					kfree(ba->ba_1_org);					nic->mac_control.stats_info->sw_stat.\					mem_freed += (BUF1_LEN + ALIGN_SIZE);					k++;				}				kfree(mac_control->rings[i].ba[j]);				nic->mac_control.stats_info->sw_stat.mem_freed +=					(sizeof(struct buffAdd) *					(rxd_count[nic->rxd_mode] + 1));			}			kfree(mac_control->rings[i].ba);			nic->mac_control.stats_info->sw_stat.mem_freed +=			(sizeof(struct buffAdd *) * blk_cnt);		}	}	if (mac_control->stats_mem) {		pci_free_consistent(nic->pdev,				    mac_control->stats_mem_sz,				    mac_control->stats_mem,				    mac_control->stats_mem_phy);		nic->mac_control.stats_info->sw_stat.mem_freed +=			mac_control->stats_mem_sz;	}	if (nic->ufo_in_band_v) {		kfree(nic->ufo_in_band_v);		nic->mac_control.stats_info->sw_stat.mem_freed			+= (ufo_size * sizeof(u64));	}}/** * s2io_verify_pci_mode - */static int s2io_verify_pci_mode(struct s2io_nic *nic){	struct XENA_dev_config __iomem *bar0 = nic->bar0;	register u64 val64 = 0;	int     mode;	val64 = readq(&bar0->pci_mode);	mode = (u8)GET_PCI_MODE(val64);	if ( val64 & PCI_MODE_UNKNOWN_MODE)		return -1;      /* Unknown PCI mode */	return mode;}#define NEC_VENID   0x1033#define NEC_DEVID   0x0125static int s2io_on_nec_bridge(struct pci_dev *s2io_pdev){	struct pci_dev *tdev = NULL;	while ((tdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, tdev)) != NULL) {		if (tdev->vendor == NEC_VENID && tdev->device == NEC_DEVID) {			if (tdev->bus == s2io_pdev->bus->parent)				pci_dev_put(tdev);				return 1;		}	}	return 0;}static int bus_speed[8] = {33, 133, 133, 200, 266, 133, 200, 266};/** * s2io_print_pci_mode - */static int s2io_print_pci_mode(struct s2io_nic *nic){	struct XENA_dev_config __iomem *bar0 = nic->bar0;	register u64 val64 = 0;	int	mode;	struct config_param *config = &nic->config;	val64 = readq(&bar0->pci_mode);	mode = (u8)GET_PCI_MODE(val64);	if ( val64 & PCI_MODE_UNKNOWN_MODE)		return -1;	/* Unknown PCI mode */	config->bus_speed = bus_speed[mode];	if (s2io_on_nec_bridge(nic->pdev)) {		DBG_PRINT(ERR_DBG, "%s: Device is on PCI-E bus\n",							nic->dev->name);		return mode;	}	if (val64 & PCI_MODE_32_BITS) {		DBG_PRINT(ERR_DBG, "%s: Device is on 32 bit ", nic->dev->name);	} else {		DBG_PRINT(ERR_DBG, "%s: Device is on 64 bit ", nic->dev->name);	}	switch(mode) {		case PCI_MODE_PCI_33:			DBG_PRINT(ERR_DBG, "33MHz PCI bus\n");			break;		case PCI_MODE_PCI_66:			DBG_PRINT(ERR_DBG, "66MHz PCI bus\n");			break;		case PCI_MODE_PCIX_M1_66:			DBG_PRINT(ERR_DBG, "66MHz PCIX(M1) bus\n");			break;		case PCI_MODE_PCIX_M1_100:			DBG_PRINT(ERR_DBG, "100MHz PCIX(M1) bus\n");			break;		case PCI_MODE_PCIX_M1_133:			DBG_PRINT(ERR_DBG, "133MHz PCIX(M1) bus\n");			break;		case PCI_MODE_PCIX_M2_66:			DBG_PRINT(ERR_DBG, "133MHz PCIX(M2) bus\n");			break;		case PCI_MODE_PCIX_M2_100:			DBG_PRINT(ERR_DBG, "200MHz PCIX(M2) bus\n");			break;		case PCI_MODE_PCIX_M2_133:			DBG_PRINT(ERR_DBG, "266MHz PCIX(M2) bus\n");			break;		default:			return -1;	/* Unsupported bus speed */	}	return mode;}/** *  init_nic - Initialization of hardware *  @nic: device peivate variable *  Description: The function sequentially configures every block *  of the H/W from their reset values. *  Return Value:  SUCCESS on success and *  '-1' on failure (endian settings incorrect). */static int init_nic(struct s2io_nic *nic){	struct XENA_dev_config __iomem *bar0 = nic->bar0;	struct net_device *dev = nic->dev;	register u64 val64 = 0;	void __iomem *add;	u32 time;	int i, j;	struct mac_info *mac_control;	struct config_param *config;	int dtx_cnt = 0;	unsigned long long mem_share;	int mem_size;	mac_control = &nic->mac_control;	config = &nic->config;	/* to set the swapper controle on the card */	if(s2io_set_swapper(nic)) {		DBG_PRINT(ERR_DBG,"ERROR: Setting Swapper failed\n");		return -EIO;	}	/*	 * Herc requires EOI to be removed from reset before XGXS, so..	 */	if (nic->device_type & XFRAME_II_DEVICE) {		val64 = 0xA500000000ULL;		writeq(val64, &bar0->sw_reset);		msleep(500);		val64 = readq(&bar0->sw_reset);	}	/* Remove XGXS from reset state */	val64 = 0;	writeq(val64, &bar0->sw_reset);	msleep(500);	val64 = readq(&bar0->sw_reset);	/* Ensure that it's safe to access registers by checking	 * RIC_RUNNING bit is reset. Check is valid only for XframeII.	 */	if (nic->device_type == XFRAME_II_DEVICE) {		for (i = 0; i < 50; i++) {			val64 = readq(&bar0->adapter_status);			if (!(val64 & ADAPTER_STATUS_RIC_RUNNING))				break;			msleep(10);		}		if (i == 50)			return -ENODEV;	}	/*  Enable Receiving broadcasts */	add = &bar0->mac_cfg;	val64 = readq(&bar0->mac_cfg);	val64 |= MAC_RMAC_BCAST_ENABLE;	writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);	writel((u32) val64, add);	writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);	writel((u32) (val64 >> 32), (add + 4));	/* Read registers in all blocks */	val64 = readq(&bar0->mac_int_mask);	val64 = readq(&bar0->mc_int_mask);	val64 = readq(&bar0->xgxs_int_mask);	/*  Set MTU */	val64 = dev->mtu;	writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len);	if (nic->device_type & XFRAME_II_DEVICE) {		while (herc_act_dtx_cfg[dtx_cnt] != END_SIGN) {			SPECIAL_REG_WRITE(herc_act_dtx_cfg[dtx_cnt],					  &bar0->dtx_control, UF);			if (dtx_cnt & 0x1)				msleep(1); /* Necessary!! */			dtx_cnt++;		}	} else {		while (xena_dtx_cfg[dtx_cnt] != END_SIGN) {			SPECIAL_REG_WRITE(xena_dtx_cfg[dtx_cnt],					  &bar0->dtx_control, UF);			val64 = readq(&bar0->dtx_control);			dtx_cnt++;		}	}	/*  Tx DMA Initialization */	val64 = 0;	writeq(val64, &bar0->tx_fifo_partition_0);	writeq(val64, &bar0->tx_fifo_partition_1);	writeq(val64, &bar0->tx_fifo_partition_2);	writeq(val64, &bar0->tx_fifo_partition_3);	for (i = 0, j = 0; i < config->tx_fifo_num; i++) {		val64 |=		    vBIT(config->tx_cfg[i].fifo_len - 1, ((i * 32) + 19),			 13) | vBIT(config->tx_cfg[i].fifo_priority,				    ((i * 32) + 5), 3);		if (i == (config->tx_fifo_num - 1)) {			if (i % 2 == 0)				i++;		}		switch (i) {		case 1:			writeq(val64, &bar0->tx_fifo_partition_0);			val64 = 0;			break;		case 3:			writeq(val64, &bar0->tx_fifo_partition_1);			val64 = 0;			break;		case 5:			writeq(val64, &bar0->tx_fifo_partition_2);			val64 = 0;			break;		case 7:			writeq(val64, &bar0->tx_fifo_partition_3);			break;		}	}	/*	 * Disable 4 PCCs for Xena1, 2 and 3 as per H/W bug	 * SXE-008 TRANSMIT DMA ARBITRATION ISSUE.	 */	if ((nic->device_type == XFRAME_I_DEVICE) &&		(nic->pdev->revision < 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);	/*	 * Initialization of Tx_PA_CONFIG register to ignore packet	 * integrity checking.	 */	val64 = readq(&bar0->tx_pa_cfg);	val64 |= TX_PA_CFG_IGNORE_FRM_ERR | TX_PA_CFG_IGNORE_SNAP_OUI |	    TX_PA_CFG_IGNORE_LLC_CTRL | TX_PA_CFG_IGNORE_L2_ERR;	writeq(val64, &bar0->tx_pa_cfg);	/* Rx DMA intialization. */	val64 = 0;	for (i = 0; i < config->rx_ring_num; i++) {		val64 |=		    vBIT(config->rx_cfg[i].ring_priority, (5 + (i * 8)),			 3);	}	writeq(val64, &bar0->rx_queue_priority);	/*	 * Allocating equal share of memory to all the	 * configured Rings.	 */	val64 = 0;	if (nic->device_type & XFRAME_II_DEVICE)		mem_size = 32;	else		mem_size = 64;	for (i = 0; i < config->rx_ring_num; i++) {		switch (i) {		case 0:			mem_share = (mem_size / config->rx_ring_num +				     mem_size % config->rx_ring_num);			val64 |= RX_QUEUE_CFG_Q0_SZ(mem_share);			continue;		case 1:			mem_share = (mem_size / config->rx_ring_num);			val64 |= RX_QUEUE_CFG_Q1_SZ(mem_share);			continue;		case 2:			mem_share = (mem_size / config->rx_ring_num);			val64 |= RX_QUEUE_CFG_Q2_SZ(mem_share);			continue;		case 3:			mem_share = (mem_size / config->rx_ring_num);			val64 |= RX_QUEUE_CFG_Q3_SZ(mem_share);			continue;		case 4:			mem_share = (mem_size / config->rx_ring_num);			val64 |= RX_QUEUE_CFG_Q4_SZ(mem_share);			continue;		case 5:			mem_share = (mem_size / config->rx_ring_num);			val64 |= RX_QUEUE_CFG_Q5_SZ(mem_share);			continue;		case 6:			mem_share = (mem_size / config->rx_ring_num);			val64 |= RX_QUEUE_CFG_Q6_SZ(mem_share);			continue;		case 7:			mem_share = (mem_size / config->rx_ring_num);			val64 |= RX_QUEUE_CFG_Q7_SZ(mem_share);			continue;		}	}	writeq(val64, &bar0->rx_queue_cfg);	/*	 * Filling Tx round robin registers	 * as per the number of FIFOs	 */	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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -