1f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger#include "headers.h"
2f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger
3f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemmingerstruct net_device *gblpnetdev;
4f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger
5f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemmingerstatic INT bcm_open(struct net_device *dev)
6f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger{
7d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev);
846c3790eb523931a803bb3c28c5bf8bbfc8acf48Stephen Hemminger
9d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	if (ad->fw_download_done == false) {
109ec4475bf10bb2c30cd5e927bc453aa307f58123Stephen Hemminger		pr_notice(PFX "%s: link up failed (download in progress)\n",
1100b6fb2e31ac668795857c9609adc11e7964ed5aVinay Sawal			  dev->name);
124fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger		return -EBUSY;
134fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger	}
144fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger
15d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	if (netif_msg_ifup(ad))
169ec4475bf10bb2c30cd5e927bc453aa307f58123Stephen Hemminger		pr_info(PFX "%s: enabling interface\n", dev->name);
174fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger
18d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	if (ad->LinkUpStatus) {
19d07b030130b94dfa527e010b66f0162699377035Matthias Beyer		if (netif_msg_link(ad))
209ec4475bf10bb2c30cd5e927bc453aa307f58123Stephen Hemminger			pr_info(PFX "%s: link up\n", dev->name);
210ad008fcbc39572ab7078975cdf7e902fbc39ce6Stephen Hemminger
22d07b030130b94dfa527e010b66f0162699377035Matthias Beyer		netif_carrier_on(ad->dev);
23d07b030130b94dfa527e010b66f0162699377035Matthias Beyer		netif_start_queue(ad->dev);
24f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger	}
25f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger
2646c3790eb523931a803bb3c28c5bf8bbfc8acf48Stephen Hemminger	return 0;
27f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger}
28f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger
29f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemmingerstatic INT bcm_close(struct net_device *dev)
30f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger{
31d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev);
324fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger
33d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	if (netif_msg_ifdown(ad))
349ec4475bf10bb2c30cd5e927bc453aa307f58123Stephen Hemminger		pr_info(PFX "%s: disabling interface\n", dev->name);
354fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger
364fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger	netif_carrier_off(dev);
374fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger	netif_stop_queue(dev);
384fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger
3946c3790eb523931a803bb3c28c5bf8bbfc8acf48Stephen Hemminger	return 0;
40f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger}
41f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger
42f663dd9aaf9ed124f25f0f8452edf238f087ad50Jason Wangstatic u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb,
4399932d4fc03a13bb3e94938fe25458fabc8f2fc3Daniel Borkmann			    void *accel_priv, select_queue_fallback_t fallback)
44937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger{
45937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger	return ClassifyPacket(netdev_priv(dev), skb);
46937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger}
47937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger
48937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger/*******************************************************************
49937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger* Function    -	bcm_transmit()
50937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger*
51937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger* Description - This is the main transmit function for our virtual
5246c3790eb523931a803bb3c28c5bf8bbfc8acf48Stephen Hemminger*		interface(eth0). It handles the ARP packets. It
5346c3790eb523931a803bb3c28c5bf8bbfc8acf48Stephen Hemminger*		clones this packet and then Queue it to a suitable
5400b6fb2e31ac668795857c9609adc11e7964ed5aVinay Sawal*		Queue. Then calls the transmit_packet().
55937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger*
56937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger* Parameter   -	 skb - Pointer to the socket buffer structure
5746c3790eb523931a803bb3c28c5bf8bbfc8acf48Stephen Hemminger*		 dev - Pointer to the virtual net device structure
58937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger*
59937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger*********************************************************************/
60937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger
61937110581650eaa517f045fb7b86b9828ba693adStephen Hemmingerstatic netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev)
62937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger{
63d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev);
64937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger	u16 qindex = skb_get_queue_mapping(skb);
65937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger
664fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger
67d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	if (ad->device_removed || !ad->LinkUpStatus)
68937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger		goto drop;
69937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger
70d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	if (ad->TransferMode != IP_PACKET_ONLY_MODE)
71937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger		goto drop;
72937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger
7346c3790eb523931a803bb3c28c5bf8bbfc8acf48Stephen Hemminger	if (INVALID_QUEUE_INDEX == qindex)
74937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger		goto drop;
75937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger
76d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	if (ad->PackInfo[qindex].uiCurrentPacketsOnHost >=
7746c3790eb523931a803bb3c28c5bf8bbfc8acf48Stephen Hemminger	    SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
78937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger		return NETDEV_TX_BUSY;
79937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger
80937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger	/* Now Enqueue the packet */
81d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	if (netif_msg_tx_queued(ad))
829ec4475bf10bb2c30cd5e927bc453aa307f58123Stephen Hemminger		pr_info(PFX "%s: enqueueing packet to queue %d\n",
834fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger			dev->name, qindex);
8446c3790eb523931a803bb3c28c5bf8bbfc8acf48Stephen Hemminger
85d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	spin_lock(&ad->PackInfo[qindex].SFQueueLock);
86d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	ad->PackInfo[qindex].uiCurrentBytesOnHost += skb->len;
87d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	ad->PackInfo[qindex].uiCurrentPacketsOnHost++;
88937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger
8946c3790eb523931a803bb3c28c5bf8bbfc8acf48Stephen Hemminger	*((B_UINT32 *) skb->cb + SKB_CB_LATENCY_OFFSET) = jiffies;
90d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	ENQUEUEPACKET(ad->PackInfo[qindex].FirstTxQueue,
91d07b030130b94dfa527e010b66f0162699377035Matthias Beyer		      ad->PackInfo[qindex].LastTxQueue, skb);
92d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	atomic_inc(&ad->TotalPacketCount);
93d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	spin_unlock(&ad->PackInfo[qindex].SFQueueLock);
94937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger
95937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger	/* FIXME - this is racy and incorrect, replace with work queue */
96d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	if (!atomic_read(&ad->TxPktAvail)) {
97d07b030130b94dfa527e010b66f0162699377035Matthias Beyer		atomic_set(&ad->TxPktAvail, 1);
98d07b030130b94dfa527e010b66f0162699377035Matthias Beyer		wake_up(&ad->tx_packet_wait_queue);
99937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger	}
100937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger	return NETDEV_TX_OK;
101937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger
102937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger drop:
103937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger	dev_kfree_skb(skb);
104937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger	return NETDEV_TX_OK;
105937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger}
106937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger
107937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger
108937110581650eaa517f045fb7b86b9828ba693adStephen Hemminger
109f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger/**
110f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger@ingroup init_functions
111f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen HemmingerRegister other driver entry points with the kernel
112f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger*/
1130ad008fcbc39572ab7078975cdf7e902fbc39ce6Stephen Hemmingerstatic const struct net_device_ops bcmNetDevOps = {
11400b6fb2e31ac668795857c9609adc11e7964ed5aVinay Sawal	.ndo_open		= bcm_open,
11500b6fb2e31ac668795857c9609adc11e7964ed5aVinay Sawal	.ndo_stop		= bcm_close,
11600b6fb2e31ac668795857c9609adc11e7964ed5aVinay Sawal	.ndo_start_xmit	        = bcm_transmit,
11700b6fb2e31ac668795857c9609adc11e7964ed5aVinay Sawal	.ndo_change_mtu	        = eth_change_mtu,
11800b6fb2e31ac668795857c9609adc11e7964ed5aVinay Sawal	.ndo_set_mac_address    = eth_mac_addr,
11900b6fb2e31ac668795857c9609adc11e7964ed5aVinay Sawal	.ndo_validate_addr	= eth_validate_addr,
12000b6fb2e31ac668795857c9609adc11e7964ed5aVinay Sawal	.ndo_select_queue	= bcm_select_queue,
121f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger};
1220ad008fcbc39572ab7078975cdf7e902fbc39ce6Stephen Hemminger
1230ad008fcbc39572ab7078975cdf7e902fbc39ce6Stephen Hemmingerstatic struct device_type wimax_type = {
1240ad008fcbc39572ab7078975cdf7e902fbc39ce6Stephen Hemminger	.name	= "wimax",
1250ad008fcbc39572ab7078975cdf7e902fbc39ce6Stephen Hemminger};
126f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger
127d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemmingerstatic int bcm_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
128d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger{
129d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger	cmd->supported		= 0;
130d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger	cmd->advertising	= 0;
131d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger	cmd->speed		= SPEED_10000;
132d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger	cmd->duplex		= DUPLEX_FULL;
133d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger	cmd->port		= PORT_TP;
134d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger	cmd->phy_address	= 0;
135d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger	cmd->transceiver	= XCVR_INTERNAL;
136d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger	cmd->autoneg		= AUTONEG_DISABLE;
137d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger	cmd->maxtxpkt		= 0;
138d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger	cmd->maxrxpkt		= 0;
139d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger	return 0;
140d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger}
141d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger
14200b6fb2e31ac668795857c9609adc11e7964ed5aVinay Sawalstatic void bcm_get_drvinfo(struct net_device *dev,
14300b6fb2e31ac668795857c9609adc11e7964ed5aVinay Sawal			    struct ethtool_drvinfo *info)
144d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger{
145d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev);
1469dd1e5542c1f1bbec2f66e30470b529cf8e30ad6Matthias Beyer	struct bcm_interface_adapter *intf_ad = ad->pvInterfaceAdapter;
1479dd1e5542c1f1bbec2f66e30470b529cf8e30ad6Matthias Beyer	struct usb_device *udev = interface_to_usbdev(intf_ad->interface);
148d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger
1497826d43f2db45c9305a6e0ba165650e1a203f517Jiri Pirko	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
1507826d43f2db45c9305a6e0ba165650e1a203f517Jiri Pirko	strlcpy(info->version, DRV_VERSION, sizeof(info->version));
151d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger	snprintf(info->fw_version, sizeof(info->fw_version), "%u.%u",
152d07b030130b94dfa527e010b66f0162699377035Matthias Beyer		 ad->uiFlashLayoutMajorVersion,
153d07b030130b94dfa527e010b66f0162699377035Matthias Beyer		 ad->uiFlashLayoutMinorVersion);
154d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger
155d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger	usb_make_path(udev, info->bus_info, sizeof(info->bus_info));
156d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger}
157d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger
158d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemmingerstatic u32 bcm_get_link(struct net_device *dev)
159d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger{
160d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev);
161d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger
162d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	return ad->LinkUpStatus;
163d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger}
164d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger
16500b6fb2e31ac668795857c9609adc11e7964ed5aVinay Sawalstatic u32 bcm_get_msglevel(struct net_device *dev)
1664fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger{
167d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev);
1684fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger
169d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	return ad->msg_enable;
1704fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger}
1714fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger
17200b6fb2e31ac668795857c9609adc11e7964ed5aVinay Sawalstatic void bcm_set_msglevel(struct net_device *dev, u32 level)
1734fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger{
174d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev);
1754fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger
176d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	ad->msg_enable = level;
1774fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger}
1784fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger
179d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemmingerstatic const struct ethtool_ops bcm_ethtool_ops = {
180d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger	.get_settings	= bcm_get_settings,
181d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger	.get_drvinfo	= bcm_get_drvinfo,
18200b6fb2e31ac668795857c9609adc11e7964ed5aVinay Sawal	.get_link	= bcm_get_link,
1834fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger	.get_msglevel	= bcm_get_msglevel,
1844fd64dd0c1b9317ffe6fdaf3de788e14df880d8dStephen Hemminger	.set_msglevel	= bcm_set_msglevel,
185d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger};
186d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger
187d07b030130b94dfa527e010b66f0162699377035Matthias Beyerint register_networkdev(struct bcm_mini_adapter *ad)
188f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger{
189d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	struct net_device *net = ad->dev;
1907f90417bb9c7f4638f87d75a24a22afc7cebc100Matthias Beyer	struct bcm_interface_adapter *intf_ad = ad->pvInterfaceAdapter;
1917f90417bb9c7f4638f87d75a24a22afc7cebc100Matthias Beyer	struct usb_interface *udev = intf_ad->interface;
1927f90417bb9c7f4638f87d75a24a22afc7cebc100Matthias Beyer	struct usb_device *xdev = intf_ad->udev;
1934ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger
1940ad008fcbc39572ab7078975cdf7e902fbc39ce6Stephen Hemminger	int result;
1950ad008fcbc39572ab7078975cdf7e902fbc39ce6Stephen Hemminger
19646c3790eb523931a803bb3c28c5bf8bbfc8acf48Stephen Hemminger	net->netdev_ops = &bcmNetDevOps;
197d21d6dde0280f0897ce6de1948bfaa5633867b28Stephen Hemminger	net->ethtool_ops = &bcm_ethtool_ops;
19846c3790eb523931a803bb3c28c5bf8bbfc8acf48Stephen Hemminger	net->mtu = MTU_SIZE;	/* 1400 Bytes */
199d7affd0f58c9f68441b4ce631d07fad2e6a448dbStephen Hemminger	net->tx_queue_len = TX_QLEN;
2007441698fe9eb0eb473cf1699d9cd8dd06dfeaf77Stephen Hemminger	net->flags |= IFF_NOARP;
2017441698fe9eb0eb473cf1699d9cd8dd06dfeaf77Stephen Hemminger
2022515ab628f227b0711393993fe3228e167cc988fStephen Hemminger	netif_carrier_off(net);
2030ad008fcbc39572ab7078975cdf7e902fbc39ce6Stephen Hemminger
2040ad008fcbc39572ab7078975cdf7e902fbc39ce6Stephen Hemminger	SET_NETDEV_DEVTYPE(net, &wimax_type);
2050ad008fcbc39572ab7078975cdf7e902fbc39ce6Stephen Hemminger
206f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger	/* Read the MAC Address from EEPROM */
207d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	result = ReadMacAddressFromNVM(ad);
2084ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger	if (result != STATUS_SUCCESS) {
2094ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger		dev_err(&udev->dev,
2104ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger			PFX "Error in Reading the mac Address: %d", result);
21100b6fb2e31ac668795857c9609adc11e7964ed5aVinay Sawal		return -EIO;
2124ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger	}
213f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger
2140ad008fcbc39572ab7078975cdf7e902fbc39ce6Stephen Hemminger	result = register_netdev(net);
2154ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger	if (result)
2164ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger		return result;
2174ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger
218d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	gblpnetdev = ad->dev;
219f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger
220d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	if (netif_msg_probe(ad))
2214ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger		dev_info(&udev->dev, PFX "%s: register usb-%s-%s %pM\n",
2224ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger			 net->name, xdev->bus->bus_name, xdev->devpath,
2234ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger			 net->dev_addr);
2244ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger
2254ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger	return 0;
2264ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger}
2274ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger
228d07b030130b94dfa527e010b66f0162699377035Matthias Beyervoid unregister_networkdev(struct bcm_mini_adapter *ad)
2294ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger{
230d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	struct net_device *net = ad->dev;
2317f90417bb9c7f4638f87d75a24a22afc7cebc100Matthias Beyer	struct bcm_interface_adapter *intf_ad = ad->pvInterfaceAdapter;
2327f90417bb9c7f4638f87d75a24a22afc7cebc100Matthias Beyer	struct usb_interface *udev = intf_ad->interface;
2337f90417bb9c7f4638f87d75a24a22afc7cebc100Matthias Beyer	struct usb_device *xdev = intf_ad->udev;
2344ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger
235d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	if (netif_msg_probe(ad))
2364ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger		dev_info(&udev->dev, PFX "%s: unregister usb-%s%s\n",
2374ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3Stephen Hemminger			 net->name, xdev->bus->bus_name, xdev->devpath);
23800b6fb2e31ac668795857c9609adc11e7964ed5aVinay Sawal
239d07b030130b94dfa527e010b66f0162699377035Matthias Beyer	unregister_netdev(ad->dev);
240f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger}
241