📄 s2io.c
字号:
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; } /* Enable all configured Tx FIFO partitions */ val64 = readq(&bar0->tx_fifo_partition_0); val64 |= (TX_FIFO_PARTITION_EN); writeq(val64, &bar0->tx_fifo_partition_0); /* 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 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]); } } /* Disable differentiated services steering logic */ for (i = 0; i < 64; i++) { if (rts_ds_steer(nic, i, 0) == FAILURE) { DBG_PRINT(ERR_DBG, "%s: failed rts ds steering", dev->name); DBG_PRINT(ERR_DBG, "set on codepoint %d\n", i); return -ENODEV; } } /* Program statistics memory */ writeq(mac_control->stats_mem_phy, &bar0->stat_addr); if (nic->device_type == XFRAME_II_DEVICE) { val64 = STAT_BC(0x320); writeq(val64, &bar0->stat_byte_cnt); } /* * Initializing the sampling rate for the device to calculate the * bandwidth utilization. */ val64 = MAC_TX_LINK_UTIL_VAL(tmac_util_period) | MAC_RX_LINK_UTIL_VAL(rmac_util_period); writeq(val64, &bar0->mac_link_util); /* * Initializing the Transmit and Receive Traffic Interrupt * Scheme. */ /* * TTI Initialization. Default Tx timer gets us about * 250 interrupts per sec. Continuous interrupts are enabled * by default. */ if (nic->device_type == XFRAME_II_DEVICE) { int count = (nic->config.bus_speed * 125)/2; val64 = TTI_DATA1_MEM_TX_TIMER_VAL(count); } else { val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0x2078); } val64 |= 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; 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); writeq(val64, &bar0->tti_data2_mem); val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD; writeq(val64, &bar0->tti_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. */ time = 0; while (TRUE) { val64 = readq(&bar0->tti_command_mem); if (!(val64 & TTI_CMD_MEM_STROBE_NEW_CMD)) { break; } if (time > 10) { DBG_PRINT(ERR_DBG, "%s: TTI init Failed\n", dev->name); return -ENODEV; } msleep(50); time++; } /* RTI Initialization */ if (nic->device_type == XFRAME_II_DEVICE) { /* * Programmed to generate Apprx 500 Intrs per * second */ int count = (nic->config.bus_speed * 125)/4; val64 = RTI_DATA1_MEM_RX_TIMER_VAL(count); } else val64 = RTI_DATA1_MEM_RX_TIMER_VAL(0xFFF); val64 |= RTI_DATA1_MEM_RX_URNG_A(0xA) | RTI_DATA1_MEM_RX_URNG_B(0x10) | RTI_DATA1_MEM_RX_URNG_C(0x30) | RTI_DATA1_MEM_RX_TIMER_AC_EN; writeq(val64, &bar0->rti_data1_mem); val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) | RTI_DATA2_MEM_RX_UFC_B(0x2) ; if (nic->config.intr_type == MSI_X) val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x20) | \ RTI_DATA2_MEM_RX_UFC_D(0x40)); else val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x40) | \ RTI_DATA2_MEM_RX_UFC_D(0x80)); writeq(val64, &bar0->rti_data2_mem); for (i = 0; i < config->rx_ring_num; i++) { val64 = RTI_CMD_MEM_WE | RTI_CMD_MEM_STROBE_NEW_CMD | RTI_CMD_MEM_OFFSET(i); 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. */ time = 0; while (TRUE) { val64 = readq(&bar0->rti_command_mem); if (!(val64 & RTI_CMD_MEM_STROBE_NEW_CMD)) break; if (time > 10) { DBG_PRINT(ERR_DBG, "%s: RTI init Failed\n", dev->name); return -ENODEV; } time++; msleep(50); } } /* * Initializing proper values as Pause threshold into all * the 8 Queues on Rx side. */ writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q0q3); writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q4q7); /* Disable RMAC PAD STRIPPING */ add = &bar0->mac_cfg; val64 = readq(&bar0->mac_cfg); val64 &= ~(MAC_CFG_RMAC_STRIP_PAD); 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)); val64 = readq(&bar0->mac_cfg); /* Enable FCS stripping by adapter */ add = &bar0->mac_cfg; val64 = readq(&bar0->mac_cfg); val64 |= MAC_CFG_RMAC_STRIP_FCS; if (nic->device_type == XFRAME_II_DEVICE) writeq(val64, &bar0->mac_cfg); else { 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)); } /* * Set the time value to be inserted in the pause frame * generated by xena. */ val64 = readq(&bar0->rmac_pause_cfg); val64 &= ~(RMAC_PAUSE_HG_PTIME(0xffff)); val64 |= RMAC_PAUSE_HG_PTIME(nic->mac_control.rmac_pause_time); writeq(val64, &bar0->rmac_pause_cfg); /* * Set the Threshold Limit for Generating the pause frame * If the amount of data in any Queue exceeds ratio of * (mac_control.mc_pause_threshold_q0q3 or q4q7)/256 * pause frame is generated */ val64 = 0; for (i = 0; i < 4; i++) { val64 |= (((u64) 0xFF00 | nic->mac_control. mc_pause_threshold_q0q3) << (i * 2 * 8)); } writeq(val64, &bar0->mc_pause_thresh_q0q3); val64 = 0; for (i = 0; i < 4; i++) { val64 |= (((u64) 0xFF00 | nic->mac_control. mc_pause_threshold_q4q7) << (i * 2 * 8)); } writeq(val64, &bar0->mc_pause_thresh_q4q7); /* * TxDMA will stop Read request if the number of read split has * exceeded the limit pointed by shared_splits */ val64 = readq(&bar0->pic_control); val64 |= PIC_CNTL_SHARED_SPLITS(shared_splits); writeq(val64, &bar0->pic_control); if (nic->config.bus_speed == 266) { writeq(TXREQTO_VAL(0x7f) | TXREQTO_EN, &bar0->txreqtimeout); writeq(0x0, &bar0->read_retry_delay); writeq(0x0, &bar0->write_retry_delay); } /* * Programming the Herc to split every write transaction * that does not start on an ADB to reduce disconnects. */ if (nic->device_type == XFRAME_II_DEVICE) { val64 = FAULT_BEHAVIOUR | EXT_REQ_EN | MISC_LINK_STABILITY_PRD(3); writeq(val64, &bar0->misc_control); val64 = readq(&bar0->pic_control2); val64 &= ~(s2BIT(13)|s2BIT(14)|s2BIT(15)); writeq(val64, &bar0->pic_control2); } if (strstr(nic->product_name, "CX4")) { val64 = TMAC_AVG_IPG(0x17); writeq(val64, &bar0->tmac_avg_ipg); } return SUCCESS;}#define LINK_UP_DOWN_INTERRUPT 1#define MAC_RMAC_ERR_TIMER 2static int s2io_link_fault_indication(struct s2io_nic *nic){ if (nic->config.intr_type != INTA) return MAC_RMAC_ERR_TIMER; if (nic->device_type == XFRAME_II_DEVICE) return LINK_UP_DOWN_INTERRUPT; else return MAC_RMAC_ERR_TIMER;}/** * do_s2io_write_bits - update alarm bits in alarm register * @value: alarm bits * @flag: interrupt status * @addr: address value * Description: update alarm bits in alarm register * Return Value: * NONE. */static void do_s2io_write_bits(u64 value, int flag, void __iomem *addr){ u64 temp64; temp64 = readq(addr); if(flag == ENABLE_INTRS) temp64 &= ~((u64) value); else temp64 |= ((u64) value); writeq(temp64, addr);}static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag){ struct XENA_dev_config __iomem *bar0 = nic->bar0; register u64 gen_int_mask = 0; if (mask & TX_DMA_INTR) { gen_int_mask |= TXDMA_INT_M; do_s2io_write_bits(TXDMA_TDA_INT | TXDMA_PFC_INT | TXDMA_PCC_INT | TXDMA_TTI_INT |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -