Skip to content

Commit 8e13f70

Browse files
sammjdavem330
authored andcommitted
net/ncsi: Probe single packages to avoid conflict
Currently the NCSI driver sends a select-package command to all possible packages simultaneously to discover what packages are available. However at this stage in the probe process the driver does not know if hardware arbitration is available: if it isn't then this process could cause collisions on the RMII bus when packages try to respond. Update the probe loop to probe each package one by one, and once complete check if HWA is universally supported. Signed-off-by: Samuel Mendoza-Jonas <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 60ab49b commit 8e13f70

File tree

2 files changed

+31
-55
lines changed

2 files changed

+31
-55
lines changed

net/ncsi/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ struct ncsi_dev_priv {
292292
#if IS_ENABLED(CONFIG_IPV6)
293293
unsigned int inet6_addr_num; /* Number of IPv6 addresses */
294294
#endif
295+
unsigned int package_probe_id;/* Current ID during probe */
295296
unsigned int package_num; /* Number of packages */
296297
struct list_head packages; /* List of packages */
297298
struct ncsi_channel *hot_channel; /* Channel was ever active */

net/ncsi/ncsi-manage.c

Lines changed: 30 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,67 +1079,28 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp)
10791079
nd->state = ncsi_dev_state_probe_package;
10801080
break;
10811081
case ncsi_dev_state_probe_package:
1082-
ndp->pending_req_num = 16;
1082+
ndp->pending_req_num = 1;
10831083

1084-
/* Select all possible packages */
10851084
nca.type = NCSI_PKT_CMD_SP;
10861085
nca.bytes[0] = 1;
1086+
nca.package = ndp->package_probe_id;
10871087
nca.channel = NCSI_RESERVED_CHANNEL;
1088-
for (index = 0; index < 8; index++) {
1089-
nca.package = index;
1090-
ret = ncsi_xmit_cmd(&nca);
1091-
if (ret)
1092-
goto error;
1093-
}
1094-
1095-
/* Disable all possible packages */
1096-
nca.type = NCSI_PKT_CMD_DP;
1097-
for (index = 0; index < 8; index++) {
1098-
nca.package = index;
1099-
ret = ncsi_xmit_cmd(&nca);
1100-
if (ret)
1101-
goto error;
1102-
}
1103-
1088+
ret = ncsi_xmit_cmd(&nca);
1089+
if (ret)
1090+
goto error;
11041091
nd->state = ncsi_dev_state_probe_channel;
11051092
break;
11061093
case ncsi_dev_state_probe_channel:
1107-
if (!ndp->active_package)
1108-
ndp->active_package = list_first_or_null_rcu(
1109-
&ndp->packages, struct ncsi_package, node);
1110-
else if (list_is_last(&ndp->active_package->node,
1111-
&ndp->packages))
1112-
ndp->active_package = NULL;
1113-
else
1114-
ndp->active_package = list_next_entry(
1115-
ndp->active_package, node);
1116-
1117-
/* All available packages and channels are enumerated. The
1118-
* enumeration happens for once when the NCSI interface is
1119-
* started. So we need continue to start the interface after
1120-
* the enumeration.
1121-
*
1122-
* We have to choose an active channel before configuring it.
1123-
* Note that we possibly don't have active channel in extreme
1124-
* situation.
1125-
*/
1094+
ndp->active_package = ncsi_find_package(ndp,
1095+
ndp->package_probe_id);
11261096
if (!ndp->active_package) {
1127-
ndp->flags |= NCSI_DEV_PROBED;
1128-
ncsi_choose_active_channel(ndp);
1129-
return;
1097+
/* No response */
1098+
nd->state = ncsi_dev_state_probe_dp;
1099+
schedule_work(&ndp->work);
1100+
break;
11301101
}
1131-
1132-
/* Select the active package */
1133-
ndp->pending_req_num = 1;
1134-
nca.type = NCSI_PKT_CMD_SP;
1135-
nca.bytes[0] = 1;
1136-
nca.package = ndp->active_package->id;
1137-
nca.channel = NCSI_RESERVED_CHANNEL;
1138-
ret = ncsi_xmit_cmd(&nca);
1139-
if (ret)
1140-
goto error;
1141-
11421102
nd->state = ncsi_dev_state_probe_cis;
1103+
schedule_work(&ndp->work);
11431104
break;
11441105
case ncsi_dev_state_probe_cis:
11451106
ndp->pending_req_num = NCSI_RESERVED_CHANNEL;
@@ -1188,22 +1149,35 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp)
11881149
case ncsi_dev_state_probe_dp:
11891150
ndp->pending_req_num = 1;
11901151

1191-
/* Deselect the active package */
1152+
/* Deselect the current package */
11921153
nca.type = NCSI_PKT_CMD_DP;
1193-
nca.package = ndp->active_package->id;
1154+
nca.package = ndp->package_probe_id;
11941155
nca.channel = NCSI_RESERVED_CHANNEL;
11951156
ret = ncsi_xmit_cmd(&nca);
11961157
if (ret)
11971158
goto error;
11981159

1199-
/* Scan channels in next package */
1200-
nd->state = ncsi_dev_state_probe_channel;
1160+
/* Probe next package */
1161+
ndp->package_probe_id++;
1162+
if (ndp->package_probe_id >= 8) {
1163+
/* Probe finished */
1164+
ndp->flags |= NCSI_DEV_PROBED;
1165+
break;
1166+
}
1167+
nd->state = ncsi_dev_state_probe_package;
1168+
ndp->active_package = NULL;
12011169
break;
12021170
default:
12031171
netdev_warn(nd->dev, "Wrong NCSI state 0x%0x in enumeration\n",
12041172
nd->state);
12051173
}
12061174

1175+
if (ndp->flags & NCSI_DEV_PROBED) {
1176+
/* Check if all packages have HWA support */
1177+
ncsi_check_hwa(ndp);
1178+
ncsi_choose_active_channel(ndp);
1179+
}
1180+
12071181
return;
12081182
error:
12091183
netdev_err(ndp->ndev.dev,
@@ -1564,6 +1538,7 @@ int ncsi_start_dev(struct ncsi_dev *nd)
15641538
return -ENOTTY;
15651539

15661540
if (!(ndp->flags & NCSI_DEV_PROBED)) {
1541+
ndp->package_probe_id = 0;
15671542
nd->state = ncsi_dev_state_probe;
15681543
schedule_work(&ndp->work);
15691544
return 0;

0 commit comments

Comments
 (0)