📄 iphase.c
字号:
NVRAM_CMD(IAREAD + addr); /* * Now read the rest of the bits, the next bit read is D14, then D13, * and so on. */ val = 0; for (i=15; i>=0; i--) { NVRAM_CLKIN(t); val |= (t << i); } NVRAM_CLR_CE; CFG_AND(~NVDI); return val;}static void ia_hw_type(IADEV *iadev) { u_short memType = ia_eeprom_get(iadev, 25); iadev->memType = memType; if ((memType & MEM_SIZE_MASK) == MEM_SIZE_1M) { iadev->num_tx_desc = IA_TX_BUF; iadev->tx_buf_sz = IA_TX_BUF_SZ; iadev->num_rx_desc = IA_RX_BUF; iadev->rx_buf_sz = IA_RX_BUF_SZ; } else if ((memType & MEM_SIZE_MASK) == MEM_SIZE_512K) { if (IA_TX_BUF == DFL_TX_BUFFERS) iadev->num_tx_desc = IA_TX_BUF / 2; else iadev->num_tx_desc = IA_TX_BUF; iadev->tx_buf_sz = IA_TX_BUF_SZ; if (IA_RX_BUF == DFL_RX_BUFFERS) iadev->num_rx_desc = IA_RX_BUF / 2; else iadev->num_rx_desc = IA_RX_BUF; iadev->rx_buf_sz = IA_RX_BUF_SZ; } else { if (IA_TX_BUF == DFL_TX_BUFFERS) iadev->num_tx_desc = IA_TX_BUF / 8; else iadev->num_tx_desc = IA_TX_BUF; iadev->tx_buf_sz = IA_TX_BUF_SZ; if (IA_RX_BUF == DFL_RX_BUFFERS) iadev->num_rx_desc = IA_RX_BUF / 8; else iadev->num_rx_desc = IA_RX_BUF; iadev->rx_buf_sz = IA_RX_BUF_SZ; } iadev->rx_pkt_ram = TX_PACKET_RAM + (iadev->num_tx_desc * iadev->tx_buf_sz); IF_INIT(printk("BUF: tx=%d,sz=%d rx=%d sz= %d rx_pkt_ram=%d\n", iadev->num_tx_desc, iadev->tx_buf_sz, iadev->num_rx_desc, iadev->rx_buf_sz, iadev->rx_pkt_ram);)#if 0 if ((memType & FE_MASK) == FE_SINGLE_MODE) { iadev->phy_type = PHY_OC3C_S; else if ((memType & FE_MASK) == FE_UTP_OPTION) iadev->phy_type = PHY_UTP155; else iadev->phy_type = PHY_OC3C_M;#endif iadev->phy_type = memType & FE_MASK; IF_INIT(printk("memType = 0x%x iadev->phy_type = 0x%x\n", memType,iadev->phy_type);) if (iadev->phy_type == FE_25MBIT_PHY) iadev->LineRate = (u32)(((25600000/8)*26)/(27*53)); else if (iadev->phy_type == FE_DS3_PHY) iadev->LineRate = (u32)(((44736000/8)*26)/(27*53)); else if (iadev->phy_type == FE_E3_PHY) iadev->LineRate = (u32)(((34368000/8)*26)/(27*53)); else iadev->LineRate = (u32)(ATM_OC3_PCR); IF_INIT(printk("iadev->LineRate = %d \n", iadev->LineRate);)}static void IaFrontEndIntr(IADEV *iadev) { volatile IA_SUNI *suni; volatile ia_mb25_t *mb25; volatile suni_pm7345_t *suni_pm7345; u32 intr_status; u_int frmr_intr; if(iadev->phy_type & FE_25MBIT_PHY) { mb25 = (ia_mb25_t*)iadev->phy; iadev->carrier_detect = Boolean(mb25->mb25_intr_status & MB25_IS_GSB); } else if (iadev->phy_type & FE_DS3_PHY) { suni_pm7345 = (suni_pm7345_t *)iadev->phy; /* clear FRMR interrupts */ frmr_intr = suni_pm7345->suni_ds3_frm_intr_stat; iadev->carrier_detect = Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV)); } else if (iadev->phy_type & FE_E3_PHY ) { suni_pm7345 = (suni_pm7345_t *)iadev->phy; frmr_intr = suni_pm7345->suni_e3_frm_maint_intr_ind; iadev->carrier_detect = Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat&SUNI_E3_LOS)); } else { suni = (IA_SUNI *)iadev->phy; intr_status = suni->suni_rsop_status & 0xff; iadev->carrier_detect = Boolean(!(suni->suni_rsop_status & SUNI_LOSV)); } if (iadev->carrier_detect) printk("IA: SUNI carrier detected\n"); else printk("IA: SUNI carrier lost signal\n"); return;}void ia_mb25_init (IADEV *iadev){ volatile ia_mb25_t *mb25 = (ia_mb25_t*)iadev->phy;#if 0 mb25->mb25_master_ctrl = MB25_MC_DRIC | MB25_MC_DREC | MB25_MC_ENABLED;#endif mb25->mb25_master_ctrl = MB25_MC_DRIC | MB25_MC_DREC; mb25->mb25_diag_control = 0; /* * Initialize carrier detect state */ iadev->carrier_detect = Boolean(mb25->mb25_intr_status & MB25_IS_GSB); return;} void ia_suni_pm7345_init (IADEV *iadev){ volatile suni_pm7345_t *suni_pm7345 = (suni_pm7345_t *)iadev->phy; if (iadev->phy_type & FE_DS3_PHY) { iadev->carrier_detect = Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV)); suni_pm7345->suni_ds3_frm_intr_enbl = 0x17; suni_pm7345->suni_ds3_frm_cfg = 1; suni_pm7345->suni_ds3_tran_cfg = 1; suni_pm7345->suni_config = 0; suni_pm7345->suni_splr_cfg = 0; suni_pm7345->suni_splt_cfg = 0; } else { iadev->carrier_detect = Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat & SUNI_E3_LOS)); suni_pm7345->suni_e3_frm_fram_options = 0x4; suni_pm7345->suni_e3_frm_maint_options = 0x20; suni_pm7345->suni_e3_frm_fram_intr_enbl = 0x1d; suni_pm7345->suni_e3_frm_maint_intr_enbl = 0x30; suni_pm7345->suni_e3_tran_stat_diag_options = 0x0; suni_pm7345->suni_e3_tran_fram_options = 0x1; suni_pm7345->suni_config = SUNI_PM7345_E3ENBL; suni_pm7345->suni_splr_cfg = 0x41; suni_pm7345->suni_splt_cfg = 0x41; } /* * Enable RSOP loss of signal interrupt. */ suni_pm7345->suni_intr_enbl = 0x28; /* * Clear error counters */ suni_pm7345->suni_id_reset = 0; /* * Clear "PMCTST" in master test register. */ suni_pm7345->suni_master_test = 0; suni_pm7345->suni_rxcp_ctrl = 0x2c; suni_pm7345->suni_rxcp_fctrl = 0x81; suni_pm7345->suni_rxcp_idle_pat_h1 = 0; suni_pm7345->suni_rxcp_idle_pat_h2 = 0; suni_pm7345->suni_rxcp_idle_pat_h3 = 0; suni_pm7345->suni_rxcp_idle_pat_h4 = 1; suni_pm7345->suni_rxcp_idle_mask_h1 = 0xff; suni_pm7345->suni_rxcp_idle_mask_h2 = 0xff; suni_pm7345->suni_rxcp_idle_mask_h3 = 0xff; suni_pm7345->suni_rxcp_idle_mask_h4 = 0xfe; suni_pm7345->suni_rxcp_cell_pat_h1 = 0; suni_pm7345->suni_rxcp_cell_pat_h2 = 0; suni_pm7345->suni_rxcp_cell_pat_h3 = 0; suni_pm7345->suni_rxcp_cell_pat_h4 = 1; suni_pm7345->suni_rxcp_cell_mask_h1 = 0xff; suni_pm7345->suni_rxcp_cell_mask_h2 = 0xff; suni_pm7345->suni_rxcp_cell_mask_h3 = 0xff; suni_pm7345->suni_rxcp_cell_mask_h4 = 0xff; suni_pm7345->suni_txcp_ctrl = 0xa4; suni_pm7345->suni_txcp_intr_en_sts = 0x10; suni_pm7345->suni_txcp_idle_pat_h5 = 0x55; suni_pm7345->suni_config &= ~(SUNI_PM7345_LLB | SUNI_PM7345_CLB | SUNI_PM7345_DLB | SUNI_PM7345_PLB);#ifdef __SNMP__ suni_pm7345->suni_rxcp_intr_en_sts |= SUNI_OOCDE;#endif __SNMP__ return;}/***************************** IA_LIB END *****************************/ /* pwang_test debug utility */int tcnter = 0, rcnter = 0;void xdump( u_char* cp, int length, char* prefix ){ int col, count; u_char prntBuf[120]; u_char* pBuf = prntBuf; count = 0; while(count < length){ pBuf += sprintf( pBuf, "%s", prefix ); for(col = 0;count + col < length && col < 16; col++){ if (col != 0 && (col % 4) == 0) pBuf += sprintf( pBuf, " " ); pBuf += sprintf( pBuf, "%02X ", cp[count + col] ); } while(col++ < 16){ /* pad end of buffer with blanks */ if ((col % 4) == 0) sprintf( pBuf, " " ); pBuf += sprintf( pBuf, " " ); } pBuf += sprintf( pBuf, " " ); for(col = 0;count + col < length && col < 16; col++){ if (isprint((int)cp[count + col])) pBuf += sprintf( pBuf, "%c", cp[count + col] ); else pBuf += sprintf( pBuf, "." ); } sprintf( pBuf, "\n" ); // SPrint(prntBuf); printk(prntBuf); count += col; pBuf = prntBuf; }} /* close xdump(... */ static struct atm_dev *ia_boards = NULL; #define ACTUAL_RAM_BASE \ RAM_BASE*((iadev->mem)/(128 * 1024)) #define ACTUAL_SEG_RAM_BASE \ IPHASE5575_FRAG_CONTROL_RAM_BASE*((iadev->mem)/(128 * 1024)) #define ACTUAL_REASS_RAM_BASE \ IPHASE5575_REASS_CONTROL_RAM_BASE*((iadev->mem)/(128 * 1024)) /*-- some utilities and memory allocation stuff will come here -------------*/ void desc_dbg(IADEV *iadev) { u_short tcq_wr_ptr, tcq_st_ptr, tcq_ed_ptr; u32 tmp, i; // regval = readl((u32)ia_cmds->maddr); tcq_wr_ptr = readw(iadev->seg_reg+TCQ_WR_PTR); printk("B_tcq_wr = 0x%x desc = %d last desc = %d\n", tcq_wr_ptr, readw(iadev->seg_ram+tcq_wr_ptr), readw(iadev->seg_ram+tcq_wr_ptr-2)); printk(" host_tcq_wr = 0x%x host_tcq_rd = 0x%x \n", iadev->host_tcq_wr, iadev->ffL.tcq_rd); tcq_st_ptr = readw(iadev->seg_reg+TCQ_ST_ADR); tcq_ed_ptr = readw(iadev->seg_reg+TCQ_ED_ADR); printk("tcq_st_ptr = 0x%x tcq_ed_ptr = 0x%x \n", tcq_st_ptr, tcq_ed_ptr); i = 0; while (tcq_st_ptr != tcq_ed_ptr) { tmp = iadev->seg_ram+tcq_st_ptr; printk("TCQ slot %d desc = %d Addr = 0x%x\n", i++, readw(tmp), tmp); tcq_st_ptr += 2; } for(i=0; i <iadev->num_tx_desc; i++) printk("Desc_tbl[%d] = %d \n", i, iadev->desc_tbl[i].timestamp);} /*----------------------------- Recieving side stuff --------------------------*/ static void rx_excp_rcvd(struct atm_dev *dev) { #if 0 /* closing the receiving size will cause too many excp int */ IADEV *iadev; u_short state; u_short excpq_rd_ptr; //u_short *ptr; int vci, error = 1; iadev = INPH_IA_DEV(dev); state = readl(iadev->reass_reg + STATE_REG) & 0xffff; while((state & EXCPQ_EMPTY) != EXCPQ_EMPTY) { printk("state = %x \n", state); excpq_rd_ptr = readw(iadev->reass_reg + EXCP_Q_RD_PTR) & 0xffff; printk("state = %x excpq_rd_ptr = %x \n", state, excpq_rd_ptr); if (excpq_rd_ptr == *(u16*)(iadev->reass_reg + EXCP_Q_WR_PTR)) IF_ERR(printk("excpq_rd_ptr is wrong!!!\n");) // TODO: update exception stat vci = readw(iadev->reass_ram+excpq_rd_ptr); error = readw(iadev->reass_ram+excpq_rd_ptr+2) & 0x0007; // pwang_test excpq_rd_ptr += 4; if (excpq_rd_ptr > (readw(iadev->reass_reg + EXCP_Q_ED_ADR)& 0xffff)) excpq_rd_ptr = readw(iadev->reass_reg + EXCP_Q_ST_ADR)& 0xffff; writew( excpq_rd_ptr, iadev->reass_reg + EXCP_Q_RD_PTR); state = readl(iadev->reass_reg + STATE_REG) & 0xffff; } #endif} static void free_desc(struct atm_dev *dev, int desc) { IADEV *iadev; iadev = INPH_IA_DEV(dev); writew(desc, iadev->reass_ram+iadev->rfL.fdq_wr); iadev->rfL.fdq_wr +=2; if (iadev->rfL.fdq_wr > iadev->rfL.fdq_ed) iadev->rfL.fdq_wr = iadev->rfL.fdq_st; writew(iadev->rfL.fdq_wr, iadev->reass_reg+FREEQ_WR_PTR); } static int rx_pkt(struct atm_dev *dev) { IADEV *iadev; struct atm_vcc *vcc; unsigned short status; struct rx_buf_desc *buf_desc_ptr; int desc; struct dle* wr_ptr; int len; struct sk_buff *skb; u_int buf_addr, dma_addr; iadev = INPH_IA_DEV(dev); if (iadev->rfL.pcq_rd == (readw(iadev->reass_reg+PCQ_WR_PTR)&0xffff)) { printk(KERN_ERR DEV_LABEL "(itf %d) Receive queue empty\n", dev->number); return -EINVAL; } /* mask 1st 3 bits to get the actual descno. */ desc = readw(iadev->reass_ram+iadev->rfL.pcq_rd) & 0x1fff; IF_RX(printk("reass_ram = 0x%x iadev->rfL.pcq_rd = 0x%x desc = %d\n", iadev->reass_ram, iadev->rfL.pcq_rd, desc); printk(" pcq_wr_ptr = 0x%x\n", readw(iadev->reass_reg+PCQ_WR_PTR)&0xffff);) /* update the read pointer - maybe we shud do this in the end*/ if ( iadev->rfL.pcq_rd== iadev->rfL.pcq_ed) iadev->rfL.pcq_rd = iadev->rfL.pcq_st; else iadev->rfL.pcq_rd += 2; writew(iadev->rfL.pcq_rd, iadev->reass_reg+PCQ_RD_PTR); /* get the buffer desc entry. update stuff. - doesn't seem to be any update necessary */ buf_desc_ptr = (struct rx_buf_desc *)iadev->RX_DESC_BASE_ADDR; /* make the ptr point to the corresponding buffer desc entry */ buf_desc_ptr += desc; if (!desc || (desc > iadev->num_rx_desc) || ((buf_desc_ptr->vc_index & 0xffff) > iadev->num_vc)) { free_desc(dev, desc); IF_ERR(printk("IA: bad descriptor desc = %d \n", desc);) return -1; } vcc = iadev->rx_open[buf_desc_ptr->vc_index & 0xffff]; if (!vcc) { free_desc(dev, desc); printk("IA: null vcc, drop PDU\n"); return -1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -