1 #include "headers.h"
2 
3 struct net_device *gblpnetdev;
4 
bcm_open(struct net_device * dev)5 static 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 
bcm_close(struct net_device * dev)29 static 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 
bcm_select_queue(struct net_device * dev,struct sk_buff * skb)42 static 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 
bcm_transmit(struct sk_buff * skb,struct net_device * dev)60 static 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
110 Register other driver entry points with the kernel
111 */
112 static 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 
122 static struct device_type wimax_type = {
123 	.name	= "wimax",
124 };
125 
bcm_get_settings(struct net_device * dev,struct ethtool_cmd * cmd)126 static 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 
bcm_get_drvinfo(struct net_device * dev,struct ethtool_drvinfo * info)141 static 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 
bcm_get_link(struct net_device * dev)157 static u32 bcm_get_link(struct net_device *dev)
158 {
159 	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
160 
161 	return Adapter->LinkUpStatus;
162 }
163 
bcm_get_msglevel(struct net_device * dev)164 static 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 
bcm_set_msglevel(struct net_device * dev,u32 level)171 static 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 
178 static 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 
register_networkdev(PMINI_ADAPTER Adapter)186 int 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 
unregister_networkdev(PMINI_ADAPTER Adapter)227 void 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