?? s2io.c
字號(hào):
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.
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -