diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 8067abb73..b6697f1e3 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -11,6 +11,7 @@
 #include <linux/vmalloc.h>
 #include <linux/bitfield.h>
 #include <linux/string.h>
+#include <linux/ctype.h>
 #include <net/cfg80211.h>
 #include <net/netlink.h>
 #include <uapi/linux/if_arp.h>
@@ -5131,7 +5132,7 @@ brcmf_update_pmklist(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp)
 			sizeof(*pmk_list));
 }
 
-static s32 
+static s32
 brcmf_update_pmksa(struct brcmf_cfg80211_info *cfg,
 		   struct brcmf_if *ifp,
 		   const u8 *bssid,
@@ -10801,38 +10802,52 @@ static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
 	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
 	struct brcmf_pub *drvr = cfg->pub;
 	struct brcmf_fil_country_le ccreq;
+	char *alpha2;
 	s32 err;
 	int i;
 
-	/* The country code gets set to "00" by default at boot, ignore */
-	if (req->alpha2[0] == '0' && req->alpha2[1] == '0')
+	err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq));
+	if (err) {
+		bphy_err(drvr, "Country code iovar returned err = %d\n", err);
 		return;
+	}
+
+	/* The country code gets set to "00" by default at boot - substitute
+	 * any saved ccode from the nvram file unless there is a valid code
+	 * already set.
+	 */
+	alpha2 = req->alpha2;
+	if (alpha2[0] == '0' && alpha2[1] == '0') {
+		extern char saved_ccode[2];
+
+		if ((isupper(ccreq.country_abbrev[0]) &&
+		     isupper(ccreq.country_abbrev[1])) ||
+		    !saved_ccode[0])
+			return;
+		alpha2 = saved_ccode;
+		pr_debug("brcmfmac: substituting saved ccode %c%c\n",
+			 alpha2[0], alpha2[1]);
+	}
 
 	/* ignore non-ISO3166 country codes */
 	for (i = 0; i < 2; i++)
-		if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
+		if (alpha2[i] < 'A' || alpha2[i] > 'Z') {
 			bphy_err(drvr, "not an ISO3166 code (0x%02x 0x%02x)\n",
-				 req->alpha2[0], req->alpha2[1]);
+				 alpha2[0], alpha2[1]);
 			return;
 		}
 
 	brcmf_dbg(INFO, "Enter: initiator=%d, alpha=%c%c\n", req->initiator,
-		  req->alpha2[0], req->alpha2[1]);
-
-	err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq));
-	if (err) {
-		bphy_err(drvr, "Country code iovar returned err = %d\n", err);
-		return;
-	}
+		alpha2[0], alpha2[1]);
 
-	err = brcmf_translate_country_code(ifp->drvr, req->alpha2, &ccreq);
+	err = brcmf_translate_country_code(ifp->drvr, alpha2, &ccreq);
 	if (err)
 		return;
 
 	/* Abort on-going scan before changing ccode */
 	brcmf_abort_scanning(cfg);
 
-	err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq));
+	err = brcmf_translate_country_code(ifp->drvr, alpha2, &ccreq);
 	if (err) {
 		bphy_err(drvr, "Firmware rejected country setting\n");
 		return;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
index f35eaf3ea..2e09a8420 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -10,6 +10,7 @@
 #include <linux/firmware.h>
 #include <linux/module.h>
 #include <linux/bcm47xx_nvram.h>
+#include <linux/ctype.h>
 
 #include "debug.h"
 #include "firmware.h"
@@ -32,6 +33,8 @@ enum nvram_parser_state {
 	END
 };
 
+char saved_ccode[2] = {};
+
 /**
  * struct nvram_parser - internal info for parser.
  *
@@ -564,11 +567,27 @@ static int brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
 			goto fail;
 	}
 
-	if (data)
+	if (data) {
+		char *ccode = strnstr((char *)data, "ccode=", data_len);
+		/* Ensure this is a whole token */
+		if (ccode && ((void *)ccode == (void *)data || isspace(ccode[-1]))) {
+			/* Comment out the line */
+			ccode[0] = '#';
+			ccode += 6;
+			if (isupper(ccode[0]) && isupper(ccode[1]) &&
+			    isspace(ccode[2])) {
+				pr_debug("brcmfmac: intercepting ccode=%c%c\n",
+					 ccode[0], ccode[1]);
+				saved_ccode[0] = ccode[0];
+				saved_ccode[1] = ccode[1];
+			}
+		};
+
 		nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length,
 					     fwctx->req->domain_nr,
 					     fwctx->req->bus_nr,
 					     fwctx->dev);
+	}
 
 	if (free_bcm47xx_nvram)
 		bcm47xx_nvram_release_contents(data);
