]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/phy/broadcom/phy-brcm-usb-init.c
Merge tag 'ceph-for-5.6-rc1' of https://github.com/ceph/ceph-client
[linux.git] / drivers / phy / broadcom / phy-brcm-usb-init.c
index 91b5b09589d630c830a64253789f76377808f55d..9391ab42a12b39b5b1f4c0c5809eb0eaab7f3646 100644 (file)
@@ -42,6 +42,7 @@
 #define   USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK         0x80000000 /* option */
 #define USB_CTRL_EBRIDGE               0x0c
 #define   USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_MASK          0x00020000 /* option */
+#define   USB_CTRL_EBRIDGE_EBR_SCB_SIZE_MASK           0x00000f80 /* option */
 #define USB_CTRL_OBRIDGE               0x10
 #define   USB_CTRL_OBRIDGE_LS_KEEP_ALIVE_MASK          0x08000000
 #define USB_CTRL_MDIO                  0x14
@@ -57,6 +58,8 @@
 #define   USB_CTRL_USB_PM_SOFT_RESET_MASK              0x40000000 /* option */
 #define   USB_CTRL_USB_PM_USB20_HC_RESETB_MASK         0x30000000 /* option */
 #define   USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK     0x00300000 /* option */
+#define   USB_CTRL_USB_PM_RMTWKUP_EN_MASK              0x00000001
+#define USB_CTRL_USB_PM_STATUS         0x38
 #define USB_CTRL_USB30_CTL1            0x60
 #define   USB_CTRL_USB30_CTL1_PHY3_PLL_SEQ_START_MASK  0x00000010
 #define   USB_CTRL_USB30_CTL1_PHY3_RESETB_MASK         0x00010000
@@ -126,10 +129,6 @@ enum {
        USB_CTRL_SELECTOR_COUNT,
 };
 
