diff options
Diffstat (limited to 'drivers/atm/iphase.c')
-rw-r--r-- | drivers/atm/iphase.c | 265 |
1 files changed, 145 insertions, 120 deletions
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index cb90f7a3e07..3d0c2b0fed9 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -818,127 +818,152 @@ static void ia_hw_type(IADEV *iadev) { } -static void IaFrontEndIntr(IADEV *iadev) { - volatile IA_SUNI *suni; - volatile ia_mb25_t *mb25; - volatile suni_pm7345_t *suni_pm7345; - - 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 */ - (void) 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; - (void) 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; - (void) suni->suni_rsop_status; - 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; +static u32 ia_phy_read32(struct iadev_priv *ia, unsigned int reg) +{ + return readl(ia->phy + (reg >> 2)); +} + +static void ia_phy_write32(struct iadev_priv *ia, unsigned int reg, u32 val) +{ + writel(val, ia->phy + (reg >> 2)); +} + +static void ia_frontend_intr(struct iadev_priv *iadev) +{ + u32 status; + + if (iadev->phy_type & FE_25MBIT_PHY) { + status = ia_phy_read32(iadev, MB25_INTR_STATUS); + iadev->carrier_detect = (status & MB25_IS_GSB) ? 1 : 0; + } else if (iadev->phy_type & FE_DS3_PHY) { + ia_phy_read32(iadev, SUNI_DS3_FRM_INTR_STAT); + status = ia_phy_read32(iadev, SUNI_DS3_FRM_STAT); + iadev->carrier_detect = (status & SUNI_DS3_LOSV) ? 0 : 1; + } else if (iadev->phy_type & FE_E3_PHY) { + ia_phy_read32(iadev, SUNI_E3_FRM_MAINT_INTR_IND); + status = ia_phy_read32(iadev, SUNI_E3_FRM_FRAM_INTR_IND_STAT); + iadev->carrier_detect = (status & SUNI_E3_LOS) ? 0 : 1; + } else { + status = ia_phy_read32(iadev, SUNI_RSOP_STATUS); + iadev->carrier_detect = (status & SUNI_LOSV) ? 0 : 1; + } + + printk(KERN_INFO "IA: SUNI carrier %s\n", + iadev->carrier_detect ? "detected" : "lost signal"); } -static void ia_mb25_init (IADEV *iadev) +static void ia_mb25_init(struct iadev_priv *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; -} + ia_phy_write32(iadev, MB25_MASTER_CTRL, MB25_MC_DRIC | MB25_MC_DREC); + ia_phy_write32(iadev, MB25_DIAG_CONTROL, 0); + + iadev->carrier_detect = + (ia_phy_read32(iadev, MB25_INTR_STATUS) & MB25_IS_GSB) ? 1 : 0; +} -static void ia_suni_pm7345_init (IADEV *iadev) +struct ia_reg { + u16 reg; + u16 val; +}; + +static void ia_phy_write(struct iadev_priv *iadev, + const struct ia_reg *regs, int len) { - 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 = - suni_pm7345->suni_rxcp_idle_pat_h2 = - 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 = - suni_pm7345->suni_rxcp_cell_pat_h2 = - suni_pm7345->suni_rxcp_cell_pat_h3 = 0; - suni_pm7345->suni_rxcp_cell_pat_h4 = 1; - - suni_pm7345->suni_rxcp_cell_mask_h1 = - suni_pm7345->suni_rxcp_cell_mask_h2 = - suni_pm7345->suni_rxcp_cell_mask_h3 = - 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); + while (len--) { + ia_phy_write32(iadev, regs->reg, regs->val); + regs++; + } +} + +static void ia_suni_pm7345_init_ds3(struct iadev_priv *iadev) +{ + static const struct ia_reg suni_ds3_init [] = { + { SUNI_DS3_FRM_INTR_ENBL, 0x17 }, + { SUNI_DS3_FRM_CFG, 0x01 }, + { SUNI_DS3_TRAN_CFG, 0x01 }, + { SUNI_CONFIG, 0 }, + { SUNI_SPLR_CFG, 0 }, + { SUNI_SPLT_CFG, 0 } + }; + u32 status; + + status = ia_phy_read32(iadev, SUNI_DS3_FRM_STAT); + iadev->carrier_detect = (status & SUNI_DS3_LOSV) ? 0 : 1; + + ia_phy_write(iadev, suni_ds3_init, ARRAY_SIZE(suni_ds3_init)); +} + +static void ia_suni_pm7345_init_e3(struct iadev_priv *iadev) +{ + static const struct ia_reg suni_e3_init [] = { + { SUNI_E3_FRM_FRAM_OPTIONS, 0x04 }, + { SUNI_E3_FRM_MAINT_OPTIONS, 0x20 }, + { SUNI_E3_FRM_FRAM_INTR_ENBL, 0x1d }, + { SUNI_E3_FRM_MAINT_INTR_ENBL, 0x30 }, + { SUNI_E3_TRAN_STAT_DIAG_OPTIONS, 0 }, + { SUNI_E3_TRAN_FRAM_OPTIONS, 0x01 }, + { SUNI_CONFIG, SUNI_PM7345_E3ENBL }, + { SUNI_SPLR_CFG, 0x41 }, + { SUNI_SPLT_CFG, 0x41 } + }; + u32 status; + + status = ia_phy_read32(iadev, SUNI_E3_FRM_FRAM_INTR_IND_STAT); + iadev->carrier_detect = (status & SUNI_E3_LOS) ? 0 : 1; + ia_phy_write(iadev, suni_e3_init, ARRAY_SIZE(suni_e3_init)); +} + +static void ia_suni_pm7345_init(struct iadev_priv *iadev) +{ + static const struct ia_reg suni_init [] = { + /* Enable RSOP loss of signal interrupt. */ + { SUNI_INTR_ENBL, 0x28 }, + /* Clear error counters. */ + { SUNI_ID_RESET, 0 }, + /* Clear "PMCTST" in master test register. */ + { SUNI_MASTER_TEST, 0 }, + + { SUNI_RXCP_CTRL, 0x2c }, + { SUNI_RXCP_FCTRL, 0x81 }, + + { SUNI_RXCP_IDLE_PAT_H1, 0 }, + { SUNI_RXCP_IDLE_PAT_H2, 0 }, + { SUNI_RXCP_IDLE_PAT_H3, 0 }, + { SUNI_RXCP_IDLE_PAT_H4, 0x01 }, + + { SUNI_RXCP_IDLE_MASK_H1, 0xff }, + { SUNI_RXCP_IDLE_MASK_H2, 0xff }, + { SUNI_RXCP_IDLE_MASK_H3, 0xff }, + { SUNI_RXCP_IDLE_MASK_H4, 0xfe }, + + { SUNI_RXCP_CELL_PAT_H1, 0 }, + { SUNI_RXCP_CELL_PAT_H2, 0 }, + { SUNI_RXCP_CELL_PAT_H3, 0 }, + { SUNI_RXCP_CELL_PAT_H4, 0x01 }, + + { SUNI_RXCP_CELL_MASK_H1, 0xff }, + { SUNI_RXCP_CELL_MASK_H2, 0xff }, + { SUNI_RXCP_CELL_MASK_H3, 0xff }, + { SUNI_RXCP_CELL_MASK_H4, 0xff }, + + { SUNI_TXCP_CTRL, 0xa4 }, + { SUNI_TXCP_INTR_EN_STS, 0x10 }, + { SUNI_TXCP_IDLE_PAT_H5, 0x55 } + }; + + if (iadev->phy_type & FE_DS3_PHY) + ia_suni_pm7345_init_ds3(iadev); + else + ia_suni_pm7345_init_e3(iadev); + + ia_phy_write(iadev, suni_init, ARRAY_SIZE(suni_init)); + + ia_phy_write32(iadev, SUNI_CONFIG, ia_phy_read32(iadev, 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__ */ @@ -1425,10 +1450,10 @@ static int rx_init(struct atm_dev *dev) iadev->dma + IPHASE5575_RX_LIST_ADDR); IF_INIT(printk("Tx Dle list addr: 0x%p value: 0x%0x\n", iadev->dma+IPHASE5575_TX_LIST_ADDR, - *(u32*)(iadev->dma+IPHASE5575_TX_LIST_ADDR)); + readl(iadev->dma + IPHASE5575_TX_LIST_ADDR)); printk("Rx Dle list addr: 0x%p value: 0x%0x\n", iadev->dma+IPHASE5575_RX_LIST_ADDR, - *(u32*)(iadev->dma+IPHASE5575_RX_LIST_ADDR));) + readl(iadev->dma + IPHASE5575_RX_LIST_ADDR));) writew(0xffff, iadev->reass_reg+REASS_MASK_REG); writew(0, iadev->reass_reg+MODE_REG); @@ -2208,7 +2233,7 @@ static irqreturn_t ia_int(int irq, void *dev_id) if (status & STAT_DLERINT) { /* Clear this bit by writing a 1 to it. */ - *(u_int *)(iadev->reg+IPHASE5575_BUS_STATUS_REG) = STAT_DLERINT; + writel(STAT_DLERINT, iadev->reg + IPHASE5575_BUS_STATUS_REG); rx_dle_intr(dev); } if (status & STAT_SEGINT) @@ -2219,13 +2244,13 @@ static irqreturn_t ia_int(int irq, void *dev_id) } if (status & STAT_DLETINT) { - *(u_int *)(iadev->reg+IPHASE5575_BUS_STATUS_REG) = STAT_DLETINT; + writel(STAT_DLETINT, iadev->reg + IPHASE5575_BUS_STATUS_REG); tx_dle_intr(dev); } if (status & (STAT_FEINT | STAT_ERRINT | STAT_MARKINT)) { if (status & STAT_FEINT) - IaFrontEndIntr(iadev); + ia_frontend_intr(iadev); } } return IRQ_RETVAL(handled); @@ -2556,7 +2581,7 @@ static int __devinit ia_start(struct atm_dev *dev) goto err_free_rx; } /* Get iadev->carrier_detect status */ - IaFrontEndIntr(iadev); + ia_frontend_intr(iadev); } return 0; @@ -2827,7 +2852,7 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg) case 0xb: if (!capable(CAP_NET_ADMIN)) return -EPERM; - IaFrontEndIntr(iadev); + ia_frontend_intr(iadev); break; case 0xa: if (!capable(CAP_NET_ADMIN)) return -EPERM; |