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