brintos

brintos / linux-shallow public Read only

0
0
Text · 36.9 KiB · da72fd2 Raw
1565 lines · c
1// SPDX-License-Identifier: ISC2/*3 * Copyright (c) 2010 Broadcom Corporation4 */5 6#include <linux/kernel.h>7#include <linux/etherdevice.h>8#include <linux/module.h>9#include <linux/inetdevice.h>10#include <linux/property.h>11#include <net/cfg80211.h>12#include <net/rtnetlink.h>13#include <net/addrconf.h>14#include <net/ieee80211_radiotap.h>15#include <net/ipv6.h>16#include <brcmu_utils.h>17#include <brcmu_wifi.h>18 19#include "core.h"20#include "bus.h"21#include "fwvid.h"22#include "debug.h"23#include "fwil_types.h"24#include "p2p.h"25#include "pno.h"26#include "cfg80211.h"27#include "fwil.h"28#include "feature.h"29#include "proto.h"30#include "pcie.h"31#include "common.h"32 33#define MAX_WAIT_FOR_8021X_TX			msecs_to_jiffies(950)34 35#define BRCMF_BSSIDX_INVALID			-136 37#define	RXS_PBPRES				BIT(2)38 39#define	D11_PHY_HDR_LEN				640 41struct d11rxhdr_le {42	__le16 RxFrameSize;43	u16 PAD;44	__le16 PhyRxStatus_0;45	__le16 PhyRxStatus_1;46	__le16 PhyRxStatus_2;47	__le16 PhyRxStatus_3;48	__le16 PhyRxStatus_4;49	__le16 PhyRxStatus_5;50	__le16 RxStatus1;51	__le16 RxStatus2;52	__le16 RxTSFTime;53	__le16 RxChan;54	u8 unknown[12];55} __packed;56 57struct wlc_d11rxhdr {58	struct d11rxhdr_le rxhdr;59	__le32 tsf_l;60	s8 rssi;61	s8 rxpwr0;62	s8 rxpwr1;63	s8 do_rssi_ma;64	s8 rxpwr[4];65} __packed;66 67char *brcmf_ifname(struct brcmf_if *ifp)68{69	if (!ifp)70		return "<if_null>";71 72	if (ifp->ndev)73		return ifp->ndev->name;74 75	return "<if_none>";76}77 78struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx)79{80	struct brcmf_if *ifp;81	s32 bsscfgidx;82 83	if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {84		bphy_err(drvr, "ifidx %d out of range\n", ifidx);85		return NULL;86	}87 88	ifp = NULL;89	bsscfgidx = drvr->if2bss[ifidx];90	if (bsscfgidx >= 0)91		ifp = drvr->iflist[bsscfgidx];92 93	return ifp;94}95 96void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable)97{98	s32 err;99	u32 mode;100 101	if (enable)102		mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;103	else104		mode = 0;105 106	/* Try to set and enable ARP offload feature, this may fail, then it  */107	/* is simply not supported and err 0 will be returned                 */108	err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);109	if (err) {110		brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",111			  mode, err);112	} else {113		err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);114		if (err) {115			brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",116				  enable, err);117		} else {118			brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",119				  enable, mode);120		}121	}122 123	err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable);124	if (err) {125		brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n",126			  enable, err);127	} else {128		brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n",129			  enable, mode);130	}131}132 133static void _brcmf_set_multicast_list(struct work_struct *work)134{135	struct brcmf_if *ifp = container_of(work, struct brcmf_if,136					    multicast_work);137	struct brcmf_pub *drvr = ifp->drvr;138	struct net_device *ndev;139	struct netdev_hw_addr *ha;140	u32 cmd_value, cnt;141	__le32 cnt_le;142	char *buf, *bufp;143	u32 buflen;144	s32 err;145 146	brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);147 148	ndev = ifp->ndev;149 150	/* Determine initial value of allmulti flag */151	cmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false;152 153	/* Send down the multicast list first. */154	cnt = netdev_mc_count(ndev);155	buflen = sizeof(cnt) + (cnt * ETH_ALEN);156	buf = kmalloc(buflen, GFP_KERNEL);157	if (!buf)158		return;159	bufp = buf;160 161	cnt_le = cpu_to_le32(cnt);162	memcpy(bufp, &cnt_le, sizeof(cnt_le));163	bufp += sizeof(cnt_le);164 165	netdev_for_each_mc_addr(ha, ndev) {166		if (!cnt)167			break;168		memcpy(bufp, ha->addr, ETH_ALEN);169		bufp += ETH_ALEN;170		cnt--;171	}172 173	err = brcmf_fil_iovar_data_set(ifp, "mcast_list", buf, buflen);174	if (err < 0) {175		bphy_err(drvr, "Setting mcast_list failed, %d\n", err);176		cmd_value = cnt ? true : cmd_value;177	}178 179	kfree(buf);180 181	/*182	 * Now send the allmulti setting.  This is based on the setting in the183	 * net_device flags, but might be modified above to be turned on if we184	 * were trying to set some addresses and dongle rejected it...185	 */186	err = brcmf_fil_iovar_int_set(ifp, "allmulti", cmd_value);187	if (err < 0)188		bphy_err(drvr, "Setting allmulti failed, %d\n", err);189 190	/*Finally, pick up the PROMISC flag */191	cmd_value = (ndev->flags & IFF_PROMISC) ? true : false;192	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PROMISC, cmd_value);193	if (err < 0) {194		/* PROMISC unsupported by firmware of older chips */195		if (err == -EBADE)196			bphy_info_once(drvr, "BRCMF_C_SET_PROMISC unsupported\n");197		else198			bphy_err(drvr, "Setting BRCMF_C_SET_PROMISC failed, err=%d\n",199				 err);200	}201	brcmf_configure_arp_nd_offload(ifp, !cmd_value);202}203 204#if IS_ENABLED(CONFIG_IPV6)205static void _brcmf_update_ndtable(struct work_struct *work)206{207	struct brcmf_if *ifp = container_of(work, struct brcmf_if,208					    ndoffload_work);209	struct brcmf_pub *drvr = ifp->drvr;210	int i, ret;211 212	/* clear the table in firmware */213	ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip_clear", NULL, 0);214	if (ret) {215		brcmf_dbg(TRACE, "fail to clear nd ip table err:%d\n", ret);216		return;217	}218 219	for (i = 0; i < ifp->ipv6addr_idx; i++) {220		ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip",221					       &ifp->ipv6_addr_tbl[i],222					       sizeof(struct in6_addr));223		if (ret)224			bphy_err(drvr, "add nd ip err %d\n", ret);225	}226}227#else228static void _brcmf_update_ndtable(struct work_struct *work)229{230}231#endif232 233static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)234{235	struct brcmf_if *ifp = netdev_priv(ndev);236	struct sockaddr *sa = (struct sockaddr *)addr;237	int err;238 239	brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);240 241	err = brcmf_c_set_cur_etheraddr(ifp, sa->sa_data);242	if (err >= 0) {243		brcmf_dbg(TRACE, "updated to %pM\n", sa->sa_data);244		memcpy(ifp->mac_addr, sa->sa_data, ETH_ALEN);245		eth_hw_addr_set(ifp->ndev, ifp->mac_addr);246	}247	return err;248}249 250static void brcmf_netdev_set_multicast_list(struct net_device *ndev)251{252	struct brcmf_if *ifp = netdev_priv(ndev);253 254	schedule_work(&ifp->multicast_work);255}256 257/**258 * brcmf_skb_is_iapp - checks if skb is an IAPP packet259 *260 * @skb: skb to check261 */262static bool brcmf_skb_is_iapp(struct sk_buff *skb)263{264	static const u8 iapp_l2_update_packet[6] __aligned(2) = {265		0x00, 0x01, 0xaf, 0x81, 0x01, 0x00,266	};267	unsigned char *eth_data;268#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)269	const u16 *a, *b;270#endif271 272	if (skb->len - skb->mac_len != 6 ||273	    !is_multicast_ether_addr(eth_hdr(skb)->h_dest))274		return false;275 276	eth_data = skb_mac_header(skb) + ETH_HLEN;277#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)278	return !(((*(const u32 *)eth_data) ^ (*(const u32 *)iapp_l2_update_packet)) |279		 ((*(const u16 *)(eth_data + 4)) ^ (*(const u16 *)(iapp_l2_update_packet + 4))));280#else281	a = (const u16 *)eth_data;282	b = (const u16 *)iapp_l2_update_packet;283 284	return !((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]));285#endif286}287 288static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,289					   struct net_device *ndev)290{291	int ret;292	struct brcmf_if *ifp = netdev_priv(ndev);293	struct brcmf_pub *drvr = ifp->drvr;294	struct ethhdr *eh;295	int head_delta;296	unsigned int tx_bytes = skb->len;297 298	brcmf_dbg(DATA, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);299 300	/* Can the device send data? */301	if (drvr->bus_if->state != BRCMF_BUS_UP) {302		bphy_err(drvr, "xmit rejected state=%d\n", drvr->bus_if->state);303		netif_stop_queue(ndev);304		dev_kfree_skb(skb);305		ret = -ENODEV;306		goto done;307	}308 309	/* Some recent Broadcom's firmwares disassociate STA when they receive310	 * an 802.11f ADD frame. This behavior can lead to a local DoS security311	 * issue. Attacker may trigger disassociation of any STA by sending a312	 * proper Ethernet frame to the wireless interface.313	 *314	 * Moreover this feature may break AP interfaces in some specific315	 * setups. This applies e.g. to the bridge with hairpin mode enabled and316	 * IFLA_BRPORT_MCAST_TO_UCAST set. IAPP packet generated by a firmware317	 * will get passed back to the wireless interface and cause immediate318	 * disassociation of a just-connected STA.319	 */320	if (!drvr->settings->iapp && brcmf_skb_is_iapp(skb)) {321		dev_kfree_skb(skb);322		ret = -EINVAL;323		goto done;324	}325 326	/* Make sure there's enough writeable headroom */327	if (skb_headroom(skb) < drvr->hdrlen || skb_header_cloned(skb)) {328		head_delta = max_t(int, drvr->hdrlen - skb_headroom(skb), 0);329 330		brcmf_dbg(INFO, "%s: insufficient headroom (%d)\n",331			  brcmf_ifname(ifp), head_delta);332		atomic_inc(&drvr->bus_if->stats.pktcowed);333		ret = pskb_expand_head(skb, ALIGN(head_delta, NET_SKB_PAD), 0,334				       GFP_ATOMIC);335		if (ret < 0) {336			bphy_err(drvr, "%s: failed to expand headroom\n",337				 brcmf_ifname(ifp));338			atomic_inc(&drvr->bus_if->stats.pktcow_failed);339			dev_kfree_skb(skb);340			goto done;341		}342	}343 344	/* validate length for ether packet */345	if (skb->len < sizeof(*eh)) {346		ret = -EINVAL;347		dev_kfree_skb(skb);348		goto done;349	}350 351	eh = (struct ethhdr *)(skb->data);352 353	if (eh->h_proto == htons(ETH_P_PAE))354		atomic_inc(&ifp->pend_8021x_cnt);355 356	/* determine the priority */357	if ((skb->priority == 0) || (skb->priority > 7))358		skb->priority = cfg80211_classify8021d(skb, NULL);359 360	/* set pacing shift for packet aggregation */361	sk_pacing_shift_update(skb->sk, 8);362 363	ret = brcmf_proto_tx_queue_data(drvr, ifp->ifidx, skb);364	if (ret < 0)365		brcmf_txfinalize(ifp, skb, false);366 367done:368	if (ret) {369		ndev->stats.tx_dropped++;370	} else {371		ndev->stats.tx_packets++;372		ndev->stats.tx_bytes += tx_bytes;373	}374 375	/* Return ok: we always eat the packet */376	return NETDEV_TX_OK;377}378 379void brcmf_txflowblock_if(struct brcmf_if *ifp,380			  enum brcmf_netif_stop_reason reason, bool state)381{382	unsigned long flags;383 384	if (!ifp || !ifp->ndev)385		return;386 387	brcmf_dbg(TRACE, "enter: bsscfgidx=%d stop=0x%X reason=%d state=%d\n",388		  ifp->bsscfgidx, ifp->netif_stop, reason, state);389 390	spin_lock_irqsave(&ifp->netif_stop_lock, flags);391	if (state) {392		if (!ifp->netif_stop)393			netif_stop_queue(ifp->ndev);394		ifp->netif_stop |= reason;395	} else {396		ifp->netif_stop &= ~reason;397		if (!ifp->netif_stop)398			netif_wake_queue(ifp->ndev);399	}400	spin_unlock_irqrestore(&ifp->netif_stop_lock, flags);401}402 403void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)404{405	/* Most of Broadcom's firmwares send 802.11f ADD frame every time a new406	 * STA connects to the AP interface. This is an obsoleted standard most407	 * users don't use, so don't pass these frames up unless requested.408	 */409	if (!ifp->drvr->settings->iapp && brcmf_skb_is_iapp(skb)) {410		brcmu_pkt_buf_free_skb(skb);411		return;412	}413 414	if (skb->pkt_type == PACKET_MULTICAST)415		ifp->ndev->stats.multicast++;416 417	if (!(ifp->ndev->flags & IFF_UP)) {418		brcmu_pkt_buf_free_skb(skb);419		return;420	}421 422	ifp->ndev->stats.rx_bytes += skb->len;423	ifp->ndev->stats.rx_packets++;424 425	brcmf_dbg(DATA, "rx proto=0x%X\n", ntohs(skb->protocol));426	netif_rx(skb);427}428 429void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb)430{431	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_RADIOTAP)) {432		/* Do nothing */433	} else if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR)) {434		struct wlc_d11rxhdr *wlc_rxhdr = (struct wlc_d11rxhdr *)skb->data;435		struct ieee80211_radiotap_header *radiotap;436		unsigned int offset;437		u16 RxStatus1;438 439		RxStatus1 = le16_to_cpu(wlc_rxhdr->rxhdr.RxStatus1);440 441		offset = sizeof(struct wlc_d11rxhdr);442		/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU443		 * subframes444		 */445		if (RxStatus1 & RXS_PBPRES)446			offset += 2;447		offset += D11_PHY_HDR_LEN;448 449		skb_pull(skb, offset);450 451		/* TODO: use RX header to fill some radiotap data */452		radiotap = skb_push(skb, sizeof(*radiotap));453		memset(radiotap, 0, sizeof(*radiotap));454		radiotap->it_len = cpu_to_le16(sizeof(*radiotap));455 456		/* TODO: 4 bytes with receive status? */457		skb->len -= 4;458	} else {459		struct ieee80211_radiotap_header *radiotap;460 461		/* TODO: use RX status to fill some radiotap data */462		radiotap = skb_push(skb, sizeof(*radiotap));463		memset(radiotap, 0, sizeof(*radiotap));464		radiotap->it_len = cpu_to_le16(sizeof(*radiotap));465 466		/* TODO: 4 bytes with receive status? */467		skb->len -= 4;468	}469 470	skb->dev = ifp->ndev;471	skb_reset_mac_header(skb);472	skb->pkt_type = PACKET_OTHERHOST;473	skb->protocol = htons(ETH_P_802_2);474 475	brcmf_netif_rx(ifp, skb);476}477 478static int brcmf_rx_hdrpull(struct brcmf_pub *drvr, struct sk_buff *skb,479			    struct brcmf_if **ifp)480{481	int ret;482 483	/* process and remove protocol-specific header */484	ret = brcmf_proto_hdrpull(drvr, true, skb, ifp);485 486	if (ret || !(*ifp) || !(*ifp)->ndev) {487		if (ret != -ENODATA && *ifp && (*ifp)->ndev)488			(*ifp)->ndev->stats.rx_errors++;489		brcmu_pkt_buf_free_skb(skb);490		return -ENODATA;491	}492 493	skb->protocol = eth_type_trans(skb, (*ifp)->ndev);494	return 0;495}496 497void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event,498		    bool inirq)499{500	struct brcmf_if *ifp;501	struct brcmf_bus *bus_if = dev_get_drvdata(dev);502	struct brcmf_pub *drvr = bus_if->drvr;503 504	brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb);505 506	if (brcmf_rx_hdrpull(drvr, skb, &ifp))507		return;508 509	if (brcmf_proto_is_reorder_skb(skb)) {510		brcmf_proto_rxreorder(ifp, skb);511	} else {512		/* Process special event packets */513		if (handle_event) {514			gfp_t gfp = inirq ? GFP_ATOMIC : GFP_KERNEL;515 516			brcmf_fweh_process_skb(ifp->drvr, skb,517					       BCMILCP_SUBTYPE_VENDOR_LONG, gfp);518		}519		brcmf_netif_rx(ifp, skb);520	}521}522 523void brcmf_rx_event(struct device *dev, struct sk_buff *skb)524{525	struct brcmf_if *ifp;526	struct brcmf_bus *bus_if = dev_get_drvdata(dev);527	struct brcmf_pub *drvr = bus_if->drvr;528 529	brcmf_dbg(EVENT, "Enter: %s: rxp=%p\n", dev_name(dev), skb);530 531	if (brcmf_rx_hdrpull(drvr, skb, &ifp))532		return;533 534	brcmf_fweh_process_skb(ifp->drvr, skb, 0, GFP_KERNEL);535	brcmu_pkt_buf_free_skb(skb);536}537 538void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success)539{540	struct ethhdr *eh;541	u16 type;542 543	eh = (struct ethhdr *)(txp->data);544	type = ntohs(eh->h_proto);545 546	if (type == ETH_P_PAE) {547		atomic_dec(&ifp->pend_8021x_cnt);548		if (waitqueue_active(&ifp->pend_8021x_wait))549			wake_up(&ifp->pend_8021x_wait);550	}551 552	if (!success)553		ifp->ndev->stats.tx_errors++;554 555	brcmu_pkt_buf_free_skb(txp);556}557 558static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,559				    struct ethtool_drvinfo *info)560{561	struct brcmf_if *ifp = netdev_priv(ndev);562	struct brcmf_pub *drvr = ifp->drvr;563	char drev[BRCMU_DOTREV_LEN] = "n/a";564 565	if (drvr->revinfo.result == 0)566		brcmu_dotrev_str(drvr->revinfo.driverrev, drev);567	strscpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));568	strscpy(info->version, drev, sizeof(info->version));569	strscpy(info->fw_version, drvr->fwver, sizeof(info->fw_version));570	strscpy(info->bus_info, dev_name(drvr->bus_if->dev),571		sizeof(info->bus_info));572}573 574static const struct ethtool_ops brcmf_ethtool_ops = {575	.get_drvinfo = brcmf_ethtool_get_drvinfo,576};577 578static int brcmf_netdev_stop(struct net_device *ndev)579{580	struct brcmf_if *ifp = netdev_priv(ndev);581 582	brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);583 584	brcmf_cfg80211_down(ndev);585 586	brcmf_net_setcarrier(ifp, false);587 588	return 0;589}590 591static int brcmf_netdev_open(struct net_device *ndev)592{593	struct brcmf_if *ifp = netdev_priv(ndev);594	struct brcmf_pub *drvr = ifp->drvr;595	struct brcmf_bus *bus_if = drvr->bus_if;596	u32 toe_ol;597 598	brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);599 600	/* If bus is not ready, can't continue */601	if (bus_if->state != BRCMF_BUS_UP) {602		bphy_err(drvr, "failed bus is not ready\n");603		return -EAGAIN;604	}605 606	atomic_set(&ifp->pend_8021x_cnt, 0);607 608	/* Get current TOE mode from dongle */609	if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0610	    && (toe_ol & TOE_TX_CSUM_OL) != 0)611		ndev->features |= NETIF_F_IP_CSUM;612	else613		ndev->features &= ~NETIF_F_IP_CSUM;614 615	if (brcmf_cfg80211_up(ndev)) {616		bphy_err(drvr, "failed to bring up cfg80211\n");617		return -EIO;618	}619 620	/* Clear, carrier, set when connected or AP mode. */621	netif_carrier_off(ndev);622	return 0;623}624 625static const struct net_device_ops brcmf_netdev_ops_pri = {626	.ndo_open = brcmf_netdev_open,627	.ndo_stop = brcmf_netdev_stop,628	.ndo_start_xmit = brcmf_netdev_start_xmit,629	.ndo_set_mac_address = brcmf_netdev_set_mac_address,630	.ndo_set_rx_mode = brcmf_netdev_set_multicast_list631};632 633int brcmf_net_attach(struct brcmf_if *ifp, bool locked)634{635	struct brcmf_pub *drvr = ifp->drvr;636	struct net_device *ndev;637	s32 err;638 639	brcmf_dbg(TRACE, "Enter, bsscfgidx=%d mac=%pM\n", ifp->bsscfgidx,640		  ifp->mac_addr);641	ndev = ifp->ndev;642 643	/* set appropriate operations */644	ndev->netdev_ops = &brcmf_netdev_ops_pri;645 646	ndev->needed_headroom += drvr->hdrlen;647	ndev->ethtool_ops = &brcmf_ethtool_ops;648 649	/* set the mac address & netns */650	eth_hw_addr_set(ndev, ifp->mac_addr);651	dev_net_set(ndev, wiphy_net(cfg_to_wiphy(drvr->config)));652 653	INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);654	INIT_WORK(&ifp->ndoffload_work, _brcmf_update_ndtable);655 656	if (locked)657		err = cfg80211_register_netdevice(ndev);658	else659		err = register_netdev(ndev);660	if (err != 0) {661		bphy_err(drvr, "couldn't register the net device\n");662		goto fail;663	}664 665	netif_carrier_off(ndev);666 667	ndev->priv_destructor = brcmf_cfg80211_free_netdev;668	brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);669	return 0;670 671fail:672	drvr->iflist[ifp->bsscfgidx] = NULL;673	ndev->netdev_ops = NULL;674	return -EBADE;675}676 677void brcmf_net_detach(struct net_device *ndev, bool locked)678{679	if (ndev->reg_state == NETREG_REGISTERED) {680		if (locked)681			cfg80211_unregister_netdevice(ndev);682		else683			unregister_netdev(ndev);684	} else {685		brcmf_cfg80211_free_netdev(ndev);686		free_netdev(ndev);687	}688}689 690static int brcmf_net_mon_open(struct net_device *ndev)691{692	struct brcmf_if *ifp = netdev_priv(ndev);693	struct brcmf_pub *drvr = ifp->drvr;694	u32 monitor;695	int err;696 697	brcmf_dbg(TRACE, "Enter\n");698 699	err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_MONITOR, &monitor);700	if (err) {701		bphy_err(drvr, "BRCMF_C_GET_MONITOR error (%d)\n", err);702		return err;703	} else if (monitor) {704		bphy_err(drvr, "Monitor mode is already enabled\n");705		return -EEXIST;706	}707 708	monitor = 3;709	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_MONITOR, monitor);710	if (err)711		bphy_err(drvr, "BRCMF_C_SET_MONITOR error (%d)\n", err);712 713	return err;714}715 716static int brcmf_net_mon_stop(struct net_device *ndev)717{718	struct brcmf_if *ifp = netdev_priv(ndev);719	struct brcmf_pub *drvr = ifp->drvr;720	u32 monitor;721	int err;722 723	brcmf_dbg(TRACE, "Enter\n");724 725	monitor = 0;726	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_MONITOR, monitor);727	if (err)728		bphy_err(drvr, "BRCMF_C_SET_MONITOR error (%d)\n", err);729 730	return err;731}732 733static netdev_tx_t brcmf_net_mon_start_xmit(struct sk_buff *skb,734					    struct net_device *ndev)735{736	dev_kfree_skb_any(skb);737 738	return NETDEV_TX_OK;739}740 741static const struct net_device_ops brcmf_netdev_ops_mon = {742	.ndo_open = brcmf_net_mon_open,743	.ndo_stop = brcmf_net_mon_stop,744	.ndo_start_xmit = brcmf_net_mon_start_xmit,745};746 747int brcmf_net_mon_attach(struct brcmf_if *ifp)748{749	struct brcmf_pub *drvr = ifp->drvr;750	struct net_device *ndev;751	int err;752 753	brcmf_dbg(TRACE, "Enter\n");754 755	ndev = ifp->ndev;756	ndev->netdev_ops = &brcmf_netdev_ops_mon;757 758	err = cfg80211_register_netdevice(ndev);759	if (err)760		bphy_err(drvr, "Failed to register %s device\n", ndev->name);761 762	return err;763}764 765void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on)766{767	struct net_device *ndev;768 769	brcmf_dbg(TRACE, "Enter, bsscfgidx=%d carrier=%d\n", ifp->bsscfgidx,770		  on);771 772	ndev = ifp->ndev;773	brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_DISCONNECTED, !on);774	if (on) {775		if (!netif_carrier_ok(ndev))776			netif_carrier_on(ndev);777 778	} else {779		if (netif_carrier_ok(ndev))780			netif_carrier_off(ndev);781	}782}783 784static int brcmf_net_p2p_open(struct net_device *ndev)785{786	brcmf_dbg(TRACE, "Enter\n");787 788	return brcmf_cfg80211_up(ndev);789}790 791static int brcmf_net_p2p_stop(struct net_device *ndev)792{793	brcmf_dbg(TRACE, "Enter\n");794 795	return brcmf_cfg80211_down(ndev);796}797 798static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb,799					    struct net_device *ndev)800{801	if (skb)802		dev_kfree_skb_any(skb);803 804	return NETDEV_TX_OK;805}806 807static const struct net_device_ops brcmf_netdev_ops_p2p = {808	.ndo_open = brcmf_net_p2p_open,809	.ndo_stop = brcmf_net_p2p_stop,810	.ndo_start_xmit = brcmf_net_p2p_start_xmit811};812 813static int brcmf_net_p2p_attach(struct brcmf_if *ifp)814{815	struct brcmf_pub *drvr = ifp->drvr;816	struct net_device *ndev;817 818	brcmf_dbg(TRACE, "Enter, bsscfgidx=%d mac=%pM\n", ifp->bsscfgidx,819		  ifp->mac_addr);820	ndev = ifp->ndev;821 822	ndev->netdev_ops = &brcmf_netdev_ops_p2p;823 824	/* set the mac address */825	eth_hw_addr_set(ndev, ifp->mac_addr);826 827	if (register_netdev(ndev) != 0) {828		bphy_err(drvr, "couldn't register the p2p net device\n");829		goto fail;830	}831 832	brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);833 834	return 0;835 836fail:837	ifp->drvr->iflist[ifp->bsscfgidx] = NULL;838	ndev->netdev_ops = NULL;839	return -EBADE;840}841 842struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,843			      bool is_p2pdev, const char *name, u8 *mac_addr)844{845	struct brcmf_if *ifp;846	struct net_device *ndev;847 848	brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", bsscfgidx, ifidx);849 850	ifp = drvr->iflist[bsscfgidx];851	/*852	 * Delete the existing interface before overwriting it853	 * in case we missed the BRCMF_E_IF_DEL event.854	 */855	if (ifp) {856		if (ifidx) {857			bphy_err(drvr, "ERROR: netdev:%s already exists\n",858				 ifp->ndev->name);859			netif_stop_queue(ifp->ndev);860			brcmf_net_detach(ifp->ndev, false);861			drvr->iflist[bsscfgidx] = NULL;862		} else {863			brcmf_dbg(INFO, "netdev:%s ignore IF event\n",864				  ifp->ndev->name);865			return ERR_PTR(-EINVAL);866		}867	}868 869	if (!drvr->settings->p2p_enable && is_p2pdev) {870		/* this is P2P_DEVICE interface */871		brcmf_dbg(INFO, "allocate non-netdev interface\n");872		ifp = kzalloc(sizeof(*ifp), GFP_KERNEL);873		if (!ifp)874			return ERR_PTR(-ENOMEM);875	} else {876		brcmf_dbg(INFO, "allocate netdev interface\n");877		/* Allocate netdev, including space for private structure */878		ndev = alloc_netdev(sizeof(*ifp), is_p2pdev ? "p2p%d" : name,879				    NET_NAME_UNKNOWN, ether_setup);880		if (!ndev)881			return ERR_PTR(-ENOMEM);882 883		ndev->needs_free_netdev = true;884		ifp = netdev_priv(ndev);885		ifp->ndev = ndev;886		/* store mapping ifidx to bsscfgidx */887		if (drvr->if2bss[ifidx] == BRCMF_BSSIDX_INVALID)888			drvr->if2bss[ifidx] = bsscfgidx;889	}890 891	ifp->drvr = drvr;892	drvr->iflist[bsscfgidx] = ifp;893	ifp->ifidx = ifidx;894	ifp->bsscfgidx = bsscfgidx;895 896	init_waitqueue_head(&ifp->pend_8021x_wait);897	spin_lock_init(&ifp->netif_stop_lock);898 899	if (mac_addr != NULL)900		memcpy(ifp->mac_addr, mac_addr, ETH_ALEN);901 902	brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n",903		  current->pid, name, ifp->mac_addr);904 905	return ifp;906}907 908static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx,909			 bool locked)910{911	struct brcmf_if *ifp;912	int ifidx;913 914	ifp = drvr->iflist[bsscfgidx];915	if (!ifp) {916		bphy_err(drvr, "Null interface, bsscfgidx=%d\n", bsscfgidx);917		return;918	}919	brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", bsscfgidx,920		  ifp->ifidx);921	ifidx = ifp->ifidx;922 923	if (ifp->ndev) {924		if (bsscfgidx == 0) {925			if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {926				rtnl_lock();927				brcmf_netdev_stop(ifp->ndev);928				rtnl_unlock();929			}930		} else {931			netif_stop_queue(ifp->ndev);932		}933 934		if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {935			cancel_work_sync(&ifp->multicast_work);936			cancel_work_sync(&ifp->ndoffload_work);937		}938		brcmf_net_detach(ifp->ndev, locked);939	} else {940		/* Only p2p device interfaces which get dynamically created941		 * end up here. In this case the p2p module should be informed942		 * about the removal of the interface within the firmware. If943		 * not then p2p commands towards the firmware will cause some944		 * serious troublesome side effects. The p2p module will clean945		 * up the ifp if needed.946		 */947		brcmf_p2p_ifp_removed(ifp, locked);948		kfree(ifp);949	}950 951	drvr->iflist[bsscfgidx] = NULL;952	if (drvr->if2bss[ifidx] == bsscfgidx)953		drvr->if2bss[ifidx] = BRCMF_BSSIDX_INVALID;954}955 956void brcmf_remove_interface(struct brcmf_if *ifp, bool locked)957{958	if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bsscfgidx] != ifp))959		return;960	brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", ifp->bsscfgidx,961		  ifp->ifidx);962	brcmf_proto_del_if(ifp->drvr, ifp);963	brcmf_del_if(ifp->drvr, ifp->bsscfgidx, locked);964}965 966static int brcmf_psm_watchdog_notify(struct brcmf_if *ifp,967				     const struct brcmf_event_msg *evtmsg,968				     void *data)969{970	struct brcmf_pub *drvr = ifp->drvr;971	int err;972 973	brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx);974 975	bphy_err(drvr, "PSM's watchdog has fired!\n");976 977	err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data,978					 evtmsg->datalen);979	if (err)980		bphy_err(drvr, "Failed to get memory dump, %d\n", err);981 982	return err;983}984 985#ifdef CONFIG_INET986#define ARPOL_MAX_ENTRIES	8987static int brcmf_inetaddr_changed(struct notifier_block *nb,988				  unsigned long action, void *data)989{990	struct brcmf_pub *drvr = container_of(nb, struct brcmf_pub,991					      inetaddr_notifier);992	struct in_ifaddr *ifa = data;993	struct net_device *ndev = ifa->ifa_dev->dev;994	struct brcmf_if *ifp;995	int idx, i, ret;996	u32 val;997	__be32 addr_table[ARPOL_MAX_ENTRIES] = {0};998 999	/* Find out if the notification is meant for us */1000	for (idx = 0; idx < BRCMF_MAX_IFS; idx++) {1001		ifp = drvr->iflist[idx];1002		if (ifp && ifp->ndev == ndev)1003			break;1004		if (idx == BRCMF_MAX_IFS - 1)1005			return NOTIFY_DONE;1006	}1007 1008	/* check if arp offload is supported */1009	ret = brcmf_fil_iovar_int_get(ifp, "arpoe", &val);1010	if (ret)1011		return NOTIFY_OK;1012 1013	/* old version only support primary index */1014	ret = brcmf_fil_iovar_int_get(ifp, "arp_version", &val);1015	if (ret)1016		val = 1;1017	if (val == 1)1018		ifp = drvr->iflist[0];1019 1020	/* retrieve the table from firmware */1021	ret = brcmf_fil_iovar_data_get(ifp, "arp_hostip", addr_table,1022				       sizeof(addr_table));1023	if (ret) {1024		bphy_err(drvr, "fail to get arp ip table err:%d\n", ret);1025		return NOTIFY_OK;1026	}1027 1028	for (i = 0; i < ARPOL_MAX_ENTRIES; i++)1029		if (ifa->ifa_address == addr_table[i])1030			break;1031 1032	switch (action) {1033	case NETDEV_UP:1034		if (i == ARPOL_MAX_ENTRIES) {1035			brcmf_dbg(TRACE, "add %pI4 to arp table\n",1036				  &ifa->ifa_address);1037			/* set it directly */1038			ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip",1039				&ifa->ifa_address, sizeof(ifa->ifa_address));1040			if (ret)1041				bphy_err(drvr, "add arp ip err %d\n", ret);1042		}1043		break;1044	case NETDEV_DOWN:1045		if (i < ARPOL_MAX_ENTRIES) {1046			addr_table[i] = 0;1047			brcmf_dbg(TRACE, "remove %pI4 from arp table\n",1048				  &ifa->ifa_address);1049			/* clear the table in firmware */1050			ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear",1051						       NULL, 0);1052			if (ret) {1053				bphy_err(drvr, "fail to clear arp ip table err:%d\n",1054					 ret);1055				return NOTIFY_OK;1056			}1057			for (i = 0; i < ARPOL_MAX_ENTRIES; i++) {1058				if (addr_table[i] == 0)1059					continue;1060				ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip",1061							       &addr_table[i],1062							       sizeof(addr_table[i]));1063				if (ret)1064					bphy_err(drvr, "add arp ip err %d\n",1065						 ret);1066			}1067		}1068		break;1069	default:1070		break;1071	}1072 1073	return NOTIFY_OK;1074}1075#endif1076 1077#if IS_ENABLED(CONFIG_IPV6)1078static int brcmf_inet6addr_changed(struct notifier_block *nb,1079				   unsigned long action, void *data)1080{1081	struct brcmf_pub *drvr = container_of(nb, struct brcmf_pub,1082					      inet6addr_notifier);1083	struct inet6_ifaddr *ifa = data;1084	struct brcmf_if *ifp;1085	int i;1086	struct in6_addr *table;1087 1088	/* Only handle primary interface */1089	ifp = drvr->iflist[0];1090	if (!ifp)1091		return NOTIFY_DONE;1092	if (ifp->ndev != ifa->idev->dev)1093		return NOTIFY_DONE;1094 1095	table = ifp->ipv6_addr_tbl;1096	for (i = 0; i < NDOL_MAX_ENTRIES; i++)1097		if (ipv6_addr_equal(&ifa->addr, &table[i]))1098			break;1099 1100	switch (action) {1101	case NETDEV_UP:1102		if (i == NDOL_MAX_ENTRIES) {1103			if (ifp->ipv6addr_idx < NDOL_MAX_ENTRIES) {1104				table[ifp->ipv6addr_idx++] = ifa->addr;1105			} else {1106				for (i = 0; i < NDOL_MAX_ENTRIES - 1; i++)1107					table[i] = table[i + 1];1108				table[NDOL_MAX_ENTRIES - 1] = ifa->addr;1109			}1110		}1111		break;1112	case NETDEV_DOWN:1113		if (i < NDOL_MAX_ENTRIES) {1114			for (; i < ifp->ipv6addr_idx - 1; i++)1115				table[i] = table[i + 1];1116			memset(&table[i], 0, sizeof(table[i]));1117			ifp->ipv6addr_idx--;1118		}1119		break;1120	default:1121		break;1122	}1123 1124	schedule_work(&ifp->ndoffload_work);1125 1126	return NOTIFY_OK;1127}1128#endif1129 1130static int brcmf_revinfo_read(struct seq_file *s, void *data)1131{1132	struct brcmf_bus *bus_if = dev_get_drvdata(s->private);1133	struct brcmf_rev_info *ri = &bus_if->drvr->revinfo;1134	char drev[BRCMU_DOTREV_LEN];1135	char brev[BRCMU_BOARDREV_LEN];1136 1137	seq_printf(s, "vendorid: 0x%04x\n", ri->vendorid);1138	seq_printf(s, "deviceid: 0x%04x\n", ri->deviceid);1139	seq_printf(s, "radiorev: %s\n", brcmu_dotrev_str(ri->radiorev, drev));1140	seq_printf(s, "chip: %s (%s)\n", ri->chipname,1141		   brcmf_fwvid_vendor_name(bus_if->drvr));1142	seq_printf(s, "chippkg: %u\n", ri->chippkg);1143	seq_printf(s, "corerev: %u\n", ri->corerev);1144	seq_printf(s, "boardid: 0x%04x\n", ri->boardid);1145	seq_printf(s, "boardvendor: 0x%04x\n", ri->boardvendor);1146	seq_printf(s, "boardrev: %s\n", brcmu_boardrev_str(ri->boardrev, brev));1147	seq_printf(s, "driverrev: %s\n", brcmu_dotrev_str(ri->driverrev, drev));1148	seq_printf(s, "ucoderev: %u\n", ri->ucoderev);1149	seq_printf(s, "bus: %u\n", ri->bus);1150	seq_printf(s, "phytype: %u\n", ri->phytype);1151	seq_printf(s, "phyrev: %u\n", ri->phyrev);1152	seq_printf(s, "anarev: %u\n", ri->anarev);1153	seq_printf(s, "nvramrev: %08x\n", ri->nvramrev);1154 1155	seq_printf(s, "clmver: %s\n", bus_if->drvr->clmver);1156 1157	return 0;1158}1159 1160static void brcmf_core_bus_reset(struct work_struct *work)1161{1162	struct brcmf_pub *drvr = container_of(work, struct brcmf_pub,1163					      bus_reset);1164 1165	brcmf_bus_reset(drvr->bus_if);1166}1167 1168static ssize_t bus_reset_write(struct file *file, const char __user *user_buf,1169			       size_t count, loff_t *ppos)1170{1171	struct brcmf_pub *drvr = file->private_data;1172	u8 value;1173 1174	if (kstrtou8_from_user(user_buf, count, 0, &value))1175		return -EINVAL;1176 1177	if (value != 1)1178		return -EINVAL;1179 1180	schedule_work(&drvr->bus_reset);1181 1182	return count;1183}1184 1185static const struct file_operations bus_reset_fops = {1186	.open	= simple_open,1187	.write	= bus_reset_write,1188};1189 1190static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops)1191{1192	int ret = -1;1193	struct brcmf_bus *bus_if = drvr->bus_if;1194	struct brcmf_if *ifp;1195	struct brcmf_if *p2p_ifp;1196 1197	brcmf_dbg(TRACE, "\n");1198 1199	/* add primary networking interface */1200	ifp = brcmf_add_if(drvr, 0, 0, false, "wlan%d",1201			   is_valid_ether_addr(drvr->settings->mac) ? drvr->settings->mac : NULL);1202	if (IS_ERR(ifp))1203		return PTR_ERR(ifp);1204 1205	p2p_ifp = NULL;1206 1207	/* signal bus ready */1208	brcmf_bus_change_state(bus_if, BRCMF_BUS_UP);1209 1210	/* do bus specific preinit here */1211	ret = brcmf_bus_preinit(bus_if);1212	if (ret < 0)1213		goto fail;1214 1215	/* Bus is ready, do any initialization */1216	ret = brcmf_c_preinit_dcmds(ifp);1217	if (ret < 0)1218		goto fail;1219 1220	brcmf_feat_attach(drvr);1221 1222	ret = brcmf_proto_init_done(drvr);1223	if (ret < 0)1224		goto fail;1225 1226	brcmf_proto_add_if(drvr, ifp);1227 1228	drvr->config = brcmf_cfg80211_attach(drvr, ops,1229					     drvr->settings->p2p_enable);1230	if (drvr->config == NULL) {1231		ret = -ENOMEM;1232		goto fail;1233	}1234 1235	ret = brcmf_net_attach(ifp, false);1236 1237	if ((!ret) && (drvr->settings->p2p_enable)) {1238		p2p_ifp = drvr->iflist[1];1239		if (p2p_ifp)1240			ret = brcmf_net_p2p_attach(p2p_ifp);1241	}1242 1243	if (ret)1244		goto fail;1245 1246#ifdef CONFIG_INET1247	drvr->inetaddr_notifier.notifier_call = brcmf_inetaddr_changed;1248	ret = register_inetaddr_notifier(&drvr->inetaddr_notifier);1249	if (ret)1250		goto fail;1251 1252#if IS_ENABLED(CONFIG_IPV6)1253	drvr->inet6addr_notifier.notifier_call = brcmf_inet6addr_changed;1254	ret = register_inet6addr_notifier(&drvr->inet6addr_notifier);1255	if (ret) {1256		unregister_inetaddr_notifier(&drvr->inetaddr_notifier);1257		goto fail;1258	}1259#endif1260#endif /* CONFIG_INET */1261 1262	INIT_WORK(&drvr->bus_reset, brcmf_core_bus_reset);1263 1264	/* populate debugfs */1265	brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read);1266	debugfs_create_file("reset", 0600, brcmf_debugfs_get_devdir(drvr), drvr,1267			    &bus_reset_fops);1268	brcmf_feat_debugfs_create(drvr);1269	brcmf_proto_debugfs_create(drvr);1270	brcmf_bus_debugfs_create(bus_if);1271 1272	return 0;1273 1274fail:1275	bphy_err(drvr, "failed: %d\n", ret);1276	if (drvr->config) {1277		brcmf_cfg80211_detach(drvr->config);1278		drvr->config = NULL;1279	}1280	brcmf_net_detach(ifp->ndev, false);1281	if (p2p_ifp)1282		brcmf_net_detach(p2p_ifp->ndev, false);1283	drvr->iflist[0] = NULL;1284	drvr->iflist[1] = NULL;1285	if (drvr->settings->ignore_probe_fail)1286		ret = 0;1287 1288	return ret;1289}1290 1291int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings)1292{1293	struct wiphy *wiphy;1294	struct cfg80211_ops *ops;1295	struct brcmf_pub *drvr = NULL;1296 1297	brcmf_dbg(TRACE, "Enter\n");1298 1299	ops = brcmf_cfg80211_get_ops(settings);1300	if (!ops)1301		return -ENOMEM;1302 1303	wiphy = wiphy_new(ops, sizeof(*drvr));1304	if (!wiphy) {1305		kfree(ops);1306		return -ENOMEM;1307	}1308 1309	set_wiphy_dev(wiphy, dev);1310	drvr = wiphy_priv(wiphy);1311	drvr->wiphy = wiphy;1312	drvr->ops = ops;1313	drvr->bus_if = dev_get_drvdata(dev);1314	drvr->bus_if->drvr = drvr;1315	drvr->settings = settings;1316 1317	return 0;1318}1319 1320int brcmf_attach(struct device *dev)1321{1322	struct brcmf_bus *bus_if = dev_get_drvdata(dev);1323	struct brcmf_pub *drvr = bus_if->drvr;1324	int ret = 0;1325	int i;1326 1327	brcmf_dbg(TRACE, "Enter\n");1328 1329	for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++)1330		drvr->if2bss[i] = BRCMF_BSSIDX_INVALID;1331 1332	mutex_init(&drvr->proto_block);1333 1334	/* Link to bus module */1335	drvr->hdrlen = 0;1336 1337	ret = brcmf_fwvid_attach(drvr);1338	if (ret != 0) {1339		bphy_err(drvr, "brcmf_fwvid_attach failed\n");1340		goto fail;1341	}1342 1343	/* Attach and link in the protocol */1344	ret = brcmf_proto_attach(drvr);1345	if (ret != 0) {1346		bphy_err(drvr, "brcmf_prot_attach failed\n");1347		goto fail;1348	}1349 1350	/* attach firmware event handler */1351	ret = brcmf_fweh_attach(drvr);1352	if (ret != 0) {1353		bphy_err(drvr, "brcmf_fweh_attach failed\n");1354		goto fail;1355	}1356 1357	/* Attach to events important for core code */1358	brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG,1359			    brcmf_psm_watchdog_notify);1360 1361	ret = brcmf_bus_started(drvr, drvr->ops);1362	if (ret != 0) {1363		bphy_err(drvr, "dongle is not responding: err=%d\n", ret);1364		goto fail;1365	}1366 1367	return 0;1368 1369fail:1370	brcmf_detach(dev);1371 1372	return ret;1373}1374 1375void brcmf_bus_add_txhdrlen(struct device *dev, uint len)1376{1377	struct brcmf_bus *bus_if = dev_get_drvdata(dev);1378	struct brcmf_pub *drvr = bus_if->drvr;1379 1380	if (drvr) {1381		drvr->hdrlen += len;1382	}1383}1384 1385void brcmf_dev_reset(struct device *dev)1386{1387	struct brcmf_bus *bus_if = dev_get_drvdata(dev);1388	struct brcmf_pub *drvr = bus_if->drvr;1389 1390	if (drvr == NULL)1391		return;1392 1393	if (drvr->iflist[0])1394		brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1);1395}1396 1397void brcmf_dev_coredump(struct device *dev)1398{1399	struct brcmf_bus *bus_if = dev_get_drvdata(dev);1400 1401	if (brcmf_debug_create_memdump(bus_if, NULL, 0) < 0)1402		brcmf_dbg(TRACE, "failed to create coredump\n");1403}1404 1405void brcmf_fw_crashed(struct device *dev)1406{1407	struct brcmf_bus *bus_if = dev_get_drvdata(dev);1408	struct brcmf_pub *drvr = bus_if->drvr;1409 1410	bphy_err(drvr, "Firmware has halted or crashed\n");1411 1412	brcmf_dev_coredump(dev);1413 1414	if (drvr->bus_reset.func)1415		schedule_work(&drvr->bus_reset);1416}1417 1418void brcmf_detach(struct device *dev)1419{1420	s32 i;1421	struct brcmf_bus *bus_if = dev_get_drvdata(dev);1422	struct brcmf_pub *drvr = bus_if->drvr;1423 1424	brcmf_dbg(TRACE, "Enter\n");1425 1426	if (drvr == NULL)1427		return;1428 1429#ifdef CONFIG_INET1430	unregister_inetaddr_notifier(&drvr->inetaddr_notifier);1431#endif1432 1433#if IS_ENABLED(CONFIG_IPV6)1434	unregister_inet6addr_notifier(&drvr->inet6addr_notifier);1435#endif1436 1437	brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN);1438	/* make sure primary interface removed last */1439	for (i = BRCMF_MAX_IFS - 1; i > -1; i--) {1440		if (drvr->iflist[i])1441			brcmf_remove_interface(drvr->iflist[i], false);1442	}1443	brcmf_bus_stop(drvr->bus_if);1444 1445	brcmf_fweh_detach(drvr);1446	brcmf_proto_detach(drvr);1447 1448	if (drvr->mon_if) {1449		brcmf_net_detach(drvr->mon_if->ndev, false);1450		drvr->mon_if = NULL;1451	}1452 1453	if (drvr->config) {1454		brcmf_p2p_detach(&drvr->config->p2p);1455		brcmf_cfg80211_detach(drvr->config);1456		drvr->config = NULL;1457	}1458 1459	brcmf_fwvid_detach(drvr);1460}1461 1462void brcmf_free(struct device *dev)1463{1464	struct brcmf_bus *bus_if = dev_get_drvdata(dev);1465	struct brcmf_pub *drvr = bus_if->drvr;1466 1467	if (!drvr)1468		return;1469 1470	bus_if->drvr = NULL;1471 1472	kfree(drvr->ops);1473 1474	wiphy_free(drvr->wiphy);1475}1476 1477s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len)1478{1479	struct brcmf_bus *bus_if = dev_get_drvdata(dev);1480	struct brcmf_if *ifp = bus_if->drvr->iflist[0];1481 1482	return brcmf_fil_iovar_data_set(ifp, name, data, len);1483}1484 1485static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)1486{1487	return atomic_read(&ifp->pend_8021x_cnt);1488}1489 1490int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp)1491{1492	struct brcmf_pub *drvr = ifp->drvr;1493	int err;1494 1495	err = wait_event_timeout(ifp->pend_8021x_wait,1496				 !brcmf_get_pend_8021x_cnt(ifp),1497				 MAX_WAIT_FOR_8021X_TX);1498 1499	if (!err) {1500		bphy_err(drvr, "Timed out waiting for no pending 802.1x packets\n");1501		atomic_set(&ifp->pend_8021x_cnt, 0);1502	}1503 1504	return !err;1505}1506 1507void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state)1508{1509	struct brcmf_pub *drvr = bus->drvr;1510	struct net_device *ndev;1511	int ifidx;1512 1513	brcmf_dbg(TRACE, "%d -> %d\n", bus->state, state);1514 1515	if (!drvr) {1516		brcmf_dbg(INFO, "ignoring transition, bus not attached yet\n");1517		return;1518	}1519 1520	bus->state = state;1521 1522	if (state == BRCMF_BUS_UP) {1523		for (ifidx = 0; ifidx < BRCMF_MAX_IFS; ifidx++) {1524			if ((drvr->iflist[ifidx]) &&1525			    (drvr->iflist[ifidx]->ndev)) {1526				ndev = drvr->iflist[ifidx]->ndev;1527				if (netif_queue_stopped(ndev))1528					netif_wake_queue(ndev);1529			}1530		}1531	}1532}1533 1534int __init brcmf_core_init(void)1535{1536	int err;1537 1538	err = brcmf_sdio_register();1539	if (err)1540		return err;1541 1542	err = brcmf_usb_register();1543	if (err)1544		goto error_usb_register;1545 1546	err = brcmf_pcie_register();1547	if (err)1548		goto error_pcie_register;1549	return 0;1550 1551error_pcie_register:1552	brcmf_usb_exit();1553error_usb_register:1554	brcmf_sdio_exit();1555	return err;1556}1557 1558void __exit brcmf_core_exit(void)1559{1560	brcmf_sdio_exit();1561	brcmf_usb_exit();1562	brcmf_pcie_exit();1563}1564 1565