-#define USB_CTRL_REG(base, reg)        ((void __iomem *)base + USB_CTRL_##reg)
-#define USB_XHCI_EC_REG(base, reg) ((void __iomem *)base + USB_XHCI_EC_##reg)
-#define USB_CTRL_MASK(reg, field) \
-       USB_CTRL_##reg##_##field##_MASK
 #define USB_CTRL_MASK_FAMILY(params, reg, field)                       \
        (params->usb_reg_bits_map[USB_CTRL_##reg##_##field##_SELECTOR])
 
@@ -140,13 +139,6 @@ enum {
        usb_ctrl_unset_family(params, USB_CTRL_##reg,   \
                USB_CTRL_##reg##_##field##_SELECTOR)
 
-#define USB_CTRL_SET(base, reg, field) \
-       usb_ctrl_set(USB_CTRL_REG(base, reg),           \
-                    USB_CTRL_##reg##_##field##_MASK)
-#define USB_CTRL_UNSET(base, reg, field)       \
-       usb_ctrl_unset(USB_CTRL_REG(base, reg),         \
-                      USB_CTRL_##reg##_##field##_MASK)
-
 #define MDIO_USB2      0
 #define MDIO_USB3      BIT(31)
 
@@ -176,6 +168,7 @@ static const struct id_to_type id_to_type_table[] = {
        { 0x33900000, BRCM_FAMILY_3390A0 },
        { 0x72500010, BRCM_FAMILY_7250B0 },
        { 0x72600000, BRCM_FAMILY_7260A0 },
+       { 0x72550000, BRCM_FAMILY_7260A0 },
        { 0x72680000, BRCM_FAMILY_7271A0 },
        { 0x72710000, BRCM_FAMILY_7271A0 },
        { 0x73640000, BRCM_FAMILY_7364A0 },
@@ -401,26 +394,14 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
        },
 };
 
-static inline u32 brcmusb_readl(void __iomem *addr)
-{
-       return readl(addr);
-}
-
-static inline void brcmusb_writel(u32 val, void __iomem *addr)
-{
-       writel(val, addr);
-}
-
 static inline
 void usb_ctrl_unset_family(struct brcm_usb_init_params *params,
                           u32 reg_offset, u32 field)
 {
        u32 mask;
-       void __iomem *reg;
 
        mask = params->usb_reg_bits_map[field];
-       reg = params->ctrl_regs + reg_offset;
-       brcmusb_writel(brcmusb_readl(reg) & ~mask, reg);
+       brcm_usb_ctrl_unset(params->regs[BRCM_REGS_CTRL] + reg_offset, mask);
 };
 
 static inline
@@ -428,45 +409,27 @@ void usb_ctrl_set_family(struct brcm_usb_init_params *params,
                         u32 reg_offset, u32 field)
 {
        u32 mask;
-       void __iomem *reg;
 
        mask = params->usb_reg_bits_map[field];
-       reg = params->ctrl_regs + reg_offset;
-       brcmusb_writel(brcmusb_readl(reg) | mask, reg);
+       brcm_usb_ctrl_set(params->regs[BRCM_REGS_CTRL] + reg_offset, mask);
 };
 
-static inline void usb_ctrl_set(void __iomem *reg, u32 field)
-{
-       u32 value;
-
-       value = brcmusb_readl(reg);
-       brcmusb_writel(value | field, reg);
-}
-
-static inline void usb_ctrl_unset(void __iomem *reg, u32 field)
-{
-       u32 value;
-
-       value = brcmusb_readl(reg);
-       brcmusb_writel(value & ~field, reg);
-}
-
 static u32 brcmusb_usb_mdio_read(void __iomem *ctrl_base, u32 reg, int mode)
 {
        u32 data;
 
        data = (reg << 16) | mode;
-       brcmusb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
+       brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
        data |= (1 << 24);
-       brcmusb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
+       brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
        data &= ~(1 << 24);
        /* wait for the 60MHz parallel to serial shifter */
        usleep_range(10, 20);
-       brcmusb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
+       brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
        /* wait for the 60MHz parallel to serial shifter */
        usleep_range(10, 20);
 
-       return brcmusb_readl(USB_CTRL_REG(ctrl_base, MDIO2)) & 0xffff;
+       return brcm_usb_readl(USB_CTRL_REG(ctrl_base, MDIO2)) & 0xffff;
 }
 
 static void brcmusb_usb_mdio_write(void __iomem *ctrl_base, u32 reg,
@@ -475,14 +438,14 @@ static void brcmusb_usb_mdio_write(void __iomem *ctrl_base, u32 reg,
        u32 data;
 
        data = (reg << 16) | val | mode;
-       brcmusb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
+       brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
        data |= (1 << 25);
-       brcmusb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
+       brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
        data &= ~(1 << 25);
 
        /* wait for the 60MHz parallel to serial shifter */
        usleep_range(10, 20);
-       brcmusb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
+       brcm_usb_writel(data, USB_CTRL_REG(ctrl_base, MDIO));
        /* wait for the 60MHz parallel to serial shifter */
        usleep_range(10, 20);
 }
@@ -581,7 +544,7 @@ static void brcmusb_usb3_pll_54mhz(struct brcm_usb_init_params *params)
 {
        u32 ofs;
        int ii;
-       void __iomem *ctrl_base = params->ctrl_regs;
+       void __iomem *ctrl_base = params->regs[BRCM_REGS_CTRL];
 
        /*
         * On newer B53 based SoC's, the reference clock for the
@@ -662,7 +625,7 @@ static void brcmusb_usb3_ssc_enable(void __iomem *ctrl_base)
 
 static void brcmusb_usb3_phy_workarounds(struct brcm_usb_init_params *params)
 {
-       void __iomem *ctrl_base = params->ctrl_regs;
+       void __iomem *ctrl_base = params->regs[BRCM_REGS_CTRL];
 
        brcmusb_usb3_pll_fix(ctrl_base);
        brcmusb_usb3_pll_54mhz(params);
@@ -704,21 +667,21 @@ static void brcmusb_memc_fix(struct brcm_usb_init_params *params)
 
 static void brcmusb_usb3_otp_fix(struct brcm_usb_init_params *params)
 {
-       void __iomem *xhci_ec_base = params->xhci_ec_regs;
+       void __iomem *xhci_ec_base = params->regs[BRCM_REGS_XHCI_EC];
        u32 val;
 
        if (params->family_id != 0x74371000 || !xhci_ec_base)
                return;
-       brcmusb_writel(0xa20c, USB_XHCI_EC_REG(xhci_ec_base, IRAADR));
-       val = brcmusb_readl(USB_XHCI_EC_REG(xhci_ec_base, IRADAT));
+       brcm_usb_writel(0xa20c, USB_XHCI_EC_REG(xhci_ec_base, IRAADR));
+       val = brcm_usb_readl(USB_XHCI_EC_REG(xhci_ec_base, IRADAT));
 
        /* set cfg_pick_ss_lock */
        val |= (1 << 27);
-       brcmusb_writel(val, USB_XHCI_EC_REG(xhci_ec_base, IRADAT));
+       brcm_usb_writel(val, USB_XHCI_EC_REG(xhci_ec_base, IRADAT));
 
        /* Reset USB 3.0 PHY for workaround to take effect */
-       USB_CTRL_UNSET(params->ctrl_regs, USB30_CTL1, PHY3_RESETB);
-       USB_CTRL_SET(params->ctrl_regs, USB30_CTL1, PHY3_RESETB);
+       USB_CTRL_UNSET(params->regs[BRCM_REGS_CTRL], USB30_CTL1, PHY3_RESETB);
+       USB_CTRL_SET(params->regs[BRCM_REGS_CTRL], USB30_CTL1, PHY3_RESETB);
 }
 
 static void brcmusb_xhci_soft_reset(struct brcm_usb_init_params *params,
@@ -747,7 +710,7 @@ static void brcmusb_xhci_soft_reset(struct brcm_usb_init_params *params,
  *   - default chip/rev.
  * NOTE: The minor rev is always ignored.
  */
-static enum brcm_family_type brcmusb_get_family_type(
+static enum brcm_family_type get_family_type(
        struct brcm_usb_init_params *params)
 {
        int last_type = -1;
@@ -775,9 +738,9 @@ static enum brcm_family_type brcmusb_get_family_type(
        return last_type;
 }
 
-void brcm_usb_init_ipp(struct brcm_usb_init_params *params)
+static void usb_init_ipp(struct brcm_usb_init_params *params)
 {
-       void __iomem *ctrl = params->ctrl_regs;
+       void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
        u32 reg;
        u32 orig_reg;
 
@@ -791,7 +754,7 @@ void brcm_usb_init_ipp(struct brcm_usb_init_params *params)
                        USB_CTRL_SET_FAMILY(params, USB30_CTL1, USB3_IPP);
        }
 
-       reg = brcmusb_readl(USB_CTRL_REG(ctrl, SETUP));
+       reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));
        orig_reg = reg;
        if (USB_CTRL_MASK_FAMILY(params, SETUP, STRAP_CC_DRD_MODE_ENABLE_SEL))
                /* Never use the strap, it's going away. */
@@ -799,8 +762,8 @@ void brcm_usb_init_ipp(struct brcm_usb_init_params *params)
                                              SETUP,
                                              STRAP_CC_DRD_MODE_ENABLE_SEL));
        if (USB_CTRL_MASK_FAMILY(params, SETUP, STRAP_IPP_SEL))
+               /* override ipp strap pin (if it exits) */
                if (params->ipp != 2)
-                       /* override ipp strap pin (if it exits) */
                        reg &= ~(USB_CTRL_MASK_FAMILY(params, SETUP,
                                                      STRAP_IPP_SEL));
 
@@ -808,50 +771,38 @@ void brcm_usb_init_ipp(struct brcm_usb_init_params *params)
        reg &= ~(USB_CTRL_MASK(SETUP, IPP) | USB_CTRL_MASK(SETUP, IOC));
        if (params->ioc)
                reg |= USB_CTRL_MASK(SETUP, IOC);
-       if (params->ipp == 1 && ((reg & USB_CTRL_MASK(SETUP, IPP)) == 0))
+       if (params->ipp == 1)
                reg |= USB_CTRL_MASK(SETUP, IPP);
-       brcmusb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
+       brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
 
        /*
         * If we're changing IPP, make sure power is off long enough
         * to turn off any connected devices.
         */
-       if (reg != orig_reg)
+       if ((reg ^ orig_reg) & USB_CTRL_MASK(SETUP, IPP))
                msleep(50);
 }
 
-int brcm_usb_init_get_dual_select(struct brcm_usb_init_params *params)
+static void usb_wake_enable(struct brcm_usb_init_params *params,
+                         bool enable)
 {
-       void __iomem *ctrl = params->ctrl_regs;
-       u32 reg = 0;
+       void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
 
-       if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {
-               reg = brcmusb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
-               reg &= USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,
-                                       PORT_MODE);
-       }
-       return reg;
+       if (enable)
+               USB_CTRL_SET(ctrl, USB_PM, RMTWKUP_EN);
+       else
+               USB_CTRL_UNSET(ctrl, USB_PM, RMTWKUP_EN);
 }
 
-void brcm_usb_init_set_dual_select(struct brcm_usb_init_params *params,
-                                  int mode)
+static void usb_init_common(struct brcm_usb_init_params *params)
 {
-       void __iomem *ctrl = params->ctrl_regs;
        u32 reg;
+       void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
 
-       if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {
-               reg = brcmusb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
-               reg &= ~USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,
-                                       PORT_MODE);
-               reg |= mode;
-               brcmusb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
-       }
-}
-
-void brcm_usb_init_common(struct brcm_usb_init_params *params)
-{
-       u32 reg;
-       void __iomem *ctrl = params->ctrl_regs;
+       /* Clear any pending wake conditions */
+       usb_wake_enable(params, false);
+       reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_PM_STATUS));
+       brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_PM_STATUS));
 
        /* Take USB out of power down */
        if (USB_CTRL_MASK_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN)) {
@@ -877,7 +828,7 @@ void brcm_usb_init_common(struct brcm_usb_init_params *params)
        /* Block auto PLL suspend by USB2 PHY (Sasi) */
        USB_CTRL_SET(ctrl, PLL_CTL, PLL_SUSPEND_EN);
 
-       reg = brcmusb_readl(USB_CTRL_REG(ctrl, SETUP));
+       reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));
        if (params->selected_family == BRCM_FAMILY_7364A0)
                /* Suppress overcurrent indication from USB30 ports for A0 */
                reg |= USB_CTRL_MASK_FAMILY(params, SETUP, OC3_DISABLE);
