Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: e100: ucode is optional in some cases

commit 9ac32e1b firmware: convert e100 driver to request_firmware()

did a straight conversion of the in-driver ucode to external
files. This introduced the possibility of the driver failing
to enable an interface due to missing ucode. There was no
evaluation of the importance of the ucode at the time.

Based on comments in earlier versions of this driver, and in
the source code for the FreeBSD fxp driver, we can assume that
the ucode implements the "CPU Cycle Saver" feature on supported
adapters. Although generally wanted, this is an optional
feature. The ucode source is not available, preventing it from
being included in free distributions. This creates unnecessary
problems for the end users. Doing a network install based on a
free distribution installer requires the user to download and
insert the ucode into the installer.

Making the ucode optional when possible improves the user
experience and driver usability.

The ucode for some adapters include a bugfix, making it
essential. We continue to fail for these adapters unless the
ucode is available.

Signed-off-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Bjørn Mork and committed by
David S. Miller
8b0d2f9e 21502937

+31 -9
+31 -9
drivers/net/ethernet/intel/e100.c
··· 1249 1249 const struct firmware *fw = nic->fw; 1250 1250 u8 timer, bundle, min_size; 1251 1251 int err = 0; 1252 + bool required = false; 1252 1253 1253 1254 /* do not load u-code for ICH devices */ 1254 1255 if (nic->flags & ich) 1255 1256 return NULL; 1256 1257 1257 - /* Search for ucode match against h/w revision */ 1258 - if (nic->mac == mac_82559_D101M) 1258 + /* Search for ucode match against h/w revision 1259 + * 1260 + * Based on comments in the source code for the FreeBSD fxp 1261 + * driver, the FIRMWARE_D102E ucode includes both CPUSaver and 1262 + * 1263 + * "fixes for bugs in the B-step hardware (specifically, bugs 1264 + * with Inline Receive)." 1265 + * 1266 + * So we must fail if it cannot be loaded. 1267 + * 1268 + * The other microcode files are only required for the optional 1269 + * CPUSaver feature. Nice to have, but no reason to fail. 1270 + */ 1271 + if (nic->mac == mac_82559_D101M) { 1259 1272 fw_name = FIRMWARE_D101M; 1260 - else if (nic->mac == mac_82559_D101S) 1273 + } else if (nic->mac == mac_82559_D101S) { 1261 1274 fw_name = FIRMWARE_D101S; 1262 - else if (nic->mac == mac_82551_F || nic->mac == mac_82551_10) 1275 + } else if (nic->mac == mac_82551_F || nic->mac == mac_82551_10) { 1263 1276 fw_name = FIRMWARE_D102E; 1264 - else /* No ucode on other devices */ 1277 + required = true; 1278 + } else { /* No ucode on other devices */ 1265 1279 return NULL; 1280 + } 1266 1281 1267 1282 /* If the firmware has not previously been loaded, request a pointer 1268 1283 * to it. If it was previously loaded, we are reinitializing the ··· 1288 1273 err = request_firmware(&fw, fw_name, &nic->pdev->dev); 1289 1274 1290 1275 if (err) { 1291 - netif_err(nic, probe, nic->netdev, 1292 - "Failed to load firmware \"%s\": %d\n", 1293 - fw_name, err); 1294 - return ERR_PTR(err); 1276 + if (required) { 1277 + netif_err(nic, probe, nic->netdev, 1278 + "Failed to load firmware \"%s\": %d\n", 1279 + fw_name, err); 1280 + return ERR_PTR(err); 1281 + } else { 1282 + netif_info(nic, probe, nic->netdev, 1283 + "CPUSaver disabled. Needs \"%s\": %d\n", 1284 + fw_name, err); 1285 + return NULL; 1286 + } 1295 1287 } 1296 1288 1297 1289 /* Firmware should be precisely UCODE_SIZE (words) plus three bytes