netxen_nic_init.c

来自「linux 内核源代码」· C语言 代码 · 共 1,553 行 · 第 1/3 页

C
1,553
字号
						return ret;				}				else {					printk(KERN_INFO "Data write did not "					   "succeed at address 0x%x\n", addridx);					break;				}			}		}		bytes += 4;		addridx += 4;	}	return ret;}int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr, 					u8 *bytes, size_t size){	int ret = 0;	ret = rom_lock(adapter);	if (ret < 0)		return ret;	ret = do_rom_fast_write_words(adapter, addr, bytes, size);	netxen_rom_unlock(adapter);	return ret;}int netxen_rom_wrsr(struct netxen_adapter *adapter, int data){	int ret;	ret = netxen_rom_wren(adapter);	if (ret < 0)		return ret;	netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_ROM_WDATA, data);	netxen_crb_writelit_adapter(adapter, 					NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0x1);	ret = netxen_wait_rom_done(adapter);	if (ret < 0)		return ret;	return netxen_rom_wip_poll(adapter);}int netxen_rom_rdsr(struct netxen_adapter *adapter){	int ret;	ret = rom_lock(adapter);	if (ret < 0)		return ret;	ret = netxen_do_rom_rdsr(adapter);	netxen_rom_unlock(adapter);	return ret;}int netxen_backup_crbinit(struct netxen_adapter *adapter){	int ret = FLASH_SUCCESS;	int val;	char *buffer = kmalloc(NETXEN_FLASH_SECTOR_SIZE, GFP_KERNEL);	if (!buffer)		return -ENOMEM;		/* unlock sector 63 */	val = netxen_rom_rdsr(adapter);	val = val & 0xe3;	ret = netxen_rom_wrsr(adapter, val);	if (ret != FLASH_SUCCESS)		goto out_kfree;	ret = netxen_rom_wip_poll(adapter);	if (ret != FLASH_SUCCESS)		goto out_kfree;	/* copy  sector 0 to sector 63 */	ret = netxen_rom_fast_read_words(adapter, NETXEN_CRBINIT_START, 					buffer, NETXEN_FLASH_SECTOR_SIZE);	if (ret != FLASH_SUCCESS)		goto out_kfree;	ret = netxen_rom_fast_write_words(adapter, NETXEN_FIXED_START, 					buffer, NETXEN_FLASH_SECTOR_SIZE);	if (ret != FLASH_SUCCESS)		goto out_kfree;	/* lock sector 63 */	val = netxen_rom_rdsr(adapter);	if (!(val & 0x8)) {		val |= (0x1 << 2);		/* lock sector 63 */		if (netxen_rom_wrsr(adapter, val) == 0) {			ret = netxen_rom_wip_poll(adapter);			if (ret != FLASH_SUCCESS)				goto out_kfree;			/* lock SR writes */			ret = netxen_rom_wip_poll(adapter);			if (ret != FLASH_SUCCESS)				goto out_kfree;		}	}out_kfree:	kfree(buffer);	return ret;}int netxen_do_rom_se(struct netxen_adapter *adapter, int addr){	netxen_rom_wren(adapter);	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,			     M25P_INSTR_SE);	if (netxen_wait_rom_done(adapter)) {		netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);		return -1;	}	return netxen_rom_wip_poll(adapter);}void check_erased_flash(struct netxen_adapter *adapter, int addr){	int i;	int val;	int count = 0, erased_errors = 0;	int range;	range = (addr == NETXEN_USER_START) ? 		NETXEN_FIXED_START : addr + NETXEN_FLASH_SECTOR_SIZE;		for (i = addr; i < range; i += 4) {		netxen_rom_fast_read(adapter, i, &val);		if (val != 0xffffffff)			erased_errors++;		count++;	}	if (erased_errors)		printk(KERN_INFO "0x%x out of 0x%x words fail to be erased "			"for sector address: %x\n", erased_errors, count, addr);}int netxen_rom_se(struct netxen_adapter *adapter, int addr){	int ret = 0;	if (rom_lock(adapter) != 0) {		return -1;	}	ret = netxen_do_rom_se(adapter, addr);	netxen_rom_unlock(adapter);	msleep(30);	check_erased_flash(adapter, addr);	return ret;}intnetxen_flash_erase_sections(struct netxen_adapter *adapter, int start, int end){	int ret = FLASH_SUCCESS;	int i;	for (i = start; i < end; i++) {		ret = netxen_rom_se(adapter, i * NETXEN_FLASH_SECTOR_SIZE);		if (ret)			break;		ret = netxen_rom_wip_poll(adapter);		if (ret < 0)			return ret;	}	return ret;}intnetxen_flash_erase_secondary(struct netxen_adapter *adapter){	int ret = FLASH_SUCCESS;	int start, end;	start = NETXEN_SECONDARY_START / NETXEN_FLASH_SECTOR_SIZE;	end   = NETXEN_USER_START / NETXEN_FLASH_SECTOR_SIZE;	ret = netxen_flash_erase_sections(adapter, start, end);	return ret;}intnetxen_flash_erase_primary(struct netxen_adapter *adapter){	int ret = FLASH_SUCCESS;	int start, end;	start = NETXEN_PRIMARY_START / NETXEN_FLASH_SECTOR_SIZE;	end   = NETXEN_SECONDARY_START / NETXEN_FLASH_SECTOR_SIZE;	ret = netxen_flash_erase_sections(adapter, start, end);	return ret;}void netxen_halt_pegs(struct netxen_adapter *adapter){	 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x3c, 1);	 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x3c, 1);	 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x3c, 1);	 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x3c, 1);}int netxen_flash_unlock(struct netxen_adapter *adapter){	int ret = 0;	ret = netxen_rom_wrsr(adapter, 0);	if (ret < 0)		return ret;	ret = netxen_rom_wren(adapter);	if (ret < 0)		return ret;	return ret;}#define NETXEN_BOARDTYPE		0x4008#define NETXEN_BOARDNUM 		0x400c#define NETXEN_CHIPNUM			0x4010#define NETXEN_ROMBUS_RESET		0xFFFFFFFF#define NETXEN_ROM_FIRST_BARRIER	0x800000000ULL#define NETXEN_ROM_FOUND_INIT		0x400int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose){	int addr, val, status;	int n, i;	int init_delay = 0;	struct crb_addr_pair *buf;	u32 off;	/* resetall */	status = netxen_nic_get_board_info(adapter);	if (status)		printk("%s: netxen_pinit_from_rom: Error getting board info\n",		       netxen_nic_driver_name);	netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,				    NETXEN_ROMBUS_RESET);	if (verbose) {		int val;		if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0)			printk("P2 ROM board type: 0x%08x\n", val);		else			printk("Could not read board type\n");		if (netxen_rom_fast_read(adapter, NETXEN_BOARDNUM, &val) == 0)			printk("P2 ROM board  num: 0x%08x\n", val);		else			printk("Could not read board number\n");		if (netxen_rom_fast_read(adapter, NETXEN_CHIPNUM, &val) == 0)			printk("P2 ROM chip   num: 0x%08x\n", val);		else			printk("Could not read chip number\n");	}	if (netxen_rom_fast_read(adapter, 0, &n) == 0	    && (n & NETXEN_ROM_FIRST_BARRIER)) {		n &= ~NETXEN_ROM_ROUNDUP;		if (n < NETXEN_ROM_FOUND_INIT) {			if (verbose)				printk("%s: %d CRB init values found"				       " in ROM.\n", netxen_nic_driver_name, n);		} else {			printk("%s:n=0x%x Error! NetXen card flash not"			       " initialized.\n", __FUNCTION__, n);			return -EIO;		}		buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL);		if (buf == NULL) {			printk("%s: netxen_pinit_from_rom: Unable to calloc "			       "memory.\n", netxen_nic_driver_name);			return -ENOMEM;		}		for (i = 0; i < n; i++) {			if (netxen_rom_fast_read(adapter, 8 * i + 4, &val) != 0			    || netxen_rom_fast_read(adapter, 8 * i + 8,						    &addr) != 0)				return -EIO;			buf[i].addr = addr;			buf[i].data = val;			if (verbose)				printk("%s: PCI:     0x%08x == 0x%08x\n",				       netxen_nic_driver_name, (unsigned int)				       netxen_decode_crb_addr(addr), val);		}		for (i = 0; i < n; i++) {			off = netxen_decode_crb_addr(buf[i].addr);			if (off == NETXEN_ADDR_ERROR) {				printk(KERN_ERR"CRB init value out of range %x\n",					buf[i].addr);				continue;			}			off += NETXEN_PCI_CRBSPACE;			/* skipping cold reboot MAGIC */			if (off == NETXEN_CAM_RAM(0x1fc))				continue;			/* After writing this register, HW needs time for CRB */			/* to quiet down (else crb_window returns 0xffffffff) */			if (off == NETXEN_ROMUSB_GLB_SW_RESET) {				init_delay = 1;				/* hold xdma in reset also */				buf[i].data = NETXEN_NIC_XDMA_RESET;			}			if (ADDR_IN_WINDOW1(off)) {				writel(buf[i].data,				       NETXEN_CRB_NORMALIZE(adapter, off));			} else {				netxen_nic_pci_change_crbwindow(adapter, 0);				writel(buf[i].data,				       pci_base_offset(adapter, off));				netxen_nic_pci_change_crbwindow(adapter, 1);			}			if (init_delay == 1) {				msleep(2000);				init_delay = 0;			}			msleep(20);		}		kfree(buf);		/* disable_peg_cache_all */		/* unreset_net_cache */		netxen_nic_hw_read_wx(adapter, NETXEN_ROMUSB_GLB_SW_RESET, &val,				      4);		netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,					    (val & 0xffffff0f));		/* p2dn replyCount */		netxen_crb_writelit_adapter(adapter,					    NETXEN_CRB_PEG_NET_D + 0xec, 0x1e);		/* disable_peg_cache 0 */		netxen_crb_writelit_adapter(adapter,					    NETXEN_CRB_PEG_NET_D + 0x4c, 8);		/* disable_peg_cache 1 */		netxen_crb_writelit_adapter(adapter,					    NETXEN_CRB_PEG_NET_I + 0x4c, 8);		/* peg_clr_all */		/* peg_clr 0 */		netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8,					    0);		netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc,					    0);		/* peg_clr 1 */		netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8,					    0);		netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc,					    0);		/* peg_clr 2 */		netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8,					    0);		netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc,					    0);		/* peg_clr 3 */		netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8,					    0);		netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc,					    0);	}	return 0;}int netxen_initialize_adapter_offload(struct netxen_adapter *adapter){	uint64_t addr;	uint32_t hi;	uint32_t lo;	adapter->dummy_dma.addr =	    pci_alloc_consistent(adapter->ahw.pdev,				 NETXEN_HOST_DUMMY_DMA_SIZE,				 &adapter->dummy_dma.phys_addr);	if (adapter->dummy_dma.addr == NULL) {		printk("%s: ERROR: Could not allocate dummy DMA memory\n",		       __FUNCTION__);		return -ENOMEM;	}	addr = (uint64_t) adapter->dummy_dma.phys_addr;	hi = (addr >> 32) & 0xffffffff;	lo = addr & 0xffffffff;	writel(hi, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI));	writel(lo, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO));	return 0;}void netxen_free_adapter_offload(struct netxen_adapter *adapter){	if (adapter->dummy_dma.addr) {		pci_free_consistent(adapter->ahw.pdev,				    NETXEN_HOST_DUMMY_DMA_SIZE,				    adapter->dummy_dma.addr,				    adapter->dummy_dma.phys_addr);		adapter->dummy_dma.addr = NULL;	}}int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val){	u32 val = 0;	int retries = 30;	if (!pegtune_val) {		do {			val = readl(NETXEN_CRB_NORMALIZE				  (adapter, CRB_CMDPEG_STATE));			pegtune_val = readl(NETXEN_CRB_NORMALIZE				  (adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE));			if (val == PHAN_INITIALIZE_COMPLETE ||				val == PHAN_INITIALIZE_ACK)				return 0;			msleep(1000);		} while (--retries);		if (!retries) {			printk(KERN_WARNING "netxen_phantom_init: init failed, "					"pegtune_val=%x\n", pegtune_val);			return -1;		}	}	return 0;}int netxen_nic_rx_has_work(struct netxen_adapter *adapter){	int ctx;	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {		struct netxen_recv_context *recv_ctx =		    &(adapter->recv_ctx[ctx]);		u32 consumer;		struct status_desc *desc_head;		struct status_desc *desc;		consumer = recv_ctx->status_rx_consumer;		desc_head = recv_ctx->rcv_status_desc_head;		desc = &desc_head[consumer];		if (netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)			return 1;	}	return 0;}static inline int netxen_nic_check_temp(struct netxen_adapter *adapter){	struct net_device *netdev = adapter->netdev;	uint32_t temp, temp_state, temp_val;	int rv = 0;	temp = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_TEMP_STATE));	temp_state = nx_get_temp_state(temp);	temp_val = nx_get_temp_val(temp);	if (temp_state == NX_TEMP_PANIC) {		printk(KERN_ALERT		       "%s: Device temperature %d degrees C exceeds"		       " maximum allowed. Hardware has been shut down.\n",		       netxen_nic_driver_name, temp_val);		netif_carrier_off(netdev);		netif_stop_queue(netdev);		rv = 1;	} else if (temp_state == NX_TEMP_WARN) {		if (adapter->temp == NX_TEMP_NORMAL) {			printk(KERN_ALERT			       "%s: Device temperature %d degrees C "			       "exceeds operating range."			       " Immediate action needed.\n",			       netxen_nic_driver_name, temp_val);		}	} else {		if (adapter->temp == NX_TEMP_WARN) {			printk(KERN_INFO			       "%s: Device temperature is now %d degrees C"			       " in normal range.\n", netxen_nic_driver_name,			       temp_val);		}	}	adapter->temp = temp_state;	return rv;}void netxen_watchdog_task(struct work_struct *work){	struct net_device *netdev;	struct netxen_adapter *adapter =

⌨️ 快捷键说明

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