@@ -893,16 +844,16 @@ void brcm_usb_init_common(struct brcm_usb_init_params *params)
                reg |= USB_CTRL_MASK_FAMILY(params, SETUP, SCB1_EN);
        if (USB_CTRL_MASK_FAMILY(params, SETUP, SCB2_EN))
                reg |= USB_CTRL_MASK_FAMILY(params, SETUP, SCB2_EN);
-       brcmusb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
+       brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
 
        brcmusb_memc_fix(params);
 
        if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {
-               reg = brcmusb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
+               reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
                reg &= ~USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,
                                        PORT_MODE);
                reg |= params->mode;
-               brcmusb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
+               brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
        }
        if (USB_CTRL_MASK_FAMILY(params, USB_PM, BDC_SOFT_RESETB)) {
                switch (params->mode) {
@@ -924,10 +875,10 @@ void brcm_usb_init_common(struct brcm_usb_init_params *params)
        }
 }
 
-void brcm_usb_init_eohci(struct brcm_usb_init_params *params)
+static void usb_init_eohci(struct brcm_usb_init_params *params)
 {
        u32 reg;
-       void __iomem *ctrl = params->ctrl_regs;
+       void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
 
        if (USB_CTRL_MASK_FAMILY(params, USB_PM, USB20_HC_RESETB))
                USB_CTRL_SET_FAMILY(params, USB_PM, USB20_HC_RESETB);
@@ -940,19 +891,30 @@ void brcm_usb_init_eohci(struct brcm_usb_init_params *params)
                USB_CTRL_SET(ctrl, EBRIDGE, ESTOP_SCB_REQ);
 
        /* Setup the endian bits */
-       reg = brcmusb_readl(USB_CTRL_REG(ctrl, SETUP));
+       reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));
        reg &= ~USB_CTRL_SETUP_ENDIAN_BITS;
        reg |= USB_CTRL_MASK_FAMILY(params, SETUP, ENDIAN);
