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

📄 s2io.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
			temp64 = readq(&bar0->general_int_mask);			val64 |= temp64;			writeq(val64, &bar0->general_int_mask);		}	}	/*  DMA Interrupts */	/*  Enabling/Disabling Tx DMA interrupts */	if (mask & TX_DMA_INTR) {		/*  Enable TxDMA Intrs in the general intr mask register */		val64 = TXDMA_INT_M;		if (flag == ENABLE_INTRS) {			temp64 = readq(&bar0->general_int_mask);			temp64 &= ~((u64) val64);			writeq(temp64, &bar0->general_int_mask);			/* Disable all interrupts other than PFC interrupt in 			 * DMA level.			 */			val64 = DISABLE_ALL_INTRS & (~TXDMA_PFC_INT_M);			writeq(val64, &bar0->txdma_int_mask);			/* Enable only the MISC error 1 interrupt in PFC block 			 */			val64 = DISABLE_ALL_INTRS & (~PFC_MISC_ERR_1);			writeq(val64, &bar0->pfc_err_mask);		} else if (flag == DISABLE_INTRS) {			/*  Disable TxDMA Intrs in the general intr mask 			 *  register */			writeq(DISABLE_ALL_INTRS, &bar0->txdma_int_mask);			writeq(DISABLE_ALL_INTRS, &bar0->pfc_err_mask);			temp64 = readq(&bar0->general_int_mask);			val64 |= temp64;			writeq(val64, &bar0->general_int_mask);		}	}	/*  Enabling/Disabling Rx DMA interrupts */	if (mask & RX_DMA_INTR) {		/*  Enable RxDMA Intrs in the general intr mask register */		val64 = RXDMA_INT_M;		if (flag == ENABLE_INTRS) {			temp64 = readq(&bar0->general_int_mask);			temp64 &= ~((u64) val64);			writeq(temp64, &bar0->general_int_mask);			/* All RxDMA block interrupts are disabled for now 			 * TODO */			writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask);		} else if (flag == DISABLE_INTRS) {			/*  Disable RxDMA Intrs in the general intr mask 			 *  register */			writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask);			temp64 = readq(&bar0->general_int_mask);			val64 |= temp64;			writeq(val64, &bar0->general_int_mask);		}	}	/*  MAC Interrupts */	/*  Enabling/Disabling MAC interrupts */	if (mask & (TX_MAC_INTR | RX_MAC_INTR)) {		val64 = TXMAC_INT_M | RXMAC_INT_M;		if (flag == ENABLE_INTRS) {			temp64 = readq(&bar0->general_int_mask);			temp64 &= ~((u64) val64);			writeq(temp64, &bar0->general_int_mask);			/* All MAC block error interrupts are disabled for now 			 * except the link status change interrupt.			 * TODO*/			val64 = MAC_INT_STATUS_RMAC_INT;			temp64 = readq(&bar0->mac_int_mask);			temp64 &= ~((u64) val64);			writeq(temp64, &bar0->mac_int_mask);			val64 = readq(&bar0->mac_rmac_err_mask);			val64 &= ~((u64) RMAC_LINK_STATE_CHANGE_INT);			writeq(val64, &bar0->mac_rmac_err_mask);		} else if (flag == DISABLE_INTRS) {			/*  Disable MAC Intrs in the general intr mask register 			 */			writeq(DISABLE_ALL_INTRS, &bar0->mac_int_mask);			writeq(DISABLE_ALL_INTRS,			       &bar0->mac_rmac_err_mask);			temp64 = readq(&bar0->general_int_mask);			val64 |= temp64;			writeq(val64, &bar0->general_int_mask);		}	}	/*  XGXS Interrupts */	if (mask & (TX_XGXS_INTR | RX_XGXS_INTR)) {		val64 = TXXGXS_INT_M | RXXGXS_INT_M;		if (flag == ENABLE_INTRS) {			temp64 = readq(&bar0->general_int_mask);			temp64 &= ~((u64) val64);			writeq(temp64, &bar0->general_int_mask);			/* All XGXS block error interrupts are disabled for now			 *  TODO */			writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask);		} else if (flag == DISABLE_INTRS) {			/*  Disable MC Intrs in the general intr mask register 			 */			writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask);			temp64 = readq(&bar0->general_int_mask);			val64 |= temp64;			writeq(val64, &bar0->general_int_mask);		}	}	/*  Memory Controller(MC) interrupts */	if (mask & MC_INTR) {		val64 = MC_INT_M;		if (flag == ENABLE_INTRS) {			temp64 = readq(&bar0->general_int_mask);			temp64 &= ~((u64) val64);			writeq(temp64, &bar0->general_int_mask);			/* All MC block error interrupts are disabled for now			 * TODO */			writeq(DISABLE_ALL_INTRS, &bar0->mc_int_mask);		} else if (flag == DISABLE_INTRS) {			/*  Disable MC Intrs in the general intr mask register			 */			writeq(DISABLE_ALL_INTRS, &bar0->mc_int_mask);			temp64 = readq(&bar0->general_int_mask);			val64 |= temp64;			writeq(val64, &bar0->general_int_mask);		}	}	/*  Tx traffic interrupts */	if (mask & TX_TRAFFIC_INTR) {		val64 = TXTRAFFIC_INT_M;		if (flag == ENABLE_INTRS) {			temp64 = readq(&bar0->general_int_mask);			temp64 &= ~((u64) val64);			writeq(temp64, &bar0->general_int_mask);			/* Enable all the Tx side interrupts */			writeq(0x0, &bar0->tx_traffic_mask);	/* '0' Enables 								 * all 64 TX 								 * interrupt 								 * levels.								 */		} else if (flag == DISABLE_INTRS) {			/*  Disable Tx Traffic Intrs in the general intr mask 			 *  register.			 */			writeq(DISABLE_ALL_INTRS, &bar0->tx_traffic_mask);			temp64 = readq(&bar0->general_int_mask);			val64 |= temp64;			writeq(val64, &bar0->general_int_mask);		}	}	/*  Rx traffic interrupts */	if (mask & RX_TRAFFIC_INTR) {		val64 = RXTRAFFIC_INT_M;		if (flag == ENABLE_INTRS) {			temp64 = readq(&bar0->general_int_mask);			temp64 &= ~((u64) val64);			writeq(temp64, &bar0->general_int_mask);			writeq(0x0, &bar0->rx_traffic_mask);	/* '0' Enables 								 * all 8 RX 								 * interrupt 								 * levels.								 */		} else if (flag == DISABLE_INTRS) {			/*  Disable Rx Traffic Intrs in the general intr mask 			 *  register.			 */			writeq(DISABLE_ALL_INTRS, &bar0->rx_traffic_mask);			temp64 = readq(&bar0->general_int_mask);			val64 |= temp64;			writeq(val64, &bar0->general_int_mask);		}	}}/*   *  Input Arguments:  *   val64 - Value read from adapter status register. *   flag - indicates if the adapter enable bit was ever written once before. *  Return Value:  *   void. *  Description:  *   Returns whether the H/W is ready to go or not. Depending on whether  *   adapter enable bit was written or not the comparison differs and the  *   calling function passes the input argument flag to indicate this. */static int verify_xena_quiescence(u64 val64, int flag){	int ret = 0;	u64 tmp64 = ~((u64) val64);	if (!	    (tmp64 &	     (ADAPTER_STATUS_TDMA_READY | ADAPTER_STATUS_RDMA_READY |	      ADAPTER_STATUS_PFC_READY | ADAPTER_STATUS_TMAC_BUF_EMPTY |	      ADAPTER_STATUS_PIC_QUIESCENT | ADAPTER_STATUS_MC_DRAM_READY |	      ADAPTER_STATUS_MC_QUEUES_READY | ADAPTER_STATUS_M_PLL_LOCK |	      ADAPTER_STATUS_P_PLL_LOCK))) {		if (flag == FALSE) {			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_IDLE) ==			     ADAPTER_STATUS_RMAC_PCC_IDLE) &&			    (!(val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ||			     ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ==			      ADAPTER_STATUS_RC_PRC_QUIESCENT))) {				ret = 1;			}		}	}	return ret;}/*  * New procedure to clear mac address reading  problems on Alpha platforms * */void FixMacAddress(nic_t * sp){	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;	u64 val64;	int i = 0;	while (fix_mac[i] != END_SIGN) {		writeq(fix_mac[i++], &bar0->gpio_control);		val64 = readq(&bar0->gpio_control);	}}/*   *  Input Arguments:  *  device private variable. *  Return Value:  *  SUCCESS on success and -1 on failure. *  Description:  *  This function actually turns the device on. Before this  *  function is called, all Registers are configured from their reset states  *  and shared memory is allocated but the NIC is still quiescent. On  *  calling this function, the device interrupts are cleared and the NIC is *  literally switched on by writing into the adapter control register. */static int startNic(struct s2io_nic *nic){	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;	struct net_device *dev = nic->dev;	register u64 val64 = 0;	u16 interruptible, i;	u16 subid;	mac_info_t *mac_control;	struct config_param *config;	mac_control = &nic->mac_control;	config = &nic->config;	/*  PRC Initialization and configuration */	for (i = 0; i < config->RxRingNum; i++) {		writeq((u64) nic->rx_blocks[i][0].block_dma_addr,		       &bar0->prc_rxd0_n[i]);		val64 = readq(&bar0->prc_ctrl_n[i]);		val64 |= PRC_CTRL_RC_ENABLED;		writeq(val64, &bar0->prc_ctrl_n[i]);	}	/* Enabling MC-RLDRAM. After enabling the device, we timeout	 * for around 100ms, which is approximately the time required	 * for the device to be ready for operation.	 */	val64 = readq(&bar0->mc_rldram_mrs);	val64 |= MC_RLDRAM_QUEUE_SIZE_ENABLE | MC_RLDRAM_MRS_ENABLE;	writeq(val64, &bar0->mc_rldram_mrs);	val64 = readq(&bar0->mc_rldram_mrs);	set_current_state(TASK_UNINTERRUPTIBLE);	schedule_timeout(HZ / 10);	/* Delay by around 100 ms. */	/* Enabling ECC Protection. */	val64 = readq(&bar0->adapter_control);	val64 &= ~ADAPTER_ECC_EN;	writeq(val64, &bar0->adapter_control);	/* Clearing any possible Link state change interrupts that 	 * could have popped up just before Enabling the card.	 */	val64 = readq(&bar0->mac_rmac_err_reg);	if (val64)		writeq(val64, &bar0->mac_rmac_err_reg);	/* Verify if the device is ready to be enabled, if so enable 	 * it.	 */	val64 = readq(&bar0->adapter_status);	if (!verify_xena_quiescence(val64, nic->device_enabled_once)) {		DBG_PRINT(ERR_DBG, "%s: device is not ready, ", dev->name);		DBG_PRINT(ERR_DBG, "Adapter status reads: 0x%llx\n",			  (unsigned long long) val64);		return FAILURE;	}	/*  Enable select interrupts */	interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR | TX_MAC_INTR |	    RX_MAC_INTR;	en_dis_able_NicIntrs(nic, interruptible, ENABLE_INTRS);	/* With some switches, link might be already up at this point.	 * Because of this weird behavior, when we enable laser, 	 * we may not get link. We need to handle this. We cannot 	 * figure out which switch is misbehaving. So we are forced to 	 * make a global change. 	 */	/* Enabling Laser. */	val64 = readq(&bar0->adapter_control);	val64 |= ADAPTER_EOI_TX_ON;	writeq(val64, &bar0->adapter_control);	/* SXE-002: Initialize link and activity LED */	subid = nic->pdev->subsystem_device;	if ((subid & 0xFF) >= 0x07) {		val64 = readq(&bar0->gpio_control);		val64 |= 0x0000800000000000ULL;		writeq(val64, &bar0->gpio_control);		val64 = 0x0411040400000000ULL;		writeq(val64, (void *) ((u8 *) bar0 + 0x2700));	}	/* 	 * 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	 */	writeq(0x8007051500000000ULL, &bar0->dtx_control);	val64 = readq(&bar0->dtx_control);	writeq(0x80070515000000E0ULL, &bar0->dtx_control);	val64 = readq(&bar0->dtx_control);	writeq(0x80070515001F00E4ULL, &bar0->dtx_control);	val64 = readq(&bar0->dtx_control);	return SUCCESS;}/*   *  Input Arguments:  *   nic - device private variable. *  Return Value:  *   void. *  Description:  *   Free all queued Tx buffers. */void freeTxBuffers(struct s2io_nic *nic){	struct net_device *dev = nic->dev;	struct sk_buff *skb;	TxD_t *txdp;	int i, j;#if DEBUG_ON	int cnt = 0;#endif	mac_info_t *mac_control;	struct config_param *config;	mac_control = &nic->mac_control;	config = &nic->config;	for (i = 0; i < config->TxFIFONum; i++) {		for (j = 0; j < config->TxCfg[i].FifoLen - 1; j++) {			txdp = mac_control->txdl_start[i] +			    (config->MaxTxDs * j);			if (!(txdp->Control_1 & TXD_LIST_OWN_XENA)) {				/* If owned by host, ignore */				continue;			}			skb =			    (struct sk_buff *) ((unsigned long) txdp->						Host_Control);			if (skb == NULL) {				DBG_PRINT(ERR_DBG, "%s: NULL skb ",					  dev->name);				DBG_PRINT(ERR_DBG, "in Tx Int\n");				return;			}#if DEBUG_ON			cnt++;#endif			dev_kfree_skb(skb);			memset(txdp, 0, sizeof(TxD_t));		}#if DEBUG_ON		DBG_PRINT(INTR_DBG,			  "%s:forcibly freeing %d skbs on FIFO%d\n",			  dev->name, cnt, i);#endif	}}/*   *  Input Arguments:  *   nic - device private variable. *  Return Value:  *   void. *  Description:  *   This function does exactly the opposite of what the startNic()  *   function does. This function is called to stop  *   the device. */static void stopNic(struct s2io_nic *nic){	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;	register u64 val64 = 0;	u16 interruptible, i;	mac_info_t *mac_control;	struct config_param *config;	mac_control = &nic->mac_control;	config = &nic->config;/*  Disable all interrupts */	interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR | TX_MAC_INTR |	    RX_MAC_INTR;	en_dis_able_NicIntrs(nic, interruptible, DISABLE_INTRS);/*  Disable PRCs */	for (i = 0; i < config->RxRingNum; i++) {		val64 = readq(&bar0->prc_ctrl_n[i]);		val64 &= ~((u64) PRC_CTRL_RC_ENABLED);		writeq(val64, &bar0->prc_ctrl_n[i]);	}}/*   *  Input Arguments:  *  device private variable *  Return Value:  *  SUCCESS on success or an appropriate -ve value on failure. *  Description:  *  The function allocates Rx side skbs and puts the physical *  address of these buffers into the RxD buffer pointers, so that the NIC *  can DMA the received frame into these locations.

⌨️ 快捷键说明

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