]> Pileus Git - ~andy/linux/blob - drivers/staging/bcm/Bcmnet.c
firewire: don't use PREPARE_DELAYED_WORK
[~andy/linux] / drivers / staging / bcm / Bcmnet.c
1 #include "headers.h"
2
3 struct net_device *gblpnetdev;
4
5 static INT bcm_open(struct net_device *dev)
6 {
7         struct bcm_mini_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
29 static INT bcm_close(struct net_device *dev)
30 {
31         struct bcm_mini_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
42 static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb,
43                             void *accel_priv)
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
61 static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev)
62 {
63         struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
64         u16 qindex = skb_get_queue_mapping(skb);
65
66
67         if (Adapter->device_removed || !Adapter->LinkUpStatus)
68                 goto drop;
69
70         if (Adapter->TransferMode != IP_PACKET_ONLY_MODE)
71                 goto drop;
72
73         if (INVALID_QUEUE_INDEX == qindex)
74                 goto drop;
75
76         if (Adapter->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(Adapter))
82                 pr_info(PFX "%s: enqueueing packet to queue %d\n",
83                         dev->name, qindex);
84
85         spin_lock(&Adapter->PackInfo[qindex].SFQueueLock);
86         Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len;
87         Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++;
88
89         *((B_UINT32 *) skb->cb + SKB_CB_LATENCY_OFFSET) = jiffies;
90         ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue,
91                       Adapter->PackInfo[qindex].LastTxQueue, skb);
92         atomic_inc(&Adapter->TotalPacketCount);
93         spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock);
94
95         /* FIXME - this is racy and incorrect, replace with work queue */
96         if (!atomic_read(&Adapter->TxPktAvail)) {
97                 atomic_set(&Adapter->TxPktAvail, 1);
98                 wake_up(&Adapter->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
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
142 static void bcm_get_drvinfo(struct net_device *dev,
143                             struct ethtool_drvinfo *info)
144 {
145         struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
146         struct bcm_interface_adapter *psIntfAdapter =
147                                                 Adapter->pvInterfaceAdapter;
148         struct usb_device *udev = interface_to_usbdev(psIntfAdapter->interface);
149
150         strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
151         strlcpy(info->version, DRV_VERSION, sizeof(info->version));
152         snprintf(info->fw_version, sizeof(info->fw_version), "%u.%u",
153                  Adapter->uiFlashLayoutMajorVersion,
154                  Adapter->uiFlashLayoutMinorVersion);
155
156         usb_make_path(udev, info->bus_info, sizeof(info->bus_info));
157 }
158
159 static u32 bcm_get_link(struct net_device *dev)
160 {
161         struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
162
163         return Adapter->LinkUpStatus;
164 }
165
166 static u32 bcm_get_msglevel(struct net_device *dev)
167 {
168         struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
169
170         return Adapter->msg_enable;
171 }
172
173 static void bcm_set_msglevel(struct net_device *dev, u32 level)
174 {
175         struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
176
177         Adapter->msg_enable = level;
178 }
179
180 static const struct ethtool_ops bcm_ethtool_ops = {
181         .get_settings   = bcm_get_settings,
182         .get_drvinfo    = bcm_get_drvinfo,
183         .get_link       = bcm_get_link,
184         .get_msglevel   = bcm_get_msglevel,
185         .set_msglevel   = bcm_set_msglevel,
186 };
187
188 int register_networkdev(struct bcm_mini_adapter *Adapter)
189 {
190         struct net_device *net = Adapter->dev;
191         struct bcm_interface_adapter *IntfAdapter = Adapter->pvInterfaceAdapter;
192         struct usb_interface *udev = IntfAdapter->interface;
193         struct usb_device *xdev = IntfAdapter->udev;
194
195         int result;
196
197         net->netdev_ops = &bcmNetDevOps;
198         net->ethtool_ops = &bcm_ethtool_ops;
199         net->mtu = MTU_SIZE;    /* 1400 Bytes */
200         net->tx_queue_len = TX_QLEN;
201         net->flags |= IFF_NOARP;
202
203         netif_carrier_off(net);
204
205         SET_NETDEV_DEVTYPE(net, &wimax_type);
206
207         /* Read the MAC Address from EEPROM */
208         result = ReadMacAddressFromNVM(Adapter);
209         if (result != STATUS_SUCCESS) {
210                 dev_err(&udev->dev,
211                         PFX "Error in Reading the mac Address: %d", result);
212                 return -EIO;
213         }
214
215         result = register_netdev(net);
216         if (result)
217                 return result;
218
219         gblpnetdev = Adapter->dev;
220
221         if (netif_msg_probe(Adapter))
222                 dev_info(&udev->dev, PFX "%s: register usb-%s-%s %pM\n",
223                          net->name, xdev->bus->bus_name, xdev->devpath,
224                          net->dev_addr);
225
226         return 0;
227 }
228
229 void unregister_networkdev(struct bcm_mini_adapter *Adapter)
230 {
231         struct net_device *net = Adapter->dev;
232         struct bcm_interface_adapter *IntfAdapter = Adapter->pvInterfaceAdapter;
233         struct usb_interface *udev = IntfAdapter->interface;
234         struct usb_device *xdev = IntfAdapter->udev;
235
236         if (netif_msg_probe(Adapter))
237                 dev_info(&udev->dev, PFX "%s: unregister usb-%s%s\n",
238                          net->name, xdev->bus->bus_name, xdev->devpath);
239
240         unregister_netdev(Adapter->dev);
241 }