-       brcmusb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
+       brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
 
        if (params->selected_family == BRCM_FAMILY_7271A0)
                /* Enable LS keep alive fix for certain keyboards */
                USB_CTRL_SET(ctrl, OBRIDGE, LS_KEEP_ALIVE);
+
+       if (params->family_id == 0x72550000) {
+               /*
+                * Make the burst size 512 bytes to fix a hardware bug
+                * on the 7255a0. See HW7255-24.
+                */
+               reg = brcm_usb_readl(USB_CTRL_REG(ctrl, EBRIDGE));
+               reg &= ~USB_CTRL_MASK(EBRIDGE, EBR_SCB_SIZE);
+               reg |= 0x800;
+               brcm_usb_writel(reg, USB_CTRL_REG(ctrl, EBRIDGE));
+       }
 }
 
-void brcm_usb_init_xhci(struct brcm_usb_init_params *params)
+static void usb_init_xhci(struct brcm_usb_init_params *params)
 {
-       void __iomem *ctrl = params->ctrl_regs;
+       void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
 
        USB_CTRL_UNSET(ctrl, USB30_PCTL, PHY3_IDDQ_OVERRIDE);
        /* 1 millisecond - for USB clocks to settle down */
@@ -978,34 +940,80 @@ void brcm_usb_init_xhci(struct brcm_usb_init_params *params)
        brcmusb_usb3_otp_fix(params);
 }
 
