bnx2x: Fix 84833 phy command handler

Current initialization sequence is lacking, causing some configurations
to fail.

Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Yuval Mintz 2016-02-21 15:07:29 +02:00 committed by David S. Miller
parent bb1187af65
commit 4ec0b6d506
2 changed files with 56 additions and 29 deletions

View File

@ -10117,15 +10117,20 @@ static int bnx2x_84858_cmd_hdlr(struct bnx2x_phy *phy,
static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy, static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy,
struct link_params *params, u16 fw_cmd, struct link_params *params, u16 fw_cmd,
u16 cmd_args[], int argc) u16 cmd_args[], int argc, int process)
{ {
int idx; int idx;
u16 val; u16 val;
struct bnx2x *bp = params->bp; struct bnx2x *bp = params->bp;
/* Write CMD_OPEN_OVERRIDE to STATUS reg */ int rc = 0;
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
MDIO_848xx_CMD_HDLR_STATUS, if (process == PHY84833_MB_PROCESS2) {
PHY84833_STATUS_CMD_OPEN_OVERRIDE); /* Write CMD_OPEN_OVERRIDE to STATUS reg */
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
MDIO_848xx_CMD_HDLR_STATUS,
PHY84833_STATUS_CMD_OPEN_OVERRIDE);
}
for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) { for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
MDIO_848xx_CMD_HDLR_STATUS, &val); MDIO_848xx_CMD_HDLR_STATUS, &val);
@ -10135,15 +10140,27 @@ static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy,
} }
if (idx >= PHY848xx_CMDHDLR_WAIT) { if (idx >= PHY848xx_CMDHDLR_WAIT) {
DP(NETIF_MSG_LINK, "FW cmd: FW not ready.\n"); DP(NETIF_MSG_LINK, "FW cmd: FW not ready.\n");
/* if the status is CMD_COMPLETE_PASS or CMD_COMPLETE_ERROR
* clear the status to CMD_CLEAR_COMPLETE
*/
if (val == PHY84833_STATUS_CMD_COMPLETE_PASS ||
val == PHY84833_STATUS_CMD_COMPLETE_ERROR) {
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
MDIO_848xx_CMD_HDLR_STATUS,
PHY84833_STATUS_CMD_CLEAR_COMPLETE);
}
return -EINVAL; return -EINVAL;
} }
if (process == PHY84833_MB_PROCESS1 ||
/* Prepare argument(s) and issue command */ process == PHY84833_MB_PROCESS2) {
for (idx = 0; idx < argc; idx++) { /* Prepare argument(s) */
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, for (idx = 0; idx < argc; idx++) {
MDIO_848xx_CMD_HDLR_DATA1 + idx, bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
cmd_args[idx]); MDIO_848xx_CMD_HDLR_DATA1 + idx,
cmd_args[idx]);
}
} }
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
MDIO_848xx_CMD_HDLR_COMMAND, fw_cmd); MDIO_848xx_CMD_HDLR_COMMAND, fw_cmd);
for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) { for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) {
@ -10157,24 +10174,30 @@ static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy,
if ((idx >= PHY848xx_CMDHDLR_WAIT) || if ((idx >= PHY848xx_CMDHDLR_WAIT) ||
(val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) { (val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) {
DP(NETIF_MSG_LINK, "FW cmd failed.\n"); DP(NETIF_MSG_LINK, "FW cmd failed.\n");
return -EINVAL; rc = -EINVAL;
} }
/* Gather returning data */ if (process == PHY84833_MB_PROCESS3 && rc == 0) {
for (idx = 0; idx < argc; idx++) { /* Gather returning data */
bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, for (idx = 0; idx < argc; idx++) {
MDIO_848xx_CMD_HDLR_DATA1 + idx, bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
&cmd_args[idx]); MDIO_848xx_CMD_HDLR_DATA1 + idx,
&cmd_args[idx]);
}
} }
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, if (val == PHY84833_STATUS_CMD_COMPLETE_ERROR ||
MDIO_848xx_CMD_HDLR_STATUS, val == PHY84833_STATUS_CMD_COMPLETE_PASS) {
PHY84833_STATUS_CMD_CLEAR_COMPLETE); bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
return 0; MDIO_848xx_CMD_HDLR_STATUS,
PHY84833_STATUS_CMD_CLEAR_COMPLETE);
}
return rc;
} }
static int bnx2x_848xx_cmd_hdlr(struct bnx2x_phy *phy, static int bnx2x_848xx_cmd_hdlr(struct bnx2x_phy *phy,
struct link_params *params, struct link_params *params,
u16 fw_cmd, u16 fw_cmd,
u16 cmd_args[], int argc) u16 cmd_args[], int argc,
int process)
{ {
struct bnx2x *bp = params->bp; struct bnx2x *bp = params->bp;
@ -10187,7 +10210,7 @@ static int bnx2x_848xx_cmd_hdlr(struct bnx2x_phy *phy,
argc); argc);
} else { } else {
return bnx2x_84833_cmd_hdlr(phy, params, fw_cmd, cmd_args, return bnx2x_84833_cmd_hdlr(phy, params, fw_cmd, cmd_args,
argc); argc, process);
} }
} }
@ -10214,7 +10237,7 @@ static int bnx2x_848xx_pair_swap_cfg(struct bnx2x_phy *phy,
status = bnx2x_848xx_cmd_hdlr(phy, params, status = bnx2x_848xx_cmd_hdlr(phy, params,
PHY848xx_CMD_SET_PAIR_SWAP, data, PHY848xx_CMD_SET_PAIR_SWAP, data,
PHY848xx_CMDHDLR_MAX_ARGS); 2, PHY84833_MB_PROCESS2);
if (status == 0) if (status == 0)
DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data[1]); DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data[1]);
@ -10303,8 +10326,8 @@ static int bnx2x_8483x_disable_eee(struct bnx2x_phy *phy,
DP(NETIF_MSG_LINK, "Don't Advertise 10GBase-T EEE\n"); DP(NETIF_MSG_LINK, "Don't Advertise 10GBase-T EEE\n");
/* Prevent Phy from working in EEE and advertising it */ /* Prevent Phy from working in EEE and advertising it */
rc = bnx2x_848xx_cmd_hdlr(phy, params, rc = bnx2x_848xx_cmd_hdlr(phy, params, PHY848xx_CMD_SET_EEE_MODE,
PHY848xx_CMD_SET_EEE_MODE, &cmd_args, 1); &cmd_args, 1, PHY84833_MB_PROCESS1);
if (rc) { if (rc) {
DP(NETIF_MSG_LINK, "EEE disable failed.\n"); DP(NETIF_MSG_LINK, "EEE disable failed.\n");
return rc; return rc;
@ -10321,8 +10344,8 @@ static int bnx2x_8483x_enable_eee(struct bnx2x_phy *phy,
struct bnx2x *bp = params->bp; struct bnx2x *bp = params->bp;
u16 cmd_args = 1; u16 cmd_args = 1;
rc = bnx2x_848xx_cmd_hdlr(phy, params, rc = bnx2x_848xx_cmd_hdlr(phy, params, PHY848xx_CMD_SET_EEE_MODE,
PHY848xx_CMD_SET_EEE_MODE, &cmd_args, 1); &cmd_args, 1, PHY84833_MB_PROCESS1);
if (rc) { if (rc) {
DP(NETIF_MSG_LINK, "EEE enable failed.\n"); DP(NETIF_MSG_LINK, "EEE enable failed.\n");
return rc; return rc;
@ -10443,7 +10466,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
cmd_args[3] = PHY84833_CONSTANT_LATENCY; cmd_args[3] = PHY84833_CONSTANT_LATENCY;
rc = bnx2x_848xx_cmd_hdlr(phy, params, rc = bnx2x_848xx_cmd_hdlr(phy, params,
PHY848xx_CMD_SET_EEE_MODE, cmd_args, PHY848xx_CMD_SET_EEE_MODE, cmd_args,
PHY848xx_CMDHDLR_MAX_ARGS); 4, PHY84833_MB_PROCESS1);
if (rc) if (rc)
DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n"); DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n");
} }

View File

@ -7339,6 +7339,10 @@ Theotherbitsarereservedandshouldbezero*/
#define PHY84833_STATUS_CMD_NOT_OPEN_FOR_CMDS 0x0040 #define PHY84833_STATUS_CMD_NOT_OPEN_FOR_CMDS 0x0040
#define PHY84833_STATUS_CMD_CLEAR_COMPLETE 0x0080 #define PHY84833_STATUS_CMD_CLEAR_COMPLETE 0x0080
#define PHY84833_STATUS_CMD_OPEN_OVERRIDE 0xa5a5 #define PHY84833_STATUS_CMD_OPEN_OVERRIDE 0xa5a5
/* Mailbox Process */
#define PHY84833_MB_PROCESS1 1
#define PHY84833_MB_PROCESS2 2
#define PHY84833_MB_PROCESS3 3
/* Mailbox status set used by 84858 only */ /* Mailbox status set used by 84858 only */
#define PHY84858_STATUS_CMD_RECEIVED 0x0001 #define PHY84858_STATUS_CMD_RECEIVED 0x0001