1#include "headers.h"
2
3struct net_device *gblpnetdev;
4
5static INT bcm_open(struct net_device *dev)
6{
7	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
8
9	if (Adapter->fw_download_done == FALSE) {
10		pr_notice(PFX "%s: link up failed (download in progress)\n",
11			  dev->name);
12		return -EBUSY;
13	}
14
15	if (netif_msg_ifup(Adapter))
16		pr_info(PFX "%s: enabling interface\n", dev->name);
17
18	if (Adapter->LinkUpStatus) {
19		if (netif_msg_link(Adapter))
20			pr_info(PFX "%s: link up\n", dev->name);
21
22		netif_carrier_on(Adapter->dev);
23		netif_start_queue(Adapter->dev);
24	}
25
26	return 0;
27}
28
29static INT bcm_close(struct net_device *dev)
30{
31	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
32
33	if (netif_msg_ifdown(Adapter))
34		pr_info(PFX "%s: disabling interface\n", dev->name);
35
36	netif_carrier_off(dev);
37	netif_stop_queue(dev);
38
39	return 0;
40}
41
42static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb)
43{
44	return ClassifyPacket(netdev_priv(dev), skb);
45}
46
47/*******************************************************************
48* Function    -	bcm_transmit()
49*
50* Description - This is the main transmit function for our virtual
51*		interface(eth0). It handles the ARP packets. It
52*		clones this packet and then Queue it to a suitable
53*		Queue. Then calls the transmit_packet().
54*
55* Parameter   -	 skb - Pointer to the socket buffer structure
56*		 dev - Pointer to the virtual net device structure
57*
58*********************************************************************/
59
60static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev)
61{
62	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
63	u16 qindex = skb_get_queue_mapping(skb);
64
65
66	if (Adapter->device_removed || !Adapter->LinkUpStatus)
67		goto drop;
68
69	if (Adapter->TransferMode != IP_PACKET_ONLY_MODE)
70		goto drop;
71
72	if (INVALID_QUEUE_INDEX == qindex)
73		goto drop;
74
75	if (Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >=
76	    SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
77		return NETDEV_TX_BUSY;
78
79	/* Now Enqueue the packet */
80	if (netif_msg_tx_queued(Adapter))
81		pr_info(PFX "%s: enqueueing packet to queue %d\n",
82			dev->name, qindex);
83
84	spin_lock(&Adapter->PackInfo[qindex].SFQueueLock);
85	Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len;
86	Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++;
87
88	*((B_UINT32 *) skb->cb + SKB_CB_LATENCY_OFFSET) = jiffies;
89	ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue,
90		      Adapter->PackInfo[qindex].LastTxQueue, skb);
91	atomic_inc(&Adapter->TotalPacketCount);
92	spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock);
93
94	/* FIXME - this is racy and incorrect, replace with work queue */
95	if (!atomic_read(&Adapter->TxPktAvail)) {
96		atomic_set(&Adapter->TxPktAvail, 1);
97		wake_up(&Adapter->tx_packet_wait_queue);
98	}
99	return NETDEV_TX_OK;
100
101 drop:
102	dev_kfree_skb(skb);
103	return NETDEV_TX_OK;
104}
105
106
107
108/**
109@ingroup init_functions
110Register other driver entry points with the kernel
111*/
112static const struct net_device_ops bcmNetDevOps = {
113	.ndo_open		= bcm_open,
114	.ndo_stop		= bcm_close,
115	.ndo_start_xmit	        = bcm_transmit,
116	.ndo_change_mtu	        = eth_change_mtu,
117	.ndo_set_mac_address    = eth_mac_addr,
118	.ndo_validate_addr	= eth_validate_addr,
119	.ndo_select_queue	= bcm_select_queue,
120};
121
122static struct device_type wimax_type = {
123	.name	= "wimax",
124};
125
126static int bcm_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
127{
128	cmd->supported		= 0;
129	cmd->advertising	= 0;
130	cmd->speed		= SPEED_10000;
131	cmd->duplex		= DUPLEX_FULL;
132	cmd->port		= PORT_TP;
133	cmd->phy_address	= 0;
134	cmd->transceiver	= XCVR_INTERNAL;
135	cmd->autoneg		= AUTONEG_DISABLE;
136	cmd->maxtxpkt		= 0;
137	cmd->maxrxpkt		= 0;
138	return 0;
139}
140
141static void bcm_get_drvinfo(struct net_device *dev,
142			    struct ethtool_drvinfo *info)
143{
144	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
145	PS_INTERFACE_ADAPTER psIntfAdapter = Adapter->pvInterfaceAdapter;
146	struct usb_device *udev = interface_to_usbdev(psIntfAdapter->interface);
147
148	strcpy(info->driver, DRV_NAME);
149	strcpy(info->version, DRV_VERSION);
150	snprintf(info->fw_version, sizeof(info->fw_version), "%u.%u",
151		 Adapter->uiFlashLayoutMajorVersion,
152		 Adapter->uiFlashLayoutMinorVersion);
153
154	usb_make_path(udev, info->bus_info, sizeof(info->bus_info));
155}
156
157static u32 bcm_get_link(struct net_device *dev)
158{
159	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
160
161	return Adapter->LinkUpStatus;
162}
163
164static u32 bcm_get_msglevel(struct net_device *dev)
165{
166	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
167
168	return Adapter->msg_enable;
169}
170
171static void bcm_set_msglevel(struct net_device *dev, u32 level)
172{
173	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
174
175	Adapter->msg_enable = level;
176}
177
178static const struct ethtool_ops bcm_ethtool_ops = {
179	.get_settings	= bcm_get_settings,
180	.get_drvinfo	= bcm_get_drvinfo,
181	.get_link	= bcm_get_link,
182	.get_msglevel	= bcm_get_msglevel,
183	.set_msglevel	= bcm_set_msglevel,
184};
185
186int register_networkdev(PMINI_ADAPTER Adapter)
187{
188	struct net_device *net = Adapter->dev;
189	PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter;
190	struct usb_interface *udev = IntfAdapter->interface;
191	struct usb_device *xdev = IntfAdapter->udev;
192
193	int result;
194
195	net->netdev_ops = &bcmNetDevOps;
196	net->ethtool_ops = &bcm_ethtool_ops;
197	net->mtu = MTU_SIZE;	/* 1400 Bytes */
198	net->tx_queue_len = TX_QLEN;
199	net->flags |= IFF_NOARP;
200
201	netif_carrier_off(net);
202
203	SET_NETDEV_DEVTYPE(net, &wimax_type);
204
205	/* Read the MAC Address from EEPROM */
206	result = ReadMacAddressFromNVM(Adapter);
207	if (result != STATUS_SUCCESS) {
208		dev_err(&udev->dev,
209			PFX "Error in Reading the mac Address: %d", result);
210		return -EIO;
211	}
212
213	result = register_netdev(net);
214	if (result)
215		return result;
216
217	gblpnetdev = Adapter->dev;
218
219	if (netif_msg_probe(Adapter))
220		dev_info(&udev->dev, PFX "%s: register usb-%s-%s %pM\n",
221			 net->name, xdev->bus->bus_name, xdev->devpath,
222			 net->dev_addr);
223
224	return 0;
225}
226
227void unregister_networkdev(PMINI_ADAPTER Adapter)
228{
229	struct net_device *net = Adapter->dev;
230	PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter;
231	struct usb_interface *udev = IntfAdapter->interface;
232	struct usb_device *xdev = IntfAdapter->udev;
233
234	if (netif_msg_probe(Adapter))
235		dev_info(&udev->dev, PFX "%s: unregister usb-%s%s\n",
236			 net->name, xdev->bus->bus_name, xdev->devpath);
237
238	unregister_netdev(Adapter->dev);
239}
240