diff options
author | Yuval Mintz <Yuval.Mintz@qlogic.com> | 2016-02-21 08:07:29 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-02-21 22:50:55 -0500 |
commit | 4ec0b6d506186de559b331bd08f8483463116f72 (patch) | |
tree | bb79856e30d6d5e4133d0efcb0a44811925327c7 | |
parent | bb1187af658f9ed05a24ab0f25d3b41324176590 (diff) |
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>
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 81 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 4 |
2 files changed, 56 insertions, 29 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 8779f154fcae..1fb80100e5e7 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | |||
@@ -10117,15 +10117,20 @@ static int bnx2x_84858_cmd_hdlr(struct bnx2x_phy *phy, | |||
10117 | 10117 | ||
10118 | static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy, | 10118 | static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy, |
10119 | struct link_params *params, u16 fw_cmd, | 10119 | struct link_params *params, u16 fw_cmd, |
10120 | u16 cmd_args[], int argc) | 10120 | u16 cmd_args[], int argc, int process) |
10121 | { | 10121 | { |
10122 | int idx; | 10122 | int idx; |
10123 | u16 val; | 10123 | u16 val; |
10124 | struct bnx2x *bp = params->bp; | 10124 | struct bnx2x *bp = params->bp; |
10125 | /* Write CMD_OPEN_OVERRIDE to STATUS reg */ | 10125 | int rc = 0; |
10126 | bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, | 10126 | |
10127 | MDIO_848xx_CMD_HDLR_STATUS, | 10127 | if (process == PHY84833_MB_PROCESS2) { |
10128 | PHY84833_STATUS_CMD_OPEN_OVERRIDE); | 10128 | /* Write CMD_OPEN_OVERRIDE to STATUS reg */ |
10129 | bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, | ||
10130 | MDIO_848xx_CMD_HDLR_STATUS, | ||
10131 | PHY84833_STATUS_CMD_OPEN_OVERRIDE); | ||
10132 | } | ||
10133 | |||
10129 | for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) { | 10134 | for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) { |
10130 | bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, | 10135 | bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, |
10131 | MDIO_848xx_CMD_HDLR_STATUS, &val); | 10136 | MDIO_848xx_CMD_HDLR_STATUS, &val); |
@@ -10135,15 +10140,27 @@ static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy, | |||
10135 | } | 10140 | } |
10136 | if (idx >= PHY848xx_CMDHDLR_WAIT) { | 10141 | if (idx >= PHY848xx_CMDHDLR_WAIT) { |
10137 | DP(NETIF_MSG_LINK, "FW cmd: FW not ready.\n"); | 10142 | DP(NETIF_MSG_LINK, "FW cmd: FW not ready.\n"); |
10143 | /* if the status is CMD_COMPLETE_PASS or CMD_COMPLETE_ERROR | ||
10144 | * clear the status to CMD_CLEAR_COMPLETE | ||
10145 | */ | ||
10146 | if (val == PHY84833_STATUS_CMD_COMPLETE_PASS || | ||
10147 | val == PHY84833_STATUS_CMD_COMPLETE_ERROR) { | ||
10148 | bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, | ||
10149 | MDIO_848xx_CMD_HDLR_STATUS, | ||
10150 | PHY84833_STATUS_CMD_CLEAR_COMPLETE); | ||
10151 | } | ||
10138 | return -EINVAL; | 10152 | return -EINVAL; |
10139 | } | 10153 | } |
10140 | 10154 | if (process == PHY84833_MB_PROCESS1 || | |
10141 | /* Prepare argument(s) and issue command */ | 10155 | process == PHY84833_MB_PROCESS2) { |
10142 | for (idx = 0; idx < argc; idx++) { | 10156 | /* Prepare argument(s) */ |
10143 | bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, | 10157 | for (idx = 0; idx < argc; idx++) { |
10144 | MDIO_848xx_CMD_HDLR_DATA1 + idx, | 10158 | bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, |
10145 | cmd_args[idx]); | 10159 | MDIO_848xx_CMD_HDLR_DATA1 + idx, |
10160 | cmd_args[idx]); | ||
10161 | } | ||
10146 | } | 10162 | } |
10163 | |||
10147 | bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, | 10164 | bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, |
10148 | MDIO_848xx_CMD_HDLR_COMMAND, fw_cmd); | 10165 | MDIO_848xx_CMD_HDLR_COMMAND, fw_cmd); |
10149 | for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) { | 10166 | for (idx = 0; idx < PHY848xx_CMDHDLR_WAIT; idx++) { |
@@ -10157,24 +10174,30 @@ static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy, | |||
10157 | if ((idx >= PHY848xx_CMDHDLR_WAIT) || | 10174 | if ((idx >= PHY848xx_CMDHDLR_WAIT) || |
10158 | (val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) { | 10175 | (val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) { |
10159 | DP(NETIF_MSG_LINK, "FW cmd failed.\n"); | 10176 | DP(NETIF_MSG_LINK, "FW cmd failed.\n"); |
10160 | return -EINVAL; | 10177 | rc = -EINVAL; |
10161 | } | 10178 | } |
10162 | /* Gather returning data */ | 10179 | if (process == PHY84833_MB_PROCESS3 && rc == 0) { |
10163 | for (idx = 0; idx < argc; idx++) { | 10180 | /* Gather returning data */ |
10164 | bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, | 10181 | for (idx = 0; idx < argc; idx++) { |
10165 | MDIO_848xx_CMD_HDLR_DATA1 + idx, | 10182 | bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, |
10166 | &cmd_args[idx]); | 10183 | MDIO_848xx_CMD_HDLR_DATA1 + idx, |
10184 | &cmd_args[idx]); | ||
10185 | } | ||
10167 | } | 10186 | } |
10168 | bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, | 10187 | if (val == PHY84833_STATUS_CMD_COMPLETE_ERROR || |
10169 | MDIO_848xx_CMD_HDLR_STATUS, | 10188 | val == PHY84833_STATUS_CMD_COMPLETE_PASS) { |
10170 | PHY84833_STATUS_CMD_CLEAR_COMPLETE); | 10189 | bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, |
10171 | return 0; | 10190 | MDIO_848xx_CMD_HDLR_STATUS, |
10191 | PHY84833_STATUS_CMD_CLEAR_COMPLETE); | ||
10192 | } | ||
10193 | return rc; | ||
10172 | } | 10194 | } |
10173 | 10195 | ||
10174 | static int bnx2x_848xx_cmd_hdlr(struct bnx2x_phy *phy, | 10196 | static int bnx2x_848xx_cmd_hdlr(struct bnx2x_phy *phy, |
10175 | struct link_params *params, | 10197 | struct link_params *params, |
10176 | u16 fw_cmd, | 10198 | u16 fw_cmd, |
10177 | u16 cmd_args[], int argc) | 10199 | u16 cmd_args[], int argc, |
10200 | int process) | ||
10178 | { | 10201 | { |
10179 | struct bnx2x *bp = params->bp; | 10202 | struct bnx2x *bp = params->bp; |
10180 | 10203 | ||
@@ -10187,7 +10210,7 @@ static int bnx2x_848xx_cmd_hdlr(struct bnx2x_phy *phy, | |||
10187 | argc); | 10210 | argc); |
10188 | } else { | 10211 | } else { |
10189 | return bnx2x_84833_cmd_hdlr(phy, params, fw_cmd, cmd_args, | 10212 | return bnx2x_84833_cmd_hdlr(phy, params, fw_cmd, cmd_args, |
10190 | argc); | 10213 | argc, process); |
10191 | } | 10214 | } |
10192 | } | 10215 | } |
10193 | 10216 | ||
@@ -10214,7 +10237,7 @@ static int bnx2x_848xx_pair_swap_cfg(struct bnx2x_phy *phy, | |||
10214 | 10237 | ||
10215 | status = bnx2x_848xx_cmd_hdlr(phy, params, | 10238 | status = bnx2x_848xx_cmd_hdlr(phy, params, |
10216 | PHY848xx_CMD_SET_PAIR_SWAP, data, | 10239 | PHY848xx_CMD_SET_PAIR_SWAP, data, |
10217 | PHY848xx_CMDHDLR_MAX_ARGS); | 10240 | 2, PHY84833_MB_PROCESS2); |
10218 | if (status == 0) | 10241 | if (status == 0) |
10219 | DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data[1]); | 10242 | DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data[1]); |
10220 | 10243 | ||
@@ -10303,8 +10326,8 @@ static int bnx2x_8483x_disable_eee(struct bnx2x_phy *phy, | |||
10303 | DP(NETIF_MSG_LINK, "Don't Advertise 10GBase-T EEE\n"); | 10326 | DP(NETIF_MSG_LINK, "Don't Advertise 10GBase-T EEE\n"); |
10304 | 10327 | ||
10305 | /* Prevent Phy from working in EEE and advertising it */ | 10328 | /* Prevent Phy from working in EEE and advertising it */ |
10306 | rc = bnx2x_848xx_cmd_hdlr(phy, params, | 10329 | rc = bnx2x_848xx_cmd_hdlr(phy, params, PHY848xx_CMD_SET_EEE_MODE, |
10307 | PHY848xx_CMD_SET_EEE_MODE, &cmd_args, 1); | 10330 | &cmd_args, 1, PHY84833_MB_PROCESS1); |
10308 | if (rc) { | 10331 | if (rc) { |
10309 | DP(NETIF_MSG_LINK, "EEE disable failed.\n"); | 10332 | DP(NETIF_MSG_LINK, "EEE disable failed.\n"); |
10310 | return rc; | 10333 | return rc; |
@@ -10321,8 +10344,8 @@ static int bnx2x_8483x_enable_eee(struct bnx2x_phy *phy, | |||
10321 | struct bnx2x *bp = params->bp; | 10344 | struct bnx2x *bp = params->bp; |
10322 | u16 cmd_args = 1; | 10345 | u16 cmd_args = 1; |
10323 | 10346 | ||
10324 | rc = bnx2x_848xx_cmd_hdlr(phy, params, | 10347 | rc = bnx2x_848xx_cmd_hdlr(phy, params, PHY848xx_CMD_SET_EEE_MODE, |
10325 | PHY848xx_CMD_SET_EEE_MODE, &cmd_args, 1); | 10348 | &cmd_args, 1, PHY84833_MB_PROCESS1); |
10326 | if (rc) { | 10349 | if (rc) { |
10327 | DP(NETIF_MSG_LINK, "EEE enable failed.\n"); | 10350 | DP(NETIF_MSG_LINK, "EEE enable failed.\n"); |
10328 | return rc; | 10351 | return rc; |
@@ -10443,7 +10466,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, | |||
10443 | cmd_args[3] = PHY84833_CONSTANT_LATENCY; | 10466 | cmd_args[3] = PHY84833_CONSTANT_LATENCY; |
10444 | rc = bnx2x_848xx_cmd_hdlr(phy, params, | 10467 | rc = bnx2x_848xx_cmd_hdlr(phy, params, |
10445 | PHY848xx_CMD_SET_EEE_MODE, cmd_args, | 10468 | PHY848xx_CMD_SET_EEE_MODE, cmd_args, |
10446 | PHY848xx_CMDHDLR_MAX_ARGS); | 10469 | 4, PHY84833_MB_PROCESS1); |
10447 | if (rc) | 10470 | if (rc) |
10448 | DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n"); | 10471 | DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n"); |
10449 | } | 10472 | } |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index d27d40e4a78e..a43dea259b12 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | |||
@@ -7339,6 +7339,10 @@ Theotherbitsarereservedandshouldbezero*/ | |||
7339 | #define PHY84833_STATUS_CMD_NOT_OPEN_FOR_CMDS 0x0040 | 7339 | #define PHY84833_STATUS_CMD_NOT_OPEN_FOR_CMDS 0x0040 |
7340 | #define PHY84833_STATUS_CMD_CLEAR_COMPLETE 0x0080 | 7340 | #define PHY84833_STATUS_CMD_CLEAR_COMPLETE 0x0080 |
7341 | #define PHY84833_STATUS_CMD_OPEN_OVERRIDE 0xa5a5 | 7341 | #define PHY84833_STATUS_CMD_OPEN_OVERRIDE 0xa5a5 |
7342 | /* Mailbox Process */ | ||
7343 | #define PHY84833_MB_PROCESS1 1 | ||
7344 | #define PHY84833_MB_PROCESS2 2 | ||
7345 | #define PHY84833_MB_PROCESS3 3 | ||
7342 | 7346 | ||
7343 | /* Mailbox status set used by 84858 only */ | 7347 | /* Mailbox status set used by 84858 only */ |
7344 | #define PHY84858_STATUS_CMD_RECEIVED 0x0001 | 7348 | #define PHY84858_STATUS_CMD_RECEIVED 0x0001 |