staging: vt6655: replace memcpy() by ether_addr_copy() using coccinelle and pack...
[linux-2.6-microblaze.git] / 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 *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
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
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
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
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 *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
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
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
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
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
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 }