-void brcm_usb_uninit_common(struct brcm_usb_init_params *params)
+static void usb_uninit_common(struct brcm_usb_init_params *params)
 {
        if (USB_CTRL_MASK_FAMILY(params, USB_PM, USB_PWRDN))
                USB_CTRL_SET_FAMILY(params, USB_PM, USB_PWRDN);
 
        if (USB_CTRL_MASK_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN))
                USB_CTRL_SET_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN);
+       if (params->wake_enabled)
+               usb_wake_enable(params, true);
 }
 
-void brcm_usb_uninit_eohci(struct brcm_usb_init_params *params)
+static void usb_uninit_eohci(struct brcm_usb_init_params *params)
 {
-       if (USB_CTRL_MASK_FAMILY(params, USB_PM, USB20_HC_RESETB))
-               USB_CTRL_UNSET_FAMILY(params, USB_PM, USB20_HC_RESETB);
 }
 
-void brcm_usb_uninit_xhci(struct brcm_usb_init_params *params)
+static void usb_uninit_xhci(struct brcm_usb_init_params *params)
 {
        brcmusb_xhci_soft_reset(params, 1);
-       USB_CTRL_SET(params->ctrl_regs, USB30_PCTL, PHY3_IDDQ_OVERRIDE);
+       USB_CTRL_SET(params->regs[BRCM_REGS_CTRL], USB30_PCTL,
+                    PHY3_IDDQ_OVERRIDE);
+}
+
+static int usb_get_dual_select(struct brcm_usb_init_params *params)
+{
+       void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+       u32 reg = 0;
+
+       pr_debug("%s\n", __func__);
+       if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {
+               reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
+               reg &= USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,
+                                       PORT_MODE);
+       }
+       return reg;
 }
 
-void brcm_usb_set_family_map(struct brcm_usb_init_params *params)
+static void usb_set_dual_select(struct brcm_usb_init_params *params, int mode)
+{
+       void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+       u32 reg;
+
+       pr_debug("%s\n", __func__);
+
+       if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {
+               reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
+               reg &= ~USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,
+                                       PORT_MODE);
+               reg |= mode;
+               brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
+       }
+}
+
+static const struct brcm_usb_init_ops bcm7445_ops = {
+       .init_ipp = usb_init_ipp,
+       .init_common = usb_init_common,
+       .init_eohci = usb_init_eohci,
+       .init_xhci = usb_init_xhci,
+       .uninit_common = usb_uninit_common,
+       .uninit_eohci = usb_uninit_eohci,
+       .uninit_xhci = usb_uninit_xhci,
+       .get_dual_select = usb_get_dual_select,
+       .set_dual_select = usb_set_dual_select,
+};
+
+void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params)
 {
        int fam;
 
-       fam = brcmusb_get_family_type(params);
+       pr_debug("%s\n", __func__);
+
+       fam = get_family_type(params);
        params->selected_family = fam;
        params->usb_reg_bits_map =
                &usb_reg_bits_map_table[fam][0];
        params->family_name = family_names[fam];
+       params->ops = &bcm7445_ops;
 }