--- a/drivers/net/wireless/bcm4329_204/dhd_sdio.c
+++ b/drivers/net/wireless/bcm4329_204/dhd_sdio.c
@@ -5105,11 +5105,11 @@ dhdsdio_release_dongle(dhd_bus_t *bus, o
return;
if (bus->sih) {
-#if !defined(BCMLXSDMMC)
dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+#if !defined(BCMLXSDMMC)
si_watchdog(bus->sih, 4);
- dhdsdio_clkctl(bus, CLK_NONE, FALSE);
#endif /* !defined(BCMLXSDMMC) */
+ dhdsdio_clkctl(bus, CLK_NONE, FALSE);
si_detach(bus->sih);
if (bus->vars && bus->varsz)
MFREE(osh, bus->vars, bus->varsz);
@@ -5352,6 +5352,91 @@ dhd_bus_set_nvram_params(struct dhd_bus
bus->nvram_params = nvram_params;
}
+#define WIFI_MAC_PARAM_STR "macaddr="
+#define WIFI_MAX_MAC_LEN 17 /* XX:XX:XX:XX:XX:XX */
+
+#define NVS_LEN_OFFSET 0x0C
+#define NVS_DATA_OFFSET 0x40
+
+extern unsigned char *get_wifi_nvs_ram(void);
+
+static uint
+get_mac_from_wifi_nvs_ram(char* buf, unsigned int buf_len)
+{
+ unsigned char *nvs_ptr;
+ unsigned char *mac_ptr;
+ uint len = 0;
+
+ if (!buf || !buf_len) {
+ return 0;
+ }
+
+ nvs_ptr = get_wifi_nvs_ram();
+ if (nvs_ptr) {
+ nvs_ptr += NVS_DATA_OFFSET;
+ }
+
+ mac_ptr = strstr(nvs_ptr, WIFI_MAC_PARAM_STR);
+ if (mac_ptr) {
+ mac_ptr += strlen(WIFI_MAC_PARAM_STR);
+
+ /* skip leading space */
+ while (mac_ptr[0] == ' ') {
+ mac_ptr++;
+ }
+
+ /* locate end-of-line */
+ len = 0;
+ while (mac_ptr[len] != '\r' && mac_ptr[len] != '\n' &&
+ mac_ptr[len] != '\0') {
+ len++;
+ }
+
+ if (len > buf_len) {
+ len = buf_len;
+ }
+ memcpy(buf, mac_ptr, len);
+ }
+
+ return len;
+}
+
+/*
+ * Modify mac address attribute in buffer
+ * return : length of modified buffer
+ */
+static uint
+modify_mac_attr(char* buf, unsigned buf_len, char *mac, unsigned int mac_len)
+{
+ unsigned char *mac_ptr;
+ uint len;
+
+ if (!buf || !mac) {
+ return buf_len;
+ }
+
+ mac_ptr = strstr(buf, WIFI_MAC_PARAM_STR);
+ if (mac_ptr) {
+ mac_ptr += strlen(WIFI_MAC_PARAM_STR);
+
+ /* locate end-of-line */
+ len = 0;
+ while (mac_ptr[len] != '\r' && mac_ptr[len] != '\n' &&
+ mac_ptr[len] != '\0') {
+ len++;
+ }
+
+ if (len != mac_len) {
+ /* shift remaining data */
+ memmove(&mac_ptr[mac_len + 1], &mac_ptr[len + 1], buf_len - len);
+ buf_len = buf_len - len + mac_len;
+ }
+ memcpy(mac_ptr, mac, mac_len);
+ }
+
+ return buf_len;
+}
+
static int
dhdsdio_download_nvram(struct dhd_bus *bus)
{
@@ -5363,6 +5448,9 @@ dhdsdio_download_nvram(struct dhd_bus *b
char *nv_path;
bool nvram_file_exists;
+ char mac[WIFI_MAX_MAC_LEN];
+ unsigned mac_len;
+
nv_path = bus->nv_path;
nvram_file_exists = ((nv_path != NULL) && (nv_path[0] != '\0'));
@@ -5385,6 +5473,11 @@ dhdsdio_download_nvram(struct dhd_bus *b
/* Download variables */
if (nvram_file_exists) {
len = dhd_os_get_image_block(memblock, MEMBLOCK, image);
+
+ mac_len = get_mac_from_wifi_nvs_ram(mac, WIFI_MAX_MAC_LEN);
+ if (mac_len > 0) {
+ len = modify_mac_attr(memblock, len, mac, mac_len);
+ }
}
else {
len = strlen(bus->nvram_params);
--- a/drivers/net/wireless/bcm4329_204/wl_iw.c
+++ b/drivers/net/wireless/bcm4329_204/wl_iw.c
@@ -6545,7 +6545,7 @@ get_channel_retry:
else {
WL_ERROR(("can't get auto channel sel, err = %d, \
chosen = %d\n", ret, chosen));
- return -1;
+ chosen = 6; /*Alan: Set default channel when get auto channel failed*/
}
}
if ((chosen == 1) && (!rescan++)) {
@@ -8663,7 +8663,13 @@ static int ap_fail_count = 0;
static int
_ap_protect_sysioc_thread(void *data)
{
+#if 0
int isup;
+#else
+ char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */
+ static unsigned int txphyerr = 0;
+ unsigned int curr_txphyerr = 0;
+#endif
int ret = 0;
DAEMONIZE("ap_sysioc");
@@ -8679,14 +8685,32 @@ _ap_protect_sysioc_thread(void *data)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
rtnl_lock();
#endif
+#if 0
if ((ret = dev_wlc_ioctl(priv_dev, WLC_GET_UP, &isup, sizeof(isup))) != 0)
ap_fail_count++;
else
ap_fail_count = 0;
+#else
+ strcpy(iovbuf, "txphyerr");
+ if ((ret = dev_wlc_ioctl(priv_dev, WLC_GET_VAR, iovbuf, sizeof(iovbuf))) < 0)
+ ap_fail_count++;
+ else {
+ curr_txphyerr = *(unsigned int*)iovbuf;
+ //myprintf("%s: curr_txphyerr(%d)/txphyerr(%d)\n", __FUNCTION__, curr_txphyerr, txphyerr);
+ if ( (curr_txphyerr - txphyerr) > 5000 ) {
+ myprintf("%s: curr_txphyerr(%d) is over txphyerr (%d). fail count + 1\n", __FUNCTION__, curr_txphyerr, txphyerr);
+ ap_fail_count++;
+ } else {
+ ap_fail_count = 0;
+ }
+ txphyerr = curr_txphyerr;
+ }
+#endif
if (ap_fail_count == AP_MAX_FAIL_COUNT) {
wl_iw_restart(priv_dev);
wl_iw_ap_restart();
+ txphyerr = 0;
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))