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
49
50
51
52
53
54
55
56
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
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
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
110
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;
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
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