#define FBNIC_PCS_VENDOR BIT(9)
#define FBNIC_PCS_ZERO_MASK (DW_VENDOR - FBNIC_PCS_VENDOR)
+static int
+fbnic_mdio_ids(int id, int regnum)
+{
+ /* return correct IDs */
+ switch (regnum) {
+ case MDIO_DEVID1:
+ return id >> 16;
+ case MDIO_DEVID2:
+ return id & 0xffff;
+ case MDIO_DEVS1:
+ return MDIO_DEVS_SEP_PMA1 | MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS;
+ case MDIO_DEVS2:
+ return 0;
+ case MDIO_STAT2:
+ return MDIO_STAT2_DEVPRST_VAL;
+ }
+
+ return 0;
+}
+
static int
fbnic_mdio_read_pmd(struct fbnic_dev *fbd, int addr, int regnum)
{
}
switch (regnum) {
- case MDIO_DEVID1:
- ret = MP_FBNIC_XPCS_PMA_100G_ID >> 16;
- break;
- case MDIO_DEVID2:
- ret = MP_FBNIC_XPCS_PMA_100G_ID & 0xffff;
- break;
- case MDIO_DEVS1:
- ret = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS;
- break;
- case MDIO_STAT2:
- ret = MDIO_STAT2_DEVPRST_VAL;
- break;
case MDIO_PMA_RXDET:
/* If training isn't complete default to 0 */
if (fbd->pmd_state != FBNIC_PMD_SEND_DATA)
(MDIO_PMD_RXDET_1 / FBNIC_AUI_MODE_R2));
break;
default:
+ ret = fbnic_mdio_ids(MP_FBNIC_XPCS_PMA_100G_ID, regnum);
break;
}
static int
fbnic_mdio_read_pcs(struct fbnic_dev *fbd, int addr, int regnum)
{
- int ret, offset = 0;
+ int ret, offset = 0, overrides = 0;
/* We will need access to both PCS instances to get config info */
if (addr >= 2)
return 0;
/* Intercept and return correct ID for PCS */
- if (regnum == MDIO_DEVID1)
- return DW_XPCS_ID >> 16;
- if (regnum == MDIO_DEVID2)
- return DW_XPCS_ID & 0xffff;
- if (regnum == MDIO_DEVS1)
- return MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS;
-
- /* Swap vendor page bit for FBNIC PCS vendor page bit */
- if (regnum & DW_VENDOR)
- offset ^= DW_VENDOR | FBNIC_PCS_VENDOR;
+ switch (regnum) {
+ case MDIO_DEVID1 ... MDIO_DEVID2:
+ ret = fbnic_mdio_ids(DW_XPCS_ID, regnum);
+ break;
+ case MDIO_DEVS1:
+ /* DW IP returns MDIO_DEVS_SEP_PMA1, MDIO_DEVS_PMAPMD,
+ * and MDIO_DEVS_PCS as 0
+ */
+ overrides = fbnic_mdio_ids(DW_XPCS_ID, regnum);
+ fallthrough;
+ default:
+ /* Swap vendor page bit for FBNIC PCS vendor page bit */
+ if (regnum & DW_VENDOR)
+ offset ^= DW_VENDOR | FBNIC_PCS_VENDOR;
- ret = fbnic_rd32(fbd, FBNIC_PCS_PAGE(addr) + (regnum ^ offset));
+ ret = fbnic_rd32(fbd, FBNIC_PCS_PAGE(addr) + (regnum ^ offset));
+ ret |= overrides;
+ break;
+ }
dev_dbg(fbd->dev,
"SWMII PCS Rd: Addr: %d RegNum: %d Value: 0x%04x\n",