diff options
author | Lin Ma <linm@broadcom.com> | 2011-07-18 11:42:36 -0700 |
---|---|---|
committer | Dmitry Shmidt <dimitrysh@google.com> | 2011-07-21 17:13:52 -0700 |
commit | 2f66cb426e32ac6c731e4eda09aded204a800d64 (patch) | |
tree | 35cc7eeb8ec6f72697259048e85e6b21c25dce9d /drivers/net/wireless/bcmdhd/dhd_linux.c | |
parent | b06f3b5edb8f9256f0435f13a439074291cd9055 (diff) |
Update to 5.90.125.40
Add monitor interface support and fix cfg80211 management frame isses
Add support for hostapd
Use private command to get p2p device address
Change-Id: Ie490e38f1af9f259ff4a96b2f7d367119c65c377
Signed-off-by: Howard M. Harte <hharte@broadcom.com>
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'drivers/net/wireless/bcmdhd/dhd_linux.c')
-rw-r--r-- | drivers/net/wireless/bcmdhd/dhd_linux.c | 68 |
1 files changed, 49 insertions, 19 deletions
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c index e952ee1ccc2..ff9f9fa9c21 100644 --- a/drivers/net/wireless/bcmdhd/dhd_linux.c +++ b/drivers/net/wireless/bcmdhd/dhd_linux.c @@ -91,6 +91,7 @@ static histo_t vi_d1, vi_d2, vi_d3, vi_d4; #if defined(SOFTAP) extern bool ap_cfg_running; +extern bool ap_fw_loaded; #endif /* enable HOSTIP cache update from the host side when an eth0:N is up */ @@ -442,6 +443,12 @@ static void dhd_htsf_addrxts(dhd_pub_t *dhdp, void *pktbuf); static void dhd_dump_htsfhisto(histo_t *his, char *s); #endif /* WLMEDIA_HTSF */ +extern s32 wl_cfg80211_ifdel_ops(struct net_device *net); + +/* Monitor interface */ +extern int dhd_monitor_init(void *dhd_pub); +extern int dhd_monitor_uninit(void); + #if defined(CONFIG_WIRELESS_EXT) struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev); @@ -491,6 +498,7 @@ extern int register_pm_notifier(struct notifier_block *nb); extern int unregister_pm_notifier(struct notifier_block *nb); #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ /* && defined(DHD_GPL) */ + static void dhd_set_packet_filter(int value, dhd_pub_t *dhd) { #ifdef PKT_FILTER_SUPPORT @@ -972,7 +980,7 @@ dhd_op_if(dhd_if_t *ifp) ret = -EOPNOTSUPP; } else { #if defined(SOFTAP) - if (ap_cfg_running && !(dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)) { + if (ap_fw_loaded && !(dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)) { /* semaphore that the soft AP CODE waits on */ flags = dhd_os_spin_lock(&dhd->pub); @@ -992,6 +1000,9 @@ dhd_op_if(dhd_if_t *ifp) case WLC_E_IF_DEL: if (ifp->net != NULL) { DHD_TRACE(("\n%s: got 'WLC_E_IF_DEL' state\n", __FUNCTION__)); +#ifdef WL_CFG80211 + wl_cfg80211_ifdel_ops(ifp->net); +#endif netif_stop_queue(ifp->net); unregister_netdev(ifp->net); ret = DHD_DEL_IF; /* Make sure the free_netdev() is called */ @@ -1234,7 +1245,7 @@ dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf) return ret; } -static int +int dhd_start_xmit(struct sk_buff *skb, struct net_device *net) { int ret; @@ -1462,7 +1473,6 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) } } - ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]); if (dhd->iflist[ifidx] && !dhd->iflist[ifidx]->state) ifp = dhd->iflist[ifidx]; @@ -1473,6 +1483,14 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) dhdp->dstats.rx_bytes += skb->len; dhdp->rx_packets++; /* Local count */ + /* Dropping packets before registering net device to avoid kernel panic */ + if (!ifp->net || ifp->net->reg_state != NETREG_REGISTERED) { + DHD_ERROR(("%s: net device is NOT registered yet. drop [%s] packet\n", + __FUNCTION__, (ntoh16(skb->protocol) == ETHER_TYPE_BRCM) ? "event" : "data")); + PKTFREE(dhdp->osh, pktbuf, TRUE); + continue; + } + if (in_interrupt()) { netif_rx(skb); } else { @@ -2363,7 +2381,6 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) dhd_attach_states_t dhd_state = DHD_ATTACH_STATE_INIT; DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - /* updates firmware nvram path if it was provided as module parameters */ if ((firmware_path != NULL) && (firmware_path[0] != '\0')) strcpy(fw_path, firmware_path); @@ -2469,6 +2486,8 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) DHD_ERROR(("wl_cfg80211_attach failed\n")); goto fail; } + + dhd_monitor_init(&dhd->pub); dhd_state |= DHD_ATTACH_STATE_CFG80211; #endif #if defined(CONFIG_WIRELESS_EXT) @@ -2563,7 +2582,6 @@ fail: dhd_free(&dhd->pub); } - return NULL; } @@ -2665,7 +2683,11 @@ dhd_bus_start(dhd_pub_t *dhdp) setbit(dhdp->eventmask, WLC_E_TXFAIL); setbit(dhdp->eventmask, WLC_E_JOIN_START); setbit(dhdp->eventmask, WLC_E_SCAN_COMPLETE); - + setbit(dhdp->eventmask, WLC_E_ACTION_FRAME_RX); + setbit(dhdp->eventmask, WLC_E_ACTION_FRAME_COMPLETE); +#if defined(WLP2P) + setbit(dhdp->eventmask, WLC_E_P2P_PROBREQ_MSG); +#endif /* WLP2P */ #ifdef PNO_SUPPORT setbit(dhdp->eventmask, WLC_E_PFN_NET_FOUND); #endif /* PNO_SUPPORT */ @@ -2694,10 +2716,6 @@ dhd_bus_start(dhd_pub_t *dhdp) dhd_write_macaddr(dhd->pub.mac.octet); #endif -#if defined(CONFIG_SYSCTL) && defined(WL_CFG80211) - wl_cfg80211_sysctl_export_devaddr(&dhd->pub); -#endif - return 0; } @@ -2724,6 +2742,7 @@ dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf, uint cmd_len, in return ret; } + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) static struct net_device_ops dhd_ops_pri = { .ndo_open = dhd_open, @@ -2848,6 +2867,8 @@ static int dhd_device_event(struct notifier_block *this, __FUNCTION__)); aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, TRUE); } + else + aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, TRUE); #endif break; @@ -2923,12 +2944,18 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx) * We have to use the primary MAC for virtual interfaces */ memcpy(temp_addr, dhd->iflist[ifidx]->mac_addr, ETHER_ADDR_LEN); - if (ifidx == 1) { - DHD_TRACE(("%s ACCESS POINT MAC: \n", __FUNCTION__)); - /* ACCESSPOINT INTERFACE CASE */ - temp_addr[0] |= 0x02; /* set bit 2 , - Locally Administered address */ + /* + * Android sets the locally administered bit to indicate that this is a + * portable hotspot. This will not work in simultaneous AP/STA mode, + * nor with P2P. Need to set the Donlge's MAC address, and then use that. + */ + if (ifidx > 0) { + DHD_ERROR(("%s interface [%s]: set locally administered bit in MAC\n", + __func__, net->name)); + temp_addr[0] |= 0x02; } } + net->hard_header_len = ETH_HLEN + dhd->pub.hdrlen; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) net->ethtool_ops = &dhd_ethtool_ops; @@ -2951,11 +2978,11 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx) DHD_ERROR(("couldn't register the net device, err %d\n", err)); goto fail; } - - printf("%s: Driver up: Broadcom Dongle Host Driver mac=%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", + printf("Broadcom Dongle Host Driver: register interface [%s]" + " MAC: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", net->name, - dhd->pub.mac.octet[0], dhd->pub.mac.octet[1], dhd->pub.mac.octet[2], - dhd->pub.mac.octet[3], dhd->pub.mac.octet[4], dhd->pub.mac.octet[5]); + net->dev_addr[0], net->dev_addr[1], net->dev_addr[2], + net->dev_addr[3], net->dev_addr[4], net->dev_addr[5]); #if defined(SOFTAP) && defined(CONFIG_WIRELESS_EXT) && !defined(WL_CFG80211) wl_iw_iscan_set_scan_broadcast_prep(net, 1); @@ -3106,8 +3133,10 @@ void dhd_detach(dhd_pub_t *dhdp) } #ifdef WL_CFG80211 - if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) + if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) { wl_cfg80211_detach(); + dhd_monitor_uninit(); + } #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) @@ -3120,6 +3149,7 @@ void dhd_detach(dhd_pub_t *dhdp) wake_lock_destroy(&dhd->wl_rxwake); #endif } + } |